diff options
author | YamaArashi <shadow962@live.com> | 2016-02-08 03:04:42 -0800 |
---|---|---|
committer | YamaArashi <shadow962@live.com> | 2016-02-08 03:04:42 -0800 |
commit | a5c638ceaca09d018d041f15e7e2518c217250bc (patch) | |
tree | 7374fe6cd30b24a25037dbdb259bbcf5300b13c2 | |
parent | 476b5c86e5bc21311dfb14d0f043fbf5b870781d (diff) |
remove Fortran, Objective C, and C++
216 files changed, 31 insertions, 340665 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b883f1f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.exe diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 37cbf5a..ec9e239 100755 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -360,10 +360,6 @@ EXTRA_PASSES =@extra_passes@ # Like EXTRA_PASSES, but these are used when linking. EXTRA_PROGRAMS = @extra_programs@ -# List of extra object files that should be compiled for this target machine. -# The rules for compiling them should be in the t-* file for the machine. -EXTRA_PARTS = @extra_parts@ - # List of extra object files that should be compiled and linked with # compiler proper (cc1, cc1obj, cc1plus). EXTRA_OBJS = @extra_objs@ @@ -376,13 +372,6 @@ EXTRA_GCC_OBJS =@host_extra_gcc_objs@ # Often this is edited directly by `configure'. EXTRA_HEADERS =@extra_headers_list@ -# Set this to `collect2' to enable use of collect2. -USE_COLLECT2 = @will_use_collect2@ -MAYBE_USE_COLLECT2 = @maybe_use_collect2@ -# It is convenient for configure to add the assignment at the beginning, -# so don't override it here. -USE_COLLECT2 = collect2$(exeext) - # List of extra C and assembler files to add to libgcc1.a. # Assembler files should have names ending in `.asm'. LIB1FUNCS_EXTRA = @@ -426,7 +415,7 @@ GCC_PASSES=xgcc$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) # List of things which should already be built whenever we try to use xgcc # to link anything. -GCC_PARTS=$(GCC_PASSES) $(LIBGCC) $(EXTRA_PROGRAMS) $(USE_COLLECT2) $(EXTRA_PARTS) +GCC_PARTS=$(GCC_PASSES) $(LIBGCC) $(EXTRA_PROGRAMS) # Directory to link to, when using the target `maketest'. DIR = ../gcc @@ -484,15 +473,6 @@ RUNTESTFLAGS = # Extra symbols for fixproto to define when parsing headers. FIXPROTO_DEFINES = -# Extra flags to use when compiling crt{begin,end}.o. -CRTSTUFF_T_CFLAGS = - -# Extra flags to use when compiling [m]crt0.o. -CRT0STUFF_T_CFLAGS = - -# "t" or nothing, for building multilibbed versions of, say, crtbegin.o. -T = - # End of variables for you to override. # Definition of `all' is here so that new rules inserted by sed @@ -671,17 +651,17 @@ STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \ insn-attr.h insn-attrtab.c insn-opinit.c genrtl.c genrtl.h tree-check.h \ s-flags s-config s-codes s-mlib s-under\ s-output s-recog s-emit s-extract s-peep s-check \ - s-attr s-attrtab s-opinit s-crt s-crtS s-crt0 \ + s-attr s-attrtab s-opinit \ genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \ genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext) \ genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \ genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \ gencheck$(build_exeext) \ xgcc$(exeext) cc1$(exeext) cpp$(exeext) $(EXTRA_PASSES) \ - $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) \ + $(EXTRA_PROGRAMS) gcc-cross$(exeext) \ $(CCCP)$(exeext) cc1obj$(exeext) enquire$(exeext) \ protoize$(exeext) unprotoize$(exeext) \ - specs collect2$(exeext) $(USE_COLLECT2) underscore.c \ + specs underscore.c \ gcov$(exeext) *.bp \ $(CYGNUS-LOCAL-range) *.range \ *.greg *.lreg *.combine *.flow *.cse *.jump *.rtl *.tree *.loop \ @@ -734,7 +714,6 @@ RTL_BASE_H = rtl.h rtl.def machmode.h machmode.def RTL_H = $(RTL_BASE_H) genrtl.h TREE_H = tree.h real.h tree.def machmode.h machmode.def tree-check.h BASIC_BLOCK_H = basic-block.h bitmap.h sbitmap.h -DEMANGLE_H = $(srcdir)/../include/demangle.h RECOG_H = recog.h EXPR_H = expr.h insn-codes.h REGS_H = regs.h varray.h machmode.h machmode.def @@ -819,17 +798,17 @@ all.internal: start.encap rest.encap # Note that we can compile enquire using the cross-compiler just built, # although we can't run it on this machine. all.cross: native gcc-cross specs stmp-headers $(STMP_FIXPROTO) $(LIBGCC) \ - $(LIBGCC1_TEST) $(EXTRA_PARTS) lang.all.cross + $(LIBGCC1_TEST) lang.all.cross # This is what to compile if making gcc with a cross-compiler. -all.build: native xgcc$(exeext) $(EXTRA_PARTS) lang.all.build +all.build: native xgcc$(exeext) lang.all.build # This is what must be made before installing GCC and converting libraries. start.encap: native xgcc$(exeext) specs $(LIBGCC1) xlimits.h lang.start.encap # These can't be made until after GCC can run. -rest.encap: stmp-headers $(STMP_FIXPROTO) $(LIBGCC) $(EXTRA_PARTS) lang.rest.encap +rest.encap: stmp-headers $(STMP_FIXPROTO) $(LIBGCC) lang.rest.encap # This is what is made with the host's compiler # whether making a cross compiler or not. native: config.status auto-host.h cpp$(exeext) $(LANGUAGES) \ - $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2) + $(EXTRA_PASSES) $(EXTRA_PROGRAMS) # Define the names for selecting languages in LANGUAGES. C c: cc1$(exeext) @@ -1025,9 +1004,9 @@ libgcc2.ready: $(GCC_PASSES) $(LIBGCC2_DEPS) stmp-int-hdrs $(STMP_FIXPROTO) touch libgcc2.ready; \ fi -LIB2ADD = $(srcdir)/frame.c $(LIB2FUNCS_EXTRA) $(LANG_LIB2FUNCS) +LIB2ADD = $(LIB2FUNCS_EXTRA) $(LANG_LIB2FUNCS) libgcc2.a: libgcc2.c libgcc2.ready $(CONFIG_H) $(FPBIT) $(DPBIT) $(LIB2ADD) \ - machmode.h longlong.h frame.h gbl-ctors.h config.status + machmode.h longlong.h config.status # Actually build it in tmplibgcc2.a, then rename at end, # so that libgcc2.a itself remains nonexistent if compilation is aborted. -rm -f tmplibgcc2.a @@ -1159,8 +1138,7 @@ s-mlib: $(srcdir)/genmultilib Makefile # Build multiple copies of libgcc.a, one for each target switch. stmp-multilib: $(LIBGCC1) libgcc2.c libgcc2.ready $(CONFIG_H) \ - frame.h \ - $(LIB2ADD) machmode.h longlong.h gbl-ctors.h config.status + $(LIB2ADD) machmode.h longlong.h config.status for i in `$(GCC_FOR_TARGET) --print-multi-lib`; do \ dir=`echo $$i | sed -e 's/;.*$$//'`; \ flags=`echo $$i | sed -e 's/^[^;]*;//' -e 's/@/ -/g'`; \ @@ -1236,47 +1214,6 @@ stmp-multilib-sub: else true; \ fi; done -# Compile two additional files that are linked with every program -# linked using GCC on systems using COFF or ELF, for the sake of C++ -# constructors. -$(T)crtbegin.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \ - defaults.h frame.h gbl-ctors.h - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ - -finhibit-size-directive -fno-inline-functions -fno-exceptions $(CRTSTUFF_T_CFLAGS) \ - -c $(srcdir)/crtstuff.c -DCRT_BEGIN -o $(T)crtbegin$(objext) - -$(T)crtend.o: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \ - defaults.h frame.h gbl-ctors.h - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(MULTILIB_CFLAGS) -g0 \ - -finhibit-size-directive -fno-inline-functions -fno-exceptions $(CRTSTUFF_T_CFLAGS) \ - -c $(srcdir)/crtstuff.c -DCRT_END -o $(T)crtend$(objext) - -# On some systems we also want to install versions of these files -# compiled using PIC for use in shared libraries. -crtbeginS.o crtendS.o: s-crtS ; @true - -s-crtS: crtstuff.c $(GCC_PASSES) $(CONFIG_H) \ - defaults.h frame.h gbl-ctors.h - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS_S) \ - -DCRT_BEGIN -DCRTSTUFFS_O -finhibit-size-directive -fno-inline-functions \ - -fno-exceptions -g0 -c $(srcdir)/crtstuff.c - mv crtstuff$(objext) crtbeginS$(objext) - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(INCLUDES) $(CRTSTUFF_T_CFLAGS_S) \ - -DCRT_END -DCRTSTUFFS_O -finhibit-size-directive -fno-inline-functions \ - -fno-exceptions -g0 -c $(srcdir)/crtstuff.c -o crtendS$(objext) - touch s-crtS - -# Compile the start modules crt0.o and mcrt0.o that are linked with every program -crt0.o: s-crt0 ; @true -mcrt0.o: s-crt0; @true - -s-crt0: $(CRT0_S) $(MCRT0_S) $(GCC_PASSES) $(CONFIG_H) - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \ - -o crt0.o -c $(CRT0_S) - $(GCC_FOR_TARGET) $(GCC_CFLAGS) $(CRT0STUFF_T_CFLAGS) \ - -o mcrt0.o -c $(MCRT0_S) - touch s-crt0 -# # Compiling object files from source files. # Note that dependencies on obstack.h are not written @@ -1326,27 +1263,8 @@ graph.o: graph.c $(CONFIG_H) system.h toplev.h flags.h output.h $(RTL_H) \ hard-reg-set.h $(BASIC_BLOCK_H) sbitmap.o: sbitmap.c $(CONFIG_H) system.h $(RTL_H) flags.h $(BASIC_BLOCK_H) -collect2$(exeext): collect2.o tlink.o hash.o cplus-dem.o underscore.o \ - version.o choose-temp.o mkstemp.o $(LIBDEPS) -# Don't try modifying collect2 (aka ld) in place--it might be linking this. - -rm -f collect2$(exeext) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ collect2.o tlink.o hash.o \ - cplus-dem.o underscore.o version.o choose-temp.o mkstemp.o $(LIBS) - -collect2.o : collect2.c $(CONFIG_H) system.h gstab.h \ - $(srcdir)/../include/obstack.h $(DEMANGLE_H) collect2.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - -DTARGET_MACHINE=\"$(target_alias)\" $(MAYBE_USE_COLLECT2) \ - -c `echo $(srcdir)/collect2.c | sed 's,^\./,,'` - -tlink.o: tlink.c $(DEMANGLE_H) hash.h $(CONFIG_H) system.h toplev.h collect2.h hash.o: hash.c hash.h system.h toplev.h -cplus-dem.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H) - rm -f cplus-dem.c - $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cplus-dem.c - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) cplus-dem.c - pexecute.o: $(srcdir)/../libiberty/pexecute.c $(CONFIG_H) system.h rm -f pexecute.c $(LN_S) $(srcdir)/../libiberty/pexecute.c pexecute.c @@ -1450,7 +1368,7 @@ toplev.o : toplev.c $(CONFIG_H) system.h $(TREE_H) $(RTL_H) \ insn-codes.h insn-config.h $(RECOG_H) Makefile toplev.h dwarfout.h \ dwarf2out.h sdbout.h dbxout.h $(EXPR_H) \ $(lang_options_files) - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(MAYBE_USE_COLLECT2) \ + $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ -DTARGET_NAME=\"$(target_alias)\" \ -c `echo $(srcdir)/toplev.c | sed 's,^\./,,'` # END CYGNUS LOCAL @@ -2322,7 +2240,7 @@ mostlyclean: lang.mostlyclean -rm -f */*.sched2 */*.stack */*.regmove */*.gcse # Delete some files made during installation. -rm -f specs float.h-* enquire SYSCALLS.c.X SYSCALLS.c - -rm -f collect collect2 mips-tfile mips-tdump alloca.s + -rm -f collect mips-tfile mips-tdump alloca.s # Delete files generated for fixproto # CYGNUS LOCAL: binary installation -rm -rf fix-header xsys-protos.h deduced.h tmp-deduced.h \ @@ -2427,7 +2345,6 @@ realclean: maintainer-clean # END CYGNUS LOCAL # # Entry points `install' and `uninstall'. -# Also use `install-collect2' to install collect2 when the config files don't. # The semicolon is to prevent the install.sh -> install default rule # from doing anything. Having it run true helps avoid problems and @@ -2489,7 +2406,7 @@ installdirs: -if [ -d $(man1dir) ] ; then true ; else mkdir $(man1dir) ; chmod a+rx $(man1dir) ; fi # Install the compiler executables built during cross compilation. -install-common: native installdirs $(EXTRA_PARTS) lang.install-common +install-common: native installdirs lang.install-common for file in $(COMPILERS); do \ if [ -f $$file ] ; then \ rm -f $(libsubdir)/$$file; \ @@ -2497,19 +2414,12 @@ install-common: native installdirs $(EXTRA_PARTS) lang.install-common else true; \ fi; \ done - for file in $(EXTRA_PASSES) $(EXTRA_PROGRAMS) $(USE_COLLECT2) ..; do \ + for file in $(EXTRA_PASSES) $(EXTRA_PROGRAMS) ..; do \ if [ x"$$file" != x.. ]; then \ rm -f $(libsubdir)/$$file; \ $(INSTALL_PROGRAM) $$file $(libsubdir)/$$file; \ else true; fi; \ done - for file in $(EXTRA_PARTS) ..; do \ - if [ x"$$file" != x.. ]; then \ - rm -f $(libsubdir)/$$file; \ - $(INSTALL_DATA) $$file $(libsubdir)/$$file; \ - chmod a-x $(libsubdir)/$$file; \ - else true; fi; \ - done # Don't mess with specs if it doesn't exist yet. -if [ -f specs ] ; then \ rm -f $(libsubdir)/specs; \ @@ -2714,12 +2624,6 @@ install-assert-h: assert.h installdirs chmod a-x $(assertdir)/assert.h; \ fi -# Use this target to install the program `collect2' under the name `collect2'. -install-collect2: collect2 installdirs - $(INSTALL_PROGRAM) collect2$(exeext) $(libsubdir)/collect2$(exeext) -# Install the driver program as $(libsubdir)/gcc for collect2. - $(INSTALL_PROGRAM) xgcc$(exeext) $(libsubdir)/gcc$(exeext) - # Cancel installation by deleting the installed files. uninstall: lang.uninstall -rm -rf $(libsubdir) @@ -3055,7 +2959,6 @@ stage1-start: # dir will work properly. -if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage1 ; else true ; fi -if [ -f ld$(exeext) ] ; then $(LN_S) ../ld$(exeext) stage1 ; else true ; fi - -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage1 ; else true ; fi -rm -f stage1/libgcc.a -cp libgcc.a stage1 -if $(RANLIB_TEST_FOR_TARGET) ; then \ @@ -3078,7 +2981,6 @@ stage2-start: # dir will work properly. -if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage2 ; else true ; fi -if [ -f ld$(exeext) ] ; then $(LN_S) ../ld$(exeext) stage2 ; else true ; fi - -if [ -f collect-ld ] ; then $(LN_S) ../collect-ld$(exeext) stage2 ; else true ; fi -rm -f stage2/libgcc.a -cp libgcc.a stage2 -if $(RANLIB_TEST_FOR_TARGET) ; then \ @@ -3101,7 +3003,6 @@ stage3-start: # dir will work properly. -if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage3 ; else true ; fi -if [ -f ld$(exeext) ] ; then $(LN_S) ../ld$(exeext) stage3 ; else true ; fi - -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage3 ; else true ; fi -rm -f stage3/libgcc.a -cp libgcc.a stage3 -if $(RANLIB_TEST_FOR_TARGET) ; then \ @@ -3124,7 +3025,6 @@ stage4-start: # dir will work properly. -if [ -f as$(exeext) ] ; then $(LN_S) ../as$(exeext) stage4 ; else true ; fi -if [ -f ld$(exeext) ] ; then $(LN_S) ../ld$(exeext) stage4 ; else true ; fi - -if [ -f collect-ld$(exeext) ] ; then $(LN_S) ../collect-ld$(exeext) stage4 ; else true ; fi -rm -f stage4/libgcc.a -cp libgcc.a stage4 -if $(RANLIB_TEST_FOR_TARGET) ; then \ diff --git a/gcc/collect2.c b/gcc/collect2.c deleted file mode 100755 index 7060c2e..0000000 --- a/gcc/collect2.c +++ /dev/null @@ -1,3742 +0,0 @@ -/* Collect static initialization info into data structures that can be - traversed by C++ initialization and finalization routines. - Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. - Contributed by Chris Smith (csmith@convex.com). - Heavily modified by Michael Meissner (meissner@cygnus.com), - Per Bothner (bothner@cygnus.com), and John Gilmore (gnu@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Build tables of static constructors and destructors and run ld. */ - -#include "config.h" -#include "system.h" -#include <signal.h> - -#ifdef vfork /* Autoconf may define this to fork for us. */ -# define VFORK_STRING "fork" -#else -# define VFORK_STRING "vfork" -#endif -#ifdef HAVE_VFORK_H -#include <vfork.h> -#endif -#ifdef VMS -#define vfork() (decc$$alloc_vfork_blocks() >= 0 ? \ - lib$get_current_invo_context(decc$$get_vfork_jmpbuf()) : -1) -#endif /* VMS */ - -#define COLLECT - -#include "collect2.h" -#include "demangle.h" -#include "obstack.h" -#ifdef __CYGWIN__ -#include <process.h> -#endif - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern char *make_temp_file PROTO ((char *)); - -/* On certain systems, we have code that works by scanning the object file - directly. But this code uses system-specific header files and library - functions, so turn it off in a cross-compiler. Likewise, the names of - the utilities are not correct for a cross-compiler; we have to hope that - cross-versions are in the proper directories. */ - -#ifdef CROSS_COMPILE -#undef SUNOS4_SHARED_LIBRARIES -#undef OBJECT_FORMAT_COFF -#undef OBJECT_FORMAT_ROSE -#undef MD_EXEC_PREFIX -#undef REAL_LD_FILE_NAME -#undef REAL_NM_FILE_NAME -#undef REAL_STRIP_FILE_NAME -#endif - -/* If we cannot use a special method, use the ordinary one: - run nm to find what symbols are present. - In a cross-compiler, this means you need a cross nm, - but that is not quite as unpleasant as special headers. */ - -#if !defined (OBJECT_FORMAT_COFF) && !defined (OBJECT_FORMAT_ROSE) -#define OBJECT_FORMAT_NONE -#endif - -#ifdef OBJECT_FORMAT_COFF - -#include <a.out.h> -#include <ar.h> - -#ifdef UMAX -#include <sgs.h> -#endif - -/* Many versions of ldfcn.h define these. */ -#ifdef FREAD -#undef FREAD -#undef FWRITE -#endif - -#include <ldfcn.h> - -/* Some systems have an ISCOFF macro, but others do not. In some cases - the macro may be wrong. MY_ISCOFF is defined in tm.h files for machines - that either do not have an ISCOFF macro in /usr/include or for those - where it is wrong. */ - -#ifndef MY_ISCOFF -#define MY_ISCOFF(X) ISCOFF (X) -#endif - -#endif /* OBJECT_FORMAT_COFF */ - -#ifdef OBJECT_FORMAT_ROSE - -#ifdef _OSF_SOURCE -#define USE_MMAP -#endif - -#ifdef USE_MMAP -#include <sys/mman.h> -#endif - -#include <unistd.h> -#include <mach_o_format.h> -#include <mach_o_header.h> -#include <mach_o_vals.h> -#include <mach_o_types.h> - -#endif /* OBJECT_FORMAT_ROSE */ - -#ifdef OBJECT_FORMAT_NONE - -/* Default flags to pass to nm. */ -#ifndef NM_FLAGS -#define NM_FLAGS "-n" -#endif - -#endif /* OBJECT_FORMAT_NONE */ - -/* Some systems use __main in a way incompatible with its use in gcc, in these - cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to - give the same symbol without quotes for an alternative entry point. You - must define both, or neither. */ -#ifndef NAME__MAIN -#define NAME__MAIN "__main" -#define SYMBOL__MAIN __main -#endif - -/* This must match tree.h. */ -#define DEFAULT_INIT_PRIORITY 65535 - -#if defined (LDD_SUFFIX) || SUNOS4_SHARED_LIBRARIES -#define SCAN_LIBRARIES -#endif - -#ifdef USE_COLLECT2 -int do_collecting = 1; -#else -int do_collecting = 0; -#endif - -/* Linked lists of constructor and destructor names. */ - -struct id -{ - struct id *next; - int sequence; - char name[1]; -}; - -struct head -{ - struct id *first; - struct id *last; - int number; -}; - -/* Enumeration giving which pass this is for scanning the program file. */ - -enum pass { - PASS_FIRST, /* without constructors */ - PASS_OBJ, /* individual objects */ - PASS_LIB, /* looking for shared libraries */ - PASS_SECOND /* with constructors linked in */ -}; - -extern char *version_string; - -int vflag; /* true if -v */ -static int rflag; /* true if -r */ -static int strip_flag; /* true if -s */ -#ifdef COLLECT_EXPORT_LIST -static int export_flag; /* true if -bE */ -static int aix64_flag; /* true if -b64 */ -#endif - -int debug; /* true if -debug */ - -static int shared_obj; /* true if -shared */ - -static char *c_file; /* <xxx>.c for constructor/destructor list. */ -static char *o_file; /* <xxx>.o for constructor/destructor list. */ -#ifdef COLLECT_EXPORT_LIST -static char *export_file; /* <xxx>.x for AIX export list. */ -static char *import_file; /* <xxx>.p for AIX import list. */ -#endif -char *ldout; /* File for ld errors. */ -static char *output_file; /* Output file for ld. */ -static char *nm_file_name; /* pathname of nm */ -#ifdef LDD_SUFFIX -static char *ldd_file_name; /* pathname of ldd (or equivalent) */ -#endif -static char *strip_file_name; /* pathname of strip */ -char *c_file_name; /* pathname of gcc */ -static char *initname, *fininame; /* names of init and fini funcs */ - -static struct head constructors; /* list of constructors found */ -static struct head destructors; /* list of destructors found */ -#ifdef COLLECT_EXPORT_LIST -static struct head exports; /* list of exported symbols */ -static struct head imports; /* list of imported symbols */ -static struct head undefined; /* list of undefined symbols */ -#endif -static struct head frame_tables; /* list of frame unwind info tables */ - -struct obstack temporary_obstack; -struct obstack permanent_obstack; -char * temporary_firstobj; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -extern FILE *fdopen (); - -#ifndef GET_ENV_PATH_LIST -#define GET_ENV_PATH_LIST(VAR,NAME) do { (VAR) = getenv (NAME); } while (0) -#endif - -/* Structure to hold all the directories in which to search for files to - execute. */ - -struct prefix_list -{ - char *prefix; /* String to prepend to the path. */ - struct prefix_list *next; /* Next in linked list. */ -}; - -struct path_prefix -{ - struct prefix_list *plist; /* List of prefixes to try */ - int max_len; /* Max length of a prefix in PLIST */ - char *name; /* Name of this list (used in config stuff) */ -}; - -#ifdef COLLECT_EXPORT_LIST -/* Lists to keep libraries to be scanned for global constructors/destructors. */ -static struct head libs; /* list of libraries */ -static struct path_prefix cmdline_lib_dirs; /* directories specified with -L */ -static struct path_prefix libpath_lib_dirs; /* directories in LIBPATH */ -static struct path_prefix *libpaths[3] = {&cmdline_lib_dirs, - &libpath_lib_dirs, NULL}; -static char *libexts[3] = {"a", "so", NULL}; /* possible library extentions */ -#endif - -void error PVPROTO((const char *, ...)) ATTRIBUTE_PRINTF_1; -void fatal PVPROTO((const char *, ...)) - ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -void fatal_perror PVPROTO((const char *, ...)) - ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; -static char *my_strerror PROTO((int)); -static const char *my_strsignal PROTO((int)); -static void handler PROTO((int)); -static int is_ctor_dtor PROTO((char *)); -static char *find_a_file PROTO((struct path_prefix *, char *)); -static void add_prefix PROTO((struct path_prefix *, char *)); -static void prefix_from_env PROTO((char *, struct path_prefix *)); -static void prefix_from_string PROTO((char *, struct path_prefix *)); -static void do_wait PROTO((char *)); -static void fork_execute PROTO((char *, char **)); -static void maybe_unlink PROTO((char *)); -static void add_to_list PROTO((struct head *, char *)); -static int extract_init_priority PROTO((char *)); -static void sort_ids PROTO((struct head *)); -static void write_list PROTO((FILE *, char *, struct id *)); -#ifdef COLLECT_EXPORT_LIST -static void dump_list PROTO((FILE *, char *, struct id *)); -#endif -#if 0 -static void dump_prefix_list PROTO((FILE *, char *, struct prefix_list *)); -#endif -static void write_list_with_asm PROTO((FILE *, char *, struct id *)); -static void write_c_file PROTO((FILE *, char *)); -static void scan_prog_file PROTO((char *, enum pass)); -#ifdef SCAN_LIBRARIES -static void scan_libraries PROTO((char *)); -#endif -#ifdef COLLECT_EXPORT_LIST -static int is_in_list PROTO((char *, struct id *)); -static void write_export_file PROTO((FILE *)); -static void write_import_file PROTO((FILE *)); -static char *resolve_lib_name PROTO((char *)); -static int use_import_list PROTO((char *)); -static int ignore_library PROTO((char *)); -#endif - -#ifdef NO_DUP2 -int -dup2 (oldfd, newfd) - int oldfd; - int newfd; -{ - int fdtmp[256]; - int fdx = 0; - int fd; - - if (oldfd == newfd) - return oldfd; - close (newfd); - while ((fd = dup (oldfd)) != newfd && fd >= 0) /* good enough for low fd's */ - fdtmp[fdx++] = fd; - while (fdx > 0) - close (fdtmp[--fdx]); - - return fd; -} -#endif - -static char * -my_strerror (e) - int e; -{ - -#ifdef HAVE_STRERROR - return strerror (e); - -#else - - static char buffer[30]; - if (!e) - return ""; - - if (e > 0 && e < sys_nerr) - return sys_errlist[e]; - - sprintf (buffer, "Unknown error %d", e); - return buffer; -#endif -} - -static const char * -my_strsignal (s) - int s; -{ -#ifdef HAVE_STRSIGNAL - return strsignal (s); -#else - if (s >= 0 && s < NSIG) - { -# ifdef NO_SYS_SIGLIST - static char buffer[30]; - - sprintf (buffer, "Unknown signal %d", s); - return buffer; -# else - return sys_siglist[s]; -# endif - } - else - return NULL; -#endif /* HAVE_STRSIGNAL */ -} - -/* Delete tempfiles and exit function. */ - -void -collect_exit (status) - int status; -{ - if (c_file != 0 && c_file[0]) - maybe_unlink (c_file); - - if (o_file != 0 && o_file[0]) - maybe_unlink (o_file); - -#ifdef COLLECT_EXPORT_LIST - if (export_file != 0 && export_file[0]) - maybe_unlink (export_file); - - if (import_file != 0 && import_file[0]) - maybe_unlink (import_file); -#endif - - if (ldout != 0 && ldout[0]) - { - dump_file (ldout); - maybe_unlink (ldout); - } - - if (status != 0 && output_file != 0 && output_file[0]) - maybe_unlink (output_file); - - exit (status); -} - - -/* Die when sys call fails. */ - -void -fatal_perror VPROTO((const char * string, ...)) -{ -#ifndef ANSI_PROTOTYPES - const char *string; -#endif - int e = errno; - va_list ap; - - VA_START (ap, string); - -#ifndef ANSI_PROTOTYPES - string = va_arg (ap, const char *); -#endif - - fprintf (stderr, "collect2: "); - vfprintf (stderr, string, ap); - fprintf (stderr, ": %s\n", my_strerror (e)); - va_end (ap); - - collect_exit (FATAL_EXIT_CODE); -} - -/* Just die. */ - -void -fatal VPROTO((const char * string, ...)) -{ -#ifndef ANSI_PROTOTYPES - const char *string; -#endif - va_list ap; - - VA_START (ap, string); - -#ifndef ANSI_PROTOTYPES - string = va_arg (ap, const char *); -#endif - - fprintf (stderr, "collect2: "); - vfprintf (stderr, string, ap); - fprintf (stderr, "\n"); - va_end (ap); - - collect_exit (FATAL_EXIT_CODE); -} - -/* Write error message. */ - -void -error VPROTO((const char * string, ...)) -{ -#ifndef ANSI_PROTOTYPES - const char * string; -#endif - va_list ap; - - VA_START (ap, string); - -#ifndef ANSI_PROTOTYPES - string = va_arg (ap, const char *); -#endif - - fprintf (stderr, "collect2: "); - vfprintf (stderr, string, ap); - fprintf (stderr, "\n"); - va_end(ap); -} - -/* In case obstack is linked in, and abort is defined to fancy_abort, - provide a default entry. */ - -void -fancy_abort () -{ - fatal ("internal error"); -} - - -static void -handler (signo) - int signo; -{ - if (c_file != 0 && c_file[0]) - maybe_unlink (c_file); - - if (o_file != 0 && o_file[0]) - maybe_unlink (o_file); - - if (ldout != 0 && ldout[0]) - maybe_unlink (ldout); - -#ifdef COLLECT_EXPORT_LIST - if (export_file != 0 && export_file[0]) - maybe_unlink (export_file); - - if (import_file != 0 && import_file[0]) - maybe_unlink (import_file); -#endif - - signal (signo, SIG_DFL); - kill (getpid (), signo); -} - - -PTR -xcalloc (size1, size2) - size_t size1, size2; -{ - PTR ptr = (PTR) calloc (size1, size2); - if (!ptr) - fatal ("out of memory"); - return ptr; -} - -PTR -xmalloc (size) - size_t size; -{ - PTR ptr = (PTR) malloc (size); - if (!ptr) - fatal ("out of memory"); - return ptr; -} - -PTR -xrealloc (old, size) - PTR old; - size_t size; -{ - register PTR ptr; - if (ptr) - ptr = (PTR) realloc (old, size); - else - ptr = (PTR) malloc (size); - if (ptr == 0) - fatal ("virtual memory exhausted"); - return ptr; -} - -int -file_exists (name) - char *name; -{ - return access (name, R_OK) == 0; -} - -/* Make a copy of a string INPUT with size SIZE. */ - -char * -savestring (input, size) - char *input; - int size; -{ - char *output = (char *) xmalloc (size + 1); - bcopy (input, output, size); - output[size] = 0; - return output; -} - -/* Parse a reasonable subset of shell quoting syntax. */ - -static char * -extract_string (pp) - char **pp; -{ - char *p = *pp; - int backquote = 0; - int inside = 0; - - for (;;) - { - char c = *p; - if (c == '\0') - break; - ++p; - if (backquote) - obstack_1grow (&temporary_obstack, c); - else if (! inside && c == ' ') - break; - else if (! inside && c == '\\') - backquote = 1; - else if (c == '\'') - inside = !inside; - else - obstack_1grow (&temporary_obstack, c); - } - - obstack_1grow (&temporary_obstack, '\0'); - *pp = p; - return obstack_finish (&temporary_obstack); -} - -void -dump_file (name) - char *name; -{ - FILE *stream = fopen (name, "r"); - int no_demangle = !! getenv ("COLLECT_NO_DEMANGLE"); - - if (stream == 0) - return; - while (1) - { - int c; - while (c = getc (stream), - c != EOF && (ISALNUM (c) || c == '_' || c == '$' || c == '.')) - obstack_1grow (&temporary_obstack, c); - if (obstack_object_size (&temporary_obstack) > 0) - { - char *word, *p, *result; - obstack_1grow (&temporary_obstack, '\0'); - word = obstack_finish (&temporary_obstack); - - if (*word == '.') - ++word, putc ('.', stderr); - p = word; - if (*p == '_' && prepends_underscore) - ++p; - - if (no_demangle) - result = 0; - else - result = cplus_demangle (p, DMGL_PARAMS | DMGL_ANSI); - - if (result) - { - int diff; - fputs (result, stderr); - - diff = strlen (word) - strlen (result); - while (diff > 0) - --diff, putc (' ', stderr); - while (diff < 0 && c == ' ') - ++diff, c = getc (stream); - - free (result); - } - else - fputs (word, stderr); - - fflush (stderr); - obstack_free (&temporary_obstack, temporary_firstobj); - } - if (c == EOF) - break; - putc (c, stderr); - } - fclose (stream); -} - -/* Decide whether the given symbol is: - a constructor (1), a destructor (2), or neither (0). */ - -static int -is_ctor_dtor (s) - char *s; -{ - struct names { char *name; int len; int ret; int two_underscores; }; - - register struct names *p; - register int ch; - register char *orig_s = s; - - static struct names special[] = { -#ifdef NO_DOLLAR_IN_LABEL -#ifdef NO_DOT_IN_LABEL - { "GLOBAL__I_", sizeof ("GLOBAL__I_")-1, 1, 0 }, - { "GLOBAL__D_", sizeof ("GLOBAL__D_")-1, 2, 0 }, - { "GLOBAL__F_", sizeof ("GLOBAL__F_")-1, 5, 0 }, -#else - { "GLOBAL_.I.", sizeof ("GLOBAL_.I.")-1, 1, 0 }, - { "GLOBAL_.D.", sizeof ("GLOBAL_.D.")-1, 2, 0 }, - { "GLOBAL_.F.", sizeof ("GLOBAL_.F.")-1, 5, 0 }, -#endif -#else - { "GLOBAL_$I$", sizeof ("GLOBAL_$I$")-1, 1, 0 }, - { "GLOBAL_$D$", sizeof ("GLOBAL_$D$")-1, 2, 0 }, - { "GLOBAL_$F$", sizeof ("GLOBAL_$F$")-1, 5, 0 }, -#endif - { "GLOBAL__FI_", sizeof ("GLOBAL__FI_")-1, 3, 0 }, - { "GLOBAL__FD_", sizeof ("GLOBAL__FD_")-1, 4, 0 }, -#ifdef CFRONT_LOSSAGE /* Do not collect cfront initialization functions. - cfront has its own linker procedure to collect them; - if collect2 gets them too, they get collected twice - when the cfront procedure is run and the compiler used - for linking happens to be GCC. */ - { "sti__", sizeof ("sti__")-1, 1, 1 }, - { "std__", sizeof ("std__")-1, 2, 1 }, -#endif /* CFRONT_LOSSAGE */ - { NULL, 0, 0, 0 } - }; - - while ((ch = *s) == '_') - ++s; - - if (s == orig_s) - return 0; - - for (p = &special[0]; p->len > 0; p++) - { - if (ch == p->name[0] - && (!p->two_underscores || ((s - orig_s) >= 2)) - && strncmp(s, p->name, p->len) == 0) - { - return p->ret; - } - } - return 0; -} - -/* Routine to add variables to the environment. */ - -#ifndef HAVE_PUTENV - -int -putenv (str) - char *str; -{ -#ifndef VMS /* nor about VMS */ - - extern char **environ; - char **old_environ = environ; - char **envp; - int num_envs = 0; - int name_len = 1; - char *p = str; - int ch; - - while ((ch = *p++) != '\0' && ch != '=') - name_len++; - - if (!ch) - abort (); - - /* Search for replacing an existing environment variable, and - count the number of total environment variables. */ - for (envp = old_environ; *envp; envp++) - { - num_envs++; - if (!strncmp (str, *envp, name_len)) - { - *envp = str; - return 0; - } - } - - /* Add a new environment variable */ - environ = (char **) xmalloc (sizeof (char *) * (num_envs+2)); - *environ = str; - bcopy ((char *) old_environ, (char *) (environ + 1), - sizeof (char *) * (num_envs+1)); - - return 0; -#endif /* VMS */ -} - -#endif /* HAVE_PUTENV */ - -/* By default, colon separates directories in a path. */ -#ifndef PATH_SEPARATOR -#define PATH_SEPARATOR ':' -#endif - -/* We maintain two prefix lists: one from COMPILER_PATH environment variable - and one from the PATH variable. */ - -static struct path_prefix cpath, path; - -#ifdef CROSS_COMPILE -/* This is the name of the target machine. We use it to form the name - of the files to execute. */ - -static char *target_machine = TARGET_MACHINE; -#endif - -/* Search for NAME using prefix list PPREFIX. We only look for executable - files. - - Return 0 if not found, otherwise return its name, allocated with malloc. */ - -static char * -find_a_file (pprefix, name) - struct path_prefix *pprefix; - char *name; -{ - char *temp; - struct prefix_list *pl; - int len = pprefix->max_len + strlen (name) + 1; - - if (debug) - fprintf (stderr, "Looking for '%s'\n", name); - -#ifdef EXECUTABLE_SUFFIX - len += strlen (EXECUTABLE_SUFFIX); -#endif - - temp = xmalloc (len); - - /* Determine the filename to execute (special case for absolute paths). */ - - if (*name == '/' -#ifdef DIR_SEPARATOR - || (DIR_SEPARATOR == '\\' && name[1] == ':' - && (name[2] == DIR_SEPARATOR || name[2] == '/')) -#endif - ) - { - if (access (name, X_OK) == 0) - { - strcpy (temp, name); - - if (debug) - fprintf (stderr, " - found: absolute path\n"); - - return temp; - } - - if (debug) - fprintf (stderr, " - failed to locate using absolute path\n"); - } - else - for (pl = pprefix->plist; pl; pl = pl->next) - { - strcpy (temp, pl->prefix); - strcat (temp, name); - - if (access (temp, X_OK) == 0) - return temp; - -#ifdef EXECUTABLE_SUFFIX - /* Some systems have a suffix for executable files. - So try appending that. */ - strcat (temp, EXECUTABLE_SUFFIX); - - if (access (temp, X_OK) == 0) - return temp; -#endif - } - - if (debug && pprefix->plist == NULL) - fprintf (stderr, " - failed: no entries in prefix list\n"); - - free (temp); - return 0; -} - -/* Add an entry for PREFIX to prefix list PPREFIX. */ - -static void -add_prefix (pprefix, prefix) - struct path_prefix *pprefix; - char *prefix; -{ - struct prefix_list *pl, **prev; - int len; - - if (pprefix->plist) - { - for (pl = pprefix->plist; pl->next; pl = pl->next) - ; - prev = &pl->next; - } - else - prev = &pprefix->plist; - - /* Keep track of the longest prefix */ - - len = strlen (prefix); - if (len > pprefix->max_len) - pprefix->max_len = len; - - pl = (struct prefix_list *) xmalloc (sizeof (struct prefix_list)); - pl->prefix = savestring (prefix, len); - - if (*prev) - pl->next = *prev; - else - pl->next = (struct prefix_list *) 0; - *prev = pl; -} - -/* Take the value of the environment variable ENV, break it into a path, and - add of the entries to PPREFIX. */ - -static void -prefix_from_env (env, pprefix) - char *env; - struct path_prefix *pprefix; -{ - char *p; - GET_ENV_PATH_LIST (p, env); - - if (p) - prefix_from_string (p, pprefix); -} - -static void -prefix_from_string (p, pprefix) - char *p; - struct path_prefix *pprefix; -{ - char *startp, *endp; - char *nstore = (char *) xmalloc (strlen (p) + 3); - - if (debug) - fprintf (stderr, "Convert string '%s' into prefixes, separator = '%c'\n", p, PATH_SEPARATOR); - - startp = endp = p; - while (1) - { - if (*endp == PATH_SEPARATOR || *endp == 0) - { - strncpy (nstore, startp, endp-startp); - if (endp == startp) - { - strcpy (nstore, "./"); - } - else if (endp[-1] != '/') - { - nstore[endp-startp] = '/'; - nstore[endp-startp+1] = 0; - } - else - nstore[endp-startp] = 0; - - if (debug) - fprintf (stderr, " - add prefix: %s\n", nstore); - - add_prefix (pprefix, nstore); - if (*endp == 0) - break; - endp = startp = endp + 1; - } - else - endp++; - } -} - -/* Main program. */ - -int -main (argc, argv) - int argc; - char *argv[]; -{ - char *ld_suffix = "ld"; - char *full_ld_suffix = ld_suffix; - char *real_ld_suffix = "real-ld"; - char *collect_ld_suffix = "collect-ld"; - char *nm_suffix = "nm"; - char *full_nm_suffix = nm_suffix; - char *gnm_suffix = "gnm"; - char *full_gnm_suffix = gnm_suffix; -#ifdef LDD_SUFFIX - char *ldd_suffix = LDD_SUFFIX; - char *full_ldd_suffix = ldd_suffix; -#endif - char *strip_suffix = "strip"; - char *full_strip_suffix = strip_suffix; - char *gstrip_suffix = "gstrip"; - char *full_gstrip_suffix = gstrip_suffix; - char *arg; - FILE *outf; -#ifdef COLLECT_EXPORT_LIST - FILE *exportf; - FILE *importf; -#endif - char *ld_file_name; - char *p; - char **c_argv; - char **c_ptr; - char **ld1_argv = (char **) xcalloc (sizeof (char *), argc+3); - char **ld1 = ld1_argv; - char **ld2_argv = (char **) xcalloc (sizeof (char *), argc+6); - char **ld2 = ld2_argv; - char **object_lst = (char **) xcalloc (sizeof (char *), argc); - char **object = object_lst; - int first_file; - int num_c_args = argc+9; - -#ifdef DEBUG - debug = 1; -#endif - - /* Parse command line early for instances of -debug. This allows - the debug flag to be set before functions like find_a_file() - are called. */ - { - int i; - - for (i = 1; argv[i] != NULL; i ++) - if (! strcmp (argv[i], "-debug")) - debug = 1; - vflag = debug; - } - -#ifndef DEFAULT_A_OUT_NAME - output_file = "a.out"; -#else - output_file = DEFAULT_A_OUT_NAME; -#endif - - obstack_begin (&temporary_obstack, 0); - obstack_begin (&permanent_obstack, 0); - temporary_firstobj = (char *) obstack_alloc (&temporary_obstack, 0); - - current_demangling_style = gnu_demangling; - p = getenv ("COLLECT_GCC_OPTIONS"); - while (p && *p) - { - char *q = extract_string (&p); - if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) - num_c_args++; - } - obstack_free (&temporary_obstack, temporary_firstobj); - ++num_c_args; - - c_ptr = c_argv = (char **) xcalloc (sizeof (char *), num_c_args); - - if (argc < 2) - fatal ("no arguments"); - -#ifdef SIGQUIT - if (signal (SIGQUIT, SIG_IGN) != SIG_IGN) - signal (SIGQUIT, handler); -#endif - if (signal (SIGINT, SIG_IGN) != SIG_IGN) - signal (SIGINT, handler); -#ifdef SIGALRM - if (signal (SIGALRM, SIG_IGN) != SIG_IGN) - signal (SIGALRM, handler); -#endif -#ifdef SIGHUP - if (signal (SIGHUP, SIG_IGN) != SIG_IGN) - signal (SIGHUP, handler); -#endif - if (signal (SIGSEGV, SIG_IGN) != SIG_IGN) - signal (SIGSEGV, handler); -#ifdef SIGBUS - if (signal (SIGBUS, SIG_IGN) != SIG_IGN) - signal (SIGBUS, handler); -#endif - - /* Extract COMPILER_PATH and PATH into our prefix list. */ - prefix_from_env ("COMPILER_PATH", &cpath); - prefix_from_env ("PATH", &path); - -#ifdef CROSS_COMPILE - /* If we look for a program in the compiler directories, we just use - the short name, since these directories are already system-specific. - But it we look for a program in the system directories, we need to - qualify the program name with the target machine. */ - - full_ld_suffix - = xcalloc (strlen (ld_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_ld_suffix, target_machine); - strcat (full_ld_suffix, "-"); - strcat (full_ld_suffix, ld_suffix); - -#if 0 - full_gld_suffix - = xcalloc (strlen (gld_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_gld_suffix, target_machine); - strcat (full_gld_suffix, "-"); - strcat (full_gld_suffix, gld_suffix); -#endif - - full_nm_suffix - = xcalloc (strlen (nm_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_nm_suffix, target_machine); - strcat (full_nm_suffix, "-"); - strcat (full_nm_suffix, nm_suffix); - - full_gnm_suffix - = xcalloc (strlen (gnm_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_gnm_suffix, target_machine); - strcat (full_gnm_suffix, "-"); - strcat (full_gnm_suffix, gnm_suffix); - -#ifdef LDD_SUFFIX - full_ldd_suffix - = xcalloc (strlen (ldd_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_ldd_suffix, target_machine); - strcat (full_ldd_suffix, "-"); - strcat (full_ldd_suffix, ldd_suffix); -#endif - - full_strip_suffix - = xcalloc (strlen (strip_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_strip_suffix, target_machine); - strcat (full_strip_suffix, "-"); - strcat (full_strip_suffix, strip_suffix); - - full_gstrip_suffix - = xcalloc (strlen (gstrip_suffix) + strlen (target_machine) + 2, 1); - strcpy (full_gstrip_suffix, target_machine); - strcat (full_gstrip_suffix, "-"); - strcat (full_gstrip_suffix, gstrip_suffix); -#endif /* CROSS_COMPILE */ - - /* Try to discover a valid linker/nm/strip to use. */ - - /* Maybe we know the right file to use (if not cross). */ - ld_file_name = 0; -#ifdef DEFAULT_LINKER - if (access (DEFAULT_LINKER, X_OK) == 0) - ld_file_name = DEFAULT_LINKER; - if (ld_file_name == 0) -#endif -#ifdef REAL_LD_FILE_NAME - ld_file_name = find_a_file (&path, REAL_LD_FILE_NAME); - if (ld_file_name == 0) -#endif - /* Search the (target-specific) compiler dirs for ld'. */ - ld_file_name = find_a_file (&cpath, real_ld_suffix); - /* Likewise for `collect-ld'. */ - if (ld_file_name == 0) - ld_file_name = find_a_file (&cpath, collect_ld_suffix); - /* Search the compiler directories for `ld'. We have protection against - recursive calls in find_a_file. */ - if (ld_file_name == 0) - ld_file_name = find_a_file (&cpath, ld_suffix); - /* Search the ordinary system bin directories - for `ld' (if native linking) or `TARGET-ld' (if cross). */ - if (ld_file_name == 0) - ld_file_name = find_a_file (&path, full_ld_suffix); - -#ifdef REAL_NM_FILE_NAME - nm_file_name = find_a_file (&path, REAL_NM_FILE_NAME); - if (nm_file_name == 0) -#endif - nm_file_name = find_a_file (&cpath, gnm_suffix); - if (nm_file_name == 0) - nm_file_name = find_a_file (&path, full_gnm_suffix); - if (nm_file_name == 0) - nm_file_name = find_a_file (&cpath, nm_suffix); - if (nm_file_name == 0) - nm_file_name = find_a_file (&path, full_nm_suffix); - -#ifdef LDD_SUFFIX - ldd_file_name = find_a_file (&cpath, ldd_suffix); - if (ldd_file_name == 0) - ldd_file_name = find_a_file (&path, full_ldd_suffix); -#endif - -#ifdef REAL_STRIP_FILE_NAME - strip_file_name = find_a_file (&path, REAL_STRIP_FILE_NAME); - if (strip_file_name == 0) -#endif - strip_file_name = find_a_file (&cpath, gstrip_suffix); - if (strip_file_name == 0) - strip_file_name = find_a_file (&path, full_gstrip_suffix); - if (strip_file_name == 0) - strip_file_name = find_a_file (&cpath, strip_suffix); - if (strip_file_name == 0) - strip_file_name = find_a_file (&path, full_strip_suffix); - - /* Determine the full path name of the C compiler to use. */ - c_file_name = getenv ("COLLECT_GCC"); - if (c_file_name == 0) - { -#ifdef CROSS_COMPILE - c_file_name = xcalloc (sizeof ("gcc-") + strlen (target_machine) + 1, 1); - strcpy (c_file_name, target_machine); - strcat (c_file_name, "-gcc"); -#else - c_file_name = "gcc"; -#endif - } - - p = find_a_file (&cpath, c_file_name); - - /* Here it should be safe to use the system search path since we should have - already qualified the name of the compiler when it is needed. */ - if (p == 0) - p = find_a_file (&path, c_file_name); - - if (p) - c_file_name = p; - - *ld1++ = *ld2++ = ld_file_name; - - /* Make temp file names. */ - c_file = make_temp_file (".c"); - o_file = make_temp_file (".o"); -#ifdef COLLECT_EXPORT_LIST - export_file = make_temp_file (".x"); - import_file = make_temp_file (".p"); -#endif - ldout = make_temp_file (".ld"); - *c_ptr++ = c_file_name; - *c_ptr++ = "-x"; - *c_ptr++ = "c"; - *c_ptr++ = "-c"; - *c_ptr++ = "-o"; - *c_ptr++ = o_file; - -#ifdef COLLECT_EXPORT_LIST - /* Generate a list of directories from LIBPATH. */ - prefix_from_env ("LIBPATH", &libpath_lib_dirs); - /* Add to this list also two standard directories where - AIX loader always searches for libraries. */ - add_prefix (&libpath_lib_dirs, "/lib"); - add_prefix (&libpath_lib_dirs, "/usr/lib"); -#endif - - /* Get any options that the upper GCC wants to pass to the sub-GCC. - - AIX support needs to know if -shared has been specified before - parsing commandline arguments. */ - - p = getenv ("COLLECT_GCC_OPTIONS"); - while (p && *p) - { - char *q = extract_string (&p); - if (*q == '-' && (q[1] == 'm' || q[1] == 'f')) - *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); - if (strcmp (q, "-EL") == 0 || strcmp (q, "-EB") == 0) - *c_ptr++ = obstack_copy0 (&permanent_obstack, q, strlen (q)); - if (strncmp (q, "-shared", sizeof ("-shared") - 1) == 0) - shared_obj = 1; - } - obstack_free (&temporary_obstack, temporary_firstobj); - *c_ptr++ = "-fno-exceptions"; - - /* !!! When GCC calls collect2, - it does not know whether it is calling collect2 or ld. - So collect2 cannot meaningfully understand any options - except those ld understands. - If you propose to make GCC pass some other option, - just imagine what will happen if ld is really ld!!! */ - - /* Parse arguments. Remember output file spec, pass the rest to ld. */ - /* After the first file, put in the c++ rt0. */ - - first_file = 1; - while ((arg = *++argv) != (char *) 0) - { - *ld1++ = *ld2++ = arg; - - if (arg[0] == '-') - { - switch (arg[1]) - { -#ifdef COLLECT_EXPORT_LIST - /* We want to disable automatic exports on AIX when user - explicitly puts an export list in command line */ - case 'b': - if (arg[2] == 'E' || strncmp (&arg[2], "export", 6) == 0) - export_flag = 1; - else if (arg[2] == '6' && arg[3] == '4') - aix64_flag = 1; - break; -#endif - - case 'd': - if (!strcmp (arg, "-debug")) - { - /* Already parsed. */ - ld1--; - ld2--; - } - break; - - case 'l': - if (first_file) - { - /* place o_file BEFORE this argument! */ - first_file = 0; - ld2--; - *ld2++ = o_file; - *ld2++ = arg; - } -#ifdef COLLECT_EXPORT_LIST - { - /* Resolving full library name. */ - char *s = resolve_lib_name (arg+2); - - /* If we will use an import list for this library, - we should exclude it from ld args. */ - if (use_import_list (s)) - { - ld1--; - ld2--; - } - - /* Saving a full library name. */ - add_to_list (&libs, s); - } -#endif - break; - -#ifdef COLLECT_EXPORT_LIST - /* Saving directories where to search for libraries. */ - case 'L': - add_prefix (&cmdline_lib_dirs, arg+2); - break; -#endif - - case 'o': - if (arg[2] == '\0') - output_file = *ld1++ = *ld2++ = *++argv; - else - output_file = &arg[2]; - break; - - case 'r': - if (arg[2] == '\0') - rflag = 1; - break; - - case 's': - if (arg[2] == '\0' && do_collecting) - { - /* We must strip after the nm run, otherwise C++ linking - will not work. Thus we strip in the second ld run, or - else with strip if there is no second ld run. */ - strip_flag = 1; - ld1--; - } - break; - - case 'v': - if (arg[2] == '\0') - vflag = 1; - break; - } - } - else if ((p = rindex (arg, '.')) != (char *) 0 - && (strcmp (p, ".o") == 0 || strcmp (p, ".a") == 0 - || strcmp (p, ".so") == 0)) - { - if (first_file) - { - first_file = 0; - if (p[1] == 'o') - *ld2++ = o_file; - else - { - /* place o_file BEFORE this argument! */ - ld2--; - *ld2++ = o_file; - *ld2++ = arg; - } - } - if (p[1] == 'o') - *object++ = arg; -#ifdef COLLECT_EXPORT_LIST - /* libraries can be specified directly, i.e. without -l flag. */ - else - { - /* If we will use an import list for this library, - we should exclude it from ld args. */ - if (use_import_list (arg)) - { - ld1--; - ld2--; - } - - /* Saving a full library name. */ - add_to_list (&libs, arg); - } -#endif - } - } - -#ifdef COLLECT_EXPORT_LIST - /* This is added only for debugging purposes. */ - if (debug) - { - fprintf (stderr, "List of libraries:\n"); - dump_list (stderr, "\t", libs.first); - } - - /* The AIX linker will discard static constructors in object files if - nothing else in the file is referenced, so look at them first. */ - { - char **export_object_lst = object_lst; - while (export_object_lst < object) - scan_prog_file (*export_object_lst++, PASS_OBJ); - } - { - struct id *list = libs.first; - for (; list; list = list->next) - scan_prog_file (list->name, PASS_FIRST); - } - { - char *buf1 = alloca (strlen (export_file) + 5); - char *buf2 = alloca (strlen (import_file) + 5); - sprintf (buf1, "-bE:%s", export_file); - sprintf (buf2, "-bI:%s", import_file); - *ld1++ = buf1; - *ld2++ = buf1; - *ld1++ = buf2; - *ld2++ = buf2; - exportf = fopen (export_file, "w"); - if (exportf == (FILE *) 0) - fatal_perror ("%s", export_file); - write_export_file (exportf); - if (fclose (exportf)) - fatal_perror ("closing %s", export_file); - importf = fopen (import_file, "w"); - if (importf == (FILE *) 0) - fatal_perror ("%s", import_file); - write_import_file (importf); - if (fclose (importf)) - fatal_perror ("closing %s", import_file); - } -#endif - - *c_ptr++ = c_file; - *object = *c_ptr = *ld1 = (char *) 0; - - if (vflag) - { - fprintf (stderr, "collect2 version %s", version_string); -#ifdef TARGET_VERSION - TARGET_VERSION; -#endif - fprintf (stderr, "\n"); - } - - if (debug) - { - char *ptr; - fprintf (stderr, "ld_file_name = %s\n", - (ld_file_name ? ld_file_name : "not found")); - fprintf (stderr, "c_file_name = %s\n", - (c_file_name ? c_file_name : "not found")); - fprintf (stderr, "nm_file_name = %s\n", - (nm_file_name ? nm_file_name : "not found")); -#ifdef LDD_SUFFIX - fprintf (stderr, "ldd_file_name = %s\n", - (ldd_file_name ? ldd_file_name : "not found")); -#endif - fprintf (stderr, "strip_file_name = %s\n", - (strip_file_name ? strip_file_name : "not found")); - fprintf (stderr, "c_file = %s\n", - (c_file ? c_file : "not found")); - fprintf (stderr, "o_file = %s\n", - (o_file ? o_file : "not found")); - - ptr = getenv ("COLLECT_GCC_OPTIONS"); - if (ptr) - fprintf (stderr, "COLLECT_GCC_OPTIONS = %s\n", ptr); - - ptr = getenv ("COLLECT_GCC"); - if (ptr) - fprintf (stderr, "COLLECT_GCC = %s\n", ptr); - - ptr = getenv ("COMPILER_PATH"); - if (ptr) - fprintf (stderr, "COMPILER_PATH = %s\n", ptr); - - ptr = getenv ("LIBRARY_PATH"); - if (ptr) - fprintf (stderr, "LIBRARY_PATH = %s\n", ptr); - - fprintf (stderr, "\n"); - } - - /* Load the program, searching all libraries and attempting to provide - undefined symbols from repository information. */ - - /* On AIX we do this later. */ -#ifndef COLLECT_EXPORT_LIST - do_tlink (ld1_argv, object_lst); -#endif - - /* If -r or they will be run via some other method, do not build the - constructor or destructor list, just return now. */ - if (rflag -#ifndef COLLECT_EXPORT_LIST - || ! do_collecting -#endif - ) - { -#ifdef COLLECT_EXPORT_LIST - /* But make sure we delete the export file we may have created. */ - if (export_file != 0 && export_file[0]) - maybe_unlink (export_file); - if (import_file != 0 && import_file[0]) - maybe_unlink (import_file); -#endif - maybe_unlink (c_file); - maybe_unlink (o_file); - return 0; - } - - /* Examine the namelist with nm and search it for static constructors - and destructors to call. - Write the constructor and destructor tables to a .s file and reload. */ - - /* On AIX we already done scanning for global constructors/destructors. */ -#ifndef COLLECT_EXPORT_LIST - scan_prog_file (output_file, PASS_FIRST); -#endif - -#ifdef SCAN_LIBRARIES - scan_libraries (output_file); -#endif - - if (debug) - { - fprintf (stderr, "%d constructor(s) found\n", constructors.number); - fprintf (stderr, "%d destructor(s) found\n", destructors.number); - } - - if (constructors.number == 0 && destructors.number == 0 - && frame_tables.number == 0 -#if defined (SCAN_LIBRARIES) || defined (COLLECT_EXPORT_LIST) - /* If we will be running these functions ourselves, we want to emit - stubs into the shared library so that we do not have to relink - dependent programs when we add static objects. */ - && ! shared_obj -#endif - ) - { -#ifdef COLLECT_EXPORT_LIST - /* Doing tlink without additional code generation */ - do_tlink (ld1_argv, object_lst); -#endif - /* Strip now if it was requested on the command line. */ - if (strip_flag) - { - char **strip_argv = (char **) xcalloc (sizeof (char *), 3); - strip_argv[0] = strip_file_name; - strip_argv[1] = output_file; - strip_argv[2] = (char *) 0; - fork_execute ("strip", strip_argv); - } - -#ifdef COLLECT_EXPORT_LIST - maybe_unlink (export_file); - maybe_unlink (import_file); -#endif - maybe_unlink (c_file); - maybe_unlink (o_file); - return 0; - } - - /* Sort ctor and dtor lists by priority. */ - sort_ids (&constructors); - sort_ids (&destructors); - - maybe_unlink(output_file); - outf = fopen (c_file, "w"); - if (outf == (FILE *) 0) - fatal_perror ("%s", c_file); - - write_c_file (outf, c_file); - - if (fclose (outf)) - fatal_perror ("closing %s", c_file); - - /* Tell the linker that we have initializer and finalizer functions. */ -#ifdef LD_INIT_SWITCH - *ld2++ = LD_INIT_SWITCH; - *ld2++ = initname; - *ld2++ = LD_FINI_SWITCH; - *ld2++ = fininame; -#endif - *ld2 = (char*) 0; - -#ifdef COLLECT_EXPORT_LIST - if (shared_obj) - { - add_to_list (&exports, initname); - add_to_list (&exports, fininame); - add_to_list (&exports, "_GLOBAL__DI"); - add_to_list (&exports, "_GLOBAL__DD"); - exportf = fopen (export_file, "w"); - if (exportf == (FILE *) 0) - fatal_perror ("%s", export_file); - write_export_file (exportf); - if (fclose (exportf)) - fatal_perror ("closing %s", export_file); - } -#endif - - if (debug) - { - fprintf (stderr, "\n========== output_file = %s, c_file = %s\n", - output_file, c_file); - write_c_file (stderr, "stderr"); - fprintf (stderr, "========== end of c_file\n\n"); -#ifdef COLLECT_EXPORT_LIST - fprintf (stderr, "\n========== export_file = %s\n", export_file); - write_export_file (stderr); - fprintf (stderr, "========== end of export_file\n\n"); -#endif - } - - /* Assemble the constructor and destructor tables. - Link the tables in with the rest of the program. */ - - fork_execute ("gcc", c_argv); -#ifdef COLLECT_EXPORT_LIST - /* On AIX we must call tlink because of possible templates resolution */ - do_tlink (ld2_argv, object_lst); -#else - /* Otherwise, simply call ld because tlink is already done */ - fork_execute ("ld", ld2_argv); - - /* Let scan_prog_file do any final mods (OSF/rose needs this for - constructors/destructors in shared libraries. */ - scan_prog_file (output_file, PASS_SECOND); -#endif - - maybe_unlink (c_file); - maybe_unlink (o_file); - -#ifdef COLLECT_EXPORT_LIST - maybe_unlink (export_file); - maybe_unlink (import_file); -#endif - - return 0; -} - - -/* Wait for a process to finish, and exit if a non-zero status is found. */ - -int -collect_wait (prog) - char *prog; -{ - int status; - - wait (&status); - if (status) - { - if (WIFSIGNALED (status)) - { - int sig = WTERMSIG (status); - error ("%s terminated with signal %d [%s]%s", - prog, - sig, - my_strsignal(sig), - (status & 0200) ? ", core dumped" : ""); - - collect_exit (FATAL_EXIT_CODE); - } - - if (WIFEXITED (status)) - return WEXITSTATUS (status); - } - return 0; -} - -static void -do_wait (prog) - char *prog; -{ - int ret = collect_wait (prog); - if (ret != 0) - { - error ("%s returned %d exit status", prog, ret); - collect_exit (ret); - } -} - - -/* Fork and execute a program, and wait for the reply. */ - -void -collect_execute (prog, argv, redir) - char *prog; - char **argv; - char *redir; -{ - int pid; - - if (vflag || debug) - { - char **p_argv; - char *str; - - if (argv[0]) - fprintf (stderr, "%s", argv[0]); - else - fprintf (stderr, "[cannot find %s]", prog); - - for (p_argv = &argv[1]; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - /* If we cannot find a program we need, complain error. Do this here - since we might not end up needing something that we could not find. */ - - if (argv[0] == 0) - fatal ("cannot find `%s'", prog); - -#ifndef __CYGWIN__ - pid = vfork (); - if (pid == -1) - fatal_perror (VFORK_STRING); - - if (pid == 0) /* child context */ - { - if (redir) - { - unlink (redir); - if (freopen (redir, "a", stdout) == NULL) - fatal_perror ("redirecting stdout: %s", redir); - if (freopen (redir, "a", stderr) == NULL) - fatal_perror ("redirecting stderr: %s", redir); - } - - execvp (argv[0], argv); - fatal_perror ("executing %s", prog); - } -#else - pid = _spawnvp (_P_NOWAIT, argv[0], argv); - if (pid == -1) - fatal ("spawnvp failed"); -#endif -} - -static void -fork_execute (prog, argv) - char *prog; - char **argv; -{ - collect_execute (prog, argv, NULL); - do_wait (prog); -} - -/* Unlink a file unless we are debugging. */ - -static void -maybe_unlink (file) - char *file; -{ - if (!debug) - unlink (file); - else - fprintf (stderr, "[Leaving %s]\n", file); -} - - -static long sequence_number = 0; - -/* Add a name to a linked list. */ - -static void -add_to_list (head_ptr, name) - struct head *head_ptr; - char *name; -{ - struct id *newid - = (struct id *) xcalloc (sizeof (struct id) + strlen (name), 1); - struct id *p; - strcpy (newid->name, name); - - if (head_ptr->first) - head_ptr->last->next = newid; - else - head_ptr->first = newid; - - /* Check for duplicate symbols. */ - for (p = head_ptr->first; - strcmp (name, p->name) != 0; - p = p->next) - ; - if (p != newid) - { - head_ptr->last->next = 0; - free (newid); - return; - } - - newid->sequence = ++sequence_number; - head_ptr->last = newid; - head_ptr->number++; -} - -/* Grab the init priority number from an init function name that - looks like "_GLOBAL_.I.12345.foo". */ - -static int -extract_init_priority (name) - char *name; -{ - int pos = 0, pri; - - while (name[pos] == '_') - ++pos; - pos += 10; /* strlen ("GLOBAL__X_") */ - - /* Extract init_p number from ctor/dtor name. */ - pri = atoi (name + pos); - return pri ? pri : DEFAULT_INIT_PRIORITY; -} - -/* Insertion sort the ids from ctor/dtor list HEAD_PTR in descending order. - ctors will be run from right to left, dtors from left to right. */ - -static void -sort_ids (head_ptr) - struct head *head_ptr; -{ - /* id holds the current element to insert. id_next holds the next - element to insert. id_ptr iterates through the already sorted elements - looking for the place to insert id. */ - struct id *id, *id_next, **id_ptr; - - id = head_ptr->first; - - /* We don't have any sorted elements yet. */ - head_ptr->first = NULL; - - for (; id; id = id_next) - { - id_next = id->next; - id->sequence = extract_init_priority (id->name); - - for (id_ptr = &(head_ptr->first); ; id_ptr = &((*id_ptr)->next)) - if (*id_ptr == NULL - /* If the sequence numbers are the same, we put the id from the - file later on the command line later in the list. */ - || id->sequence > (*id_ptr)->sequence - /* Hack: do lexical compare, too. - || (id->sequence == (*id_ptr)->sequence - && strcmp (id->name, (*id_ptr)->name) > 0) */ - ) - { - id->next = *id_ptr; - *id_ptr = id; - break; - } - } - - /* Now set the sequence numbers properly so write_c_file works. */ - for (id = head_ptr->first; id; id = id->next) - id->sequence = ++sequence_number; -} - -/* Write: `prefix', the names on list LIST, `suffix'. */ - -static void -write_list (stream, prefix, list) - FILE *stream; - char *prefix; - struct id *list; -{ - while (list) - { - fprintf (stream, "%sx%d,\n", prefix, list->sequence); - list = list->next; - } -} - -#ifdef COLLECT_EXPORT_LIST -/* This function is really used only on AIX, but may be useful. */ -static int -is_in_list (prefix, list) - char *prefix; - struct id *list; -{ - while (list) - { - if (!strcmp (prefix, list->name)) return 1; - list = list->next; - } - return 0; -} -#endif - -/* Added for debugging purpose. */ -#ifdef COLLECT_EXPORT_LIST -static void -dump_list (stream, prefix, list) - FILE *stream; - char *prefix; - struct id *list; -{ - while (list) - { - fprintf (stream, "%s%s,\n", prefix, list->name); - list = list->next; - } -} -#endif - -#if 0 -static void -dump_prefix_list (stream, prefix, list) - FILE *stream; - char *prefix; - struct prefix_list *list; -{ - while (list) - { - fprintf (stream, "%s%s,\n", prefix, list->prefix); - list = list->next; - } -} -#endif - -static void -write_list_with_asm (stream, prefix, list) - FILE *stream; - char *prefix; - struct id *list; -{ - while (list) - { - fprintf (stream, "%sx%d __asm__ (\"%s\");\n", - prefix, list->sequence, list->name); - list = list->next; - } -} - -/* Write out the constructor and destructor tables statically (for a shared - object), along with the functions to execute them. */ - -static void -write_c_file_stat (stream, name) - FILE *stream; - char *name; -{ - char *prefix, *p, *q; - int frames = (frame_tables.number > 0); - - /* Figure out name of output_file, stripping off .so version. */ - p = rindex (output_file, '/'); - if (p == 0) - p = (char *) output_file; - else - p++; - q = p; - while (q) - { - q = index (q,'.'); - if (q == 0) - { - q = p + strlen (p); - break; - } - else - { - if (strncmp (q, ".so", 3) == 0) - { - q += 3; - break; - } - else - q++; - } - } - /* q points to null at end of the string (or . of the .so version) */ - prefix = xmalloc (q - p + 1); - strncpy (prefix, p, q - p); - prefix[q - p] = 0; - for (q = prefix; *q; q++) - if (!ISALNUM ((unsigned char)*q)) - *q = '_'; - if (debug) - fprintf (stderr, "\nwrite_c_file - output name is %s, prefix is %s\n", - output_file, prefix); - -#define INIT_NAME_FORMAT "_GLOBAL__FI_%s" - initname = xmalloc (strlen (prefix) + sizeof (INIT_NAME_FORMAT) - 2); - sprintf (initname, INIT_NAME_FORMAT, prefix); - -#define FINI_NAME_FORMAT "_GLOBAL__FD_%s" - fininame = xmalloc (strlen (prefix) + sizeof (FINI_NAME_FORMAT) - 2); - sprintf (fininame, FINI_NAME_FORMAT, prefix); - - free (prefix); - - /* Write the tables as C code */ - - fprintf (stream, "static int count;\n"); - fprintf (stream, "typedef void entry_pt();\n"); - write_list_with_asm (stream, "extern entry_pt ", constructors.first); - - if (frames) - { - write_list_with_asm (stream, "extern void *", frame_tables.first); - - fprintf (stream, "\tstatic void *frame_table[] = {\n"); - write_list (stream, "\t\t&", frame_tables.first); - fprintf (stream, "\t0\n};\n"); - - /* This must match what's in frame.h. */ - fprintf (stream, "struct object {\n"); - fprintf (stream, " void *pc_begin;\n"); - fprintf (stream, " void *pc_end;\n"); - fprintf (stream, " void *fde_begin;\n"); - fprintf (stream, " void *fde_array;\n"); - fprintf (stream, " __SIZE_TYPE__ count;\n"); - fprintf (stream, " struct object *next;\n"); - fprintf (stream, "};\n"); - - fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); - fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); - - fprintf (stream, "static void reg_frame () {\n"); - fprintf (stream, "\tstatic struct object ob;\n"); - fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); - fprintf (stream, "\t}\n"); - - fprintf (stream, "static void dereg_frame () {\n"); - fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); - fprintf (stream, "\t}\n"); - } - - fprintf (stream, "void %s() {\n", initname); - if (constructors.number > 0 || frames) - { - fprintf (stream, "\tstatic entry_pt *ctors[] = {\n"); - write_list (stream, "\t\t", constructors.first); - if (frames) - fprintf (stream, "\treg_frame,\n"); - fprintf (stream, "\t};\n"); - fprintf (stream, "\tentry_pt **p;\n"); - fprintf (stream, "\tif (count++ != 0) return;\n"); - fprintf (stream, "\tp = ctors + %d;\n", constructors.number + frames); - fprintf (stream, "\twhile (p > ctors) (*--p)();\n"); - } - else - fprintf (stream, "\t++count;\n"); - fprintf (stream, "}\n"); - write_list_with_asm (stream, "extern entry_pt ", destructors.first); - fprintf (stream, "void %s() {\n", fininame); - if (destructors.number > 0 || frames) - { - fprintf (stream, "\tstatic entry_pt *dtors[] = {\n"); - write_list (stream, "\t\t", destructors.first); - if (frames) - fprintf (stream, "\tdereg_frame,\n"); - fprintf (stream, "\t};\n"); - fprintf (stream, "\tentry_pt **p;\n"); - fprintf (stream, "\tif (--count != 0) return;\n"); - fprintf (stream, "\tp = dtors;\n"); - fprintf (stream, "\twhile (p < dtors + %d) (*p++)();\n", - destructors.number + frames); - } - fprintf (stream, "}\n"); - - if (shared_obj) - { - fprintf (stream, "void _GLOBAL__DI() {\n\t%s();\n}\n", initname); - fprintf (stream, "void _GLOBAL__DD() {\n\t%s();\n}\n", fininame); - } -} - -/* Write the constructor/destructor tables. */ - -#ifndef LD_INIT_SWITCH -static void -write_c_file_glob (stream, name) - FILE *stream; - char *name; -{ - /* Write the tables as C code */ - - int frames = (frame_tables.number > 0); - - fprintf (stream, "typedef void entry_pt();\n\n"); - - write_list_with_asm (stream, "extern entry_pt ", constructors.first); - - if (frames) - { - write_list_with_asm (stream, "extern void *", frame_tables.first); - - fprintf (stream, "\tstatic void *frame_table[] = {\n"); - write_list (stream, "\t\t&", frame_tables.first); - fprintf (stream, "\t0\n};\n"); - - /* This must match what's in frame.h. */ - fprintf (stream, "struct object {\n"); - fprintf (stream, " void *pc_begin;\n"); - fprintf (stream, " void *pc_end;\n"); - fprintf (stream, " void *fde_begin;\n"); - fprintf (stream, " void *fde_array;\n"); - fprintf (stream, " __SIZE_TYPE__ count;\n"); - fprintf (stream, " struct object *next;\n"); - fprintf (stream, "};\n"); - - fprintf (stream, "extern void __register_frame_info_table (void *, struct object *);\n"); - fprintf (stream, "extern void *__deregister_frame_info (void *);\n"); - - fprintf (stream, "static void reg_frame () {\n"); - fprintf (stream, "\tstatic struct object ob;\n"); - fprintf (stream, "\t__register_frame_info_table (frame_table, &ob);\n"); - fprintf (stream, "\t}\n"); - - fprintf (stream, "static void dereg_frame () {\n"); - fprintf (stream, "\t__deregister_frame_info (frame_table);\n"); - fprintf (stream, "\t}\n"); - } - - fprintf (stream, "\nentry_pt * __CTOR_LIST__[] = {\n"); - fprintf (stream, "\t(entry_pt *) %d,\n", constructors.number + frames); - write_list (stream, "\t", constructors.first); - if (frames) - fprintf (stream, "\treg_frame,\n"); - fprintf (stream, "\t0\n};\n\n"); - - write_list_with_asm (stream, "extern entry_pt ", destructors.first); - - fprintf (stream, "\nentry_pt * __DTOR_LIST__[] = {\n"); - fprintf (stream, "\t(entry_pt *) %d,\n", destructors.number + frames); - write_list (stream, "\t", destructors.first); - if (frames) - fprintf (stream, "\tdereg_frame,\n"); - fprintf (stream, "\t0\n};\n\n"); - - fprintf (stream, "extern entry_pt %s;\n", NAME__MAIN); - fprintf (stream, "entry_pt *__main_reference = %s;\n\n", NAME__MAIN); -} -#endif /* ! LD_INIT_SWITCH */ - -static void -write_c_file (stream, name) - FILE *stream; - char *name; -{ - fprintf (stream, "#ifdef __cplusplus\nextern \"C\" {\n#endif\n"); -#ifndef LD_INIT_SWITCH - if (! shared_obj) - write_c_file_glob (stream, name); - else -#endif - write_c_file_stat (stream, name); - fprintf (stream, "#ifdef __cplusplus\n}\n#endif\n"); -} - -#ifdef COLLECT_EXPORT_LIST -static void -write_export_file (stream) - FILE *stream; -{ - struct id *list = exports.first; - for (; list; list = list->next) - fprintf (stream, "%s\n", list->name); -} - -static void -write_import_file (stream) - FILE *stream; -{ - struct id *list = imports.first; - fprintf (stream, "%s\n", "#! ."); - for (; list; list = list->next) - fprintf (stream, "%s\n", list->name); -} -#endif - -#ifdef OBJECT_FORMAT_NONE - -/* Generic version to scan the name list of the loaded program for - the symbols g++ uses for static constructors and destructors. - - The constructor table begins at __CTOR_LIST__ and contains a count - of the number of pointers (or -1 if the constructors are built in a - separate section by the linker), followed by the pointers to the - constructor functions, terminated with a null pointer. The - destructor table has the same format, and begins at __DTOR_LIST__. */ - -static void -scan_prog_file (prog_name, which_pass) - char *prog_name; - enum pass which_pass; -{ - void (*int_handler) (); - void (*quit_handler) (); - char *nm_argv[4]; - int pid; - int argc = 0; - int pipe_fd[2]; - char *p, buf[1024]; - FILE *inf; - - if (which_pass == PASS_SECOND) - return; - - /* If we do not have an `nm', complain. */ - if (nm_file_name == 0) - fatal ("cannot find `nm'"); - - nm_argv[argc++] = nm_file_name; - if (NM_FLAGS[0] != '\0') - nm_argv[argc++] = NM_FLAGS; - - nm_argv[argc++] = prog_name; - nm_argv[argc++] = (char *) 0; - - if (pipe (pipe_fd) < 0) - fatal_perror ("pipe"); - - inf = fdopen (pipe_fd[0], "r"); - if (inf == (FILE *) 0) - fatal_perror ("fdopen"); - - /* Trace if needed. */ - if (vflag) - { - char **p_argv; - char *str; - - for (p_argv = &nm_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - /* Spawn child nm on pipe */ - pid = vfork (); - if (pid == -1) - fatal_perror (VFORK_STRING); - - if (pid == 0) /* child context */ - { - /* setup stdout */ - if (dup2 (pipe_fd[1], 1) < 0) - fatal_perror ("dup2 (%d, 1)", pipe_fd[1]); - - if (close (pipe_fd[0]) < 0) - fatal_perror ("close (%d)", pipe_fd[0]); - - if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); - - execv (nm_file_name, nm_argv); - fatal_perror ("executing %s", nm_file_name); - } - - /* Parent context from here on. */ - int_handler = (void (*) ())signal (SIGINT, SIG_IGN); -#ifdef SIGQUIT - quit_handler = (void (*) ())signal (SIGQUIT, SIG_IGN); -#endif - - if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); - - if (debug) - fprintf (stderr, "\nnm output with constructors/destructors.\n"); - - /* Read each line of nm output. */ - while (fgets (buf, sizeof buf, inf) != (char *) 0) - { - int ch, ch2; - char *name, *end; - - /* If it contains a constructor or destructor name, add the name - to the appropriate list. */ - - for (p = buf; (ch = *p) != '\0' && ch != '\n' && ch != '_'; p++) - if (ch == ' ' && p[1] == 'U' && p[2] == ' ') - break; - - if (ch != '_') - continue; - - name = p; - /* Find the end of the symbol name. - Do not include `|', because Encore nm can tack that on the end. */ - for (end = p; (ch2 = *end) != '\0' && !ISSPACE (ch2) && ch2 != '|'; - end++) - continue; - - - *end = '\0'; - switch (is_ctor_dtor (name)) - { - case 1: - if (which_pass != PASS_LIB) - add_to_list (&constructors, name); - break; - - case 2: - if (which_pass != PASS_LIB) - add_to_list (&destructors, name); - break; - - case 3: - if (which_pass != PASS_LIB) - fatal ("init function found in object %s", prog_name); -#ifndef LD_INIT_SWITCH - add_to_list (&constructors, name); -#endif - break; - - case 4: - if (which_pass != PASS_LIB) - fatal ("fini function found in object %s", prog_name); -#ifndef LD_FINI_SWITCH - add_to_list (&destructors, name); -#endif - break; - - case 5: - if (which_pass != PASS_LIB) - add_to_list (&frame_tables, name); - - default: /* not a constructor or destructor */ - continue; - } - - if (debug) - fprintf (stderr, "\t%s\n", buf); - } - - if (debug) - fprintf (stderr, "\n"); - - if (fclose (inf) != 0) - fatal_perror ("fclose of pipe"); - - do_wait (nm_file_name); - - signal (SIGINT, int_handler); -#ifdef SIGQUIT - signal (SIGQUIT, quit_handler); -#endif -} - -#if SUNOS4_SHARED_LIBRARIES - -/* Routines to scan the SunOS 4 _DYNAMIC structure to find shared libraries - that the output file depends upon and their initialization/finalization - routines, if any. */ - -#include <a.out.h> -#include <fcntl.h> -#include <link.h> -#include <sys/mman.h> -#include <sys/param.h> -#include <unistd.h> -#include <sys/dir.h> - -/* pointers to the object file */ -unsigned object; /* address of memory mapped file */ -unsigned objsize; /* size of memory mapped to file */ -char * code; /* pointer to code segment */ -char * data; /* pointer to data segment */ -struct nlist *symtab; /* pointer to symbol table */ -struct link_dynamic *ld; -struct link_dynamic_2 *ld_2; -struct head libraries; - -/* Map the file indicated by NAME into memory and store its address. */ - -static void -mapfile (name) - char *name; -{ - int fp; - struct stat s; - if ((fp = open (name, O_RDONLY)) == -1) - fatal ("unable to open file '%s'", name); - if (fstat (fp, &s) == -1) - fatal ("unable to stat file '%s'", name); - - objsize = s.st_size; - object = (unsigned) mmap (0, objsize, PROT_READ|PROT_WRITE, MAP_PRIVATE, - fp, 0); - if (object == -1) - fatal ("unable to mmap file '%s'", name); - - close (fp); -} - -/* Helpers for locatelib. */ - -static char *libname; - -static int -libselect (d) - struct direct *d; -{ - return (strncmp (libname, d->d_name, strlen (libname)) == 0); -} - -/* If one file has an additional numeric extension past LIBNAME, then put - that one first in the sort. If both files have additional numeric - extensions, then put the one with the higher number first in the sort. - - We must verify that the extension is numeric, because Sun saves the - original versions of patched libraries with a .FCS extension. Files with - invalid extensions must go last in the sort, so that they will not be used. */ - -static int -libcompare (d1, d2) - struct direct **d1, **d2; -{ - int i1, i2 = strlen (libname); - char *e1 = (*d1)->d_name + i2; - char *e2 = (*d2)->d_name + i2; - - while (*e1 && *e2 && *e1 == '.' && *e2 == '.' - && e1[1] && ISDIGIT (e1[1]) && e2[1] && ISDIGIT (e2[1])) - { - ++e1; - ++e2; - i1 = strtol (e1, &e1, 10); - i2 = strtol (e2, &e2, 10); - if (i1 != i2) - return i1 - i2; - } - - if (*e1) - { - /* It has a valid numeric extension, prefer this one. */ - if (*e1 == '.' && e1[1] && ISDIGIT (e1[1])) - return 1; - /* It has a invalid numeric extension, must prefer the other one. */ - else - return -1; - } - else if (*e2) - { - /* It has a valid numeric extension, prefer this one. */ - if (*e2 == '.' && e2[1] && ISDIGIT (e2[1])) - return -1; - /* It has a invalid numeric extension, must prefer the other one. */ - else - return 1; - } - else - return 0; -} - -/* Given the name NAME of a dynamic dependency, find its pathname and add - it to the list of libraries. */ - -static void -locatelib (name) - char *name; -{ - static char **l; - static int cnt; - char buf[MAXPATHLEN]; - char *p, *q; - char **pp; - - if (l == 0) - { - char *ld_rules; - char *ldr = 0; - /* counting elements in array, need 1 extra for null */ - cnt = 1; - ld_rules = (char *) (ld_2->ld_rules + code); - if (ld_rules) - { - cnt++; - for (; *ld_rules != 0; ld_rules++) - if (*ld_rules == ':') - cnt++; - ld_rules = (char *) (ld_2->ld_rules + code); - ldr = (char *) malloc (strlen (ld_rules) + 1); - strcpy (ldr, ld_rules); - } - p = getenv ("LD_LIBRARY_PATH"); - q = 0; - if (p) - { - cnt++; - for (q = p ; *q != 0; q++) - if (*q == ':') - cnt++; - q = (char *) malloc (strlen (p) + 1); - strcpy (q, p); - } - l = (char **) malloc ((cnt + 3) * sizeof (char *)); - pp = l; - if (ldr) - { - *pp++ = ldr; - for (; *ldr != 0; ldr++) - if (*ldr == ':') - { - *ldr++ = 0; - *pp++ = ldr; - } - } - if (q) - { - *pp++ = q; - for (; *q != 0; q++) - if (*q == ':') - { - *q++ = 0; - *pp++ = q; - } - } - /* built in directories are /lib, /usr/lib, and /usr/local/lib */ - *pp++ = "/lib"; - *pp++ = "/usr/lib"; - *pp++ = "/usr/local/lib"; - *pp = 0; - } - libname = name; - for (pp = l; *pp != 0 ; pp++) - { - struct direct **namelist; - int entries; - if ((entries = scandir (*pp, &namelist, libselect, libcompare)) > 0) - { - sprintf (buf, "%s/%s", *pp, namelist[entries - 1]->d_name); - add_to_list (&libraries, buf); - if (debug) - fprintf (stderr, "%s\n", buf); - break; - } - } - if (*pp == 0) - { - if (debug) - fprintf (stderr, "not found\n"); - else - fatal ("dynamic dependency %s not found", name); - } -} - -/* Scan the _DYNAMIC structure of the output file to find shared libraries - that it depends upon and any constructors or destructors they contain. */ - -static void -scan_libraries (prog_name) - char *prog_name; -{ - struct exec *header; - char *base; - struct link_object *lo; - char buff[MAXPATHLEN]; - struct id *list; - - mapfile (prog_name); - header = (struct exec *)object; - if (N_BADMAG (*header)) - fatal ("bad magic number in file '%s'", prog_name); - if (header->a_dynamic == 0) - return; - - code = (char *) (N_TXTOFF (*header) + (long) header); - data = (char *) (N_DATOFF (*header) + (long) header); - symtab = (struct nlist *) (N_SYMOFF (*header) + (long) header); - - if (header->a_magic == ZMAGIC && header->a_entry == 0x20) - { - /* shared object */ - ld = (struct link_dynamic *) (symtab->n_value + code); - base = code; - } - else - { - /* executable */ - ld = (struct link_dynamic *) data; - base = code-PAGSIZ; - } - - if (debug) - fprintf (stderr, "dynamic dependencies.\n"); - - ld_2 = (struct link_dynamic_2 *) ((long) ld->ld_un.ld_2 + (long)base); - for (lo = (struct link_object *) ld_2->ld_need; lo; - lo = (struct link_object *) lo->lo_next) - { - char *name; - lo = (struct link_object *) ((long) lo + code); - name = (char *) (code + lo->lo_name); - if (lo->lo_library) - { - if (debug) - fprintf (stderr, "\t-l%s.%d => ", name, lo->lo_major); - sprintf (buff, "lib%s.so.%d.%d", name, lo->lo_major, lo->lo_minor); - locatelib (buff); - } - else - { - if (debug) - fprintf (stderr, "\t%s\n", name); - add_to_list (&libraries, name); - } - } - - if (debug) - fprintf (stderr, "\n"); - - /* now iterate through the library list adding their symbols to - the list. */ - for (list = libraries.first; list; list = list->next) - scan_prog_file (list->name, PASS_LIB); -} - -#else /* SUNOS4_SHARED_LIBRARIES */ -#ifdef LDD_SUFFIX - -/* Use the List Dynamic Dependencies program to find shared libraries that - the output file depends upon and their initialization/finalization - routines, if any. */ - -static void -scan_libraries (prog_name) - char *prog_name; -{ - static struct head libraries; /* list of shared libraries found */ - struct id *list; - void (*int_handler) (); - void (*quit_handler) (); - char *ldd_argv[4]; - int pid; - int argc = 0; - int pipe_fd[2]; - char buf[1024]; - FILE *inf; - - /* If we do not have an `ldd', complain. */ - if (ldd_file_name == 0) - { - error ("cannot find `ldd'"); - return; - } - - ldd_argv[argc++] = ldd_file_name; - ldd_argv[argc++] = prog_name; - ldd_argv[argc++] = (char *) 0; - - if (pipe (pipe_fd) < 0) - fatal_perror ("pipe"); - - inf = fdopen (pipe_fd[0], "r"); - if (inf == (FILE *) 0) - fatal_perror ("fdopen"); - - /* Trace if needed. */ - if (vflag) - { - char **p_argv; - char *str; - - for (p_argv = &ldd_argv[0]; (str = *p_argv) != (char *) 0; p_argv++) - fprintf (stderr, " %s", str); - - fprintf (stderr, "\n"); - } - - fflush (stdout); - fflush (stderr); - - /* Spawn child ldd on pipe */ - pid = vfork (); - if (pid == -1) - fatal_perror (VFORK_STRING); - - if (pid == 0) /* child context */ - { - /* setup stdout */ - if (dup2 (pipe_fd[1], 1) < 0) - fatal_perror ("dup2 (%d, 1)", pipe_fd[1]); - - if (close (pipe_fd[0]) < 0) - fatal_perror ("close (%d)", pipe_fd[0]); - - if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); - - execv (ldd_file_name, ldd_argv); - fatal_perror ("executing %s", ldd_file_name); - } - - /* Parent context from here on. */ - int_handler = (void (*) ()) signal (SIGINT, SIG_IGN); -#ifdef SIGQUIT - quit_handler = (void (*) ()) signal (SIGQUIT, SIG_IGN); -#endif - - if (close (pipe_fd[1]) < 0) - fatal_perror ("close (%d)", pipe_fd[1]); - - if (debug) - fprintf (stderr, "\nldd output with constructors/destructors.\n"); - - /* Read each line of ldd output. */ - while (fgets (buf, sizeof buf, inf) != (char *) 0) - { - int ch, ch2; - char *name, *end, *p = buf; - - /* Extract names of libraries and add to list. */ - PARSE_LDD_OUTPUT (p); - if (p == 0) - continue; - - name = p; - if (strncmp (name, "not found", sizeof ("not found") - 1) == 0) - fatal ("dynamic dependency %s not found", buf); - - /* Find the end of the symbol name. */ - for (end = p; - (ch2 = *end) != '\0' && ch2 != '\n' && !ISSPACE (ch2) && ch2 != '|'; - end++) - continue; - *end = '\0'; - - if (access (name, R_OK) == 0) - add_to_list (&libraries, name); - else - fatal ("unable to open dynamic dependency '%s'", buf); - - if (debug) - fprintf (stderr, "\t%s\n", buf); - } - if (debug) - fprintf (stderr, "\n"); - - if (fclose (inf) != 0) - fatal_perror ("fclose of pipe"); - - do_wait (ldd_file_name); - - signal (SIGINT, int_handler); -#ifdef SIGQUIT - signal (SIGQUIT, quit_handler); -#endif - - /* now iterate through the library list adding their symbols to - the list. */ - for (list = libraries.first; list; list = list->next) - scan_prog_file (list->name, PASS_LIB); -} - -#endif /* LDD_SUFFIX */ -#endif /* SUNOS4_SHARED_LIBRARIES */ - -#endif /* OBJECT_FORMAT_NONE */ - - -/* - * COFF specific stuff. - */ - -#ifdef OBJECT_FORMAT_COFF - -#if defined(EXTENDED_COFF) -# define GCC_SYMBOLS(X) (SYMHEADER(X).isymMax + SYMHEADER(X).iextMax) -# define GCC_SYMENT SYMR -# define GCC_OK_SYMBOL(X) ((X).st == stProc && (X).sc == scText) -# define GCC_SYMINC(X) (1) -# define GCC_SYMZERO(X) (SYMHEADER(X).isymMax) -# define GCC_CHECK_HDR(X) (PSYMTAB(X) != 0) -#else -# define GCC_SYMBOLS(X) (HEADER(ldptr).f_nsyms) -# define GCC_SYMENT SYMENT -# define GCC_OK_SYMBOL(X) \ - (((X).n_sclass == C_EXT) && \ - ((X).n_scnum > N_UNDEF) && \ - (((X).n_type & N_TMASK) == (DT_NON << N_BTSHFT) || \ - ((X).n_type & N_TMASK) == (DT_FCN << N_BTSHFT))) -# define GCC_UNDEF_SYMBOL(X) \ - (((X).n_sclass == C_EXT) && ((X).n_scnum == N_UNDEF)) -# define GCC_SYMINC(X) ((X).n_numaux+1) -# define GCC_SYMZERO(X) 0 -# define GCC_CHECK_HDR(X) \ - ((HEADER (X).f_magic == U802TOCMAGIC && ! aix64_flag) \ - || (HEADER (X).f_magic == 0757 && aix64_flag)) -#endif - -extern char *ldgetname (); - -/* COFF version to scan the name list of the loaded program for - the symbols g++ uses for static constructors and destructors. - - The constructor table begins at __CTOR_LIST__ and contains a count - of the number of pointers (or -1 if the constructors are built in a - separate section by the linker), followed by the pointers to the - constructor functions, terminated with a null pointer. The - destructor table has the same format, and begins at __DTOR_LIST__. */ - -static void -scan_prog_file (prog_name, which_pass) - char *prog_name; - enum pass which_pass; -{ - LDFILE *ldptr = NULL; - int sym_index, sym_count; - int is_shared = 0; -#ifdef COLLECT_EXPORT_LIST - /* Should we generate an import list for given prog_name? */ - int import_flag = (which_pass == PASS_OBJ ? 0 : use_import_list (prog_name)); -#endif - - if (which_pass != PASS_FIRST && which_pass != PASS_OBJ) - return; - -#ifdef COLLECT_EXPORT_LIST - /* We do not need scanning for some standard C libraries. */ - if (which_pass == PASS_FIRST && ignore_library (prog_name)) - return; - - /* On AIX we have a loop, because there is not much difference - between an object and an archive. This trick allows us to - eliminate scan_libraries() function. */ - do - { -#endif - if ((ldptr = ldopen (prog_name, ldptr)) != NULL) - { - if (! MY_ISCOFF (HEADER (ldptr).f_magic)) - fatal ("%s: not a COFF file", prog_name); - - if (GCC_CHECK_HDR (ldptr)) - { - sym_count = GCC_SYMBOLS (ldptr); - sym_index = GCC_SYMZERO (ldptr); - -#ifdef COLLECT_EXPORT_LIST - /* Is current archive member a shared object? */ - is_shared = HEADER (ldptr).f_flags & F_SHROBJ; -#endif - - while (sym_index < sym_count) - { - GCC_SYMENT symbol; - - if (ldtbread (ldptr, sym_index, &symbol) <= 0) - break; - sym_index += GCC_SYMINC (symbol); - - if (GCC_OK_SYMBOL (symbol)) - { - char *name; - - if ((name = ldgetname (ldptr, &symbol)) == NULL) - continue; /* should never happen */ - -#ifdef XCOFF_DEBUGGING_INFO - /* All AIX function names have a duplicate entry - beginning with a dot. */ - if (*name == '.') - ++name; -#endif - - switch (is_ctor_dtor (name)) - { - case 1: - if (! is_shared) add_to_list (&constructors, name); -#ifdef COLLECT_EXPORT_LIST - if (which_pass == PASS_OBJ) - add_to_list (&exports, name); - /* If this symbol was undefined and we are building - an import list, we should add a symbol to this - list. */ - else - if (import_flag - && is_in_list (name, undefined.first)) - add_to_list (&imports, name); -#endif - break; - - case 2: - if (! is_shared) add_to_list (&destructors, name); -#ifdef COLLECT_EXPORT_LIST - if (which_pass == PASS_OBJ) - add_to_list (&exports, name); - /* If this symbol was undefined and we are building - an import list, we should add a symbol to this - list. */ - else - if (import_flag - && is_in_list (name, undefined.first)) - add_to_list (&imports, name); -#endif - break; - -#ifdef COLLECT_EXPORT_LIST - case 3: - if (is_shared) - add_to_list (&constructors, name); - break; - - case 4: - if (is_shared) - add_to_list (&destructors, name); - break; -#endif - - default: /* not a constructor or destructor */ -#ifdef COLLECT_EXPORT_LIST - /* If we are building a shared object on AIX we need - to explicitly export all global symbols or add - them to import list. */ - if (shared_obj) - { - if (which_pass == PASS_OBJ && (! export_flag)) - add_to_list (&exports, name); - else if (! is_shared && which_pass == PASS_FIRST - && import_flag - && is_in_list(name, undefined.first)) - add_to_list (&imports, name); - } -#endif - continue; - } - -#if !defined(EXTENDED_COFF) - if (debug) - fprintf (stderr, "\tsec=%d class=%d type=%s%o %s\n", - symbol.n_scnum, symbol.n_sclass, - (symbol.n_type ? "0" : ""), symbol.n_type, - name); -#else - if (debug) - fprintf (stderr, - "\tiss = %5d, value = %5ld, index = %5d, name = %s\n", - symbol.iss, (long) symbol.value, symbol.index, name); -#endif - } -#ifdef COLLECT_EXPORT_LIST - /* If we are building a shared object we should collect - information about undefined symbols for later - import list generation. */ - else if (shared_obj && GCC_UNDEF_SYMBOL (symbol)) - { - char *name; - - if ((name = ldgetname (ldptr, &symbol)) == NULL) - continue; /* should never happen */ - - /* All AIX function names have a duplicate entry - beginning with a dot. */ - if (*name == '.') - ++name; - add_to_list (&undefined, name); - } -#endif - } - } -#ifdef COLLECT_EXPORT_LIST - else - { - /* If archive contains both 32-bit and 64-bit objects, - we want to skip objects in other mode so mismatch normal. */ - if (debug) - fprintf (stderr, "%s : magic=%o aix64=%d mismatch\n", - prog_name, HEADER (ldptr).f_magic, aix64_flag); - } -#endif - } - else - { - fatal ("%s: cannot open as COFF file", prog_name); - } -#ifdef COLLECT_EXPORT_LIST - /* On AIX loop continues while there are more members in archive. */ - } - while (ldclose (ldptr) == FAILURE); -#else - /* Otherwise we simply close ldptr. */ - (void) ldclose(ldptr); -#endif -} - - -#ifdef COLLECT_EXPORT_LIST - -/* This new function is used to decide whether we should - generate import list for an object or to use it directly. */ -static int -use_import_list (prog_name) - char *prog_name; -{ - char *p; - - /* If we do not build a shared object then import list should not be used. */ - if (! shared_obj) return 0; - - /* Currently we check only for libgcc, but this can be changed in future. */ - p = strstr (prog_name, "libgcc.a"); - if (p != 0 && (strlen (p) == sizeof ("libgcc.a") - 1)) - return 1; - return 0; -} - -/* Given a library name without "lib" prefix, this function - returns a full library name including a path. */ -static char * -resolve_lib_name (name) - char *name; -{ - char *lib_buf; - int i, j, l = 0; - - for (i = 0; libpaths[i]; i++) - if (libpaths[i]->max_len > l) - l = libpaths[i]->max_len; - - lib_buf = xmalloc (l + strlen(name) + 10); - - for (i = 0; libpaths[i]; i++) - { - struct prefix_list *list = libpaths[i]->plist; - for (; list; list = list->next) - { - for (j = 0; libexts[j]; j++) - { - /* The following lines are needed because path_prefix list - may contain directories both with trailing '/' and - without it. */ - char *p = ""; - if (list->prefix[strlen(list->prefix)-1] != '/') - p = "/"; - sprintf (lib_buf, "%s%slib%s.%s", - list->prefix, p, name, libexts[j]); -if (debug) fprintf (stderr, "searching for: %s\n", lib_buf); - if (file_exists (lib_buf)) - { -if (debug) fprintf (stderr, "found: %s\n", lib_buf); - return (lib_buf); - } - } - } - } - if (debug) - fprintf (stderr, "not found\n"); - else - fatal ("Library lib%s not found", name); - return (NULL); -} - -/* Array of standard AIX libraries which should not - be scanned for ctors/dtors. */ -static char* aix_std_libs[] = { - "/unix", - "/lib/libc.a", - "/lib/libc_r.a", - "/usr/lib/libc.a", - "/usr/lib/libc_r.a", - "/usr/lib/threads/libc.a", - "/usr/ccs/lib/libc.a", - "/usr/ccs/lib/libc_r.a", - NULL -}; - -/* This function checks the filename and returns 1 - if this name matches the location of a standard AIX library. */ -static int -ignore_library (name) - char *name; -{ - char **p = &aix_std_libs[0]; - while (*p++ != NULL) - if (! strcmp (name, *p)) return 1; - return 0; -} - -#endif - -#endif /* OBJECT_FORMAT_COFF */ - - -/* - * OSF/rose specific stuff. - */ - -#ifdef OBJECT_FORMAT_ROSE - -/* Union of the various load commands */ - -typedef union load_union -{ - ldc_header_t hdr; /* common header */ - load_cmd_map_command_t map; /* map indexing other load cmds */ - interpreter_command_t iprtr; /* interpreter pathname */ - strings_command_t str; /* load commands strings section */ - region_command_t region; /* region load command */ - reloc_command_t reloc; /* relocation section */ - package_command_t pkg; /* package load command */ - symbols_command_t sym; /* symbol sections */ - entry_command_t ent; /* program start section */ - gen_info_command_t info; /* object information */ - func_table_command_t func; /* function constructors/destructors */ -} load_union_t; - -/* Structure to point to load command and data section in memory. */ - -typedef struct load_all -{ - load_union_t *load; /* load command */ - char *section; /* pointer to section */ -} load_all_t; - -/* Structure to contain information about a file mapped into memory. */ - -struct file_info -{ - char *start; /* start of map */ - char *name; /* filename */ - long size; /* size of the file */ - long rounded_size; /* size rounded to page boundary */ - int fd; /* file descriptor */ - int rw; /* != 0 if opened read/write */ - int use_mmap; /* != 0 if mmap'ed */ -}; - -extern int decode_mach_o_hdr (); -extern int encode_mach_o_hdr (); - -static void add_func_table PROTO((mo_header_t *, load_all_t *, - symbol_info_t *, int)); -static void print_header PROTO((mo_header_t *)); -static void print_load_command PROTO((load_union_t *, size_t, int)); -static void bad_header PROTO((int)); -static struct file_info *read_file PROTO((char *, int, int)); -static void end_file PROTO((struct file_info *)); - -/* OSF/rose specific version to scan the name list of the loaded - program for the symbols g++ uses for static constructors and - destructors. - - The constructor table begins at __CTOR_LIST__ and contains a count - of the number of pointers (or -1 if the constructors are built in a - separate section by the linker), followed by the pointers to the - constructor functions, terminated with a null pointer. The - destructor table has the same format, and begins at __DTOR_LIST__. */ - -static void -scan_prog_file (prog_name, which_pass) - char *prog_name; - enum pass which_pass; -{ - char *obj; - mo_header_t hdr; - load_all_t *load_array; - load_all_t *load_end; - load_all_t *load_cmd; - int symbol_load_cmds; - off_t offset; - int i; - int num_syms; - int status; - char *str_sect; - struct file_info *obj_file; - int prog_fd; - mo_lcid_t cmd_strings = -1; - symbol_info_t *main_sym = 0; - int rw = (which_pass != PASS_FIRST); - - prog_fd = open (prog_name, (rw) ? O_RDWR : O_RDONLY); - if (prog_fd < 0) - fatal_perror ("cannot read %s", prog_name); - - obj_file = read_file (prog_name, prog_fd, rw); - obj = obj_file->start; - - status = decode_mach_o_hdr (obj, MO_SIZEOF_RAW_HDR, MOH_HEADER_VERSION, &hdr); - if (status != MO_HDR_CONV_SUCCESS) - bad_header (status); - - - /* Do some basic sanity checks. Note we explicitly use the big endian magic number, - since the hardware will automatically swap bytes for us on loading little endian - integers. */ - -#ifndef CROSS_COMPILE - if (hdr.moh_magic != MOH_MAGIC_MSB - || hdr.moh_header_version != MOH_HEADER_VERSION - || hdr.moh_byte_order != OUR_BYTE_ORDER - || hdr.moh_data_rep_id != OUR_DATA_REP_ID - || hdr.moh_cpu_type != OUR_CPU_TYPE - || hdr.moh_cpu_subtype != OUR_CPU_SUBTYPE - || hdr.moh_vendor_type != OUR_VENDOR_TYPE) - { - fatal ("incompatibilities between object file & expected values"); - } -#endif - - if (debug) - print_header (&hdr); - - offset = hdr.moh_first_cmd_off; - load_end = load_array - = (load_all_t *) xcalloc (sizeof (load_all_t), hdr.moh_n_load_cmds + 2); - - /* Build array of load commands, calculating the offsets */ - for (i = 0; i < hdr.moh_n_load_cmds; i++) - { - load_union_t *load_hdr; /* load command header */ - - load_cmd = load_end++; - load_hdr = (load_union_t *) (obj + offset); - - /* If modifying the program file, copy the header. */ - if (rw) - { - load_union_t *ptr = (load_union_t *) xmalloc (load_hdr->hdr.ldci_cmd_size); - bcopy ((char *)load_hdr, (char *)ptr, load_hdr->hdr.ldci_cmd_size); - load_hdr = ptr; - - /* null out old command map, because we will rewrite at the end. */ - if (ptr->hdr.ldci_cmd_type == LDC_CMD_MAP) - { - cmd_strings = ptr->map.lcm_ld_cmd_strings; - ptr->hdr.ldci_cmd_type = LDC_UNDEFINED; - } - } - - load_cmd->load = load_hdr; - if (load_hdr->hdr.ldci_section_off > 0) - load_cmd->section = obj + load_hdr->hdr.ldci_section_off; - - if (debug) - print_load_command (load_hdr, offset, i); - - offset += load_hdr->hdr.ldci_cmd_size; - } - - /* If the last command is the load command map and is not undefined, - decrement the count of load commands. */ - if (rw && load_end[-1].load->hdr.ldci_cmd_type == LDC_UNDEFINED) - { - load_end--; - hdr.moh_n_load_cmds--; - } - - /* Go through and process each symbol table section. */ - symbol_load_cmds = 0; - for (load_cmd = load_array; load_cmd < load_end; load_cmd++) - { - load_union_t *load_hdr = load_cmd->load; - - if (load_hdr->hdr.ldci_cmd_type == LDC_SYMBOLS) - { - symbol_load_cmds++; - - if (debug) - { - char *kind = "unknown"; - - switch (load_hdr->sym.symc_kind) - { - case SYMC_IMPORTS: kind = "imports"; break; - case SYMC_DEFINED_SYMBOLS: kind = "defined"; break; - case SYMC_STABS: kind = "stabs"; break; - } - - fprintf (stderr, "\nProcessing symbol table #%d, offset = 0x%.8lx, kind = %s\n", - symbol_load_cmds, load_hdr->hdr.ldci_section_off, kind); - } - - if (load_hdr->sym.symc_kind != SYMC_DEFINED_SYMBOLS) - continue; - - str_sect = load_array[load_hdr->sym.symc_strings_section].section; - if (str_sect == (char *) 0) - fatal ("string section missing"); - - if (load_cmd->section == (char *) 0) - fatal ("section pointer missing"); - - num_syms = load_hdr->sym.symc_nentries; - for (i = 0; i < num_syms; i++) - { - symbol_info_t *sym = ((symbol_info_t *) load_cmd->section) + i; - char *name = sym->si_name.symbol_name + str_sect; - - if (name[0] != '_') - continue; - - if (rw) - { - char *n = name + strlen (name) - strlen (NAME__MAIN); - - if ((n - name) < 0 || strcmp (n, NAME__MAIN)) - continue; - while (n != name) - if (*--n != '_') - continue; - - main_sym = sym; - } - else - { - switch (is_ctor_dtor (name)) - { - case 1: - add_to_list (&constructors, name); - break; - - case 2: - add_to_list (&destructors, name); - break; - - default: /* not a constructor or destructor */ - continue; - } - } - - if (debug) - fprintf (stderr, "\ttype = 0x%.4x, sc = 0x%.2x, flags = 0x%.8x, name = %.30s\n", - sym->si_type, sym->si_sc_type, sym->si_flags, name); - } - } - } - - if (symbol_load_cmds == 0) - fatal ("no symbol table found"); - - /* Update the program file now, rewrite header and load commands. At present, - we assume that there is enough space after the last load command to insert - one more. Since the first section written out is page aligned, and the - number of load commands is small, this is ok for the present. */ - - if (rw) - { - load_union_t *load_map; - size_t size; - - if (cmd_strings == -1) - fatal ("no cmd_strings found"); - - /* Add __main to initializer list. - If we are building a program instead of a shared library, do not - do anything, since in the current version, you cannot do mallocs - and such in the constructors. */ - - if (main_sym != (symbol_info_t *) 0 - && ((hdr.moh_flags & MOH_EXECABLE_F) == 0)) - add_func_table (&hdr, load_array, main_sym, FNTC_INITIALIZATION); - - if (debug) - fprintf (stderr, "\nUpdating header and load commands.\n\n"); - - hdr.moh_n_load_cmds++; - size = sizeof (load_cmd_map_command_t) + (sizeof (mo_offset_t) * (hdr.moh_n_load_cmds - 1)); - - /* Create new load command map. */ - if (debug) - fprintf (stderr, "load command map, %d cmds, new size %ld.\n", - (int)hdr.moh_n_load_cmds, (long)size); - - load_map = (load_union_t *) xcalloc (1, size); - load_map->map.ldc_header.ldci_cmd_type = LDC_CMD_MAP; - load_map->map.ldc_header.ldci_cmd_size = size; - load_map->map.lcm_ld_cmd_strings = cmd_strings; - load_map->map.lcm_nentries = hdr.moh_n_load_cmds; - load_array[hdr.moh_n_load_cmds-1].load = load_map; - - offset = hdr.moh_first_cmd_off; - for (i = 0; i < hdr.moh_n_load_cmds; i++) - { - load_map->map.lcm_map[i] = offset; - if (load_array[i].load->hdr.ldci_cmd_type == LDC_CMD_MAP) - hdr.moh_load_map_cmd_off = offset; - - offset += load_array[i].load->hdr.ldci_cmd_size; - } - - hdr.moh_sizeofcmds = offset - MO_SIZEOF_RAW_HDR; - - if (debug) - print_header (&hdr); - - /* Write header */ - status = encode_mach_o_hdr (&hdr, obj, MO_SIZEOF_RAW_HDR); - if (status != MO_HDR_CONV_SUCCESS) - bad_header (status); - - if (debug) - fprintf (stderr, "writing load commands.\n\n"); - - /* Write load commands */ - offset = hdr.moh_first_cmd_off; - for (i = 0; i < hdr.moh_n_load_cmds; i++) - { - load_union_t *load_hdr = load_array[i].load; - size_t size = load_hdr->hdr.ldci_cmd_size; - - if (debug) - print_load_command (load_hdr, offset, i); - - bcopy ((char *) load_hdr, (char *) (obj + offset), size); - offset += size; - } - } - - end_file (obj_file); - - if (close (prog_fd)) - fatal_perror ("closing %s", prog_name); - - if (debug) - fprintf (stderr, "\n"); -} - - -/* Add a function table to the load commands to call a function - on initiation or termination of the process. */ - -static void -add_func_table (hdr_p, load_array, sym, type) - mo_header_t *hdr_p; /* pointer to global header */ - load_all_t *load_array; /* array of ptrs to load cmds */ - symbol_info_t *sym; /* pointer to symbol entry */ - int type; /* fntc_type value */ -{ - /* Add a new load command. */ - int num_cmds = ++hdr_p->moh_n_load_cmds; - int load_index = num_cmds - 1; - size_t size = sizeof (func_table_command_t) + sizeof (mo_addr_t); - load_union_t *ptr = xcalloc (1, size); - load_all_t *load_cmd; - int i; - - /* Set the unresolved address bit in the header to force the loader to be - used, since kernel exec does not call the initialization functions. */ - hdr_p->moh_flags |= MOH_UNRESOLVED_F; - - load_cmd = &load_array[load_index]; - load_cmd->load = ptr; - load_cmd->section = (char *) 0; - - /* Fill in func table load command. */ - ptr->func.ldc_header.ldci_cmd_type = LDC_FUNC_TABLE; - ptr->func.ldc_header.ldci_cmd_size = size; - ptr->func.ldc_header.ldci_section_off = 0; - ptr->func.ldc_header.ldci_section_len = 0; - ptr->func.fntc_type = type; - ptr->func.fntc_nentries = 1; - - /* copy address, turn it from abs. address to (region,offset) if necessary. */ - /* Is the symbol already expressed as (region, offset)? */ - if ((sym->si_flags & SI_ABSOLUTE_VALUE_F) == 0) - { - ptr->func.fntc_entry_loc[i].adr_lcid = sym->si_value.def_val.adr_lcid; - ptr->func.fntc_entry_loc[i].adr_sctoff = sym->si_value.def_val.adr_sctoff; - } - - /* If not, figure out which region it's in. */ - else - { - mo_vm_addr_t addr = sym->si_value.abs_val; - int found = 0; - - for (i = 0; i < load_index; i++) - { - if (load_array[i].load->hdr.ldci_cmd_type == LDC_REGION) - { - region_command_t *region_ptr = &load_array[i].load->region; - - if ((region_ptr->regc_flags & REG_ABS_ADDR_F) != 0 - && addr >= region_ptr->regc_addr.vm_addr - && addr <= region_ptr->regc_addr.vm_addr + region_ptr->regc_vm_size) - { - ptr->func.fntc_entry_loc[0].adr_lcid = i; - ptr->func.fntc_entry_loc[0].adr_sctoff = addr - region_ptr->regc_addr.vm_addr; - found++; - break; - } - } - } - - if (!found) - fatal ("could not convert 0x%l.8x into a region", addr); - } - - if (debug) - fprintf (stderr, - "%s function, region %d, offset = %ld (0x%.8lx)\n", - (type == FNTC_INITIALIZATION) ? "init" : "term", - (int)ptr->func.fntc_entry_loc[i].adr_lcid, - (long)ptr->func.fntc_entry_loc[i].adr_sctoff, - (long)ptr->func.fntc_entry_loc[i].adr_sctoff); - -} - - -/* Print the global header for an OSF/rose object. */ - -static void -print_header (hdr_ptr) - mo_header_t *hdr_ptr; -{ - fprintf (stderr, "\nglobal header:\n"); - fprintf (stderr, "\tmoh_magic = 0x%.8lx\n", hdr_ptr->moh_magic); - fprintf (stderr, "\tmoh_major_version = %d\n", (int)hdr_ptr->moh_major_version); - fprintf (stderr, "\tmoh_minor_version = %d\n", (int)hdr_ptr->moh_minor_version); - fprintf (stderr, "\tmoh_header_version = %d\n", (int)hdr_ptr->moh_header_version); - fprintf (stderr, "\tmoh_max_page_size = %d\n", (int)hdr_ptr->moh_max_page_size); - fprintf (stderr, "\tmoh_byte_order = %d\n", (int)hdr_ptr->moh_byte_order); - fprintf (stderr, "\tmoh_data_rep_id = %d\n", (int)hdr_ptr->moh_data_rep_id); - fprintf (stderr, "\tmoh_cpu_type = %d\n", (int)hdr_ptr->moh_cpu_type); - fprintf (stderr, "\tmoh_cpu_subtype = %d\n", (int)hdr_ptr->moh_cpu_subtype); - fprintf (stderr, "\tmoh_vendor_type = %d\n", (int)hdr_ptr->moh_vendor_type); - fprintf (stderr, "\tmoh_load_map_cmd_off = %d\n", (int)hdr_ptr->moh_load_map_cmd_off); - fprintf (stderr, "\tmoh_first_cmd_off = %d\n", (int)hdr_ptr->moh_first_cmd_off); - fprintf (stderr, "\tmoh_sizeofcmds = %d\n", (int)hdr_ptr->moh_sizeofcmds); - fprintf (stderr, "\tmon_n_load_cmds = %d\n", (int)hdr_ptr->moh_n_load_cmds); - fprintf (stderr, "\tmoh_flags = 0x%.8lx", (long)hdr_ptr->moh_flags); - - if (hdr_ptr->moh_flags & MOH_RELOCATABLE_F) - fprintf (stderr, ", relocatable"); - - if (hdr_ptr->moh_flags & MOH_LINKABLE_F) - fprintf (stderr, ", linkable"); - - if (hdr_ptr->moh_flags & MOH_EXECABLE_F) - fprintf (stderr, ", execable"); - - if (hdr_ptr->moh_flags & MOH_EXECUTABLE_F) - fprintf (stderr, ", executable"); - - if (hdr_ptr->moh_flags & MOH_UNRESOLVED_F) - fprintf (stderr, ", unresolved"); - - fprintf (stderr, "\n\n"); - return; -} - - -/* Print a short summary of a load command. */ - -static void -print_load_command (load_hdr, offset, number) - load_union_t *load_hdr; - size_t offset; - int number; -{ - mo_long_t type = load_hdr->hdr.ldci_cmd_type; - char *type_str = (char *) 0; - - switch (type) - { - case LDC_UNDEFINED: type_str = "UNDEFINED"; break; - case LDC_CMD_MAP: type_str = "CMD_MAP"; break; - case LDC_INTERPRETER: type_str = "INTERPRETER"; break; - case LDC_STRINGS: type_str = "STRINGS"; break; - case LDC_REGION: type_str = "REGION"; break; - case LDC_RELOC: type_str = "RELOC"; break; - case LDC_PACKAGE: type_str = "PACKAGE"; break; - case LDC_SYMBOLS: type_str = "SYMBOLS"; break; - case LDC_ENTRY: type_str = "ENTRY"; break; - case LDC_FUNC_TABLE: type_str = "FUNC_TABLE"; break; - case LDC_GEN_INFO: type_str = "GEN_INFO"; break; - } - - fprintf (stderr, - "cmd %2d, sz: 0x%.2lx, coff: 0x%.3lx, doff: 0x%.6lx, dlen: 0x%.6lx", - number, - (long) load_hdr->hdr.ldci_cmd_size, - (long) offset, - (long) load_hdr->hdr.ldci_section_off, - (long) load_hdr->hdr.ldci_section_len); - - if (type_str == (char *) 0) - fprintf (stderr, ", ty: unknown (%ld)\n", (long) type); - - else if (type != LDC_REGION) - fprintf (stderr, ", ty: %s\n", type_str); - - else - { - char *region = ""; - switch (load_hdr->region.regc_usage_type) - { - case REG_TEXT_T: region = ", .text"; break; - case REG_DATA_T: region = ", .data"; break; - case REG_BSS_T: region = ", .bss"; break; - case REG_GLUE_T: region = ", .glue"; break; -#if defined (REG_RDATA_T) && defined (REG_SDATA_T) && defined (REG_SBSS_T) /*mips*/ - case REG_RDATA_T: region = ", .rdata"; break; - case REG_SDATA_T: region = ", .sdata"; break; - case REG_SBSS_T: region = ", .sbss"; break; -#endif - } - - fprintf (stderr, ", ty: %s, vaddr: 0x%.8lx, vlen: 0x%.6lx%s\n", - type_str, - (long) load_hdr->region.regc_vm_addr, - (long) load_hdr->region.regc_vm_size, - region); - } - - return; -} - - -/* Fatal error when {en,de}code_mach_o_header fails. */ - -static void -bad_header (status) - int status; -{ - char *msg = (char *) 0; - - switch (status) - { - case MO_ERROR_BAD_MAGIC: msg = "bad magic number"; break; - case MO_ERROR_BAD_HDR_VERS: msg = "bad header version"; break; - case MO_ERROR_BAD_RAW_HDR_VERS: msg = "bad raw header version"; break; - case MO_ERROR_BUF2SML: msg = "raw header buffer too small"; break; - case MO_ERROR_OLD_RAW_HDR_FILE: msg = "old raw header file"; break; - case MO_ERROR_UNSUPPORTED_VERS: msg = "unsupported version"; break; - } - - if (msg == (char *) 0) - fatal ("unknown {de,en}code_mach_o_hdr return value %d", status); - else - fatal ("%s", msg); -} - - -/* Read a file into a memory buffer. */ - -static struct file_info * -read_file (name, fd, rw) - char *name; /* filename */ - int fd; /* file descriptor */ - int rw; /* read/write */ -{ - struct stat stat_pkt; - struct file_info *p = (struct file_info *) xcalloc (sizeof (struct file_info), 1); -#ifdef USE_MMAP - static int page_size; -#endif - - if (fstat (fd, &stat_pkt) < 0) - fatal_perror ("fstat %s", name); - - p->name = name; - p->size = stat_pkt.st_size; - p->rounded_size = stat_pkt.st_size; - p->fd = fd; - p->rw = rw; - -#ifdef USE_MMAP - if (debug) - fprintf (stderr, "mmap %s, %s\n", name, (rw) ? "read/write" : "read-only"); - - if (page_size == 0) - page_size = sysconf (_SC_PAGE_SIZE); - - p->rounded_size = ((p->size + page_size - 1) / page_size) * page_size; - p->start = mmap ((caddr_t) 0, - (rw) ? p->rounded_size : p->size, - (rw) ? (PROT_READ | PROT_WRITE) : PROT_READ, - MAP_FILE | MAP_VARIABLE | MAP_SHARED, - fd, - 0L); - - if (p->start != (char *) 0 && p->start != (char *) -1) - p->use_mmap = 1; - - else -#endif /* USE_MMAP */ - { - long len; - - if (debug) - fprintf (stderr, "read %s\n", name); - - p->use_mmap = 0; - p->start = xmalloc (p->size); - if (lseek (fd, 0L, SEEK_SET) < 0) - fatal_perror ("lseek to 0 on %s", name); - - len = read (fd, p->start, p->size); - if (len < 0) - fatal_perror ("read %s", name); - - if (len != p->size) - fatal ("read %ld bytes, expected %ld, from %s", len, p->size, name); - } - - return p; -} - -/* Do anything necessary to write a file back from memory. */ - -static void -end_file (ptr) - struct file_info *ptr; /* file information block */ -{ -#ifdef USE_MMAP - if (ptr->use_mmap) - { - if (ptr->rw) - { - if (debug) - fprintf (stderr, "msync %s\n", ptr->name); - - if (msync (ptr->start, ptr->rounded_size, MS_ASYNC)) - fatal_perror ("msync %s", ptr->name); - } - - if (debug) - fprintf (stderr, "munmap %s\n", ptr->name); - - if (munmap (ptr->start, ptr->size)) - fatal_perror ("munmap %s", ptr->name); - } - else -#endif /* USE_MMAP */ - { - if (ptr->rw) - { - long len; - - if (debug) - fprintf (stderr, "write %s\n", ptr->name); - - if (lseek (ptr->fd, 0L, SEEK_SET) < 0) - fatal_perror ("lseek to 0 on %s", ptr->name); - - len = write (ptr->fd, ptr->start, ptr->size); - if (len < 0) - fatal_perror ("write %s", ptr->name); - - if (len != ptr->size) - fatal ("wrote %ld bytes, expected %ld, to %s", len, ptr->size, ptr->name); - } - - free (ptr->start); - } - - free (ptr); -} - -#endif /* OBJECT_FORMAT_ROSE */ diff --git a/gcc/collect2.h b/gcc/collect2.h deleted file mode 100755 index 04844bc..0000000 --- a/gcc/collect2.h +++ /dev/null @@ -1,36 +0,0 @@ -/* Header file for collect/tlink routines. - Copyright (C) 1998 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef __COLLECT2_H__ -#define __COLLECT2_H__ - -extern void do_tlink PARAMS ((char **, char **)); - -extern void collect_execute PARAMS ((char *, char **, char *)); - -extern void collect_exit PARAMS ((int)) ATTRIBUTE_NORETURN; - -extern int collect_wait PARAMS ((char *)); - -extern void dump_file PARAMS ((char *)); - -extern int file_exists PARAMS ((char *)); - -#endif /* ! __COLLECT2_H__ */ diff --git a/gcc/config/arm/t-arm-elf b/gcc/config/arm/t-arm-elf index 5890380..b57eeca 100755 --- a/gcc/config/arm/t-arm-elf +++ b/gcc/config/arm/t-arm-elf @@ -4,8 +4,6 @@ LIB1ASMSRC = arm/lib1funcs.asm LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX # END CYGNUS LOCAL interworking -EXTRA_PARTS = crtbegin.o crtend.o - # These are really part of libgcc1, but this will cause them to be # built correctly, so... @@ -30,7 +28,6 @@ MULTILIB_OPTIONS = mlittle-endian/mbig-endian mhard-float/msoft-float mapcs-32/ MULTILIB_DIRNAMES = le be fpu soft 32bit 26bit normal interwork elf under nofmult MULTILIB_EXCEPTIONS = *mapcs-26/*mthumb-interwork* *mthumb-interwork*/*mcpu=arm7* MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle mcpu?arm7=mcpu?arm7d mcpu?arm7=mcpu?arm7di mcpu?arm7=mcpu?arm70 mcpu?arm7=mcpu?arm700 mcpu?arm7=mcpu?arm700i mcpu?arm7=mcpu?arm710 mcpu?arm7=mcpu?arm710c mcpu?arm7=mcpu?arm7100 mcpu?arm7=mcpu?arm7500 mcpu?arm7=mcpu?arm7500fe mcpu?arm7=mcpu?arm6 mcpu?arm7=mcpu?arm60 mcpu?arm7=mcpu?arm600 mcpu?arm7=mcpu?arm610 mcpu?arm7=mcpu?arm620 -EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib # END CYGNUS LOCAL diff --git a/gcc/config/arm/t-thumb-elf b/gcc/config/arm/t-thumb-elf index 57b5d7b..2f5054d 100755 --- a/gcc/config/arm/t-thumb-elf +++ b/gcc/config/arm/t-thumb-elf @@ -4,7 +4,6 @@ LIB1ASMSRC = arm/lib1thumb.asm LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_tls _call_via_rX _interwork_call_via_rX # adddi3/subdi3 added to machine description -EXTRA_PARTS=crtbegin.o crtend.o # These are really part of libgcc1, but this will cause them to be # built correctly, so... @@ -28,7 +27,6 @@ dp-bit.c: $(srcdir)/config/fp-bit.c MULTILIB_OPTIONS = mlittle-endian/mbig-endian mno-thumb-interwork/mthumb-interwork fno-leading-underscore/fleading-underscore MULTILIB_DIRNAMES = le be normal interwork elf under MULTILIB_MATCHES = mbig-endian=mbe mlittle-endian=mle -EXTRA_MULTILIB_PARTS = crtbegin.o crtend.o LIBGCC = stmp-multilib INSTALL_LIBGCC = install-multilib diff --git a/gcc/configure b/gcc/configure index d2d1749..05c0782 100755 --- a/gcc/configure +++ b/gcc/configure @@ -2819,8 +2819,6 @@ for machine in $build $host $target; do extra_gcc_objs= xm_defines= float_format= - # Set this to force installation and use of collect2. - use_collect2= # Set this to override the default target model. target_cpu_default= # Set this to control which fixincludes program to use. @@ -2895,2578 +2893,11 @@ for machine in $build $host $target; do case $machine in # Support site-specific machine types. - *local*) - cpu_type=`echo $machine | sed -e 's/-.*//'` - rest=`echo $machine | sed -e "s/$cpu_type-//"` - xm_file=${cpu_type}/xm-$rest.h - tm_file=${cpu_type}/$rest.h - if test -f $srcdir/config/${cpu_type}/x-$rest; \ - then xmake_file=${cpu_type}/x-$rest; \ - else true; \ - fi - if test -f $srcdir/config/${cpu_type}/t-$rest; \ - then tmake_file=${cpu_type}/t-$rest; \ - else true; \ - fi - ;; - 1750a-*-*) - ;; - a29k-*-bsd* | a29k-*-sym1*) - tm_file="${tm_file} a29k/unix.h" - xm_defines=USG - xmake_file=a29k/x-unix - use_collect2=yes - ;; - a29k-*-udi | a29k-*-coff) - tm_file="${tm_file} dbxcoff.h a29k/udi.h" - tmake_file=a29k/t-a29kbare - ;; - a29k-wrs-vxworks*) - tm_file="${tm_file} dbxcoff.h a29k/udi.h a29k/vx29k.h" - tmake_file=a29k/t-vx29k - extra_parts="crtbegin.o crtend.o" - thread_file='vxworks' - ;; - a29k-*-*) # Default a29k environment. - use_collect2=yes - ;; - alpha*-*-linux-gnuecoff*) - tm_file="${tm_file} alpha/linux-ecoff.h alpha/linux.h" - target_cpu_default="MASK_GAS" - gas=no - xmake_file=none - gas=yes gnu_ld=yes - ;; - alpha*-*-linux-gnulibc1*) - tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.wrap - xmake_file=none - gas=yes gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - alpha*-*-linux-gnu*) - tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="t-linux alpha/t-linux alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - xmake_file=none - fixincludes=Makefile.in - gas=yes gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - alpha*-*-netbsd*) - tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - xmake_file=none - fixincludes=fixinc.wrap - gas=yes gnu_ld=yes - ;; - - alpha*-dec-osf*) - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - if test x$gas != xyes - then - extra_passes="mips-tfile mips-tdump" - fi - use_collect2=yes - case $machine in - *-*-osf1*) - tm_file="${tm_file} alpha/osf.h alpha/osf12.h alpha/osf2or3.h" - ;; - *-*-osf[23]*) - tm_file="${tm_file} alpha/osf.h alpha/osf2or3.h" - ;; - *-*-osf4*) - tm_file="${tm_file} alpha/osf.h" - # Some versions of OSF4 (specifically X4.0-9 296.7) have - # a broken tar, so we use cpio instead. - install_headers_dir=install-headers-cpio - ;; - esac - case $machine in - *-*-osf4.0[b-z] | *-*-osf4.[1-9]*) - target_cpu_default=MASK_SUPPORT_ARCH - ;; - esac - ;; - alpha*-*-vxworks*) - tm_file="${tm_file} dbx.h alpha/vxworks.h" - if x$gas != xyes - then - extra_passes="mips-tfile mips-tdump" - fi - use_collect2=yes - ;; - alpha*-*-winnt*) - tm_file="${tm_file} alpha/win-nt.h" - xm_file="${xm_file} config/winnt/xm-winnt.h alpha/xm-winnt.h" - tmake_file=t-libc-ok - xmake_file=winnt/x-winnt - extra_host_objs=oldnames.o - extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if test x$gnu_ld != xyes - then - extra_programs=ld.exe - fi - if test x$enable_threads = xyes; then - thread_file='win32' - fi - ;; - alpha*-dec-vms*) - tm_file=alpha/vms.h - xm_file="${xm_file} alpha/xm-vms.h" - tmake_file=alpha/t-vms - fixincludes=Makefile.in - ;; - arc-*-elf*) - extra_parts="crtinit.o crtfini.o" - ;; - arm-*-coff* | armel-*-coff*) - tm_file=arm/coff.h - tmake_file=arm/t-bare - ;; - arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) - tm_file=arm/riscix1-1.h - use_collect2=yes - ;; - arm-*-riscix*) # Acorn RISC machine - if test x$gas = xyes - then - tm_file=arm/rix-gas.h - else - tm_file=arm/riscix.h - fi - xmake_file=arm/x-riscix - tmake_file=arm/t-riscix - use_collect2=yes - ;; - arm-semi-aout | armel-semi-aout) - tm_file=arm/semi.h - tmake_file=arm/t-semi - fixincludes=Makefile.in # There is nothing to fix - ;; - arm-semi-aof | armel-semi-aof) - tm_file=arm/semiaof.h - tmake_file=arm/t-semiaof - fixincludes=Makefile.in # There is nothing to fix - ;; - arm*-*-netbsd*) - tm_file=arm/netbsd.h - xm_file="arm/xm-netbsd.h ${xm_file}" - tmake_file="t-netbsd arm/t-netbsd" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - ;; - arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out - cpu_type=arm - xmake_file=x-linux - tm_file=arm/linux-aout.h - tmake_file=arm/t-linux - fixincludes=Makefile.in - gnu_ld=yes - ;; - arm*-*-linux-gnu*) # ARM GNU/Linux with ELF - xm_file=arm/xm-linux.h - xmake_file=x-linux - case $machine in - armv2*-*-*) - tm_file=arm/linux-elf26.h - ;; - *) - tm_file=arm/linux-elf.h - ;; - esac - tmake_file="t-linux arm/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # Nothing to fix - gnu_ld=yes - ;; - arm*-*-aout) - tm_file=arm/aout.h - tmake_file=arm/t-bare - ;; - arm*-*-ecos-elf) - tm_file=arm/ecos-elf.h - tmake_file=arm/t-elf - ;; - arm*-*-elf) + arm*-*-elf*) tm_file=arm/unknown-elf.h tmake_file=arm/t-arm-elf ;; - arm*-*-oabi) - tm_file=arm/unknown-elf-oabi.h - tmake_file=arm/t-arm-elf - ;; - c1-convex-*) # Convex C1 - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - c2-convex-*) # Convex C2 - target_cpu_default=2 - use_collect2=yes - fixincludes=Makefile.in - ;; - c32-convex-*) - target_cpu_default=4 - use_collect2=yes - fixincludes=Makefile.in - ;; - c34-convex-*) - target_cpu_default=8 - use_collect2=yes - fixincludes=Makefile.in - ;; - c38-convex-*) - target_cpu_default=16 - use_collect2=yes - fixincludes=Makefile.in - ;; - c4x-*) - cpu_type=c4x - tmake_file=c4x/t-c4x - ;; - clipper-intergraph-clix*) - tm_file="${tm_file} svr3.h clipper/clix.h" - xm_file=clipper/xm-clix.h - xmake_file=clipper/x-clix - extra_headers=va-clipper.h - extra_parts="crtbegin.o crtend.o" - install_headers_dir=install-headers-cpio - ;; - dsp16xx-*) - ;; - elxsi-elxsi-*) - use_collect2=yes - ;; -# This hasn't been upgraded to GCC 2. -# fx80-alliant-*) # Alliant FX/80 -# ;; - h8300-*-*) - float_format=i32 - ;; - hppa1.1-*-pro*) - tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h" - xm_file=pa/xm-papro.h - tmake_file=pa/t-pro - ;; - hppa1.1-*-osf*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-osf.h" - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.1-*-rtems*) - tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h" - xm_file=pa/xm-papro.h - tmake_file=pa/t-pro - ;; - hppa1.0-*-osf*) - tm_file="${tm_file} pa/pa-osf.h" - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.1-*-bsd*) - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.0-*-bsd*) - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.0-*-hpux7*) - tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux8.0[0-2]*) - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - else - tm_file="pa/pa-oldas.h ${tm_file}" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux8.0[0-2]*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - else - tm_file="pa/pa-oldas.h ${tm_file}" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux8*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux8*) - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux10* | hppa2*-*-hpux10*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=pa/t-pa - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - if test x$enable_threads = x; then - enable_threads=$have_pthread_h - fi - if test x$enable_threads = xyes; then - thread_file='dce' - tmake_file="${tmake_file} pa/t-dce-thr" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux10*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - if test x$enable_threads = x; then - enable_threads=$have_pthread_h - fi - if test x$enable_threads = xyes; then - thread_file='dce' - tmake_file="${tmake_file} pa/t-dce-thr" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - # CYGNUS LOCAL hpux11 - hppa1.1-*-hpux11* | hppa2*-*-hpux11*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux11.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=pa/t-pa - if [ x$gas = xyes ] - then - tm_file="${tm_file} pa/pa-gas.h" - fi -# if [[ x$enable_threads = x ]]; then -# enable_threads=$have_pthread_h -# fi -# if [[ x$enable_threads = xyes ]]; then -# thread_file='dce' -# tmake_file="${tmake_file} pa/t-dce-thr" -# fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux11*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux11.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if [ x$gas = xyes ] - then - tm_file="${tm_file} pa/pa-gas.h" - fi -# if [[ x$enable_threads = x ]]; then -# enable_threads=$have_pthread_h -# fi -# if [[ x$enable_threads = xyes ]]; then -# thread_file='dce' -# tmake_file="${tmake_file} pa/t-dce-thr" -# fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - # END CYGNUS LOCAL - hppa1.1-*-hpux* | hppa2*-*-hpux*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hiux* | hppa2*-*-hiux*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hiux*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa*-*-lites*) - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - i370-*-mvs*) - ;; - i[34567]86-ibm-aix*) # IBM PS/2 running AIX - if test x$gas = xyes - then - tm_file=i386/aix386.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - else - tm_file=i386/aix386ng.h - use_collect2=yes - fi - xm_file="xm-alloca.h i386/xm-aix.h ${xm_file}" - xm_defines=USG - xmake_file=i386/x-aix - ;; - i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - xmake_file=i386/x-ncr3000 - if test x$stabs = xyes -a x$gas = xyes - then - tm_file=i386/sysv4gdb.h - else - tm_file=i386/sysv4.h - fi - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtpic - ;; - i[34567]86-next-*) - tm_file=i386/next.h - xm_file=i386/xm-next.h - tmake_file=i386/t-next - xmake_file=i386/x-next - extra_objs=nextstep.o - extra_parts="crtbegin.o crtend.o" - if test x$enable_threads = xyes; then - thread_file='mach' - fi - ;; - i[34567]86-sequent-bsd*) # 80386 from Sequent - use_collect2=yes - if test x$gas = xyes - then - tm_file=i386/seq-gas.h - else - tm_file=i386/sequent.h - fi - ;; - i[34567]86-sequent-ptx1*) - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - tm_file=i386/seq-sysv3.h - tmake_file=i386/t-crtstuff - fixincludes=fixinc.ptx - extra_parts="crtbegin.o crtend.o" - install_headers_dir=install-headers-cpio - ;; - i[34567]86-sequent-ptx2* | i[34567]86-sequent-sysv3*) - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - tm_file=i386/seq2-sysv3.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx - install_headers_dir=install-headers-cpio - ;; - i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - xmake_file=x-svr4 - tm_file=i386/ptx4-i.h - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx - install_headers_dir=install-headers-cpio - ;; - i386-sun-sunos*) # Sun i386 roadrunner - xm_defines=USG - tm_file=i386/sun.h - use_collect2=yes - ;; - i[34567]86-wrs-vxworks*) - tm_file=i386/vxi386.h - tmake_file=i386/t-i386bare - ;; - i[34567]86-*-aout*) - tm_file=i386/i386-aout.h - tmake_file=i386/t-i386bare - ;; - i[34567]86-*-bsdi* | i[34567]86-*-bsd386*) - tm_file=i386/bsd386.h -# tmake_file=t-libc-ok - ;; - i[34567]86-*-bsd*) - tm_file=i386/386bsd.h -# tmake_file=t-libc-ok -# Next line turned off because both 386BSD and BSD/386 use GNU ld. -# use_collect2=yes - ;; - i[34567]86-*-freebsdelf*) - tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h" - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - tmake_file=i386/t-freebsd - gas=yes - gnu_ld=yes - stabs=yes - ;; - i[34567]86-*-freebsd*) - tm_file=i386/freebsd.h - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - tmake_file=i386/t-freebsd - ;; - # We are hoping OpenBSD is still close enough to NetBSD that we can - # share the configurations. - i[34567]86-*-netbsd* | i[34567]86-*-openbsd*) - tm_file=i386/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - i[34567]86-*-coff*) - tm_file=i386/i386-coff.h - tmake_file=i386/t-i386bare - ;; - i[34567]86-*-isc*) # 80386 running ISC system - xm_file="${xm_file} i386/xm-isc.h" - xm_defines="USG SVR3" - case $machine in - i[34567]86-*-isc[34]*) - xmake_file=i386/x-isc3 - ;; - *) - xmake_file=i386/x-isc - ;; - esac - if test x$gas = xyes -a x$stabs = xyes - then - tm_file=i386/iscdbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.ifile" - else - tm_file=i386/isccoff.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fi - install_headers_dir=install-headers-cpio - ;; - i[34567]86-*-linux-gnuoldld*) # Intel 80386's running GNU/Linux - # pre BFD linkers - xmake_file=x-linux-aout - tmake_file="t-linux-aout i386/t-crtstuff" - tm_file=i386/linux-oldld.h - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - ;; - i[34567]86-*-linux-gnuaout*) # Intel 80386's running GNU/Linux - xmake_file=x-linux-aout - tmake_file="t-linux-aout i386/t-crtstuff" - tm_file=i386/linux-aout.h - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - ;; - i[34567]86-*-linux-gnulibc1) # Intel 80386's running GNU/Linux - # GNU/Linux C library 5 - xmake_file=x-linux - tm_file=i386/linux.h - tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - if test x$enable_threads = xyes; then - thread_file='single' - fi - ;; - i[34567]86-*-linux-gnu*) # Intel 80386's running GNU/Linux - # aka GNU/Linux C library 6 - xmake_file=x-linux - tm_file=i386/linux.h - tmake_file="t-linux i386/t-crtstuff" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - i[34567]86-*-gnu*) - ;; - i[34567]86-go32-msdos | i[34567]86-*-go32*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - xmake_file=i386/x-go32 # CYGNUS LOCAL - tmake_file=i386/t-go32 - ;; - i[34567]86-pc-msdosdjgpp*) - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 - xmake_file=i386/x-go32 - gnu_ld=yes - gas=yes - exeext=.exe - case $host in - *pc-msdosdjgpp*) - target_alias=djgpp - ;; - esac - ;; - i[34567]86-moss-msdos* | i[34567]86-*-moss*) - tm_file=i386/moss.h - tmake_file=t-libc-ok - fixincludes=Makefile.in - gnu_ld=yes - gas=yes - ;; - i[34567]86-*-lynxos*) - if test x$gas = xyes - then - tm_file=i386/lynx.h - else - tm_file=i386/lynx-ng.h - fi - xm_file=i386/xm-lynx.h - tmake_file=i386/t-i386bare - xmake_file=x-lynx - ;; - i[34567]86-*-mach*) - tm_file=i386/mach.h -# tmake_file=t-libc-ok - use_collect2=yes - ;; - i[34567]86-*-osfrose*) # 386 using OSF/rose - if test x$elf = xyes - then - tm_file=i386/osfelf.h - use_collect2= - else - tm_file=i386/osfrose.h - use_collect2=yes - fi - xm_file="i386/xm-osf.h ${xm_file}" - xmake_file=i386/x-osfrose - tmake_file=i386/t-osf - extra_objs=halfpic.o - ;; - i[34567]86-go32-rtems*) - cpu_type=i386 - xm_file=i386/xm-go32.h - tm_file=i386/go32-rtems.h - tmake_file="i386/t-go32 t-rtems" - ;; - i[34567]86-*-rtemself*) - cpu_type=i386 - tm_file=i386/rtemself.h - tmake_file="i386/t-i386bare t-rtems" - ;; - i[34567]86-*-rtems*) - cpu_type=i386 - tm_file=i386/rtems.h - tmake_file="i386/t-i386bare t-rtems" - ;; - i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5 - xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h" - xm_defines="USG SVR3" - xmake_file=i386/x-sco5 - fixincludes=fixinc.sco - install_headers_dir=install-headers-cpio - tm_file=i386/sco5.h - if test x$gas = xyes - then - tm_file="i386/sco5gas.h ${tm_file}" - tmake_file=i386/t-sco5gas - else - tmake_file=i386/t-sco5 - fi - extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o" - ;; - i[34567]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system - xm_file="${xm_file} i386/xm-sco.h" - xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST" - xmake_file=i386/x-sco4 - fixincludes=fixinc.sco - install_headers_dir=install-headers-cpio - if test x$stabs = xyes - then - tm_file=i386/sco4dbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/sco4.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fi - truncate_target=yes - ;; - i[34567]86-*-sco*) # 80386 running SCO system - xm_file=i386/xm-sco.h - xmake_file=i386/x-sco - install_headers_dir=install-headers-cpio - if test x$stabs = xyes - then - tm_file=i386/scodbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/sco.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - truncate_target=yes - ;; - i[34567]86-*-solaris2*) - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - if test x$stabs = xyes - then - tm_file=i386/sol2dbg.h - else - tm_file=i386/sol2.h - fi - tmake_file=i386/t-sol2 - extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" - xmake_file=x-svr4 - case $machine in - *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - if test x$enable_threads = xyes; then - thread_file='solaris' - fi - ;; - i[34567]86-*-sysv5*) # Intel x86 on System V Release 5 - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - tm_file=i386/sysv4.h - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.svr4 - ;; - i[34567]86-*-sysv4*) # Intel 80386's running system V.4 - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - tm_file=i386/sysv4.h - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - ;; - i[34567]86-*-udk*) # Intel x86 on SCO UW/OSR5 Dev Kit - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - tm_file=i386/udk.h - tmake_file="i386/t-crtpic i386/t-udk" - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes="fixinc.svr4" - ;; - i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+ - cpu_type=i386 - xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h" - xm_defines="USE_C_ALLOCA SMALL_ARG_MAX" - fixincludes=Makefile.in #Don't do it on OSF/1 - if test x$stabs = xyes - then - tm_file=i386/osf1elfgdb.h - else - tm_file=i386/osf1elf.h - fi - tmake_file=i386/t-osf1elf - xmake_file=i386/x-osf1elf - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - ;; - i[34567]86-*-sysv*) # Intel 80386's running system V - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=i386/svr3dbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/svr3gas.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - else - tm_file=i386/sysv3.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - ;; - i386-*-vsta) # Intel 80386's running VSTa kernel - xm_file="${xm_file} i386/xm-vsta.h" - tm_file=i386/vsta.h - tmake_file=i386/t-vsta - xmake_file=i386/x-vsta - ;; - i[34567]86-*-win32) - xm_file="${xm_file} i386/xm-cygwin.h" - tmake_file=i386/t-cygwin - tm_file=i386/win32.h - xmake_file=i386/x-cygwin - extra_objs=winnt.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - ;; - i[34567]86-*-pe | i[34567]86-*-cygwin*) - xm_file="${xm_file} i386/xm-cygwin.h" - tmake_file=i386/t-cygwin - tm_file=i386/cygwin.h - xmake_file=i386/x-cygwin - extra_objs=winnt.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - ;; - i[34567]86-*-mingw32*) - tm_file=i386/mingw32.h - xm_file="${xm_file} i386/xm-mingw32.h" - tmake_file="i386/t-cygwin i386/t-mingw32" - extra_objs=winnt.o - xmake_file=i386/x-cygwin - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - case $machine in - *mingw32msv*) - ;; - *minwg32crt* | *mingw32*) - tm_file="${tm_file} i386/crtdll.h" - ;; - esac - ;; - i[34567]86-*-winnt3*) - tm_file=i386/win-nt.h - out_file=i386/i386.c - xm_file="xm-winnt.h ${xm_file}" - xmake_file=winnt/x-winnt - tmake_file=i386/t-winnt - extra_host_objs="winnt.o oldnames.o" - extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if test x$gnu_ld != xyes - then - extra_programs=ld.exe - fi - if test x$enable_threads = xyes; then - thread_file='win32' - fi - ;; - i[34567]86-dg-dgux*) - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - out_file=i386/dgux.c - tm_file=i386/dgux.h - tmake_file=i386/t-dgux - xmake_file=i386/x-dgux - fixincludes=fixinc.dgux - install_headers_dir=install-headers-cpio - ;; - i860-alliant-*) # Alliant FX/2800 - tm_file="${tm_file} svr4.h i860/sysv4.h i860/fx2800.h" - xm_file="${xm_file}" - xmake_file=i860/x-fx2800 - tmake_file=i860/t-fx2800 - extra_parts="crtbegin.o crtend.o" - ;; - i860-*-bsd*) - tm_file="${tm_file} i860/bsd.h" - if test x$gas = xyes - then - tm_file="${tm_file} i860/bsd-gas.h" - fi - use_collect2=yes - ;; - i860-*-mach*) - tm_file="${tm_file} i860/mach.h" - tmake_file=t-libc-ok - ;; - i860-*-osf*) # Intel Paragon XP/S, OSF/1AD - tm_file="${tm_file} svr3.h i860/paragon.h" - xm_defines="USG SVR3" - tmake_file=t-osf - ;; - i860-*-sysv3*) - tm_file="${tm_file} svr3.h i860/sysv3.h" - xm_defines="USG SVR3" - xmake_file=i860/x-sysv3 - extra_parts="crtbegin.o crtend.o" - ;; - i860-*-sysv4*) - tm_file="${tm_file} svr4.h i860/sysv4.h" - xm_defines="USG SVR3" - xmake_file=i860/x-sysv4 - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - ;; - i960-wrs-vxworks5 | i960-wrs-vxworks5.0*) - tm_file="${tm_file} i960/vx960.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-wrs-vxworks5* | i960-wrs-vxworks) - tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/vx960-coff.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-wrs-vxworks*) - tm_file="${tm_file} i960/vx960.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-*-coff*) - tm_file="${tm_file} dbxcoff.h i960/i960-coff.h libgloss.h" - tmake_file=i960/t-960bare - use_collect2=yes - ;; - i960-*-rtems) - tmake_file="i960/t-960bare t-rtems" - tm_file="${tm_file} dbxcoff.h i960/rtems.h" - use_collect2=yes - ;; - i960-*-*) # Default i960 environment. - use_collect2=yes - ;; - m32r-*-elf*) - extra_parts="crtinit.o crtfini.o" - extra_parts="crtinit.o crtfini.o m32rx/crtinit.o m32rx/crtfini.o" - ;; - m68000-convergent-sysv*) - tm_file=m68k/ctix.h - xm_file="m68k/xm-3b1.h ${xm_file}" - xm_defines=USG - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-hp-bsd*) # HP 9000/200 running BSD - tm_file=m68k/hp2bsd.h - xmake_file=m68k/x-hp2bsd - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-hp-hpux*) # HP 9000 series 300 - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp310g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp310.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-sun-sunos3*) - tm_file=m68k/sun2.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-sun-sunos4*) - tm_file=m68k/sun2o4.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-att-sysv*) - xm_file="m68k/xm-3b1.h ${xm_file}" - xm_defines=USG - if test x$gas = xyes - then - tm_file=m68k/3b1g.h - else - tm_file=m68k/3b1.h - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-apple-aux*) # Apple Macintosh running A/UX - xm_defines="USG AUX" - tmake_file=m68k/t-aux - install_headers_dir=install-headers-cpio - extra_headers=math-68881.h - extra_parts="crt1.o mcrt1.o maccrt1.o crt2.o crtn.o" - tm_file= - if test "$gnu_ld" = yes - then - tm_file="${tm_file} m68k/auxgld.h" - else - tm_file="${tm_file} m68k/auxld.h" - fi - if test "$gas" = yes - then - tm_file="${tm_file} m68k/auxgas.h" - else - tm_file="${tm_file} m68k/auxas.h" - fi - tm_file="${tm_file} m68k/a-ux.h" - float_format=m68k - ;; - m68k-apollo-*) - tm_file=m68k/apollo68.h - xmake_file=m68k/x-apollo68 - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-altos-sysv*) # Altos 3068 - if test x$gas = xyes - then - tm_file=m68k/altos3068.h - xm_defines=USG - else - echo "The Altos is supported only with the GNU assembler" 1>&2 - exit 1 - fi - extra_headers=math-68881.h - ;; - m68k-bull-sysv*) # Bull DPX/2 - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=m68k/dpx2cdbx.h - else - tm_file=m68k/dpx2g.h - fi - else - tm_file=m68k/dpx2.h - fi - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - xmake_file=m68k/x-dpx2 - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-atari-sysv4*) # Atari variant of V.4. - tm_file=m68k/atari.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines="USG FULL_PROTOTYPES" - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-motorola-sysv*) - tm_file=m68k/mot3300.h - xm_file="xm-alloca.h m68k/xm-mot3300.h ${xm_file}" - xm_defines=NO_SYS_SIGLIST - if test x$gas = xyes - then - xmake_file=m68k/x-mot3300-gas - if test x$gnu_ld = xyes - then - tmake_file=m68k/t-mot3300-gald - else - tmake_file=m68k/t-mot3300-gas - use_collect2=yes - fi - else - xmake_file=m68k/x-mot3300 - if test x$gnu_ld = xyes - then - tmake_file=m68k/t-mot3300-gld - else - tmake_file=m68k/t-mot3300 - use_collect2=yes - fi - fi - gdb_needs_out_file_path=yes - extra_parts="crt0.o mcrt0.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-ncr-sysv*) # NCR Tower 32 SVR3 - tm_file=m68k/tower-as.h - xm_defines="USG SVR3" - xmake_file=m68k/x-tower - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - ;; - m68k-plexus-sysv*) - tm_file=m68k/plexus.h - xm_file="xm-alloca.h m68k/xm-plexus.h ${xm_file}" - xm_defines=USG - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-tti-*) - tm_file=m68k/pbb.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - extra_headers=math-68881.h - ;; - m68k-crds-unos*) - xm_file="xm-alloca.h m68k/xm-crds.h ${xm_file}" - xm_defines="USG unos" - xmake_file=m68k/x-crds - tm_file=m68k/crds.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-cbm-sysv4*) # Commodore variant of V.4. - tm_file=m68k/amix.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines="USG FULL_PROTOTYPES" - xmake_file=m68k/x-amix - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-ccur-rtu) - tm_file=m68k/ccur-GAS.h - xmake_file=m68k/x-ccur - extra_headers=math-68881.h - use_collect2=yes - float_format=m68k - ;; - m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd - tm_file=m68k/hp3bsd44.h - xmake_file=m68k/x-hp3bsd44 - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix - tm_file=m68k/hp3bsd.h - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-isi-bsd*) - if test x$with_fp = xno - then - tm_file=m68k/isi-nfp.h - else - tm_file=m68k/isi.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7. - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hpux7.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-hp-hpux*) # HP 9000 series 300 - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp320.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sun-mach*) - tm_file=m68k/sun3mach.h - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sony-newsos3*) - if test x$gas = xyes - then - tm_file=m68k/news3gas.h - else - tm_file=m68k/news3.h - fi - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sony-bsd* | m68k-sony-newsos*) - if test x$gas = xyes - then - tm_file=m68k/newsgas.h - else - tm_file=m68k/news.h - fi - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-next-nextstep2*) - tm_file=m68k/next21.h - xm_file="m68k/xm-next.h ${xm_file}" - tmake_file=m68k/t-next - xmake_file=m68k/x-next - extra_objs=nextstep.o - extra_headers=math-68881.h - use_collect2=yes - float_format=m68k - ;; - m68k-next-nextstep3*) - tm_file=m68k/next.h - xm_file="m68k/xm-next.h ${xm_file}" - tmake_file=m68k/t-next - xmake_file=m68k/x-next - extra_objs=nextstep.o - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - if test x$enable_threads = xyes; then - thread_file='mach' - fi - ;; - m68k-sun-sunos3*) - if test x$with_fp = xno - then - tm_file=m68k/sun3n3.h - else - tm_file=m68k/sun3o3.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-sun-sunos*) # For SunOS 4 (the default). - if test x$with_fp = xno - then - tm_file=m68k/sun3n.h - else - tm_file=m68k/sun3.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-wrs-vxworks*) - tm_file=m68k/vxm68k.h - tmake_file=m68k/t-vxworks68 - extra_headers=math-68881.h - thread_file='vxworks' - float_format=m68k - ;; - m68k-*-aout*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-aout.h libgloss.h" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - float_format=m68k - ;; - m68020-*-elf* | m68k-*-elf*) - tm_file="m68k/m68020-elf.h libgloss.h" - xm_file=m68k/xm-m68kv.h - tmake_file=m68k/t-m68kelf - header_files=math-68881.h - ;; - m68k-*-lynxos*) - if test x$gas = xyes - then - tm_file=m68k/lynx.h - else - tm_file=m68k/lynx-ng.h - fi - xm_file=m68k/xm-lynx.h - xmake_file=x-lynx - tmake_file=m68k/t-lynx - extra_headers=math-68881.h - float_format=m68k - ;; - m68k*-*-netbsd*) - tm_file=m68k/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - float_format=m68k - ;; - m68k-*-sysv3*) # Motorola m68k's running system V.3 - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - xmake_file=m68k/x-m68kv - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-sysv4*) # Motorola m68k's running system V.4 - tm_file=m68k/m68kv4.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-linux-gnuaout*) # Motorola m68k's running GNU/Linux - # with a.out format - xmake_file=x-linux - tm_file=m68k/linux-aout.h - tmake_file="t-linux-aout m68k/t-linux-aout" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - ;; - m68k-*-linux-gnulibc1) # Motorola m68k's running GNU/Linux - # with ELF format using the - # GNU/Linux C library 5 - xmake_file=x-linux - tm_file=m68k/linux.h - tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - ;; - m68k-*-linux-gnu*) # Motorola m68k's running GNU/Linux - # with ELF format using glibc 2 - # aka the GNU/Linux C library 6. - xmake_file=x-linux - tm_file=m68k/linux.h - tmake_file="t-linux m68k/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - m68k-*-psos*) - tmake_file=m68k/t-m68kbare - tm_file=m68k/m68k-psos.h - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-rtems*) - tmake_file="m68k/t-m68kbare t-rtems" - tm_file=m68k/rtems.h - extra_headers=math-68881.h - float_format=m68k - ;; - - m88k-dg-dgux*) - case $machine in - m88k-dg-dguxbcs*) - tm_file=m88k/dguxbcs.h - tmake_file=m88k/t-dguxbcs - ;; - *) - tm_file=m88k/dgux.h - tmake_file=m88k/t-dgux - ;; - esac - extra_parts="crtbegin.o bcscrtbegin.o crtend.o m88kdgux.ld" - xmake_file=m88k/x-dgux - if test x$gas = xyes - then - tmake_file=m88k/t-dgux-gas - fi - fixincludes=fixinc.dgux - ;; - m88k-dolphin-sysv3*) - tm_file=m88k/dolph.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-dolph - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-tektronix-sysv3) - tm_file=m88k/tekXD88.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-tekXD88 - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-*-aout*) - tm_file=m88k/m88k-aout.h - ;; - m88k-*-coff*) - tm_file=m88k/m88k-coff.h - tmake_file=m88k/t-bug - ;; - m88k-*-luna*) - tm_file=m88k/luna.h - extra_parts="crtbegin.o crtend.o" - if test x$gas = xyes - then - tmake_file=m88k/t-luna-gas - else - tmake_file=m88k/t-luna - fi - ;; - m88k-*-sysv3*) - tm_file=m88k/sysv3.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-sysv3 - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-*-sysv4*) - tm_file=m88k/sysv4.h - extra_parts="crtbegin.o crtend.o" - xmake_file=m88k/x-sysv4 - tmake_file=m88k/t-sysv4 - ;; - mips-lsi-elf*) # CYGNUS LOCAL angela - tm_file="mips/elf.h" - tmake_file=mips/t-lsi - ;; - mips-sgi-irix6*) # SGI System V.4., IRIX 6 - tm_file=mips/iris6.h - xm_file=mips/xm-iris6.h - fixincludes=fixinc.irix - xmake_file=mips/x-iris6 - tmake_file=mips/t-iris6 -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-wrs-vxworks) - tm_file="mips/elf.h libgloss.h mips/vxworks.h" - tmake_file=mips/t-ecoff - gas=yes - gnu_ld=yes - extra_parts="crtbegin.o crtend.o" -# thread_file='vxworks' - ;; - mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 - tm_file="mips/iris6.h mips/cross64.h" - xm_defines=USG - xm_file="mips/xm-iris5.h" - fixincludes=Makefile.in - xmake_file=mips/x-iris - tmake_file=mips/t-cross64 - # See comment in mips/iris[56].h files. - use_collect2=yes -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sni-sysv4) - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=mips/iris5gdb.h - else - tm_file="mips/sni-svr4.h mips/sni-gas.h" - fi - else - tm_file=mips/sni-svr4.h - fi - xm_defines=USG - xmake_file=mips/x-sni-svr4 - tmake_file=mips/t-mips-gas - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-sgi-irix5*) # SGI System V.4., IRIX 5 - if test x$gas = xyes - then - tm_file="mips/iris5.h mips/iris5gas.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - else - tm_file=mips/iris5.h - fi - xm_defines=USG - xm_file="mips/xm-iris5.h" - fixincludes=fixinc.irix - xmake_file=mips/x-iris - # mips-tfile doesn't work yet - tmake_file=mips/t-mips-gas - # See comment in mips/iris5.h file. - use_collect2=yes -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-irix4loser*) # Mostly like a MIPS. - tm_file="mips/iris4loser.h mips/iris3.h ${tm_file} mips/iris4.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-irix4*) # Mostly like a MIPS. - tm_file="mips/iris3.h ${tm_file} mips/iris4.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-*) # Mostly like a MIPS. - tm_file="mips/iris3.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris3 - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-dec-osfrose*) # Decstation running OSF/1 reference port with OSF/rose. - tm_file="mips/osfrose.h ${tm_file}" - xmake_file=mips/x-osfrose - tmake_file=mips/t-osfrose - extra_objs=halfpic.o - use_collect2=yes - ;; - mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL - tm_file=mips/dec-osf1.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xmake_file=mips/x-dec-osf1 - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-dec-bsd*) # Decstation running 4.4 BSD - tm_file=mips/dec-bsd.h - fixincludes= - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD - tm_file=mips/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - mips*-*-linux*) # Linux MIPS, either endian. - xmake_file=x-linux - xm_file="xm-siglist.h ${xm_file}" - case $machine in - mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;; - *) tm_file="mips/elf.h mips/linux.h" ;; - esac - extra_parts="crtbegin.o crtend.o" - gnu_ld=yes - gas=yes - fixincludes=Makefile.in - ;; - mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. - tm_file="mips/news4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - xmake_file=mips/x-sony - ;; - mips-sony-sysv*) # Sony NEWS 3800 with NEWSOS5.0. - # That is based on svr4. - # t-svr4 is not right because this system doesn't use ELF. - tm_file="mips/news5.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-tandem-sysv4*) # Tandem S2 running NonStop UX - tm_file="mips/svr4-5.h mips/svr4-t.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - extra_parts="crtbegin.o crtend.o" - else - tmake_file=mips/t-mips - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-ultrix* | mips-dec-mach3) # Decstation. - tm_file="mips/ultrix.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xmake_file=mips/x-ultrix - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-riscos[56789]bsd*) - tm_file=mips/bsd-5.h # MIPS BSD 4.3, RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd*) - tm_file="mips/bsd-4.h ${tm_file}" # MIPS BSD 4.3, RISC-OS 4.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-riscos[56789]sysv4*) - tm_file=mips/svr4-5.h # MIPS System V.4., RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4*) - tm_file="mips/svr4-4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-riscos[56789]sysv*) - tm_file=mips/svr3-5.h # MIPS System V.3, RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-sysv* | mips-*-riscos*sysv*) - tm_file="mips/svr3-4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-riscos[56789]*) # Default MIPS RISC-OS 5.0. - tm_file=mips/mips-5.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-gnu*) - ;; - mipsel-*-ecoff*) - tm_file=mips/ecoffl.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mips-*-ecoff*) - tm_file="gofast.h mips/ecoff.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mipsel-*-elf*) - tm_file="mips/elfl.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips-*-elf*) - tm_file="mips/elf.h" - tmake_file=mips/t-elf - ;; - mips64el-*-elf*) - tm_file="mips/elfl64.h" - tmake_file=mips/t-elf - ;; - mips64orionel-*-elf*) - tm_file="mips/elforion.h mips/elfl64.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips64-*-elf*) - tm_file="mips/elf64.h" - tmake_file=mips/t-elf - ;; - mips64orion-*-elf*) - tm_file="mips/elforion.h mips/elf64.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips64orion-*-rtems*) - tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h" - tmake_file="mips/t-ecoff t-rtems" - ;; - mipstx39el-*-elf*) - tm_file="mips/r3900.h mips/elfl.h mips/abi64.h" - tmake_file=mips/t-r3900 - ;; - mipstx39-*-elf*) - tm_file="mips/r3900.h mips/elf.h mips/abi64.h" - tmake_file=mips/t-r3900 - ;; - mips-*-*) # Default MIPS RISC-OS 4.0. - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mn10200-*-*) - cpu_type=mn10200 - tm_file="mn10200/mn10200.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - mn10300-*-*) - cpu_type=mn10300 - tm_file="mn10300/mn10300.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - ns32k-encore-bsd*) - tm_file=ns32k/encore.h - use_collect2=yes - ;; - ns32k-sequent-bsd*) - tm_file=ns32k/sequent.h - use_collect2=yes - ;; - ns32k-tek6100-bsd*) - tm_file=ns32k/tek6100.h - use_collect2=yes - ;; - ns32k-tek6200-bsd*) - tm_file=ns32k/tek6200.h - use_collect2=yes - ;; -# This has not been updated to GCC 2. -# ns32k-ns-genix*) -# xm_defines=USG -# xmake_file=ns32k/x-genix -# tm_file=ns32k/genix.h -# use_collect2=yes -# ;; - ns32k-merlin-*) - tm_file=ns32k/merlin.h - use_collect2=yes - ;; - ns32k-pc532-mach*) - tm_file=ns32k/pc532-mach.h - use_collect2=yes - ;; - ns32k-pc532-minix*) - tm_file=ns32k/pc532-min.h - xm_file="ns32k/xm-pc532-min.h ${xm-file}" - xm_defines=USG - use_collect2=yes - ;; - ns32k-*-netbsd*) - tm_file=ns32k/netbsd.h - xm_file="ns32k/xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - pdp11-*-bsd) - tm_file="${tm_file} pdp11/2bsd.h" - ;; - pdp11-*-*) - ;; - pyramid-*-*) - cpu_type=pyr - xmake_file=pyr/x-pyr - use_collect2=yes - ;; - romp-*-aos*) - use_collect2=yes - ;; - romp-*-mach*) - xmake_file=romp/x-mach - use_collect2=yes - ;; - powerpc-*-beos*) - cpu_type=rs6000 - tm_file=rs6000/beos.h - xm_file=rs6000/xm-beos.h - tmake_file=rs6000/t-beos - xmake_file=rs6000/x-beos - ;; - powerpc-*-sysv* | powerpc-*-elf*) - tm_file=rs6000/sysv4.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - extra_headers=ppc-asm.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - ;; - powerpc-*-eabiaix*) - tm_file=rs6000/eabiaix.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-eabisim*) - tm_file=rs6000/eabisim.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-eabi*) - tm_file=rs6000/eabi.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-rtems*) - tm_file=rs6000/rtems.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-linux-gnulibc1) - tm_file=rs6000/linux.h - xm_file=rs6000/xm-sysv4.h - out_file=rs6000/rs6000.c - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm" - fi - xmake_file=x-linux - fixincludes=Makefile.in - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - extra_headers=ppc-asm.h - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - powerpc-*-linux-gnu*) - tm_file=rs6000/linux.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG ${xm_defines}" - out_file=rs6000/rs6000.c - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm" - fi - xmake_file=x-linux - fixincludes=Makefile.in - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - extra_headers=ppc-asm.h - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - powerpc-wrs-vxworks*) - cpu_type=rs6000 - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - tm_file=rs6000/vxppc.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - extra_headers=ppc-asm.h - thread_file='vxworks' - ;; - powerpcle-*-sysv* | powerpcle-*-elf*) - tm_file=rs6000/sysv4le.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - extra_headers=ppc-asm.h - ;; - powerpcle-*-eabisim*) - tm_file=rs6000/eabilesim.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpcle-*-eabi*) - tm_file=rs6000/eabile.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpcle-*-winnt* ) - tm_file=rs6000/win-nt.h - tmake_file=rs6000/t-winnt -# extra_objs=pe.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - extra_headers=ppc-asm.h - ;; - powerpcle-*-pe | powerpcle-*-cygwin*) - tm_file=rs6000/cygwin.h - xm_file="rs6000/xm-cygwin.h ${xm_file}" - tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin -# extra_objs=pe.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - extra_headers=ppc-asm.h - ;; - powerpcle-*-solaris2*) - tm_file=rs6000/sol2.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - case $machine in - *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - extra_headers=ppc-asm.h - ;; - rs6000-ibm-aix3.[01]*) - tm_file=rs6000/aix31.h - xmake_file=rs6000/x-aix31 - use_collect2=yes - ;; - rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*) - tm_file=rs6000/aix3newas.h - if test x$host != x$target - then - tmake_file=rs6000/t-xnewas - else - tmake_file=rs6000/t-newas - fi - use_collect2=yes - ;; - rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*) - tm_file=rs6000/aix41.h - if test x$host != x$target - then - tmake_file=rs6000/t-xnewas - else - tmake_file=rs6000/t-newas - fi - xmake_file=rs6000/x-aix41 - use_collect2=yes - ;; - rs6000-ibm-aix4.[3456789].* | powerpc-ibm-aix4.[3456789].*) - tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 - use_collect2=yes - ;; - rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) - tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 - use_collect2=yes - ;; - rs6000-ibm-aix*) - use_collect2=yes - ;; - rs6000-bull-bosx) - use_collect2=yes - ;; - rs6000-*-mach*) - tm_file=rs6000/mach.h - xm_file="${xm_file} rs6000/xm-mach.h" - xmake_file=rs6000/x-mach - use_collect2=yes - ;; - rs6000-*-lynxos*) - tm_file=rs6000/lynx.h - xm_file=rs6000/xm-lynx.h - tmake_file=rs6000/t-rs6000 - xmake_file=rs6000/x-lynx - use_collect2=yes - ;; - sh-*-elf*) - tm_file=sh/elf.h - float_format=sh - ;; - sh-*-rtemself*) - tmake_file="sh/t-sh t-rtems" - tm_file=sh/rtemself.h - float_format=sh - ;; - sh-*-rtems*) - tmake_file="sh/t-sh t-rtems" - tm_file=sh/rtems.h - float_format=sh - ;; - sh-*-*) - float_format=sh - ;; - sparc-tti-*) - tm_file=sparc/pbd.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - ;; - sparc-wrs-vxworks* | sparclite-wrs-vxworks*) - tm_file=sparc/vxsparc.h - tmake_file=sparc/t-vxsparc - use_collect2=yes - thread_file='vxworks' - ;; - sparc-*-aout*) - tmake_file=sparc/t-sparcbare - tm_file="sparc/aout.h libgloss.h" - ;; - sparc-*-netbsd*) - tm_file=sparc/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - sparc-*-bsd*) - tm_file=sparc/bsd.h - ;; - sparc-*-elf*) - tm_file=sparc/elf.h - tmake_file=sparc/t-elf - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - #float_format=i128 - float_format=i64 - ;; - sparc-*-linux-gnuaout*) # Sparc's running GNU/Linux, a.out - xm_file="${xm_file} sparc/xm-linux.h" - tm_file=sparc/linux-aout.h - xmake_file=x-linux - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - ;; - sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5 - xm_file="${xm_file} sparc/xm-linux.h" - xmake_file=x-linux - tm_file=sparc/linux.h - tmake_file="t-linux t-linux-gnulibc1" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - ;; - sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6 - xm_file="${xm_file} sparc/xm-linux.h" - xmake_file=x-linux - tm_file=sparc/linux.h - tmake_file="t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - sparc-*-lynxos*) - if test x$gas = xyes - then - tm_file=sparc/lynx.h - else - tm_file=sparc/lynx-ng.h - fi - xm_file=sparc/xm-lynx.h - tmake_file=sparc/t-sunos41 - xmake_file=x-lynx - ;; - sparc-*-rtems*) - tmake_file="sparc/t-sparcbare t-rtems" - tm_file=sparc/rtems.h - ;; - sparcv9-*-solaris2*) - tm_file=sparc/sol2-sld-64.h - xm_file="sparc/xm-sysv4-64.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tmake_file="sparc/t-sol2 sparc/t-sol2-64" - xmake_file=sparc/x-sysv4 - extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o" - fixincludes=fixinc.wrap - float_format=none - if test x${enable_threads} = x ; then - enable_threads=$have_pthread_h - if test x${enable_threads} = x ; then - enable_threads=$have_thread_h - fi - fi - if test x${enable_threads} = xyes ; then - if test x${have_pthread_h} = xyes ; then - thread_file='posix' - else - thread_file='solaris' - fi - fi - ;; - sparc-*-solaris2*) - if test x$gnu_ld = xyes - then - tm_file=sparc/sol2.h - else - tm_file=sparc/sol2-sld.h - fi - xm_file="xm-siglist.h sparc/xm-sysv4.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tmake_file=sparc/t-sol2 - xmake_file=sparc/x-sysv4 - extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" - case $machine in - *-*-solaris2.[0-4]) - fixincludes=fixinc.svr4 - float_format=i128 - ;; - *) - fixincludes=fixinc.wrap - float_format=none - ;; - esac - if test x${enable_threads} = x; then - enable_threads=$have_pthread_h - if test x${enable_threads} = x; then - enable_threads=$have_thread_h - fi - fi - if test x${enable_threads} = xyes; then - if test x${have_pthread_h} = xyes; then - thread_file='posix' - else - thread_file='solaris' - fi - fi - ;; - sparc-*-sunos4.0*) - tm_file=sparc/sunos4.h - tmake_file=sparc/t-sunos40 - use_collect2=yes - ;; - sparc-*-sunos4*) - tm_file=sparc/sunos4.h - tmake_file=sparc/t-sunos41 - use_collect2=yes - if test x$gas = xyes; then - tm_file="${tm_file} sparc/sun4gas.h" - fi - ;; - sparc-*-sunos3*) - tm_file=sparc/sun4o3.h - use_collect2=yes - ;; - sparc-*-sysv4*) - tm_file=sparc/sysv4.h - xm_file="xm-siglist.h sparc/xm-sysv4.h" - xm_defines="USG POSIX" - tmake_file=t-svr4 - xmake_file=sparc/x-sysv4 - extra_parts="crtbegin.o crtend.o" - ;; - sparc-*-vxsim*) - xm_file="xm-siglist.h sparc/xm-sysv4.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tm_file=sparc/vxsim.h - tmake_file=sparc/t-vxsparc - xmake_file=sparc/x-sysv4 - ;; - sparclet-*-aout*) - tm_file="sparc/splet.h libgloss.h" - tmake_file=sparc/t-splet - ;; - sparclite-*-coff*) - tm_file="sparc/litecoff.h libgloss.h" - tmake_file=sparc/t-sparclite - ;; - sparclite-*-aout*) - tm_file="sparc/lite.h aoutos.h" - tmake_file=sparc/t-sparclite - use_collect2=yes - ;; - sparclite-*-elf*) - tm_file="sparc/liteelf.h" - tmake_file=sparc/t-sparclite - extra_parts="crtbegin.o crtend.o" - ;; - sparc86x-*-aout*) - tm_file="sparc/sp86x-aout.h aoutos.h libgloss.h" - tmake_file=sparc/t-sp86x - use_collect2=yes - ;; - sparc86x-*-elf*) - tm_file="sparc/sp86x-elf.h libgloss.h" - tmake_file=sparc/t-sp86x - extra_parts="crtbegin.o crtend.o" - ;; - sparc64-*-aout*) - tmake_file=sparc/t-sp64 - tm_file=sparc/sp64-aout.h - ;; - sparc64-*-elf*) - tmake_file=sparc/t-sp64 - tm_file=sparc/sp64-elf.h - extra_parts="crtbegin.o crtend.o" - ;; - sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux - tmake_file="t-linux sparc/t-linux64" - xm_file="sparc/xm-sp64.h sparc/xm-linux.h" - tm_file=sparc/linux64.h - xmake_file=x-linux - fixincludes=Makefile.in # The headers are ok already. - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - gnu_ld=yes - ;; -# This hasn't been upgraded to GCC 2. -# tahoe-harris-*) # Harris tahoe, using COFF. -# tm_file=tahoe/harris.h -# ;; -# tahoe-*-bsd*) # tahoe running BSD -# ;; - thumb-*-coff* | thumbel-*-coff*) - tm_file=arm/tcoff.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-thumb - ;; - # CYGNUS LOCAL clm/arm-elf - thumb-*-elf* | thumbel-*-elf*) + thumb-*-elf*) tm_file=arm/telf.h out_file=arm/thumb.c xm_file=arm/xm-thumb.h @@ -5474,277 +2905,6 @@ for machine in $build $host $target; do tmake_file=arm/t-thumb-elf fixincludes=Makefile.in # There is nothing to fix ;; - thumb*-*-oabi*) - tm_file=arm/telf-oabi.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-thumb-elf - fixincludes=Makefile.in # There is nothing to fix - ;; - # END CYGNUS LOCAL -# This hasn't been upgraded to GCC 2. -# tron-*-*) -# cpu_type=gmicro -# use_collect2=yes -# ;; - v850-*-*) - cpu_type=v850 - tm_file="v850/v850.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - # CYGNUS LOCAL v850e/nick - v850e-*-*) - cpu_type=v850 - tm_file="v850/v850e.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if [ x$stabs = xyes ] - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - v850ea-*-*) - cpu_type=v850 - tm_file="v850/v850ea.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if [ x$stabs = xyes ] - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - # end CYGNUS LOCAL - vax-*-bsd*) # vaxen running BSD - use_collect2=yes - float_format=vax - ;; - vax-*-sysv*) # vaxen running system V - tm_file="${tm_file} vax/vaxv.h" - xm_defines=USG - float_format=vax - ;; - vax-*-netbsd*) - tm_file="${tm_file} netbsd.h vax/netbsd.h" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - float_format=vax - ;; - vax-*-ultrix*) # vaxen running ultrix - tm_file="${tm_file} vax/ultrix.h" - use_collect2=yes - float_format=vax - ;; - vax-*-vms*) # vaxen running VMS - xm_file=vax/xm-vms.h - tm_file=vax/vms.h - float_format=vax - ;; - vax-*-*) # vax default entry - float_format=vax - ;; - we32k-att-sysv*) - xm_file="${xm_file} xm-svr3" - use_collect2=yes - ;; - # CYGNUS LOCAL ports - arm-*-pe*) - tm_file=arm/pe.h - tmake_file=arm/t-pe - extra_objs=pe.o - ;; - d10v-*-*) - float_format=d10v - ;; - d30v-*-*) - float_format=i64 - ;; - fr30-*-elf) - tm_file="fr30/fr30.h" - tmake_file=fr30/t-fr30 - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - ;; - i[34567]86-*-elf*) - xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h" - tm_file=i386/i386elf.h - tmake_file=i386/t-i386elf - xmake_file=x-svr4 - ;; - i[34567]86-*-netware) # Intel 80386's running netware - # CYGNUS LOCAL - tm_file=i386/netware.h - tmake_file=i386/t-netware - fixincludes=Makefile.in - ;; - i[34567]86-*-unixware) - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - tm_file=i386/sysv4.h - if [ x$stabs = xyes ] - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - ;; - i960-intel-nindy) - tmake_file=i960/t-vxworks960 - use_collect2=yes - ;; - m68000-ncr-sysv*) - tm_file=m68k/tower-as.h - xm_file=m68k/xm-tower.h - xmake_file=m68k/x-tower - tmake_file=m68k/t-svr3 - extra_headers=math-68881.h - ;; - m68k-ericsson-OSE |\ - m68k-ericsson-ose) - tm_file=m68k/ose68k.h - tmake_file=m68k/t-ose68 - extra_headers=math-68881.h - ;; - m680[01234]0-wrs-vxworks*) - tm_file=m68k/vxm68k.h - tmake_file=m68k/t-vxworks68 - extra_headers=math-68881.h - ;; - m680[0234]0-*-aout* |\ - m683[03]2-*-aout*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-aout.h libgloss.h" - extra_headers=math-68881.h - ;; - m680[0234]0-*-coff* |\ - m683[03]2-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - ;; - m68360-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68360-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - ;; - m68000-*-os68k*) - tm_file=m68k/os68000.h - extra_headers=math-68881.h - ;; - m68k-*-os68k*) - tm_file=m68k/os68000.h - extra_headers=math-68881.h - ;; - # This is a host port only, and won't work as a target. - mips*-nec-sysv4*) # MIPS NEC SVR4 - tm_file=mips/svr4-t.h - if [ x$stabs = xyes ]; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - if [ x$gas = xyes ] - then - tmake_file=mips/t-mips-gas - extra_parts="crtbegin.o crtend.o" - else - tmake_file=mips/t-mips - extra_passes="mips-tfile mips-tdump" - fi - if [ x$gnu_ld != xyes ] - then - use_collect2=yes - fi - ;; - mips*-*-lnews*) - tm_file=mips/ecoffl.h - if [ x$stabs = xyes ]; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mips64vr4300-*-elf*) - tm_file="mips/elfb4300.h" - tmake_file=mips/t-vr4300 - ;; - mips64vr4300el-*-elf*) - tm_file="mips/elfl4300.h libgloss.h" - tmake_file=mips/t-vr4300 - ;; - mips64vr4100-*-elf*) - tm_file="mips/elfb4100.h mips/abi64.h" - tmake_file=mips/t-vr4100 - ;; - mips64vr4100el-*-elf*) - tm_file="mips/elfl4100.h mips/abi64.h libgloss.h" - tmake_file=mips/t-vr4100 - ;; - mips64vr5000-*-elf*) - tm_file="mips/elfb5000.h" - tmake_file=mips/t-vr5000 - # Use haifa by default. - if [ x$enable_haifa != xno ]; then - enable_haifa=yes - fi - ;; - mips64vr5000el-*-elf*) - tm_file="mips/elfl5000.h libgloss.h" - tmake_file=mips/t-vr5000 - # Use haifa by default. - if [ x$enable_haifa != xno ]; then - enable_haifa=yes - fi - ;; - sparclite-*-elf*) - tm_file="sparc/liteelf.h libgloss.h" - tmake_file=sparc/t-sparclite - extra_parts="crtbegin.o crtend.o" - ;; - thumb-*-pe) - tm_file=arm/tpe.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-pe-thumb - extra_objs=pe.o - ;; - z8k-*-*) - ;; - # END CYGNUS LOCAL - - # CYGNUS LOCAL raeburn/vr5400 - mips64vr5400-*-elf*) - tm_file="mips/big.h mips/elf5400.h libgloss.h" - tmake_file=mips/t-biendian - # Use haifa by default for the r5400 - if [ x$enable_haifa != xno ]; then - enable_haifa=yes - fi - ;; - mips64vr5400el-*-elf*) - tm_file="mips/little.h mips/elf5400.h libgloss.h" - tmake_file=mips/t-biendian - # Use haifa by default for the r5400 - if [ x$enable_haifa != xno ]; then - enable_haifa=yes - fi - ;; - # END CYGNUS LOCAL raeburn/vr5400 - -# This hasn't been upgraded to GCC 2. - *) - echo "Configuration $machine not supported" 1>&2 - exit 1 - ;; esac case $machine in @@ -5756,7 +2916,6 @@ for machine in $build $host $target; do # supports are matched above and just set $cpu_type. xm_file="xm-gnu.h ${xm_file}" tm_file=${cpu_type}/gnu.h - extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o" # GNU always uses ELF. elf=yes # GNU tools are the only tools. @@ -5927,15 +3086,6 @@ for machine in $build $host $target; do fi fi - # No need for collect2 if we have the GNU linker. - # Actually, there is now; GNU ld doesn't handle the EH info or - # collecting for shared libraries. - #case x$gnu_ld in - #xyes) - # use_collect2= - # ;; - #esac - # Save data on machine being used to compile GCC in build_xm_file. # Save data on host machine in vars host_xm_file and host_xmake_file. if test x$pass1done = x @@ -6269,22 +3419,6 @@ else done fi -if test x$use_collect2 = xno; then - use_collect2= -fi - -# Add a definition of USE_COLLECT2 if system wants one. -# Also tell toplev.c what to do. -# This substitutes for lots of t-* files. -if test x$use_collect2 = x -then - will_use_collect2= - maybe_use_collect2= -else - will_use_collect2="collect2" - maybe_use_collect2="-DUSE_COLLECT2" -fi - # NEED TO CONVERT # Set MD_DEPS if the real md file is in md.pre-cpp. # Set MD_CPP to the cpp to pass the md file through. Md files use ';' @@ -6311,11 +3445,7 @@ fi # If we have ld in the build tree, make a link to it. if test -f ../ld/Makefile; then -# if test x$use_collect2 = x; then -# rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null -# else - rm -f collect-ld; $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext 2>/dev/null -# fi + rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null fi # Figure out what assembler alignment features are present. @@ -7058,8 +4188,6 @@ s%@build_install_headers_dir@%$build_install_headers_dir%g s%@build_exeext@%$build_exeext%g s%@host_exeext@%$host_exeext%g s%@float_h_file@%$float_h_file%g -s%@will_use_collect2@%$will_use_collect2%g -s%@maybe_use_collect2@%$maybe_use_collect2%g s%@cc_set_by_configure@%$cc_set_by_configure%g s%@stage_prefix_set_by_configure@%$stage_prefix_set_by_configure%g s%@install@%$install%g diff --git a/gcc/configure.in b/gcc/configure.in index ce1367e..5d801fa 100755 --- a/gcc/configure.in +++ b/gcc/configure.in @@ -444,8 +444,6 @@ for machine in $build $host $target; do extra_gcc_objs= xm_defines= float_format= - # Set this to force installation and use of collect2. - use_collect2= # Set this to override the default target model. target_cpu_default= # Set this to control which fixincludes program to use. @@ -522,2706 +520,12 @@ changequote([,])dnl case $machine in # Support site-specific machine types. - *local*) - cpu_type=`echo $machine | sed -e 's/-.*//'` - rest=`echo $machine | sed -e "s/$cpu_type-//"` - xm_file=${cpu_type}/xm-$rest.h - tm_file=${cpu_type}/$rest.h - if test -f $srcdir/config/${cpu_type}/x-$rest; \ - then xmake_file=${cpu_type}/x-$rest; \ - else true; \ - fi - if test -f $srcdir/config/${cpu_type}/t-$rest; \ - then tmake_file=${cpu_type}/t-$rest; \ - else true; \ - fi - ;; - 1750a-*-*) - ;; - a29k-*-bsd* | a29k-*-sym1*) - tm_file="${tm_file} a29k/unix.h" - xm_defines=USG - xmake_file=a29k/x-unix - use_collect2=yes - ;; - a29k-*-udi | a29k-*-coff) - tm_file="${tm_file} dbxcoff.h a29k/udi.h" - tmake_file=a29k/t-a29kbare - ;; - a29k-wrs-vxworks*) - tm_file="${tm_file} dbxcoff.h a29k/udi.h a29k/vx29k.h" - tmake_file=a29k/t-vx29k - extra_parts="crtbegin.o crtend.o" - thread_file='vxworks' - ;; - a29k-*-*) # Default a29k environment. - use_collect2=yes - ;; - alpha*-*-linux-gnuecoff*) - tm_file="${tm_file} alpha/linux-ecoff.h alpha/linux.h" - target_cpu_default="MASK_GAS" - gas=no - xmake_file=none - gas=yes gnu_ld=yes - ;; - alpha*-*-linux-gnulibc1*) - tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="t-linux t-linux-gnulibc1 alpha/t-linux alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.wrap - xmake_file=none - gas=yes gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - alpha*-*-linux-gnu*) - tm_file="${tm_file} alpha/elf.h alpha/linux.h alpha/linux-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="t-linux alpha/t-linux alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - xmake_file=none - fixincludes=Makefile.in - gas=yes gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - alpha*-*-netbsd*) - tm_file="${tm_file} alpha/elf.h alpha/netbsd.h alpha/netbsd-elf.h" - target_cpu_default="MASK_GAS" - tmake_file="alpha/t-crtbe" - extra_parts="crtbegin.o crtend.o" - xmake_file=none - fixincludes=fixinc.wrap - gas=yes gnu_ld=yes - ;; - - alpha*-dec-osf*) - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - if test x$gas != xyes - then - extra_passes="mips-tfile mips-tdump" - fi - use_collect2=yes - case $machine in - *-*-osf1*) - tm_file="${tm_file} alpha/osf.h alpha/osf12.h alpha/osf2or3.h" - ;; -changequote(,)dnl - *-*-osf[23]*) -changequote([,])dnl - tm_file="${tm_file} alpha/osf.h alpha/osf2or3.h" - ;; - *-*-osf4*) - tm_file="${tm_file} alpha/osf.h" - # Some versions of OSF4 (specifically X4.0-9 296.7) have - # a broken tar, so we use cpio instead. - install_headers_dir=install-headers-cpio - ;; - esac - case $machine in -changequote(,)dnl - *-*-osf4.0[b-z] | *-*-osf4.[1-9]*) -changequote([,])dnl - target_cpu_default=MASK_SUPPORT_ARCH - ;; - esac - ;; - alpha*-*-vxworks*) - tm_file="${tm_file} dbx.h alpha/vxworks.h" - if [ x$gas != xyes ] - then - extra_passes="mips-tfile mips-tdump" - fi - use_collect2=yes - ;; - alpha*-*-winnt*) - tm_file="${tm_file} alpha/win-nt.h" - xm_file="${xm_file} config/winnt/xm-winnt.h alpha/xm-winnt.h" - tmake_file=t-libc-ok - xmake_file=winnt/x-winnt - extra_host_objs=oldnames.o - extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if test x$gnu_ld != xyes - then - extra_programs=ld.exe - fi - if test x$enable_threads = xyes; then - thread_file='win32' - fi - ;; - alpha*-dec-vms*) - tm_file=alpha/vms.h - xm_file="${xm_file} alpha/xm-vms.h" - tmake_file=alpha/t-vms - fixincludes=Makefile.in - ;; - arc-*-elf*) - extra_parts="crtinit.o crtfini.o" - ;; - arm-*-coff* | armel-*-coff*) - tm_file=arm/coff.h - tmake_file=arm/t-bare - ;; -changequote(,)dnl - arm-*-riscix1.[01]*) # Acorn RISC machine (early versions) -changequote([,])dnl - tm_file=arm/riscix1-1.h - use_collect2=yes - ;; - arm-*-riscix*) # Acorn RISC machine - if test x$gas = xyes - then - tm_file=arm/rix-gas.h - else - tm_file=arm/riscix.h - fi - xmake_file=arm/x-riscix - tmake_file=arm/t-riscix - use_collect2=yes - ;; - arm-semi-aout | armel-semi-aout) - tm_file=arm/semi.h - tmake_file=arm/t-semi - fixincludes=Makefile.in # There is nothing to fix - ;; - arm-semi-aof | armel-semi-aof) - tm_file=arm/semiaof.h - tmake_file=arm/t-semiaof - fixincludes=Makefile.in # There is nothing to fix - ;; - arm*-*-netbsd*) - tm_file=arm/netbsd.h - xm_file="arm/xm-netbsd.h ${xm_file}" - tmake_file="t-netbsd arm/t-netbsd" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - ;; - arm*-*-linux-gnuaout*) # ARM GNU/Linux with a.out - cpu_type=arm - xmake_file=x-linux - tm_file=arm/linux-aout.h - tmake_file=arm/t-linux - fixincludes=Makefile.in - gnu_ld=yes - ;; - arm*-*-linux-gnu*) # ARM GNU/Linux with ELF - xm_file=arm/xm-linux.h - xmake_file=x-linux - case $machine in - armv2*-*-*) - tm_file=arm/linux-elf26.h - ;; - *) - tm_file=arm/linux-elf.h - ;; - esac - tmake_file="t-linux arm/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # Nothing to fix - gnu_ld=yes - ;; - arm*-*-aout) - tm_file=arm/aout.h - tmake_file=arm/t-bare - ;; - arm*-*-ecos-elf) - tm_file=arm/ecos-elf.h - tmake_file=arm/t-elf - ;; arm*-*-elf) tm_file=arm/unknown-elf.h tmake_file=arm/t-arm-elf ;; - arm*-*-oabi) - tm_file=arm/unknown-elf-oabi.h - tmake_file=arm/t-arm-elf - ;; - c1-convex-*) # Convex C1 - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - c2-convex-*) # Convex C2 - target_cpu_default=2 - use_collect2=yes - fixincludes=Makefile.in - ;; - c32-convex-*) - target_cpu_default=4 - use_collect2=yes - fixincludes=Makefile.in - ;; - c34-convex-*) - target_cpu_default=8 - use_collect2=yes - fixincludes=Makefile.in - ;; - c38-convex-*) - target_cpu_default=16 - use_collect2=yes - fixincludes=Makefile.in - ;; - c4x-*) - cpu_type=c4x - tmake_file=c4x/t-c4x - ;; - clipper-intergraph-clix*) - tm_file="${tm_file} svr3.h clipper/clix.h" - xm_file=clipper/xm-clix.h - xmake_file=clipper/x-clix - extra_headers=va-clipper.h - extra_parts="crtbegin.o crtend.o" - install_headers_dir=install-headers-cpio - ;; - dsp16xx-*) - ;; - elxsi-elxsi-*) - use_collect2=yes - ;; -# This hasn't been upgraded to GCC 2. -# fx80-alliant-*) # Alliant FX/80 -# ;; - h8300-*-*) - float_format=i32 - ;; - hppa1.1-*-pro*) - tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h" - xm_file=pa/xm-papro.h - tmake_file=pa/t-pro - ;; - hppa1.1-*-osf*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-osf.h" - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.1-*-rtems*) - tm_file="pa/pa-pro.h ${tm_file} pa/pa-pro-end.h libgloss.h pa/rtems.h" - xm_file=pa/xm-papro.h - tmake_file=pa/t-pro - ;; - hppa1.0-*-osf*) - tm_file="${tm_file} pa/pa-osf.h" - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.1-*-bsd*) - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.0-*-bsd*) - use_collect2=yes - fixincludes=Makefile.in - ;; - hppa1.0-*-hpux7*) - tm_file="pa/pa-oldas.h ${tm_file} pa/pa-hpux7.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; -changequote(,)dnl - hppa1.0-*-hpux8.0[0-2]*) -changequote([,])dnl - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - else - tm_file="pa/pa-oldas.h ${tm_file}" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; -changequote(,)dnl - hppa1.1-*-hpux8.0[0-2]*) -changequote([,])dnl - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - else - tm_file="pa/pa-oldas.h ${tm_file}" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux8*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux8*) - tm_file="${tm_file} pa/pa-hpux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hpux10* | hppa2*-*-hpux10*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=pa/t-pa - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - if test x$enable_threads = x; then - enable_threads=$have_pthread_h - fi - if test x$enable_threads = xyes; then - thread_file='dce' - tmake_file="${tmake_file} pa/t-dce-thr" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux10*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux10.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - if test x$enable_threads = x; then - enable_threads=$have_pthread_h - fi - if test x$enable_threads = xyes; then - thread_file='dce' - tmake_file="${tmake_file} pa/t-dce-thr" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - # CYGNUS LOCAL hpux11 - hppa1.1-*-hpux11* | hppa2*-*-hpux11*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux11.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - tmake_file=pa/t-pa - if [[ x$gas = xyes ]] - then - tm_file="${tm_file} pa/pa-gas.h" - fi -# if [[ x$enable_threads = x ]]; then -# enable_threads=$have_pthread_h -# fi -# if [[ x$enable_threads = xyes ]]; then -# thread_file='dce' -# tmake_file="${tmake_file} pa/t-dce-thr" -# fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux11*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux11.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if [[ x$gas = xyes ]] - then - tm_file="${tm_file} pa/pa-gas.h" - fi -# if [[ x$enable_threads = x ]]; then -# enable_threads=$have_pthread_h -# fi -# if [[ x$enable_threads = xyes ]]; then -# thread_file='dce' -# tmake_file="${tmake_file} pa/t-dce-thr" -# fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - # END CYGNUS LOCAL - hppa1.1-*-hpux* | hppa2*-*-hpux*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hpux*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hpux9.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.1-*-hiux* | hppa2*-*-hiux*) - target_cpu_default=1 - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa1.0-*-hiux*) - tm_file="${tm_file} pa/pa-hpux.h pa/pa-hiux.h" - xm_file=pa/xm-pahpux.h - xmake_file=pa/x-pa-hpux - if test x$gas = xyes - then - tm_file="${tm_file} pa/pa-gas.h" - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - ;; - hppa*-*-lites*) - target_cpu_default=1 - use_collect2=yes - fixincludes=Makefile.in - ;; - i370-*-mvs*) - ;; -changequote(,)dnl - i[34567]86-ibm-aix*) # IBM PS/2 running AIX -changequote([,])dnl - if test x$gas = xyes - then - tm_file=i386/aix386.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - else - tm_file=i386/aix386ng.h - use_collect2=yes - fi - xm_file="xm-alloca.h i386/xm-aix.h ${xm_file}" - xm_defines=USG - xmake_file=i386/x-aix - ;; -changequote(,)dnl - i[34567]86-ncr-sysv4*) # NCR 3000 - ix86 running system V.4 -changequote([,])dnl - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - xmake_file=i386/x-ncr3000 - if test x$stabs = xyes -a x$gas = xyes - then - tm_file=i386/sysv4gdb.h - else - tm_file=i386/sysv4.h - fi - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtpic - ;; -changequote(,)dnl - i[34567]86-next-*) -changequote([,])dnl - tm_file=i386/next.h - xm_file=i386/xm-next.h - tmake_file=i386/t-next - xmake_file=i386/x-next - extra_objs=nextstep.o - extra_parts="crtbegin.o crtend.o" - if test x$enable_threads = xyes; then - thread_file='mach' - fi - ;; -changequote(,)dnl - i[34567]86-sequent-bsd*) # 80386 from Sequent -changequote([,])dnl - use_collect2=yes - if test x$gas = xyes - then - tm_file=i386/seq-gas.h - else - tm_file=i386/sequent.h - fi - ;; -changequote(,)dnl - i[34567]86-sequent-ptx1*) -changequote([,])dnl - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - tm_file=i386/seq-sysv3.h - tmake_file=i386/t-crtstuff - fixincludes=fixinc.ptx - extra_parts="crtbegin.o crtend.o" - install_headers_dir=install-headers-cpio - ;; -changequote(,)dnl - i[34567]86-sequent-ptx2* | i[34567]86-sequent-sysv3*) -changequote([,])dnl - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - tm_file=i386/seq2-sysv3.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx - install_headers_dir=install-headers-cpio - ;; -changequote(,)dnl - i[34567]86-sequent-ptx4* | i[34567]86-sequent-sysv4*) -changequote([,])dnl - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - xmake_file=x-svr4 - tm_file=i386/ptx4-i.h - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.ptx - install_headers_dir=install-headers-cpio - ;; - i386-sun-sunos*) # Sun i386 roadrunner - xm_defines=USG - tm_file=i386/sun.h - use_collect2=yes - ;; -changequote(,)dnl - i[34567]86-wrs-vxworks*) -changequote([,])dnl - tm_file=i386/vxi386.h - tmake_file=i386/t-i386bare - ;; -changequote(,)dnl - i[34567]86-*-aout*) -changequote([,])dnl - tm_file=i386/i386-aout.h - tmake_file=i386/t-i386bare - ;; -changequote(,)dnl - i[34567]86-*-bsdi* | i[34567]86-*-bsd386*) -changequote([,])dnl - tm_file=i386/bsd386.h -# tmake_file=t-libc-ok - ;; -changequote(,)dnl - i[34567]86-*-bsd*) -changequote([,])dnl - tm_file=i386/386bsd.h -# tmake_file=t-libc-ok -# Next line turned off because both 386BSD and BSD/386 use GNU ld. -# use_collect2=yes - ;; -changequote(,)dnl - i[34567]86-*-freebsdelf*) -changequote([,])dnl - tm_file="i386/i386.h i386/att.h linux.h i386/freebsd-elf.h i386/perform.h" - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - tmake_file=i386/t-freebsd - gas=yes - gnu_ld=yes - stabs=yes - ;; -changequote(,)dnl - i[34567]86-*-freebsd*) -changequote([,])dnl - tm_file=i386/freebsd.h - # On FreeBSD, the headers are already ok, except for math.h. - fixincludes=fixinc.wrap - tmake_file=i386/t-freebsd - ;; - # We are hoping OpenBSD is still close enough to NetBSD that we can - # share the configurations. -changequote(,)dnl - i[34567]86-*-netbsd* | i[34567]86-*-openbsd*) -changequote([,])dnl - tm_file=i386/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; -changequote(,)dnl - i[34567]86-*-coff*) -changequote([,])dnl - tm_file=i386/i386-coff.h - tmake_file=i386/t-i386bare - ;; -changequote(,)dnl - i[34567]86-*-isc*) # 80386 running ISC system -changequote([,])dnl - xm_file="${xm_file} i386/xm-isc.h" - xm_defines="USG SVR3" - case $machine in -changequote(,)dnl - i[34567]86-*-isc[34]*) -changequote([,])dnl - xmake_file=i386/x-isc3 - ;; - *) - xmake_file=i386/x-isc - ;; - esac - if test x$gas = xyes -a x$stabs = xyes - then - tm_file=i386/iscdbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.ifile" - else - tm_file=i386/isccoff.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fi - install_headers_dir=install-headers-cpio - ;; -changequote(,)dnl - i[34567]86-*-linux-gnuoldld*) # Intel 80386's running GNU/Linux -changequote([,])dnl # with a.out format using - # pre BFD linkers - xmake_file=x-linux-aout - tmake_file="t-linux-aout i386/t-crtstuff" - tm_file=i386/linux-oldld.h - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - ;; -changequote(,)dnl - i[34567]86-*-linux-gnuaout*) # Intel 80386's running GNU/Linux -changequote([,])dnl # with a.out format - xmake_file=x-linux-aout - tmake_file="t-linux-aout i386/t-crtstuff" - tm_file=i386/linux-aout.h - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - ;; -changequote(,)dnl - i[34567]86-*-linux-gnulibc1) # Intel 80386's running GNU/Linux -changequote([,])dnl # with ELF format using the - # GNU/Linux C library 5 - xmake_file=x-linux - tm_file=i386/linux.h - tmake_file="t-linux t-linux-gnulibc1 i386/t-crtstuff" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - if test x$enable_threads = xyes; then - thread_file='single' - fi - ;; -changequote(,)dnl - i[34567]86-*-linux-gnu*) # Intel 80386's running GNU/Linux -changequote([,])dnl # with ELF format using glibc 2 - # aka GNU/Linux C library 6 - xmake_file=x-linux - tm_file=i386/linux.h - tmake_file="t-linux i386/t-crtstuff" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=fixinc.x86-linux-gnu - gnu_ld=yes - float_format=i386 - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; -changequote(,)dnl - i[34567]86-*-gnu*) -changequote([,])dnl - ;; -changequote(,)dnl - i[34567]86-go32-msdos | i[34567]86-*-go32*) -changequote([,])dnl - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - xmake_file=i386/x-go32 # CYGNUS LOCAL - tmake_file=i386/t-go32 - ;; -changequote(,)dnl - i[34567]86-pc-msdosdjgpp*) -changequote([,])dnl - xm_file=i386/xm-go32.h - tm_file=i386/go32.h - tmake_file=i386/t-go32 - xmake_file=i386/x-go32 - gnu_ld=yes - gas=yes - exeext=.exe - case $host in - *pc-msdosdjgpp*) - target_alias=djgpp - ;; - esac - ;; -changequote(,)dnl - i[34567]86-moss-msdos* | i[34567]86-*-moss*) -changequote([,])dnl - tm_file=i386/moss.h - tmake_file=t-libc-ok - fixincludes=Makefile.in - gnu_ld=yes - gas=yes - ;; -changequote(,)dnl - i[34567]86-*-lynxos*) -changequote([,])dnl - if test x$gas = xyes - then - tm_file=i386/lynx.h - else - tm_file=i386/lynx-ng.h - fi - xm_file=i386/xm-lynx.h - tmake_file=i386/t-i386bare - xmake_file=x-lynx - ;; -changequote(,)dnl - i[34567]86-*-mach*) -changequote([,])dnl - tm_file=i386/mach.h -# tmake_file=t-libc-ok - use_collect2=yes - ;; -changequote(,)dnl - i[34567]86-*-osfrose*) # 386 using OSF/rose -changequote([,])dnl - if test x$elf = xyes - then - tm_file=i386/osfelf.h - use_collect2= - else - tm_file=i386/osfrose.h - use_collect2=yes - fi - xm_file="i386/xm-osf.h ${xm_file}" - xmake_file=i386/x-osfrose - tmake_file=i386/t-osf - extra_objs=halfpic.o - ;; -changequote(,)dnl - i[34567]86-go32-rtems*) -changequote([,])dnl - cpu_type=i386 - xm_file=i386/xm-go32.h - tm_file=i386/go32-rtems.h - tmake_file="i386/t-go32 t-rtems" - ;; -changequote(,)dnl - i[34567]86-*-rtemself*) -changequote([,])dnl - cpu_type=i386 - tm_file=i386/rtemself.h - tmake_file="i386/t-i386bare t-rtems" - ;; -changequote(,)dnl - i[34567]86-*-rtems*) -changequote([,])dnl - cpu_type=i386 - tm_file=i386/rtems.h - tmake_file="i386/t-i386bare t-rtems" - ;; -changequote(,)dnl - i[34567]86-*-sco3.2v5*) # 80386 running SCO Open Server 5 -changequote([,])dnl - xm_file="xm-siglist.h xm-alloca.h ${xm_file} i386/xm-sco5.h" - xm_defines="USG SVR3" - xmake_file=i386/x-sco5 - fixincludes=fixinc.sco - install_headers_dir=install-headers-cpio - tm_file=i386/sco5.h - if test x$gas = xyes - then - tm_file="i386/sco5gas.h ${tm_file}" - tmake_file=i386/t-sco5gas - else - tmake_file=i386/t-sco5 - fi - extra_parts="crtbegin.o crtend.o crtbeginS.o crtendS.o" - ;; -changequote(,)dnl - i[34567]86-*-sco3.2v4*) # 80386 running SCO 3.2v4 system -changequote([,])dnl - xm_file="${xm_file} i386/xm-sco.h" - xm_defines="USG SVR3 BROKEN_LDEXP SMALL_ARG_MAX NO_SYS_SIGLIST" - xmake_file=i386/x-sco4 - fixincludes=fixinc.sco - install_headers_dir=install-headers-cpio - if test x$stabs = xyes - then - tm_file=i386/sco4dbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/sco4.h - tmake_file=i386/t-crtstuff - extra_parts="crtbegin.o crtend.o" - fi - truncate_target=yes - ;; -changequote(,)dnl - i[34567]86-*-sco*) # 80386 running SCO system -changequote([,])dnl - xm_file=i386/xm-sco.h - xmake_file=i386/x-sco - install_headers_dir=install-headers-cpio - if test x$stabs = xyes - then - tm_file=i386/scodbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/sco.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - truncate_target=yes - ;; -changequote(,)dnl - i[34567]86-*-solaris2*) -changequote([,])dnl - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - if test x$stabs = xyes - then - tm_file=i386/sol2dbg.h - else - tm_file=i386/sol2.h - fi - tmake_file=i386/t-sol2 - extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" - xmake_file=x-svr4 - case $machine in -changequote(,)dnl - *-*-solaris2.[0-4]) -changequote([,])dnl - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - if test x$enable_threads = xyes; then - thread_file='solaris' - fi - ;; -changequote(,)dnl - i[34567]86-*-sysv5*) # Intel x86 on System V Release 5 -changequote([,])dnl - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - tm_file=i386/sysv4.h - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes=fixinc.svr4 - ;; -changequote(,)dnl - i[34567]86-*-sysv4*) # Intel 80386's running system V.4 -changequote([,])dnl - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - tm_file=i386/sysv4.h - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - ;; -changequote(,)dnl - i[34567]86-*-udk*) # Intel x86 on SCO UW/OSR5 Dev Kit -changequote([,])dnl - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - tm_file=i386/udk.h - tmake_file="i386/t-crtpic i386/t-udk" - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - fixincludes="fixinc.svr4" - ;; -changequote(,)dnl - i[34567]86-*-osf1*) # Intel 80386's running OSF/1 1.3+ -changequote([,])dnl - cpu_type=i386 - xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h i386/xm-osf1elf.h" - xm_defines="USE_C_ALLOCA SMALL_ARG_MAX" - fixincludes=Makefile.in #Don't do it on OSF/1 - if test x$stabs = xyes - then - tm_file=i386/osf1elfgdb.h - else - tm_file=i386/osf1elf.h - fi - tmake_file=i386/t-osf1elf - xmake_file=i386/x-osf1elf - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - ;; -changequote(,)dnl - i[34567]86-*-sysv*) # Intel 80386's running system V -changequote([,])dnl - xm_defines="USG SVR3" - xmake_file=i386/x-sysv3 - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=i386/svr3dbx.h - tmake_file=i386/t-svr3dbx - extra_parts="svr3.ifile svr3z.rfile" - else - tm_file=i386/svr3gas.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - else - tm_file=i386/sysv3.h - extra_parts="crtbegin.o crtend.o" - tmake_file=i386/t-crtstuff - fi - ;; - i386-*-vsta) # Intel 80386's running VSTa kernel - xm_file="${xm_file} i386/xm-vsta.h" - tm_file=i386/vsta.h - tmake_file=i386/t-vsta - xmake_file=i386/x-vsta - ;; -changequote(,)dnl - i[34567]86-*-win32) -changequote([,])dnl - xm_file="${xm_file} i386/xm-cygwin.h" - tmake_file=i386/t-cygwin - tm_file=i386/win32.h - xmake_file=i386/x-cygwin - extra_objs=winnt.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - ;; -changequote(,)dnl - i[34567]86-*-pe | i[34567]86-*-cygwin*) -changequote([,])dnl - xm_file="${xm_file} i386/xm-cygwin.h" - tmake_file=i386/t-cygwin - tm_file=i386/cygwin.h - xmake_file=i386/x-cygwin - extra_objs=winnt.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - ;; -changequote(,)dnl - i[34567]86-*-mingw32*) -changequote([,])dnl - tm_file=i386/mingw32.h - xm_file="${xm_file} i386/xm-mingw32.h" - tmake_file="i386/t-cygwin i386/t-mingw32" - extra_objs=winnt.o - xmake_file=i386/x-cygwin - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - case $machine in - *mingw32msv*) - ;; - *minwg32crt* | *mingw32*) - tm_file="${tm_file} i386/crtdll.h" - ;; - esac - ;; -changequote(,)dnl - i[34567]86-*-winnt3*) -changequote([,])dnl - tm_file=i386/win-nt.h - out_file=i386/i386.c - xm_file="xm-winnt.h ${xm_file}" - xmake_file=winnt/x-winnt - tmake_file=i386/t-winnt - extra_host_objs="winnt.o oldnames.o" - extra_gcc_objs="spawnv.o oldnames.o" - fixincludes=fixinc.winnt - if test x$gnu_ld != xyes - then - extra_programs=ld.exe - fi - if test x$enable_threads = xyes; then - thread_file='win32' - fi - ;; -changequote(,)dnl - i[34567]86-dg-dgux*) -changequote([,])dnl - xm_file="xm-alloca.h xm-siglist.h ${xm_file}" - xm_defines="USG POSIX" - out_file=i386/dgux.c - tm_file=i386/dgux.h - tmake_file=i386/t-dgux - xmake_file=i386/x-dgux - fixincludes=fixinc.dgux - install_headers_dir=install-headers-cpio - ;; - i860-alliant-*) # Alliant FX/2800 - tm_file="${tm_file} svr4.h i860/sysv4.h i860/fx2800.h" - xm_file="${xm_file}" - xmake_file=i860/x-fx2800 - tmake_file=i860/t-fx2800 - extra_parts="crtbegin.o crtend.o" - ;; - i860-*-bsd*) - tm_file="${tm_file} i860/bsd.h" - if test x$gas = xyes - then - tm_file="${tm_file} i860/bsd-gas.h" - fi - use_collect2=yes - ;; - i860-*-mach*) - tm_file="${tm_file} i860/mach.h" - tmake_file=t-libc-ok - ;; - i860-*-osf*) # Intel Paragon XP/S, OSF/1AD - tm_file="${tm_file} svr3.h i860/paragon.h" - xm_defines="USG SVR3" - tmake_file=t-osf - ;; - i860-*-sysv3*) - tm_file="${tm_file} svr3.h i860/sysv3.h" - xm_defines="USG SVR3" - xmake_file=i860/x-sysv3 - extra_parts="crtbegin.o crtend.o" - ;; - i860-*-sysv4*) - tm_file="${tm_file} svr4.h i860/sysv4.h" - xm_defines="USG SVR3" - xmake_file=i860/x-sysv4 - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - ;; - i960-wrs-vxworks5 | i960-wrs-vxworks5.0*) - tm_file="${tm_file} i960/vx960.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-wrs-vxworks5* | i960-wrs-vxworks) - tm_file="${tm_file} dbxcoff.h i960/i960-coff.h i960/vx960-coff.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-wrs-vxworks*) - tm_file="${tm_file} i960/vx960.h" - tmake_file=i960/t-vxworks960 - use_collect2=yes - thread_file='vxworks' - ;; - i960-*-coff*) - tm_file="${tm_file} dbxcoff.h i960/i960-coff.h libgloss.h" - tmake_file=i960/t-960bare - use_collect2=yes - ;; - i960-*-rtems) - tmake_file="i960/t-960bare t-rtems" - tm_file="${tm_file} dbxcoff.h i960/rtems.h" - use_collect2=yes - ;; - i960-*-*) # Default i960 environment. - use_collect2=yes - ;; - m32r-*-elf*) - extra_parts="crtinit.o crtfini.o" - extra_parts="crtinit.o crtfini.o m32rx/crtinit.o m32rx/crtfini.o" - ;; - m68000-convergent-sysv*) - tm_file=m68k/ctix.h - xm_file="m68k/xm-3b1.h ${xm_file}" - xm_defines=USG - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-hp-bsd*) # HP 9000/200 running BSD - tm_file=m68k/hp2bsd.h - xmake_file=m68k/x-hp2bsd - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-hp-hpux*) # HP 9000 series 300 - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp310g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp310.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-sun-sunos3*) - tm_file=m68k/sun2.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-sun-sunos4*) - tm_file=m68k/sun2o4.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68000-att-sysv*) - xm_file="m68k/xm-3b1.h ${xm_file}" - xm_defines=USG - if test x$gas = xyes - then - tm_file=m68k/3b1g.h - else - tm_file=m68k/3b1.h - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-apple-aux*) # Apple Macintosh running A/UX - xm_defines="USG AUX" - tmake_file=m68k/t-aux - install_headers_dir=install-headers-cpio - extra_headers=math-68881.h - extra_parts="crt1.o mcrt1.o maccrt1.o crt2.o crtn.o" - tm_file= - if test "$gnu_ld" = yes - then - tm_file="${tm_file} m68k/auxgld.h" - else - tm_file="${tm_file} m68k/auxld.h" - fi - if test "$gas" = yes - then - tm_file="${tm_file} m68k/auxgas.h" - else - tm_file="${tm_file} m68k/auxas.h" - fi - tm_file="${tm_file} m68k/a-ux.h" - float_format=m68k - ;; - m68k-apollo-*) - tm_file=m68k/apollo68.h - xmake_file=m68k/x-apollo68 - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-altos-sysv*) # Altos 3068 - if test x$gas = xyes - then - tm_file=m68k/altos3068.h - xm_defines=USG - else - echo "The Altos is supported only with the GNU assembler" 1>&2 - exit 1 - fi - extra_headers=math-68881.h - ;; - m68k-bull-sysv*) # Bull DPX/2 - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=m68k/dpx2cdbx.h - else - tm_file=m68k/dpx2g.h - fi - else - tm_file=m68k/dpx2.h - fi - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - xmake_file=m68k/x-dpx2 - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-atari-sysv4*) # Atari variant of V.4. - tm_file=m68k/atari.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines="USG FULL_PROTOTYPES" - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-motorola-sysv*) - tm_file=m68k/mot3300.h - xm_file="xm-alloca.h m68k/xm-mot3300.h ${xm_file}" - xm_defines=NO_SYS_SIGLIST - if test x$gas = xyes - then - xmake_file=m68k/x-mot3300-gas - if test x$gnu_ld = xyes - then - tmake_file=m68k/t-mot3300-gald - else - tmake_file=m68k/t-mot3300-gas - use_collect2=yes - fi - else - xmake_file=m68k/x-mot3300 - if test x$gnu_ld = xyes - then - tmake_file=m68k/t-mot3300-gld - else - tmake_file=m68k/t-mot3300 - use_collect2=yes - fi - fi - gdb_needs_out_file_path=yes - extra_parts="crt0.o mcrt0.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-ncr-sysv*) # NCR Tower 32 SVR3 - tm_file=m68k/tower-as.h - xm_defines="USG SVR3" - xmake_file=m68k/x-tower - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - ;; - m68k-plexus-sysv*) - tm_file=m68k/plexus.h - xm_file="xm-alloca.h m68k/xm-plexus.h ${xm_file}" - xm_defines=USG - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-tti-*) - tm_file=m68k/pbb.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - extra_headers=math-68881.h - ;; - m68k-crds-unos*) - xm_file="xm-alloca.h m68k/xm-crds.h ${xm_file}" - xm_defines="USG unos" - xmake_file=m68k/x-crds - tm_file=m68k/crds.h - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-cbm-sysv4*) # Commodore variant of V.4. - tm_file=m68k/amix.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines="USG FULL_PROTOTYPES" - xmake_file=m68k/x-amix - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-ccur-rtu) - tm_file=m68k/ccur-GAS.h - xmake_file=m68k/x-ccur - extra_headers=math-68881.h - use_collect2=yes - float_format=m68k - ;; - m68k-hp-bsd4.4*) # HP 9000/3xx running 4.4bsd - tm_file=m68k/hp3bsd44.h - xmake_file=m68k/x-hp3bsd44 - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-hp-bsd*) # HP 9000/3xx running Berkeley Unix - tm_file=m68k/hp3bsd.h - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-isi-bsd*) - if test x$with_fp = xno - then - tm_file=m68k/isi-nfp.h - else - tm_file=m68k/isi.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-hp-hpux7*) # HP 9000 series 300 running HPUX version 7. - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hpux7.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-hp-hpux*) # HP 9000 series 300 - xm_file="xm_alloca.h ${xm_file}" - xm_defines="USG NO_SYS_SIGLIST" - if test x$gas = xyes - then - xmake_file=m68k/x-hp320g - tm_file=m68k/hp320g.h - else - xmake_file=m68k/x-hp320 - tm_file=m68k/hp320.h - fi - install_headers_dir=install-headers-cpio - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sun-mach*) - tm_file=m68k/sun3mach.h - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sony-newsos3*) - if test x$gas = xyes - then - tm_file=m68k/news3gas.h - else - tm_file=m68k/news3.h - fi - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-sony-bsd* | m68k-sony-newsos*) - if test x$gas = xyes - then - tm_file=m68k/newsgas.h - else - tm_file=m68k/news.h - fi - use_collect2=yes - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-next-nextstep2*) - tm_file=m68k/next21.h - xm_file="m68k/xm-next.h ${xm_file}" - tmake_file=m68k/t-next - xmake_file=m68k/x-next - extra_objs=nextstep.o - extra_headers=math-68881.h - use_collect2=yes - float_format=m68k - ;; - m68k-next-nextstep3*) - tm_file=m68k/next.h - xm_file="m68k/xm-next.h ${xm_file}" - tmake_file=m68k/t-next - xmake_file=m68k/x-next - extra_objs=nextstep.o - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - if test x$enable_threads = xyes; then - thread_file='mach' - fi - ;; - m68k-sun-sunos3*) - if test x$with_fp = xno - then - tm_file=m68k/sun3n3.h - else - tm_file=m68k/sun3o3.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-sun-sunos*) # For SunOS 4 (the default). - if test x$with_fp = xno - then - tm_file=m68k/sun3n.h - else - tm_file=m68k/sun3.h - float_format=m68k - fi - use_collect2=yes - extra_headers=math-68881.h - ;; - m68k-wrs-vxworks*) - tm_file=m68k/vxm68k.h - tmake_file=m68k/t-vxworks68 - extra_headers=math-68881.h - thread_file='vxworks' - float_format=m68k - ;; - m68k-*-aout*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-aout.h libgloss.h" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - float_format=m68k - ;; - m68020-*-elf* | m68k-*-elf*) - tm_file="m68k/m68020-elf.h libgloss.h" - xm_file=m68k/xm-m68kv.h - tmake_file=m68k/t-m68kelf - header_files=math-68881.h - ;; - m68k-*-lynxos*) - if test x$gas = xyes - then - tm_file=m68k/lynx.h - else - tm_file=m68k/lynx-ng.h - fi - xm_file=m68k/xm-lynx.h - xmake_file=x-lynx - tmake_file=m68k/t-lynx - extra_headers=math-68881.h - float_format=m68k - ;; - m68k*-*-netbsd*) - tm_file=m68k/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - float_format=m68k - ;; - m68k-*-sysv3*) # Motorola m68k's running system V.3 - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - xmake_file=m68k/x-m68kv - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-sysv4*) # Motorola m68k's running system V.4 - tm_file=m68k/m68kv4.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - tmake_file=t-svr4 - extra_parts="crtbegin.o crtend.o" - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-linux-gnuaout*) # Motorola m68k's running GNU/Linux - # with a.out format - xmake_file=x-linux - tm_file=m68k/linux-aout.h - tmake_file="t-linux-aout m68k/t-linux-aout" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - ;; - m68k-*-linux-gnulibc1) # Motorola m68k's running GNU/Linux - # with ELF format using the - # GNU/Linux C library 5 - xmake_file=x-linux - tm_file=m68k/linux.h - tmake_file="t-linux t-linux-gnulibc1 m68k/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - ;; - m68k-*-linux-gnu*) # Motorola m68k's running GNU/Linux - # with ELF format using glibc 2 - # aka the GNU/Linux C library 6. - xmake_file=x-linux - tm_file=m68k/linux.h - tmake_file="t-linux m68k/t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in # The headers are ok already. - extra_headers=math-68881.h - float_format=m68k - gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - m68k-*-psos*) - tmake_file=m68k/t-m68kbare - tm_file=m68k/m68k-psos.h - extra_headers=math-68881.h - float_format=m68k - ;; - m68k-*-rtems*) - tmake_file="m68k/t-m68kbare t-rtems" - tm_file=m68k/rtems.h - extra_headers=math-68881.h - float_format=m68k - ;; - m88k-dg-dgux*) - case $machine in - m88k-dg-dguxbcs*) - tm_file=m88k/dguxbcs.h - tmake_file=m88k/t-dguxbcs - ;; - *) - tm_file=m88k/dgux.h - tmake_file=m88k/t-dgux - ;; - esac - extra_parts="crtbegin.o bcscrtbegin.o crtend.o m88kdgux.ld" - xmake_file=m88k/x-dgux - if test x$gas = xyes - then - tmake_file=m88k/t-dgux-gas - fi - fixincludes=fixinc.dgux - ;; - m88k-dolphin-sysv3*) - tm_file=m88k/dolph.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-dolph - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-tektronix-sysv3) - tm_file=m88k/tekXD88.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-tekXD88 - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-*-aout*) - tm_file=m88k/m88k-aout.h - ;; - m88k-*-coff*) - tm_file=m88k/m88k-coff.h - tmake_file=m88k/t-bug - ;; - m88k-*-luna*) - tm_file=m88k/luna.h - extra_parts="crtbegin.o crtend.o" - if test x$gas = xyes - then - tmake_file=m88k/t-luna-gas - else - tmake_file=m88k/t-luna - fi - ;; - m88k-*-sysv3*) - tm_file=m88k/sysv3.h - extra_parts="crtbegin.o crtend.o" - xm_file="m88k/xm-sysv3.h ${xm_file}" - xmake_file=m88k/x-sysv3 - if test x$gas = xyes - then - tmake_file=m88k/t-m88k-gas - fi - ;; - m88k-*-sysv4*) - tm_file=m88k/sysv4.h - extra_parts="crtbegin.o crtend.o" - xmake_file=m88k/x-sysv4 - tmake_file=m88k/t-sysv4 - ;; - mips-lsi-elf*) # CYGNUS LOCAL angela - tm_file="mips/elf.h" - tmake_file=mips/t-lsi - ;; - mips-sgi-irix6*) # SGI System V.4., IRIX 6 - tm_file=mips/iris6.h - xm_file=mips/xm-iris6.h - fixincludes=fixinc.irix - xmake_file=mips/x-iris6 - tmake_file=mips/t-iris6 -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-wrs-vxworks) - tm_file="mips/elf.h libgloss.h mips/vxworks.h" - tmake_file=mips/t-ecoff - gas=yes - gnu_ld=yes - extra_parts="crtbegin.o crtend.o" -# thread_file='vxworks' - ;; - mips-sgi-irix5cross64) # Irix5 host, Irix 6 target, cross64 - tm_file="mips/iris6.h mips/cross64.h" - xm_defines=USG - xm_file="mips/xm-iris5.h" - fixincludes=Makefile.in - xmake_file=mips/x-iris - tmake_file=mips/t-cross64 - # See comment in mips/iris[56].h files. - use_collect2=yes -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sni-sysv4) - if test x$gas = xyes - then - if test x$stabs = xyes - then - tm_file=mips/iris5gdb.h - else - tm_file="mips/sni-svr4.h mips/sni-gas.h" - fi - else - tm_file=mips/sni-svr4.h - fi - xm_defines=USG - xmake_file=mips/x-sni-svr4 - tmake_file=mips/t-mips-gas - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-sgi-irix5*) # SGI System V.4., IRIX 5 - if test x$gas = xyes - then - tm_file="mips/iris5.h mips/iris5gas.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - else - tm_file=mips/iris5.h - fi - xm_defines=USG - xm_file="mips/xm-iris5.h" - fixincludes=fixinc.irix - xmake_file=mips/x-iris - # mips-tfile doesn't work yet - tmake_file=mips/t-mips-gas - # See comment in mips/iris5.h file. - use_collect2=yes -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-irix4loser*) # Mostly like a MIPS. - tm_file="mips/iris4loser.h mips/iris3.h ${tm_file} mips/iris4.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-irix4*) # Mostly like a MIPS. - tm_file="mips/iris3.h ${tm_file} mips/iris4.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi -# if test x$enable_threads = xyes; then -# thread_file='irix' -# fi - ;; - mips-sgi-*) # Mostly like a MIPS. - tm_file="mips/iris3.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-iris3 - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-dec-osfrose*) # Decstation running OSF/1 reference port with OSF/rose. - tm_file="mips/osfrose.h ${tm_file}" - xmake_file=mips/x-osfrose - tmake_file=mips/t-osfrose - extra_objs=halfpic.o - use_collect2=yes - ;; - mips-dec-osf*) # Decstation running OSF/1 as shipped by DIGITAL - tm_file=mips/dec-osf1.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xmake_file=mips/x-dec-osf1 - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-dec-bsd*) # Decstation running 4.4 BSD - tm_file=mips/dec-bsd.h - fixincludes= - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mipsel-*-netbsd* | mips-dec-netbsd*) # Decstation running NetBSD - tm_file=mips/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - mips*-*-linux*) # Linux MIPS, either endian. - xmake_file=x-linux - xm_file="xm-siglist.h ${xm_file}" - case $machine in - mipsel-*) tm_file="mips/elfl.h mips/linux.h" ;; - *) tm_file="mips/elf.h mips/linux.h" ;; - esac - extra_parts="crtbegin.o crtend.o" - gnu_ld=yes - gas=yes - fixincludes=Makefile.in - ;; - mips-sony-bsd* | mips-sony-newsos*) # Sony NEWS 3600 or risc/news. - tm_file="mips/news4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - xmake_file=mips/x-sony - ;; - mips-sony-sysv*) # Sony NEWS 3800 with NEWSOS5.0. - # That is based on svr4. - # t-svr4 is not right because this system doesn't use ELF. - tm_file="mips/news5.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-tandem-sysv4*) # Tandem S2 running NonStop UX - tm_file="mips/svr4-5.h mips/svr4-t.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - extra_parts="crtbegin.o crtend.o" - else - tmake_file=mips/t-mips - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-ultrix* | mips-dec-mach3) # Decstation. - tm_file="mips/ultrix.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xmake_file=mips/x-ultrix - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - tmake_file=mips/t-ultrix - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-riscos[56789]bsd*) -changequote([,])dnl - tm_file=mips/bsd-5.h # MIPS BSD 4.3, RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-bsd* | mips-*-riscosbsd* | mips-*-riscos[1234]bsd*) -changequote([,])dnl - tm_file="mips/bsd-4.h ${tm_file}" # MIPS BSD 4.3, RISC-OS 4.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-bsd-gas - else - tmake_file=mips/t-bsd - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-riscos[56789]sysv4*) -changequote([,])dnl - tm_file=mips/svr4-5.h # MIPS System V.4., RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-sysv4* | mips-*-riscos[1234]sysv4* | mips-*-riscossysv4*) -changequote([,])dnl - tm_file="mips/svr4-4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr4-gas - else - tmake_file=mips/t-svr4 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-riscos[56789]sysv*) -changequote([,])dnl - tm_file=mips/svr3-5.h # MIPS System V.3, RISC-OS 5.0 - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-sysv* | mips-*-riscos*sysv*) - tm_file="mips/svr3-4.h ${tm_file}" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - xm_defines=USG - xmake_file=mips/x-sysv - if test x$gas = xyes - then - tmake_file=mips/t-svr3-gas - else - tmake_file=mips/t-svr3 - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; -changequote(,)dnl - mips-*-riscos[56789]*) # Default MIPS RISC-OS 5.0. -changequote([,])dnl - tm_file=mips/mips-5.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mips-*-gnu*) - ;; - mipsel-*-ecoff*) - tm_file=mips/ecoffl.h - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mips-*-ecoff*) - tm_file="gofast.h mips/ecoff.h" - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mipsel-*-elf*) - tm_file="mips/elfl.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips-*-elf*) - tm_file="mips/elf.h" - tmake_file=mips/t-elf - ;; - mips64el-*-elf*) - tm_file="mips/elfl64.h" - tmake_file=mips/t-elf - ;; - mips64orionel-*-elf*) - tm_file="mips/elforion.h mips/elfl64.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips64-*-elf*) - tm_file="mips/elf64.h" - tmake_file=mips/t-elf - ;; - mips64orion-*-elf*) - tm_file="mips/elforion.h mips/elf64.h libgloss.h" - tmake_file=mips/t-elf - ;; - mips64orion-*-rtems*) - tm_file="mips/elforion.h mips/elf64.h mips/rtems64.h" - tmake_file="mips/t-ecoff t-rtems" - ;; - mipstx39el-*-elf*) - tm_file="mips/r3900.h mips/elfl.h mips/abi64.h" - tmake_file=mips/t-r3900 - ;; - mipstx39-*-elf*) - tm_file="mips/r3900.h mips/elf.h mips/abi64.h" - tmake_file=mips/t-r3900 - ;; - mips-*-*) # Default MIPS RISC-OS 4.0. - if test x$stabs = xyes; then - tm_file="${tm_file} dbx.h" - fi - if test x$gas = xyes - then - tmake_file=mips/t-mips-gas - else - extra_passes="mips-tfile mips-tdump" - fi - if test x$gnu_ld != xyes - then - use_collect2=yes - fi - ;; - mn10200-*-*) - cpu_type=mn10200 - tm_file="mn10200/mn10200.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - mn10300-*-*) - cpu_type=mn10300 - tm_file="mn10300/mn10300.h" - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - ns32k-encore-bsd*) - tm_file=ns32k/encore.h - use_collect2=yes - ;; - ns32k-sequent-bsd*) - tm_file=ns32k/sequent.h - use_collect2=yes - ;; - ns32k-tek6100-bsd*) - tm_file=ns32k/tek6100.h - use_collect2=yes - ;; - ns32k-tek6200-bsd*) - tm_file=ns32k/tek6200.h - use_collect2=yes - ;; -# This has not been updated to GCC 2. -# ns32k-ns-genix*) -# xm_defines=USG -# xmake_file=ns32k/x-genix -# tm_file=ns32k/genix.h -# use_collect2=yes -# ;; - ns32k-merlin-*) - tm_file=ns32k/merlin.h - use_collect2=yes - ;; - ns32k-pc532-mach*) - tm_file=ns32k/pc532-mach.h - use_collect2=yes - ;; - ns32k-pc532-minix*) - tm_file=ns32k/pc532-min.h - xm_file="ns32k/xm-pc532-min.h ${xm-file}" - xm_defines=USG - use_collect2=yes - ;; - ns32k-*-netbsd*) - tm_file=ns32k/netbsd.h - xm_file="ns32k/xm-netbsd.h ${xm_file}" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - pdp11-*-bsd) - tm_file="${tm_file} pdp11/2bsd.h" - ;; - pdp11-*-*) - ;; - pyramid-*-*) - cpu_type=pyr - xmake_file=pyr/x-pyr - use_collect2=yes - ;; - romp-*-aos*) - use_collect2=yes - ;; - romp-*-mach*) - xmake_file=romp/x-mach - use_collect2=yes - ;; - powerpc-*-beos*) - cpu_type=rs6000 - tm_file=rs6000/beos.h - xm_file=rs6000/xm-beos.h - tmake_file=rs6000/t-beos - xmake_file=rs6000/x-beos - ;; - powerpc-*-sysv* | powerpc-*-elf*) - tm_file=rs6000/sysv4.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - extra_headers=ppc-asm.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - ;; - powerpc-*-eabiaix*) - tm_file=rs6000/eabiaix.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-eabisim*) - tm_file=rs6000/eabisim.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-eabi*) - tm_file=rs6000/eabi.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-rtems*) - tm_file=rs6000/rtems.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas t-rtems rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-rtems rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpc-*-linux-gnulibc1) - tm_file=rs6000/linux.h - xm_file=rs6000/xm-sysv4.h - out_file=rs6000/rs6000.c - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos t-linux t-linux-gnulibc1 rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-linux t-linux-gnulibc1 rs6000/t-ppccomm" - fi - xmake_file=x-linux - fixincludes=Makefile.in - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - extra_headers=ppc-asm.h - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - powerpc-*-linux-gnu*) - tm_file=rs6000/linux.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG ${xm_defines}" - out_file=rs6000/rs6000.c - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos t-linux rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc t-linux rs6000/t-ppccomm" - fi - xmake_file=x-linux - fixincludes=Makefile.in - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - extra_headers=ppc-asm.h - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - powerpc-wrs-vxworks*) - cpu_type=rs6000 - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - tm_file=rs6000/vxppc.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - extra_headers=ppc-asm.h - thread_file='vxworks' - ;; - powerpcle-*-sysv* | powerpcle-*-elf*) - tm_file=rs6000/sysv4le.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - extra_headers=ppc-asm.h - ;; - powerpcle-*-eabisim*) - tm_file=rs6000/eabilesim.h - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpcle-*-eabi*) - tm_file=rs6000/eabile.h - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcgas rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - fixincludes=Makefile.in - extra_headers=ppc-asm.h - ;; - powerpcle-*-winnt* ) - tm_file=rs6000/win-nt.h - tmake_file=rs6000/t-winnt -# extra_objs=pe.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - extra_headers=ppc-asm.h - ;; - powerpcle-*-pe | powerpcle-*-cygwin*) - tm_file=rs6000/cygwin.h - xm_file="rs6000/xm-cygwin.h ${xm_file}" - tmake_file=rs6000/t-winnt - xmake_file=rs6000/x-cygwin -# extra_objs=pe.o - fixincludes=Makefile.in - if test x$enable_threads = xyes; then - thread_file='win32' - fi - exeext=.exe - extra_headers=ppc-asm.h - ;; - powerpcle-*-solaris2*) - tm_file=rs6000/sol2.h - xm_file="xm-siglist.h rs6000/xm-sysv4.h" - xm_defines="USG POSIX" - if test x$gas = xyes - then - tmake_file="rs6000/t-ppcos rs6000/t-ppccomm" - else - tmake_file="rs6000/t-ppc rs6000/t-ppccomm" - fi - xmake_file=rs6000/x-sysv4 - case $machine in -changequote(,)dnl - *-*-solaris2.[0-4]) -changequote([,])dnl - fixincludes=fixinc.svr4;; - *) - fixincludes=fixinc.wrap;; - esac - extra_headers=ppc-asm.h - ;; -changequote(,)dnl - rs6000-ibm-aix3.[01]*) -changequote([,])dnl - tm_file=rs6000/aix31.h - xmake_file=rs6000/x-aix31 - use_collect2=yes - ;; -changequote(,)dnl - rs6000-ibm-aix3.2.[456789]* | powerpc-ibm-aix3.2.[456789]*) -changequote([,])dnl - tm_file=rs6000/aix3newas.h - if test x$host != x$target - then - tmake_file=rs6000/t-xnewas - else - tmake_file=rs6000/t-newas - fi - use_collect2=yes - ;; -changequote(,)dnl - rs6000-ibm-aix4.[12]* | powerpc-ibm-aix4.[12]*) -changequote([,])dnl - tm_file=rs6000/aix41.h - if test x$host != x$target - then - tmake_file=rs6000/t-xnewas - else - tmake_file=rs6000/t-newas - fi - xmake_file=rs6000/x-aix41 - use_collect2=yes - ;; -changequote(,)dnl - rs6000-ibm-aix4.[3456789].* | powerpc-ibm-aix4.[3456789].*) -changequote([,])dnl - tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 - use_collect2=yes - ;; -changequote(,)dnl - rs6000-ibm-aix[56789].* | powerpc-ibm-aix[56789].*) -changequote([,])dnl - tm_file=rs6000/aix43.h - if test x$host != x$target - then - tmake_file=rs6000/t-xaix43 - else - tmake_file=rs6000/t-aix43 - fi - xmake_file=rs6000/x-aix43 - use_collect2=yes - ;; - rs6000-ibm-aix*) - use_collect2=yes - ;; - rs6000-bull-bosx) - use_collect2=yes - ;; - rs6000-*-mach*) - tm_file=rs6000/mach.h - xm_file="${xm_file} rs6000/xm-mach.h" - xmake_file=rs6000/x-mach - use_collect2=yes - ;; - rs6000-*-lynxos*) - tm_file=rs6000/lynx.h - xm_file=rs6000/xm-lynx.h - tmake_file=rs6000/t-rs6000 - xmake_file=rs6000/x-lynx - use_collect2=yes - ;; - sh-*-elf*) - tm_file=sh/elf.h - float_format=sh - ;; - sh-*-rtemself*) - tmake_file="sh/t-sh t-rtems" - tm_file=sh/rtemself.h - float_format=sh - ;; - sh-*-rtems*) - tmake_file="sh/t-sh t-rtems" - tm_file=sh/rtems.h - float_format=sh - ;; - sh-*-*) - float_format=sh - ;; - sparc-tti-*) - tm_file=sparc/pbd.h - xm_file="xm-alloca.h ${xm_file}" - xm_defines=USG - ;; - sparc-wrs-vxworks* | sparclite-wrs-vxworks*) - tm_file=sparc/vxsparc.h - tmake_file=sparc/t-vxsparc - use_collect2=yes - thread_file='vxworks' - ;; - sparc-*-aout*) - tmake_file=sparc/t-sparcbare - tm_file="sparc/aout.h libgloss.h" - ;; - sparc-*-netbsd*) - tm_file=sparc/netbsd.h - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - ;; - sparc-*-bsd*) - tm_file=sparc/bsd.h - ;; - sparc-*-elf*) - tm_file=sparc/elf.h - tmake_file=sparc/t-elf - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - #float_format=i128 - float_format=i64 - ;; - sparc-*-linux-gnuaout*) # Sparc's running GNU/Linux, a.out - xm_file="${xm_file} sparc/xm-linux.h" - tm_file=sparc/linux-aout.h - xmake_file=x-linux - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - ;; - sparc-*-linux-gnulibc1*) # Sparc's running GNU/Linux, libc5 - xm_file="${xm_file} sparc/xm-linux.h" - xmake_file=x-linux - tm_file=sparc/linux.h - tmake_file="t-linux t-linux-gnulibc1" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - ;; - sparc-*-linux-gnu*) # Sparc's running GNU/Linux, libc6 - xm_file="${xm_file} sparc/xm-linux.h" - xmake_file=x-linux - tm_file=sparc/linux.h - tmake_file="t-linux" - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - fixincludes=Makefile.in #On Linux, the headers are ok already. - gnu_ld=yes - if test x$enable_threads = xyes; then - thread_file='posix' - fi - ;; - sparc-*-lynxos*) - if test x$gas = xyes - then - tm_file=sparc/lynx.h - else - tm_file=sparc/lynx-ng.h - fi - xm_file=sparc/xm-lynx.h - tmake_file=sparc/t-sunos41 - xmake_file=x-lynx - ;; - sparc-*-rtems*) - tmake_file="sparc/t-sparcbare t-rtems" - tm_file=sparc/rtems.h - ;; - sparcv9-*-solaris2*) - tm_file=sparc/sol2-sld-64.h - xm_file="sparc/xm-sysv4-64.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tmake_file="sparc/t-sol2 sparc/t-sol2-64" - xmake_file=sparc/x-sysv4 - extra_parts="crt1.o crti.o crtn.o gcrt1.o crtbegin.o crtend.o" - fixincludes=fixinc.wrap - float_format=none - if test x${enable_threads} = x ; then - enable_threads=$have_pthread_h - if test x${enable_threads} = x ; then - enable_threads=$have_thread_h - fi - fi - if test x${enable_threads} = xyes ; then - if test x${have_pthread_h} = xyes ; then - thread_file='posix' - else - thread_file='solaris' - fi - fi - ;; - sparc-*-solaris2*) - if test x$gnu_ld = xyes - then - tm_file=sparc/sol2.h - else - tm_file=sparc/sol2-sld.h - fi - xm_file="xm-siglist.h sparc/xm-sysv4.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tmake_file=sparc/t-sol2 - xmake_file=sparc/x-sysv4 - extra_parts="crt1.o crti.o crtn.o gcrt1.o gmon.o crtbegin.o crtend.o" - case $machine in -changequote(,)dnl - *-*-solaris2.[0-4]) -changequote([,])dnl - fixincludes=fixinc.svr4 - float_format=i128 - ;; - *) - fixincludes=fixinc.wrap - float_format=none - ;; - esac - if test x${enable_threads} = x; then - enable_threads=$have_pthread_h - if test x${enable_threads} = x; then - enable_threads=$have_thread_h - fi - fi - if test x${enable_threads} = xyes; then - if test x${have_pthread_h} = xyes; then - thread_file='posix' - else - thread_file='solaris' - fi - fi - ;; - sparc-*-sunos4.0*) - tm_file=sparc/sunos4.h - tmake_file=sparc/t-sunos40 - use_collect2=yes - ;; - sparc-*-sunos4*) - tm_file=sparc/sunos4.h - tmake_file=sparc/t-sunos41 - use_collect2=yes - if test x$gas = xyes; then - tm_file="${tm_file} sparc/sun4gas.h" - fi - ;; - sparc-*-sunos3*) - tm_file=sparc/sun4o3.h - use_collect2=yes - ;; - sparc-*-sysv4*) - tm_file=sparc/sysv4.h - xm_file="xm-siglist.h sparc/xm-sysv4.h" - xm_defines="USG POSIX" - tmake_file=t-svr4 - xmake_file=sparc/x-sysv4 - extra_parts="crtbegin.o crtend.o" - ;; - sparc-*-vxsim*) - xm_file="xm-siglist.h sparc/xm-sysv4.h sparc/xm-sol2.h" - xm_defines="USG POSIX" - tm_file=sparc/vxsim.h - tmake_file=sparc/t-vxsparc - xmake_file=sparc/x-sysv4 - ;; - sparclet-*-aout*) - tm_file="sparc/splet.h libgloss.h" - tmake_file=sparc/t-splet - ;; - sparclite-*-coff*) - tm_file="sparc/litecoff.h libgloss.h" - tmake_file=sparc/t-sparclite - ;; - sparclite-*-aout*) - tm_file="sparc/lite.h aoutos.h" - tmake_file=sparc/t-sparclite - use_collect2=yes - ;; - sparclite-*-elf*) - tm_file="sparc/liteelf.h" - tmake_file=sparc/t-sparclite - extra_parts="crtbegin.o crtend.o" - ;; - sparc86x-*-aout*) - tm_file="sparc/sp86x-aout.h aoutos.h libgloss.h" - tmake_file=sparc/t-sp86x - use_collect2=yes - ;; - sparc86x-*-elf*) - tm_file="sparc/sp86x-elf.h libgloss.h" - tmake_file=sparc/t-sp86x - extra_parts="crtbegin.o crtend.o" - ;; - sparc64-*-aout*) - tmake_file=sparc/t-sp64 - tm_file=sparc/sp64-aout.h - ;; - sparc64-*-elf*) - tmake_file=sparc/t-sp64 - tm_file=sparc/sp64-elf.h - extra_parts="crtbegin.o crtend.o" - ;; - sparc64-*-linux*) # 64-bit Sparc's running GNU/Linux - tmake_file="t-linux sparc/t-linux64" - xm_file="sparc/xm-sp64.h sparc/xm-linux.h" - tm_file=sparc/linux64.h - xmake_file=x-linux - fixincludes=Makefile.in # The headers are ok already. - extra_parts="crtbegin.o crtbeginS.o crtend.o crtendS.o" - gnu_ld=yes - ;; -# This hasn't been upgraded to GCC 2. -# tahoe-harris-*) # Harris tahoe, using COFF. -# tm_file=tahoe/harris.h -# ;; -# tahoe-*-bsd*) # tahoe running BSD -# ;; - thumb-*-coff* | thumbel-*-coff*) - tm_file=arm/tcoff.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-thumb - ;; - # CYGNUS LOCAL clm/arm-elf - thumb-*-elf* | thumbel-*-elf*) + thumb-*-elf) tm_file=arm/telf.h out_file=arm/thumb.c xm_file=arm/xm-thumb.h @@ -3229,273 +533,7 @@ changequote([,])dnl tmake_file=arm/t-thumb-elf fixincludes=Makefile.in # There is nothing to fix ;; - thumb*-*-oabi*) - tm_file=arm/telf-oabi.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-thumb-elf - fixincludes=Makefile.in # There is nothing to fix - ;; - # END CYGNUS LOCAL -# This hasn't been upgraded to GCC 2. -# tron-*-*) -# cpu_type=gmicro -# use_collect2=yes -# ;; - v850-*-*) - cpu_type=v850 - tm_file="v850/v850.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if test x$stabs = xyes - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - # CYGNUS LOCAL v850e/nick - v850e-*-*) - cpu_type=v850 - tm_file="v850/v850e.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if [[ x$stabs = xyes ]] - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - v850ea-*-*) - cpu_type=v850 - tm_file="v850/v850ea.h" - xm_file="v850/xm-v850.h" - tmake_file=v850/t-v850 - if [[ x$stabs = xyes ]] - then - tm_file="${tm_file} dbx.h" - fi - use_collect2=no - ;; - # end CYGNUS LOCAL - vax-*-bsd*) # vaxen running BSD - use_collect2=yes - float_format=vax - ;; - vax-*-sysv*) # vaxen running system V - tm_file="${tm_file} vax/vaxv.h" - xm_defines=USG - float_format=vax - ;; - vax-*-netbsd*) - tm_file="${tm_file} netbsd.h vax/netbsd.h" - # On NetBSD, the headers are already okay, except for math.h. - fixincludes=fixinc.wrap - tmake_file=t-netbsd - float_format=vax - ;; - vax-*-ultrix*) # vaxen running ultrix - tm_file="${tm_file} vax/ultrix.h" - use_collect2=yes - float_format=vax - ;; - vax-*-vms*) # vaxen running VMS - xm_file=vax/xm-vms.h - tm_file=vax/vms.h - float_format=vax - ;; - vax-*-*) # vax default entry - float_format=vax - ;; - we32k-att-sysv*) - xm_file="${xm_file} xm-svr3" - use_collect2=yes - ;; - # CYGNUS LOCAL ports - arm-*-pe*) - tm_file=arm/pe.h - tmake_file=arm/t-pe - extra_objs=pe.o - ;; - d10v-*-*) - float_format=d10v - ;; - d30v-*-*) - float_format=i64 - ;; - fr30-*-elf) - tm_file="fr30/fr30.h" - tmake_file=fr30/t-fr30 - extra_parts="crti.o crtn.o crtbegin.o crtend.o" - ;; - i[[34567]]86-*-elf*) - xm_file="${xm_file} xm-svr4.h i386/xm-sysv4.h" - tm_file=i386/i386elf.h - tmake_file=i386/t-i386elf - xmake_file=x-svr4 - ;; - i[[34567]]86-*-netware) # Intel 80386's running netware - # CYGNUS LOCAL - tm_file=i386/netware.h - tmake_file=i386/t-netware - fixincludes=Makefile.in - ;; - i[[34567]]86-*-unixware) - xm_file="xm-siglist.h xm-alloca.h ${xm_file}" - xm_defines="USG POSIX SMALL_ARG_MAX" - tm_file=i386/sysv4.h - if [[ x$stabs = xyes ]] - then - tm_file="${tm_file} dbx.h" - fi - tmake_file=i386/t-crtpic - xmake_file=x-svr4 - extra_parts="crtbegin.o crtend.o" - ;; - i960-intel-nindy) - tmake_file=i960/t-vxworks960 - use_collect2=yes - ;; - m68000-ncr-sysv*) - tm_file=m68k/tower-as.h - xm_file=m68k/xm-tower.h - xmake_file=m68k/x-tower - tmake_file=m68k/t-svr3 - extra_headers=math-68881.h - ;; - m68k-ericsson-OSE |\ - m68k-ericsson-ose) - tm_file=m68k/ose68k.h - tmake_file=m68k/t-ose68 - extra_headers=math-68881.h - ;; - m680[[01234]]0-wrs-vxworks*) - tm_file=m68k/vxm68k.h - tmake_file=m68k/t-vxworks68 - extra_headers=math-68881.h - ;; - m680[[0234]]0-*-aout* |\ - m683[[03]]2-*-aout*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-aout.h libgloss.h" - extra_headers=math-68881.h - ;; - m680[[0234]]0-*-coff* |\ - m683[[03]]2-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68k-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - ;; - m68360-*-coff*) - tmake_file=m68k/t-m68kbare - tm_file="m68k/m68360-coff.h dbx.h libgloss.h" - extra_headers=math-68881.h - ;; - m68000-*-os68k*) - tm_file=m68k/os68000.h - extra_headers=math-68881.h - ;; - m68k-*-os68k*) - tm_file=m68k/os68000.h - extra_headers=math-68881.h - ;; - # This is a host port only, and won't work as a target. - mips*-nec-sysv4*) # MIPS NEC SVR4 - tm_file=mips/svr4-t.h - if [[ x$stabs = xyes ]]; then - tm_file="${tm_file} dbx.h" - fi - xm_file="xm-siglist.h ${xm_file}" - xm_defines=USG - if [[ x$gas = xyes ]] - then - tmake_file=mips/t-mips-gas - extra_parts="crtbegin.o crtend.o" - else - tmake_file=mips/t-mips - extra_passes="mips-tfile mips-tdump" - fi - if [[ x$gnu_ld != xyes ]] - then - use_collect2=yes - fi - ;; - mips*-*-lnews*) - tm_file=mips/ecoffl.h - if [[ x$stabs = xyes ]]; then - tm_file="${tm_file} dbx.h" - fi - tmake_file=mips/t-ecoff - ;; - mips64vr4300-*-elf*) - tm_file="mips/elfb4300.h" - tmake_file=mips/t-vr4300 - ;; - mips64vr4300el-*-elf*) - tm_file="mips/elfl4300.h libgloss.h" - tmake_file=mips/t-vr4300 - ;; - mips64vr4100-*-elf*) - tm_file="mips/elfb4100.h mips/abi64.h" - tmake_file=mips/t-vr4100 - ;; - mips64vr4100el-*-elf*) - tm_file="mips/elfl4100.h mips/abi64.h libgloss.h" - tmake_file=mips/t-vr4100 - ;; - mips64vr5000-*-elf*) - tm_file="mips/elfb5000.h" - tmake_file=mips/t-vr5000 - # Use haifa by default. - if [[ x$enable_haifa != xno ]]; then - enable_haifa=yes - fi - ;; - mips64vr5000el-*-elf*) - tm_file="mips/elfl5000.h libgloss.h" - tmake_file=mips/t-vr5000 - # Use haifa by default. - if [[ x$enable_haifa != xno ]]; then - enable_haifa=yes - fi - ;; - sparclite-*-elf*) - tm_file="sparc/liteelf.h libgloss.h" - tmake_file=sparc/t-sparclite - extra_parts="crtbegin.o crtend.o" - ;; - thumb-*-pe) - tm_file=arm/tpe.h - out_file=arm/thumb.c - xm_file=arm/xm-thumb.h - md_file=arm/thumb.md - tmake_file=arm/t-pe-thumb - extra_objs=pe.o - ;; - z8k-*-*) - ;; - # END CYGNUS LOCAL - - # CYGNUS LOCAL raeburn/vr5400 - mips64vr5400-*-elf*) - tm_file="mips/big.h mips/elf5400.h libgloss.h" - tmake_file=mips/t-biendian - # Use haifa by default for the r5400 - if [[ x$enable_haifa != xno ]]; then - enable_haifa=yes - fi - ;; - mips64vr5400el-*-elf*) - tm_file="mips/little.h mips/elf5400.h libgloss.h" - tmake_file=mips/t-biendian - # Use haifa by default for the r5400 - if [[ x$enable_haifa != xno ]]; then - enable_haifa=yes - fi - ;; - # END CYGNUS LOCAL raeburn/vr5400 -# This hasn't been upgraded to GCC 2. *) echo "Configuration $machine not supported" 1>&2 exit 1 @@ -3682,15 +720,6 @@ changequote([,])dnl fi fi - # No need for collect2 if we have the GNU linker. - # Actually, there is now; GNU ld doesn't handle the EH info or - # collecting for shared libraries. - #case x$gnu_ld in - #xyes) - # use_collect2= - # ;; - #esac - # Save data on machine being used to compile GCC in build_xm_file. # Save data on host machine in vars host_xm_file and host_xmake_file. if test x$pass1done = x @@ -4026,22 +1055,6 @@ else done fi -if test x$use_collect2 = xno; then - use_collect2= -fi - -# Add a definition of USE_COLLECT2 if system wants one. -# Also tell toplev.c what to do. -# This substitutes for lots of t-* files. -if test x$use_collect2 = x -then - will_use_collect2= - maybe_use_collect2= -else - will_use_collect2="collect2" - maybe_use_collect2="-DUSE_COLLECT2" -fi - # NEED TO CONVERT # Set MD_DEPS if the real md file is in md.pre-cpp. # Set MD_CPP to the cpp to pass the md file through. Md files use ';' @@ -4068,11 +1081,7 @@ fi # If we have ld in the build tree, make a link to it. if test -f ../ld/Makefile; then -# if test x$use_collect2 = x; then -# rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null -# else - rm -f collect-ld; $symbolic_link ../ld/ld-new$host_exeext collect-ld$host_exeext 2>/dev/null -# fi +# rm -f ld; $symbolic_link ../ld/ld-new$host_exeext ld$host_exeext 2>/dev/null fi # Figure out what assembler alignment features are present. @@ -4536,8 +1545,6 @@ AC_SUBST(build_install_headers_dir) AC_SUBST(build_exeext) AC_SUBST(host_exeext) AC_SUBST(float_h_file) -AC_SUBST(will_use_collect2) -AC_SUBST(maybe_use_collect2) AC_SUBST(cc_set_by_configure) AC_SUBST(stage_prefix_set_by_configure) AC_SUBST(install) diff --git a/gcc/cp/.cvsignore b/gcc/cp/.cvsignore deleted file mode 100755 index c1033b2..0000000 --- a/gcc/cp/.cvsignore +++ /dev/null @@ -1,10 +0,0 @@ -Makefile -parse.c -parse.h -parse.output -stamp-parse -y.tab.c -*.bb -*.bbg -*.da -*.gcov diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog deleted file mode 100755 index 342442f..0000000 --- a/gcc/cp/ChangeLog +++ /dev/null @@ -1,14199 +0,0 @@ -1999-09-07 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (binfo_for_vtable): Use CLASSTYPE_VFIELD_PARENT. - (dfs_bfv_queue_p, dfs_bfv_helper, struct bfv_info): Remove. - -1999-03-03 Jason Merrill <jason@yorick.cygnus.com> - - * class.c, decl2.c, method.c, pt.c: Add 'static' to make SunOS 4 - cc happy. - -1999-02-25 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c: Check ANSI_PROTOTYPES instead of __STDC__. - -1999-02-04 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu> - - * pt.c (unify): Call coerce_template_parms with the COMPLAIN flag - turned off. - -1999-02-04 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (retrofit_lang_decl): Split out... - (build_lang_decl): From here. - * decl.c (pushdecl): Call it for functions generated by the middle - end that don't have DECL_LANG_SPECIFIC. - * cp-tree.h: Declare it. - - * decl2.c: Remove flag_init_priority. Always enable initp stuff. - (start_objects, finish_objects): Only use special - init_priority code if the user specified a priority. - (do_ctors, do_dtors): Use DEFAULT_INIT_PRIORITY for the non-initp - objects. - -1999-02-01 Mark Mitchell <mark@markmitchell.com> - - * pt.c (tsubst, case TYPENAME_TYPE): Check TYPE_BEING_DEFINED - before calling complete_type_or_else. - -1999-01-28 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (struct tree_binding): Replace scope field with a union. - (BINDING_SCOPE): Adjust. - * decl.c (BINDING_LEVEL): Adjust. - -1999-01-26 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Set up the DECL_INITIAL of - member constants. - - * init.c (expand_member_init): Pull out TYPE_MAIN_VARIANT in - a ctor initializer. - - * tree.c (equal_functions): Fix name in prototype. - - * decl.c (push_local_binding): Add FLAGS argument. - (pushdecl, push_overloaded_decl): Pass it. - * decl2.c (do_local_using_decl): Likewise. - * cp-tree.h: Adjust prototype. - * decl.c (poplevel): Fix logic. - - * decl.c (push_local_binding): Also wrap used decls in a TREE_LIST. - (poplevel): Handle that. Fix logic for removing TREE_LISTs. - (cat_namespace_levels): Don't loop forever. - -1999-01-25 Richard Henderson <rth@cygnus.com> - - * typeck.c (build_reinterpret_cast): Fix typo in duplicated test. - -1999-01-25 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (resolve_address_of_overloaded_function): Mark the - chosen function used. - - * call.c (build_call): Make sure that a function coming in has - been marked used already. - * decl.c (expand_static_init): Call mark_used instead of - assemble_external. - * except.c (call_eh_info, do_pop_exception, expand_end_eh_spec, - alloc_eh_object, expand_throw): Likewise. - * init.c (build_builtin_delete_call): Likewise. - * rtti.c (call_void_fn, get_tinfo_fn, build_dynamic_cast_1, - expand_si_desc, expand_class_desc, expand_ptr_desc, expand_attr_desc, - expand_generic_desc): Likewise. - -1999-01-25 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * tree.c (equal_functions): New function. - (ovl_member): Call it. - -1999-01-24 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Fix conversion of 0 to pmf. - -1999-01-25 Martin von Loewis <loewis@informatik.hu-berlin.de> - - * decl.c (decls_match): Return 1 if old and new are identical. - (push_overloaded_decl): Set OVL_USED when PUSH_USING. - -1999-01-24 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_function): Make member functions one_only on windows. - * decl2.c (import_export_decl): Likewise. - - * decl.c (grokdeclarator): Don't complain about implicit int in - a system header. Change same-name field check to not complain in - a system header instead of within extern "C". - -1999-01-21 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (PUSH_GLOBAL): New macro. - (PUSH_LOCAL): Likewise. - (PUSH_USING): Likewise. - (namespace_bindings_p): Declare. - (push_overloaded_decl): Likewise. - * decl.c (push_overloaded_decl): Don't make it static. Check for - illegal declarations after using declarations here. - (namespace_bindings_p): Likewise. - (duplicate_decls): Don't consider declarations from different - namespaces to be the same. - (pushdecl): Use symbolic PUSH_ constants in calls to - push_overloaded_decl. - (push_overloaded_decl_1): Likewise. - * decl2.c (validate_nonmember_using_decl): Tweak `std' handling. - (do_nonmember_using_decl): Check for illegal using declarations - after ordinary declarations here. - (do_local_using_decl): Call pushdecl to insert declarations. - -1999-01-21 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Fix lang_c -> lang_name_c typo. - -1999-01-21 Mark Mitchell <mark@markmitchell.com> - - * tree.c (build_cplus_array_type_1): Don't call build_array_type - for types involving template parameters. - - * cp-tree.h (PARM_DECL_EXPR): Delete. - (convert_default_arg): Change prototype. - (check_default_argument): Declare. - (search_tree): Likewise. - * call.c (convert_default_arg): Take the function to which the - default argument belongs as a parameter, and do any necessary - instantiation here, instead of ... - (build_over_call): Here. - * decl.c (local_variable_p): New function. - (check_default_argument): Likewise, split out and tidied from ... - (grokparms): Here. - * error.c (dump_expr): Don't set PARM_DECL_EXPR. - * pt.c (tsubst_call_declarator_parms): New function. - (for_each_template_parm): Handle ARRAY_REFs. Do the obvious thing - with CALL_EXPRs, rather than trying to be clever. - (tsubst): Use tsubst_call_declarator_parms. - * tree.c (search_tree): Don't make it static. - * typeck.c (convert_arguments): Use new interface to - convert_default_arg. - -1999-01-20 Mark Mitchell <mark@markmitchell.com> - - * error.c (dump_function_decl): Don't print the argument types for - a function when the verbosity level is negative. - - * call.c (build_over_call): Check format attributes at call-time. - - * pt.c (tsubst_copy): Fix comment. - (unify): Don't allow unification with variable-sized arrays. - - * semantics.c (finish_stmt_expr): When processing a template make - the BIND_EXPR long-lived. - -1999-01-19 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Make vtables comdat here. - (import_export_vtable): Not here. - -1999-01-18 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_component_ref): Wrap an OVERLOAD around a unique - non-static member function. - -1999-01-18 Nathan Sidwell <nathan@acm.org> - - * class.c (instantiate_type): Only diagnose illegal address of member - function if complaining. - - * decl.c (lookup_name_real): Remove duplicate code. - -1999-01-18 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (copy_template_template_parm): Use permanent_obstack. - -1999-01-18 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu> - - * pt.c (unify): Remove restrictions on deduction of argument - of template template parameters. - -1999-01-18 Nathan Sidwell <nathan@acm.org> - - * rtti.c (build_dynamic_cast_1): Resolve OFFSET_REF exprs. - - * class.c (resolve_address_of_overloaded_function): Show list of - all candidates, when none of them match. - -1999-01-18 Chip Salzenberg <chip@perlsupport.com> - - * typeck.c (comp_ptr_ttypes_reinterpret): Per ANSI, tighten up - definition of 'casting away const' in reinterpret_cast<>. - -1999-01-18 Graham <grahams@rcp.co.uk> - - * cvt.c: Add include for decl.h, remove extern for - static_aggregates which is now provided by decl.h. - - * Makefile.in (cvt.o): Add dependency for decl.h and missing - dependencies for convert.h and flags.h. - -1999-01-18 Nathan Sidwell <nathan@acm.org> - - * decl2.c (do_dtors): Set current location to that of the - decl, for sensible diagnostics and debugging. - (check_classfn): Issue `incomplete type' error, if - class is not defined. - -1999-01-16 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h: Add prototype for bound_pmf_p. - -1999-01-16 Jason Merrill <jason@yorick.cygnus.com> - Manfred Hollstein <manfred@s-direktnet.de> - - * decl.c (grokdeclarator): Don't make 'main(){}' an error with only - -Wreturn-type. - -1999-01-16 Nathan Sidwell <nathan@acm.org> - - * cp-tree.h (struct lang_type): Added has_mutable flag. - (CLASSTYPE_HAS_MUTABLE): New macro to access it. - (TYPE_HAS_MUTABLE_P): New macro to read it. - (cp_has_mutable_p): Prototype for new function. - * class.c (finish_struct_1): Set has_mutable from members. - * decl.c (cp_finish_decl): Clear decl's TREE_READONLY flag, if - it contains a mutable. - * typeck.c (cp_has_mutable_p): New function. - -1999-01-15 Mark Mitchell <mark@markmitchell.com> - - * pt.c (process_template_parm): Ignore top-level qualifiers on - non-type parameters. - - * decl.c (start_function): Use current_function_parms in the call - to require_complete_type_for_parms, not the probably empty - DECL_ARGUMENTS. - -1999-01-14 Jason Merrill <jason@yorick.cygnus.com> - - * semantics.c (finish_asm_stmt): Don't warn about redundant volatile. - - * decl2.c (import_export_class): MULTIPLE_SYMBOL_SPACES only means - that we don't suppress the other copies. - * lex.c (handle_cp_pragma): Likewise. - -1999-01-13 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Undo 1998-12-14 change. - * tree.c (build_cplus_array_type_1): Likewise. - * pt.c (instantiate_class_template): Remove misleading comment. - (tsubst_aggr_type): Substitute if there are template parameters, - regardless of whether or not they use template arguments. - (unify): Likewise, but for unification. - -1999-01-12 Richard Henderson <rth@cygnus.com> - - * cp-tree.h (flag_permissive): Declare extern. - -1999-01-06 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (IDENTIFIER_TYPENAME_P): Use OPERATOR_TYPENAME_FORMAT - here. - (lang_type): Add is_partial_instantiation. Decrease width of - dummy. - (PARTIAL_INSTANTIATION_P): New macro. - (OPERATOR_TYPENAME_P): Remove. - * decl.c (unary_op_p): Use IDENTIFIER_TYPENAME_P, not - OPERATOR_TYPENAME_P. - (grok_op_properties): Likewise. - * friend.c (do_friend): Handle friends that are member functions - correctly. - * lex.c (init_parse): Use OPERATOR_TYPENAME_FORMAT. - * pt.c (instantiate_class_template): Rework for clarity. Avoid - leaving TYPE_BEING_DEFINED set in obscure cases. Don't do - any more partial instantiation than is absolutely necessary for - implicit typename. Set PARTIAL_INSTANTIATION_P. - (tsubst_decl): Use IDENTIFIER_TYPENAME_P. - * semantics.c (begin_class_definition): Handle partial - specializations of a type that was previously partially - instantiated. - -Wed Jan 6 03:18:53 1999 Mark Elbrecht <snowball3@usa.net. - - * g++spec.c (LIBSTDCXX): Provide default definition. - (lang_specific_driver): Use LIBSTDCXX instead of "-lstdc++". - -Tue Jan 5 22:11:25 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Make-lang.in (g++.o): Depend on prefix.h. - -1999-01-04 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (bound_pmf_p): New fn. - * typeck.c (build_c_cast): Use it. - - * decl.c (grok_op_properties): Use same_type_p. - -Tue Dec 22 15:09:25 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (cvt.o): Depend on toplev.h. - - * cp-tree.h (check_template_shadow, pod_type_p): Add prototypes. - - * cvt.c: Include toplev.h. - - * except.c (get_eh_caught, get_eh_handlers): Hide prototypes and - definitions. - - * init.c (expand_vec_init): Initialize variable `itype'. - - * lex.c (yyerror): Cast the argument passed to a ctype function to - an unsigned char. - - * method.c (build_mangled_C9x_name): Wrap prototype and definition - in "HOST_BITS_PER_WIDE_INT >= 64". - - * typeck.c (build_binary_op): Mark parameter `convert_p' with - ATTRIBUTE_UNUSED. - -1998-12-22 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (TYPE_RAISES_EXCEPTIONS): Improve documentation. - * tree.c (build_exception_variant): Don't crash on empty throw - specs. - -1998-12-18 DJ Delorie <dj@cygnus.com> - - * cvt.c (convert_to_reference): Check for both error_mark_node - and NULL_NODE after call to convert_for_initialization. - -1998-12-17 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (interesting_scope_p): New fn. - (dump_simple_decl): Use it. - (dump_expr, case CONSTRUCTOR): Force a & for a PMF. - (dump_expr, case OFFSET_REF): Print ->* if appropriate. - -1998-12-16 Mark Mitchell <mark@markmitchell.com> - - * class.c (resolve_address_of_overloaded_function): Do conversion - to correct type here, rather than ... - (instantiate_type): Here. - - * cp-tree.h (DECL_TEMPLATE_PARM_P): New macro. - (DECL_TEMPLATE_TEMPLATE_PARM_P): Use it. - (decl_template_parm_p): Remove. - * decl.c (pushdecl): Don't set DECL_CONTEXT for a template - paramter. - * lex.c (do_identifier): Use DECL_TEMPLATE_PARM_P. - * pt.c (push_inline_template_parms_recursive): Set it. - (decl_template_parm_p): Remove. - (check_template_shadow): Use DECL_TEMPLATE_PARM_P. - (process_template_parm): Set it. - -Wed Dec 16 16:33:58 1998 Dave Brolley <brolley@cygnus.com> - - * lang-specs.h (default_compilers): Pass -MD, -MMD and -MG to cc1plus - if configured with cpplib. - -1998-12-15 Mark Mitchell <mark@markmitchell.com> - - * decl.c (poplevel): Make sure ns_binding is initialized. - - * decl.c (finish_function): Undo inadvertant change in previous - patch. - -1998-12-14 Mark Mitchell <mark@markmitchell.com> - - * class.c (pushclass): Tweak handling of class-level bindings. - (resolve_address_of_overloaded_function): Update pointer-to-member - handling. - (instantiate_type): Likewise. - * cvt.c (cp_convert_to_pointer): Likewise. - * decl.c (pop_binding): Take the DECL to pop, not just the name. - Deal with `struct stat' hack. - (binding_level): Add to documentation. - (push_binding): Clear BINDING_TYPE. - (add_binding): New function. - (push_local_binding): Use it. - (push_class_binding): Likewise. - (poplevel): Adjust calls to pop_binding. - (poplevel_class): Likewise. - (pushdecl): Adjust handling of TYPE_DECLs; add bindings for hidden - declarations to current binding level. - (push_class_level_binding): Likewise. - (push_overloaded_decl): Adjust handling of OVERLOADs in local - bindings. - (lookup_namespace_name): Don't crash when confronted with a - TEMPLATE_DECL. - (lookup_name_real): Do `struct stat' hack in local binding - contexts. - (build_ptrmemfunc_type): Adjust documentation. - (grokdeclarator): Don't avoid building real array types when - processing templates unless really necessary. - (finish_method): Adjust calls to pop_binding. - * decl2.c (reparse_absdcl_as_expr): Recursively call ourselves, - not reparse_decl_as_expr. - (build_expr_from_tree): Deal with a template-id as the function to - call in a METHOD_CALL_EXPR. - * pt.c (convert_nontype_argument): Tweak pointer-to-member handling. - (maybe_adjust_types_For_deduction): Don't do peculiar things with - METHOD_TYPEs here. - (resolve_overloaded_unification): Handle COMPONENT_REFs. Build - pointer-to-member types where necessary. - * tree.c (build_cplus_array_type_1): Don't avoid building real - array types when processing templates unless really necessary. - (build_exception_variant): Compare the exception lists correctly. - -1998-12-13 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.def (CPLUS_BINDING): Update documentation. - * cp-tree.h (LOCAL_BINDING_P): New macro. - (lang_identifier): Rename local_value to bindings. - (tree_binding): Make `scope' of type `void*', not `tree'. - (BINDING_SCOPE): Update documentation. - (IDENTIFIER_LOCAL_VALUE): Remove. - (IDENTIFIER_CLASS_VALUE): Document. - (IDENTIFIER_BINDING): New macro. - (IDENTIFIER_VALUE): Likewise. - (TIME_IDENTIFIER_TIME): Likewise. - (TIME_IDENTIFIER_FILEINFO): Likewise. - (IMPLICIT_TYPENAME_P): Likewise. - (set_identifier_local_value): Remove. - (push_local_binding): New function. - (push_class_binding): Likewise. - * class.c (pushclass): Update comments; use push_class_binding. - * decl.c (set_identifier_local_value_with_scope): Remove. - (set_identifier_local_value): Likewise. - (push_binding): New function. - (pop_binding): Likewise. - (binding_level): Update documentation. Remove shadowed. - (BINDING_LEVEL): New macro. - (free_binding_nodes): New variable. - (poplevel): Adjust for new name-lookup scheme. Don't mess up - BLOCK_VARs when doing for-scope extension. Remove effectively - dead code. - (pushlevel_class): Tweak formatting. - (poplevel_class): Adjust for new name-lookup scheme. - (print_binding_level): Likewise. - (store_bindings): Likewise. - (pushdecl): Likewise. - (pushdecl_class_level): Likewise. - (push_class_level_binding): Likewise. - (push_overloaded_decl): Update comments. Adjust for new - name-lookup scheme. - (lookup_name_real): Likewise. - (lookup_name_current_level): Likewise. - (cp_finish_decl): Likewise. - (require_complete_types_for_parms): Likewise. Remove misleading - #if 0'd code. - (grok_parms): Likewise. Don't call - require_complete_types_for_parms here. - (grok_ctor_properties): Don't treat templates as copy - constructors. - (grop_op_properties): Or as assignment operators. - (start_function): Document. Adjust for new name-lookup scheme. - (finish_function): Likewise. - * decl2.c (do_local_using_decl): Use push_local_binding. - * lex.c (begin_definition_of_inclass_inline): New function, split - out from ... - (do_pending_inlines): Here, and ... - (process_next_inline): Here. - (get_time_identifier): Use TIME_IDENTIFIER_* macros. - (init_filename_times): Likewise. - (extract_interface_info): Likewise. - (ste_typedecl_interface_info): Likewise. - (check_newline): Likewise. - (dump_time_statistics): Likewise. - (handle_cp_pragma): Likewise. - (do_identifier): Adjust for new name-lookup scheme. - * parse.y (function_try_block): Return ctor_initializer_opt value. - (fndef): Use it. - (fn.defpen): Pass appropriate values to start_function. - (pending_inline): Use functor_try_block value, and pass - appropriate values to finish_function. - * pt.c (is_member_template): Update documentation; remove handling - of FUNCTION_DECLs. As per name, this function should deal only in - TEMPLATE_DECLs. - (decl_template_parm_p): Change name of olddecl parameter to decl. - (check_template_shadow): Adjust for new name-lookup scheme. - (lookup_template_class): Likewise. - (tsubst_decl): Tweak so as not to confuse member templates with - copy constructors and assignment operators. - (unify): Handle UNION_TYPEs. - * ptree.c (print_lang_identifier): Adjust for new name-lookup scheme. - (lang_print_xnode): Adjust for new name-lookup scheme. - * typeck.c (mark_addressable): Likewise. - (c_expand_return): Likewise. - -1998-12-08 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Allow field with same name as class - in extern "C". - - * decl.c (lookup_name_real): Don't limit field lookup to types. - * class.c (check_member_decl_is_same_in_complete_scope): No error - if icv and x are the same. - * lex.c (do_identifier): Tweak error message. - -1998-12-10 Mark Mitchell <mark@markmitchell.com> - - * decl.c (start_enum): Use push_obstacks, not - end_temporary_allocation. - (finish_enum): Call pop_obstacks. - -1998-12-10 Mark Mitchell <mark@markmitchell.com> - - * class.c (instantiate_type): Return error_mark_node rather than - junk. - -1998-12-09 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (most_specialized_instantiation): New function. - (print_candidates): Likewise. - * class.c (validate_lhs): Remove. - (resolve_address_of_overloaded_function): New function, split out - and then substantially reworked, from ... - (instantiate_type): Use it. Simplify. - * cvt.c (convert_to_reference): Complain when caller has indicated - that's the right thing to do. Don't crash if instantiate_type - fails. - * pt.c: Substitute `parameters' for `paramters' throughout. - (print_candidates): Don't make it static. - (most_specialized_instantiation): Split out from ... - (most_specialized): Here. - -Wed Dec 9 15:33:01 1998 Dave Brolley <brolley@cygnus.com> - - * lex.c (lang_init_options): Initialize cpplib. - * decl2.c (parse_options,cpp_initialized): Removed. - (lang_decode_option): Move initialization of cpplib to - lang_init_options. - -1998-12-09 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Update the name of the TEMPLATE_DECL, as - well as the TYPE_DECL, when a typedef name is assigned to a - previously anonymous type. - -1998-12-08 Andrew MacLeod <amacleod@cygnus.com> - - * cp/except.c (call_eh_info): use __start_cp_handler instead of - __cp_eh_info for getting the eh info pointer. Add table_index to - field list. - (push_eh_cleanup): Don't increment 'handlers' data field. - (process_start_catch_block): Don't set the 'caught' field. - - * cp/exception.cc (CP_EH_INFO): New macro for getting the - exception info pointer within library routines. - (__cp_eh_info): Use CP_EH_INFO. - (__start_cp_handler): Get exception info pointer, set caught field, - and increment the handlers field. Avoids this being done by handlers. - (__uncatch_exception, __check_eh_spec): Use CP_EH_INFO macro. - (uncaught_exception): Use CP_EH_INFO macro. - -Tue Dec 8 10:48:21 1998 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (cxxmain.o): Depend on $(DEMANGLE_H), not demangle.h - -Mon Dec 7 17:56:06 1998 Mike Stump <mrs@wrs.com> - - * lex.c (check_newline): Add support for \ as `natural' - characters in file names in #line to be consistent with #include - handling. We support escape prcessing in the # 1 "..." version of - the command. See also support in cp/lex.c. - -1998-12-07 Zack Weinberg <zack@rabi.phys.columbia.edu> - - * cp/decl2.c: s/data/opts/ when initializing cpp_reader - structure. - -1998-12-07 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (build_typename_type): Set DECL_ARTIFICIAL. - - * error.c (dump_simple_decl): Also print namespace context. - (dump_function_decl): Likewise. - - * decl2.c (ambiguous_decl): Don't print old value if it's - error_mark_node. - - * decl.c (lookup_name_real): Fix handling of local types shadowed - by a non-type decl. Remove obsolete code. - * cp-tree.h (DECL_FUNCTION_SCOPE_P): New macro. - - * lang-options.h: Add -fpermissive. - * decl2.c: Likewise. - * cp-tree.h: Add flag_permissive. - * decl.c (init_decl_processing): If neither -fpermissive or -pedantic - were specified, set flag_pedantic_errors. - * call.c (build_over_call): Turn dropped qualifier messages - back into pedwarns. - * cvt.c (convert_to_reference): Likewise. - * typeck.c (convert_for_assignment): Likewise. - -1998-12-05 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (coerce_new_type): Use same_type_p. - (coerce_delete_type): Likewise. - - * call.c (check_dtor_name): Return 1, not error_mark_node. - -1998-12-04 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (handle_cp_pragma): Disable #pragma interface/implementation - if MULTIPLE_SYMBOL_SPACES. - - * pt.c (check_template_shadow): New fn. - * decl2.c (grokfield): Use it. - * decl.c (pushdecl): Likewise. - (pushdecl_class_level): Likewise. - (start_method): Likewise. - (xref_tag): Don't try to use 't' if we're defining. - - * call.c (check_dtor_name): Just return an error_mark_node. - * pt.c (lookup_template_class): Complain about using non-template here. - * parse.y (apparent_template_type): Not here. - - * pt.c (check_explicit_specialization): Complain about specialization - with C linkage. - - * lang-options.h: Add -f{no-,}implicit-inline-templates. - - * pt.c (convert_nontype_argument): Don't assume that any integer - argument is intended to be a constant-expression. - -1998-12-03 Mark Mitchell <mark@markmitchell.com> - - * class.c (handle_using_decl): Fix comment. Don't lookup - constructors in base classes. - (validate_lhs): Fix typo in comment. - * search.c (lookup_field_1): Don't return a USING_DECL. - - * cp-tree.h (DECL_ACCESS): Improve documentation. - - * decl.c (expand_static_init): Don't set the initialization-done - flag until the initialization is done. - -1998-12-02 Mark Mitchell <mark@markmitchell.com> - - * decl2.c (validate_nonmember_using_decl): Complain about using - declarations for class members. - -1998-11-29 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (process_init_constructor): Use same_type_p. - - * decl.c (check_tag_decl): Don't warn about null decl inside a - class. - - * pt.c (unify, case OFFSET_TYPE): Pass down 'strict' rather than - UNIFY_ALLOW_NONE. - (convert_nontype_argument): Use TYPE_PTRMEMFUNC_FN_TYPE. - (resolve_overloaded_unification): Strip baselinks. - -Fri Nov 27 13:07:23 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * g++spec.c: Don't prototype xmalloc. - -1998-11-25 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_throw): Use TYPE_PTR_P to check for pointers. - - * decl.c (check_tag_decl): Do complain about null friend decl at - file scope. - -1998-11-25 Andreas Schwab <schwab@issan.cs.uni-dortmund.de> - - * lex.c (make_lang_type): Clear the whole struct lang_type, not - only the first multiple of sizeof (int). - -1998-11-24 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): An explicit specialization of a static data - member is only a definition if it has an initializer. - - * except.c (expand_throw): Use cp_finish_decl for the throw temp. - * cvt.c (build_up_reference): Pass DIRECT_BIND down into - cp_finish_decl. - * init.c (expand_default_init): Check for DIRECT_BIND instead of - DECL_ARTIFICIAL. - - * call.c (build_over_call): Use build_decl. - - * except.c (expand_throw): Just use convert, not - build_reinterpret_cast. - - * lex.c (handle_generic_pragma): Use token_buffer. - - * decl.c (check_tag_decl): Don't complain about null friend decl. - -1998-11-24 Dave Pitts <dpitts@cozx.com> - - * Make-lang.in (DEMANGLER_PROG): Move the output argumnts to the - first position. - * lex.c (check_newline): Use ISALPHA. - (readescape): Use ISGRAPH. - (yyerror): Use ISGRAPH. - -1998-11-24 Nathan Sidwell <nathan@acm.org> - - * search.c (get_abstract_virtuals): Do not use initial - CLASSTYPE_ABSTRACT_VIRTUALS. - * typeck2.c (abstract_virtuals_error): Show location of abstract - declaration. - * call.c (build_new_method_call): Use - CLASSTYPE_ABSTRACT_VIRTUAL, rather than recalculate. - * class.c (finish_struct_bits): Don't bother working out whether - get_abstract_virtuals will do anything, just do it. - -1998-11-24 Graham <grahams@rcp.co.uk> - - * typeck.c (build_component_ref): Remove unused statement. - -1998-11-24 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (add_method): Catch invalid overloads. - - * class.c (add_method): Build up OVERLOADs properly for conversion ops. - * search.c (lookup_conversions): Handle getting real OVERLOADs. - (add_conversions): Likewise. Revert last change. - * call.c (add_conv_candidate): Pass totype to add_candidate instead - of fn. Don't add a new candidate if the last one was for the same - type. - (print_z_candidates): Handle getting a type as a function. - (joust): If we got two conversion candidates to the same type, - just pick one. - (build_object_call): Lose 'templates'. - (build_user_type_conversion_1): Handle getting real OVERLOADs. - -1998-11-23 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (process_init_constructor): If there are elements - that don't have initializers and they need to have constructors - run, supply them with initializers. - - * class.c (finish_struct_1): A class with a 0-width bitfield is - still empty. - -1998-11-23 Mark Mitchell <mark@markmitchell.com> - - * pt.c (instantiate_class_template): Don't try to figure out what - specialization to use for a partial instantiation. Correct - typos in a couple of comments. Avoid calling uses_template_parms - multiple times. - -1998-11-23 Benjamin Kosnik <bkoz@cygnus.com> - - * method.c (process_overload_item): Add call to - build_mangled_C9x_name for intTI_type_nodes. - (build_mangled_C9x_name): Add prototype, define. - * decl.c (init_decl_processing): Add names for - TImode_type_node. - -1998-11-23 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (named_class_head): Update CLASSTYPE_DECLARED_CLASS. - - * class.c (finish_struct_1): Set things up for 0-width bitfields - like we do for others. - - * decl.c (check_tag_decl): New fn. - (shadow_tag): Split out from here. - * decl2.c (grok_x_components): Call it. - -1998-11-22 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c: Lose warn_about_return_type. - (grokdeclarator): Always complain about implicit int, except for - `main () { ... }'. - - * decl.c (tag_name): New fn. - (xref_tag): Complain about using typedef-name after class-key. - - * init.c (expand_vec_init): Also keep going if from_array. - - * tree.c (is_overloaded_fn): Also handle the output of - build_offset_ref. - - * decl.c (grokdeclarator): Use constructor_name when comparing - field name against enclosing class. - * class.c (finish_struct_anon): Likewise. - -1998-11-22 Mark Mitchell <mark@markmitchell.com> - - * decl.c (poplevel): Remove code to handle KEEP == 2. - (finish_function): Don't confuse BLOCK-order when - processing a destructor. - -1998-11-21 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (require_complete_types_for_parms): Call layout_decl - after we've completed the type. - -1998-11-21 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl2.c (validate_nonmember_using_decl): Allow using templates - from the global namespace. - -1998-11-21 Jason Merrill <jason@yorick.cygnus.com> - - Handle specifying template args to member function templates. - * tree.c (build_overload): Always create an OVERLOAD for a template. - * search.c (add_conversions): Handle finding an OVERLOAD. - * decl2.c (check_classfn): Likewise. - * lex.c (identifier_type): See through a baselink. - * parse.y (do_id): Don't call do_identifier if we got a baselink. - * class.c (instantiate_type, case TREE_LIST): Recurse. - - * decl.c (grokdeclarator): Allow a boolean constant for array - bounds, odd as that sounds. - - * pt.c (unify): Be more strict about non-type parms, except for - array bounds. - (UNIFY_ALLOW_INTEGER): New macro. - -1998-11-19 Manfred Hollstein <manfred@s-direktnet.de> - - * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir). - -1998-11-19 Jason Merrill <jason@yorick.cygnus.com> - - * semantics.c (begin_class_definition): Call - maybe_process_partial_specialization before push_template_decl. - Don't call push_template_decl for a specialization. - * search.c (lookup_field): Do return a member template class. - * decl2.c (handle_class_head): Handle member template classes. - - * decl.c (grokdeclarator): A parm type need not be complete. - - * pt.c (convert_nontype_argument): Fix thinko. - -1998-11-18 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (PTRMEM_CST_CLASS): Fix typo. - (global_delete_fndecl): New variable. - * decl.c (global_delete_fndecl): Define it. - (init_decl_processing): Set it. - * init.c (build_builtin_delete_call): Use it. - * tree.c (mapcar): Recursively call mapcar for the type of EXPR - nodes. - -1998-11-18 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (cplus_expand_expr_stmt): Always complain about unresolved - type. - - * tree.c (lvalue_p_1): An INDIRECT_REF to a function is an lvalue. - * call.c (build_object_call): Also support references to functions. - * typeck.c (convert_for_initialization): Don't decay a function - if the target is a reference to function. - - * search.c (add_conversions): Get all the overloads from a class. - - * decl.c (grok_ctor_properties): Complain about any constructor - that will take a single arg of the class type by value. - - * typeck2.c (build_functional_cast): Can't create objects of - abstract classes this way. - * cvt.c (ocp_convert): Likewise. - - * decl.c (grokfndecl): Member functions of local classes are not - public. - -1998-11-18 Mark Mitchell <mark@markmitchell.com> - - * Make-lang.in (cc1plus): Add dependency on hash.o. - -1998-11-18 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (get_abstract_virtuals): Complain about virtuals with - no final overrider. - * typeck2.c (abstract_virtuals_error): Remove handling for virtuals - with no final overrider. - * class.c (override_one_vtable): Don't set DECL_ABSTRACT_VIRTUAL_P - on virtuals with no final overrider. - - * lex.c (reinit_parse_for_block): Add a space after the initial ':'. - - * class.c (finish_struct_1): Don't remove zero-width bit-fields until - after layout_type. - - * friend.c (do_friend): Don't set_mangled_name_for_decl. - - * class.c (finish_struct_anon): Complain about non-fields. - * decl2.c (build_anon_union_vars): Likewise. - - * decl.c (grokdeclarator): Normal data members can't have the same - name as the class, either. - * class.c (finish_struct_anon): Neither can members of an - anonymous union. - -1998-11-17 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (TYPE_ALIAS_SET): Document language-dependent uses. - (TYPE_BINFO): Likewise. - (IS_AGGR_TYPE): Tweak. - (SET_IS_AGGR_TYPE): New macro. - (CLASS_TYPE_P): Tweak. - (lang_type): Group mark bitfields together. Remove linenum. - (CLASSTYPE_SOURCE_LINE): Remove macro. - (CLASSTYPE_MARKED_N): New macro. - (SET_CLASSTYPE_MARKED_N): Likewise. - (CLEAR_CLASSTYPE_MARKED_N): Likewise. - (CLASS_TYPE_MARKED_*): Use them. - (SET_CLASSTYPE_MARKED_*): Likewise. - (CLEAR_CLASSTYPE_MARKED_*): Likewise. - (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO): Likewise. - (TYPE_TEMPLATE_INFO): Handle TEMPLATE_TEMPLATE_PARMs as well. - (TYPENAME_TYPE_FULLNAME): Use TYPE_BINFO rather than CLASSTYPE_SIZE. - * class.c (class_cache_obstack): New variable. - (class_cache_firstobj): Likewise. - (finish_struct): Don't set CLASSTYPE_SOURCE_LINE. - (pushclass): Free the cache, when appropriate. - (popclass): Tidy. - (maybe_push_cache_obstack): Use class_cache_obstack. - * decl.c (include hash.h). - (typename_hash): New function. - (typename_compare): Likewise. - (build_typename_type): Check the hash table to avoid creating - duplicates. - (build_ptrmemfunc_type): Use SET_IS_AGGR_TYPE. - (grokdeclarator): Use CLASS_TYPE_P. - (xref_basetypes): Likewise. - (start_function): Likewise. Don't put current_class_ref on the - permanent obstack. - * error.c (dump_type_real): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO - and TYPE_TI_ARGS. - * lex.c (note_got_semicolon): Use CLASS_TYPE_P. - (make_lang_type): Don't create TYPE_LANG_SPECIFIC and associated - fields for types other than class types. Do clear TYPE_ALIAS_SET - for types other than class types, though. - * method.c (build_overload_identifier): Use CLASS_TYPE_P and - TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. - * pt.c (process_template_parm): Don't set - CLASSTYPE_GOT_SEMICOLON. - (lookup_template_class) Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. - Coerce arguments on the momentary obstack. - (for_each_template_parm): Use TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. - (instantiate_class_template): Calculate template arguments on the - momentary obstack. Tidy. - (tsubst_template_arg_vector): Use make_temp_vec. - (tsubst_aggr_type): Put template arguments on the momentary - obstack. - (tsubst_decl): Likewise. - (tsubst): Copy the array bounds index to the permanent obstack - before building index types. Use new macros. - (unify): Use new macros. - (do_type_instantiation): Likewise. - * search.c (lookup_fnfields_1): Use new macros. - (dfs_pushdecls): Build envelopes on the cache obstack. - (dfs_compress_decls): Use new macros. - (push_class_decls): Build on the cache obstack. - * semantics.c (finish_typeof): Don't set CLASSTYPE_GOT_SEMICOLON. - * sign.c (build_signature_pointer_or_reference_type): Use - SET_IS_AGGR_TYPE. - * tree.c (make_binfo): Check CLASS_TYPE_P. - (copy_template_template_parm): Adjust. - (make_temp_vec): Use push_expresion_obstack. - * typeck.c (complete_type): Use new macros. - (comptypes): Likewise. - -1998-11-17 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Add diagnostics for invalid array, reference - and pointer to member types. - -1998-11-16 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (my_friendly_abort): Don't fatal twice in a row. - - * typeck.c (c_expand_start_case): Use build_expr_type_conversion. - Simplify. - - * parse.y (structsp): Fix cut-and-paste error. - - * init.c (build_new): Complain about non-integral size. - - * parse.y (unary_expr): Complain about defining types in sizeof. - - * typeck.c (expr_sizeof): Complain about sizeof an overloaded fn. - - * rtti.c (build_x_typeid): Complain about typeid without - including <typeinfo>. - (get_typeid): Likewise. Complain about typeid of incomplete type. - (get_tinfo_fn_dynamic): Likewise. - (get_typeid_1): Not static anymore. - * except.c (build_eh_type_type): Use get_typeid_1. - - * rtti.c (build_dynamic_cast_1): Give errors for dynamic_cast to - ambiguous or private bases. Fix warning for reference cast. - -1998-11-16 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (DECL_TEMPLATE_INSTANTIATED): New macro. - * decl.c (duplicate_decls): Remove special-case code to deal with - template friends, and just do the obvious thing. - * pt.c (register_specialization): Tweak for clarity, and also to - clear DECL_INITIAL for an instantiation before it is merged with a - specialization. - (check_explicit_specialization): Fix indentation. - (tsubst_friend_function): Handle both definitions in friend - declaration and outside friend declarations. - (tsubst_decl): Don't clear DECL_INITIAL for an instantiation. - (regenerate_decl_from_template): Tweak accordingly. - (instantiate_decl): Likewise. - -1998-11-16 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (cplus_expand_expr_stmt): Promote warning about naked - member function reference to error. - * cvt.c (ocp_convert): Complain about converting an overloaded - function to void. - - * init.c (build_offset_ref): Just return a lone static member - function. - - * decl.c (cp_finish_decl): Only complain about real CONSTRUCTORs, - not internal ones. - - * typeck.c (build_binary_op_nodefault): Improve error handling. - - * decl.c (grokfndecl): Complain about making 'main' a template. - - * typeck.c (string_conv_p): Don't convert from wchar_t[] to char*. - - * call.c (build_method_call): Handle a BIT_NOT_EXPR around a - TYPE_DECL in a template. - -1998-11-15 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (my_friendly_abort): Add URL in the other case, too. - - * decl.c (struct cp_function): Add named_label_uses. - (push_cp_function_context): Save it. - (pop_cp_function_context): Restore it. - (define_label): Also complain about jumping into the scope of - non-POD objects that don't have constructors. - * tree.c (pod_type_p): New fn. - - * pt.c (instantiate_class_template): Clear TYPE_BEING_DEFINED sooner. - * rtti.c (synthesize_tinfo_fn): Call import_export_decl here. - (get_tinfo_fn): Not here. - * repo.c (repo_get_id): Abort if we get called for an incomplete - type. - -1998-11-13 Mark Mitchell <mark@markmitchell.com> - - * except.c (expand_throw): Make sure first argument to - __cp_push_exception is of type `void*' to avoid spurious error - messages. - -1998-11-11 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (try_one_overload): Take orig_targs again. Only check for - mismatches against them; we don't care what a previous call found. - (resolve_overloaded_unification): Adjust. - - * search.c (lookup_field): Don't return anything for a non-type - field from a dependent type. - * decl.c (grokdeclarator): Resolve SCOPE_REFs of the current class - in an array declarator. - (start_decl): Push into the class before looking for the field. - -1998-11-08 Mark Mitchell <mark@markmitchell.com> - - * method.c (build_overload_value): Handle REFERENCE_TYPE. - -1998-11-08 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl.c (grokdeclarator): Allow namespace-scoped members if they - are friends. - -1998-11-08 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_decl): Don't mess with the global value of an - un-mangled DECL_ASSEMBLER_NAME. - -1998-11-03 Christopher Faylor <cgf@cygnus.com> - - * decl.c (init_decl_processing): Remove CYGWIN conditional - since CYGWIN is now able to deal with trapping signals. - -Sat Nov 7 15:48:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * cp-tree.h: Don't include gansidecl.h. - * exception.cc: Include gansidecl.h (since we don't include config.h) - * g++spec.c: Don't include gansidecl.h. - -1998-11-06 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (lang_decl_flags): Add defined_in_class. Decrease - size of dummy. - (DECL_DEFINED_IN_CLASS_P): New macro. - (TEMPLATE_PARMS_FOR_INLINE): Document. - (check_static_variable_definition): New function. - * decl.c (cp_finish_decl): Set DECL_DEFINED_IN_CLASS_P, if - appropriate. - (check_static_variable_definition): Split out from ... - (grokdeclarator): Here. - * pt.c (check_default_tmpl_args): New function, split out from ... - (push_template_decl_real): Here. - (instantiate_template): Fix comment. - -1998-11-04 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (CP_TYPE_CONST_P): Make {0,1}-valued. - (CP_TYPE_VOLATILE_P): Likewise. - (CP_TYPE_RESTRICT_P): Likewise. - -1998-11-03 Mark Mitchell <mark@markmitchell.com> - - * pt.c (tsubst): Use build_index_type, not build_index_2_type. - -1998-11-02 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (instantiate_type): Be more helpful. - - * decl2.c (import_export_decl): Call import_export_class. - - * cp-tree.h (EMPTY_CONSTRUCTOR_P): Check !TREE_HAS_CONSTRUCTOR. - * decl2.c (build_expr_from_tree): Propagate TREE_HAS_CONSTRUCTOR. - * pt.c (tsubst_copy): Likewise. - -1998-11-02 Mark Mitchell <mark@markmitchell.com> - - * init.c (expand_vec_init): Fix off-by-one error. - -1998-11-02 Alexandre Oliva <oliva@dcc.unicamp.br> - - * parse.y (apparent_template_type): new type - (named_complex_class_head_sans_basetype): use it - * Makefile.in (CONFLICTS): one new conflict - * parse.c: Regenerated - -1998-11-01 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (COMPARE_STRICT): New macro. - (COMPARE_BASE): Likewise. - (COMPARE_RELAXED): Likewise. - (COMPARE_REDECLARATION): Likewise. - (same_type_p): Likewise. - (same_or_base_type_p): Likewise. - * call.c (standard_conversion): Use them, in place of comptypes - with numeric arguments. - (reference_binding): Likewise. - (convert_like): Likewise. - (build_over_call): Likewise. - (is_subseq): Likewise. - (is_properly_derived_from): Likewise. - (compare_ics): Likewise. - (joust): Likewise. - * class.c (delete_duplicate_fields_1): Likewise. - (resolves_to_fixed_type_p): Likewise. - (instantiate_type): Likewise. Remove #if 0'd code. - * decl.c (decls_match): Likewise. Use COMPARE_REDECLARATION here. - (pushdecl): Likewise. - (lookup_name_real): Likewise. - (grokdeclarator): Likewise. Check for illegal array declarations. - (grokparms): Likewise. - (grok_op_properties): Likewise. - * decl2.c (check_classfn): Likewise. - * friend.c (is_friend): Likewise. - (make_friend_class): Likewise. - * init.c (expand_aggr_init): Likewise. - (expand_vec_init): Likewise. - * pt.c (is_member_template_class): Remove declaration. - (is_specialization_of): Use COMPARE_* and new macros. - (comp_template_parms): Likewise. - (convert_nontype_argument): Likewise. - (coerce_template_template_parms): Likewise. - (template_args_equal): Likewise. - (lookup_template_class): Likewise. - (type_unification_real): Likewise. - (unify): Likewise. - (get_bindings_real): Likewise. - * search.c (covariant_return_p): Likewise. - (get_matching_virtual): Likewise. - * sig.c (match_method_types): Likewise. - * tree.c (vec_binfo_member): Likewise. - (cp_tree_equal): Likewise. - * typeck.c (common_type): Likewise. - (comp_array_types): Likewise. Get issues involving unknown array - bounds right. - (comptypes): Update comments. Use new flags. - (comp_target_types): Use new macros. - (compparms): Likewise. - (comp_target_parms): Likewise. - (string_conv_p): Likewise. - (build_component_ref): Likewise. - (build_indirect_ref): Likewise. - (build_conditional_expr): Likewise. - (build_static_cast): Likewise. - (build_reinterpret_cast): Likewise. - (build_const_cast): Likewise. - (build_modify_expr): Likewise. - (convert_for_assignment): Likewise. - (comp_ptr_ttypes_real): Likewise. - (ptr_reasonably_similar): Likewise. - (comp_ptr_ttypes_const): Likewise. - -1998-10-31 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (build_dynamic_cast_1): Fix cut-and-paste error. - -1998-10-30 Mark Mitchell <mark@markmitchell.com> - - * decl2.c (delete_sanity): Pass integer_zero_node, not - integer_two_node, to build_vec_delete. - * init.c (build_array_eh_cleanup): Remove. - (expand_vec_init_try_block): New function. - (expand_vec_init_catch_clause): Likewise. - (build_vec_delete_1): Don't deal with case that auto_delete_vec - might be integer_two_node anymore. - (expand_vec_init): Rework for initialization-correctness and - exception-correctness. - * typeck2.c (process_init_constructor): Make mutual exclusivity - of cases more obvious. - -1998-10-29 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): OK, only warn if not lexing. - Simplify suggested fix. - - * cp-tree.h (IDENTIFIER_MARKED): New macro. - * search.c (lookup_conversions): Use breadth_first_search. - (add_conversions): Avoid adding two conversions to the same type. - (breadth_first_search): Work with base binfos, rather - than binfos and base indices. - (get_virtual_destructor): Adjust. - (tree_has_any_destructor_p): Adjust. - (get_matching_virtual): Adjust. - - * pt.c (push_template_decl_real): Generalize check for incorrect - number of template parms. - (is_member_template_class): #if 0. - -1998-10-29 Richard Henderson <rth@cygnus.com> - - * Makefile.in (cc1plus): Put CXX_OBJS, and thence @extra_cxx_objs@, - last. - -1998-10-28 Zack Weinberg <zack@rabi.phys.columbia.edu> - - * lex.c: Call check_newline from lang_init always. After - calling cpp_start_read, set yy_cur and yy_lim to read from the - cpplib token buffer. - -1998-10-28 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (instantiate_type): Don't consider templates for a normal - match. - - * class.c (finish_struct_1): Don't complain about non-copy - assignment ops in union members. - - * class.c (build_vtable): Don't pass at_eof to import_export_vtable. - (prepare_fresh_vtable): Likewise. - (finish_struct_1): Don't call import_export_class. - * decl2.c (finish_vtable_vardecl): Do import/export stuff. - (finish_prevtable_vardecl): Lose. - (finish_file): Don't call it. - * pt.c (instantiate_class_template): Likewise. - * cp-tree.h: Remove it. - - * init.c (build_delete): Reset TYPE_HAS_DESTRUCTOR here. - * decl.c (finish_function): Not here. - (start_function): Do set DECL_INITIAL. - - * pt.c (push_template_decl_real): Complain about default template - args for enclosing classes. - - * call.c (add_function_candidate): Treat conversion functions - as coming from the argument's class. - * cp-tree.h (DECL_CONV_FN_P): New fn. - (DECL_DESTRUCTOR_P): Also check DECL_LANGUAGE. - * class.c (add_method): Use DECL_CONV_FN_P. - * decl2.c (check_classfn): Likewise. - * error.c (dump_function_name): Likewise. - (dump_function_decl): Likewise. - * pt.c (fn_type_unification): Likewise. - * search.c (add_conversions): Likewise. - -1998-10-27 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_identifier): Also generate LOOKUP_EXPR for RESULT_DECL. - * method.c (hack_identifier): Also check for using RESULT_DECL - from outer context. - -1998-10-27 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Use type_quals, rather than constp, - consistently. - -1998-10-27 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (standard_conversion): instantiate_type here. - (reference_binding): And here. - (implicit_conversion): Not here. - (build_op_delete_call): No need to cons up an OVERLOAD. - * cvt.c (cp_convert_to_pointer): instantiate_type here. - (convert_to_reference): And here. - * decl.c (grok_reference_init): Not here. - (grokparms): Or here. - * typeck2.c (digest_init): Or here. - * typeck.c (decay_conversion): Take the address of overloaded - functions, too. - (require_instantiated_type): Lose. - (convert_arguments): Don't handle unknown types here. - (build_c_cast): Likewise. - (build_binary_op): Gut. - (build_conditional_expr): Don't require_instantiated_type. - (build_modify_expr): Likewise. - (build_static_cast): Don't instantiate_type. - (build_reinterpret_cast): Likewise. - (build_const_cast): Likewise. - (convert_for_initialization): Likewise. - (build_ptrmemfunc): Use type_unknown_p. - (convert_for_assignment): Also do default_conversion on overloaded - functions. Hand them off to ocp_convert. - -1998-10-26 Mark Mitchell <mark@markmitchell.com> - - * error.c (dump_decl): Deal with TEMPLATE_DECLs that are - VAR_DECLs. Handle vtables whose DECL_CONTEXT is not a type. - - * class.c (finish_struct_1): Use build_cplus_array_type to build - array types. - * decl.c (init_decl_processing): Likewise. - * except.c (expand_end_eh_spec): Likewise. - * search.c (expand_upcast_fixups): Simplify very slightly. - -1998-10-26 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Complain about a variable using - constructor syntax coming back null from start_decl. - - * friend.c (make_friend_class): Complain about trying to make - a non-class type a friend. - - * decl.c (grokfndecl): Set DECL_INITIAL for a defn here. - (start_function): Not here. - -1998-10-26 Brendan Kehoe <brendan@cygnus.com> - - * decl.c (grokdeclarator): Disallow `explicit' in a friend declaration. - -1998-10-26 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (process_init_constructor): Only skip anonymous fields - if they are bitfields. - - * cp-tree.def (TYPEOF_TYPE): New code. - * error.c (dump_type_real): Handle it. - * pt.c (tsubst): Likewise. - * tree.c (search_tree): Likewise. - * semantics.c (finish_typeof): New fn. - * parse.y (typespec): Use it. - * cp-tree.h: Declare it. - -1998-10-26 Manfred Hollstein <manfred@s-direktnet.de> - - * cp-tree.h (FORMAT_VBASE_NAME): Make definition unconditional. - -1998-10-26 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (convert_arguments): Don't handle pmf references - specially. - - * init.c (build_member_call): Don't try to convert to the base type - if it's ambiguous or pedantic. - - * typeck2.c (check_for_new_type): Only depend on pedantic for - C-style casts. - -1998-10-25 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Set DECL_NONCONVERTING_P for all - non-converting constructors. - -1998-10-24 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * gxxint.texi: Correct documentation for n, N, Q, and B. - -1998-10-23 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * parse.y (condition): Convert VAR_DECL from reference to indirect - reference. - -1998-10-23 Andrew MacLeod <amacleod@cygnus.com> - - * exception.cc (__cp_pop_exception): Free the original exception - value, not the potentially coerced one. - -1998-10-23 Mark Mitchell <mark@markmitchell.com> - - * Makefile.in (hash.h): Run gperf when necessary. - - * cp-tree.h (CP_TYPE_READONLY): Remove. - (CP_TYPE_VOLATILE): Likewise. - (CP_TYPE_QUALS): New macro. - (CP_TYPE_CONST_P): Likewise. - (CP_TYPE_VOLATILE_P): Likewise. - (CP_TYPE_RESTRICT_P): Likewise. - (CP_TYPE_CONST_NON_VOLATILE_P): Likewise. - (cp_build_type_variant): Rename to ... - (cp_build_qualified_type): New function. - (c_apply_type_quals_to_decl): Declare. - (SIGNATURE_POINTER_NAME_FORMAT): Modify to allow `restrict'. - (SIGNATURE_REFERENCE_NAME_FORMAT): Likewise. - (cp_type_qual_from_rid): New function. - (compparms): Remove unused parameter. All callers changed. - (cp_type_quals): New function. - (at_least_as_qualified_p): Likewise. - (more_qualified_p): Likewise. - - * call.c (standard_conversion): Replace calls to - cp_build_type_variant with cp_build_qualified_type. Use - CP_TYPE_QUALS to get qualifiers and at_least_as_qualified_p to - compare them. Use CP_TYPE_* macros to check qualifiers. - (reference_binding): Likewise. - (implicit_conversion): Likewise. - (add_builtin_candidates): Likewise. - (build_over_call): Likewise. - * class.c (overrides): Compare all qualifiers, not just `const', - on method declarations. - * cvt.c (convert_to_reference): More CP_TYPE_QUALS conversion, etc. - (convert_pointer_to_real): Likewise. - (type_promotes_to): Likewise. - * decl.c (check_for_uninitialized_const_var): New function. - (init_decl_processing): More CP_TYPE_QUALS conversion, etc. - (cp_finish_decl): Use check_for_uninitialized_const_var. - (grokdeclarator): More CP_TYPE_QUALS conversion, etc. Update to - handle `restrict'. - (grok_ctor_properties): Likewise. - (grok_op_properties): Likewise. - (start_function): Likewise. - (rever_static_member_fn): Likewise. - * decl2.c (grok_method_quals): Likewise. - (grokfield): Likewise. - * error.c (dump_readonly_or_volatile): Rename to ... - (dump_qualifiers): New function. Handle `restrict'. - (dump_type_real): Use it. - (dump_aggr_type): Likewise. - (dump_type_prefix): Likewise. - (dump_type_suffix): Likewise. - (dump_function_decl): Likewise. - (cv_as_string): Likewise. - * gxx.gperf: Add __restrict and __restrict__. - * gxxint.texi: Document `u' as used for `__restrict', and a few - other previously undocumented codes. - * hash.h: Regenerated. - * init.c (expand_aggr_init): More CP_TYPE_QUALS conversion, etc. - (build_member_call): Likewise. - (build_new_1): Likewise. - * lex.c (init_parse): Add entry for RID_RESTRICT. - (cons_up_default_function): More CP_TYPE_QUALS conversion, etc. - (cp_type_qual_from_rid): Define. - * lex.h (enum rid): Add RID_RESTRICT. - * method.c (process_modifiers): Deal with `restrict'. - * parse.y (primary): More CP_TYPE_QUALS conversion, etc. - * parse.c: Regenerated. - * pt.c (convert_nontype_argument): More CP_TYPE_QUALS conversion, etc. - (tsubst_aggr_type): Likewise. - (tsubst): Likewise. - (check_cv_quals_for_unify): Likewise. - (unify): Likewise. - * rtti.c (init_rtti_processing): Likewise. - (build_headof): Likewise. - (get_tinfo_var): Likewise. - (buidl_dynamic_cast_1): Likewise. Fix `volatile' handling. - (expand_class_desc): Likewise. - (expand_attr_desc): Likewise. - (synthesize_tinfo_fn): Likewise. - * search.c (covariant_return_p): Likewise. Fix `volatile' handling. - (get_matching_virtual): Likewise. - (expand_upcast_fixups): Likewise. - * sig.c (build_signature_pointer_or_reference_name): Take - type_quals, not constp and volatilep. - (build_signature_pointer_or_reference_type): Likewise. - (match_method_types): More CP_TYPE_QUALS conversion, etc. - (build_signature_pointer_constructor): Likewise. - (build_signature_method_call): Likewise. - * tree.c (build_cplus_array_type): Likewise. - (cp_build_type_variant): Rename to ... - (cp_build_qualified_type): New function. Deal with `__restrict'. - (canonical_type_variant): More CP_TYPE_QUALS conversion, etc. - (build_exception_variant): Likewise. - (mapcar): Likewise. - * typeck.c (qualif_type): Likewise. - (common_type): Likewise. - (comptypes): Likewise. - (comp_cv_target_types): Likewise. - (at_least_as_qualified_p): Define. - (more_qualified_p): Likewise. - (comp_cv_qualification): More CP_TYPE_QUALS conversion, etc. - (compparms): Likewise. - (inline_conversion): Likewise. - (string_conv_p): Likewise. - (build_component_ref): Likewise. - (build_indirect_ref): Likewise. - (build_array_ref): Likewise. - (build_unary_op): Likewise. - (build_conditional_expr): Likewise. - (build_static_cast): Likewise. - (build_c_cast): Likewise. - (build_modify_expr): Likewise. - (convert_For_assignment): Likewise. - (comp_ptr_ttypes_real): Likewise. - (cp_type_quals): New function. - -1998-10-23 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (CP_TYPE_READONLY): New macro to handle arrays. - (CP_TYPE_VOLATILE): Likewise. - * decl.c (grokdeclarator): Use them. - * tree.c (canonical_type_variant): Likewise. - -1998-10-22 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * parse.y (named_class_head): Push into class while parsing the - base class list. - * decl2.c (push_scope, pop_scope): New functions. - * cp-tree.h: Declare them. - * init.c (build_new_1): Delay cleanup until end of full expression. - -1998-10-21 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_component_ref): Use of a type here is an error. - -1998-10-19 Jason Merrill <jason@yorick.cygnus.com> - - Revamp references to member functions. - * method.c (hack_identifier): Call build_component_ref for a - reference to a member function. - * typeck.c (build_component_ref): Only return a single function - if it's static. Otherwise, return a COMPONENT_REF. - (build_x_function_call): Handle a COMPONENT_REF. - (build_unary_op): Handle all unknown-type things. - * decl2.c (arg_assoc): Handle COMPONENT_REF. - * class.c (instantiate_type): Complain if the function we get is a - nonstatic member function. Remove code for finding "compatible" - functions. - * pt.c (tsubst_copy): Handle NOP_EXPR. - * tree.c (build_dummy_object): New fn. - (maybe_dummy_object): New fn. - (is_dummy_object): New fn. - * cp-tree.h: Declare them. - * cvt.c (cp_convert_to_pointer): Use maybe_dummy_object. - * error.c (dump_expr, case OFFSET_REF): Use is_dummy_object. - * init.c (build_member_call): Use maybe_dummy_object and - is_dummy_object. - (build_offset_ref): Use maybe_dummy_object. - (resolve_offset_ref): Use is_dummy_object. - * typeck.c (build_x_function_call): Call build_dummy_object. - (unary_complex_lvalue): Call is_dummy_object. - - * typeck.c (build_component_addr): Make sure field is a field. - - * call.c (build_new_op): Delete obsolete code. - - * pt.c (tsubst, TEMPLATE*PARM*): Abort if we don't have any args. - -1998-10-18 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl2.c (validate_nonmember_using_decl): Fix using-directives of - std if std is ignored. - -1998-10-18 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokvardecl): Fix thinko. - - * decl.c (grokdeclarator): Embedded attrs bind to the right, - not the left. - - * parse.y (fn.def2): Fix 'attrs' format. - -1998-10-18 Alastair J. Houghton <ajh8@doc.ic.ac.uk> - - * Makefile.in (CONFLICTS): Update. - * parse.y (expr_or_declarator_intern): New rule. - (expr_or_declarator, direct_notype_declarator, primary, - functional_cast): Use it. - (notype_declarator_intern): New rule. - (notype_declarator, complex_notype_declarator): Use it. - -1998-10-17 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokfndecl): Set DECL_CONTEXT to namespace if appropriate. - (grokvardecl): Likewise. - -Sat Oct 17 23:27:20 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * class.c (make_method_vec): Cast 1st argument of `bzero' to (PTR). - (add_method): Likewise for arguments 1 & 2 of `bcopy'. - - * decl.c (signal_catch): Mark with ATTRIBUTE_NORETURN. - - * pt.c (process_partial_specialization): Cast 1st argument of - `bzero' to (PTR). - - * tree.c (build_base_fields): Cast `base_align' to (int) when - comparing against one. - -1998-10-16 Mark Mitchell <mark@markmitchell.com> - - * decl.c (lookup_name_real): Handle template parameters for member - templates where said parameters have the same name as the - surrounding class. - - * decl.c (expand_static_init): Build cleanups before entering the - anonymous function used to do them to avoid access-checking - confusion. - - * decl.c (grokfndecl): Add back call to cplus_decl_attributes - accidentally removed by previous change, and make DECL_RTL here. - * class.c (add_method): Don't make DECL_RTL here. - - * pt.c (for_each_template_parm): Don't examine uninstantiated - default arguments. - -1998-10-16 Dave Brolley <brolley@cygnus.com> - - * lex.c (real_yylex): Fix unaligned access of wchar_t. - -1998-10-16 Mark Mitchell <mark@markmitchell.com> - - * class.c (add_method): Fix documentation to reflect previous - changes. Check for duplicate method declarations here. - * decl.c (decls_match): Handle FUNCTION_DECL vs TEMPLATE_DECL - correctly; such things never match. - (grokfndecl): Don't look for duplicate methods here. - * decl2.c (check_classfn): Don't assume names are mangled. - Don't add bogus member function declarations to a class before the - class type is complete. - (grokfield): Reformat error message. - * method.c (set_mangled_name_for_decl): Don't mangle names while - procesing_template_decl. - -1998-10-16 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_indirect_ref): Complain about a pointer to data - member, too. - * typeck2.c (build_m_component_ref): Don't indirect a pointer to - data member. - * init.c (resolve_offset_ref): Don't undo the above. - - * cp-tree.h (DECL_C_BIT_FIELD, SET_DECL_C_BIT_FIELD): New macros. - (struct lang_decl_flags): Add `bitfield'. - * class.c (finish_struct_1): Use DECL_C_BIT_FIELD instead of - DECL_BIT_FIELD. - * decl2.c (grokbitfield, grok_alignof): Likewise. - * init.c (build_offset_ref): Likewise. - * typeck.c (build_component_addr, expr_sizeof): Likewise. - * cvt.c (build_up_reference): Don't crash if taking the address - returns error_mark_node. - - * decl.c (grokfndecl): Also check ctype when checking for ::main(). - -1998-10-15 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokfndecl): ::main and __builtin_* get C linkage. - Do mangling here. - (grokdeclarator): Instead of here. - * friend.c (do_friend): Lose special handling of ::main and - __builtin_*. - * cp-tree.h (DECL_MAIN_P): Check for C linkage. - - * spew.c (yylex): Clear looking_for_typename if we got - 'enum { ... };'. - -1998-10-15 Mark Mitchell <mark@markmitchell.com> - - * class.c (maybe_warn_about_overly_private_class): Improve error - messages for class with only private constructors. - - * cp-tree.def (TYPENAME_TYPE): Add to documentation. - * cp-tree.h (TYPENAME_TYPE_FULLNAME): Document. - (build_typename_type): New function. - * decl.c (build_typename_type): Broken out from ... - (make_typename_type): Use it. - * search.c (lookup_field): Likewise. - -1998-10-14 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * pt.c (convert_nontype_argument): Check against type_referred_to. - * decl.c (grokvardecl): Check for declarator name before building - DECL_ASSEMBLER_NAME. - -1998-10-14 Mark Mitchell <mark@markmitchell.com> - - * pt.c (lookup_template_class): Add comment. - (instantiate_class_template): Don't mark the _TYPE node for - member class templates as an instantiation. - -1998-10-14 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokfndecl): Fix my thinko. - -1998-10-13 Jason Merrill <jason@yorick.cygnus.com> - - * tinfo2.cc (fast_compare): Remove. - (before): Just use strcmp. - * tinfo.cc (operator==): Just use strcmp. - -1998-10-13 Klaus-Georg Adams <Klaus-Georg.Adams@chemie.uni-karlsruhe.de> - - * decl.c (grokfndecl): Don't check for linkage in `extern "C"' - declarations. - -1998-10-13 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (specializations_of_same_template_p): Remove. - * search.c (get_template_base): Don't use it. - (get_template_base_recursive): Likewise. - * pt.c (specializations_of_same_template_p): Remove. - (unify): Don't use it. - (lookup_template_class): Find the correct parent when setting - CLASSTYPE_TI_TEMPLATE. - -1998-10-12 Jason Merrill <jason@yorick.cygnus.com> - - * tinfo.cc (operator==): Always compare names. - -1998-10-12 Herman ten Brugge <Haj.Ten.Brugge@net.HCC.nl> - - * decl.c (start_function): Fix cut-and-paste error. - -1998-10-12 Jason Merrill <jason@yorick.cygnus.com> - - * inc/typeinfo: Add #pragma interface. - (operator!=): Just call operator==. - * tinfo.cc: Add #pragma implementation. - (operator==): Move from inc/typeinfo and tinfo2.cc. - Check __COMMON_UNRELIABLE instead of _WIN32. - - * typeck2.c (my_friendly_abort): Add URL. - -1998-10-12 Alastair J. Houghton <ajh8@doc.ic.ac.uk> - - * decl.c (start_method): Added extra parameter for attributes. - * cp-tree.h (start_method): Update prototype. - * parse.y (fn.def2): Update start_method parameter list. - -1998-10-11 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (specializations_of_same_template_p): Declare. - * pt.c (specializations_of_same_template_p): New function. - (unify): Use it. - * search.c (get_template_base): Use it. - (get_template_base_recursive): Likewise. - -1998-10-10 Manfred Hollstein <manfred@s-direktnet.de> - - * decl2.c (start_objects): Add new variable `joiner' and - initialize it properly. - -1998-10-09 Mark Mitchell <mark@markmitchell.com> - - * search.c (expand_upcast_fixups): Tweak to match 1998-10-07 - change to vtable types. - - * cvt.c (ocp_convert): Avoid infinite recursion caused by - 1998-10-03 change. - -1998-10-08 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (resolve_overloaded_unification): New fn. - (try_one_overload): Likewise. - (unify): Don't fail on unknown type. - (type_unification_real): Likewise. Use resolve_overloaded_unification - to handle an overloaded argument. - (template_args_equal): Split out... - (comp_template_args): From here. - (determine_specialization): Also allow a template with more - parms than were explicitly specified. - * cp-tree.h: Add template_args_equal. - * call.c (resolve_args): Remove TEMPLATE_ID_EXPR code. - -Thu Oct 8 15:58:30 1998 Anthony Green <green@cygnus.com> - - * semantics.c (finish_asm_stmt): Revert my 1998-09-28 - change. - -Thu Oct 8 06:00:19 1998 Jeffrey A Law (law@cygnus.com) - - * typeck.c (unsigned_type): Only return TItype nodes when - HOST_BITS_PER_WIDE_INT is >= 64 bits. - (signed_type): Similarly. - * decl.c (intTI_type_node, unsigned_intTI_type_node): Only declare - when HOST_BITS_PER_WIDE_INT is >= 64 bits. - (init_decl_processing): Only create TItype nodes when - HOST_BITS_PER_WIDE_INT is >= 64 bits. - * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Only declare - when HOST_BITS_PER_WIDE_INT is >= 64 bits. - -Wed Oct 7 12:32:44 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (hash.h): Add -L KR-C -F ', 0, 0' flags to gperf. - (gxx.gperf): Update comments describing invocation flags. - (hash.h): Regenerate using gperf 2.7.1 (19981006 egcs). - -1998-10-07 Mark Mitchell <mark@markmitchell.com> - - * class.c (finish_struct_1): Add commentary on prevous change. - - * cp-tree.h (vtbl_ptr_type_node): New variable. - * class.c (build_vtbl_ref): Don't indirect through the vptr; it's - already of the right type. - (finish_struct_1): Make the vptr be of type vtbl_ptr_type_node. - Simplify code to grow vtable. - * decl.c (vtbl_ptr_type_node): Define. - (init_decl_processing): Initialize it. - -1998-10-06 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.def (PTRMEM_CST): New tree node. - * cp-tree.h (ptrmem_cst): New type. - (lang_type): Remove local_typedecls. - (dummy): Increase to 12 bits from 11. - (CLASSTYPE_LOCAL_TYPEDECLS): Remove. - (PTRMEM_CST_CLASS): New macro. - (PTRMEM_CST_MEMBER): Likewise. - (current_access_specifier): New variable. - (current_class_type): Remove duplicate declaration. - (finish_struct): Change prototype. - (unreverse_member_declarations): New function. - (pushdecl_class_level): Change prototype. - (grok_enum_decls): Remove. - (fixup_anonymous_union): New function. - (grok_x_components): Change prototype. - (tsubst_chain): Remove. - (finish_member_template_decl): Likewise. - (check_explicit_specialization): Fix indentation. - (finish_class_definition): Change prototype. - (finish_member_class_template): Likewise. - (finish_member_declaration): New function. - (check_multiple_declarators): Likewise. - * class.c (class_stack_node_t): New type. - (current_class_base): Remove. - (current_class_stack): Change type. - (current_access_specifier): New variable. - (grow_method): Remove. - (check_member_decl_is_same_in_complete_scope): Break out from - finish_struct. - (make_method_vec): New function. - (free_method_vec): Likewise. - (add_implicitly_declared_members): Break out from finish_struct_1. - (free_method_vecs): New variable. - (add_method): Rework for direct use from parser. - (handle_using_decl): Watch for NULL_TREE while iterating through - CLASSTYPE_METHOD_VEC. - (finish_struct_methods): Don't build CLASSTYPE_METHOD_VEC here; - just do some error-checking. - (warn_hidden): Change iteration through CLASSTYPE_METHOD_VEC. - (finish_struct_1): Simplify. Use add_implicitly_declared_members. - (finish_struct): Change prototype. Simplify; fields and methods - are already set up at this point. - (init_class_processing): Set up current_class_stack. - (pushclass): Save current_access_specifier. - (popclass): Restore it. - (currently_open_class): Simplify. - (build_self_reference): Remove use of CLASSTYPE_LOCAL_TYPEDECLS. - * decl.c (saved_scope): Add access_specifier. - (maybe_push_to_top_level): Save it. - (pop_from_top_level): Restore it. - (maybe_process_template_type_declaration): Use - finish_member_declaration. - (pushtag): Likewise. - (pushdecl_class_level): Don't return a value. - (fixup_anonymous_union): Break out from grok_x_components. - (shadow_tag): Use it. - (xref_tag): Complain about using an elaborated type specifier to - reference a template type parameter or typedef name. - (xref_basetypes): Don't set CLASSTYPE_LOCAL_TYPEDECLS. - (current_local_enum): Remove. - (build_enumerator): Call finish_member_declaration. - (grok_enum_decls): Remove. - * decl2.c (grok_x_components): Simplify. - (check_classfn): Change iteration through CLASSTYPE_METHOD_VEC. - (grokfield): Don't set CLASSTYPE_LOCAL_TYPEDECLS. - (merge_functions): Add to comment. - (arg_assoc_type): Prototype. - (arg_assoc): Pass as many arguments as there are parameters. - * error.c (dump_expr): Handle PTRMEM_CST. Improve handling of - OFFSET_REF. - * expr.c (cpls_expand_expr): Remove dead code. Handle - PTRMEM_CST. - * friend.c (do_friend): Lookup friends when in nested classes. - Change comments. - * init.c (build_offset_ref): Do lookup even for classes that are - only partially defined. - (decl_constant_value): Remove dead code. - * method.c (build_overload_value): Remove hack where by TYPE was - not a TYPE. Handle PTRMEM_CST. - (build_template_parm_names): Don't pass a PARM_DECL where a TYPE - should go. - * parse.y (components, notype_components, component_decl, - component_decl_1, component_declarator, component_declarator0): - Now all are itype rather than ttype. Rework to add members to - classes on the fly. - (typesqpecqual_reserved): Use check_multiple_declarators. - (structsp): Update class to finish_class_definition. - (do_xref_defn): Unsplit into named_class_head. - (access_specifier): Set current_access_specifier. - * pt.c (set_current_access_from_decl): New function. - (finish_member_template_decl): Don't take the parameters. - (comp_template_args): Make more robust. - (lookup_template_class): Don't use current_local_enum. - (for_each_template_parm): Handle PTRMEM_CST. - (instantiate_class_template): Use set_current_access_from_decl, - finish_member_declaration and unreverse_member_declarations. Set - lineno/input_filename before generating implicit member functions. - (type_unification_real): Don't assume back-unification happens - only for the last argument. - (regenerate_decl_from_template): Call pushclass a bit earlier. - (tsubst_chain): Remove. - (tsubst_enum): Use set_current_access_from_decl. - (set_mangled_name_for_template_decl): Fix indentation. - * search.c (lookup_fnfields_1): Change iteration through - CLASSTYPE_METHOD_VEC. - (dfs_pushdecls): Likewise. - (dfs_compress_decls): Likewise. - (add_conversions): Likewise. - * semantics.c (finish_class_definition): Don't take components. - Change call to finish_struct. - (finish_member_declaration): New function. - (finish_member_class_template): Don't take template parameters. - Change call to grok_x_components. Call finish_member_template_decl. - (check_multiple_declarators): New function. - * sig.c (append_signature_fields): Work from the TYPE_METHODS, not - a passed in fieldlist. - * tree.c (search_tree): Handle PTRMEM_CST. - (mapcar): Likewise. - * typeck.c (unary_complex_lvalue): Build PTRMEM_CSTs, not - INTEGER_CSTs, for pointer-to-data members. - - * call.c (resolve_args): Resolve template specializations, if - possible. - -Tue Oct 6 07:57:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (spew.o): Depend on toplev.h. - - * call.c (compare_ics): Initialize variables `deref_from_type2', - `deref_to_type1' and `deref_to_type2'. - - * except.c (get_eh_type): Hide prototype and definition. - (process_start_catch_block_old): Remove unused static prototype. - - * pt.c (tsubst_decl): Initialize variable `argvec'. - - * spew.c: Include toplev.h. - -1998-10-05 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Do save and restore file position. - -1998-10-05 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * method.c (build_decl_overload_real): Clear - numeric_output_need_bar after __. - -1998-10-05 Nathan Sidwell <nathan@acm.org> - - * call.c (build_new_method_call): Issue 'incomplete type' error, - if class is not defined. - -1998-10-05 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * call.c (build_object_call): Move declaration of variable - `fn' into the scope where it is used. Don't access variable - `fn' when it is uninitialized, instead use `fns'. - -1998-10-04 Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr> - - * errfn.c (cp_thing): Print buf as a string not as a printf format - to avoid problems with the operator%. Consequently, `%%' sequences - in format are copied as `%' in buf. - -1998-10-04 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (pop_tinst_level): Call extract_interface_info. - (instantiate_decl): Don't save and restore file position. - - * decl.c (cp_finish_decl): Make statics in extern inlines and - templates common, if possible and the target doesn't support weak - symbols. - - * decl.c (grokdeclarator): Remove redundant calls to - build_type_variant and some duplicated code. - * sig.c (build_signature_reference_type): Only take the type parm. - (build_signature_pointer_type): Likewise. - * tree.c (build_cplus_method_type): Adjust. - * cp-tree.h: Update. - -1998-10-04 Mark Mitchell <mark@markmitchell.com> - - * call.c (build_over_call): Make pedwarns about dropped qualifiers - into full-fledged errors. - * cvt.c (convert_to_reference): Likewise. - * typeck.c (convert_for_assignment): Likewise. - - * search.c (expand_upcast_vtables): In addition to unsetting - TREE_READONLY, remove top-level const type qualifier. - -1998-10-03 Mark Mitchell <mark@markmitchell.com> - - * class.c (current_class_ptr, current_class_ref): Clarify - documentation. - * cvt.c (ocp_convert): Don't expect fold to remove all trivial - NOP type conversions. - * decl.c (decls_match): Use comptypes directly; ignore - qualifiers on the DECL. - (duplicate_decls): Remove qualifier checks on DECL. - (grokdeclarator): Make the type built up include top-level - qualifiers. - * decl2.c (do_dtors): Fix spelling error. - * error.c (dump_simple_decl): Don't look at qualifiers on the decl - when printing type information. - * init.c (build_new_1): Add documentation. Deal with the fact - that type of allocated memory now contains qualifiers. - * lex.c (is_global): Improve error-recovery. - * sig.c (build_member_function_pointer): Don't cast away const - on fields of sigtable_entry_type. - * tree.c (lvalue_type): Don't look at top-level qualifiers on - expressions. - * typeck.c (decay_conversion): Likewise. - (build_component_ref): Make sure the type of the COMPONENT_REF - contains top-level qualifiers, as appropriate. Improve - error-handling. - (build_indirect_ref): Simplify. Don't strip top-level qualifiers. - (build_array_ref): Likewise. - (build_unary_op): Improve error-recovery. - (unary_complex_lvalue): Make taking the address a bound member - function an error, not a sorry. - (build_conditional_expr): Look at the type qualifiers, not the - qualifiers on the expression itself. - -1998-10-03 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (merge_functions): Remove duplicates. - - * decl2.c: Add -f{no-,}implicit-inline-templates. - (import_export_decl): Check it. - - * decl.c (lookup_name_real): Template parms also take precedence - over implicit typename. Only warn if yylex. - - * typeck.c (build_conditional_expr): Only fold if ifexp is an - INTEGER_CST. - - * decl2.c (finish_vtable_vardecl): Check DECL_INTERFACE_KNOWN - instead of linkage. - -1998-10-01 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (FORMAT_VBASE_NAME): New macro. - * class.c (build_vbase_pointer): Use it. - * rtti.c (expand_class_desc): Likewise. - * tree.c (build_vbase_pointer_fields): Likewise. - -Thu Oct 1 10:43:45 1998 Nick Clifton <nickc@cygnus.com> - - * decl.c (start_decl): Add invocation of - SET_DEFAULT_DECL_ATTRIBUTES, if defined. - (start_function): Add invocation of - SET_DEFAULT_DECL_ATTRIBUTES, if defined. - - * lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with - HANDLE_GENERIC_PRAGMAS. - -1998-09-28 Anthony Green <green@cygnus.com> - - * semantics.c (finish_asm_stmt): Always permit volatile asms. - -1998-09-28 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Tighten checks for invalid - destructors. Improve error-messages and error-recovery. - * decl2.c (check_classfn): Don't assume that mangled destructor - names contain type information. - -1998-09-25 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (get_base_distance): Remove assert. - - * decl2.c (build_anon_union_vars): Don't process a field with no - name. - (finish_anon_union): Also complain about local anon unions with no - members. - -1998-09-25 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl.c (lookup_namespace_name): If the name is a namespace, - return it immediately. - -Fri Sep 25 11:45:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * cp-tree.h (define_case_label): Remove unused parameter. - (check_java_method): Likewise. - (grokclassfn): Likewise. - (expand_aggr_init): Likewise. - (build_x_delete): Likewise. - (maybe_end_member_template_processing): Likewise. - (unshare_base_binfos): Add prototype. - (string_conv_p): Likewise. - (my_friendly_abort): Mark with ATTRIBUTE_NORETURN. - - * cvt.c (build_up_reference): Remove unused parameter - `checkconst', all callers changed. - (build_type_conversion): Mark parameter `code' with - ATTRIBUTE_UNUSED. - (build_expr_type_conversion): Initialize variable `conv'. - - * decl.c (push_namespace): Initialize variable `d'. - (define_case_label): Remove unused parameter `decl', all callers - changed. - - * decl2.c (lang_decode_option): If !USE_CPPLIB, mark parameter - `argc' with ATTRIBUTE_UNUSED. - (grokclassfn): Remove unused parameter `cname', all callers - changed. - (check_java_method): Likewise for parameter `ctype'. - (copy_assignment_arg_p): Mark parameter `virtualp' with - ATTRIBUTE_UNUSED. - (finish_prevtable_vardecl): Likewise for parameter `prev'. - - * expr.c (extract_init): Likewise for parameters `decl' and `init'. - - * init.c (expand_aggr_init_1): Remove unused parameter - `alias_this', all callers changed. - (expand_aggr_init): Likewise. - (expand_default_init): Likewise. - (build_new_1): Initialize variable `susp'. - (build_x_delete): Remove unused parameter `type', all callers - changed. - - * lex.c (set_typedecl_interface_info): Mark parameter `prev' with - ATTRIBUTE_UNUSED. - (readescape): Use (unsigned) value in shift. - (real_yylex): Likewise. Likewise. Also cast `sizeof' to int when - comparing to a signed quantity. - - * pt.c (maybe_end_member_template_processing): Remove unused - parameter `decl', all callers changed. - (check_explicit_specialization): Add braces around empty body in - an else-statement. - (current_template_args): Initialize variable `args'. - (lookup_template_class): Likewise for variable `prev_local_enum'. - (tsubst_decl): Likewise for variable `r'. - (set_mangled_name_for_template_decl): Initialize variable - `context'. - - * spew.c (scan_tokens): Change type of parameter `n' to unsigned. - Likewise for variable `i'. - (yylex): Initialize variable `trrr'. - - * typeck.c (compparms): Mark variable `strict' with - ATTRIBUTE_UNUSED. - - * xref.c (simplify_type): Cast argument of ctype function to - `unsigned char'. - -1998-09-24 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (language_lvalue_valid): Remove. - * decl.c (grokdeclarator): Don't disallow references to functions. - * tree.c (lvalue_p_1): New function, combining duplicated - code from ... - (lvalue_p): Use it. - (real_lvalue_p): Likewise. - * typeck.c (language_lvalue_valid): Remove. - (build_modify_expr): Treat FUNCTION_TYPEs as readonly, even though - they don't have TREE_READONLY set. - * typeck2.c (readonly_error): Add case for FUNCTION_DECLs. - -1998-09-24 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * spew.c (yylex): Give diagnostic. - * hash.h (is_reserved_word): Add export. - * gxx.gperf: Ditto. - * lex.h (rid): Add RID_EXPORT. - * lex.c (init_parse): Ditto. - -Tue Sep 22 21:01:19 1998 Gerald Pfeifer <pfeifer@dbai.tuwien.ac.at> - - * friend.c (do_friend): Make warning a full sentence. - -1998-09-22 Mark Mitchell <mark@markmitchell.com> - - * parse.y (component_decl_list): Improve error-recovery. - -1998-09-22 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * decl.c (make_typename_type): Move error to point where name - variable can be used by dump_type. - -1998-09-22 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokfndecl): Improve error-recovery. - * decl2.c (grokfield): Likewise. - * pt.c (finish_member_template_decl): Likewise. - -1998-09-20 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * method.c (hack_identifier): Finding multiple members is always - an error. - -1998-09-21 Per Bothner <bothner@cygnus.com> - - * Make-lang.in (c++-filt): Link libiberty.a after cxxmain.o. - -Mon Sep 21 01:53:05 1998 Felix Lee <flee@cygnus.com> - - * lex.c (init_lex): Use getenv ("LANG"), not GET_ENVIRONMENT (). - -1998-09-20 Mark Mitchell <mark@markmitchell.com> - - * class.c (maybe_warn_about_overly_private_class): Reformat. - -1998-09-17 Andrew MacLeod <amacleod@cygnus.com> - - * exception.cc (__cplus_type_matcher): realign some code. - -1998-09-16 Mark Mitchell <mark@markmitchell.com> - - * Make-lang.in (tinfo.o): Use CXXFLAGS when compiling. - (tinfo2.o): Likewise. - (exception.o): Likewise. - (new.o): Likewise. - (opnew.o): Likewise. - (opnewnt.o): Likewise. - (opvnew.o): Likewise. - (opvnewnt.o): Likewise. - (opdel.o): Likewise. - (opdelnt.o): Likewise. - (opvdel.o): Likewise. - (opvdelnt.o): Likewise. - -1998-09-16 Richard Henderson <rth@cygnus.com> - - * decl.c (init_decl_processing): Kill __builtin_fp and __builtin_sp. - -1998-09-15 Alexandre Oliva <oliva@dcc.unicamp.br> - - * call.c (build_field_call): handle static data members too - - * typeck.c (comptypes): when comparing pointer types, check - whether referred types match even in strictest modes - -1998-09-15 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h: Revert previous change. - (finish_struct_methods): Remove declaration. - * class.c: Revert previous change. - (maybe_warn_about_overly_private_class): New function. - (finish_struct_methods): Declare here, and make static. Remove - unnecessary parameters. Tidy slightly. Use - maybe_warn_about_overly_private_class. - (finish_struct_1): Adjust. Remove check for private constructors, - now done elsewhere. - (finish_struct): Adjust. - -1998-09-15 Andrew MacLeod <amacleod@cygnus.com> - - * except.c (expand_start_catch_block): No need to check for new - exception model. - (process_start_catch_block_old): Deleted. - (process_start_catch_block): Add call to start_decl_1(). - (expand_end_catch_block): Add call to end_catch_handler(). - * exception.cc (__cplus_type_matcher): Only check the exception - language if there is an exception table. - -1998-09-15 Andrew MacLeod <amacleod@cygnus.com> - - * search.c (expand_indirect_vtbls_init): Mark temporary stack slots - as used to prevent conflicts with virtual function tables. - -1998-09-14 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (lang_type): Add has_non_private_static_mem_fn. - (CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN): New macro, to access it. - * class.c (maybe_class_too_private_p): New function. - (finish_struct_methods): Use it. - (finish_struct_1): Likewise. - (finish_struct): Set CLASSTYPE_HAS_NON_PRIVATE_STATIC_MEM_FN if - appropriate. - - * pt.c (check_specialization_scope): Fix spelling error. - (check_explicit_specialization): Remove code to handle explicit - specializations in class scope; they are now correctly diagnosed - as errors. - -1998-09-10 Mark Mitchell <mark@markmitchell.com> - - * decl.c (pushdecl): Don't copy types if the - DECL_ABSTRACT_ORIGIN of the new decl matches the TYPE_NAME of the - type. - -1998-09-09 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu> - - * class.c (get_enclosing_class): New function. - (is_base_of_enclosing_class): Likewise. - * cp-tree.h (get_enclosing_class): Declare. - (is_base_of_enclosing_class): Likewise. - * pt.c (coerce_template_parms): Use them. - -1998-09-09 Jason Merrill <jason@yorick.cygnus.com> - - * g++spec.c (lang_specific_driver): Check whether MATH_LIBRARY is - null to decide whether to use it. - - * error.c (dump_type_real): Handle NAMESPACE_DECL. - * parse.y (base_class.1): Avoid crash on error. - -1998-09-08 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl.c (make_typename_type): If context is a namespace, the code - is in error. - -1998-09-08 Mumit Khan <khan@xraylith.wisc.edu> - - * parse.y (nomods_initdcl0): Set up the parser stack correctly. - -1998-09-08 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (anonymous_namespace_name): Declare. - * decl.c: Define it. - (push_namespace): Use anonymous_namespace_name, rather than local - static anon_name. - * error.c (dump_decl): If a namespace is named - anonymous_namespace_name, call it {anonymous}. - - * decl.c (grokparms): Distinguish between references and pointers - in error message. - -1998-09-08 Richard Henderson <rth@cygnus.com> - Mark Mitchell <mark@markmitchell.com> - - * pt.c (process_partial_specialization): Consistantly allocate - and zero tpd.parms based on ntparms. Use tpd2.parms, not - tpd.parms, where appropriate. - -Sun Sep 6 00:00:51 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (INCLUDES): Update after recent toplevel gcc - reorganizations. - -1998-09-05 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (TI_PENDING_SPECIALIZATION_FLAG): Remove. - * class.c (finish_struct): Remove hackery to deal with explicit - specializations in class scope. - * decl.c (grokfndecl): Improve error-recovery. - * decl2.c (grokfield): Likewise. - * pt.c (check_specialization_scope): New function. - (begin_specialization): Call it. - (process_partial_specialization): New function, split out from - push_template_decl. Check partial specializations more - stringently. - (push_template_decl): Call it. - (check_explicit_specialization): Don't attempt to handle explicit - specializations in class scope. - (template_parm_data): Document. Add current_arg and - arg_uses_template_parms. - (mark_template_parm): Set it. - (tsubst_arg_types): Remove unused variable. - * semantics.c (begin_class_definition): Tweak. - -1998-09-04 Mark Mitchell <mark@markmitchell.com> - - * inc/typeinfo (type_info::type_info(const char*)): Make - `explicit'. - - * cp-tree.h (hash_tree_cons_simple): New macro. - * pt.c (tsubst_arg_types): New function. Use hash_tree_cons. - (coerce_template_parms): Use make_temp_vec, instead of - make_tree_vec. Document this behavior. - (lookup_template_class): Likewise. - (tsubst, cases METHOD_TYPE, FUNCTION_TYPE): Use tsubst_arg_types. - Remove dead code (and add ssertion to check its deadness). Fix - bug w.r.t. exception specifications. - -1998-09-03 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_vtable): Always make artificials comdat. - (import_export_decl): Likewise. - * pt.c (mark_decl_instantiated): Likewise. - -1998-09-03 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (finish_globally_qualified_member_call_expr): - Rename to ... - (finish_qualified_call_expr). - * semantics.c: Likewise. - * parse.y (primary): Use it. - * method.c (hack_identifier): Remove redundant code. - - * init.c (resolve_offset_ref): Call convert_from_reference to - handle members of reference type. Improve error recovery. - -1998-09-03 Benjamin Kosnik <bkoz@cygnus.com> - - * cp-tree.h: Declare warn_nontemplate_friend. - * decl2.c (lang_decode_option): Set. - * lang-options.h: Add -Wnon-template-friend. - * friend.c (do_friend): Use to toggle non-template function warning. - -1998-09-03 Mark Mitchell <mark@markmitchell.com> - - * decl.c (finish_enum): Don't resolve CONST_DECLs to their - corresponding INTEGER_CSTs when processing_template_decl. - * pt.c (tsubst_enum): Tweak accordingly. - -1998-09-03 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (pushdecl_class_level): Add warning here. - (pushdecl): Tweak. - -1998-09-02 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (convert_pointer_to_real): Tidy. - * search.c (get_base_distance_recursive): Simplify. - (get_base_distance): Likewise. - - * pt.c (unify): Only special-case INTEGER_TYPE if it uses template - parms. - -Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com> - - * lex.c (check_newline): Call HANDLE_PRAGMA before - HANDLE_SYSV_PRAGMA if both are defined. Generate warning messages - if unknown pragmas are encountered. - (handle_sysv_pragma): Interpret return code from - handle_pragma_token (). Return success/failure indication rather - than next unprocessed character. - (pragma_getc): New function: retrieves characters from the - input stream. Defined when HANDLE_PRAGMA is defined. - (pragma_ungetc): New function: replaces characters back into the - input stream. Defined when HANDLE_PRAGMA is defined. - -1998-09-01 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (output_vtable_inherit): Use %cDIGIT in the operands. - * class.c (build_vtable_entry_ref): Likewise. - -1998-09-01 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION): New macro. - * decl2.c (import_export_decl): Likewise. - * pt.c (instantiate_decl): Use it. - -1998-09-01 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): Also do implicit typename thing for - artificial TYPE_DECLs. - * search.c (lookup_field): Likewise. - (lookup_fnfields, lookup_field): Adjust for implicit typename kludge. - * semantics.c (begin_constructor_declarator): Use enter_scope_of. - (enter_scope_of): Extract type from implicit typename. - (begin_class_definition): Likewise. - * lex.c (identifier_type): Handle implicit typename when checking - for SELFNAME. - - * cp-tree.h: Declare flag_strict_prototype. - * lex.c (do_scoped_id, do_identifier): Don't implicitly_declare if - -fstrict-prototype. - * decl.c (init_decl_processing): If -f{no,-}strict-prototype wasn't - specified, set it to the value of pedantic. - -1998-09-01 Mark Mitchell <mark@markmitchell.com> - - * decl2.c (arg_assoc): Handle template-id expressions as arguments. - -1998-08-31 Mark Mitchell <mark@markmitchell.com> - - * decl.c (finish_enum): Handle member enums of classes declared in - template functions. - - * decl2.c (grok_x_components): Strip attributres before calling - groktypename. - -1998-08-31 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h, decl2.c: Remove support for -fall-virtual, - -fenum-int-equivalence and -fno-nonnull-objects. - * class.c (check_for_override): Remove support for -fall-virtual. - (finish_struct_1): Likewise. - * call.c (build_new_op): Remove support for -fenum-int-equivalence. - * typeck.c (build_binary_op_nodefault): Likewise. - * cvt.c (ocp_convert): Likewise. - * call.c (build_vfield_ref): Remove support for -fno-nonnull-objects. - * class.c (build_vbase_path): Likewise. - -Sun Aug 30 22:16:31 1998 H.J. Lu (hjl@gnu.org) - - * Makefile.in (INTERFACE): New, set to 1. - -1998-08-30 Mark Mitchell <mark@markmitchell.com> - - * error.c (dump_decl): Use CP_DECL_CONTEXT, not DECL_CONTEXT, when - comparing with global_namespace. - (dump_aggr_type): Likewise. - - * decl.c (grokfndecl): Issue error on declaration of friend - templates with explicit template arguments. - - * pt.c (convert_template_argument): New function, split out - from... - (coerce_template_parms): Here. - (tsubst): Attempt better error-recovery. - -1998-08-28 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * pt.c (decl_template_parm_p): Add checks for - TEMPLATE_TEMPLATE_PARM. - -1998-08-28 Mark Mitchell <mark@markmitchell.com> - - * lex.c (do_identifier): Fix thinko in previous change. - -1998-08-28 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (dfs_search, binfo_for_vtable, dfs_bfv_helper): New fns. - * decl2.c (output_vtable_inherit): Call binfo_for_vtable. - -1998-08-28 Richard Henderson <rth@cygnus.com> - - Add support for discarding unused virtual functions. - * lang-options.h: Add -fvtable-gc. - * cp-tree.h: Add flag_vtable_gc. - * decl2.c (output_vtable_inherit): New fn. - (finish_vtable_vardecl): Call it. - * class.c (build_vtable_entry_ref): New fn. - (build_vtbl_ref): Call it. - -1998-08-28 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (build_enumerator): Take the enumeration type as a - paramter. - * decl.c (finish_enum): Don't set the TREE_TYPE for the - enumeration constant values if we're processing_template_decls. - Don't set the type for the CONST_DECLs either; that's done in - build_enumerator. - (build_enumerator): Take the enumeration type as a - parameter. - * lex.c (do_identifier): Don't resolve enumeration constants while - processing template declarations, even if they happen to be - TEMPLATE_PARM_INDEXs. - - * parse.y (current_enum_type): New variable. - (primary): Don't allow statement-expression in local classes just - as we don't in global classes. - (structsp): Use current_enum_type. - (enum_list): Likewise. - * pt.c (tsubst_enum): Don't check for NOP_EXPRs introduced by - finish_enum; they no longer occur. - - * cp-tree.h (finish_base_specifier): New function. - * parse.y (base_class): Use it. - * semantics.c (finish_base_specifier): Define it. - - * parse.y (structsp): Warn on use of typename outside of template - declarations. - -1998-08-27 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (handle_cp_pragma): Remove #pragma vtable. - * lang-options.h: Remove +e options. - * decl2.c (lang_decode_option): Likewise. - (import_export_vtable): Don't check write_virtuals. - (finish_vtable_vardecl, finish_file): Likewise. - * search.c (dfs_debug_mark): Likewise. - * semantics.c (begin_class_definition): Likewise. - * class.c (build_vtable, finish_vtbls, finish_struct_1): Likewise. - - * call.c (build_over_call): Check flag_elide_constructors. - * decl2.c: flag_elide_constructors defaults to 1. - * typeck.c (convert_arguments): Remove return_loc parm. - (build_function_call_real): Adjust. - - * search.c: Tear out all mi_matrix and memoize code. - (lookup_field, lookup_fnfields): Use scratch_tree_cons. - * lang-options.h: Remove documentation for -fhandle-exceptions, - -fmemoize-lookups and -fsave-memoized. - * cp-tree.h: Lose mi_matrix and memoize support. - * decl2.c: Ignore -fmemoize-lookups and -fsave-memoized. - * class.c: Lose struct class_level. - (pushclass, popclass): Lose memoize support. - * init.c (build_offset_ref): Likewise. - - Never change BINFO_INHERITANCE_CHAIN. - * init.c (emit_base_init): Change modification of - BINFO_INHERITANCE_CHAIN to an assert. - * search.c (get_base_distance_recursive): Likewise. - (get_base_distance): Likewise. - (lookup_member): Likewise. - (convert_pointer_to_single_level): Likewise. - (lookup_field): Likewise. Lose setting TREE_VIA_* on TREE_LISTs. - (lookup_fnfields): Likewise. - * tree.c (propagate_binfo_offsets): Don't call unshare_base_binfos. - (unshare_base_binfos): Don't call propagate_binfo_offsets. - (layout_basetypes): Call propagate_binfo_offsets instead of - unshare_base_binfos. - * decl.c (xref_basetypes): Call unshare_base_binfos. - * pt.c (instantiate_class_template): Likewise. - * tree.c (reverse_path): Remove 'copy' parm; always make a - temporary copy. - * class.c (build_vbase_path): Just call it. - * search.c (compute_access): Likewise. Don't re-reverse. - -1998-08-27 Mark Mitchell <mark@markmitchell.com> - - * class.c (build_vbase_path): Use reverse_path. - (finish_base_struct): Move warnings for inaccessible bases to - layout_basetypes. - (modify_one_vtable): Remove check of TREE_USED (binfo). - (fixup_vtable_deltas1): Likewise. - * cp-tree.h (BINFO_INHERITANCE_CHAIN): Document here. - (xref_tag): Remove binfos parameter. - (make_binfo): Remove chain parameter. - (reverse_path): Add copy parameter. - * decl.c (init_decl_processing): Change calls to xref_tag. - (xref_tag): Remove binfos parameter. - (xref_basetypes): Change calls to make_binfo. - * decl2.c (grok_x_components): Change calls to xref_tag. - (handle_class_head): Likewise. - * friend.c (do_friend): Likewise. - * lex.c (make_lang_type): Change calls to make_binfo. - * parse.y (structsp): Change calls to xref_tag. - (named_complex_class_head_sans_basetype): Likewise. - (named_class_head): Likewise. - * rtti.c (init_rtti_processing): Likewise. - * search.c (compute_access): Change calls to reverse_path. - (dfs_get_vbase_types): Change calls to make_binfo. - (get_vbase_types): Remove dead code. - * tree.c (unshare_base_binfos): Change calls to make_binfo. - (layout_basetypes): Warn here about inaccessible bases. - (make_binfo): Remove chain parameter. - (reverse_path): Add copy parameter. - -1998-08-27 Jason Merrill <jason@yorick.cygnus.com> - - * class.c: #if 0 complete_type_p. - * init.c (build_java_class_ref, build_new_1): Remove unused locals. - * method.c (process_overload_item): Likewise. - * typeck.c (comp_target_types): Likewise. - - Stop sharing binfos for indirect virtual bases. - * tree.c (propagate_binfo_offsets): Unshare vbases, too. - (layout_basetypes): Likewise. - (unshare_base_binfos): Copy vbases, too. - * cp-tree.h (BINFO_VIA_PUBLIC, BINFO_BASEINIT_MARKED, - BINFO_VBASE_INIT_MARKED): Remove obsolete macros. - (BINFO_PUSHDECLS_MARKED, SET_BINFO_PUSHDECLS_MARKED, - CLEAR_BINFO_PUSHDECLS_MARKED): New macros. - * search.c (lookup_field, lookup_fnfields, lookup_member): Remove - reference to BINFO_VIA_PUBLIC. - (marked_pushdecls_p, unmarked_pushdecls_p): New fns. - (push_class_decls): Use them. - (dfs_pushdecls): Use SET_BINFO_PUSHDECLS_MARKED. - (dfs_compress_decls): Use CLEAR_BINFO_PUSHDECLS_MARKED. - -1998-08-27 Mark Mitchell <mark@markmitchell.com> - - * decl.c (build_enumerator): Set DECL_CONTEXT for the - CONST_DECLs. - -1998-08-26 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (finish_enum): Change prototype. - * decl.c (finish_enum): Use TYPE_VALUES, rather than taking a - VALUES parameter. Don't try to compute mins/maxs if - processing_template_decl. - * parse.y (structsp): Use new calling sequence for finish_enum. - * pt.c (tsubst_enum): Likewise. Take the new type as input. - (lookup_template_class): Remove unused variables. Tweak. - Register enums on instantiation list before substituting - enumeration constants. - (tsubst_decl): Remove unused variables. - (regenerate_decl_from_template): Likewise. - - * decl.c (duplicate_decls): Don't obliterate the - DECL_TEMPLATE_INFO for a template if we're not replacing it with - anything. - - * lex.c (do_identifier): Fix typo in comment. - -Wed Aug 26 10:54:51 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * errfn.c: Remove stdarg.h/varargs.h. - * tree.c: Likewise. - -1998-08-25 Brendan Kehoe <brendan@cygnus.com> - - * pt.c (tsubst_copy): Only do typename overloading on an - IDENTIFIER_NODE that happens to look like a typename if it actually - has a type for us to use. - -1998-08-25 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (comp_cv_target_types): Split out... - (comp_target_types): From here. Don't allow cv-qual changes under - a pointer if nptrs == 0. Fix OFFSET_TYPE handling. - (build_ptrmemfunc): Pass 1 to nptrs. - * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes. - -1998-08-25 Mark Mitchell <mark@markmitchell.com> - - * search.c (dependent_base_p): Don't compare a binfo to - current_class_type; use the TREE_TYPE of the binfo instead. - - * cp-tree.h (CLASS_TYPE_P): Revise definition. - -1998-08-25 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (duplicate_decls): Don't complain about different - exceptions from an internal decl even if pedantic. - - * typeck.c (convert_for_assignment): Converting from pm of vbase - to derived is an error, not a sorry. - - * call.c (build_over_call): Use convert_pointer_to_real for 'this'. - * class.c (fixed_type_or_null): Rename from - resolves_to_fixed_type_p. Return the dynamic type of the - expression, if fixed, or null. - (resolves_to_fixed_type_p): Use it. Return 0 if the dynamic type - does not match the static type. - (build_vbase_path): Rename 'alias_this' to 'nonnull'. Use - resolves_to_fixed_type_p again. - -1998-08-24 Mark Mitchell <mark@markmitchell.com> - - * pt.c (tsubst_decl): Move special case code for dealing with - tricky friend templates here from ... - (regenerate_decl_from_template): Here. - -1998-08-24 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): Remove redundant linkage check. - -1998-08-24 Gavin Romig-Koch <gavin@cygnus.com> - - * typeck.c (c_expand_return): Handle the case that valtype - is wider than the functions return type. - -1998-08-24 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (CLASS_TYPE_P): New macro. - * decl.c (grokdeclarator): Use it instead of IS_AGGR_TYPE. - * pt.c (process_template_parm): Undo previous change. - -1998-08-24 Benjamin Kosnik <bkoz@cygnus.com> - - * cp-tree.h: Declare. - * pt.c (decl_template_parm_p): New function. - * decl.c (pushdecl): Check decls for redeclaring template parms. - (xref_tag): Make redeclaration an error, print decl. - * decl2.c (grokfield): Check field_decls for redeclaration as well. - -1998-08-24 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (primary): Fix up the type of string constants. - -1998-08-24 Mark Mitchell <mark@markmitchell.com> - - * typeck.c (convert_for_initialization): Move check for odd uses - of NULL to avoid duplicate warnings. - -1998-08-24 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (lvalue_type): Fix for arrays. - * typeck.c (string_conv_p): New fn. - (convert_for_assignment): Use it. - (build_unary_op): Use lvalue_type. - * call.c (standard_conversion, convert_like): Use string_conv_p. - (add_function_candidate): Use lvalue_type. - * cvt.c (convert_to_reference): Likewise. - * decl2.c (lang_decode_option): Ignore -traditional. - * decl.c (init_decl_processing): flag_writable_strings inhibits - flag_const_strings. - -1998-08-24 Andrew MacLeod <amacleod@cygnus.com> - - * lang-options.h (lang_options): Add fconst-strings to the list - of valid options. - * decl2.c (lang_f_options, lang_decode_option): Likewise. - -1998-08-24 Nathan Sidwell <nathan@acm.org> - - * lex.c (real_yylex): Don't warn about long long constants if - we're allowing long long. - -1998-08-24 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl.c (pushdecl): Use IDENTIFIER_NAMESPACE_VALUE instead of - accessing bindings directly. - - * search.c (my_tree_cons): Reimplement. - - * lang-specs.h: Remove __HONOR_STD. - * inc/exception, inc/new, inc/new.h, inc/typeinfo: Likewise. - -1998-08-23 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Complain about in-class initialization - of aggregates and/or references. - * pt.c (process_template_parm): Clear IS_AGGR_TYPE for - TEMPLATE_TYPE_PARMs. - - * decl2.c (grok_array_decl): Add comment. - (mark_used): Don't instantiate an explicit instantiation. - * friend.c (make_friend_class): Remove bogus comment. Fix check - for partial specializations. - * pt.c (check_explicit_specialization): Don't - SET_DECL_EXPLICIT_INSTANTIATION here. - (mark_decl_instantiated): Or here. - (do_decl_instantiation): Do it here, instead. Add checks for - duplicate explicit instantiations, etc. Tidy. - (do_type_instantiation): Likewise. - (instantiate_decl): Improve comments. Complain about explicit - instantiations where no definition is available. - - * cp-tree.h (ansi_null_node): Remove. - * call.c (build_over_call): Warn about converting NULL to an - arithmetic type. - * cvt.c (build_expr_type_conversion): Likewise. Use - null_ptr_cst_p instead of expanding it inline. - * decl.c (ansi_null_node): Remove. - (init_decl_processing): Make null_node always have integral type. - * except.c (build_throw): Warn about converting NULL to an - arithmetic type. - * lex.c (init_parse): Remove handling of ansi_null_node. - * pt.c (type_unification_real): Don't convert NULL to void* type. - * typeck.c (build_binary_op_nodefault): Fix NULL warnings. - (convert_for_assignment): Warn about converting NULL to an - arithmetic type. - (convert_for_initialization): Likewise. - -1998-08-20 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (search_tree, no_linkage_helper, no_linkage_check): New fn. - * pt.c (coerce_template_parms): Use no_linkage_check. - * decl.c (grokvardecl): Likewise. - (grokfndecl): Likewise. Members of anonymous types have no linkage. - - * method.c (process_overload_item): Remove useless code. - -1998-08-20 Per Bothner <bothner@cygnus.com> - - Handle new'ing of Java classes. - * init.c (build_class_classref): New function. - (build_new_1): If type is TYPE_FOR_JAVA: Call _Jv_AllocObject; - constructor does not return this; don't need to exception-protect. - - * pt.c (lookup_template_class): Copy TYPE_FOR_JAVA flag. - * decl2.c (acceptable_java_type): Handle template-derived types. - -1998-08-20 Per Bothner <bothner@cygnus.com> - - * decl2.c (import_export_vtable): Suppress vtables for Java classes. - -1998-08-20 Mark Mitchell <mark@markmitchell.com> - - * decl.c (duplicate_decls): Always merge the old and new patterns - for templates, regardless of whether or not the new one has - DECL_INITIAL. Don't throw away specializations. Merge - DECL_SAVED_TREE. - * pt.c (tsubst_decl): Use the right pattern when calculating the - complete args for a new template instance. - (do_decl_instantiation): Fix typo in comment. - (regenerate_decl_from_template): Deal with tricky friend template - case. - (instantiate_decl): Likewise. - -Thu Aug 20 09:09:45 1998 Jeffrey A Law (law@cygnus.com) - - * init.c (build_builtin_delete_call): Add missing assemble_external - call. - -1998-08-20 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (notype_unqualified_id): Also accept ~A<int>. - -1998-08-19 Mark Mitchell <mark@markmitchell.com> - - * typeck.c (build_binary_op_nodefault): Warn on use of NULL in - arithmetic. - * except.c (build_throw): Warn when NULL is thrown, even with - -ansi. Use ansi_null_node, rather than integer_zero_node, in the - thrown expression. - - * cp-tree.h (ansi_null_node): New variable. - * decl.c (ansi_null_node): New variable. - (init_decl_processing): Initialize its type. - * lex.c (init_parse): Initialize its value. Use ansi_null_node - for null_node in non-ANSI mode. - * typeck.c (build_binary_op_nodefault): Use ansi_null_node in - place of null_node to avoid spurious errors. - -1998-08-17 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (enter_scope_of): New function. - * parse.y (complex_direct_notype_declarator): Use it. - * semantics.c (enter_scope_of): New function. - -1998-08-17 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokparms): No, here. - - * decl.c (grokdeclarator): Catch parm with pointer to array of - unknown bound here... - * method.c (process_overload_item): ...not here. - - * gxxint.texi: Remove obsolete documentation of overloading code. - - * decl.c (finish_enum): Also set TYPE_SIZE_UNIT. - * class.c (finish_struct_bits): Likewise. - - * tree.c (lvalue_type): Fix for arrays. - * typeck.c (build_unary_op): Use lvalue_type. - * call.c (add_function_candidate): Likewise. - * cvt.c (convert_to_reference): Likewise. - - * decl2.c (lang_decode_option): Ignore -traditional. - - * init.c (build_offset_ref): Don't mess with error_mark_node. - * lex.c (do_scoped_id): Use cp_error. - - * rtti.c (get_tinfo_fn): Don't mess with the context for now. - -1998-08-17 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * decl.c (grokdeclarator): Allow anonymous types to be cv-qualified. - -Mon Aug 17 10:40:18 1998 Jeffrey A Law (law@cygnus.com) - - * cp-tree.h (set_identifier_local_value): Provide prototype. - - * decl2.c (do_namespace_alias): Remove unused variables `binding' - and `old'. - -Fri Aug 14 16:42:27 1998 Nick Clifton <nickc@cygnus.com> - - * Makefile.in: Rename BBISON to BISON so that it can be properly - inherited from the parent makefile. - -1998-08-13 Jason Merrill <jason@yorick.cygnus.com> - - * lang-options.h: Add -finit-priority. - * decl2.c: Likewise. Check flag_init_priority instead of - USE_INIT_PRIORITY. - - * decl2.c (setup_initp): New fn. - (start_objects, finish_objects, do_ctors): Handle init_priority. - (do_dtors, finish_file): Likewise. - -1998-08-13 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_copy): Hush warning. - - * rtti.c (get_tinfo_fn): Also set DECL_IGNORED_P. - -1998-08-12 Mark Mitchell <mark@markmitchell.com> - - * pt.c (print_template_context): Don't abort when instantiating a - synthesized method. - - * decl.c (grokdeclarator): Issue errors on namespace qualified - declarators in parameter lists or in class scope. - -1998-08-09 Mark Mitchell <mark@markmitchell.com> - - * pt.c (check_explicit_specialization): Don't abort on bogus - explicit instantiations. - -1998-08-07 Mark Mitchell <mark@markmitchell.com> - - * typeck.c (require_complete_type): Use complete_type_or_else. - (complete_type_or_else): Always return NULL_TREE on failure, as - documented. - - * pt.c (tsubst_aggr_type): Prototype. - (tsubst_decl): New function, split out from tsubst. Set - input_filename and lineno as appropriate. - (pop_tinst_level): Restore the file and line number saved in - push_tinst_level. - (instantiate_class_template): Set input_filename and lineno as - appropriate. - (tsubst): Move _DECL processing to tsubst_decl. Make sure the - context for a TYPENAME_TYPE is complete. - - * decl2.c (grokbitfield): Issue errors on bitfields declared with - function type. - (do_dtors): As in do_ctors, pretend to be a member of the same - class as a static data member while generating a call to its - destructor. - - * cvt.c (cp_convert_to_pointer): Handle NULL pointer - conversions, even in complex virtual base class hierarchies. - -1998-08-06 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (ENUM_TEMPLATE_INFO): New macro. - (TYPE_TEMPLATE_INFO): Likewise. - (SET_TYPE_TEMPLATE_INFO): Likewise. - (ENUM_TI_TEMPLATE): Likewise. - (ENUM_TI_ARGS): Likewise. - (lookup_nested_type_by_name): Remove. - * decl.c (maybe_process_template_type_declaration): Handle enums. - (start_enum): Don't check for primary-template enum declarations - here. - (finish_enum): Clean up, document. Make sure template enum - constants get the correct type. - (build_enumerator): Copy initializers for template enumerations, - too. - (grok_enum_decls): Document. - * lex.c (do_identifier): Document use of LOOKUP_EXPR a bit - better. Build LOOKUP_EXPRs for local variables, even if they are - TREE_PERMANENT. - * pt.c (tsubst_enum): Remove field_chain parameter. - (template_class_depth): Include the depth of surrounding function - contexts. - (push_template_decl): Check for primary-template enum declarations - here. Deal with enumeration templates. - (lookup_template_class): Likewise. - (for_each_template_parm): Likewise. - (instantiate_class_template): Don't call tsubst_enum directly, - call tsubst instead, to instantiate enums. Deal with all - field_chain issues here, not in tsubst_enum. - (lookup_nested_type_by_name): Remove. - (tsubst_aggr_type): Revise handling of enumeration types. - (tsubst): Likewise. - (tsubst_copy): Likewise. - (tsubst_expr): Call tsubst, not tsubst_enum for TAG_DEFNs. - -1998-08-04 Mark Mitchell <mark@markmitchell.com> - - * decl.c (pushtag): Don't mangle the name of a TYPE_DECL if it - uses template parameters. - * method.c (build_template_parm_names): Use the full set of - template arguments for tsubst'ing. - (build_overload_identifier): Pass the full set of template - arguments to build_template_parm_names, not just the - innermost_args. - * pt.c (TMPL_ARGS_DEPTH): Define using - TMPL_ARGS_HAVE_MULTIPLE_LEVELS, for clarity. - (NUM_TMPL_ARGS): New macro. - (add_outermost_template_args): Deal with the case where the outer - args will be completely discarded. - (coerce_template_parms): Use the full set of template arguments - for tsubst'ing. Simplify. Add some asserts. Improve - error messages. - (lookup_template_class): Pass the full set of template arguments - to coerce_template_parms. - (tsubst): Add assertion. - (do_type_instantiation): Don't instantiate member template - classes. - - * init.c (build_offset_ref): Deal with a TEMPLATE_ID_EXPR whose - name is a LOOKUP_EXPR, rather than an IDENTIFIER_NODE. - -1998-08-03 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (set_mangled_name_for_decl): Change return type to void. - - * decl.c (lookup_name_real): A namespace-level decl takes priority - over implicit typename. Avoid doing the same lookup twice. - - * search.c (dependent_base_p): New fn. - (dfs_pushdecls, dfs_compress_decls): Use it. - - * typeck.c (get_member_function_from_ptrfunc): Don't try to handle - virtual functions if the type doesn't have any. - -1998-08-03 Mark Mitchell <mark@markmitchell.com> - - * decl2.c (grokfield): Don't mangle the name of a TYPE_DECL if it - uses template parameters. - -1998-08-02 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.def (LOOKUP_EXPR): Document. Remove second argument. - * cp-tree.h (DECL_TI_TEMPLATE): Improve documentation. - * lex.c (do_identifier): Don't use a second argument, or a type, - when building LOOKUP_EXPRs. - (do_identifier): Likewise. - (do_scoped_id): Likewise. - * method.c (hack_identifier): Improve error message. - * pt.c (lookup_template_function): Don't needlessly call - copy_to_permanent or build_min. - (tsubst_copy): Remove #if 0'd code. Tsubst into LOOKUP_EXPRs if - necessary. - (do_decl_instantiation): Improve error message. - * tree.c (mapcar, case LOOKUP_EXPR): Don't be sorry; make a copy. - (build_min): Copy the type to the permanent obstack, too. - -1998-08-01 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (init_init_processing): Remove BI* handling. - (build_builtin_call): Remove. - (build_builtin_delete_call): New fn. - (build_delete): Use it. - -1998-07-31 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (PROCESSING_REAL_TEMPLATE_DECL_P): New macro. - (maybe_check_template_type): New function. - * decl.c (maybe_process_template_type_declaration): New function, - split out from pushtag Call maybe_check_template_type. - (pushtag): Use it. Use PROCESSING_REAL_TEMPLATE_DECL_P. - (xref_tag): Use PROCESSING_REAL_TEMPLATE_DECL_P. - * friend.c (do_friend): Use PROCESSING_REAL_TEMPLATE_DECL_P. - * pt.c (template_class_depth_real): Generalization of ... - (template_class_depth): Use it. - (register_specialization): Use duplicate_decls for duplicate - declarations of specializations. - (maybe_check_template_type): New function. - (push_template_decl_real): Fix comment. - (convert_nontype_argument): Likewise. - (lookup_template_class): Likewise. Avoid an infinite loop on - erroneous code. - (tsubst_friend_function): Fix comment. - (tsubst, case FUNCTION_DECL): Deal with a DECL_TI_TEMPLATE that is - an IDENTIFIER_NODE. - * semantics.c (begin_function_definition): Use - reset_specialization to note that template headers don't apply - directly to declarations after the opening curly for a function. - -1998-07-29 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (push_overloaded_decl): Use current_namespace instead of - DECL_CONTEXT (decl) to determine where we go. - - * decl.c (lookup_name_real): Fix typo. - -1998-07-28 Mark Mitchell <mark@markmitchell.com> - - * friend.c (is_friend): Be lenient with member functions to deal - with nested friends. - -1998-07-28 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Convert integer_zero_node to - ssizetype before passing it to set_rtti_entry. - * typeck2.c (initializer_constant_valid_p): Allow conversion of 0 - of any size to a pointer. - -1998-07-27 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (TI_USES_TEMPLATE_PARMS): Remove. - (build_template_decl_overload): Remove. - (set_mangled_name_for_decl): New function. - (innermost_args): Remove is_spec parameter. - (most_specialized, most_specialized_class): Remove declarations. - (lookup_template_class): Add entering_scope parameter. - (maybe_process_partial_specialization): New function. - (finish_template_decl): Likewise. - (finish_template_type): Likewise. - * class.c (finish_struct): Clean up processing of member template - specializations. - * decl.c (pushtag): Fix formatting. - (lookup_tag): Improve handling of pseudo-global levels. - (make_typename_type): Adjust call to lookup_template_class. - (shadow_tag): Use maybe_process_partial_specialization. - (xref_tag): Improve handling of member friends. - (start_function): Call push_nested_class before - push_template_decl. Don't call push_template_decl for - specializations. - * decl2.c (grok_x_components): Don't call xref_tag for - template instantiations. Handle UNION_TYPEs like RECORD_TYPEs. - (grokclassfn): Use set_mangled_name_for_decl. - (arg_assoc_class): Adjust call to innermost_args. - (mark_used): Don't call instantiate_decl for a TEMPLATE_DECL. - * error.c (dump_function_name): Improve printing of template - function names. - * friend.c (is_friend): Don't compare types of decls to determine - friendship, unless flag_guiding_decls. - (make_friend_class): Partial specializations cannot be friends. - (do_friend): Use set_mangled_name_for_decl. Call - push_template_decl_real instead of push_template_decl. - * method.c (build_decl_overload_real): Remove prototype. Give it - external linkage. - (build_overload_identififer): Adjust call to innermost_args. - (build_template_decl_overload): Remove. - (set_mangled_name_for_decl): New function. - * parse.y (.finish_template_type): New non-terminal. - (template_def): Use finish_template_decl. Use template_extdef - instead of extdef. - (template_extdef, template_datadef): New non-terminals, containing - only those rules for things which can be templates. - (datadef): Tidy. - (template_type, self_template_type): Use .finish_template_type. - (named_class_head): Use maybe_process_partial_specialization. - * pt.c (mangle_class_name_for_template): Remove context parameter. - (get_class_bindings): Remove outer_args parameter. - (complete_template_args): Remove. - (add_outermost_template_args): New function. - (register_specialization): Return the specialization. - (unregister_specialization): New function. - (tsubst_template_parms): Likewise. - (most_specialized, most_specialized_class): Prototype here as - static. - (original_template): Rename to most_general_template. - (tsubst_template_parms): New function. - (set_mangled_name_for_template_decl): Likewise. - (TMPL_ARGS_DEPTH): New macro. - (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): Adjust. - (TMPL_ARGS_LEVEL): New macro. - (SET_TMPL_ARGS_LEVEL): Likewise. - (TMPL_ARG): Likewise. - (SET_TMPL_ARG): Likewise. - (TMPL_ARGS_DEPTH): Likewise. - (finish_member_template_decl): Use finish_template_decl. - (maybe_process_partial_specialization): New function, split out - from tsubst. - (inline_needs_template_parms): Use TMPL_PARMS_DEPTH. - (maybe_begin_member_template_processing): Use new macros. - (is_member_template): Likewise. - (is_member_template_class): Likewise. - (add_to_template_args): Likewise. Deal with multiple levels of - args. - (maybe_process_partial_specialization): New function. - (retrieve_specialization): Add consistency check. - (determine_specialization): Return full argument list. - (check_explicit_specialization): Tweak friend handling. Use full - argument lists. Simplify. - (current_template_args): Use new macros. - (push_template_decl_real): Change ill-named mainargs to specargs. - Check that a partial specialization actually specializes at least - one parameter. Improve friend handling. Modify for full - template arguments. - (classtype_mangled_name): Don't mangle the names of - specializations. - (lookup_template_class): Add entering_scope parameter. Use it to - avoid finding a template type when an instantiation is required. - Simplify. Use full template arguments. - (tsubst_friend_function): Use unregister_specialization. Use new - macros. Use full template arguments. - (tsubst_friend_class): Substitute, using tsubst_template_parms, - into the template parameters before passing them to - redeclare_class_template. - (instantiate_class_template): Simplify. Use full template - arguments. Adjust calls to get_class_bindings. Use - SET_IDENTIFIER_TYPE_VALUE where needed. Improve friend handling. - (innermost_args): Use new macros. - (tsubst_aggr_type): New function, split out from tsubst. - (tsubst): Use tsubst_aggr_type, tsubst_template_parms, new calling - conventions for lookup_tmeplate_class. Refine handling of partial - instantiations. Remove calls to complete_template_args. - Simplify. Add consistency checks. Use set_mangled_name_for_decl - and set_mangled_name_for_template_decl. - (tsubst_copy): Use tsubst_aggr_type. - (instantiate_template): Use full template arguments. - (more_specialized): Improve formatting. - (more_specialized_class): Adjust calls to get_class_bindings. - (get_bindings_real): Don't call complete_template_args. - (most_specialized): Don't overwrite input; create a new list. - (most_specialized_class): Use most_general_template. - (regenerate_decl_from_template): Use unregister_specialization. - Use full template arguments. - (instantiate_decl): Use full template arguments. - (set_mangled_name_for_template_decl): New function. - * semantics.c (begin_class_definition): Use - maybe_process_partial_specialization. - (finish_member_class_template): New function. - (finish_template_decl): Likewise. - (finish_template_type): Likewise. - (typeck.c): Don't crash after issuing a compiler_error. - * Makefile.in (CONFLICTS): Adjust; we removed a s/r conflict. - -1998-07-27 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (build_functional_cast): Handle default-initialization. - - * call.c (build_over_call): Pass 1 to popclass. - - * parse.y (direct_notype_declarator): Add precedence declaration - to notype_unqualified_id case. - * Makefile.in (EXPECT): Adjust. - - * tree.c (ovl_member): Fix for single function in OVL. - -1998-07-27 Dave Brolley <brolley@cygnus.com> - - * c-lex.c (yylex): Fix boundary conditions in character literal and - string literal loops. - -1998-07-24 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): OK, do return the from_obj value - unless got_object depends on template parms. - - * parse.y (nested_name_specifier_1): Pull out the TYPE_MAIN_VARIANT. - - * pt.c (coerce_template_parms): Also complain about local enums. - - * cp-tree.h: Add prototype for set_identifier_local_value. - * decl.c (set_identifier_local_value_with_scope): Make static, - prototype. - * search.c (covariant_return_p): Likewise. - * except.c (build_terminate_handler, alloc_eh_object): Likewise. - - * call.c (build_method_call): Only pull out the type of a destructor - if it's a template type parm. - * decl.c (lookup_name_real): Never return the from_obj value. - -1998-07-23 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (process_start_catch_block_old): Call start_decl_1 for - catch parm. - * decl.c (start_decl_1): Avoid duplicate error. - - * init.c (expand_default_init): Only perform the initialization if - it will do something. - -1998-07-23 H.J. Lu (hjl@gnu.org) - - * parse.y (base_class): Check for invalid base class. - -1998-07-23 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_template): Fold in... - (import_export_class): ...to here. Handle dllimport/export. - - * class.c (build_vtable): Pass at_eof to import_export_vtable. - (prepare_fresh_vtable): Likewise. - * decl2.c (import_export_class): Split out... - (finish_prevtable_vardecl): From here. - * class.c (finish_struct_1): Call import_export_class if at_eof. - - * decl.c (start_function): #if 0 mysterious code I wrote and have - forgotten why. - * rtti.c (get_tinfo_fn): If this is for a class type, set - DECL_CONTEXT. - -1998-07-22 Jason Merrill <jason@yorick.cygnus.com> - - * inc/exception: Change terminate and unexpected to (). - - * parse.y (named_class_head_sans_basetype_defn): A - named_class_head_sans_basetype followed by '{' or ':' is a defn. - -1998-07-21 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (canonical_type_variant): New fn to handle arrays. - * cp-tree.h (CANONICAL_TYPE_VARIANT): Remove. - * pt.c (unify, default case): Also fold arg. Fix array bounds case. - * method.c (process_overload_item): Use build_overload_value for - arrays. - -1998-07-20 Dave Brolley <brolley@cygnus.com> - - * lex.c (mbchar.h): #include it. - (GET_ENVIRONMENT): New macro. - (init_parse): Set character set based on LANG environment variable. - (real_yylex): Handle multibyte characters in character literals. - (real_yylex): Handle multibyte characters in string literals. - -1998-07-19 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_identifier): Look for class value even if we don't - have a global value. Do implicit declaration if parsing is 2. - * semantics.c (finish_call_expr): Pass 2 if we're doing Koenig - lookup. - -1998-07-19 Mark Mitchell <mark@markmitchell.com> - - * decl.c (pushtag): Revert previous change. - * pt.c (lookup_template_class): Don't put out debugging - information for types that use template parameters. - - * decl.c (pushtag): Don't put out debugging information for - compiler-generated typedefs. - - * error.c (dump_type_real): Don't crash when presented with - intQI_type_node or the like. - - * semantics.c (finish_translation_unit): Fix spelling error in - comment. - -1998-07-17 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): Pull out single function here. - (select_decl): Not here. - (unqualified_namespace_lookup): Use CP_DECL_CONTEXT. - - * decl.c (qualify_lookup): Tweak again. - - * pt.c (lookup_template_class): Don't mess with the context of the - instantiation. - * decl2.c (current_decl_namespace): Remove special handling for - templates. - - * pt.c (tsubst, case FUNCTION_DECL): Fix getting complete args for - a member template specialization. - - * tree.c (ovl_member): Use decls_match to compare functions. - * decl.c (decls_match): Check the context of a function. - - * parse.y (primary): Use notype_unqualified_id instead of IDENTIFIER - in Koenig lookup support rules. - * semantics.c (finish_call_expr): Handle the new cases. - - * typeck.c (build_x_function_call): Handle overloaded methods. - - * decl.c (grokvardecl): Don't call build_static_name for extern "C". - -1998-07-16 Mark Mitchell <mark@markmitchell.com> - - * semantics.c (finish_object_call_expr): Revert previous change. - * call.c (build_new_method_call): Likewise. Instead, convert - TYPE_DECLs to IDENTIFIERs here, in the presence of templates. - -1998-07-16 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (qualify_lookup): Handle templates. - - * decl2.c (do_using_directive): Don't pass ancestor. - * decl.c (push_using_directive): Calculate ancestor. - - * decl2.c (do_nonmember_using_decl): Allow for type shadowing. - * decl.c (pushdecl): Move type shadowing handling from here... - (duplicate_decls): ...to here. - * decl.c (set_identifier_local_value_with_scope): New fn. - (pushdecl): Use it. - (set_identifier_local_value, lookup_type_current_level): New fns. - * decl2.c (do_local_using_decl): Handle types and binding level - stuff properly. - - * init.c (build_offset_ref): Don't call mark_used on an OVERLOAD. - * decl.c (select_decl): Extract a lone function from an OVERLOAD. - (lookup_namespace_name): Likewise. - * typeck.c (build_unary_op): Not here anymore. - - * decl2.c (do_class_using_decl): Make sure we get an identifier. - * class.c (handle_using_decl): Ignore TYPE_DECLs. - - * decl.c (qualify_lookup): New fn. - (lookup_name_real): Use it. - -1998-07-16 Martin v. Loewis <loewis@informatik.hu-berlin.de> - - * decl2.c (add_using_namespace): When directly using a namespace - that was indirect before, promote it. - - * cp-tree.h (LOOKUP_PREFER_TYPES, LOOKUP_PREFER_NAMESPACES, - LOOKUP_PREFER_BOTH, LOOKUP_NAMESPACES_ONLY, LOOKUP_TYPES_ONLY, - LOOKUP_QUALIFIERS_ONLY, LOOKUP_TEMPLATES_EXPECTED): New macros. - * decl.c (select_decl): Replace two flag parameters by one. - (unqualified_namespace_lookup): Likewise, pass flag. - (lookup_flags): New function. - (lookup_name_real): Compute flags, pass them. - (lookup_namespace_name): Call with zero-flag. - * decl2.c (ambiguous_decl): Add flag parameter, complain only - according to flags. - (lookup_using_namespace, qualified_lookup_using_namespace): - Add flag parameter, pass them through. - * lex.c (do_scoped_id): Call with zero-flag. - -1998-07-16 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (convert_for_assignment): Use comptypes. - -1998-07-16 Mark Mitchell <mark@markmitchell.com> - - * semantics.c (finish_object_call_expr): Move test for the - function called being a TYPE_DECL to ... - * call.c (build_new_method_call): Here. - -1998-07-15 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (arg_assoc_class): Also look at template arguments, if any. - (arg_assoc): Handle error_mark_node and multiple levels of TREE_LIST. - - * lex.c (looking_for_typename): Don't initialize. - - * decl2.c (ambiguous_decl): Clarify error message. - - * decl.c (push_using_directive): Iterate over namespaces used - indirectly. - -1998-07-15 Martin v. Löwis <loewis@informatik.hu-berlin.de> - - * decl2.c (add_using_namespace): Iterate over namespaces used - indirectly. - - * decl.c (lookup_name_real): Accept namespace aliases as locals. - (cat_namespace_levels): Ignore aliases. - (duplicate_decls): Ignore duplicate aliases. - * decl2.c (do_namespace_alias): Process block level namespace - aliases. Store alias with pushdecl. Remove odr errors. - * parse.y (namespace_alias): New non-terminal. - (extdef): Use it. - -1998-07-15 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (arg_assoc_type): Handle METHOD_TYPE like FUNCTION_TYPE. - Handle TEMPLATE_TYPE_PARM. - (arg_assoc): Rewrite. - - * pt.c (complete_template_args): Don't look at the context unless - we have to. - - * method.c (build_decl_overload_real): Fix namespace handling. - - * typeck.c (build_unary_op): Extract a lone function from an - OVERLOAD. - - * call.c (build_scoped_method_call): Handle getting a namespace - for basetype in a destructor call. - (check_dtor_name): Handle enums. - - * parse.y (using_directive): New nonterminal. - (extdef, simple_stmt): Use it. - -1998-07-14 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl2.c (add_function): Move error message ... - (arg_assoc_namespace): ... from here. - -1998-07-14 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (namespace_qualifier): Fix multiple level handling. - * decl2.c (namespace_ancestor): Use CP_DECL_CONTEXT. - (arg_assoc): Don't skip the first argument of a function. - -Tue Jul 14 20:09:22 1998 Jeffrey A Law (law@cygnus.com) - - * search.c (my_tree_cons): Clean up. - -1998-07-14 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (joust): Don't warn about "confusing" conversions to the - same type. - -1998-07-14 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * class.c (push_nested_class): Complain about namespaces. - * decl.c (start_decl): Enter the object's namespace. - (cp_finish_decl): Leave it. - (grokdeclarator): Likewise. - * decl2.c (check_decl_namespace): New function. - (finish_file): Call it. - * parse.y (complex_direct_notype_declarator): Set complexity - of namespace-qualified ids to -1, enter the namespace. - - * method.c (build_template_decl_overload): Expect _DECL as first - parameter. Put context temporarily into current_namespace. - * pt.c (check_explicit_specialization): Change caller. - (tsubst): Likewise. - - * init.c (build_offset_ref): Call mark_used and - convert_from_reference for namespace members. - -Mon Jul 13 23:25:28 1998 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * search.c (my_tree_cons): The bitfield is at index 2. - -Mon Jul 13 17:21:01 1998 Nick Clifton <nickc@cygnus.com> - - * lang-options.h: Format changed to work with new --help support - in gcc/toplev.c - -1998-07-12 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * decl2.c (build_expr_from_tree): Change calls of do_identifier. - Do Koenig lookup in CALL_EXPR. - (arg_assoc): Handle error_mark. - * lex.c (is_global): New function. - (do_identifier): Expect arguments for Koenig lookup. - * parse.y (primary): Add rules for calls of unqualified function calls. - (do_id): Change call of do_identifier. - * pt.c (finish_stmt_expr): Likewise. - * semantics.c (finish_id_expr): Likewise. - (finish_call_expr): Add integer parameter to indicate - argument-dependent lookup. - - * decl.c (struct binding_level): New field using_directives. - (push_using_decl): Not sorry anymore. - (push_using_directive): New function. - (lookup_tag): Use CP_DECL_CONTEXT to iterate. - (unqualified_namespace_lookup): New function, code from ... - (lookup_name_real): ... here. - * decl2.c (lookup_using_namespace): Pass using list instead of - initial scope. - (validate_nonmember_using_decl): New function. - (do_nonmember_using_decl): New function. - (do_toplevel_using_decl): Use them. - (do_local_using_decl): New function. - (do_using_directive): Support block-level directives. - * parse.y (simple_stmt): Support using declarations and - directives. - (namespace_qualifier, namespace_using_decl): New non-terminals. - - * xref.c (classname): New function. - (GNU_xref_hier): Change class and base parameters to tree. - * decl.c (xref_baseypes): Change caller. - * friend.c (make_friend_class): Likewise. - -1998-07-12 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu> - - * typeck.c (comptypes, case TEMPLATE_TEMPLATE_PARM): Add parameter - comparison. - - * pt.c (for_each_template_parm, case TEMPLATE_DECL): If it is a - template template parameter, record its use. - (for_each_template_parm, case TEMPLATE_TEMPLATE_PARM): Traverse - its template arguments if exists. - - * pt.c (coerce_template_template_parms): New function equivalent - to coerce_template_parms when IS_TMPL_PARM is true. - (coerce_template_parms): Use it. Remove the IS_TMPL_PARM parameter, - all callers changed. - - (coerce_template_parms): Access ARGLIST properly when creating a - new vector. Only accept implicit TYPE_DECL as valid argument for - a template template parameter when it is a base class of - current_class_type. Don't display error message when COMPLAIN is - false. - -1998-07-12 Klaus Kaempf (kkaempf@progis.de) - - * repo.c (get_base_filename): Use file_name_nondirectory. - (open_repo_file): Ditto. - * cp-tree.h (file_name_nondirectory): Add prototype. - -1998-07-12 Jason Merrill <jason@yorick.cygnus.com> - - * friend.c (do_friend): Pull the identifier out of declarator. - Use cp_error and friends. - * decl2.c (qualified_lookup_using_namespace): Fix call to - purpose_member. - * decl.c (lookup_name_real): Don't call complete_type on a namespace. - (grokvardecl): Use DECL_CLASS_SCOPE_P. - * cvt.c (convert_pointer_to_real): Check for error_mark_node sooner. - * class.c (warn_hidden): Fix for OVERLOAD. - From grahams@rcp.co.uk: - * cp-tree.h (DEFARG_NODE_CHECK): New macro. - (DEFARG_LENGTH, DEFARG_POINTER): Use it. - -Sun Jul 12 01:20:57 1998 Jeffrey A Law (law@cygnus.com) - - * g++.1 (-traditional): Remove duplicated documentation. - -1998-07-11 Mark Mitchell <mark@markmitchell.com> - - * method.c (flush_repeats): Add nrepeats parameter. - (issue_nrepeats): Likewise. - (is_back_referenceable_type): New function. Don't back-reference - TEMPLATE_TYPE_PARMs as well as simple types like integers. - (build_mangled_name_for_type): Likewise. - (build_mangled_name_for_type_with_Gcode): Likewise. - (lasttype): Remove. - (nrepeats): Likewise. - (Nrepeats): Likewise. - (start_squangling): Don't clear the variables removed above. - (end_squangling): Likewise. - (flush_repeats): Tidy. Use nrepeats parameter rather than - Nrepeats global. - (issue_nrepeats): Likewise, but with nrepeats global. Use - is_backreferenceable_type. - (build_overload_nested_name): Tidy. Add comment. Use - build_mangled_name_for_type. - (build_underscore_int): Comment. - (build_overload_scope_ref): Use build_mangled_name_for_type. - (build_overload_int): Likewise. - (build_template_template_parm_names): Tidy. - (build_template_parm_names): Use build_mangled_name_for_type. - (build_overload_identifier): Add comments. - (build_mangled_name_for_type_with_Gcode): Split out from - build_mangled_name. - (build_mangled_name_for_type): Use it. - (build_mangled_name): Rework to use build_mangled_name_for_type - and to not use global nrepeats/Nrepeats. Tidy. - (process_modifiers): Tidy. - (check_btype): Use is_backreferenceable_type. Add comment. - Rename `node' to `type'. - (process_overload_item): Set numeric_output_need_bar here. - Use build_mangled_name_for_type. Tidy. - (build_decl_overload_real): Tidy. Don't use Nrepeats. Use - build_mangled_name_for_type. - - * pt.c (push_template_decl_real): Don't look at DECL_TEMPLATE_INFO - for TYPE_DECLs. - -1998-07-08 Vladimir N. Makarov <vmakarov@cygnus.com> - - * cp-tree.h (warn_long_long): Define. - * decl.c (grokdeclarator): Add flag `warn_long_long' as guard for - warning "ANSI C++ does not support `long long'". - * decl2.c (warn_long_long): Define. - (lang_decode_option): Parse -Wlong-long, -Wno-long-long options. - -1998-07-07 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (xref_tag): Handle attributes between 'class' and name. - * parse.y (aggr): Likewise. - * semantics.c (finish_class_definition): Likewise. - * Makefile.in (EXPECTED): Adjust. - - * cp-tree.h: Declare flag_optional_diags and warn_multichar. - * decl2.c: Define them. - (lang_decode_option): Handle them. - * lang-options.h: Add -foptional-diags. - * class.c (finish_struct): Don't complain about multiple meanings of - name if -fno-optional-diags. - * decl.c (pushdecl_class_level): Likewise. - * lex.c (real_yylex): Check warn_multichar. - -1998-07-06 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_tag): Use CP_DECL_CONTEXT. - - * tree.c (make_binfo): Fix length. - -1998-06-30 Benjamin Kosnik <bkoz@bliss.nabi.net> - - * decl2.c (lang_decode_option): Remove warn_template_debugging. - * lang-options.h: Ditto. - -Mon Jun 29 20:17:40 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * except.c (build_eh_type_type_ref): Remove unused variable `susp'. - (process_start_catch_block): Likewise for variables - `false_label_rtx', `call_rtx' and `return_value_rtx'. - -1998-06-29 Brendan Kehoe <brendan@cygnus.com> - - * tree.c (build_srcloc): Make sure we allocate this node on the - permanent obstack. - -Sat Jun 27 23:34:18 1998 Fred Fish <fnf@ninemoons.com> - - * g++spec.c (NEED_MATH_LIBRARY): Define to 1 if not already defined. - (lang_specific_driver): Initialize need_math with NEED_MATH_LIBRARY. - (lang_specific_driver): Only add -lm automatically if need_math is - nonzero. - -Sat Jun 27 12:22:56 1998 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (g++): Depend on mkstemp.o. Link in mkstemp.o - -Sat Jun 27 07:36:09 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (EXPR_H): New dependency variable. - (decl2.o): Depend on $(EXPR_H). - (typeck.o): Likewise. - (init.o): Likewise. - (expr.o): Likewise. - -1998-06-25 Benjamin Kosnik <bkoz@lisa.cygnus.com> - - * decl.c (start_enum): Put local enums on permanent_obstack. - -1998-06-25 Mark Mitchell <mark@markmitchell.com> - - * cp-tree.h (c_get_alias_set): Declare. - * decl.c (init_decl_processing): Set lang_get_alias_set. - -1998-06-25 Andrew MacLeod <amacleod@cygnus.com> - - * cp-tree.h (mark_all_runtime_matches): Add function prototype. - * except.c (mark_all_runtime_matches): Set TREE_SYMBOL_REFERENCED - flag for all function decls which are in the exception table. - * exception.cc (__cplus_type_matcher): Check for CATCH_ALL_TYPE match. - * decl2.c (finish_file): Call mark_all_runtime_matches to make sure - code is emitted for any referenced rtti function. - -1998-06-25 Dave Brolley <brolley@cygnus.com> - - * lang-specs.h: Use new | syntax to eliminate - string concatenation. - -1998-06-25 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (CP_DECL_CONTEXT): New macro. - * decl2.c (is_namespace_ancestor, lookup_using_namespace): Use it. - * method.c (build_overload_nested_name): Likewise. - * sig.c (build_signature_pointer_or_reference_type): Don't set - DECL_CONTEXT. - -1998-06-24 Martin v. Löwis <loewis@informatik.hu-berlin.de> - - Set DECL_CONTEXT for globals to NULL_TREE instead of global_namespace. - * cp-tree.h (FROB_CONTEXT): New macro. - (DECL_MAIN_P): ::main should have a DECL_CONTEXT of NULL_TREE. - * decl.c (namespace_binding): Replace NULL_TREE with - global_namespace. - (set_namespace_binding, pop_namespace, lookup_name_real): Likewise. - * decl2.c (is_namespace_ancestor, lookup_using_namespace): - Likewise. - * decl.c (pushtag): Use FROB_CONTEXT. - (pushdecl, make_typename_type, define_function, grokdeclarator): - Likewise. - * decl2.c (set_decl_namespace, do_namespace_alias): Likewise. - * pt.c (push_template_decl_real, lookup_template_class, tsubst): - Likewise. - * decl2.c (decl_namespace): Return global_namespace if no context. - * method.c (build_overload_nested_name): Expect null as context. - * pt.c (mangle_class_name_for_template): Do nothing for null - contexts. - (lookup_template_class): Allow for null id_context. - -1998-06-25 Richard Henderson <rth@cygnus.com> - - * method.c (emit_thunk): Set current_function_is_thunk for the - ASM_OUTPUT_MI_THUNK case as well. - -1998-06-23 Andrew MacLeod <amacleod@cygnus.com> - - * exception.cc (__cplus_type_matcher): Get a match_info pointer - instead of an exception table entry as a parameter. - -1998-06-23 Andrew MacLeod <amacleod@cygnus.com> - - * parse.y (function_try_block): Don't call start_catch_handler. - * except.c (call_eh_info): Remove coerced field from declaration. - (build_eh_type_type_ref): New function to create an address of a - rtti function for the new style exception tables. - (expand_start_catch_block): Split function, this contains the - common part. - (process_start_catch_block_old): New function to perform the rest - of expand_start_catch_block under old style exceptions. - (process_start_catch_block_old): New function to perform the rest - of expand_start_catch_block under new style exceptions. - (expand_end_catch_block): Only pop the false label off the stack under - the old style of exceptions. - * semantics.c (finish_try_block): Don't call start_catch_handler. - * exception.cc (struct cp_eh_info): Add original_value field. - (__cplus_type_matcher): Perform type matching on the original exception - value, and if we have a match, set the current value. - (__cp_push_exception): Set the original expcetion value. - -1998-06-23 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (joust): Fix confusing conversion warning. - - * call.c (build_op_delete_call): Add placement parm. Check - LOOKUP_SPECULATIVELY. - * cp-tree.h, decl2.c, init.c: Adjust. - * decl.c (finish_function): Use it. - - * pt.c (tsubst): Diagnose creating void fields or variables. - -Mon Jun 22 08:50:26 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * call.c (build_scoped_method_call): Remove unused variable `tmp'. - - * cp-tree.h (check_dtor_name): Add prototype. - - * init.c (expand_member_init): Remove unused variables - `ptr_type_node', `parm' and `rval'. - - * ptree.c (print_lang_type): Use HOST_WIDE_INT_PRINT_DEC specifier - in call to fprintf. - (lang_print_xnode): Likewise. - - * typeck2.c (enum_name_string): Cast argument to sprintf to long - and use %ld specifier. - - * xref.c (GNU_xref_end_scope): Use HOST_WIDE_INT_PRINT_DEC - specifier in call to fprintf. - (GNU_xref_member): Cast argument to sprintf to int. - -Fri Jun 19 23:22:42 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * typeck2.c (pop_init_level): Warn about implicit zero initialization - of struct members. - -Thu Jun 18 09:32:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * cp-tree.h: Prototype function `check_java_method'. - -1998-06-17 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct): Make conflicting use of id a pedwarn. - * decl.c (pushdecl_class_level): Likewise. - -1998-06-17 Mark Mitchell <mark@markmitchell.com> - - * pt.c (convert_nontype_argument): Issue an error when presented - with an integer (real) constant that cannot be simplified to an - INT_CST (REAL_CST). - - * cp-tree.h (c_get_alias_set): Remove declaration added in - 1998-06-13 change that should never have been checked in. - -1998-06-17 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Change % in format strings - to %%. - - * decl.c (grokvardecl): Don't build_static_name for decls that - aren't at namespace scope. - - * init.c (perform_member_init): Catch default-initialization of - references. - -1998-06-17 Mark Mitchell <mark@markmitchell.com> - - * errfn.c (cp_thing): Handle the `%%' formatting sequence. - -1998-06-17 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (hack_identifier): Complain about getting a namespace - or class template. - * typeck.c (decay_conversion): Remove check for namespaces. - * typeck2.c (incomplete_type_error): Likewise. - * parse.y (template_arg): Add PTYPENAME expansion. - -1998-06-16 Andrew MacLeod <amacleod@cygnus.com> - - * decl.c (grokvardecl): Don't build external assembler names for - TYPENAMEs in other namespaces as there is no declarator. - * error.c (cp_file_of, cp_line_of): Don't extract file or line number - info from DECL_CONTEXT if it is NULL. - -1998-06-16 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (check_dtor_name): Split out. - (build_scoped_method_call): Use it. - (build_method_call): Use it. - * init.c (build_offset_ref): Use it. - - * typeck.c (build_static_cast): Fix handling of pointers to members. - - * decl.c (finish_function): Just return nothing from a constructor. - * typeck.c (c_expand_return): Complain about returning a void - expression from a destructor. - -1998-06-13 Mark Mitchell <mark@markmitchell.com> - - * class.c (alter_access): Accept a BINFO explaining how to get - from the entity whose accessed is being altered to the type doing - the altering. - (handle_using_decl): New function containing code split out from ... - (finish_struct_1): Here. - - * cp-tree.h (complete_type_or_else): Declare. - * init.c (build_new_1, build_delete): Use it. - * typeck.c (require_complete_type): Use complete_type, rather than - expanding it inline. - (complete_type_or_else): New function. - (build_component_ref): Use it. - (pointer_int_sum): Make sure the type pointed to is complete. - (pointer_diff): Likewise. - - * pt.c (for_each_template_parm): Traverse the TYPE_CONTEXT for - types. - - * search.c (get_matching_virtual): Note that member templates - cannot override virtual functions. - -1998-06-12 Brendan Kehoe <brendan@cygnus.com> - - * pt.c (check_explicit_specialization): If DECLARATOR turned into - an error_mark_node from lookup_template_function, return the same. - (determine_specialization): Also make sure TEMPLATE_ID isn't an - error_mark_node, before we try to read its operands. - * decl.c (grokdeclarator): If we got an error_mark_node from - check_explicit_specialization, just return it right back. - -1998-06-12 Mark Mitchell <mark@markmitchell.com> - - * class.c (instantiate_type): Don't treat template-ids that don't - specify any template arguments as equivalent to ordinary - identifiers. Use OFFSET_REF instead of SCOPE_REF to refer to - pointer-to-members for member templates. Tidy slightly. - * cp-tree.def (TEMPLATE_ID_EXPR): Revise documentation. - * init.c (build_offset_ref): Handle template-ids like ordinary - identifiers, for the most part, but store a TEMPLATE_ID_EXPR in the - offset part of the OFFSET_REF. - * typeck.c (build_unary_op): Change check for unknown types to - look for OFFSET_REFs, not SCOPE_REFs. - -1998-06-11 Mark Mitchell <mark@markmitchell.com> - - * pt.c (is_member_template_class): New function. - (push_template_decl_real): Use it. - -1998-06-11 Benjamin Kosnik <bkoz@elmo.cygnus.com> - - * friend.c (do_friend): Add support for nested classes using - member functions of the enclosing class as friends. - -1998-06-10 Mark Mitchell <mark@markmitchell.com> - - * call.c (convert_default_arg): Make global, not static. - (convert_arg_for_ellipsis): Split out from ... - (build_over_call): Here. - * cp-tree.h (convert_default_arg); Declare. - (convert_arg_to_ellipsis): Likewise. - (do_member_init): Remove. - * init.c (do_member_init): Remove; this code is dead. - (expand_member_init): Remove much of this code; it is dead. - * typeck.c (convert_arguments): Use convert_default_arg and - convert_arg_for_ellipsis, rather than duplicating here. - - * call.c (convert_like): Don't fail silently if - build_user_type_conversion fails. Always return error_mark_node - for failure. - -1998-06-10 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (covariant_return_p): Complain about ambiguous base. - - * typeck.c (build_component_ref): Diagnose ref to nested type. - -1998-06-10 Brendan Kehoe <brendan@cygnus.com> - - * decl.c (grokparms): Check that INIT isn't an error_mark_node - before giving error about invalid type for default arg. - -1998-06-10 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_method_call): Fix thinko. - -1998-06-10 Dave Brolley <brolley@cygnus.com> - - * decl2.c (lang_decode_option): New argc/argv interface. - * cp-tree.h (lang_decode_option): New argc/argv interface. - * lang-specs.h (default_compilers): Only call cpp if -E, -M or -MM is - specified for cpplib-enabled compilers. - * lex.c (lang_init): Don't check_newline for cpplib. - (init_parse): Don't initialize cpplib here. - -1998-06-10 Brendan Kehoe <brendan@cygnus.com> - - * typeck.c (build_component_ref): Make sure FIELD has a lang_specific - piece before checking DECL_MUTABLE_P. - -1998-06-10 John Carr <jfc@mit.edu> - - * tree.c (debug_binfo): Make printf format match arguments. - - * error.c (OB_PUTI): Make printf format match arguments. - -1998-06-10 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (perform_member_init): Handle default-initialization. - - * except.c (build_throw): Handle throwing NULL. - - * typeck.c (build_x_function_call): Use resolve_offset_ref. - - * search.c (compute_access): Only strip an anonymous union - for a FIELD_DECL. - - * call.c (add_builtin_candidates): Tweak. - - * cvt.c (build_expr_type_conversion): Restore code for conversion - from class types. - * decl2.c (delete_sanity): Use it. Clean up. - - * typeck.c (comp_ptr_ttypes_real): Fix cv-qual comparisons. - -1998-06-10 Branko Cibej <branko.cibej@hermes.si> - - * typeck.c (c_expand_return): Don't warn about void expressions on - return statements in functions returning void. - -1998-06-09 Mark Mitchell <mark@markmitchell.com> - - * pt.c (fn_type_unification): Revise documentation. Tidy. - (type_unification): Likewise. - -1998-06-09 Andrew MacLeod <amacleod@cygnus.com> - - * semantics.c (finish_try_block): Rename expand_start_catch, and delete - expand_end_catch. - * parse.y (function_try_block): Rename expand_start_catch, and delete - expand_end_catch. - * except.c (expand_end_eh_spec): Rename expand_start_catch, and delete - expand_end_catch. - -1998-06-09 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (lookup_member): New fn. - * class.c (finish_struct_1): Use it. - * decl.c (lookup_name_real): Use it. - -Mon Jun 8 20:45:52 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (decl2.o): Depend on dwarf2out.h and dwarfout.h. - - * cp-tree.h: Add prototype for `maybe_print_template_context' and - `maybe_make_one_only'. - - * decl.c (auto_function): Remove unused variable `decl'. - - * decl2.c: Include dwarf2out.h and dwarfout.h. - - * lex.c: Remove redundant declarations of `set_float_handler' and - `asm_out_file'. - -1998-06-08 Andrew MacLeod <amacleod@cygnus.com> - - * except.c (init_exception_processing): Remove NEW_EH_MODEL compile - time flag. Call __cp_eh_info instead of __cp_exception_info. - * exception.cc (struct cp_eh_info): Remove NEW_EH_MODEL flag. - (__cp_exception_info): Return offset into cp_eh_info structure to - match what use to be the start of this structure. - (__cp_eh_info): New function to return a pointer to cp_eh_info struct. - (__cplus_type_matcher, __cp_push_exception): Remove NEW_EH_MODEL - compile time flag. - (__uncatch_exception, __check_eh_spec, std::uncaught_exception): Call - __cp_eh_info instead of __cp_exception_info. - -1998-06-08 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (cp_finish_decl): Disable inlining of extern inlines - with static variables. - -1998-06-08 Mark Mitchell <mark@markmitchell.com> - - * init.c (build_offset_ref): Correct previous change to use build, - not build_min. - -1998-06-07 Mark Mitchell <mark@markmitchell.com> - - * class.c (instantiate_type): Handle pointer-to-members where the - member is a template. - * init.c (build_offset_ref): Likewise. - * typeck.c (build_unary_op): Likewise. - -1998-06-07 Richard Henderson <rth@cygnus.com> - - * lex.c (lang_init_options): New function. - (lang_init): Remove flag_exceptions == 2 hack. - -1998-06-05 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (envelope_add_decl): Tweak for implicit typename. - - * call.c (joust): Also warn about confusing conversion op/constructor - overload resolution. - - * spew.c (yylex): Also return the TYPE_DECL if got_object. - Don't clear got_object after '~'. - * call.c (build_scoped_method_call): Tweak destructor handling. - (build_method_call): Likewise. - * pt.c (tsubst_copy, case METHOD_CALL_EXPR): Don't mess with - TYPE_MAIN_VARIANT for destructors. - * semantics.c (finish_object_call_expr): Complain about calling a - TYPE_DECL. - -1998-06-05 Per Bothner <bothner@cygnus.com> - - * g++spec.c (lang_specific_pre_link, lang_specific_extra_ofiles): - Define - update needed by gcc.c change. - -1998-06-05 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (cp_printers): Use 'o' instead of '_' for the null entry. - -1998-06-05 Martin v. Loewis <loewis@informatik.hu-berlin.de> - - * cp-tree.h (DECL_NAMESPACE_ALIAS, ORIGINAL_NAMESPACE): Declare. - * decl.c (lookup_name_real): Add namespaces_only parameter. - If set, return only NAMESPACE_DECLs. - (select_decl): Likewise. - (identifier_type_value): Give additional parameter. - (lookup_name_nonclass): Likewise. - (lookup_name): Likewise. - (find_binding): Skip namespace aliases. - (binding_for_name): Likewise. - (push_namespace): Check for namespace aliases. - (lookup_name_namespace_only): New function. - (begin_only_namespace_names, end_only_namespace_names): New functions. - * decl2.c (set_decl_namespace): Skip namespace aliases. - (do_using_directive): Likewise. - (do_namespace_alias): Produce namespace aliases, fix alias - redeclaration. - * error.c (dump_decl): Support SCOPE_REF. - * parse.y (extdef): Wrap lookup with namespace_only for namespace - aliases and using declarations. - -1998-06-04 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (really_overloaded_fn): Only see through one TREE_LIST. - - * error.c (dump_expr): Clean up NEW_EXPR case. - -1998-06-04 Martin von Löwis <loewis@informatik.hu-berlin.de> - - Suggested by Brendan Kehoe - * decl2.c (do_toplevel_using_decl): When decl is a TYPE_DECL, - treat it as using ::decl. - - * decl2.c (arg_assoc_type): Process unknown_type_node and OFFSET_TYPE. - - * tree.c (mapcar): Support NEW_EXPR. - - * error.c (dump_expr): Support NEW_EXPR. - -1998-06-03 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (make_thunk): Use overload machinery to make name. - * search.c (covariant_return_p): New fn. - (get_matching_virtual): Use it. - - * init.c (build_new_1): Fix check for void. - -1998-06-01 Per Bothner <bothner@cygnus.com> - - * cp-tree.h (TYPE_FOR_JAVA): New macro. - * decl.c, cp-tree.h (java_byte_type_node, java_short_type_node, - java_int_type_node, java_long_type_node, java_float_type_node, - java_double_type_node, java_char_type_node, java_boolean_type_node): - New "primitive" types, with predefined names __java_byte etc. - (record_builtin_java_type): New function. - (init_decl_processing): Make Java types with record_builtin_java_type. - (pushtag, grokdeclarator): Set TYPE_FOR_JAVA if in extern "JAVA". - (xref_baseypes): If base class was TYPE_FOR_JAVA, so is this class. - (grokfndecl): Call check_java_method for Java classes. - * method.c (is_java_type): Removed. Replaced with TYPE_FOR_JAVA. - (process_overload_item): Match types against specific - java_XX_type_node types, rather than using is_java_type. - * class.c (finish_struct_1): Don't add default copy constructor - or operator= if TYPE_FOR_JAVA. - (pop_lang_conext): Restore strict_prototyp proper if Java. - * decl2.c (acceptable_java_type, check_java_method): New functions. - * pt.c (instantiate_class_template): Copy TYPE_FOR_JAVA from pattern. - (tsubst): Move common statement after if statement. - * typeck.c (comptypes): If strict, TYPE_FOR_JAVA must match. - -1998-06-01 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (for_each_template_parm): Use first_rtl_op. - - * tree.c (build_cplus_array_type_1): Also check index_type for - template parms. - -1998-05-31 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Always copy BINFO_BASETYPES. - -1998-05-29 scott snyder <snyder@d0sgif.fnal.gov> - - * tree.c (layout_basetypes): If we change TYPE_SIZE, change - TYPE_SIZE_UNIT too. - -1998-05-29 Mark Mitchell <mark@markmitchell.com> - - * decl.c (grokdeclarator): Don't complain about in-class - initialization of static consts if we don't really know the type - of the variable. - -1998-05-29 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (DECL_DESTRUCTOR_P): New macro. - * method.c (build_destructor_name): New fn. - * decl2.c (maybe_retrofit_in_chrg): Split out... - (grokclassfn): From here. Reorganize. - * decl.c (grok_ctor_properties): Make sure ctors for types with - vbases have the in_chrg parm. - * pt.c (instantiate_class_template): Update - TYPE_USES_VIRTUAL_BASECLASSES from tsubsted bases. Don't call - grok_*_properties. - (tsubst): Call grok_ctor_properties and maybe_retrofit_in_chrg. - -1998-05-28 Mark Mitchell <mark@markmitchell.com> - - * pt.c (instantiate_decl): Make test for whether or not static - variables should be instantiated early match its comment. - -1998-05-28 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): Always pedwarn about vacuously redeclaring - a member. - (start_function): Call check_default_args. - * decl2.c (grokfield): Don't call check_default_args. - (check_default_args): Use cp_error_at. - * lex.c (do_pending_defargs): Call check_default_args. - -1998-05-27 Brendan Kehoe <brendan@cygnus.com> - - * call.c (build_method_call): Make sure get_type_value returns - something before we try to use its TYPE_MAIN_VARIANT. - (build_scoped_method_call): Likewise. - -1998-05-27 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (digest_init): Complain about getting a TREE_LIST to - initialize an array. - - * search.c (expand_upcast_fixups): Don't set DECL_CONTEXT and - DECL_VIRTUAL_P. - - * friend.c (do_friend): Clarify template warning. - -1998-05-27 Mark Mitchell <mark@markmitchell.com> - - * decl.c (shadow_label): Don't treat decls as identifiers. - (maybe_push_to_top_level): Clear shadowed_labels. - - * pt.c (instantiate_decl): Reset lineno and filename after calling - regenerate_decl_from_template. - - * decl.c (grokdeclarator): Don't try to use TYPE_OBSTACK on an - error_mark_node. - -1998-05-27 Kevin Buhr <buhr@stat.wisc.edu> - - * parse.y (base_class): Use is_aggr_type, not IS_AGGR_TYPE. - -1998-05-26 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (process_template_parm): Accept TYPENAME_TYPE nodes. - (convert_nontype_argument): Handle cases when nontype template - parameters become classes after substitution. - -1998-05-26 Mark Mitchell <mark@markmitchell.com> - - * friend.c (is_friend): Use comptypes, rather than == to compare - types. Modify for new representation of template friends. - (make_friend_class): Likewise. - * pt.c (tsubst_friend_class): Undo 1998-05-21 change. Tweak. - (instantiate_class_template): Deal with template friends. - - * decl.c (store_parm_decls): Remove redundant call to - expand_main_function. - -1998-05-26 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * decl.c (start_decl): Check for DECL_LANG_SPECIFIC before - DECL_USE_TEMPLATE. - -1998-05-26 Per Bothner <bothner@cygnus.com> - - * language_as_string: Handle lang_java. - -1998-05-26 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (pushdecl): Don't copy the type_decl. - -1998-05-26 Martin v. Löwis <loewis@informatik.hu-berlin.de> - - * class.c (pushclass): Always store TYPE_MAIN_VARIANT in - current_class_type. - * decl.c (grokdeclarator): Put typedefs on the type's obstack. - - * parse.y (complex_direct_notype_declarator): Use $1 to access - scope of notype_qualified_id. - -1998-05-26 Dave Brolley <brolley@cygnus.com> - - * lex.c (parse_options,yy_cur,yy_lim): Add for cpplib. - (init_parse): Initialize cpplib interface. - - * Makefile.in (CXX_OBJS): Make sure dependencies never end with an - empty continuation. - -1998-05-26 Mark Mitchell <mark@markmitchell.com> - - * decl.c (pushtag): Avoid crashing on erroneous input. - -1998-05-25 Martin v. Löwis <loewis@informatik.hu-berlin.de> - - * decl.c (push_namespace): Only produce one unique name for - anonymous namespaces. - (get_unique_name): Remove. - -1998-05-25 Mark Mitchell <mark@markmitchell.com> - - * call.c (tourney): Don't do any extra comparisons. - - * decl2.c (build_anon_union_vars): Don't crash on empty sub-unions. - - * cp-tree.h (processing_template_parmlist): Declare. - * decl.c (pushtag): Don't call push_template_decl when we - shouldn't. - * pt.c (processing_template_parmlist): New variable. - (TMPL_ARGS_HAVE_MULTIPLE_LEVELS): New macro. - (complete_template_args): Use it. - (add_to_template_args): Likewise. - (innermost_args): Likewise. - (tsubst): Likewise. - (begin_template_parm_list): Use processing_template_parmlist. - (end_template_parm_list): Likewise. - - * cp-tree.h (ANON_UNION_TYPE_P): New macro. - * decl.c (grokdeclarator): Use it. - * decl2.c (grok_x_components): Likewise. - * init.c (initializing_context): Likewise. - * method.c (do_build_copy_constructor): Likewise. - (do_build_assign_ref): Likewise. - * search.c (compute_access): Likewise. - * typeck.c (build_component_ref): Likewise. - - * decl.c (grokdeclarator): Don't give a cv-qualified version of an - unnamed type a typedef name "for linkage purposes". - - * pt.c (lookup_template_class): Don't look at - IDENTIFIER_CLASS_VALUE when there's no current_class_type. - - * method.c (build_overload_int): Handle error cases gracefully. - - * pt.c (instantiate_decl): Handle static member variables - correctly. - - * pt.c (tsubst): Use the tsubst'd type when producing new - TEMPLATE_PARM_INDEX nodes. - -1998-05-24 Mark Mitchell <mark@markmitchell.com> - - * tree.c (cp_tree_equal): Handle pointers to member functions. - - * call.c (maybe_handle_implicit_object): Handle QUAL_CONVs. Make - sure the type of the REF_BIND is a reference type. - (maybe_handle_ref_bind, compare_ics): Rename reference_type to - target_type for clarity. - - * parse.y (xcond): Move call to condition_conversion ... - * semantics.c (finish_for_cond): Here. - * parse.c: Regenerated. - -1998-05-24 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (push_namespace): Namespaces have type void. - * typeck2.c (incomplete_type_error): Complain about namespace - used as expression. - * typeck.c (decay_conversion): Likewise. - -1998-05-24 Martin von Löwis <loewis@informatik.hu-berlin.de> - - * error.c (dump_expr): Support namespaces. - -1998-05-23 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.def: Add SRCLOC. - * cp-tree.h: Add struct tree_srcloc and accessor macros. - * tree.c (build_srcloc, build_srcloc_here): New fns. - * pt.c (add_pending_template): Use build_srcloc_here. - (push_tinst_level): Update last_template_error_tick before erroring. - (instantiate_decl): Restore lineno and input_filename before - calling add_pending_template. - * decl2.c (finish_file): Set up lineno and input_filename for - pending templates. - -1998-05-22 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lang_print_error_function): New fn. - (init_decl_processing): Set print_error_function to use it. - * errfn.c (cp_thing): Don't call maybe_print_template_context here. - - * call.c (maybe_handle_ref_bind): Propagate ICS_USER_FLAG and - ICS_BAD_FLAG. - - * cvt.c (ocp_convert): Don't set LOOKUP_NO_CONVERSION for - copy-initialization. - - * class.c (build_vtable_entry): Use int_fits_type_p. - (build_vtable): Pass a signed offset to build_vtable_entry. - (prepare_fresh_vtable, modify_one_vtable, fixup_vtable_deltas1, - set_rtti_entry): Likewise. - -1998-05-22 Per Bothner <bothner@cygnus.com> - - * cp-tree.h: Add comments documenting which LANG_FLAGS are used. - (C_TYPE_VARIABLE_SIZE, C_DECL_VARIABLE_SIZE): Removed, not used. - -1998-05-22 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (print_template_context): Use fprintf instead of cp_error. - - * pt.c (determine_specialization): Just return an error_mark_node. - Also print the decl we want in error messages. If we complain, - return error_mark_node. - (tsubst_friend_function): Set lineno and input_filename so - error messages will be useful. - (instantiate_template): Just return an error_mark_node. - (check_explicit_specialization): Don't mess with a returned - error_mark_node. - - * pt.c (print_template_context): Add new argument. - (maybe_print_template_context): New fn. - (push_tinst_level): Increment tinst_level_tick. - (pop_tinst_level): Likewise. - * errfn.c (cp_thing): Call maybe_print_template_context. Use - xrealloc instead of xmalloc. - - * typeck.c (build_unary_op, CONVERT_EXPR): Propagate TREE_CONSTANT. - -1998-05-21 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_friend_class): Don't call redeclare_class_template - if the template we looked up is the same as the one we already - have. - -Thu May 21 11:54:44 1998 Dave Brolley <brolley@cygnus.com> - - * lex.c: (handle_sysv_pragma): FILE* parameter not used. - (cpp_reader,parse_in): Add for cpplib. - (check_newline): Call handle_sysv_pragma with new interface. - (check_newline): Call GET_DIRECTIVE_LINE, not get_directive_line. - - * input.c: (yy_cur,yy_lim,yy_get_token,GETC): Add for cpplib. - (sub_getch): Call GETC for cpplib. - - * cp-tree.h: (get_directive_line): Different prototype for cpplib. - (GET_DIRECTIVE_LINE): Macro wrapper for get_directive_line. - - * Makefile.in (CXX_OBJS): add @extra_cxx_objs@ for cpplib. - -1998-05-21 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (maybe_make_one_only): New fn. - (import_export_vtable): Use it. - (import_export_decl): Likewise. - * pt.c (mark_decl_instantiated): Likewise. - -1998-05-21 Mark Mitchell <mmitchell@usa.net> - - * decl2.c (find_representative_member): Rename to ... - (build_anon_union_vars): New function. - (finish_anon_union): Fix stupidity of previous change. - -1998-05-20 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokfndecl): Handle definition of specialization in - friend declaration. - - * error.c (dump_decl): Fix LOOKUP_EXPR handling. - -1998-05-20 Mark Mitchell <mmitchell@usa.net> - - * class.c (delete_duplicate_fields_1): Use DECL_DECLARES_TYPE_P - to look for type declarations. - (finish_struct): Deal with templates on the CLASSTYPE_TAGS list. - * cp-tree.h (DECL_DECLARES_TYPE_P): New macro. - (finish_member_class_template): Declare. - * decl.c (pushtag): Put member class templates on the - CLASSTYPE_TAGS list, just as for ordinary member classes. - (pushdecl_class_level): Use DECL_DECLARES_TYPE_P. - (lookup_tag): Look for IDENTIFIER_CLASS_VALUEs, just as with - IDENTIFIER_NAMESPACE_VALUEs. - * parse.y (component_decl): Move code to ... - * semantics.c (finish_member_class_template): New function. - Don't put member class templates on the list of components for a - class. - * parse.c: Regenerated. - * pt.c (classtype_mangled_name): Don't try DECL_CONTEXT on types. - In fact, don't use DECL_CONTEXT at all here. - -1998-05-20 Martin von Loewis <loewis@informatik.hu-berlin.de> - - * decl.c (record_unknown_type): New function. - (init_decl_processing): Call it for the unknown and global type - nodes. - -1998-05-20 Mark Mitchell <mmitchell@usa.net> - - * decl2.c (find_representative_member): New function. - (finish_anon_union): Use it. - - * cp-tree.h (MAIN_NAME_P): New macro. - (DECL_MAIN_P): Likwise. - * decl.c (pushdecl): Avoid crashing on redefinitions of `main'. - (grokfndecl): Use the new macros. - (grokdeclarator): Likewise. - (start_function): Likewise. - (store_parm_decls): Likewise. - (finsh_function): Likewise. - * friend.c (do_friend): Likewise. - * typeck.c (build_function_call_real): Likewise. - (build_unary_op): Likewise. - -Wed May 20 02:16:01 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (start_objects, finish_objects, do_dtors, - do_ctors): Split out from... - (finish_file): ...here. - -Tue May 19 20:36:23 1998 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (is_overloaded_fn): Don't abort on placeholders from - push_class_decls. - -Tue May 19 15:16:22 1998 Brendan Kehoe <brendan@cygnus.com> - - * class.c (is_empty_class): Return 0 if TYPE is an error_mark_node. - - * error.c (dump_expr): Handle an ARROW_EXPR. - -Tue May 19 15:13:39 1998 Mark Mitchell <mmitchell@usa.net> - - * decl.c (saveable_obstack): Declare. - (pushdecl): Copy TYPE_DECLs to the same obstack as the type they - declare, if necessary. - -Tue May 19 14:50:27 1998 Mark Mitchell <mmitchell@usa.net> - - * call.c (compare_qual): Remove. - (is_subseq): Tweak. - (is_properly_derived_from): New function. - (maybe_handle_ref_bind): Likewise. - (maybe_handle_implicit_object): Likewise. - (compare_ics): Modify substantially to bring into conformance with - the standard. - * cp-tree.h (TYPE_PTRMEMFUNC_OBJECT_TYPE): New macro. - (comp_cv_qualification): Declare. - (comp_cv_qual_signature): Likewise. - * typeck.c (comp_cv_qualification): Likewise. - (comp_cv_qual_signature): Likewise. - -Tue May 19 10:05:02 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (parse.o): Depend on toplev.h. - - * class.c (typecode_p): Remove prototype and definition. - - * cp-tree.h (currently_open_class, is_empty_class, member_p): - Add prototype. - - * decl.c (push_overloaded_decl_top_level): Remove prototype and - definition. - - * errfn.c (cp_error): Cast function pointer `error' to (errorfn *) - in call to `cp_thing'. - (cp_warning): Likewise for function pointer `warning'. - - * except.c (do_function_call): Remove prototype and definition. - (call_eh_info): Wrap variable `t1' in macro NEW_EH_MODEL. - - * method.c (is_java_type): Add prototype and make it static. - - * parse.y: Include toplev.h. - - * pt.c (type_unification): Remove unused variable `arg'. - (instantiate_decl): likewise for `save_ti'. - - * tree.c (propagate_binfo_offsets): Likewise for `base_binfos'. - -Tue May 19 02:43:25 1998 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_member_call): Handle template_ids. - * parse.y (primary): Add global_scope template_id. - -Mon May 18 23:22:52 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (get_sentry): Use end_temporary_allocation. - Don't declare permanent_obstack. - -Mon May 18 12:28:44 1998 Mark Mitchell <mmitchell@usa.net> - - * parse.y (.finish_new_placement): New non-terminal. - (unary_expr, new_type_id): Use it. - * parse.c: Regenerated. - -Mon May 18 12:20:27 1998 Brendan Kehoe <brendan@cygnus.com> - - * pt.c (redeclare_class_template): Say where the original definition - of the template-parameter's default argument appeared. - -Mon May 18 03:00:57 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Tweak empty class handling. - - * decl.c (make_typename_type): Use currently_open_class. - - * class.c (instantiate_type): Don't abort on TREE_NONLOCAL_FLAG. - -Mon May 18 01:43:01 1998 Martin v. Loewis <loewis@informatik.hu-berlin.de> - - * decl.c (lookup_name_real): Don't look at IDENTIFIER_LOCAL_VALUE - for a type unless it is one. - - * class.c (finish_struct_1): Use OVL_CURRENT in error message. - -Mon May 18 01:24:08 1998 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (program_transform_name, objdir): Define. - - * Makefile.in (BISON): Use bison from the build tree if it exists. - (FLEX): Similarly. - -Sun May 17 14:52:08 1998 Martin v. Loewis <loewis@informatik.hu-berlin.de> - - * typeck.c (type_unknown_p): Return true for TREE_LIST also. - - * call.c (build_method_call): Use TYPE_MAIN_VARIANT on typedefs. - -Sun May 17 14:51:41 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_scoped_method_call): Likewise. - -Sun May 17 13:53:48 1998 Mark Mitchell <mmitchell@usa.net> - - * init.c (build_new_1): Call suspend_momentary around the creation - of values that must be saved for exception handling. - * parse.y (.build_new_placement): New non-terminal. - (unary_expr, new_placement): Use it. - * parse.c: Regenerated. - -Sun May 17 12:32:08 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (duplicate_decls): Use CANONICAL_TYPE_VARIANT to compare - old and new types. - - * pt.c (tsubst): Make sure that BINFO_TYPE of new binfos is the - canonical type. - - * call.c (build_over_call): Don't use IS_SIGNATURE on a namespace. - -Fri May 15 20:28:00 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): Revert problem change. - - * Makefile.in (CONFLICTS): Fix. - -Fri May 15 15:34:02 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (duplicate_decls): Clean up, add DECL_DATA_AREA bits. - -Fri May 15 00:46:05 1998 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Use BINFO_SIZE. - - * decl.c (start_decl): Use 'tem'. - -Thu May 14 16:30:47 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> - - * exception.cc: Include eh-common.h. - (struct cp_eh_info): add eh_info struct with NEW_EH_MODEL. - (__cplus_type_matcher): First stab at new C++ runtime type matcher. - (__cp_push_exception): Initialize eh_info struct as well. - * except.c: Remove local structs and include eh-common.h. - (init_exception_processing): Set language and version codes. - (call_eh_info): add presence of eh_info to runtime description of - struct cp_eh_info. - (expand_end_eh_spec): call start_catch_block() and end_catch_block(). - * semantics.c (finish_try_block): call start_catch_block() and - end_catch_block(). - * parse.y (function_try_block): call start_catch_block() and - end_catch_block(). - -Thu May 14 12:27:34 1998 Brendan Kehoe <brendan@cygnus.com> - - * typeck.c (original_type): New function. - (common_type): Use it to get the DECL_ORIGINAL_TYPE for T1 and T2, - to see if they're actually the same. - * cp-tree.h (original_type): Declare. - -Wed May 13 12:54:30 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (lex.o): Depend on output.h. - - * call.c (add_function_candidate): Remove unused variable `cand'. - (add_conv_candidate): Likewise. - (build_builtin_candidate): Likewise. - - * cp-tree.h: Add prototype for `types_overlap_p'. - - * decl.c (signal_catch): Mark parameter `sig' with ATTRIBUTE_UNUSED. - - * decl2.c (merge_functions): Remove unused variables `tmp' and - `tempn'. - - * error.c (expr_as_string): Mark parameter `v' with ATTRIBUTE_UNUSED. - (code_as_string): Likewise. - (language_as_string): Likewise. - (parm_as_string): Likewise. - (op_as_string): Likewise. - (assop_as_string): Likewise. - (cv_as_string): Likewise. - - * lex.c: Include output.h. - - * pt.c (type_unification): Cast first argument of `bzero' to a char*. - - * search.c (dfs_no_overlap_yet): Mark parameter `t' with - ATTRIBUTE_UNUSED. - - * tinfo.cc (__class_type_info::dcast): Change the type of variable - `i' from int to size_t. - - * typeck.c (language_lvalue_valid): Mark parameter `exp' with - ATTRIBUTE_UNUSED. - -Tue May 12 21:37:49 1998 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (dump_simple_decl): Use DECL_CLASS_SCOPE_P and/or - DECL_NAMESPACE_SCOPE_P. - (lang_decl_name): Likewise. - * pt.c (tsubst_friend_function, tsubst): Likewise. - * decl.c (pushdecl, redeclaration_error_message, start_decl, - cp_finish_decl, start_function): Likewise. - * class.c (finish_struct_1): Likewise. - * call.c (build_over_call): Likewise. - (compare_ics): Use DERIVED_FROM_P. - -Tue May 12 07:24:18 1998 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (CANONICAL_TYPE_VARIANT): New macro. - * method.c (build_mangled_name): Use it. - (build_decl_overload_real): Likewise. - - * error.c (dump_simple_decl): New function, broken out from ... - (dump_decl): Use it. - -Mon May 11 11:38:07 1998 Mark Mitchell <mmitchell@usa.net> - - * ptree.c (lang_print_xnode): Add missing `break'. - - * pt.c (tsubst): Remove duplicate check for IDENTIFIER_NODE. - - * call.c (add_template_candidate): Adjust for changes to - fn_type_unification. - (add_template_candidate_real): Likewise. - (add_template_conv_candidate): Likewise. - (build_user_type_conversion_1): Likewise. - (build_new_function_call): Likewise. - (build_object_call): Likewise. - (build_new_op): Likewise. - (build_new_method_call): Likewise. - * class.c (instantiate_type): Likewise. - * cp-tree.h (unification_kind_t): New type. - (fn_type_unification): Adjust prototype. - (type_unificaiton): Likewise. - * pt.c (UNIFY_ALLOW_NONE): New macro. - (UNIFY_ALLOW_MORE_CV_QUAL): Likewise. - (UNIFY_ALLOW_LESS_CV_QUAL): Likewise. - (UNIFY_ALLOW_DERIVED): Likewise. - (unify): Change prototype. - (maybe_adjust_types_for_deduction): New function. - (check_cv_quals_for_unify): Likewise. - (determine_specialization): Adjust. - (fn_type_unification): Likewise. - (type_unification): Likewise. - (type_unification_real): Likewise. Use - maybe_adjust_types_for_deduction. Fix mishandling of - back-unification of template functions passed as arguments. Pass - appropriate combination of UNIFY_ALLOW_* to unify. - (unify): Remove unused NTPARMS parameter. Use - check_cv_quals_for_unify. Remove bogus code that allowed - too-generous unification in order to adhere more closely to standard. - (get_bindings_real): Adjust. - (get_class_bindings): Likewise. - - * method.c (build_overload_identifier): Only use the innermost - template arguments when mangling. - * pt.c (tsubst_template_argument_vector): New function. - (complete_template_args): Deal with the situation where the - extra_args contain more than one level of arguments. - (lookup_template_class): Deal with member template classes, which - may have more than one level of arguments. - (tsubst): Don't tsbust into the TREE_TYPE of an IDENTIFIER_NODE. - Improve handling of member template classes. Use - DECL_PRIMARY_TEMPLATE instead of inline expansion. Use - tsubst_template_argument_vector where appropriate. - (regenerate_decl_from_template): Break out from ... - (instantiate_decl): Here. - - * lex.c (yyprint): Remove TYPENAME_ELLIPSIS. - * parse.h: Regenerated. - * parse.c: Really regenerated. - - * cp-tree.h (finish_unary_op_expr): New function. - (finish_id_expr): Likewise. - (begin_new_placement): Likewise. - (finish_new_placement): Likewise. - (finish_declarator): Likewise. - (finish_translation_unit): Likewise. - (finish_parmlist): Likewise. - (begin_class_definition): Likewise. - (finish_class_definition): Likewise. - (finish_default_args): Likewise. - (finish_inline_definitions): Likewise. - * parse.y (GCC_ASM_KEYWORD): Remove. - (TYPENAME_ELLIPSIS): Likewise. - * parse.c: Regenerated. - Use new functions in semantics.c in the actions for many rules. - * gxx.gperf (GCC_ASM_KEYWORD): Just use ASM_KEYWORD. - * hash.h: Regenerated. - * semantics.c (finish_expr_stmt): Allow NULL expr. - (finish_unary_op_expr): New function, containing - code previously in parse.y. - (finish_id_expr): Likewise. - (begin_new_placement): Likewise. - (finish_new_placement): Likewise. - (finish_declarator): Likewise. - (finish_translation_unit): Likewise. - (finish_parmlist): Likewise. - (begin_class_definition): Likewise. - (finish_class_definition): Likewise. - (finish_default_args): Likewise. - (finish_inline_definitions): Likewise. - -Sun May 10 23:43:13 1998 Mark Mitchell <mmitchell@usa.net> - - * typeck.c (build_c_cast): Don't decay arrays and functions to - pointer type when converting to a class type. - -Sun May 10 22:53:56 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (DECL_NAMESPACE_SCOPE_P): New macro. - (DECL_CLASS_SCOPE_P): Likewise. - -Sun May 10 22:48:22 1998 H.J. Lu (hjl@gnu.org) - - * class.c (finish_struct_1): Use OVL_CURRENT on TREE_VEC_ELT. - * decl2.c (constructor_name_full): Likewise. - -Sun May 10 22:48:12 1998 Mike Stump <mrs@wrs.com> - - * tree.c (mapcar): Add OVERLOAD support. - - * init.c (resolve_offset_ref): We must use basetype_path before we - destroy it with a call to convert_pointer_to. - -Sat May 9 14:44:37 1998 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (currently_open_class): New fn. - * decl.c (lookup_name_real): Use it. - * search.c (lookup_field): Likewise. - -Fri May 8 23:32:42 1998 Martin von Loewis <loewis@informatik.hu-berlin.de> - - * cp-tree.def (OVERLOAD): New node. - * cp-tree.h (BINDING_TYPE, SET_IDENTIFIER_GLOBAL_VALUE, - SET_IDENTIFIER_NAMESPACE_VALUE): Define. - (NAMESPACE_BINDING): Remove. - (IDENTIFIER_GLOBAL_VALUE, IDENTIFIER_NAMESPACE_VALUE): Use - namespace_binding. - (OVL_FUNCTION, OVL_CHAIN, OVL_CURRENT, OVL_NEXT, OVL_USED): - Define. - (tree_overload): New struct. - (IDENTIFIER_TYPE_VALUE): Use identifier_type_value. - (REAL_IDENTIFIER_TYPE_VALUE): Define. - (IDENTIFIER_HAS_TYPE_VALUE): Use IDENTIFIER_TYPE_VALUE. - (lang_decl_flags): Remove in_namespace. - (lang_decl): Remove chain. - (DECL_CHAIN, DECL_NAMESPACE): Remove. - (flag_honor_std): Declare extern. - (identifier_type_value, pushdecl_namespace_level, push_using_decl, - namespace_binding, set_namespace_binding, - lookup_function_nonclass, cat_namespace_levels, - set_decl_namespace, lookup_arg_dependent, binding_init, ovl_cons, - scratch_ovl_cons, ovl_member, build_overload): Declare. - (decl_list_length, get_namespace_id, current_namespace_id, - overloaded_globals_p): Remove. - (lookup_using_namespace, qualified_lookup_using_namespace): Change - return type. - (push_scratch_obstack): New macro. - * call.c (add_function_candidate): Special-case type of OVERLOAD node. - (build_user_conversions_1): Iterate using OVL_NEXT for ctors, - convs, fns. - (build_new_function_call): Iterate using OVL_CHAIN. - Print DECL_NAME in when reporting ambiguities. - (build_object_call): Iterate using OVL_NEXT for fns, convs. - (build_new_op): Call lookup_function_nonclass. - Iterate using OVL_NEXT. - (build_op_delete_call): Change detection of members. - Do not wrap TREE_LIST around fields and single global functions. - (build_over_call): Don't push a class level if the context is a - namespace. - (build_new_method_call): Iterate using OVL_NEXT. - * class.c (add_method): Chain overloaded members using - build_overload. Remove copying of method. - (grow_method): When iterating through the obstack, expect OVERLOAD - nodes. Chain overload members. - (finish_struct_methods): Chain overload members. Unpack OVERLOAD - nodes in call to get_baselinks. - (duplicate_tag_error): Expect OVERLOAD nodes when unchaining. - (finish_struct_1): Iterate over ctor using OVL_NEXT. Handle - fdecls that are OVERLOAD nodes. - (validate_lhs): New function. - (instantiate_type): Do not copy OVERLOAD nodes. Remove dead - code. Use DECL_NAME in error messages. Split code between global - and member function processing. - * decl.c (global_type_node): New static variable. - (in_std): New global. - (struct binding_level): New field usings. - (resume_binding_level): Assert that we are not in a class. - (toplevel_bindings_p): Just check for namespace_p or - pseudo_global. - (resume_level): Remove. - (find_binding): New function. - (binding_for_name): Call it. - (namespace_binding, set_namespace_binding): New functions. - (push_namespace): Associate binding level with new namespace, - resume_binding_level for existing namespace. Remove old code. - Fake std by counting. - (store_bindings): Use REAL_IDENTIFIER_TYPE_VALUE. - (maybe_push_to_top_level): Save current namespace. - (pop_from_top_level): Restore saved namespace. - (pop_namespace): Call suspend_binding_level. Remove old code. - (cat_namespace_levels): New function. - (set_identifier_type_value_with_scope): For namespace bindings, - set BINDING_TYPE, and use global_type_node. - Use REAL_IDENTIFIER_TYPE_VALUE otherwise. - (identifier_type_value): New function. - (pushtag): If no context, use current_namespace. - (duplicate_decls): Don't process DECL_CHAIN. - (pushdecl): Set DECL_CONTEXT to current_namespace, if it is not - already set. Never reset it to NULL_TREE. Lookup global variables - in their namespace. Push overloaded templates if they are on - namespace level. - (pushdecl_namespace_level): New function. - (pushdecl_top_level): Implement using pushdecl_namespace_level. - (pushdecl_using_decl): New function. - (overloaded_globals_p): Remove. - (push_overloaded_decl): Create OVERLOAD nodes, and iterate through - them. Use namespace_binding and set_namespace_value. - (redeclaration_error_message): Complain if the declarations come - from different namespaces. - (lookup_tag): On namespace level, look in the BINDING_TYPE. - (lookup_namespace_name): Pass tree_bindings from stack. Remove - old code. - (select_decl): New function. - (lookup_name_real): Call it for qualified and unqualified lookup. - Pass tree_bindings from the stack. - If prefer_type is 1, also accept namespaces. - (lookup_function_nonclass): New function. - (init_decl_processing): Set the binding level of the global - namespace to global_binding_level. - Build a proper type list for __builtin_apply. - Initialize std_node to "fake std" if flag_honor_std is set. - Initialize global_type_node. - Allocated bad_alloc in namespace std if flag_honor_std. - (define_function): Set the DECL_CONTEXT to the current_namespace. - (start_decl): A namespace is not considered as a context here. If - the DECL_CONTEXT is a namespace, push the decl. - (cp_finish_decl): Check for namespaces used as initializers. - (grokfndecl): Add namespace parameter. Remove processing of - DECL_CHAIN. - (grokvardecl): Add namespace parameter. - (grokdeclarator): Process SCOPEs that are namespaces. For - mangling, temporarily set the DECL_CONTEXT on anonymous structs. - (start_function): Check for contexts that are namespaces. - Set context for declarations that have not been pushed. - (store_parm_decls): Check for ::main only. - (finish_function): Likewise. - (start_method): Check for contexts that are namespaces. - (start_method): Remove DECL_CHAIN processing. - * decl2.c (flag_honor_std): Declare. - (lang_decode_option): Set it if -fhonor-std or -fnew-abi is given. - (decl_namespace_list): New static global. - (grok_x_components): Ignore namespaces as type contexts. - (check_classfn): Expect OVERLOAD nodes. - (grokfield): Remove DECL_CHAIN processing. - (finish_file): Call cat_namespace_levels. - (merge_functions): New function. - (ambiguous_decl): Rewrite. - (lookup_using_namespace): Produce tree_bindings. - (qualified_lookup_using_namespace): Likewise. - (set_decl_namespace, decl_namespace, current_decl_namespace, - push_decl_namespace, pop_decl_namespace): New functions. - (arg_lookup): New struct. - (add_function, arg_assoc_namespace, arg_assoc_class, - arg_assoc_type, arg_assoc_args, arg_assoc, lookup_arg_dependent): - New functions. - (get_namespace_id, current_namespace_id): Remove. - (do_toplevel_using_decl): Rewrite. - (do_class_using_decl): Complain about namespace qualifiers. - (do_using_directive): Sorry if not on namespace level. Complain - about unknown namespaces. - * error.c (dump_aggr_type): Check for namespace contexts. - * except.c (init_exception_processing): Push terminate into std. - * friend.c (is_friend): A namespace is not a context, here. - * init.c (expand_member_init): Remove DECL_CHAIN processing. - (build_offset_ref): Process OVERLOAD nodes. - * lang-specs.h (__HONOR_STD): Define if -fnew-abi or -fhonor-std. - * lex.c (identifier_type): Loop using OVL_CHAIN. - (see_typename): Set looking_for_typename to 2. - (real_yylex): Likewise. - (do_identifier): Expect OVERLOAD nodes instead of TREE_LISTs. - (do_scoped_id): Expect OVERLOAD nodes. - Change calling convention for qualified_lookup_using_namespace. - (build_lang_decl): Don't set in_namespace anymore. - * method.c (typevec_size): New global. - (build_overload_nested_name): Return if global_namespace. - Otherwise, always expect a declaration context. - (build_qualified_name): Likewise. - Make sure we don't write beyond typevec_size. - (build_decl_overload_real): Likewise. - Allocate one extra slot for the namespace. - (hack_identifier): Mark code dead. - Process OVERLOAD and NAMESPACE_DECL nodes. - * parse.y (program): Pop namespaces until in global namespace. - (extdef): In a using-declaration, don't discard the identifier if - there is no declaration. - (left_curly): Ignore type contexts which are namespaces. - (typename_sub2): Use IDENTIFIER_TYPE_VALUE to retrieve the type - used as scope. - * pt.c (template_class_depth): Expect types to be namespaces. - (determine_specialization): Simplify by expecting OVERLOAD nodes. - (push_template_decl): Push into namespace level. - Reset ctx if it is a namespace. - Set DECL_CONTEXT to current_namespace if not set already. - Ignore real contexts that are namespaces. - (mangle_class_name_for_template): Skip global_namespace. - Mangle other namepaces as declarations. - (lookup_template_function): Set type of OVERLOAD nodes to unknown. - (lookup_template_class): Push into namespace of context. - If the context is a namespace, set it to global_namespace. - Use id_context for mangling. - (for_each_template_parm): Handle OVERLOAD and NAMESPACE_DECL nodes. - (tsubst_friend_function): Ignore namespace contexts. - Push into namespace level. - (tsubst): Handle NAMESPACE_DECL nodes. - Remove DECL_CHAIN processing. - (type_unification_real): Recognize OVERLOAD instead of TREE_LIST nodes. - * ptree.c (print_lang_identifier): Print bindings. - (lang_print_xnode): Print OVERLOAD nodes. - * rtti.c (init_rtti_processing): Push type_info into std. - * search.c (lookup_fnfields_here): Expect OVERLOAD nodes. - (lookup_fnfields_1, get_virtuals_named_this, get_matching_virtual, - dfs_debug_mark, dfs_pushdecls, dfs_compress_decls, add_conversions, - lookup_fnfields_here): Likewise. - Process all nodes, instead of going through TREE_CHAIN. - * sig.c (build_signature_pointer_or_reference_type): Set context - to global_namespace. - (build_signature_table_constructor): Expect OVERLOAD nodes. - * spew.c (yylex): Save old setting of looking_for_typename. - * tree.c (decl_list_length): Remove. - (binding_init): New function. - (count_functions): Rewrite. - (is_overloaded_fn): Expect OVERLOAD nodes. - (really_overloaded_fn, get_first_fn, lvalue_type): Likewise. - (ovl_cons, scratch_ovl_cons, build_overload, build_overload_after, - ovl_member): New functions. - * typeck.c (require_complete_type): Expect OVERLOAD nodes. - (type_unknown_p): Likewise. - (require_instantiated_type): Likewise. - (build_component_ref): Declare code dead. - (build_x_function_call): Create and expect OVERLOAD nodes. - (build_function_call_real): Check for ::main only. - (build_unary_op): Likewise. Expect OVERLOAD nodes. - (convert_for_assignment): Check for TREE_LIST before accessing - TREE_VALUE. - * decl.c (duplicate_decls): Check for namespace bindings instead - of global bindings. - (pushdecl, push_overloaded_decl, lookup_tag, lookup_name_real, - lookup_name_current_level, start_decl, xref_tag, - finish_enum): Likewise. - * init.c (build_offset_ref): Likewise. - * search.c (lookup_field): Likewise. - (lookup_fnfields): Likewise. - (dfs_debug_mark): Likewise. - * decl.c (poplevel): Use SET_IDENTIFIER_TYPE_VALUE. - (poplevel_class, pop_from_top_level): Likewise. - * decl2.c (finish_method): Likewise. - * class.c (build_vtable): Use SET_IDENTIFIER_GLOBAL_VALUE. - * decl.c (record_builtin_type): Likewise. - (init_decl_processing, grokfndecl): Likewise. - * lex.c (get_time_identifier, do_identifier, do_scoped_id): Likewise. - (make_lang_type): Likewise. - * parse.y (make_thunk): Likewise. - * pt.c (tsubst): Likewise. - * tree.c (debug_binfo): Likewise. - * exception.cc, new.cc, new1.cc, new2.cc, tinfo.cc, tinfo.h, - tinfo2.cc, inc/new.h: Add std qualifications. - * inc/new: Wrap with namespace std if __HONOR_STD. - * inc/typeinfo: Likewise. - -Fri May 8 00:43:50 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_user_type_conversion_1): Handle second_conv - properly for templates. - -Thu May 7 17:09:25 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> - - * method.c (build_decl_overload_real): Set TREE_USED flag to - zero for build_type_variants nodes as well. - -Wed May 6 19:27:09 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Don't tsubst the type of an IDENTIFIER_NODE. - -Wed May 6 16:49:48 1998 Jim Wilson <wilson@cygnus.com> - - * Makefile.in (call.o, class.o, decl.o, decl2.o, errfn.o, error.o, - except.o, expr.o, friend.o, init.o, lex.o, method.o, pt.o, repo.o, - rtti.o, search.o, semantics.o, sig.o, tree.o, typeck.o, typeck2.o, - xref.o): Add toplev.h dependencies. - -Wed May 6 16:44:58 1998 Jeffrey A Law (law@cygnus.com) - - * errfn.c (cp_error, cp_warning): Remove declarations for - error and warning respectively. - -Wed May 6 14:28:18 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * error.c: Convert to using ctype macros defined in system.h. - * method.c: Likewise. - * xref.c: Likewise. - * lex.c: Likewise. Also remove redundant system header stuff. - -Wed May 6 06:36:41 1998 Robert Lipe <robertl@dgii.com> - - * call.c, class.c, decl.c, decl2.c, errfn.c, error.c, except.c, - expr.c, friend.c, init.c, lex.c, method.c, pt.c, repo.c, rtti.c, - search.c, semantics.c, sig.c, tree.c, typeck.c, typeck2.c, - xref.c: Add include of toplev.h. - -Wed May 6 02:33:39 1998 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (perm_manip): Also regenerate the RTL of an extern. - (copy_to_permanent): Use end_temporary_allocation. - -Tue May 5 23:54:04 1998 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_vec_init): The initialization of each array - element is a full-expression. - -Tue May 5 18:24:13 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> - - * method.c (build_mangled_name): Add a call to build_type_variant - to get the right type. - -Tue May 5 01:25:03 1998 Jason Merrill <jason@yorick.cygnus.com> - - * Makefile.in: Add .SUFFIXES. - - * cp-tree.def: Remove NAMESPACE_DECL. - -Sun May 3 01:32:14 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Do evaluate arg even if it has empty - class type. - * decl.c (start_function): Don't push a member function. - -Thu Apr 30 18:59:23 1998 Jim Wilson <wilson@cygnus.com> - - * Makefile.in (g++FAQ.info): Put -o option before input file. - -Thu Apr 30 13:05:33 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> - - * gxxint.texi: Add info for squangling codes K and B. - -Tue Apr 28 13:22:01 1998 Mark Mitchell <mmitchell@usa.net> - - * semantics.c (begin_stmt_expr): Avoid duplicating the effect of - the expression in templates. - (finish_stmt_expr): Likewise. - -1998-04-28 Brendan Kehoe <brendan@cygnus.com> - - * decl2.c (ambiguous_decl): Fix NAME parm to be a tree, not int. - -Mon Apr 27 13:58:10 1998 Mark Mitchell <mmitchell@usa.net> - - * decl.c (maybe_push_to_top_level): Always clear - current_template_parms and processing_template_decl. - (pushtag): Remove check of current_class_type and some comments, - since maybe_push_to_top_level no longer creates confusion. - -Sun Apr 26 12:10:18 1998 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (CLASSTYPE_IS_TEMPLATE): New macro. - (DECL_CLASS_TEMPLATE_P): Likewise. - (DECL_PRIMARY_TEMPLATE): Likewise. - (PRIMARY_TEMPLATE_P): Use it. - (push_template_decl_real): New function. - (redeclare_class_template): Take new template parameters as - input. - (is_specialization_of): New function. - (comp_template_args): Declare. - * decl.c (pushtag): Handle friend template classes. - (xref_tag): Likewise. Use new calling convention for - redeclare_class_template. - * decl2.c (grok_x_components): Handle friend templates. - * friend.c (is_friend): Use is_specialization_of where - appropriate. Deal with friend class templates. - (make_friend_class): Let a class template be friends with itself. - * pt.c (comp_template_args): Remove declaration. - (tsubst_friend_class): New function. - (push_template_decl_real): New function. - (push_template_decl): Use it. - (redeclare_class_template): Adjust for new calling convention. - (comp_template_args): Give it external linkage. - (instantiate_class_type): Use tsubst_friend_class to deal - with friend templates. - * typeck.c (comptypes): Use comp_template_args, rather than - expanding it inline. - * parse.y (component_decl): Handle a nested template type - like other component type declarations. - - * pt.c (check_explicit_specialization): Handle overloaded - constructors correctly. - - * pt.c (mabybe_get_template_decl_from_type_decl): New function. - (lookup_template_class): Use it. - -Thu Apr 23 21:19:06 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.def: Add WRAPPER. USER_CONV now only has two ops. - * cp-tree.h: Add WRAPPER support. - * call.c (add_candidate): Split out from add_*_candidate fns. - (build_over_call): Take the candidate instead of function and args. - Enforce access control here. Emit overload warnings here. - (add_warning): New fn. - (joust): Add WARN parm. If not set, call add_warning instead of - printing a warning. Reenable some warnings. - (tourney): Pass it. - (convert_like): Adjust. - (build_new_op): Adjust. - (build_new_function_call): Adjust. - (build_user_type_conversion_1): Adjust. - (USER_CONV_FN): Adjust. - * tree.c (build_expr_wrapper, build_expr_ptr_wrapper, - build_int_wrapper): New fns. - -Thu Apr 23 18:27:53 1998 Mark P. Mitchell <mmitchell@usa.net> - - * pt.c (unify): Fix typo in previous change. - -Thu Apr 23 09:32:58 1998 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (dump_type_real): Declare canonical_name. - - * typeck.c (comp_target_types): Fix PMFs. - -Wed Apr 22 13:24:48 1998 Mark Mitchell <mmitchell@usa.net> - - * class.c (finish_struct): Set TREE_PRIVATE and TREE_PROTECTED for - the DECL_RESULTs of a member TEMPLATE_DECL, not just the - TEMPLATE_DECL. - - * pt.c (tsubst): Decrease the template-level of - TEMPLATE_TEMPLATE_PARMS. Likewise for the DECL_INITIAL of a - TEMPLATE_PARM_INDEX. - (template_decl_level): New function. - (unify): Make sure to record unifications for template - parameters, even when the parameters exactly match the arguments. - Combine duplicated code for TEMPLATE_TEMPLATE_PARMs and - TEMPLATE_TYPE_PARMS. Don't try to unify template parameters that - aren't from the level we're currently working on. - -Tue Apr 21 22:00:04 1998 Mark Mitchell <mmitchell@usa.net> - - * errfn.c (cp_thing): Use xrealloc, not xmalloc, to copy memory. - - * decl2.c (check_member_template): Set DECL_IGNORED for member - class templates, too. - - * decl2.c (grokfield): Remangle the name of a member TYPE_DECL. - -Tue Apr 21 18:59:11 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (duplicate_decls): Only check DECL_FRIEND_P if function. - -Tue Apr 21 14:22:00 1998 Jeffrey A Law (law@cygnus.com) - - * cp-tree.h (intTI_type_node, unsigned_intTI_type_node): Declare. - * decl.c (intTI_type_node, unsigned_intTI_type_node): Define. - (init_decl_processing): Handle TI types. - * typeck.c (unsigned_type, signed_type): Handle TI types. - -Sat Apr 18 15:25:21 1998 Jim Wilson <wilson@cygnus.com> - - * g++spec.c (lang_specific_driver): New argument in_added_libraries. - New local added_libraries. Increment count when add library to - arglist. - -Fri Apr 17 21:25:00 1998 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (type_as_string_real): New function. - * pt.c (mangle_class_name_for_template): Use it. - * error.c (dump_aggr_type): Change prototype. - (dump_type_prefix): Likewise. - (dump_type_suffix): Likewise. - (dump_type_real): Convert from dump_type. If desired, the - "canonica" name of a typedef, i.e., the name of the underlying - type, can be printed. - (dump_type): Call dump_type_real. - -Fri Apr 17 14:30:45 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (lang_decode_option): -fnew-abi implies -fvtable-thunks. - - * typeck.c (comp_target_types): Tweak pedantic case. - (comp_target_parms): Tweak pedantic case. Clean up somewhat. - Return -1 or 1 instead of 1 or 2. - (compparms): Remove STRICT handling. - (convert_for_assignment): Fix handling of pmfs. - -Fri Apr 17 14:04:16 1998 Mark Mitchell <mmitchell@usa.net> - - * typeck.c (comp_target_types): Handle references like pointers. - (comp_target_parms): Note that return code from comp_target_types - can be negative to indicate failure. - -Fri Apr 17 09:10:52 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * Make-lang.in (c++.all.build): Don't depend on $(DEMANGLER_PROG), - which requires a working target compiler to build. - -Fri Apr 17 08:57:35 1998 Jeffrey A Law (law@cygnus.com) - - * tree.c (avoid_overlap): Add prototype. - - * spew.c (num_tokens): Add prototype. - (nth_noken, add_token, consume_token, debug_yychar): Likewise. - - * search.c (dfs_check_overlap): Add prototype. - (dfs_no_overlap_yet): Likewise. - - * pt.c (original_template): Add prototype. - (inline_needs_template_parms): Likewise. - (push_inline_template_parms_recursive): Likewise. - (retrieve_specialization, register_specialization): Likewise. - (print_candidates, reduce_template_parm_level): Likewise. - (build_template_decl, mark_template_parm): Likewise. - (tsubst_friend_function, get_bindings_real): Likewise. - - * method.c (start_squangling): Add prototype. - (end_squangling, check_ktype, issue_ktype): Likewise. - (build_overloaded_scope_ref, check_btype): Likewise. - (build_mangled_template_parm_index): Likewise. - - * lex.c (init_cpp_parse): Add prototype. - (handle_cp_pragma, handle_sysv_pragma): Likewise. - (reduce_cmp, token_cmp): Likewise. - - * except.c (call_eh_info): Add prototype. - (push_eh_info, get_eh_info, get_eh_value, get_eh_type): Likewise. - (get_eh_caught, get_eh_handlers, do_pop_exception): Likewise. - - * decl2.c (is_namespace_ancestor): Add prototype. - (namespace_ancestor, add_using_namespace): Likewise. - (ambiguous_decl): Likewise. - - * decl.c (indent): Add prototype. - - * call.c (add_template_candidate_real): Add prototype. - -Fri Apr 17 01:57:12 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (build_expr_from_tree): Just return a PMF. - -Fri Apr 17 00:45:12 1998 Mark Mitchell <mmitchell@usa.net> - - * typeck2.c (process_init_constructor): Don't strip cv-qualifiers - when doing initializations. - - * pt.c (unify): Use comptypes to compare type args. - -Fri Apr 17 00:24:22 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (duplicate_decls): Fix check for when it's safe to free - the new decl. - - * pt.c (mangle_class_name_for_template): Don't pass a typedef type - to type_as_string. - -Thu Apr 16 17:47:30 1998 Jeffrey A Law (law@cygnus.com) - - * pt.c (build_template_parm_index): Add prototype. - - * search.c (my_tree_cons): Don't clear words outside the - newly allocated node. - -Wed Apr 15 15:34:44 1998 Dave Brolley <brolley@cygnus.com> - - * lex.c (init_parse): Now returns char* containing the filename. - -Wed Apr 15 13:20:06 1998 John Carr <jfc@mit.edu> - Jeff Law <law@cygnus.com> - - * errfn.c: Rework to avoid problems when HOST_WIDE_INT is longer - than a pointer. - -Sun Apr 12 22:31:19 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * cvt.c (cp_convert_to_pointer): Use TYPE_PRECISION. - -Fri Apr 10 12:16:49 1998 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * decl.c (duplicate_decls): Don't warn for redundant decls if - friend: let add_friend take care of it. - -Thu Apr 9 02:40:48 1998 Jason Merrill <jason@yorick.cygnus.com> - - * sig.c (build_signature_pointer_constructor): Don't set - TREE_HAS_CONSTRUCTOR for a signature pointer. - * cvt.c (ocp_convert): Don't force a temporary for internal structs. - * init.c (resolve_offset_ref): Warn about implicit & on pmfs - here, too. - * typeck.c (build_unary_op): Only allow taking the address of a - real constructor. - * typeck2.c (digest_init): Simplify. - (store_init_value): Don't pedwarn about using { } for pmfs. - -Thu Apr 9 22:16:57 1998 Per Bothner <bothner@cygnus.com> - - * cp-tree.h (start_decl): Update prototype. - * decl.c (start_decl): Like the C version, new parameters - for the attributes. Call cplus_decl_attributes here, - (pushdecl): Like C version, do build_type_copy if TYPE_DECL, - (grokdeclarator): Pass NULL for new start_decl arguments. - * pt.c (tsubst_expr): Likewise. - * parse.y: Merge cplus_decl_attribute calls into start_decl calls. - * typeck.c (common_type): Check TYPE_MAIN_VARIANT. - * lex.c (build_lang_decl): Add lang_name_java. - * class.c (push_lang_context): Add lang_name_java. - * method.c (build_mangled_name): Check for is_java_type. - -Thu Apr 9 22:16:57 1998 Benjamin Kosnik <bkoz@loony.cygnus.com> - - * decl.c (grokdeclarator): Check TYPE_MAIN_VARIANT. - * call.c (build_scoped_method_call): Check for TREE_CODE for - VOID_TYPE instead of type == void_type_node. - (build_method_call): Ditto. - * decl.c (lookup_name_real): Ditto. - (grokdeclarator): Ditto. - (start_decl): Ditto. - (grokparms): Ditto. - (start_function): Ditto. - (finish_function): Ditto. - (start_method): Ditto. - -Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com) - - * lex.c (finput): New variable. - (init_cpp_parse): Renamed from init_parse. - (init_parse): Handle !USE_CPPLIB. Call init_cpp_parse when finished. - (finish_parse): New function. - * cp-tree.h (init_lex, init_parse): Remove declarations. - -Mon Apr 6 02:25:05 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_call): Still evaluate the actual argument. - * class.c (is_empty_class): Update for -fnew-abi. - - * decl2.c: -fnew-abi implies -fsquangle. - - * method.c (do_build_assign_ref): Don't do anything to copy - an empty class. - (do_build_copy_constructor): Likewise. - * call.c (build_over_call): Likewise. - -Sat Apr 4 18:43:58 1998 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (avoid_overlap): Return a value. - -Sat Apr 4 12:52:35 1998 Jeffrey A Law (law@cygnus.com) - - * method.c (check_btype): Add missing argument to xrealloc. - (check_ktype): Likewise. - -Fri Apr 3 02:22:59 1998 Jason Merrill <jason@yorick.cygnus.com> - - Implement empty base optimization. - * class.c (finish_struct_1): Add vbase fields earlier. Set - CLASSTYPE_SIZE of an empty base to 0. Types with bases can be empty. - * search.c (dfs_check_overlap, dfs_no_overlap_yet): New fns. - (types_overlap_p): New fn. - * tree.c (avoid_overlap): New fn. - (build_base_fields): Use it to avoid overlapping empty bases. - * cp-tree.h, decl2.c, lang-options.h: Add -fnew-abi. - - * decl.c (cplus_expand_expr_stmt): Strip unused INDIRECT_REFs. - - Re-implement allocation of base class subobjects. - * tree.c (unshare_base_binfos): New fn. - (layout_basetypes): Use it. Now handles offsets of both virtual and - non-virtual bases, after layout_type. - (layout_vbasetypes): Remove. - (build_base_fields): Generate FIELD_DECLs for each non-virtual base. - (build_vbase_pointer_fields): Split out from old layout_basetypes. - * class.c (finish_base_struct): Lose offset handling code. - Move nonvdtor warning here. Don't mess with t_binfo anymore. - (finish_struct_1): Don't mess with t_binfo anymore. Use fns above. - * cp-tree.h: Adjust. - -Thu Apr 2 14:25:13 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h: Lose CLASSTYPE_VBASE_SIZE, some unused stuff. - * decl.c, decl2.c, pt.c, ptree.c, lex.c: Likewise. - * class.c (duplicate_tag_error): Likewise. - (finish_struct_1): Set CLASSTYPE_SIZE, CLASSTYPE_MODE, CLASSTYPE_ALIGN. - * tree.c (layout_vbasetypes): Update from layout_record, remove - var_size support, use CLASSTYPE_SIZE instead of CLASSTYPE_VBASE_SIZE. - (layout_basetypes): Likewise. - -Wed Apr 1 18:22:25 1998 Jeffrey A Law (law@cygnus.com) - - * class.c, Make sure system.h is included just after config.h. - Delete lingering stdio and errno references too. - * decl.c, errfn.c, parse.y, ptree.c search.c, xref.c: Likewise. - -Wed Apr 1 15:38:36 1998 Jason Merrill <jason@yorick.cygnus.com> - - * friend.c (is_friend): Fix access control for local classes. - - * class.c (is_empty_class): New fn. - * call.c (build_call): Don't pass empty class objects to a function. - -Wed Apr 1 14:58:35 1998 Mark Mitchell <mmitchell@usa.net> - - * call.c (build_over_call): Do name resolution for default - arguments of function templates in the scope of the templates. - -Tue Mar 31 13:43:57 1998 Jeffrey A Law (law@cygnus.com) - - * call.c: Include system.h. Remove includes, declarations and - defines provided by system.h. - * class.c, cvt.c, decl.c, decl2.c, errfn.c error.c: Likewise. - * except.c, expr.c friend.c, g++spec.c, init.c, input.c: Likewise. - * lex.c, parse.y, pt.c, ptree.c repo.c rtti.c, search.c: Likewise. - * semantics.c, sig.c, spew.c, tree.c, typeck.c: Likewise. - * typeck2.c, xref.c: Likewise. - * Makefile.in: Dependencies updated as appropriate. - * Make-lang.in: Likewise. - -Mon Mar 30 12:15:00 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (fn_type_unification): Allow incomplete unification without - an immediate error message. - -Mon Mar 30 08:55:42 1998 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (member_p): New fn. - * decl2.c (finish_file): Only set DECL_STATIC_FUNCTION_P for - initializing class members. - - * cp-tree.def (TEMPLATE_PARM_INDEX): Class 'x'. - * ptree.c (lang_print_xnode): Handle TEMPLATE_PARM_INDEX. - - * call.c (build_method_call): Handle non-scoped destructors, too. - * pt.c (tsubst_copy): Likewise. - - * pt.c (print_template_context): Split out... - (push_tinst_level): ...from here. - - * friend.c (is_friend): Don't pass a type to decl_function_context. - - * typeck.c (convert_for_initialization): Always hand off - conversions to class type. - -Sun Mar 29 20:01:59 1998 Jason Merrill <jason@yorick.cygnus.com> - - * friend.c (is_friend): Local classes have the same access as the - enclosing function. - -Sun Mar 29 00:47:32 1998 Jeffrey A Law (law@cygnus.com) - - * typeck.c (expand_target_expr): Delete dead function. - - * search.c: Put various prototypes inside #ifdef MI_MATRIX. - - * repo.c (save_string): Delete dead function. - - * method.c (thunk_printable_name): Delete dead function. - - * lex.c (yynextch): Delete dead function. - - * expr.c (tree_extract_aggr_init): #if 0 out. - - * except.c (do_unwind): Delete dead function. - (easy_expand_asm): Likewise. - - * cvt.c (build_conversion_type_1): Delete dead function. - - * cp-tree.h (push_expression_obstack): Declare. - - * call.c (source_type): #if 0 out. - - * class.c (alter_access): Remove unused label. Add braces - around empty else clause. - - * lex.c (yyprint): Fix argument to printf. - -Sat Mar 28 17:43:52 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (tsubst): Clear TREE_USED for new FUNCTION_DECLs. - - * pt.c (instantiate_class_template): Make sure template - arguments are permanent. - * init.c (resolve_offset_ref): Don't go looking around in - template types. - - * semantics.c: Add routines to handle expressions, and some - declaration processing. - * parse.y: Use them. - (current_class_depth): Move declaration to cp-tree.h. - * parse.c: Regenerated. - * cp-tree.h: Use them. - (current_class_depth): Declare. - * pt.c (tsubst_copy): Use begin_stmt_expr and finish_stmt_expr. - -Fri Mar 27 20:23:18 1998 Mark Mitchell <mmitchell@usa.net> - - * error.c (dump_decl): Be a bit more explicit with template - type arguments, when verbose. - -Fri Mar 27 18:16:40 1998 Jason Merrill <jason@yorick.cygnus.com> - - * inc/exception: Reorder closing braces. - -Fri Mar 27 13:22:18 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (redeclare_class_template): New function. - * cp_tree.h (redeclare_class_template): Declare it. - * decl.c (xref_tag): Use it. - -Thu Mar 26 11:16:30 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Check IS_AGGR_TYPE, not - TYPE_LANG_SPECIFIC. - * typeck.c (convert_arguments): Likewise. - - * decl.c (grokdeclarator): Remove const and volatile from type after - setting constp and volatilep. - - * class.c (finish_struct_1): Don't warn about bool bitfield larger - than one bit. - -Thu Mar 26 10:25:52 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (convert_nontype_argument): STRIP_NOPS where appropriate. - -Thu Mar 26 10:24:05 1998 Mark Mitchell <mmitchell@usa.net> - - * call.c (build_object_call): Complain about ambiguous operator(), - rather that crashing. - (build_new_op): Likewise. - (build_op_delete_call): Likewise. - -Thu Mar 26 10:23:24 1998 Mark Mitchell <mmitchell@usa.net> - - * cvt.c (perform_qualification_conversions): Use comp_target_types - instead of comp_ptr_ttypes. - -Wed Mar 25 16:10:50 1998 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (enforce_access): Declare. - * call.c (enforce_access): Make it extern, not static. - * class.c (alter_access): Use enforce_access; modify code for ISO - compliance, rather than ARM rules. - -Wed Mar 25 12:10:45 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * cp-tree.h: Fix typo. - -Wed Mar 25 02:01:02 1998 Jason Merrill <jason@yorick.cygnus.com> - - * expr.c (cplus_expand_expr): Only do PCC_STATIC_STRUCT_RETURN thing - if (aggregate_value_p (type)). - - * decl2.c (constructor_name_full): Handle TYPENAME_TYPE. - -Tue Mar 24 16:12:01 1998 Mark Mitchell <mmitchell@usa.net> - - * tree.c (mapcar): When dealing with a DECL, use it's constant - value, if any. - * pt.c (lookup_template_class): Don't mangle the names of template - classes whose arguments are unknown. - - * pt.c (tsubst_expr): Handle GOTO_STMT correctly. - -Tue Mar 24 12:21:55 1998 Benjamin Kosnik <bkoz@lisa.cygnus.com> - - * decl.c (init_decl_processing): Set TYPE_PRECISON for bools to 1. - -Tue Mar 24 12:21:48 1998 Jim Wilson <wilson@cygnus.com> - - * decl.c (init_decl_processing): Initialize TYPE_MAX_VALUE for - boolean_type_node to 1. - -Tue Mar 24 10:23:47 1998 Mark Mitchell <mmitchell@usa.net> - - * error.c (dump_expr): Remove unused variable `l'. - - * pt.c (for_each_template_parm): New function, created by - converting uses_template_parms. - (tree_fn_t): New typedef. - (uses_template_parms): Use it. - (mark_template_parm): New function. - (push_template_decl): Check that the argument list of a partial - specialization uses all the template parameters. - - * Make-lang.in (c++filt): Don't delete cxxmain.c after we're done - with it; we might want it for debugging. - * cp-tree.h (type_unification): Change interface. - * class.c (finish_struct_1): Skip nested template types, just like - ordinary nested types. - (instantiate_type): Use new interface to type_unification. - * lex.c (init_lex): Add __sz as opname for sizeof. - * method.c (build_overload_scope_ref): New function. - (build_overload_int): Handle complex expressions. Set - numeric_output_need_bar if necessary. - (build_overload_value): Handle non-PARM_DECL nodes; this - routine is now used by build_overload_int. Remove some - assignments to numeric_output_need_bar. Use - build_overload_scope_ref. - (build_qualified_name): Note that some template mangled names end - with digits, and set numeric_output_need_bar appropriately. Use - build_underscore_int. - * pt.c (unify): Change interface. - (type_unification_real): Likewise. - (determine_specialization): Use new interfaces. - (tsubst): Deal gracefully with situations in which the argument - vector is not fully filled. - (fn_type_unification): Use new interfaces. - (type_unification): Likewise. Remove NOP_EXPR hack. - (type_unification_real): Likewise. - (unify): Likewise. Deal with unification of complex expresions. - -Mon Mar 23 12:24:37 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (complete_template_args): Initialize skip properly. - - * decl.c (make_typename_type): Revert. - (make_implicit_typename): Remove. - (lookup_name_real): Don't call it. Call lookup_field if we see a - TYPE_DECL from a template base. - * search.c (lookup_field): Do implicit typename stuff. - -Sun Mar 22 00:50:42 1998 Nick Clifton <nickc@cygnus.com> - Geoff Noer <noer@cygnus.com> - - * Makefile.in: Various fixes for building cygwin32 native toolchains. - * Make-lang.in: Likewise. - -Fri Mar 20 18:07:39 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (tsubst, TEMPLATE_TEMPLATE_PARM): Simplify. - -Fri Mar 20 10:42:07 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (make_implicit_typename): Rewrite removed code. - (make_typename_type): Call it if the type we look up comes from - a base that uses template parms. - - * pt.c (complete_template_args): Rewrite. - (tsubst, FUNCTION_DECL): Use it. - -Fri Mar 20 08:12:43 1998 H.J. Lu (hjl@gnu.org) - - * semantics.c (finish_asm_stmt): Fix combine strings. Call - c_expand_asm_operands () if output_operands, input_operands or - clobbers is not NULL_TREE. - -Fri Mar 20 00:10:19 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (complete_template_args): New function. - (get_bindings): Deal with specializations of function templates - with return type containing parameters from outer class - templates. - (tsubst, TEMPLATE_TEMPLATE_PARM): When reducing parameter level, - substitute arguments and compose a new type. - -Thu Mar 19 19:01:48 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (tsubst): Clear DECL_PENDING_INLINE_INFO for new - FUNCTION_DECLs. - -Thu Mar 19 11:51:58 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (make_implicit_typename): Lose useless code. - - * call.c (standard_conversion): Handle A* -> const A* properly. - - * pt.c (get_bindings_real): Rename from get_bindings. Add - check_rettype parm. - (get_bindings): Pass 1. - (get_bindings_overload): Pass 0. - -Wed Mar 19 09:08:12 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (check_explicit_specialization): When reverting a static - member function, also remove the `this' parameter from - last_function_parms. - -Thu Mar 19 02:27:48 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_copy, CONST_DECL): Don't bother tsubsting - a function context. - - * decl.c (store_bindings): Use free_binding_vecs. - (pop_from_top_level): Likewise. - -Wed Mar 18 12:41:43 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (make_implicit_typename): Only change the type of a - TYPENAME_TYPE. - -Wed Mar 18 10:09:51 1998 Mark Mitchell <mmitchell@usa.net> - - * semantics.c: New file, containing routines to perform the - semantic phase of parsing. - * parse.y: Use it. - * pt.c (tsubst_expr): Likewise. - * cp-tree.h: Declare the various functions in semantics.c. - Provide macros to access _STMT tree nodes. - * cp-tree.def: Add ASM_STMT tree node. - * Makefile.in, Make-lang.in: Add dependencies on and for - semantics.c. - -Wed Mar 18 00:24:10 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (push_template_decl): Only check primary templates. - - * pt.c (check_explicit_specialization): Complain about default args - in explicit specialization. - - * parse.y (nomods_initdcl0): Also call cp_finish_decl for a - constructor_declarator. - -Tue Mar 17 14:44:54 1998 Mark Mitchell <mmitchell@usa.net> - - * typeck2.c (build_x_arrow): Don't crash when an aggregate type - has no overloaded operator ->. - - * call.c (build_field_call): Don't crash when presented with a - field that is actually a nested type. - - * decl.c (pushtag): Deal with friend class injection in local - classes. - - * call.c (build_object_call): Don't crash if OBJ is a - pointer-to-member-function. - -Tue Mar 17 11:40:26 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (push_template_decl): Complain about template with C linkage, - anonymous template class. - -Mon Mar 16 12:10:39 1998 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (pushclass): Only use the mi_matrix stuff #ifdef MI_MATRIX. - * search.c: Likewise. - - * lex.c (do_pending_defargs): Only call - maybe_{begin,end}_member_template_processing for FUNCTION_DECLs. - - * parse.y (initdcl0_innards): Move maybeasm back into initdcl0 et al. - -Mon Mar 16 10:47:22 1998 Mark Mitchell <mmitchell@usa.net> - - * parse.y: Deal with CONSTRUCTORS in new_initializers. - -Mon Mar 16 10:54:21 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (tsubst_copy): Deal with BIND_EXPR in a way that more - closely mimics the behavior in parse.y. - (tsubst_expr): Return the resuting BLOCK when making a tsubst'ing - into a compound statement. - -Sun Mar 15 02:07:26 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (TEMPLATE_PARMS_FOR_INLINE): New macro. - * pt.c (inline_needs_template_parms): New fn. - (original_template): New fn. - (push_inline_template_parms_recursive): New fn. - (maybe_begin_member_template_processing): Use them. - (maybe_end_member_template_processing): Likewise. - (is_member_or_friend_template): Rename to is_member_template. - Member functions of local classes are never member templates. - -Sun Mar 15 01:14:22 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * lex.c (do_identifier): Handle TEMPLATE_DECL that was - added in the class scope to catch redefinition error. - - * pt.c (reduce_template_parm_level): Also copy - the DECL_TEMPLATE_PARMS field. - -Sun Mar 15 10:54:08 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (tsubst): Clear TYPE_REFERENCE_TO when creating a - reduced-level template type parameter. - -Sun Mar 15 12:26:02 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * cp-tree.h (struct lang_decl_flags): Add needs_final_overrider. - (DECL_NEEDS_FINAL_OVERRIDER_P): New macro. - * class.c (override_one_vtable): Set DECL_NEEDS_FINAL_OVERRIDER_P. - * decl.c (duplicate_decls): Propagate it. - * typeck2.c (abstract_virtuals_error): Use two loops to emit - abstract virtual functions and virtual functions which need a - final overrider separately. - -Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * lang-specs.h: Properly put brackets around array elements in - initializer. - - * typeck.c (build_binary_op_nodefault): Correctly place parens around - && and || in expression. - -Thu Mar 12 09:26:04 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * call.c (default_parm_conversions): Remove prototype definition. - (build_method_call): Remove unused variable result. - - * cvt.c (ocp_convert): Remove unused variable conversion. - - * decl2.c (ambiguous_decl): Add explicit parameter definition for name. - - * except.c (do_unwind): #if 0 definition of unused variables fcall - and next_pc. - - * expr.c (extract_scalar_init): #if 0 prototype and function - definition. - - * init.c (expand_aggr_init_1): Remove unused variable init_type. - (build_new_1): Remove unused variable t. - - * pt.c (instantiate_class_template): Remove unused variable newtag; - cast called function return value to void. - (do_decl_instantiation): Remove unused variables name and fn. - - * tree.c (get_type_decl): Add default return to shut up compiler from - complaining control reaches end of non-void function. - - * typeck.c (build_x_conditional_expr): Remove unused variable rval. - -Thu Mar 12 09:12:15 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * call.c (default_parm_conversions): Remove prototype definition. - (build_method_call): Remove unused variable result. - (build_over_call): Add default case in enumeration switch. - -Thu Mar 12 08:39:13 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * decl2.c (lang_decode_option): Change j's type to size_t. - - * tree.c (layout_vbasetypes): record_align and desired_align are of - type unsigned int; const_size and nonvirtual_const_size likewise. - -Wed Mar 11 07:25:20 1998 Mark Mitchell <mmitchell@usa.net> - - * parse.y (new_initializer): Make sure all initializers are - lists. - -Tue Mar 10 07:32:36 1998 Mark Mitchell <mmitchell@usa.net> - - * decl2.c (import_export_decl): Mark tinfo functions for - cv-qualified versions of class types as DECL_NOT_REALLY_EXTERN. - -Fri Mar 6 23:27:35 1998 Jeffrey A Law (law@cygnus.com) - - * method.c: Fix typo. - -Fri Mar 6 10:06:59 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * method.c: Include "system.h" to get stdlib.h, stdio.h, - ctype.h, string.h, etc. - (issue_nrepeats): Add default case in enumeration switch. - (check_btype): Likewise. - (process_overload_item): Likewise. - - * Makefile.in (method.o): Depend on system.h. - -Wed Mar 4 22:26:53 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * lex.c (do_scoped_id): Fix parenthesizing. - -Wed Mar 4 12:11:53 1998 Michael Tiemann <tiemann@axon.cygnus.com> - - * rtti.c (get_tinfo_fn_dynamic): If this function is called an - FLAG_RTTI is unset, initialize type info machinery and continue - with FLAG_RTTI enabled. - (get_typeid): Ditto. - -Wed Mar 4 11:47:55 1998 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (unary_complex_lvalue): &D::i has type B::* if i comes - from B. - -Wed Mar 4 11:28:08 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (finish_member_template_decl): Deal more gracefully with - invalid declarations. - -Tue Mar 3 01:38:17 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c, decl.c, decl2.c, init.c, rtti.c, typeck.c, typeck2.c, - cp-tree.h: Clean up more old overloading code, old RTTI code, and - some formatting quirks. - - * call.c, class.c, cp-tree.h, cvt.c, decl.c, init.c, lex.c, - method.c, pt.c, ptree.c, typeck.c: Remove support for - -fno-ansi-overloading and overloading METHOD_CALL_EXPR. - * class.h: Remove. - * Makefile.in: Adjust. - - * pt.c (unify): Don't allow reduced cv-quals when strict. - - * call.c, class.c, pt.c, cp-tree.h: Remove nsubsts parm from - *type_unification* and unify. - -Mon Mar 2 12:11:06 1998 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (explicit_template_type): Remove TEMPLATE keyword. - (nested_name_specifier): And add it before this use. - (typename_sub0): And this use. Also add use without the keyword. - (typename_sub1): Likewise. - * pt.c (instantiate_class_template): Don't actually instantiate - anything if our type uses template parms. - -Mon Mar 2 11:04:59 1998 Jim Wilson <wilson@cygnus.com> - - * decl.c (start_function): Don't call temporary_allocation for a - nested function. - -Sun Mar 1 21:06:37 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Don't mess with friends if - our type uses template parms. - -Sat Feb 28 12:06:44 1998 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (nested_name_specifier): Use explicit_template_type. - (typename_sub): Allow a template_type, an explicit_template_type, - or an implicit template type at the end. - * lex.c (yyprint): Handle a PTYPENAME being a TEMPLATE_DECL. - * decl.c (make_typename_type): Handle template-id where the name - is a TEMPLATE_DECL. - * call.c (build_scoped_method_call): Handle member template - destructor call. - * pt.c (tsubst_copy, METHOD_CALL_EXPR): Don't assume a member - destructor is represented by the type. - - * cp-tree.h (TYPENAME_TYPE_FULLNAME): New macro. - * parse.y (nested_name_specifier): Add 'template' case. - (explicit_template_type): New rule. - (typename_sub): Use it. - * decl.c (make_typename_type): Handle getting a template-id for NAME. - * pt.c (tsubst): Likewise. - -Fri Feb 27 11:17:50 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (add_to_template_args): Fix thinko. - (instantiate_class_template): Call it later. - - * pt.c (get_class_bindings): Add outer_args parm. - (most_specialized_class): Likewise. - (instantiate_class_template): Pass it. - (more_specialized_class): Likewise. - (lookup_template_class): Get context from template if none - was specified. - (finish_member_template_decl): Don't do anything with a - partial specialization. - * decl2.c (check_member_template): Use IS_AGGR_TYPE instead of - AGGREGATE_TYPE_P. - * class.c (finish_struct): Member class templates have already been - checked for name clashes. - * decl.c (pushdecl_with_scope): Handle pushing at class level. - -Fri Feb 27 02:25:16 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst, TEMPLATE_DECL): Support member class templates. - (tsubst, *_PARM): Support multiple levels of template classes. - (instantiate_class_template): Look up the pattern from the - original template. - (lookup_template_class): Handle getting a template for d1. - (push_template_decl): Correct setting of 'primary'. - (reduce_template_parm_level): Add 'levels' parm. - (finish_member_template_decl): Support member class templates. - (template_class_depth): Handle multiple levels. - * parse.y (component_decl_1, fn.def2): Remove member template case. - (component_decl): Add member template cases. - * decl2.c (check_member_template): We now handle member template - classes. - * decl.c (pushtag): Handle member templates. - * method.c (do_inline_function_hair): Don't touch - IDENTIFIER_GLOBAL_VALUE. - * init.c (build_offset_ref): If name isn't an identifier, just - return it. - * spew.c (yylex): Handle PTYPENAME like TYPENAME. - - * typeck.c (get_delta_difference): Do adjust for conversions to - and from virtual base. - -Wed Feb 25 09:51:29 1998 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (get_delta_difference): Give hard error for conversion - from virtual base. - - * cp-tree.h: Tweak formatting. - -Wed Feb 25 00:35:33 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (push_namespace): Handle redeclaration error. - - * cp-tree.h (IDENTIFIER_NAMESPACE_VALUE): New macro. - (IDENTIFIER_NAMESPACE_BINDINGS): New macro. - (NAMESPACE_BINDING): New macro. - (IDENTIFIER_GLOBAL_VALUE): Use NAMESPACE_BINDING. - * *.c: Use them. - - * pt.c (push_template_decl): Use innermost_args. - - * decl.c (get_unique_name): Tweak from earlier in the name. - -Tue Feb 24 22:15:04 1998 Martin von Loewis <loewis@informatik.hu-berlin.de> - - * cp-tree.def: Add CPLUS_BINDING node. - * cp-tree.h (tree_binding): new struct - (BINDING_SCOPE, BINDING_VALUE): new macros - (current_namespace, global_namespace): declare extern - (struct lang_decl_flags): new field in_namespace - (DECL_NAMESPACE_USING, DECL_NAMESPACE_USERS): new macros - (DECL_NAMESPACE, SET_DECL_NAMESPACE): new macros - (TREE_INDIRECT_USING): new macro - * decl2.c (current_namespace, global_namespace): Declare. The - value is a NAMESPACE_DECL now, not a TREE_LIST. - (is_namespace_ancestor, namespace_ancestor):new static functions. - (add_using_namespace, ambiguous_decl): likewise. - (lookup_using_namespace): new support function for lookup_name. - (qualified_lookup_using_namespace): new support function for - do_scoped_id and lookup_namespace_name - (get_namespace_id): mark as obsolete. - (current_namespace_id): Likewise. - (do_namespace_alias): Implement. - (do_using_directive): Implement as call to add_using_namespace. - * decl.c (binding_for_name): new function. - (push_namespace, pop_namespace): implement. - (push_decl): don't install a FUNCTION_DECL in the global branch. - (lookup_namespace_name): implement using qualified lookup. - (lookup_name_real): For global scoping, lookup in - global_namespace. For namespace scoping, lookup in given - namespace. For unscoped lookup, iterate over namespace, - considering using directives. - (init_decl_processing): initialize global_namespace. - (grokvardecl): Build assembler name as static name for globals. - (grokdeclarator): Remove old namespace mangling. - (xref_tag): When installing a global binding for the - tag, make sure we have an identifier. - * method.c (build_overload_nested_name): mangle namespaces. - (build_qualified_name): Likewise. - (build_decl_overload_real): Likewise. - * lex.c (build_lang_decl): set namespace for new declaration to - current_namespace. - (do_scoped_id): find global names in global or current - namespace, or using qualified namespace lookup, depending on - context. - * init.c (build_member_call): When scope is namespace, use - build_x_function_call instead. - (build_offset_ref): When scope is namespace, collapse processing - to lookup_namespace_name instead. - * error.c (dump_decl): Support NAMESPACE_DECL. - * decl.c (pushdecl): Bind globals to current namespace. - (push_overloaded_decl): Likewise. - (lookup_tag): Likewise. - (lookup_name_current_level): Likewise. - (xref_tag): Likewise. - (start_function): Likewise. - * lex.c (do_identifier): Likewise. - (identifier_typedecl_value): Likewise. - (real_yylex): Likewise. - * method.c (do_inline_function_hair): Likewise. - * parse.y (unscoped): Likewise. - * pt.c (check_explicit_specialization): Likewise. - (lookup_template_class): Likewise. - * rtti.c (call_void_fn): Likewise. - * sig.c (build_sigtable): Likewise. - * ptree.c (lang_print_xnode): New function. - -Tue Feb 24 01:40:24 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Don't instantiate if pedantic - and the args use template parms. - - * pt.c (push_tinst_level): If the instantiaton uses template parms, - fail silently. - * decl.c (xref_basetypes): Do call complete_type for basetypes - that involve template parameters. - -Tue Feb 24 00:36:43 1998 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (process_init_constructor): Fix labeled init check. - -Mon Feb 23 05:08:55 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c, call.c, decl.c, method.c, cp-tree.h: Remove unused NARGS - argument to tsubst and friends. - - * pt.c (tsubst, FUNCTION_DECL): Tidy. - - * typeck.c (build_x_function_call): Handle static member function - templates like non-templates. Handle friend templates like normal - function templates. - * pt.c (tsubst, *_PARM): Don't use orig_level. - (get_bindings): Don't call add_to_template_args. - (instantiate_template): Likewise. - (tsubst, FUNCTION_DECL): Call add_to_template_args as appropriate. - * ptree.c (print_lang_type): Print index/level for template parms. - -Mon Feb 23 02:52:29 1998 Mark Mitchell <mmitchell@usa.net> - - * Make-lang.in (cc1plus): Note that cc1plus depends on - cp/cp-tree.h and cp/cp-tree.def. - - * cp-tree.def (TEMPLATE_CONST_PARM): Remove. - (TEMPLATE_PARM_INDEX): New tree code, used to indicate a - position in a template parameter list. - * cp-tree.h (template_parm_index): New structure, used as the tree - structure for a TEMPLATE_PARM_INDEX. - (TEMPLATE_PARM_IDX): New macro. - (TEMPLATE_PARM_LEVEL): Likewise. - (TEMPLATE_PARM_DESCENDANTS): Likewise. - (TEMPLATE_PARM_ORIG_LEVEL): Likewise. - (TEMPLATE_PARM_DECL): Likewise. - (TEMPLATE_TYPE_PARM_INDEX): Likewise. - (TEMPLATE_TYPE_ORIG_LEVEL): Likewise. - (TEMPLATE_TYPE_DECL): Likewise. - (TEMPLATE_CONST_IDX): Remove. - (TEMPLATE_CONST_LEVEL): Likewise. - (TEMPLATE_CONST_SET_INFO): Likewise. - (TEMPLATE_TYPE_SET_INFO): Likewise. - (TEMPLATE_TYPE_IDX): Redefine in terms of TEMPLATE_PARM_INDEX - node. - (TEMPLATE_TYPE_LEVEL): Likewise. - * decl.c (decls_match): Call comp_template_parms, rather than - expanding it inline. - (duplicate_decls): If two template declarations are being merged, - then their TEMPLATE_INFOs should be merged as well. - (grokfndecl): Save template-id information when declaring a friend - with explicit template arguments. Pass arguments to - check_explicit_specialization via correct convention; at some - point check_explicit_specialization changed, but these call-sites - did not. - (grokdeclarator): Tidy up slightly. - * decl2.c (check_classfn): Tidy up slightly. Don't assume that - two template functions with the same DECL_ASSEMBLER_NAME the same, - since the names are not yet mangled. - * error.c (dump_decl): Use TEMPLATE_PARM_INDEX instead of - TEMPLATE_CONST_PARM. - (dump_expr): Likewise. Use the TEMPLATE_PARM_DECL to get at the - decl for a non-type parameter, rather than printing `<tparm ...>'. - * friend.c (is_friend): Handle TEMPLATE_DECL friends. - (do_friend): Deal with template friends. - * lex.c (do_pending_inlines): Call - maybe_begin_member_template_processing, rather than - conditionally calling begin_member_template_processing. - (process_next_inline): Likewise. Call - maybe_end_member_template_processing, rather than - conditionally calling end_member_template_processing. - (do_pending_defargs): Likewise. - (do_identifier): Use TEMPLATE_PARM_INDEX instead of - TEMPLATE_CONST_PARM. - * method.c (build_mangled_template_parm_index): New function. - (build_overload_value): Use it. - (build_overload_name): Likewise. - * pt.c (finish_member_template_decl): Allow friend declarations. - (template_class_depth): New function. - (is_member_template): Rename, and modify, to become... - (is_member_or_friend_template): New function. - (end_member_template_processing): Rename, and modify, to become... - (maybe_end_member_template_processing). - (build_template_parm_index): New function. - (reduce_template_parm_level): New function. - (process_template_parm): Modify to use build_template_parm_index. - (push_template_decl): Deal with friend templates. - (uses_template_parms): Use TEMPLATE_PARM_INDEX instead of - TEMPLATE_CONST_PARM. - (tsubst_friend_function): New function. - (instantiate_class_template): Generate the DECL_FRIENDLIST - for a new instantiation by using tsubst_friend_function rather - than just tsubst. - (tsubst): Don't tsubst into a type which is a TEMPLATE_DECL. - Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM, and the - appropriate new macros. Use reduce_template_parm_level to - generate lower-level template parameters. Handle tsubst'ing into - TEMPLATE_DECLS that declare TEMPLATE_TEMPLATE_PARMS. Don't forget - to tsubst the DECL_CONTEXT and DECL_CLASS_CONTEXT of newly created - templates. Similarly for the template parameters for a new - template. - (tsubst_copy): Tidy up slightly. Use TEMPLATE_PARM_INDEX instead - of TEMPLATE_CONST_PARM. Handle TYPE_DECLs by tsubsting into them. - (unify): Use TEMPLATE_PARM_INDEX instead of TEMPLATE_CONST_PARM. - (get_bindings): Call add_to_template_args if necessary. - (instantiate_decl): Handle instantiations of friend templates. - * search.c (lookup_field_1): Don't treat the TYPE_FIELDS of a - TEMPLATE_TYPE_PARM as a list of fields; it's not! - * spew.c (yylex): Do a little manual constant propogation to - clarify the code. - -Sun Feb 22 19:53:29 1998 Jeffrey A Law (law@cygnus.com) - - * error.c: Include sys/types.h. - -Thu Feb 19 14:49:09 1998 Jeffrey A Law (law@cygnus.com) - - * method.c (build_mangled_name): Start CPP directives in column zero. - -Thu Feb 19 10:36:48 1998 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (process_init_constructor): Sorry about non-trivial - labeled initializers. - * parse.y (initlist): Reenable labeled initializers. - -Thu Feb 19 10:15:55 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (coerce_template_parms) Add a new parameter, is_tmpl_parm, - all callers changed. Rely on the new parameter instead of arg - being a TREE_LIST when determine whether we are working inside - template template parameter. Clean up is_type test. - -Thu Feb 19 10:04:12 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Preserve TREE_CONSTANT. - * typeck2.c (initializer_constant_valid_p): Allow conversions - between pointers and refrerences. - -1998-02-19 Brendan Kehoe <brendan@cygnus.com> - - * typeck.c (build_unary_op): Only warn about incr/decr a pointer - if pedantic || warn_pointer_arith. - -Thu Feb 19 09:37:21 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (unify): Handle TEMPLATE_DECL. - -1998-02-18 Brendan Kehoe <brendan@cygnus.com> - - * cp-tree.h (strip_attrs): Remove decl. - -1998-02-18 Doug Evans <devans@cygnus.com> - - * decl.c (duplicate_decls): Call merge_machine_decl_attributes. - Update olddecl's attributes too. - (strip_attrs): Remove function. - * typeck.c (common_type): Call merge_machine_type_attributes. - -Tue Feb 17 14:07:52 1998 Mark Mitchell <mmitchell@usa.net> - - * parse.y (initdcl0_innards): New grammar symbol. - (nomods_initdecls, nomods_initdcl0): Change type from itype to - none, since the resulting value is never used. - (parse_decl): New function. - (datadef): Remove redundant actions. - (initdcl0, notype_initdcl0, nomods_initdcl0): Use initdcl0_innards. - * parse.c: Regenerated. - -Tue Feb 17 11:54:16 1998 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (simple_stmt): Use getdecls() to check for decl. - -Sat Feb 14 11:50:51 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * Make-lang.in (DEMANGLER_INSTALL_NAME, DEMANGLER_CROSS_NAME): New - macros. - (c++.install-common): Install c++filt properly as native or as cross - variant. - (c++.uninstall): Add c++filt. - -Fri Feb 13 14:55:37 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (standard_conversion): Fix multi-level ptr conversions. - -Fri Feb 13 14:06:22 1998 Mike Stump <mrs@wrs.com> - - * init.c (build_new): Propagate error_mark_node up. - -Fri Feb 13 13:24:32 1998 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (simple_stmt): If the condition isn't a declaration, - start the controlled block after the test. - -Fri Feb 13 02:26:10 1998 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * call.c (build_over_call): Convert builtin abs, labs and fabs to - tree-codes. - * decl.c (init_decl_processing): Reenable abs, labs and fabs as - builtins. - -Fri Feb 13 01:36:42 1998 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (standard_conversion): A BASE_CONV replaces an RVALUE_CONV. - -Fri Feb 13 00:21:59 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h: Add access_protected_virtual_node. - * class.c (init_class_processing): Initialize it. - * decl.c (xref_basetypes): Use it. - * parse.y (base_class_access_list): Likewise. - - * Make-lang.in (DEMANGLER_PROG): Add $(exeext). - (c++.install-common): Install c++filt. - -Thu Feb 12 12:46:51 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (shadow_tag): Give error for typedef-ing built-in types. - -Wed Feb 11 23:28:05 1998 Mark Mitchell <mmitchell@usa.net> - - * call.c (reference_binding): Use comptypes when comparing - TYPE_MAIN_VARIANTS to handle non-canonical array/index types. - -Wed Feb 11 16:42:04 1998 Mark Mitchell <mmitchell@usa.net> - - * tree.c (is_overloaded_fn): Use really_overloaded_fn. - (really_overloaded_fn): Move check here from is_overloaded_fn. - (get_first_fn): Use really_overloaded_fn and is_overloaded_fn. - -Wed Feb 11 15:54:18 1998 Mark Mitchell <mmitchell@usa.net> - - * typeck.c (build_ptrmemfunc): Type-check pointer-to-member - conversions. - -Mon Feb 9 22:23:31 1998 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (push_template_decl): Return the decl passed in, or an - equivalent duplicate. - * decl.c (pushtag): Use the return value from push_template_decl. - (duplicate_decls): When duplicating a template declaration, merge - the DECL_TEMPLATE_RESULTs as well. - (make_implicit_typename): Don't try to dive into typename types to - find a context for making a new implicit typename. - (start_decl): Use the return value from push_template_decl. - (grokdeclarator): Complain about declarations list `const operator - int'. Since we don't correctly handle in-class initializations of - non-static data members, complain about this (now illegal) - practice. Issue an error for initializations of non-const statics - since that is illegal as well, and since we don't handle that case - correctly either. - (start_function): Use the return value from push_template_decl. - (start_method): Likewise. - * decl2.c (grokfield): Likewise. Since the change to - grokdeclarator ensures that all initialized fields are in fact - static, remove a redundant test for TREE_PUBLIC. - * parse.y (initlist): Disable labeled initializers since they do - not work as per the documentation, and since they do not use the - same syntax as the C front end. - * pt.c (push_template_decl): Return the decl passed in, or an - equivalent duplicate. - (lookup_template_class): When searching in a nested context, - use the right arguments. - (uses_template_parms): Handle the DECL_INITIAL for a CONST_DECL. - * typeck.c (build_component_ref): Assign the correct type to the - result of build_vfn_ref. - -Tue Feb 10 23:56:46 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (convert_nontype_argument): Fix typo. - (check_explicit_specialization): Allow old-style specialization - of class template members. - -Tue Feb 10 20:36:52 1998 Jason Merrill <jason@yorick.cygnus.com> - Manfred Hollstein <manfred@s-direktnet.de> - - * decl.c (grokdeclarator): Use DECL_USE_TEMPLATE instead - when deciding to override DECL_ASSEMBLER_NAME. - -Tue Feb 10 15:30:55 EST 1998 Andrew MacLeod <amacleod@torpedo.to.cygnus.com> - - * decl2.c (lang_f_options): Add -fsquangle to option processing list. - * cp-tree.h (flag_do_squangling): Add declaration. - * lang-options.h: Add -fsquangle and -fno-squangle. - * method.c: Add macros and static variables for squangling. - (build_overload_name): Rename to build_mangled_name, add logic for B - compression, and split into process_modifiers and - process_overload_item. - (process_modifiers): New function, to handle constant, reference, - and pointer types. - (process_overload_item): New function, handles issue of type codes. - (build_overload_name): New function, start squangling and call - build_mangled_name. - (ALLOCATE_TYPEVEC, DEALLOCATE_TYPEVEC): Remove macro and expand inline. - (start_squangling): New function to initialize squangling structs. - (end_squangling): New function to destroy squangling structs. - (nrepeats): Rename variable to Nrepeats. - (issue_nrepeats): New function for issuing 'n' type repeats. - (check_ktype): New function to check for type K name compression. - (build_overload_nested_name): Add a check for K name compression. - (build_qualified_name): Add a check for K name compression and don't - use DECL_ASSEMBLER_NAME when squangling is on. - (check_btype): New function, checks for B type compression. - (build_static_name, build_decl_overload_real): Initiate squangling. - (build_typename_overload, build_overload_with_type): Initiate - squangling - -Sun Feb 8 23:47:38 1998 scott snyder <sss@d0linux01.fnal.gov> - - * method.c (make_thunk): Avoid name buffer overflow. - -Sat Feb 7 16:48:54 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Call cp_finish_decl for vars even if we - don't define them yet. - - * parse.y (nomods_initdcl0): Add constructor_declarator case. - -Fri Feb 6 21:32:25 1998 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * config-lang.in (diff_excludes): Use basename only. - -Thu Feb 5 19:10:40 1998 Jason Merrill <jason@yorick.cygnus.com> - - * tinfo2.cc: Add tinfo for signed char. - -Thu Feb 5 14:38:23 1998 Mike Stump <mrs@wrs.com> - - * search.c (compute_access): Handle protected constructors in derived - classes as accessible. - -Wed Feb 4 01:26:49 1998 Jason Merrill <jason@yorick.cygnus.com> - - * expr.c (cplus_expand_expr, PCC_STATIC_STRUCT_RETURN code): - Call convert_from_reference sooner. - -Tue Feb 3 23:50:52 1998 Mark Mitchell <mmitchell@usa.net> - - * cvt.c (ocp_convert): Obtain the constant values from constant - decls even if the destination type is the same as the type of the - decl. - - * decl2.c (finish_file): Make sure that static inlines with - definitions are not marked DECL_EXTERNAL before returning. - -Tue Feb 3 22:43:42 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c: Lose arg_looking_for_template. - (lookup_name_real): Likewise. - * parse.y: Lose processing_template_arg, template_arg1 - (primary): Likewise. - * spew.c (yylex): Set lastiddecl for PTYPENAMEs, too. - -Tue Feb 3 22:04:01 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * error.c (dump_decl): Fix type of default arguments for template - template parameters and nontype template parameters. - * parse.y (template_parm): Handle invalid default template - template arguments here. - - * parse.y (template_parm): Use template_arg instead of PTYPENAME - for default template template argument. - * pt.c (coerce_template_parms): Merge default template argument - codes. Can treat RECORD_TYPE as template name if it is implicitly - created. Fix argument index in error message. - * typeck.c (comptypes): Merge template argument comparison codes in - TEMPLATE_TEMPLATE_PARM and RECORD_TYPE. - -Tue Jan 6 01:42:44 1998 Mumit Khan <khan@xraylith.wisc.edu> - - * lex.c (file_name_nondirectory): Also check for '/'. - -Mon Feb 2 11:24:22 1998 Mark Mitchell <mmitchell@usa.net> - - * parse.y (primary): Deal with statement-expressions in - templates. - * pt.c (tsubst_copy): Handle BIND_EXPR. - * tree.c (mapcar): Likewise. - - * call.c (add_template_candidate_real): Pass extra parameter to - fn_type_unification. - * cp-tree.h (fn_type_unification): Add parameter. - * pt.c (fn_type_unification): Add additional parameter to deal with - static member functions. - (get_bindings): Deal with static member functions. - - * cp-tree.h (DECL_NONSTATIC_MEMBER_FUNCTION_P): New macro. - (revert_static_member_fn): Declare. - * decl.c (revert_static_member_fn): Remove declaration. Change - linkage from internal to external. - (cp_finish_decl): Deal with virtual functions in classes local to - template functions. - * decl2.c (finish_file): Don't forget to emit increment/decrement - expressions in initializers for file-scope variables. - * parse.y (typename_sub2): If the typename doesn't names a - template, rather than a type, issue an error message. - * pt.c (check_explicit_specialization): Handle specializations of - static member functions. - (coerce_template_parms): Handle offset references to lists of - member functions. - * search.c (note_debug_info_needed): Don't crash when handed a - type which is being defined. - * typeck.c (complete_type): Don't crash when handed NULL_TREE; - that can happen with some illegal code. - -Mon Feb 2 00:57:38 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * call.c (user_harshness): Initialize `code' to 0. - (build_method_call): Initialize `candidates', `cp' and `len' to 0. - (null_ptr_cst_p): Add parentheses around && within ||. - (standard_conversion): Likewise. - (z_candidate): Likewise. - (build_user_type_conversion_1): Initialize `args' to NULL_TREE. - (build_object_call): Likewise for `mem_args'. - (build_new_op): Likewise for `mem_arglist'. Add `return' from - default case in enumeration switch. - - * class.c (build_vtable_entry): Add explicit braces to avoid - ambiguous `else'. - (build_class_init_list): Likewise. - (finish_struct_1): Initialize `width' to 0. - (instantiate_type): Initialize `name' to NULL_TREE. Add - explicit braces to avoid ambiguous `else'. - - * cvt.c (convert_to_aggr): Add explicit braces to avoid ambiguous - `else'. - - * decl.c (grok_reference_init): Eliminate unused parameter, all - callers changed. - (record_builtin_type): Initialize `tdecl' to NULL_TREE. - (init_decl_processing): Initialize `vb_off_identifier' to NULL_TREE. - (cp_finish_decl): Initialize `ttype' to NULL_TREE. - (grokdeclarator): Add parentheses around && within ||. Add - explicit braces to avoid ambiguous `else'. - (grokparms): Initialize `type' to NULL_TREE. - (xref_tag): Remove unused label `just_return'. - (finish_enum): Initialize `minnode' and `maxnode' to NULL_TREE. - (finish_function): Initialize `cond' and `thenclause' to NULL_TREE. - (hack_incomplete_structures): Add parentheses around assignment - used as truth value. - - * decl2.c (coerce_delete_type): Hide definition of `e3'. - - * error.c: Include <stdlib.h>. - (dump_expr): Change the type of `i' to size_t. Remove unused - label `error'. - - * except.c (init_exception_processing): Remove unused variable `d'. - (expand_throw): Likewise for `label'. - - * friend.c (add_friends): Add explicit braces to avoid ambiguous - `else'. - - * init.c (sort_member_init): Initialize `last_field' to NULL_TREE. - (sort_base_init): Likewise for `binfo'. - (expand_member_init): Likewise for `rval'. - (build_member_call): Add parentheses around assignment used as - truth value. - (build_offset_ref): Add explicit braces to avoid ambiguous `else'. - (build_new): Initialize `nelts' to NULL_TREE. Initialize - `old_immediate_size_expand' to 0. - (build_new_1): Initialize `nelts' and `alloc_node' to NULL_TREE. - (build_vec_delete_1): Remove unused variable `block'. - (expand_vec_init): Initialize `itype' to NULL_TREE. - - * lex.c: Include <strings.h> if we don't have <string.h>. Protect - declaration of `index' and `rindex' with autoconf macros. - (reinit_parse_for_expr): Remove unused variables - `look_for_semicolon' and `look_for_lbrac'. - (cons_up_default_function): Initialize `args' to NULL_TREE. - (readescape): Initialize `firstdig' to 0. - (real_yylex): Add parentheses around assignment used as truth value. - - * method.c: Include <strings.h> if we don't have <string.h>. - Protect declaration of `index' with autoconf macro. - - * parse.y (primary): Add explicit braces to avoid ambiguous `else'. - Initialize `type' to NULL_TREE. - (structsp): Remove unused variable `id'. - - * pt.c (coerce_template_parms): Add explicit braces to avoid - ambiguous `else'. - (lookup_template_class): Initialize `template' to NULL_TREE. - (instantiate_class_template): Remove unused variable `name' and `e'. - (tsubst): Likewise for `i'. Initialize `last' to NULL_TREE. - (do_poplevel): Initialize `saved_warn_unused' to 0. - (type_unification): Remove unused varable `parm'. - (unify): Likewise for `j'. - - * repo.c (init_repo): Add parentheses around assignment used as - truth value. - (finish_repo): Remove unused varable `p'. - - * search.c (get_binfo): Initiize `type' to NULL_TREE. - (get_base_distance): Likewise. - (lookup_field): Initialize `rval_binfo_h', `type', `basetype_path' - and `new_v' to NULL_TREE. - (lookup_fnfields): Likewise for `rval_binfo_h'. - (breadth_first_search): Add parentheses around assignment used as - truth value. - (get_template_base): Initialize `type' to NULL_TREE. - - * sig.c (append_signature_fields): Initialize `last_mfptr' to - NULL_TREE. - (build_signature_table_constructor): Likewise for - `last_rhs_field', `pfn' and `vt_off'. - (build_sigtable): Likewise for `init'. - - * tree.c (break_out_calls): Initialize `t2' to NULL_TREE. - (propagate_binfo_offsets): Likewise for `delta'. - (hash_tree_cons): Initialize hashcode to 0. - (can_free): Likewise for `size'. - (cp_tree_equal): Add explicit braces to avoid ambiguous `else'. - - * typeck.c (convert_sequence): Hide prototype. - (common_type): Add explicit braces to avoid ambiguous `else'. - (comp_target_types): Likewise. - (build_x_function_call): Initialize `ctypeptr' to NULL_TREE. - (build_function_call_real): Add explicit braces to avoid ambiguous - `else'. - (convert_arguments): Initialize `called_thing' to 0. - (convert_for_initialization): Initialize `savew' and `savee' to 0. - - * typeck2.c (incomplete_type_error): Initialize `errmsg' to 0. - (digest_init): Initialize `old_tail_contents' to NULL_TREE. - (build_x_arrow): Likewise for `last_rval'. - - * xref.c (GNU_xref_decl): Initialize `cls' to 0. - -Sun Feb 1 12:45:34 1998 J"orn Rennecke <amylaar@cygnus.co.uk> - - * decl.c (init_decl_processing): Use set_sizetype. - * decl2.c (sizetype): Don't declare. - * typeck.c (c_sizeof): Convert result of *_DIV_EXPR to sizetype. - (c_sizeof_nowarn, build_binary_op_nodefault): Likewise. - (build_component_addr, unary_complex_lvalue): Likewise. - * rtti.c (expand_class_desc): Likewise. - * class.c (get_vfield_offset): Likewise. - -Thu Jan 29 10:39:30 1998 Mark Mitchell <mmitchell@usa.net> - - * pt.c (convert_nontype_argument): Move check for is_overloaded_fn - early to avoid bogus error. Handle overloaded function - names provided as template arguments correctly. - (coerce_template_parms): Don't mishandle overloaded functions when - dealing with template template parameters. - (lookup_template_class): Issue an error message, rather than - crashing, when the TYPE_DECL provided is not a template type. - -Wed Jan 28 23:14:44 1998 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (instantiate_type): Don't just return a known type if - it's wrong. - -Wed Jan 28 11:04:07 1998 Mark Mitchell <mmitchell@usa.net> - - * class.c (instantiate_type): Remove handling of FUNCTION_DECL - since that code could never be reached. - - * error.c (dump_decl): Avoid aborting in the midst of printing an - error message about an illegal template declaration. - - * parse.y (structsp): Print an error message, rather than crashing, - when a class-head does not name a class. - - * pt.c (convert_nontype_argument): Allow REAL_TYPE and COMPLEX_TYPE - template arguments as a g++ extension. - - * cp-tree.def (ALIGNOF_EXPR): New tree code. - * decl2.c (grok_alignof): If processing_template_decl, just store - the expression. - * typeck.c (c_alignof): Likewise. - * decl2.c (build_expr_from_tree): Handle ALIGNOF_EXPR. - * error.c (dump_expr): Likewise. - * pt.c (tsubst_copy): Likewise. - * tree.c (cp_tree_equal): Likewise. - * pt.c (uses_template_parms): Correctly determine whether or not a - SIZEOF_EXPR/ALIGNOF_EXPR uses template parameters so that constant - folding can be done. - - * cp-tree.h (grok_enum_decls): Remove type parameter. - * decl.c (grok_enum_decls): Likewise. - * decl2.c (grok_x_components): Call grok_enum_decls - unconditionally, since it will do nothing if there is no - current_local_enum. Use the new calling sequence. - * pt.c (tsubst_enum): Use the new calling sequence for - grok_enum_decls. - - * decl.c (start_function): Make member functions of local classes - in extern inline functions have comdat linkage here... - (grokdeclarator): Rather than here. - -Wed Jan 28 10:55:47 1998 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (convert_nontype_argument): Use decl_constant_value. - -Tue Jan 27 16:42:21 1998 Mark Mitchell <mmitchell@usa.net> - - * call.c (add_template_candidate_real): New function. - (add_template_candidate): Use it. - (add_template_conv_candidate): Likewise. - (joust): Pass extra argument to more_specialized. - * class.c (instantiate_type): Handle a single FUNCTION_DECL. - (is_local_class): Remove. - (finish_struct): Check TI_PENDING_SPECIALIZATION_FLAG. - * cp-tree.h (is_local_class): Remove. - (perform_array_to_pointer_conversion): Likewise. - (finish_member_template_decl): Add. - (check_explicit_specialization): Return a tree, not an int. - (more_specialized): Take additional argument. - (get_bindings): Likewise. - (TI_PENDING_SPECIALIZATION_FLAG): New macro. - * cvt.c (perform_qualification_conversions): Use comp_ptr_ttypes. - (perform_array_to_pointer_conversion): Remove. - * decl.c (saved_scope): Add processing_specialization, - processing_explicit_instantiation fields. - (maybe_push_to_top_level): Save them. - (pop_from_top_level): Restore them. - (grokfndecl): Use new return value from - check_explicit_specialization. - (start_decl): Don't check flag_guiding_decls before pushing - decls. - (cp_finish_decl): Remove previous (bogus) change. - (grok_declarator): Use decl_function_context rather than - is_local_class. - * decl2.c (finish_file): Pass extra argument to get_bindings. - (build_expr_from_tree): Let build_x_component_ref check - validity of arguments rather than doing it here. - * lex.c (cons_up_default_function): Remove code fooling with - processing_specialization, processing_explicit_instantiation - flags, as that is now done in {maybe_push_top,pop_from}_top_level. - * method.c (build_overload_identifier): Mangle local classes in - template functions correctly. - * parse.y (finish_member_template_decl): Move to pt.c. - * pt.c (finish_member_template_decl): Moved here from parse.y. - (print_candidates): New function. - (determine_specialization): Change interface. Properly look for - most specialized versions of template candidates. - (check_explicit_specialization): Fully process explicit - instantiations. - (push_template_decl): Avoid looking at CLASSTYPE fields in - FUNCTION_DECLS. - (determine_overloaded_function): Remove. - (convert_nontype_argument): Change name from - convert_nontype_parameter. Use determine_overloaded_function - instead of instantiate_type. - (mangle_class_name_for_template): Handle type contexts as well as - function contexts. - (classtype_mangled_name): Likewise. - (lookup_template_class): Likewise. - (tsubst): Likewise. - (more_specialized): Take explict template arguments as a - parameter. - (most_specialized): Likewise. - (get_bindings): Likewise. Check that return types match before - proclaiming a function a match. - (do_decl_instantiation): Remove code searching for function to - instantiate; that is now done in check_explicit_specialization. - (add_maybe_template): Pass extra argument to get_bindings. - * tree.c (really_overloaded_fn): Use is_overloaded_fn to simplify - implementation. - * typeck.c (build_component_ref): Check for invalid arguments. - -Tue Jan 27 01:44:02 1998 Jason Merrill <jason@yorick.cygnus.com> - - * expr.c (cplus_expand_expr, AGGR_INIT_EXPR): Don't check that - return_target and call_target are equivalent. - - * pt.c (type_unification_real): Just accept function parms that - don't use any template parms. - -Sun Jan 25 03:30:00 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (cp_finish_decl): When bailing on a comdat variable, also - unset DECL_NOT_REALLY_EXTERN. - - * parse.y (typename_sub*): Fix std::. - -Sat Jan 24 12:13:54 1998 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (dump_decl): Fix type default template args. - (dump_type): Hand TEMPLATE_DECL off to dump_decl. - -Fri Jan 23 18:34:37 1998 Mumit Khan <khan@xraylith.wisc.edu> - - * lex.c (DIR_SEPARATOR): Define to be '/' if not already defined. - (file_name_nondirectory): Use. - -Wed Jan 21 10:29:57 1998 Kriang Lerdsuwanakij <lerdsuwa@scf.usc.edu> - - * pt.c (coerce_template_parms): Don't access elements of ARGLIST - that are not really present. Substitute default arguments in - template template arguments. Correctly convert TEMPLATE_DECL to - TEMPLATE_TEMPLATE_PARM. - (comp_template_args): TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM - are no longer treated specially here. - * parse.y (template_template_parm): Fix copy error. - * decl.c (grokdeclarator): Warn about missing `typename' for nested - type created from template template parameters. - * parse.y (bad_parm): Likewise - - * class.c (finish_struct): Handle TEMPLATE_TEMPLATE_PARM. - (push_nested_class): Likewise. - * cp-tree.def (TEMPLATE_TEMPLATE_PARM): New tree code. - * cp-tree.h (DECL_TEMPLATE_TEMPLATE_PARM_P): New macro. - (copy_template_template_parm): Declare. - * decl.c (arg_looking_for_template): New variable. - (lookup_name_real): Handle TEMPLATE_TEMPLATE_PARM. - Try to return TEMPLATE_DECL or TEMPLATE_TEMPLATE_PARM - node if arg_looking_for_template is nonzero. - (pushdecl): Handle TEMPLATE_TEMPLATE_PARM. - (grok_op_properties, xref_tag, xref_basetypes): Likewise. - (grokdeclarator): Handle TEMPLATE_DECL. - * decl2.c (constructor_name_full): Handle TEMPLATE_TEMPLATE_PARM. - * error.c (dump_type): Add TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM. - (dump_type_prefix, dump_type_suffix) Handle TEMPLATE_TEMPLATE_PARM. - (dump_decl): Handle unnamed template type parameters. - Handle template template parameters. - (dump_function_name): Handle template template parameters. - * init.c (is_aggr_typedef, is_aggr_type, get_aggr_from_typedef): - Handle TEMPLATE_TEMPLATE_PARM. - * method.c (build_template_template_parm_names): New function. - (build_template_parm_names): Handle TEMPLATE_DECL. - (build_overload_nested_name, build_overload_name): - Handle TEMPLATE_TEMPLATE_PARM. - * parse.y (maybe_identifier): New nonterminal. - (template_type_parm): Use it. - (template_template_parm, template_arg1): New nonterminal. - (template_parm): Add template_template_parm rules. - (template_arg): Set processing_template_arg. - (template_arg1): Rules moved from template_arg. - (primary, nonnested_type): Set arg_looking_for_template if we are - processing template arguments. - * pt.c (begin_member_template_processing): Handle TEMPLATE_DECL. - (process_template_parm): Handle template template parameters. - (coerce_template_parms, comp_template_args): Likewise. - (mangle_class_name_for_template, lookup_template_class): Likewise. - (uses_template_parms): Handle TEMPLATE_DECL and - TEMPLATE_TEMPLATE_PARM. - (current_template_args): Handle TEMPLATE_DECL. - (tsubst, tsubst_copy, unify): Handle TEMPLATE_TEMPLATE_PARM. - * search.c (dfs_walk, dfs_record_inheritance): - Handle TEMPLATE_TEMPLATE_PARM. - * tree.c (copy_template_template_parm): New function. - (mapcar): Handle TEMPLATE_TEMPLATE_PARM. - * typeck.c (comptypes): Handle TEMPLATE_TEMPLATE_PARM. - -Mon Jan 19 22:40:03 1998 Mark Mitchell <mmitchell@usa.net> - - * decl.c (start_decl): Don't allow duplicate definitions of static - data members. - - * call.c (build_user_type_conversion_1): Handle user-defined - template conversion operators correctly. - - * decl2.c (build_expr_from_tree): Issue an error message if the - object in a COMPONENT_REF is a TEMPLATE_DECL. - - * typeck.c (incomplete_type_error): Handle TEMPLATE_TYPE_PARMs. - - * class.c (is_local_class): New function. - * cp-tree.h (is_local_class): Declare it. - (last_tree): Likewise. - (begin_tree): Likewise. - (end_tree): Likewise. - (lookup_template_class): Change prototype. - * decl.c (cp_finish_decl): Check for NULL where necesary. - Consider FUNCTION_DECLS to declare objects with top-level binding, - when calling make_decl_rtl. - (grokdeclarator): Give members of local classes internal linkage. - (start_function): Remove declaration of last_tree. - (finish_function): Set flag_keep_inline_functions around call to - rest_of_compilation if we are processing a member function in a - local class. - (start_method): Call push_template_decl for member functions of - local classes in template functions. - * decl2.c (import_export_decl): Don't give external linkage to - instantiations of templates with internal linkage. - * parse.y (last_tree): Remove declaration. - (template_type): Pass extra parameter to lookup_template_class. - (self_template_type): Likewise. - (structsp): Move call to reset_specialization into left_curly. - (left_curly): Call reset_specialization, and begin_tree. - * pt.c (saved_trees): New variable. - (mangle_class_name_for_template): Change prototype. Use - additional function context to name local classes in templates - correctly. - (classtype_mangled_name): Pass the context. - (push_template_decl): Handle local classes and templates, and - member functions for such classes. - (convert_nontype_parameter): Fix handling of pointer-to-member - constants. - (lookup_template_class): Handle local classes in templates. - (tsubst): Likewise. Don't assume that template instantiations - have external linkage; pay attention to the template declaration. - (mark_decl_instantiated): Likewise. - (begin_tree): New function. - (end_tree): Likewise. - - * decl.c (xref_basetypes): Don't call complete_type for basetypes - that involve template parameters; that can lead to infinite - recursion unnecessarily. - - * pt.c (register_specialization): Do not register specializations - that aren't ready to be registered yet. - (check_explicit_specialization): Handle explicit specialization of - constructors and destructors. - (build_template_decl): New function. - (push_template_delc): Handle out-of-class specializations of - member templates. - - * pt.c (check_explicit_specialization): Set up the template - information before registering the specialization. - (coerce_template_parms): Fix thinko. - (tsubst): Handle specializations of member templates correctly. - - * class.c (finish_struct_methods): Remove calls to - check_explicit_specialization from here. - (finish_struct): And insert them here. - * cp-tree.h (perform_qualification_conversions): New function. - (perform_array_to_pointer_conversion): Likewise. - (begin_explicit_instantiation): Likewise. - (end_explicit_instantiation): Likewise. - (determine_specialization): Renamed from - determine_explicit_specialization. - (comp_template_parms): New function. - (processing_explicit_instantiation): New variable. - * cvt.c (perform_qualification_conversions): New function. - (perform_array_to_pointer_conversion): Likewise. - * decl.c (duplicate_decls): Don't consider template functions - alike unless they have the same parameters. Refine handling of - instantiation/specialization mismatches. - (start_decl): Don't call pushdecl for template specializations, - since they don't affect overloading. - (start_function): Likewise - (grokfndecl): Call check_explicit_specialization a little later. - Don't call duplicate_decls for memberm template specializations. - (grokdeclarator): Don't update template_count for classes that are - themselves specializations. Remove use of `2' as parameter to - grokfndecl since that value isn't used. - * lex.c (cons_up_default_function): Save and restore - processing_explicit_instantiation around calls to grokfield. - * parse.y (finish_member_template_decl): New function. - (component_decl_1): Use it. - (fn.def2): Likewise. - (template_arg_list_opt): New nonterminal. - (template_type): Use it. - (self_template_type): Likewise. - (template_id): Likewise. - (object_template_id): Likewise. - (notype_template_declarator): Likwise. - (begin_explicit_instantiation): Likewise. - (end_explicit_instantiation): Likewise. - (explicit_instantiation): Use them. - * pt.c (coerce_template_parms): Add parameters. - (processing_explicit_instantiation): New variable. - (convert_nontype_parameter): New function. - (determine_overloaded_function): Likewise. - (begin_explicit_instantiation): Likewise. - (end_explicit_instantiation): Likewise. - (retrieve_specialization): Likewise. - (register_specialization): Likewise. - (processing_explicit_specialization): Removed. - (determine_specialization): Handle specializations of member - functions of template class instantiations. - (check_explicit_specialization): Refine to conform to standard. - (comp_template_parms): New function. - (coerce_template_parms): Call convert_nontype_parameter. - (tsubst): Refine handling of member templates. Use - register_specialization. - (instantiate_template): Use retrieve_specialization. - (do_decl_instantiation): Likewise. - (instantiate_decl): Likewise. - (type_unification): Improve handling of explict template - arguments. - * tree.c (mapcar): Return error_mark_node, rather than aborting, - on VAR_DECLS, FUNCTION_DECLS, and CONST_DECLS. - * typeck.c (build_unary_op): Call determine_specialization, rather - than determine_explicit_specialization. - -Mon Jan 19 13:18:51 1998 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_up_reference): A TARGET_EXPR has side effects. - -Fri Jan 16 11:40:50 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * error.c (dump_decl): For enum tags, output the tag, not its value. - -1998-01-13 Brendan Kehoe <brendan@cygnus.com> - - * decl.c (init_decl_processing): Only call init_rtti_processing - FLAG_RTTI is set. - -Mon Jan 12 01:35:18 1998 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new_1): Split out from build_new. - (build_new): Just return a NEW_EXPR. - * expr.c (cplus_expand_expr): Handle NEW_EXPR. - - * decl2.c (get_temp_regvar): Tweak. - - * cp-tree.h (TREE_CALLS_NEW): Comment out. - * class.c (resolves_to_fixed_type_p): Remove use. - * method.c (build_opfncall): Likewise. - * call.c (build_new_op): Likewise. - -Wed Jan 7 23:47:13 1998 Jason Merrill <jason@yorick.cygnus.com> - - * exception.cc (__eh_alloc, __eh_free): New fns. - (__cp_push_exception, __cp_pop_exception): Use them. - (__uncatch_exception): Call terminate here if no exception. - * except.c (build_terminate_handler): New fn. - (expand_start_catch_block): Use it. - (expand_exception_blocks): Likewise. - (alloc_eh_object): New fn. - (expand_throw): Use it. Protect exception init with terminate. - * typeck.c (build_modify_expr): Remove code that ignores trivial - methods. - -Mon Dec 22 11:36:27 1997 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * call.c (add_builtin_candidate): Add default case in enumeration - switch. - (build_new_op): Likewise. - (convert_like): Likewise. - * cvt.c (build_expr_type_conversion): Likewise. - * tree.c (real_lvalue_p): Likewise. - (lvalue_p): Likewise. - (cp_tree_equal): Likewise. - * typeck.c (comptypes): Likewise. - (build_component_ref): Likewise. - (build_function_call_real): Likewise. - (build_binary_op_nodefault): Likewise. - (build_unary_op): Likewise. - (build_modify_expr): Likewise. - * typeck2.c (initializer_constant_valid_p): Likewise. - -Sun Dec 21 15:59:00 1997 Nick Clifton <nickc@cygnus.com> - - * decl2.c (lang_decode_option): Add support for -Wunknown-pragmas. - -Thu Dec 18 14:51:50 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (coerce_template_parms): Make sure to digest_init if - possible. - - * decl.c (duplicate_decls): Make the newdecl virtual if the - olddecl was, just as is done with other attributes of olddecl. - -Thu Dec 18 14:43:19 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (unary_complex_lvalue): Ignore op0 when taking the - address of an OFFSET_REF. - - * cp-tree.def: Add AGGR_INIT_EXPR. - * error.c, tree.c, typeck.c: Replace uses of NEW_EXPR with - AGGR_INIT_EXPR where appropriate. - * expr.c (cplus_expand_expr): Likewise. Simplify. - - * decl2.c (finish_file): Remove call to register_exception_table. - -Wed Dec 17 17:08:52 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * pt.c (instantiate_class_template): Don't do injection when - processing_template_decl is true, as pollutes current_binding_level - for base classes. - -Wed Dec 17 21:17:39 1997 Peter Schmid <schmid@ltoi.iap.physik.tu-darmstadt.de> - - * pt.c (maybe_fold_nontype_arg): Add prototype. - -Tue Dec 16 10:31:20 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (mapcar): Handle TRY_CATCH_EXPR et al. - * error.c (dump_expr): Likewise. - -Mon Dec 15 12:22:04 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_function_call_real): Remove "inline called before - definition" pedwarn. - - * pt.c (coerce_template_parms): Use maybe_fold_nontype_arg. - -Sun Dec 14 22:34:20 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Fix base conversion of pm's. - - * pt.c (type_unification_real): Change __null to type void* with - a warning. - -Sun Dec 14 20:38:35 1997 Mark Mitchell <mmitchell@usa.net> - - * call.c (implicit_conversion): Don't call - build_user_type_conversion_1 with a NULL expr, since it will - crash. - - * pt.c (unify): Don't try to unify array bounds if either array is - unbounded. - -Fri Dec 12 16:09:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * errfn.c (cp_pedwarn, cp_pedwarn_at, cp_error_at, cp_warning_at): - Replace extern decls with casts. - - * decl.c (expand_start_early_try_stmts): Don't mess with a sequence. - Update last_parm_cleanup_insn. - (store_after_parms): Remove. - * cp-tree.h: Adjust. - -Thu Dec 11 22:18:37 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (comdat_linkage): Also set DECL_COMDAT. - (finish_file): Check DECL_COMDAT instead of weak|one_only. - (import_export_vtable): Use make_decl_one_only instead of - comdat_linkage for win32 tweak. - (import_export_decl): Likewise. - * pt.c (mark_decl_instantiated): Likewise. - - * decl2.c (finish_file): Lose handling of templates in pending_statics. - -Thu Dec 11 21:12:09 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Lose call to expand_builtin_throw. - * except.c (expand_builtin_throw): Remove. - * cp-tree.h: Remove ptr_ptr_type_node. - * decl.c: Likewise. - -Thu Dec 11 20:43:33 1997 Teemu Torma <tot@trema.com> - - * decl.c (ptr_ptr_type_node): Define. - (init_decl_processing): Initialize it. - * cp-tree.h: Declare it. - * exception.cc (__cp_exception_info): Use __get_eh_info. - (__cp_push_exception): Ditto. - (__cp_pop_exception): Ditto. - - From Scott Snyder <snyder@d0sgif.fnal.gov>: - * except.c (expand_builtin_throw): Use get_saved_pc_ref instead of - saved_pc. - (init_exception_processing): Removed saved_pc initialization. - -Wed Dec 10 11:04:45 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Defer all templates but inline functions. - -Mon Dec 8 23:17:13 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_vec_init): Don't fold a list of parameters. - - * decl.c (copy_args_p): Handle copy elision for types with virtual - bases. - * call.c (build_over_call): Likewise. - -Sun Dec 7 22:38:12 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (lookup_template_function): Copy the template arguments, - not just the list containing them, to the permanent obstack. - -Sun Dec 7 15:53:06 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_start_catch_block): suspend_momentary for the - terminate handler. - - * error.c (dump_decl): Handle LOOKUP_EXPR. - -Sun Dec 7 15:45:07 1997 Mark Mitchell <mmitchell@usa.net> - - * rtti.c (build_dynamic_cast): Copy the cast-to type to the - permanent obstack if we are processing a template decl. - * typeck.c (build_static_cast): Likewise. - (build_const_cast): Likewise. - (build_reinterpret_cast): Likewise. - - * pt.c (coerce_template_parms): Coerce some expressions, even - when processing_template_decl. - -Sun Dec 7 01:46:33 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * typeck.c (build_binary_op_nodefault, pointer_diff): Symmetric - handling of pointer difference expressions. - - * typeck.c (comp_target_types): Comparison of function/method types - is independent of nptrs. - -Sun Dec 7 01:40:27 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (tsubst): Avoid creating pointer to reference and - reference to reference types. - -Sat Dec 6 01:29:37 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (do_id): New nonterminal. - (template_id): Use it. - -Fri Dec 5 01:17:34 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (template_id): do_identifier for PFUNCNAMEs, too. - * spew.c (yylex): Don't do_identifier here. - * decl2.c (build_expr_from_tree): Revert last change. - - * decl2.c (build_expr_from_tree): Expand the name for a method call. - * parse.y (object_template_id): Don't try to take the DECL_NAME. - -Wed Dec 3 20:02:39 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Use a TARGET_EXPR instead of SAVE_EXPR for - alloc_expr. - * call.c (build_op_delete_call): Adjust. - - * except.c (expand_end_catch_block): Lose rethrow region. - (expand_start_catch_block): Likewise. - (expand_end_catch_block): Don't expand_leftover_cleanups. - -Wed Dec 3 13:24:04 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * pt.c (tsubst): Remove tree_cons call (places redundant info into - DECL_TEMPLATE_INSTANTIATION). - -Wed Dec 3 11:44:52 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (is_overloaded_fn): Handle getting a fn template. - (really_overloaded_fn): Likewise. - * error.c (dump_decl): Handle TEMPLATE_ID_EXPRs better. - * pt.c (check_explicit_specialization): Tweak. - (determine_explicit_specialization): Tweak. - - * tree.c, cp-tree.h (get_target_expr): New fn. - -Wed Dec 3 08:47:27 1997 Paul Eggert <eggert@twinsun.com> - - * pt.c (check_explicit_specialization): Fix misspelling in - diagnostic: `preceeded'. - * typeck.c (get_delta_difference): Fix misspelling in diagnostic: - `conversiona'. - -1997-12-02 Mark Mitchell <mmitchell@usa.net> - - * pt.c (determine_explicit_specialization): Avoid an internal - error for bad specializations. - - * method.c (build_overload_value): Handle SCOPE_REF. - -Tue Dec 2 19:18:50 1997 Mike Stump <mrs@wrs.com> - - * class.c (prepare_fresh_vtable): Enable even more complex MI - vtable names. - -Tue Dec 2 01:37:19 1997 Jason Merrill <jason@yorick.cygnus.com> - - * exception.cc (__check_eh_spec): Optimize a bit. - - * exception.cc (__cp_pop_exception): Lose handler arg. - * except.c (do_pop_exception): Likewise. - (push_eh_cleanup): Let the cleanup mechanism supply the handler. - (expand_end_catch_block): Likewise. - -Fri Nov 28 01:58:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (check_explicit_specialization): Complain about using a - template-id for a non-specialization. - -Fri Nov 28 12:35:19 1997 Scott Christley <scottc@net-community.com> - - * repo.c: Prototype rindex only if needed. - * xref.c: Likewise. - -Fri Nov 28 01:56:35 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * error.c (dump_decl): Handle TEMPLATE_ID_EXPR. - -Thu Nov 27 00:59:46 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_const_cast): Handle references here instead of - handing off to convert_to_reference. - - * except.c: Lose Unexpected, SetTerminate, SetUnexpected, - TerminateFunctionCall. - (init_exception_processing): Likewise. Terminate et al are now - the fns, not ADDR_EXPRs. - (various): Lose redundant assemble_external calls. - (do_unwind): s/BuiltinReturnAddress/builtin_return_address_fndecl/. - - * cp-tree.h (struct lang_decl_flags): Add comdat. - (DECL_COMDAT): New macro. - * decl.c (duplicate_decls): Propagate it. - (cp_finish_decl): Handle it. - * decl2.c (import_export_decl): Just set DECL_COMDAT on VAR_DECLs. - - * class.c: Remove static pending_hard_virtuals. - (add_virtual_function): Take pointers to pending_virtuals - and pending_hard_virtuals. - (finish_struct_1): Pass them. Declare pending_hard_virtuals. - -Wed Nov 26 20:28:49 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_vtable): If we support one_only but not - weak symbols, mark instantiated template vtables one_only. - (import_export_decl): Likewise for tinfo functions. - (finish_vtable_vardecl): Also write out vtables from explicitly - instantiated template classes. - * pt.c (mark_class_instantiated): Revert last change. - - * except.c (expand_throw): Call mark_used on the destructor. - -Wed Nov 26 15:13:48 1997 Jeffrey A Law (law@cygnus.com) - - * lex.c (lang_init): Enable flag_exceptions by default if no - command line switch was specified. - -1997-11-26 Mark Mitchell <mmitchell@usa.net> - - * pt.c (unify): Handle `void' template parameters in - specializations. - -Wed Nov 26 01:11:24 1997 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (build_dynamic_cast): Handle template case here. - (build_dynamic_cast_1): Not here. - - * typeck2.c (digest_init): Make copies where appropriate. - - * decl2.c (delete_sanity): resolve_offset_ref. - - * except.c: Call terminate without caching so many bits. - - * except.c (expand_start_catch_block): Fix catching a reference - to pointer. - -Tue Nov 25 11:28:21 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Copy size to the saveable obstack. - - * init.c (build_new): Stick a CLEANUP_POINT_EXPR inside the - TRY_CATCH_EXPR for now. - -Mon Nov 24 12:15:55 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (mark_addressable): Don't assume a FUNCTION_DECL - has DECL_LANG_SPECIFIC. - - * exception.cc (struct cp_eh_info): Add handlers field. - (__cp_push_exception): Initialize it. - (__cp_pop_exception): Decrement it. Don't pop unless it's 0. - (__throw_bad_exception): Remove. - * except.c (call_eh_info): Add handlers field. - (get_eh_handlers): New fn. - (push_eh_cleanup): Increment handlers. - -Fri Nov 21 12:22:07 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_start_eh_spec): Use the try/catch code. - (expand_end_eh_spec): Likewise. Call __check_eh_spec instead of - doing everything inline. - (init_exception_processing): throw_type_match now takes - const void pointers. - * exception.cc (__check_eh_spec): New fn. - * inc/exception: Neither terminate nor unexpected return. - * decl.c: Make const_ptr_type_node public. - * tinfo2.cc (__throw_type_match_rtti): Take the typeinfos constly. - - * except.c (expand_start_catch_block): We only need the rethrow - region for non-sjlj exceptions. - (expand_end_catch_block): Likewise. Use outer_context_label_stack. - -Thu Nov 20 14:40:17 1997 Jason Merrill <jason@yorick.cygnus.com> - - * Make-lang.in (CXX_LIB2FUNCS): Add new op new and op delete objs. - (various.o): Likewise. - * inc/new: Add placement deletes. Add throw specs for default new. - * new.cc (set_new_handler): Move here from libgcc2. - * new1.cc (new (nothrow)): Catch a bad_alloc thrown from the handler. - (new): Move from libgcc2. Throw bad_alloc. - * new2.cc: Move the rest of the op news and op deletes from libgcc2. - * decl.c (init_decl_processing): Update exception specs on new and - delete. - - * method.c (build_decl_overload_real): Don't mess with global - placement delete. - - * init.c (build_new): Check for null throw spec, not nothrow_t. - - * decl.c (duplicate_decls): Don't complain about different exceptions - from an internal declaration. - - * call.c (build_op_delete_call): Fix check for member fns again. - - * decl2.c (import_export_decl): Interface hackery affects - virtual synthesized methods. - -Wed Nov 19 18:24:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): Don't just complain about a mismatched - scope, fix it. - - * decl.c (make_implicit_typename): Handle case where t is not - actually from context. - * tree.c (get_type_decl): Lose identifier case. - * spew.c (yylex): Lose useless call to identifer_typedecl_value. - * parse.y (nonnested_type): Just use lookup_name. - (complex_type_name): Just use IDENTIFIER_GLOBAL_VALUE. - -Wed Nov 19 11:45:07 1997 Michael Tiemann <tiemann@axon.cygnus.com> - - * error.c (dump_function_name): Test DECL_LANG_SPECIFIC in case - T was built in C language context (for example, by - output_func_start_profiler). - -Wed Nov 19 10:39:27 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (make_implicit_typename): New fn. - (lookup_name_real): Use it. Use current_class_type as the context. - -Mon Nov 17 23:42:03 1997 Bruno Haible <haible@ilog.fr> - - * pt.c (do_poplevel): Don't prohibit jumps into this contour. - -Mon Nov 17 02:01:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * friend.c (do_friend): Warn about non-template friends in templates. - - * call.c (build_op_delete_call): Fix handling of inherited delete. - - * search.c (dfs_record_inheritance): Ignore template type parms. - -Sat Nov 15 00:30:51 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_op): Fix copy error. - (build_op_new_call): New fn. - (build_op_delete_call): New fn. - * cp-tree.h: Declare them. - * init.c (build_new): Use them. Support placement delete. - (build_x_delete): Use build_op_delete_call. - (build_delete): Likewise. - * decl2.c (delete_sanity): Likewise. - (coerce_delete_type): Don't complain about placement delete. - -Thu Nov 13 01:52:36 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_function_call): Remove unused 'obj' parm. - * cp-tree.h, typeck.c: Adjust. - - * init.c (build_new): Make the cleanup last longer. - (expand_vec_init): Call do_pending_stack_adjust. - -Wed Nov 12 11:04:33 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (do_type_instantiation): Fix typo. - (mark_class_instantiated): If we support one_only but not weak - symbols, don't mark this as known. - - * init.c (build_new): Handle vec delete in EH cleanup. - -Wed Nov 12 08:11:55 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * call.c (build_method_call): Call complete_type before checking - for destructor. - -Sun Nov 9 01:29:55 1997 Jim Wilson (wilson@cygnus.com) - - * decl.c (add_block_current_level): Delete. - * init.c (build_vec_delete_1): Delete build_block and - add_block_current_level calls. - -Wed Nov 12 00:48:16 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Handle freeing allocated memory when the - constructor throws. - - * call.c (build_new_method_call): Fix flags arg. - - * pt.c (do_type_instantiation): Don't try to instantiate - member templates. - (mark_decl_instantiated): If we support one_only but not - weak symbols, mark this one_only. - * decl2.c (import_export_vtable): Don't defer handling of vtables - if MULTIPLE_SYMBOL_SPACES. - -Tue Nov 11 12:02:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_end_catch_block): Lose call to __sjpopnthrow. - -Tue Nov 11 02:53:44 1997 Jason Merrill <jason@lasher.cygnus.com> - - * except.c (do_pop_exception): Return a value. - -Mon Nov 10 20:25:31 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_method_call): Handle getting a - TEMPLATE_ID_EXPR around a TEMPLATE_DECL. Don't look for a field - if we got template parms. - * typeck.c (build_x_function_call): Remember the TEMPLATE_ID_EXPR, - not just the args. - * decl2.c (build_expr_from_tree): Tweak last change. - * pt.c (tsubst_copy): Use get_first_fn instead of TREE_VALUE. - (maybe_fold_nontype_arg): Split out from tsubst_copy. - * tree.c (get_first_fn): Just return a TEMPLATE_ID_EXPR. - -Mon Nov 10 20:08:38 1997 Kriang Lerdsuwanakij <lerdsuwa@scf-fs.usc.edu> - - * pt.c (tsubst_copy): Handle explicit template arguments in - function calls. - * typeck.c (build_x_function_call): Likewise. - * decl2.c (build_expr_from_tree): Lookup function name if it - hasn't been done. - - * pt.c (tsubst): Instantiate template functions properly when - template parameter does not appear in function arguments and return - type. - (comp_template_args): Handle member templates required by tsubst. - -Mon Nov 10 20:08:38 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Tweak conditions for pedwarn in - previous change. - -Mon Nov 10 20:08:29 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * pt.c (coerce_template_parms): Tweak error message. - - * decl.c (grokdeclarator): If -Wreturn-type, warn everytime a - return type defaults to `int', even if there are storage-class - specifiers. - -Mon Nov 10 03:04:20 1997 Jason Merrill <jason@yorick.cygnus.com> - - Complete nested exception support. - * except.c (do_pop_exception): Split out... - (push_eh_cleanup): From here. Handle the EH region by hand. - (expand_start_catch_block): Add a new level for the catch parm. - Move the rethrow region outside the two cleanup regions. - Protect the initializer for the catch parm with terminate. - (expand_end_catch_block): Likewise. End the region for the eh_cleanup. - * exception.cc (__cp_pop_exception): Now takes two parms. Handle - popping off the middle of the stack. - * tree.c (lvalue_p, real_lvalue_p): Handle TRY_CATCH_EXPR, - WITH_CLEANUP_EXPR, and UNSAVE_EXPR. - (build_cplus_new): Only wrap CALL_EXPRs. - * init.c (expand_default_init): Handle a TRY_CATCH_EXPR around - the constructor call. - -Sun Nov 9 18:00:26 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * Make-lang.in (c++.distdir): Make inc subdirectory. - -Fri Nov 7 11:57:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Put back some code. - -Thu Nov 6 11:28:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Remove redundant code. - * method.c (emit_thunk): Don't let the backend defer generic thunks. - -Wed Nov 5 23:52:50 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (call_eh_info): Split out... - (push_eh_info): From here. - (expand_builtin_throw): Use it. - (expand_start_catch_block): Move region start back. - -Tue Nov 4 13:45:10 1997 Doug Evans <devans@canuck.cygnus.com> - - * lex.c (MULTIBYTE_CHARS): #undef if cross compiling. - (real_yylex): Record wide strings using target endianness, not host. - -1997-11-03 Brendan Kehoe <brendan@lisa.cygnus.com> - - * repo.c (rindex): Add decl unconditionally. - (get_base_filename, open_repo_file): Don't cast rindex. - * xref.c (rindex): Add decl unconditionally. - (index): Remove unused decl. - (open_xref_file): Don't cast rindex. - -Sun Nov 2 15:04:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (build_vbase_path): Propagate the result type properly. - -1997-11-01 Brendan Kehoe <brendan@lisa.cygnus.com> - - * except.c (expand_builtin_throw) [!DWARF2_UNWIND_INFO]: Replace - remaining use of saved_throw_type with a call to get_eh_type. - -1997-10-31 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (FILE_NAME_NONDIRECTORY): Delete macro. - (file_name_nondirectory): New function, doing the same as the macro. - (set_typedecl_interface_info): Use it instead of the macro. - (check_newline): Likewise. - (handle_cp_pragma): Likewise. - - * repo.c (get_base_filename): Cast result of rindex to char*. - (open_repo_file): Likewise. - * xref.c (open_xref_file): Likewise. - * error.c (dump_char): Make its arg int, not char. - - * except.c (push_eh_info): Pass the number of fields - 1 down, not - the exact number of fields. - -Fri Oct 31 01:47:57 1997 Jason Merrill <jason@yorick.cygnus.com> - - Support for nested exceptions. - * tinfo2.cc (__is_pointer): New fn. - * exception.cc (struct cp_eh_info): Define. - (__cp_exception_info, __uncatch_exception): New fns. - (__cp_push_exception, __cp_pop_exception): New fns. - * except.c: Lose saved_throw_{type,value,cleanup,in_catch}. - Lose empty_fndecl. - (init_exception_processing): Likewise. __eh_pc is now external. - (push_eh_info): New fn. - (get_eh_{info,value,type,caught}): New fns. - (push_eh_cleanup): Just call __cp_pop_exception. - (expand_start_catch_block): Use push_eh_info. Start the eh region - sooner. - (expand_end_eh_spec): Use push_eh_info. - (expand_throw): Call __cp_push_exception to set up the exception info. - Just pass the destructor or 0 as the cleanup. Call __uncatch_exception - when we rethrow. - (expand_builtin_throw): Don't refer to empty_fndecl. - -Thu Oct 23 02:01:30 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): SET_DECL_IMPLICIT_INSTANTIATION on new decl. - -1997-10-22 Brendan Kehoe <brendan@cygnus.com> - - * method.c (build_template_parm_names, build_decl_overload_real): - Add static to definitions. - * pt.c (add_to_template_args, note_template_header, - processing_explicit_specialization, type_unification_real): Likewise. - ({determine,check}_explicit_specialization): Use a single string for - error messages. - -Mon Oct 20 12:06:34 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_exception_blocks): Call do_pending_stack_adust. - (expand_end_catch_block): Likewise. - (expand_end_eh_spec): Likewise. - -Mon Oct 20 11:44:20 1997 Mark Mitchell <mmitchell@usa.net> - - * decl.c (duplicate_decls): Handle template specializations - correctly. - * error.c (dump_function_name): Fix printing of specializations of - member functions that are not member templates. - * cp-tree.h (processing_specialization): Make global. - * pt.c (processing_specialization): Likewise. - * lex.c (cons_up_default_function): Save and restore - processing_specialization to avoid confusion. - -Mon Oct 20 10:52:22 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (init_decl_processing): Give null_node unknown* type. - * typeck.c (comp_target_types): Handle UNKNOWN_TYPE. - (common_type): Likewise. - * error.c (args_as_string): Recognize null_node. - -Sun Oct 19 09:13:01 1997 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * typeck.c (rationalize_conditional_expr): Handle {MIN,MAX}_EXPR. - (unary_complex_lvalue): Call it for {MIN,MAX}_EXPR. - - * decl.c (init_decl_processing): Call using_eh_for_cleanups. - - * Make-lang.in (g++): Include prefix.o. - -Thu Oct 16 15:31:09 1997 Judy Goldberg <judygold@sanwafp.com> - - * pt.c (determine_explicit_specialization): Initialize "dummy" - to keep Purify quiet. - -Thu Oct 16 00:14:48 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (build_overload_value): Handle TEMPLATE_CONST_PARMs here. - (build_overload_int): Not here. - -Wed Oct 15 00:35:28 1997 Mike Stump <mrs@wrs.com> - - * class.c (build_type_pathname): Remove. - (prepare_fresh_vtable): Fix problem with complex MI vtable names. - -1997-10-14 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (unary_expr): Give a pedwarn if someone tries to use the - &&label GNU extension. - -Tue Oct 14 12:01:00 1997 Mark Mitchell <mmitchell@usa.net> - - * decl.c (pushtag): Unset DECL_ASSEMBLER_NAME before setting it, - so as to avoid incorrect manglings. - * method.c (build_decl_overload_real): Don't mangle return types - for constructors. - -Tue Oct 14 11:46:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (scratchalloc, build_scratch_list, make_scratch_vec, - scratch_tree_cons): Define as macros for now. - * call.c, class.c, cvt.c, decl.c, decl2.c, except.c, expr.c, init.c, - lex.c, method.c, parse.y, pt.c, rtti.c, search.c, tree.c, typeck.c, - typeck2.c: Use them and the expression_obstack variants. - -Mon Oct 13 17:41:26 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (store_return_init): Allow classes with explicit ctors to - be used with the named return values extension. - -Fri Oct 10 12:21:11 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Fix previous change. - -Thu Oct 9 12:08:21 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Fix thinko. - (instantiate_decl): Really use the original template. - - * call.c (build_new_method_call): Use simple constructor_name for - error messages. - -Wed Oct 8 22:44:42 1997 Jeffrey A Law (law@cygnus.com) - - * method.c (build_underscore_int): Don't use ANSI specific - features. - -Wed Oct 8 00:18:22 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_prevtable_vardecl): Check DECL_REALLY_EXTERN - for our key method; it might have been inlined by -O3. - -Tue Oct 7 23:00:12 1997 Mark Mitchell <mmitchell@usa.net> - - * decl.c (make_typename_type): Do not try to call lookup_field for - non-aggregate types. - -Tue Oct 7 22:52:10 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_reinterpret_cast): Tweak. - -Tue Oct 7 22:45:31 1997 Alexandre Oliva <oliva@dcc.unicamp.br> - - * typeck.c (build_reinterpret_cast): converting a void pointer - to function pointer with a reinterpret_cast produces a warning - if -pedantic is issued - -Tue Oct 7 22:43:43 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * typeck.c (c_expand_return): Don't warn about returning a - reference-type variable as a reference. - -Tue Oct 7 21:11:22 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (build_static_name): Fix typo. - -1997-10-07 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (duplicate_decls): Make sure DECL_LANG_SPECIFIC is set on - OLDDECL before we try to do DECL_USE_TEMPLATE. - -Tue Oct 7 00:48:36 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (duplicate_decls): Don't warn about template instances. - - * typeck.c (mark_addressable): Lose ancient code that unsets - DECL_EXTERNAL. - - * pt.c (do_decl_instantiation): Lose support for instantiating - non-templates. - - * call.c (build_new_function_call): Fix handling of null explicit - template args. - (build_new_method_call): Likewise. - -Mon Oct 6 23:44:34 1997 Mark Mitchell <mmitchell@usa.net> - - * method.c (build_underscore_int): Fix typo. - -1997-10-06 Brendan Kehoe <brendan@lisa.cygnus.com> - - * tree.c (print_lang_statistics): #if 0 call to - print_inline_obstack_statistics until its definition is checked in. - -Mon Oct 6 09:27:29 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Move dump_tree_statistics to end. - - * pt.c (instantiate_decl): Look for the original template. - (tsubst): Set DECL_IMPLICIT_INSTANTIATION on partial instantiations - of member templates. - -Wed Oct 1 08:41:38 1997 Jason Merrill <jason@yorick.cygnus.com> - - * Makefile.in (g++FAQ.*): New rules. - (CONFLICTS): Update. - * g++FAQ.texi: Moved from libg++. - - * parse.y (PFUNCNAME): Only specify the type once. - -1997-10-01 Brendan Kehoe <brendan@lasher.cygnus.com> - - * lex.c (real_yylex): Clean up the code to fully behave the way - the c-lex.c parser does for complex and real numbers. - -Tue Sep 30 08:51:36 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (build_decl_overload_real): Reformat. - -Tue Sep 30 00:18:26 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (synthesize_method): If at_eof, determine our linkage. - -1997-09-29 Paul Eggert <eggert@twinsun.com> - - * lex.c (real_yylex): Treat `$' just like `_', except issue a - diagnostic if !dollars_in_ident or if pedantic. - - * lang-specs.h (@c++): -ansi no longer implies -$. - - * decl2.c (lang_decode_option): - -traditional and -ansi now do not mess with - dollars_in_ident. - -Mon Sep 29 19:57:51 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * Makefile.in (parse.o, decl.o): Also depend on - $(srcdir)/../except.h $(srcdir)/../output.h. - (decl2.o): Also depend on $(srcdir)/../expr.h ../insn-codes.h - $(srcdir)/../except.h $(srcdir)/../output.h. - (typeck.o, init.o): Also depend on $(srcdir)/../expr.h - ../insn-codes.h. - - * call.c, cp-tree.h, decl.c, tree.c: Finish prototyping. - - * expr.c (cplus_expand_expr): Make it static. - - * decl2.c, init.c, typeck.c: Include "expr.h". - (expand_expr): Use proper values when calling the function. - -Mon Sep 29 11:05:54 1997 Alexandre Oliva <oliva@dcc.unicamp.br> - - * lang-options.h: new -Wold-style-cast flag. - * cp-tree.h (warn_old_style_cast): new variable. - * decl2.c (warn_old_style_cast): ditto. - (lang_decode_option): support -Wold-style-cast. - (reparse_absdcl_as_casts): produce old-style-cast warning. - -Mon Sep 29 09:20:53 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * decl.c (cp_finish_decl): Allow expand_aggr_init to set - TREE_USED, reset value based on already_used. - - * init.c (expand_member_init): Revert change. - -Mon Sep 29 08:57:53 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h, decl.c, decl2.c, pt.c: - Lose DECL_C_STATIC and DECL_PUBLIC. Don't pretend statics are public. - - * decl2.c (lang_decode_option): Add missing ;. - -Sat Sep 27 16:22:48 1997 Jason Merrill <jason@yorick.cygnus.com> - - * friend.c (do_friend): Disable injection for all template-derived - decls. - * decl2.c (lang_decode_option): Handle -fguiding-decls. - * parse.y (notype_template_declarator): New nonterminal. - (direct_notype_declarator): Use it. - (complex_direct_notype_declarator): Likewise. - (object_template_id): Accept any kind of identifier after TEMPLATE. - (notype_qualified_id): Don't add template declarators here. - -Sat Sep 27 16:21:58 1997 Mark Mitchell <mmitchell@usa.net> - - * call.c (add_template_candidate): Add explicit_targs parameter. - (build_scoped_method_call): Use it. - (build_overload_call_real): Likewise. - (build_user_type_conversion_1): Likewise. - (build_new_function_call): Likewise. - (build_object_call): Likewise. - (build_new_op): Likewise. - (build_new_method_call): Likewise. - (build_new_function_call): Handle TEMPLATE_ID_EXPR. - (build_new_method_call): Likewise. - - * class.c (finish_struct_methods): Add specialization pass to - determine which methods were specializing which other methods. - (instantiate_type): Handle TEMPLATE_ID_EXPR. - - * cp-tree.def (TEMPLATE_ID_EXPR): New tree code. - - * cp-tree.h (name_mangling_version): New variable. - (flag_guiding_decls): Likewise. - (build_template_decl_overload): New function. - (begin_specialization): Likewise. - (reset_specialization): Likewise. - (end_specialization): Likewise. - (determine_explicit_specialization): Likewise. - (check_explicit_specialization): Likewise. - (lookup_template_function): Likewise. - (fn_type_unification): Add explicit_targs parameter. - (type_unification): Likewise. - - * decl.c (duplicate_decls): Add smarts for explicit - specializations. - (grokdeclarator): Handle TEMPLATE_ID_EXPR, and function - specializations. - (grokfndecl): Call check_explicit_specialization. - - * decl2.c (lang_decode_option): Handle -fname-mangling-version. - (build_expr_from_tree): Handle TEMPLATE_ID_EXPR. - (check_classfn): Handle specializations. - - * error.c (dump_function_name): Print specialization arguments. - - * friend.c (do_friend): Don't call pushdecl for template - instantiations. - - * init.c (build_member_call): Handle TEMPLATE_ID_EXPR. - - * lang-options.h: Add -fname-mangling-version, -fguiding-decls, - and -fno-guiding-decls. - - * lex.c (identifier_type): Return PFUNCNAME for template function - names. - - * method.c (build_decl_overload_real): New function. - (build_template_parm_names): New function. - (build_overload_identifier): Use it. - (build_underscore_int): New function. - (build_overload_int): Use it. Add levels for template - parameters. - (build_overload_name): Likewise. Also, handle TYPENAME_TYPEs. - (build_overload_nested_names): Handle template type parameters. - (build_template_decl_overload): New function. - - * parse.y (YYSTYPE): New ntype member. - (nested_name_specifier): Use it. - (nested_name_specifier_1): Likewise. - (PFUNCNAME): New token. - (template_id, object_template_id): New non-terminals. - (template_parm_list): Note specializations. - (template_def): Likewise. - (structsp): Likewise. - (fn.def2): Handle member template specializations. - (component_decl_1): Likewise. - (direct_notype_declarator): Handle template-ids. - (component_decl_1): Likewise. - (direct_notype_declarator): Handle template-ids. - (primary): Handle TEMPLATE_ID_EXPR, and template-ids. - - * pt.c (processing_specializations): New variable. - (template_header_count): Likewise. - (type_unification_real): New function. - (processing_explicit_specialization): Likewise. - (note_template_header): Likewise. - (is_member_template): Handle specializations. - (end_template_decl): Call reset_specialization. - (push_template_decl): Handle member template specializations. - (tsubst): Likewise. - (tsubst_copy): Handle TEMPLATE_ID_EXPR. - (instantiate_template): Handle specializations. - (instantiate_decl): Likewise. - (fn_type_unification): Handle explicit_targs. - (type_unification): Likewise. Allow incomplete unification - without an error message, if allow_incomplete. - (get_bindings): Use new calling sequence for fn_type_unification. - - * spew.c (yylex): Handle PFUNCNAME. - - * tree.c (is_overloaded_fn): Handle TEMPLATE_ID_EXPR. - (really_overloaded_fn): Likewise. - (get_first_fn): Handle function templates. - - * typeck.c (build_x_function_call): Use really_overloaded_fn. - Handle TEMPLATE_ID_EXPR. - (build_x_unary_op): Likewise. - (build_unary_op): Likewise. - (mark_addressable): Templates whose address is taken are marked - as used. - -1997-09-25 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * decl.c (init_decl_processing): Declare __builtin_constant_p as - accepting any kind of type, not only int. - -Fri Sep 26 00:22:56 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (get_matching_virtual): Notice virtual bases when sorrying - about covariant returns. - - * parse.y (member_init): Also imply typename here. Remove ancient - extension for initializing base members. - -Thu Sep 25 11:11:13 1997 Jason Merrill <jason@yorick.cygnus.com> - - Handle multi-level typenames and implicit typename in base list. - * parse.y (typename_sub{,[0-2]}): New rules. - (structsp, rule TYPENAME_KEYWORD): Use typename_sub. - (nonnested_type): New rule. - (complete_type_name): Use it. - (base_class.1): Use typename_sub and nonnested_type. - (nested_name_specifier): Don't elide std:: here. - * decl.c (make_typename_type): Handle getting a type for NAME. - (lookup_name_real): Turn std:: into :: here. - - Rvalue conversions were removed in London. - * call.c (is_subseq): Don't consider lvalue transformations. - (build_conv): LVALUE_CONV and RVALUE_CONV get IDENTITY_RANK. - (joust): Reenable ?: kludge. - -1997-09-22 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (start_function): Up warning of no return type to be a - pedwarn. - -Mon Sep 22 14:15:34 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * init.c (expand_member_init): Don't set TREE_USED. - * decl.c (cp_finish_decl): Mark decls used if type has TREE_USED - set,don't clear TREE_USED wholesale. - -Sat Sep 20 15:31:00 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Do require_complete_type before - build_cplus_new. - -Thu Sep 18 16:47:52 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (lookup_field): Call complete_type in all cases. - - * decl.c (finish_function): Just warn about flowing off the end. - -Wed Sep 17 10:31:25 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokparms): Don't bash a permanent list node if we're - in a function. - -1997-09-17 Brendan Kehoe <brendan@lisa.cygnus.com> - - * Makefile.in (CONFLICTS): Fix s/r conflict count to 18. - -Tue Sep 16 14:06:56 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_op): Give better error for syntactically - correct, but semantically invalid, use of undeclared template. - - * call.c (compare_qual): Handle pmfs. - - * decl.c (store_parm_decls): last_parm_cleanup_insn is the insn - after the exception spec. - -Mon Sep 15 11:52:13 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (null_ptr_cst_p): Integer type, not integral type. - - * call.c (joust): Disable warnings until they can be moved to the - right place. - -Fri Sep 12 16:11:13 1997 Per Bothner <bothner@cygnus.com> - - * Makefile.in, config-lang.in: Convert to autoconf. - -Thu Sep 11 17:14:55 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): Add implicit 'typename' to types from - base classes. - - * pt.c (most_specialized_class): Fix typo. - (tsubst): Move constant folding to TREE_VEC case. - -Thu Sep 11 10:08:45 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (do_poplevel): Don't warn about unused local variables - while processing_template_decl since we don't always know whether - or not they will need constructing/destructing. - - * pt.c (uses_template_parms): Check the values of an enumeration - type to make sure they don't depend on template parms. - - * decl.c (make_typename_type): Don't lookup the field if the - context uses template parms, even if we're not - processing_template_decl at the moment. - - * pt.c (coerce_template_parms): Avoid looking at the - TYPE_LANG_DECL portion of a typename type, since there won't be - one. - (tsubst): Do constant folding as necessary to make sure that - arguments passed to lookup_template_class really are constants. - -Wed Sep 10 11:21:55 1997 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (expand_builtin_throw): #ifndef DWARF2_UNWIND_INFO. - * decl2.c (finish_file): Only register exception tables if we - need to. - - * decl.c (init_decl_processing): Add __builtin_[fs]p. - -Tue Sep 9 19:49:38 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (unify): Just return 0 for a TYPENAME_TYPE. - -Tue Sep 9 17:57:25 1997 Mark Mitchell <mmitchell@usa.net> - - * error.c (dump_decl): Avoid crashing when presented with a - uninitialized constant, as can occur with a template parameter. - (dump_expr): Make sure that there are enough levels of - current_template_parms before we start diving through them. - -1997-09-09 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (build_indirect_ref): Heed FLAG_VOLATILE similar to - c-typeck.c. - -Tue Sep 9 09:36:39 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * except.c (expand_throw): Call build_delete for all - exception types, not just objects with destructors. - -Mon Sep 8 02:33:20 1997 Jody Goldberg <jodyg@idt.net> - - * decl.c (current_local_enum): Remove static. - * pt.c (tsubst_enum): Save and restore value of current_local_enum - in case template is expanded in enum decl. - (instantiate_class_template) : Use new tsubst_enum signature. - (tsubst_expr): Likewise. - -Mon Sep 8 01:21:43 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (begin_member_template_processing): Take a function as - argument, not a set of template arguments. Use the template - parameters, rather than the arguments. Handle non-type parameters - correctly. Push a binding level for the parameters so that multiple - member templates using the same parameter names can be declared. - (end_member_template_processing): Pop the binding level. - (push_template_decl): Mark member templates as static when - appropriate. - - * lex.c (do_pending_inlines): Pass the function, not its template - arguments, to begin_member_template_processing. - (process_next_inline): Likewise. - (do_pending_defargs): Likewise. - - * error.c (dump_expr): Obtain the correct declaration for a - TEMPLATE_CONST_PARM. - - * call.c (add_template_conv_candidate): New function. - (build_object_call): Handle member templates, as done in the other - build_ functions. - -Sat Sep 6 10:20:27 1997 Mark Mitchell <mmitchell@usa.net> - - * decl.c (replace_defag): Undo previous change. - * lex.c (do_pending_defargs): Deal with member templates. - - * pt.c (is_member_template): Avoid crashing when passed a - non-function argument. - -Fri Sep 5 17:27:38 1997 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (grow_method): Remove check for redeclaration. - -Fri Sep 5 01:37:17 1997 Mark Mitchell <mmitchell@usa.net> - - * cp-tree.h (INNERMOST_TEMPLATE_PARMS): New macro. - (DECL_INNERMOST_TEMPLATE_PARMS): Likewise. - (PRIMARY_TEMPLATE_P): Use it. - * call.c (build_overload_call_real): Use it. - * class.c (instantiate_type): Likewise. - * decl.c (decls_match): Likewise. - * method.c (build_overload_identifier): Likewise. - * pt.c (push_template_decl): Likewise. - (classtype_mangled_name): Likewise. - (lookup_template_class): Likewise. - - * cp-tree.h (DECL_NTPARMS): Change name from DECL_NT_PARMS to - DECL_NTPARMS to conform to usage elsewhere. - * call.c (add_template_candidate): Likewise. - * class.c (instantiate_type): Likewise. - * pt.c (instantiate_template): Likewise. - (get_bindings): Likewise. - - * class.c (grow_method): Use DECL_FUNCTION_TEMPLATE_P instead of - is_member_template. - - * pt.c (unify): Undo changes to allow multiple levels of template - parameters. - (type_unification): Likewise. - (fn_type_unification): Likewise. - (get_class_bindings): Likewise. - * cp-tree.h (Likewise). - - * decl.c (replace_defarg): Check that the type of the default - parameter does not invlove a template type before complaining - about the initialization. - - * error.c (dump_expr): Deal with template constant parameters in - member templates correctly. - - * pt.c (is_member_template): Deal with class specializations - correctly. - (tsubst): Handle "partial instantiation" of member templates - correctly. - -Wed Sep 3 12:30:24 1997 Mark Mitchell <mmitchell@usa.net> - - * pt.c (type_unification): Change calling squence to allow for - multiple levels of template parameters. - (tsubst_expr): Likewise. - (tsubst): Likewise. - (tsubst_copy): Likewise. - (instantiate_template): Likewise. - (unify): Likewise. - * call.c (build_overload_call_real): Use it. - (add_builtin_candidate): Use it. - (build_new_method_call): Use it. - * class.c (instantiate_type): Use it. - * decl.c (grokdeclarator): Use it. - * decl2.c (finish_file): Use it. - * method.c (build_overload_identifier): Use it. - - * call.c (add_template_candidate): Add additional parameter for - the function return type. Call fn_type_unification istead of - type_unification. - (build_user_type_conversion_1): Handle member templates. - (build_new_function_call): Likewise. - (build_new_op): Likewise. - (build_new_method_call): Likewise. - - * class.c (grow_method): Don't give an error message indicating - that two member templates with the same name are ambiguous. - (finish_struct): Treat member template functions just like member - functions. - - * cp-tree.h (check_member_template): Add declaration. - (begin_member_template_processing): Likewise. - (end_member_template_processing): Likewise. - (fn_type_unification): Likewise. - (is_member_template): Likewise. - (tsubst): Change prototype. - (tsubst_expr): Likewise. - (tsubst_copy): Likewise. - (instantiate_template): Likewise. - (get_bindings): Likewise. - - * decl.c (decls_match): Handle multiple levels of template - parameters. - (pushdecl): Handle template type params just like other type - declarations. - (push_class_level_binding): Return immediately if the - class_binding_level is NULL. - (grokfndecl): If check_classfn() returns a member_template, use - the result of the template, not the template itself. - - * decl2.c (check_member_template): New function. Check to see - that the entity declared to be a member template can be one. - (check_classfn): Allow redeclaration of member template functions - with different types; the new functions can be specializations or - explicit instantiations. - - * error.c (dump_decl): Handle multiple levels of template - parameters. - (dump_function_decl): Update to handle function templates. - - * lex.c (do_pending_inlines): Set up template parameter context - for member templates. - (process_next_inline): Likewise. - - * method. (build_overload_identifier): Adjust for multiple levels - of template parameters. - - * parse.y (fn.def2): Add member templates. - (component_decl_1): Likewise. - - * pt.c (begin_member_template_processing): New function. - (end_member_template_processing): Likewise. - (is_member_template): Likewise. - (fn_type_unification): Likewise. - (current_template_parms): Return a vector of all the template - parms, not just the innermost level of parms. - (push_template_decl): Deal with the possibility of member - templates. - (lookup_template_class): Likewise. - (uses_template_parms): Likewise. - (tsubst): Modify processing to TEMPLATE_TYPE_PARM and - TEMPLATE_CONST_PARM to deal with multiple levels of template - arguments. Add processing of TEMPLATE_DECL to produce new - TEMPLATE_DECLs from old ones. - (do_decl_instantiation): Handle member templates. - - * search.c (lookup_fnfields_1): Handle member template conversion - operators. - - * tree.c (cp_tree_equal): Check the levels, as well as the - indices, of TEMPLATE_CONST_PARMs. - - * typeck.c (comptypes): Check the levels, as well as the indices, - fo TEMPLATE_TYPE_PARMs. - (build_x_function_call): Treat member templates like member - functions. - -Wed Sep 3 11:09:25 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (c_expand_return): Always convert_for_initialization - before checking for returning a pointer to local. - - * pt.c (type_unification): If strict and the function parm doesn't - use template parms, just compare types. - -Wed Sep 3 10:35:49 1997 Klaus Espenlaub <kespenla@student.informatik.uni-ulm.de> - - * method.c (build_overloaded_value): Replace direct call - to the floating point emulator with REAL_VALUE_TO_DECIMAL macro. - -Wed Sep 3 00:02:53 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (convert_arguments): Don't arbitrarily choose the first - of a set of overloaded functions. - -Tue Sep 2 12:09:13 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (real_yylex): Don't elide __FUNCTION__. - - * method.c (build_overload_value): Add in_template parm. - (build_overload_int): Likewise. - (build_overload_identifier): Pass it. - - * decl.c (duplicate_decls): Don't bash a previous template - definition with a redeclaration. - - * pt.c (unify): float doesn't match double. - - * pt.c (do_type_instantiation): Handle getting a _TYPE or a - TYPE_DECL. Handle getting non-template types. - * parse.y (explicit_instantiation): Use typespec instead of - aggr template_type. - -Tue Sep 2 10:27:08 1997 Richard Henderson <rth@cygnus.com> - - * typeck.c (build_ptrmemfunc1): Clean up ptr->int cast warnings. - -Mon Sep 1 13:19:04 1997 Eugene Mamchits <eugin@ips.ras.ru> - - * call.c (add_builtin_candidate): Add missing TREE_TYPE. - (compare_ics): Likewise. - -Mon Sep 1 13:19:04 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (joust): Warn about choosing one conversion op over - another because of 'this' argument when the other return type is - better. - (source_type): New fn. - - * call.c (build_new_op): Strip leading REF_BIND from first operand - to builtin operator. - - * decl2.c (mark_vtable_entries): Mark abort_fndecl as used when we - use its RTL. - -Thu Aug 28 09:45:23 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (null_ptr_cst_p): Remove support for (void*)0. - -Wed Aug 27 02:03:34 1997 Jeffrey A Law (law@cygnus.com) - - * typeck.c (expand_target_expr): Make definition match declaration. - - * class.c (get_basefndecls): Make definition match declaration. - -Mon Aug 25 14:30:02 1997 Jason Merrill <jason@yorick.cygnus.com> - - * input.c (sub_getch): Eventually give up and release the input file. - - * decl.c (cp_finish_decl): If #p i/i, put inline statics in the - right place. - - * call.c (joust): Tweak message. - -Sat Aug 23 18:02:59 1997 Mark Mitchell <mmitchell@usa.net> - - * error.c (type_as_string): Put const/volatile on template type - parameters where appropriate. - -Sat Aug 23 17:47:22 1997 Jeffrey A Law (law@cygnus.com) - - * call.c (strictly_better): Make arguments unsigned ints. - -Thu Aug 21 18:48:44 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (real_yylex): Refer to __complex instead of complex. - -Thu Aug 21 22:25:46 1997 J"orn Rennecke <amylaar@cygnus.co.uk> - - * lex.c (real_yylex): Don't use getc directly. - -Wed Aug 20 17:25:08 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (is_subseq): Don't try to be clever. - -Wed Aug 20 03:13:36 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * parse.y, pt.c: Include "except.h". - * call.c, class.c, class.h, cp-tree.h, cvt.c, decl.c, decl2.c, - error.c, except.c, expr.c, friend.c, g++spec.c, init.c, input.c, - lex.c, lex.h, method.c, parse.y, pt.c, repo.c, rtti.c, search.c, - sig.c, spew.c, tree.c, typeck.c, typeck2.c, xref.c: Finish - prototyping. - -Wed Aug 20 01:34:40 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (mark_vtable_entries): Instead of replacing pure - virtuals with a reference to __pure_virtual, copy the decl and - change the RTL. - -Tue Aug 19 02:26:07 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (lookup_nested_type_by_name): Handle typedef wierdness. - - * typeck2.c (my_friendly_abort): Report bugs to egcs-bugs@cygnus.com. - - * pt.c (instantiate_class_template): Call repo_template_used - before finish_prevtable_vardecl. - - * call.c (is_subseq): New fn. - (compare_ics): Use it. - - * repo.c (finish_repo): Don't crash on no args. - - * parse.y (named_complex_class_head_sans_basetype): Handle - explicit global scope. - * decl2.c (handle_class_head): New fn. - - * pt.c (unify): Add CONST_DECL case. - -Thu Aug 14 10:05:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * rtti.c (permanent_obstack): Fix decl to not be a pointer. - - * cp-tree.h (report_type_mismatch): Add prototype. - * call.c (build_overload_call_real): Remove erroneous fourth - argument to report_type_mismatch. - (build_user_type_conversion_1): Remove erroneous second arg to - tourney. - (build_new_function_call): Likewise. - (build_object_call): Likewise. - (build_new_op): Likewise. - (build_new_method_call): Likewise. - -Wed Aug 13 19:19:25 1997 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (dump_decl): Don't bother processing a function with no - DECL_LANG_SPECIFIC. - - * method.c (emit_thunk): Call init_function_start in the macro case. - -Wed Aug 13 10:46:19 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * decl2.c (DEFAULT_VTABLE_THUNKS): Define to be 0 if not - defined and used to set flag_vtable_thunks. - -Tue Aug 12 20:13:57 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y: Don't clear the inlines from their obstack until they've - all been processed. - - * decl.c (duplicate_decls): Don't complain about exception - specification mismatch if flag_exceptions is off. - -Mon Aug 11 15:01:56 1997 Marc Lehmann <pcg@goof.com> - - * Make-lang.in (c++.distclean): Remove g++.c on make distclean. - -Sun Aug 10 12:06:09 1997 Paul Eggert <eggert@twinsun.com> - - * cp-tree.h: Replace STDIO_PROTO with PROTO in include files. - * cvt.c, error.c, except.c, expr.c, friend.c, init.c, rtti.c: - Include <stdio.h> before include files that formerly used STDIO_PROTO. - - * decl.c, g++spec.c, lex.c, method.c, repo.c: - Include "config.h" first, as per autoconf manual. - -Fri Aug 8 11:47:48 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (duplicate_decls): Tweak wording. - * lex.c (do_pending_defargs): Don't die if we see a default arg - that isn't a DEFAULT_ARG. - * error.c (dump_expr): Handle DEFAULT_ARG. - - * decl2.c (lang_decode_option): Handle -fhandle-exceptions. - * lang-options.h: Add -fhandle-exceptions. - - * class.c (build_vtable): vtables are artificial. - (prepare_fresh_vtable): Likewise. - -Wed Aug 6 11:02:36 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (ocp_convert): After converting to the target type, set - LOOKUP_NO_CONVERSION. - - * call.c (joust): Warn about potentially confusing promotion rules - with -Wsign-promo. - * cp-tree.h, lang-options.h, decl2.c: Support -Wsign-promo. - -Tue Aug 5 15:15:07 1997 Michael Meissner <meissner@cygnus.com> - - * exception.cc: Declare __terminate_func with noreturn attribute. - -Fri Aug 1 03:18:15 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y: Break out eat_saved_input, handle errors. - (function_try_block): Use compstmt instead of compstmt_or_error. - -Thu Jul 31 17:14:04 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (build_cplus_new): Don't set TREE_ADDRESSABLE. - -Fri Jul 4 01:45:16 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * Make-lang.in (cplib2.txt, cplib2.ready): Instead of checking for - existence of cc1plus check whether $(LANGUAGES) contains C++. - -Wed Jul 30 13:04:21 1997 Andreas Schwab <schwab@issan.informatik.uni-dortmund.de> - - * method.c (do_build_copy_constructor): When copying an anonymous - union member loop around to handle nested anonymous unions. Use - the offset of the member relative to the outer structure, not the - union. - -Tue Jul 29 21:17:29 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (resolve_args): New fn. - (build_new_function_call): Use it. - (build_object_call): Likewise. - (build_new_method_call): Likewise. - -Mon Jul 28 16:02:36 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): tsubst all default parms from templates. - -Wed Jul 23 13:36:25 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (struct cp_function): Add static_labelno. - (push_cp_function_context): Save it. - (pop_cp_function_context): Restore it. - -Tue Jul 22 14:43:29 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_component_ref_1): Convert from reference. - -Tue Jul 22 11:06:23 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (current_declspecs, prefix_attributes): Initialize to - NULL_TREE. - - * parse.y (initdcl0): Make sure CURRENT_DECLSPECS is non-nil - before we try to force it to be a TREE_LIST. - (decl): Make sure $1.t is non-nil. - -Sun Jul 20 11:53:07 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (uses_template_parms): Handle template first-parse codes. - - * decl.c (cp_finish_decl): Only warn about user-defined statics. - -Fri Jul 18 17:56:08 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (unify): Handle BOOLEAN_TYPE. - - * cp-tree.h: Lose PARM_DEFAULT_FROM_TEMPLATE. - * pt.c (tsubst): Don't set it. - * call.c (build_over_call): Use uses_template_parms. - -Thu Jul 17 18:06:30 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (build_overload_nested_name): Use static_labelno - instead of var_labelno. - (build_qualified_name): New fn. - (build_overload_name): Split out from here. - (build_static_name): Use build_qualified_name. - * decl.c (cp_finish_decl): Statics in extern inline functions - have comdat linkage. - (start_function): Initialize static_labelno. - -Thu Jul 17 11:20:17 1997 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * class.c (finish_struct_methods): add check of warn_ctor_dtor_privacy - before "all member functions in class [] are private" - -Wed Jul 16 23:47:08 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_scoped_id): convert_from_reference. - * init.c (build_offset_ref): Likewise. - -Wed Jul 16 12:34:29 1997 Benjamin Kosnik <bkoz@lisa.cygnus.com> - - * error.c (dump_expr): Check TREE_OPERAND before dump_expr_list. - -Mon Jul 14 03:23:46 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (get_member_function_from_ptrfunc): Promote index - before saving it. - -Sun Jul 13 00:11:52 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (layout_basetypes): Move non-virtual destructor warning. - * decl.c (xref_basetypes): Remove non-virtual destructor warning. - -Sat Jul 12 12:47:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Call add_defarg_fn for the function - type, too. - * lex.c (add_defarg_fn): Adjust. - (do_pending_defargs): Adjust. Don't skip the first parm. - -Fri Jul 11 01:39:50 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (build_enumerator): Global enumerators are also readonly. - - * rtti.c (build_dynamic_cast_1): Renamed from build_dynamic_cast. - (build_dynamic_cast): Call it and convert_from_reference. - - * lex.c (add_defarg_fn): New fn. - (snarf_defarg): Don't add to defarg_types. - (do_pending_defargs): Lose defarg_types. All fns we process now - have defargs. - * decl.c (grokfndecl): Call add_defarg_fn. - - * Makefile.in (CONFLICTS): Expect 18 s/r conflicts. - * cp-tree.def: Add DEFAULT_ARG. - * spew.c (yylex): Call snarf_defarg as appropriate. - * parse.y: New tokens DEFARG and DEFARG_MARKER. - (defarg_again, pending_defargs, defarg, defarg1): New rules. - (structsp): Use pending_defargs. - (parms, full_parm): Use defarg. - * lex.c (init_lex): Initialize inline_text_firstobj. - (do_pending_inlines): Never pass the obstack to feed_input. - (process_next_inline): Call end_input instead of restore_pending_input. - (clear_inline_text_obstack, reinit_parse_for_expr, do_pending_defargs, - finish_defarg, feed_defarg, snarf_defarg, maybe_snarf_defarg): New fns. - * input.c (end_input): New fn. - (sub_getch): At the end of some fed input, just keep returning EOF - until someone calls end_input. - Remove 'obstack' field from struct input_source. - * decl.c (grokparms): Handle DEFAULT_ARG. - (replace_defarg): New fn. - * cp-tree.h (DEFARG_LENGTH, DEFARG_POINTER): New macros. - -Wed Jul 9 13:44:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (implicit_conversion): If nothing else works, try binding - an rvalue to a reference. - -Wed Jul 9 13:04:38 1997 Geoffrey Noer <noer@cygnus.com> - - * decl.c (init_decl_processing): fix Jun 30 patch -- move - ifndef for Cygwin32 to include SIGSEGV. - -Thu Jul 3 01:44:05 1997 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Only complain about pointers without - copy stuff if there are any constructors. - - * rtti.c (build_dynamic_cast): Call complete_type on the types. - - * decl.c (grokfndecl): If the function we chose doesn't actually - match, die. - - * decl2.c (grokclassfn): Don't specify 'const int' for the - artificial destructor parm. - - * pt.c (type_unification): If we are called recursively, nothing - decays. - -Mon Jun 30 17:53:21 1997 Geoffrey Noer <noer@cygnus.com> - - * decl.c (init_decl_processing): Stop trying to catch signals - other than SIGABRT since the Cygwin32 library doesn't support - them correctly yet. This fixes a situation in which g++ causes - a hang on SIGSEGVs and other such signals in our Win32-hosted - tools. - -Mon Jun 30 14:50:01 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (mapcar, case CALL_EXPR): Handle all the parse node data. - -Fri Jun 27 15:18:49 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (store_init_value): Always return the value if our - type needs constructing. - - * method.c (hack_identifier): Convert class statics from - reference, too. - -Thu Jun 26 11:44:46 1997 Jason Merrill <jason@yorick.cygnus.com> - - * Make-lang.in (cplib2.ready): Add $(LANGUAGES) dependency. - -Thu Jun 19 16:49:28 1997 Mike Stump <mrs@cygnus.com> - - * typeck.c (c_expand_return): Make sure we clean up temporaries at - the end of return x; - -Thu Jun 19 12:28:43 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (check_for_missing_semicolon): Also check for CV_QUALIFIER. - -Tue Jun 17 18:35:57 1997 Mike Stump <mrs@cygnus.com> - - * except.c (expand_builtin_throw): Add support - -fno-sjlj-exceptions -fPIC exception handling on the SPARC. - -Mon Jun 16 01:24:37 1997 Jason Merrill <jason@yorick.cygnus.com> - - * repo.c (extract_string): Null-terminate. - - * cp-tree.h (TI_SPEC_INFO): New macro. - (CLASSTYPE_TI_SPEC_INFO): New macro. - * pt.c (push_template_decl): Correctly determine # of template parms - for partial specs. - - * call.c (compare_ics): Really fix 'this' conversions. - - * pt.c (do_decl_instantiation): Don't crash on explicit inst of - non-template fn. - - * pt.c (push_template_decl): Complain about mismatch in # of - template parms between a class template and a member template. - -Sun Jun 15 02:38:20 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (synthesize_method): You can't call - function_cannot_inline_p after finish_function. - * decl.c (finish_function): Turn on flag_inline_functions and turn - off DECL_INLINE before handing a synthesized method to the - backend. - -Thu Jun 12 17:35:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (synthesize_method): Remove July 30 change to never set - DECL_INLINE if at_eof. - -Thu Jun 12 15:25:08 1997 Mike Stump <mrs@cygnus.com> - - * xref.c (GNU_xref_member): Ensure that the node has a - decl_lang_specific part before checking DECL_FRIEND_P. - -Thu Jun 12 12:36:05 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Diagnose non-class types used - as bases. - -Wed Jun 11 17:33:40 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_conditional_expr): Use convert_for_initialization - instead of convert_and_check. - -Wed Jun 11 12:31:33 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (typespec): Don't pedwarn for typeof. - -Tue Jun 10 00:22:09 1997 Jason Merrill <jason@yorick.cygnus.com> - - * repo.c (finish_repo): Only check changes if we would write a - repo file. - - * call.c (compare_ics): Fix handling of 'this' conversions. - - * pt.c (do_decl_instantiation): Support static data too. Rename - from do_function_instantiation. - * cp-tree.h: Adjust. - * parse.y: Adjust. - - * repo.c (extract_string): New fn. - (get_base_filename): Use it. - (init_repo): Compare old args with current args. - -Mon Jun 9 14:25:30 1997 Mike Stump <mrs@cygnus.com> - - * Makefile.in, Make-lang.in: Protect C-ls with a comment - character, idea from Paul Eggert <eggert@twinsun.com>. - -Mon Jun 9 01:52:03 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (c_expand_return): Be more persistent in looking for - returned temps. - - * cvt.c (build_up_reference): Use NOP_EXPR for switching from - pointer to reference. - - * class.c (build_vbase_path): Don't do anything if PATH has no steps. - -Sun Jun 8 03:07:05 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_member_call, build_offset_ref): - Use do_scoped_id instead of do_identifier. - - * cvt.c (convert): Remove bogosity. - -Sat Jun 7 20:50:17 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cvt.c (build_up_reference): Do checks of ARGTYPE and - TARGET_TYPE before trying to use get_binfo. - -Fri Jun 6 17:36:39 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_up_reference): Call get_binfo to get access control. - - * decl2.c (import_export_decl): If we don't support weaks, leave - statics undefined. - -Fri Jun 6 15:55:49 1997 Mike Stump <mrs@cygnus.com> - - * except.c (expand_builtin_throw): Add support for machines that - cannot access globals after throw's epilogue when - -fno-sjlj-exceptions is used. - -Thu Jun 5 16:28:43 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y: 'std::' becomes '::'. - * lex.c (real_yylex): Remove 'namespace' warning. - * init.c (build_member_call): Ignore 'std::'. - (build_offset_ref): Likewise. - * decl2.c (do_using_directive): Ignore 'using namespace std;'. - (do_toplevel_using_decl): Ignore 'using std::whatever'. - * decl.c (push_namespace): Just sorry. - (pop_namespace): Nop. - (init_decl_processing): Declare std namespace. - -Tue Jun 3 18:08:23 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (push_class_decls): A name which ambiguously refers to - several instantiations of the same template just refers to the - template. - -Tue Jun 3 12:30:40 1997 Benjamin Kosnik <bkoz@cirdan.cygnus.com> - - * decl.c (build_enumerator): fix problem with unsigned long - enumerated values being smashed to ints, causing overflow - when computing next enumerated value. (for enum values around - MAX_VAL). - -Mon Jun 2 17:40:56 1997 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_component_ref): Only call mark_used on a decl. - -Thu May 29 15:54:17 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (build_c_cast): Make the check for a ptr to function - more specific before possible default_conversion call. - -Thu May 29 13:02:06 1997 Mike Stump <mrs@cygnus.com> - - * except.c (expand_exception_blocks): Simplify and fix and make - sure we don't end a region in a sequence, as expand_end_bindings - doesn't like it. - -Wed May 28 17:08:03 1997 Mike Stump <mrs@cygnus.com> - - * except.c (init_exception_processing): Mark terminate as not - returning so that the optimizer can optimize better. - -Tue May 27 19:49:19 1997 Mike Stump <mrs@cygnus.com> - - * cvt.c (convert): Don't do any extra work, if we can avoid it - easily. - -Tue May 27 18:21:47 1997 Mike Stump <mrs@cygnus.com> - - * *.[chy]: Change cp_convert to ocp_convert, change convert to - cp_convert. convert is now reserved for the backend, and doesn't - have the semantics a frontend person should ever want. - -Fri May 23 10:58:31 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lang-specs.h: Define __EXCEPTIONS if exceptions are enabled. - Lose -traditional support. - -Thu May 22 15:41:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (get_tinfo_var): Use TYPE_PRECISION (sizetype). - - * parse.y (self_reference): Do it for templates, too. - * class.c (pushclass): Don't overload_template_name; the alias - generated by build_self_reference serves the same purpose. - - * tree.c (list_hash): Make static, take more args. - (list_hash_lookup): Likewise. - (list_hash_add): Make static. - (list_hash_canon): Lose. - (hash_tree_cons): Only build a new node if one isn't already in the - hashtable. - (hash_tree_chain): Use hash_tree_cons. - * cp-tree.h: Adjust. - * decl.c (grokfndecl): Just check IDENTIFIER_GLOBAL_VALUE instead - of calling lookup_name. - -Wed May 21 18:24:19 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): TYPE_VALUES for an enum - doesn't refer to the CONST_DECLs. - -Tue May 20 21:09:32 1997 Bob Manson <manson@charmed.cygnus.com> - - * rtti.c (get_tinfo_var): Either INT_TYPE_SIZE or 32, whichever - is bigger. - (expand_class_desc): Convert the last argument to a sizetype. - -Tue May 20 13:55:57 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * gxx.gperf (__complex, __complex__, __imag, __imag__, __real, - __real__): Add reswords. - * hash.h: Regenerate. - * lex.h (rid): Add RID_COMPLEX. - (RID_LAST_MODIFIER): Set to RID_COMPLEX. - * lex.c (init_lex): Add building of RID_COMPLEX. - (real_yylex): General cleanup in line with what c-lex.c also has, - sans the cruft for traditional; add handling of SPEC_IMAG, complex - types, and imaginary numeric constants. - * parse.y (REALPART, IMAGPART): Add tokens. - (unary_expr): Add REALPART and IMAGPART rules. - * cp-tree.h (complex_{integer,float,double,long}_type_node): Declare. - * decl.c (complex_{integer,float,double,long}_type_node): Define - types. - (init_decl_processing): Set up the types. - (grokdeclarator): Add handling of RID_COMPLEX. Set and use - DEFAULTED_INT instead of EXPLICIT_INT when we default to int type. - * call.c (build_new_op): Add REALPART_EXPR and IMAGPART_EXPR cases. - * cvt.c (cp_convert): Handle COMPLEX_TYPE. - * error.c (dump_type_prefix, dump_type, dump_type_suffix): Add - COMPLEX_TYPE case. - * method.c (build_overload_name): Add handling of the different - COMPLEX_TYPEs, prefixing them with `J'. - * pt.c (process_template_parm): Don't let them use a COMPLEX_TYPE - as a template parm. - (uses_template_parms, tsubst, unify): Add COMPLEX_TYPE case. - * tree.c (lvalue_p): Add REALPART_EXPR and IMAGPART_EXPR cases. - (mapcar): Handle COMPLEX_CST. - * typeck.c (build_binary_op_nodefault): Handle COMPLEX_TYPE. - (common_type): Add code for complex types. - (build_unary_op): Add REALPART_EXPR and IMAGPART_EXPR cases. - (convert_for_assignment): Likewise. - (mark_addressable): Add REALPART_EXPR and IMAGPART_EXPR cases. - -Mon May 19 12:26:27 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Don't pass the MINUS_EXPR for an array domain to - tsubst_expr, as it might try to do overload resolution. - -Sat May 17 10:48:31 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Oops. - -Fri May 16 14:23:57 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.def: Add TAG_DEFN. - * pt.c (tsubst_enum): New fn. - (instantiate_class_template): Use it. - (tsubst_expr): Support TAG_DEFN. - (tsubst): Support local enums. - (tsubst_copy): Likewise. - * decl.c (finish_enum): Likewise. - (start_enum): If this is a local enum, switch to permanent_obstack. - -Wed May 14 19:08:28 1997 Mike Stump <mrs@cygnus.com> - - * decl.c (store_parm_decls): Set last_parm_cleanup_insn here. - (finish_function): Put the base init code for constructors just - after the parm cleanup insns. - (struct cp_function): Add last_parm_cleanup_insn. - (push_cp_function_context): Likewise. - (pop_cp_function_context): Likewise. - -Tue May 13 15:51:20 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_copy): Handle BIT_NOT_EXPR. - -Wed May 7 11:17:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * method.c (emit_thunk) [ASM_OUTPUT_MI_THUNK]: Build up the RTL - for THUNK_FNDECL before we switch to temporary allocation. - -Mon May 5 14:46:53 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_op): Handle null arg2 for ?:. - -Thu May 1 18:26:37 1997 Mike Stump <mrs@cygnus.com> - - * except.c (expand_exception_blocks): Ensure that we flow through - the end of the exception region for the exception specification. - Move exception region for the exception specification in, so that - it doesn't protect the parm cleanup. Remove some obsolete code. - * decl.c (store_parm_decls): Likewise. - (finish_function): Likewise. - -Tue Apr 29 15:38:54 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Fix nothrow handling. - -Tue Apr 29 14:29:50 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (emit_base_init): Don't warn about the initialization - list for an artificial member. - -Fri Apr 25 17:47:59 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * expr.c (do_case): Handle !START case for the error msg. - -Fri Apr 25 11:55:23 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c, lang-options.h: New option -Weffc++. - * class.c, decl.c, init.c, typeck.c: Move Effective C++ warnings - to -Weffc++. - - * decl2.c (finish_prevtable_vardecl): Change NO_LINKAGE_HEURISTICS - to MULTIPLE_SYMBOL_SPACES. - -Wed Apr 23 18:06:50 1997 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (emit_thunk, generic case): Set current_function_is_thunk. - - * method.c (emit_thunk, macro case): Set up DECL_RESULT. - - * typeck.c (c_expand_return): Don't complain about returning void - to void in an artificial function. - * method.c (make_thunk): Change settings of READONLY/VOLATILE, - don't set DECL_RESULT, set DECL_ARTIFICIAL. - (emit_thunk, generic code): Also set up DECL_LANG_SPECIFIC. - -Wed Apr 23 14:43:06 1997 Mike Stump <mrs@cygnus.com> - - * init.c (init_decl_processing): Add supoprt for setjmp/longjmp based - exception handling. - * except.c (init_exception_processing): Likewise. - (expand_end_catch_block): Likewise. - (expand_exception_blocks): Likewise. - (expand_throw): Likewise. - * exception.cc (__default_terminate): Likewise. - - * init.c (perform_member_init): Use new method of expr level - cleanups, instead of cleanups_this_call and friends. - (emit_base_init): Likewise. - (expand_aggr_vbase_init_1): Likewise. - (expand_vec_init): Likewise. - * decl.c (cp_finish_decl): Likewise. - (expand_static_init): Likewise. - (store_parm_decls): Likewise. - (cplus_expand_expr_stmt): Likewise. - * decl2.c (finish_file): Likewise. - - * Make-lang.in (exception.o): Ok to compile with -O now. - - * decl.c (maybe_build_cleanup_1): We no longer have to unsave, as - we know it will be done later by the backend. - - * decl2.c (lang_f_options): Remove support for short temps. - * lang-options.h: Likewise. - -Wed Apr 23 04:12:06 1997 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (varargs_function_p): New fn. - * method.c (emit_thunk): Replace broken generic code with code to - generate a heavyweight thunk function. - -Tue Apr 22 02:45:18 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (process_template_parm): pedwarn about floating-point parms. - - * decl.c (grokdeclarator): inline no longer implies static. - - * spew.c (yylex): Always return the TYPE_DECL if we got a scope. - -Mon Apr 21 15:42:27 1997 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (check_for_override): The signature of an overriding - function is not changed. - - * call.c (build_over_call): Move setting of conv into the loop. - Note: this change, along with the related changes of the 18th thru - the 20th of April, fix an infinite loop problem in conversions. - -Sun Apr 20 16:24:29 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_user_type_conversion_1): Really ignore rvalue - conversions when looking for a REFERENCE_TYPE. - - * cvt.c (build_up_reference): Eviscerate, use build_unary_op. - * cp-tree.h (TREE_REFERENCE_EXPR): #if 0. - * typeck.c (decay_conversion): Don't set TREE_REFERENCE_EXPR. - (build_unary_op): Likewise. - * call.c (build_over_call): See through a CONVERT_EXPR around the - ADDR_EXPR for on a temporary. - * typeck.c (c_expand_return): See through a CONVERT_EXPR around - the ADDR_EXPR for a local variable. - -Fri Apr 18 12:11:33 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_user_type_conversion_1): If we're trying to - convert to a REFERENCE_TYPE, only consider lvalue conversions. - (build_new_function_call): Print candidates. - (implicit_conversion): Try a temp binding if the lvalue conv is BAD. - (reference_binding): Binding a temporary of a reference-related type - is BAD. - -Thu Apr 17 14:37:22 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * inc/typeinfo (type_info::before): Add cv-qualifier-seq. - * tinfo2.cc (type_info::before): Likewise. - -Mon Apr 14 12:38:17 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (implicit_conversion): Oops. - -Fri Apr 11 02:18:30 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (implicit_conversion): Try to find a reference conversion - before binding a const reference to a temporary. - -Wed Apr 2 12:51:36 1997 Mike Stump <mrs@cygnus.com> - - * exception.cc (__default_unexpected): Call terminate by default, - so that if the user overrides terminate, the correct function will - be called. - -Wed Mar 19 14:14:45 1997 Mike Stump <mrs@cygnus.com> - - * parse.y (left_curly): Avoid trying to use any fields of - error_mark_node, as there aren't any. - -Thu Mar 13 16:33:22 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_identifier): Avoid breaking on overloaded methods - as default arguments. - -Wed Mar 12 13:55:10 1997 Hans-Peter Nilsson <Hans-Peter.Nilsson@axis.se> - - * call.c (add_template_candidate): Initialize the variable "dummy". - -Mon Mar 10 15:13:14 1997 Brendan Kehoe <brendan@canuck.cygnus.com> - - * decl.c (start_decl): Make sure TYPE isn't an error_mark_node - before we try to use TYPE_SIZE and TREE_CONSTANT on it. - -Fri Mar 7 13:19:36 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (comp_ptr_ttypes, more_specialized): Add decl. - (debug_binfo): Delete decl, not needed. - - * tree.c (fnaddr_from_vtable_entry, function_arg_chain, - promotes_to_aggr_type): Delete fns. - * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY, - SET_FNADDR_FROM_VTABLE_ENTRY, FUNCTION_ARG_CHAIN, - PROMOTES_TO_AGGR_TYPE): Delete alternates to #if 1. - - * decl.c (pending_invalid_xref{,_file,_line}): Delete unused vars. - - * friend.c (is_friend_type): Delete fn. - * cp-tree.h (is_friend_type): Delete decl. - - * decl.c (original_result_rtx, double_ftype_double, - double_ftype_double_double, int_ftype_int, long_ftype_long, - float_ftype_float, ldouble_ftype_ldouble, last_dtor_insn): Make static. - * typeck.c (original_result_rtx, warn_synth): Delete extern decls. - - * decl.c (push_overloaded_decl{,_top_level}): Make static, adding - fwd decls. - * cp-tree.h (push_overloaded_decl{,_top_level}): Delete decls. - - * decl.c (pushdecl_nonclass_level): #if 0, unused. - * cp-tree.h (pushdecl_nonclass_level): #if 0 decl. - - * lex.c (reinit_lang_specific): #if 0, unused. - * cp-tree.h (reinit_lang_specific): #if 0 decl. - - * decl.c (revert_static_member_fn): Make static, adding fwd decl. - * cp-tree.h (revert_static_member_fn): Delete decl. - - * class.c (root_lang_context_p): Delete fn. - * cp-tree.h (root_lang_context_p): Delete decl. - - * decl.c (set_current_level_tags_transparency): #if 0, unused. - * cp-tree.h (set_current_level_tags_transparency): #if 0 decl. - - * lex.c (set_vardecl_interface_info): Make static. - * cp-tree.h (set_vardecl_interface_info): Delete decl. - - * call.c (find_scoped_type): Make static. - * cp-tree.h (find_scoped_type): Delete decl. - - * search.c (convert_pointer_to_vbase): Make static. - * cp-tree.h (convert_pointer_to_vbase): Delete decl. - - * decl.c (const_ptr_type_node): Likewise. - * cp-tree.h (const_ptr_type_node): Delete decl. - - * typeck.c (common_base_type): Make static. - * cp-tree.h (common_base_types): Delete erroneous decl. - - * pt.c (classtype_mangled_name): Make static. - * cp-tree.h (classtype_mangled_name): Delete decl. - - * lex.c (check_newline): Make static. - * cp-tree.h (check_newline): Delete decl. - - * typeck.c (build_x_array_ref): Delete fn, same idea as - grok_array_decl. - * cp-tree.h (build_x_array_ref): Delete decl. - - * lex.c (copy_decl_lang_specific): Delete fn, same idea as - copy_lang_decl. - * cp-tree.h (copy_decl_lang_specific): #if 0 decl. - - * class.c (build_vtable_entry): Make static. - * cp-tree.h (build_vtable_entry): Delete decl. - - * class.c (build_vbase_pointer): Make static. - * cp-tree.h (build_vbase_pointer): Delete decl. - - * sig.c (build_sptr_ref): Add forward decl and make static. - * cp-tree.h (build_sptr_ref): Delete decl. - - * call.c (build_new_method_call): Add forward decl and make static. - * cp-tree.h (build_new_method_call): Delete decl. - - * call.c (build_object_call): Make static. - * class.c (check_for_override, complete_type_p, mark_overriders): - Likewise. - * decl.c (cp_function_chain): Likewise. - * lex.c (set_typedecl_interface_info, reinit_parse_for_block): - Likewise. - * pt.c (comp_template_args, get_class_bindings, push_tinst_level): - Likewise. - * tree.c (build_cplus_array_type_1): Likewise. - * typeck.c (comp_ptr_ttypes_{const,real,reinterpret}): Likewise. - (comp_target_parms): Likewise. - - * init.c (build_builtin_call): Make static. - * cp-tree.h (build_builtin_call): Delete decl. - - * typeck.c (binary_op_error): Delete decl. - * cp-tree.h (binary_op_error): Likewise. - -Thu Mar 6 16:13:52 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (build_method_call): Compare against error_mark_node - directly, rather than the ERROR_MARK tree code. - * cvt.c (cp_convert): Likewise. - * decl.c (print_binding_level): Likewise. - (duplicate_decls): Likewise. - (grokdeclarator): Likewise. - (grokdeclarator): Likewise. - * init.c (expand_aggr_init_1): Likewise. - (decl_constant_value): Likewise. - * method.c (build_opfncall): Likewise. - (hack_identifier): Likewise. - * typeck.c (build_modify_expr): Likewise. - - * typeck.c (build_c_cast): Don't decl TYPE as register tree. - -Sun Mar 2 02:54:36 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * pt.c (unify): Strip NOP_EXPR wrappers before unifying integer values. - - * pt.c (coerce_template_parms): Add new error message. - - * method.c (build_overload_value): Implement name mangling for - floating-point template arguments. - - * method.c (build_overload_int, icat, dicat): Fix mangling of template - arguments whose absolute value doesn't fit in a signed word. - -Mon Mar 3 12:14:54 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * friend.c: New file; put all of the friend stuff in here. - * init.c: Instead of here. - * Makefile.in (CXX_OBJS): Add friend.o. - (friend.o): Add dependencies. - * Make-lang.in (CXX_SRCS): Add $(srcdir)/cp/friend.c. - -Sun Mar 2 11:04:43 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_scoped_method_call): Complain if the scope isn't a - base. - -Wed Feb 26 11:31:06 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (left_curly): Don't crash on erroneous type. - - * init.c (build_delete): Fix type of ref. - -Tue Feb 25 12:41:48 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (get_vbase_1): Renamed from get_vbase. - (get_vbase): Wrapper, now non-static. - (convert_pointer_to_vbase): Now static. - - * call.c (build_scoped_method_call): Accept a binfo for BASETYPE. - * init.c (build_delete): Pass one. - (build_partial_cleanup_for): Use build_scoped_method_call. - * decl.c (finish_function): Pass a binfo. - -Mon Feb 24 15:00:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Only synthesize non-trivial copy ctors. - - * typeck.c (build_c_cast): Lose other reference to flag. - - * call.c (build_field_call): Don't look for [cd]tor_identifier. - * decl2.c (delete_sanity): Remove meaningless use of - LOOKUP_HAS_IN_CHARGE. - * decl.c (finish_function): Use build_scoped_method_call instead - of build_delete for running vbase dtors. - * init.c (build_delete): Call overload resolution code instead of - duplicating it badly. - -Thu Feb 20 15:12:15 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Call mark_used before trying to elide - the call. - - * decl.c (implicitly_declare): Don't set DECL_ARTIFICIAL. - -Wed Feb 19 11:18:53 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (build_modify_expr): Always pedwarn for a cast to - non-reference used as an lvalue. - -Wed Feb 19 10:35:37 1997 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Convert from 0 to a pmf properly. - -Tue Feb 18 15:40:57 1997 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (handler): Fix template typo. - -Sun Feb 16 02:12:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (lang_decl_name): New fn. - * tree.c (lang_printable_name): Use it. - -Fri Feb 14 16:57:05 1997 Mike Stump <mrs@cygnus.com> - - * g++spec.c: Include config.h so that we can catch bzero #defines - from the config file. - -Tue Feb 11 13:50:48 1997 Mike Stump <mrs@cygnus.com> - - * new1.cc: Include a declaration for malloc, to avoid warning, and - avoid lossing on systems that require one (ones that define malloc - in xm.h). - -Mon Feb 10 22:51:13 1997 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de> - - * decl2.c (max_tinst_depth): New variable. - (lang_decode_option): Parse "-ftemplate-depth-NN" command line - option. - * pt.c (max_tinst_depth): Variable moved. - * lang-options.h: Declare "-ftemplate-depth-NN" command line option - as legal. - -Fri Feb 7 15:43:34 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (xref_basetypes): Allow a base class that depends on - template parms to be incomplete. - - * decl2.c (build_expr_from_tree): Support typeid(type). - * rtti.c (get_typeid): Support templates. - (expand_si_desc, expand_class_desc): Fix string length. - (expand_ptr_desc, expand_attr_desc, expand_generic_desc): Likewise. - -Tue Feb 4 11:28:24 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (unify, case TEMPLATE_CONST_PARM): Use cp_tree_equal. - - * pt.c (tsubst): Put it back for -fno-ansi-overloading. - -Mon Feb 3 18:41:12 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst, case FUNCTION_DECL): Lose obsolete code that - smashes together template and non-template decls of the same - signature. - -Thu Jan 30 19:18:00 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Don't recurse for the type of a TYPENAME_TYPE. - -Wed Jan 29 11:40:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (duplicate_decls): Next route, pedwarn about different - exceptions if -pedantic *or* olddecl !DECL_IN_SYSTEM_HEADER. - -Tue Jan 28 20:43:29 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (HAS_DEFAULT_IMPLEMENTATION): Delete macro. - (struct lang_type): Delete has_default_implementation member. - Increase dummy to 21. - * decl.c (start_method): Delete usage. - - * cp-tree.h (build_call, null_ptr_cst_p, in_function_p, - store_after_parms, start_decl_1, auto_function): Add decls. - (get_arglist_len_in_bytes, declare_implicit_exception, - have_exceptions_p, make_type_decl, typedecl_for_tag, - store_in_parms, pop_implicit_try_blocks, push_exception_cleanup, - build_component_type_expr, cplus_exception_name, - {make,clear}_anon_parm_name, dont_see_typename): Removed decls. - * call.c (build_this): Make static. - (is_complete): Likewise. - (implicit_conversion): Likewise. - (reference_binding): Likewise. - (standard_conversion): Likewise. - (strip_top_quals): Likewise. - (non_reference): Likewise. - (build_conv): Likewise. - (user_harshness): Likewise. - (rank_for_ideal): Likewise. - * decl.c (start_decl_1): Delete forward decl. - (push_decl_level): Make static. - (resume_binding_level): Make static. - (namespace_bindings_p): Make static. - (declare_namespace_level): Make static. - (lookup_name_real): Make static. - (duplicate_decls): Make static. Take register off NEWDECL and - OLDDECL parm decls. - * decl2.c (get_sentry): Make static. - (temp_name_p): Delete fn. - * except.c (auto_function): Delete decl. - * lex.c (handle_{cp,sysv}_pragma): Make static. - (handle_sysv_pragma) [HANDLE_SYSV_PRAGMA]: Add forward decl. - * method.c (do_build_{copy_constructor,assign_ref}): Make static. - * pt.c (tsubst_expr_values): Make static. - * rtti.c (combine_strings): Delete decl. - -Tue Jan 28 16:40:40 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (push_template_decl): Handle getting a typedef. - - * call.c (build_new_function_call): Complain about void arg. - -Tue Jan 28 15:25:09 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (duplicate_decls): Give pedwarn of different exceptions - if -pedantic, instead of olddecl !DECL_IN_SYSTEM_HEADER. - -Mon Jan 27 19:21:29 1997 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Don't expand the cleanup tree here, - since we are not going to write the rtl out. Fixes problem with - -g -O on SPARC. - -Mon Jan 27 16:24:35 1997 Sean McNeil <sean@mcneil.com> - - * Make-lang.in: Add $(exeext) as necessary. - -Mon Jan 27 13:20:39 1997 Mike Stump <mrs@cygnus.com> - - * parse.y (handler_seq): Must have at least one catch clause. - -Sat Jan 25 12:00:05 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (add_builtin_candidate): Restore ?: hack. - - * decl.c (grok_op_properties): More warnings. - -Sat Jan 25 08:50:03 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (duplicate_decls): On second thought, do it as a pedwarn - still but only if !DECL_IN_SYSTEM_HEADER (olddecl). - - * decl.c (duplicate_decls): Scale back to a warning, and only do - 'em if -pedantic. - -Fri Jan 24 17:52:54 1997 Mike Stump <mrs@cygnus.com> - - * decl.c (duplicate_decls): pedwarn mismatched exception - specifications. - -Thu Jan 23 18:18:54 1997 Mike Stump <mrs@cygnus.com> - - * call.c (build_new_method_call): Don't display the invisible - argument for controlling virtual bases. - -Thu Jan 23 16:48:10 1997 Mike Stump <mrs@cygnus.com> - - * new: Add nothrow new and delete, bad_alloc and throw specifications - for delete. - * decl.c (init_decl_processing): Add throw specification for delete. - * new.cc (nothrow): Define. - * lex.c (real_yylex): Removing warning that throw and friends are - keywords. - * new1.cc (operator new (size_t sz, const nothrow_t&)): Define. - * new2.cc (operator new[] (size_t sz, const nothrow_t&): Define. - * Make-lang.in: Add new{1,2}.{cc,o}. - -Thu Jan 23 16:39:06 1997 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (cons_up_default_function): Fix return type of synth op=. - - * init.c (emit_base_init): Add warnings for uninitialized members - and bases. - - * decl.c (xref_basetypes): Add warning for non-polymorphic type - with destructor used as base type. - - * decl.c (grok_op_properties): Add warning for op= returning void. - * typeck.c (c_expand_return): Add warning for op= returning anything - other than *this. - - * class.c (finish_struct_1): Add warning for class with pointers - but not copy ctor or copy op=. - - * cp-tree.h (TI_PENDING_TEMPLATE_FLAG): New macro. - * pt.c (add_pending_template): Use it instead of LANG_FLAG_0. - (instantiate_template): If -fexternal-templates, add this - instantiation to pending_templates. - - * decl2.c (copy_assignment_arg_p): Disable old hack to support - Booch components. - -Tue Jan 21 18:32:04 1997 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert): Pedwarn enum to pointer conversions. - -Mon Jan 20 17:59:51 1997 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (standard_conversion): Handle getting references. Tack - on RVALUE_CONV here. Do it for non-class types, too. - (reference_binding): Pass references to standard_conversion. - (implicit_conversion): Likewise. - (add_builtin_candidate): Disable one ?: kludge. - (convert_like): Handle RVALUE_CONVs for non-class types. - (joust): Disable the other ?: kludge. - -Mon Jan 20 14:53:13 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (init_decl_processing): Add code to build up common - function types beforehand, to avoid creation then removal of - things already in the hash table. - -Mon Jan 20 14:43:49 1997 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (finish_function): Also zero out DECL_INCOMING_RTL for - the arguments. - - * error.c (dump_expr, TEMPLATE_CONST_PARM): Don't require - current_template_parms. - -Fri Jan 17 10:25:42 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (lookup_field): Don't return a function, check want_type. - -Thu Jan 16 18:14:35 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_new): Make sure PLACEMENT has a type. - -Thu Jan 16 17:40:28 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Support new (nothrow). - -Wed Jan 15 12:38:14 1997 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Also do push_to_top_level before setting - up DECL_INITIAL. - - * cp-tree.h (PARM_DEFAULT_FROM_TEMPLATE): New macro. - * pt.c (tsubst): Defer instantiation of default args. - * call.c (build_over_call): Until here. - -Wed Jan 15 10:08:10 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * search.c (lookup_field): Make sure we have an - IDENTIFIER_CLASS_VALUE before we try to return it. - -Thu Jan 9 07:19:01 1997 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (build_method_call): Delete unused var PARM. - (build_overload_call_real): Likewise. - (build_object_call): Delete unused var P. - (build_new_op): Likewise. - * decl.c (builtin_type_tdescs_{arr, len, max}): #if 0 out static - var definitions, which are never used. - (shadow_tag): Delete unused var FN. - * expr.c (cplus_expand_expr): Delete unused var ORIGINAL_TARGET. - * init.c (build_new): Delete unused var ALLOC_TEMP. - * method.c (hack_identifier): Delete unused var CONTEXT. - (do_build_copy_constructor): Delete unused var NAME. - (synthesize_method): Delete unused var BASE. - * pt.c (lookup_template_class): Delete unused var CODE_TYPE_NODE. - * rtti.c (build_headof): Delete unused var VPTR. - (get_typeid): Delete unused var T. - * typeck.c (build_conditional_expr): Delete unused vars ORIG_OP1 - and ORIG_OP2. - (build_ptrmemfunc): Delete unused vars U and NINDEX. - * typeck2.c (build_functional_cast): Delete unused var BINFO. - -Wed Jan 8 13:09:54 1997 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (lookup_field): Use IDENTIFIER_CLASS_VALUE to look up - things in a type being defined. - * decl.c (finish_enum): Reverse the values so that they are in - the correct order. - - * pt.c (instantiate_class_template): Don't initialize - BINFO_BASETYPES until the vector is filled out. - (unify): Don't abort on conflicting bindings, just fail. - (instantiate_decl): Do push_tinst_level before any tsubsting. - - * method.c (build_overload_value): Handle getting a - TEMPLATE_CONST_PARM for a pointer. - -Tue Jan 7 14:00:58 1997 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_member_init): Don't give 'not a base' error for - templates. - - * pt.c (instantiate_decl): Call import_export_decl later. - - * pt.c (instantiate_class_template): Return a value. - - * parse.y (extension): New rule for __extension__. - (extdef, unary_expr, decl, component_decl): Use it. - -Tue Jan 7 09:20:28 1997 Mike Stump <mrs@cygnus.com> - - * class.c (base_binfo): Remove unused base_has_virtual member. - (finish_base_struct): Likewise. - (finish_struct_1): Likewise. - -Tue Dec 31 20:25:50 1996 Mike Stump <mrs@cygnus.com> - - * search.c (expand_upcast_fixups): Fix bogus code generation - problem where the generated code uses the wrong index into the - runtime built vtable on the stack. Old code could clobber random - stack values. - -Tue Dec 31 15:16:56 1996 Mike Stump <mrs@cygnus.com> - - * init.c (perform_member_init): Make sure the partial EH cleanups - live on the function_obstack. - -Fri Dec 27 10:31:40 1996 Paul Eggert <eggert@twinsun.com> - - * Make-lang.in (g++spec.o): Don't use $< with an explicit target; - this isn't portable to some versions of `make' (e.g. Solaris 2.5.1). - -Tue Dec 24 10:24:03 1996 Jeffrey A Law (law@cygnus.com) - - * decl.c (grokvardecl): Avoid ANSI style initialization. - -Sun Dec 22 04:22:06 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Tweak arg types for a FUNCTION_TYPE. - -Fri Dec 20 17:09:25 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Call grok_{ctor,op}_properties. - -Fri Dec 20 12:17:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++spec.c (lang_specific_driver): Put missing hyphen in front of - arguments we compare against. Start the count of I at 1, not 0, - since argv[0] is still the command. - -Thu Dec 19 11:53:57 1996 Stan Shebs <shebs@andros.cygnus.com> - - * lang-specs.h: Accept .cp as an C++ extension. - -Mon Dec 16 22:43:31 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (ptr_reasonably_similar): Add decl. - -Thu Dec 12 15:00:35 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokvardecl): Change SPECBITS parm to be the SPECBITS_IN - pointer. New local SPECBITS with the parm's value. - (grokdeclarator): Pass &specbits down. - - * parse.y (expr_no_commas): Make sure $$ is not an error_mark_node - before we try to do C_SET_EXP_ORIGINAL_CODE on it. - - * search.c (envelope_add_decl): Check that the CLASSTYPE_CID of - CONTEXT is not 0 before we try to use TYPE_DERIVES_FROM. - - * decl.c (cplus_expand_expr_stmt): Only expand the expr if EXP is - not an error_mark_node. - -Sat Dec 7 17:20:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (TYPE_MAIN_DECL): Use TYPE_STUB_DECL. - * *.c: Use TYPE_MAIN_DECL instead of TYPE_NAME where appropriate. - -Fri Dec 6 14:40:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): When giving an anonymous struct a name, - replace TYPE_NAME instead of TYPE_IDENTIFIER (so TYPE_STUB_DECL is - not affected). - - * typeck2.c (build_m_component_ref): If component is a pointer - to data member, resolve the OFFSET_REF now. - - * call.c (convert_like): Don't go into infinite recursion. - - * pt.c (coerce_template_parms): Use tsubst_expr for non-type args. - - * class.c (finish_struct_1): Set DECL_ARTIFICIAL on the vptr. - * tree.c (layout_basetypes): And on the vbase ptr. - -Thu Dec 5 02:11:28 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (BOOL_TYPE_SIZE): Define in terms of POINTER_SIZE or - CHAR_TYPE_SIZE so bool is always the same size as another type. - - * decl.c (pushtag): Set DECL_IGNORED_P for DWARF, too. - -Tue Dec 3 23:18:37 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (grok_x_components): Remove synthesized methods from - TYPE_METHODS of an anonymous union, complain about member - functions. - * decl.c (shadow_tag): Wipe out memory of synthesized methods in - anonymous unions. - (finish_function): Just clear the DECL_RTL of our arguments. - -Fri Nov 29 21:54:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Emit DWARF debugging info for static data - members. - - * pt.c (tsubst): If t is a stub decl, return the stub decl for type. - -Wed Nov 27 14:47:15 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (build_component_ref): Don't die if COMPONENT isn't a - IDENTIFIER_NODE. - -Wed Nov 27 16:05:19 1996 Michael Meissner <meissner@tiktok.cygnus.com> - - * Make-lang.in (g++-cross$(exeext)): Fix typo. - -Wed Nov 27 08:14:00 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - Make the g++ driver now be a standalone program, rather than one - that tries to run the gcc driver after munging up the options. - * Make-lang.in (g++.c, g++spec.o): New rules. - (g++.o): New rule, based on gcc.o with -DLANG_SPECIFIC_DRIVER - added. - (g++$(exeext)): New rule, based on xgcc rule. - (g++-cross$(exeext)): Now just copies g++$(exeext) over. - * g++spec.c: New file. - * g++.c: Removed file. - -Tue Nov 26 19:01:09 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): Arrange for any temporary values - that have been keep in registers until now to be put into memory. - -Mon Nov 25 15:16:41 1996 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Make-lang.in (c++.stage[1234]): Depend upon stage[1-4]-start, so - that make -j3 bootstrap works better. - -Sun Nov 24 02:09:39 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (pushtag): Do pushdecl for anon tags. - -Thu Nov 21 16:30:24 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (c_expand_return): Fix logic. - (unary_complex_lvalue): Avoid unused warning on address of INIT_EXPR. - -Wed Nov 20 18:47:31 1996 Bob Manson <manson@charmed.cygnus.com> - - * g++.c (main): Make sure arglist has a final NULL entry. Add - PEXECUTE_LAST to the flags passed to pexecute, as otherwise - stdin/stdout of the invoked program are redirected to - nowheresville. - -Tue Nov 19 16:12:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (implicitly_declare): Set DECL_ARTIFICIAL. - -Tue Nov 19 15:48:19 1996 Mike Stump <mrs@cygnus.com> - - * init.c (resolve_offset_ref): Handle obj.vfn better. - * typeck.c (build_component_ref): Set TREE_TYPE on result from - build_vfn_ref. - -Tue Nov 19 13:14:33 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (convert_for_assignment): Also handle anachronistic - implicit conversions from (::*)() to cv void*. - * cvt.c (cp_convert_to_pointer): Likewise. - -Mon Nov 18 17:05:26 1996 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (handle_cp_pragma): Fix bogus warning. - -Mon Nov 18 16:10:43 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert_to_pointer): Avoid thinking a POINTER_TYPE - (METHOD_TYPE) is a TYPE_PTRMEMFUNC_P. - -Thu Nov 14 23:18:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Support DWARF2_DEBUG. - * search.c (dfs_debug_mark): Likewise. - * decl2.c (finish_vtable_vardecl): Likewise. - * decl.c (pushtag, finish_enum): Likewise. - * lex.c (check_newline): Use debug_* instead of calling *out - functions directly. - -Thu Nov 14 15:21:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * Make-lang.in (cplib2.ready): Add else clause to avoid problems - on some picky hosts. - -Wed Nov 13 12:32:07 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): A class has a non-trivial copy - constructor if it has virtual functions. - - * cvt.c (cp_convert): Always call a constructor. - - * call.c (reference_binding): Still tack on a REF_BIND - for bad conversions. - (build_user_type_conversion_1): Propagate ICS_BAD_FLAG. - - * typeck.c (convert_arguments): Pass LOOKUP_ONLYCONVERTING. - (c_expand_return): Likewise. - * typeck2.c (digest_init): Likewise for { }. - * init.c (expand_aggr_init_1): Keep the CONSTRUCTOR handling. - * cvt.c (cp_convert): Handle failure better. - -Wed Nov 13 11:51:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++.c (main): Also set PEXECUTE_SEARCH, to make the invocation - of GCC be path-relative. - -Wed Nov 13 11:27:16 1996 Michael Meissner <meissner@tiktok.cygnus.com> - - * Make-lang.in (g++-cross): G++-cross doesn't need version.o, but - it does need choose-temp.o and pexecute.o. - -Wed Nov 13 07:53:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++.c (error) [!HAVE_VPRINTF]: Put error back for the only time - that we still use it. - (P_tmpdir, R_OK, W_OK, X_OK) [__MSDOS__]: Delete unnecessary macros. - -Wed Nov 13 02:00:26 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_default_init): Avoid calling constructors to - initialize reference temps. - - * cvt.c (convert_to_reference): Fix. - -Tue Nov 12 19:10:07 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert): Simplify for flag_ansi_overloading. - (convert_to_reference): Likewise. - * typeck.c (convert_for_initialization): Likewise. - * init.c (expand_default_init): Likewise. - (expand_aggr_init_1): Likewise. - * cp-tree.h (CONV_NONCONVERTING): Lose. - * typeck.c (build_c_cast): Lose allow_nonconverting parm. - * *.c: Adjust. - * call.c (build_user_type_conversion_1): Assume LOOKUP_ONLYCONVERTING. - -Tue Nov 12 16:29:04 1996 Brendan Kehoe <brendan@canuck.cygnus.com> - - * pt.c (tsubst_expr): Reverse args to expand_start_catch_block. - -Tue Nov 12 15:26:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_aggr_init_1): Don't crash on non-constructor - TARGET_EXPR. - -Tue Nov 12 14:00:50 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++.c: Include gansidecl.h. - (VPROTO, PVPROTO, VA_START): Delete. - (choose_temp_base_try, choose_temp_base, perror_exec, - run_dos) [__MSDOS__]: Delete fns. - (pfatal_with_name): Delete fn. - (temp_filename): Declare like in gcc.c. - (pexecute, pwait, choose_temp_base): Declare from gcc.c. - (error_count, signal_count): Define. - (error): Delete both definitions. - (PEXECUTE_{FIRST,LAST,SEARCH,VERBOSE}): Define from gcc.c. - (pfatal_pexecute): Add fn from gcc.c. - (main): Rename local VERBOSE var to VERBOSE_FLAG. Rewrite the - code to use the pexecute stuff also used by gcc.c. - (MIN_FATAL_STATUS): Define. - * Make-lang.in (g++): Add dependency on and linking with - choose-temp.o and pexecute.o. - - * cp-tree.h: Include gansidecl.h. - (STDIO_PROTO): Delete #undef/#define. - * cvt.c (NULL): Delete #undef/#define. - * expr.c (NULL): Likewise. - * init.c (NULL): Likewise. - * rtti.c (NULL): Likewise. - * xref.c (NULL): Likewise. - - * cp-tree.h (build_user_type_conversion): Add prototype. - * call.c (build_user_type_conversion): Delete prototype. Correct - decl of FLAGS arg to be an int. - * cvt.c (build_user_type_conversion): Likewise. - -Tue Nov 12 12:16:20 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.def: Add TRY_BLOCK and HANDLER. - * except.c (expand_start_catch_block): Support templates. - * parse.y (try_block, handler_seq): Likewise. - * pt.c (tsubst_expr): Support TRY_BLOCK and HANDLER. - -Mon Nov 11 13:57:31 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (current_template_args): New fn. - (push_template_decl): Use it. - * decl.c (grokdeclarator): Use it. - - * decl2.c (build_expr_from_tree): Dereference ref vars. - - * decl.c (grokdeclarator): Generalize handling of TYPENAME_TYPEs in - the decl-specifier-seq. - - * decl.c (grok_op_properties): Don't force the type of a conversion - op to be complete. Don't warn about converting to the same type - for template instantiations. - - * decl2.c (finish_file): Don't call instantiate_decl on synthesized - methods. - -Mon Nov 11 13:20:34 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (get_delta_difference): Remove previous bogusness. - Don't give errors if force is set. - -Fri Nov 8 17:38:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Don't emit debug info. - * decl.c (pushdecl): Lose obsolete code. - (grokdeclarator): Still do the long long thing after complaining. - * search.c (note_debug_info_needed): Don't do anything if we're in a - template. - * method.c (synthesize_method): For non-local classes, - push_to_top_level first. - -Fri Nov 8 11:52:28 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (get_delta_difference): Add no_error parameter. - (build_ptrmemfunc): Call get_delta_difference with no_error set; - we don't want error messages when converting unrelated - pointer-to-member functions. - -Thu Nov 7 11:16:24 1996 Mike Stump <mrs@cygnus.com> - - * error.c (dump_expr): Improve the wording on error messages that - involve pointer to member functions. - -Tue Nov 5 17:12:05 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert_to_pointer): Move code for conversions from - (::*)() to void* or (*)() up a bit, so that we can convert from - METHOD_TYPEs as well. - -Tue Nov 5 14:54:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (get_tinfo_fn): Make sure 'type' is permanent. - There are no 'member' types. - (get_tinfo_fn_dynamic): Diagnose typeid of overloaded fn. - (build_x_typeid): Handle errors. - -Mon Nov 4 17:43:12 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (convert_for_assignment): Handle anachronistic implicit - conversions from (::*)() to void* or (*)(). - * cvt.c (cp_convert_to_pointer): Likewise. - (cp_convert_to_pointer_force): Remove cp_convert_to_pointer - conversions from here. - * decl2.c (lang_decode_option): Add -W{no-,}pmf-conversions. - * lang-options.h: Likewise. - * decl2.c (warn_pmf2ptr): Define. - * cp-tree.h: Declare it. - * typeck2.c (digest_init): Allow pmfs down into - convert_for_initialization. - -Sun Nov 3 09:43:00 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (c_expand_return): Fix for returning overloaded fn. - -Fri Nov 1 08:53:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (DIRECT_BIND): Change from INDIRECT_BIND. - * decl.c (grok_reference_init): Pass DIRECT_BIND. - * cvt.c (build_up_reference): Don't mark 'this' addressable. Use - DIRECT_BIND. - * call.c (convert_like): Don't pass INDIRECT_BIND. - * typeck.c (convert_arguments): Likewise. - * typeck.c (mark_addressable): Allow &this if flag_this_is_variable. - -Thu Oct 31 17:08:49 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (mark_addressable): Support TARGET_EXPR, unify with - similar code in build_up_ref. - * cvt.c (build_up_reference): Drastically simplify. - -Mon Oct 28 12:45:05 1996 Jeffrey A Law (law@cygnus.com) - - * typeck.c (signed_or_unsigned_type): If the given type already - as the correct signedness, then just return it. - - * typeck.c ({un,}signed_type): If can't do anything, call - signed_or_unsigned_type. - -Thu Oct 24 14:21:59 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl2.c (copy_assignment_arg_p): Don't buy the farm if - current_class_type is NULL. - -Wed Oct 23 00:43:10 1996 Jason Merrill <jason@gerbil.cygnus.com> - - * class.c (finish_struct_1): Avoid empty structs by adding a field - so layout_type gets the mode right. - - * typeck.c (c_expand_return): Drastically simplify. - -Mon Oct 21 22:34:02 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (decay_conversion): Handle overloaded methods. - -Fri Oct 18 16:03:48 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): A TARGET_EXPR has side-effects. - -Thu Oct 17 11:31:59 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (convert_to_pointer_force): Add code to support pointer to - member function to pointer to function conversions. - * init.c (resolve_offset_ref): Add code to allow faked up objects, - ignoring them if they are not used, and giving an error, if they - are needed. - * typeck.c (get_member_function_from_ptrfunc): Fold e1 to improve - code, and so that we can give an error, if we needed an object, - and one was not provided. - (build_c_cast): Don't call default_conversion when we want to - convert to pointer to function from a METHOD_TYPE. - -Mon Oct 14 00:28:51 1996 Jason Merrill <jason@yorick.cygnus.com> - - * Make-lang.in (cplib2.ready): Fix logic. - - * decl.c (shadow_tag): Only complain about non-artificial function - members. - - * class.c (finish_struct_1): Add synthesized methods to TYPE_METHODS. - -Fri Oct 11 16:12:40 1996 Jason Merrill <jason@yorick.cygnus.com> - - * expr.c (cplus_expand_expr): Pre-tweak call_target like - expand_inline_function would. - - * pt.c (mark_decl_instantiated): If extern_p, call - mark_inline_for_output. - -Thu Oct 10 15:58:08 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (unary_complex_lvalue): Add code to handle intermediate - pmd conversions. - - * typeck.c (get_delta_difference): Fix wording, as we can be used - for pointer to data members. - -Tue Oct 8 12:43:51 1996 Bob Manson <manson@charmed.cygnus.com> - - * pt.c (tsubst): If the function decl isn't a member of this - template, return a copy of the decl (including copying the - lang-specific part) so we don't hose ourselves later. - -Thu Oct 3 16:24:28 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct): Remove DWARF-specific tag handling. - * decl.c (pushtag): Likewise. - (finish_function): Always clear DECL_ARGUMENTS on function decls with - no saved RTX. - * decl2.c (finish_file): Emit DWARF debugging info for static data - members. - -Wed Oct 2 21:58:01 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl.c (duplicate_decls): Make sure the old DECL_LANG_SPECIFIC - isn't the same as the new one before we whack it. - -Mon Sep 30 13:38:24 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c, cp-tree.h, cvt.c, decl.c, decl2.c, gxx.gperf, hash.h, - lex.c, method.c, parse.y, typeck.c, typeck2.c: Remove - warn_traditional and warn_strict_prototypes; remove ancient - 'overload' code; remove references to flag_traditional. - -Mon Sep 30 12:58:40 1996 Mike Stump <mrs@cygnus.com> - - * input.c (sub_getch): Handle 8-bit characters in string literals. - -Sun Sep 29 03:12:01 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (mapcar): Handle CONSTRUCTORs. - (copy_to_permanent): Handle expression_obstack properly. - - * Make-lang.in (cplib2.txt): Also depend on the headers. - - * rtti.c (get_tinfo_var): Don't assume that POINTER_SIZE == - INT_TYPE_SIZE. - (expand_class_desc): Use USItype for offset field. - * tinfo.h (struct __class_type_info): Likewise. - - * method.c (build_overload_int): TYPE_PRECISION should be applied - to types. - -Sat Sep 28 14:44:50 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_op): A COND_EXPR involving void must be a - builtin. - -Fri Sep 27 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_x_component_ref): New fn. - (build_object_ref): Use it. - * parse.y (primary): Use it. - * decl2.c (build_expr_from_tree): Use it. - * cp-tree.h: Declare it. - - * decl.c (start_decl): variable-sized arrays cannot be initialized. - * error.c (dump_type_suffix): Handle variable arrays. - -Fri Sep 27 13:14:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * Make-lang.in (exception.o): Put back compiling it with -fPIC. - -Fri Sep 27 03:00:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): Don't try to look up anything in a - TYPENAME_TYPE. - - * tinfo2.cc (__throw_type_match_rtti): Oops. - -Thu Sep 26 22:11:05 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * Make-lang.in (exception.o): Use -fno-PIC for now. - -Thu Sep 26 10:59:00 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (build_dynamic_cast): Pass tinfo fns rather than - calling them. - (get_tinfo_fn_dynamic): Extracted from build_typeid. - * tinfo2.cc (__dynamic_cast): Adjust. - - * rtti.c (build_typeid): Use resolves_to_fixed_type_p. - (build_x_typeid): Likewise. - - * parse.y: Call build_x_typeid instead of build_typeid. - * cp-tree.def: Add TYPEID_EXPR. - * pt.c (tsubst_copy): Handle typeid. - * decl2.c (build_expr_from_tree): Likewise. - * rtti.c (build_x_typeid): Throw bad_typeid from here. - (build_typeid): Not here. - * cp-tree.h: Declare build_x_typeid. - -Wed Sep 25 17:26:16 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (convert_like): Pull out constant values. - - * tree.c (mapcar): Use build_cplus_array_type, not build_array_type. - -Wed Sep 25 17:28:53 1996 Michael Meissner <meissner@tiktok.cygnus.com> - - * decl.c (init_decl_processing): Create short int types before - creating size_t in case a machine description needs to use - unsigned short for size_t. - -Tue Sep 24 18:18:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * Make-lang.in (exception.o): Turn off pic. - - * tinfo2.cc (__throw_type_match_rtti): Fix cv-variants of the same - type, multi-level ptr conversions. - - * rtti.c (call_void_fn): Renamed and genericized from throw_bad_cast. - (throw_bad_cast): Use it. - (throw_bad_typeid): New fn. - (build_typeid): Throw bad_typeid as needed. - Use build_call. - (synthesize_tinfo_fn): Handle functions and arrays before checking - for cv-quals. - - * Remove .h from standard C++ headers, add new.h, move into inc - subdirectory. - - * exception*: Remove pointer from object, constructors. Add - default exception::what that uses type_info::name. Add - __throw_bad_typeid. - - * init.c (build_new): Don't add a cookie to new (void *) T[2]. - -Mon Sep 23 15:21:53 1996 Jason Merrill <jason@yorick.cygnus.com> - - * Make-lang.in: Building C++ code depends on cc1plus. - -Mon Sep 23 12:38:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (struct saved_scope): Declare PROCESSING_TEMPLATE_DECL as - a HOST_WIDE_INT, not a tree. - -Mon Sep 23 12:36:02 1996 Jason Merrill <jason@yorick.cygnus.com> - - * exception.cc: Don't include <stdlib.h>. - - * Make-lang.in (c++.clean): Remove cplib2.*. - -Mon Sep 23 09:42:19 1996 Doug Evans <dje@canuck.cygnus.com> - - * parse.y (component_decl_1, component_costructor_declarator case): - Pass attributes/prefix_attributes in tree list. - -Mon Sep 23 01:18:50 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tinfo{,2}.cc: #include <stddef.h> instead of <stdlib.h>. - -Sun Sep 22 05:31:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_identifier): Don't do deferred lookup in a template - header. - - * typeck2.c (store_init_value): Oops. - - * new.{h,cc}, exception.{h,cc}, typeinfo.h, tinfo{2.cc,.cc,.h}: - New files for C++ lang-support library. - * Make-lang.in (CXX_EXTRA_HEADERS): Define. - (CXX_LIB2FUNCS): Define. - And rules for building the C++ lang-support code. - * config-lang.in (headers): Define. - (lib2funcs): Define. - -Sat Sep 21 19:17:28 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (build_expr_from_tree): If CONSTRUCTOR has a type, call - digest_init. - * pt.c (tsubst_copy): Compute type for CONSTRUCTOR. - * typeck2.c (store_init_value): Check for initializing pmf with { } - here. - (process_init_constructor): Not here. - -Thu Sep 19 16:41:07 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (begin_template_parm_list): Increment - processing_template_decl here. - (end_template_parm_list): Not here. - (process_template_parm): No need to add 1 to it now. - * *.c: Use processing_template_decl instead of current_template_parms - to check for being in a template. - - * pt.c (uses_template_parms): Handle SCOPE_REF. Fix CONSTRUCTOR. - (tsubst_copy): Handle CONSTRUCTOR. - (instantiate_decl): Set up context properly for variables. - * decl2.c (build_expr_from_tree): Handle CONSTRUCTOR. - * class.c (finish_struct): Reverse CLASSTYPE_TAGS. - -Wed Sep 18 13:30:20 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (enum tree_node_kind) [GATHER_STATISTICS]: Put the enum back. - -Wed Sep 18 04:24:07 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (make_thunk): Call comdat_linkage before setting the - TREE_CODE. - - * decl2.c (comdat_linkage): Use make_decl_one_only. - (import_export_decl): Likewise. - * decl.c (init_decl_processing): Check supports_one_only instead of - SUPPORTS_WEAK. - -Sat Sep 14 08:34:41 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (grokfield): Tighten checking for access decls. - - * decl.c (make_typename_type): Resolve references to - current_class_type. Set CLASSTYPE_GOT_SEMICOLON. - (lookup_name_real): Types that depend on a template parameter get - an implicit 'typename' unless they're in the current scope. - (start_decl_1): We don't care about incomplete types that depend - on a template parm. - (grokdeclarator): Resolve 'typename's in the type specifier that - refer to members of the current scope. - - * call.c (build_over_call): Remove 'inline called before - definition' diagnostic. - (build_method_call): Likewise. - * decl.c (duplicate_decls): Downgrade 'used before declared - inline' to a warning, only with -Winline. - -Fri Sep 13 17:31:40 1996 Stan Shebs <shebs@andros.cygnus.com> - - * mpw-make.sed: Fix include paths, add @DASH_C_FLAG@ to compile. - -Wed Sep 11 22:38:13 1996 Gerald Baumgartner <gb@cs.purdue.edu> - - * call.c (build_method_call): When calling a signature - default implementation, as in other cases, let instance_ptr simply - be instance. - -Wed Sep 11 22:14:44 1996 Mike Stump <mrs@cygnus.com> - - * parse.y (simple_stmt): Cleanup and use do_poplevel (). - -Wed Sep 11 22:10:48 1996 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_catch_block): Add a pushlevel so that -g - works on hppa and SPARC. - -Wed Sep 11 10:18:06 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (build_indirect_ref): Catch PTR being an error_mark_node. - -Mon Sep 9 19:51:14 1996 Gerald Baumgartner <gb@cs.purdue.edu> - - * call.c (build_over_call): Check first whether DECL_CONTEXT exists - before testing whether it's a signature. - -Sun Sep 8 16:06:57 1996 Gerald Baumgartner <gb@cs.purdue.edu> - - * call.c (build_new_method_call): Don't complain about signature - pointers and references not being an aggr type. - (build_this): If a signature pointer or reference was passed in, - just return it. - (build_new_method_call): If instance is a signature pointer, set - basetype to the signature type of instance. - * sig.c (build_signature_method_call): Deleted basetype and - instance parameters, they can be found as the DECL_CONTEXT of - function and as the first argument passed in. - * cp-tree.h: Changed declaration of build_signature_method_call. - * call.c (build_method_call): Deleted first two arguments in call - of build_signature_method_call. - (build_over_call): Added call to build_signature_method_call. - -Thu Sep 5 16:51:28 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_c_cast): Don't tack a non_lvalue_expr onto a - target_expr. - -Thu Sep 5 10:05:38 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cvt.c (convert_to_reference): Use %#T, not %#D, for error. - -Wed Sep 4 17:16:09 1996 Bob Manson <manson@charmed.cygnus.com> - - * except.c (expand_start_try_stmts): Move to except.c in the backend. - (expand_end_try_stmts): Remove. - - * init.c (perform_member_init): Use add_partial_entry () instead - of directly manipulating lists. - (emit_base_init): Ditto. - -Wed Sep 4 12:14:36 1996 Mike Stump <mrs@cygnus.com> - - * except.c (expand_exception_blocks): Always make sure USE and - CLOBBER insns that came at the end still do, the backend relies - upon this. - -Wed Sep 4 07:44:48 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): We can only use a TARGET_EXPR of the - right type. - -Tue Sep 3 19:26:05 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (convert_to_reference): Revert last change, don't complain - about temp without target decl. - -Tue Sep 3 10:22:56 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (grokdeclarator): Don't core dump when void() is given. - -Tue Sep 3 02:38:56 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (copy_args_p): Don't crash. - -Fri Aug 30 14:26:57 1996 Mike Stump <mrs@cygnus.com> - - * pt.c (tsubst): And support template args inside the exception - specification. - - * pt.c (tsubst): Add support for exception specifications in - template functions. - -Fri Aug 30 10:01:55 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.def (DECL_STMT): Eliminate the throw spec field, only 3 - fields now. - * cp-tree.h (start_decl): Eliminate the throw spec parameter. - (start_function): Likewise. - (start_method): Likewise. - (grokfield): Likewise. - (make_call_declarator): Add throw spec parameter. - (set_quals_and_spec): Add routine. - * lex.c (set_quals_and_spec): Likewise. - * decl.h (grokdeclarator): Eliminate the throw spec parameter. - * decl.c (shadow_tag): Eliminate the throw spec parameter to - grokdeclarator. - (groktypename): Likewise. - (start_decl): Eliminate the throw spec parameter. Eliminate the - throw spec parameter to grokdeclarator. Eliminate the throw spec - field in DECL_STMT. - (cp_finish_decl): Eliminate the throw spec field in DECL_STMT. - (grokfndecl): Remove useless set of raises. - (grokdeclarator): Eliminate the throw spec parameter. Eliminate - the throw spec parameter to start_decl. Pull the throw spec out - of the call declarator. - (grokparms): Eliminate the throw spec parameter to grokdeclarator. - (start_function): Eliminate the throw spec parameter. Eliminate - the throw spec parameter to grokdeclarator. - (start_method): Likewise. - * decl2.c (grokfield): Likewise. - (grokbitfield): Eliminate the throw spec parameter to grokdeclarator. - (grokoptypename): Likewise. - (finish_file): Eliminate the throw spec parameter to - start_function. Add throw spec to make_call_declarator. - * except.c (init_exception_processing): Add throw spec to - make_call_declarator. Eliminate the throw spec parameter to - start_decl. - (expand_start_catch_block): Eliminate the throw spec parameter to - grokdeclarator. - (expand_builtin_throw): Add throw spec to make_call_declarator. - Eliminate the throw spec parameter to start_function. - (start_anon_func): Likewise. - * lex.c (make_call_declarator): Add throw spec parameter. - (set_quals_and_spec): New routine. - (cons_up_default_function): Add throw spec to make_call_declarator. - Eliminate the throw spec parameter to grokfield. - * method.c (synthesize_method): Eliminate the throw spec parameter - to start_function. - * pt.c (process_template_parm): Eliminate the throw spec parameter - to grokdeclarator. - (tsubst): Add throw spec to make_call_declarator. - (tsubst_expr): Eliminate the throw spec parameter to start_decl. - (do_function_instantiation): Eliminate the throw spec parameter to - grokdeclarator. Eliminate the throw spec parameter to - start_function. - * rtti.c (synthesize_tinfo_fn): Eliminate the throw spec parameter - to start_function. - * parse.y (datadef): Remove non-winning optimization. - (decl): Likewise. - (fndef): Remove ambiguous error productions uncovered by grammer - fixing. - (constructor_declarator): Add exception_specification_opt here. - (component_constructor_declarator): Likewise. - (direct_after_type_declarator): Likewise. - (complex_direct_notype_declarator): Likewise. - (direct_abstract_declarator): Likewise. - (fn.def1): Remove exception_specification_opt. - (fn.def2): Likewise. - (condition): Likewise. - (initdcl0): Likewise. - (initdcl): Likewise. - (notype_initdcl0): Likewise. - (nomods_initdcl0): Likewise. - (component_decl_1): Likewise. - (component_declarator): Likewise. - (after_type_component_declarator0): Likewise. - (after_type_component_declarator): Likewise. - (notype_component_declarator): Likewise. - -Wed Aug 28 01:40:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Also use an INIT_EXPR when - initializing anything from an rvalue. - - * call.c (build_over_call): Call stabilize_reference when building - an INIT_EXPR instead of calling the copy ctor. - - * call.c (joust): Extend the previous change to all comparisons. - - * decl2.c, method.c, lex.c: Use MAKE_DECL_ONE_ONLY and - NO_LINKAGE_HEURISTICS. - - * decl2.c (finish_file): Emit any statics that weren't already. - - * typeck.c (build_static_cast): Implement. - * tree.c (build_cplus_new): Handle getting a TARGET_EXPR. - * decl.c (grokparms): Use can_convert_arg instead of - implicit_conversion directly. - (copy_args_p): New fn. - * cvt.c (convert_to_reference): Don't complain about temp with - static_cast. - (build_up_reference): Handle TARGET_EXPRs. - * call.c (build_over_call): Elide unnecessary temps. - (can_convert*): Use new overloading code. - -Tue Aug 27 13:12:21 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c: Move TYPE_PTR*_MACROS ... - * cp-tree.h: To here. - * typeck.c (build_reinterpret_cast): Implement. - - * call.c (add_builtin_candidate): Use TYPE_PTROB_P instead of - ptr_complete_ob. - (joust): If we're comparing a function to a builtin and the worst - conversion for the builtin is worse than the worst conversion for the - function, take the function. - - * typeck.c (build_const_cast): Implement. - (comp_ptr_ttypes_const): Like comp_ptr_ttypes, for const_cast. - (comp_ptr_ttypes_reinterpret): Like cpt, for reinterpret_cast. - -Tue Aug 27 13:14:58 1996 Bob Manson <manson@charmed.cygnus.com> - - * rtti.c (build_dynamic_cast): Don't try to dereference exprtype - too early. Make sure we explode if exprtype turns out to be a - NULL_TREE when it shouldn't be. - -Tue Aug 27 10:56:21 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.h: New routine make_call_declarator. - * lex.c (make_call_declarator): Define it. - * except.c (init_exception_processing): Use it. - (expand_builtin_throw): Likewise. - (start_anon_func): Likewise. - * decl2.c (finish_file): Likewise. - * lex.c (cons_up_default_function): Likewise. - * parse.y: Likewise. - * pt.c (tsubst): Likewise. - -Mon Aug 26 17:40:03 1996 Mike Stump <mrs@cygnus.com> - - * decl2.c (groktypefield): Remove unused code. - -Mon Aug 26 17:00:33 1996 Mike Stump <mrs@cygnus.com> - - * gxx.gperf: Change TYPE_QUAL into CV_QUALIFIER. - * parse.y: Likewise. Change maybe_type_qual into maybe_cv_qualifier. - Change type_quals into cv_qualifiers. Change nonempty_type_quals into - nonempty_cv_qualifiers. - * hash.h: Rebuild. - - * lex.c (make_pointer_declarator): Change type_quals into - cv_qualifiers. - (make_reference_declarator): Likewise. - -Thu Aug 22 01:09:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_function): Only check interface_* for templates - with flag_alt_external_templates. - - * call.c (build_new_op): Check for comparison of different enum types. - (build_over_call): Fix arg # output. - - * typeck.c (build_component_ref): Handle pre-found TYPE_DECL. - -Wed Aug 21 00:13:15 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_new_op): Check for erroneous args. - - * call.c (build_new_method_call): Add missing args to cp_error. - - * tree.c (error_type): Dont print reference-to-array. - - * typeck.c (convert_for_assignment): Don't say contravariance for - removing const. - -Tue Aug 20 13:23:00 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_over_call): Diagnose bad convs for `this'. - - * lex.c (cons_up_default_function): Set DECL_ARTIFICIAL - on _ctor_arg. - - * call.c (convert_like): Handle bad convs. - (build_over_call): Handle bad convs better. - - * decl2.c: -fansi-overloading is now the default. - - * call.c (build_new_method_call): Check for erroneous args. - - * pt.c (instantiate_class_template): Propagate - TYPE_USES_MULTIPLE_INHERITANCE. - -Tue Aug 20 13:09:57 1996 Mike Stump <mrs@cygnus.com> - - * call.c (enforce_access): Add static to routine. - -Sun Aug 18 14:35:54 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_user_type_conversion_1): Fix bad handling. - (compare_ics): Likewise. - -Sat Aug 17 21:54:11 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (standard_conversion): Oops. - -Sat Aug 17 16:28:11 1996 Geoffrey Noer <noer@cygnus.com> - - * g++.c: Update test for win32 (&& ! cygwin32). - -Sat Aug 17 03:45:31 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (comp_ptr_ttypes_real): Handle OFFSET_TYPEs properly. - (ptr_reasonably_similar): New fn. - * call.c (BAD_RANK): New rank. - (ICS_BAD_FLAG): New macro. - (standard_conversion): Handle almost-right pointer conversions. - (reference_binding): Handle bad rvalue bindings. - (add_*_candidate): Stuff. - (build_over_call): Pass bad conversions to convert_for_initialization. - (compare_ics): Handle bad convs. - (joust): Likewise. - -Fri Aug 16 15:02:19 1996 Bob Manson <manson@charmed.cygnus.com> - - * init.c (expand_vec_init): Use ptrdiff_type_node instead of - integer_type_node when computing pointer offsets. - -Fri Aug 16 01:28:32 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (lvalue_type): New fn. - (error_type): New fn. - * call.c (op_error): Use error_type. - (add_conv_candidate): Use lvalue_type. - (add_builtin_candidates): Likewise. - * error.c (args_as_string): Use error_type. - -Thu Aug 15 17:27:13 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Evaluate DECL_INITIAL of a VAR_DECL here. - (tsubst): Not here. - - * decl.c (init_decl_processing): With -ansi, __null's type is the - signed integral type with the same number of bits as a pointer. - Introduce a new variable null_node for it. - * cp-tree.h: Adjust. - * call.c (null_ptr_cst_p): Adjust. - -Thu Aug 15 17:09:54 1996 Mike Stump <mrs@cygnus.com> - - * except.c (do_unwind): Mark %i7 as used on the SPARC so we can - optimize. - -Thu Aug 15 01:36:49 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_decl): Ignore #pragma interface for tinfo - fns of classes without virtual functions. - - * call.c (add_function_candidate): Handle `this' specially. - (compare_ics): Likewise. - -Tue Aug 13 12:16:10 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_conditional_expr): Fix handling of __null. - - * decl2.c (comdat_linkage): New fn. - (import_export_vtable): Use it. - (import_export_decl): Use it. - * method.c (make_thunk): Use it. - -Mon Aug 12 00:09:18 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (end_template_decl): If we don't actually have parms, return. - * parse.y (template_header): Accept 'template <>'. - - * errfn.c: Allow 5 args. - -Sun Aug 11 15:20:58 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (make_temp_vec): New fn. - * pt.c (push_template_decl): Handle partial specs. - (instantiate_class_template): Likewise. - (more_specialized): Use get_bindings. - (more_specialized_class): New fn. - (get_class_bindings): New fn. - (most_specialized_class): New fn. - (do_function_instantiation): List candidates for ambiguous case. - * decl.c (duplicate_decls): Lose reference to DECL_TEMPLATE_MEMBERS. - (shadow_tag): Call push_template_decl for partial specializations. - * parse.y: Likewise. - * cp-tree.h (DECL_TEMPLATE_SPECIALIZATIONS): Replaces - DECL_TEMPLATE_MEMBERS. - * call.c (print_z_candidates): Reduce duplication. - -Fri Aug 9 14:36:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (lang_decode_option): Allow -fansi-overloading. - -Thu Aug 8 17:04:18 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (get_bindings): New fn. - (most_specialized): Likewise. - (do_function_instantiation): Use them. - (add_maybe_template): New fn. - * cp-tree.h (DECL_MAYBE_TEMPLATE): New macro. - * call.c (build_new_op): Handle guiding decls. - (build_new_function_call): Likewise. - * decl2.c (finish_file): Likewise. - - * decl2.c (mark_used): Do synthesis here. - * call.c (build_method_call): Not here. - (build_over_call): Or here. - * typeck.c (build_function_call_real): Or here. - * tree.c (bot_manip): Call mark_used on functions used in default - args. - -Thu Aug 8 17:48:16 1996 Michael Meissner <meissner@tiktok.cygnus.com> - - * decl2.c (import_export_vtable): Delete code that disabled vtable - heuristic on systems with ASM_OUTPUT_EXTERNAL. - -Wed Aug 7 12:44:11 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_x_function_call): Handle static call context - better. - - * decl.c (finish_function): Set the DECL_CONTEXT of the result to - the function, not its outer block. - - * call.c (build_field_call): Pass fields on to build_opfncall - regardless of TYPE_OVERLOADS_CALL_EXPR. - (build_method_call): Pass on to build_new_method_call sooner. - - * typeck.c (build_ptrmemfunc): Just return what instantiate_type - gives us. - * class.c (instantiate_type): Don't put a POINTER_TYPE to - METHOD_TYPE on an expression. Also make a copy of rhs instead of - modifying it. - -Tue Aug 6 12:58:46 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (compare_ics): Handle qual_conv after lvalue_conv. - (add_builtin_candidate): Don't take enums for ++. - (build_new_method_call): Handle non-aggregates and field calls. - Move new overloading code from... - * cvt.c: Here. - - * decl.c (grokparms): Don't check default args in templates. - -Mon Aug 5 17:17:06 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_new_op): Fix args to build_unary_op. - (add_builtin_candidates): Don't call type_promotes_to on float. - - * decl.c (grokparms): Check the type of the default arg. - - * cvt.c (build_new_op): Pass non-overloaded cases on rather than - returning NULL_TREE. - - * typeck.c (build_x_binary_op): Avoid doing extra work. - (build_x_unary_op): Likewise. - (build_x_conditional_expr): Likewise. - * cvt.c (build_over_call): Return. - (add_builtin_candidate): Fix MEMBER_REF. - (build_new_op): Likewise. - -Mon Aug 5 17:07:47 1996 Mike Stump <mrs@cygnus.com> - - * method.c (build_overload_name): Put bug fix into code but leave - disabled for now so we can be bug compatible with older releases - that do repeats incorrectly. In the future, we can enable it. - -Mon Aug 5 13:46:28 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (convert_like): Don't call build_cplus_new twice. - - * call.c, cp-tree.h, cvt.c, decl2.c, init.c, method.c, pt.c, typeck.c: - Control new overloading code with -fansi-overloading. - -Sun Aug 4 15:29:11 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_over_call): Call build_cplus_new. - * call.c (build_method_call): Likewise. - * typeck.c (build_function_call_real): Likewise. - (build_conditional_expr): If both operands are TARGET_EXPRs, wrap - the COND_EXPR in a TARGET_EXPR so they use the same slot. - - * cvt.c (build_up_reference): Propagate INDIRECT_BIND to - recursive calls. - * typeck.c (complete_type): Propagate - TYPE_NEEDS_{CONSTRUCTING,DESTRUCTOR}. - -Sat Aug 3 14:05:07 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (joust): More ?: kludging. Sigh. - (build_over_call): Don't try to synthesize global fns. - - * search.c (lookup_conversions): Use binfo marking. - -Sat Aug 3 12:33:42 1996 Bob Manson <manson@charmed.cygnus.com> - - * search.c (build_mi_matrix): Use the correct value of cid - when determining the new mi_size. - -Sat Aug 3 01:27:41 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (add_builtin_candidates): Do consider type conversion ops - for the first parms of += et al. - (strip_top_quals): New fn. - (reference_binding): Use it instead of TYPE_MAIN_VARIANT. - (implicit_conversion): Likewise. - (add_builtin_candidates): Be careful about arrays. - (build_new_method_call): Handle vtable optimization. - -Fri Aug 2 01:26:59 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h (LOOKUP_NO_TEMP_BIND): New flag. - * cvt.c (reference_binding): Use it. - (implicit_conversion): Use it. - (add_builtin_candidate, COND_EXPR): Use it. - - * cvt.c (build_new_function_call): Check for error args. - - * typeck.c (comptypes): Just check DERIVED_FROM_P, not UNIQUELY. - - * gxx.gperf: Add __null. - * hash.h: Regenerate. - * lex.h: Add RID_NULL. - * lex.c (init_lex): Create null_pointer_node here, stick it in - RID_NULL. - * decl.c (init_decl_processing): Still set its type here. - * cvt.c (cp_convert_to_pointer): Don't produce null_pointer_node. - (convert_to_pointer_force): Likewise. - (null_ptr_cst_p): Check for null_pointer_node; only accept (void*)0 - if (! pedantic). - * call.c (convert_harshness): Use null_ptr_cst_p. - * typeck.c (convert_for_assignment): Likewise. Don't produce - null_pointer_node. - - * error.c (args_as_string): Handle lists of actual args, too. - * cvt.c (null_ptr_cst): Support (void*)0 for now. - (build_user_type_conversion_1): Improve diagnostics. - (build_new_function_call): Likewise. - (build_object_call): Likewise. - (build_new_method_call): Likewise. Move call before def diagnostic... - (build_over_call): Here. - - * cvt.c (build_new_method_call): Don't complain about no match if - LOOKUP_SPECULATIVELY. - (build_over_call): Fix 'this' for virtual fn. - (build_new_method_call): Add diagnostic. - -Thu Aug 1 16:45:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (add_function_candidate): Expect 'this' and 'in_chrg' for - constructors to be passed in. - (build_over_call): Likewise. - (build_user_type_conversion_1): Pass them in. - (convert_like): Likewise. - (build_object_call): Handle overloaded conversions. - (build_over_call): Pass the right args to build_vfn_ref. - (standard_conversion): Fix pmf convs. - (joust): Handle comparing statics and non-statics. - (build_new_method_call): New fn. - * call.c (build_method_call): Call it if NEW_OVER. - -Thu Aug 1 16:06:14 1996 Mike Stump <mrs@cygnus.com> - - * lex.c (do_identifier): Don't use %O on IDENTIFIER_OPNAME_Ps, use - %D instead. - -Thu Aug 1 15:24:02 1996 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Use maybe_build_cleanup_and_delete - instead of just maybe_build_cleanup so that we deallocate the - thrown object. - -Thu Aug 1 15:18:00 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (finish_prevtable_vardecl): Make non-static for pt.c's use. - * cp-tree.h (finish_prevtable_vardecl): Add decl. - -Thu Aug 1 11:53:51 1996 Bob Manson <manson@charmed.cygnus.com> - - * pt.c (instantiate_class_template): Call complete_type. Also, if - we're at the end of the file and we just instantiated a template - class with a vtable, call finish_prevtable_vardecl. - - * error.c (dump_decl): Don't explode (or explode more gracefully - as appropriate) if the object being dumped has a null type. - (dump_expr): Likewise. - - * search.c (build_mi_matrix): Ensure that mi_size is large enough, - by counting the number of nodes that we'll need before allocating - the array. - (lookup_fnfields): Fix comment. - (breadth_first_search): Fix comment. - -Wed Jul 31 09:57:05 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Propagate TYPE_PACKED and - TYPE_ALIGN. - * class.c (finish_struct): Call cplus_decl_attributes here. - (finish_struct_1): Not here. - * cp-tree.h: Adjust. - - * pt.c (type_unification): New parameter STRICT. - (unify): If STRICT, don't allow cv addition or base deduction. - * call.c, class.c, cvt.c, cp-tree.h: Adjust. - -Tue Jul 30 13:06:13 1996 Jason Merrill <jason@yorick.cygnus.com> - - * search.c (get_template_base{_recursive}): New fns. - * pt.c (more_specialized): New fn. - (do_function_instantiation): Use it. - (unify): Handle base deduction. - * cvt.c (joust): Use more_specialized. - Don't arbitrarily choose between non-builtin candidates. - (build_over_call): Call require_complete_type. - - * decl.c (start_function): Statics are static even in a #pragma - interface file. - - * decl2.c (import_export_vtable): Disable vtable heuristic on - systems with ASM_OUTPUT_EXTERNAL. - - * cvt.c (compare_ics): Fix comparison of PMEM_CONV and BASE_CONV. - (standard_conversion): No std conv to enum type. - - * cvt.c (standard_conversion): Fix order of args to DERIVED_FROM_P - for ptm's. - - * cvt.c (reference_binding): Bind directly to a base subobject of - a class rvalue. - - * cvt.c (build_new_op): Enforce access control. - -Tue Jul 30 09:22:53 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck2.c (process_init_constructor): When scanning the - union for a named field, skip things that aren't FIELD_DECLs. - - * method.c (synthesize_method): Don't scan fndecl's rtl if - we're at the end of the file; just assume the function can't - be inlined. - -Mon Jul 29 15:48:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_builtin_candidate): Stick a dummy conversion in if - it failed. - - * cvt.c (build_user_type_conversion_1): Handle overloaded - conversion ops. - - * cvt.c (add_builtin_candidates): Don't consider type conversion - operators for the first parameter of operator=. - -Mon Jul 29 15:33:55 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (complete_type): Only call layout_type if we're not - expanding a template. - -Mon Jul 29 14:40:38 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (compare_ics): Oops. - - * cvt.c (op_error): Oops. - - * cp-tree.def: Add RVALUE_CONV, rename EXACT_CONV to IDENTITY_CONV. - * cvt.c: Add IDENTITY_RANK before others. Use real_lvalue_p. - (build_conv): Use them. - (implicit_conversion): Use them. - (convert_like): Handle them. - (build_new_op): Handle builtin COND_EXPR again. - (add_builtin_candidates): Strip cv-quals. Fix oops. Include enums - in lists of types for COND_EXPR. - (add_builtin_candidate): Add enum candidates for COND_EXPR. - -Mon Jul 29 12:05:40 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (build_modify_expr): Always attempt to build a call to - the assignment operator, even if we're using a default one. - (convert_for_initialization): Call complete_type. - -Mon Jul 29 11:25:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (reference_binding): A REF_BIND gets the reference type. - (implicit_conversion): Likewise. - (convert_like): Likewise. - (compare_ics): Likewise. - (compare_qual): Likewise. - (print_z_candidates): Handle no candidates. - (build_new_op): Don't handle builtin COND_EXPR for now. - -Sat Jul 27 11:27:47 1996 Stan Shebs <shebs@andros.cygnus.com> - - * cvt.c (build_builtin_candidate): Init local var in an ANSI way. - -Fri Jul 26 01:07:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (joust): If the candidates are the same, arbitrarily pick one. - - * cvt.c (build_builtin_candidate): Oops. - (build_new_op): Oops. - - * method.c (build_opfncall): Pass COND_EXPR on. - * cvt.c (build_builtin_candidate): Reorganize, support COND_EXPR. - (add_builtin_candidate{,s}): Likewise. - (add_builtin_candidates): Likewise. - (print_z_candidates, op_error, build_new_op): Likewise. - (type_decays_to): New fn. - * lex.c (init_lex): Just say ?: for COND_EXPR. - -Thu Jul 25 09:33:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (complete_type): Call layout_type rather than building - a new array type. - - * cvt.c (add_builtin_candidate): Pointer arithmetic candidates - only use ptrdiff_t. - -Wed Jul 24 12:45:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c: Always compile the new overloading code (but don't use it). - (implicit_conversion): Add a BASE_CONV when converting to - the same class type. - (convert_like): Handle BASE_CONV. - -Tue Jul 23 12:46:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_new_op): Support {MAX,MIN}_EXPR. - (add_builtin_candidate): Likewise. - - NEW_OVER changes: - * typeck.c (build_x_function_call): Try an operator function - whenever we call an object of class type. - * method.c (build_opfncall): Pass CALL_EXPRs through. - * cvt.c (implicit_conversion): Do const-ref case first. - (add_conv_candidate, build_object_call, op_error): New fns. - (ptr_complete_ob, TYPE_PTROB_P): void is not an object type. - ({add,build}_builtin_candidate{,s}, print_z_candidates): Display - builtin candidates. - (build_new_op): Handle CALL_EXPR. Don't try to decay void. - Fall back on preincrement handling. Use op_error. - Handle warn_synth. - (convert_like): Pass INDIRECT_BIND. Don't try to do anything with - an error_mark_node. - (build_over_call): Handle PROMOTE_PROTOTYPES and ellipsis promotions - properly. - -Mon Jul 22 16:21:55 1996 Bob Manson <manson@charmed.cygnus.com> - - * pt.c (tsubst_expr): Handle CONTINUE_STMT. - -Mon Jul 22 15:38:58 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_component_ref_1): Use build_component_ref - instead of open coding it here. - -Mon Jul 22 12:18:54 1996 Jason Merrill <jason@yorick.cygnus.com> - - * g++.c (main): Don't link with -lg++. - - NEW_OVER changes: - * cvt.c (convert_to_reference): Don't use convert_from_refeence on - result of build_type_conversion. - (cp_convert): Only call build_method_call for ctors if - build_type_conversion failed. - (ptr_complete_ob): New function. - (TYPE_PTR{,OB,MEM}_P): New macros. - ({add,build}_builtin_candidate{,s}): New functions. - (print_z_candidates): Handle builtins. - (build_user_type_conversion_1): Don't use conversion fns for - converting to a base type. - (build_user_type_conversion_1): Set ICS_USER_FLAG on AMBIG_CONVs. - (build_user_type_conversion): Use convert_from_reference. - (build_new_op): New function. - (build_over_call): Fix handling of methods. - (compare_ics): Handle AMBIG_CONV properly. - * typeck2.c: Increment abort count. - * method.c (build_opfncall): Forward most requests to build_new_op. - * cp-tree.h (IS_OVERLOAD_TYPE): Tweak. - -Fri Jul 19 17:59:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * error.c (dump_expr, case CONSTRUCTOR, case CAST_EXPR): Take out - invalid second argument to dump_expr_list. - -Fri Jul 19 14:04:05 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (lookup_name_real): Make sure we do obj->X::i correctly. - -Thu Jul 18 14:48:23 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl2.c (import_export_vtable): ASM_OUTPUT_EXTERNAL, not - ASSEMBLE_EXTERNAL. - -Mon Jul 15 17:48:43 1996 Mike Stump <mrs@cygnus.com> - - * typeck2.c (process_init_constructor): New pedwarn for using { } - to initialize a pointer to member function. - * typeck.c (build_ptrmemfunc1): Avoid use of digest_init so that - we can avoid the new error. - -Mon Jul 15 15:42:03 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_ptrmemfunc1): New function to hide details of - pointer to member functions better. - -Mon Jul 15 14:23:02 1996 Mike Stump <mrs@cygnus.com> - - * init.c (resolve_offset_ref): Resolve OFFSET_REFs that are - methods into the actual method, as we know the implied object is - not used. - -Mon Jul 15 13:08:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (maybecomma_warn): Only emit the pedwarn if we're not - inside a system header. - -Fri Jul 12 16:30:05 1996 Bob Manson <manson@charmed.cygnus.com> - - * call.c (build_method_call): Call complete_type on the - instance type. - -Thu Jul 11 17:16:40 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_component_ref): Always build up an OFFSET_REF - for obj_ptr->func so that we can know which object to use in a - method call. - -Wed Jul 10 19:36:37 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_ptrmemfunc): Remove sorry, now we can cast - around things. Also improve maintainability. - -Wed Jul 10 18:20:11 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl.c (grokdeclarator): Check for overflow when evaluating an - array dimension. - -Wed Jul 10 17:26:19 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert): Don't check for ambiguity with constructor - if NEW_OVER. - - * typeck.c (build_x_function_call): Pass function overload - questions to new overloading code if NEW_OVER. - * init.c (expand_aggr_init_1): Only check for type conversion ops - if we're doing copy-initialization (i.e. LOOKUP_ONLYCONVERTING). - Don't check for ambiguity with constructor if NEW_OVER. - * cvt.c (convert_to_reference): Dereference the result of a type - conversion operator. - (build_conv): Propagate ICS_USER_FLAG. - (implicit_conversion): Call instantiate_type. - Pass LOOKUP_ONLYCONVERTING instead of LOOKUP_NORMAL. - (add_function_candidate): Fix cv-quals on argtype. - (print_z_candidates): New function. - (build_new_function_call): Call it. - (build_user_type_conversion_1): If LOOKUP_ONLYCONVERTING, don't - consider non-converting constructors. - Call print_z_candidates. - Return an AMBIG_CONV for an ambiguous conversion. - (build_user_type_conversion): Handle AMBIG_CONV. - (convert_like): Fix test for building TARGET_EXPR. - Call instantiate_type. - Handle AMBIG_CONV and LVALUE_CONV. - (build_over_call): Handle 0 args and ellipsis. - * cp-tree.def: Add AMBIG_CONV. - -Tue Jul 9 17:48:48 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (lookup_name_real): If we find mem in obj when parsing - `obj->mem', make sure we return the right value. - -Tue Jul 9 16:11:28 1996 Bob Manson <manson@charmed.cygnus.com> - - * search.c (get_base_distance): Call complete_type. - -Tue Jul 9 12:46:34 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (store_bindings): Make static. - -Mon Jul 8 16:42:31 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (expand_aggr_init_1): Don't check type conversions if - NEW_OVER. - - * cvt.c (z_candidate): Put back template field. - (add_function_candidate): Set it. - (add_template_candidate): Likewise. - (joust): Use it. - (compare_qual): Handle references and pointers to members. - (compare_ics): Handle reference bindings. - - * decl.c (duplicate_decls): Propagate DECL_ONE_ONLY. - -Mon Jul 8 16:18:56 1996 Bob Manson <manson@charmed.cygnus.com> - - * call.c (compute_conversion_costs): Call complete_type. - - * tree.c (vec_binfo_member): Use comptypes instead of comparing - pointers, so we can handle template parameters. - -Fri Jul 5 16:51:53 1996 Bob Manson <manson@charmed.cygnus.com> - - * cvt.c (cp_convert_to_pointer): We have to call complete_type - here; let's make it explicit instead of a side effect of an - error check. - -Wed Jul 3 16:29:51 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (z_candidate): Remove template field. - (reference_binding): Handle binding to temporary. - (implicit_conversion): Likewise. - (add_function_candidate): Handle artificial constructor parms. - Handle functions with too few parms. - (add_template_candidate): New function. - (build_user_type_conversion_1): Handle constructors. - (convert_like): Likewise. - (build_over_call): Likewise. - (build_new_function_call): Support templates. - (compare_ics): Fix reference, inheritance handling. - -Mon Jul 1 22:58:18 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl.c: Add signed_size_zero_node. - (init_decl_processing): Build it. - * class.c (prepare_fresh_vtable): Use it instead of size_zero_node - when we're trying to make a negative delta. - -Mon Jul 1 17:56:19 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - Stop doing this damn index==strchr variable name confusion. - * class.c (add_virtual_function): Change local var INDEX to be - named IDX. - (add_method): Likewise. - * lex.c (print_parse_statistics): Likewise. - * search.c (make_memoized_table_entry): Likewise. - (lookup_fnfields_here): Likewise. - (lookup_field): Likewise. - (lookup_fnfields): Likewise. - (get_baselinks): Likewise. - * sig.c (build_signature_table_constructor): Likewise. - (build_signature_method_call): Likewise. - * typeck.c (build_x_array_ref): Change INDEX parm to be named IDX. - (get_member_function_from_ptrfunc): Likewise. - (build_ptrmemfunc): Change local var INDEX to be IDX. - (c_expand_start_case): Likewise. - -Sat Jun 29 14:05:46 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Move user-defined type conversion - handling to before extraction of TYPE_PTRMEMFUNC_FN_TYPE. - (convert_to_reference): Use build_type_conversion to convert to - the reference type directly. - (standard_conversion): Fix void* case, non-conversions. - (reference_binding): Fix expr == 0 case, non-conversions. - (convert_like): Support REF_BIND. - (compare_qual): Split out from compare_ics. - (compare_ics): Use it, handle icses with only a qual_conv. - - * init.c (expand_vec_init): Don't crash if decl is NULL. - -Fri Jun 28 11:52:51 1996 Stan Shebs <shebs@andros.cygnus.com> - - * mpw-config.in: New file, configury for Mac MPW. - * mpw-make.sed: New file, makefile editing for MPW. - -Thu Jun 27 15:18:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Call repo_template_used. - - * search.c (lookup_conversions): Only lookup conversions in - complete types. - -Thu Jun 27 12:59:53 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.def: Renamed from tree.def, to avoid confusion with - gcc's tree.def. - * cp-tree.h, lex.c: Include cp-tree.def. - * Makefile.in (CXX_TREE_H): Reference cp-tree.def. - -Wed Jun 26 18:29:47 1996 Bob Manson <manson@charmed.cygnus.com> - - * init.c (build_vec_delete_1): Call complete_type. - -Mon Jun 24 17:17:32 1996 Mike Stump <mrs@cygnus.com> - - * except.c (start_anon_func): Make sure anonymous functions are - never external. - -Fri Jun 21 15:10:58 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (finish_function): If function_depth > 1, set nested. - - * decl2.c (grokbitfield): Revert Bob's change. - * class.c (finish_struct_1): Fix handling of named bitfield widths. - -Thu Jun 20 23:35:38 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (add_pending_template): Handle types. - (lookup_template_class): With -fexternal-templates, just add the class - to pending_templates instead of instantiating it now. - * decl2.c (finish_file): Handle types in pending_templates. - -Thu Jun 20 14:08:40 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl2.c (grokbitfield): Handle constant decls appropriately. - Give an appropriate error message now instead of spewing core - later. - -Thu Jun 20 13:01:51 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c: Don't turn on thunks by default for now. - -Wed Jun 19 11:37:04 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (complete_type): Handle error_mark_node. - (common_type, OFFSET_TYPE): Handle template_type_parms. - -Tue Jun 18 10:02:15 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): If at_eof, call import_export_decl - regardless of DECL_INLINE. - - * typeck.c (mark_addressable): Set TREE_ADDRESSABLE on CONSTRUCTORs. - - * class.c (finish_struct_bits): Copy TYPE_SIZE. - - * rtti.c (build_dynamic_cast): Support templates. - * tree.def: Support DYNAMIC_CAST_EXPR. - * pt.c (tsubst_copy): Likewise. - * decl2.c (build_expr_from_tree): Likewise. - -Mon Jun 17 15:23:36 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_static_cast): Support templates. - (build_const_cast): Likewise. - * tree.def: Support CONST/STATIC_CAST_EXPR. - * pt.c (tsubst_copy): Likewise. - * decl2.c (build_expr_from_tree): Likewise. - -Sun Jun 16 12:33:57 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Don't trust - TREE_SYMBOL_REFERENCED for vtables of local classes. - -Fri Jun 14 18:13:36 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_copy): Handle operator T. - -Wed Jun 12 17:52:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_delete): Move creation of PARMS inside test of - TYPE_HAS_DESTRUCTOR, since it's never used outside of that block. - -Tue Jun 11 15:09:18 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (build_conditional_expr): Don't assume that - the arguments to ?: are always pointers or records. - -Tue Jun 11 13:56:23 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_decl): Still emit static/weak/comdat - copies of inline template functions with -fno-implicit-templates. - -Tue Jun 11 11:42:13 1996 Bob Manson <manson@charmed.cygnus.com> - - * init.c (build_delete): Determine the complete basetype - path to the destructor we're calling. - -Fri Jun 7 15:30:10 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl.c (build_enumerator): Always copy the INTEGER_CST used to - initialize the enum, because we really and truly don't know where - it came from. - (start_enum): Don't copy integer_zero_node because - build_enumerator will do it. - -Fri Jun 7 11:11:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (finish_function): Do access control on base destructors. - - * pt.c (tsubst, case FUNCTION_DECL): Set up - IDENTIFIER_GLOBAL_VALUE for member functions so pushdecl doesn't - hose us. - -Fri Jun 7 10:37:33 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): If we have already extended the - lifetime of the temporary, don't try it again. - * typeck.c (c_expand_return): Don't try and convert the return - value twice when we want a reference, once is enough. - -Tue Jun 4 15:41:45 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_expr, case DECL_STMT): Don't pass - LOOKUP_ONLYCONVERTING at all for now. - - * search.c (add_conversions): Put the conversion function in - TREE_VALUE, the basetype in TREE_PURPOSE. - * cvt.c (build_type_conversion): Adjust. - * cvt.c (build_expr_type_conversion): Adjust. - * call.c (user_harshness): Adjust. - -Mon Jun 3 15:30:52 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (emit_thunk): Pretend this is a FUNCTION_DECL for the - backend's benefit. - -Mon Jun 10 18:58:19 1996 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_catch_block): Add a dummy region, if we - get an error, so that we can avoid core dumping later. - -Fri May 31 14:56:13 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (OFFSET_REF): Remove. - * tree.def (CP_OFFSET_REF): Rename to OFFSET_REF. - * expr.c (cplus_expand_expr): Cleanup callers of expand_expr. - * init.c (expand_aggr_init_1): Likewise. - (build_new): Likewise. - * typeck.c (expand_target_expr): Likewise. - -Fri May 31 14:22:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_modify_expr): Don't use TREE_VALUE on a - TARGET_EXPR. - -Wed May 29 17:04:33 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): Redo how and when temporaries are - created. - * decl.c (grok_reference_init): Don't try and be smart about - running cleanups. - -Wed May 29 16:02:08 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): Add NULL_TREE to all calls to build - (TARGET_EXPR...), now that it has 4 arguments. - * tree.c (build_cplus_new): Likewise. - -Thu May 23 16:40:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * error.c (dump_expr, case CAST_EXPR): Handle T() properly. - - * pt.c (instantiate_decl): Don't call push/pop_cp_function_context. - * decl.c (struct saved_scope): Remove named_labels, - {base,member}_init_list. - (maybe_push_to_top_level): Don't set them. Call - push_cp_function_context if appropriate. - (pop_from_top_level): Likewise. - - * method.c (do_build_assign_ref): Remove obsolete check of - TYPE_HAS_ASSIGN_REF (basetype). - - * decl.c (grokfndecl): Diagnose user definition of - implicitly-declared methods. - -Thu May 23 12:13:08 1996 Bob Manson <manson@charmed.cygnus.com> - - * method.c (do_build_copy_constructor): Add code to give - meaningful error messages instead of crashing. - (do_build_assign_ref): Don't synthesize assignment operators for - classes containing reference or const members. - - * class.c (struct base_info): Remove cant_synth_copy_ctor - and cant_synth_asn_ref. - (finish_base_struct): Remove the code that tries to conditionalize - synthesis of copy constructors & assignment operators based on - access permissions. Instead, let it fail when it tries to - synthesize the copy constructor. This will give meaningful error - messages instead of silently generating code to perform a bitcopy. - -Wed May 22 11:45:19 1996 Bob Manson <manson@charmed.cygnus.com> - - * lex.c (real_yylex): Remove old-n-crufty #if 0 code for - determining types for constant values. - - * decl.c (struct named_label_list): Use instead of stuffing - random items into a TREE_LIST node. - (named_label_uses): Use the new struct. - (poplevel): Likewise. - (lookup_label): Likewise. - (define_label): Add an error message to tell the user the line - where the goto is located in addition to the destination of the - goto. - (init_decl_processing): Use NULL instead of NULL_TREE to initialize - named_label_uses. - (finish_function): Likewise. - - (start_decl): Complain about defining a static data member - in a different type from which it was declared. - -Wed May 22 09:33:23 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_expr_type_conversion): Adjust. - -Tue May 21 11:21:56 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (build_method_call): Always convert 'this' to the - appropriate type. - - * search.c (add_conversions): Put the conversion function in - TREE_VALUE, the type in TREE_PURPOSE. - * cvt.c (build_type_conversion): Adjust. - * call.c (user_harshness): Adjust. - - * method.c (emit_thunk): Call temporary_allocation and - permanent_allocation around the ASM_OUTPUT_MI_THUNK case, too. - - * tree.c (build_cplus_array_type): Handle tweaking of - TYPE_MAIN_VARIANT here. - * typeck.c (common_type): Not here. - - * typeck.c (complete_type): Only try to complete an array type if - it has a domain. - -Mon May 20 14:55:59 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokvardecl): Call complete_type. - (grokdeclarator): Call complete_type for PARM_DECLs. - -Fri May 17 16:41:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Re-set - CLASSTYPE_GOT_SEMICOLON after calling finish_struct_1. - -Fri May 17 14:56:55 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (cp_expand_decl_cleanup): Remove, the backend is now - smart enough to do it right. - * tree.c (cp_expand_decl_cleanup): Likewise. - * decl.c (cp_finish_decl): Use expand_decl_cleanup instead of - cp_expand_decl_cleanup. - (store_parm_decls): Likewise. - (hack_incomplete_structures): Likewise. - * except.c (push_eh_cleanup): Likewise. - -Fri May 17 13:13:51 1996 Mike Stump <mrs@cygnus.com> - - * expr.c (expand_expr, cond UNSAVE_EXPR): Move from the C++ - frontend to the backend where it belongs. - * tree.c (unsave_expr): Likewise. - (unsave_expr_now): Likewise. - * tree.def (UNSAVE_EXPR): Likewise. - * cp-tree.h (unsave_expr): Likewise. - (unsave_expr_now): Likewise. - -Fri May 17 11:02:41 1996 Mike Stump <mrs@cygnus.com> - - * init.c (emit_base_init): Make sure the partial EH cleanups live - on the function_obstack. - -Thu May 16 15:29:33 1996 Bob Manson <manson@charmed.cygnus.com> - - * expr.c (do_case): Don't try to dereference null TREE_TYPEs - when checking for pointer types. - -Thu May 16 13:38:58 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Remove obsolete check for - access declarations. - -Thu May 16 13:34:15 1996 Mike Stump <mrs@cygnus.com> - - * call.c (build_overload_call): Simplify calls to - build_overload_call by removing last parameter. - (build_method_call): Likewise. - * cp-tree.h: Likewise. - * method.c (build_opfncall): Likewise. - * typeck.c (build_x_function_call): Likewise. - -Thu May 16 13:15:43 1996 Mike Stump <mrs@cygnus.com> - - * call.c (default_parm_conversions): Factor out common code. - (build_method_call): Use it. - (build_overload_call_real): Use it. - -Wed May 15 14:46:14 1996 Mike Stump <mrs@cygnus.com> - - * call.c (build_method_call): Allow implicit & on METHOD_TYPEs, - but pedwarn as the code is bogus. - * typeck.c (decay_conversion): Likewise. - (build_function_call_real): Use build_addr_func instead of - default_conversion. Don't allow pointer-to-method functions down - here. - (build_unary_op): Use real pointer-to-member functions instead of - fake ones. - (build_ptrmemfunc): Use build_addr_func instead of build_unary_op. - (convert_for_assignment): Removed some obsolete code. - * decl2.c (reparse_absdcl_as_expr): Pass current_class_ref to - build_x_function_call instead of current_class_ptr. Only call - digest_init once on an initializer, we do this just checking - TREE_TYPE. - (build_expr_from_tree): Pass current_class_ref to - build_x_function_call instead of current_class_ptr. - * init.c (build_member_call): Likewise. - * pase.y: Likewise. - * error.c (dump_expr): Handle OFFSET_REFs better. - * pt.c (unify): Handle pointer-to-member functions better. - * decl.c (finish_function): Clear out current_class_ref just like - we do for current_class_ptr. - - * typeck.c (get_delta_difference): Handle virtual bases better. - -Tue May 14 16:37:37 1996 Jason Merrill <jason@yorick.cygnus.com> - - * sig.c (build_signature_table_constructor): Use the delta for - the original basetype for this virtual function with thunks. - (build_signature_method_call): We still need to adjust 'this' - with thunks. - -Tue May 14 16:27:25 1996 Mike Stump <mrs@cygnus.com> - - * call.c (build_addr_func): New routine. Used to get the `real' - address of a function or a method. Needed to avoid getting a - pointer-to-member function. - (build_call): New routine to build CALL_EXPRs. - (build_method_call): Use it. - * cvt.c (convert_to_aggr): Likewise. - * typeck.c (build_function_call_real): Likewise. - * sig.c (build_signature_table_constructor): Use build_addr_func. - * cp-tree.h (build_call, build_addr_func): Declare them. - -Tue May 14 12:47:47 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (LOOKUP_AGGR): Remove, unused. - * parse.y: Remove uses of LOOKUP_AGGR. - -Tue May 14 12:07:51 1996 Mike Stump <mrs@cygnus.com> - - * *.[chy]: Rename current_class_decl to current_class_ptr, and - C_C_D to current_class_ref. - -Mon May 13 16:55:23 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (convert_harshness): Tighten up pointer conversions. - -Sat May 11 04:33:50 1996 Doug Evans <dje@canuck.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Surround DECL_ONE_ONLY with ifdef. - (finish_file): Likewise. - -Fri May 10 11:09:57 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (convert_fn_ptr): We don't use thunks for pmfs. - - * method.c (emit_thunk): Set flag_omit_frame_pointer in default - code. - -Thu May 9 18:18:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c: Turn on thunks by default where supported. - -Tue May 7 20:39:57 1996 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (build_overload_call_maybe): Removed. - * call.c (build_overload_call_real): Invert meaning of last arg to - be require_complete. - (build_overload_call): Likewise. - * typeck.c (build_x_function_call): Use build_overload_call_real - instead of build_overload_call_maybe. - -Mon May 6 01:23:32 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Don't try to emit functions that haven't - been compiled. - -Fri May 3 09:30:13 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Oops. - - * decl.c (maybe_push_to_top_level): Do save previous_class_*. - Also store the bindings from previous_class_values. - (pop_from_top_level): Restore them. - -Thu May 2 21:56:49 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Only write out vtable if its - symbol has been referenced. - (finish_file): Re-join synthesis/vtable loop with inline emission - loop, disable inlining when an inline is output. - -Thu May 2 17:20:02 1996 Mike Stump <mrs@cygnus.com> - - * except.c (init_exception_processing): Setup saved_in_catch. - (push_eh_cleanup): Reset __eh_in_catch. - (expand_start_catch_block): Set __eh_in_catch. - -Thu May 2 16:21:17 1996 Mike Stump <mrs@cygnus.com> - - * except.c (push_eh_cleanup): Add tracking for whether or not we - have an active exception object. - (expand_builtin_throw): Use it to make sure a rethrow without an - exception object is caught. - -Thu May 2 11:26:41 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (maybe_push_to_top_level): Clear out class-level bindings - cache. - -Wed May 1 11:26:52 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Also use sentries for vars with - DECL_ONE_ONLY or DECL_WEAK set (should any such happen to be - created). - - * lex.c (handle_cp_pragma): Disable #pragma - interface/implementation if SUPPORTS_ONE_ONLY > 1. - -Tue Apr 30 11:25:46 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (emit_thunk): Wrap default case in - temporary/permanent_allocation. - - * method.c (make_thunk): Use DECL_ONE_ONLY. - (emit_thunk): Call assemble_end_function. - -Mon Apr 29 15:38:29 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_vtable): Use DECL_ONE_ONLY. - (import_export_decl): Likewise. - (finish_prevtable_vardecl): Disable vtable hack if - SUPPORTS_ONE_ONLY > 1. - -Mon Apr 29 14:32:47 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_modify_expr): PREINCREMENT_EXPR and - PREDECREMENT_EXPRs take two arguments, not one. - -Mon Apr 29 00:27:53 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (build_vtable_entry): Don't build thunks for abstract - virtuals. - - * lex.c (real_yylex): Fix handling of __PRETTY_FUNCTION__ like C - frontend. - -Sat Apr 27 16:45:35 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (set_rtti_entry): Use size_zero_node. - (build_vtable): Likewise. - -Sat Apr 27 14:48:57 1996 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct_1): Pass size_zero_node to set_rtti_entry. - (prepare_fresh_vtable): Likewise. - -Fri Apr 26 13:14:14 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (emit_thunk): Call mark_used on the target function. - - * call.c (build_method_call): Don't warn about pending templates. - -Thu Apr 25 14:55:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Fix list walking logic. - - * typeck2.c (check_for_new_type): Only warn if -pedantic. - -Wed Apr 24 15:41:15 1996 Bob Manson <manson@charmed.cygnus.com> - - * class.c (finish_struct_1): Remove old code for - dont_allow_type_definitions. - * cp-tree.h: Likewise. - * spew.c: Make sure cp-tree.h is included before parse.h, so the - definition of flagged_type_tree is found before it is used. - * lex.c: Likewise. - * parse.y: Added the ftype member to the type union, and changed a - number of rules to use it instead of ttype. Added calls to - check_for_new_type() as appropriate. - * typeck2.c (check_for_new_type): New function for checking - if a newly defined type appears in the specified tree. - * cp-tree.h: Add new type flagged_type_tree. Add a prototype - for check_for_new_type(). - -Wed Apr 24 00:36:21 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Only use a sentry if the decl is public. - - * pt.c (tsubst_expr, DECL_STMT): If we don't have an initializer, - don't pass LOOKUP_ONLYCONVERTING. - -Tue Apr 23 17:18:47 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (common_type): Fix the ARRAY_TYPE case so it - properly keeps track of const and volatile type modifiers. - -Tue Apr 23 10:52:56 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (cp_tree_equal): C++ version of simple_cst_equal. - * pt.c (comp_template_args): Use it. - - * rtti.c (get_tinfo_fn, build_dynamic_cast, expand_*_desc): Call - assemble_external for artificial function decls. - - * decl.c (cp_finish_decl): Oops. - -Mon Apr 22 17:28:27 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (import_export_decl): Put static data member templates - into common storage, or make them weak, depending on whether they - are dynamically or statically initialized. - (get_sentry): New function. - (finish_file): Do import_export_decl for static data members before - building the init/fini functions. Don't init/fini a variable that's - EXTERNAL. Use a sentry for variables in common. Fix mismatching - push/pop_temp_slots. - * decl.c (cp_finish_decl): If DECL_NOT_REALLY_EXTERN, do the - expand_static_init thang. - * method.c (get_id_2): New function. - -Mon Apr 22 15:32:45 1996 Bob Manson <manson@charmed.cygnus.com> - - * parse.y (empty_parms): Make sure we use C++-style prototypes - when we're declaring member functions. - -Sun Apr 21 10:08:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * Makefile.in (CONFLICTS): 16 s/r conflicts. - * parse.y (self_template_type): New nonterminal. - -Thu Apr 18 08:56:54 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (make_typename_type): Handle getting a TYPE_DECL for a - name. - * parse.y (base_class.1): Allow 'typename foo::bar'. - - * lex.c (check_newline): Remove #pragma code that plays with the - input stream, since we now deal with tokens. Clear nextchar when - we're done. - (handle_cp_pragma): Use real_yylex. - (handle_sysv_pragma): Don't do skipline here. Only call real_yylex - in one place. - - * lex.c (check_for_missing_semicolon): Handle SELFNAME. - - * lex.c (handle_cp_pragma): Fix "#pragma implementation". - -Wed Apr 17 16:51:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y: New token SELFNAME for potential constructor. - * spew.c (yylex): Handle it. - * lex.c (identifier_type): Produce it. - - * parse.y (complete_type_name): In :: case, don't push class binding. - (complex_type_name): Likewise. - -Wed Apr 17 15:02:40 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_reinterpret_cast): Handle pointer to member - functions. - -Wed Apr 17 12:28:26 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (handle_cp_pragma): New function, with decl, doing the cc1plus - pragmas. - (check_newline): Put the vtable/unit/implementation/interface pragma - code into handle_cp_pragma, replacing it with a call. - (handle_sysv_pragma): Give int return type, and take FINPUT and TOKEN - args. Get the next token after handling the pragma token. - -Wed Apr 17 10:28:34 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Avoid doing base analysis on pmfs. - (convert_to_pointer_force): Likewise. - - * init.c (build_new): Fix array new without -fcheck-new. - -Tue Apr 16 13:44:58 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h, call.c, class.c, decl.c, parse.y, pt.c, rtti.c, - tree.c: Lose TYPE_NESTED_NAME. - - * parse.y (nested_name_specifier_1): Don't treat non-identifiers - as identifiers. - - * tree.def: Add VEC_INIT_EXPR. - * expr.c (cplus_expand_expr): Handle it. - * init.c (build_new): Use it instead of the RTL_EXPR nastiness and - the extra file-scope symbol nastiness. - -Mon Apr 15 16:21:29 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (make_thunk): Thunks are static. - (emit_thunk): Use ASM_OUTPUT_MI_THUNK if it's defined. - - * decl2.c (mark_vtable_entries): Emit thunks as needed. - (finish_file): Don't emit them here. - -Sun Apr 14 11:34:39 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (build_dynamic_cast): Handle null pointers. - (ifnonnull): New function. - -Fri Apr 12 09:08:27 1996 Bob Manson <manson@charmed.cygnus.com> - - * call.c (build_method_call): Remember the original basetype we - were called with. Give an error message instead of trying - (incorrectly) to call a non-static member function through a - non-inherited class. - - * search.c (expand_upcast_fixups): Mark the new fixup as - DECL_ARTIFICIAL. - -Thu Apr 11 03:57:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Use a TARGET_EXPR for alloc_expr. - - * class.c (set_rtti_entry): Fix for thunks. - - * decl2.c (import_export_decl): Still emit typeinfo fns for - cv-variants of builtin types. - - * rtti.c (expand_class_desc): Set up base_info_type_node here. - (init_rtti_processing): Instead of here. - -Wed Apr 10 14:17:13 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (init_rtti_processing): Do init regardless of -frtti. - (build_typeid): Only complain about taking dynamic typeid without - -frtti. - - * decl2.c: flag_rtti defaults to 1. - - * rtti.c (get_tinfo_var): The general class case is now smaller. - (init_rtti_processing): Pack the latter three fields of base_info - into 32 bits. - -Wed Apr 10 13:50:14 1996 Mike Stump <mrs@cygnus.com> - - * init.c (expand_member_init): Don't dump if name is NULL_TREE. - -Wed Apr 10 12:56:02 1996 Mike Stump <mrs@cygnus.com> - - * search.c (make_memoized_table_entry): Undefer the pop, if necessary. - (push_memoized_context): Split out code to undefer pop_type_level to - (clear_memoized_cache): here. - (pop_memoized_context): We can only handle one layer of deferral of - pop_type_level so clear the cache, if there was a previous level. - -Tue Apr 9 23:06:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (init_rtti_processing): Build up base_info_type_node. - (expand_class_desc): Use one pointer to an array of base_info - structs, passed using a CONSTRUCTOR. - -Tue Apr 9 14:20:57 1996 Mike Stump <mrs@cygnus.com> - - * class.c (build_vbase_path): Remove block extern for - flag_assume_nonnull_objects here. - (build_vfn_ref): Split out functionality into build_vtbl_ref. - (build_vtbl_ref): New routine. - (build_vtable): Set up rtti info here. - (add_virtual_function): Note in CLASSTYPE_RTTI the best - place where we can get the rtti pointers from to avoid having to - search around for a place. - (finish_base_struct): Likewise. - (finish_struct_1): Likewise. Never create totally new vtables - with totally new vtable pointers for rtti. Disable code to layout - vtable pointers better until we want to break binary - compatibility. - * rtti.c (build_headof_sub): New routine to convert down to a - sub-object that has an rtti pointer in the vtable. - (build_headof): Use it. Also, use build_vtbl_ref now to be more - maintainable. - (build_dynamic_cast): Make sure we have saved it, if we need to. - * search.c (dfs_init_vbase_pointers): Disable code that deals with - a more efficient vtable layout, enable later. - * call.c (flag_assume_nonnull_objects): Moved declaration to - * cp-tree.h: here. Declare build_vtbl_ref. - * pt.c (instantiate_class_template): Use NULL_TREE instead of 0 in - function calls that want a tree. - -Tue Apr 9 12:10:26 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (build_dynamic_cast): Handle downcasting to X* given - other X subobjects in the most derived type. Ack. - - * rtti.c (build_dynamic_cast): No need to strip cv-quals here, - get_typeid will do it for us. - (get_typeid_1): Break out call-building for expand_*_desc to use. - (get_typeid): Call it. - (expand_*_desc): Likewise. - * decl.c (init_decl_processing): Don't set TYPE_BUILT_IN on char * - and void *. - (init_decl_processing): Lose builtin_type_tdescs lossage. - * decl2.c (finish_vtable_vardecl): Remove obsolete code. - -Mon Apr 8 17:23:23 1996 Bob Manson <manson@charmed.cygnus.com> - - * pt.c (tsubst): When calling set_nested_typename, use - TYPE_NESTED_NAME (current_class_type) instead of - current_class_name. - - * decl.c (pushdecl): Likewise. - (pushdecl_class_level): Likewise. - (grokdeclarator): Use NULL_TREE instead of 0 in the call to - set_nested_typename. - -Sun Apr 7 10:44:31 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (synthesize_tinfo_fn): Handle arrays. - - * cp-tree.h (DECL_REALLY_EXTERN): New macro. - -Sat Apr 6 13:56:27 1996 Jason Merrill <jason@yorick.cygnus.com> - - * rtti.c (throw_bad_cast): Use entry point __throw_bad_cast. - (init_rtti_processing): Lose bad_cast_type. - (build_dynamic_cast): Use throw_bad_cast. - - * rtti.c (synthesize_tinfo_fn): Handle enums and pmfs. - - * decl2.c (finish_file): Don't synthesize artificial functions - that are external and not inline. - - * rtti.c (get_tinfo_fn): If at_eof, call import_export_decl. - - * decl2.c (finish_file): Handle having new inlines added to - saved_inlines by synthesis. - - * rtti.c (get_bad_cast_node): Don't require <typeinfo>. - -Fri Apr 5 17:02:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - RTTI rewrite to initialize nodes as needed, not require that - users #include <typeinfo>, complete functionality and reduce wasted - space. - * rtti.c (init_rtti_processing): New fn. - (build_typeid): The vtable entry is now a function. - (get_tinfo_var): New fn. - (get_tinfo_fn): Likewise. - (get_typeid): Use it. - (build_dynamic_cast): Declare and use entry point __dynamic_cast. - (build_*_desc): Rename to expand_*_desc and rewrite to use entry - points __rtti_*. - (add_uninstantiated_desc, get_def_to_follow, build_t_desc): Lose. - (synthesize_tinfo_fn): New fn. - * method.c (build_t_desc_overload): Lose. - (build_overload_with_type): More generic. - * decl.c (init_decl_processing): Call init_rtti_processing. - * class.c (set_rtti_entry): Use get_tinfo_fn. - * decl2.c (mark_vtable_entries): Mark the rtti function. - (finish_prevtable_vardecl): Don't build_t_desc. - (import_export_decl): Handle tinfo functions. - (finish_file): Likewise. - * typeck.c (inline_conversion): New fn. - (build_function_call_real): Use it. - * cp-tree.h: Add decls. - - * method.c (hack_identifier): Also convert component_refs from - references. - - * lex.c (cons_up_default_function): Use the type, not the name, in - declspecs. - - * decl2.c (import_export_vtable): Fix weak vtables. - -Fri Apr 5 13:30:17 1996 Bob Manson <manson@charmed.cygnus.com> - - * search.c (get_base_distance_recursive): Fix access checks for - protected bases. - -Fri Apr 5 11:02:06 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (unary_complex_lvalue): Delete unneeded decl, it's in - cp-tree.h. - (convert_harshness): Add prototypes wrapped by PROTO. - * decl2.c (grok_function_init): Likewise. - (do_toplevel_using_decl): Change to void return type. - * class.c (build_vtable_entry): Remove decl of make_thunk. - (merge_overrides): Fix order of arg definitions. - (finish_vtbls): Likewise. - (fixup_vtable_deltas): Likewise. - (modify_all_direct_vtables): Likewise. - (modify_all_indirect_vtables): Likewise. - * search.c (get_base_distance_recursive): Likewise. - (get_abstract_virtuals_1): Likewise. - (fixup_virtual_upcast_offsets): Likewise. - (lookup_fnfields_1): Add prototypes wrapped by PROTO. - * init.c (perform_member_init): Fix order of arg definitions. - (expand_aggr_init_1): Add prototypes wrapped by PROTO. - * cp-tree.h (make_thunk): Add decl. - (overload_template_name, push_template_decl): Add decls. - (do_toplevel_using_decl): Change to void return type. - (vec_binfo_member): Add decl. - -Thu Apr 4 13:33:10 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (mark_addressable, convert_for_assignment, - convert_for_initialization, pointer_int_sum, pointer_diff, - unary_complex_lvalue): Add prototypes wrapped by PROTO. - (convert_sequence): #if 0 fn decl, since definition also is. - -Thu Apr 4 11:00:53 1996 Mike Stump <mrs@cygnus.com> - - * rtti.c (build_dynamic_cast): Make sure we strip qualifiers on - cast to pointer types for type searching. - -Wed Apr 3 17:10:57 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (get_delta_difference): Use cp_error, not error, in the - case where BINFO == 0. - -Wed Apr 3 12:01:02 1996 Mike Stump <mrs@cygnus.com> - - * call.c (build_method_call): Fix wording of error messages so - constructors come out right. - -Tue Apr 2 16:06:59 1996 Bob Manson <manson@charmed.cygnus.com> - - * decl.c (push_overloaded_decl): Don't warn about hidden - constructors when both the type and the function are declared - in a system header file. - -Mon Apr 1 09:03:13 1996 Bob Manson <manson@charmed.cygnus.com> - - * class.c (finish_struct_1): Propagate the TYPE_PACKED - flag for the type to the type's fields. - -Sat Mar 30 12:14:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (complex_parmlist, ELLIPSES): Take out ARM-based warning. - -Fri Mar 29 15:51:36 1996 Bob Manson <manson@charmed.cygnus.com> - - * class.c (base_info, finish_base_struct): Replace - needs_virtual_dtor with base_has_virtual. - - (finish_struct_1): Remove the old code that tried to make default - destructors virtual. Use base_has_virtual when checking if we need - to add a vtable entry for the rtti code. - -Fri Mar 29 14:02:36 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (push_template_decl): Complain about template decl with - inappropriate declaration. - -Fri Mar 29 12:15:35 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (build_x_unary_op): Remove bogus check for taking - the address of a member function. - -Fri Mar 29 11:56:02 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (constructor_declarator): Only push the class if - we are not already in the class. - -Fri Mar 29 09:41:02 1996 Jeffrey A. Law <law@cygnus.com> - - * method.c (emit_thunk): Remove current_call_is_indirect nonsense. - Add additional argument to INIT_CUMULATIVE_ARGS. - -Thu Mar 28 16:41:39 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (shadow_tag): Fix error about anon union with methods. - - * parse.y (self_reference): Only generate a self-reference if this - is a non-template class. - (opt.component_decl_list): Only use it if it was generated. - - * parse.y (component_decl_1): Use constructor_declarator. - (fn.def2): Likewise. - (notype_component_declarator0): Likewise. - -Thu Mar 28 15:11:35 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (build_x_unary_op): Add checks for taking the address - of a TARGET_EXPR or of a member function, and give appropriate - warnings. - -Thu Mar 28 14:49:26 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (process_template_parm): Allow template type parms to be - used as types for template const parms. - -Wed Mar 27 15:51:19 1996 Mike Stump <mrs@cygnus.com> - - * init.c (expand_vec_init): Ensure the eh cleanups are on the - function_obstack. - -Wed Mar 27 10:14:30 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (lookup_name_real): Be even more picky about the - ambiguous lookup warning. - (grokdeclarator): Tweak SCOPE_REF constructor declarators here. - * parse.y (constructor_declarator): Rather than here. - - * parse.y (constructor_declarator): New nonterminal. - (fn.def1): Use it. - (explicit_instantiation): Likewise. - -Tue Mar 26 13:41:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - Add implicit declaration of class name at class scope. - * decl.c (lookup_name_real): Restrict pedwarn about ambiguous lookup. - * parse.y (self_reference): New nonterminal. - (opt.component_decl_list): Use it. - (fn.def1): Add nested_name_specifier type_name cases. - * class.c (build_self_reference): New function. - (finish_struct): Handle access_default later, move self-reference - decl to the end. - * pt.c (lookup_template_class): Handle getting a TYPE_DECL. - * cp-tree.h: Adjust. - - * pt.c (do_function_instantiation): Separate handling of member - functions and non-member functions properly. - -Mon Mar 25 14:23:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (process_template_parm): Improve error for 'volatile class K'. - - * class.c (finish_struct_1): Check the right slot for destructors. - - * decl.c (start_enum): Complain about enum templates. - -Mon Mar 25 13:25:31 1996 Mike Stump <mrs@cygnus.com> - - * init.c (resolve_offset_ref): Offset pointers to member data by one. - * typeck.c (unary_complex_lvalue): Likewise. - -Mon Mar 25 13:30:42 1996 Bob Manson <manson@charmed.cygnus.com> - - * typeck.c (c_expand_return): Check for a returned local - array name, similar to the check for an ADDR_EXPR. - -Mon Mar 25 13:07:19 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (cp_finish_decl): Don't build cleanups for static - variables here. - -Fri Mar 22 17:57:55 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_modify_expr): Fix error messages to be more - accurate. - * cp-tree.h (assop_as_string): Parallel to op_as_string, but for - assignment operators. - * error.c (assop_as_string): Likewise. Add support for `%Q' for - assignment operators. - -Fri Mar 22 13:48:29 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Call bad_specifiers for typedefs. Also - give an error if initialized. Pedwarn about nested type with the - same name as its enclosing class. - - * pt.c (tsubst, case TYPE_DECL): Set DECL_CONTEXT. - - * typeck.c (require_complete_type): Be sure to instantiate the - MAIN_VARIANT of the type. - - * decl2.c (finish_file): Instantiate pending templates before - processing static constructors and destructors. - - * pt.c (instantiate_decl): Don't instantiate functions at toplevel - unless at_eof. - -Fri Mar 22 09:30:17 1996 Bob Manson <manson@beauty.cygnus.com> - - * decl2.c (delete_sanity): If error_mark_node is passed - in as an expression, quit while we're ahead. - - * decl.c (grokdeclarator): Give an error message if `friend' - is combined with any storage class specifiers. - -Wed Mar 20 14:51:55 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (named_complex_class_head_sans_basetype): Don't crash on - definition of nonexistent nested type. - - * error.c (dump_decl, case TYPE_DECL): Fix decision for whether or - not to say 'typedef'. - -Wed Mar 20 00:11:47 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (struct lang_type): Make search_slot a tree, not a char*. - * search.c (dfs_walk, dfs_init_vbase_pointers, - expand_upcast_fixups): Remove cast of CLASSTYPE_SEARCH_SLOT. - (dfs_find_vbases): Remove cast for CLASSTYPE_SEARCH_SLOT init. - -Tue Mar 19 17:56:03 1996 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (build_throw): Support minimal parse. - * pt.c (tsubst_copy): Support THROW_EXPR. - * decl2.c (build_expr_from_tree): Likewise. - - * pt.c (mangle_class_name_for_template): Always allocate - scratch_firstobj. - -Tue Mar 19 16:34:31 1996 Bob Manson <manson@beauty.cygnus.com> - - * cvt.c (cp_convert_to_pointer): Give an appropriate error - when trying to cast from an incomplete type. - -Tue Mar 19 16:00:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): Don't bother setting up - CLASSTYPE_TAGS explicitly, as the nested types will add - themselves. - -Tue Mar 19 15:48:43 1996 Bob Manson <manson@beauty.cygnus.com> - - * decl.c (shadow_tag): Remove old error check for usage of - an enum without a previous declaration. - (xref_tag): Add error message about usage of enums without a - previous declaration. - -Tue Mar 19 09:21:35 1996 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (do_identifier): Only do name consistency check if we're - parsing. - - * pt.c (push_template_decl): Don't crash if we get a member defn - that doesn't match. - - * decl.c (xref_tag_from_type): New function to do an xref without - always having to figure out code_type_node. - * cp-tree.h: Declare it. - * pt.c (instantiate_class_template): Use it for friend classes. - (lookup_template_class): Use it. - - * typeck2.c (build_functional_cast): Pull out a single parm before - passing it to build_c_cast. - -Tue Mar 19 09:07:15 1996 Bob Manson <manson@beauty.cygnus.com> - - * expr.c (do_case): Give an error message if a pointer is - given as a case value. - -Mon Mar 18 21:57:54 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_c_cast): Don't pull single TEMPLATE_DECL out of - an overload list. - - * lex.c (cons_up_default_function): Really, now, interface hackery - does not apply to synthesized methods. - -Mon Mar 18 18:20:57 1996 Mike Stump <mrs@cygnus.com> - - * call.c (build_method_call): Ctors and dtors now have special names - with respect to lookups. - * class.c (add_method): Likewise. - (grow_method): Likewise. - (finish_struct_methods): Likewise. - (warn_hidden): Likewise. - (finish_struct_1): Likewise. - * cvt.c (convert_to_reference): Likewise. - (convert_to_aggr): Likewise. - (cp_convert): Likewise. - * decl2.c (check_classfn): Likewise. - * init.c (expand_member_init): Likewise. - (expand_default_init): Likewise. - (expand_aggr_init_1): Likewise. - (build_offset_ref): Likewise. - (build_new): Likewise. - (build_delete): Likewise. - * lex.c (do_inline_function_hair): Likewise. - * search.c (lookup_field_1): Likewise. - (lookup_fnfields_here): Likewise. - (lookup_field): Likewise. - (lookup_fnfields): Likewise. - (get_virtual_destructor): Likewise. - (dfs_debug_mark): Likewise. - (dfs_pushdecls): Likewise. - (dfs_compress_decls): Likewise. - * tree.c (layout_basetypes): Likewise. - * typeck.c (build_component_ref): Likewise. - (build_x_function_call): Likewise. - (build_modify_expr): Likewise. - (convert_for_initialization): Likewise. - (build_functional_cast): Likewise. - * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Likewise. - (CTOR_NAME): New. - (DTOR_NAME): New. - * decl.c (ctor_identifier): New. - (dtor_identifier): New. - (init_decl_processing): Set them. - -Mon Mar 18 18:00:51 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_component_ref): Don't get confused by fields whose - context has no type name, like pointer to member functions. - -Mon Mar 18 13:19:03 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Handle typedef without declarator. - - * pt.c (tsubst): Handle SCOPE_REF in declarator. - - * parse.y (bad_parm): Catch another case of missing `typename'. - - * lex.c (yyprint): Handle TYPE_DECLs. - - * decl.c (start_function): Don't try to be clever. - - * lex.c: Lose compiler_error_with_decl. - * typeck2.c: Lose error_with_aggr_type. - (incomplete_type_error): Use cp_* instead of old functions. - (readonly_error): Likewise. - * typeck.c (convert_arguments): Likewise. - * search.c (lookup_nested_field): Likewise. - * method.c (make_thunk): Likewise. - * decl.c (grokparms): Likewise. - * cp-tree.h: Update. - - * tree.c (min_tree_cons): Call copy_to_permanent for the purpose - and value. - -Mon Mar 18 11:25:52 1996 Bob Manson <manson@beauty.cygnus.com> - - * method.c (build_opfncall): When deleting a pointer to an - array, build a new pointer to the tree past any ARRAY_TYPE - nodes. - -Mon Mar 18 10:11:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (lookup_name_real): Initialize local var TYPE to NULL_TREE. - -Fri Mar 15 11:03:57 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_decl): Only call import_export_decl if at_eof - and ! DECL_INLINE. - - * decl.c (finish_function): Don't set nested based on - hack_decl_function_context. - * parse.y (function_try_block): Check for nested function. - (pending_inlines): Likewise. - - * decl2.c (build_expr_from_tree): If a unary op already has a - type, just return it. - - * decl2.c (finish_prevtable_vardecl): Use ADJUST_VTABLE_LINKAGE. - - * decl2.c (walk_vtables): vardecl_fn returns int; return 1 if it does. - (finish_file): Check the return value of walk_vtables. - (finish_prevtable_vardecl): Return int. - (finish_vtable_vardecl): Likewise. - (prune_vtable_vardecl): Likewise. - * lex.c (set_vardecl_interface_info): Likewise. - * cp-tree.h: Adjust return types. - - * class.c (delete_duplicate_fields_1): Don't complain about - duplicate nested types if they're the same type. - (finish_struct): Remove check for duplicate. - * decl2.c (grokfield): Don't check for typedef of anonymous type. - -Thu Mar 14 10:00:19 1996 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h: Lose SIGNATURE_GROKKING_TYPEDEF. - - * decl.c (grokdeclarator): Lose special handling of class-level - typedef. Lose SIGNATURE_GROKKING_TYPEDEF. Set - SIGNATURE_HAS_OPAQUE_TYPEDECLS later. - - * cvt.c (convert_pointer_to_real): Retain cv-quals in conversion. - - * pt.c (tsubst_copy): Strip cv-quals from destructor name types. - - * search.c (compute_access): Fix handling of anonymous union - members. - * class.c (finish_struct_anon): Propagate TREE_{PRIVATE,PROTECTED} - from anonymous unions to their members. - - * typeck.c (build_x_function_call): For static member functions, - hand off to build_member_call. - -Wed Mar 13 14:03:34 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_component_ref): Handle OFFSET_REFs. - - * init.c (expand_vec_init): Fix init == 0 case. - -Tue Mar 12 14:36:02 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_new): Pedwarn about init and array new. - (expand_vec_init): Handle lists, use convert_for_initialization. - - * typeck.c (convert_for_initialization): Pass LOOKUP_NO_CONVERSION - when converting to an aggregate type. - * cvt.c (cp_convert): Pass it through. - - * typeck.c (build_conditional_expr): Handle user-defined - conversions to slightly different types. - - * decl.c (grokdeclarator): Force an array type in a parm to be - permanent. - - * decl2.c (do_using_directive): Sorry. - (do_namespace_alias): Likewise. - * lex.c (real_yylex): Warn about using the `namespace' keyword. - -Sun Mar 10 22:26:09 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (datadef): Move call to note_list_got_semicolon up. - -Fri Mar 8 11:47:26 1996 Mike Stump <mrs@cygnus.com> - - * tree.c (unsave_expr): Don't unsave, UNSAVE_EXPRs. - -Fri Mar 8 11:29:06 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (cp_finish_decl): The exception regions have to be - nested, not overlapping. We start the exception region for a - decl, after it has been fully built, and all temporaries for it - have been cleaned up. - -Thu Mar 7 17:46:06 1996 Mike Stump <mrs@cygnus.com> - - * tree.c (vec_binfo_member): Don't core dump if we have no bases. - -Thu Mar 7 14:11:49 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.def: Add RETURN_INIT. - * pt.c (instantiate_decl): Handle RETURN_INIT. - * decl.c (store_return_init): Handle minimal_parse_mode. - - * tree.c (cp_build_type_variant): Just return an error_mark_node. - * decl.c (make_typename_type): Don't try to get the file and line - of an identifier. - * typeck.c (comptypes): Handle TYPENAME_TYPE. - -Wed Mar 6 18:47:50 1996 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (poplevel): Make sure we clear out and restore old local - non-VAR_DECL values by default when they go out of scope. - -Wed Mar 6 09:57:36 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (build_overload_value): Use DECL_ASSEMBLER_NAME in - referring to addresses of variables and functions. - - * error.c (dump_expr): Support SIZEOF_EXPR. - - * init.c (do_friend): Use the return value of check_classfn. - - * typeck.c (convert_arguments): Call complete_type. - - * method.c (hack_identifier): After giving an error, set value to - error_mark_node. - -Tue Mar 5 16:00:15 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (hack_decl_function_context): Kludge around DECL_CONTEXT - lossage for local classes. - * cp-tree.h: Declare it. - * decl.c (lookup_name_real): Evil, painful hack for local classes. - (grokfndecl): Set DECL_CLASS_CONTEXT and DECL_NO_STATIC_CHAIN here. - Use hack_decl_function_context. - (grokdeclarator): Don't set DECL_NO_STATIC_CHAIN here. - (start_function): Use hack_decl_function_context. - (finish_function): Likewise. - * method.c (synthesize_method): Likewise. - * lex.c (process_next_inline): Likewise. - (do_pending_inlines): Likewise. - * decl2.c (finish_file): Unset DECL_STATIC_FUNCTION_P when we're - done with it. - -Mon Mar 4 22:38:39 1996 Gerald Baumgartner <gb@alexander.cs.purdue.edu> - - * sig.c (build_signature_pointer_or_reference_type): Align - signature pointers/references on 8-byte boundaries so they can be - grabbed 2 words at a time on a Sparc. - -Tue Mar 5 10:21:01 1996 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (hack_identifier): Requiring a static chain is now a - hard error. - * decl.c (grokdeclarator): Set DECL_NO_STATIC_CHAIN on nested - functions. - -Mon Mar 4 20:03:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * init.c (build_offset_ref): Call complete_type. - - * decl.c (pop_from_top_level): Always pop previous_class_type. - - * parse.y: Handle multiple decls in a for-init-statement. - * pt.c (tsubst_expr): Likewise. - - * pt.c (tsubst): Use tsubst_expr for the second operand of an - ARRAY_REF. - - * decl.c (maybe_push_to_top_level): Don't save previous_class_type. - (poplevel_class): Set it here. - (pop_from_top_level): Pop it here if we're returning to class scope. - * class.c (pushclass): Don't set it here. - - * decl.c (maybe_push_to_top_level): Save current_template_parms, - and clear it if !pseudo. - (pop_from_top_level): Restore it. - - * decl2.c (finish_file): Push the dummy each time we walk the list - of vtables. - - * error.c (dump_expr): Support LOOKUP_EXPR and actually do - something for CAST_EXPR. - -Mon Feb 19 14:49:18 1996 Rusty Russell <rusty@adelaide.maptek.com.au> - - * cvt.c (cp_convert): Warn about implicit conversion of the - address of a function to bool, as it is always true. - -Fri Feb 23 23:06:01 1996 Rusty Russell <rusty@adelaide.maptek.com.au> - - * typeck.c (c_expand_return): Fix warning for local externs returned. - -Mon Mar 4 15:03:11 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (mapcar): Propagate const and volatile properly. - - * typeck.c (complete_type): Be sure to instantiate the - MAIN_VARIANT of the type. - - * method.c (synthesize_method): Class interface hackery does not - apply to synthesized methods. - -Mon Mar 4 14:05:23 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (comp_template_args): Use comptypes rather than just - checking for TEMPLATE_TYPE_PARM equivalence. - - * typeck.c (build_x_function_call): Call complete_type before - checking TYPE_OVERLOADS_CALL_EXPR. - -Mon Mar 4 18:48:30 1996 Manfred Hollstein <manfred@lts.sel.alcatel.de> - - * g++.c (main): Check also for new define ALT_LIBM. - -Fri Mar 1 13:09:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_class_template): If we don't have a pattern - yet, that's OK. - (coerce_template_parms): If we see a local class, bail. - - * decl.c (grok_reference_init): Make sure there's a type before - checking its code. - - * pt.c (do_function_instantiation): Avoid crashing on invalid decls. - (push_template_decl): Likewise. - - * parse.y (named_class_head): Set - CLASSTYPE_TEMPLATE_SPECIALIZATION here if we have basetypes. - - * decl.c (xref_tag): Diagnose redeclaration of template - type-parameter name. - - * error.c (dump_type): Handle anonymous template type parms. - - * pt.c (instantiate_template): Use TYPE_MAIN_DECL instead of - TYPE_STUB_DECL. - (coerce_template_parms): Likewise. - -Thu Feb 29 16:26:01 1996 Mike Stump <mrs@cygnus.com> - - * class.c (instantiate_type, case {ARRAY,INDIRECT}_REF, - case ADDR_EXPR): Don't modify rhs if a subinstantiation fails. - -Thu Feb 29 08:20:25 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (instantiate_template): Take the MAIN_VARIANT of the type - before trying to get its STUB_DECL. - (coerce_template_parms): Likewise. - - * parse.y (template_type_parm): If they didn't use 'class', - pretend they did after giving an error. - - * pt.c (coerce_template_parms): Diagnose use of local class. - - * decl.c (grok_reference_init): Use instantiate_type. - - * error.c (dump_expr): Handle TEMPLATE_DECLs. - - * parse.y (named_class_head): Diagnose mismatching types and tags. - - * decl.c (pushdecl): Type decls and class templates clash with - artificial type decls, not hide them. - - * decl.c (redeclaration_error_message): Diagnose redefinition of - templates properly. - (duplicate_decls): Diagnose disallowed overloads for template - functions, too. - - * decl.c (start_decl): Call complete_type before checking for a - destructor. - - * pt.c (tsubst): Use tsubst_expr on the elts of a VEC. - - * decl.c (xref_tag): A TEMPLATE_TYPE_PARM is a match. - -Wed Feb 28 09:28:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grok_op_properties): Don't check for operator++(int) in - a template. - - * tree.c (perm_manip): Return a copy of variable and function - decls with external linkage. - - * tree.def: Change some of the min tree codes to type "1". - * pt.c (uses_template_parms): Handle 'e's, return 1 for LOOKUP_EXPRs. - * method.c (build_overload_int): Emit something arbitrary for - anything but an INTEGER_CST if we're in a template. - - * decl.c (cp_finish_decl): Call complete_type before deciding - whether or not to lay out the decl. - - * lex.c (do_identifier): Check for DECL_INITIAL before using it. - -Tue Feb 27 16:35:32 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck2.c (build_x_arrow): Call complete_type. - - * pt.c (add_pending_template): Broken out. - (lookup_template_class): If -fexternal-templates, call it for all - the methods of implemented types. - (instantiate_class_template): Instead of instantiating them here. - (instantiate_decl): Handle -fexternal-templates earlier. - -Tue Feb 27 15:51:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * search.c, lex.c, decl.c, class.c, cp-tree.h: Don't wrap the - memoized lookup stuff inside GATHER_STATISTICS. - -Tue Feb 27 10:38:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_decl): Complain about array of incomplete type - here. - (grokdeclarator): Not here. - - * parse.y (template_parm): Expand full_parm inline so we can set - the rule's precedence. - - * pt.c (tsubst_expr): If we're in a template, just do tsubst_copy. - (tsubst): tsubst_expr the DECL_INITIAL of FIELD_DECLs. - * decl2.c (grokbitfield): Don't check for integer constant here. - * class.c (finish_struct_1): Check here. - - * decl.c (define_label): Make the min decl go on permanent_obstack. - - * pt.c (unify): Don't handle CONST_DECLs. - (uses_template_parms): Don't check DECL_INITIAL on a CONST_DECL. - (tsubst_copy): Likewise. - - * lex.c (do_identifier): Do pull the DECL_INITIAL out of a - CONST_DECL for a template parm. - -Mon Feb 26 12:48:18 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokdeclarator): Complain about array of incomplete type - here. - (start_decl_1): Not here. - - * pt.c (tsubst): Handle pointer-to-function declarators. - - * method.c (hack_identifier): If pedantic, diagnose local class - methods that require a static chain. - - * decl.c (grok_op_properties): No longer static. - * cp-tree.h: Declare it. - * pt.c (tsubst): Call it for operators. - Use tsubst_copy for TREE_VECs. - - * parse.y (template_arg): The expr has precedence like '>'. - -Fri Feb 23 14:51:52 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (coerce_template_parms): Don't coerce an expression using - template parms. - (uses_template_parms): Also check DECL_INITIAL in CONST_DECLs. - (tsubst): Don't use build_index_2_type if the max_value uses template - parms. - * method.c (build_overload_int): Emit something arbitrary for an - expression using template parms. - - * parse.y (template_close_bracket): New non-terminal to catch use - of '>>' instead of '> >' in template class names. - (template_type): Use it. - * Makefile.in (CONFLICTS): Causes one more r/r conflict. - - * tree.def: Add CAST_EXPR. - * typeck2.c (build_functional_cast): Use CAST_EXPR instead of - CONVERT_EXPR for minimal_parse_mode. - * typeck.c (build_c_cast): Likewise. - * pt.c (tsubst_copy): Likewise. - * decl2.c (build_expr_from_tree): Likewise. - * error.c (dump_expr): Likewise. - -Fri Feb 23 10:36:46 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * except.c (SetTerminate, SetUnexpected): Put back global vars. - (init_exception_processing): Put back decl/init of - set_unexpected_fndecl and set_terminate_fndecl, needed to get the - fns from libstdc++. - - * decl.c (struct binding_level): Delete ACCEPT_ANY bitfield. - (declare_uninstantiated_type_level, uninstantiated_type_level_p): - Delete unused fns. - * cp-tree.h (declare_uninstantiated_type_level, - uninstantiated_type_level_p): Delete prototypes. - -Thu Feb 22 19:36:15 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst_expr): Add default return. - -Thu Feb 22 16:47:24 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * error.c (fndecl_as_string): Delete unused arg CNAME. - * sig.c (build_signature_table_constructor, - build_signature_method_call): Fix calls. - - * class.c (the_null_vtable_entry): Delete var definition. - (init_class_processing): Delete tree the_null_vtable_entry init. - * decl.c (no_print_{functions, builtins}): Declare as static. - (__tp_desc_type_node): #if 0 var definition. - (init_type_desc): #if 0 init of __tp_desc_type_node. - (vb_off_identifier): Move var decl into init_decl_processing. - (current_function_assigns_this): Declare as static. - (int_ftype_ptr_ptr_int, void_ftype_ptr_int_int): Delete var decls. - (init_decl_processing): Delete init of void_ftype_ptr_ptr_int. - Move decls of string_ftype_ptr_ptr and int_ftype_string_string here. - * decl2.c (delete_sanity): Delete definition/mod of local var ELT_SIZE. - * init.c (BI_header_type, BI_header_size): Declare as static. - * pt.c (template_classes): Delete unused var. - (add_pending_template): Delete decl for non-existent fn. - (lookup_template_class): Delete vars CODE and TAG_CODE. - (instantiate_template): Delete unused var TARGS. - * cp-tree.h (vb_off_identifier, current_function_assigns_this): - Delete decls. - (__tp_desc_type_node): #if 0 var decl. - (fndecl_as_string): Fix prototype. - -Thu Feb 22 15:56:19 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.def: Add GOTO_STMT. - * pt.c (tsubst_expr): Support goto and labels. - * decl.c (define_label): Support minimal parsing. - * parse.y (simple_stmt): Likewise. - -Thu Feb 22 15:30:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * xref.c (GNU_xref_member): Only define/set var I if - XREF_SHORT_MEMBER_NAMES is defined, to match when it's actually - used. - (GNU_xref_end_scope): Delete unused fifth arg TRNS. - (GNU_xref_end): Fix call. - * decl.c (poplevel, poplevel_class, finish_method): Fix calls. - * cp-tree.h (GNU_xref_end_scope): Fix prototype. - - * tree.c (build_exception_variant): Delete unused vars I, A, T, - T2, and CNAME. - (layout_vbasetypes): Delete unused var NONVIRTUAL_VAR_SIZE. - (mapcar): Delete unused var CODE. - (build_cplus_new): Delete unused arg WITH_CLEANUP_P. - (break_out_cleanups): Fix call. - (bot_manip): Likewise. - * call.c (build_method_call): Likewise. - * cvt.c (build_up_reference, convert_to_reference, cp_convert): - Likewise. - * typeck.c (unary_complex_lvalue, build_modify_expr, - convert_for_initialization): Likewise. - * typeck2.c (build_functional_cast): Likewise. - * cp-tree.h (build_cplus_new): Fix prototype. - - * repo.c (open_repo_file): Delete unused var Q. - (repo_compile_flags, repo_template_declared, - repo_template_defined, repo_class_defined, repo_inline_used, - repo_vtable_used, repo_tinfo_used): #if 0 unused fns. - (repo_get_id, repo_vtable_used): Declare as static. - * cp-tree.h (mark_{decl,class}_instantiated, finish_repo): Add - prototypes. - -Thu Feb 22 14:53:35 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (pending_inlines): Add function_try_block case. - - * pt.c (unify): Fix for template const parms. - -Thu Feb 22 13:24:15 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (extract_interface_info): Delete forward decl. - (default_copy_constructor_body, default_assign_ref_body): Delete - decls for non-existent functions. - (synth_firstobj, inline_text_firstobjs): Delete unused vars. - (init_lex): Delete setting them. - (cons_up_default_function): Delete unused vars FUNC_BUF, - FUNC_LEN, and COMPLEX. Delete code setting COMPLEX. Delete old - #if 0'd synth code. - (toplevel, expression_obstack): Delete unused extern decls. - (tree_node_kind): Delete unused enum. - (tree_node_counts, tree_node_sizes): Wrap with #ifdef - GATHER_STATISTICS. - (tree_node_kind_names): Delete unused extern decl. - (synth_obstack): Delete unused var. - (init_lex): Don't set it. - (init_parse): Add decl before use. - (reduce_count): Only define #ifdef GATHER_STATISTICS && REDUCE_LENGTH. - (current_unit_{name, language}): Delete unused vars. - (check_newline): Don't bother setting them, just accept the #pragma. - * cp-tree.h (init_repo, peek_yylex): Add prototypes. - (current_unit_{name, language}): Delete decls. - - * search.c: Wrap all of the memoized functions, macros, and - variables inside #ifdef GATHER_STATISTICS. - (lookup_field, lookup_fnfields): Likewise. - (init_search_processing): Likewise. - (reinit_search_statistics): Wrap whole function. - * lex.c (reinit_lang_specific): Wrap call to reinit_search_statistics. - - * decl.c (finish_function): Only call pop_memoized_context if - GATHER_STATISTICS is defined. - (start_function): Likewise for push_memoized_context. - * class.c (pushclass, popclass): Likewise. - - * cp-tree.h (CLASSTYPE_MTABLE_ENTRY): Move definition from here... - * search.c (CLASSTYPE_MTABLE_ENTRY): ... to here. - - * cvt.c (cp_convert): Delete unused local var FORM. - * cp-tree.h (can_convert, can_convert_arg, real_lvalue_p): Add - prototypes. - -Thu Feb 22 13:19:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (do_poplevel): Oops; really return what we get from - poplevel this time. - -Thu Feb 22 11:41:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (is_aggr_type): Add prototype. - - * cp-tree.h ({push,pop}_cp_function_context): Add decls. - * method.c ({push,pop}_cp_function_context): Delete decls. - * except.c (start_eh_unwinder, end_eh_unwinder): Declare as void. - (SetUnexpected, SetTerminate): Delete unused vars. - (init_exception_processing): Don't set SetUnexpected or - SetTerminate. Don't set SET_UNEXPECTED_FNDECL or SET_TERMINATE_FNDECL. - (output_exception_table_entry): Delete unused array LABEL. - (expand_internal_throw): Delete unused var PARAMS. - (expand_start_catch_block): Delete unused var CLEANUP. - (emit_exception_table): Delete unused var EH_NODE_DECL. - (expand_builtin_throw): Delete unused vars UNWIND_AND_THROW and - GOTO_UNWIND_AND_THROW. Don't set them. - (end_eh_unwinder): Add top decl. - (pop_rtl_from_perm): Delete unused decl of PERMANENT_OBSTACK. - (exception_section, push_rtl_perm, do_function_call, - lang_interim_eh, push_eh_cleanup, eh_outer_context, - expand_end_eh_spec, end_eh_unwinder): Declare as static. - (saved_pc, saved_throw_type, saved_throw_value, saved_cleanup, - throw_used): Likewise. - * cp-tree.h (expand_end_eh_spec): Delete prototype. - - * search.c (dfs_mark, dfs_mark_vtable_path, - dfs_unmark_vtable_path, dfs_mark_new_vtable, - dfs_unmark_new_vtable, dfs_clear_search_slot, - dfs_search_slot_nonempty_p, bfs_markedp, bfs_unmarkedp, - bfs_marked_vtable_pathp, bfs_unmarked_vtable_pathp, - bfs_marked_new_vtablep, bfs_unmarked_new_vtablep): #if 0 unused - functions. - (n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1, - n_calls_lookup_fnfields, n_calls_lookup_fnfields_1, - n_calls_get_base_type, n_outer_fields_searched, n_contexts_saved): - Only define #ifdef GATHER_STATISTICS. - (reinit_search_statistics): Only init some vars if GATHER_STATISTICS - is defined. - (vbase_decl): Delete var definition. - (init_search): Delete old decl. - (init_vbase_pointers): Delete building of VBASE_DECL, since it's - never actually used. - (expand_indirect_vtbls_init): Delete init of VBASE_DECL. - (get_base_distance_recursive): Delete unused fourth arg - BASETYPE_PATH. Fix call . - (get_base_distance): Fix call. - (push_class_decls): Delete unused var ID. - (make_memoized_table_entry): Declare as static. - (breadth_first_search): Declare as static. - (tree_has_any_destructor_p): Declare as static. - (pop_class_decls): Delete unused arg pop_class_decls. - * class.c (popclass): Fix call to pop_class_decls. - * cp-tree.h (make_memoized_table_entry, breadth_first_search, - tree_has_any_destructor_p): Delete prototypes. - - * rtti.c (build_ptmf_desc): Delete unused arg TYPE. - (build_t_desc): Fix call. Delete unused vars ELEMS and TT. - (build_dynamic_cast): Delete unused local vars TMP1 and RETVAL. - (build_user_desc): Delete unused var T. - (build_class_desc): Delete unused vars T and OFF. - (build_t_desc): Delete unused var NAME_STRING. - (build_headof): Make static. - (get_bad_cast_node): Likewise. - (get_def_to_follow): Likewise. - * cp-tree.h (init_type_desc): Add prototype. - (build_headof): Remove prototype. - -Thu Feb 22 00:54:22 1996 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (tsubst): Only look for matching decls at file scope for - non-member functions. - - * call.c (build_scoped_method_call): Handle scoped destructor - calls in templates. - - * decl.c (*_top_level): Also save previous_class_values. - - * pt.c (tsubst_expr): Support do {} while loops. - * parse.y (simple_stmt): Likewise. - * tree.def: Likewise. - - * method.c (build_overload_identifier): For a class nested in a - template class, don't mangle in the template parms from our - context. - - * lex.c, cp-tree.h: Remove support for template instantiations in - the pending_inlines code. - * pt.c: Remove dead functions and unused arguments. - (uses_template_parms): TYPENAME_TYPEs always use template parms. - * parse.y: Stop passing anything to end_template_decl. - * tree.c (print_lang_statistics): Only print tinst info #ifdef - GATHER_STATISTICS. - -Wed Feb 21 16:57:33 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (expand_recursive_init{,_1}): Delete decls. - (sort_member_init): Delete unused var INIT. - (emit_base_init): Delete unused var X. - (build_offset_ref): Delete unused var CNAME. - (sort_member_init): Delete unused var FIELDS_TO_UNMARK. - (emit_base_init): Delete unused local var BASE. Delete extern - decl of IN_CHARGE_IDENTIFIER. - (build_delete): Delete unused local var VIRTUAL_SIZE. - - * init.c (build_vec_delete): Delete unused third arg ELT_SIZE. - (build_delete): Fix call. - * decl2.c (delete_sanity): Likewise. - * cp-tree.h (build_vec_delete): Update prototype. - - * typeck.c (common_base_type): Delete unused var TMP. - (build_binary_op): Delete local var ARGS_SAVE. - (build_array_ref): Delete unused var ITYPE. - (c_expand_return): Delete unused var USE_TEMP. - - * typeck.c (compexcepttypes): Delete unused arg STRICT. - (comptypes): Fix calls. - * decl.c (duplicate_decls): Likewise. - * cp-tree.h (compexcepttypes): Delete extra arg. - - * decl2.c (check_classfn): Delete unused second arg CNAME. - * decl.c (start_decl, grokfndecl): Fix calls. - * init.c (do_friend): Likewise. - * cp-tree.h (check_classfn): Update prototype. - - * cp-tree.h (signature_error, import_export_vtable, - append_signature_fields, id_in_current_class, mark_used, - copy_assignment_arg_p): Add decls. - * decl2.c (mark_used): Delete decl. - - * class.c (n_*): Wrap with #ifdef GATHER_STATISTICS. - - * class.c (get_vtable_entry): Diable unused function. - (doing_hard_virtuals): Delete unused static global var. - (finish_struct_1): Don't init DOING_HARD_VIRTUALS. - (prepare_fresh_vtable): Delete unused vars PATH and RESULT. - (overrides): Delete unused vars RETTYPE and BASE_RETTYPE. - (modify_one_vtable): Delete unused var OLD_RTTI. - (finish_struct_anon): Delete unused vars OFFSET and X. - (finish_struct_bits): Delete unused var METHOD_VEC. - (get_basefndecls): Delete unused var PURPOSE. Delete unused - for-scope local variable METHODS. - - * call.c (user_harshness): Delete unused/unneeded arg PARM. - (ideal_candidate): Delete unused args BASETYPE and PARMS. - (build_method_call): Delete unused args passed into ideal_candidate. - (build_overload_call_real): Likewise. Delete unused var OVERLOAD_NAME. - * cp-tree.h (synthesize_method): Add decl. - - * decl.c (note_level_for_for): Give void return type. - (pushdecl_nonclass_level): Likewise. - (finish_function): Delete unused vars VFIELDS and ALLOCATED_THIS. - (poplevel): Delete unused var IMPLICIT_TRY_BLOCK. - (suspend_binding_level): Delete unused var LEVEL. - (duplicate_decls): Delete unused var CTYPE. - (duplicate_decls): Delete unused var PREVIOUS_C_DECL. - (init_decl_processing): Delete unused vars FLOAT_ENDLINK and - PTR_ENDLINK. - (grokdeclarator): Delete unused var C. - (grokdeclarator): Delete unused var SIZE_VARIES. - (grokparms): Delete unused var SAW_VOID. - (start_function): Delete unused var OLDDECL. - (cplus_expand_expr_stmt): Delete unused var - REMOVE_IMPLICIT_IMMEDIATELY. - - * cp-tree.h (pushdecl_nonclass_level): Fix prototype. - - * Makefile.in (CONFLICTS): Update to 12 shift/reduce. - -Wed Feb 21 00:06:17 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (build_min): Set TREE_COMPLEXITY to lineno. - (build_min_nt): Likewise. - * pt.c (do_pushlevel): Emit line note. - (do_poplevel): Return what we get from poplevel. - (tsubst_expr): Set lineno from TREE_COMPLEXITY in stmt nodes. - * parse.y: Use do_pushlevel and do_poplevel. - * cp-tree.h: Declare do_poplevel. - - * cp-tree.h: Declare at_eof. - * decl.c (cp_finish_decl): Pass it to rest_of_decl_compilation. - * decl2.c (import_export_decl): Renamed from import_export_inline. - (finish_file): Call it to do interface handling for statics. - * pt.c (tsubst_copy): Call mark_used on variables and functions - used here. - - * decl2.c (finish_file): Don't emit statics we can't generate. - * pt.c (instantiate_decl): Don't set interface on instantiations - we can't generate. - - * cp-tree.h (struct tinst_level): Change 'classname' to 'decl'. - * tree.c (print_lang_statistics): Print max template depth. - * pt.c (push_tinst_level): Dump entire instantiation context. - (instantiate_class_template): Use it and pop_tinst_level. - (instantiate_decl): Likewise. - - * call.c class.c cp-tree.h decl.c decl2.c error.c lex.c method.c - pt.c ptree.c tree.def: Remove all traces of UNINSTANTIATED_P_TYPE. - -Tue Feb 20 18:21:51 1996 Jason Merrill <jason@yorick.cygnus.com> - - * call.c class.c cp-tree.h cvt.c decl.c decl2.c error.c expr.c - init.c lex.c method.c parse.y pt.c repo.c search.c spew.c tree.c - tree.def typeck.c typeck2.c xref.c: Massive, systemic changes for - the new template implementation. - -Tue Feb 20 17:14:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (check_cp_case_value): Use STRIP_TYPE_NOPS. - -Thu Feb 15 18:44:42 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (cp_finish_decl): Delay emitting the debug information for - a typedef that has been installed as the canonical typedef, if the - type has not yet been defined. - -Thu Feb 15 09:39:08 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (grokfield): Still call pop_nested_class for access decls. - -Wed Feb 14 17:30:04 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (lookup_label): Call label_rtx. - - * decl.c (make_binding_level): New function. - (pushlevel, pushlevel_class): Call it instead of explicit - duplicate calls to xmalloc. - - * decl.c (init_decl_processing): Delete useless build_pointer_type - call. - - * decl.c (float_ftype_float, ldouble_ftype_ldouble): Add definitions. - (sizet_ftype_string): Delete variable. - (init_decl_processing): Add built-in functions fabsf, fabsl, - sqrtf, sqrtl, sinf, sin, sinl, cosf, cos, cosl. New local - variable strlen_ftype, used for strlen. - -Wed Feb 14 16:21:25 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (push_to_top_level): Start from current_binding_level - again for now; the stl hacks depend on g++ being broken in this - way, and it'll be fixed in the template rewrite. - - * tree.def: Add USING_DECL. - * decl2.c (do_class_using_decl): Implement. - (grokfield): Pass access decls off to do_class_using_decl instead of - grokdeclarator. - * error.c (dump_decl): Handle USING_DECLs. - * decl.c (grokdeclarator): Remove code for handling access decls. - * class.c (finish_struct_1): Adjust accordingly, treat using-decls - as access decls for now. - (finish_struct): Don't check USING_DECLs for other uses of the name. - - * search.c (get_matching_virtual): Use cp_error_at. - -Wed Feb 14 10:36:58 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (comptypes): Default COMP_TYPE_ATTRIBUTES to 1, to - match c-typeck.c. - (self_promoting_args_p): Move the check that TYPE is non-nil - before trying to look at its main variant. - (unsigned_type, signed_type): Add checking of DI/SI/HI/QI nodes. - - * cp-tree.h (DECL_WAITING_FRIENDS, SET_DECL_WAITING_FRIENDS): - Delete macros. - * init.c (xref_friend, embrace_waiting_friends): Delete functions. - (do_friend): Delete call to xref_friend. - * class.c (finish_struct_1): Delete call to embrace_waiting_friends. - - * typeck.c (convert_sequence): #if 0 unused function. - - * cp-tree.h (DECL_IN_MEMORY_P): New macro w/ the check that used to - be in decl_in_memory_p. - (decl_in_memory_p): Delete decl. - * expr.c (decl_in_memory_p): Delete fn. - * typeck.c (mark_addressable): Use DECL_IN_MEMORY_P. - - * decl.c (cp_finish_decl): Use DECL_IN_MEMORY_P. - -Tue Feb 13 12:51:21 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Check for a pure-specifier on a - non-virtual function here. - - * decl2.c (grok_function_init): Don't check whether the function - is virtual here. - (grokfield): Don't call check_for_override here. - - * decl.c (push_to_top_level): Start from inner_binding_level, - check class_shadowed in class levels. - -Mon Feb 12 17:46:59 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (resume_level): Ignore things that don't have names, instead - of core dumping. - -Mon Feb 12 15:47:44 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (grokfield): Set DECL_VINDEX properly for FUNCTION_DECLs. - -Sat Feb 10 17:59:45 1996 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_1): Set DECL_VINDEX properly on a - synthesized dtor. - - * parse.y (complete_type_name): Bind global_scope earlier. - (complex_type_name): Likewise. - (qualified_type_name): Remove. - -Thu Feb 8 15:15:14 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (grokfndecl): Move code that looks for virtuals in base - classes... - * class.c (check_for_override): ... to a new function. - (finish_struct_1): Call it. - - * cp-tree.h: Declare warn_sign_compare. - - * typeck.c (build_binary_op_nodefault): Check warn_sign_compare - rather than extra_warnings to decide whether to warn about - comparison of signed and unsigned. - - * decl2.c (lang_decode_option): Handle warn_sign_compare. -Wall - implies -Wsign-compare. -Wall doesn't imply -W. - -Wed Feb 7 15:27:57 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_component_ref): Fix to handle anon unions in base - classes as well. - -Wed Feb 7 14:29:12 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * class.c (resolves_to_fixed_type_p): Delete code dealing with - a WITH_CLEANUP_EXPR, since we don't generate them any more. - * cvt.c (build_up_reference): Likewise. - * decl.c (grok_reference_init): Likewise. - (cp_finish_decl): Likewise. - * error.c (dump_expr): Likewise. - * tree.c (real_lvalue_p): Likewise. - (lvalue_p): Likewise. - (build_cplus_new): Likewise. - (unsave_expr_now): Likewise. - * typeck.c (unary_complex_lvalue, build_modify_expr, - c_expand_return): Likewise. - -Tue Feb 6 13:39:22 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - Make the C++ front-end pay attention to attributes for structures. - * class.c (finish_struct): New argument ATTRIBUTES, passed down into - finish_struct_1. - (finish_struct_1): New argument ATTRIBUTES; call cplus_decl_attributes. - Take out old round_up_size use and setting the DECL_ALIGN possibly - using it. Take out setting of TYPE_ALIGN to round_up_size, which - can override what the attribute set. - * cp-tree.h (finish_struct): Update prototype. - * parse.y (template_instantiate_once): Pass a NULL_TREE for the - attributes to finish_struct. - (structsp): For a CLASS decl, add maybe_attribute to rule and pass that - value down into finish_struct. - * Makefile.in (CONFLICTS): Switch to 7 shift/reduce conflicts. - -Tue Feb 6 13:12:15 1996 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (poplevel): Re-word dead for local handling. - (pushdecl): Remove useless DECL_DEAD_FOR_LOCAL test. - (cp_finish_decl): If is_for_scope, check for duplicates so - we can disable is_for_scope. Otherwise, preserve_temp_slots. - - * lex.c (do_identifier): Use global binding in preference of - dead for local variable. - -Mon Feb 5 17:46:46 1996 Mike Stump <mrs@cygnus.com> - - * init.c (initializing_context): Handle anon union changes, the - context where fields of anon unions can be initialized now has to be - found by walking up the TYPE_CONTEXT chain. - -Fri Feb 2 14:54:04 1996 Doug Evans <dje@charmed.cygnus.com> - - * decl.c (start_decl): #ifdef out code to set DECL_COMMON - if ASM_OUTPUT{,_ALIGNED}_BSS is defined. - (obscure_complex_init): If bss is supported, always set - DECL_INITIAL to error_mark_node. - -Thu Feb 1 16:19:56 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (is_friend): Make sure there's a context before we see if - it's an aggr type. - -Thu Feb 1 15:44:53 1996 Mike Stump <mrs@cygnus.com> - - * init.c (is_friend): Classes are not friendly with nested classes. - -Thu Feb 1 15:27:37 1996 Doug Evans <dje@charmed.cygnus.com> - - * lex.c (check_newline): Pass last character read to HANDLE_PRAGMA, - and record its result. - -Thu Feb 1 09:27:01 1996 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct_anon): Switch around code to not move anon - union elements around, nor mess up their contexts, nor offsets, - instead we now build up the right number of COMPONENT_REFs for all - the anon unions that may be present at build_component_ref time. - * typeck.c (lookup_anon_field): New routine to handle field lookup - on fields without names. We find them, based upon their unique type - instead. - * typeck.c (build_component_ref): Allow FIELD_DECL components. - Handle finding components in anonymous unions, and ensure that a - COMPONENT_REF is built for each level as necessary. - -Tue Jan 30 18:18:23 1996 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): Make the INDIRECT_BIND case come after - code that ensures that copy ctors are used if appropriate. - -Tue Jan 30 17:35:14 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_vec_delete): Only give an error if base isn't an - error_mark_node. - -Mon Jan 29 17:09:06 1996 Mike Stump <mrs@cygnus.com> - - * spew.c (do_aggr): `new struct S;' isn't a forward declaration. - (yylex): If we see `new', keep slurping. - -Thu Jan 25 18:31:36 1996 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct_1): Move code for handling anon unions... - (finish_struct_anon): to here. Fixup so that we do the offset - calculations right, and so that the fields are physically moved to - the containers's chain. - -Thu Jan 25 18:27:37 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Avoid trying to get an operand off an - identifier node. - -Wed Jan 24 11:25:30 1996 Jim Wilson <wilson@chestnut.cygnus.com> - - * typeck.c (pointer_int_sum): Use TYPE_PRECISION (sizetype) not - POINTER_SIZE to agree with expr.c. - -Thu Jan 25 13:01:23 1996 Mike Stump <mrs@cygnus.com> - - * search.c (lookup_field): Don't report ambiguities if protect is 0, - instead return NULL_TREE. - -Wed Jan 24 13:01:26 1996 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct_1): Call warn_hidden if we want warnings - about overloaded virtual functions. - (warn_hidden): New routine to warn of virtual functions that are - hidden by other virtual functions, that are not overridden. - (get_basefndecls): New routine, used by warn_hidden. - (mark_overriders): New routine, used by warn_hidden. - * search.c (get_matching_virtual): Remove old warning that just - isn't very useful. - -Tue Jan 23 12:26:10 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (output_builtin_tdesc_entries): #if 0 the function definition. - - * typeck.c (null_ptr_cst_p): Delete unused fn. - (build_function_call_maybe): Delete unused fn. - - * expr.c (extract_init): #if 0 the code after unconditional return 0 - for now. - - Delete old cadillac code. - * edsel.c: Remove file. - * Make-lang.in (CXX_SRCS): Take edsel.c off the list. - * Makefile.in (CXX_OBJS): Delete edsel.o. - (edsel.o): Delete rule. - * cp-tree.h (flag_cadillac): Delete var decl. - * lang-options.h: Delete "-fcadillac" and "-fno-cadillac". - * decl2.c (flag_cadillac): Delete var definition. - (lang_decode_option): Delete handling of -fcadillac and -fno-cadillac. - (grokfield): Delete code depending on flag_cadillac. - (finish_anon_union): Likewise. - * class.c (finish_struct_1): Likewise. - (pushclass): Likewise. - (popclass): Likewise. - (push_lang_context): Likewise. - (pop_lang_context): Likewise. - * decl.c (init_decl_processing): Likewise. - (start_decl): Likewise. - (cp_finish_decl): Likewise. - (xref_tag): Likewise. - (finish_enum): Likewise. - (start_function): Likewise. - (finish_function): Likewise. - (finish_stmt): Likewise. - * lex.c (lang_init): Likewise. - (check_newline): Likewise. - - * lex.c (do_pending_inlines): Delete synthesized method kludge. - - Delete defunct, ancient garbage collection implementation. - * rtti.c: New file with the RTTI stuff from gc.c. - * gc.c: Removed file (moved the remaining stuff into rtti.c). - * Makefile.in (CXX_OBJS): Replace gc.o with rtti.o. - (rtti.o): New rule, replacing gc.o. - * Make-lang.in (CXX_SRCS): Replace gc.c with rtti.c. - * cp-tree.h: Delete gc-related fn decls. - (DECL_GC_OFFSET): Delete macro. - (flag_gc): Delete extern decl. - * decl.c (current_function_obstack_index): Delete var decl. - (current_function_obstack_usage): Delete var decl. - (start_function): Delete clearing of current_function_obstack_index - and current_function_obstack_usage. - (init_decl_processing): Delete code relying on -fgc. - Delete call to init_gc_processing. - (cp_finish_decl): Delete calls to build_static_gc_entry and - type_needs_gc_entry. Delete gc code setting DECL_GC_OFFSET. - (store_parm_decls): Delete -fgc calls to cp_expand_decl_cleanup - and to expand_expr of a __gc_main call. - (maybe_gc_cleanup): Delete var decl. - (finish_function): Delete call to expand_gc_prologue_and_epilogue. - * decl2.c (flag_gc): Delete var decl. - (lang_f_options): Delete offering of -fgc. - (lang_decode_option): Delete -fgc and -fno-gc handling. - (get_temp_regvar): Delete gc code. - * init.c (build_new): Delete gc code. - * lex.c (init_lex): Delete checking of flag_gc. - - * typeck.c (convert_arguments): Delete gc code. - (build_component_addr): Delete -fgc warning. - (build_modify_expr): Delete gc code. - - * decl2.c (build_push_scope): Delete fn. - * cp-tree.h (build_push_scope): Delete decl. - - * search.c (clear_search_slots): Delete fn. - * cp-tree.h (clear_search_slots): Delete decl. - - * search.c (tree_needs_constructor_p): Delete fn. - * cp-tree.h (tree_needs_constructor_p): Delete decl. - - * tree.c (id_cmp): Delete fn. - - * tree.c (set_fnaddr_from_vtable_entry): Delete fn. - * cp-tree.h (set_fnaddr_from_vtable_entry): Delete decl. - - * tree.c (decl_value_member): Delete fn. - * cp-tree.h (decl_value_member): Delete decl. - - * tree.c (list_hash_lookup_or_cons): Delete fn. - * cp-tree.h (list_hash_lookup_or_cons): Delete decl. - - * method.c (cplus_exception_name): Delete fn. - (EXCEPTION_NAME_{PREFIX, LENGTH}): Delete macros. - - * spew.c (shift_tokens): Delete fn. - -Mon Jan 22 17:49:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * except.c (init_exception_processing): Pass 1 to needs_pop in calls - to cp_finish_decl. - * parse.y: Likewise. - -Mon Jan 22 17:34:29 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * tree.c (build_cplus_staticfn_type): Delete function definition; - never used. - * cp-tree.h (build_cplus_staticfn_type): Delete decl. - - * tree.c (virtual_member): Delete function definition; never used. - * cp-tree.h (virtual_member): Delete decl. - -Fri Jan 19 18:03:14 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_component_ref): Handle getting vbase pointers - out of complex multiple inheritance better. - -Fri Jan 19 16:27:40 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_object_ref): Make sure we use the real type, not - any reference type. - -Fri Jan 19 16:01:47 1996 Mike Stump <mrs@cygnus.com> - - * tree.c (build_exception_variant): Don't create new types if we - don't have to, also build new types on the right obstack. - -Fri Jan 19 14:09:44 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (store_bindings): Split out from push_to_top_level. - (push_to_top_level): Call it for b->type_shadowed on class binding - levels. - -Fri Jan 19 13:53:14 1996 Mike Stump <mrs@cygnus.com> - - * search.c (expand_upcast_fixups): Fix so that offsets stored in - vbase_offsets are always right. Fixes a problem where virtual base - upcasting and downcasting could be wrong during conversions on this - during virtual function dispatch at ctor/dtor time when dynamic - vtable fixups for deltas are needed. This only sounds easier than - it is. :-) - (fixup_virtual_upcast_offsets): Change to reflect new calling - convention for expand_upcast_fixups. - -Fri Jan 19 12:23:08 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (grokbitfield): Strip the NOPs from WIDTH before we - check that it's usable as the bitfield width. - -Wed Jan 17 21:22:40 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (grokfield): Call cplus_decl_attributes with the attrlist. - Pass a null tree to grokdeclarator for its ATTRLIST arg, since it's - only ever used for functions in it. - -Wed Jan 17 12:10:38 1996 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (qualified_type_name): Use the TYPE_DECL, not the type. - (nested_type): Likewise. - (nested_name_specifier): Use lastiddecl. - - * decl.c (grokdeclarator): Adjust accordingly. - * init.c (expand_member_init): Likewise. - * parse.y (base_class): Likewise. - * typeck2.c (build_functional_cast): Likewise. - - * typeck2.c (build_functional_cast): Fill in name after we've - checked for non-aggr type. - -Wed Jan 17 10:18:01 1996 Mike Stump <mrs@cygnus.com> - - * decl2.c (warn_pointer_arith): Default to on. - -Tue Jan 16 12:45:38 1996 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (is_rid): New function. - * decl.c (grokdeclarator): Diagnose reserved words used as - declarator-ids. - -Tue Jan 16 11:39:40 1996 Jason Merrill <jason@yorick.cygnus.com> - - * tree.c (get_decl_list): Don't lose cv-quals. - - * decl.c (grokdeclarator): Fix SCOPE_REF handling and diagnose - typespecs used as declarator-ids. - -Tue Jan 16 11:09:42 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (poplevel): When poping a level, don't give a warning for - any subblocks that already exist. - -Tue Jan 16 00:25:33 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_object_ref): Finish what I started. - - * parse.y (qualified_type_name): Don't check TYPE_BUILT_IN. - - * decl2.c (constructor_name_full): Handle TEMPLATE_TYPE_PARMs. - - * decl.c (grokdeclarator): Also accept TEMPLATE_TYPE_PARM as a - scope. - -Mon Jan 15 16:19:32 1996 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (xref_tag): Handle passing a type in directly. - - * parse.y (qualified_type_name): Pull out the type. - (nested_type): Likewise. - Take types directly instead of as identifiers. - * call.c (build_scoped_method_call): Take types directly instead of - as identifiers. - * decl.c (xref_basetypes): Likewise. - * init.c (expand_member_init): Likewise. - (build_member_call): Likewise. - (build_offset_ref): Likewise. - * typeck2.c (build_scoped_ref): Likewise, remove bogus code. - * method.c (do_build_assign_ref): Likewise. - * decl.c (grokdeclarator): Handle a type appearing as the - declarator-id for constructors. - * method.c (do_build_copy_constructor): current_base_init_list now - uses the types directly, not their names. - * init.c (sort_base_init): Likewise. - (expand_member_init): Likewise. - * init.c (is_aggr_type): New function, like is_aggr_typedef. - -Mon Jan 15 08:45:01 1996 Jeffrey A Law <law@cygnus.com> - - * tree.c (layout_basetypes): Call build_lang_field_decl instead - of build_lang_decl if first arg is a FIELD_DECL. - -Thu Jan 11 14:55:07 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (cp_finish_decl): Only clear TREE_USED if DECL_NAME is - non-empty. - * except.c (expand_start_catch_block): Set TREE_USED to avoid - warnings about the catch handler. - -Mon Jan 8 17:35:12 1996 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (build_modify_expr): Use a COMPOUND_EXPR instead of - expand_target_expr. - -Thu Jan 4 12:30:32 1996 Brendan Kehoe <brendan@lisa.cygnus.com> - - Fix access control to use trees rather than integers. - * class.c (access_{default, public, protected, private, - default_virtual, public_virtual, private_virtual}_node): Add - definitions. - (init_class_processing): Do creation of those nodes. - * cp-tree.h (access_type): Delete enum decl. - (access_{default, public, protected, private, default_virtual, - public_virtual, private_virtual}_node): Add decls. - (compute_access): Change return type. - * search.c (compute_access): Have tree return type, instead of enum. - (lookup_field): Declare THIS_V and NEW_V to be tree nodes. - * lex.c (real_yylex): Use yylval.ttype for giving the value of the - access_* node for each of RID_{PUBLIC, PRIVATE, PROTECTED}. - * parse.y (VISSPEC): Make ttype rather than itype. - (base_class_access_list): Likewise. - * *.[cy]: Change all refs of `access_public' to `access_public_node', - etc. - * call.c (build_method_call): Make ACCESS be a tree. - * class.c (alter_access, finish_struct_1, filter_struct): Likewise. - * cvt.c (convert_to_aggr): Likewise. - * init.c (build_offset_ref, resolve_offset_ref, build_delete): - Likewise. - * method.c (hack_identifier): Likewise. - * typeck.c (build_component_ref_1, build_component_ref): ): Likewise. - -Thu Jan 4 11:02:20 1996 Mike Stump <mrs@cygnus.com> - - * typeck.c (pointer_int_sum, pointer_diff): Make code agree with C - frontend, and make it more consistent with respect to - warn_pointer_arith. - -Tue Jan 2 00:13:38 1996 Rusty Russell <rusty@adelaide.maptek.com.au> - - * decl.c (pushdecl): Check for duplicate parameter names. - -Wed Jan 3 09:25:48 1996 Mike Stump <mrs@cygnus.com> - - * decl.c (expand_static_init): Call assemble_external for atexit. - -Wed Jan 3 07:55:19 1996 Mike Stump <mrs@cygnus.com> - - * except.c (do_unwind): Remove some generated dead code. - (eh_outer_context): New routine, factor out some common code from - expand_builtin_throw and end_eh_unwinder. Add code to do return - address masking for the PA. - (expand_builtin_throw): Use eh_outer_context instead of open coding - it here. - (end_eh_unwinder): Likewise. - -Tue Jan 2 17:00:56 1996 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Call assemble_external for __empty, if we - use it. - -Thu Dec 28 11:13:15 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_builtin_throw): Use RETURN_ADDR_OFFSET instead of - NORMAL_RETURN_ADDR_OFFSET. - (end_eh_unwinder): Likewise. - -Wed Dec 27 22:18:16 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_dynamic_cast): Make sure we don't cast away const - when dealing with references, and make sure we handle dynamic - casting to a cv qualified reference. - -Thu Dec 21 23:50:35 1995 Mike Stump <mrs@cygnus.com> - - * except.c (struct eh_context): New structure top hold eh context - information. - (push_eh_context): New routine. - (pop_eh_context): Likewise. - * decl.c (push_cp_function_context): Use them. - (pop_cp_function_context): Likewise. - -Wed Dec 20 12:42:51 1995 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Also prune uninteresting functions in the - inline emission loop. - -Wed Dec 20 02:32:07 1995 Jeffrey A Law <law@cygnus.com> - - * sig.c (build_signature_table_constructor): Mark functions - in the signature as referenced. - -Tue Dec 19 22:36:56 1995 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (finish_file): Do all the vtable/synthesis stuff before - the inline emission stuff. - -Mon Dec 18 15:51:33 1995 Jason Merrill <jason@yorick.cygnus.com> - - * cp-tree.h, decl2.c (flag_weak): New flag to control the use of - weak symbols. - * lang-options.h: Add -f{no-,}weak. - * decl.c (init_decl_processing): If the target does not support weak - symbols, don't use them. - * decl2.c, pt.c: s/SUPPORTS_WEAK/flag_weak/. - -Sun Dec 17 21:13:23 1995 Rusty Russell <rusty@adelaide.maptek.com.au> - - * init.c (expand_member_init): warning for base init after members. - -Fri Dec 15 15:32:18 1995 Jason Merrill <jason@yorick.cygnus.com> - - * cvt.c (build_expr_type_conversion): Don't convert to a reference - type. - -Thu Dec 14 16:05:58 1995 Mike Stump <mrs@cygnus.com> - - * method.c (report_type_mismatch): Improve wording for volatile - mismatches. - -Thu Dec 14 14:16:26 1995 Mike Stump <mrs@cygnus.com> - - * init.c (expand_aggr_init_1): Use expand_aggr_init_1 instead of - expand_assignment, as the later doesn't handle things that have - copy constructors well. The compiler would do bitwise copying, - instead of ctor calling in some cases. - -Wed Dec 13 17:05:54 PST 1995 Paul Eggert <eggert@twinsun.com> - - * g++.c (my_strerror): Return "cannot access" if errno is 0. - (pfatal_with_name, perror_exec): Don't assume that - the returned value from my_strerror contains no '%'s. - (concat): Remove. - (sys_nerror): Declare only if HAVE_STRERROR is not defined. - -Wed Dec 13 16:22:38 1995 Jason Merrill <jason@yorick.cygnus.com> - - Lose CLASSTYPE_METHODS/DECL_NEXT_METHOD chain; make - TYPE_METHODS/TREE_CHAIN mean what they used to. - * decl2.c (constructor_name_full): Refer to CLASSTYPE_METHOD_VEC - instead of TYPE_METHODS. - * decl.c (duplicate_decls): Lose references to DECL_NEXT_METHOD. - * tree.c (tree_copy_lang_decl_for_deferred_output): Likewise. - * cp-tree.h (CLASSTYPE_METHODS): Lose. - (CLASSTYPE_METHOD_VEC): Point to lang_spec->methods instead of - TYPE_METHODS. - (struct lang_decl): Lose next_method field. - (DECL_NEXT_METHOD): Lose. - * class.c (finish_struct_methods): Don't mess with TYPE_METHODS. - (finish_struct): Just use TYPE_METHODS; we don't need fn_fields - anymore. - (finish_struct_methods): Don't mess with the TREE_CHAINs in - fn_fields. - - * search.c (add_conversions): Don't use TREE_CHAIN to traverse method - vector. - - * call.c (build_method_call): Synthesize here even when not inlining. - * typeck.c (build_function_call_real): Likewise. - -Wed Dec 13 15:02:39 1995 Ian Lance Taylor <ian@cygnus.com> - - * cp/lex.c (check_newline): If DBX_DEBUGGING_INFO and write_symbols - == DBX_DEBUG, call dbxout_start_new_source_file and - dbxout_resume_previous_source_file when appropriate. - -Tue Dec 12 20:38:55 1995 Mike Stump <mrs@cygnus.com> - - * except.c (start_anon_func): Push to the top level. - (end_anon_func): Pop from the top level. - -Mon Dec 11 18:56:14 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (build_cleanup): New routine to build cleanups. - * decl.c (expand_static_init): Use build_cleanup to build a cleanup - call at ctor time and use atexit to run it later. - * decl2.c (build_cleanup): New routine, taken from finish_file. - (finish_file): Use build_cleanup instead, and don't put function - local statics in global dtor list. - -Wed Dec 6 14:34:29 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Ensure that we have cleanups, if we try - and expand cleanups. - -Wed Dec 6 11:48:21 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Add logic to manage dynamic cleanups for - the EH object. - (expand_end_catch_block): Use the magic of expand_goto, instead of - emit_jump so that we get the cleanup for any catch clause parameter - and the cleanup for the exception object. Update to reflect label - changes. - (push_eh_cleanup): New routine to register a cleanup for an - exception object. - (empty_fndecl): Used to default cleanup actions to - nothing. - (init_exception_processing): Setup empty_fndecl. Setup - saved_cleanup. - (expand_start_catch_block): Update to reflect label changes. Call - push_eh_object to register the cleanup for the EH object. - (start_anon_func): New routine to start building lambda expressions - from trees. - (end_anon_func): New routine to end them. - (struct labelNode): Change so that we can use tree labels, or rtx - labels. - (saved_cleanup): Object to check for dynamic cleanups for the - exception handling object. - (push_label_entry): Change so that we can use tree labels, or rtx - labels. - (pop_label_entry): Likewise. - (top_label_entry): Likewise. - (expand_start_all_catch): Use tree label instead of rtx label, so - that we can get the magic of expand_goto. - (expand_end_all_catch): Update to reflect label changes. - - * class.c (build_vfn_ref): Remove building_cleanup logic, as we now - use UNSAVE_EXPRs. - typeck.c (get_member_function_from_ptrfunc): Remove remnants of - building_cleanup logic, as we now use UNSAVE_EXPRs. - * cp-tree.h (unsave_expr): Declare it. - * decl.c (building_cleanup): Remove. - (maybe_build_cleanup): Remove building_cleanup logic, and use - UNSAVE_EXPR instead. - -Sun Dec 3 01:34:58 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_t_desc): Update error message to say <typeinfo>. - -Thu Nov 30 12:30:05 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (pushdecl): Only warn about shadowing a local variable if - warn_shadow is true. - -Sun Nov 26 16:06:55 1995 Rusty Russell <rusty@adelaide.maptek.com.au> - - * typeck.c (build_binary_op_nodefault): Added warning about - comparisons between different enum types with -Wall, unless - -fenum-int-equiv set. - -Wed Nov 22 15:44:02 1995 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct_1): Skip down to the inner type in - multidimensional arrays. Ensures ctors will be made for types that - need constructing. - -Wed Nov 22 14:19:22 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (last_dtor_insn): New to track the last compiler generated - insn in a dtor. - (store_parm_decls): Set it. - (finish_function): Use it to see if the dtor is empty. Avoid doing - vtable setup all the time, if we can. - (struct cp_function): Add last_dtor_insn. - (push_cp_function_context): Save it. - (pop_cp_function_context): Restore it. - -Wed Nov 22 11:52:19 1995 Paul Russell <Rusty.Russell@adelaide.maptek.com.au> - - * typeck.c (build_unary_op): Set TREE_NO_UNUSED_WARNING to avoid - warnings. - -Tue Nov 21 17:15:23 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (expand_target_expr): Make sure targets get put into the - current temp_slot_level, so that the free_temp_slots call will reuse - them. - -Tue Nov 21 13:32:03 1995 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct_1): Delay delta fixups for virtual bases - until after we have done the hard virtuals, to avoid a bogus `every - virtual function must have a unique final overrider' for virtual - functions that are only overridden by hard virtuals. - -Thu Nov 9 13:35:30 1995 Jason Merrill <jason@yorick.cygnus.com> - - * pt.c (do_function_instantiation): Don't try to find a file-scope - template for a member function. - -Tue Nov 14 06:20:35 1995 Mike Stump <mrs@cygnus.com> - - * g++.c (main): Add handling of -nodefaultlibs. - -Mon Nov 13 15:45:34 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (INDIRECT_BIND): Add a way for the frontend to - distinguish between direct bindings of reference variables, and - indirect bindings of reference variables. - * cvt.c (build_up_reference): Use it. - * typeck.c (convert_arguments): Use it to indicate this is an - indirect binding. - * decl.c (cp_finish_decl): Ensure that we reuse stack slots as fast - as they are unused. - (expand_static_init): Likewise. - (cplus_expand_expr_stmt): Likewise. - * decl2.c (finish_file): Likewise. - * init.c (perform_member_init): Likewise. - (emit_base_init): Likewise. - (expand_aggr_vbase_init_1): Likewise. - -Fri Nov 10 09:18:09 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (push_namespace): Rewrite to use build_lang_decl, so we - get a DECL_LANG_SPECIFIC node. - * cp-tree.h (lang_decl_flags): Add new member `level'. - (NAMESPACE_LEVEL): Don't use decl.arguments, instead use the - decl_flags level member. - -Mon Nov 6 18:36:13 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (build_method_call): Make sure instance has a - TYPE_LANG_SPECIFIC node before we dive into it. - -Sat Nov 4 20:01:52 1995 Jason Molenda <crash@phydeaux.cygnus.com> - - * method.c (make_thunk): use TREE_SET_CODE to set thunk's tree code. - -Thu Nov 2 17:56:57 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (duplicate_decls): When smashing decls, smash staticness in - the usual way. - -Thu Nov 2 16:44:02 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (poplevel): Handle the merging of subblocks of cleanups - when finishing blocks that have already been created (usually due to - the fixup goto code). Fixes bad debugging information. - -Wed Nov 1 12:33:53 1995 Jason Merrill <jason@yorick.cygnus.com> - - * method.c (hack_identifier): Don't abort when we get a TREE_LIST - that's not a list of overloaded functions. - -Wed Nov 1 11:38:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (mark_vtable_entries): Check DECL_LANG_SPECIFIC on fn - before trying to use DECL_ABSTRACT_VIRTUAL_P. - -Tue Oct 31 11:56:55 1995 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (mark_used): New function for hooking into setting of - TREE_USED on decls. - * call.c (build_method_call): Use it. - * class.c (instantiate_type): Likewise. - * init.c (build_offset_ref): Likewise. Don't call assemble_external - for all like-named functions. - * method.c (hack_identifier): Likewise. - (emit_thunk): Don't call assemble_external. - (make_thunk): Create thunk as a FUNCTION_DECL so that it - gets the right mode and ENCODE_SECTION_INFO works. - - * parse.y: Use mark_used. Pass operator names to do_identifier. - * lex.c (do_identifier): Handle operator names. - - * decl2.c (grokclassfn): Tweak __in_chrg attributes. - -Thu Oct 26 16:45:58 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * errfn.c: Include stdio.h. - (cp_sprintf): Take out decl of sprintf, and cast sprintf to errorfn*. - -Wed Oct 25 18:58:41 1995 Mike Stump <mrs@cygnus.com> - - * typeck2.c (digest_init): Always convert initializers to the - right type. - -Wed Oct 25 13:25:24 1995 Mike Stump <mrs@cygnus.com> - - * init.c (member_init_ok_or_else): Don't allow member initializers - for indirect members, as it is invalid. - -Wed Oct 25 11:35:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Don't allow `friend signed ()'. - -Fri Oct 20 10:30:59 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (for.init.statement): Catch compound statements inside for - initializations, if we're being pedantic. - -Fri Oct 20 10:03:42 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (lookup_tag): Return NULL_TREE if we don't find what we are - looking for. - -Thu Oct 19 14:26:10 1995 Mike Stump <mrs@cygnus.com> - - * error.c (dump_expr): Don't core dump when a boolean expression is - used as a default argument. - -Thu Oct 19 10:36:30 1995 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_bits): Check aggregate_value_p instead of - RETURN_IN_MEMORY. - -Wed Oct 18 18:12:32 1995 Jason Merrill <jason@yorick.cygnus.com> - - * class.c (finish_struct_bits): Also set TREE_ADDRESSABLE on a - BLKmode type that would otherwise be returned in registers. - -Mon Oct 16 12:32:19 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++.c (WITHLIBC): New macro. - (main): Declare saw_libc. Use WITHLIBC if `-lc' was used; set - saw_libc and pass it at the end if it was set. - -Wed Oct 11 16:30:34 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (fn.def1): Call split_specs_attrs in - declmods notype_declarator case. diff --git a/gcc/cp/ChangeLog.1 b/gcc/cp/ChangeLog.1 deleted file mode 100755 index 78fa179..0000000 --- a/gcc/cp/ChangeLog.1 +++ /dev/null @@ -1,9451 +0,0 @@ -Sun Nov 26 14:47:42 1995 Richard Kenner <kenner@mole.gnu.ai.mit.edu> - - * Version 2.7.2 released. - -Mon Nov 20 14:05:00 1995 Mike Stump <mrs@cygnus.com> - - * g++.c (pfatal_with_name): Add missing third argument to concat. - -Thu Oct 26 13:59:54 1995 Mike Stump <mrs@cygnus.com> - - * init.c (expand_aggr_init): Handle cv qualifiers on the object's - type. - -Sat Nov 11 08:25:55 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * Version 2.7.1 released. - -Thu Nov 2 17:02:47 1995 Jason Merrill <jason@yorick.cygnus.com> - - * call.c (convert_harshness): Handle references to arrays. - -Fri Oct 27 14:20:21 1995 Jason Merrill <jason@yorick.cygnus.com> - - * typeck.c (comp_target_types): Check multi-level pointer - conversions in both directions. - -Tue Oct 17 21:39:05 1995 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (explicit_instantiation): Fix 'extern template' with no - return type. - -Mon Oct 16 14:35:20 1995 Jason Merrill <jason@yorick.cygnus.com> - - * parse.y (explicit_instantiation): Support automatic instantiation - of constructors. - (named_class_head_*): Support out-of-class definition of nested - types. - -Wed Oct 11 12:20:56 1995 Mike Stump <mrs@cygnus.com> - - * search.c (envelope_add_decl): New routine. Fix so that - methods are hidden in the same way that other members are. - (dfs_pushdecls): Cleanup and move functionality out of line, - into envelope_add_decl. - -Tue Oct 10 15:46:01 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (mark_addressable): Only call assemble_external if we - have started the output file. - -Tue Oct 10 11:27:18 1995 Jason Merrill <jason@yorick.cygnus.com> - - * decl.c (start_function): Fix earlier cv-quals change. - -Mon Oct 9 23:53:05 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (complex_direct_notype_declarator): Only push the class if - we are not already in the class. - -Mon Oct 9 11:22:03 1995 Doug Evans <dje@canuck.cygnus.com> - - * decl.c (duplicate_decls): Call merge_machine_decl_attributes. - Update olddecl's attributes too. - (grokdeclarator): #if 0 out call to build_decl_attribute_variant. - * typeck.c (common_type): Call merge_machine_type_attributes. - -Fri Oct 6 14:44:27 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (mark_addressable): Add missing call to - assemble_external. - -Wed Oct 4 15:06:39 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (store_parm_decls): Make sure the unwinder start comes - before the exception specification start. - * except.c (expand_exception_blocks): Make sure the unwinder end - comes after the terminate protected catch clause region and after - the end of the exception specification region. - -Wed Oct 4 12:47:02 1995 Jason Merrill <jason@yorick.cygnus.com> - - * lex.c (real_yylex): Fix identifier case for linemode. - (handle_sysv_pragma): Don't abort when we see a pragma we don't - recognize. - -Tue Oct 3 14:09:46 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (store_parm_decls): Add a call to start_eh_unwinder. - * except.c (init_exception_processing): __throw doesn't take any - arguments. - (expand_builtin_throw): Likewise. Always use Pmode, instead of SImode - for all pointers. Use expand_builtin_return_addr to unwind the - first level off the stack. - (do_unwind): Always use Pmode, instead of SImode for all pointers. - (expand_exception_blocks): Add a call to end_eh_unwinder. - (start_eh_unwinder, end_eh_unwinder): New routines to build machine - independent stack unwinders for function/method calls. - -Mon Oct 2 17:20:42 1995 Mike Stump <mrs@cygnus.com> - - * tree.c (unsave_expr_now): Make sure we process the argument list - of any called functions. Fixes incorrect code generation for - cleanups. - -Mon Oct 2 13:04:16 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (get_member_function_from_ptrfunc): Save function if it - needs it. Cures core dump on things like (this->*(f()))(). - -Sat Sep 23 22:51:25 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Conform to gcc cv-quals convention (no - expression has a cv-qualified type) in RESULT_DECLs. - * method.c (make_thunk): Likewise. - -Fri Sep 22 10:21:13 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (pushtag): Add in the namespace name for the tag. - -Thu Sep 21 13:11:13 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (maybe_base_class_list, base_class_list, base_class, - base_class_access_list): Make sure we see the typenames for base - classes. - * lex.c (see_typename): Instead of failing to see a typename when - there is no next token, perfer a typename, and get the next token. - -Wed Sep 20 12:35:27 1995 Michael Meissner <meissner@cygnus.com> - - * decl.c (init_decl_processing): Add __builtin_expect. - -Tue Sep 19 16:48:11 1995 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert_to_pointer): Don't allow leftover conversions to - or from pointer to member functions, they must all be handled before - this point. - -Fri Sep 15 17:14:47 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (resolve_offset_ref): Fix wording of non-static member - being referenced as a static. - -Fri Sep 15 12:39:11 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_indirect_ref): Only bash pointer if we actually - call build_expr_type_conversion. - -Thu Sep 14 18:24:56 1995 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_expr_type_conversion): Handle conversion from - reference. - * typeck.c (build_indirect_ref): Avoid infinite recursion. - -Thu Sep 14 17:23:28 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (expand_start_early_try_stmts): New routine to start a try - block at the start of the function, for function-try-blocks. - * cp-tree.h (expand_start_early_try_stmts): Declare it. - * parse.y (function_try_block): Use it, instead of doing it here, as - we don't want to include rtl.h here, as that conflicts with RETURN - in the parser. - -Wed Sep 13 18:32:24 1995 Mike Stump <mrs@cygnus.com> - - * lex.c (reinit_parse_for_block): Support saving inline - function-try-blocks, uses peekyylex. - * parse.y (eat_saved_input): New rule, permit the parser to see that - END_OF_SAVED_INPUT is ok, as it can see this when parsing the - handlers of a function-try-block. - (fndef): Use it. - (component_decl): Make sure TRY and RETURN can come after fn.def2. - * spew.c (peekyylex): New routine to peek at what will come next. - -Wed Sep 13 16:52:06 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (comptypes): Tighten up comparisons of template type - parms. - - * decl.c (duplicate_decls): Turn off whining about virtual functions - redeclared inline for now. - -Wed Sep 13 11:13:40 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (store_in_parms): New routine to put things before we - put base inits. - * cp-tree.h (store_in_parms): Declare it. - * decl.c (store_parm_decls): Use it to makr sure the starting of the - eh spec comes before base inits. - (finish_function): Use sequences instead of the obsolete - reorder_insns. - * parse.y (fndef): Enhance readability and maintainability. Update - to include function_try_block syntax. - (function_try_block): Add. - -Tue Sep 12 17:43:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (convert_harshness): Use comptypes, not ==, to check if - TYPE and PARMTYPE are equivalent on a function type. - -Tue Sep 12 17:31:33 1995 Douglas Rupp <drupp@cs.washington.edu> - - * Make-lang.in (cc1plus) : Removed unnecessary $(exeext). - -Mon Sep 11 23:24:07 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Never allocate storage for thrown pointer - to objects. - -Mon Sep 11 19:36:45 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_catch_block): Pointers to objects come - back from catch matching already dereferenced, don't dereference - again. - -Mon Sep 11 15:46:28 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Only decay the throw expression, don't do - any default conversions. This is so that one can throw and catch - characters, and not have them match integers. - -Mon Sep 11 13:46:45 1995 Mike Stump <mrs@cygnus.com> - - * error.c (dump_aggr_type): Deal with anonymous unions that don't - have a TYPE_NAME. - -Fri Sep 8 20:40:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (handle_sysv_pragma): Deal with getting a comma from yylex. - -Fri Sep 8 15:51:41 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_end_eh_spec): Handle empty EH specifications. - -Fri Sep 8 15:27:22 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (expand_start_eh_spec): Declare new routine. - (expand_end_eh_spec): Likewise. - * decl.c (store_parm_decls): Call expand_start_eh_spec to process - exception specifications. - * except.c (expand_leftover_cleanups): Remove unused parameter. - (expand_end_catch_block): Likewise. - (expand_exception_blocks): Likewise. - (expand_start_eh_spec): New routine to mark the start of an - exception specification region. - (expand_end_eh_spec): New routine to mark the end of an exception - specification region. - (expand_exception_blocks): Call expand_end_eh_spec to process - exception specifications. - -Fri Sep 8 14:40:48 1995 Per Bothner <bothner@kalessin.cygnus.com> - - * lex.c (do_identifier): Use global binding in preference of - dead for local variable. - -Wed Sep 6 19:32:59 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (build_exception_variant): Remove used first argument. - * decl.c (duplicate_decls): Likewise. - (grokfndecl): Likewise. - (revert_static_member_fn): Likewise. - * decl2.c (grok_method_quals): Likewise. - * tree.c (build_exception_variant): Likewise. - * typeck.c (common_type): Likewise. - * decl2.c (grokclassfn): After changing the type, call - build_exception_variant, if necessary. - -Tue Sep 5 15:56:27 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Run cleanups for the throw expression. - -Wed Aug 30 15:24:38 1995 Stephen L. Favor <sfavor@tigger.intecom.com> - - * except.c (expand_builtin_throw): Moved gen_label_rtx calls beyond - the store_parm_decls call which does initialization in the emit_* - code concerning label numbering. - -Thu Aug 31 09:01:07 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_internal_throw): Let the frontend be responsible - for managing all frontend EH parameters, the backend routine only - needs to deal with backend values. type and value are no longer - passed to __throw. - (init_exception_processing): Likewise. - (expand_start_all_catch): Likewise. - (expand_end_all_catch): Likewise. - (expand_leftover_cleanups): Likewise. - (expand_end_catch_block): Likewise. - (expand_builtin_throw): Likewise. - (expand_throw): Likewise. - -Tue Aug 29 15:04:36 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cp-tree.h (DECL_REAL_CONTEXT): Give the real declaration context - for a decl. - * decl.c (cp_finish_decl): Use it. - -Tue Aug 29 10:30:27 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_internal_throw): Oops, almost forgot type and - value are now trees. - -Mon Aug 28 17:57:45 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - Fix the attribute handling to make sure they get noted before we - create the function's RTL, in case they can affect that. - * decl.c (grokfndecl): New arg ATTRLIST. Run - cplus_decl_attributes before creating the decl's rtl. - (grokdeclarator): New arg ATTRLIST, passed down into grokfndecl. - (shadow_tag, groktypename, start_decl, start_method): Pass a - NULL_TREE to grokdeclarator's new last arg. - * decl2.c (grokfield): New arg ATTRLIST, passed into grokdeclarator. - (grokbitfield, grokoptypename): Pass a NULL_TREE to - grokdeclarator's new last arg. - * except.c (expand_start_catch_block): Likewise. - * pt.c (process_template_parm, end_template_decl, - do_function_instantiation): Likewise. - * cp-tree.h (grokfield): Add arg. - (grokdeclarator): Move the prototype from here... - * decl.h: ...to here. - * lex.c (cons_up_default_function): Pass NULL_TREE to grokfield - ATTRLIST argument. - * parse.y: Create a list for the grokfield arg where appropriate, - and pass it down instead of calling cplus_decl_attributes. - -Mon Aug 28 15:07:24 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Always allow turning on exception handling. Allow cross - compilations to use EH. - -Thu Aug 24 17:39:24 1995 Mike Stump <mrs@cygnus.com> - - * except.c (saved_pc, saved_throw_type, saved_throw_value): Use - trees, instead of rtxs, and don't depend on using special machine - dependent registers. - (expand_internal_throw): Likewise. - (init_exception_processing): Likewise. - (expand_start_all_catch): Likewise. - (expand_end_all_catch): Likewise. - (expand_start_catch_block): Likewise. - (expand_leftover_cleanups): Likewise. - (expand_end_catch_block): Likewise. - (expand_builtin_throw): Likewise. - (expand_throw): Likewise. - -Wed Aug 23 17:25:51 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (build_expr_type_conversion): Handle conversions to - reference types. - -Wed Aug 23 15:33:59 1995 Mike Stump <mrs@cygnus.com> - - * except.c (do_unwind): Work around backend bug with -fpic. - -Tue Aug 22 17:20:07 1995 Per Bothner <bothner@kalessin.cygnus.com> - - * decl2.c (flag_new_for_scope): Add a new mode that follows ANSI - for-scoping, but supports (and warns about) old programs. - Make the new mode (with value 1) the default. - (lang_f_options): The on-value for flag_new_for_scope is now 2. - * cp-tree.h (DECL_DEAD_FOR_LOCAL, DECL_ERROR_REPORTED): New macros - (DECL_SHADOWED_FOR_VAR): Likewise. - * decl.c (struct binding_level): New fields dead_vars_from_for - and is_for_scope. - (note_level_for_for): New function. - (poplevel): Special processing if is_for_scope. - (pushdecl): Warn if for-scope variable shadows local. - * lex.c (do_identifier): Handle old (non-ANSI) for scoping, - and warn if conflicts. - * parse.y (FOR): Call note_level_for_for. - -Mon Aug 21 10:28:31 1995 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (import_export_inline): Class interface hackery does not - apply to synthesized methods. - -Sun Aug 20 16:29:00 1995 Mike Stump <mrs@cygnus.com> - - * search.c (virtual_context): Find the right context more often. - Solves a `recoverable compiler error, fixups for virtual function' - problem. - -Sun Aug 20 13:53:24 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_all_catch): Ensure that we always transfer - control to the right EH handler, by rethrowing the end label on the - region, instead of hoping we are nested and falling through. - (expand_leftover_cleanups): Likewise. - (end_protect): Since we now rethrow the end label, put a - nop after it, so that outer regions are recognized. - * init.c (build_vec_delete_1): New routine to handle most of vector - deleting, all code moved here from build_vec_delete. - (build_array_eh_cleanup): Use build_vec_delete_1 to do all the real - work. - (expand_vec_init): If the array needs partial destructing, setup an - EH region to handle it. - (build_vec_delete): Move lots of code to build_vec_delete_1, use - build_vec_delete_1 to do the grunt work. - -Sat Aug 19 14:25:33 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - Handle decl attributes properly for function definitions without - previous attribute-loaded declarations. - * decl.c (start_function): New arg ATTRS. Add a call to - cplus_decl_attributes with it before we create the RTL. - * cp-tree.h (start_function): Update prototype. - * parse.y (fn.def1): Pass ATTRS into start_function instead of - trying to call cplus_decl_attributes too late. Pass a NULL_TREE - for other use. - * decl2.c (finish_file): Pass NULL_TREE as fourth arg to - start_function. - * method.c (synthesize_method): Likewise. - * except.c (expand_builtin_throw): Likewise for start on __throw. - -Sat Aug 19 13:36:08 1995 Mike Stump <mrs@cygnus.com> - - * class.c (set_rtti_entry): Turn on -fvtable-thunk -frtti support. - This changes -fvtable-thunks vtable layout, so a recompile will be - necessary, if you use -fvtable-thunks. - (get_vtable_entry): Use n, instead of i to be consistent with the - rest of the compiler. - (get_vtable_entry_n): Likewise. - (add_virtual_function): Add a slot for the tdesc, if -fvtable-thunks - are being used. - (finish_struct_1): Likewise. - (skip_rtti_stuff): New routine to collapse similar code from many - different parts of the compiler. I think I got them all. - (modify_one_vtable): Use it. - (fixup_vtable_deltas1): Likewise. - (override_one_vtable): Likewise. - * decl2.c (mark_vtable_entries): Likewise. - * tree.c (debug_binfo): Likewise. - * search.c (expand_upcast_fixups): Likewise. - (get_abstract_virtuals_1): Likewise. Use virtuals, instead of tmp to - consistent with the rest of the compiler. - (get_abstract_virtuals): Likewise. - * cp-tree.h (skip_rtti_stuff): New routine, declare it. - * gc.c (build_headof): Support -fvtable-thunk and -frtti together. - (build_typeid): Likewise. - (build_classof): Remove old style way of doing rtti. Remove support - for `classof' and `headof'. - * gxx.gperf: Likewise. - * hash.h: Likewise. - * parse.y: Likewise. - -Fri Aug 18 17:31:58 1995 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_function): Clear ctor_label and dtor_label. - - * class.c (finish_struct_1): Fix handling of access decls. - -Tue Aug 15 19:21:54 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct): Only do minimal processing here, so it - can be used for class template definitions, as well. - (finish_struct_1): New function with the rest of the code. - -Tue Aug 15 09:46:16 1995 Mike Stump <mrs@cygnus.com> - - * class.c (prepare_fresh_vtable): On second though, always build the - offset (see Aug 10 change), unless -fvtable-thunks is given. It - does this by calling the new routine set_rtti_entry. - (finish_struct): Likewise. - (set_rtti_entry): New routine to update the rtti information at the - start of the vtable. - -Mon Aug 14 12:21:22 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * error.c (dump_decl, case IDENTIFIER_NODE): Only work on a dtor - if it's declared in the C++ language spec. - (dump_function_decl): Likewise. - (dump_function_name): Likewise. - (ident_fndecl): Make sure we got something back from lookup_name. - * decl.c (start_function): Likewise. - -Fri Aug 11 16:52:15 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Don't call build_new when calling a - constructor without an instance. - -Thu Aug 10 20:00:17 1995 Mike Stump <mrs@cygnus.com> - - * class.c (prepare_fresh_vtable): Always build the offset to the - complete object, as it doesn't cost much. This allows dynamic_cast - to void * to work when -frtti isn't given. - (finish_struct): Likewise. - -Thu Aug 10 16:31:28 1995 Mike Stump <mrs@cygnus.com> - - * except.c (build_eh_type): Split out some functionality to new - routine named build_eh_type_type. - (build_eh_type_type): New routine. - (expand_start_catch_block): Use build_eh_type_type, as we never want - the dynamic type of the catch parameter, just the static type. - Fixes core dumps when -frtti is used and one catchs pointers to - classes. - -Thu Aug 10 14:55:29 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_builtin_throw): Since we now use normal calling - conventions for __throw, we have to remove the first layer off the - stack, so that the next context we search for handlers is the outer - context instead of the context that had the call to __throw, if we - don't immediately find the desired context. - -Tue Aug 8 17:44:23 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * tree.c (cp_expand_decl_cleanup): Returns int, not tree. - * cp-tree.h: Update. - - * parse.y (template_type_parm): Add support for `typename'. - -Tue Aug 8 12:06:31 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_internal_throw): New internal routine to throw a - value. - (expand_end_all_catch, expand_leftover_cleanups): All throwers - changed to use `expand_internal_throw' instead of jumping to throw - label. - (expand_end_catch_block, expand_throw): Likewise. - (throw_label): Removed. - (expand_builtin_throw): Changed so that EH parameters are passed by - normal function call conventions. Completes Aug 4th work. - -Fri Aug 4 17:17:08 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (expand_builtin_throw): Declare it. - * decl2.c (finish_file): Call expand_builtin_throw. - * except.c (make_first_label): Remove. - (init_exception_processing): Don't use a LABEL_REF for throw_label, - instead use a SYMBOL_REF, this is so that we don't use LABEL_REFs in - other functions that don't really appear in those functions. This - solves a problem where cc1plus consumed exponential amounts of - memory when -Wall was used. - (expand_end_all_catch, expand_leftover_cleanups, - expand_end_catch_block, expand_throw): Change all uses of - throw_label to match new style. - (do_unwind): Rename parameter to inner_throw_label, as it is now - different from throw_label. Also, assume that our caller will wrap - the passed label with a LABEL_REF, if needed. - (expand_builtin_throw): Make external, change so that the generated - throw is now a real function. - (expand_exception_blocks): Never generate throw code inside another - function. - -Fri Aug 4 12:20:02 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (grokdeclarator): Move checking of mutable const objects - and mutable static objects down, as we might decide during parsing - to unset staticp or constp (for example, when const is part of the - object being pointed to). - -Thu Aug 3 17:13:43 1995 Mike Stump <mrs@cygnus.com> - - * except.c (output_exception_table_entry): Enhance portability to - weird machines. - (emit_exception_table): Likewise. - -Thu Aug 3 16:41:38 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_ptrmemfunc): Handle casting of pointer to - non-virtual member functions. - -Wed Aug 2 11:58:25 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_typeid): Strip cv qualifiers so that const T&, T&, T - and const T all match. - -Wed Aug 2 11:25:33 1995 Mike Stump <mrs@cygnus.com> - - * except.c (build_eh_type): Strip cv qualifiers so that const T&, - T&, T and const T all match. - -Tue Aug 1 14:20:16 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Fix up comments, cleanup code and eliminate exceptNode, - exceptStack, exceptstack, push_except_stmts, pop_except_stmts, - new_except_stack, push_last_insn, pop_last_insn, insn_save_node and - InsnSave. Also, numerous speed improvements, and correctness - improvements. Double faulting in all situations should now be - handled correctly. - (expand_start_all_catch): Instead of having many terminate protected - regions, just have one. - (expand_start_catch_block): No longer have to protect - false_label_rtx, as it isn't used for EH region marking. - (expand_end_catch_block): Expand out EH cleanups here by using - expand_leftover_cleanups. - (expand_end_all_catch): Use sequences instead of playing with insn - links directly. - (expand_exception_blocks): Likewise. Also protect all catch clauses - with one terminate region. - -Mon Jul 31 13:24:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (report_type_mismatch): Don't talk about an object - parameter for non-methods. - -Sun Jul 30 13:13:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct): Catch private and protected members of - anonymous unions here. - * decl2.c (finish_anon_union): And here. - * parse.y: Instead of here. - - * errfn.c (ARGSLIST): Support passing four args. - * error.c (cv_as_string): New function. - (cp_printers): Add it. - * call.c (build_method_call): Report 'const' at end of pseudo-decl. - - * method.c (report_type_mismatch): Deal with a bad_arg of 0. - - * init.c (expand_aggr_init): Handle volatile objects, too. - -Sat Jul 29 13:42:03 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (struct binding_level): Keep list of incomplete decls. - (print_binding_level): Use list_length to count them. - (pushdecl): Build up the list. - (hack_incomplete_structures): Walk it and prune completed decls. - -Fri Jul 28 15:26:44 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (comp_target_types): Don't check const and volatile for - function types. - (comp_ptr_ttypes_real): Likewise. - -Thu Jul 27 15:40:48 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (comp_target_types): Fix. - -Thu Jul 27 15:10:48 1995 Mike Stump <mrs@cygnus.com> - - * cp-tree.h (unsave_expr_now, build_unsave_expr, - cp_expand_decl_cleanup): Declare new routines. - * decl.c (cp_finish_decl, store_parm_decls, - hack_incomplete_structures): Change all cals from - expand_decl_cleanup to cp_expand_decl_cleanup. - * gc.c (protect_value_from_gc): Likewise. - * expr.c (cplus_expand_expr): Handle UNSAVE_EXPRs. - * tree.c (unsave_expr): New routine to build an UNSAVE_EXPR. - (unsave_expr_now): Backend routine used by tree expander. - (cp_expand_decl_cleanup): Wrap second argument in an UNSAVE_EXPR to - work around a limitation in the backend. The backend uses the - cleanups multiple times, on disjoint control flows, so we cannot - pass unsaved SAVE_EXPRs to the backend. - * tree.def (UNSAVE_EXPR): New tree code. - * typeck.c (c_expand_return): Move goto/return code up inside - conditional, as we don't always want to do this, we only want to do - this when we don't otherwise finish with this control flow. - -Thu Jul 27 10:38:43 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (typespec): Only complain about typeof if we're not - getting it from a system header. - -Thu Jul 27 10:26:23 1995 Doug Evans <dje@canuck.cygnus.com> - - Clean up prefix attribute handling. - * parse.y (reserved_declspecs): Link prefix attributes with declspecs. - (declmods): Likewise. - (all rules that reference typed_declspecs and declmods): Call - split_specs_attrs or strip_attrs to separate declspecs and attrs. - (lang_extdef): Delete resetting of prefix_attributes. - (template_def, notype_declarator rule): Use NULL_TREE for - prefix_attributes. - (condition): Use NULL_TREE for prefix_attributes. - (setattrs): Deleted. - (nomods_initdcl0): Set prefix_attributes to NULL_TREE. - (component_decl): Delete resetting of prefix_attributes. - (component_decl_1, notype_components rule): Use NULL_TREE for - prefix_attributes. - (simple_stmt): Delete resetting of prefix_attributes. - -Mon Jul 24 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (convert_harshness): Deal with reference conversions before - others. Actually do array->pointer decay. Call comp_target_types - with pointer types rather than their targets. - - * typeck.c (comp_target_types): Avoid assigning D const * to B *. - -Mon Jul 24 08:54:46 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * pt.c (to_be_restored): Move decl to global scope. - -Sat Jul 22 12:22:11 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_decl): Put back clearing of DECL_IN_AGGR_P. - -Fri Jul 21 17:09:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grokdeclarator): Downgrade error about 'extern int A::i' - to pedwarn. - - * pt.c (instantiate_template): Also avoid instantiation if the - function has already been declared to be a specialization. - - * decl2.c (check_classfn): Ignore cname argument, and return the - matching function. - - * decl.c (start_decl): Handle declarations of member functions - outside of the class (i.e. specialization declarations). - -Thu Jul 20 10:34:48 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct): Don't mess with the type of bitfields. - - * various.c: s/TYPE_POINTER_TO/build_pointer_type/. - -Thu Jul 20 01:43:10 1995 Mike Stump <mrs@cygnus.com> - - * init.c (expand_aggr_init): Assume LOOKUP_ONLYCONVERTING if init - is not a parameter list (TREE_LIST). - (expand_default_init): If LOOKUP_ONLYCONVERTING is set, then set - LOOKUP_NO_CONVERSION so that we don't allow two-level conversions, - but don't set it otherwise. - -Wed Jul 19 20:32:01 1995 Mike Stump <mrs@cygnus.com> - - * init.c (expand_default_init): Don't allow two-level conversions - during construction. - -Wed Jul 19 18:06:37 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_headof): The type of dyncasting to a pointer to cv - void, should be pointer to cv void. - -Wed Jul 19 17:25:43 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_dynamic_cast): Allow casting in const. - -Wed Jul 19 16:34:27 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_const_cast): If we are passed error_mark_node, - return it. - -Wed Jul 19 15:24:48 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * class.c (push_nested_class): Make sure TYPE is non-nil. - - * cvt.c (type_promotes_to): Watch for error_mark_node on the - incoming TYPE. - -Wed Jul 19 13:23:12 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu> - - * cp-tree.h (SIGTABLE_VT_OFF_NAME): Renamed from SIGTABLE_OFFSET_NAME. - (SIGTABLE_VB_OFF_NAME): New macro. - (vt_off_identifier): Renamed from offset_identifier. - (vb_off_identifier): Added extern declaration. - - * decl.c (vt_off_identifier): Renamed from offset identifier. - (vb_off_identifier): New variable to hold the identifier for the - sigtable field vb_off. - (init_decl_processing): Initialize vb_off_identifier. - Renamed vt_off_identifier from offset_identifier. - * sig.c (build_signature_method_call): Renamed offset_identifier and - local variable offset to vt_off_identifer and vt_off, respecitively. - * sig.c (build_signature_table_constructor): Renamed offset to vt_off. - - * decl.c (init_decl_processing): Add vb_off field to - sigtable_entry_type. Reorder fields so that pfn gets properly - aligned at a 64 bit boundary on the Alpha. - * sig.c (build_signature_table_constructor): Build the constructor - according to the new layout. Set the vb_off field to -1 for now. - - * decl.c (init_decl_processing): Align sigtable_entry_type on word - boundaries instead of double word boundaries to save space. - -Tue Jul 18 16:58:37 1995 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert): Always call build_cplus_new for a ctor. - -Tue Jul 18 14:24:53 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (opt.component_decl_list): Only forbid private/protected - in anonymous unions. We need to make this know when the type is - defined for an object, to not give the error. - -Mon Jul 17 14:22:44 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (opt.component_decl_list): Don't allow access control - as private or protected for union members. - -Sun Jul 16 14:01:00 1995 Jim Wilson <wilson@chestnut.cygnus.com> - - * lex.c (check_newline): For 'p' case, move goto skipline line to - before end brace for 'pragma'. - -Fri Jul 7 13:55:58 1995 Mike Stump <mrs@cygnus.com> - - * g++.1: Tiny updates. - -Fri Jul 7 13:05:20 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (cp_finish_decl): Only destruct local static variables if - they are constructed, and only construct the first time control - passes completely through its declaration (if not initialized with a - constant-expression). - (expand_static_init): Likewise. - -Wed Jul 5 14:05:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (comptypes, case OFFSET_REF): If either offset basetype - is a TEMPLATE_TYPE_PARM, give a match. - -Fri Jun 30 15:42:57 1995 Mike Stump <mrs@cygnus.com> - - * method.c (build_overload_value): Handle encoding of null pointer - constants (or any pointer with a constant numeric value) for - templates. - -Fri Jun 30 13:45:51 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (convert_harshness): Add QUAL_CODE when we're faced with - const vs non-const for void conversions. - -Fri Jun 30 10:19:52 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_all_catch): Fix problem with finding an - outer nested try block when there is no code to separate it from an - inner try block. - -Fri Jun 30 02:22:26 1995 Mike Stump <mrs@cygnus.com> - - * search.c (dfs_pushdecls): Consume 2 or 3 orders of magnitude less - memory please when virtual bases are used. - -Thu Jun 29 19:03:47 1995 Mike Stump <mrs@cygnus.com> - - * class.c (build_vbase_path): Avoid testing things that cannot be - null to see if they are null. - * cvt.c (convert_pointer_to_vbase): Remove code that doesn't work. - * decl.c (finish_function): Pass a type into the new - convert_pointer_to_vbase instead of a binfo. - * search.c (convert_pointer_to_vbase): Rewritten to use get_vbase - and convert_pointer_to_real. - (expand_indirect_vtbls_init): Use convert_pointer_to_vbase instead - of the more cryptic call to get_vbase. - -Thu Jun 29 09:35:05 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (BOOL_TYPE_SIZE): Fix broken SLOW_BYTE_ACCESS check. - -Thu Jun 29 03:43:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (instantiate_template): Don't strip 'this' twice. - - * pt.c (coerce_template_parms): Allow null pointer constants. - - * decl.c (revert_static_member_fn): But only if DECL_ARGUMENTS is - set. - -Wed Jun 28 18:39:03 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (revert_static_member_fn): Also remove 'this' from - DECL_ARGUMENTS. - * decl2.c (check_classfn): Don't revert this function until we get a - match. - -Wed Jun 28 14:07:27 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (component_decl): Clear PREFIX_ATTRIBUTES here. - -Wed Jun 28 11:05:13 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_file): Handle global vector news. - * init.c (build_new): Encode vector news so that later we will know - how many elements there are. - -Mon Jun 26 13:38:06 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * expr.c (cplus_expand_expr): Don't mess with temp slots. - - * decl2.c (warn_if_unknown_interface): Don't crash if tinst_for_decl - returns null. - - * decl2.c (check_classfn): Use revert_static_member_fn. - * decl.c (revert_static_member_fn): Diagnose static member functions - declared const or volatile. - - * decl2.c (grokfield): Check for missing default args here, too. - (check_default_args): Function to do the checking. - * decl.c (pushdecl): Use it. - - * decl.c (pushdecl): Don't warn about shadowing a member of `this' - if there is no `this'. - -Sun Jun 25 11:34:25 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Downgrade 'called before definition' - to a warning, as it ought to go away after Monterey. - -Sat Jun 24 14:18:42 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (coerce_template_parms): Don't do extra checking on pointer - to member arguments. - - * class.c (finish_struct): const and reference members don't prevent - a class from being an aggregate. - - * class.c (finish_struct): Signatures are always aggregates. - -Fri Jun 23 17:20:29 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (check_classfn): Improve error message. - - * pt.c (tsubst): Handle PROMOTE_PROTOTYPES. - -Thu Jun 22 01:50:42 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (comptypes): Don't ignore method quals. - - * class.c (finish_struct): Non-abstract virtuals are always USED. - - * decl.c (build_ptrmemfunc_type): The underlying union type isn't - IS_AGGR_TYPE, either. - * class.c (finish_struct): Use CLASSTYPE_NON_AGGREGATE instead. - * cp-tree.h: Likewise. - - * cp-tree.h (lang_type): Add aggregate. - (CLASSTYPE_AGGREGATE): New macro. - (TYPE_NON_AGGREGATE_CLASS): Likewise. - * class.c (finish_struct): Determine whether a class is an - aggregate. - * decl.c (cp_finish_decl): Check TYPE_NON_AGGREGATE_CLASS instead of - TYPE_NEEDS_CONSTRUCTING. - * typeck2.c (digest_init): Check TYPE_NON_AGGREGATE_CLASS for - subobjects, too. - - * pt.c (tsubst, PARM_TYPE): Propagate DECL_ARTIFICIAL. - - * decl.c (start_function): For pre-parsed functions, layout all of - the parm decls again. - (grokvardecl): TREE_PUBLIC depends on DECL_THIS_EXTERN, not - DECL_EXTERNAL. - - * pt.c (coerce_template_parms): Improve checking for invalid - template parms. - -Wed Jun 21 12:01:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Forbid declaration of a static member - with the same name as its enclosing class. - -Mon Jun 19 10:28:14 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_function): Clear current_class_decl. - - * typeck.c (build_conditional_expr): Use convert (boolean_type_node - instead of truthvalue_conversion. - - * class.c (finish_struct): A data member with the same name as the - class doesn't suppress constructors. - -Fri Jun 16 18:11:39 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu> - - * decl.c (start_function): If current_class_decl is a signature - pointer, don't dereference it but set C_C_D to current_class_decl. - -Fri Jun 16 17:06:28 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (duplicate_decls): Complain about virtual functions - redeclared to be inline. - -Fri Jun 16 13:20:38 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (get_unique_name): New routine to name unnamed namespaces. - (push_namespace): Use get_unique_name for naming unnamed namespaces. - -Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y: Call cplus_decl_attributes with prefix_attributes where - appropriate. - -Wed Jun 14 19:24:49 1995 Mike Stump <mrs@cygnus.com> - - * search.c (get_vbase): New routine to switch hierarchies from the - CLASSTYPE_VBASECLASSES to the normal one. - (expand_indirect_vtbls_init): Use get_vbase to figure out how we - want to convert to a vbase pointer. - -Mon Jun 12 17:50:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (instantiate_class_template): Add the new instantiation to - template_classes. - (do_pending_expansions): Call instantiate_member_templates on all of - the classes in template_classes. - -Mon Jun 12 12:36:59 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (complete_array_type): Fill in the TYPE_DOMAIN of our - TYPE_MAIN_VARIANT if it is not filled in. - * init.c (build_delete): If the TYPE_DOMAIN is not set, give an - error instead of core dumping. - -Mon Jun 12 10:41:40 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (can_convert): Also check for distance > 0. - (can_convert_arg): Likewise. - (user_harshness): Likewise. - -Fri Jun 9 19:17:21 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * g++.c (MATH_LIBRARY): Provide default. - (main): Always link with the math library if we link with libstdc++. - - * decl.c (start_function): Complain about redefinition of a function - even when the pending_inline version is compiled after the other - version. - -Thu Jun 8 15:44:38 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * gc.c (build_dynamic_cast): Build up a reference to a parameter of - aggregate type. - -Wed Jun 7 15:31:57 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_vec_delete): Resolve an offset ref before we try to - use it. - -Wed Jun 7 14:19:32 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): If the class lacks a constructor or - assignment operator, return error_mark_node. - (common_type): Use build_cplus_array_type. - -Tue Jun 6 09:41:27 1995 Mike Stump <mrs@cygnus.com> - - * class.c (dont_allow_type_definitions): New variable set when types - cannot be defined. - (finish_struct): Use it. - * cp-tree.h (dont_allow_type_definitions): Define it. - * parse.y (primary, handler_seq): Set it. - -Mon Jun 5 18:49:38 1995 Mike Stump <mrs@cygnus.com> - - * method.c (build_opfncall): Use DECL_CHAIN, not TREE_CHAIN for - results from lookup_fnfields. Always give warning/error on bad - code. - -Mon Jun 5 11:39:37 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (member_init_ok_or_else): Don't allow initialization of - an ancestor's member from within a constructor. - -Mon Jun 5 11:20:34 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu> - - * sig.c (build_signature_table_constructor): Use DECL_CONTEXT - instead of DECL_CLASS_CONTEXT for calculating the vfield offset so - abstract virtual functions are handled correctly. - - * sig.c (build_signature_table_constructor): Store the correct - delta in signature table entries. It does not yet work for - classes with virtual base classes as implementations of signatures. - (build_signature_method_call): Add the delta to the object_ptr - before generating the function call. - - * call.c (build_method_call): Make instance_ptr the signature - pointer itself instead of dereferencing the optr. - * sig.c (build_signature_method_call): Dereference the optr for the - direct and virtual calls. - - * sig.c (build_signature_table_constructor): Make the tag for - default implementations -1 instead of 2. - (build_signature_method_call): Change the generated conditional - expression correspondingly. - - * sig.c (build_signature_pointer_constructor): Deleted the sorry - message that said we can't handle multiple inheritance for - implementations of signatures - (build_signature_method_call): Use the offset from the sigtable - entry instead of the vptr field from the signature pointer for - building a virtual function call. - - * class.c (build_vfn_ref): Deleted signature specific code, we don't - call this function anymore from build_signature_method_call. - - * cp-tree.h (SIGNATURE_VPTR_NAME): Deleted. We use the right vptr - field in the object now instead of in the signature pointer/ref. - (build_vptr_ref): Deleted extern declaration. - * sig.c (build_vptr_ref): Deleted. - (build_signature_pointer_or_reference_type): Deleted construction of - the vptr field. - (build_signature_pointer_constructor): Deleted initialization of/ - assignment to the vptr field. - - * sig.c (build_signature_table_constructor): Convert the signature - table entry fields to their correct types. - - * sig.c (build_signature_table_constructor): Don't call digest_init - for the fields of a sigtable entry, it's wasted time. - - * sig.c (build_signature_table_constructor): Correctly set the - offset and index fields of a sigtable entry. Build the constructor - the way digest_init does, digest_init can't handle initializing an - anonymous union inside a struct. - (build_signature_method_call): Use the index field instead of the - delta field to get the vtable index. - - * decl.c (init_decl_processing): Fix number of fields for building - sigtable_entry_type. - - * cp-tree.h (tag_identifier, offset_identifier): Added extern decls. - (SIGTABLE_CODE_NAME): Renamed to SIGTABLE_TAG_NAME. - (SIGTABLE_PFN_NAME): Deleted, we'll use VTABLE_PFN_NAME instead. - * decl.c (tag_identifier, offset_identifier): New variables to - hold the identifiers for the sigtable fields tag and offset. - (init_decl_processing): Initialize these variables. - (init_decl_processing): Use these variables to build the - sigtable_entry_type structure. Rename the code and offset fields - to tag and delta, respectively; add offset and index fields. Changed - types of fields from short_integer_type_node to delta_type_node. - * sig.c (build_signature_table_constructor): Rename code and offset - to tag and delta, respectively. - (build_signature_method_call): Likewise. Use above variables. - -Thu Jun 1 17:03:51 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (lookup_name_real): Don't try to look anything up in an - erroneous object. - -Fri Jun 2 10:30:14 1995 Mike Stump <mrs@cygnus.com> - - * method.c (build_overload_int): New routine. Break out - functionality from build_overload_value so we can reuse it. - (build_overload_value): Handle pointer to member functions as value - parameters for templates. - (build_overload_identifier): Since template parameters are shared - among all instantiations, we have to substitute in the real types - in TREE_TYPE (parm). - pt.c (coerce_template_parms): Likewise. - (push_template_decls): Likewise. - (grok_template_type): Deleted as template parameters are shared - among all instantiations. - -Wed May 31 19:10:32 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (grokdeclarator): Always give errors on constant overflow - for array indices. - -Wed May 31 11:39:43 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (commonparms): Don't abort if simple_cst_equal returns < 0. - (build_c_cast): Don't tack on a NON_LVALUE_EXPR when casting to - reference type. - (build_indirect_ref): Fix check for *&. - -Fri Jun 16 06:54:03 1995 Mike Stump <mrs@cygnus.com> - - * Version 2.7.0 released. - -Fri Jun 16 15:07:29 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * Make-lang.in (DEMANGLER_PROG): Add LIBS. - -Thu Jun 15 15:00:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (define_function): Don't set DECL_INTERFACE_KNOWN. - -Wed Jun 7 20:00:31 1995 Mike Stump <mrs@cygnus.com> - - * *.[chy]: Change all callers of finish_decl to cp_finish_decl. - * decl.c (finish_decl): New routine to handle call backs from the - mid end (declare_hidden_char_array). - -Wed Jun 7 19:02:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Handle setting C_C_D here. - (set_C_C_D): Removed. - (struct saved_scope): Remove class_decl. - (push_to_top_level): Don't save current_class_decl. - (pop_from_top_level): Don't restore current_class_decl or C_C_D. - (struct cp_function): Add C_C_D. - (push_cp_function_context): Save C_C_D. - (pop_cp_function_context): Restore C_C_D. - -Fri Jun 2 11:05:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (set_C_C_D): New function. suspend_momentary before - building C_C_D. - (pop_from_top_level): Call it. - (start_function): Likewise. - (pop_cp_function_context): Likewise. - - * class.c, cp-tree.h, decl.c, decl2.c, parse.y: Lose all references - to current_vtable_decl, CLASSTYPE_INST_VAR and CLASSTYPE_VTBL_PTR. - - * decl.c (push_cp_function_context): Save current_class_decl. - (pop_cp_function_context): Restore current_class_decl and set C_C_D. - (pop_from_top_level): Don't use CLASSTYPE_INST_VAR to set C_C_D. - (start_function): Likewise. - - * class.c (popclass): Don't mess with current_class_decl, - current_vtable_decl, or C_C_D. - -Mon May 29 12:45:10 1995 Paul Eggert <eggert@twinsun.com> - - * Make-lang.in (c++.mostlyclean): Remove $(DEMANGLER_PROG). - -Wed May 24 15:55:18 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * decl.c (duplicate_decls): Check simple_cst_equal result against 0. - * decl2.c (finish_anon_union): Likewise. - * method.c (largest_union_member): Likewise. - -Wed May 24 14:41:11 1995 H.J. Lu <hjl@nynexst.com> - - * Make-lang.in (cxxmain.o): Replace single quotes with backslashes. - -Mon May 22 17:38:48 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * Make-lang.in (g++, g++-cross, cc1plus, DEMANGLER_PROG): - Use $@ instead of output name so works even if have .exe. - (cxxmain.o): Use cp if ln -s fails. - (c++.install-man): Use $(exeext) in executable names. - (c++.mostlyclean, stage[1-4]): Use $(objext) in object file names. - * Makefile.in (../cc1plus): Use $(exeext) in name of executable. - -Wed May 24 01:39:03 1995 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): parms can be null, duh. - -Tue May 23 01:32:09 1995 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): If convert_arguments failed, just bail. - -Fri May 19 10:31:11 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (convert_force): Pass LOOKUP_NORMAL to cp_convert. - - * tree.c (copy_to_permanent): Oops. - -Fri May 19 10:01:07 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (break_out_target_exprs): Add decl. - -Thu May 18 13:02:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Move *all* interface handling stuff after - the pushdecl. - - * tree.c (mapcar): Renamed from make_deep_copy and generalized. - (perm_manip): Return t if permanent, otherwise 0. - (copy_to_permanent): Use them. - (bot_manip): Helper for break_out_target_exprs. - (break_out_target_exprs): New function. Uses mapcar. - - * typeck.c (convert_arguments): Use it. - - * method.c (hack_identifier): Use convert_from_reference to - dereference a reference. - -Wed May 17 17:54:54 1995 Mike Stump <mrs@cygnus.com> - - * call.c (convert_harshness): Move reference bashing before pointer - to member bashing. - -Wed May 17 16:57:53 1995 Mike Stump <mrs@cygnus.com> - - * cvt.c (convert_to_reference): Only complain, if complaints are - wanted. - * typeck.c (build_function_call_real): Likewise. If - LOOKUP_SPECULATIVELY is set and something won't work, return - NULL_TREE. - * cvt.c (cp_convert): Likewise. Pass flags down to build_method_call. - (convert): Pass LOOKUP_NORMAL to cp_convert. - * typeck.c (convert_for_assignment): Likewise. - (convert_force): Pass LOOKUP_COMPLAIN to cp_convert. - (convert_arguments): Get out early if we get an error_mark_node. - (convert_for_initialization): Use cp_convert instead of convert so - that we can pass flags down. - * cp-tree.h (LOOKUP_SPECULATIVELY): Added documentation. - -Wed May 17 01:43:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck2.c (store_init_value): Don't take the MAIN_VARIANT of the - decl type. - - * class.c (finish_struct): Don't complain about a class with no - user-defined constructors but with a member that has no default - constructor, as this is OK for aggregates. - - * expr.c (cplus_expand_expr, NEW_EXPR): If this is an explicit - constructor call, mark slot addressable. - -Tue May 16 18:37:51 1995 Douglas Rupp <drupp@cs.washington.edu> - - * g++.c: Changed WINNT to _WIN32. - -Tue May 16 12:40:16 1995 Jason Merrill <jason@lisa.cygnus.com> - - * lex.c (handle_sysv_pragma): Don't use token_buffer. - -Tue May 16 12:05:26 1995 Mike Stump <mrs@cygnus.com> - - * call.c (resolve_scope_to_name): Add initial semantic support for - namespaces. - * class.c (finish_struct): Likewise. - * cp-tree.h (NAMESPACE_LEVEL): Likewise. - * cvt.c (build_up_reference, convert_to_reference): Likewise. - * decl.c (binding_level::namespace_p, suspend_binding_level): Likewise. - (resume_binding_level, toplevel_bindings_p): Likewise - (namespace_bindings_p, declare_namespace_level): Likewise. - (resume_level, push_namespace, pop_namespace): Likewise. - (pop_everything, pushtag, duplicate_decls, pushdecl): Likewise. - (implicitly_declare, lookup_namespace_name): Likewise. - (lookup_name_real, start_decl, make_temporary_for_reference): Likewise. - (obscure_complex_init, finish_decl, expand_static_init): Likewise. - (grokvardecl, grokdeclarator, parmlist_is_exprlist): Likewise. - (store_parm_decls, hack_incomplete_structures): Likewise. - * decl2.c (get_temp_name, finish_anon_union): Likewise. - (current_namespace, push_namespace, pop_namespace): Likewise. - (do_namespace_alias, do_toplevel_using_decl): Likewise. - (do_class_using_decl): Likewise. - * error.c (dump_decl): Likewise. - * init.c (build_member_call, build_offset_ref): Likewise. - * lex.c (identifier_type): Likewise. - * parse.y (lang_extdef, using_decl, extdef): Likewise. - (component_decl_1, nested_name_specifier_1): Likewise. - * spew.c (yylex): Likewise. - * tree.def (NAMESPACE_DECL): Likewise. - -Tue May 16 11:55:35 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (push_overloaded_decl): Return the new decl even if it - can't be pushed. - -Tue May 16 11:00:37 1995 Jason Merrill <jason@lisa.cygnus.com> - - * typeck.c (decay_conversion): Split out from default_conversion. - (default_conversion): Call it. - (build_binary_op): Likewise. - (build_binary_op_nodefault): Use decay_conversion for truth ops. - -Mon May 15 12:47:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (warn_extern_redeclared_static): This is a pedwarn. - (duplicate_decls): Always use the old decl's linkage info. Don't - play with linkage of consts. - (pushdecl): Don't play with linkage of consts. - (redeclaration_error_message): Don't complain about an old public - decl and a new non-public decl here. - (grokvardecl): Handle linkage of consts here. - (grokdeclarator): An 'extern inline' is public. Pass constp to - grokvardecl. - (start_function): Wait until after the pushdecl to do some linkage - stuff. - - * decl2.c (import_export_vtable): Make duplicates weak rather than - static if supported. - (import_export_inline): Likewise. - * pt.c (do_pending_expansions): Likewise. - - * class.c (build_vbase_path): flag_assume_nonnull_objects only - affects reference conversion. - - * init.c (emit_base_init): Build up an RTL_EXPR and add it to - rtl_expr_chain. - * decl.c, decl2.c: s/base_init_insns/base_init_expr/. - -Tue May 16 07:06:28 1995 Paul Eggert <eggert@twinsun.com> - - * method.c (numeric_output_need_bar): Renamed from misspelling. - - * typeck.c (build_ptrmemfunc): Fix misspellings in messages. - -Sun May 14 10:26:22 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * lang-options.h, lang-specs.h: New files. - -Thu May 11 00:31:48 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (default_conversion): Don't check for BLKmode before - pulling out the decl_constant_value. - - * decl.c (start_function): Clear named_labels and shadowed_labels. - - * typeck.c (build_function_call_real): Also synthesize methods here. - -Wed May 10 00:55:59 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_file): Synthesize exported methods before the - reconsider loop. - - * parse.y: Move declaration of flag_new_for_scope to file scope. - -Tue May 9 19:10:33 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c: Add flag_new_for_scope for new -ffor-scope flag. - * parse.y (FOR): Conditionalize the pushing and poping of scope for - the for-init-statement upon the new flag_new_for_scope. - * parse.y (try_block): Simplify and use compstmt. - -Mon May 8 12:41:52 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (define_function): Mark function decl artificial. - -Sun May 7 00:51:28 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (simple_stmt, FOR): Put back push/pop for condition scope. - - * decl2.c (grokclassfn): DECLs don't have cv-qualified types. - * tree.c (build_cplus_method_type): Likewise. - - * cp-tree.h (SET_DECL_ARTIFICIAL): Just set DECL_ARTIFICIAL to 1. - - * typeck.c (build_function_call_real): If convert_arguments failed, - just bail. - (convert_arguments): If one of the arguments is error_mark_node, - just bail. - -Sat May 6 02:39:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (duplicate_decls): Don't check DECL_NOT_REALLY_EXTERN for - decls that don't include it. - -Fri May 5 14:23:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (duplicate_decls): Decls that have DECL_INTERFACE_KNOWN or - DECL_NOT_REALLY_EXTERN set aren't extern decls. - - * typeck.c (build_indirect_ref): Don't call default_conversion for a - parameter of reference_type. - * cvt.c (convert_from_reference): Just use build_indirect_ref. - - * pt.c (do_type_instantiation): Only instantiate member functions - that actually come from templates. - -Fri May 5 09:46:05 1995 Mike Stump <mrs@cygnus.com> - - * parse.y: Generalized cleanup of poplevels, and compound statements - and compound statements in try blocks. Rewritten `for' rule so that - the scope of variables declared in the for clause is shortened to - span just to the end of the statement, instead of the whole - containing block. - -Fri May 5 00:37:14 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (convert_harshness): Handle pointers to members better. - -Thu May 4 16:00:26 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (delete_sanity): Do access control here. - * init.c (build_delete): Instead of here. - - * Make-lang.in: Build c++filt. - -Wed May 3 02:59:53 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (cplus_decl_attributes): If we just modified a TYPE_DECL, - update our IDENTIFIER_TYPE_VALUE. - -Fri Apr 28 07:58:41 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * lex.c (cons_up_default_function): Fix linkage of #pragma - implemented functions. - -Thu Apr 27 16:56:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (build_overload_name): Simplify and fix repeated type - folding. - - * decl.c (grokdeclarator): Prohibit pointers to void or reference - members. - -Thu Apr 27 09:49:07 1995 Mike Stump <mrs@cygnus.com> - - * typeck2.c (process_init_constructor): Make sure initializers are - fully digested. - -Thu Apr 27 01:11:55 1995 Jason Merrill <jason@python.cygnus.com> - - * lex.c (cons_up_default_function): Always defer synthesis. - -Thu Apr 27 00:20:37 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (mark_inline_for_output): Don't play with pending_inline - stuff. - -Wed Apr 26 17:48:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (user_harshness): New function; like build_type_conversion, - but doesn't actually build anything. - (compute_conversion_costs): Use it instead of build_type_conversion. - -Wed Apr 26 17:11:25 1995 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_function_call_real): Improve error message for - calling a non-function. - - * method.c (hack_identifier): Lose check for calling a data member. - -Wed Apr 26 16:59:13 1995 Mike Stump <mrs@cygnus.com> - - * typeck2.c (build_functional_cast): Remove very old cruft. - Seems like good code is generated without it. - -Wed Apr 26 00:47:16 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (do_build_assign_ref): Fix handling of anonymous unions. - (do_build_copy_constructor): Likewise. - - * parse.y (simple_stmt, SWITCH): Call {push,pop}_switch. - - * decl.c (push_switch): New function. - (pop_switch): Likewise. - (define_case_label): Check for jumping over initialization. - - * call.c (build_method_call): Check for an inline function being - called before its definition has been seen. - * typeck.c (build_function_call_real): Likewise. - - * decl.c (duplicate_decls): Check for a function being redeclared - inline after its address has been taken. - - * typeck.c (build_conditional_expr): Handle related class lvalues. - -Tue Apr 25 13:20:45 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (do_pending_expansions): Don't expand unused templates. - - * parse.y (component_decl): Accept a lone semicolon. - -Tue Apr 25 00:25:56 1995 Jason Merrill <jason@rtl.cygnus.com> - - * call.c (build_method_call): Don't allow an RTL_EXPR to serve as the - object parameter anymore. - - * expr.c (cplus_expand_expr): Don't create RTL_EXPRs with no insns. - -Mon Apr 24 12:35:48 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (simple_stmt, decl case): Clear prefix_attributes. - (lang_extdef): Likewise. - - * parse.y (maybe_parmlist): New rule for use in declarators where - this could either be a list of expressions or parameters. Calls - suspend_momentary before deciding which. - (direct_after_type_declarator): Use it. - (complex_direct_notype_declarator): Use it. - - * pt.c (tsubst): Propagate attributes const and noreturn. - - * typeck.c (build_modify_expr): If warn_synth, call build_opfncall - before doing the default thing. - -Thu Apr 27 21:49:36 1995 Doug Evans <dje@cygnus.com> - - * typeck.c (common_type): Call lookup_attribute instead of - value_member. - -Tue Apr 25 18:07:43 1995 Richard Kenner <kenner@vlsi1.ultra.nyu.edu> - - * Make-lang.in: Change "realclean" to "maintainer-clean". - -Sun Apr 23 12:32:38 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_file): Fix broken linked list handling. - -Fri Apr 21 18:08:43 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_base_struct): Don't set TYPE_HAS_COMPLEX_*_REF - as often. - (finish_struct): Likewise. - - * various: Use TYPE_HAS_TRIVIAL_* instead of TYPE_HAS_COMPLEX_*. - - * cp-tree.h (TYPE_HAS_TRIVIAL_INIT_REF): New macro. - (TYPE_HAS_TRIVIAL_ASSIGN_REF): New macro. - -Fri Apr 21 15:52:22 1995 Jason Merrill <jason@python.cygnus.com> - - * typeck.c (c_expand_return): Only expand a returned TARGET_EXPR if - it is of the same type as the return value. - -Fri Apr 21 03:01:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_file): Reconsider if synthesizing a method wrote - out its assembly. - - * typeck.c (convert_for_initialization): Don't call a trivial copy - constructor. - - * typeck2.c (store_init_value): Only abort if the type has a - non-trivial copy constructor. - - * typeck.c (c_expand_return): If we're returning in a register and - the return value is a TARGET_EXPR, expand it. Only do - expand_aggr_init if we're returning in memory. - (expand_target_expr): Function to expand a TARGET_EXPR. - (build_modify_expr): Use it. - - * tree.c (build_cplus_new): Layout the slot. - - * expr.c (cplus_expand_expr): Use expand_call to expand the call - under a NEW_EXPR, so the target is not discarded. - -Thu Apr 20 14:59:31 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_dynamic_cast): Tighten error checking. - -Thu Apr 20 11:23:54 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * expr.c (cplus_expand_expr): Only abort if the returned target is - different from what we expected if the type has a non-trivial copy - constructor. - - * decl2.c (cplus_decl_attributes): Attributes applied to a template - really apply to the template's result. - - * tree.c (lvalue_p): Check IS_AGGR_TYPE instead of TREE_ADDRESSABLE - to decide whether to consider a CALL_EXPR an lvalue. - - * class.c (finish_struct_bits): Only set TREE_ADDRESSABLE if the - type has a non-trivial copy constructor. - - * decl.c (start_function): If interface_known, unset - DECL_NOT_REALLY_EXTERN on the function. - -Wed Apr 19 16:53:13 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (do_function_instantiation): Handle explicit instantiation of - member functions. - (do_type_instantiation): Handle 'inline template class foo<int>', - meaning just spit out the vtable. - - * lex.c (cons_up_default_function): Set DECL_NOT_REALLY_EXTERN on - the consed functions. - - * decl2.c (import_export_inline): Set DECL_INTERFACE_KNOWN. - -Wed Apr 19 16:28:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c, class.c, decl2.c, gc.c, init.c, parse.y, pt.c, search.c, - typeck.c: Include output.h. - -Wed Apr 19 14:57:21 1995 Gerald Baumgartner <gb@alexander.cs.purdue.edu> - - * call.c (build_method_call): Allow a signature member functions to - be called from a default implementation. - -Wed Apr 19 10:21:17 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c (finish_repo): Remember what directory we are in. - - * search.c (expand_upcast_fixups): Don't mess with abort_fndecl. - - * repo.c: Use obstacks instead of fixed-size buffers. Don't spit - out the second copy of the symbol name. Don't remember COLLECT_GCC. - -Wed Apr 19 02:32:40 1995 Mike Stump <mrs@cygnus.com> - - * search.c (virtual_context): New function to get the virtual - context of a function. - (expand_upcast_fixups): New function to generate runtime vtables. - (fixup_virtual_upcast_offsets): Likewise. - (expand_indirect_vtbls_init): Use fixup_virtual_upcast_offsets to - ensure that the this offsets for upcasts from virtual bases into - other virtual bases or non-virtual bases are correct at construction - time and destruction time. - * class.c (fixup_vtable_deltas): Modify to fixup all offsets in all - vtables in all virtual bases, instead of just one vtable in each - virtual base. - (fixup_vtable_deltas1): Likewise. - -Tue Apr 18 03:57:35 1995 Michael Meissner <meissner@cygnus.com> - - * Makefile.in (lex.o): Add dependency on c-pragma.h. - - * lex.c (handle_sysv_pragma): Use NULL_PTR and NULL_TREE as - appropriate, instead of 0. - -Mon Apr 17 12:28:42 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (pushdecl): Use decls_match, not duplicate_decls, for - comparing local and global decls. - -Fri Apr 14 01:46:52 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (convert_arguments): Only prohibit passing to ... of - types with non-trivial copy constructors. - - * repo.c (repo_template_used): Don't try to mess with no id. - -Fri Apr 14 23:32:50 1995 Per Bothner <bothner@rtl.cygnus.com> - - * decl.c (duplicate_decls): Use cp_warning_at for redundant-decls. - -Thu Apr 13 15:37:42 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (current_tinst_level): Delete declaration, since it's - static inside pt.c. - - * typeck.c (build_modify_expr): Catch incompatible array assignment. - - * parse.y (attribute_list, attrib): Rewrite actions to feed the - right stuff to decl_attributes. - -Thu Apr 13 11:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * search.c (dfs_debug_mark): Check for magic virtual like - import_export_vtable. - - * typeck.c (build_binary_op_nodefault): Don't call cp_pedwarn with - four args. - -Wed Apr 12 12:02:57 1995 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (finish_file): Move prevtable pass before needs_messing_up - decision. - -Tue Apr 11 11:20:27 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_decl): If we're writing out a static data member of - a class, we want the debug info for that class. - - * gc.c (build_t_desc): Check linkage of a class properly. - - * class.c (finish_struct): Set the 'headof' offset for the main - vtable properly. - (prepare_fresh_vtable): Fix typeinfo pointer here. - (modify_one_vtable): Instead of here. - -Mon Apr 10 12:15:59 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c (repo_get_id): New function to return the interesting - identifier for a repo entity. - (repo_template_used): Use it. - (repo_template_instantiated): Mark the id as chosen. - (init_repo): Record whether or not the id was chosen. - (finish_repo): Note if an id was newly chosen. - - * pt.c (do_function_instantiation): Call repo_template_instantiated. - (do_type_instantiation): Likewise. Don't diagnose multiple - instantiation. - - * decl2.c (finish_file): Use DECL_NOT_REALLY_EXTERN when deciding - whether or not to synthesize a method. - - Undo these changes: - * class.c (finish_vtbls): build more vtables if flag_rtti is on. - * class.c (modify_all_direct_vtables): ditto. - * init.c (expand_direct_vtbls_init): expand more vtables if - flag_rtti is on. - -Sat Apr 8 17:45:41 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_headof): Use ptrdiff_type_node instead of - integer_type_node on pointer arithmetic. - -Sat Apr 8 11:57:04 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): Undo previous change. - -Thu Apr 6 01:23:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * Makefile.in (compiler): Remove ../cc1plus before rebuilding it. - - * repo.c (get_base_filename): Put the .rpo file in the directory - with the object file, not the source. - - * typeck.c (build_conditional_expr): Handle pmf's better. - - * repo.c (finish_repo): Also use ASM_OUTPUT_LABELREF to print out - the name of the symbol. - -Wed Apr 5 15:24:12 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c (open_repo_file): Make repo filename DOS-compliant. - (*): Also write a new repo file if some previously-used - templates are no longer used. Only remember the identifier. - - * lex.c (cons_up_default_function): If this function belongs to a - template class, call repo_template_used for it. - - * repo.c (repo_template_used): Using a class means using its vtable, - if any. - (finish_repo): Likewise. - - * typeck.c (build_modify_expr): Only wrap TARGET_EXPRs in RTL_EXPRs - if the type has a complex copy constructor. - - * decl2.c (lang_decode_option): -frepo implies - -fno-implicit-templates. - - * decl.c (start_function): Clear current_{base,member}_init_list. - - * lex.c (init_lex): Also unset *_eq if ! flag_operator_names. - -Tue Apr 4 16:11:08 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (struct cp_function): Add {base,member}_init_list. - (push_cp_function_context): Save current_{base,member}_init_list. - (pop_cp_function_context): Restore them. - -Mon Apr 3 16:55:08 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c (get_base_filename): Take filename parm, fix logic bug. - - * typeck.c (build_compound_expr): Do not warn about a compound expr - in which the first expression has no side effects. - (build_x_compound_expr): Warn here instead. - (build_conditional_expr): Don't warn about a conditional expression - between an enum and the type it promotes to. - - * init.c (build_new): Handle initialization of arrays of builtins - properly. - -Mon Apr 3 15:08:04 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * repo.c: Include config.h to get definitions of bcopy and rindex - on systems that don't have them (e.g., SVR4). - -Mon Apr 3 14:41:55 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_table): Pass NULL_TREE instead of init to - finish_decl so that it won't try and do error checking on the - initializer. - -Mon Apr 3 10:45:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c (get_base_filename): Analyze COLLECT_GCC_OPTIONS to - determine whether this compile used -c -o. - (open_repo_file): Use get_base_filename. Remove the extension. - (finish_repo): Spit out the values of main_input_filename, - COLLECT_GCC and COLLECT_GCC_OPTIONS. - - * parse.y (structsp): Add TYPENAME_KEYWORD complex_type_name. - -Sun Apr 2 23:43:51 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * search.c (compute_access): Don't try to do access control on - nested types. - -Fri Mar 31 10:14:23 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * repo.c: New file to handle things repo. - - * pt.c (instantiate_template): Call repo_template_used if the - definition is accessible. - (mark_function_instantiated): Split out from - do_function_instantiation. - (mark_class_instantiated): Split out from do_type_instantiation. - - * parse.y (template_instantiate_once): Call repo_template_used. - - * lex.c (lang_init): Call init_repo. - - * decl2.c: Handle flag_use_repository. - (finish_file): Call finish_repo. - - * decl.c (start_method): Call repo_template_used if this is a - template method. - - * Makefile.in (CXX_OBJS): Add repo.o. - (repo.o): Add dependencies. - - * Make-lang.in (CXX_SRCS): Add repo.c. - - * decl.c (start_function): If DECL_INTERFACE_KNOWN and - DECL_NOT_REALLY_EXTERN are both set, unset DECL_EXTERNAL. - - * typeck.c (build_binary_op_nodefault): Identify the invalid operand - types used. - - * decl.c (duplicate_decls): Propagate DECL_NOT_REALLY_EXTERN. - -Thu Mar 30 17:54:42 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Tidy up use of build_type - and result_type. When checking for comparison between signed - and unsigned, use result_type rather than the (possibly shortened) - type of op0. Also, don't warn about equality comparison of a - signed operand to an unsigned constant that fits in the signed - type. - - * method.c (do_build_copy_constructor): Reverse - current_base_init_list after we've built it up. - -Thu Mar 30 14:35:18 1995 Mike Stump <mrs@cygnus.com> - - * except.c (build_throw): Never warn about the value of throw not - being used. - -Thu Mar 30 13:16:54 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_catch_block): Check for bad catch parameter - declarations. - -Thu Mar 30 13:06:11 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_function): Only set DECL_NOT_REALLY_EXTERN if - DECL_EXTERNAL is not already set. - -Thu Mar 30 11:26:24 1995 Mike Stump <mrs@cygnus.com> - - * method.c (emit_thunk): Let poplevel know that the last level is - for a function so it can create a BLOCK_NODE and set DECL_INITIAL. - -Thu Mar 30 11:15:06 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (import_export_inline): Don't set DECL_NOT_REALLY_EXTERN - here. - - * decl.c (grokdeclarator): OK, don't abort if we see a decl with - METHOD_TYPE. - (finish_function): Set DECL_EXTERNAL and DECL_NOT_REALLY_EXTERN on - all deferred inlines. - -Wed Mar 29 19:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cp-tree.h (DECL_THIS_INLINE): New macro. - (DECL_NOT_REALLY_EXTERN): New macro. - (DECL_THIS_STATIC): New macro. - - * decl.c: Lose all references to current_extern_inline. Break - inline semantics into DECL_INLINE for actual inlining and - DECL_THIS_INLINE for the linkage wierdness. Use DECL_THIS_STATIC. - * decl2.c: Use DECL_NOT_REALLY_EXTERN to indicate that we want to - emit an inline here. Associated changes. - * lex.c: Likewise. - * pt.c: Likewise. - * typeck.c: Likewise. - - * call.c (build_method_call): Don't bother trying to handle inlines - specially. - * cvt.c (convert_to_aggr): Likewise. - - * pt.c (do_function_instantiation): Handle instantiation of - public inlines, too. - -Wed Mar 29 16:04:25 1995 Mike Stump <mrs@cygnus.com> - - * except.c (init_exception_processing): Change the interface for - __throw_type_match and add decl for new rtti matching routine - __throw_type_match_rtti. - (build_eh_type): New routine to build a run time descriptor for the - expression given. - (expand_start_catch_block): Update to use new calling convention for - the matcher. - (expand_throw): Update to use build_eh_type. - -Mon Mar 27 07:14:33 1995 Warner Losh <imp@village.org> - - * g++.c: Removed __NetBSD__ from conditional. - Declare strerror if HAVE_STRERROR is defined; otherwise - declare sys_errlist and sys_nerr. - (my_strerror): New function. - -Tue Mar 28 14:16:35 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * search.c (get_binfo): Don't try to be so clever. - - * tree.c (copy_to_permanent): Also suspend_momentary(). - - * cvt.c (cp_convert_to_pointer): Hand off to convert_fn_pointer even - if the types are the same. - - * decl.c (start_function): Handle extern inlines more like C++ says - we should. - - * init.c (build_member_call): Hand constructor calls off to - build_functional_cast. - - * typeck2.c (build_functional_cast): Use DECL_NESTED_TYPENAME to get - the name of the type. - -Tue Mar 28 13:13:56 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Check for the decl returned by - grokfndecl to be null before using build_decl_attribute_variant. - -Mon Mar 27 18:04:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_new): Use build_pointer_type instead of - TYPE_POINTER_TO. - -Fri Mar 24 12:11:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_conditional_expr): Handle pmfs. - (convert_for_assignment): Fix pmf support. - - * cvt.c (convert_fn_ptr): Support !flag_vtable_thunks. - (cp_convert_to_pointer): Handle pmfs. - (cp_convert): Pass pmfs to cp_convert_to_pointer. - - * typeck.c (common_type): Handle inheritance for pmfs. - - * typeck2.c (build_m_component_ref): Do access control. - - * typeck.c (comp_target_types): Check for conversion to void * - before checking trickier conversions. - - * decl.c (duplicate_decls): Propagate DECL_ABSTRACT_VIRTUAL_P. - - * pt.c (push_tinst_level): Complain if template instantiation depth - is greater than max_tinst_depth. - - * typeck.c (common_type): Assume that we can call common_type to - unify the target type of a pointer. - -Thu Mar 23 00:48:44 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_file): Don't synthesize methods at - finish_vtable_prevardecl time. Do synthesize methods that are not - used, but are public and not external. - - * cvt.c (build_type_conversion): Only give an error if for_sure. - - * typeck.c (comp_target_types): Only support pointer conversions if - nptrs > 0. - -Wed Mar 22 19:30:15 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_new): Catch use of an initializer list where it - shouldn't be. - -Wed Mar 22 16:21:07 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_new): Wrap alloc_expr in an RTL_EXPR if nelts is - non-constant. - - * decl2.c: temp_name_counter is now public. - - * decl.c (struct cp_function): Add temp_name_counter field. - (push_cp_function_context): Save it. - (pop_cp_function_context): Restore it. - - * typeck.c (common_type): Handle unifying function types, and unify - unmatched things to void* with a compiler_error, rather than - silently like before. - -Wed Mar 22 15:10:34 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_prevtable_vardecl, finish_vtable_vardecl): Revert - Brendan's last change and fix latent problem that causes TD entries - to not come out when the things that need them has yet to be - expanded. - -Wed Mar 22 15:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op_nodefault, comparison ops): Update type0 - and type1, since we might have changed op0 or op1. - -Wed Mar 22 13:33:45 1995 Jason Merrill <jason@python.cygnus.com> - - * typeck.c (common_type): Don't mess up templates. - -Wed Mar 22 04:56:00 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (common_type): Handle ptms properly. Also handle - T* -> void*. - (build_binary_op_nodefault): New variable build_type controls what - type is given to the expression when it is created. Set this to - boolean_type_node for comparison ops instead of using result_type. - (comp_target_types): Allow T * -> void *. - - * cvt.c (cp_convert_to_pointer): Do access control when converting - ptms, too. - -Tue Mar 21 17:25:06 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (extern_lang_string): Catch use of linkage specs that - aren't all naming the same language. - - * class.c (finish_struct): Delete accidental duplicate code. - -Tue Mar 21 14:00:57 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Disable pedwarns about - comparing functions and incomplete types. - - * decl.c (finish_function): Only unset current_function_decl if - !nested. - (duplicate_decls): Last change went too far; we only want to stop - checking for value/reference ambiguity. - -Tue Mar 21 01:26:39 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (build_generic_desc): Zap the DECL_SIZE so that we can lay it - out fresh, as the new type may be larger. - -Mon Mar 20 19:01:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * expr.c (extract_init): Try to expand the RTL for the - initialization and figure out what it will look like so we can avoid - run-time initialization. Disabled for now. - (extract_scalar_init): Helper for scalar initialization. - (extract_aggr_init): Helper for aggregate initialization. - - * decl.c (duplicate_decls): Don't complain about ambiguous - declarations. - (obscure_complex_init): Now returns a tree. Call extract_init if - we're optimizing and this is a toplevel decl. - (finish_decl): Update accordingly. - - * lex.c (check_newline): If we're just changing files (not pushing - or popping), update input_file_stack->name. - -Mon Mar 20 17:55:04 1995 Mike Stump <mrs@cygnus.com> - - * pt.c (type_unification): Only TEMPLATE_DECLs are handled right now - in the transitive unification code. - -Mon Mar 20 16:07:50 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (shadow_tag): Don't allow inline, virtual, or explicit on - non-functions. - (grokdeclarator): Don't allow friends to be defined in local classes. - -Sat Mar 18 04:03:33 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_prevtable_vardecl): Use DECL_DECLARED_STATIC - rather than DECL_SAVED_INSNS to decide whether or not this method - was declared inline. - - * method.c (synthesize_method): Turn off DECL_INLINE if - function_cannot_inline_p thinks we're too large. - - * typeck.c (build_indirect_ref): Use build_expr_type_conversion. - -Fri Mar 17 17:47:36 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (instantiate_type): Handle pmfs. - - * typeck.c (convert_for_assignment): Check types when assigning one - pmf to another. - - * decl.c (define_label): Fix logic for printing out the name of the - label in an error message. - - * error.c (dump_expr): Support ARRAY_REF. - -Fri Mar 17 17:43:02 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (finish_vtable_vardecl): Call build_t_desc here. - (finish_prevtable_vardecl): Instead of here. - -Fri Mar 17 14:40:45 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (expand_static_init): Also use expand_aggr_init if the - initializer is a TREE_LIST. - (grokdeclarator): Only pedwarn about extra qualification if -pedantic. - - * pt.c (unify): Fix unification of return type. - - * expr.c (fixup_result_decl): Use store_expr, rather than - emit_move_insn, to move the return value into the place where - callers will expect it. - -Thu Mar 16 22:05:25 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_offset_ref): Call assmble_external on functions. - * typeck.c (build_component_ref): Likewise. - -Thu Mar 16 20:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (struct saved_scope): Add members base_init_list and - member_init_list. - (push_to_top_level): Save current_base_init_list and - current_member_init_list to them. - (pop_from_top_level): Put it back. - -Thu Mar 16 19:21:14 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (instantiate_template): Call assemble_external. - -Thu Mar 16 18:07:54 1995 Brendan Kehoe <brendan@phydeaux.cygnus.com> - - * class.c: Include rtl.h, to get NULL_RTX. - (finish_struct): Also zero out DECL_SAVED_INSNS, to avoid problems - on hosts with different sizes for each part of the union. - * tree.c: Also include rtl.h. - (layout_basetypes): Same change for DECL_SAVED_INSNS. - -Thu Mar 16 13:57:36 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (unify): Fix array domain unification for 64-bit targets. - - * decl2.c (finish_file): Push bizarre type decl before walking the - vtables the first time. - (walk_vtables): OK, don't set prev to vars if the vardecl_fn messed - with TREE_CHAIN (prev). - - * init.c (emit_base_init): Use convert_pointer_to_real instead of - convert_pointer_to when converting to a direct base. - -Wed Mar 15 20:26:29 1995 Mike Stump <mrs@cygnus.com> - - * pt.c (type_unification): Handle transitive unification better. - -Wed Mar 15 13:56:16 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (walk_vtables): Always set prev to vars. - (mark_vtable_entries): Call assemble_external on the vtable entries. - - * class.c (finish_struct): Set the vtable's size to NULL_TREE before - calling layout_decl, so that it gets updated properly. - - Finally re-enable dynamic synthesis. This time it works. - * method.c (synthesize_method): Pass decl_function_context (fndecl) - to {push,pop}_cp_function_context. - * decl.c (push_cp_function_context): Now takes a tree argument. - (pop_cp_function_context): Likewise. - * call.c (build_method_call): Enable synthesis. - * lex.c (cons_up_default_function): Likewise. - -Tue Mar 14 19:14:19 1995 Doug Evans <dje@chestnut.cygnus.com> - - * parse.y (setattrs): Chain onto prefix_attributes rather than - setting it. - -Wed Mar 15 13:00:00 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (pushdecl): Check if the type of the VAR_DECL is an - error_mark_node before trying to read TYPE_LANG_SPECIFIC. - -Mon Mar 13 21:00:28 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator, case ARRAY_REF): Wrap the exp with fold, - and convert the size and integer_one_node to the index type. - -Mon Mar 13 08:01:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (get_member_function_from_ptrfunc): Save the instance - argument, and tack it onto the front of the COND_EXPR to make the - semantics come out right. Grab the instance argument from - '*instance_ptrptr', rather than having it passed in separately. - - * various: Change various consed-up comparison operations to have - boolean type. Remove the instance argument in calls to - get_member_function_from_ptrfunc. - - * error.c (dump_expr): Dump true and false as "true" and "false". - - * decl2.c (finish_file): Also set DECL_STATIC_FUNCTION_P on the - global init function. - - * decl.c (finish_function): Only set DECL_EXTERNAL here if the - inline function is public. - -Sat Mar 11 00:58:03 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (is_friend): Be more careful about checking - DECL_CLASS_CONTEXT on non-member functions. - - * decl2.c (finish_vtable_vardecl): Don't bother calling - assemble_external here. - (prune_vtable_vardecl): New function that just splices out the - vtable decl from the top-level decls. - (import_export_inline): Unset DECL_EXTERNAL at first. - (finish_file): Don't bother calling assemble_external here. Do - splice out all of the vtables. - -Fri Mar 10 14:42:29 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_function): If we're not emitting the function yet, - call assemble_external for it. - - * decl2.c (finish_prevtable_vardecl): Don't call mark_vtable_entries - here. - (finish_vtable_vardecl): Don't do the linkage deduction thing here. - Also don't splice out the current vtable if it is unused. - (finish_file): Move the second walk_vtables and the synthesis check - inside the 'reconsider' loop. Move thunk emission after the - 'reconsider' loop. - -Thu Mar 9 16:28:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * pt.c (tsubst): Don't bother calling cp_build_type_variant, since it - was passing bogus values for readonly and volatile from the original - template decl, not the resultant type of the tsubst call. - - * class.c (duplicate_tag_error): Use cp_error_at to point out the - previous definition of the tag. - -Thu Mar 9 10:46:17 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Clear base_init_insns and protect_list. - (struct cp_function): Add base_init_insns field. - (push_cp_function_context): Also save base_init_insns. - (pop_cp_function_context): Also restore base_init_insns. - -Wed Mar 8 13:31:44 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (member_init_ok_or_else): Check for initializing a static - member here. - (emit_base_init): Instead of here. - -Tue Mar 7 16:03:26 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Disable synthesis as needed. - * lex.c (cons_up_default_function): Likewise. - -Tue Mar 7 10:14:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y: New rules to allow attributes in a prefix position. - (prefix_attributes): New variable. Pass it into cplus_decl_attributes. - (setattr): New rule. - (reserved_declspecs, declmods): Catch attributes here. - * decl2.c (cplus_decl_attributes): Add PREFIX_ATTRIBUTES argument. - * decl.c (duplicate_decls): Pass DECL_MACHINE_ATTRIBUTES to - descendent typedef. - (grokdeclarator): Added code to support machine attributes. - * Makefile.in (stamp-parse): Expect 5 shift/reduce failures. - -Mon Mar 6 15:07:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Don't synthesize methods outside of a - function. - - Make base initialization more re-entrant so that synthesis on the - fly will work (and, eventually, template instantation on the fly). - * init.c (sort_member_init): Don't bother with members that can't be - initialized. Reorganize a bit. Don't initialize base members here. - (sort_base_init): New function, like sort_member_init, but for base - classes. Steals some code from emit_base_init. - (emit_base_init): Simplify. Call sort_{member,base}_init before - doing any initialization, so we don't have to save - current_{member,base}_init_list in push_cp_function_context. - (expand_aggr_vbase_init_1): Adjust for sort_base_init. - (expand_aggr_vbase_init): Simplify. - * decl.c (struct cp_function): Add protect_list field. - (push_cp_function_context): Also save protect_list. - (pop_cp_function_context): Also restore protect_list. - * call.c (build_method_call): Enable synthesis at point of call. - * lex.c (cons_up_default_function): Likewise. - - * parse.y: Turn -ansi checks back into -pedantic checks. - - * init.c (build_new): Fix -fcheck-new for array new. - -Sat Mar 4 15:55:42 1995 Fergus Henderson <fjh@cs.mu.oz.au> - - * typeck.c (build_compound_expr): warn if left-hand operand of - comma expression has no side-effects. - -Fri Mar 3 15:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (primary): Change 'object qualified_id *' rules to 'object - overqualified_id *'. - -Fri Mar 3 12:48:17 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (unary_expr): Catch doing sizeof an overloaded function. - Make the error look the same as the one we issue in c_sizeof. - - * typeck.c (build_binary_op_nodefault): Give an error for trying - to compare a pointer-to-member to `void *'. - -Fri Mar 3 11:28:50 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_unary_op): Handle bool increment with smoke and - mirrors here, rather than in expand_increment where it belongs, - because Kenner doesn't agree with me. - -Fri Mar 3 00:08:10 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokparms): Catch a PARM_DECL being used for a default - argument as well. - -Thu Mar 2 20:05:54 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * init.c (build_new): Don't allow new on a function type. - - * parse.y (primary): Avoid a crash when seeing if the arg is of - the same type as that given for the typespec in an explicit dtor call. - -Thu Mar 2 00:49:38 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_function): Change test for calling - mark_inline_for_output. - -Wed Mar 1 11:23:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): Complain if - build_default_binary_type_conversion fails. - - * init.c (expand_default_init): Handle arguments of unknown type - properly. - - * cvt.c (build_expr_type_conversion): Only complain about ambiguity - if 'complain'. - * various: Pass 'complain'. - - * typeck.c (comptypes): Be more picky about comparing UPTs. - -Wed Mar 1 11:03:41 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): If declarator is null, say that the - type used has an incomplete type. - -Wed Mar 1 10:06:20 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (instantiate_template): Copy the template arguments to the - permanent_obstack. Also use simple_cst_equal to compare them when - looking for a previous instantiation. - - * tree.c (make_deep_copy): Support copying INTEGER_TYPEs (assuming - they are array domain types). - -Tue Feb 28 23:24:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cp-tree.h: Define WANT_* constants for passing to - build_expr_type_conversion. - * cvt.c (build_expr_type_conversion): New function to build - conversion to one of a group of suitable types. - (build_default_binary_type_conversion): Use it. - * decl2.c (grok_array_decl): Likewise. - * typeck.c (build_unary_op): Likewise. - (build_array_ref): Tidy up a bit. - (build_binary_op): Likewise. - -Tue Feb 28 19:57:31 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Don't allow decl of an argument as `void'. - -Tue Feb 28 17:23:36 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (typed_declspecs1): Add 'typespec reserved_typespecquals - reserved_declspecs' rule. - - * parse.y (expr_or_declarator): Remove notype_qualified_id rule. - (direct_notype_declarator): Likewise. - (complex_direct_notype_declarator): Add notype_qualified_id rule. - - * lex.c (real_yylex): Handle :> digraph properly. - -Tue Feb 28 12:26:29 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Check if it's a friend, not if it's - non-virtual, that's being initialized. Move the check up to - before FRIENDP would get cleared. Catch an unnamed var/field - being declared void. Say just `field' instead of `structure field' - in the error message. Only go for the operator name if DECLARATOR - is non-null. - -Tue Feb 28 00:08:01 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (start_function): Complain about abstract return type. - (grokdeclarator): Complain about declaring constructors and - destructors to be const or volatile. Complain about declaring - destructors to be static. - - * pt.c (uses_template_parms): Handle pmfs. - - * decl.c (grokdeclarator): Don't call variable_size for array bounds - that only depend on template constant parameters. - -Mon Feb 27 15:38:16 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * error.c (dump_decl): Only look to see if it's a vtable if we - actually have a name to check out. - -Mon Feb 27 13:37:53 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (convert_to_aggr): Lose misleading shortcut. - -Sun Feb 26 17:27:32 1995 Doug Evans <dje@canuck.cygnus.com> - - * decl.c (set_nested_typename): Always set DECL_IGNORED_P, - not just for dwarf. - -Sun Feb 26 00:10:18 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Don't allow a static member to be - declared `register'. - - * init.c (make_friend_class): Move up to a pedwarn for the warning - about a class declaring friends with itself. - - * decl.c (grokdeclarator): You can't do `volatile friend class foo' - or `inline friend class foo'. Only try to make a friend out of - TYPE if we didn't already reset it to integer_type_node. - -Sat Feb 25 22:32:03 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Don't allow initialization of a - non-virtual function. - - * decl.c (start_function): Do a pedwarn if we're changing `main' - to have an int return type. - -Sat Feb 25 00:02:05 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): Handle simple assignment from - TARGET_EXPRs by building up an RTL_EXPR to force expansion. Whew. - -Fri Feb 24 18:27:14 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Also don't allow virtual outside of a - class decl for a scope method definition performed at global binding. - - * init.c (build_offset_ref): Don't allow creation of an OFFSET_REF - of a bitfield. - - * decl.c (grokdeclarator): Don't allow a const to be declared mutable. - - * typeck.c (build_binary_op): Return an error_mark_node if either - one of the args turned into an error_mark_node when we tried to - use default_conversion. - - * typeck.c (build_unary_op): Forbid using postfix -- on a bool. - - * decl.c (grokdeclarator): Allow `signed' and `unsigned' to be - used on `__wchar_t'. - -Fri Feb 24 13:59:53 1995 Mike Stump <mrs@cygnus.com> - - * except.c (end_protect_partials): Do it the right way. - -Wed Feb 22 15:42:56 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Upgrade warning about - comparing distinct pointer types to pedwarn. - - * typeck2.c (digest_init): Cope with extra braces. - - * typeck.c (build_binary_op_nodefault): Use tree_int_cst_sgn instead - of INT_CST_LT (..., interger_zero_node). - -Wed Feb 22 14:45:52 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * except.c [!TRY_NEW_EH] (end_protect_partials): Define dummy - function for systems that don't have EH. - -Tue Feb 21 19:18:31 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (can_convert_arg): Like can_convert, but takes an arg as - well. - - * pt.c (type_unification): Allow implicit conversions for parameters - that do not depend on template parameters. - -Tue Feb 21 18:43:48 1995 Douglas Rupp <drupp@cs.washington.edu> - - * Make-lang.in, config-lang.in: ($exeext): New macro. - * Make-lang.in: Try a "cp" if "ln" fails. - * cp-tree.h (decl_attributes): Added argument. - * decl2.c (cplus_decl_attribute): Add arg to decl_attributes. - * cp/g++.c: Added #ifdefs for sys/file.h and process.h for NT. - Modified spawnvp to have to correct number of arguments for OS/2, NT. - -Tue Feb 21 18:36:55 1995 Mike Stump <mrs@cygnus.com> - - * decl.c (finish_function): Add calls to end_protect_partials to end - the exception region that protects constructors so that partially - constructed objects can be partially destructed when the constructor - throws an exception. - * init.c (perform_member_init, sort_member_init, emit_base_init): - Added support for partially constructed objects. - * init.c (build_partial_cleanup_for): New routine to do partial - cleanups of a base class. - * decl2.c (finish_file): Move the emitting of the exception table - down, after we emit all code that might have exception regions in - them. - * except.c (end_protect_partials, might_have_exceptions_p): New - routines. - (emit_exception_table): Always output table if called. - * cp-tree.h (protect_list, end_protect_partials, - might_have_exceptions_p, emit_exception_table): Added. - -Tue Feb 21 16:05:59 1995 Brendan Kehoe <brendan@lisa.cygnus.com> - - * gc.c (build_typeid): Pass a NULL_TREE, not the bogus, unused - address of a local variable. - * class.c (build_vfn_ref): Only try to build the PLUS_EXPR if we - were given a non-null PTR_TO_INSTPTR. - -Tue Feb 21 01:53:18 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (duplicate_decls): Always lay out the merged decl. - - * decl2.c (finish_vtable_vardecl): Don't do vtable hack on templates. - (finish_prevtable_vardecl): Likewise. - - * method.c (synthesize_method): Set interface_{unknown,only} - according to the settings for our class, not the file where it comes - from. - -Sat Feb 18 12:26:48 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Handle systems that define __i386__ but not __i386. - -Fri Feb 17 15:31:31 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (reparse_decl_as_expr): Support being called without a - type argument. - - * parse.y (primary): Add '(' expr_or_declarator ')'. Adds 4 r/r - conflicts. Sigh. - -Fri Feb 17 12:02:06 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (template_def, fndef, fn.def1, return_init, condition, - initdcl0, initdcl, notype_initdcl0, nomods_initdcl0, - component_decl_1, after_type_component_declarator0, - notype_component_declarator0, after_type_component_declarator, - notype_component_declarator, after_type_component_declarator, - full_parm, maybe_raises, exception_specification_opt): Fix up, - include exception_specification_opt maybeasm maybe_attribute and - maybe_init if missing. Rename maybe_raises to - exception_specification_opt to match draft wording. Use maybe_init - to simplify rules. - -Fri Feb 17 01:54:46 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_new): Set TREE_NO_UNUSED_WARNING on COMPOUND_EXPRs - built for news of scalar types. - -Thu Feb 16 17:48:28 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Update code for warning - about signed/unsigned comparisons from C frontend. Realize that the - code in the C frontend is, if anything, even more bogus. Fix it. - (build_binary_op): Undo default_conversion if it wasn't useful. - - * typeck.c (build_unary_op, ADDR_EXPR): Lose bogus special case for - PRE*CREMENT_EXPR. - - * decl2.c (import_export_vtable): Don't try the vtable hack - if the class doesn't have any real non-inline virtual functions. - (finish_vtable_vardecl): Don't bother trying to find a non-inline - virtual function in a non-polymorphic class. - (finish_prevtable_vardecl): Likewise. - - * decl2.c (import_export_vtable): Use and set DECL_INTERFACE_KNOWN. - - * cp-tree.h (DECL_INTERFACE_KNOWN): Use DECL_LANG_FLAG_5. - - * init.c (expand_virtual_init): Always call assemble_external. - - * class.c (build_vfn_ref): Always call assemble_external. - (build_vtable): Always call import_export_vtable. - (prepare_fresh_vtable): Likewise. - (add_virtual_function): Don't bother setting TREE_ADDRESSABLE. - -Thu Feb 16 03:28:49 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct): Use TYPE_{MIN,MAX}_VALUE to determine - whether an enumerated type fits in a bitfield. - -Wed Feb 15 15:38:12 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (grow_method): Update method_vec after growing the class - obstack. - -Wed Feb 15 13:42:59 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (handler_seq): Push a level for the catch parameters. - -Wed Feb 15 12:42:57 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (emit_base_init): Update BINFO_INHERITANCE_CHAIN on my - bases, in case they've been clobbered. - -Wed Feb 15 12:07:29 1995 Mike Stump <mrs@cygnus.com> - - * class.c (finish_base_struct): Set up BINFO_INHERITANCE_CHAIN here, - so that one day it will always be valid. - * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise. - - * cp-tree.h (copy_binfo): Removed, unused. - * tree.c (copy_binfo): Likewise. - -Wed Feb 15 00:05:30 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_new): Save the allocation before calling - expand_vec_init on it. - - * decl.c (finish_enum): The TYPE_PRECISION of the enum type mush - match the TYPE_PRECISION of the underlying type for constant folding - to work. - -Tue Feb 14 15:31:25 1995 Mike Stump <mrs@cygnus.com> - - * except.c (push_eh_entry, expand_start_all_catch, - expand_leftover_cleanups, expand_end_catch_block): Keep track of - the context in which the exception region occurs. - (build_exception_table): If the region was not output, don't output - the entry in the eh table for it. - -Tue Feb 14 02:15:43 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (expand_default_init): Only use a previous constructor call - if it's a call to our constructor. Does the word "Duh" mean - anything to you? - - * decl.c (grokparms): Fine, just don't call - convert_for_initialization at all. OK? Happy now? - -Mon Feb 13 02:23:44 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cp-tree.h (CLASSTYPE_FIRST_CONVERSION): Make sure that the class - method vector has a second element before returning it. - - * decl.c (grokparms): Don't strip REFERENCE_TYPE before calling - convert_for_initialization. - -Sun Feb 12 03:57:06 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): Compare function name to - constructor_name (current_class_type) instead of current_class_name. - - * decl.c (grokparms): Don't do anything with the return value of - convert_for_initialization. - - * error.c (dump_decl): Also dump_readonly_or_volatile on the decl. - - * decl.c (duplicate_decls): Tweak error message. - - * typeck.c (build_const_cast): Implement checking. - (build_reinterpret_cast): Implement some checking. - - * cp-tree.h (CONV_FORCE_TEMP): Require a new temporary when - converting to the same aggregate type. - (CONV_STATIC_CAST): Include it. - (CONV_C_CAST): Likewise. - * cvt.c (convert_force): Use CONV_C_CAST instead of CONV_OLD_CONVERT. - (cp_convert): Only force a new temporary if CONV_FORCE_TEMP. - -Fri Feb 10 16:18:52 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_c_cast): Use non_lvalue to tack something on - where necessary. - - * decl.c (auto_function): Now a function. - * except.c (init_exception_processing): terminate, unexpected, - set_terminate, and set_unexpected have C++ linkage. - - * typeck.c (build_unary_op, TRUTH_NOT_EXPR): Use convert instead of - truthvalue_conversion for converting to bool, as it handles - user-defined conversions properly. - (condition_conversion): Likewise. - - * except.c (expand_throw): Don't call convert_to_reference. - Pass the correct parameters to build_new. - - * method.c (do_build_assign_ref): Don't use access control when - converting to a base reference here. - (do_build_copy_constructor): Or here. - - * init.c (build_new): Unset TREE_READONLY on the dereferenced - pointer before assigning to it. - - * decl.c (maybe_build_cleanup): Don't bother stripping const here. - - * decl2.c (delete_sanity): You can now delete pointer to const. - -Fri Feb 10 13:28:38 1995 Jason Merrill <jason@python.cygnus.com> - - * decl.c (finish_function): Don't rely on actual parameters being - evaluated left-to-right. - * except.c (expand_end_catch_block): Likewise. - -Fri Feb 10 00:52:04 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * tree.c (real_lvalue_p): Like lvalue_p, but class temps aren't - considered lvalues. - * cvt.c (convert_to_reference): Use real_lvalue_p instead of - lvalue_p. - - * cvt.c (build_type_conversion_1): Don't call convert on aggregate - types. - (convert_to_reference): Fix erroneous text substitution. - - * typeck2.c (initializer_constant_valid_p): Update from C frontend. - Add new argument to all callers. - - * typeck.c (convert_arguments): Check for error_mark_node before - trying to do anything with the actual parameter. - - * typeck.c (condition_conversion): Build up a CLEANUP_POINT_EXPR and - fold it. - (bool_truthvalue_conversion): Remove. Fix all callers to call - truthvalue_conversion instead. - (various): Fold CLEANUP_POINT_EXPRs. - - * parse.y (conditions): Call condition_conversion rather than - building up a CLEANUP_POINT_EXPR. - - * pt.c (end_template_decl): Don't warn_if_unknown_interface here - under -falt-external-templates. - -Thu Feb 9 05:24:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_new): Complain about new of const type without - initializer. Other cleanup. - - * call.c (compute_conversion_costs): Don't call - build_type_conversion with a reference type; convert to the target - type and check its lvaluetude. - * cvt.c (convert_to_reference): Likewise. - - * cvt.c (build_type_conversion_1): There will never be any need to - dereference references here now. - -Thu Feb 9 00:37:47 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_builtin_throw): Make sure we only `use' the - value of return_val_rtx. - -Wed Feb 8 15:45:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (structsp): Don't complain about declaring a type being - defined to be a friend. - - * decl2.c (warn_if_unknown_interface): Note the template in question - and the point of instantiation, for -falt-external-templates. - * lex.c (reinit_parse_for_method): Pass the decl to - warn_if_unknown_interface. - * pt.c (instantiate_template): Likewise. - (end_template_decl): Likewise. - - * decl.c (set_nested_typename): Set IDENTIFIER_TYPE_VALUE on the - nested name again, to make local classes work a bit better. - - * typeck.c (build_function_call_real): Dereference reference after - checking for incomplete type. - - * init.c (build_new): Accept new of const and volatile types. - -Wed Feb 8 14:04:16 1995 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Fix error message. - -Wed Feb 8 03:16:15 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (convert_for_initialization): Do bash arrays when - converting to a reference to non-array. - -Tue Feb 7 15:50:33 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (cp_convert): Don't call convert_to_reference, or - automatically dereference references. Do pass reference conversions - to cp_convert_to_pointer. - (cp_convert_to_pointer): Support references. - - * call.c (build_method_call): Don't build up a reference to the - parameter here; let build_overload_call handle that. - - * typeck.c (build_c_cast): Call convert_to_reference directly if - converting to a reference type. - * method.c (do_build_copy_constructor): Likewise. - * method.c (do_build_copy_constructor): Likewise. - (do_build_assign_ref): Likewise. - - * call.c (build_method_call): Dereference a returned reference. - * typeck.c (build_function_call_real): Likewise. - - * decl.c (xref_basetypes): Check for unions with basetypes here. - (xref_tag): Instead of here. - - * pt.c (process_template_parm): Template type parm decls are - artificial. - -Mon Feb 6 04:32:09 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y (typed_declspecs): Add missing semicolon. - (do_xref_defn): Resurrect. - (named_class_head_sans_basetype): Move template specialization - definition cases to named_class_head_sans_basetype_defn. - - * decl2.c (grokfield): Call pushdecl_class_level after setting the - TYPE_NAME, not before. - -Sun Feb 5 02:50:45 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (convert_harshness): Don't call sorry here. Don't allow - conversions between function pointer types if pedantic. - - * pt.c (overload_template_name): Pass globalize=1 to xref_tag. - - * lex.c (cons_up_default_function): Use the full name for the return - type of op=. - - * decl.c (set_nested_typename): Don't worry about anonymous types, - as they already have a unique name. - (pushdecl): Remove redundant set_nested_typename - (xref_tag): Split out base handling into xref_basetypes. - - * cp-tree.h (TYPE_INCOMPLETE): New macro; TEMPLATE_TYPE_PARMs are - not considered incomplete even though their definition is unknown. - - * decl.c (xref_defn_tag): Lose. - (xref_tag): xref_next_defn = ! globalize. - (pushdecl): Don't set DECL_NESTED_TYPENAME on artificial decls. The - ones that should have it set will have it set by pushtag. - (pushdecl_class_level): Likewise. - (pushtag): Tidy up a bit. - (set_nested_typename): Push a decl for the nested typename from - here, rather than from xref_defn_tag. - - * parse.y (do_xref): Lose. - (named_class_head): If we see 'class foo:' we know it's a - definition, so don't worry about base lists for non-definitions. - - * pt.c (push_template_decls): Template parm decls are artificial. - - * decl.c (duplicate_decls): Restore check for qualifier - disagreement for non-functions. - (decls_match): Remove check for qualifier disagreement. - -Fri Feb 3 14:58:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grok_reference_init): Convert initializer from - reference. - * typeck.c (convert_for_initialization): Likewise. - - * decl.c (duplicate_decls): Propagate DECL_NESTED_TYPENAME. - - * cvt.c (cp_convert): Don't convert to the same class type by just - tacking on a NOP_EXPR. - (convert_to_reference): Use comp_target_types instead of comptypes - so that we don't allow conversions two levels down. - -Thu Feb 2 15:07:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (build_vbase_path): Bash types to make the backend happy. - * cvt.c (build_up_reference): Bash the types bashed by - build_vbase_path to be reference types instead of pointer types. - (convert_to_reference): Likewise. - - * typeck.c (build_c_cast): Don't strip NOPs if we're converting to a - reference type. - - * parse.y (structsp): Put back error for 'struct B: public A;'. - -Wed Feb 1 23:02:06 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Add support for mips systems that don't define __mips - but do define mips, like Ultrix. - -Wed Feb 1 22:39:07 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Add support for exception handling on the Alpha. - -Wed Feb 1 10:12:14 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_file): Fix bug in Jan 31st change. - -Tue Jan 31 16:59:15 1995 Gerald Baumgartner <gb@lorenzo.cs.purdue.edu> - - * sig.c (build_signature_pointer_or_reference_type): Don't set - IS_AGGR_TYPE for signature pointers/reference so expand_default_init - doesn't expect to find a copy constructor. - * call.c (build_method_call): Treat signature pointers/reference - as if IS_AGGR_TYPE were set. - -Tue Jan 31 13:28:56 1995 Mike Stump <mrs@cygnus.com> - - * gc.c (get_typeid): Pawn off error messages to build_t_desc. - (build_t_desc): Inform the user here if they try and build - with -frtti and don't include <typeinfo.h>. - - * decl2.c (finish_prevtable_vardecl): Support rescanning. - (finish_file): Move finish_prevtable_vardecl up to before the global - initializers are done as tdecls are initialized in the global - initializer. Also Pick up any new tdecls or vtables needed by - synthesized methods. - - * class.c (finish_struct): Simplify. We have to do rtti scanning at - end, so we might as well do all of it there. - -Tue Jan 31 05:35:02 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Fix -fthis-is-variable for 32-bit - targets, too. - -Tue Jan 31 00:11:04 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_prevtable_vardecl): New routine, mostly split from - finish_vtable_vardecl. It has the first half functionality from - that routine. - * decl2.c (finish_vtable_vardecl): Update to not include stuff not - in finish_prevtable_vardecl. - * decl2.c (finish_file): Call finish_prevtable_vardecl. - * gc.c (build_generic_desc): Allow it to be called when not at the - global binding layer, but behave as if we were. - (build_t_desc): Rearrange a bit so that it really works and is - easier to follow. - * class.c (finish_struct): Don't decide on tdecls here, as we have - to wait until the end of the file in general to decide whether or - not they come out. - -Mon Jan 30 01:00:40 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_delete): Check access to operator delete before - calling the destructor. - * method.c (build_opfncall, DELETE_EXPR): build_method is allowed to - return error_mark_node. - * call.c (build_method_call): Use the one-argument op delete even if - it's an error. - - * init.c (build_new): Fix -fthis-is-variable support. - * call.c (build_method_call): Likewise. - - * call.c (convert_harshness): Make conversion from a pointer to bool - worse than conversion to another pointer. - -Sat Jan 28 16:46:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (build_new): Check new return value if -fcheck-new. - - * lex.c (check_newline): Clear end_of_file when we're done, too. - -Sat Jan 28 10:38:39 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_vtable_vardecl): Make rtti TD tables follow - vtables whereever they go. - - * gc.c (build_t_desc): Remove old way of setting it up, as it wasn't - right. - -Sat Jan 28 09:10:44 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (finish_vtable_vardecl): Now set the - interface/implementation of vtables on the first virtual function, - if one exists, otherwise we use the old method. This is a major win - in terms of cutting down the size of objects and executables in - terms of text space and data space. Now most of the savings that - #pragma interface/implementation gives is automatic in a fair number - of cases. - -Sat Jan 28 04:57:33 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grokdeclarator): Discard the template parameters in a - template constructor declaration so that the function is always - named constructor_name (ctype). - - * lex.c (check_newline): Use ungetc to put back the character before - calling HANDLE_PRAGMA. - -Fri Jan 27 17:23:47 1995 Mike Stump <mrs@cygnus.com> - - * decl2.c (check_classfn): If the cname is T<int> and fn_name is T, - make sure we still match them. - -Fri Jan 27 16:32:10 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y: Add END_OF_LINE token. - - * lex.c (check_newline): Set linemode when we see a # directive, and - unset it when we're done. Turn all 'return's into 'goto skipline'. - Fix all uses of '\n', since we won't see it anymore. Put back the - character we read before checking for a sysv or target pragma. - (real_yylex): If we see an EOF in linemode, return END_OF_LINE. - (handle_sysv_pragma): Don't look at the input stream; quit when we - see an END_OF_LINE token. - - * input.c (getch): Return EOF if we're in line mode and at the end - of a line. - (put_back): Don't put back an EOF. - -Thu Jan 26 19:26:34 1995 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Do the newing of the exception object - before we load the type descriptor or the address so that we don't - wipe any of the values out. - -Thu Jan 26 19:20:00 1995 Mike Stump <mrs@cygnus.com> - - * except.c (init_exception_processing): Don't use r12 on the rs6000. - -Tue Jan 24 16:36:31 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grokparms): Don't try to build up a reference at this point. - - * typeck2.c (build_functional_cast): Don't assume that a NOP_EXPR - will suffice to convert from integer_zero_node. - -Wed Jan 25 15:02:09 1995 David S. Miller <davem@nadzieja.rutgers.edu> - - * class.c (instantiate_type): Change error message text. - * typeck2.c (store_init_value): Likewise. - -Mon Jan 23 21:57:14 1995 Mike Stump <mrs@cygnus.com> - - * pt.c (tsubst): When we copy a node, don't forget to copy - TREE_CHAIN, we use it later. - -Mon Jan 23 03:33:47 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (convert_for_assignment): Initialize variable before use. - -Fri Jan 20 01:17:59 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * g++.c (main): Link with both libstdc++ and libg++ if called as - something ending with "g++", otherwise only libstdc++. Move -lm to - the end of the line. - -Thu Jan 19 15:43:11 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Don't mess with 'this' before calling - compute_conversion_costs. - -Wed Jan 18 15:40:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * search.c (get_matching_virtual): Give line number for previous - declaration. - - * call.c (convert_harshness): Handle conversions to references - better. - - * cvt.c (build_up_reference): OK, handle {MIN,MAX}_EXPR *properly*. - -Wed Jan 18 15:21:38 1995 Mike Stump <mrs@cygnus.com> - - * class.c (instantiate_type): Use DECL_CHAIN to walk lists instead, - as the TREE_CHAIN for methods will take us to the next differently - named function, DECL_CHAIN won't. - -Wed Jan 18 14:26:59 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * tree.c (lvalue_p): Handle {MIN,MAX}_EXPR. - - * decl2.c (lang_decode_option): -Wall implies -Wparentheses. - warn_parentheses defaults to 0. - - * decl.c (grokparms): Put back call to require_instantiated_type. - -Tue Jan 17 19:56:15 1995 Mike Stump <mrs@cygnus.com> - - * except.c (exception_section): Use the data section on the rs6000. - Change calling convention for named_section. - -Wed Jan 17 18:20:57 1994 Fergus Henderson <fjh@munta.cs.mu.oz.au> - - * cp-tree.h : Make if (x=0) warn with wall - * parse.y : Make if (x=0) warn with wall - -Tue Jan 17 14:12:00 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (BOOL_TYPE_SIZE): BITS_PER_WORD if SLOW_BYTE_ACCESS, - BITS_PER_UNIT otherwise. - - * search.c (get_matching_virtual): Don't check the binfo if the - types are the same. - - * cvt.c (cp_convert): Just call truthvalue_conversion to convert to - bool. - -Mon Jan 16 13:28:48 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * various: Use boolean_type_node, boolean_true_node, - boolean_false_node. - - * search.c (get_matching_virtual): Allow covariant returns that - don't require pointer adjustment. - - * typeck.c (build_conditional_expr): Don't call default_conversion - on ifexp. - - * cvt.c (build_up_reference): Handle MIN_EXPR and MAX_EXPR. - - * decl.c (grokdeclarator): Upgrade warning about &const to pedwarn. - -Sun Jan 15 22:17:32 1995 David Binderman <dcb@lovat.fmrco.COM> - - * pt.c (do_function_instantiation): Free targs once we're done. - -Sun Jan 15 22:17:32 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (BOOL_TYPE_SIZE): Defaults to BITS_PER_WORD. - (init_decl_processing): Use BOOL_TYPE_SIZE instead of CHAR_TYPE_SIZE - for bool. - -Sat Jan 14 05:33:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_file): We need to mess up if there are any - variables in the list, not just if there is one with a constructor. - -Fri Jan 13 14:42:55 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (duplicate_decls): Propagate DECL_STATIC_{CON,DE}STRUCTOR. - (finish_function): Handle DECL_STATIC_{CON,DE}STRUCTOR. - (finish_function): Trust rest_of_compilation. - - * decl2.c (finish_file): Also call functions designated as static - constructors/destructors. - - * decl.c (grokdeclarator): Allow access decls of operator functions. - (grokparms): Only do convert_for_initialization if the initializer - has a type. - (duplicate_decls): Put back push_obstacks_nochange call. - - * lex.c (real_yylex): Downgrade complaint about the escape sequence - being too large from pedwarn to warning. - - * decl.c (grokdeclarator): Don't complain about long long in system - headers. - - * lex.c (real_yylex): Handle digraphs. - -Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (init_decl_processing): -f{no-,}strict-prototype only - affects C linkage declarations now. - - * typeck.c (comp_target_types): Grok simple contravariant conversions. - (common_type): t1 and t2 are interchangeable. - - * various: Test return value of comp_target_types differently in - different places; it now returns -1 for a contravariant conversion - (which is fine in symmetric cases). - - (common_type): Prefer long double to double even when - they have the same precision. - - * decl.c (grokparms): Call convert_for_initialization to check - default arguments. - - * init.c (build_new): void_type_node has a size (of 0). - - * decl.c (decls_match): Also check for agreement of TREE_READONLY - and TREE_THIS_VOLATILE. - (push_class_level_binding): Properly handle shadowing of - nested tags by fields. - - * search.c (dfs_pushdecls): Likewise. - - * decl2.c (finish_file): Don't second-guess self-initialization. - - * cvt.c (convert_to_reference): Work with expr directly, rather than - a copy. - - * decl.c (push_overloaded_decl): Only shadow artificial TYPE_DECLs. - - * init.c (add_friend): Downgrade duplicate friend message from - pedwarn to warning. - - * decl.c (duplicate_decls): Push obstacks before calling common_type. - -Thu Jan 12 17:15:21 1995 Michael Ben-Gershon <mybg@cs.huji.ac.il> - - * except.c (push_eh_entry): set LABEL_PRESERVE_P flag for - exception table labels. - (expand_start_all_catch): Likewise. - (expand_leftover_cleanups): Likewise. - (expand_end_catch_block): Likewise. - * except.c (make_first_label): new function. - (expand_start_all_catch): add a call to make_first_label() before - using a label as a jump destination. - (expand_end_all_catch): Likewise. - (expand_leftover_cleanups): Likewise. - (expand_end_catch_block): Likewise. - (expand_builtin_throw): Likewise. - (expand_throw): Likewise. - * except.c: Add ARM processor support for exception handling. - -Thu Jan 12 12:17:24 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - (complete_array_type): Copy code from C frontend. - - * lex.c (real_yylex): Don't multiply the length of a wide string - literal by WCHAR_BYTES. - - * decl.c (pushdecl): Check for redeclaration of wchar_t here. - (duplicate_decls): Instead of here. - (define_label): Complain about a label named wchar_t. - (grokdeclarator): Complain about declarations of - operator-function-ids as non-functions. - - * typeck.c (unary_complex_lvalue): Also wrap prefix -- and ++ in - COMPOUND_EXPRs. - (build_unary_op): Wrap unary plus in a NON_LVALUE_EXPR. - - * lex.c (real_yylex): Don't skip whitespace when reading the next - character after ->. - -Wed Jan 11 16:32:49 1995 Mike Stump <mrs@cygnus.com> - - * except.c: Allow cc1plus to be built with native compiler on rs6000. - (expand_start_all_catch): Add assemble_external calls for various - routines we call. - (expand_leftover_cleanups): Likewise. - (expand_start_catch_block): Likewise. - (do_unwind): Likewise. - (expand_builtin_throw): Likewise. - -Wed Jan 11 01:05:42 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (pushtag): Only look for a previous decl in the current - binding level. Use explicit global scope in DECL_NESTED_TYPENAME. - - * gxx.gperf: Add __signature__ and __sigof__ keywords. - - * decl2.c (lang_decode_option): -ansi does not set flag_no_asm. It - does set flag_no_gnu_keywords and flag_operator_names. - - * lex.c (init_lex): 'overload' is not a keyword unless -traditional. - Unset extension keywords if -fno-gnu-keywords. - Allow operator names ('bitand') if -foperator-names. - Never unset 'asm'; -fno-asm only affects 'typeof'. - - * decl.c (lookup_name_real): The got_object special lookup only - applies to types. - -Tue Jan 10 18:07:51 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * spew.c (yylex): Also use DECL_NESTED_TYPENAME if got_object is set. - - * parse.y (primary): Unset got_object after all rules that use the - 'object' nonterminal. - (object): Set got_object. - - * lex.h: Declare got_object. - - * decl.c (lookup_name_real): Also lookup names in the context of an - object specified. - -Tue Jan 10 14:30:30 1995 Mike Stump <mrs@cygnus.com> - - * typeck.c (get_member_function_from_ptrfunc): Use ptrdiff_type_node - for things that have to be added to pointers, not size_type. Cures - problems with pointer to members on Alphas. - (build_binary_op_nodefault): Likewise. - (get_delta_difference_: Likewise. - (build_ptrmemfunc): Likewise. - -Tue Jan 10 01:49:25 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (pushtag): Stick the new decl in TYPE_NAME before pushing - it. - - * typeck.c (build_component_ref): Don't build up a COMPONENT_REF - when dealing with overloaded member functions; just act like - build_offset_ref. - (commonparms): Remove misleading comment. - - * decl.c (duplicate_decls): Complain about repeated default - arguments here. - (redeclaration_error_message): Instead of here. - (pushdecl): Complain about missing default arguments here. - (grokparms): Instead of here. - (lookup_name_current_level): Also match on DECL_ASSEMBLER_NAME. - (grok_reference_init): Do not complain about missing initializer if - declared 'extern'. - - * search.c (lookup_field): Don't return a TYPE_DECL if there is a - function alternative and want_type is not set. - -Mon Jan 9 18:16:23 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (pushtag): Don't set TYPE_NAME to an identifier. Do push - the decl when the type has no TYPE_NAME. - (lookup_nested_type): Don't assume that type has TYPE_NAME set. - (lookup_name_real): Call lookup_field with want_type = - prefer_type. - - * search.c (lookup_field): Handle want_type properly in the presence - of fields with the same name. - - * decl.c (set_nested_typename): Set nested name for file-scope types - to include leading ::. - (pushdecl): Set the nested typename if the decl doesn't have one, - rather than if the type's canonical decl doesn't have one. - -Mon Jan 9 03:44:33 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (convert_for_assignment): Complain about contravariance - violation here. - (comp_target_types): Instead of here. - (build_unary_op): resolve_offset_ref before checking for a valid - type. - - * spew.c (yylex): Decrement looking_for_typename after we see a - _DEFN. - - * decl.c (pushdecl): Don't install an artificial TYPE_DECL in - IDENTIFIER_LOCAL_VALUE if we already have a decl with that name. - - * typeck.c (convert_for_assignment): Converting pointers to bool - does not need a cast. - -Sun Jan 8 18:16:45 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (instantiate_type): Initialize nsubsts parm. - - * pt.c (do_function_instantiation): Likewise. - -Sat Jan 7 14:37:05 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (tsubst): Use TREE_STATIC instead of DECL_INLINE && - DECL_SAVED_INSNS to determine whether or not we've seen a definition - of this function. - (instantiate_template): Likewise. - - * call.c (convert_harshness): Allow const reference binding when - called from the overloading code, but not when called from - can_convert (since it isn't a conversion). - (convert_harshness): Put back some disabled code. - -Fri Jan 6 14:10:57 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (convert_harshness): There is no implicit conversion from - void* to other pointer types (unless the parameter is (void*)0). - (convert_harshness): Non-lvalues do not convert to reference types. - - * class.c (finish_struct_methods): Still set - TYPE_HAS_{INT,REAL}_CONVERSION. - - * call.c (can_convert): Don't use aggregate initialization. - - * cp-tree.h: Declare lookup_conversions. - -Thu Jan 5 21:08:00 1995 Mike Stump <mrs@cygnus.com> - - * parse.y (simple_stmt): Fix duplicate case value error messages to - be more readable. - -Wed Jan 4 16:44:19 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (build_type_conversion): Total rewrite to use - convert_harshness instead of reproducing conversion logic here. Now - much shorter. - - * call.c (convert_harshness): Support conversions to bool. - (can_convert): Checks whether a conversion is less harsh - than USER_CODE, for build_type_conversion. - - * search.c (add_conversions): Function for passing to dfs_walk which - adds all the type conversion operators in the current type to a list. - (lookup_conversions): Calls dfs_walk with add_conversions and return - the list. - (dfs_walk): Don't require a qfn. - - * cp-tree.h: Lose CLASSTYPE_CONVERSIONS hackery. - (CLASSTYPE_FIRST_CONVERSION): Points to elt 1 of CLASSTYPE_METHOD_VEC. - - * class.c (finish_struct_bits): Lose CLASSTYPE_CONVERSIONS hackery. - (grow_method): A separate function for building onto the growing - method vector. - (finish_struct_methods): Use it. Put all type conversion operators - right after the constructors. Perhaps we should sort the methods - alphabetically? - -Mon Jan 2 14:42:58 1995 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Lose another misleading shortcut. - -Fri Dec 30 17:57:30 1994 Mike Stump <mrs@cygnus.com> - - * gc.c (build_bltn_desc): Handle bool as a built-in type. - -Fri Dec 30 14:20:21 1994 Mike Stump <mrs@cygnus.com> - - * tree.c (layout_vbasetypes): Ensure that we don't loose alignment - on the complete type because of small virtual bases. - -Fri Dec 30 12:22:29 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (n_incomplete): Bump n_incomplete up to int to match C - front end. - (pushdecl): Also count decls pushed that are of a type being defined - as incomplete things. - * class.c (finish_struct): Move hack_incomplete_structures up to - just after we set it as not being defined, so that the decls we - build for RTTI don't count as incomplete. - -Thu Dec 29 18:20:57 1994 Mike Stump <mrs@cygnus.com> - - * pt.c (tsubst): Fix problem with defining constructors in templated - classes with virtual bases. - -Wed Dec 28 08:31:00 1994 Mike Stump <mrs@cygnus.com> - - * parse.y (TYPEID): Strip top-level cv-qualifiers on typeid - expressions. - * gc.c (build_typeid): Likewise. - -Thu Dec 22 17:26:33 1994 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_up_reference): Fix breakage introduced on Nov 29, - don't assert on complex AGGR inits. - -Thu Dec 22 14:32:31 1994 Mike Stump <mrs@cygnus.com> - - * method.c (build_overload_value): Handle pointer to members as - template arguments. - -Thu Dec 22 13:09:07 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (unary_complex_lvalue): Don't call sorry if we know how - to do take the address of a data member for a pointer to data - member. - -Thu Dec 22 10:04:19 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (grokdeclarator): Use the typedef name for linkage if the - type doesn't otherwise have a name. - - * decl2.c (grokfield): Likewise. - - * class.c (finish_struct): Since we reuse the TYPE_DECL for the - DECL_NAME of enums, structs and classes, we have to avoid trying to - put it in the TYPE_FIELDS again. - -Wed Dec 21 11:07:05 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (check_classfn): Ignore this parameter on static functions - when checking to see if we match. - -Tue Dec 20 17:47:02 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (unary_complex_lvalue): Handle address of non-left most - pointers to members by calling get_delta_difference. - -Mon Dec 19 22:40:53 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (check_classfn): Don't use decls_match yet, as it modifies - static functions to early. - -Thu Dec 19 22:37:48 1994 Mike Stump <mrs@cygnus.com> - - * method.c (make_thunk): Handle encoding of positive thunk offsets. - -Sat Dec 17 13:29:50 1994 Doug Evans <dje@canuck.cygnus.com> - - * Make-lang.in (.PHONY): Tell GNU make C++ and c++ are phony targets. - -Thu Dec 15 16:32:12 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (check_classfn): Use decls_match to check if this has - already been declared, as the DECL_ASSEMBLER_NAME may have been - changed via asm("new_name"). - * decl.c (decls_match): Make public. - -Thu Dec 15 15:17:55 1994 Mike Stump <mrs@cygnus.com> - - * *.[chy] (expand_aggr_init) Add fourth argument to handle - distinction between = init and (init) style of initializations. - * *.[chy] (finish_decl): Add fifth argument to handle - distinction between = init and (init) style of initializations. - -Tue Dec 13 19:16:05 1994 Mike Stump <mrs@cygnus.com> - - Fix some random `explicit' bugs. - - * cvt.c (convert_to_reference): Add third parameter to - convert_force. - (convert_force): Likewise. - * call.c (build_method_call): Likewise. - * decl2.c (setup_vtbl_ptr): Likewise. - * init.c (expand_virtual_init): Likewise. - (build_member_call): Likewise. - (build_delete): Likewise. - (build_vbase_delete): Likewise. - * typeck.c (build_component_addr): Likewise. - (build_c_cast): Likewise. - (build_modify_expr): Likewise. - * cp-tree.h (CONV_NONCONVERTING): Likewise. Add so that we can - distinguish the context in which the conversion appears. Add thrid - argument to build_c_cast. - * cvt.c (cp_convert): Pass whether or not we want to consider - non-converting constructors down to build_method_call. - * decl2.c (reparse_absdcl_as_casts): Add third argument to - build_c_cast. - * gc.c (build_m_desc): Likewise. - * init.c (build_new): Likewise. - * parse.y (expr_no_commas): Likewise. - (primary): Likewise. - * typeck.c (build_x_function_call): Likewise. - (build_static_cast): Likewise. - (build_reinterpret_cast): Likewise. - (build_const_cast): Likewise. - (build_c_cast): Likewise. - (build_ptrmemfunc): Likewise. - * typeck2.c (build_functional_cast): Likewise. - * init.c (expand_aggr_init): Added LOOKUP_ONLYCONVERTING to - expand_aggr_init_1 as inits are converted to the destination type. - -Tue Dec 13 16:18:57 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * Make-lang.in (cc1plus): Depends on c-pragma.o. - - * Makefile.in (OBJ{DEP,}S): Add ../c-pragma.o. - - * lex.c (check_newline): If the #pragma is not recognized by g++, - try machine-specific ones too. - (handle_sysv_pragma): Copied from c-lex.c. - -Mon Dec 12 23:53:06 1994 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Fix Dec 6th change, build_new likes a - reference better. - -Mon Dec 12 18:01:00 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_binary_op): Lose checks on TYPE_PTRMEMFUNC_P with - IS_AGGR_TYPE, since now they will not both be set on the same type. - - * pt.c (do_pending_expansions): Don't clear TREE_PUBLIC on - instantiations controlled by -fexternal-templates. - - * decl.c (duplicate_decls): Don't complain about different values of - __attribute__ ((const)) and ((noreturn)). - -Fri Dec 9 18:17:37 1994 Doug Evans <dje@cygnus.com> - - * Makefile.in (BISONFLAGS): Delete --yacc. - (PARSE_H): Depend on $(PARSE_C), for parallel makes. - (PARSE_C): Undo last patch. - -Fri Dec 2 10:44:36 1994 Mike Stump <mrs@cygnus.com> - - * Makefile.in (BISONFLAGS): Add --yacc so that output winds up in - y.tab.c. - -Thu Dec 8 17:39:46 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (finish_decl): Don't call obscure_complex_init for decls - of indeterminate size. - -Wed Dec 7 16:49:22 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (obscure_complex_init): Function to tweak the decl to - prevent expand_decl from tring to initialize it. - (finish_decl): Use it rather than writing the same code in three - different places. - - * parse.y (bad_parm): Stop trying to support parms without types. - -Wed Dec 7 12:06:56 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (grokfield): Make asm specs on static member functions - work. - -Tue Dec 6 15:43:20 1994 Mike Stump <mrs@cygnus.com> - - * except.c (expand_throw): Make a copy of the thrown object. - -Tue Dec 6 14:16:34 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * parse.y: : has lower precedence than =. - -Tue Dec 6 12:46:17 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (pushdecl): Use DECL_NAME of VAR_DECLs to avoid namespace - manglings. - (grokvardecl): Add namespace into variable name. - -Tue Dec 6 11:26:55 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (current_namespace_id): New routine to transform a simple - name into a name in a namespace. - * decl.c (grokdeclarator): Use it. - * decl2.c (get_namespace_id): Find the name of the current - namespace. - (push_namespace, pop_namespace): Complete out missing - functionality. - -Mon Dec 5 17:11:51 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * class.c (finish_struct): Don't use LONG_LONG_TYPE_SIZE, as it may - not be defined. Fix warning message for enums and restore warning - for non-enums. - - * decl2.c (push_namespace): Dummy function. - (pop_namespace): Likewise. - (do_namespace_alias): Likewise. - (do_using_decl): Likewise. - (do_using_directive): Likewise. - - * parse.y: New token NSNAME for namespace names. - (extdef): Add namespace, using definitions. - (using_decl): New rule for using declarations. - (any_id): New rule for identifiers with any degree of scoping. - (identifier): Add NSNAME. - (notype_identifier): Likewise. - (component_decl): Add using_decl. - (nested_name_specifier): Add NSNAME SCOPE. - - * typeck.c (convert_for_assignment): Handle conversions between - enums and bool. - - * decl.c (duplicate_decls): Only propagate DECL_MAIN_VARIANT on - FUNCTION_DECLs. - -Mon Dec 5 13:03:16 1994 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct): Give an error if one tries to declare a - bit-field's size greater than a long long, as the backend will dump. - It is not an error to declare an enum bit-field greater than its - precision. Warn if an enum bit-field is too small to hold all - its values. - -Mon Dec 5 11:41:50 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (convert_for_assignment): Use cp_convert instead of - convert so that we don't get static casts. - -Sun Dec 4 11:59:01 1994 Mike Stump <mrs@cygnus.com> - - * cvt.c (cp_convert): Don't complain about int->enum conversion if - we are doing static casts. - -Fri Dec 2 18:32:41 1994 Mike Stump <mrs@cygnus.com> - - * error.c (dump_expr): Do something more intelligent with SAVE_EXPRs - when dumping expressions in error messages. - -Fri Dec 2 17:04:27 1994 Mike Stump <mrs@cygnus.com> - - * gc.c (build_dynamic_cast): Change interface to libg++, ensure that - the return type is the right type, and make references work. - -Fri Dec 2 16:36:43 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (poplevel): Don't be confused by function-scope - declarations of non-nested functions. - (duplicate_decls): Propagate DECL_MAIN_VARIANT. - (pushdecl): Use duplicate_decls to copy info from old decl into new - function-scope one rather than doing it here. - - * decl2.c (mark_inline_for_output): Deal with the DECL_MAIN_VARIANT - of this decl, in case this is a function-scope declaration. - - * decl.c (finish_enum): Make sure that the type has the right - precision when we call fixup_*_type. - -Tue Nov 29 19:12:07 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (build_up_reference): Strip superfluous NOP_EXPRs; we do - want to build up references to rvalues if possible. - (cp_convert): Stick on a NOP_EXPR when converting to the same type. - -Tue Nov 29 11:28:59 1994 Mike Stump <mrs@cygnus.com> - - * parse.y (maybe_raises): Handle throw (). - * parse.y (ansi_raise_identifier): grok type-ids in exception - specifications. - * tree.c (build_exception_variant): Use list compare to check if - two exception specifications match. - * decl.c (duplicate_decls, bad_specifiers): Enhance wording on error - messages. - * call.c (build_method_call): Remove TREE_RAISES. - * cvt.c (convert_to_aggr): Likewise. - * typeck.c (build_function_call_real, convert_arguments): Likewise. - * init.c (expand_aggr_init_1): Likewise. - -Tue Nov 29 09:50:39 1994 Mike Stump <mrs@cygnus.com> - - * except.c: Add support for m68k and mips exception handling - support. - -Tue Nov 29 08:48:33 1994 Mike Stump <mrs@cygnus.com> - - * except.c (expand_end_all_catch): Throw into outer context, if we - fall off end of catch handlers. - -Mon Nov 28 16:44:41 1994 Mike Stump <mrs@cygnus.com> - - * Makefile.in: Make is easier to decide where parse.[ch] will be - built. - -Thu Nov 17 20:11:24 1994 Doug Evans <dje@cygnus.com> - - * cp/Make-lang.in (CXX_INSTALL_NAME) Use program_transform_name. - (GXX_INSTALL_NAME) Likewise. - (CXX_CROSS_NAME) Use program_transform_cross_name. - (GXX_CROSS_NAME) Likewise. - (c++.install-man): Use program_transform_name on g++.1. - (c++.uninstall): Likewise. - -Mon Nov 28 13:53:03 1994 Mike Stump <mrs@cygnus.com> - - * parse.y (THROW): Fix precedence of throw expressions. - -Mon Nov 28 13:15:16 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_unary_op): Allow promotions from bool to int on - unary ~. - -Sun Nov 27 00:16:21 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (build_overload_name): Use DECL_ASSEMBLER_NAME for - classes when appropriate. - (build_overload_nested_name): When dealing with a function context, - use ASM_FORMAT_PRIVATE_NAME to tweak the name of the function to - avoid conflicts between local classes of the same name. - -Wed Nov 23 17:59:42 1994 Mike Stump <mrs@cygnus.com> - - * gxx.gperf, parse.y, lex.h, hash.h, lex.c (init_lex), delc.c - (duplicate_decls, grokdeclarator), cp-tree.h: Add support for - `explicit'. - * cvt.c (convert_to_reference, cp_convert, build_type_conversion_1, - build_type_conversion): Use LOOKUP_ONLYCONVERTING in - build_method_calls so that non-converting constructors are not used. - * call.c (build_method_call): If we shouldn't use a non-converting - constructor, then don't. - -Wed Nov 23 14:46:56 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_method_call): Don't try to synthesize methods yet. - -Tue Nov 22 12:45:21 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (push_template_decls): Create CONST_DECLs for template - constant parameters, not VAR_DECLs. - -Sat Nov 19 15:28:31 1994 Jim Wilson <wilson@chestnut.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Can shorten shift only if - shift count is less than size in bits of arg0. - -Thu Nov 17 15:30:50 1994 Mike Stump <mrs@cygnus.com> - - * gxx.gperf, hash.h, lex.c (init_lex, real_yylex), parse.y: Add new - ANSI keywords and, and_eq, bitand, bitor, explicit, namespace, not, - not_eq, or, or_eq, typename, using, xor, xor_eq to g++. Still need - to add support for explicit, namespace, typename, and using, support - for the rest is already in. - -Fri Nov 4 19:04:18 1994 Mike Stump <mrs@cygnus.com> - - * gc.c (get_bad_cast_node): New routine to support compile time - throws of bad_cast. - * gc.c (build_dynamic_cast): Support throwing of bad_cast at compile - time. - -Fri Nov 4 11:12:00 1994 Mike Stump <mrs@cygnus.com> - - * except.c: Add hppa support. - -Fri Nov 4 10:50:50 1994 Mike Stump <mrs@cygnus.com> - - * except.c: Add rs6000 support. - -Thu Nov 3 14:24:23 1994 Mike Stump <mrs@cygnus.com> - - * except.c (do_unwind): Add i[34]86 support. - -Thu Nov 3 00:10:46 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (do_pending_expansions): Unset TREE_PUBLIC on implicit - instantiations. - -Wed Nov 2 15:08:24 1994 Kung Hsu <kung@mexican.cygnus.com> - - * decl.c (finish_function): Emit types used in method parameters - into symbol table. - -Wed Nov 2 15:05:47 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (process_template_parm): Allow pointer to member function - template parameter types. - (uses_template_parms): Handle pointer to member function - CONSTRUCTORs. - - * g++.c (main): Cast first argument of bzero to (char *). - Pass -lstdc++ instead of -lg++ unless we are invoked as 'g++'. - -Mon Oct 31 14:50:48 1994 Kung Hsu <kung@mexican.cygnus.com> - - * gc.c (build_dynamic_cast): rewrite to make it work. - * class.c (finish_vtbls): build more vtables if flag_rtti is on. - * class.c (modify_all_direct_vtables): ditto. - * init.c (expand_direct_vtbls_init): expand more vtables if - flag_rtti is on. - * decl.c (init_type_desc): add default return. - -Tue Oct 25 17:13:09 1994 Kung Hsu <kung@mexican.cygnus.com> - - * tree.c (debug_binfo): get rid of the initial size entry of - vtable. - * cp-tree.h: change flag_dossier to flag rtti, define type - descriptor type nodes. - * decl.c (init_type_desc): new function to initialize type - descriptor type nodes. - * decl.c (record_builtin_type): change flag_dossier to flag_rtti. - * lex.c (init_lex): ditto. - * decl.c : change variable flag_dossier to flag_rtti. - * decl.c (duplicate_decls): get rid initial size entry of vtable. - * decl.c (hack_incomplete_structures): take out assert 164. - * search.c (get_abstract_virtuals_1): ditto. - * search.c (dfs_init_vbase_pointers): change CLASSTYPE_DOSSIER to - CLASSTYPE_RTTI. - * parse.y: ditto. - * class.c (prepare_fresh_vtable): for virtual bases, get right - offset. - * class.c (add_virtual_function): change flag_dossier to - flag_rtti. - * class.c (modify_one_vtable): modify the right rtti entry. - * class.c (override_one_vtable): get rid of size entry. - * class.c (finish_struct): change flag_dossier to flag_rtti, and - build extra vtables, build type descriptors for polymorphic - classes. - * gc.c (build_headof): make headof() works correctly with new - rtti. - * gc.c (build_typeid): make this function work with new rtti. - * gc.c (get_typeid): make this function work with new rtti. - * gc.c (build_bltn_desc): new function for new rtti. - * gc.c (build_user_desc): ditto. - * gc.c (build_class_desc): ditto. - * gc.c (build_ptr_desc): ditto. - * gc.c (build_attr_desc): ditto. - * gc.c (build_func_desc): ditto. - * gc.c (build_ptmf_desc): ditto. - * gc.c (build_ptmd_desc): ditto. - * gc.c (build_t_desc): ditto. - * gc.c : comment out old build_t_desc, build_i_desc, build_m_desc. - -Tue Oct 25 13:37:41 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (convert_harshness): Check for TREE_UNSIGNED differences - after checking for integral conversions. - -Wed Nov 30 19:13:50 1994 Mike Stump <mrs@cygnus.com> - - * Version 2.6.3 released. - -Thu Nov 17 10:56:50 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck2.c (build_m_component_ref): Check the basetype of the - member pointer against the main variant of the object type. - -Mon Nov 14 14:21:52 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (convert_to_reference): Make sure that the original expr - gets its type back when converting a reference. - - * method.c (build_overload_name): Clear numeric_outputed_need_bar here. - (build_decl_overload): Instead of here. - -Tue Nov 8 17:11:24 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (cp_convert): Don't build a TARGET_EXPR if we're not in a - function. - - * typeck.c (convert_for_initialization): Handle initialization from - a TARGET_EXPR. - -Sun Nov 6 01:34:24 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (lookup_nested_type_by_name): Fix list-walking logic. - (tsubst): When replacing a TEMPLATE_TYPE_PARM, propagate - TYPE_READONLY and TYPE_VOLATILE from the argument. - (unify): When unifying with a TEMPLATE_TYPE_PARM, remove cv-quals - present in parm from arg. - (type_unification): Strip REFERENCE_TYPE from the argument type. - (unify): Don't strip REFERENCE_TYPE from the argument type. - -Sat Nov 5 22:42:15 1994 Greg McGary <gkm@magilla.cichlid.com> - - * pt.c (do_type_instantiation): Check to see if there's a - IDENTIFIER_TEMPLATE on a class before calling - instantiate_member_templates(). - -Sat Nov 12 06:35:42 1994 Mike Stump <mrs@cygnus.com> - - * Version 2.6.2 released. - -Thu Nov 3 18:48:19 1994 Paul Eggert <eggert@twinsun.com> - - * Makefile.in (spew.o, lex.o, pt.o): - Depend on $(srcdir)/parse.h, not parse.h. - -Tue Nov 1 19:19:41 1994 Mike Stump <mrs@cygnus.com> - - * Version 2.6.1 released. - -Sun Oct 23 13:19:55 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c: Declare flag_access_control. - (struct lang_f_options): Add access-control. - * expr.c (cplus_expand_expr, NEW_EXPR): Unset flag_access_control - for the call to expand_aggr_init to copy the object out of the - pcc_struct_return slot. - * search.c (compute_access): if (!flag_access_control) return - access_public. - -Fri Oct 21 00:32:54 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * lex.c (cons_up_default_function): Don't try to defer method - synthesis now. - - * decl.c (init_decl_processing): Use __pure_virtual for abort_fndecl - instead of abort, since the OSF/1 dynamic linker doesn't like to see - relocation entries for abort. - - * tree.c (array_type_nelts_total): Use sizetype, not - integer_type_node. - (array_type_nelts_top): Likewise. - -Thu Oct 20 15:48:27 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (grokdeclarator): Added handling for catch parameters - (CATCHPARM). - * except.c (expand_start_catch_block): Use the new CATCHPARM context - instead of NORMAL. - * except.c (expand_throw): Don't let convert_to_reference complain - about what we are doing. - -Thu Oct 20 12:55:24 1994 Jim Wilson <wilson@cygnus.com> - - * method.c (emit_thunk): Call instantiate_virtual_regs. - -Wed Oct 19 14:15:33 1994 Mike Stump <mrs@cygnus.com> - - * except.c (expand_exception_blocks): Make sure throw code doesn't - get put in function that won't be output. - -Mon Oct 17 18:03:15 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (init_decl_processing): Make alloca a builtin. - -Thu Oct 27 21:10:25 1994 Craig Burley <craig@burley> - - * g++.c (main): Only decrement "added" and set "library" to - NULL when "library" != NULL (just like 940829 fix). - -Mon Oct 17 15:56:11 1994 Mike Stump <mrs@cygnus.com> - - * except.c (expand_start_catch_block): Make sure the false label - gets onto the permanent obstack, as it is used for the exception - table. - -Fri Oct 14 18:54:48 1994 Mike Stump <mrs@cygnus.com> - - * class.c (modify_one_vtable): Since the DECL_CONTEXT of fndecl can - be set just below, use current_fndecl instead. - -Fri Oct 14 15:12:22 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * init.c (expand_aggr_vbase_init_1): Don't call expand_aggr_init_1 - with LOOKUP_SPECULATIVELY. - (expand_default_init): Abort if build_method_call returns NULL_TREE. - - * typeck.c (build_modify_expr): Don't just build a MODIFY_EXPR if - the rhs is a TARGET_EXPR. - - * parse.y (left_curly): Anonymous types are not affected by #pragma - interface/implementation. - - * method.c (synthesize_method): Don't call setup_vtbl_ptr for the - default constructor if it isn't needed. - - * lex.c (cons_up_default_function): Do synthesize methods for - anonymous types if necessary. - -Thu Oct 13 17:44:55 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (build_decl_overload): Set numeric_outputed_need_bar to 0. - -Wed Oct 12 13:27:57 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * typeck.c (build_modify_expr): Understand how to copy an aggregate. - - * init.c (expand_default_init): Likewise. Also remove some of the - crufty code that assumes methods will not be synthesized properly. - - * lex.c (cons_up_default_function): If the containing type has no - name, these functions should never need to be called, so just - declare them. - - * lex.c (real_yylex): Use HOST_BITS_PER_WIDE_INT to determine the - bitmask for lexing character constants. - - * call.c (build_method_call): Disable code that tries to do tricky - stuff with a default parameter that is a constructor call, but - actually does other tricky stuff that breaks things. - -Wed Oct 12 16:14:01 1994 Benoit Belley <belley@cae.ca> - - * decl.c (finish_enum): Disable code which forces enums to be signed, - since this conflicts with their use as bitfields. type_promotes_to - handles promotion of enums of underlying unsigned types to signed - integer types. - -Wed Oct 12 13:24:03 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * cvt.c (type_promotes_to): Also promote enums to long if - appropriate. - - * typeck.c (default_conversion): Don't expect type_promotes_to to - return a main variant. - -Wed Oct 12 12:19:45 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_scoped_method_call): Don't lose side effects in the - object expression when calling a non-existent destructor. - -Fri Sep 2 19:05:21 1994 Rohan Lenard <rjl@iassf.easams.com.au> - - * call.c (build_scoped_method_call): Remove erroneous error message - when destructor call is written as a scoped call. - -Tue Oct 11 23:48:31 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * various: Cast pointer arguments to bzero and bcopy to char *. - -Tue Oct 11 19:34:32 1994 Mike Stump <mrs@cygnus.com> - - * class.c (get_derived_offset): Added a type parameter to limit how - far up the CLASSTYPE_VFIELD_PARENT chain we search. - * class.c (modify_one_vtable, fixup_vtable_deltas): When forming the - offset to put into the vtable for the this parameter, make sure we - don't offset from a parent of the DECL_CONTEXT of the function. - -Tue Oct 11 16:10:52 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * pt.c (do_function_instantiation): Set DECL_EXTERNAL and - TREE_STATIC when setting DECL_INTERFACE_KNOWN. - (do_type_instantiation): Likewise. - - * lex.c (cons_up_default_function): Set DECL_INTERFACE_KNOWN, - DECL_EXTERNAL and TREE_STATIC as appropriate. - - * decl2.c (finish_file): Also synthesize methods that don't have - DECL_EXTERNAL set. Set interface_unknown before doing so. - - * decl.c (start_function): If DECL_INTERFACE_KNOWN is set on the - function decl, don't muck with TREE_PUBLIC and DECL_EXTERNAL. - -Mon Oct 10 00:56:53 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * lex.c (cons_up_default_function): Mark methods in a template class - as template instances. Store the values of interface_unknown and - interface_only for do_pending_inlines. - (do_pending_inlines): Use them. - - * decl2.c (finish_file): If we haven't seen a definition of a - function declared static, make the decl non-PUBLIC so compile_file - can give an error. - -Sun Oct 9 02:42:29 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * method.c (do_build_copy_constructor): Handle anonymous unions. - (do_build_assign_ref): Likewise. - (largest_union_member): Move from lex.c. - -Sat Oct 8 14:59:43 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - Re-implement g++'s vague linkage independent of TREE_PUBLIC. - * pt.c (instantiate_member_templates): Lose redundant - -fexternal-templates handling. - (tsubst): Set TREE_PUBLIC and DECL_EXTERNAL on new decls. Don't set - TREE_STATIC or DECL_INTERFACE_KNOWN. - (do_pending_expansions): Predicate on DECL_INTERFACE_KNOWN instead - of DECL_EXTERNAL for explicit instantiations. - (do_function_instantiation): Do the new thing. - (do_type_instantiation): Likewise. - (instantiate_template): Deal with member templates defined in a .cc - file with -fexternal-templates. - * except.c (expand_exception_blocks): Use DECL_LINKAGE_KNOWN to - decide whether to stick builtin_throw here. - * decl2.c (import_export_inline): Predicate on DECL_INTERFACE_KNOWN - rather than TREE_PUBLIC. Generally fix rules. - (finish_file): Use DECL_INITIAL to determine whether or not a method - has been synthesized, rather than TREE_ASM_WRITTEN. - * decl.c (warn_extern_redeclared_static): Use DECL_PUBLIC instead of - TREE_PUBLIC. - (pushdecl): Likewise. - (duplicate_decls): Likewise. Deal with DECL_DECLARED_STATIC and - DECL_INTERFACE_KNOWN. - (redeclaration_error_message): Fix checking for conflicting linkage. - (define_function): Set DECL_INTERFACE_KNOWN. - (grokfndecl): Function decls are PUBLIC until we are sure about - their linkage. Set DECL_DECLARED_STATIC as needed. - (start_function): Deal with linkage. Move pushdecl after linkage - magic. - (finish_function): Don't set TREE_ASM_WRITTEN on discarded inlines. - * cp-tree.h (lang_decl_flags): Add interface_known and - declared_static. - (DECL_INTERFACE_KNOWN): New macro. - (DECL_DECLARED_STATIC): New macro. - (DECL_PUBLIC): New macro. - - Clean up bogus use of TREE_PUBLIC. - * class.c (alter_access): Fix mistaken use of TREE_PUBLIC (it - doesn't correspond to TREE_PROTECTED and TREE_PRIVATE). - * init.c (do_friend): Don't arbitrarily set TREE_PUBLIC. - -Wed Oct 5 13:44:41 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * call.c (build_overload_call_real): Don't immediately do - array->pointer conversion. - - * pt.c (type_unification): If not passing to a reference, strip - cv-quals. Also handle array->pointer conversion. - -Tue Oct 4 17:45:37 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grokdeclarator): Don't warn about applying const to a - const typedef or template type parameter. - - * decl2.c (finish_file): Also synthesize methods after walking the - vtables. Ugly ugly ugly. - -Mon Oct 3 15:02:41 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * various: Remove lingering remnants of old exception handling code. - - * decl2.c (finish_file): Synthesize methods before walking the - vtables, so that the vtables get emitted as needed. - - * decl.c (shadow_tag): Remove obsolete code for pushing tags and - dealing with exceptions. - -Mon Oct 3 13:05:27 1994 Ian Lance Taylor <ian@sanguine.cygnus.com> - - * Make-lang.in (g++-cross): Depend upon version.o and $(LIBDEPS). - -Mon Oct 3 02:59:28 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl2.c (finish_file): Fix inline handling. - -Sun Oct 2 00:21:56 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - * decl.c (grokdeclarator): Handle redundant scope even better. - ({push,pop}_cp_function_context): Take toplev parameter. - - * method.c (synthesize_method): Pass toplev parameter to - {push,pop}_cp_function_context depending on decl_function_context - (fndecl). - - * typeck.c (build_x_unary_op): Unary & on OFFSET_REFs is always the - built-in version. - - * method.c (synthesize_method): Don't be confused by __in_chrg - parameter. - - * class.c (popclass): Set C_C_D like start_function does. - - * decl.c (grokdeclarator): Handle redundant scope better. - - * parse.y (expr_or_declarator): Add '(' expr_or_declarator ')' rule. - (direct_notype_declarator): Likewise. - (complex_direct_notype_declarator): Remove it here. - -Sat Oct 1 21:42:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (resolve_offset_ref): Fix types used in resolving .* - expressions. - -Sat Oct 1 15:18:49 1994 Jason Merrill <jason@phydeaux.cygnus.com> - - Beginnings of work to synthesize methods only when needed. - * call.c (build_method_call): Synthesize methods as necessary - (currently never necessary). - * class.c (popclass): Don't try to set C_C_D here, as it'll end up - on the wrong obstack. - * decl.c (push_cp_function_context): Mostly copied from - push_c_function_context. - (pop_cp_function_context): Similarly. - (finish_function): Reverse order of poplevel and pop_nested_class so - that current_class_decl is restored properly. - (start_function): Likewise. - (finish_function): Add parameter 'nested'. Don't call - permanent_allocation if (nested). - * various: Pass extra parameter to finish_function. - * decl2.c (finish_file): Reorganize end-of-file inline handling, - synthesizing methods as necessary. - * lex.c (cons_up_default_function): Call mark_inline_for_output. - Only synthesize methods immediately if #pragma implementation - (currently disabled). - (do_pending_inlines): Call synthesize_method. - * method.c (synthesize_method): New function; all method synthesis - goes through here. Calls do_build_assign_ref and - do_build_copy_constructor. - (build_default_constructor): Remove. - (build_dtor): Likewise. - (build_assign_ref): Rename to do_build_assign_ref and remove stuff - done by synthesize_method. - (build_copy_constructor): Similarly. - -Thu Sep 29 16:58:52 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (c_expand_return): Use magic so the backend can fixup the - assignment into the return register, so cleanups won't clobber it. - -Thu Sep 29 13:08:50 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (hack_identifier): Don't call assemble_external for - template decls. - - * decl.c (finish_decl): Also end temporary allocation if the decl in - question has a type of error_mark_node. - -Wed Sep 28 21:45:00 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (build_modify_expr): When optimizing ?: on lhs, make sure - that if the ?: was a reference type, that the subparts will be also. - -Wed Sep 28 16:14:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * except.c (register_exception_table): Use Pmode, not PTRmode. - -Fri Sep 23 13:54:27 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (do_pending_inlines): Do method synthesis after the - pending_inlines have been reversed. - -Thu Sep 22 12:53:03 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl2.c (finish_file): Fix Brendan's fix: Only call - register_exception_table if there is a non-empty exception table. - -Thu Sep 22 12:03:46 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl2.c (finish_file): Only do register_exception_table if - -fhandle-exceptions is being used. - -Wed Sep 21 19:01:51 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * except.c (output_exception_table_entry): Simplify - by using assemble_integer. - (build_exception_table): Change to return a count. - Cleanup to use standard macros, instead of hard-wired - sparc asm format. Don't make __EXCEPTION_TABLE__ global. - (register_exception_table): New function. Generate call to builtin. - * decl2.c (finish_file): Call register_exception_table. - * cp-tree.h (build_exception_table): Fix prototype. - -Wed Sep 21 13:20:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * tree.c (break_out_calls): Don't try to duplicate the DECL_INITIAL. - - * decl2.c (delete_sanity): Give an error at trying to delete a - function. - -Wed Sep 21 11:47:10 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (cons_up_default_function): Mark synthesized destructors - inline. - - * decl.c (duplicate_decls): Ignore redeclarations of wchar_t as - something other than __wchar_t, complaining if -pedantic and not in - a system header. - -Tue Sep 20 09:43:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (xref_tag): Set up BINFO_INHERITANCE_CHAIN on base binfos - here. - - * typeck.c (build_modify_expr): Require complete type after checking - for error_mark_node. - - * call.c (build_method_call): Print parmtypes when complaining of - ambiguous call. - - * typeck.c (build_modify_expr): Handle assignment to array from - non-array. - - * decl.c (lookup_name_real): Deal with got_scope == error_mark_node. - - * call.c (build_method_call): Don't bother with the exact match. - -Mon Sep 19 00:51:39 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (expand_aggr_init): If we munge the type of the variable, - also munge the type of the initializer. - - * decl.c (grokdeclarator): Use <= when comparing to RID_LAST_MODIFIER. - (init_decl_processing): Push artificial declaration of wchar_t so - people don't have to declare it before they can use it. - - * error.c (cp_line_of): return lineno in lieu of 0. - - * typeck.c (convert_for_assignment): Handle conversion of pmfs to - int and bool. - (build_component_ref): Fold the COMPONENT_REF in case it can be - reduced. - - * typeck2.c (store_init_value): Don't pedwarn about non-constant - bracketed initializers for automatic variables. - -Sun Sep 18 10:12:12 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_decl): Don't say `typedef enum foo foo'. - - * decl.c (start_decl): Don't set TREE_PUBLIC on template decls just - because they're affected by #pragma i/i. We'll deal with that when - they get instantiated. - - * typeck.c (build_unary_op): Clean up cruft in ADDR_EXPR case. - - * class.c (instantiate_type): Set TREE_CONSTANT on instantiated - ADDR_EXPRs if appropriate. - - * decl.c (build_ptrmemfunc_type): Unset IS_AGGR_TYPE on pmf types. - - * typeck.c (build_ptrmemfunc): Handle &overloaded_method as an - initializer properly. - * typeck2.c (digest_init): Likewise. - - * tree.c (cp_build_type_variant): Like c_build_type_variant, except - it uses build_cplus_array_type. - * *.c: Use cp_build_type_variant instead of c_build_type_variant. - - * pt.c (do_type_instantiation): Don't try to instantiate nested - enums. - -Tue Sep 13 10:56:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_up_reference): Handle preincrement and predecrement - properly. - -Tue Sep 13 09:51:59 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (finish_decl): Only lay out the rtl for DECL if it is, in - fact, static. - -Mon Sep 12 14:40:30 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (finish_decl): Lay out the rtl for DECL before doing - grok_reference_init, in case it's static. - -Mon Sep 12 12:45:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Don't synthesize constructors if the - class has a field with the same name as the class. Don't die on - classes with no constructors or destructors. Don't die if the head - and tail of the class are in different files. - - * decl.c (grokdeclarator): Don't treat a function pointer field - with the same name as the class as a constructor. - -Fri Sep 9 13:17:00 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_c_cast): Pull constant values out of their - variables here. - - * decl.c (duplicate_decls): Only propagate DECL_CHAIN in - FUNCTION_DECLs and TEMPLATE_DECLs. - -Thu Sep 8 10:07:48 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (duplicate_decls): Propagate DECL_CHAIN in all DECLs that - have it. - - * pt.c (unify): REALs and INTEGERs only unify with their own genus. - (instantiate_member_templates): Don't muck with DECL_EXTERNAL and - TREE_PUBLIC unless -fexternal-templates. - -Wed Sep 7 13:17:10 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (do_type_instantiation): Call instantiate_member_templates. - Deal with specializations. - (tsubst): Don't stick the mangled name in DECL_NAME for function - instantiations. Don't push them, either. - - * decl2.c (grokfield): Move code for generating the - DECL_ASSEMBLER_NAME for static members from here. - * method.c (build_static_name): To here. - * decl.c (grokvardecl): Call build_static_name. - (duplicate_decls): Keep old DECL_ASSEMBLER_NAME. - -Mon Sep 5 12:49:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): if -Wsynth, warn when selecting - synthesized op= over user-supplied one cfront would select. - * decl2.c (lang_decode_option): Handle -Wsynth. - -Fri Sep 2 15:11:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (finish_enum): Overhaul to fix several bugs. - (start_enum): Disable useless code. - -Thu Sep 1 16:04:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (c_expand_return): Warn about returning a reference to a - temporary. - (convert_arguments): Increment argument counter when using default - arguments, too. - -Wed Aug 31 14:29:22 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (finish_decl): If the type of decl is error_mark_node, - don't bother trying to do anything. - - * typeck.c (convert_for_initialization): If the rhs contains a - constructor call, pretend the lhs type needs to be constructed. - - * init.c (expand_default_init): If we stick the object inside the - initializer, mark the initializer used. - -Tue Aug 30 13:50:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (build_assign_ref): return *this; - (build_assign_ref): Fix base assignment order. - (build_copy_constructor): Fix member init order. - -Mon Aug 29 13:54:39 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * g++.c (main): Remember to clear out SAW_SPECLANG after we see - its argument. - -Sat Aug 27 09:36:03 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (build_copy_constructor): Also copy virtual bases. - -Fri Aug 26 17:05:15 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (do_pending_inlines): Clear out pending_inlines before doing - any synthesis. Also first set deja_vu on all pending_inlines. - - * method.c (build_assign_ref): Use build_member_call to invoke base - operator=, rather than build_modify_expr. And use - build_reference_type instead of TYPE_REFERENCE_TO. - (build_copy_constructor): Use TYPE_NESTED_NAME to identify the - basetype. - - * decl2.c (grokfield): Don't complain about undefined local class - methods. - - * class.c (finish_struct): Don't try to synthesize methods here. - * lex.c (do_pending_inlines): Instead, synthesize them here. - (init_lex): Initialize synth_obstack. - (cons_up_default_function): Stick synthesis request on - pending_inlines. - -Fri Aug 26 12:24:14 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * call.c (build_method_call) [PCC_STATIC_STRUCT_RETURN]: Also - accept an RTL_EXPR in what we're about to use for the instance, - since anything which would end up with pcc_struct_return set - inside cplus_expand_expr. - - * cp-tree.h (cons_up_default_function): Note change of prototype. - -Thu Aug 25 23:05:30 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * class.c (finish_struct): Undid change from Aug 21 testing - CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING. - * parse.y (left_curly): Likewise, undid change from Aug 21. - * decl.c (xref_tag): Undid change from Aug 21, set - CLASSTYPE_INTERFACE correctly, and added comments. - -Thu Aug 25 00:36:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - Rework approach to synthesized methods; don't go through the parser - anymore. - * class.c (finish_struct): Use new synthesis approach. - * lex.c (cons_up_default_function): Now just creates declaration, - not code. - (largest_union_member): #if 0 out. - (default_assign_ref_body): Likewise. - (default_copy_constructor_body): Likewise. - * method.c (build_default_constructor): New function to synthesize X(). - (build_copy_constructor): Synthesize X(X&). - (build_assign_ref): Synthesize X::operator=(X&). - (build_dtor): Synthesize ~X(). - - * error.c (cp_line_of): If we're dealing with an artificial - TYPE_DECL, look at the type instead. - -Wed Aug 24 11:11:50 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (sort_member_init): Check warn_reorder. - * decl2.c (lang_decode_option): Handle -W{no-,}reorder. - - * cp-tree.h (CLASSTYPE_SOURCE_LINE): New macro. - * error.c (cp_line_of): Use CLASSTYPE_SOURCE_LINE for aggregates. - * class.c (finish_struct): Set CLASSTYPE_SOURCE_LINE. - -Tue Aug 23 09:28:35 1994 Mike Stump <mrs@cygnus.com> - - * error.c (dump_decl): Improve wording, so that error messages - dont't read template<, class foo>... - -Mon Aug 22 15:30:51 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (label_colon): Also match a TYPENAME as a label name, - since they may have declared a class by that name but have also - tried to have a local label under the same name. - - * pt.c (coerce_template_parms): Call cp_error, not cp_error_at, - for the message so they know at what point it was instantiated. - -Sun Aug 21 23:07:35 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and - CLASSTYPE_VTABLE_NEEDS_WRITING for signatures up to left_curly time. - * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and - CLASSTYPE_VTABLE_NEEDS_WRITING for signatures down to left_curly time. - * parse.y (left_curly): New final resting place for setting - CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING for signatures. - - * class.c (finish_struct): Don't test for function/field name - conflicts in signatures, since all the fields are compiler-constructed. - -Fri Aug 19 14:04:47 1994 Kung Hsu <kung@mexican.cygnus.com> - - * method.c (build_overload_nested_name): in qualified name - mangling, the template with value instantiation will have numeric - at end and may mixed with the name length of next nested level. - Add a '_' in between. - * method.c (build_overload_name): ditto. - * method.c (build_overload_identifier): ditto. - -Thu Aug 18 16:24:43 1994 Mike Stump <mrs@cygnus.com> - - * error.c (dump_decl): Handle NULL args. - -Thu Sep 29 16:15:36 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * g++.c: Rework last change so it's done like collect.c (and - gcc.c). - -Wed Sep 14 10:17:27 1994 Michael I Bushnell <mib@churchy.gnu.ai.mit.edu> - - * g++.c: Include <sys/errno.h> in case `errno' is a macro - as permitted by ANSI C. - -Thu Aug 18 12:48:09 1994 Mike Stump <mrs@cygnus.com> - - * class.c (finish_struct): Move setting of CLASSTYPE_INTERFACE and - CLASSTYPE_VTABLE_NEEDS_WRITING up to left_curly time. - * decl.c (xref_tag): Move setting of CLASSTYPE_INTERFACE and - CLASSTYPE_VTABLE_NEEDS_WRITING down to left_curly time. - * parse.y (left_curly): New final resting place for setting - CLASSTYPE_INTERFACE and CLASSTYPE_VTABLE_NEEDS_WRITING. - -Thu Aug 11 11:32:42 1994 H.J. Lu <hjl@nynexst.com> - - * g++.c (main): Only decrement "added" and set "library" to - NULL when "library" != NULL. - -Sat Aug 13 00:14:52 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Don't set TREE_PUBLIC on a function decl - just because its class has a known interface. - (decls_match): Deal with new format of template parms. - - * lex.c (cons_up_default_function): Don't play with TREE_PUBLIC and - DECL_EXTERNAL here. - -Fri Aug 12 01:55:15 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (pushtag): SET_DECL_ARTIFICIAL on gratuitous typedefs. - (xref_defn_tag): Likewise. - (pushdecl): Only allow artificial typedefs to be shadowed. - - * init.c (emit_base_init): Pass the right binfos to - expand_aggr_init_1. - - * class.c (delete_duplicate_fields_1): Make it work right. - (finish_struct): Catch function/field name conflict. - - * decl2.c (check_classfn): Pass the function to cp_error, not just - the name. - - * init.c (sort_member_init): Warn when order of member initializers - does not match order of member declarations. - (emit_base_init): Call expand_aggr_init_1 with LOOKUP_PROTECT. - - * error.c (dump_expr): Handle lists of functions. - - * decl.c (start_function): #pragma interface only affects functions - that would otherwise be static. - (finish_decl): Don't warn about an unused variable if it has both - constructor and destructor, since the 'resource allocation is - initialization' idiom is relatively common. - - * typeck.c (comp_target_types): Don't handle TEMPLATE_TYPE_PARMs. - (comp_target_parms): Likewise. - (compparms): Never consider default parms. - (common_base_type): Don't choose a virtual baseclass if there is a - more derived class in common. - (build_conditional_expr): If pedantic, pedwarn about conversion to - common base in conditional expr. - - * class.c (instantiate_type): Handle template instantiation better. - - * typeck.c (convert_arguments): Don't try to get tricky and convert - to int directly when PROMOTE_PROTOTYPES is set, as it breaks - user-defined conversions. - - * lex.c (check_for_missing_semicolon): Also give error at end of - file. - - * call.c (build_method_call): Don't promote arrays to pointers here. - - * typeck.c (convert_arguments): Don't require the actual parameter - to be of a complete type if the formal parameter is a reference. - -Thu Aug 11 15:21:40 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Soften 'static' on member function error - to pedwarn. - - * init.c (build_new): Don't automatically save rval. - (build_offset_ref): Do field lookup with proper basetype_path. - -Thu Aug 11 12:46:54 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * errfn.c (cp_silent): Declare to mark when we should avoid - emitting warnings and errors. - (cp_error): Check it. - (cp_warning): Likewise. - (cp_pedwarn): Likewise. - (cp_compiler_error): Likewise. - (cp_error_at): Likewise. - (cp_warning_at): Likewise. - (cp_pedwarn_at): Likewise. - * call.c (compute_conversion_costs): Set CP_SILENT when we start - out, and make sure we turn it off before we leave. - -Thu Aug 11 00:02:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (grok_array_decl): Try computing *(A+B) if neither - argument is obviously an array. - -Wed Aug 10 15:32:04 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (c_expand_start_case): Do cleanups here. - - * parse.y (xcond): Do bool conversion here, too. - (simple_stmt, SWITCH case): Don't do cleanups here. - - * decl.c (duplicate_decls): Don't treat builtins that have been - explicitly declared specially. - -Tue Aug 9 01:16:09 1994 Jason Merrill <jason@deneb.cygnus.com> - - * tree.c (make_deep_copy): Support copying pointer, reference, - function, array, offset and method types. - - * decl.c (init_decl_processing): Mark exit and abort as - BUILT_IN_NONANSI so that duplicate_decls is kinder about - redeclaration. - (duplicate_decls): Don't give two errors for redeclaring a C - function with the same parms but a different return type. - - * parse.y (paren_cond_or_null): Do cleanup and bool conversion here. - (condition): Instead of here. - (simple_stmt, SWITCH case): Also do cleanup here. - - * decl2.c (finish_anon_union): Only break out FIELD_DECLs. - - * call.c (build_method_call): Don't throw away the side effects of - the object in a call to a non-existent constructor. - * parse.y (primary): Likewise. - - * method.c (build_decl_overload): Oop. - - * decl2.c (lang_decode_option): Deal with flag_no_nonansi_builtin, - warn about uselessness of specifying -fansi-overloading. - - * method.c (build_decl_overload): Treat any non-member new with one - parameter as __builtin_new. - - * decl.c (init_decl_processing): Setup built-in meanings of exit, - _exit and abort. - -Mon Aug 8 15:03:30 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_readonly_or_volatile): Put a space between const and - volatile if both apply. - - * init.c (perform_member_init): Clean up after this initialization. - (emit_base_init): Clean up after each base init, not after all have - been done. - (expand_aggr_vbase_init_1): Clean up after this init. - -Sun Aug 7 14:55:05 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Deal with destroying references. - - * parse.y (condition): Do bool_truthvalue_conversion here. - (paren_expr_or_null): And here. - (simple_if): Not here. - (simple_stmt): Or here. - -Sat Aug 6 22:29:45 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (paren_expr_or_null): Wrap the expression in a - CLEANUP_POINT_EXPR. - (condition): Likewise. - -Sat Aug 6 19:46:37 1994 Rohan Lenard <rjl@easams.com.au> - - * call.c (build_scoped_method_call): Fix error message when - destructor call refers to a nonexistent type. - -Sat Apr 16 22:43:30 1993 Gerald Baumgartner <gb@cs.purdue.edu> - - * lex.h (rid): Deleted RID_RAISES, it's never used. - Moved RID_PUBLIC, RID_PRIVATE, RID_PROTECTED, RID_EXCEPTION, - RID_TEMPLATE and RID_SIGNATURE to the end of the enumeration, - they don't need to be touched in `grokdeclarator.' - (RID_LAST_MODIFIER): Defined macro to be RID_MUTABLE. - - * decl.c (grokdeclarator): Use RID_LAST_MODIFIER instead of - RID_MAX as loop limit for finding declaration specifiers. - -Sat Apr 3 21:59:07 1993 Gerald Baumgartner <gb@cs.purdue.edu> - - * lex.c (debug_yytranslate): Moved to parse.y since it needs to - access `yytname,' which is static in parse.c. - -Fri Apr 2 23:36:57 1993 Gerald Baumgarnter <gb@cs.purdue.edu> - - * cp-tree.h (GNU_xref_ref): Fixed typo in extern declaration, it - was `GNU_xref_def' instead of `GNU_xref_ref.' - -Fri Aug 5 14:20:16 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (do_function_instantiation): Don't set TREE_PUBLIC and - DECL_EXTERNAL on 'extern' instantiations; wait until EOF to do that. - (do_type_instantiation): Likewise. - - * decl2.c (import_export_inline): Decides at EOF what an inline's - linkage should be. - (finish_file): Call it. - - * decl.c (start_function): Don't rely on the settings of TREE_PUBLIC - and DECL_EXTERNAL from do_*_instantiation. Only set - DECL_DEFER_OUTPUT on inlines whose linkage might actually change. - (finish_function): Use DECL_DEFER_OUTPUT to decide which inlines to - mark for later consideration, rather than DECL_FUNCTION_MEMBER_P. - -Fri Aug 5 01:12:20 1994 Mike Stump <mrs@cygnus.com> - - * class.c (get_class_offset_1, get_class_offset): New routine to - find the offset of the class where a virtual function is defined, - from the complete type. - * class.c (modify_one_vtable, fixup_vtable_deltas): Use - get_class_offset instead of virtual_offset as get_class_offset will - always provide the right answer. - * tree.c (virtual_offset): Remove. It only ever worked some of the - time. - -Tue Aug 2 12:44:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Put back unary_complex_lvalue call - that I thought was redundant. - - * typeck.c (c_expand_return): Fix a case I missed before. - -Sun Jul 31 17:54:02 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (unify): Strip cv-quals from template type arguments (when - 'const T*' is matched to 'const char*', that does not mean that T is - 'const char'). - -Fri Jul 29 01:03:06 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (do_type_instantiation): Instantiate nested TAGS, not - typedefs. Third time's the charm? - - * parse.y (template_parm): Support default template parms. - * pt.c (process_template_parm): Likewise. - (end_template_parm_list): Likewise. - (coerce_template_parms): Likewise. - (mangle_class_name_for_template): Likewise. - (push_template_decls): Likewise. - (unify): Likewise. - * method.c (build_overload_identifier): Likewise. - * error.c (dump_decl): Likewise. - -Wed Jul 27 17:47:00 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (do_type_instantiation): Only instantiate nested *classes*. - -Tue Jul 26 13:22:40 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (note_debug_info_needed): Also emit debugging information - for the types of fields. - -Mon Jul 25 00:34:44 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (lookup_template_class): Pass 'template' to - coerce_template_parms instead of 'in_decl', since it's a more - meaningful context. - - * typeck.c (c_expand_return): Make sure any cleanups for the return - expression get run. - (build_c_cast): Use CONVERT_EXPR for conversion to void. - - * pt.c (do_type_instantiation): Also instantiate nested types. - - * typeck.c (convert_for_assignment): Don't die when comparing - pointers with different levels of indirection. - - * decl.c (grokdeclarator): The sub-call to grokdeclarator for - class-local typedefs sets DECL_ARGUMENTS, so we need to clear it - out. - - * decl2.c (finish_anon_union): Don't die if the union has no - members. - - * decl.c (grokdeclarator): Undo changes to declspecs when we're done - so that 'typedef int foo, bar;' will work. - - * decl2.c (finish_file): Don't call expand_aggr_init for - non-aggregates. - -Mon Jul 25 00:03:10 1994 Teemu Torma <tot@trema.fi> - - * decl.c (finish_function): We can't inline constructors and - destructors under some conditions with -fpic, but don't unset - DECL_INLINE. - -Mon Jul 25 00:03:10 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_object_ref): Make sure 'datum' is a valid object. - -Sun Jul 24 14:19:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Don't set DECL_FIELD_BITPOS on - non-fields. - (finish_struct_methods): Use copy_assignment_arg_p. - - * cvt.c (cp_convert): If expr is an OFFSET_REF, resolve it instead - of giving an error. - - * typeck.c (build_binary_op_nodefault): Don't set result_type if we - don't know how to compare the operands. - - * decl.c (grokdeclarator): Avoid seg fault when someone uses '__op' - as a declarator-id in their program. Like the Linux headers do. - Arrgh. - - * tree.c (lvalue_p): Treat calls to functions returning objects by - value as lvalues again. - - * typeck.c (build_component_addr): Use convert_force to convert the - pointer in case the component type is also a private base class. - - * search.c (get_matching_virtual): Fix bogus warning of overloaded - virtual. - - * pt.c (overload_template_name): Set DECL_ARTIFICIAL on the created - TYPE_DECL to fix bogus shadowing warnings. - -Fri Jul 22 01:15:32 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (expand_aggr_init_1): const and volatile mismatches do not - prevent a TARGET_EXPR from initializing an object directly. - -Tue Jul 19 17:55:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_up_reference): Allow building up references to - `this', don't warn about making references to artificial variables - (like `this'). - - * tree.c (lvalue_p): `this' is not an lvalue. - - * call.c (build_method_call): Accept using a typedef name (or - template type parameter) for explicit destructor calls. - -Thu Jul 14 09:42:23 1994 Mike Stump <mrs@cygnus.com> - - * Version 2.6.0 released. - -Wed Jul 13 03:57:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (hack_identifier): Put back old code so lists of - non-functions will be handled properly. - - * cp-tree.h (TYPE_NEEDS_CONSTRUCTING): #if 0 out; this macro is now - defined in the language-independent tree.h. - - * tree.c (count_functions): Avoid bogus warning when compiling this - function. - -Mon Jul 11 18:37:20 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_reference_init): Always save the initializer of a - reference. - -Fri Jul 8 17:41:46 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (cplus_expand_expr_stmt): Wrap statement expressions inside - CLEANUP_POINT_EXPRs so that the stack slots can be reused. - (disabled for now) - -Fri Jul 8 12:59:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (hack_identifier): Fix for new overloading. - - * typeck.c (build_binary_op_nodefault): Don't mess with division by - zero. - -Fri Jul 8 13:20:28 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * decl2.c (finish_file): Only call walk_sigtables, if - flag_handle_signatures is turned on, don't waste time otherwise. - -Fri Jul 8 02:27:41 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (push_overloaded_decl): Don't create overloads of one when - shadowing a class type. - * typeck.c (build_x_function_call): Complain about overloads of one. - - * decl.c (grokdeclarator): Don't try to treat a char* as a tree. - (grokdeclarator): Fix setting of TREE_STATIC. - (start_decl): Clear DECL_IN_AGGR_P after calling duplicate_decls. - -Thu Jul 7 22:20:46 1994 Gerald Baumgartner <gb@andros.cygnus.com> - - * cp-tree.h (walk_sigtables): Created extern declaration. - * decl2.c (walk_sigtables): Created function, patterned after - walk_vtables, even though we only need it to write out sigtables. - (finish_sigtable_vardecl): Created function. - (finish_vtable_vardecl): Changed 0 to NULL_PTR. - (finish_file): Call walk_sigtables. - - * sig.c (build_signature_table_constructor): Mark class member - function pointed to from signature table entry as addressable. - -Thu Jul 7 13:39:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_decl): Check new decl of static member variable - against the declaration in the class here. - (grokvardecl): Instead of here. - - * class.c (prepare_fresh_vtable): Call import_export_vtable if not - -fvtable-thunks. - (build_vtable): Likewise. - - * decl2.c (import_export_vtable): Move logic for deciding the - interface of a template class from here. - (import_export_template): To here. - (finish_vtable_vardecl): Call import_export_template before - import_export_vtable. - -Wed Jul 6 20:25:48 1994 Mike Stump <mrs@cygnus.com> - - * except.c (init_exception_processing): Setup interim_eh_hook to - call lang_interim_eh. - * except.c (do_unwind): Propagate throw object value across - stack unwinding. - * except.c (saved_throw_value): Used to hold the value of the object - being thrown. It is always a reference to the real value. - * except.c (expand_start_catch_block): Add handling for the - value of the exception object. - * except.c (expand_start_catch_block): Add handler for the handler, - so that throws inside the handler go to the outer block. - * except.c (expand_end_catch_block): Likewise. - * parse.y (handler_args): Use parm instead, as the other doesn't yet - handle references correctly. - -Wed Jul 6 17:55:32 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl2.c (mark_vtable_entries): If -ftable-thunks, set the - vtable entry properly to abort. - -Tue Jul 5 14:07:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Downgrade division by zero - errors to warnings. - - * call.c (build_overload_call_real): Handle fnname being a list of - functions. - * typeck.c (build_x_function_call): Pass list of functions to - build_overload_call, not just the name. - * tree.c (count_functions): Complain when called for invalid - argument. - - * decl.c (grokdeclarator): Fix settings of TREE_STATIC, TREE_PUBLIC - and DECL_EXTERNAL on static members and initialized const members. - * decl2.c (grokfield): Reflect this change. - -Fri Jul 1 09:35:51 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (init): ANSI C++ does not forbid { }. - -Thu Jun 30 00:35:22 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (lang_decode_option): Set warn_nonvdtor along with -Wall. - warn_nonvdtor defaults to off. - - * class.c (instantiate_type): Use comptypes rather than relying on - types to satisfy ==. - - * decl.c (start_function): Set DECL_DEFER_OUTPUT on all inlines that - might be static. - - * tree.c (build_cplus_new): Never build WITH_CLEANUP_EXPRs. - - * decl.c (grok_reference_init): Deal with ADDR_EXPRs of TARGET_EXPRs. - - * cvt.c (cp_convert): Pass 0 to with_cleanup_p arg of - build_cplus_new. - -Wed Jun 29 22:31:09 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (finish_file): Maybe consider static inlines multiple - times, in case they reference each other. - -Tue Jun 28 11:58:38 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * class.c (finish_struct): Don't `cons_up_default_function's - for signatures. - (finish_struct): Handle an empty method_vec correctly. - - * decl.c (grokdeclarator): Don't warn about a signature being - empty in a signature pointer declaration if we only saw a - forward declaration of the signature. Changed `warning's into - `cp_warning's. - - * sig.c (build_sigtable): Don't die if a null signature table - constructor is returned. - (build_signature_pointer_constructor): If the signature table - constructor is null, the _sptr field is set to a null pointer - and cast to the appropriate type. Make copies of all null - pointers so that the type null_pointer_node doesn't get changed. - (build_signature_table_constructor): Added comments. - - * sig.c (build_signature_pointer_constructor): Complain if we - try to assign to/initialize a signature pointer/reference of - an undefined signature. - -Mon Jun 27 14:05:16 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * typeck2.c (store_init_value): Don't be pedantic about - non-constant initializers of signature tables/pointers/references. - -Fri Jun 24 16:49:41 1994 Gerald Baumgartner <gb@cs.purdue.edu> - - * decl.c (grokdeclarator): If we are grokking an opaque typedef - in a signature, don't complain about it begin static. - -Wed Jun 29 16:44:45 1994 Mike Stump <mrs@cygnus.com> - - Fixes a problem of the this pointer being wrong in virtual calls to - methods that are not overridden in more derived classes. - - * class.c (fixup_vtable_delta): New routine. It will fixup the - delta entries in vtables, wheever they need updating. - * class.c (finish_struct): Call the new routine for all virtual - bases, as they can have different offsets, than those used in base - classes that we derive our vtable from. - -Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_binary_op): Use the types before default - conversions in the error message. - - * *.c: Use c_build_type_variant instead of build_type_variant where - the type might be an array. - - * call.c (build_method_call): Call build_type_variant and - build_reference_type in the right order. - * decl.c (record_builtin_type): Likewise. - -Wed Jun 29 16:58:53 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Call build_type_variant and - build_reference_type in the right order. - * decl.c (record_builtin_type): Likewise. - -Tue Jun 28 23:49:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_binary_op): Use the types before default - conversions in the error message. - - * *.c: Use c_build_type_variant instead of build_type_variant where - the type might be an array. - -Sat Jun 25 11:50:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): Try UDC's before doing the - reinterpret_cast thang, though. - -Fri Jun 24 01:24:01 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (c_expand_return): Don't USE the return value location - after we've expanded the jump. - - * decl2.c (finish_file): Make sure DECL_SAVED_INSNS is not 0 before - trying to write out an inline. - - * cvt.c (build_up_reference): Also do address adjustment when the - target type uses MI. - (convert_to_reference): Try UDCs only after built-in conversions. - (build_type_conversion_1): Don't play games with the argument to the - method. - (build_type_conversion): #if 0 out code for binding to reference. - -Thu Jun 23 00:22:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (finish_file): Use TREE_SYMBOL_REFERENCED to decide - whether to emit inlines. - - * decl.c (grokdeclarator): Set explicit_int for decls that just - specify, say, 'long'. - - * init.c (do_friend): Do overload C functions (or call pushdecl, - anyaway). - -Wed Jun 22 13:40:49 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_up_reference): Don't call readonly_error. - (convert_to_reference): Propagate const and volatile from expr to - its type. - - * tree.c (lvalue_p): Random CALL_EXPRs are not lvalues. - - * cvt.c (build_up_reference): Break out WITH_CLEANUP_EXPR when - creating a temporary. - (convert_to_reference): Lose excessive and incorrect trickiness. - (cp_convert): Call build_cplus_new with with_cleanup_p set. - - * typeck2.c (build_functional_cast): Likewise. - -Tue Jun 21 17:38:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): signed, unsigned, long and short all - imply 'int'. - - * decl.c (grokdeclarator): Allow "this is a type" syntax. - (grok_reference_init): Simplify and fix. - -Sun Jun 19 17:08:48 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): pedwarn about a typedef that specifies no - type. - -Sat Jun 18 04:16:50 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_function): Move TREE_PUBLIC and DECL_EXTERNAL - tinkering to after call to pushdecl. - -Fri Jun 17 14:48:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Handle destructors for non-aggregate - types properly. - -Thu Jun 16 16:48:05 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Make sure that the name given for the - destructor matches the constructor_name of the instance. - - * pt.c (do_function_instantiation): A non-extern instantiation - overrides a later extern one. - (do_type_instantiation): Likewise. - -Wed Jun 15 19:34:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (expand_aggr_init): Use TYPE_MAIN_VARIANT to get the - unqualified array type. - - * cp-tree.h (EMPTY_CONSTRUCTOR_P): Tests whether NODE is a - CONSTRUCTOR with no elements. - - * decl.c (various): Lose empty_init_node. - (finish_decl): Use EMPTY_CONSTRUCTOR_P, do the empty CONSTRUCTOR - thing depending on the value of DECL_COMMON instead of - flag_conserve_space, do the empty CONSTRUCTOR thing for types that - don't have constructors, don't treat a real empty CONSTRUCTOR - specially. - - * typeck2.c (process_init_constructor): Don't treat empty_init_node - specially. - -Wed Jun 15 19:05:25 1994 Mike Stump <mrs@cygnus.com> - - * class.c (override_one_vtable): Don't forget to merge in an old - overrider when we wanted to reuse a vtable, but couldn't. - -Wed Jun 15 15:03:16 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_decl): Put statics in common again. - - * decl.c (grokdeclarator): Return NULL_TREE for an error rather than - setting the type to error_mark_node. - - * typeck.c (build_modify_expr): Build up a COMPOUND_EXPR for enum - bitfield assignments. - -Tue Jun 14 12:23:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_op_properties): Const objects can be passed by value. - -Mon Jun 13 03:10:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (import_export_vtable): Force implicit instantiations to - be interface_only when -fno-implicit-templates. - - * decl.c (duplicate_decls): Redeclaring a class template name is an - error. - - * pt.c (end_template_decl): Call GNU_xref_decl for class templates. - * xref.c (GNU_xref_decl): Support templates. - -Sat Jun 11 17:09:05 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_op_properties): Split out checking for whether this - function should suppress the default assignment operator. - * decl2.c (grok_function_init): Likewise. - (copy_assignment_arg_p): New function to do just that. - Now considers virtual assignment operators that take a base as an - argument to count as copy assignment operators. - - * search.c (dfs_debug_mark): Lose checks for DWARF_DEBUG and - TREE_ASM_WRITTEN, as they are redundant. - - * pt.c (end_template_decl): Don't try to set DECL_CLASS_CONTEXT on a - decl that has no LANG_SPECIFIC part. - (do_type_instantiation): Force the debugging information for this - type to be emitted. - - * decl.c (start_decl): Clear up uses of various types of templates - (say sorry for static data members, rather than "invalid template"). - (expand_static_init): Fix initialization of static data members of - template classes. - -Fri Jun 10 00:41:19 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Set DECL_CONTEXT on static data members. - - * g++.c (main): Use -xc++-cpp-output for .i files. - - * pt.c (tsubst): Give meaningful error about declaring template for - a copy constructor which was not declared in the class template. - (do_type_instantiation): Explicit instantiation before the class - template is an error. - (instantiate_template): Don't die if tsubst returns error_mark_node. - -Thu Jun 9 19:04:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - Don't synthesize the copy assignment operator if the one in a base - class is pure virtual. - * cp-tree.h (TYPE_HAS_ABSTRACT_ASSIGN_REF): New macro to indicate - whether the type has a pure virtual copy assignment operator. - * class.c (finish_base_struct): Don't generate the copy assignment - operator if a base class has a pure virtual one. - * decl.c (grok_op_properties): Add disabled code to set - TYPE_HAS_ABSTRACT_ASSIGN_REF with comment pointing to where it is - actually set. - * decl2.c (grok_function_init): Set TYPE_HAS_ABSTRACT_ASSIGN_REF. - - * decl2.c (import_export_vtable): Always treat template - instantiations as if write_virtuals >= 2, and treat implicit - instantiations as external if -fno-implicit-templates. - (finish_file): Output all pending inlines if - flag_keep_inline_functions. - -Wed Jun 8 20:48:02 1994 Mike Stump <mrs@cygnus.com> - - * tree.c (layout_vbasetypes): Align virtual base classes inside - complete objects, so that we don't core dump on machines such as - SPARCs when we access members that require larger than normal - alignments, such as a double. Also, we bump up the total alignment - on the complete type, as necessary. - -Wed Jun 8 16:18:14 1994 Jason Merrill <jason@deneb.cygnus.com> - - * gxxint.texi (Free Store): New section with code for examining - cookie. - (Limitations of g++): Remove operator delete entry, since it is no - longer accurate. Fix access control entry. - - * typeck.c (build_unary_op): Pedwarn about taking the address of or - incrementing a cast to non-reference type. - (build_modify_expr): Use convert instead of convert_force again. - - * search.c (get_base_distance): Use IS_AGGR_TYPE_CODE to check for - class type, not == RECORD_TYPE. - - * decl.c (grokdeclarator): Cope with grokfndecl returning NULL_TREE. - - * typeck2.c (report_case_error): #if 0 out. - * lex.c (real_yylex): Lose RANGE. - * parse.y: Likewise. - -Tue Jun 7 18:17:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (simple_stmt, case ranges): Use ELLIPSIS instead of RANGE. - -Mon Jun 6 19:39:57 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_c_cast): Don't shortcut conversions to the same - type. Don't replace consts with their values here, since that's now - done in cp_convert. - - * cvt.c (cp_convert): When converting to bool, take - integer_zero_node to false_node and all other INTEGER_CSTs to - true_node. - (build_type_conversion): Don't complain about multiple conversions - to float if we're not really converting. - -Fri Jun 3 02:10:56 1994 Jason Merrill <jason@deneb.cygnus.com> - - Implement 'extern template class A<int>;' syntax for suppressing - specific implicit instantiations. - * cp-tree.h: Update prototypes for do_*_instantiation. - * pt.c (do_pending_expansions): Don't compile 'extern' explicit - instantiations. - (do_function_instantiation): Set DECL_EXTERNAL on 'extern' explicit - instantiations. - (do_type_instantiation): Likewise. - * parse.y (explicit_instantiation): Support 'extern template class - A<int>;' syntax. - * decl.c (start_function): Don't modify the settings of TREE_PUBLIC - and DECL_EXTERNAL on explicit instantiations. - - * cvt.c (cp_convert): Replace constants with their values before - converting. - (cp_convert): Consistently use 'e' instead of 'expr'. - -Thu Jun 2 03:53:30 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck2.c (build_x_arrow): Resolve OFFSET_REFs first. - -Wed Jun 1 18:57:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck2.c (digest_init): Handle initializing a pmf with an - overloaded method. - * typeck.c (build_ptrmemfunc): Handle overloaded methods. - - * decl.c (pushtag): Use build_decl to make TYPE_DECLs. - (xref_defn_tag): Likewise. - * pt.c (process_template_parm): Likewise. - (lookup_template_class): Likewise. - (push_template_decls): Likewise. - (instantiate_class_template): Likewise. - (create_nested_upt): Likewise. - * class.c (finish_struct): Don't try to set DECL_CLASS_CONTEXT on - TYPE_DECLs. - - * typeck.c (convert_arguments): Make sure type is not NULL before - checking its TREE_CODE. - -Wed Jun 1 17:40:39 1994 Mike Stump <mrs@cygnus.com> - - * class.c (get_derived_offset): New routine. - * class.c (finish_base_struct): Make sure we set BINFO_VTABLE and - BINFO_VIRTUALS when we choose a new base class to inherit from. - * class.c (modify_one_vtable): Use get_derived_offset to get the - offset to the most base class subobject that we derived this binfo - from. - * class.c (finish_struct): Move code to calculate the - DECL_FIELD_BITPOS of the vfield up, as we need might need it for - new calls to get_derived_offset in modify_one_vtable. - -Wed Jun 1 16:50:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_member_call): Use build_pointer_type instead of - TYPE_POINTER_TO. - -Wed Jun 1 11:11:15 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (grokdeclarator): Make sure we have a DNAME set before we - try to use it in an error. - -Wed Jun 1 09:48:49 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (convert_arguments, convert_for_initialization): Don't - strip NOP_EXPRs, when we are converting to a reference. - -Wed Jun 1 01:11:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_modify_expr): Don't dereference references when - initializing them. - - * decl2.c (grokfield): Don't check for grokdeclarator returning - error_mark_node any more. - - * decl.c (grokfndecl): Return NULL_TREE instead of error_mark_node. - (start_method): Return void_type_node instead of error_mark_node. - - * typeck.c (build_modify_expr): Resolve offset refs earlier. - -Tue May 31 16:06:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Resolve OFFSET_REFs in the object. - - * typeck.c (build_modify_expr): Dereference references before trying - to assign to them. - - * call.c (build_method_call): Don't confuse type conversion - operators with constructors. - * typeck2.c (build_functional_cast): Just call build_c_cast if there - was only one parameter. - * method.c (build_typename_overload): Don't set - IDENTIFIER_GLOBAL_VALUE on these identifiers. - * decl.c (grok_op_properties): Warn about defining a type conversion - operator that converts to a base class (or reference to it). - * cvt.c (cp_convert): Don't try to use a type conversion operator - when converting to a base class. - (build_type_conversion_1): Don't call constructor_name_full on an - identifier. - * cp-tree.h (DERIVED_FROM_P): Should be self-explanatory. - - * decl.c (start_decl): Don't complain that error_mark_node is an - incomplete type. - (finish_decl): Check for type == error_mark_node. - -Mon May 30 23:38:55 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_function): Set DECL_DEFER_OUTPUT on implicit - instantiations and inline members. - - * spew.c (yylex): Set looking_for_template if the next token is a '<'. - - * lex.h: Declare looking_for_template. - - * decl.c (lookup_name_real): Use looking_for_template to arbitrate - between type and template interpretations of an identifier. - -Sat May 28 04:07:40 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (instantiate_template): Zero out p if we found a - specialization. - - * decl.c (grokdeclarator): Elucidate warning. - (grokdeclarator): If pedantic AND -ansi, complain about long long. - - Make explicit instantiation work reasonably. It is now appropriate - to deprecate the use of -fexternal-templates. - * pt.c (instantiate_template): Set DECL_TEMPLATE_SPECIALIZATION or - DECL_IMPLICIT_INSTANTIATION on fndecl as appropriate. - (end_template_instantiation): Reflect changes in USE_TEMPLATE - semantics. - (do_pending_expansions): if (!flag_implicit_templates) DECIDE(0); - (do_function_instantiation): Don't set EXPLICIT_INST if - flag_external_templates is set. Do set TREE_PUBLIC and DECL_EXTERN - appropriately otherwise. - (do_type_instantiation): Set interface info for class. Set - TREE_PUBLIC and DECL_EXTERN for methods. Do none of this if - flag_external_templates is set. - * parse.y: Reflect changes in USE_TEMPLATE semantics. - * decl2.c: New flag flag_implicit_templates determines whether or - not implicit instantiations get emitted. This flag currently - defaults to true, and must be true for -fexternal-templates to work. - (finish_file): Consider flag_implement_inlines when - setting DECL_EXTERNAL. Consider flag_implicit_templates when - deciding whether or not to emit a static copy. - * decl.c (start_function): Set TREE_PUBLIC and DECL_EXTERNAL - properly for template instantiations. - (start_method): Set DECL_IMPLICIT_INSTANTIATION on methods of a - template class. - * cp-tree.h (CLASSTYPE_USE_TEMPLATE): Change semantics. - (DECL_USE_TEMPLATE): Parallel macro for FUNCTION and VAR_DECLs. - (various others): Accessor macros for the above. - -Fri May 27 13:57:40 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Division by constant zero is - an error. - -Fri May 27 13:50:15 1994 Mike Stump <mrs@cygnus.com> - - * class.c (override_one_vtable): Don't modify things we don't own. - -Fri May 27 01:42:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (finish_decl): Don't postpone processing the initializer of - a decl with DECL_EXTERNAL set, and do call rest_of_compilation for a - PUBLIC const at toplevel. - (grokdeclarator): pedwarn about initializing non-const or - non-integral statics in the class body. - - * decl.c (pushtag): Don't try to set DECL_CLASS_CONTEXT on a - TYPE_DECL. - - * call.c (convert_harshness): Dereference reference on rhs before - proceeding, properly grok passing const things to non-const - references. - - * typeck.c (build_unary_op): Soften error about taking the address - of main() to a pedwarn. - - * lex.c (default_copy_constructor_body): Unambiguously specify base - classes (i.e. A((const class ::A&)_ctor_arg) ). - (default_assign_ref_body): Likewise. - -Thu May 26 13:13:55 1994 Gerald Baumgartner <gb@mexican.cygnus.com> - - * decl2.c (grokfield): Don't complain about local signature - method declaration without definition. - - * call.c (convert_harshness): If `type' is a signature pointer - and `parmtype' is a pointer to a signature, just return 0. We - don't really convert in this case; it's a result of making the - `this' parameter of a signature method a signature pointer. - - * call.c (build_method_call): Distinguish calling the default copy - constructor of a signature pointer/reference from a signature - member function call. - -Thu May 26 12:56:25 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (grokfield): Don't set TREE_PUBLIC on member function - declarations. - - * decl.c (duplicate_decls): A previous function declaration as - static overrides a subsequent non-static definition. - (grokdeclarator): Don't set TREE_PUBLIC on inline method - declarations. - -Wed May 25 14:36:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Handle initialization of static const - members. - (finish_decl): Likewise. - - * decl2.c (grokfield): Allow initialization of static const members - even when pedantic. - - * decl2.c (grokfield): Deal with grokdeclarator returning - error_mark_node. - - * decl.c (grok_ctor_properties): Return 0 for A(A) constructor. - (grokfndecl): Check the return value of grok_ctor_properties. - (start_method): Likewise. - - * parse.y (absdcl): Expand type_quals inline. - -Tue May 24 19:10:32 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (pushtag): Use IS_AGGR_TYPE rather than checking for a - RECORD_TYPE. - -Tue May 24 18:09:16 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks, - always use "__vt_%s". - * decl2.c (finish_vtable_vardecl): Don't consider abstract virtuals - when looking for a "sentinal" method (to decide on emitting vtables). - * decl2.c (finish_file): Scan all decls for thunks that need - to be emitted. - * decl2.c (finish_vtable_vardecl): Don't bother calling emit_thunk. - * method.c (make_thunk): Use a more meaningful label. If there - exists a matching top-level THUNK_DECL re-use it; otherwise - create a new THUNK_DECL (and declare it). - * method.c (emit_thunk): Make thunk external/public depending - on the underlying method. - -Tue May 24 00:22:04 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (tsubst): Use lookup_name_nonclass to find guiding decls, not - lookup_name. - - * call.c (build_overload_call_real): Don't immediately pick a - function which matches perfectly. - - * decl.c (grokdeclarator): Use c_build_type_variant for arrays. - (grokdeclarator): Warn about, and throw away, cv-quals attached to a - reference (like 'int &const j'). - - * typeck.c (convert_arguments): Don't mess with i for methods. - * call.c (build_method_call): Pass the function decl to - convert_arguments. - - * typeck.c (comp_ptr_ttypes_real): New function. Implements the - checking for which multi-level pointer conversions are allowed. - (comp_target_types): Call it. - (convert_for_assignment): Check const parity on the ultimate target - type, too. And make those warnings pedwarns. - -Mon May 23 14:11:24 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_char): Use TARGET_* for character constants. - -Mon May 23 13:03:03 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * tree.c (debug_no_list_hash): Make static. - - * decl.c (decls_match): Say the types don't match if newdecl ends up - with a null type, after we've checked if olddecl does. - (pushdecl): Check if the decls themselves match before looking for - an extern redeclared as static, to avoid inappropriate and incorrect - warnings. - -Fri May 20 14:04:34 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Make warning about duplicate short, etc. - a pedwarn. - - * typeck.c (build_c_cast): Casting to function or method type is an - error. - - * class.c (finish_struct): Make warning for anonymous class with no - instances a pedwarn. - - * Makefile.in (stamp-parse): Expect a s/r conflict. - - * typeck.c (build_modify_expr): pedwarn about using a non-lvalue - cast as an lvalue. - -Thu May 19 12:08:48 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (type_promotes_to): Make sure bool promotes to int rather - than unsigned on platforms where sizeof(char)==sizeof(int). - -Wed May 18 14:27:06 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_c_cast): Tack on a NOP_EXPR when casting to - another variant. - (build_modify_expr): Don't strip NOP_EXPRs, and don't get tricky - and treat them as lvalues. - - * decl.c (shadow_tag): Do complain about forward declarations of - enums and empty declarations. - * parse.y: Don't complain about forward declarations of enums and - empty declarations. - - * typeck.c (convert_for_assignment): Complain about changing - the signedness of a pointer's target type. - - * parse.y (stmt): Move duplicated code for checking case values from - here. - * decl2.c (check_cp_case_value): To here. And add a call to - constant_expression_warning. - - * typeck.c (convert_for_assignment): Don't complain about assigning - a negative value to bool. - - * decl.c (init_decl_processing): Make bool unsigned. - - * class.c (finish_struct): Allow bool bitfields. - -Wed May 18 12:35:27 1994 Ian Lance Taylor <ian@tweedledumb.cygnus.com> - - * Make-lang.in (c++.install-man): Get g++.1 from $(srcdir)/cp. - -Wed May 18 03:28:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_type_conversion): Lose special handling of - truthvalues. - - * search.c (dfs_pushdecls): Improve shadowing warning. - -Tue May 17 13:34:46 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_delete): Throw away const and volatile on `this'. - - * decl.c (finish_enum): Put the constants in TYPE_VALUES again, - rather than the enumerators. - (pushtag): s/cdecl/c_decl/g - -Mon May 16 23:04:01 1994 Stephen R. van den Berg <berg@pool.informatik.rwth-aachen.de> - - * cp/typeck.c (common_type): Attribute merging. - (comp_types): Utilise COMP_TYPE_ATTRIBUTES macro. - - * cp/parse.y: Revamp attribute parsing. - -Mon May 16 01:40:34 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (shadow_tag): Also check for inappropriate use of auto and - register. - - * method.c (build_overload_name): Clarify that the illegal case is a - pointer or reference to array of unknown bound. - - * error.c (dump_type_prefix): Print references to arrays properly. - - * typeck.c (various): Be more helpful in pointer - comparison diagnostics. - - * tree.c (lvalue_p): MODIFY_EXPRs are lvalues again. Isn't this - fun? - - * parse.y: Also catch an error after valid stmts. - - * search.c (dfs_init_vbase_pointers): Don't abort because `this' is - const. - - * typeck.c (convert_for_initialization): If call to - convert_to_reference generated a diagnostic, print out the parm - number and function decl if any. - - * errfn.c (cp_thing): Check atarg1 to determine whether or not we're - specifying a line, not atarg. - - * tree.c (build_cplus_method_type): Always make `this' const. - - * decl2.c (grokclassfn): If -fthis-is-variable and this function is - a constructor or destructor, make `this' non-const. - - * typeck.c (build_modify_expr): Don't warn specially about - assignment to `this' here anymore, since it will be caught by the - usual machinery. - - * various: Disallow specific GNU extensions (variable-size arrays, - etc.) when flag_ansi is set, not necessarily when pedantic is set, - so that people can compile with -pedantic-errors for tighter const - checking and such without losing desirable extensions. - - * typeck2.c (build_functional_cast): Call build_method_call with - LOOKUP_PROTECT. - (process_init_constructor): Only process FIELD_DECLs. - - * decl.c (finish_decl): Also force static consts with no explicit - initializer that need constructing into the data segment. - - * init.c (build_delete): Undo last patch, as it interferes with - automatic cleanups. - -Sat May 14 01:59:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c, class.h, cp-tree.h, cvt.c, decl2.c: Lose old overloading - code. - - * init.c (build_delete): pedwarn about using plain delete to delete - an array. - -Fri May 13 16:45:07 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (comp_target_types): Be more helpful in contravariance - warnings, and make them pedwarns. - - * decl.c (grokdeclarator): Use decl_context to decide whether or not - this is an access declaration. - - * class.c (finish_struct_bits): Set TYPE_HAS_INT_CONVERSION if it - has a conversion to enum or bool, too. - -Fri May 13 16:31:27 1994 Mike Stump <mrs@cygnus.com> - - * method.c (emit_thunk): Make declaration for - current_call_is_indirect local (needed for hppa). - -Fri May 13 16:16:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (uses_template_parms): Grok BOOLEAN_TYPE. - (tsubst): Likewise. - -Fri May 13 16:23:32 1994 Mike Stump <mrs@cygnus.com> - - * pt.c (tsubst): If there is already a function for this expansion, - use it. - * pt.c (instantiate_template): Likewise. - -Fri May 13 10:30:42 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * parse.y (implicitly_scoped_stmt, simple_stmt case): Use - kept_level_p for MARK_ENDS argument to expand_end_bindings, to avoid - generating debug info for unemitted symbols on some systems. - - * cp-tree.h (build_static_cast, build_reinterpret_cast, - build_const_cast): Add declarations. - -Fri May 13 09:50:31 1994 Mike Stump <mrs@cygnus.com> - - * search.c (expand_indirect_vtbls_init): Fix breakage from Apr 27 - fix. We now try get_binfo, and if that doesn't find what we want, - we go back to the old method, which still sometimes fails. - -Fri May 13 01:43:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (initdcl): Call cplus_decl_attributes on the right - variable. - * decl2.c (cplus_decl_attributes): Don't call decl_attributes for - void_type_node. - - * typeck.c (build_binary_op_nodefault): Change result_type for - comparison ops to bool. - (build_binary_op): Convert args of && and || to bool. - * cvt.c (build_default_binary_type_conversion): Convert args of && - and || to bool. - (build_default_unary_type_conversion): Convert arg of ! to bool. - (type_promotes_to): bool promotes to int. - -Fri May 13 01:43:18 1994 Mike Stump <mrs@cygnus.com> - - Implement the new builtin `bool' type. - * typeck.c (build_binary_op_nodefault): Convert args of && and || to - bool. - (build_unary_op): Convert arg of ! to bool. - * parse.y: Know true and false. Use bool_truthvalue_conversion. - * method.c (build_overload_value): Know bool. - (build_overload_name): Likewise. - * lex.c (init_lex): Set up RID_BOOL. - * gxx.gperf: Add bool, true, false. - * error.c (*): Know bool. - * decl.c (init_decl_processing): Set up bool, true, false. - * cvt.c (cp_convert): Handle conversion to bool. - (build_type_conversion): Likewise. - * *.c: Accept bool where integers and enums are accepted (use - INTEGRAL_CODE_P macro). - -Thu May 12 19:13:54 1994 Richard Earnshaw <rwe11@cl.cam.ac.uk> - - * g++.c: Use #ifdef for __MSDOS__, not #if. - -Thu May 12 18:05:18 1994 Mike Stump <mrs@cygnus.com> - - * decl2.c (lang_f_options): Handle -fshort-temps. -fshort-temps - gives old behavior , and destroys temporaries earlier. Default - behavior now conforms to the ANSI working paper. - -Thu May 12 14:45:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_modify_expr): Understand MODIFY_EXPR as an lvalue. - Use convert_force to convert the result of a recursive call when we - are dealing with a NOP_EXPR. Don't automatically wrap MODIFY_EXPRs - in COMPOUND_EXPRs any more. - (various): Lose pedantic_lvalue_warning. - (unary_complex_lvalue): Understand MODIFY_EXPR. - - * cvt.c (convert_to_reference): Allow DECL to be error_mark_node if - we don't know what we're initializing. - -Wed May 11 01:59:36 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): Modify to use convtype parameter. - Only create temporaries when initializing a reference, not when - casting. - (cp_convert): New main function. - (convert): Call cp_convert. - * cvt.c, decl.c, typeck.c: Fix calls to convert_to_reference. - * cp-tree.h (CONV_*): New constants used by conversion code for - selecting conversions to perform. - - * tree.c (lvalue_p): MODIFY_EXPRs are no longer lvalues. - - * typeck.c (build_{static,reinterpret,const_cast): Stubs that just - call build_c_cast. - * parse.y: Add {static,reinterpret,const}_cast. - * gxx.gperf: Likewise. - - * typeck.c (common_type): Allow methods with basetypes of different - UPTs. - (comptypes): Deal with UPTs. - (build_modify_expr): Wrap all MODIFY_EXPRs in a COMPOUND_EXPR. - - * pt.c (end_template_decl): Check for multiple definitions of member - templates. - - * call.c (build_method_call): Complain about calling an abstract - virtual from a constructor. - - * typeck.c (pointer_int_sum): Check for the integer operand being 0 - after checking the validity of the pointer operand. - - * typeck2.c (digest_init): Pedwarn about string initializer being - too long. - -Tue May 10 12:10:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (push_overloaded_decl): Only throw away a builtin if the - decl in question is the artificial one. - - * parse.y (simple_stmt, switch): Use implicitly_scoped_stmt because - expand_{start,end}_case cannot happen in the middle of a block. - - * cvt.c (build_type_conversion_1): Use convert again. - -Tue May 10 11:52:04 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck2.c (digest_init): Make sure we check for signed and - unsigned chars as well when warning about string initializers. - - * init.c (emit_base_init): Check if there's a DECL_NAME on the - member before trying to do an initialization for it. - -Tue May 10 11:34:37 1994 Mike Stump <mrs@cygnus.com> - - * except.c: Don't do anything useful when cross compiling. - -Tue May 10 03:04:13 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (duplicate_decls): Fix up handling of builtins yet again. - (push_overloaded_decl): Likewise. - - * cvt.c (convert): Don't look for void type conversion. - -Mon May 9 18:05:41 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (do_friend): Only do a pushdecl for friends, not - pushdecl_top_level. - -Mon May 9 13:36:34 1994 Jim Wilson <wilson@sphagnum.cygnus.com> - - * decl.c (lookup_name_current_level): Put empty statement after - the label OUT to make the code valid C. - -Mon May 9 12:20:57 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_binary_op_nodefault): Only complain about - comparing void * and a function pointer if void * is smaller. - -Sun May 8 01:29:13 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (lookup_name_current_level): Move through temporary binding - levels. - - * parse.y (already_scoped_stmt): Revive. - (simple_stmt): Use it again. - - * decl.c (poplevel): Always call poplevel recursively if we're - dealing with a temporary binding level. - -Sat May 7 10:52:28 1994 Mike Stump <mrs@cygnus.com> - - * decl.c (finish_decl): Make sure we run cleanups for initial values - of decls. Cures memory leak. - * decl.c (expand_static_init): Likewise for static variables. - * decl2.c (finish_file): Likewise for globals. - -Sat May 7 03:57:44 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (commonparms): Don't complain about redefining default - args. - - * decl.c (duplicate_decls): Don't complain twice about conflicting - function decls. - (decls_match): Don't look at default args. - (redeclaration_error_message): Complain about redefining default - args. - - * call.c (build_overload_call_real): Also deal with guiding - declarations coming BEFORE the template decl. - - * pt.c (unify): Allow different parms to have different - cv-qualifiers. - (unify): Allow trivial conversions on non-template parms. - -Fri May 6 03:53:23 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (tsubst): Support OFFSET_TYPEs. - (unify): Likewise. - - * decl2.c (finish_decl_parsing): Call push_nested_class with a type. - - * init.c (build_offset_ref): Fix error message. - * search.c (lookup_field): Likewise. - - * call.c (build_scoped_method_call): Pass binfo to - build_method_call. - * typeck.c (build_object_ref): Likewise. - - * typeck2.c (binfo_or_else): Don't return a _TYPE. - - * class.c (finish_struct): Don't complain about re-use of inherited - names or shadowing of type decls. - * decl.c (pushdecl_class_level): Likewise. - - * decl.c (finish_enum): Set the type of all the enums. - - * class.c (finish_struct): Don't get confused by access decls. - - * cp-tree.h (TYPE_MAIN_DECL): New macro to get the _DECL for a - _TYPE. You can stop using TYPE_NAME for that now. - - * parse.y: Lose doing_explicit (check $0 instead). - * gxx.gperf: 'template' now has a RID. - * lex.h (rid): Likewise. - * lex.c (init_lex): Set up the RID for 'template'. - - * parse.y (type_specifier_seq): typed_typespecs or - nonempty_type_quals. Use it. - (handler_args): Fix bogus syntax. - (raise_identifier{,s}, optional_identifier): Lose. - * except.c (expand_start_catch_block): Use grokdeclarator to parse - the catch variable. - (init_exception_processing): The second argument to - __throw_type_match is ptr_type_node. - - Fri May 6 07:18:54 1994 Chip Salzenberg <chip@fin.uucp> - - [ change propagated from c-decl.c of snapshot 940429 ] - * cp/decl.c (finish_decl): Setting asmspec_tree should not - zero out the old RTL. - -Fri May 6 01:25:38 1994 Mike Stump <mrs@cygnus.com> - - Add alpha exception handling support to the compiler. - Quick and dirty backend in except.c. - - * cp/*: Remove most remnants of old exception handling support. - * decl.c (finish_function): Call expand_exception_blocks to put - the exception hanlding blocks at the end of the function. - * dec.c (hack_incomplete_structures): Make sure expand_decl_cleanup - comes after expand_decl_init. - * except.c: Reimplementation. - * expr.c (cplus_expand_expr): Handle THROW_EXPRs. - * lex.c (init_lex): Always have catch, try and throw be reserved - words, so that we may always parse exception handling. - * parse.y: Cleanup to support new interface into exception handling. - * tree.def (THROW_EXPR): Add. - -Thu May 5 17:35:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (simple_stmt, for loops): Use implicitly_scoped_stmt. - (various): Lose .kindof_pushlevel and partially_scoped_stmt. - -Thu May 5 16:17:27 1994 Kung Hsu <kung@mexican.cygnus.com> - - * parse.y (already_scoped_stmt): move expand_end_binding() to - fix the unmatched LBB/LBE in stabs. - -Thu May 5 14:36:17 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (set_nested_typename): Set TREE_MANGLED on the new - identifiers. - (pushdecl): Check TREE_MANGLED. - (xref_tag): Likewise. - * cp-tree.h (TREE_MANGLED): This identifier is a - DECL_NESTED_TYPENAME (named to allow for future use to denote - mangled function names as well). - - Implement inconsistency checking specified in [class.scope0]. - * decl.c (lookup_name_real): Don't set ICV here after all. - (finish_enum): Also set the type of the enumerators themselves. - (build_enumerator): Put the CONST_DECL in the list instead of its - initial value. - (pushdecl_class_level): Check inconsistent use of a name in the - class body. - * class.c (finish_struct): Check inconsistent use of a name in the - class body. Don't set DECL_CONTEXT on types here anymore. - * parse.y (qualified_type_name): Note that the identifier has now - been used (as a type) in the class body. - * lex.c (do_identifier): Note that the identifier has now been used - (as a constant) in the class body. - * error.c (dump_decl): Print type and enum decls better. - -Thu May 5 09:35:35 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * typeck.c (build_modify_expr): Warn about assignment to `this'. - -Wed May 4 15:55:49 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_delete): Use the global operator delete when - requested. - - * decl.c (lookup_name_real): If we find the type we're looking in a - base class while defining a class, set IDENTIFIER_CLASS_VALUE for - the type. - - * class.c (finish_struct): Remove a couple of dependencies on - language linkage. - - * decl.c (pushtag): Classes do nest in extern "C" blocks. - (pushdecl): Only set DECL_NESTED_TYPENAME on the canonical one for - the type. - (pushtag): Remove another dependency on the language linkage. - - * lex.c (cons_up_default_function): Don't set DECL_CLASS_CONTEXT to - a const-qualified type. - - * decl.c (push_overloaded_decl): Throw away built-in decls here. - (duplicate_decls): Instead of here. - -Wed May 4 15:27:40 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * typeck.c (get_member_function_from_ptrfunc): Do The Right - Thing (I hope) if we're using thunks. - -Wed May 4 13:52:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (specialization): aggr template_type_name ';'. - (named_class_head_sans_basetype): Use it. - (explicit_instantiation): Likewise. - (tmpl.2): Revert. - - * cvt.c (build_type_conversion_1): Use convert_for_initialization, - rather than convert, to do conversions after the UDC. - - * cp-tree.h (SHARED_MEMBER_P): This member is shared between all - instances of the class. - - * search.c (lookup_field): If the entity found by two routes is the - same, it's not ambiguous. - -Wed May 4 12:10:00 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (lookup_name_real): Check for a NULL TREE_VALUE, - to prevent the compiler from crashing ... - -Wed May 4 11:19:45 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): If we don't have an object, check - basetype_path to figure out where to look up the function. - - * typeck.c (convert_for_initialization): Pass TYPE_BINFO (type) to - build_method_call in case exp is NULL_TREE. - -Tue May 3 16:02:53 1994 Per Bothner <bothner@kalessin.cygnus.com> - - Give a vtable entries a unique named type, for the sake of gdb. - * class.c (build_vtable_entry): The addres of a thunk now has - type vtable_entry_type, not ptr_type_node. - * method.c (make_thunk): Fix type of THUNK_DECL. - * class.c (add_virtual_function, override_one_vtable): Use - vfunc_ptr_type_node, instead of ptr_type_node. - * cp-tree.h (vfunc_ptr_type_node): New macro. - * decl.c (init_decl_processing): Make vtable_entry_type - be a unique type of pointer to a unique function type. - -Tue May 3 09:20:44 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (do_explicit): Sets doing_explicit to 1. - (explicit_instantiation): Use do_explicit rather than TEMPLATE - directly, add "do_explicit error" rule. - (datadef): Set doing_explicit to 0 after an explicit instantiation. - (tmpl.2): Don't instantiate if we see a ';' unless we're doing an - explicit instantiation. - (named_class_head_sans_basetype): Remove aggr template_type_name - ';' again. - -Mon May 2 23:17:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (lookup_nested_tag): Lose. - - * decl2.c (grokfield): Set DECL_CONTEXT on TYPE_DECLs. - (lookup_name_nonclass): Lose. - - * decl.c (poplevel_class): Add force parameter. - (lookup_name_real): Fix handling of explicit scoping which specifies - a class currently being defined. Add 'nonclass' argument. - (lookup_name, lookup_name_nonclass): Shells for lookup_name_real. - - * class.c (finish_struct): Don't unset IDENTIFIER_CLASS_VALUEs here. - (popclass): Force clearing of IDENTIFIER_CLASS_VALUEs if we're being - called from finish_struct. - -Mon May 2 19:06:21 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (init_decl_processing), cp-tree.h: Removed memptr_type. - (It seeems redundant, given build_ptrmemfunc_type.) - * typeck.c (get_member_function_from_ptrfunc), gc.c (build_headof, - build_classof): Use vtable_entry_type instead of memptr_type. - * method.c (emit_thunk): Call poplevel with functionbody==0 - to prevent DECL_INITIAL being set to a BLOCK. - -Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (named_class_head_sans_basetype): Add "aggr - template_type_name ';'" rule for forward declaration of - specializations. - -Mon May 2 15:02:11 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (instantiate_type): Deal with pmf's. - - * Make-lang.in (cc1plus): Don't depend on OBJS or BC_OBJS, since - stamp-objlist does. - - * Makefile.in (../cc1plus): Depend on OBJDEPS. - (OBJDEPS): Dependency version of OBJS. - -Mon May 2 12:51:31 1994 Kung Hsu <kung@mexican.cygnus.com> - - * search.c (dfs_debug_mark): unmark TYPE_DECL_SUPPRESS_DEBUG, not - DECL_IGNORED_P. - -Fri Apr 29 12:29:56 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Clear out memory of local tags. And - typedefs. - - * decl2.c (grokclassfn): Don't set DECL_CONTEXT to a cv-qualified - type. - * search.c (get_matching_virtual): Be more helpful in error message. - - * *: Use DECL_ARTIFICIAL (renamed from DECL_SYNTHESIZED). - - * lex.c (default_assign_ref_body): Expect TYPE_NESTED_NAME to work. - (default_copy_constructor_body): Likewise. - - * class.c (finish_struct): Don't gratuitously create multiple decls - for nested classes. - -Thu Apr 28 23:39:38 1994 Jason Merrill <jason@deneb.cygnus.com> - - Avoid clobbering the arg types of other functions when reverting - static member functions. - * decl.c (revert_static_member_fn): Rearrange arguments, don't - require values for 'fn' and 'argtypes', add warning to comment - above. - (decls_match): Rearrange arguments in call to rsmf. - (grok_op_properties): Don't pass values for fn and argtypes. - * pt.c (instantiate_template): Don't pass values for fn and argtypes. - -Thu Apr 28 16:29:11 1994 Doug Evans <dje@canuck.cygnus.com> - - * Make-lang.in (cc1plus): Depend on stamp-objlist. - * Makefile.in (BC_OBJS): Delete. - (OBJS): Cat ../stamp-objlist to get language independent files. - Include ../c-common.o. - (../cc1plus): Delete reference to BC_OBJS. - -Thu Apr 28 02:12:08 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (compute_access): No really, deal with static members - properly. Would I lie to you? - - Implement lexical hiding of function declarations. - * pt.c (tsubst): Use lookup_name to look for function decls to guide - instantiation. - * method.c (build_opfncall): Use lookup_name_nonclass to look for - non-member functions. - * init.c (do_friend): Use lookup_name_nonclass to look for - functions. - * error.c (ident_fndecl): Use lookup_name to look for functions. - * decl2.c (lookup_name_nonclass): New function, skips over - CLASS_VALUE. - * decl.c (struct binding_level): Lose overloads_shadowed field. - (poplevel): Don't deal with overloads_shadowed. - (push_overloaded_decl): Do lexical hiding for functions. - * class.c (instantiate_type): Don't check non-members if we have - members with the same name. - * call.c (build_method_call): Use lookup_name_nonclass instead of - IDENTIFIER_GLOBAL_VALUE to check for non-member functions. - (build_overload_call_real): Likewise. - - * decl.c (duplicate_decls): Check for ambiguous overloads here. - (push_overloaded_decl): Instead of here. - - * decl.c (pushdecl): Back out Chip's last change. - - * decl.c (grok_op_properties): operators cannot be static members. - - * cp-tree.h (DECL_SYNTHESIZED): DECL_SOURCE_LINE == 0 - (SET_DECL_SYNTHESIZED): DECL_SOURCE_LINE = 0 - * lex.c (cons_up_default_function): Use SET_DECL_SYNTHESIZED. - - * method.c (do_inline_function_hair): Don't put friends of local - classes into global scope, either. - - * typeck2.c (build_functional_cast): Don't look for a function call - interpretation. - -Thu Apr 28 15:19:46 1994 Mike Stump <mrs@cygnus.com> - - * cp-tree.h: disable use of backend EH. - -Wed Apr 27 21:01:24 1994 Doug Evans <dje@canuck.cygnus.com> - - * Make-lang.in (c++.distdir): mkdir tmp/cp first. - * Makefile.in (INCLUDES): Move definition to same place as - parent makefile. - (ALLOCA): Define. - (OLDAR_FLAGS): Delete. - (OLDCC): Define. - (DIR): Delete. - (CLIB): Define. - (####site): Delete. - (SUBDIR_USE_ALLOCA): Don't use ALLOCA if compiling with gcc. - -Wed Apr 27 19:10:04 1994 Kung Hsu <kung@mexican.cygnus.com> - - * decl.c (xref_tag): not to use strstr(), it's not available on - all platforms. - -Wed Apr 27 18:10:12 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Resolve yet another class/pmf confusion. - - * call.c (build_overload_call_real): Don't take the single-function - shortcut if we're dealing with an overloaded operator. - -Wed Apr 27 17:35:37 1994 Mike Stump <mrs@cygnus.com> - - * search.c (get_base_distance): Search the virtual base class - binfos, incase someone wants to convert to a real virtual base - class. - * search.c (expand_indirect_vtbls_init): Use convert_pointer_to_real - instead of convert_pointer_to, as it now will work. - -Wed Apr 27 15:36:49 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): Don't complain about casting away - const and volatile. - - * typeck.c (build_unary_op): References are too lvalues. - -Wed Apr 27 13:58:05 1994 Mike Stump <mrs@cygnus.com> - - * class.c (override_one_vtable): We have to prepare_fresh_vtable - before we modify it, not after, also, we cannot reuse an old vtable, - once we commit to a new vtable. Implement ambiguous overrides in - virtual bases as abstract. Hack until we make the class - ill-formed. - -Wed Apr 27 01:17:08 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (unary_expr): Expand new_placement[opt] and - new_initializer[opt] inline. - - * search.c (lookup_fnfields): Don't throw away the inheritance - information here, either. - (compute_access): Handle static members properly. - - * init.c (build_member_call): Always set basetype_path, and pass it - to lookup_fnfields. - - * search.c (lookup_field): Deal properly with the case where - xbasetype is a chain of binfos; don't throw away the inheritance - information. - (compute_access): protected_ok always starts out at 0. - - * init.c (resolve_offset_ref): Don't cast `this' to the base type - until we've got our basetype_path. - - * cp-tree.h (IS_OVERLOAD_TYPE): aggregate or enum. - - * cvt.c (build_up_reference): Use build_pointer_type rather than - TYPE_POINTER_TO. - - * call.c (convert_harshness_ansi): Call type_promotes_to for reals - as well. - - * cvt.c (type_promotes_to): Retain const and volatile, add - float->double promotion. - - * decl.c (grokdeclarator): Don't bash references to arrays into - references to pointers in function parms. Use type_promotes_to. - -Tue Apr 26 23:44:36 1994 Mike Stump <mrs@cygnus.com> - - Finish off Apr 19th work. - - * class.c (finish_struct_bits): Rename has_abstract_virtuals to - might_have_abstract_virtuals. - * class.c (strictly_overrides, override_one_vtable, - merge_overrides): New routines to handle virtual base overrides. - * class.c (finish_struct): Call merge_overrides to handle overrides - in virtual bases. - -Tue Apr 26 12:45:53 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_function_call): Call build_function_call_real with - LOOKUP_NORMAL. - - * *: Don't deal with TYPE_EXPRs. - - * tree.c (lvalue_p): If the type of the expression is a reference, - it's an lvalue. - - * cvt.c (convert_to_reference): Complain about passing const - lvalues to non-const references. - (convert_from_reference): Don't arbitrarily throw away const and - volatile on the target type. - - * parse.y: Simplify and fix rules for `new'. - - * decl.c (grok_op_properties): operator void is illegal. - -Mon Apr 25 02:36:28 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (components): Anonymous bitfields can still have declspecs. - - * decl.c (pushdecl): Postpone handling of function templates like we - do C functions. - - * search.c (expand_indirect_vtbls_init): Fix infinite loop when - convert_pointer_to fails. - - * call.c (compute_conversion_costs_ansi): A user-defined conversion - by itself is better than that UDC followed by standard conversions. - Don't treat integers and reals specially. - - * cp-tree.h: Declare flag_ansi. - - * typeck.c (c_expand_return): pedwarn on return in void function - even if the expression is of type void. - (build_c_cast): Don't do as much checking for casts to void. - (build_modify_expr): pedwarn about array assignment if this code - wasn't generated by the compiler. - - * tree.c (lvalue_p): A comma expression is an lvalue if its second - operand is. - - * typeck.c (default_conversion): Move code for promoting enums and - ints from here. - * cvt.c (type_promotes_to): To here. - * call.c (convert_harshness_ansi): Use type_promotes_to. Also fix - promotion semantics for reals. - -Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com> - - * Make-lang.in (c++.install-common): Check for g++-cross. - * Makefile.in: Remove Cygnus cruft. - (config.status): Delete. - (RTL_H): Define. - (TREE_H): Use complete pathname, some native makes have minimal - VPATH support. - (*.o): Use complete pathname to headers in parent dir. - (doc, info, dvi): Delete. - -Sun Apr 24 16:52:51 1994 Doug Evans <dje@canuck.cygnus.com> - - * Make-lang.in (c++.install-common): Check for g++-cross. - * Makefile.in: Remove Cygnus cruft. - (config.status): Delete. - (RTL_H): Define. - (TREE_H): Use complete pathname, some native makes have minimal - VPATH support. - (*.o): Use complete pathname to headers in parent dir. - (doc, info, dvi): Delete. - -Sun Apr 24 00:47:49 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (pushdecl): Avoid redundant warning on redeclaring function - with different return type. - (decls_match): Compare return types strictly. - -Fri Apr 22 12:55:42 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (build_type_conversion): Do try to convert through other - pointers. This will fail if the class defines multiple pointer - conversions. - - * error.c (dump_type_prefix): Print out pointers to arrays properly. - (dump_type_suffix): Likewise. (was 'int *[]', now 'int (*)[]') - - * typeck.c (build_unary_op): Disallow ++/-- on pointers to - incomplete type. - - * decl.c (duplicate_decls): Check mismatched TREE_CODES after - checking for shadowing a builtin. If we're redeclaring a builtin - function, bash the old decl to avoid an ambiguous overload. - - * cvt.c (convert_to_reference): Don't force arrays to decay here. - - * tree.c (lvalue_p): A MODIFY_EXPR is an lvalue. - - * decl.c (duplicate_decls): Don't assume that the decls will have - types. - - Mon Apr 18 11:35:32 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940318 snapshot ] - * c-decl.c (pushdecl): Warn if type mismatch with another external decl - in a global scope. - - Fri Apr 22 06:38:56 1994 Chip Salzenberg <chip@fin.uucp> - - * cp/typeck2.c (signature_error): Use cp_error for "%T". - - Mon Apr 18 11:59:59 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940415 snapshot ] - * cp/decl.c (duplicate_decls, pushdecl, builtin_function): - Use DECL_FUNCTION_CODE instead of DECL_SET_FUNCTION_CODE. - - Mon Apr 18 11:55:18 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940409 snapshot ] - * cp/decl.c (duplicate_decls): Put new type in same obstack as - old ones, or permanent if old ones in different obstacks. - - Mon Apr 18 11:48:49 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940401 snapshot ] - * cp/parse.y (attrib): Handle string args as expressions, - merging the two rules. `mode' attribute now takes a string arg. - Delete the rule for an identifier as arg. - - Mon Apr 18 11:24:00 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940312 snapshot ] - * cp/typeck.c (pointer_int_sum): Multiplication should be done signed. - (pointer_diff): Likewise the division. - - Sun Mar 6 19:43:39 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940304 snapshot ] - * cp/decl.c (finish_decl): Issue warning for large objects, - if requested. - - Sat Feb 19 22:20:32 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940218 snapshot ] - * cp/parse.y (attrib): Handle attribute ((section ("string"))). - * cp/decl.c (duplicate_decls): Merge section name into new decl. - - Tue Feb 8 09:49:17 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp/* changes propagated from c-* changes in 940206 snapshot ] - * cp/typeck.c (signed_or_unsigned_type): Check for any - INTEGRAL_TYPE_P not just INTEGER_TYPE. - - Mon Dec 6 13:35:31 1993 Norbert Kiesel (norbert@i3.INformatik.rwth-aachen.DE) - - * cp/decl.c (finish_enum): Start from 0 when determining precision - for short enums. - - Fri Dec 3 17:07:58 1993 Ralph Campbell (ralphc@pyramid.COM) - - * cp/parse.y (unary_expr): Look at $1 for tree_code rather than - casting $$. - - Wed Nov 17 19:22:09 1993 Chip Salzenberg <chip@fin.uucp> - - * cp/typeck.c (build_binary_op_nodefault): Propagate code - from C front-end to optimize unsigned short division. - (build_conditional_expr): Fix bug in "1 ? 42 : (void *) 8". - - Wed Nov 17 19:17:18 1993 Chip Salzenberg <chip@fin.uucp> - - * cp/call.c (convert_harshness_ansi): Given an (e.g.) char - constant, prefer 'const char &' to 'int'. - - Wed Feb 3 13:11:48 1993 Chip Salzenberg <chip@fin.uucp> - - * cp/class.c (finish_struct_methods): Handle multiple - constructors in fn_fields list. - -Fri Apr 22 12:48:10 1994 Kung Hsu <kung@mexican.cygnus.com> - - * class.c (finish_struct): use TYPE_DECL_SUPPRESS_DEBUG to flag - types not to be dumped in stabs, like types in #pragma interface. - * decl.c (init_decl_processing): use TYPE_DECL_SUPPRESS_DEBUG to - mark unknown type. - -Fri Apr 22 03:27:26 1994 Doug Evans <dje@cygnus.com> - - * Language directory reorganization. - See parent makefile. - -Thu Apr 21 18:27:57 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * cp-tree.h (THUNK_DELTA): It is normally negative, so - use signed .i variant of frame_size rather than unsigned .u. - * cp-tree.h (VTABLE_NAME_FORMAT): If flag_vtable_thunks, - use "VT" rather than "vt" due to binary incompatibility. - * class.c (get_vtable_name): Use strlen of VTABLE_NAME_FORMAT, - rather than sizeof, since it is now an expression. - * class.c (modify_one_vtable): Modify to skip initial element - containing a count of the vtable. - -Thu Apr 21 00:09:02 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (check_newline): Force interface_unknown on main input file. - - * pt.c (do_pending_expansions): Always emit functions that have been - explicitly instantiated. - (do_function_instantiation): Set DECL_EXPLICITLY_INSTANTIATED. - (do_type_instantiation): Set CLASSTYPE_VTABLE_NEEDS_WRITING and - DECL_EXPLICITLY_INSTANTIATED on all my methods. - * parse.y (explicit_instantiation): Call do_type_instantiation for - types. - * decl2.c (finish_vtable_vardecl): Call import_export_vtable. - * decl.c (start_function): Don't set DECL_EXTERNAL on a function - that has been explicitly instantiated. - * cp-tree.h (DECL_EXPLICITLY_INSTANTIATED): Alias for - DECL_LANG_FLAG_4. - * class.c: Move import_export_vtable to decl2.c, and comment out all - uses. - -Wed Apr 20 16:51:06 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (process_next_inline): Don't muck with DECL_INLINE. - (do_pending_inlines): Likewise. - -Tue Apr 19 22:25:41 1994 Mike Stump <mrs@cygnus.com> - - Reimplement vtable building, and most vtable pointer setting. - Allows for earier maintenance, easier understandability, and most - importantly, correct semantics. - - * class.c (build_vtable): Removed unneeded - SET_BINFO_VTABLE_PATH_MARKED. - * class.c (prepare_fresh_vtable): Likewise. Added argument. - * class.c (modify_vtable_entry): General cleanup. - * class.c (related_vslot, is_normal, modify_other_vtable_entries, - modify_vtable_entries): Removed. - * class.c (add_virtual_function): General cleanup. - * class.c (finish_base_struct): Setup BINFO_VTABLE and - BINFO_VIRTUALS as early as we can, so that modify_all_vtables can - work. - * class.c (finish_vtbls): New routine, mostly from - unmark_finished_struct. - * class.c (overrides): New routine. - * class.c (modify_one_vtable): New routine, mostly from - modify_other_vtable_entries and modify_vtable_entries. - * class.c (modify_all_direct_vtables, modify_all_indirect_vtables, - modify_all_vtables): New routines. - * class.c (finish_struct): Added arguemnt to prepare_fresh_vtable - call. General cleanup on how pending_hard_virtuals are handled. - General cleanup on modifying vtables. Use finish_vtbls, instead of - unmark_finished_struct. - * cp-tree.h (init_vtbl_ptrs, expand_direct_vtbls_init, - get_first_matching_virtual, get_matching_virtual, - expand_vbase_vtables_init, expand_indirect_vtbls_init): Update. - * cvt.c (convert_pointer_to_real): cleanup error message. - * decl.c (grokfndecl): General cleanup. - * decl.c (finish_function): Change init_vtbl_ptrs call to - expand_direct_vtbls_init. Change expand_vbase_vtables_init call to - expand_indirect_vtbls_init. - * init.c (expand_virtual_init): Remove unneeded argument. - * init.c (init_vtbl_ptrs): Rename to expand_direct_vtbls_init, added - two arguments to make more general. Made more general. Now can be - used for vtable pointer initialization from virtual bases. - * init.c (emit_base_init): Change expand_vbase_vtables_init call to - expand_indirect_vtbls_init. Change init_vtbl_ptrs call to - expand_direct_vtbls_init. - * init.c (expand_virtual_init): General cleanup. - * init.c (expand_default_init): Change expand_vbase_vtables_init - call to expand_indirect_vtbls_init. - * init.c (expand_recursive_init_1): Change expand_vbase_vtables_init - call to expand_indirect_vtbls_init. - * init.c (expand_recursive_init): Change expand_vbase_vtables_init - call to expand_indirect_vtbls_init. - * search.c (get_first_matching_virtual): Rename to - get_matching_virtual. General cleanup and remove setting of - DECL_CONTEXT. That is now done in a cleaner way in - modify_vtable_entry and add_virtual_function. - * search.c (expand_vbase_vtables_init): Rename to - expand_indirect_vtbls_init. General cleanup. Use - expand_direct_vtbls_init to do hard work. Ensures that _all_ vtable - pointers from virtual bases are set up. - * search.c (bfs_unmark_finished_struct, unmark_finished_struct): - Removed. - - * *.[chy]: Remove support for VTABLE_USES_MASK. - -Tue Apr 19 12:51:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): Use NOP_EXPRs to switch between - reference and pointer types instead of bashing the types directly. - - * call.c (build_overload_call_real): Use the TREE_CODE to determine - whether the function is overloaded or not, rather than - TREE_OVERLOADED. - * *: Remove all uses of TREE_OVERLOADED. - - * decl.c (grokdeclarator): Only complain about initializing const - fields when -ansi or -pedantic. - -Tue Apr 19 12:42:42 1994 Doug Evans <dje@canuck.cygnus.com> - - * cp-tree.h (THUNK_DELTA): frame_size is now a union. - -Mon Apr 18 00:17:13 1994 Jason Merrill <jason@deneb.cygnus.com> - - Do overloading on a block-by-block basis, not function-by-function. - * decl.c: Lose overloads_to_forget. - (struct binding_level): Add overloads_shadowed field. - (poplevel): Restore overloads_shadowed. - (push_overloaded_decl): Use overloads_shadowed instead of - overloads_to_forget. - (finish_function): Don't look at overloads_to_forget. - - Copy enum_overflow logic from c-decl.c. - * decl.c (start_enum): Initialize enum_overflow. - (build_enumerator): Use enum_overflow. Also use current_scope(). - - * search.c (current_scope): Move Brendan's comment from - build_enumerator here. - - * typeck.c (convert_for_assignment): Change warnings to pedwarns for - discarding const/volatile. - -Sat Apr 16 01:18:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (comp_target_parms): Accept TEMPLATE_TYPE_PARMs on the rhs. - (comp_target_types): Likewise. - - * decl.c (lookup_name): Don't unset got_scope here. - - * spew.c (yylex): Only replace yylval with the TYPE_NESTED_NAME if - got_scope != NULL_TREE. - -Fri Apr 15 16:36:33 1994 Jason Merrill <jason@deneb.cygnus.com> - - Horrible kludge to prevent templates from being instantiated by - their base classes. - * parse.y (template_instantiate_once): Unset TYPE_BEING_DEFINED - before we get to left_curly. - * pt.c (instantiate_class_template): Set TYPE_BEING_DEFINED. - - * error.c (dump_decl): If it's a typedef, print out the name of the - decl, not just the underlying type. - - * decl.c (pushdecl): If the old duplicate decl was a TYPE_DECL, - update the IDENTIFIER_TYPE_VALUE of its name. - - * decl2.c (finish_file): When processing the initializer for a - static member, pretend that the dummy function is a member of the - same class. - -Fri Apr 15 15:56:35 1994 Kung Hsu <kung@mexican.cygnus.com> - - * class.c (build_vtable_entry): revert Apr 4 change. - * decl2.c (mark_vtable_entries): replace pure virtual function - decl with abort's. - -Fri Apr 15 13:49:33 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_conditional_expr): Pedwarn on pointer/integer - mismatch, and don't pedwarn on 0/function pointer mismatch. - - * typeck2.c (digest_init): Lose code for special handling of unions. - (process_init_constructor): Since they're handled just fine here. - Pedwarn on excess elements. - - * decl2.c (grokfield): Complain about local class method declaration - without definition. - -Fri Apr 15 13:19:40 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * method.c (emit_thunk): Add extern declaration for - current_call_is_indirect (needed for hppa). - -Thu Apr 14 16:12:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - Improve local class support; allow classes in different blocks to - have the same name. - * decl.c (pushtag): Support local classes better. - (pushdecl_nonclass_level): New function for pushing mangled decls of - nested types into the appropriate scope. - (xref_defn_tag): Use pushdecl_nonclass_level instead of - pushdecl_top_level. - (grokfndecl): Don't mess with IDENTIFIER_GLOBAL_VALUE for local - class methods. - * method.c (do_inline_function_hair): Likewise. - - * class.c (finish_struct): It is legal for a class with no - constructors to have nonstatic const and reference members. - -Thu Apr 14 07:15:11 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * decl.c (push_overloaded_decl): Avoid giving errors about - built-ins, since duplicate_decls will have given warnings/errors - for them. - -Thu Apr 14 03:45:12 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): Warn about casting pointer type to - reference type when this is probably not what they wanted. - -Wed Apr 13 13:12:35 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (finish_decl): Don't mindlessly set TREE_USED for - static consts any more (toplev.c has now been modified to - not emit warnings if they are unused). - -Wed Apr 13 00:22:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_op_properties): If op new/delete get here with - METHOD_TYPEs, do a revert_static_member_fn. - - * cp-tree.h (IDENTIFIER_CLASS_TYPE_VALUE): Lose. - * init.c (is_aggr_typedef): Don't look at - IDENTIFIER_CLASS_TYPE_VALUE. - (get_aggr_from_typedef): Likewise. - (get_type_value): Likewise. - * call.c (build_scoped_method_call): Don't rely on overloaded - template names having IDENTIFIER_CLASS_VALUE set. - - * parse.y (component_decl_1, fn.def2): Revert rules for - constructors. - (component_decl_1, fn.def2): Use $1 instead of $$, since $$ is being - clobbered. - - * decl.c (start_function): Only warn about `void main()' if pedantic - || warn_return_type. - -Tue Apr 12 02:14:17 1994 Jason Merrill <jason@deneb.cygnus.com> - - Clean up overloading of the template name. - * class.c (pushclass): overload the template name whenever pushing - into the scope of a template class, not just if it is - uninstantiated. - (popclass): Correspondingly. - * search.c (push_class_decls): Don't overload_template_name. - * pt.c (overload_template_name): Don't set IDENTIFIER_LOCAL_VALUE or - DECL_CONTEXT on things. - * parse.y (left_curly): Don't overload_template_name. - * class.c (finish_struct): Don't undo_template_name_overload. - - * method.c (build_opfncall): Only pass one argument to global op - delete. - - * call.c (build_method_call): Use TYPE_VEC_DELETE_TAKES_SIZE to - decide how many arguments to use for vec delete. - - * decl.c (grok_op_properties): Be consistent in modifying - current_class_type. - (grokdeclarator): Only complain about function decls with no return - type if we're being pedantic. - -Mon Apr 11 00:10:53 1994 Jason Merrill <jason@deneb.cygnus.com> - - Add support for operator new [] and operator delete []. - - * tree.def: Add VEC_NEW_EXPR and VEC_DELETE_EXPR. - * ptree.c (print_lang_type): Indicate vec new/delete. - * parse.y: Support vec new/delete. - * method.c (build_decl_overload): Deal with vec new/delete. - (build_opfncall): Likewise. - * lex.c (init_lex): Set up values of ansi_opname and opname_tab for - vec new/delete. vec new uses "__vn", and vec delete uses "__vd". - * init.c (init_init_processing): Set up BIVN and BIVD. - (do_friend): Don't clean up after mistaken setting of TREE_GETS_NEW, - since it doesn't happen any more. - (build_new): Support vec new. Always call something. - (build_x_delete): Support vec delete. - (build_vec_delete): Lose dtor_dummy argument, add use_global_delete, - and pass it to build_x_delete. - * decl2.c (delete_sanity): Don't change behavior by whether or not - the type has a destructor. Pass use_global_delete to - build_vec_delete. - (coerce_delete_type): Make sure that the type returned has a first - argument of ptr_type_node. - * decl.c (init_decl_processing): Also declare the global vec - new/delete. - (grokdeclarator): Also force vec new/delete to be static. - (grok_op_properties): Note presence of vec new/delete, and play with - their args. If vec delete takes the optional size_t argument, set - TYPE_VEC_DELETE_TAKES_SIZE. - * cp-tree.h (TYPE_GETS_{REG,VEC}_DELETE): New macros to simplify - checking for one delete or the other. - (lang_type): gets_new and gets_delete are now two bits long. The - low bit is for the non-array version. Lose gets_placed_new. - (TYPE_VEC_DELETE_TAKES_SIZE): New macro indicating that the vec - delete defined by this class wants to know how much space it is - deleting. - (TYPE_VEC_NEW_USES_COOKIE): New macro to indicate when vec new must - add a header containing the number of elements in the vector; i.e. - when the elements need to be destroyed or vec delete wants to know - the size. - * class.c (finish_struct_methods): Also check for overloading vec - delete. - * call.c (build_method_call): Also delete second argument for vec - delete. - - * decl.c (grokdeclarator): Correct complaints again. - (grokdeclarator): Fix segfault on null declarator. - (decls_match): Also accept redeclaration with no arguments if both - declarations were in C context. Bash TREE_TYPE (newdecl) here. - (duplicate_decls): Instead of here. - - * parse.y (nested_name_specifier_1): Lose rules for dealing with - syntax errors nicely, since they break parsing of 'const i;'. - - * decl.c (lookup_name): if (got_scope == current_class_type) - val = IDENTIFIER_CLASS_VALUE (name). - - * search.c (lookup_nested_tag): Look in enclosing classes, too. - - * spew.c (yylex): Only look one character ahead when checking for a - SCOPE. - - * lex.c (check_newline): Read first nonwhite char before - incrementing lineno. - - * decl.c (grokdeclarator): Don't claim that typedefs are variables - in warning. - - * parse.y: Divide up uses of unqualified_id into - notype_unqualified_id and unqualified_id, so that TYPENAME can be - used as an identifier after an object. - - * class.c (push_nested_class): Don't push into non-class scope. - - * decl.c (grokdeclarator): If an identifier could be a type - conversion operator, but has no associated type, it's not a type - conversion operator. - - * pt.c (unify): Check for equality of constants better. - - * decl.c (grokdeclarator): Don't complain about access decls. - -Sun Apr 10 02:39:55 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): pedwarn about data definitions without - types here. - - * parse.y (datadef): Don't pedwarn about decls without types here, - since that is valid for functions. - (fn.def2, component_decl): Support constructors with declmods again. - (nomods_initdecls): For decls without any mods, so that we don't try - to get declspecs from some arbitrary $0. - - * search.c (lookup_field): Use cp_error. - - * parse.y (nested_name_specifier_1): Don't check aggr/non-aggr type - here; it breaks destructors for non-aggr types. - - * decl.c (lookup_name): Only look for TYPE_DECLs in base classes of - a type being defined, like the comment says. - If got_scope is not an aggregate, just return NULL_TREE. - - * pt.c (create_nested_upt): Kung's code for creating types nested - within uninstantiated templates now lives here (it used to live in - hack_more_ids). It needs to be expanded. - - * parse.y: Stop calling see_typename so much. - - * decl.c (lookup_name): Deal with TTPs and UPTs. - - * lex.c (real_yylex): Don't set looking_for_typename just because we - saw a 'new'. - (dont_see_typename): #if 0 out. - - * spew.c (yylex): Increment looking_for_typename if the next - character is SCOPE, rather than setting it to 1; this way, the value - from seeing an aggr specifier will not be lost. This kinda relies - on looking_for_typename never being < 0, which is now true. - - * parse.y (nested_name_specifier_1): Accept TEMPLATE_TYPE_PARMs, - too. - (named_class_head_sans_basetype): Accept template types, too. Oops. - -Fri Apr 8 16:39:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (reparse_decl_as_expr1): Handle SCOPE_REFs. - - * parse.y: Lose START_DECLARATOR. - - * search.c (lookup_nested_tag): New function to scan CLASSTYPE_TAGS - for a class. - - * parse.y: Simplify fn.def2 and component_decl. Support 'enum - A::foo' syntax. Catch invalid scopes better. - - * parse.y, lex.c: lose TYPENAME_COLON. - - * decl2.c (groktypefield): #if 0 out. - - * decl.c (lookup_name): If the type denoted by got_scope is - currently being defined, look in CLASSTYPE_TAGS rather than FIELDS. - - * class.c (push_nested_class): Don't try to push into - error_mark_node. - -Fri Apr 8 07:26:36 1994 Brendan Kehoe <brendan@lisa.cygnus.com> - - * Makefile.in (stamp-parse): Update count of conflicts to 33. - -Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com> - - A saner implementation of nested types that treats template types - no differently from non-template types. There are still some - shortcomings of our system; most notably, it is difficult to look - for a nested type that is hidden by another name, because of the way - we keep track of hidden types. But this shouldn't be a problem for - just about anyone. Perhaps lookup_field should be fixed up a bit. - - * spew.c: Moved handling of nested types/scoping from the lexer - into the parser. Removed variable template_type_seen_before_scope. - Removed functions frob_identifier, hack_more_ids, and various cruft - that was #if 0'd out in the past, reducing the size of the file from - 1146 lines to 450 lines. We can't quite do away with spew.c yet, - though; we still need it for do_aggr () and checking for SCOPE after - the current identifier. And setting lastiddecl. - - * parse.y: Moved handling of nested types/scoping from the lexer - into the parser, using a new global variable `got_scope'. Reduced - the number of states by 53. Implemented all uses of explicit global - scope. Removed terminals SCOPED_TYPENAME and SCOPED_NAME. Removed - nonterminals tmpl.1, scoped_base_class, id_scope, typename_scope, - scoped_typename. Added nonterminals nested_type, - qualified_type_name, complete_type_name, qualified_id, ptr_to_mem, - nested_name_specifier, global_scope, overqualified_id, type_name. - Changed many others. Added 9 new reduce/reduce conflicts, which are - nested type parallels of 9 that were already in the grammar for - non-nested types. Eight of the now 33 conflicts should be removed - in the process of resolving the late binding between variable and - function decls. - - * gxxint.texi (Parser): Update. - - * cp-tree.h (IS_AGGR_TYPE_CODE): Add UNINSTANTIATED_P_TYPE. - - * lex.h: Add decl for got_scope. - - * lex.c (see_typename): Claim to be the lexer when calling - lookup_name. - - * decl.c (lookup_name): When called from the lexer, look at - got_scope and looking_at_typename; otherwise don't. - -Thu Apr 7 22:05:47 1994 Mike Stump <mrs@cygnus.com> - - 31th Cygnus<->FSF merge. - -Thu Apr 7 17:47:53 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (mark_vtable_entries): Call this to mark all the - entries in the vtable addressable. - (finish_decl_parsing): Handle SCOPE_REFs. - - * decl.c (decls_match): Always call compparms with strict == 1. - Handle the special case of C function redecl here. - (duplicate_decls): Only keep the old type if the new decl takes no - arguments. - - * typeck.c (compparms): Also allow t1 to be ... if strict == 0. - -Thu Apr 7 16:17:50 1994 Mike Stump <mrs@cygnus.com> - - * class.c (build_vtable_entry): Fix breakage introduced Apr 5 - 17:48:41. - -Wed Apr 6 16:05:10 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * init.c (build_virtual_init), search.c (build_vbase_vtables_init), - ch-tree.h: Every place these functions were called, the result was - immediately passed to expand_expr_stmt. Reduce redundancy by - calling expand_expr_init *inside* these functions. These - makes for a simpler interface, and we don't have to build - compound expressions. Hence, rename these function to: - expand_virtual_init and expand_vbase_vtables_init respectively. - * init.c, decl.c: Change callers of these functions. - * init.c, cp-tree.h (expand_virtual_init): Make static. - - * decl2.c (finish_file): Check TREE_PUBLIC||TREE_ADDRESSABLE - rather than DECL_SAVED_INSNS before emitting inlines. - -Wed Apr 6 13:06:39 1994 Jason Merrill <jason@deneb.cygnus.com> - - * spew.c (init_spew): #if 0 out stuff used by arbitrate_lookup. - - * decl.c (duplicate_decls): If this is a new declaration of an - extern "C" function, keep the type (for the argtypes). - (redeclaration_error_message): Don't check DECL_LANGUAGE here. - (decls_match): Call compparms with a value of strict dependent on - the value of strict_prototypes for DECL_LANGUAGE (oldecl). - - * typeck.c (compparms): ... is only equivalent to non-promoting - parms if we're not being strict. - - * parse.y (empty_parms): Don't check flag_ansi || pedantic here. - - * decl.c (init_decl_processing): if (flag_ansi || pedantic) - strict_prototypes_lang_c = strict_prototypes_lang_cplusplus; - - * decl2.c (grok_function_init): Don't set DECL_INITIAL on pure - virtuals. - -Tue Apr 5 17:48:41 1994 Per Bothner <bothner@kalessin.cygnus.com> - - Support for implementing vtables with thunks. - * tree.def (THUNK_DECL): New TREE_CODE. - * cp-tree.h (FNADDR_FROM_VTABLE_ENTRY), tree.c - (fnaddr_from_vtable_entry): Handle flag_vtable_thunks case. - * cp-tree.h (memptr_type): New variable. - * class.c (build_vtable_entry): Build thunk if necessary. - * class.c (build_vfn_ref): If using thunks, don't need - to add delta field from vtable (there is none!). - * decl.c: Add memptr_type as well as vtable_entry_type. - If using thunks, the latter is just ptr_type_node. - * gc.c, typeck.c: Use memptr_typeChange, not vtable_entry_type. - * decl2.c (finish_vtable_vardecl): Handle thunks. - * expr.c (cplus_expand_expr): Support THUNK_DECL. - - * decl.c (grokdeclarator): Set DECL_THIS_EXTERN if "extern". - * decl.c (start_function): Set current_extern_inline based on - DECL_THIS_EXTERN, not TREE_PUBLIC. - * decl.c (finish_function): Call mark_inline_for_output if needed, - - Improve intelligence about when to emit inlines. - * cp-tree.h (lang_decl_flags): New field saved_inline. - * cp-tree.h (DECL_SAVED_INLINE): New macro. - * class.c (add_virtual_function): Don't set TREE_ADDRESSABLE. - * decl.h, decl.c (pending_addressable_inlines): Removed. - * decl2.c (pending_addressable_inlines): Renamed to saved_inlines. - * decl2.c (mark_inline_for_output): Do nothing if - DECL_SAVED_INLINE; otherwise set it (and add to saved_inlines list). - * decl2.c (finish_vtable_vardecl): SET_CLASSTYPE_INTERFACE_KNOWN - and set CLASSTYPE_INTERFACE_ONLY if there is a non-inline virtual. - * decl2.c (finish_file): Writing out inlines later, so we can - also handle the ones needed for vtbales. - * decl2.c (write_vtable_entries, finish_vtable_typedecl): Removed. - - * cp-tree.h, class.c, decl2.c, search.c: Remove -fvtable-hack - and flag_vtable_hack. Use -fvtable-thunks and flag_vtable_thunks - instead. (The rationale is that these optimizations both break binary - compatibility, but should become the default in a future release.) - -Wed Apr 6 10:53:56 1994 Mike Stump <mrs@cygnus.com> - - * class.c (modify_vtable_entries): Never reset the DECL_CONTEXT - of a fndecl, as we might not be from that vfield. - -Tue Apr 5 17:43:35 1994 Kung Hsu <kung@mexican.cygnus.com> - - * class.c (add_virtual_function): fix bug for pure virtual, so - that DECL_VINDEX of the dummy decl copied won't be error. - (see also Apr 4 change) - -Tue Apr 5 17:23:45 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * typeck.c (c_expand_return): Before checking that we're not - returning the address of a local, make sure it's a VAR_DECL. - (And don't worry about it being a TREE_LIST.) - -Tue Apr 5 13:26:42 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (YYDEBUG): Always define. - * lex.c (YYDEBUG): Likewise. - -Mon Apr 4 11:28:17 1994 Kung Hsu <kung@mexican.cygnus.com> - - * class.c (finish_struct): backup out the change below, put the - new change for the same purpose. The change below breaks code. - - * class.c (finish_struct): if pure virtual, copy node and make - RTL point to abort, then put in virtual table. - * decl2.c (grok_function_iit): reinstate Mar 31 change. - -Sat Apr 2 03:12:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_new): pedwarn about newing const and volatile - types. - - * tree.c (get_identifier_list): Only do the special handling - thing if we're dealing with the main variant of the record type. - - * cvt.c (convert_to_reference): When converting between - compatible reference types, use the pointer conversion machinery. - Don't just blindly overwrite the old type. - -Fri Apr 1 17:14:42 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): When looking at global functions, - be sure to use instance_ptr for the first argument, not some version - of it that has been cast to a base class. Also do this before - comparing candidates. - -Thu Mar 31 19:50:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Constructors can be called for - const objects. - -Thu Mar 31 16:20:16 1994 Kung Hsu <kung@mexican.cygnus.com> - - * decl2.c (grok_func_init): do not abort as rtl for pur virtual - fucntions. They can be defined somewhere else. - -Sat Jan 23 23:23:26 1994 Stephen R. van den Berg (berg@pool.informatik.rwth-aachen.de) - - * decl.c (init_decl_processing): Declare __builtin_return_address - and __builtin_frame_address for C++ as well. - -Thu Mar 31 12:35:49 1994 Mike Stump <mrs@cygnus.com> - - * typeck2.c (store_init_value): Integral constant variables are - always constant, even when doing -fpic. - -Sat Jan 23 23:23:26 1994 Stephen R. van den Berg (berg@pool.informatik.rwth-aachen.de) - - * decl.c (redeclaration_error_message): Pass the types to - comptypes. - -Wed Mar 30 21:29:25 1994 Mike Stump <mrs@cygnus.com> - - Cures incorrect errors about pure virtuals in a class, when they - have been overridden in a derived class. - - * search.c (get_abstract_virtuals): Reimplement. - * search.c (get_abstract_virtuals_1): New routine. - -Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (push_template_decls): Make the pushed level pseudo - global. - - * parse.y (extdefs): Don't pop everything if the current binding - level is pseudo_global. - - * decl.c (pop_everything): Stop on reaching a pseudo-global - binding level. - - * cp-tree.h (DECL_FUNCTION_MEMBER_P): Change to more reliable test. - - * decl.c (duplicate_decls): Only copy DECL_SOURCE_{FILE_LINE} if - the old decl actually had an initializer. - - * {various}: Clean up gcc -W complaints. - - * cp-tree.h (DECL_FUNCTION_MEMBER_P): Currently defined to be - (DECL_CONTEXT (NODE) != NULL_TREE). - - * parse.y (lang_extdef): Call pop_everything if necessary. - - * decl.c (pop_everything): New function for popping binding - levels left over after a syntax error. - (pushdecl): Use DECL_FUNCTION_MEMBER_P to decide whether or not - a function is a member. - -Wed Mar 30 14:20:50 1994 Mike Stump <mrs@cygnus.com> - - Cures calling a more base base class function, when a more derived - base class member should be called in some MI situations. - - * search.c (make_binfo): Use more the more specialized base - binfos from the binfo given as the second argument to make_binfo, - instead of the unspecialized ones from the TYPE_BINFO. - * class.c (finish_base_struct): Likewise, update callers. - * search.c (dfs_get_vbase_types): Likewise. - * tree.c (propagate_binfo_offsets, layout_vbasetypes): Likewise. - * decl.c (xref_tag): Use NULL_TREE instead of 0. - * lex.c (make_lang_type): Likewise. - -Wed Mar 30 14:10:04 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (pushdecl): If pushing a C-linkage function, only do a - push_overloaded_decl. - (duplicate_decls): Standard overloading does not shadow built-ins. - -Tue Mar 29 00:54:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (end_template_decl): Don't call push_overloaded_decl. - - * init.c (do_friend): Don't call push_overloaded_decl. - - * decl.c (pushdecl): Call push_overloaded_decl for functions and - function templates. - (duplicate_decls): functions and function templates are not - duplicates, but don't complain about calling this function to - compare them. - (push_overloaded_decl): Don't deal with linkage. Call - duplicate_decls. - (redeclaration_error_message): Deal with linkage. - - * decl.c (start_function): If push_overloaded_decl returns an - older version of the function, deal with it. - - * decl.c (start_function): Be sure only to push_overloaded_decl - for non-members. - - * decl.c (grokfndecl): Put back clearing of DECL_CHAIN for - methods. - (start_function): Lose broken and redundant code for checking old - decl. - - * init.c (add_friend): Give line numbers of both friend decls - when warning about re-friending. - - * pt.c (tsubst): Use comptypes rather than == to compare the - types of the method as declared and as defined, since default - parameters may be different. - - * call.c (build_method_call): Use brendan's candidate printing - routine. - - * decl.c (start_method): Methods defined in the class body are - inline whether or not it's a template class. - -Mon Mar 28 16:39:26 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (initdcl0): Add "extern" to current_declspecs if - have_extern_spec && ! used_extern_spcec. - - * tree.c (really_overloaded_fn): A fn with more than one - overload. - - * pt.c (end_template_decl): Use really_overloaded_fn. - - * decl.c (duplicate_decls): When smashing a decl into a previous - definition, keep the old file and line. - Don't deal with overloaded functions. - Lose old code for checking arg types of functions. - Check for overloaded C functions. - (pushdecl): Deal with overloaded functions. - (start_decl): Expect pushdecl to return an appropriate function decl. - (start_function): Likewise. - (push_overloaded_decl): Don't check for overloaded C functions. - - * *.c: Stop using DECL_OVERLOADED, it being archaic. - TREE_OVERLOADED should probably go, too. - -Mon Mar 28 14:00:45 1994 Ron Guilmette <rfg@netcom.com> - - * typeck.c (comp_target_types): Call comp_target_parms with - strict == 1. - -Sun Mar 27 00:07:45 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (empty_parms): Don't parse () as (...) in extern "C" - sections if we're compiling with -ansi or -pedantic. - - * decl.c (decls_match): Don't treat (int) and (int&) as matching. - - * decl2.c (grokfield): Don't pedwarn twice about initializing - field. - - * decl.c (push_overloaded_decl): Warn about shadowing - constructor. - (redeclaration_error_message): Don't allow 'int a; int a;' - - * cvt.c (build_up_reference): Only check for valid upcast if - LOOKUP_PROTECT is set, not just any flag. - -Fri Mar 25 01:22:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (check_newline): When we see a #pragma implementation, - also set it for the main input file. - - * init.c (build_new): Convert array size argument to size_t. - - * parse.y (primary): If we're doing a parenthesized type-id, call - groktypename before passing it to build_new. - - * call.c (build_method_call): Deal properly with const and - volatile for instances of reference type. - - * decl.c (store_return_init): Change 'if (pedantic) error' to 'if - (pedantic) pedwarn'. - - * decl.c (grokdeclarator): Don't complain about putting `static' - and `inline' on template function decls. - -Thu Mar 24 23:18:19 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Preserve const & volatile on - `this'. - -Thu Mar 24 16:21:52 1994 Mike Stump <mrs@cygnus.com> - - * init.c (build_new, build_vec_delete): Use global new and delete - for arrays. - * decl2.c (delete_sanity): Likewise. - -Thu Mar 24 02:10:46 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): If i is an lvalue, - (int &)i -> *(int*)&i, as per 5.2.8p9 of the latest WP. - (convert_force): Call convert_to_reference with LOOKUP_COMPLAIN. - -Wed Mar 23 17:45:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (duplicate_decls): Also propagate DECL_TEMPLATE_MEMBERS - and DECL_TEMPLATE_INSTANTIATIONS. - - * init.c (build_new): Handle array typedefs properly. - -Wed Mar 23 18:23:33 1994 Mike Stump <mrs@cygnus.com> - - 30th Cygnus<->FSF merge. - -Wed Mar 23 00:46:24 1994 Mike Stump <mrs@cygnus.com> - - * class.c (modify_vtable_entries): Avoid running off the end of the - virtuals list when processing a virtual destructor. - * class.c (get_vtable_entry): Likewise. - -Wed Mar 23 00:23:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (duplicate_decls): If two template decls don't match, - just return 0. - -Tue Mar 22 23:49:41 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (convert_for_assignment): Don't pedwarn about - converting function pointer to void *. - -Tue Mar 22 22:23:19 1994 Mike Stump <mrs@cygnus.com> - - Major revamp of pointer to member functions. Cures major - nonfunctionality when used in casts, and MI situations. - - * cvt.c (convert_force): Update call site of build_ptrmemfunc. - * typeck.c (convert_for_assignment): Likewise. - * typeck2.c (digest_init): Likewise. - * typeck2.c (process_init_constructor): Simplify by moving code into - digest_init. - * typeck2.c (digest_init): Do default_conversions on init value, if - we are processing pointer to member functions. - * class.c (get_vfield_offset): Now non-static. Convert bit offset - into byte offset. - * cp-tree.h (get_vfield_offset): Likewise. - * typeck.c (get_member_function_from_ptrfunc): Convert down to right - instance, before fetching vtable pointer. - * typeck.c (get_delta_difference): New routine. - * typeck.c (build_ptrmemfunc): Revamp to handle casting better, also - get vtable pointer out of right subobject. - -Tue Mar 22 17:56:48 1994 Mike Stump <mrs@cygnus.com> - - * search.c (get_binfo): Return NULL instead of aborting, when - passed a UNION_TYPE. - -Tue Mar 22 12:44:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - These patches implement handling of redefinition/redeclaration of - templates. - - * typeck.c (comptypes): Simplify. All TEMPLATE_TYPE_PARMs are - considered compatible. - - * parse.y (template_def): Pass defn argument to end_template_decl. - - * pt.c (end_template_decl): Add defn argument. Check for - redefinition. Simplify. - - * error.c (OB_UNPUT): New macro, to remove mistakes. - (aggr_variety): Subroutine of dump_aggr_type. - - * decl.c (decls_match): Support templates. - (duplicate_decls): No longer static. Don't try to lay out template - decls. - (pushdecl): Simplify. - - * cp-tree.h (DECL_TEMPLATE_MEMBERS): Use DECL_SIZE instead of - DECL_INITIAL. - -Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_decl): Support class template decls. - (dump_type): Don't adorn template type parms. - - * decl.c (duplicate_decls): Save DECL_TEMPLATE_INFO from old decl - if it was a definition. - (redeclaration_error_message): Do the cp_error thang, and reject - redefinition of templates. - -Mon Mar 21 19:36:06 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (grokdeclarator): Set TREE_PUBLIC for METHOD_TYPE - in FIELD context, when appropriate. Also, - CLASSTYPE_INTERFACE_ONLY is irrelevant to setting TREE_PUBLIC. - Also, simplify check for bogus return specifiers. - -Mon Mar 21 11:46:55 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (after_type_declarator1): Expand type_quals. - (notype_declarator1): Likewise. - (absdcl1): Likewise. - -Sat Mar 19 01:05:17 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Treat class-local typedefs like static - members; i.e. 'typedef int f();' means that f is a function type, - not a method type. - - * parse.y (decl): Change direct_* back to *. - (type_id): Change direct_abstract_declarator to absdcl. - (direct_declarator, direct_initdecls, direct_initdcl0): Remove again. - -Fri Mar 18 12:47:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - These two patches fix crashes on instantiating a template inside a - function with C linkage or containing labels. - - * class.c (current_lang_stacksize): No longer static. - - * decl.c (struct saved_scope): Add lang_base, lang_stack, - lang_name, lang_stacksize, and named_labels. - (push_to_top_level): Save them. - (pop_from_top_level): Restore them. - - * gxxint.texi (Parser): Update. - - These two patches finish moving the task of expr/declarator - ambiguity resolution from the lexer to the parser, and add one more - r/r conflict. START_DECLARATOR can now be nuked. - - * parse.y (decl): Add "direct_" in typespec X rules. - (direct_declarator): New nonterminal for - direct_after_type_declarator and direct_notype_declarator. - (direct_initdecls): Like initdecls, but uses direct_initdcl0. - (direct_initdcl0): Like initdcl0, but uses direct_declarator. - (named_parm): Add typespec direct_declarator rule. - - * spew.c (yylex): #if 0 out START_DECLARATOR insertion. - - These two patches disable some excessive cleverness on the part of - g++; a non-class declaration always hides a class declaration in the - same scope, and g++ was trying to unhide it depending on the - enclosing expression. - - * spew.c (arbitrate_lookup): #if 0 out. - - * decl.c (lookup_name): Never call arbitrate_lookup. - - * parse.y (complex_notype_declarator1): Add '*' - complex_notype_declarator1 and '&' complex_notype_declarator1 rules. - - * parse.y (complex_direct_notype_declarator): Restore id_scope - see_typename TYPENAME rule, remove all other rules beginning with - those tokens. - (notype_unqualified_id): Add '~' see_typename IDENTIFIER rule. - -Thu Mar 17 17:30:01 1994 Jason Merrill <jason@deneb.cygnus.com> - - These changes fix the compiler's handling of the functional cast/ - object declaration ambiguities in section 6.8 of the ARM. They also - add 11 reduce/reduce conflicts. Sigh. - - * parse.y: Add precedence decls for OPERATOR and '~'. - (notype_unqualified_id): New nonterminal, encompasses all of the - ANSI unqualified-id nonterminal except TYPENAMEs. - (expr_or_declarator): New nonterminal to delay parsing of code like - `int (*a)'. - (primary): Use notype_unqualified_id. - (decl): Add typespec initdecls ';' and typespec declarator ';' - rules. - (initdcl0): Deal with the above. - (complex_notype_declarator1): A notype_declarator that is not also - an expr_or_declarator. - (complex_direct_notype_declarator): A direct_notype_declarator that - doesn't conflict with expr_or_declarator. Use - notype_unqualified_id. Remove id_scope see_typename TYPENAME rule. - (functional_cast): New nonterminal, for the three functional cast - rules. So that they can be moved after - complex_direct_notype_declarator. - (see_typename): Don't accept type_quals any more. - - * decl2.c (reparse_decl_as_expr): New function to deal with parse - nodes for code like `int (*a)++;'. - (reparse_decl_as_expr1): Recursive subroutine of the above. - (finish_decl_parsing): New function to deal with parse nodes for - code like `int (*a);'. See the difference? - -Thu Mar 17 12:16:10 1994 Mike Stump <mrs@cygnus.com> - - These changes break binary compatibility in code with classes - that use virtual bases. - - * search.c (dfs_get_vbase_types): Simplify and correct to make - sure virtual bases are initialized in dfs ordering. - * search.c (get_vbase_types): Simplify and make readable. - -Thu Mar 17 12:01:10 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y: s/ typename / type_id /g - -Wed Mar 16 17:42:52 1994 Kung Hsu <kung@mexican.cygnus.com> - - * parse.y (typespec): add SCOPE TYPENAME for global scoped - type. e.g. ::B x. - - * decl.c (complete_array_type): fix a bug that in -pendantic - mode even there's no initializer, it will continue to build - default index. - -Wed Mar 16 17:43:07 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (direct_notype_declarator): Add PTYPENAME rule, remove - all of the scoped PTYPENAME rules. - -Wed Mar 16 16:39:02 1994 Mike Stump <mrs@cygnus.com> - - * init.c (build_offset_ref): The value of A::typedef_name is - always the TYPE_DECL, and never an error. - -Tue Mar 15 20:02:35 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (get_base_distance_recursive): Two binfos can only - represent the same object if they are both via_virtual. - - * class.c (finish_base_struct): Check vbases for ambiguity, too. - - * search.c (get_vbase_types): Accept binfo argument, too. - -Tue Mar 15 19:22:05 1994 Kung Hsu <kung@mexican.cygnus.com> - - * decl.c (complete_array_type): complete TYPE_DOMAIN of the - initializer also, because back-end requires it. - -Tue Mar 15 15:33:31 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_expr): Support member functions (which show up as - OFFSET_REFs). - -Mon Mar 14 16:24:36 1994 Mike Stump <mrs@cygnus.com> - - * init.c (build_new): Set the return type of multidimensional - news correctly. - -Fri Mar 11 15:35:39 1994 Kung Hsu <kung@mexican.cygnus.com> - - * call.c (build_method_call): if basetype not equal to type - of the instance, use the type of the instance in building - destructor. - -Thu Mar 10 17:07:10 1994 Kung Hsu <kung@mexican.cygnus.com> - - * parse.y (direct_notype_declarator): add push_nested_type for - 'template_type SCOPED_NAME' rule. - -Tue Mar 8 00:19:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (parm): Add typed_declspec1 {absdcl, epsilon} rules. - -Sat Mar 5 04:47:48 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (regcast_or_absdcl): New nonterminal to implement late - reduction of constructs like `int ((int)(int)(int))'. - (cast_expr): Use it. - (sub_cast_expr): Everything that can come after a cast. - (typed_declspecs1): typed_declspecs that are not typed_typespecs. - (direct_after_type_declarator): Lose PAREN_STAR_PAREN rule. - (direct_abstract_declarator): Replace '(' parmlist ')' rule with - '(' complex_parmlist ')' and regcast_or_absdcl. - (parmlist): Split - (complex_parmlist): Parmlists that are not also typenames. - (parms_comma): Enabler. - (named_parm): A parm that is not also a typename. Use declarator - rather than dont_see_typename abs_or_notype_decl. Expand - typed_declspecs inline. - (abs_or_notype_decl): Lose. - (dont_see_typename): Comment out. - (bad_parm): Break out abs_or_notype_decl into two rules. - -Fri Mar 4 18:22:39 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl2.c (reparse_decl_as_casts): New function to change parse - nodes for `(int)(int)(int)' from "function taking int and returning - function taking int and returning function taking int" to "... cast - to int, cast to int, cast to int". - - * decl2.c (reparse_decl_as_expr): Recursive function to change - parse nodes for `A()()' from "function returning function returning - A" to "A().operator()". - - * parse.y (primary): Replace `typespec LEFT_RIGHT' rule with - `typespec fcast_or_absdcl' rule. - (fcast_or_absdcl): New nonterminal to implement late reduction of - constructs like `A()()()()'. - (typename): Replace `typespec absdcl1' rule with - `typespec direct_abstract_declarator' rule. - (direct_abstract_declarator): Replace `LEFT_RIGHT type_quals' rule - with `fcast_or_absdcl type_quals' rule. - -Fri Mar 4 16:18:03 1994 Mike Stump <mrs@cygnus.com> - - * tree.c (lvalue_p): Improve OFFSET_REF handling, so that it - matches Section 5.5. - -Fri Mar 4 14:01:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * error.c (dump_type_prefix): Don't print basetype twice for - pmfs. - -Fri Mar 4 13:24:33 1994 Mike Stump <mrs@cygnus.com> - - * typeck.c (convert_arguments): Handle setHandler(A::handlerFn) - so that it is like setHandler(&A::handlerFn). Cures an `invalid - lvalue in unary `&''. - -Fri Mar 4 11:15:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * gxxint.texi (Copying Objects): New section discussing default - op= problems with virtual inheritance. - - * decl2.c (grokoptypename): Just does grokdeclarator and - build_typename_overload, since the parser can't call grokdeclarator - directly. - - * method.c (build_typename_overload): Set IDENTIFIER_GLOBAL_VALUE - and TREE_TYPE on generated identifiers. - - * decl.c (grokdeclarator): Don't deal with TYPE_EXPRs anymore. - - * parse.y (parm): Convert `const char *' to `__opPCc' here. - - * error.c (dump_decl): Say sorry rather than my_friendly_aborting - if we can't figure out what to do. - (dump_type*): Likewise. - - * typeck2.c (build_m_component_ref): 'component' is an expr, not - a decl. Also move the IS_AGGR_TYPE check after the stripping of - REFERENCE_TYPE. - -Fri Mar 4 04:46:05 1994 Mike Stump <mrs@cygnus.com> - - * call.c (build_method_call): Handle b->setHandler(A::handlerFn) - so that it is like b->setHandler(&A::handlerFn). Cures an `invalid - lvalue in unary `&''. - -Thu Mar 3 12:38:15 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y: Add precedence specification for START_DECLARATOR. - (type_quals): Move before primary. - (typename): Move before typed_declspecs, add 'typespec absdcl1' rule. - - * decl2.c (grokoptypename): Lose. - - * decl.c (grokdeclarator): Parse TYPE_EXPRs in the initial scan, - rather than waiting until later. - -Wed Mar 2 14:12:23 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (unary_expr): Use 'typename' in 'new' rules, rather - than expanding it inline. - (typename): Expand empty option of (former) absdcl inline. - (abs_or_notype_decl): Likewise. - (absdcl): Lose empty rule. - (conversion_declarator): New nonterminal for 'typename' of 'operator - typename'. - (operator_name): Use it instead of absdcl. - - * parse.y: Add precedence declarations for SCOPED_TYPENAME, - TYPEOF, and SIGOF. - (typed_declspecs): Accept typed_typespecs, rather than typespec - directly. Add rules with reserved_typespecquals. - (reserved_declspecs): Don't accept typespecqual_reserved at the - beginning of the list. The typed_declspecs rule will deal with this - omission. - (declmods): Accept nonempty_type_quals, rather than TYPE_QUAL - directly. - - * parse.y (direct_notype_declarator, - direct_after_type_declarator, direct_abstract_declarator): Split up - the declarator1 nonterminals to match the draft standard and avoid - ambiguities. - (new_type_id, new_declarator, direct_new_declarator, - new_member_declarator): New nonterminals to implement the subset of - 'typename' allowed in new expressions. - (unary_expr): Use new_type_id instead of typename. - (after_type_declarator1, absdcl1): Fix semantics of member pointers. - (abs_member_declarator, after_type_member_declarator): Lose. - - * parse.y (absdcl1): Don't require parens around - abs_member_declarator. - (abs_member_declarator): Lose see_typename from rules. - (after_type_member_declarator): Likewise. - - * tree.c (get_identifier_list): New function, containing code - previously duplicated in get_decl_list and list_hash_lookup_or_cons. - (get_decl_list): Use it. - (list_hash_lookup_or_cons): Likewise. - - * parse.y (typed_declspecs, declmods): It's not necessary to hash - the declspecs on class_obstack, so don't. This way typed_typespecs - can reduce to typed_declspecs. - -Wed Mar 2 14:29:18 1994 Jason Merrill <jason@cygnus.com> - - * cvt.c (build_up_reference): If we aren't checking visibility, - also allow base->derived conversions. - -Mon Feb 28 15:14:29 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * typeck.c (build_c_cast): Remove bogus hack when converting - to a reference type. - - * cp-tree.h (lang_decl::vbase_init_list, DECL_VBASE_INIT_LIST): - Removed, not used. - (lang_stype::methods, lang_decl::next_method): New fields. - (CLASSTYPE_METHODS, DECL_NEXT_METHOD): New macros. - * decl.c (duplicate_decls): Preserve DECL_NEXT_METHOD. - - * cp-tree.h, decl2.c (flag_vtable_hack): New flag. - * decl2.c (finish_vtable_vardecl): If flag_vtable_hack, - and !CLASSTYPE_INTERFACE_KNOWN, try to use the presence of - a non-inline virtual function to control emitting of vtables. - * class.c (finish_struct): Build CLASSTYPE_METHODS list. - * search.c (build_vbase_vtables_init): Don't assemble_external - (yet) if flag_vtable_hack. - * class.c (build_vfn_ref): Likewise. - -Mon Feb 28 14:54:13 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (component_decl): Don't include "typed_declspecs - declarator ';'" speedup, since it breaks enums. - -Fri Feb 25 15:43:44 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * class.c (finish_struct): Minor optimization for building - fn_fields list. - -Fri Feb 25 15:23:42 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (start_function): Fix detection of function overloading. - -Thu Feb 24 22:26:19 1994 Mike Stump <mrs@cygnus.com> - - * lex.c (check_newline): #pragma interface can take a string - argument, just like #pragma implementation. #pragma implementation - checks for garbage on the line, line #pragma interface does. Main - input files do not auto implement like named files, #pragma - implementation must be used explicitly. - -Thu Feb 24 17:09:01 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y (components): Handle list of one again. - (notype_components): Likewise. - (after_type_declarator1): Take maybe_raises out again. - - * gxxint.texi (Parser): Document additional r/r conflict. - -Wed Feb 23 14:42:55 1994 Jason Merrill <jason@deneb.cygnus.com> - - * gxxint.texi (Parser): Add node. - - * Makefile.in (stamp-parse): Update expected conflict count. - - * parse.y (various): Replace "declmods declarator" with "declmods - notype_declarator". The comment saying that "declmods declarator ';'" - corresponds to "int i;" was wrong; it corresponds to "const i;". - (component_decl): Add "typed_declspecs declarator ';'" rule; this - *does* correspond to "int i;". Change "declmods components" to - "declmods notype_components". - (components): Don't deal with a list of one anymore. - (notype_components): New nonterminal, corresponds to notype_declarator. - ({after_,no}type_component_decl{,0}): More new nonterminals. - ({after_,no}type_declarator): Fold in START_DECLARATOR token. - Eliminates four reduce/reduce conflicts. - - (expr): Depend on nontrivial_exprlist instead of nonnull_exprlist. - (nontrivial_exprlist): New nonterminal: A list of at least two - expr_no_commas's. - (nonnull_exprlist): Depend on nontrival_exprlist. - Eliminates four reduce/reduce conflicts. - - (named_class_head): Move intermediate code block into separate - nonterminal so that we can stick %prec EMPTY on it. - - Add more %prec EMPTY's to eliminate remaining shift/reduce - conflicts. - - (after_type_declarator): Add maybe_raises to fndecl rules. - (after_type_declarator_no_typename): Remove. - For correctness. - - Document remaining reduce/reduce conflicts. - -Tue Feb 22 12:10:32 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (get_base_distance): Only bash BINFO_INHERITANCE_CHAIN - (TYPE_BINFO (type)) if we care about the path. - - * tree.c (lvalue_p): A COND_EXPR is an lvalue if both of the - options are. - -Mon Feb 21 19:59:40 1994 Mike Stump <mrs@cygnus.com> - - * Makefile.in (mostlyclean): lex.c is a source file, don't - remove. - -Sat Feb 19 01:27:14 1994 Jason Merrill <jason@deneb.cygnus.com> - - * parse.y: Eliminate 20 shift/reduce conflicts. - -Fri Feb 18 11:49:42 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (type_unification): Add subr argument; if set, it means - that we are calling ourselves recursively, so a partial match is OK. - (unify): Support pointers to methods and functions. - (tsubst): Support method pointers. - * decl.c (build_ptrmemfunc_type): No longer static, so that - tsubst can get at it. - - * init.c (is_aggr_typedef): Pretend template type parms are - aggregates. - * decl2.c (build_push_scope): If cname refers to a template type - parm, just grin and nod. - - * call.c (build_overload_call_real): Pass subr argument to - type_unification. - * pt.c (do_function_instantiation): Likewise. - * class.c (instantiate_type): Likewise. - - * search.c (get_base_distance): If BINFO is a binfo, use it and - don't mess with its BINFO_INHERITANCE_CHAIN. - - * cvt.c (convert_to_reference): Fix temporary generation. - If ambiguous, return error_mark_node. - - * init.c (build_new): Put back some necessary code. - -Thu Feb 17 15:39:47 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_new): Deal with array types properly. - - * search.c (get_binfo): Become a shell for get_base_distance. - (get_binfo_recursive): Lose. - (get_base_distance_recursive): Find the path to the via_virtual base - that provides the most access. - (get_base_distance): Likewise. - - * parse.y (explicit_instantiation): Syntax is 'template class - A<int>', not 'template A<int>'. - - * typeck.c (convert_for_initialization): Remove bogus warning. - - * parse.y (datadef): Revert patch of Oct 27. - -Thu Feb 17 15:12:29 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * class.c (build_vfn_ref): Cast delta field to ptrdiff_type_node, - rather than integer_type_node. Does wonders for the Alpha. - -Thu Feb 17 13:36:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (build_ptrmemfunc_type): Make sure that the pmf type - goes onto the same obstack as its target type. - -Wed Feb 16 00:34:46 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cvt.c (convert_to_reference): If converting via constructor - on local level, go back to build_cplus_new approach. - - * tree.c (build_cplus_new): If with_cleanup_p, set cleanup slot - to error_mark_node to prevent expand_expr from building a cleanup - for this variable. - - * lex.c (default_assign_ref_body): Return *this from the memcpy - version, too. - - * decl.c (grok_reference_init): Just return if called with - error_mark_node, don't worry about initializing non-const reference - with temporary. - - * cvt.c (convert_to_reference): Do the right thing for - non-aggregate reference conversions, pedwarn when generating a - non-const reference to a temporary. - - * class.c (finish_struct): TYPE_HAS_COMPLEX_{INIT,ASSIGN}_REF and - TYPE_NEEDS_CONSTRUCTING all depend on TYPE_USES_VIRTUAL_BASECLASSES - again. - -Tue Feb 15 19:47:19 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_reference_init): Pawn off a lot of the work on - convert_to_reference. Generally do the right thing. - - * cvt.c (convert_to_reference): Conform to the initial comment; - i.e. don't create temps if decl != error_mark_node. Handle - cleanups better for temps that do get created. Don't pretend - that we can use an 'A' to initialize a 'const double &' just by - tacking on a NOP_EXPR. Support LOOKUP_SPECULATIVELY. - - * call.c (build_method_call): Set TREE_HAS_CONSTRUCTOR on - constructor calls. - -Mon Feb 14 14:50:17 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grok_reference_init): Make a temporary for initializing - const reference from constant expression. - -Mon Feb 14 11:31:31 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * cp-tree.h, decl.c (set_identifier_local_value): Deleted function. - * decl.c (pushdecl): Define decl in correct binding_level - (which isn't always the inner_binding_level). - - * cvt.c (build_up_reference): Don't ever call expand_aggr_init. - It's ugly, and I don't think it's the right thing to do. - - * cp-tree.h, class.c, decl.c, decl2.c, sp/search.c: - Remove NEW_CLASS_SCOPING, assuming it is always 1. - * decl.c (pop_decl_level): Removed; manually inlined. - -Sun Feb 13 19:04:56 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.h (candidate): Add basetypes field. - - * call.c (build_method_call): Do access checking after choosing a - function, not before. - - * Makefile.in (cvt.o, call.o, method.o): Depend on class.h. - (mostlyclean): Remove ../cc1plus. - -Fri Feb 11 11:52:26 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Don't allow adjusting access to a field - of a base class if a local field has the same name. - - * error.c (dump_type_prefix): Output basetype for METHOD_TYPEs. - -hu Jan 13 17:55:51 EST 1994 Gnanasekaran Swaminathan <gs4t@virginia.edu> - - * cp-tree.h (DESTRUCTOR_NAME_P): do not confuse AUTO_TEMP names - with destructor names when either NO_DOLLAR_IN_LABEL or - NO_DOT_IN_LABEL are not defined. - - Now `template <class T, T f(T&), const T*> class A {...}' works. - - * pt.c (grok_template_type): substitute template parm types - with actual types in complex type as well. - (coerce_template_parms): update the grok_template_type () - function call. - - * pt.c (tsubst): Traverse method list using DECL_CHAIN. - - * decl.c (grok_op_properties): Allow operator++/-- to have - default arguments. - - * typeck2.c (store_init_value): Don't abort when called to - initialize a type that needs constructing with a CONSTRUCTOR. - - * init.c (expand_aggr_init_1, CONSTRUCTOR case): If - store_init_value fails, build and expand an INIT_EXPR. If - store_init_value succeeds, call expand_decl_init. - -Fri Feb 11 02:49:23 1994 Mike Stump <mrs@cygnus.com> - - * class.c (build_vbase_path): Use complete_type_p instead of - resolves_to_fixed_type_p to determine if the virtual bases are in - their right place for the type of expr. Cures problem of thinking a - virtual base class is one place, when it is in fact someplace else. - -Fri Feb 11 00:26:46 1994 Mike Stump <mrs@cygnus.com> - - * init.c (resolve_offset_ref): Make sure we first convert to - intermediate type, if given, when dealing with members off `this'. - Solves an incorrrect `type `foo' is not a base type for type - `multiple'' when it is infact, a base type. - -Thu Feb 10 21:49:35 1994 Mike Stump <mrs@cygnus.com> - - * class.c (modify_other_vtable_entries): Use get_binfo, instead - of binfo_value. Solves problem with compiler giving a `base class - `B' ambiguous in binfo_value (compiler error)' on complex MI - herarchies, when a virtual function is first defied in a virtual - base class. - -Thu Feb 10 17:19:32 1994 Mike Stump <mrs@cygnus.com> - - * class.c (build_vbase_path): Don't complain about ambiguous - intermediate conversion when converting down to a virtual base - class, even if they might seem to be ambiguous. - -Thu Feb 10 12:18:26 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck2.c (build_functional_cast): #if 0 out constructor - inheritance code, improve error messages. - - * class.c (finish_base_struct): Complain about base with only - non-default constructors in derived class with no constructors. - - * decl.c (grokdeclarator): Fix detection of virtual new/delete. - -Wed Feb 9 22:02:32 1994 Mike Stump <mrs@cygnus.com> - - * search.c (build_mi_virtuals, add_mi_virtuals, - report_ambiguous_mi_virtuals): Removed unneeded code. - * class.c (finish_struct_bits): Likewise. - -Wed Feb 9 11:27:17 1994 Jason Merrill <jason@deneb.cygnus.com> - - * pt.c (end_template_instantiation): Push decl before - pop_from_top_level. - - * typeck2.c (build_m_component_ref): Make sure datum is of - aggregate type. - - * init.c (get_type_value): New function, returns - IDENTIFIER_TYPE_VALUE or IDENTIFIER_CLASS_TYPE_VALUE or NULL_TREE. - - * call.c (build_method_call): Don't die on call to destructor for - non-type. - - * decl.c (grokdeclarator): Complain about virtual op new and op - delete, make static virtuals unvirtual instead of unstatic. - - * typeck.c (build_c_cast): Also call default_conversion on - methods. - - * decl.c (grokdeclarator): Don't complain about anonymous - bitfields. - - * parse.y (simple_stmt, for loops): Move the continue point after - the cleanups. - - * class.c (finish_struct): Fix setting of - TYPE_HAS_COMPLEX_INIT_REF. - -Tue Feb 8 13:21:40 1994 Jason Merrill <jason@deneb.cygnus.com> - - * init.c (build_new): Deal with `new double (1)'. - - * class.c (finish_struct): TYPE_HAS_COMPLEX_*_REF are supersets of - TYPE_HAS_REAL_*_REF, but TYPE_HAS_COMPLEX_INIT_REF is independent of - TYPE_NEEDS_CONSTRUCTING. - - * decl.c (duplicate_decls): Propagate access decls. - - * typeck2.c (process_init_constructor): Accept empty_init_node - for initializing unions. - - * class.c, lex.c, cp-tree.h: Use - TYPE_HAS_COMPLEX_ASSIGN_REF where TYPE_HAS_REAL_ASSIGN_REF was used - before, use TYPE_HAS_COMPLEX_INIT_REF for TYPE_NEEDS_CONSTRUCTING in - some places. - - * decl.c (finish_decl): Don't complain about uninitialized const - if it was initialized before. - -Mon Feb 7 18:12:34 1994 Jason Merrill <jason@deneb.cygnus.com> - - * lex.c (default_assign_ref_body): Don't deal with vbases for - now. - - * decl.c (finish_decl): Fix reversed logic for objects and other - things that need to be constructed but have no initializer. - - * class.c (finish_struct): Don't set TYPE_HAS_* flags that are - set by grok_op_properties or finish_decl. - - * decl.c: Don't warn about extern redeclared inline unless - -Wextern-inline is given. - * decl2.c (lang_decode_option): Likewise. - * cp-tree.h: Likewise. - -Mon Feb 7 17:29:24 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (pushdecl_with_scope): Fix thinko. Add forward - declaration. - - * decl.c (pushdecl_with_scope): New function. - * decl.c (pushdecl_top_level): Use new function. - * decl.c (pushtag): Initialize newdecl. - * decl.c (pushtag): Push new type decl into correct scope. - -Mon Feb 7 14:42:03 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c, cvt.c, init.c, search.c, cp-tree.h: - Eradicate LOOKUP_PROTECTED_OK. - -Mon Feb 7 13:57:19 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * decl.c (pushtag, xref_tag), cp-tree.h: Add extra parameter - 'globalize' to signify implicit declarations. - * decl.c (globalize_nested_type, maybe_globalize_type): Removed. - * decl.c (set_identifier_type_value_with_scope): New function. - * decl.c (set_identifier_local_value): Simplify. - * spew.c (yylex, do_addr): Modify to return a _DEFN if a - forward declaration (followed by ';' and not preceded by 'friend'). - * class.c, decl.c, except.c, init.c, parse.y, - pt.c, search.c: Add new argument to calls to xref_tag and - pushtag. - -Mon Feb 7 00:22:59 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.h (ACCESSIBLY_UNIQUELY_DERIVED_P): New macro, means what - ACCESSIBLY_DERIVED_FROM_P meant before. - (ACCESSIBLY_DERIVED_FROM_P): Now disregards ambiguity. - - * cvt.c (build_up_reference): Call get_binfo with PROTECT == 1. - - * search.c (get_base_distance_recursive): Members and friends of - a class X can implicitly convert an X* to a pointer to a private or - protected immediate base class of X. - (get_binfo_recursive): Likewise. - (get_base_distance): Ignore ambiguity if PROTECT < 0. - (get_binfo): Lose multiple values of PROTECT. - (compute_access): Protected is OK if the start of the - search is an accessible base class of current_class_type. - - * method.c (build_opfncall): Do check access on operator new here. - - * decl.c (finish_function): Don't check access on operator new - here. - -Sun Feb 6 14:06:58 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (xref_tag): The base of a derived struct is NOT always - public. Duh. - - * pt.c (do_explicit_instantiation): New function, called from - parser to do explicit function instantiation. - (type_unification): Allow the args list to be terminated with - void_list_node. - (do_pending_expansions): Look at i->interface for non-member - templates. - - * parse.y (datadef): Move explicit_instantiation here. - (structsp): From here. - (datadef): Complain about `int;'. - -Sun Feb 6 12:33:18 1994 Per Bothner <bothner@kalessin.cygnus.com> - - * pt.c (end_template_instantiation), cp-tree.h: Remove unused - second parameter, and simplify first from a TREE_LIST where - we only care about its TREE_VALUE to just the value (an IDENTIFIER). - * pt.c (instantiate_member_templates): Simplify argument list - from a TREE_LIST to just an IDENTIFIER. - * lex.c (yyprint): PRE_PARSED_CLASS_DECL is now just an IDENTIFIER. - * parse.y (template_instantiate_once): Simplify accordingly. - * decl.c (inner_binding_level): New. Use various places to - simplify. - -Sun Feb 6 02:49:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck2.c (build_functional_cast): int() -> int(0). - -Sat Feb 5 00:53:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Don't do a bitwise copy for op= if the - class has a virtual function table. - - * typeck.c (convert_for_initialization): Restore warnings about - not using defined op=. Should really be my_friendly_aborts, I - s'pose. - -Fri Feb 4 14:21:00 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Tidy up conditions for doing bitwise - copies of objects. - - * decl.c (build_default_constructor): #if 0 out. - - * *: Eradicate TYPE_GETS_{ASSIGNMENT,ASSIGN_REF,CONST_ASSIGN_REF, - CONST_INIT_REF}, TYPE_HAS_REAL_CONSTRUCTOR. - - * decl.c (grokdeclarator): Don't return void_type_node for - friends being defined here. - - * init.c (perform_member_init): Only do the init if it's useful. - - * lex.c (default_copy_constructor_body): If we don't need to do - memberwise init, just call __builtin_memcpy. - (default_assign_ref_body): Likewise. - - * decl.c (grokdeclarator): If friendp && virtualp, friendp = 0. - -Fri Feb 4 13:02:56 1994 Mike Stump <mrs@cygnus.com> - - * lex.c (reinit_parse_for_method, cons_up_default_function): - Don't give warn_if_unknown_interface warning when it came from a - system header file. - * pt.c (end_template_decl, instantiate_template): Likewise. - * decl.c (start_decl): Likewise. - -Fri Feb 4 00:41:21 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Don't try to set TYPE_WAS_ANONYMOUS on - enums. - - * decl2.c (constructor_name_full): Use IS_AGGR_TYPE_CODE instead of - IS_AGGR_TYPE, since we don't know it's a type. - -Thu Feb 3 11:36:46 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokdeclarator): Don't complain about anonymous unions. - - * cp-tree.h (TYPE_WAS_ANONYMOUS): This struct was originally - anonymous, but had a name given to it by a typedef. - - * decl.c (grokdeclarator): When renaming an anonymous struct, set - TYPE_WAS_ANONYMOUS. - - * decl2.c (constructor_name_full): Use TYPE_WAS_ANONYMOUS. - - * cp-tree.h (DECL_UNDEFINED_FRIENDS): #if 0 out. - - * init.c (xref_friend): Don't set up DECL_UNDEFINED_FRIENDS. - (embrace_waiting_friends): Don't use DECL_UNDEFINED_FRIENDS. - - * decl.c (grokdeclarator): Set TYPE_NESTED_NAME properly on nested - anonymous structs that get typedef'd. - - * decl.c (grokdeclarator): Always return void_type_node for - friends. - - * error.c (dump_function_decl): Don't use DECL_CLASS_CONTEXT for - friends. - (dump_function_decl): Don't print out default args for - a function used in an expression. - - * decl.c (grokdeclarator): Give error on abstract declarator used - in an invalid context (i.e. `void (*)();'). - - * error.c (cp_line_of): Support _TYPE nodes. - (cp_file_of): Likewise. - - * cvt.c (build_up_reference): Don't abort if passed a SAVE_EXPR; - it can happen for the RHS of an assignment stmt where the LHS is - a COND_EXPR. - - * init.c (expand_aggr_init_1): Deal with bracketed initializer - lists properly. - - * class.c (finish_struct): Deal with enumerators and typedefs - again. - -Wed Feb 2 11:30:22 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Tidy up loop over fields. - - * errfn.c (cp_thing): Don't advance twice after a format. - - * class.c (finish_struct): Complain about needing a constructor - if a member has only non-default constructors, and don't try to - generate a default constructor. - - * decl.c (finish_decl): Also do the constructor thing if - TYPE_NEEDS_CONSTRUCTING is set (for arrays). - - * search.c (unuse_fields): New function: mark all fields in this - type unused. - (dfs_unuse_fields): Helper function. - - * class.c (pushclass): If the new class is the same as the old - class, still unuse the fields. - (unuse_fields): Move to search.c. - - * decl.c (grok_op_properties): Add friendp argument. - (grokfndecl): Pass it. - (start_method): Likewise. - - * decl2.c (delete_sanity): Add use_global_delete parameter to catch - ::delete calls. - - * parse.y (unary_expr): Pass new parameter to delete_sanity. - - * lex.c (default_copy_constructor_body): Don't choke if the union - has no fields. - (default_assign_ref_body): Likewise. - - * call.c (compute_conversion_costs_ansi): Do the right thing for - ellipsis matches. - - * decl.c (push_to_top_level): Optimize. - - * decl.c (start_function): Look for the lexical scope of a friend - in DECL_CLASS_CONTEXT. - - * init.c (do_friend): Set DECL_CLASS_CONTEXT on global friends. - -Tue Feb 1 15:59:24 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.h (TREE_GETS_PLACED_NEW): New macro. - - * init.c (init_init_processing): Don't assign BIN/BID to the - IDENTIFIER_GLOBAL_VALUEs of their respective operators. - (build_new): Check TREE_GETS_PLACED_NEW. - - * decl.c (grok_op_properties): Don't set TREE_GETS_NEW for a decl of - op new with placement, set TREE_GETS_PLACED_NEW. - - * cp-tree.h (ANON_UNION_P): New macro. Applies to decls. - - * class.c (finish_struct): Don't treat anonymous unions like - other aggregate members. Do synthesize methods for unions without - a name, since they may or may not be "anonymous unions". - - * decl2.c (grok_x_components): Wipe out memory of synthesized methods - in anonymous unions. - - * lex.c (default_copy_constructor_body): Support unions. - (default_assign_ref_body): Likewise. - -Mon Jan 31 12:07:30 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.h: Fix documentation of LOOKUP_GLOBAL, add prototypes. - - * error.c (args_as_string): New function (%A), like type_as_string - except NULL_TREE -> "..." - - * call.c (build_overload_call_real): Fix for new overloading. - - * decl.c (grok_op_properties): Set all of the TYPE_OVERLOADS_* flags - here. - - * parse.y (operator_name): Instead of here. - - * typeck2.c (build_functional_cast): Treat a TREE_LIST as a list - of functions. - - * call.c (build_overload_call_real): Support LOOKUP_SPECULATIVELY. - - * method.c (build_opfncall): Don't need to massage return value - any more, call build_overload_call with all flags. - - * typeck.c (build_x_binary_op): Put back speculative call to - build_opfncall. - (build_x_unary_op): Likewise. - (build_x_conditional_expr): Likewise. - -Mon Jan 31 10:00:30 1994 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_type_conversion_1): Change call to pedwarn into - warning, and conditionalize upon warn_cast_qual. - -Fri Jan 28 11:48:15 1994 Jason Merrill <jason@deneb.cygnus.com> - - * search.c (lookup_field): If xbasetype is a binfo, copy it to - avoid clobbering its inheritance info. - - * call.c (build_method_call): Don't overwrite basetype_path with - TYPE_BINFO (inst_ptr_basetype) if they have the same type. - - * search.c (compute_access): Fix handling of protected inheritance - and friendship with the enclosing class. - - * typeck2.c (store_init_value): Allow passing of TREE_CHAIN for - initialization of arbitrary variable. - - * typeck2.c (build_functional_cast): Only try calling a method if - one exists. - - * decl.c (grokdeclarator): Move handling of constructor syntax - initialization into first loop for generality. - (parmlist_is_random): Lose. - - * lex.c (cons_up_default_function): Set TREE_PARMLIST on arguments - to default function. - -Thu Jan 27 19:26:51 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (grokparms): Abort if we get called with something we don't - expect. - -Thu Jan 27 17:37:25 1994 Mike Stump <mrs@cygnus.com> - - * call.c (build_overload_call_real): Change argument complain to - flags to match style of rest of code. Pass it down to - build_function_call_real as necessary. - * call.c (build_overload_call, build_overload_call_maybe): Change - argument complain to flags to match style of rest of code. - * cp-tree.h (build_function_call_real): Added fourth flags - argument. - * cvt.c (convert_to_reference): Only give warning messages, if - LOOKUP_COMPLAIN is set. - * typeck.c (build_x_function_call): Change simple complain - argument to build_overload_call_maybe and build_overload_call, to - LOOKUP_COMPLAIN to match style of rest of code. - * typeck2.c (build_functional_cast): Likewise. - * typeck.c (build_function_call_real): Add flags, so that we can - not complain, if we don't want to complain. Complain about - arguments, if we are complaining, otherwise don't. - * typeck.c (build_function_call, build_function_call_maybe): - Stick in flags argument. - * typeck.c (build_x_binary_op, build_x_unary_op, - build_x_conditional_expr, build_x_compound_expr): Follow style of - build_x_indirect_ref, as it is more correct and more common. - -Thu Jan 27 14:36:20 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (build_method_call): Don't check for being called with - a pointer. - - * decl2.c (finish_file): Don't play with DECL_CLASS_CONTEXT for the - static initializer function. - - * init.c (build_member_call): Use convert_force here, too. - - * search.c (compute_access): Only treat static members specially - if they are referenced directly. - -Wed Jan 26 18:28:14 1994 Jason Merrill <jason@deneb.cygnus.com> - - * gxxint.texi (Access Control): New node. - - * search.c (current_scope): New function; returns whichever of - current_class_type and current_function_decl is the most nested. - (compute_access): Total overhaul to make it clearer and more - correct. Don't use the cache for now; in the only situation where - it was used before, it gained nothing. This frees up three of the - DECL_LANG_FLAGs for possible other use! - - * cp-tree.h: #if 0 out DECL_PUBLIC & friends. - - * typeck.c (build_component_ref_1): Don't check DECL_PUBLIC. - - * call.c (build_method_call): Use convert_force to cast `this' -- - rely on the access checking for the method itself. - - * init.c (is_friend): Do the nesting thing, handle types. I am - my own friend. - (is_friend_type): Become a shell for is_friend. - (add_friend): Never stick in ctype. - Why are the friendship functions in init.c, anyway? - -Wed Jan 26 17:50:00 1994 Mike Stump <mrs@cygnus.com> - - * cvt.c (build_type_conversion_1): Don't conditionalize call to - pedwarn upon pedantic. - -Wed Jan 26 17:20:46 1994 Mike Stump <mrs@cygnus.com> - - * cvt.c (convert_to_reference): Add 8.4.3 checking so that one - gets a warning if one tries to initialize a non-const & from a - non-lvalue. - * cvt.c (convert_to_reference): Use %P format for argument - numbers in warnings. - -Wed Jan 26 14:35:06 1994 Mike Stump <mrs@cygnus.com> - - * init.c (build_delete): Follow style in call.c to construct the - virtual call to the desctructor, as that code is right. Fixes a - problem of the compiler saying a pointer conversion is ambiguous. - -Wed Jan 26 11:28:14 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.h (VTABLE_NAME_P): Change other occurrence of - VTABLE_NAME_FORMAT to VTABLE_NAME. - - * *: s/visibility/access/g - -Tue Jan 25 18:39:12 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_modify_expr): Don't smash references if INIT_EXPR. - -Tue Jan 25 13:54:29 1994 Mike Stump <mrs@cygnus.com> - - * init.c (build_delete): Back out Jan 17th & 18th pacthes, as - they break libg++. - -Tue Jan 25 13:11:45 1994 Jason Merrill <jason@deneb.cygnus.com> - - * decl.c (duplicate_decls): Fix pointer arithmetic. - -Mon Jan 24 15:50:06 1994 Chip Salzenberg <chip@fin.uucp> - - [ cp-* changes propagated from c-* changes in 940114 snapshot ] - * cp-parse.y (maybe_attribute): Allow multiple __attribute__ - clauses on a declaration. - -Mon Jan 24 17:06:23 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Do synthesize methods for anon - structs, just not unions. - -Mon Jan 24 13:50:13 1994 Kung Hsu <kung@mexican.cygnus.com> - - * decl.c (xref_tag): handle anonymous nested type. - * decl.c (globalize_nested_type): add no globalize bit check. - * spew.c (hack_more_ids) : templated nested decl not push top - level. - - * parse.y : get rid of 'goto do_components'. It is much better - for debugging. - - * decl.c (is_anon_name): get rid of the function and use the - macro ANON_AGGRNAME_P. - * pt.c : ditto. - -Fri Jan 21 14:06:02 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct): Don't synthesize any methods for - anonymous structs/unions. - - * typeck.c (build_modify_expr): Don't treat pmf's as class objects. - -Thu Jan 20 18:56:46 1994 Jason Merrill <jason@deneb.cygnus.com> - - * method.c (build_opfncall): Call build_indirect_ref on - synthesized instance for operator delete. - - * pt.c (type_unification): Don't abort if called with a list of - types in ARGS. - - * class.c (instantiate_type): Deal with function templates. - -Thu Jan 20 16:55:35 1994 Jim Wilson <wilson@sphagnum.cygnus.com> - - * Makefile.in (CC): Default to cc not gcc. - -Thu Jan 20 13:47:54 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_modify_expr): Call constructor if appropriate. - - * decl.c (push_to_top_level): Clear out class-level bindings cache. - -Wed Jan 19 13:51:22 1994 Jason Merrill <jason@deneb.cygnus.com> - - * call.c (resolve_scope_to_name): Work recursively (previously only - looked down one level). - - * lex.c (do_pending_inlines): If we're still dealing with the last - batch of inlines, don't start working on a new one. - - * Makefile.in (stamp-parse): Update conflict count. - (TAGS): Fix. - - * parse.y (explicit_instantiation): New rule; implements - 'template A<int>' syntax (though not 'template foo(int)' yet). - (structsp): Add explicit_instantiation. - -Tue Jan 18 13:53:05 1994 Jason Merrill <jason@deneb.cygnus.com> - - * class.c (finish_struct, etc.): Simplify decision to synthesize - a destructor. - - * call.c, class.c, cp-tree.h, decl.c, init.c, - ptree.c, search.c, typeck.c, typeck2.c: Nuke - TYPE_NEEDS_CONSTRUCTOR (change all calls to TYPE_NEEDS_CONSTRUCTING). - * init.c (expand_aggr_init_1): Don't try non-constructor methods - of initializing objects. - (build_new): Don't try other methods if the constructor lookup fails. - - * class.c (finish_base_struct): Set cant_have_default_ctor and - cant_synth_copy_ctor properly. - (finish_struct): Likewise. - -Mon Jan 17 13:58:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * typeck.c (build_modify_expr_1): #if 0 out again. - (build_modify_expr): #if 0 out memberwise init code again. - - * lex.c (default_copy_constructor_body): Be const-correct. - (default_assign_ref_body): Likewise. - - * init.c (perform_member_init): Use TYPE_HAS_CONSTRUCTOR to decide - whether or not to use it, rather than TYPE_NEEDS_CONSTRUCTING. - (expand_aggr_init): Disable silent conversion from initializer list - to list of args for a constructor. - - * class.c (base_info): Lose needs_default_ctor. - (finish_base_struct): Likewise. - (finish_struct): Likewise. - - * decl.c (init_decl_processing): Don't turn off flag_default_inline - just because flag_no_inline is on. - (finish_decl): Use TYPE_HAS_CONSTRUCTOR to decide to use - constructor. - - * class.c (finish_struct): Synthesize default ctor whenever - allowed. - - * Makefile.in (TAGS): Don't try to run etags on cp-parse.y. - -Sat Jan 15 18:34:33 1994 Mike Stump <mrs@cygnus.com> - - * Makefile.in, configure: Handle the C++ front-end in a - subdirectory. - * cp-*: Move C++ front-end to cp/*. - -Fri Jan 14 14:09:37 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-typeck.c (build_function_call_real): Modify to match other - instances of taking the address of the function. - - * cp-class.c (finish_struct): Set TYPE_HAS_REAL_CONSTRUCTOR to 1 if - there are non-synthesized constructors. - Only set TYPE_NEEDS_CONSTRUCTOR if TYPE_HAS_REAL_CONSTRUCTOR. - Always generate copy constructor if possible. - - * cp-tree.h (lang_type): Add has_real_constructor bitfield. - (TYPE_HAS_REAL_CONSTRUCTOR): Define. - - * cp-lex.c (default_copy_constructor_body): Use init syntax - for all bases. - - * cp-type2.c (store_init_value): Only give error for initializer list - if TYPE_HAS_REAL_CONSTRUCTOR. - -Thu Jan 13 15:38:29 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.h (DECL_SYNTHESIZED): Add defn. - (lang_decl): Add synthesized bitfield to decl_flags. - - * cp-lex.c (cons_up_default_function): Use DECL_SYNTHESIZED to mark - artificial methods, rather than a line # of 0. - -Fri Jan 14 18:25:29 1994 Kung Hsu <kung@mexican.cygnus.com> - - * cp-decl (xref_tag): fix a bug in conflict type. - * cp-parse.y : add SCOPED_NAME for uninstantiated template nested - type reference. - * cp-spew.c (yylex) : generated SCOPED_NAME token. - * cp-lex.c (yyprint): handle SCOPED_NAME. - -Fri Jan 14 17:00:29 1994 Mike Stump <mrs@cygnus.com> - - * cp-decl.c (pushdecl): Revert patch from Jan 11 19:33:03, as it is - not right. - -Thu Jan 13 14:00:35 1994 Kung Hsu <kung@mexican.cygnus.com> - - * cp-decl2.c (grok_x_components): fix a bug that enum type does not - have type_flags. - -Thu Jan 13 11:39:34 1994 Mike Stump <mrs@cygnus.com> - - Ensure that all vtable pointers are initialized with all the right - values. - - * cp-class.c (is_normal): Changed to reflect new meaning of - CLASSTYPE_VFIELD_PARENT. - * cp-class.c (maybe_fixup_vptrs): Use of - CLASSTYPE_NEEDS_VIRTUAL_REINIT here is misguided. Use - BINFO_MODIFIED instead. - * cp-class.c (finish_struct): Changed to reflect new meaning of - CLASSTYPE_VFIELD_PARENT. - * cp-decl.c (get_binfo_from_vfield): Removed, unneeded now. - * cp-decl.c (finish_function): Use init_vtbl_ptrs, instead of open - coding it here. - * cp-init.c (init_vfields): Changed name to init_vtbl_ptrs, and - re-implement. - * cp-init.c (emit_base_init): Use new name init_vtbl_ptrs. - * cp-tree.h (vfield_parent): Changed to integer. - * cp-tree.h (CLASSTYPE_VFIELD_PARENT): Changed docs to reflect new - meaning. - * cp-tree.h (init_vtbl_ptrs): Added init_vtbl_ptrs. - -Wed Jan 12 18:24:16 1994 Kung Hsu <kung@mexican.cygnus.com> - - * cp-decl.c (xref_tag): re-implement globalize nested type. - * cp-decl2.c (grok_x_components): ditto. - * cp-parse.y: ditto. - * cp-tree.h (lang_type): add no_globalize bit in type_flags. - -Wed Jan 12 14:08:09 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (grokdeclarator): Don't set TREE_PUBLIC on friend - decls with a definition attached. - - * cp-typeck.c (build_modify_expr): Undo previous change in the case - of INIT_EXPRs. - -Tue Jan 11 19:33:03 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-typeck.c (build_modify_expr): Replace code for generating - assignment semantics for classes with an error. - (build_modify_expr_1): #if 0 out. - - * cp-decl.c (pushdecl): Patch bogus design of pushdecl - behavior for overloaded functions (it doesn't push anything). - - * cp-class.c (finish_struct): When generating default op=, - set TYPE_HAS_ASSIGNMENT. - -Mon Jan 10 18:48:06 1994 Mike Stump <mrs@cygnus.com> - - * cp-cvt.c (convert): Make {double, clashing enum} -> enum - invalid. - * cp-typeck.c (convert_for_assignment): Simplify. - * cp-decl2.c (warn_enum_clash): Removed. - * invoke.texi (-Wenum-clash): Removed. - * toplev.c (-Wenum-clash): Removed. - -Mon Jan 10 17:48:37 1994 Kung Hsu <kung@mexican.cygnus.com> - - * cp-decl.c (finish_decl): fix incorrect popclass call. - - * cp-decl.c (is_anon_name): new function, check whether the name - is anonymous name generated by compiler. - * cp-decl.c (grokdeclarator): allow nested SCOPE_REF - * cp-spew.c (hack_more_ids): handle nested type in template. - * cp-parse.y : handle nested type reference in uninstantiated - template. - * cp-call.c (build_method_call): handle uninstantiated template - case. - * cp-pt.c (search_nested_type_in_tmpl): new function, search nested - type in template. - * cp-pt.c (lookup_nested_type_by_name): new function, lookup nested - type by name. - * cp-pt.c (tsubst): handle nested type search by name. - -Mon Jan 10 14:32:18 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-init.c (build_member_call): Propagate qualifiers to new type. - - * cp-call.c (build_method_call): Count functions the new way. - -Fri Jan 7 19:03:26 1994 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (pushtag): Set DECL_ASSEMBLER_NAME for nested classes, - too. - -Tue Jan 4 16:45:51 1994 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-parse.y: change to handle whether to globalize nested class. - * cp-decl.c(xref_tag, maybe_globalize_type): Likewise. - -Mon Jan 3 22:22:32 1994 Gerald Baumgartner <gb@cygnus.com> - - * Makefile.in cp-call.c cp-class.c cp-cvt.c cp-decl.c cp-decl2.c - cp-error.c cp-init.c cp-lex.c cp-lex.h cp-method.c cp-parse.y - cp-spew.c cp-tree.c cp-tree.h cp-type2.c cp-typeck.c cp-xref.c - gplus.gperf toplev.c: Incorporated C++ signature extension. - * cp-sig.c: New file, contains most of signature processing. - * cp-hash.h: Regenerated from gplus.gperf. - - * gcc.1 g++.1: Added explanation for the `-fhandle-signatures' - and `-fno-handle-signatures' command line flags. - - * gcc.texi: Changed the last-modification date. - * invoke.texi: Added `-fhandle-signatures' in the list of - C++ language options. Added explanation for this option. - -Tue Dec 28 21:10:03 1993 Mike Stump <mrs@cygnus.com> - - * cp-init.c (expand_vec_init): Remove comptypes test, as it is too - harsh here. - -Tue Dec 28 13:42:22 1993 Mike Stump <mrs@cygnus.com> - - * cp-pt.c (do_pending_expansions): Decide to expand a template - member function, based upon it's class type, not the class type of - the first place it was declared. - -Tue Dec 28 05:42:31 1993 Mike Stump <mrs@cygnus.com> - - * cp-class.c (is_normal): New routine, use to determine when the - given binfo is the normal one. (The one that should have the simple - vtable name.) - * cp-class.c (modify_other_vtable_entries): Use DECL_ASSEMBLER_NAME - to check if two fndecls are `the same'. Sometimes this routine can - modify the main vtable, and normal should be 1, in that case, so use - is_normal() to determine if this is the main vtable for the class. - Don't recurse down virtual bases, as they are shared, and we take - care of them elsewhere. - * cp-class.c (modify_vtable_entries): If we have already updated the - vtable with the new virtual, don't do it again. - * cp-class.c (finish_struct): Set CLASSTYPE_VFIELD_PARENT as - appropriate. Do virtual function overriding in virtual bases, after - normal overriding, so that the base function list in DECL_VINDEX is - not overridden, before we have a chance to run through the list. - Use DECL_ASSEMBLER_NAME to check if two fndecls are `the same'. - Make sure we pass the right address into modify_vtable_entries. - * cp-tree.h (CLASSTYPE_VFIELD_PARENT): New field to indicate which - binfo is the one that has the vtable that we based our vtable on. - -Fri Dec 24 09:40:52 1993 Michael Tiemann <tiemann@blues.cygnus.com> - - * cp-typeck.c (c_expand_start_case): Use default_conversion to - convert expression from reference type if necessary. - -Wed Dec 22 17:58:43 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-typeck.c (build_unary_op): Make sure that it's a TREE_LIST before - trying to read its TREE_VALUE. - - * cp-class.c (finish_struct_methods): Clear DECL_IN_AGGR_P here. - (finish_struct): Instead of here. - -Tue Dec 21 14:34:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.c (list_hash_lookup_or_cons): Make sure the type doesn't - have TYPE_PTRMEMFUNC_P set before we try to build its - CLASSTYPE_ID_AS_LIST. - (get_decl_list): Likewise, when trying to read it. - - * cp-tree.h (VTABLE_NAME): No def with NO_{DOLLAR,DOT} defined. - (VTABLE_NAME_P): Use it instead of VTABLE_NAME_FORMAT. - -Mon Dec 20 13:35:03 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-typeck.c (rationalize_conditional_expr): New function. - (unary_complex_lvalue): Use it. - (build_modify_expr): Use it, since trying to do an ADDR_EXPR of it - with build_unary_op won't cut it. Don't wrap the COND_EXPR with a - SAVE_EXPR either. - - * cp-decl2.c (explicit_warn_return_type): Deleted variable. - (lang_decode_option): Set warn_return_type, not explicit_*, for - -Wreturn-type and -Wall. This is what rest_of_compilation uses to - decide if it should go into jump_optimize or not. - * cp-tree.h (explicit_warn_return_type): Deleted. - * cp-decl.c (grokdeclarator): Use warn_return_type, not explicit_*. - (finish_function): Also complain about no return in a non-void fn if - we're being pedantic (don't rely on use of -Wreturn-type). - -Fri Dec 17 15:45:46 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-decl.c (grokdeclarator): Forbid declaration of a function as - static if it's being done inside another function. - - * cp-search.c (compute_visibility): Check for friendship both ways. - -Fri Dec 17 14:28:25 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-cvt.c (build_default_binary_type_conversion): Make error - messages more helpful. - - * cp-error.c (op_as_string): New function, returns "operator ==" - given EQ_EXPR or suchlike. - -Fri Dec 17 13:28:11 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-call.c (print_n_candidates): New function. - (build_overload_call_real): Use it when we complain about a call - being ambiguous. - -Fri Dec 17 12:41:17 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-call.c (build_method_call): Fix checking for static call - context. - - * cp-method.c (build_opfncall): Call build_indirect_ref on argument - to operator new. - - * cp-init.c (build_new): Don't mess with rval when building - indirect ref. - -Thu Dec 16 16:48:05 1993 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-lex.c (default_assign_ref_body): add check when TYPE_NESTED_ - NAME(type) may not be exist. It's not a problem for old compiler. - -Thu Dec 16 14:46:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (CLASSTYPE_ALTERS_VISIBILITIES_P): Delete macro, it's - never used for anything. - (struct lang_type, member type_flags): Delete field - `alters_visibility', and up `dummy' by 1. - * cp-class.c (finish_base_struct): Delete code that copies the - setting of CLASSTYPE_ALTERS_VISIBILITIES_P. - (finish_struct): Delete code that sets it. - -Thu Dec 16 14:44:39 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c, cp-init.c, cp-typeck.c: Fix arguments to - build_method_call that I messed up before. - - * cp-search.c (get_base_distance): If protect > 1, allow immediate - private base. - - * cp-class.c (finish_base_struct): Set cant_synth_* correctly. - (finish_struct): Likewise. Well, nigh-correctly; it won't deal - properly with the case where a class contains an object of an - ambiguous base class which has a protected op=. Should be fixed - when the access control code gets overhauled. - (finish_struct_methods): Set TYPE_HAS_NONPUBLIC_* correctly. - -Thu Dec 16 12:17:06 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-lex.c (real_yylex): Turn the code back on that deals with - __FUNCTION__ and __PRETTY_FUNCTION__. Don't use lookup_name, to - avoid the ambiguity problems that led to it being turned off in the - first place. - - * cp-method.c (hack_identifier): Also check for a TYPE_PTRMEMFUNC_P - to see if something is a method. - -Wed Dec 15 18:35:58 1993 Mike Stump <mrs@cygnus.com> - - * cp-typeck.c (build_modify_expr): Avoid error messages on small - enum bit fields. - * cp-typeck.c (convert_for_assignment): Add missing argument to - cp_warning and cp_pedwarn calls. - -Wed Dec 15 18:25:32 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-parse.y (member_init): ANSI C++ doesn't forbid old-style base - initializers; it's just anachronistic. - - * cp-decl.c (finish_decl): Don't require external-linkage arrays - to have a complete type at declaration time when pedantic. - -Tue Dec 14 11:37:23 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (pushdecl): Don't set DECL_CONTEXT if it's already set. - - * cp-call.c (build_method_call): Don't dereference pointer given - as instance. - - * cp-decl.c (finish_function): Don't pass pointer to - build_method_call. - (finish_function): Likewise. - - * cp-typeck.c (build_x_function_call): Likewise. - - * cp-method.c (build_component_type_expr): Likewise. - - * cp-init.c (build_member_call): Likewise. - (build_new): Likewise. - -Mon Dec 13 18:04:33 1993 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-decl.c (xref_tag): fix regression created by changes made - in Dec. 7 1993. - * cp-decl.c (xref_defn_tag): fix parallel nested class problem. - -Fri Dec 10 12:40:25 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-call.c (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print - out the final evaluation of the function, so we can see if ELLIPSIS, - USER, and EVIL were set at the end. - - * cp-call.c (convert_harshness_ansi): When the parm isn't an lvalue, - only go for setting TRIVIAL_CODE if we are dealing with types that - are compatible. - -Thu Dec 9 18:27:22 1993 Mike Stump <mrs@cygnus.com> - - * cp-decl.c (flag_huge_objects): New flag to allow large objects. - * toplev.c (lang_options): Likewise. - * cp-decl2.c (flag_huge_objects, lang_f_options): Likewise. - * cp-decl.c (delta_type_node): New type for delta entries. - * cp-tree.h (delta_type_node): Likewise. - * cp-decl.c (init_decl_processing): Setup delta_type_node. - * cp-decl.c (init_decl_processing, build_ptrmemfunc_type): Use - delta_type_node instead of short_integer_type_node. - * cp-class.c (build_vtable_entry): Likewise. - -Thu Dec 9 16:19:05 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-tree.h (OPERATOR_TYPENAME_P): Define outside of - NO_{DOLLAR,DOT} macro checks, so it always gets defined. - (VTABLE_NAME_P): Define for NO_DOT && NO_DOLLAR_IN_LABEL. - -Wed Dec 8 17:38:06 1993 Mike Stump <mrs@cygnus.com> - - * cp-decl.c (finish_decl): Make sure things that can go into - "common", do go into common, if -fcommon is given. - -Wed Dec 8 13:01:54 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-call.c (print_harshness) [DEBUG_MATCHING]: New function. - (compute_conversion_costs_ansi) [DEBUG_MATCHING]: Print out - argument matching diagnostics to make instantly clear what the - compiler is doing. - - * cp-call.c (convert_harshness_ansi): If the parm isn't an lvalue, - then check to see if the penalty was increased due to - signed/unsigned mismatch, and use a TRIVIAL_CODE if it wasn't. - -Tue Dec 7 18:29:14 1993 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-decl.c (xref_tag, pushtag): Fix nested class search/resolution - problem. - -Tue Dec 7 16:09:34 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-class.c (finish_struct): Before synthesizing methods, if no - methods have yet been declared then set nonprivate_method. Don't - set non_private method after synthesizing a method. - - * cp-lex.c (extract_interface_info): If flag_alt_external_templates - is set, tie emitted code to the location of template instantiation, - rather than definition. - - * cp-tree.h: Declare flag_alt_external_templates. - - * cp-decl2.c (lang_decode_option): Support -falt-external-templates. - - * toplev.c (lang_options): Likewise. - -Mon Oct 4 12:50:02 1993 Chip Salzenberg <chip@fin.uucp> - - [changes propagated from 930810 snapshot] - * cp-decl.c (init_decl_processing): Make long long available for use - as SIZE_TYPE and PTRDIFF_TYPE. - (finish_decl): Allow file-scope static incomplete array. - (grokdeclarator): Don't pass on const and volatile fron function - value type to function type. - Warn here for volatile fn returning non-void type. - * cp-parse.y (attrib): Accept attributes `volatile' with alias - `noreturn', and `const'. - * cp-typeck.c (default_conversion): Don't lose const and volatile. - (build_binary_op_nodefault): Generate pedantic warning for comparison - of complete pointer type with incomplete pointer type. - (build_c_cast): Be careful that null pointer constant be INTEGER_CST. - -Tue Dec 7 10:46:48 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-init.c (expand_vec_init): When creating a temporary for copying - arrays, use the type of the source, not the target. - - * cp-cvt.c (convert): Pass an argument for errtype to - convert_to_reference. - - * cp-error.c (dump_expr, COMPONENT_REF & CALL_EXPR): Deal with - methods, -> and `this'. - -Mon Dec 6 17:12:33 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-error.c (parm_as_string): New function; returns `this' or arg - number. Corresponds to %P. - (dump_expr): Deal with method calls. - - * cp-cvt.c (convert_to_reference): Stop using warn_for_assignment. - * cp-typeck.c (convert_for_assignment): Likewise. - (warn_for_assignment): Lose. - -Mon Dec 6 11:33:35 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-call.c (ideal_candidate_ansi): Delete code that was never - doing anything useful. Instead, sort once, and DO NOT wipe - out any codes with EVIL_CODE, since that's what we use as a - marker for the end of the list of candidates. - - * cp-cvt.c (convert_to_aggr): Make sure to always set H_LEN. - -Mon Dec 6 12:49:17 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-init.c (get_aggr_from_typedef): New function, like - is_aggr_typedef but returns the _TYPE. - - * cp-call.c, cp-init.c, cp-method.c: Eradicate err_name. - -Sun Dec 5 18:12:48 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-lex.c (readescape): Pedwarn when a hex escape is out of range. - -Thu Nov 25 23:50:19 1993 Chip Salzenberg <chip@fin.uucp> - - Delay language context change until beginning of next decl. - - * cp-lex.h (c_header_level): Removed. - (pending_lang_change): Declared. - * cp-lex.c (c_header_level): Renamed from in_c_header, made static. - (pending_lang_change): Defined. - (check_newline): Rework code that recognizes line number and - filename changes. Instead of pushing and popping lang context, - increment and decrement pending_lang_change. - (do_pending_lang_change): Push and pop lang context according - to value of pending_lang_change. - * cp-parse.y (extdefs): Use lang_extdef instead of extdef. - (extdef): Same as extdef, but call do_pending_lang_change() first. - -Mon Nov 15 15:39:15 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-typeck.c (build_binary_op_nodefault): Warn for ordered - compare of ptr with 0 only if pedantic in both cases. - -Thu Nov 25 13:31:37 1993 Chip Salzenberg <chip@fin.uucp> - - Reinstate the below patch, which got lost in the Cygnus merge: - Tue Nov 23 13:59:24 1993 Hallvard B Furuseth (hbf@durin.uio.no) - * cp-parse.y (maybe_type_qual): Don't fail to set $$. - -Wed Nov 17 19:03:30 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-parse.y (attrib): Allow "ident(ident)" like the C front end. - -Fri Oct 22 20:43:37 1993 Paul Eggert <eggert@twinsun.com> - - * cp-lex.c (real_yylex): Diagnose floating point constants - that are too large. - -Wed Nov 17 19:10:37 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-type2.c (build_functional_cast): ARM page 16: When a class - and an object, function or enumerator are declared in the same - scope with the same name, the class name is hidden. - -Wed Nov 17 19:07:18 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-call.c (convert_harshness_ansi): Distinguish float, double, - and long double from each other when overloading. - (compute_conversion_costs_{ansi,old}, build_method_call, - build_overlay_call_real, convert_to_aggr): Always set and - always use H_LEN member of candidate structure. - -Mon Oct 11 23:10:53 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-decl.c (duplicate_decls): Note redeclarations of library - functions, and generate distinct warnings for them. - -Mon Oct 4 12:26:49 1993 Chip Salzenberg <chip@fin.uucp> - - Support format warnings in G++. - - * cp-tree.h: Protect against multiple inclusion. - Declare all public functions in c-common.c (copy from c-tree.h). - (STDIO_PROTO): Define. - (warn_format): Declare. - (record_format_info): Remove declaration. - * cp-decl.c (init_decl_processing): Call init_function_format_info. - * cp-decl2.c (lang_decode_option): Make "-Wall" include warn_format. - * cp-typeck.c (build_function_call_real): Call check_function_format. - (record_format_info): Remove -- obsolete stub. - -Sat Jul 24 12:04:29 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-decl.c (duplicate_decls): Don't warn for non-extern var decl - following an extern one (for -Wredundant-decls). - * cp-parse.y (primary): In statement expression case, if compstmt - returns something other than a BLOCK, return it unchanged. - -Thu Dec 2 20:44:58 1993 Chip Salzenberg <chip@fin.uucp> - - * cp-decl.c (warn_extern_redeclared_static): New function made - from code extracted from pushdecl. - (duplicate_decls, pushdecl): Call new function. - (lookup_name_current_level): Allow for IDENTIFIER_GLOBAL_VALUE - to be a TREE_LIST when function is declared in 'extern "C" {}'. - -Fri Dec 3 16:01:10 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-class.c (duplicate_tag_error): Use cp_error. - (finish_base_struct): Check for ambiguity with direct base, and don't - generate op= or copy ctor if it exists. - -Fri Dec 3 15:32:34 1993 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-init.c (expand_member_init): when initializer name is null, - don't try to build it now because emit_base_init will handle it. - -Fri Dec 3 12:28:59 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-lex.c (init_lex): Initialize input_filename to "<internal>" for - code such as ExceptionHandler::operator=. - -Fri Dec 3 10:32:08 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (grokdeclarator): Don't try to print out dname when - complaining about arrays of references if decl_context==TYPENAME, - since it will be null. - - * cp-decl2.c: Default to flag_ansi_overloading. - -Thu Dec 2 18:05:56 1993 Kung Hsu <kung@cirdan.cygnus.com> - - * cp-call.c (build_method_call): use binfo from instance if it's - different from binfo (basetype_path) passed from above. - -Wed Nov 17 19:14:29 1993 Chip Salzenberg <chip@fin.uucp> - - cp-error.c (dump_expr): Use unsigned chars to output a - TREE_REAL_CST in hex. - -Thu Dec 2 11:05:48 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-class.c (finish_struct): Fix typo in setting - cant_synth_asn_ref. - - * cp-tree.h (TYPE_NESTED_NAME): New macro, does - DECL_NESTED_TYPENAME (TYPE_NAME (NODE)). - - * cp-lex.c (default_copy_constructor_body): Change - DECL_NAME (TYPE_NAME (btype)) to TYPE_NESTED_NAME (btype). - (default_assign_ref_body): Likewise. - (default_copy_constructor_body): Call operator= explicitly for - base classes that have no constructor. - -Thu Dec 2 10:47:15 1993 Michael Tiemann <tiemann@blues.cygnus.com> - - * cp-call.c (build_method_call): If the instance variable is - converted to error_mark_node when we're trying to convert it to the - base type of a method we're looking up, return error_mark_node. - -Thu Dec 2 10:41:16 1993 Torbjorn Granlund <tege@cygnus.com> - - * cp-typeck.c (build_binary_op_nodefault): In *_DIV_EXPR *_MOD_EXPR - cases, tests for unsigned operands by peeking inside a NOP_EXPR. - -Wed Dec 1 13:33:34 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-call.c (compute_conversion_costs_ansi): Use the size of struct - harshness_code, not the size of short, for clearing out the - ansi_harshness. - - * cp-call.c (print_candidates): New function. - (build_method_call): When we had some candidates, but didn't get a - usable match, don't report that we got an error with the first - candidate. Instead, say there were no matches, and list the - candidates with print_candidates. In the second pass, make sure we - clear out ever_seen, so we can accurately count the number of - functions that qualified. - -Wed Dec 1 09:53:59 1993 Torbjorn Granlund <tege@cygnus.com> - - * cp-typeck.c (build_binary_op_nodefault): Shorten for *_MOD_EXPR - only if op1 is known to be != -1. - (build_binary_op_nodefault): Handle *_DIV_EXPR likewise. - -Tue Nov 30 14:07:26 1993 Brendan Kehoe <brendan@lisa.cygnus.com> - - * cp-method.c (hack_identifier): If the field itself is private, and - not from a private base class, say so. - -Mon Nov 29 03:00:56 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (grokdeclarator): Always warn on initialization of - const member. - -Wed Nov 24 00:49:35 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-class.c (finish_struct): Set TYPE_GETS_CONST_* properly. - (finish_base_struct): Set cant_synth_asn_ref properly. - - * cp-lex.c (cons_up_default_function): Add section for operator=. - (default_assign_ref_body): New function, mostly cribbed from - default_copy_constructor_body. - - * cp-class.c (base_info): Add members cant_synth_copy_ctor, - cant_synth_asn_ref, no_const_asn_ref. - (finish_base_struct): Update no_const_asn_ref, note that you should - update cant_synth_*, propagate TYPE_GETS_ASSIGN_REF. - (finish_struct): Add decls for cant_synth_*, no_const_asn_ref, and - initialize them properly. Set no_const_asn_ref properly. Set - cant_synth_* in some of the situations where they should be set. - Propagate TYPE_GETS_ASSIGN_REF. Use cant_synth_copy_ctor. Add call - to cons_up_default_function for operator=. - -Tue Nov 23 20:24:58 1993 Mike Stump <mrs@cygnus.com> - - * cp-cvt.c (convert_force): Add code to perform casting of pointer - to member function types. - * cp-typeck.c (build_ptrmemfunc): Add FORCE parameter to indicate - when the conversion should be done, regardless. - * cp-tree.h (build_ptrmemfunc): Likewise. - * cp-type2.c (digest_init): Likewise. - * cp-typeck.c (convert_for_assignment): Likewise. - -Tue Nov 23 18:06:58 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-error.c (dump_expr): Do the right thing for variables of - reference type. - - * cp-decl.c (grok_op_properties): Set TYPE_HAS_ASSIGN_REF - and its kin properly. - (xref_tag): Propagate TYPE_GETS_ASSIGN_REF. - -Tue Nov 23 12:26:13 1993 Mike Stump <mrs@cygnus.com> - - * cp-method.c (build_opfncall): Don't count pointer to member - functions as aggregates here, as we don't want to look up methods in - them. The compiler would core dump if we did, as they don't have - normal names. - * cp-typeck.c (build_indirect_ref): Improve wording on error - message. - -Mon Nov 22 14:22:23 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c (grok_op_properties): Allow operator?: with pedwarn - (since it's supported in other compiler bits). - - * cp-method.c (report_type_mismatch): Use cp_error; ignore err_name - argument. - - * cp-error.c (dump_function_decl): Don't print return type for - constructors and destructors. - - * cp-cvt.c (cp_convert_to_pointer): Import code from - convert_to_pointer so we can return error_mark_node in the case of an - error, and to allow more meaningful error messages. - (build_type_conversion): Don't go through void* when trying - to convert to a pointer type. - - * cp-decl.c (grokfndecl): Move call to grok_op_properties back - after grokclassfn so that it's dealing with the right decl. - (grok_op_properties): Don't assert !methodp for op new and op delete. - - * cp-init.c (build_delete): Don't use TYPE_BUILT_IN (there are now - no uses of it in the compiler). - - * cp-call.c (build_scoped_method_call): Fix for destructors of simple - types. - (build_method_call): Likewise. - -Fri Nov 19 12:59:38 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.c (count_functions): Abstraction function. - - * cp-call.c (build_overload_call_real): Deal with new overloading - properly, remove dead code. - - * gcc.c (default_compilers): Generate and use .ii files in the - intermediate stage of compiling C++ source. - -Fri Nov 19 11:26:09 1993 Jim Wilson <wilson@sphagnum.cygnus.com> - - * cp-expr.c (cplus_expand_expr): Make call_target a valid memory - address before using it, so it can be later safely compared. - -Fri Nov 12 15:30:27 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-pt.c (tsubst): Deal with new overloading. - - * cp-typeck.c (fntype_p): is the arg function type? - (comp_target_parms): pedwarn on conversion from (anything) to (...). - (build_x_function_call): Deal with new overloading. - - * cp-tree.c (decl_list_length): Deal with new overloading. - (decl_value_member): Like value_member, but for DECL_CHAINs. - - * cp-decl.c (duplicate_decls): Deal with new overloading. - (start_decl): Likewise. - - * cp-class.c (instantiate_type): Deal with new overloading. - - * cp-call.c (convert_harshness_ansi): Deal with new overloading. - (convert_harshness_old): Deal with new overloading. - (build_overload_call_real): Likewise. - -Mon Nov 8 13:50:49 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-tree.c (get_unique_fn): New function; returns FUNCTION_DECL - if unambiguous, NULL_TREE otherwise. - (get_first_fn): Returns the first appropriate FUNCTION_DECL. - (is_overloaded_fn): Returns whether or not the passed tree is - a function or list of functions. - - * cp-init.c (init_init_processing): use `get_first_fn' to find - the FUNCTION_DEFN for new and delete. - - * cp-decl.c (push_overloaded_decl): Use new overloading strategy, cut - code size in half (I spit on special cases). - -Tue Sep 7 20:03:33 1993 Jason Merrill <jason@deneb.cygnus.com> - - * cp-decl.c: Allow references and template type parameters as well diff --git a/gcc/cp/ChangeLog.Cygnus b/gcc/cp/ChangeLog.Cygnus deleted file mode 100755 index 6f43ebf..0000000 --- a/gcc/cp/ChangeLog.Cygnus +++ /dev/null @@ -1,93 +0,0 @@ -1999-01-15 Brendan Kehoe <brendan@cygnus.com> - - * typeck2.c (my_friendly_abort): Adjust where to report bugs as a - cygnus-local change. - -Fri Jan 15 12:32:23 1999 Dave Brolley (brolley@cygnus.com) - - * lex.c (lang_init_options): Fix typo: data->opts. - -Tue Oct 27 23:48:33 1998 Jeffrey A Law (law@cygnus.com) - - * lang-specs.h (default_compilers): Remove spurious backslashes. - -Thu Oct 8 11:00:50 1998 Nick Clifton <nickc@cygnus.com> - - * decl.c (duplicate_decls): Remove code to copy data_area - field of struct tree_decl. - -1998-08-27 Benjamin Kosnik <bkoz@cygnus.com> - - * decl.c (duplicate_decls): Add DECL_DATA_AREA bits. - - -Thu May 21 10:21:04 EDT 1998 Andrew MacLeod <amacleod@cygnus.com> - - * TODO: Updated the exception handling todo list a bit. - -Wed Feb 18 12:18:23 1998 Michael Tiemann <tiemann@axon.cygnus.com> - - * inc/new: (__THROW, __nothing): New macros, for making libgcc2 - functionality conditional on -fembedded-cxx. - (operator new*, operator delete*): Change type signatures to be - correct when -fembedded-cxx is specified. - - * new1.cc (operator new): Change `throw' to __THROW, so that file - can be compiled with -fembedded-cxx. Also, don't try to call - `handler' if __EMBEDDED_CXX__ is defined. - * new2.cc (operator new[], operator delete, operator delete []): - Likewise. - - * new.cc (nothrow): Only define if not __EMBEDDED_CXX__. - - * exception.cc: Contents of this file depend on __EMBEDDED_CXX__ - not being defined. - * tinfo2.cc: Ditto. - -Mon Feb 9 17:28:39 EST 1998 Andrew MacLeod <amacleod@torpedo.to.cygnus.com> - - * TODO: Add new file with G++ todo items. - -Tue Jan 27 12:04:38 1998 Jason Merrill <jason@yorick.cygnus.com> - - * decl2.c (lang_decode_option): -fembedded-cxx implies - -fvtable-thunks. - -Wed Jan 21 10:01:32 1998 Benjamin Kosnik <bkoz@rhino.cygnus.com> - - * inc/new: Remove orphan C-style end comment. - -1997-10-31 Brendan Kehoe <brendan@lisa.cygnus.com> - - * lex.c (embedded_pedwarn): Change its return type to void. - -1997-10-14 Brendan Kehoe <brendan@lisa.cygnus.com> - - Compliance with the Embedded C++ language specification. - By default we generate warnings; use -pedantic-errors to turn them - into hard errors. - * decl2.c (flag_embedded_cxx): Define. - (struct lang_f_options): Add -fembedded-cxx. - (lang_decode_option): If -fembedded-cxx, set FLAG_EMBEDDED_CXX, - and clear FLAG_RTTI and FLAG_EXCEPTIONS. - * lang-options.h: Add -fembedded-cxx and -fno-embedded-cxx. - * lang-specs.h: If -fembedded-cxx, define __EMBEDDED_CXX__. - * cp-tree.h (flag_embedded_cxx): Add decl. - * parse.y (base_class_list): Give a pedwarn about inheritance if - FLAG_EMBEDDED_CXX. - (base_class): Likewise for the base_class_access_list case. - - * lex.c (real_yylex): Give pedwarns if FLAG_EMBEDDED_CXX is true and - the token VALUE is any of TRY, CATCH, THROW, TEMPLATE, TYPENAME, - USING, or NAMESPACE. Likewise for DYNAMIC_CAST, STATIC_CAST, - REINTERPRET_CAST, CONST_CAST, or TYPEID. - (embedded_{template,eh,namespace}_error): New global variables to - make us only give a warning/error about each once. - (embedded_pedwarn): New fn to do the actual pedwarn. - * decl.c (grokdeclarator): Give a pedwarn for using mutable. - - * inc/new: Only make the EH stuff appear if !__EMBEDDED_CXX__. - (new, new[]) [__EMBEDDED_CXX__]: For placement versions, take out - the default throw. This particular bit is under discussion with - the EC++ committee currently. - diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in deleted file mode 100755 index bd2e939..0000000 --- a/gcc/cp/Make-lang.in +++ /dev/null @@ -1,317 +0,0 @@ -# Top level makefile fragment for GNU C++. -# Copyright (C) 1994, 1995, 1997, 1998, 1999 Free Software Foundation, Inc. - -#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 Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# This file provides the language dependent support in the main Makefile. -# Each language makefile fragment must provide the following targets: -# -# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap, -# foo.info, foo.dvi, -# foo.install-normal, foo.install-common, foo.install-info, foo.install-man, -# foo.uninstall, foo.distdir, -# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean, -# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4 -# -# where `foo' is the name of the language. -# -# It should also provide rules for: -# -# - making any compiler driver (eg: g++) -# - the compiler proper (eg: cc1plus) -# - define the names for selecting the language in LANGUAGES. -# -# Extra flags to pass to recursive makes. -CXX_FLAGS_TO_PASS = \ - "CXX_FOR_BUILD=$(CXX_FOR_BUILD)" \ - "CXXFLAGS=$(CXXFLAGS)" \ - "CXX_FOR_TARGET=$(CXX_FOR_TARGET)" - -# Actual names to use when installing a native compiler. -CXX_INSTALL_NAME = `t='$(program_transform_name)'; echo c++ | sed $$t` -GXX_INSTALL_NAME = `t='$(program_transform_name)'; echo g++ | sed $$t` -DEMANGLER_INSTALL_NAME = `t='$(program_transform_name)'; echo c++filt | sed $$t` - -# Actual names to use when installing a cross-compiler. -CXX_CROSS_NAME = `t='$(program_transform_cross_name)'; echo c++ | sed $$t` -GXX_CROSS_NAME = `t='$(program_transform_cross_name)'; echo g++ | sed $$t` -DEMANGLER_CROSS_NAME = `t='$(program_transform_cross_name)'; echo c++filt | sed $$t` - -# The name to use for the demangler program. -DEMANGLER_PROG = c++filt$(exeext) - -# Extra headers to install. -CXX_EXTRA_HEADERS = $(srcdir)/cp/inc/typeinfo $(srcdir)/cp/inc/exception \ - $(srcdir)/cp/inc/new $(srcdir)/cp/inc/new.h - -# Extra code to include in libgcc2. -CXX_LIB2FUNCS = tinfo.o tinfo2.o new.o opnew.o opnewnt.o opvnew.o opvnewnt.o \ - opdel.o opdelnt.o opvdel.o opvdelnt.o exception.o -CXX_LIB2SRCS = $(srcdir)/cp/new.cc $(srcdir)/cp/new1.cc $(srcdir)/cp/new2.cc \ - $(srcdir)/cp/exception.cc $(srcdir)/cp/tinfo.cc \ - $(srcdir)/cp/tinfo2.cc $(srcdir)/cp/tinfo.h -# -# Define the names for selecting c++ in LANGUAGES. -# Note that it would be nice to move the dependency on g++ -# into the C++ rule, but that needs a little bit of work -# to do the right thing within all.cross. -C++ c++: cc1plus$(exeext) - -# Tell GNU make to ignore these if they exist. -.PHONY: C++ c++ - -g++.c: $(srcdir)/gcc.c - -rm -f $@ - $(LN_S) $(srcdir)/gcc.c $@ - -g++spec.o: $(srcdir)/cp/g++spec.c - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/cp/g++spec.c - -# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added. -# It'd be nice if we could find an easier way to do this---rather than have -# to track changes to the toplevel gcc Makefile as well. -# We depend on g++.c last, to make it obvious where it came from. -g++.o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) g++.c \ - system.h prefix.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - $(DRIVER_DEFINES) \ - -DLANG_SPECIFIC_DRIVER \ - -c g++.c - -# Create the compiler driver for g++. -g++$(exeext): g++.o g++spec.o version.o choose-temp.o pexecute.o prefix.o mkstemp.o $(LIBDEPS) $(EXTRA_GCC_OBJS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ g++.o g++spec.o prefix.o \ - version.o choose-temp.o pexecute.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS) - -# Create a version of the g++ driver which calls the cross-compiler. -g++-cross$(exeext): g++$(exeext) - -rm -f g++-cross$(exeext) - cp g++$(exeext) g++-cross$(exeext) - -cxxmain.o: $(srcdir)/../libiberty/cplus-dem.c $(DEMANGLE_H) - rm -f cxxmain.c - $(LN_S) $(srcdir)/../libiberty/cplus-dem.c cxxmain.c - $(CC) -c -DMAIN $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \ - -DVERSION=\"$(version)\" cxxmain.c - -# Apparently OpenVM needs the -o to be at the beginning of the link line. -$(DEMANGLER_PROG): cxxmain.o underscore.o getopt.o getopt1.o $(LIBDEPS) - $(CC) -o $@ $(ALL_CFLAGS) $(LDFLAGS) \ - cxxmain.o underscore.o getopt.o getopt1.o $(LIBS) - -CXX_SRCS = $(srcdir)/cp/call.c $(srcdir)/cp/decl2.c \ - $(srcdir)/cp/except.c $(srcdir)/cp/input.c $(srcdir)/cp/pt.c \ - $(srcdir)/cp/spew.c $(srcdir)/cp/xref.c $(srcdir)/cp/class.c \ - $(srcdir)/cp/expr.c $(srcdir)/cp/lex.c \ - $(srcdir)/cp/ptree.c $(srcdir)/cp/tree.c $(srcdir)/cp/cvt.c \ - $(srcdir)/cp/errfn.c $(srcdir)/cp/rtti.c $(srcdir)/cp/method.c \ - $(srcdir)/cp/search.c $(srcdir)/cp/typeck.c $(srcdir)/cp/decl.c \ - $(srcdir)/cp/error.c $(srcdir)/cp/friend.c $(srcdir)/cp/init.c \ - $(srcdir)/cp/parse.y $(srcdir)/cp/sig.c $(srcdir)/cp/typeck2.c \ - $(srcdir)/cp/repo.c $(srcdir)/cp/semantics.c - -cc1plus$(exeext): $(P) $(CXX_SRCS) $(LIBDEPS) stamp-objlist c-common.o c-pragma.o \ - $(srcdir)/cp/cp-tree.h $(srcdir)/cp/cp-tree.def hash.o - cd cp; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) ../cc1plus$(exeext) -# -# Build hooks: - -c++.all.build: g++$(exeext) -c++.all.cross: g++-cross$(exeext) $(DEMANGLER_PROG) -c++.start.encap: g++$(exeext) -c++.rest.encap: $(DEMANGLER_PROG) - -c++.info: -c++.dvi: - -# C++ language-support library pieces for libgcc. -tinfo.o: cc1plus$(exeext) $(srcdir)/cp/tinfo.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/tinfo.cc -tinfo2.o: cc1plus$(exeext) $(srcdir)/cp/tinfo2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/tinfo2.cc -exception.o: cc1plus$(exeext) $(srcdir)/cp/exception.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c -fexceptions $(srcdir)/cp/exception.cc -new.o: cc1plus$(exeext) $(srcdir)/cp/new.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new.cc -opnew.o: cc1plus$(exeext) $(srcdir)/cp/new1.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new1.cc -DL_op_new -o opnew.o -opnewnt.o: cc1plus$(exeext) $(srcdir)/cp/new1.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new1.cc -DL_op_newnt -o opnewnt.o -opvnew.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_vnew -o opvnew.o -opvnewnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_vnewnt -o opvnewnt.o -opdel.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_delete -o opdel.o -opdelnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_delnt -o opdelnt.o -opvdel.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_vdel -o opvdel.o -opvdelnt.o: cc1plus$(exeext) $(srcdir)/cp/new2.cc - $(GCC_FOR_TARGET) $(LIBGCC2_CFLAGS) $(CXXFLAGS) $(INCLUDES) \ - -c $(srcdir)/cp/new2.cc -DL_op_vdelnt -o opvdelnt.o - -# We want to update cplib2.txt if any of the source files change... -cplib2.txt: $(CXX_LIB2SRCS) $(CXX_EXTRA_HEADERS) cplib2.ready - case " $(LANGUAGES) " in \ - *" "[cC]"++ "*) \ - echo $(CXX_LIB2FUNCS) > cplib2.new;; \ - *) \ - echo "" > cplib2.new;; \ - esac - mv -f cplib2.new cplib2.txt - -# Or if it would be different. -cplib2.ready: $(GCC_PASSES) $(LANGUAGES) $(LIBGCC2_DEPS) stmp-int-hdrs - @if [ -r cplib2.txt ]; then \ - case " $(LANGUAGES) " in \ - *" "[cC]"++ "*) \ - echo $(CXX_LIB2FUNCS) > cplib2.new;; \ - *) \ - echo "" > cplib2.new;; \ - esac; \ - if cmp -s cplib2.new cplib2.txt; then true; else \ - touch cplib2.ready; \ - fi; \ - rm -f cplib2.new; \ - else true ; \ - fi - @if [ -f cplib2.ready ]; then true; else \ - touch cplib2.ready; \ - fi -# -# Install hooks: -# cc1plus is installed elsewhere as part of $(COMPILERS). - -# Nothing to do here. -c++.install-normal: - -# Install the driver program as $(target)-g++ -# and also as either g++ (if native) or $(tooldir)/bin/g++. -c++.install-common: - -if [ -f cc1plus$(exeext) ] ; then \ - if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g++-cross$(exeext) $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - chmod a+x $(bindir)/$(GXX_CROSS_NAME)$(exeext); \ - rm -f $(bindir)/$(CXX_CROSS_NAME)$(exeext); \ - $(LN) $(bindir)/$(GXX_CROSS_NAME)$(exeext) $(bindir)/$(CXX_CROSS_NAME)$(exeext); \ - else \ - rm -f $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g++$(exeext) $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - chmod a+x $(bindir)/$(GXX_INSTALL_NAME)$(exeext); \ - rm -f $(bindir)/$(CXX_INSTALL_NAME)$(exeext); \ - $(LN) $(bindir)/$(GXX_INSTALL_NAME)$(exeext) $(bindir)/$(CXX_INSTALL_NAME)$(exeext); \ - fi ; \ - if [ x$(DEMANGLER_PROG) != x ] && [ -x "$(DEMANGLER_PROG)" ]; then \ - if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - chmod a+x $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext); \ - else \ - rm -f $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) $(DEMANGLER_PROG) $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - chmod a+x $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext); \ - fi ; \ - fi ; \ - fi - -c++.install-info: - -c++.install-man: $(srcdir)/cp/g++.1 - -if [ -f cc1plus$(exeext) ] ; then \ - if [ -f g++-cross$(exeext) ] ; then \ - rm -f $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ - chmod a-x $(man1dir)/$(GXX_CROSS_NAME)$(manext); \ - else \ - rm -f $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/cp/g++.1 $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ - chmod a-x $(man1dir)/$(GXX_INSTALL_NAME)$(manext); \ - fi; \ - else true; fi - -c++.uninstall: - -rm -rf $(bindir)/$(CXX_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(CXX_CROSS_NAME)$(exeext) - -rm -rf $(bindir)/$(GXX_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(GXX_CROSS_NAME)$(exeext) - -rm -rf $(bindir)/$(DEMANGLER_INSTALL_NAME)$(exeext) - -rm -rf $(bindir)/$(DEMANGLER_CROSS_NAME)$(exeext) - -rm -rf $(man1dir)/$(GXX_INSTALL_NAME)$(manext) - -rm -rf $(man1dir)/$(GXX_CROSS_NAME)$(manext) -# -# Clean hooks: -# A lot of the ancillary files are deleted by the main makefile. -# We just have to delete files specific to us. - -c++.mostlyclean: - -rm -f cp/*$(objext) $(DEMANGLER_PROG) -# CYGNUS LOCAL - Delete these files here instead of in realclean because they -# are now created in the build subdirectories. - -rm -f cp/parse.c cp/parse.h cp/parse.output cp/y.tab.c -c++.clean: - -rm -f cplib2.txt cplib2.ready -c++.distclean: - -rm -f cp/config.status cp/Makefile - -rm -f cp/parse.output - -rm -f g++.c -c++.extraclean: -c++.maintainer-clean: - -rm -f cp/parse.c cp/parse.h -# -# Stage hooks: -# The main makefile has already created stage?/cp. - -c++.stage1: stage1-start - -mv cp/*$(objext) stage1/cp -c++.stage2: stage2-start - -mv cp/*$(objext) stage2/cp -c++.stage3: stage3-start - -mv cp/*$(objext) stage3/cp -c++.stage4: stage4-start - -mv cp/*$(objext) stage4/cp -# -# Maintenance hooks: - -# This target creates the files that can be rebuilt, but go in the -# distribution anyway. It then copies the files to the distdir directory. -c++.distdir: - mkdir tmp/cp - mkdir tmp/cp/inc - cd cp ; $(MAKE) $(FLAGS_TO_PASS) $(CXX_FLAGS_TO_PASS) parse.c hash.h - cd cp; \ - for file in *[0-9a-zA-Z+]; do \ - $(LN) $$file ../tmp/cp; \ - done - cd cp/inc; \ - for file in *[0-9a-zA-Z+]; do \ - ln $$file ../../tmp/cp/inc >/dev/null 2>&1 \ - || cp $$file ../../tmp/cp/inc; \ - done diff --git a/gcc/cp/Makefile.in b/gcc/cp/Makefile.in deleted file mode 100755 index 6d0f450..0000000 --- a/gcc/cp/Makefile.in +++ /dev/null @@ -1,343 +0,0 @@ -# Makefile for GNU C++ compiler. -# Copyright (C) 1987, 88, 90-5, 1998 Free Software Foundation, Inc. - -#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 Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# The makefile built from this file lives in the language subdirectory. -# Its purpose is to provide support for: -# -# 1) recursion where necessary, and only then (building .o's), and -# 2) building and debugging cc1 from the language subdirectory, and -# 3) nothing else. -# -# The parent makefile handles all other chores, with help from the -# language makefile fragment, of course. -# -# The targets for external use are: -# all, TAGS, ???mostlyclean, ???clean. - -# Suppress smart makes who think they know how to automake Yacc files -.y.c: - -# It defines the c++ interface name. It should be changed when the -# c++ interface is changed. -INTERFACE = 1 - -# Variables that exist for you to override. -# See below for how to change them for certain systems. - -ALLOCA = - -# Various ways of specifying flags for compilations: -# CFLAGS is for the user to override to, e.g., do a bootstrap with -O2. -# BOOT_CFLAGS is the value of CFLAGS to pass -# to the stage2 and stage3 compilations -# XCFLAGS is used for most compilations but not when using the GCC just built. -XCFLAGS = -CFLAGS = -g -BOOT_CFLAGS = -O $(CFLAGS) -# These exists to be overridden by the x-* and t-* files, respectively. -X_CFLAGS = -T_CFLAGS = - -X_CPPFLAGS = -T_CPPFLAGS = - -CC = @CC@ -BISON = `if [ -f ../../bison/bison ] ; then echo ../../bison/bison -L $(srcdir)/../../bison/ ; else echo bison ; fi` -BISONFLAGS = -LEX = `if [ -f ../../flex/flex ] ; then echo ../../flex/flex ; else echo flex ; fi` -LEXFLAGS = -AR = ar -AR_FLAGS = rc -SHELL = /bin/sh -MAKEINFO = makeinfo -TEXI2DVI = texi2dvi - -# Define this as & to perform parallel make on a Sequent. -# Note that this has some bugs, and it seems currently necessary -# to compile all the gen* files first by hand to avoid erroneous results. -P = - -# This is used in the definition of SUBDIR_USE_ALLOCA. -# ??? Perhaps it would be better if it just looked for *gcc*. -OLDCC = cc - -# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. -# It omits XCFLAGS, and specifies -B./. -# It also specifies -B$(tooldir)/ to find as and ld for a cross compiler. -GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) - -# Tools to use when building a cross-compiler. -# These are used because `configure' appends `cross-make' -# to the makefile when making a cross-compiler. - -# We don't use cross-make. Instead we use the tools -# from the build tree, if they are available. -# program_transform_name and objdir are set by configure.in. -program_transform_name = -objdir = . - -target=@target@ -xmake_file=@dep_host_xmake_file@ -tmake_file=@dep_tmake_file@ -#version=`sed -e 's/.*\"\([^ \"]*\)[ \"].*/\1/' < $(srcdir)/version.c` -#mainversion=`sed -e 's/.*\"\([0-9]*\.[0-9]*\).*/\1/' < $(srcdir)/version.c` - -# Directory where sources are, from where we are. -srcdir = @srcdir@ -VPATH = @srcdir@ - -# Additional system libraries to link with. -CLIB= - -# Change this to a null string if obstacks are installed in the -# system library. -OBSTACK=obstack.o - -# Choose the real default target. -ALL=all - -# End of variables for you to override. - -# Definition of `all' is here so that new rules inserted by sed -# do not specify the default target. -all: all.indirect - -# This tells GNU Make version 3 not to put all variables in the environment. -.NOEXPORT: - -# sed inserts variable overrides after the following line. -####target overrides -@target_overrides@ -####host overrides -@host_overrides@ -####cross overrides -@cross_defines@ -@cross_overrides@ -####build overrides -@build_overrides@ - -# CYGNUS LOCAL --site -####site overrides -# END CYGNUS LOCAL -# -# Now figure out from those variables how to compile and link. - -all.indirect: Makefile ../cc1plus$(exeext) - -# IN_GCC tells obstack.h that we are using gcc's <stddef.h> file. -INTERNAL_CFLAGS = $(CROSS) -DIN_GCC @extra_c_flags@ - -# This is the variable actually used when we compile. -ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) - -# Likewise. -ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) - -# CYGNUS LOCAL: SUBDIR_USE_ALLOCA is different from FSF. -# Even if ALLOCA is set, don't use it if compiling with GCC. - -SUBDIR_OBSTACK = `if [ x$(OBSTACK) != x ]; then echo ../$(OBSTACK); else true; fi` -#SUBDIR_USE_ALLOCA = `case "${CC}" in "${OLDCC}") if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi ;; esac` -SUBDIR_USE_ALLOCA = `if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi` -SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi` - -# How to link with both our special library facilities -# and the system's installed libraries. -LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB) - -# Specify the directories to be searched for header files. -# Both . and srcdir are used, in that order, -# so that tm.h and config.h will be found in the compilation -# subdirectory rather than in the source directory. -INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)/../../include - -# Always use -I$(srcdir)/config when compiling. -.c.o: - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< - -# The only suffixes we want for implicit rules are .c and .o. -.SUFFIXES: -.SUFFIXES: .c .o - -# This tells GNU make version 3 not to export all the variables -# defined in this file into the environment. -.NOEXPORT: -# -# Lists of files for various purposes. - -# Language-specific object files for g++ - -CXX_OBJS = call.o decl.o errfn.o expr.o pt.o sig.o typeck2.o \ - class.o decl2.o error.o lex.o parse.o ptree.o rtti.o spew.o typeck.o cvt.o \ - except.o friend.o init.o method.o search.o semantics.o tree.o xref.o \ - repo.o @extra_cxx_objs@ - -# Language-independent object files. -OBJS = `cat ../stamp-objlist` ../c-common.o ../c-pragma.o ../hash.o -OBJDEPS = ../stamp-objlist ../c-common.o ../c-pragma.o ../hash.o - -compiler: ../cc1plus$(exeext) -../cc1plus$(exeext): $(P) $(OBJDEPS) $(CXX_OBJS) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(CXX_OBJS) $(LIBS) - -Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure - cd ..; $(SHELL) config.status - -native: config.status ../cc1plus$(exeext) -# -# Compiling object files from source files. - -# Note that dependencies on obstack.h are not written -# because that file is not part of GCC. - -# C++ language specific files. - -RTL_H = $(srcdir)/../rtl.h $(srcdir)/../rtl.def \ - $(srcdir)/../machmode.h $(srcdir)/../machmode.def -TREE_H = $(srcdir)/../tree.h $(srcdir)/../real.h $(srcdir)/../tree.def \ - $(srcdir)/../machmode.h $(srcdir)/../machmode.def -CXX_TREE_H = $(TREE_H) cp-tree.h cp-tree.def -EXPR_H = $(srcdir)/../expr.h ../insn-codes.h -# CYGNUS LOCAL: We build parse.[ch] in the build directory. -PARSE_H = parse.h -PARSE_C = parse.c - -parse.o : $(PARSE_C) $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h lex.h \ - $(srcdir)/../except.h $(srcdir)/../output.h $(srcdir)/../system.h \ - $(srcdir)/../toplev.h - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(BIG_SWITCHFLAG) \ - `echo $(PARSE_C) | sed 's,^\./,,'` - -CONFLICTS = expect 36 shift/reduce conflicts and 42 reduce/reduce conflicts. -# CYGNUS LOCAL build in build tree -$(PARSE_H) : $(PARSE_C) -$(PARSE_C) : $(srcdir)/parse.y - @echo $(CONFLICTS) - $(BISON) $(BISONFLAGS) -d -o $(PARSE_C) $(srcdir)/parse.y - grep '^#define[ ]*YYEMPTY' $(PARSE_C) >>$(PARSE_H) -# END CYGNUS LOCAL - -# We used to try to protect people from having to rerun gperf. But, -# the C front-end already requires this if c-parse.gperf is changed, -# so we should be consistent. -$(srcdir)/hash.h: $(srcdir)/gxx.gperf - gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word \ - '-k1,4,7,$$' $(srcdir)/gxx.gperf >$(srcdir)/hash.h - -spew.o : spew.c $(CONFIG_H) $(CXX_TREE_H) $(PARSE_H) $(srcdir)/../flags.h \ - lex.h $(srcdir)/../system.h $(srcdir)/../toplev.h -lex.o : lex.c $(CONFIG_H) $(CXX_TREE_H) \ - $(PARSE_H) input.c $(srcdir)/../flags.h hash.h lex.h \ - $(srcdir)/../c-pragma.h $(srcdir)/../system.h $(srcdir)/../toplev.h \ - $(srcdir)/../output.h $(srcdir)/../mbchar.h -decl.o : decl.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - lex.h decl.h $(srcdir)/../stack.h $(srcdir)/../output.h \ - $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h \ - $(srcdir)/../hash.h -decl2.o : decl2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - lex.h decl.h $(EXPR_H) $(srcdir)/../except.h \ - $(srcdir)/../output.h $(srcdir)/../except.h $(srcdir)/../system.h \ - $(srcdir)/../toplev.h $(srcdir)/../dwarf2out.h $(srcdir)/../dwarfout.h -typeck2.o : typeck2.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -typeck.o : typeck.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ - $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h -class.o : class.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -call.o : call.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -friend.o : friend.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -init.o : init.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ - $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h -method.o : method.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \ - $(srcdir)/../toplev.h -cvt.o : cvt.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h decl.h \ - $(srcdir)/../flags.h $(srcdir)/../toplev.h $(srcdir)/../convert.h -search.o : search.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../stack.h \ - $(srcdir)/../flags.h $(srcdir)/../system.h $(srcdir)/../toplev.h -tree.o : tree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -ptree.o : ptree.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h -rtti.o : rtti.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -except.o : except.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h $(RTL_H) \ - $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h -expr.o : expr.c $(CONFIG_H) $(CXX_TREE_H) $(RTL_H) $(srcdir)/../flags.h \ - $(EXPR_H) $(srcdir)/../system.h $(srcdir)/../toplev.h -xref.o : xref.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../input.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -pt.o : pt.c $(CONFIG_H) $(CXX_TREE_H) decl.h $(PARSE_H) lex.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -error.o : error.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \ - $(srcdir)/../toplev.h -errfn.o : errfn.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \ - $(srcdir)/../toplev.h -sig.o : sig.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../flags.h \ - $(srcdir)/../system.h $(srcdir)/../toplev.h -repo.o : repo.c $(CONFIG_H) $(CXX_TREE_H) $(srcdir)/../system.h \ - $(srcdir)/../toplev.h -semantics.o: semantics.c $(CONFIG_H) $(CXX_TREE_H) lex.h \ - $(srcdir)/../except.h $(srcdir)/../system.h $(srcdir)/../toplev.h - - -# -# These exist for maintenance purposes. - -# Update the tags table. -TAGS: force - cd $(srcdir) ; \ - etags *.c *.h ; \ - echo 'l' | tr 'l' '\f' >> TAGS ; \ - echo 'parse.y,0' >> TAGS ; \ - etags -a ../*.h ../*.c; - -.PHONY: TAGS - -force: - -g++FAQ.info: $(srcdir)/g++FAQ.texi - $(MAKEINFO) --no-split -o ./g++FAQ.info $(srcdir)/g++FAQ.texi - -# Preprocess the texi file so that the final document will have -# hyperlinks. -# It would be nice if texi2html could do something like this itself. - -# Assumption 1: the FAQ puts all http: and ftp: links in a @file{...}. -# Assumption 2: newsgroups are like @file{comp.foo} -# Assumption 3: email addresses match the regexp shown. - -g++FAQ.html: $(srcdir)/g++FAQ.texi - mkdir work - sed -e 's?@file{\([fth]*p://[^}]*\)}?@strong{<A HREF="\1">\1</A>}?' \ - -e 's?@file{\(comp\.[-a-z+.]*\)}?<A HREF="news:\1">\1</A>?' \ - -e 's?@file{\(gnu\.[-a-z+.]*\)}?<A HREF="news:\1">\1</A>?' \ - -e 's?\([.+a-zA-Z0-9-]*@@[.a-zA-Z0-9-]*[a-zA-Z0-9]\)?<A HREF="mailto:\1">\1</A>?' \ - $(srcdir)/g++FAQ.texi > work/g++FAQ.texi - cd work; texi2html g++FAQ.texi - mv work/*.html . - rm -r work - -# Make plain-text form. - -g++FAQ.txt: $(srcdir)/g++FAQ.texi - $(MAKEINFO) --no-split --no-headers -o - $(srcdir)/g++FAQ.texi |\ - sed '/^Concept Index/,$$d' > g++FAQ.txt - diff --git a/gcc/cp/NEWS b/gcc/cp/NEWS deleted file mode 100755 index 0cdcc22..0000000 --- a/gcc/cp/NEWS +++ /dev/null @@ -1,232 +0,0 @@ -*** Changes since EGCS 1.1: - -* Messages about non-conformant code that we can still handle ("pedwarns") - are now errors by default, rather than warnings. This can be reverted - with -fpermissive, and is overridden by -pedantic or -pedantic-errors. - -*** Changes in EGCS 1.1: - -* Namespaces are fully supported. The library has not yet been converted - to use namespace std, however, and the old std-faking code is still on by - default. To turn it off, you can use -fhonor-std. - -* Massive template improvements: - + member template classes are supported. - + template friends are supported. - + template template parameters are supported. - + local classes in templates are supported. - + lots of bugs fixed. - -* operator new now throws bad_alloc where appropriate. - -* Exception handling is now thread safe, and supports nested exceptions and - placement delete. Exception handling overhead on x86 is much lower with - GNU as 2.9. - -* protected virtual inheritance is now supported. - -* Loops are optimized better; we now move the test to the end in most - cases, like the C frontend does. - -* For class D derived from B which has a member 'int i', &D::i is now of - type 'int B::*' instead of 'int D::*'. - -* An _experimental_ new ABI for g++ can be turned on with -fnew-abi. The - current features of this are more efficient allocation of base classes - (including the empty base optimization), and more compact mangling of C++ - symbol names (which can be turned on separately with -fsquangle). This - ABI is subject to change without notice, so don't use it for anything - that you don't want to rebuild with every release of the compiler. - - As with all ABI-changing flags, this flag is for experts only, as all - code (including the library code in libgcc and libstdc++) must be - compiled with the same ABI. - -*** Changes in EGCS 1.0: - -* A public review copy of the December 1996 Draft of the ISO/ANSI C++ - standard is now available. See - - http://www.cygnus.com/misc/wp/ - - for more information. - -* g++ now uses a new implementation of templates. The basic idea is that - now templates are minimally parsed when seen and then expanded later. - This allows conformant early name binding and instantiation controls, - since instantiations no longer have to go through the parser. - - What you get: - - + Inlining of template functions works without any extra effort or - modifications. - + Instantiations of class templates and methods defined in the class - body are deferred until they are actually needed (unless - -fexternal-templates is specified). - + Nested types in class templates work. - + Static data member templates work. - + Member function templates are now supported. - + Partial specialization of class templates is now supported. - + Explicit specification of template parameters to function templates - is now supported. - - Things you may need to fix in your code: - - + Syntax errors in templates that are never instantiated will now be - diagnosed. - + Types and class templates used in templates must be declared - first, or the compiler will assume they are not types, and fail. - + Similarly, nested types of template type parameters must be tagged - with the 'typename' keyword, except in base lists. In many cases, - but not all, the compiler will tell you where you need to add - 'typename'. For more information, see - - http://www.cygnus.com/misc/wp/dec96pub/template.html#temp.res - - + Guiding declarations are no longer supported. Function declarations, - including friend declarations, do not refer to template instantiations. - You can restore the old behavior with -fguiding-decls until you fix - your code. - - Other features: - - + Default function arguments in templates will not be evaluated (or - checked for semantic validity) unless they are needed. Default - arguments in class bodies will not be parsed until the class - definition is complete. - + The -ftemplate-depth-NN flag can be used to increase the maximum - recursive template instantiation depth, which defaults to 17. If you - need to use this flag, the compiler will tell you. - + Explicit instantiation of template constructors and destructors is - now supported. For instance: - - template A<int>::A(const A&); - - Still not supported: - - + Member class templates. - + Template friends. - -* Exception handling support has been significantly improved and is on by - default. The compiler supports two mechanisms for walking back up the - call stack; one relies on static information about how registers are - saved, and causes no runtime overhead for code that does not throw - exceptions. The other mechanism uses setjmp and longjmp equivalents, and - can result in quite a bit of runtime overhead. You can determine which - mechanism is the default for your target by compiling a testcase that - uses exceptions and doing an 'nm' on the object file; if it uses __throw, - it's using the first mechanism. If it uses __sjthrow, it's using the - second. - - You can turn EH support off with -fno-exceptions. - -* RTTI support has been rewritten to work properly and is now on by default. - This means code that uses virtual functions will have a modest space - overhead. You can use the -fno-rtti flag to disable RTTI support. - -* On ELF systems, duplicate copies of symbols with 'initialized common' - linkage (such as template instantiations, vtables, and extern inlines) - will now be discarded by the GNU linker, so you don't need to use -frepo. - This support requires GNU ld from binutils 2.8 or later. - -* The overload resolution code has been rewritten to conform to the latest - C++ Working Paper. Built-in operators are now considered as candidates - in operator overload resolution. Function template overloading chooses - the more specialized template, and handles base classes in type deduction - and guiding declarations properly. In this release the old code can - still be selected with -fno-ansi-overloading, although this is not - supported and will be removed in a future release. - -* Standard usage syntax for the std namespace is supported; std is treated - as an alias for global scope. General namespaces are still not supported. - -* New flags: - - + New warning -Wno-pmf-conversion (don't warn about - converting from a bound member function pointer to function - pointer). - - + A flag -Weffc++ has been added for violations of some of the style - guidelines in Scott Meyers' _Effective C++_ books. - - + -Woverloaded-virtual now warns if a virtual function in a base - class is hidden in a derived class, rather than warning about - virtual functions being overloaded (even if all of the inherited - signatures are overridden) as it did before. - - + -Wall no longer implies -W. The new warning flag, -Wsign-compare, - included in -Wall, warns about dangerous comparisons of signed and - unsigned values. Only the flag is new; it was previously part of - -W. - - + The new flag, -fno-weak, disables the use of weak symbols. - -* Synthesized methods are now emitted in any translation units that need - an out-of-line copy. They are no longer affected by #pragma interface - or #pragma implementation. - -* __FUNCTION__ and __PRETTY_FUNCTION__ are now treated as variables by the - parser; previously they were treated as string constants. So code like - `printf (__FUNCTION__ ": foo")' must be rewritten to - `printf ("%s: foo", __FUNCTION__)'. This is necessary for templates. - -* local static variables in extern inline functions will be shared between - translation units. - -* -fvtable-thunks is supported for all targets, and is the default for - Linux with glibc 2.x (also called libc 6.x). - -* bool is now always the same size as another built-in type. Previously, - a 64-bit RISC target using a 32-bit ABI would have 32-bit pointers and a - 64-bit bool. This should only affect Irix 6, which was not supported in - 2.7.2. - -* new (nothrow) is now supported. - -* Synthesized destructors are no longer made virtual just because the class - already has virtual functions, only if they override a virtual destructor - in a base class. The compiler will warn if this affects your code. - -* The g++ driver now only links against libstdc++, not libg++; it is - functionally identical to the c++ driver. - -* (void *)0 is no longer considered a null pointer constant; NULL in - <stddef.h> is now defined as __null, a magic constant of type (void *) - normally, or (size_t) with -ansi. - -* The name of a class is now implicitly declared in its own scope; A::A - refers to A. - -* Local classes are now supported. - -* __attribute__ can now be attached to types as well as declarations. - -* The compiler no longer emits a warning if an ellipsis is used as a - function's argument list. - -* Definition of nested types outside of their containing class is now - supported. For instance: - - struct A { - struct B; - B* bp; - }; - - struct A::B { - int member; - }; - -* On the HPPA, some classes that do not define a copy constructor - will be passed and returned in memory again so that functions - returning those types can be inlined. - -*** The g++ team thanks everyone that contributed to this release, - but especially: - -* Joe Buck <jbuck@synopsys.com>, the maintainer of the g++ FAQ. -* Brendan Kehoe <brendan@cygnus.com>, who coordinates testing of g++. -* Jason Merrill <jason@cygnus.com>, the g++ maintainer. -* Mark Mitchell <mmitchell@usa.net>, who implemented member function - templates and explicit qualification of function templates. -* Mike Stump <mrs@wrs.com>, the previous g++ maintainer, who did most of - the exception handling work. diff --git a/gcc/cp/call.c b/gcc/cp/call.c deleted file mode 100755 index c478a50..0000000 --- a/gcc/cp/call.c +++ /dev/null @@ -1,4515 +0,0 @@ -/* Functions related to invoking methods and overloaded functions. - Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@cygnus.com) and - modified by Brendan Kehoe (brendan@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* High-level class interface. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "output.h" -#include "flags.h" -#include "rtl.h" -#include "toplev.h" - -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern int inhibit_warnings; -extern tree ctor_label, dtor_label; - -static tree build_new_method_call PROTO((tree, tree, tree, tree, int)); - -static tree build_field_call PROTO((tree, tree, tree, tree)); -static tree find_scoped_type PROTO((tree, tree, tree)); -static struct z_candidate * tourney PROTO((struct z_candidate *)); -static int joust PROTO((struct z_candidate *, struct z_candidate *, int)); -static int compare_ics PROTO((tree, tree)); -static tree build_over_call PROTO((struct z_candidate *, tree, int)); -static tree convert_like PROTO((tree, tree)); -static void op_error PROTO((enum tree_code, enum tree_code, tree, tree, - tree, char *)); -static tree build_object_call PROTO((tree, tree)); -static tree resolve_args PROTO((tree)); -static struct z_candidate * build_user_type_conversion_1 - PROTO ((tree, tree, int)); -static void print_z_candidates PROTO((struct z_candidate *)); -static tree build_this PROTO((tree)); -static struct z_candidate * splice_viable PROTO((struct z_candidate *)); -static int any_viable PROTO((struct z_candidate *)); -static struct z_candidate * add_template_candidate - PROTO((struct z_candidate *, tree, tree, tree, tree, int, - unification_kind_t)); -static struct z_candidate * add_template_candidate_real - PROTO((struct z_candidate *, tree, tree, tree, tree, int, - tree, unification_kind_t)); -static struct z_candidate * add_template_conv_candidate - PROTO((struct z_candidate *, tree, tree, tree, tree)); -static struct z_candidate * add_builtin_candidates - PROTO((struct z_candidate *, enum tree_code, enum tree_code, - tree, tree *, int)); -static struct z_candidate * add_builtin_candidate - PROTO((struct z_candidate *, enum tree_code, enum tree_code, - tree, tree, tree, tree *, tree *, int)); -static int is_complete PROTO((tree)); -static struct z_candidate * build_builtin_candidate - PROTO((struct z_candidate *, tree, tree, tree, tree *, tree *, - int)); -static struct z_candidate * add_conv_candidate - PROTO((struct z_candidate *, tree, tree, tree)); -static struct z_candidate * add_function_candidate - PROTO((struct z_candidate *, tree, tree, int)); -static tree implicit_conversion PROTO((tree, tree, tree, int)); -static tree standard_conversion PROTO((tree, tree, tree)); -static tree reference_binding PROTO((tree, tree, tree, int)); -static tree strip_top_quals PROTO((tree)); -static tree non_reference PROTO((tree)); -static tree build_conv PROTO((enum tree_code, tree, tree)); -static int is_subseq PROTO((tree, tree)); -static int is_properly_derived_from PROTO((tree, tree)); -static int maybe_handle_ref_bind PROTO((tree*, tree*)); -static void maybe_handle_implicit_object PROTO((tree*)); - -tree -build_vfield_ref (datum, type) - tree datum, type; -{ - tree rval; - - if (datum == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (datum)) == REFERENCE_TYPE) - datum = convert_from_reference (datum); - - if (! TYPE_USES_COMPLEX_INHERITANCE (type)) - rval = build (COMPONENT_REF, TREE_TYPE (CLASSTYPE_VFIELD (type)), - datum, CLASSTYPE_VFIELD (type)); - else - rval = build_component_ref (datum, DECL_NAME (CLASSTYPE_VFIELD (type)), NULL_TREE, 0); - - return rval; -} - -/* Build a call to a member of an object. I.e., one that overloads - operator ()(), or is a pointer-to-function or pointer-to-method. */ - -static tree -build_field_call (basetype_path, instance_ptr, name, parms) - tree basetype_path, instance_ptr, name, parms; -{ - tree field, instance; - - if (name == ctor_identifier || name == dtor_identifier) - return NULL_TREE; - - if (instance_ptr == current_class_ptr) - { - /* Check to see if we really have a reference to an instance variable - with `operator()()' overloaded. */ - field = IDENTIFIER_CLASS_VALUE (name); - - if (field == NULL_TREE) - { - cp_error ("`this' has no member named `%D'", name); - return error_mark_node; - } - - if (TREE_CODE (field) == FIELD_DECL || TREE_CODE (field) == VAR_DECL) - { - /* If it's a field, try overloading operator (), - or calling if the field is a pointer-to-function. */ - instance = build_component_ref_1 (current_class_ref, field, 0); - if (instance == error_mark_node) - return error_mark_node; - - if (TYPE_LANG_SPECIFIC (TREE_TYPE (instance))) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, instance, parms, NULL_TREE); - - if (TREE_CODE (TREE_TYPE (instance)) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == FUNCTION_TYPE) - return build_function_call (instance, parms); - else if (TREE_CODE (TREE_TYPE (TREE_TYPE (instance))) == METHOD_TYPE) - return build_function_call (instance, expr_tree_cons (NULL_TREE, current_class_ptr, parms)); - } - } - return NULL_TREE; - } - - /* Check to see if this is not really a reference to an instance variable - with `operator()()' overloaded. */ - field = lookup_field (basetype_path, name, 1, 0); - - /* This can happen if the reference was ambiguous or for access - violations. */ - if (field == error_mark_node) - return error_mark_node; - - if (field && (TREE_CODE (field) == FIELD_DECL || - TREE_CODE (field) == VAR_DECL)) - { - tree basetype; - tree ftype = TREE_TYPE (field); - - if (TREE_CODE (ftype) == REFERENCE_TYPE) - ftype = TREE_TYPE (ftype); - - if (TYPE_LANG_SPECIFIC (ftype)) - { - /* Make the next search for this field very short. */ - basetype = DECL_FIELD_CONTEXT (field); - instance_ptr = convert_pointer_to (basetype, instance_ptr); - - instance = build_indirect_ref (instance_ptr, NULL_PTR); - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, - build_component_ref_1 (instance, field, 0), - parms, NULL_TREE); - } - if (TREE_CODE (ftype) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (ftype)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (ftype)) == METHOD_TYPE) - { - /* This is a member which is a pointer to function. */ - tree ref - = build_component_ref_1 (build_indirect_ref (instance_ptr, - NULL_PTR), - field, LOOKUP_COMPLAIN); - if (ref == error_mark_node) - return error_mark_node; - return build_function_call (ref, parms); - } - } - else if (TREE_CODE (ftype) == METHOD_TYPE) - { - error ("invalid call via pointer-to-member function"); - return error_mark_node; - } - else - return NULL_TREE; - } - return NULL_TREE; -} - -static tree -find_scoped_type (type, inner_name, inner_types) - tree type, inner_name, inner_types; -{ - tree tags = CLASSTYPE_TAGS (type); - - while (tags) - { - /* The TREE_PURPOSE of an enum tag (which becomes a member of the - enclosing class) is set to the name for the enum type. So, if - inner_name is `bar', and we strike `baz' for `enum bar { baz }', - then this test will be true. */ - if (TREE_PURPOSE (tags) == inner_name) - { - if (inner_types == NULL_TREE) - return TYPE_MAIN_DECL (TREE_VALUE (tags)); - return resolve_scope_to_name (TREE_VALUE (tags), inner_types); - } - tags = TREE_CHAIN (tags); - } - - /* Look for a TYPE_DECL. */ - for (tags = TYPE_FIELDS (type); tags; tags = TREE_CHAIN (tags)) - if (TREE_CODE (tags) == TYPE_DECL && DECL_NAME (tags) == inner_name) - { - /* Code by raeburn. */ - if (inner_types == NULL_TREE) - return tags; - return resolve_scope_to_name (TREE_TYPE (tags), inner_types); - } - - return NULL_TREE; -} - -/* Resolve an expression NAME1::NAME2::...::NAMEn to - the name that names the above nested type. INNER_TYPES - is a chain of nested type names (held together by SCOPE_REFs); - OUTER_TYPE is the type we know to enclose INNER_TYPES. - Returns NULL_TREE if there is an error. */ - -tree -resolve_scope_to_name (outer_type, inner_stuff) - tree outer_type, inner_stuff; -{ - register tree tmp; - tree inner_name, inner_type; - - if (outer_type == NULL_TREE && current_class_type != NULL_TREE) - { - /* We first try to look for a nesting in our current class context, - then try any enclosing classes. */ - tree type = current_class_type; - - while (type && (TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE)) - { - tree rval = resolve_scope_to_name (type, inner_stuff); - - if (rval != NULL_TREE) - return rval; - type = DECL_CONTEXT (TYPE_MAIN_DECL (type)); - } - } - - if (TREE_CODE (inner_stuff) == SCOPE_REF) - { - inner_name = TREE_OPERAND (inner_stuff, 0); - inner_type = TREE_OPERAND (inner_stuff, 1); - } - else - { - inner_name = inner_stuff; - inner_type = NULL_TREE; - } - - if (outer_type == NULL_TREE) - { - tree x; - /* If we have something that's already a type by itself, - use that. */ - if (IDENTIFIER_HAS_TYPE_VALUE (inner_name)) - { - if (inner_type) - return resolve_scope_to_name (IDENTIFIER_TYPE_VALUE (inner_name), - inner_type); - return inner_name; - } - - x = lookup_name (inner_name, 0); - - if (x && TREE_CODE (x) == NAMESPACE_DECL) - { - x = lookup_namespace_name (x, inner_type); - return x; - } - return NULL_TREE; - } - - if (! IS_AGGR_TYPE (outer_type)) - return NULL_TREE; - - /* Look for member classes or enums. */ - tmp = find_scoped_type (outer_type, inner_name, inner_type); - - /* If it's not a type in this class, then go down into the - base classes and search there. */ - if (! tmp && TYPE_BINFO (outer_type)) - { - tree binfos = TYPE_BINFO_BASETYPES (outer_type); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tmp = resolve_scope_to_name (BINFO_TYPE (base_binfo), inner_stuff); - if (tmp) - return tmp; - } - tmp = NULL_TREE; - } - - return tmp; -} - -/* Returns nonzero iff the destructor name specified in NAME - (a BIT_NOT_EXPR) matches BASETYPE. The operand of NAME can take many - forms... */ - -int -check_dtor_name (basetype, name) - tree basetype, name; -{ - name = TREE_OPERAND (name, 0); - - /* Just accept something we've already complained about. */ - if (name == error_mark_node) - return 1; - - if (TREE_CODE (name) == TYPE_DECL) - name = TREE_TYPE (name); - else if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') - /* OK */; - else if (TREE_CODE (name) == IDENTIFIER_NODE) - { - if ((IS_AGGR_TYPE (basetype) && name == constructor_name (basetype)) - || (TREE_CODE (basetype) == ENUMERAL_TYPE - && name == TYPE_IDENTIFIER (basetype))) - name = basetype; - else - name = get_type_value (name); - } - else - my_friendly_abort (980605); - - if (name && TYPE_MAIN_VARIANT (basetype) == TYPE_MAIN_VARIANT (name)) - return 1; - return 0; -} - -/* Build a method call of the form `EXP->SCOPES::NAME (PARMS)'. - This is how virtual function calls are avoided. */ - -tree -build_scoped_method_call (exp, basetype, name, parms) - tree exp, basetype, name, parms; -{ - /* Because this syntactic form does not allow - a pointer to a base class to be `stolen', - we need not protect the derived->base conversion - that happens here. - - @@ But we do have to check access privileges later. */ - tree binfo, decl; - tree type = TREE_TYPE (exp); - - if (type == error_mark_node - || basetype == error_mark_node) - return error_mark_node; - - if (processing_template_decl) - { - if (TREE_CODE (name) == BIT_NOT_EXPR - && TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) - { - tree type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0); - if (type) - name = build_min_nt (BIT_NOT_EXPR, type); - } - name = build_min_nt (SCOPE_REF, basetype, name); - return build_min_nt (METHOD_CALL_EXPR, name, exp, parms, NULL_TREE); - } - - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - if (TREE_CODE (basetype) == TREE_VEC) - { - binfo = basetype; - basetype = BINFO_TYPE (binfo); - } - else - binfo = NULL_TREE; - - /* Check the destructor call syntax. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - /* We can get here if someone writes their destructor call like - `obj.NS::~T()'; this isn't really a scoped method call, so hand - it off. */ - if (TREE_CODE (basetype) == NAMESPACE_DECL) - return build_method_call (exp, name, parms, NULL_TREE, LOOKUP_NORMAL); - - if (! check_dtor_name (basetype, name)) - cp_error ("qualified type `%T' does not match destructor name `~%T'", - basetype, TREE_OPERAND (name, 0)); - - /* Destructors can be "called" for simple types; see 5.2.4 and 12.4 Note - that explicit ~int is caught in the parser; this deals with typedefs - and template parms. */ - if (! IS_AGGR_TYPE (basetype)) - { - if (TYPE_MAIN_VARIANT (type) != TYPE_MAIN_VARIANT (basetype)) - cp_error ("type of `%E' does not match destructor type `%T' (type was `%T')", - exp, basetype, type); - - return cp_convert (void_type_node, exp); - } - } - - if (! is_aggr_type (basetype, 1)) - return error_mark_node; - - if (! IS_AGGR_TYPE (type)) - { - cp_error ("base object `%E' of scoped method call is of non-aggregate type `%T'", - exp, type); - return error_mark_node; - } - - if (! binfo) - { - binfo = get_binfo (basetype, type, 1); - if (binfo == error_mark_node) - return error_mark_node; - if (! binfo) - error_not_base_type (basetype, type); - } - - if (binfo) - { - if (TREE_CODE (exp) == INDIRECT_REF) - decl = build_indirect_ref - (convert_pointer_to_real - (binfo, build_unary_op (ADDR_EXPR, exp, 0)), NULL_PTR); - else - decl = build_scoped_ref (exp, basetype); - - /* Call to a destructor. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - if (! TYPE_HAS_DESTRUCTOR (TREE_TYPE (decl))) - return cp_convert (void_type_node, exp); - - return build_delete (TREE_TYPE (decl), decl, integer_two_node, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, - 0); - } - - /* Call to a method. */ - return build_method_call (decl, name, parms, binfo, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); - } - return error_mark_node; -} - -/* We want the address of a function or method. We avoid creating a - pointer-to-member function. */ - -tree -build_addr_func (function) - tree function; -{ - tree type = TREE_TYPE (function); - - /* We have to do these by hand to avoid real pointer to member - functions. */ - if (TREE_CODE (type) == METHOD_TYPE) - { - tree addr; - - type = build_pointer_type (type); - - if (mark_addressable (function) == 0) - return error_mark_node; - - addr = build1 (ADDR_EXPR, type, function); - - /* Address of a static or external variable or function counts - as a constant */ - if (staticp (function)) - TREE_CONSTANT (addr) = 1; - - function = addr; - } - else - function = default_conversion (function); - - return function; -} - -/* Build a CALL_EXPR, we can handle FUNCTION_TYPEs, METHOD_TYPEs, or - POINTER_TYPE to those. Note, pointer to member function types - (TYPE_PTRMEMFUNC_P) must be handled by our callers. */ - -tree -build_call (function, result_type, parms) - tree function, result_type, parms; -{ - int is_constructor = 0; - tree tmp; - tree decl; - - function = build_addr_func (function); - - if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) - { - sorry ("unable to call pointer to member function here"); - return error_mark_node; - } - - if (TREE_CODE (function) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL) - decl = TREE_OPERAND (function, 0); - else - decl = NULL_TREE; - - if (decl && DECL_CONSTRUCTOR_P (decl)) - is_constructor = 1; - - if (decl) - my_friendly_assert (TREE_USED (decl), 990125); - - /* Don't pass empty class objects by value. This is useful - for tags in STL, which are used to control overload resolution. - We don't need to handle other cases of copying empty classes. */ - if (! decl || ! DECL_BUILT_IN (decl)) - for (tmp = parms; tmp; tmp = TREE_CHAIN (tmp)) - if (is_empty_class (TREE_TYPE (TREE_VALUE (tmp))) - && ! TREE_ADDRESSABLE (TREE_TYPE (TREE_VALUE (tmp)))) - { - tree t = make_node (RTL_EXPR); - TREE_TYPE (t) = TREE_TYPE (TREE_VALUE (tmp)); - RTL_EXPR_RTL (t) = const0_rtx; - RTL_EXPR_SEQUENCE (t) = NULL_RTX; - TREE_VALUE (tmp) = build (COMPOUND_EXPR, TREE_TYPE (t), - TREE_VALUE (tmp), t); - } - - function = build_nt (CALL_EXPR, function, parms, NULL_TREE); - TREE_HAS_CONSTRUCTOR (function) = is_constructor; - TREE_TYPE (function) = result_type; - TREE_SIDE_EFFECTS (function) = 1; - - return function; -} - -/* Build something of the form ptr->method (args) - or object.method (args). This can also build - calls to constructors, and find friends. - - Member functions always take their class variable - as a pointer. - - INSTANCE is a class instance. - - NAME is the name of the method desired, usually an IDENTIFIER_NODE. - - PARMS help to figure out what that NAME really refers to. - - BASETYPE_PATH, if non-NULL, contains a chain from the type of INSTANCE - down to the real instance type to use for access checking. We need this - information to get protected accesses correct. This parameter is used - by build_member_call. - - FLAGS is the logical disjunction of zero or more LOOKUP_ - flags. See cp-tree.h for more info. - - If this is all OK, calls build_function_call with the resolved - member function. - - This function must also handle being called to perform - initialization, promotion/coercion of arguments, and - instantiation of default parameters. - - Note that NAME may refer to an instance variable name. If - `operator()()' is defined for the type of that field, then we return - that result. */ - -tree -build_method_call (instance, name, parms, basetype_path, flags) - tree instance, name, parms, basetype_path; - int flags; -{ - tree basetype, instance_ptr; - -#ifdef GATHER_STATISTICS - n_build_method_call++; -#endif - - if (instance == error_mark_node - || name == error_mark_node - || parms == error_mark_node - || (instance != NULL_TREE && TREE_TYPE (instance) == error_mark_node)) - return error_mark_node; - - if (processing_template_decl) - { - /* We need to process template parm names here so that tsubst catches - them properly. Other type names can wait. */ - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - tree type = NULL_TREE; - - if (TREE_CODE (TREE_OPERAND (name, 0)) == IDENTIFIER_NODE) - type = get_aggr_from_typedef (TREE_OPERAND (name, 0), 0); - else if (TREE_CODE (TREE_OPERAND (name, 0)) == TYPE_DECL) - type = TREE_TYPE (TREE_OPERAND (name, 0)); - - if (type && TREE_CODE (type) == TEMPLATE_TYPE_PARM) - name = build_min_nt (BIT_NOT_EXPR, type); - } - - return build_min_nt (METHOD_CALL_EXPR, name, instance, parms, NULL_TREE); - } - - /* This is the logic that magically deletes the second argument to - operator delete, if it is not needed. */ - if (name == ansi_opname[(int) DELETE_EXPR] && list_length (parms)==2) - { - tree save_last = TREE_CHAIN (parms); - - /* get rid of unneeded argument */ - TREE_CHAIN (parms) = NULL_TREE; - if (build_method_call (instance, name, parms, basetype_path, - (LOOKUP_SPECULATIVELY|flags) & ~LOOKUP_COMPLAIN)) - { - /* If it finds a match, return it. */ - return build_method_call (instance, name, parms, basetype_path, flags); - } - /* If it doesn't work, two argument delete must work */ - TREE_CHAIN (parms) = save_last; - } - /* We already know whether it's needed or not for vec delete. */ - else if (name == ansi_opname[(int) VEC_DELETE_EXPR] - && TYPE_LANG_SPECIFIC (TREE_TYPE (instance)) - && ! TYPE_VEC_DELETE_TAKES_SIZE (TREE_TYPE (instance))) - TREE_CHAIN (parms) = NULL_TREE; - - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - if (parms) - error ("destructors take no parameters"); - basetype = TREE_TYPE (instance); - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); - - if (! check_dtor_name (basetype, name)) - cp_error - ("destructor name `~%T' does not match type `%T' of expression", - TREE_OPERAND (name, 0), basetype); - - if (! TYPE_HAS_DESTRUCTOR (complete_type (basetype))) - return cp_convert (void_type_node, instance); - instance = default_conversion (instance); - instance_ptr = build_unary_op (ADDR_EXPR, instance, 0); - return build_delete (build_pointer_type (basetype), - instance_ptr, integer_two_node, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0); - } - - return build_new_method_call (instance, name, parms, basetype_path, flags); -} - -/* New overloading code. */ - -struct z_candidate { - tree fn; - tree convs; - tree second_conv; - int viable; - tree basetype_path; - tree template; - tree warnings; - struct z_candidate *next; -}; - -#define IDENTITY_RANK 0 -#define EXACT_RANK 1 -#define PROMO_RANK 2 -#define STD_RANK 3 -#define PBOOL_RANK 4 -#define USER_RANK 5 -#define ELLIPSIS_RANK 6 -#define BAD_RANK 7 - -#define ICS_RANK(NODE) \ - (ICS_BAD_FLAG (NODE) ? BAD_RANK \ - : ICS_ELLIPSIS_FLAG (NODE) ? ELLIPSIS_RANK \ - : ICS_USER_FLAG (NODE) ? USER_RANK \ - : ICS_STD_RANK (NODE)) - -#define ICS_STD_RANK(NODE) TREE_COMPLEXITY (NODE) - -#define ICS_USER_FLAG(NODE) TREE_LANG_FLAG_0 (NODE) -#define ICS_ELLIPSIS_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) -#define ICS_THIS_FLAG(NODE) TREE_LANG_FLAG_2 (NODE) -#define ICS_BAD_FLAG(NODE) TREE_LANG_FLAG_3 (NODE) - -#define USER_CONV_CAND(NODE) \ - ((struct z_candidate *)WRAPPER_PTR (TREE_OPERAND (NODE, 1))) -#define USER_CONV_FN(NODE) (USER_CONV_CAND (NODE)->fn) - -int -null_ptr_cst_p (t) - tree t; -{ - if (t == null_node - || (integer_zerop (t) && TREE_CODE (TREE_TYPE (t)) == INTEGER_TYPE)) - return 1; - return 0; -} - -static tree -build_conv (code, type, from) - enum tree_code code; - tree type, from; -{ - tree t = build1 (code, type, from); - int rank = ICS_STD_RANK (from); - switch (code) - { - case PTR_CONV: - case PMEM_CONV: - case BASE_CONV: - case STD_CONV: - if (rank < STD_RANK) - rank = STD_RANK; - break; - - case QUAL_CONV: - if (rank < EXACT_RANK) - rank = EXACT_RANK; - - default: - break; - } - ICS_STD_RANK (t) = rank; - ICS_USER_FLAG (t) = ICS_USER_FLAG (from); - ICS_BAD_FLAG (t) = ICS_BAD_FLAG (from); - return t; -} - -static tree -non_reference (t) - tree t; -{ - if (TREE_CODE (t) == REFERENCE_TYPE) - t = TREE_TYPE (t); - return t; -} - -static tree -strip_top_quals (t) - tree t; -{ - if (TREE_CODE (t) == ARRAY_TYPE) - return t; - return TYPE_MAIN_VARIANT (t); -} - -/* Returns the standard conversion path (see [conv]) from type FROM to type - TO, if any. For proper handling of null pointer constants, you must - also pass the expression EXPR to convert from. */ - -static tree -standard_conversion (to, from, expr) - tree to, from, expr; -{ - enum tree_code fcode, tcode; - tree conv; - int fromref = 0; - - if (TREE_CODE (to) == REFERENCE_TYPE) - to = TREE_TYPE (to); - if (TREE_CODE (from) == REFERENCE_TYPE) - { - fromref = 1; - from = TREE_TYPE (from); - } - to = strip_top_quals (to); - from = strip_top_quals (from); - - if ((TYPE_PTRFN_P (to) || TYPE_PTRMEMFUNC_P (to)) - && expr && type_unknown_p (expr)) - { - expr = instantiate_type (to, expr, 0); - if (expr == error_mark_node) - return NULL_TREE; - from = TREE_TYPE (expr); - } - - fcode = TREE_CODE (from); - tcode = TREE_CODE (to); - - conv = build1 (IDENTITY_CONV, from, expr); - - if (fcode == FUNCTION_TYPE) - { - from = build_pointer_type (from); - fcode = TREE_CODE (from); - conv = build_conv (LVALUE_CONV, from, conv); - } - else if (fcode == ARRAY_TYPE) - { - from = build_pointer_type (TREE_TYPE (from)); - fcode = TREE_CODE (from); - conv = build_conv (LVALUE_CONV, from, conv); - } - else if (fromref || (expr && real_lvalue_p (expr))) - conv = build_conv (RVALUE_CONV, from, conv); - - if (from == to) - return conv; - - if ((tcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (to)) - && expr && null_ptr_cst_p (expr)) - { - conv = build_conv (STD_CONV, to, conv); - } - else if (tcode == POINTER_TYPE && fcode == POINTER_TYPE) - { - enum tree_code ufcode = TREE_CODE (TREE_TYPE (from)); - enum tree_code utcode = TREE_CODE (TREE_TYPE (to)); - - if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (from)), - TYPE_MAIN_VARIANT (TREE_TYPE (to)))) - ; - else if (utcode == VOID_TYPE && ufcode != OFFSET_TYPE - && ufcode != FUNCTION_TYPE) - { - from = build_pointer_type - (cp_build_qualified_type (void_type_node, - CP_TYPE_QUALS (TREE_TYPE (from)))); - conv = build_conv (PTR_CONV, from, conv); - } - else if (ufcode == OFFSET_TYPE && utcode == OFFSET_TYPE) - { - tree fbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (from)); - tree tbase = TYPE_OFFSET_BASETYPE (TREE_TYPE (to)); - - if (DERIVED_FROM_P (fbase, tbase) - && (same_type_p - (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (from))), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (to)))))) - { - from = build_offset_type (tbase, TREE_TYPE (TREE_TYPE (from))); - from = build_pointer_type (from); - conv = build_conv (PMEM_CONV, from, conv); - } - } - else if (IS_AGGR_TYPE (TREE_TYPE (from)) - && IS_AGGR_TYPE (TREE_TYPE (to))) - { - if (DERIVED_FROM_P (TREE_TYPE (to), TREE_TYPE (from))) - { - from = - cp_build_qualified_type (TREE_TYPE (to), - CP_TYPE_QUALS (TREE_TYPE (from))); - from = build_pointer_type (from); - conv = build_conv (PTR_CONV, from, conv); - } - } - - if (same_type_p (from, to)) - /* OK */; - else if (comp_ptr_ttypes (TREE_TYPE (to), TREE_TYPE (from))) - conv = build_conv (QUAL_CONV, to, conv); - else if (expr && string_conv_p (to, expr, 0)) - /* converting from string constant to char *. */ - conv = build_conv (QUAL_CONV, to, conv); - else if (ptr_reasonably_similar (TREE_TYPE (to), TREE_TYPE (from))) - { - conv = build_conv (PTR_CONV, to, conv); - ICS_BAD_FLAG (conv) = 1; - } - else - return 0; - - from = to; - } - else if (TYPE_PTRMEMFUNC_P (to) && TYPE_PTRMEMFUNC_P (from)) - { - tree fromfn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (from)); - tree tofn = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (to)); - tree fbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fromfn))); - tree tbase = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (tofn))); - - if (! DERIVED_FROM_P (fbase, tbase) - || ! same_type_p (TREE_TYPE (fromfn), TREE_TYPE (tofn)) - || ! compparms (TREE_CHAIN (TYPE_ARG_TYPES (fromfn)), - TREE_CHAIN (TYPE_ARG_TYPES (tofn))) - || CP_TYPE_QUALS (fbase) != CP_TYPE_QUALS (tbase)) - return 0; - - from = cp_build_qualified_type (tbase, CP_TYPE_QUALS (fbase)); - from = build_cplus_method_type (from, TREE_TYPE (fromfn), - TREE_CHAIN (TYPE_ARG_TYPES (fromfn))); - from = build_ptrmemfunc_type (build_pointer_type (from)); - conv = build_conv (PMEM_CONV, from, conv); - } - else if (tcode == BOOLEAN_TYPE) - { - if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE - || fcode == POINTER_TYPE || TYPE_PTRMEMFUNC_P (from))) - return 0; - - conv = build_conv (STD_CONV, to, conv); - if (fcode == POINTER_TYPE - || (TYPE_PTRMEMFUNC_P (from) && ICS_STD_RANK (conv) < PBOOL_RANK)) - ICS_STD_RANK (conv) = PBOOL_RANK; - } - /* We don't check for ENUMERAL_TYPE here because there are no standard - conversions to enum type. */ - else if (tcode == INTEGER_TYPE || tcode == BOOLEAN_TYPE - || tcode == REAL_TYPE) - { - if (! (INTEGRAL_CODE_P (fcode) || fcode == REAL_TYPE)) - return 0; - conv = build_conv (STD_CONV, to, conv); - - /* Give this a better rank if it's a promotion. */ - if (to == type_promotes_to (from) - && ICS_STD_RANK (TREE_OPERAND (conv, 0)) <= PROMO_RANK) - ICS_STD_RANK (conv) = PROMO_RANK; - } - else if (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) - && DERIVED_FROM_P (to, from)) - { - if (TREE_CODE (conv) == RVALUE_CONV) - conv = TREE_OPERAND (conv, 0); - conv = build_conv (BASE_CONV, to, conv); - } - else - return 0; - - return conv; -} - -/* Returns the conversion path from type FROM to reference type TO for - purposes of reference binding. For lvalue binding, either pass a - reference type to FROM or an lvalue expression to EXPR. - - Currently does not distinguish in the generated trees between binding to - an lvalue and a temporary. Should it? */ - -static tree -reference_binding (rto, rfrom, expr, flags) - tree rto, rfrom, expr; - int flags; -{ - tree conv; - int lvalue = 1; - tree to = TREE_TYPE (rto); - tree from = rfrom; - int related; - - if (TREE_CODE (to) == FUNCTION_TYPE && expr && type_unknown_p (expr)) - { - expr = instantiate_type (to, expr, 0); - if (expr == error_mark_node) - return NULL_TREE; - from = TREE_TYPE (expr); - } - - if (TREE_CODE (from) == REFERENCE_TYPE) - from = TREE_TYPE (from); - else if (! expr || ! real_lvalue_p (expr)) - lvalue = 0; - - related = (same_type_p (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from)) - || (IS_AGGR_TYPE (to) && IS_AGGR_TYPE (from) - && DERIVED_FROM_P (to, from))); - - if (lvalue && related && at_least_as_qualified_p (to, from)) - { - conv = build1 (IDENTITY_CONV, from, expr); - - if (same_type_p (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from))) - conv = build_conv (REF_BIND, rto, conv); - else - { - conv = build_conv (REF_BIND, rto, conv); - ICS_STD_RANK (conv) = STD_RANK; - } - } - else - conv = NULL_TREE; - - if (! conv) - { - conv = standard_conversion (to, rfrom, expr); - if (conv) - { - conv = build_conv (REF_BIND, rto, conv); - - /* Bind directly to a base subobject of a class rvalue. Do it - after building the conversion for proper handling of ICS_RANK. */ - if (TREE_CODE (TREE_OPERAND (conv, 0)) == BASE_CONV) - TREE_OPERAND (conv, 0) = TREE_OPERAND (TREE_OPERAND (conv, 0), 0); - } - if (conv - && ((! (CP_TYPE_CONST_NON_VOLATILE_P (to) - && (flags & LOOKUP_NO_TEMP_BIND) == 0)) - /* If T1 is reference-related to T2, cv1 must be the same - cv-qualification as, or greater cv-qualification than, - cv2; otherwise, the program is ill-formed. */ - || (related && !at_least_as_qualified_p (to, from)))) - ICS_BAD_FLAG (conv) = 1; - } - - return conv; -} - -/* Returns the implicit conversion sequence (see [over.ics]) from type FROM - to type TO. The optional expression EXPR may affect the conversion. - FLAGS are the usual overloading flags. Only LOOKUP_NO_CONVERSION is - significant. */ - -static tree -implicit_conversion (to, from, expr, flags) - tree to, from, expr; - int flags; -{ - tree conv; - struct z_candidate *cand; - - if (TREE_CODE (to) == REFERENCE_TYPE) - conv = reference_binding (to, from, expr, flags); - else - conv = standard_conversion (to, from, expr); - - if (conv) - ; - else if (expr != NULL_TREE - && (IS_AGGR_TYPE (non_reference (from)) - || IS_AGGR_TYPE (non_reference (to))) - && (flags & LOOKUP_NO_CONVERSION) == 0) - { - cand = build_user_type_conversion_1 - (to, expr, LOOKUP_ONLYCONVERTING); - if (cand) - conv = cand->second_conv; - if ((! conv || ICS_BAD_FLAG (conv)) - && TREE_CODE (to) == REFERENCE_TYPE - && (flags & LOOKUP_NO_TEMP_BIND) == 0) - { - cand = build_user_type_conversion_1 - (TYPE_MAIN_VARIANT (TREE_TYPE (to)), expr, LOOKUP_ONLYCONVERTING); - if (cand) - { - if (!CP_TYPE_CONST_NON_VOLATILE_P (TREE_TYPE (to))) - ICS_BAD_FLAG (cand->second_conv) = 1; - if (!conv || (ICS_BAD_FLAG (conv) - > ICS_BAD_FLAG (cand->second_conv))) - conv = build_conv (REF_BIND, to, cand->second_conv); - } - } - } - - return conv; -} - -/* Add a new entry to the list of candidates. Used by the add_*_candidate - functions. */ - -static struct z_candidate * -add_candidate (candidates, fn, convs, viable) - struct z_candidate *candidates; - tree fn, convs; - int viable; -{ - struct z_candidate *cand - = (struct z_candidate *) scratchalloc (sizeof (struct z_candidate)); - - cand->fn = fn; - cand->convs = convs; - cand->second_conv = NULL_TREE; - cand->viable = viable; - cand->basetype_path = NULL_TREE; - cand->template = NULL_TREE; - cand->warnings = NULL_TREE; - cand->next = candidates; - - return cand; -} - -/* Create an overload candidate for the function or method FN called with - the argument list ARGLIST and add it to CANDIDATES. FLAGS is passed on - to implicit_conversion. */ - -static struct z_candidate * -add_function_candidate (candidates, fn, arglist, flags) - struct z_candidate *candidates; - tree fn, arglist; - int flags; -{ - tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (fn)); - int i, len; - tree convs; - tree parmnode = parmlist; - tree argnode = arglist; - int viable = 1; - - /* The `this' and `in_chrg' arguments to constructors are not considered - in overload resolution. */ - if (DECL_CONSTRUCTOR_P (fn)) - { - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) - { - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); - } - } - - len = list_length (argnode); - convs = make_scratch_vec (len); - - for (i = 0; i < len; ++i) - { - tree arg = TREE_VALUE (argnode); - tree argtype = lvalue_type (arg); - tree t; - - if (parmnode == void_list_node) - break; - - if (parmnode) - { - tree parmtype = TREE_VALUE (parmnode); - - /* [over.match.funcs] For conversion functions, the function is - considered to be a member of the class of the implicit object - argument for the purpose of defining the type of the implicit - object parameter. - - Since build_over_call ignores the ICS for the `this' parameter, - we can just change the parm type. */ - if (DECL_CONV_FN_P (fn) && i == 0) - { - parmtype - = build_qualified_type (TREE_TYPE (argtype), - TYPE_QUALS (TREE_TYPE (parmtype))); - parmtype = build_pointer_type (parmtype); - } - - t = implicit_conversion (parmtype, argtype, arg, flags); - } - else - { - t = build1 (IDENTITY_CONV, argtype, arg); - ICS_ELLIPSIS_FLAG (t) = 1; - } - - if (i == 0 && t && TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE - && ! DECL_CONSTRUCTOR_P (fn)) - ICS_THIS_FLAG (t) = 1; - - TREE_VEC_ELT (convs, i) = t; - if (! t) - break; - - if (ICS_BAD_FLAG (t)) - viable = -1; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); - } - - if (i < len) - viable = 0; - - /* Make sure there are default args for the rest of the parms. */ - for (; parmnode && parmnode != void_list_node; - parmnode = TREE_CHAIN (parmnode)) - if (! TREE_PURPOSE (parmnode)) - { - viable = 0; - break; - } - - return add_candidate (candidates, fn, convs, viable); -} - -/* Create an overload candidate for the conversion function FN which will - be invoked for expression OBJ, producing a pointer-to-function which - will in turn be called with the argument list ARGLIST, and add it to - CANDIDATES. FLAGS is passed on to implicit_conversion. - - Actually, we don't really care about FN; we care about the type it - converts to. There may be multiple conversion functions that will - convert to that type, and we rely on build_user_type_conversion_1 to - choose the best one; so when we create our candidate, we record the type - instead of the function. */ - -static struct z_candidate * -add_conv_candidate (candidates, fn, obj, arglist) - struct z_candidate *candidates; - tree fn, obj, arglist; -{ - tree totype = TREE_TYPE (TREE_TYPE (fn)); - tree parmlist = TYPE_ARG_TYPES (TREE_TYPE (totype)); - int i, len = list_length (arglist) + 1; - tree convs = make_scratch_vec (len); - tree parmnode = parmlist; - tree argnode = arglist; - int viable = 1; - int flags = LOOKUP_NORMAL; - - /* Don't bother looking up the same type twice. */ - if (candidates && candidates->fn == totype) - return candidates; - - for (i = 0; i < len; ++i) - { - tree arg = i == 0 ? obj : TREE_VALUE (argnode); - tree argtype = lvalue_type (arg); - tree t; - - if (i == 0) - t = implicit_conversion (totype, argtype, arg, flags); - else if (parmnode == void_list_node) - break; - else if (parmnode) - t = implicit_conversion (TREE_VALUE (parmnode), argtype, arg, flags); - else - { - t = build1 (IDENTITY_CONV, argtype, arg); - ICS_ELLIPSIS_FLAG (t) = 1; - } - - TREE_VEC_ELT (convs, i) = t; - if (! t) - break; - - if (ICS_BAD_FLAG (t)) - viable = -1; - - if (i == 0) - continue; - - if (parmnode) - parmnode = TREE_CHAIN (parmnode); - argnode = TREE_CHAIN (argnode); - } - - if (i < len) - viable = 0; - - for (; parmnode && parmnode != void_list_node; - parmnode = TREE_CHAIN (parmnode)) - if (! TREE_PURPOSE (parmnode)) - { - viable = 0; - break; - } - - return add_candidate (candidates, totype, convs, viable); -} - -static struct z_candidate * -build_builtin_candidate (candidates, fnname, type1, type2, - args, argtypes, flags) - struct z_candidate *candidates; - tree fnname, type1, type2, *args, *argtypes; - int flags; - -{ - tree t, convs; - int viable = 1, i; - tree types[2]; - - types[0] = type1; - types[1] = type2; - - convs = make_scratch_vec (args[2] ? 3 : (args[1] ? 2 : 1)); - - for (i = 0; i < 2; ++i) - { - if (! args[i]) - break; - - t = implicit_conversion (types[i], argtypes[i], args[i], flags); - if (! t) - { - viable = 0; - /* We need something for printing the candidate. */ - t = build1 (IDENTITY_CONV, types[i], NULL_TREE); - } - else if (ICS_BAD_FLAG (t)) - viable = 0; - TREE_VEC_ELT (convs, i) = t; - } - - /* For COND_EXPR we rearranged the arguments; undo that now. */ - if (args[2]) - { - TREE_VEC_ELT (convs, 2) = TREE_VEC_ELT (convs, 1); - TREE_VEC_ELT (convs, 1) = TREE_VEC_ELT (convs, 0); - t = implicit_conversion (boolean_type_node, argtypes[2], args[2], flags); - if (t) - TREE_VEC_ELT (convs, 0) = t; - else - viable = 0; - } - - return add_candidate (candidates, fnname, convs, viable); -} - -static int -is_complete (t) - tree t; -{ - return TYPE_SIZE (complete_type (t)) != NULL_TREE; -} - -/* Create any builtin operator overload candidates for the operator in - question given the converted operand types TYPE1 and TYPE2. The other - args are passed through from add_builtin_candidates to - build_builtin_candidate. */ - -static struct z_candidate * -add_builtin_candidate (candidates, code, code2, fnname, type1, type2, - args, argtypes, flags) - struct z_candidate *candidates; - enum tree_code code, code2; - tree fnname, type1, type2, *args, *argtypes; - int flags; -{ - switch (code) - { - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - args[1] = integer_zero_node; - type2 = integer_type_node; - break; - default: - break; - } - - switch (code) - { - -/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, - and VQ is either volatile or empty, there exist candidate operator - functions of the form - VQ T& operator++(VQ T&); - T operator++(VQ T&, int); - 5 For every pair T, VQ), where T is an enumeration type or an arithmetic - type other than bool, and VQ is either volatile or empty, there exist - candidate operator functions of the form - VQ T& operator--(VQ T&); - T operator--(VQ T&, int); - 6 For every pair T, VQ), where T is a cv-qualified or cv-unqualified - complete object type, and VQ is either volatile or empty, there exist - candidate operator functions of the form - T*VQ& operator++(T*VQ&); - T*VQ& operator--(T*VQ&); - T* operator++(T*VQ&, int); - T* operator--(T*VQ&, int); */ - - case POSTDECREMENT_EXPR: - case PREDECREMENT_EXPR: - if (TREE_CODE (type1) == BOOLEAN_TYPE) - return candidates; - case POSTINCREMENT_EXPR: - case PREINCREMENT_EXPR: - if ((ARITHMETIC_TYPE_P (type1) && TREE_CODE (type1) != ENUMERAL_TYPE) - || TYPE_PTROB_P (type1)) - { - type1 = build_reference_type (type1); - break; - } - return candidates; - -/* 7 For every cv-qualified or cv-unqualified complete object type T, there - exist candidate operator functions of the form - - T& operator*(T*); - - 8 For every function type T, there exist candidate operator functions of - the form - T& operator*(T*); */ - - case INDIRECT_REF: - if (TREE_CODE (type1) == POINTER_TYPE - && (TYPE_PTROB_P (type1) - || TREE_CODE (TREE_TYPE (type1)) == FUNCTION_TYPE)) - break; - return candidates; - -/* 9 For every type T, there exist candidate operator functions of the form - T* operator+(T*); - - 10For every promoted arithmetic type T, there exist candidate operator - functions of the form - T operator+(T); - T operator-(T); */ - - case CONVERT_EXPR: /* unary + */ - if (TREE_CODE (type1) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type1)) != OFFSET_TYPE) - break; - case NEGATE_EXPR: - if (ARITHMETIC_TYPE_P (type1)) - break; - return candidates; - -/* 11For every promoted integral type T, there exist candidate operator - functions of the form - T operator~(T); */ - - case BIT_NOT_EXPR: - if (INTEGRAL_TYPE_P (type1)) - break; - return candidates; - -/* 12For every quintuple C1, C2, T, CV1, CV2), where C2 is a class type, C1 - is the same type as C2 or is a derived class of C2, T is a complete - object type or a function type, and CV1 and CV2 are cv-qualifier-seqs, - there exist candidate operator functions of the form - CV12 T& operator->*(CV1 C1*, CV2 T C2::*); - where CV12 is the union of CV1 and CV2. */ - - case MEMBER_REF: - if (TREE_CODE (type1) == POINTER_TYPE - && (TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2))) - { - tree c1 = TREE_TYPE (type1); - tree c2 = (TYPE_PTRMEMFUNC_P (type2) - ? TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (type2))) - : TYPE_OFFSET_BASETYPE (TREE_TYPE (type2))); - - if (IS_AGGR_TYPE (c1) && DERIVED_FROM_P (c2, c1) - && (TYPE_PTRMEMFUNC_P (type2) - || is_complete (TREE_TYPE (TREE_TYPE (type2))))) - break; - } - return candidates; - -/* 13For every pair of promoted arithmetic types L and R, there exist can- - didate operator functions of the form - LR operator*(L, R); - LR operator/(L, R); - LR operator+(L, R); - LR operator-(L, R); - bool operator<(L, R); - bool operator>(L, R); - bool operator<=(L, R); - bool operator>=(L, R); - bool operator==(L, R); - bool operator!=(L, R); - where LR is the result of the usual arithmetic conversions between - types L and R. - - 14For every pair of types T and I, where T is a cv-qualified or cv- - unqualified complete object type and I is a promoted integral type, - there exist candidate operator functions of the form - T* operator+(T*, I); - T& operator[](T*, I); - T* operator-(T*, I); - T* operator+(I, T*); - T& operator[](I, T*); - - 15For every T, where T is a pointer to complete object type, there exist - candidate operator functions of the form112) - ptrdiff_t operator-(T, T); - - 16For every pointer type T, there exist candidate operator functions of - the form - bool operator<(T, T); - bool operator>(T, T); - bool operator<=(T, T); - bool operator>=(T, T); - bool operator==(T, T); - bool operator!=(T, T); - - 17For every pointer to member type T, there exist candidate operator - functions of the form - bool operator==(T, T); - bool operator!=(T, T); */ - - case MINUS_EXPR: - if (TYPE_PTROB_P (type1) && TYPE_PTROB_P (type2)) - break; - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) - { - type2 = ptrdiff_type_node; - break; - } - case MULT_EXPR: - case TRUNC_DIV_EXPR: - if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - break; - return candidates; - - case EQ_EXPR: - case NE_EXPR: - if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) - || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2))) - break; - if ((TYPE_PTRMEMFUNC_P (type1) || TYPE_PTRMEM_P (type1)) - && null_ptr_cst_p (args[1])) - { - type2 = type1; - break; - } - if ((TYPE_PTRMEMFUNC_P (type2) || TYPE_PTRMEM_P (type2)) - && null_ptr_cst_p (args[0])) - { - type1 = type2; - break; - } - case LT_EXPR: - case GT_EXPR: - case LE_EXPR: - case GE_EXPR: - case MAX_EXPR: - case MIN_EXPR: - if ((ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2))) - break; - if (TYPE_PTR_P (type1) && null_ptr_cst_p (args[1])) - { - type2 = type1; - break; - } - if (null_ptr_cst_p (args[0]) && TYPE_PTR_P (type2)) - { - type1 = type2; - break; - } - return candidates; - - case PLUS_EXPR: - if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - break; - case ARRAY_REF: - if (INTEGRAL_TYPE_P (type1) && TYPE_PTROB_P (type2)) - { - type1 = ptrdiff_type_node; - break; - } - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) - { - type2 = ptrdiff_type_node; - break; - } - return candidates; - -/* 18For every pair of promoted integral types L and R, there exist candi- - date operator functions of the form - LR operator%(L, R); - LR operator&(L, R); - LR operator^(L, R); - LR operator|(L, R); - L operator<<(L, R); - L operator>>(L, R); - where LR is the result of the usual arithmetic conversions between - types L and R. */ - - case TRUNC_MOD_EXPR: - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) - break; - return candidates; - -/* 19For every triple L, VQ, R), where L is an arithmetic or enumeration - type, VQ is either volatile or empty, and R is a promoted arithmetic - type, there exist candidate operator functions of the form - VQ L& operator=(VQ L&, R); - VQ L& operator*=(VQ L&, R); - VQ L& operator/=(VQ L&, R); - VQ L& operator+=(VQ L&, R); - VQ L& operator-=(VQ L&, R); - - 20For every pair T, VQ), where T is any type and VQ is either volatile - or empty, there exist candidate operator functions of the form - T*VQ& operator=(T*VQ&, T*); - - 21For every pair T, VQ), where T is a pointer to member type and VQ is - either volatile or empty, there exist candidate operator functions of - the form - VQ T& operator=(VQ T&, T); - - 22For every triple T, VQ, I), where T is a cv-qualified or cv- - unqualified complete object type, VQ is either volatile or empty, and - I is a promoted integral type, there exist candidate operator func- - tions of the form - T*VQ& operator+=(T*VQ&, I); - T*VQ& operator-=(T*VQ&, I); - - 23For every triple L, VQ, R), where L is an integral or enumeration - type, VQ is either volatile or empty, and R is a promoted integral - type, there exist candidate operator functions of the form - - VQ L& operator%=(VQ L&, R); - VQ L& operator<<=(VQ L&, R); - VQ L& operator>>=(VQ L&, R); - VQ L& operator&=(VQ L&, R); - VQ L& operator^=(VQ L&, R); - VQ L& operator|=(VQ L&, R); */ - - case MODIFY_EXPR: - switch (code2) - { - case PLUS_EXPR: - case MINUS_EXPR: - if (TYPE_PTROB_P (type1) && INTEGRAL_TYPE_P (type2)) - { - type2 = ptrdiff_type_node; - break; - } - case MULT_EXPR: - case TRUNC_DIV_EXPR: - if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - break; - return candidates; - - case TRUNC_MOD_EXPR: - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - if (INTEGRAL_TYPE_P (type1) && INTEGRAL_TYPE_P (type2)) - break; - return candidates; - - case NOP_EXPR: - if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - break; - if ((TYPE_PTRMEMFUNC_P (type1) && TYPE_PTRMEMFUNC_P (type2)) - || (TYPE_PTR_P (type1) && TYPE_PTR_P (type2)) - || (TYPE_PTRMEM_P (type1) && TYPE_PTRMEM_P (type2)) - || ((TYPE_PTRMEMFUNC_P (type1) - || TREE_CODE (type1) == POINTER_TYPE) - && null_ptr_cst_p (args[1]))) - { - type2 = type1; - break; - } - return candidates; - - default: - my_friendly_abort (367); - } - type1 = build_reference_type (type1); - break; - - case COND_EXPR: - /* Kludge around broken overloading rules whereby - bool ? const char& : enum is ambiguous - (between int and const char&). */ - flags |= LOOKUP_NO_TEMP_BIND; - - /* Extension: Support ?: of enumeral type. Hopefully this will not - be an extension for long. */ - if (TREE_CODE (type1) == ENUMERAL_TYPE && type1 == type2) - break; - else if (TREE_CODE (type1) == ENUMERAL_TYPE - || TREE_CODE (type2) == ENUMERAL_TYPE) - return candidates; - if (ARITHMETIC_TYPE_P (type1) && ARITHMETIC_TYPE_P (type2)) - break; - if (TREE_CODE (type1) == TREE_CODE (type2) - && (TREE_CODE (type1) == REFERENCE_TYPE - || TREE_CODE (type1) == POINTER_TYPE - || TYPE_PTRMEMFUNC_P (type1) - || IS_AGGR_TYPE (type1))) - break; - if (TREE_CODE (type1) == REFERENCE_TYPE - || TREE_CODE (type2) == REFERENCE_TYPE) - return candidates; - if (((TYPE_PTRMEMFUNC_P (type1) || TREE_CODE (type1) == POINTER_TYPE) - && null_ptr_cst_p (args[1])) - || IS_AGGR_TYPE (type1)) - { - type2 = type1; - break; - } - if (((TYPE_PTRMEMFUNC_P (type2) || TREE_CODE (type2) == POINTER_TYPE) - && null_ptr_cst_p (args[0])) - || IS_AGGR_TYPE (type2)) - { - type1 = type2; - break; - } - return candidates; - - default: - my_friendly_abort (367); - } - - /* If we're dealing with two pointer types, we need candidates - for both of them. */ - if (type2 && type1 != type2 - && TREE_CODE (type1) == TREE_CODE (type2) - && (TREE_CODE (type1) == REFERENCE_TYPE - || (TREE_CODE (type1) == POINTER_TYPE - && TYPE_PTRMEM_P (type1) == TYPE_PTRMEM_P (type2)) - || TYPE_PTRMEMFUNC_P (type1) - || IS_AGGR_TYPE (type1))) - { - candidates = build_builtin_candidate - (candidates, fnname, type1, type1, args, argtypes, flags); - return build_builtin_candidate - (candidates, fnname, type2, type2, args, argtypes, flags); - } - - return build_builtin_candidate - (candidates, fnname, type1, type2, args, argtypes, flags); -} - -tree -type_decays_to (type) - tree type; -{ - if (TREE_CODE (type) == ARRAY_TYPE) - return build_pointer_type (TREE_TYPE (type)); - if (TREE_CODE (type) == FUNCTION_TYPE) - return build_pointer_type (type); - return type; -} - -/* There are three conditions of builtin candidates: - - 1) bool-taking candidates. These are the same regardless of the input. - 2) pointer-pair taking candidates. These are generated for each type - one of the input types converts to. - 3) arithmetic candidates. According to the WP, we should generate - all of these, but I'm trying not to... */ - -static struct z_candidate * -add_builtin_candidates (candidates, code, code2, fnname, args, flags) - struct z_candidate *candidates; - enum tree_code code, code2; - tree fnname, *args; - int flags; -{ - int ref1, i; - tree type, argtypes[3], types[2]; - - for (i = 0; i < 3; ++i) - { - if (args[i]) - argtypes[i] = lvalue_type (args[i]); - else - argtypes[i] = NULL_TREE; - } - - switch (code) - { -/* 4 For every pair T, VQ), where T is an arithmetic or enumeration type, - and VQ is either volatile or empty, there exist candidate operator - functions of the form - VQ T& operator++(VQ T&); */ - - case POSTINCREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case PREDECREMENT_EXPR: - case MODIFY_EXPR: - ref1 = 1; - break; - -/* 24There also exist candidate operator functions of the form - bool operator!(bool); - bool operator&&(bool, bool); - bool operator||(bool, bool); */ - - case TRUTH_NOT_EXPR: - return build_builtin_candidate - (candidates, fnname, boolean_type_node, - NULL_TREE, args, argtypes, flags); - - case TRUTH_ORIF_EXPR: - case TRUTH_ANDIF_EXPR: - return build_builtin_candidate - (candidates, fnname, boolean_type_node, - boolean_type_node, args, argtypes, flags); - - case ADDR_EXPR: - case COMPOUND_EXPR: - case COMPONENT_REF: - return candidates; - - default: - ref1 = 0; - } - - types[0] = types[1] = NULL_TREE; - - for (i = 0; i < 2; ++i) - { - if (! args[i]) - ; - else if (IS_AGGR_TYPE (argtypes[i])) - { - tree convs = lookup_conversions (argtypes[i]); - - if (i == 0 && code == MODIFY_EXPR && code2 == NOP_EXPR) - return candidates; - - convs = lookup_conversions (argtypes[i]); - - if (code == COND_EXPR) - { - if (real_lvalue_p (args[i])) - types[i] = scratch_tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); - - types[i] = scratch_tree_cons - (NULL_TREE, TYPE_MAIN_VARIANT (argtypes[i]), types[i]); - } - - else if (! convs) - return candidates; - - for (; convs; convs = TREE_CHAIN (convs)) - { - type = TREE_TYPE (TREE_TYPE (TREE_VALUE (convs))); - - if (i == 0 && ref1 - && (TREE_CODE (type) != REFERENCE_TYPE - || CP_TYPE_CONST_P (TREE_TYPE (type)))) - continue; - - if (code == COND_EXPR && TREE_CODE (type) == REFERENCE_TYPE) - types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); - - type = non_reference (type); - if (i != 0 || ! ref1) - { - type = TYPE_MAIN_VARIANT (type_decays_to (type)); - if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) - types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); - if (INTEGRAL_TYPE_P (type)) - type = type_promotes_to (type); - } - - if (! value_member (type, types[i])) - types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); - } - } - else - { - if (code == COND_EXPR && real_lvalue_p (args[i])) - types[i] = scratch_tree_cons - (NULL_TREE, build_reference_type (argtypes[i]), types[i]); - type = non_reference (argtypes[i]); - if (i != 0 || ! ref1) - { - type = TYPE_MAIN_VARIANT (type_decays_to (type)); - if (code == COND_EXPR && TREE_CODE (type) == ENUMERAL_TYPE) - types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); - if (INTEGRAL_TYPE_P (type)) - type = type_promotes_to (type); - } - types[i] = scratch_tree_cons (NULL_TREE, type, types[i]); - } - } - - for (; types[0]; types[0] = TREE_CHAIN (types[0])) - { - if (types[1]) - for (type = types[1]; type; type = TREE_CHAIN (type)) - candidates = add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), - TREE_VALUE (type), args, argtypes, flags); - else - candidates = add_builtin_candidate - (candidates, code, code2, fnname, TREE_VALUE (types[0]), - NULL_TREE, args, argtypes, flags); - } - - return candidates; -} - - -/* If TMPL can be successfully instantiated as indicated by - EXPLICIT_TARGS and ARGLIST, adds the instantiation to CANDIDATES. - - TMPL is the template. EXPLICIT_TARGS are any explicit template - arguments. ARGLIST is the arguments provided at the call-site. - The RETURN_TYPE is the desired type for conversion operators. If - OBJ is NULL_TREE, FLAGS are as for add_function_candidate. If an - OBJ is supplied, FLAGS are ignored, and OBJ is as for - add_conv_candidate. */ - -static struct z_candidate* -add_template_candidate_real (candidates, tmpl, explicit_targs, - arglist, return_type, flags, - obj, strict) - struct z_candidate *candidates; - tree tmpl, explicit_targs, arglist, return_type; - int flags; - tree obj; - unification_kind_t strict; -{ - int ntparms = DECL_NTPARMS (tmpl); - tree targs = make_scratch_vec (ntparms); - struct z_candidate *cand; - int i; - tree fn; - - i = fn_type_unification (tmpl, explicit_targs, targs, arglist, - return_type, strict, NULL_TREE); - - if (i != 0) - return candidates; - - fn = instantiate_template (tmpl, targs); - if (fn == error_mark_node) - return candidates; - - if (obj != NULL_TREE) - /* Aha, this is a conversion function. */ - cand = add_conv_candidate (candidates, fn, obj, arglist); - else - cand = add_function_candidate (candidates, fn, arglist, flags); - if (DECL_TI_TEMPLATE (fn) != tmpl) - /* This situation can occur if a member template of a template - class is specialized. Then, instantiate_template might return - an instantiation of the specialization, in which case the - DECL_TI_TEMPLATE field will point at the original - specialization. For example: - - template <class T> struct S { template <class U> void f(U); - template <> void f(int) {}; }; - S<double> sd; - sd.f(3); - - Here, TMPL will be template <class U> S<double>::f(U). - And, instantiate template will give us the specialization - template <> S<double>::f(int). But, the DECL_TI_TEMPLATE field - for this will point at template <class T> template <> S<T>::f(int), - so that we can find the definition. For the purposes of - overload resolution, however, we want the original TMPL. */ - cand->template = tree_cons (tmpl, targs, NULL_TREE); - else - cand->template = DECL_TEMPLATE_INFO (fn); - - return cand; -} - - -static struct z_candidate * -add_template_candidate (candidates, tmpl, explicit_targs, - arglist, return_type, flags, strict) - struct z_candidate *candidates; - tree tmpl, explicit_targs, arglist, return_type; - int flags; - unification_kind_t strict; -{ - return - add_template_candidate_real (candidates, tmpl, explicit_targs, - arglist, return_type, flags, - NULL_TREE, strict); -} - - -static struct z_candidate * -add_template_conv_candidate (candidates, tmpl, obj, arglist, return_type) - struct z_candidate *candidates; - tree tmpl, obj, arglist, return_type; -{ - return - add_template_candidate_real (candidates, tmpl, NULL_TREE, arglist, - return_type, 0, obj, DEDUCE_CONV); -} - - -static int -any_viable (cands) - struct z_candidate *cands; -{ - for (; cands; cands = cands->next) - if (pedantic ? cands->viable == 1 : cands->viable) - return 1; - return 0; -} - -static struct z_candidate * -splice_viable (cands) - struct z_candidate *cands; -{ - struct z_candidate **p = &cands; - - for (; *p; ) - { - if (pedantic ? (*p)->viable == 1 : (*p)->viable) - p = &((*p)->next); - else - *p = (*p)->next; - } - - return cands; -} - -static tree -build_this (obj) - tree obj; -{ - /* Fix this to work on non-lvalues. */ - if (IS_SIGNATURE_POINTER (TREE_TYPE (obj)) - || IS_SIGNATURE_REFERENCE (TREE_TYPE (obj))) - return obj; - else - return build_unary_op (ADDR_EXPR, obj, 0); -} - -static void -print_z_candidates (candidates) - struct z_candidate *candidates; -{ - char *str = "candidates are:"; - for (; candidates; candidates = candidates->next) - { - if (TREE_CODE (candidates->fn) == IDENTIFIER_NODE) - { - if (candidates->fn == ansi_opname [COND_EXPR]) - cp_error ("%s %D(%T, %T, %T) <builtin>", str, candidates->fn, - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)), - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1)), - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 2))); - else if (TREE_VEC_LENGTH (candidates->convs) == 2) - cp_error ("%s %D(%T, %T) <builtin>", str, candidates->fn, - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0)), - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 1))); - else - cp_error ("%s %D(%T) <builtin>", str, candidates->fn, - TREE_TYPE (TREE_VEC_ELT (candidates->convs, 0))); - } - else if (TYPE_P (candidates->fn)) - cp_error ("%s %T <conversion>", str, candidates->fn); - else - cp_error_at ("%s %+D%s", str, candidates->fn, - candidates->viable == -1 ? " <near match>" : ""); - str = " "; - } -} - -/* Returns the best overload candidate to perform the requested - conversion. This function is used for three the overloading situations - described in [over.match.copy], [over.match.conv], and [over.match.ref]. - If TOTYPE is a REFERENCE_TYPE, we're trying to find an lvalue binding as - per [dcl.init.ref], so we ignore temporary bindings. */ - -static struct z_candidate * -build_user_type_conversion_1 (totype, expr, flags) - tree totype, expr; - int flags; -{ - struct z_candidate *candidates, *cand; - tree fromtype = TREE_TYPE (expr); - tree ctors = NULL_TREE, convs = NULL_TREE, *p; - tree args = NULL_TREE; - tree templates = NULL_TREE; - - if (IS_AGGR_TYPE (totype)) - ctors = lookup_fnfields (TYPE_BINFO (totype), ctor_identifier, 0); - if (IS_AGGR_TYPE (fromtype) - && (! IS_AGGR_TYPE (totype) || ! DERIVED_FROM_P (totype, fromtype))) - convs = lookup_conversions (fromtype); - - candidates = 0; - flags |= LOOKUP_NO_CONVERSION; - - if (ctors) - { - tree t = build_int_2 (0, 0); - TREE_TYPE (t) = build_pointer_type (totype); - args = build_scratch_list (NULL_TREE, expr); - if (TYPE_USES_VIRTUAL_BASECLASSES (totype)) - args = scratch_tree_cons (NULL_TREE, integer_one_node, args); - args = scratch_tree_cons (NULL_TREE, t, args); - - ctors = TREE_VALUE (ctors); - } - for (; ctors; ctors = OVL_NEXT (ctors)) - { - tree ctor = OVL_CURRENT (ctors); - if (DECL_NONCONVERTING_P (ctor)) - continue; - - if (TREE_CODE (ctor) == TEMPLATE_DECL) - { - templates = scratch_tree_cons (NULL_TREE, ctor, templates); - candidates = - add_template_candidate (candidates, ctor, - NULL_TREE, args, NULL_TREE, flags, - DEDUCE_CALL); - } - else - candidates = add_function_candidate (candidates, ctor, - args, flags); - - if (candidates) - { - candidates->second_conv = build1 (IDENTITY_CONV, totype, NULL_TREE); - candidates->basetype_path = TYPE_BINFO (totype); - } - } - - if (convs) - args = build_scratch_list (NULL_TREE, build_this (expr)); - - for (; convs; convs = TREE_CHAIN (convs)) - { - tree fns = TREE_VALUE (convs); - int convflags = LOOKUP_NO_CONVERSION; - tree ics; - - /* If we are called to convert to a reference type, we are trying to - find an lvalue binding, so don't even consider temporaries. If - we don't find an lvalue binding, the caller will try again to - look for a temporary binding. */ - if (TREE_CODE (totype) == REFERENCE_TYPE) - convflags |= LOOKUP_NO_TEMP_BIND; - - if (TREE_CODE (OVL_CURRENT (fns)) != TEMPLATE_DECL) - ics = implicit_conversion - (totype, TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))), 0, convflags); - else - /* We can't compute this yet. */ - ics = error_mark_node; - - if (TREE_CODE (totype) == REFERENCE_TYPE && ics && ICS_BAD_FLAG (ics)) - /* ignore the near match. */; - else if (ics) - for (; fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - struct z_candidate *old_candidates = candidates; - - if (TREE_CODE (fn) == TEMPLATE_DECL) - { - templates = scratch_tree_cons (NULL_TREE, fn, templates); - candidates = - add_template_candidate (candidates, fn, NULL_TREE, - args, totype, flags, - DEDUCE_CONV); - } - else - candidates = add_function_candidate (candidates, fn, - args, flags); - - if (candidates != old_candidates) - { - if (TREE_CODE (fn) == TEMPLATE_DECL) - ics = implicit_conversion - (totype, TREE_TYPE (TREE_TYPE (candidates->fn)), - 0, convflags); - - candidates->second_conv = ics; - candidates->basetype_path = TREE_PURPOSE (convs); - - if (ics == NULL_TREE) - candidates->viable = 0; - else if (candidates->viable == 1 && ICS_BAD_FLAG (ics)) - candidates->viable = -1; - } - } - } - - if (! any_viable (candidates)) - { -#if 0 - if (flags & LOOKUP_COMPLAIN) - { - if (candidates && ! candidates->next) - /* say why this one won't work or try to be loose */; - else - cp_error ("no viable candidates"); - } -#endif - - return 0; - } - - candidates = splice_viable (candidates); - cand = tourney (candidates); - - if (cand == 0) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error ("conversion from `%T' to `%T' is ambiguous", - fromtype, totype); - print_z_candidates (candidates); - } - - cand = candidates; /* any one will do */ - cand->second_conv = build1 (AMBIG_CONV, totype, expr); - ICS_USER_FLAG (cand->second_conv) = 1; - ICS_BAD_FLAG (cand->second_conv) = 1; - - return cand; - } - - for (p = &(cand->second_conv); TREE_CODE (*p) != IDENTITY_CONV; ) - p = &(TREE_OPERAND (*p, 0)); - - /* Pedantically, normal function declarations are never considered - to refer to template instantiations, so we only do this with - -fguiding-decls. */ - if (flag_guiding_decls && templates && ! cand->template - && !DECL_INITIAL (cand->fn) - && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE) - add_maybe_template (cand->fn, templates); - - *p = build - (USER_CONV, - (DECL_CONSTRUCTOR_P (cand->fn) - ? totype : non_reference (TREE_TYPE (TREE_TYPE (cand->fn)))), - expr, build_expr_ptr_wrapper (cand)); - ICS_USER_FLAG (cand->second_conv) = 1; - if (cand->viable == -1) - ICS_BAD_FLAG (cand->second_conv) = 1; - - return cand; -} - -tree -build_user_type_conversion (totype, expr, flags) - tree totype, expr; - int flags; -{ - struct z_candidate *cand - = build_user_type_conversion_1 (totype, expr, flags); - - if (cand) - { - if (TREE_CODE (cand->second_conv) == AMBIG_CONV) - return error_mark_node; - return convert_from_reference (convert_like (cand->second_conv, expr)); - } - return NULL_TREE; -} - -/* Do any initial processing on the arguments to a function call. */ - -static tree -resolve_args (args) - tree args; -{ - tree t; - for (t = args; t; t = TREE_CHAIN (t)) - { - if (TREE_VALUE (t) == error_mark_node) - return error_mark_node; - else if (TREE_CODE (TREE_TYPE (TREE_VALUE (t))) == VOID_TYPE) - { - error ("invalid use of void expression"); - return error_mark_node; - } - else if (TREE_CODE (TREE_VALUE (t)) == OFFSET_REF) - TREE_VALUE (t) = resolve_offset_ref (TREE_VALUE (t)); - } - return args; -} - -tree -build_new_function_call (fn, args) - tree fn, args; -{ - struct z_candidate *candidates = 0, *cand; - tree explicit_targs = NULL_TREE; - int template_only = 0; - - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - { - explicit_targs = TREE_OPERAND (fn, 1); - fn = TREE_OPERAND (fn, 0); - template_only = 1; - } - - if (really_overloaded_fn (fn)) - { - tree t1; - tree templates = NULL_TREE; - - args = resolve_args (args); - - if (args == error_mark_node) - return error_mark_node; - - for (t1 = fn; t1; t1 = OVL_CHAIN (t1)) - { - tree t = OVL_FUNCTION (t1); - if (TREE_CODE (t) == TEMPLATE_DECL) - { - templates = scratch_tree_cons (NULL_TREE, t, templates); - candidates = add_template_candidate - (candidates, t, explicit_targs, args, NULL_TREE, - LOOKUP_NORMAL, DEDUCE_CALL); - } - else if (! template_only) - candidates = add_function_candidate - (candidates, t, args, LOOKUP_NORMAL); - } - - if (! any_viable (candidates)) - { - if (candidates && ! candidates->next) - return build_function_call (candidates->fn, args); - cp_error ("no matching function for call to `%D (%A)'", - DECL_NAME (OVL_FUNCTION (fn)), args); - if (candidates) - print_z_candidates (candidates); - return error_mark_node; - } - candidates = splice_viable (candidates); - cand = tourney (candidates); - - if (cand == 0) - { - cp_error ("call of overloaded `%D (%A)' is ambiguous", - DECL_NAME (OVL_FUNCTION (fn)), args); - print_z_candidates (candidates); - return error_mark_node; - } - - /* Pedantically, normal function declarations are never considered - to refer to template instantiations, so we only do this with - -fguiding-decls. */ - if (flag_guiding_decls && templates && ! cand->template - && ! DECL_INITIAL (cand->fn)) - add_maybe_template (cand->fn, templates); - - return build_over_call (cand, args, LOOKUP_NORMAL); - } - - /* This is not really overloaded. */ - fn = OVL_CURRENT (fn); - - return build_function_call (fn, args); -} - -static tree -build_object_call (obj, args) - tree obj, args; -{ - struct z_candidate *candidates = 0, *cand; - tree fns, convs, mem_args = NULL_TREE; - tree type = TREE_TYPE (obj); - - if (TYPE_PTRMEMFUNC_P (type)) - { - /* It's no good looking for an overloaded operator() on a - pointer-to-member-function. */ - cp_error ("pointer-to-member function %E cannot be called", obj); - cp_error ("without an object; consider using .* or ->*"); - return error_mark_node; - } - - fns = lookup_fnfields (TYPE_BINFO (type), ansi_opname [CALL_EXPR], 1); - if (fns == error_mark_node) - return error_mark_node; - - args = resolve_args (args); - - if (args == error_mark_node) - return error_mark_node; - - if (fns) - { - tree base = TREE_PURPOSE (fns); - mem_args = scratch_tree_cons (NULL_TREE, build_this (obj), args); - - for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - if (TREE_CODE (fn) == TEMPLATE_DECL) - { - candidates - = add_template_candidate (candidates, fn, NULL_TREE, - mem_args, NULL_TREE, - LOOKUP_NORMAL, DEDUCE_CALL); - } - else - candidates = add_function_candidate - (candidates, fn, mem_args, LOOKUP_NORMAL); - - if (candidates) - candidates->basetype_path = base; - } - } - - convs = lookup_conversions (type); - - for (; convs; convs = TREE_CHAIN (convs)) - { - tree fns = TREE_VALUE (convs); - tree totype = TREE_TYPE (TREE_TYPE (OVL_CURRENT (fns))); - - if ((TREE_CODE (totype) == POINTER_TYPE - || TREE_CODE (totype) == REFERENCE_TYPE) - && TREE_CODE (TREE_TYPE (totype)) == FUNCTION_TYPE) - for (; fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - if (TREE_CODE (fn) == TEMPLATE_DECL) - { - candidates = add_template_conv_candidate (candidates, - fn, - obj, - args, - totype); - } - else - candidates = add_conv_candidate (candidates, fn, obj, args); - - if (candidates) - candidates->basetype_path = TREE_PURPOSE (convs); - } - } - - if (! any_viable (candidates)) - { - cp_error ("no match for call to `(%T) (%A)'", TREE_TYPE (obj), args); - print_z_candidates (candidates); - return error_mark_node; - } - - candidates = splice_viable (candidates); - cand = tourney (candidates); - - if (cand == 0) - { - cp_error ("call of `(%T) (%A)' is ambiguous", TREE_TYPE (obj), args); - print_z_candidates (candidates); - return error_mark_node; - } - - if (DECL_NAME (cand->fn) == ansi_opname [CALL_EXPR]) - return build_over_call (cand, mem_args, LOOKUP_NORMAL); - - obj = convert_like (TREE_VEC_ELT (cand->convs, 0), obj); - - /* FIXME */ - return build_function_call (obj, args); -} - -static void -op_error (code, code2, arg1, arg2, arg3, problem) - enum tree_code code, code2; - tree arg1, arg2, arg3; - char *problem; -{ - char * opname - = (code == MODIFY_EXPR ? assignop_tab [code2] : opname_tab [code]); - - switch (code) - { - case COND_EXPR: - cp_error ("%s for `%T ? %T : %T'", problem, - error_type (arg1), error_type (arg2), error_type (arg3)); - break; - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - cp_error ("%s for `%T%s'", problem, error_type (arg1), opname); - break; - case ARRAY_REF: - cp_error ("%s for `%T[%T]'", problem, - error_type (arg1), error_type (arg2)); - break; - default: - if (arg2) - cp_error ("%s for `%T %s %T'", problem, - error_type (arg1), opname, error_type (arg2)); - else - cp_error ("%s for `%s%T'", problem, opname, error_type (arg1)); - } -} - -tree -build_new_op (code, flags, arg1, arg2, arg3) - enum tree_code code; - int flags; - tree arg1, arg2, arg3; -{ - struct z_candidate *candidates = 0, *cand; - tree fns, mem_arglist = NULL_TREE, arglist, fnname; - enum tree_code code2 = NOP_EXPR; - tree templates = NULL_TREE; - tree conv; - - if (arg1 == error_mark_node - || arg2 == error_mark_node - || arg3 == error_mark_node) - return error_mark_node; - - /* This can happen if a template takes all non-type parameters, e.g. - undeclared_template<1, 5, 72>a; */ - if (code == LT_EXPR && TREE_CODE (arg1) == TEMPLATE_DECL) - { - cp_error ("`%D' must be declared before use", arg1); - return error_mark_node; - } - - if (code == MODIFY_EXPR) - { - code2 = TREE_CODE (arg3); - arg3 = NULL_TREE; - fnname = ansi_assopname[code2]; - } - else - fnname = ansi_opname[code]; - - switch (code) - { - case NEW_EXPR: - case VEC_NEW_EXPR: - case VEC_DELETE_EXPR: - case DELETE_EXPR: - /* Use build_op_new_call and build_op_delete_call instead. */ - my_friendly_abort (981018); - - case CALL_EXPR: - return build_object_call (arg1, arg2); - - default: - break; - } - - /* The comma operator can have void args. */ - if (TREE_CODE (arg1) == OFFSET_REF) - arg1 = resolve_offset_ref (arg1); - if (arg2 && TREE_CODE (arg2) == OFFSET_REF) - arg2 = resolve_offset_ref (arg2); - if (arg3 && TREE_CODE (arg3) == OFFSET_REF) - arg3 = resolve_offset_ref (arg3); - - if (code == COND_EXPR) - { - if (arg2 == NULL_TREE - || TREE_CODE (TREE_TYPE (arg2)) == VOID_TYPE - || TREE_CODE (TREE_TYPE (arg3)) == VOID_TYPE - || (! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)) - && ! IS_OVERLOAD_TYPE (TREE_TYPE (arg3)))) - goto builtin; - } - else if (! IS_OVERLOAD_TYPE (TREE_TYPE (arg1)) - && (! arg2 || ! IS_OVERLOAD_TYPE (TREE_TYPE (arg2)))) - goto builtin; - - if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR) - arg2 = integer_zero_node; - - if (arg2 && arg3) - arglist = scratch_tree_cons (NULL_TREE, arg1, scratch_tree_cons - (NULL_TREE, arg2, build_scratch_list (NULL_TREE, arg3))); - else if (arg2) - arglist = scratch_tree_cons (NULL_TREE, arg1, build_scratch_list (NULL_TREE, arg2)); - else - arglist = build_scratch_list (NULL_TREE, arg1); - - fns = lookup_function_nonclass (fnname, arglist); - - if (fns && TREE_CODE (fns) == TREE_LIST) - fns = TREE_VALUE (fns); - for (; fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - if (TREE_CODE (fn) == TEMPLATE_DECL) - { - templates = scratch_tree_cons (NULL_TREE, fn, templates); - candidates - = add_template_candidate (candidates, fn, NULL_TREE, - arglist, TREE_TYPE (fnname), - flags, DEDUCE_CALL); - } - else - candidates = add_function_candidate (candidates, fn, arglist, flags); - } - - if (IS_AGGR_TYPE (TREE_TYPE (arg1))) - { - fns = lookup_fnfields (TYPE_BINFO (TREE_TYPE (arg1)), fnname, 1); - if (fns == error_mark_node) - return fns; - } - else - fns = NULL_TREE; - - if (fns) - { - tree basetype = TREE_PURPOSE (fns); - mem_arglist = scratch_tree_cons (NULL_TREE, build_this (arg1), TREE_CHAIN (arglist)); - for (fns = TREE_VALUE (fns); fns; fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - tree this_arglist; - - if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) - this_arglist = mem_arglist; - else - this_arglist = arglist; - - if (TREE_CODE (fn) == TEMPLATE_DECL) - { - /* A member template. */ - templates = scratch_tree_cons (NULL_TREE, fn, templates); - candidates - = add_template_candidate (candidates, fn, NULL_TREE, - this_arglist, TREE_TYPE (fnname), - flags, DEDUCE_CALL); - } - else - candidates = add_function_candidate - (candidates, fn, this_arglist, flags); - - if (candidates) - candidates->basetype_path = basetype; - } - } - - { - tree args[3]; - - /* Rearrange the arguments for ?: so that add_builtin_candidate only has - to know about two args; a builtin candidate will always have a first - parameter of type bool. We'll handle that in - build_builtin_candidate. */ - if (code == COND_EXPR) - { - args[0] = arg2; - args[1] = arg3; - args[2] = arg1; - } - else - { - args[0] = arg1; - args[1] = arg2; - args[2] = NULL_TREE; - } - - candidates = add_builtin_candidates - (candidates, code, code2, fnname, args, flags); - } - - if (! any_viable (candidates)) - { - switch (code) - { - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - /* Look for an `operator++ (int)'. If they didn't have - one, then we fall back to the old way of doing things. */ - if (flags & LOOKUP_COMPLAIN) - cp_pedwarn ("no `%D (int)' declared for postfix `%s', trying prefix operator instead", - fnname, opname_tab [code]); - if (code == POSTINCREMENT_EXPR) - code = PREINCREMENT_EXPR; - else - code = PREDECREMENT_EXPR; - return build_new_op (code, flags, arg1, NULL_TREE, NULL_TREE); - - /* The caller will deal with these. */ - case ADDR_EXPR: - case COMPOUND_EXPR: - case COMPONENT_REF: - return NULL_TREE; - - default: - break; - } - if (flags & LOOKUP_COMPLAIN) - { - op_error (code, code2, arg1, arg2, arg3, "no match"); - print_z_candidates (candidates); - } - return error_mark_node; - } - candidates = splice_viable (candidates); - cand = tourney (candidates); - - if (cand == 0) - { - if (flags & LOOKUP_COMPLAIN) - { - op_error (code, code2, arg1, arg2, arg3, "ambiguous overload"); - print_z_candidates (candidates); - } - return error_mark_node; - } - - if (TREE_CODE (cand->fn) == FUNCTION_DECL) - { - extern int warn_synth; - if (warn_synth - && fnname == ansi_opname[MODIFY_EXPR] - && DECL_ARTIFICIAL (cand->fn) - && candidates->next - && ! candidates->next->next) - { - cp_warning ("using synthesized `%#D' for copy assignment", - cand->fn); - cp_warning_at (" where cfront would use `%#D'", - cand == candidates - ? candidates->next->fn - : candidates->fn); - } - - /* Pedantically, normal function declarations are never considered - to refer to template instantiations, so we only do this with - -fguiding-decls. */ - if (flag_guiding_decls && templates && ! cand->template - && ! DECL_INITIAL (cand->fn) - && TREE_CODE (TREE_TYPE (cand->fn)) != METHOD_TYPE) - add_maybe_template (cand->fn, templates); - - return build_over_call - (cand, - TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE - ? mem_arglist : arglist, - LOOKUP_NORMAL); - } - - /* Check for comparison of different enum types. */ - switch (code) - { - case GT_EXPR: - case LT_EXPR: - case GE_EXPR: - case LE_EXPR: - case EQ_EXPR: - case NE_EXPR: - if (TREE_CODE (TREE_TYPE (arg1)) == ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (arg2)) == ENUMERAL_TYPE - && (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)) - != TYPE_MAIN_VARIANT (TREE_TYPE (arg2)))) - { - cp_warning ("comparison between `%#T' and `%#T'", - TREE_TYPE (arg1), TREE_TYPE (arg2)); - } - break; - default: - break; - } - - /* We need to strip any leading REF_BIND so that bitfields don't cause - errors. This should not remove any important conversions, because - builtins don't apply to class objects directly. */ - conv = TREE_VEC_ELT (cand->convs, 0); - if (TREE_CODE (conv) == REF_BIND) - conv = TREE_OPERAND (conv, 0); - arg1 = convert_like (conv, arg1); - if (arg2) - arg2 = convert_like (TREE_VEC_ELT (cand->convs, 1), arg2); - if (arg3) - arg3 = convert_like (TREE_VEC_ELT (cand->convs, 2), arg3); - -builtin: - switch (code) - { - case MODIFY_EXPR: - return build_modify_expr (arg1, code2, arg2); - - case INDIRECT_REF: - return build_indirect_ref (arg1, "unary *"); - - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case GT_EXPR: - case LT_EXPR: - case GE_EXPR: - case LE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case MAX_EXPR: - case MIN_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case TRUNC_MOD_EXPR: - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - return build_binary_op_nodefault (code, arg1, arg2, code); - - case CONVERT_EXPR: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - return build_unary_op (code, arg1, candidates != 0); - - case ARRAY_REF: - return build_array_ref (arg1, arg2); - - case COND_EXPR: - return build_conditional_expr (arg1, arg2, arg3); - - case MEMBER_REF: - return build_m_component_ref - (build_indirect_ref (arg1, NULL_PTR), arg2); - - /* The caller will deal with these. */ - case ADDR_EXPR: - case COMPONENT_REF: - case COMPOUND_EXPR: - return NULL_TREE; - - default: - my_friendly_abort (367); - return NULL_TREE; - } -} - -/* Build up a call to operator new. This has to be handled differently - from other operators in the way lookup is handled; first members are - considered, then globals. CODE is either NEW_EXPR or VEC_NEW_EXPR. - TYPE is the type to be created. ARGS are any new-placement args. - FLAGS are the usual overloading flags. */ - -tree -build_op_new_call (code, type, args, flags) - enum tree_code code; - tree type, args; - int flags; -{ - tree fnname = ansi_opname[code]; - - if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL) - && (TYPE_GETS_NEW (type) & (1 << (code == VEC_NEW_EXPR)))) - { - return build_method_call (build_dummy_object (type), - fnname, args, NULL_TREE, flags); - } - else - return build_new_function_call - (lookup_function_nonclass (fnname, args), args); -} - -/* Build a call to operator delete. This has to be handled very specially, - because the restrictions on what signatures match are different from all - other call instances. For a normal delete, only a delete taking (void *) - or (void *, size_t) is accepted. For a placement delete, only an exact - match with the placement new is accepted. - - CODE is either DELETE_EXPR or VEC_DELETE_EXPR. - ADDR is the pointer to be deleted. For placement delete, it is also - used to determine what the corresponding new looked like. - SIZE is the size of the memory block to be deleted. - FLAGS are the usual overloading flags. - PLACEMENT is the corresponding placement new call, or 0. */ - -tree -build_op_delete_call (code, addr, size, flags, placement) - enum tree_code code; - tree addr, size, placement; - int flags; -{ - tree fn, fns, fnname, fntype, argtypes, args, type; - - if (addr == error_mark_node) - return error_mark_node; - - type = TREE_TYPE (TREE_TYPE (addr)); - fnname = ansi_opname[code]; - - if (IS_AGGR_TYPE (type) && ! (flags & LOOKUP_GLOBAL)) - /* In [class.free] - - If the result of the lookup is ambiguous or inaccessible, or if - the lookup selects a placement deallocation function, the - program is ill-formed. - - Therefore, we ask lookup_fnfields to complain ambout ambiguity. */ - { - fns = lookup_fnfields (TYPE_BINFO (type), fnname, 1); - if (fns == error_mark_node) - return error_mark_node; - } - else - fns = NULL_TREE; - - if (fns == NULL_TREE) - fns = lookup_name_nonclass (fnname); - - if (placement) - { - /* placement is a CALL_EXPR around an ADDR_EXPR around a function. */ - - /* Extract the function. */ - argtypes = TREE_OPERAND (TREE_OPERAND (placement, 0), 0); - /* Then the second parm type. */ - argtypes = TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (argtypes))); - - /* Also the second argument. */ - args = TREE_CHAIN (TREE_OPERAND (placement, 1)); - } - else - { - /* First try it without the size argument. */ - argtypes = void_list_node; - args = NULL_TREE; - } - - argtypes = tree_cons (NULL_TREE, ptr_type_node, argtypes); - fntype = build_function_type (void_type_node, argtypes); - - /* Strip const and volatile from addr. */ - if (type != TYPE_MAIN_VARIANT (type)) - addr = cp_convert (build_pointer_type (TYPE_MAIN_VARIANT (type)), addr); - - fn = instantiate_type (fntype, fns, 0); - - if (fn != error_mark_node) - { - if (TREE_CODE (fns) == TREE_LIST) - /* Member functions. */ - enforce_access (TREE_PURPOSE (fns), fn); - return build_function_call (fn, expr_tree_cons (NULL_TREE, addr, args)); - } - - /* If we are doing placement delete we do nothing if we don't find a - matching op delete. */ - if (placement) - return NULL_TREE; - - /* Normal delete; now try to find a match including the size argument. */ - argtypes = tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, sizetype, void_list_node)); - fntype = build_function_type (void_type_node, argtypes); - - fn = instantiate_type (fntype, fns, 0); - - if (fn != error_mark_node) - { - if (TREE_CODE (fns) == TREE_LIST) - /* Member functions. */ - enforce_access (TREE_PURPOSE (fns), fn); - return build_function_call - (fn, expr_tree_cons (NULL_TREE, addr, - build_expr_list (NULL_TREE, size))); - } - - /* finish_function passes LOOKUP_SPECULATIVELY if we're in a - destructor, in which case the error should be deferred - until someone actually tries to delete one of these. */ - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - - cp_error ("no suitable operator delete for `%T'", type); - return error_mark_node; -} - -/* If the current scope isn't allowed to access DECL along - BASETYPE_PATH, give an error. */ - -void -enforce_access (basetype_path, decl) - tree basetype_path, decl; -{ - tree access = compute_access (basetype_path, decl); - - if (access == access_private_node) - { - cp_error_at ("`%+#D' is %s", decl, - TREE_PRIVATE (decl) ? "private" - : "from private base class"); - error ("within this context"); - } - else if (access == access_protected_node) - { - cp_error_at ("`%+#D' %s", decl, - TREE_PROTECTED (decl) ? "is protected" - : "has protected accessibility"); - error ("within this context"); - } -} - -/* Perform the conversions in CONVS on the expression EXPR. */ - -static tree -convert_like (convs, expr) - tree convs, expr; -{ - if (ICS_BAD_FLAG (convs) - && TREE_CODE (convs) != USER_CONV - && TREE_CODE (convs) != AMBIG_CONV) - { - tree t = convs; - for (; t; t = TREE_OPERAND (t, 0)) - { - if (TREE_CODE (t) == USER_CONV) - { - expr = convert_like (t, expr); - break; - } - else if (TREE_CODE (t) == AMBIG_CONV) - return convert_like (t, expr); - else if (TREE_CODE (t) == IDENTITY_CONV) - break; - } - return convert_for_initialization - (NULL_TREE, TREE_TYPE (convs), expr, LOOKUP_NORMAL, - "conversion", NULL_TREE, 0); - } - - switch (TREE_CODE (convs)) - { - case USER_CONV: - { - struct z_candidate *cand - = WRAPPER_PTR (TREE_OPERAND (convs, 1)); - tree fn = cand->fn; - tree args; - - if (DECL_CONSTRUCTOR_P (fn)) - { - tree t = build_int_2 (0, 0); - TREE_TYPE (t) = build_pointer_type (DECL_CONTEXT (fn)); - - args = build_scratch_list (NULL_TREE, expr); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) - args = scratch_tree_cons (NULL_TREE, integer_one_node, args); - args = scratch_tree_cons (NULL_TREE, t, args); - } - else - args = build_this (expr); - expr = build_over_call (cand, args, LOOKUP_NORMAL); - - /* If this is a constructor or a function returning an aggr type, - we need to build up a TARGET_EXPR. */ - if (DECL_CONSTRUCTOR_P (fn)) - expr = build_cplus_new (TREE_TYPE (convs), expr); - - return expr; - } - case IDENTITY_CONV: - if (type_unknown_p (expr)) - expr = instantiate_type (TREE_TYPE (convs), expr, 1); - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return expr; - case AMBIG_CONV: - /* Call build_user_type_conversion again for the error. */ - return build_user_type_conversion - (TREE_TYPE (convs), TREE_OPERAND (convs, 0), LOOKUP_NORMAL); - - default: - break; - }; - - expr = convert_like (TREE_OPERAND (convs, 0), expr); - if (expr == error_mark_node) - return error_mark_node; - - switch (TREE_CODE (convs)) - { - case RVALUE_CONV: - if (! IS_AGGR_TYPE (TREE_TYPE (convs))) - return expr; - /* else fall through */ - case BASE_CONV: - { - tree cvt_expr = build_user_type_conversion - (TREE_TYPE (convs), expr, LOOKUP_NORMAL); - if (!cvt_expr) - { - /* This can occur if, for example, the EXPR has incomplete - type. We can't check for that before attempting the - conversion because the type might be an incomplete - array type, which is OK if some constructor for the - destination type takes a pointer argument. */ - if (TYPE_SIZE (TREE_TYPE (expr)) == 0) - { - if (same_type_p (TREE_TYPE (expr), TREE_TYPE (convs))) - incomplete_type_error (expr, TREE_TYPE (expr)); - else - cp_error ("could not convert `%E' (with incomplete type `%T') to `%T'", - expr, TREE_TYPE (expr), TREE_TYPE (convs)); - } - else - cp_error ("could not convert `%E' to `%T'", - expr, TREE_TYPE (convs)); - return error_mark_node; - } - return cvt_expr; - } - - case REF_BIND: - return convert_to_reference - (TREE_TYPE (convs), expr, - CONV_IMPLICIT, LOOKUP_NORMAL|LOOKUP_NO_CONVERSION, - error_mark_node); - case LVALUE_CONV: - return decay_conversion (expr); - - case QUAL_CONV: - /* Warn about deprecated conversion if appropriate. */ - string_conv_p (TREE_TYPE (convs), expr, 1); - break; - - default: - break; - } - return ocp_convert (TREE_TYPE (convs), expr, CONV_IMPLICIT, - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); -} - -/* ARG is being passed to a varargs function. Perform any conversions - required. Return the converted value. */ - -tree -convert_arg_to_ellipsis (arg) - tree arg; -{ - if (TREE_CODE (TREE_TYPE (arg)) == REAL_TYPE - && (TYPE_PRECISION (TREE_TYPE (arg)) - < TYPE_PRECISION (double_type_node))) - /* Convert `float' to `double'. */ - arg = cp_convert (double_type_node, arg); - else if (IS_AGGR_TYPE (TREE_TYPE (arg)) - && ! TYPE_HAS_TRIVIAL_INIT_REF (TREE_TYPE (arg))) - cp_warning ("cannot pass objects of type `%T' through `...'", - TREE_TYPE (arg)); - else - /* Convert `short' and `char' to full-size `int'. */ - arg = default_conversion (arg); - - return arg; -} - -/* ARG is a default argument expression being passed to a parameter of - the indicated TYPE, which is a parameter to FN. Do any required - conversions. Return the converted value. */ - -tree -convert_default_arg (type, arg, fn) - tree type; - tree arg; - tree fn; -{ - if (fn && DECL_TEMPLATE_INFO (fn)) - { - /* This default argument came from a template. Instantiate the - default argument here, not in tsubst. In the case of - something like: - - template <class T> - struct S { - static T t(); - void f(T = t()); - }; - - we must be careful to do name lookup in the scope of S<T>, - rather than in the current class. */ - if (DECL_CLASS_SCOPE_P (fn)) - pushclass (DECL_REAL_CONTEXT (fn), 2); - - arg = tsubst_expr (arg, DECL_TI_ARGS (fn), NULL_TREE); - - if (DECL_CLASS_SCOPE_P (fn)) - popclass (1); - - /* Make sure the default argument is reasonable. */ - arg = check_default_argument (type, arg); - } - - arg = break_out_target_exprs (arg); - - if (TREE_CODE (arg) == CONSTRUCTOR) - { - arg = digest_init (type, arg, 0); - arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", 0, 0); - } - else - { - /* This could get clobbered by the following call. */ - if (TREE_HAS_CONSTRUCTOR (arg)) - arg = copy_node (arg); - - arg = convert_for_initialization (0, type, arg, LOOKUP_NORMAL, - "default argument", 0, 0); -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - arg = default_conversion (arg); -#endif - } - - return arg; -} - -static tree -build_over_call (cand, args, flags) - struct z_candidate *cand; - tree args; - int flags; -{ - tree fn = cand->fn; - tree convs = cand->convs; - tree converted_args = NULL_TREE; - tree parm = TYPE_ARG_TYPES (TREE_TYPE (fn)); - tree conv, arg, val; - int i = 0; - int is_method = 0; - - /* Give any warnings we noticed during overload resolution. */ - if (cand->warnings) - for (val = cand->warnings; val; val = TREE_CHAIN (val)) - joust (cand, WRAPPER_PTR (TREE_VALUE (val)), 1); - - if (DECL_FUNCTION_MEMBER_P (fn)) - enforce_access (cand->basetype_path, fn); - - if (args && TREE_CODE (args) != TREE_LIST) - args = build_scratch_list (NULL_TREE, args); - arg = args; - - /* The implicit parameters to a constructor are not considered by overload - resolution, and must be of the proper type. */ - if (DECL_CONSTRUCTOR_P (fn)) - { - converted_args = expr_tree_cons (NULL_TREE, TREE_VALUE (arg), converted_args); - arg = TREE_CHAIN (arg); - parm = TREE_CHAIN (parm); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) - { - converted_args = expr_tree_cons - (NULL_TREE, TREE_VALUE (arg), converted_args); - arg = TREE_CHAIN (arg); - parm = TREE_CHAIN (parm); - } - } - /* Bypass access control for 'this' parameter. */ - else if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) - { - tree parmtype = TREE_VALUE (parm); - tree argtype = TREE_TYPE (TREE_VALUE (arg)); - tree t; - if (ICS_BAD_FLAG (TREE_VEC_ELT (convs, i))) - cp_pedwarn ("passing `%T' as `this' argument of `%#D' discards qualifiers", - TREE_TYPE (argtype), fn); - - /* [class.mfct.nonstatic]: If a nonstatic member function of a class - X is called for an object that is not of type X, or of a type - derived from X, the behavior is undefined. - - So we can assume that anything passed as 'this' is non-null, and - optimize accordingly. */ - if (TREE_CODE (parmtype) == POINTER_TYPE) - t = convert_pointer_to_real (TREE_TYPE (parmtype), TREE_VALUE (arg)); - else - /* This happens with signatures. */ - t = convert_force (parmtype, TREE_VALUE (arg), CONV_C_CAST); - converted_args = expr_tree_cons (NULL_TREE, t, converted_args); - parm = TREE_CHAIN (parm); - arg = TREE_CHAIN (arg); - ++i; - is_method = 1; - } - - for (; arg && parm; - parm = TREE_CHAIN (parm), arg = TREE_CHAIN (arg), ++i) - { - tree type = TREE_VALUE (parm); - - conv = TREE_VEC_ELT (convs, i); - if (ICS_BAD_FLAG (conv)) - { - tree t = conv; - val = TREE_VALUE (arg); - - for (; t; t = TREE_OPERAND (t, 0)) - { - if (TREE_CODE (t) == USER_CONV - || TREE_CODE (t) == AMBIG_CONV) - { - val = convert_like (t, val); - break; - } - else if (TREE_CODE (t) == IDENTITY_CONV) - break; - } - val = convert_for_initialization - (NULL_TREE, type, val, LOOKUP_NORMAL, - "argument passing", fn, i - is_method); - } - else - { - /* Issue warnings about peculiar, but legal, uses of NULL. */ - if (ARITHMETIC_TYPE_P (TREE_VALUE (parm)) - && TREE_VALUE (arg) == null_node) - cp_warning ("converting NULL to non-pointer type"); - - val = convert_like (conv, TREE_VALUE (arg)); - } - -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node))) - val = default_conversion (val); -#endif - converted_args = expr_tree_cons (NULL_TREE, val, converted_args); - } - - /* Default arguments */ - for (; parm && parm != void_list_node; parm = TREE_CHAIN (parm)) - converted_args - = expr_tree_cons (NULL_TREE, - convert_default_arg (TREE_VALUE (parm), - TREE_PURPOSE (parm), - fn), - converted_args); - - /* Ellipsis */ - for (; arg; arg = TREE_CHAIN (arg)) - converted_args - = expr_tree_cons (NULL_TREE, - convert_arg_to_ellipsis (TREE_VALUE (arg)), - converted_args); - - converted_args = nreverse (converted_args); - - if (warn_format && (DECL_NAME (fn) || DECL_ASSEMBLER_NAME (fn))) - check_function_format (DECL_NAME (fn), DECL_ASSEMBLER_NAME (fn), - converted_args); - - /* Avoid actually calling copy constructors and copy assignment operators, - if possible. */ - - if (! flag_elide_constructors) - /* Do things the hard way. */; - else if (DECL_CONSTRUCTOR_P (fn) - && TREE_VEC_LENGTH (convs) == 1 - && copy_args_p (fn)) - { - tree targ; - arg = TREE_CHAIN (converted_args); - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (fn))) - arg = TREE_CHAIN (arg); - arg = TREE_VALUE (arg); - - /* Pull out the real argument, disregarding const-correctness. */ - targ = arg; - while (TREE_CODE (targ) == NOP_EXPR - || TREE_CODE (targ) == NON_LVALUE_EXPR - || TREE_CODE (targ) == CONVERT_EXPR) - targ = TREE_OPERAND (targ, 0); - if (TREE_CODE (targ) == ADDR_EXPR) - { - targ = TREE_OPERAND (targ, 0); - if (!same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (arg))), - TYPE_MAIN_VARIANT (TREE_TYPE (targ)))) - targ = NULL_TREE; - } - else - targ = NULL_TREE; - - if (targ) - arg = targ; - else - arg = build_indirect_ref (arg, 0); - - /* [class.copy]: the copy constructor is implicitly defined even if - the implementation elided its use. */ - if (TYPE_HAS_COMPLEX_INIT_REF (DECL_CONTEXT (fn))) - mark_used (fn); - - /* If we're creating a temp and we already have one, don't create a - new one. If we're not creating a temp but we get one, use - INIT_EXPR to collapse the temp into our target. Otherwise, if the - ctor is trivial, do a bitwise copy with a simple TARGET_EXPR for a - temp or an INIT_EXPR otherwise. */ - if (integer_zerop (TREE_VALUE (args))) - { - if (! real_lvalue_p (arg)) - return arg; - else if (TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) - { - val = build_decl (VAR_DECL, NULL_TREE, DECL_CONTEXT (fn)); - val = build (TARGET_EXPR, DECL_CONTEXT (fn), val, arg, 0, 0); - TREE_SIDE_EFFECTS (val) = 1; - return val; - } - } - else if (! real_lvalue_p (arg) - || TYPE_HAS_TRIVIAL_INIT_REF (DECL_CONTEXT (fn))) - { - tree to = stabilize_reference - (build_indirect_ref (TREE_VALUE (args), 0)); - - /* Don't copy the padding byte; it might not have been allocated - if to is a base subobject. */ - if (is_empty_class (DECL_CLASS_CONTEXT (fn))) - return build_unary_op - (ADDR_EXPR, build (COMPOUND_EXPR, TREE_TYPE (to), - cp_convert (void_type_node, arg), to), - 0); - - val = build (INIT_EXPR, DECL_CONTEXT (fn), to, arg); - TREE_SIDE_EFFECTS (val) = 1; - return build_unary_op (ADDR_EXPR, val, 0); - } - } - else if (DECL_NAME (fn) == ansi_opname[MODIFY_EXPR] - && copy_args_p (fn) - && TYPE_HAS_TRIVIAL_ASSIGN_REF (DECL_CLASS_CONTEXT (fn))) - { - tree to = stabilize_reference - (build_indirect_ref (TREE_VALUE (converted_args), 0)); - - arg = build_indirect_ref (TREE_VALUE (TREE_CHAIN (converted_args)), 0); - - /* Don't copy the padding byte; it might not have been allocated - if to is a base subobject. */ - if (is_empty_class (DECL_CLASS_CONTEXT (fn))) - return build (COMPOUND_EXPR, TREE_TYPE (to), - cp_convert (void_type_node, arg), to); - - val = build (MODIFY_EXPR, TREE_TYPE (to), to, arg); - TREE_SIDE_EFFECTS (val) = 1; - return val; - } - - mark_used (fn); - - if (DECL_CLASS_SCOPE_P (fn) && IS_SIGNATURE (DECL_CONTEXT (fn))) - return build_signature_method_call (fn, converted_args); - else if (DECL_VINDEX (fn) && (flags & LOOKUP_NONVIRTUAL) == 0) - { - tree t, *p = &TREE_VALUE (converted_args); - tree binfo = get_binfo - (DECL_CONTEXT (fn), TREE_TYPE (TREE_TYPE (*p)), 0); - *p = convert_pointer_to_real (binfo, *p); - if (TREE_SIDE_EFFECTS (*p)) - *p = save_expr (*p); - t = build_pointer_type (TREE_TYPE (fn)); - fn = build_vfn_ref (p, build_indirect_ref (*p, 0), DECL_VINDEX (fn)); - TREE_TYPE (fn) = t; - } - else if (DECL_INLINE (fn)) - fn = inline_conversion (fn); - else - fn = build_addr_func (fn); - - /* Recognize certain built-in functions so we can make tree-codes - other than CALL_EXPR. We do this when it enables fold-const.c - to do something useful. */ - - if (TREE_CODE (fn) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (fn, 0)) == FUNCTION_DECL - && DECL_BUILT_IN (TREE_OPERAND (fn, 0))) - switch (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0))) - { - case BUILT_IN_ABS: - case BUILT_IN_LABS: - case BUILT_IN_FABS: - if (converted_args == 0) - return integer_zero_node; - return build_unary_op (ABS_EXPR, TREE_VALUE (converted_args), 0); - default: - break; - } - - fn = build_call (fn, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), converted_args); - if (TREE_TYPE (fn) == void_type_node) - return fn; - fn = require_complete_type (fn); - if (IS_AGGR_TYPE (TREE_TYPE (fn))) - fn = build_cplus_new (TREE_TYPE (fn), fn); - return convert_from_reference (fn); -} - -static tree -build_new_method_call (instance, name, args, basetype_path, flags) - tree instance, name, args, basetype_path; - int flags; -{ - struct z_candidate *candidates = 0, *cand; - tree explicit_targs = NULL_TREE; - tree basetype, mem_args = NULL_TREE, fns, instance_ptr; - tree pretty_name; - tree user_args = args; - tree templates = NULL_TREE; - int template_only = 0; - - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - explicit_targs = TREE_OPERAND (name, 1); - name = TREE_OPERAND (name, 0); - if (TREE_CODE (name) == TEMPLATE_DECL) - name = DECL_NAME (name); - template_only = 1; - } - - /* If there is an extra argument for controlling virtual bases, - remove it for error reporting. */ - if (flags & LOOKUP_HAS_IN_CHARGE) - user_args = TREE_CHAIN (args); - - args = resolve_args (args); - - if (args == error_mark_node) - return error_mark_node; - - if (instance == NULL_TREE) - basetype = BINFO_TYPE (basetype_path); - else - { - if (TREE_CODE (instance) == OFFSET_REF) - instance = resolve_offset_ref (instance); - if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) - instance = convert_from_reference (instance); - basetype = TREE_TYPE (instance); - - /* XXX this should be handled before we get here. */ - if (! IS_AGGR_TYPE (basetype) - && ! (TYPE_LANG_SPECIFIC (basetype) - && (IS_SIGNATURE_POINTER (basetype) - || IS_SIGNATURE_REFERENCE (basetype)))) - { - if ((flags & LOOKUP_COMPLAIN) && basetype != error_mark_node) - cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", - name, instance, basetype); - - return error_mark_node; - } - - /* If `instance' is a signature pointer/reference and `name' is - not a constructor, we are calling a signature member function. - In that case set the `basetype' to the signature type. */ - if ((IS_SIGNATURE_POINTER (basetype) - || IS_SIGNATURE_REFERENCE (basetype)) - && TYPE_IDENTIFIER (basetype) != name) - basetype = SIGNATURE_TYPE (basetype); - } - - if (basetype_path == NULL_TREE) - basetype_path = TYPE_BINFO (basetype); - - if (instance) - { - instance_ptr = build_this (instance); - - if (! template_only) - { - /* XXX this should be handled before we get here. */ - fns = build_field_call (basetype_path, instance_ptr, name, args); - if (fns) - return fns; - } - } - else - { - instance_ptr = build_int_2 (0, 0); - TREE_TYPE (instance_ptr) = build_pointer_type (basetype); - } - - pretty_name - = (name == ctor_identifier ? constructor_name (basetype) : name); - - fns = lookup_fnfields (basetype_path, name, 1); - - if (fns == error_mark_node) - return error_mark_node; - if (fns) - { - tree fn = TREE_VALUE (fns); - if (name == ctor_identifier && TYPE_USES_VIRTUAL_BASECLASSES (basetype) - && ! (flags & LOOKUP_HAS_IN_CHARGE)) - { - flags |= LOOKUP_HAS_IN_CHARGE; - args = scratch_tree_cons (NULL_TREE, integer_one_node, args); - } - mem_args = scratch_tree_cons (NULL_TREE, instance_ptr, args); - for (; fn; fn = OVL_NEXT (fn)) - { - tree t = OVL_CURRENT (fn); - tree this_arglist; - - /* We can end up here for copy-init of same or base class. */ - if (name == ctor_identifier - && (flags & LOOKUP_ONLYCONVERTING) - && DECL_NONCONVERTING_P (t)) - continue; - if (TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE) - this_arglist = mem_args; - else - this_arglist = args; - - if (TREE_CODE (t) == TEMPLATE_DECL) - { - /* A member template. */ - templates = scratch_tree_cons (NULL_TREE, t, templates); - candidates = - add_template_candidate (candidates, t, explicit_targs, - this_arglist, - TREE_TYPE (name), flags, DEDUCE_CALL); - } - else if (! template_only) - candidates = add_function_candidate (candidates, t, - this_arglist, flags); - - if (candidates) - candidates->basetype_path = TREE_PURPOSE (fns); - } - } - - if (! any_viable (candidates)) - { - /* XXX will LOOKUP_SPECULATIVELY be needed when this is done? */ - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - if (TYPE_SIZE (basetype) == 0) - incomplete_type_error (instance_ptr, basetype); - else - cp_error ("no matching function for call to `%T::%D (%A)%V'", - basetype, pretty_name, user_args, - TREE_TYPE (TREE_TYPE (instance_ptr))); - print_z_candidates (candidates); - return error_mark_node; - } - candidates = splice_viable (candidates); - cand = tourney (candidates); - - if (cand == 0) - { - cp_error ("call of overloaded `%D(%A)' is ambiguous", pretty_name, - user_args); - print_z_candidates (candidates); - return error_mark_node; - } - - if (DECL_ABSTRACT_VIRTUAL_P (cand->fn) - && instance == current_class_ref - && DECL_CONSTRUCTOR_P (current_function_decl) - && ! (flags & LOOKUP_NONVIRTUAL) - && value_member (cand->fn, CLASSTYPE_ABSTRACT_VIRTUALS (basetype))) - cp_error ("abstract virtual `%#D' called from constructor", cand->fn); - if (TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE - && is_dummy_object (instance_ptr)) - cp_error ("cannot call member function `%D' without object", cand->fn); - - if (DECL_VINDEX (cand->fn) && ! (flags & LOOKUP_NONVIRTUAL) - && ((instance == current_class_ref && (dtor_label || ctor_label)) - || resolves_to_fixed_type_p (instance, 0))) - flags |= LOOKUP_NONVIRTUAL; - - /* Pedantically, normal function declarations are never considered - to refer to template instantiations, so we only do this with - -fguiding-decls. */ - if (flag_guiding_decls && templates && ! cand->template - && ! DECL_INITIAL (cand->fn)) - add_maybe_template (cand->fn, templates); - - return build_over_call - (cand, - TREE_CODE (TREE_TYPE (cand->fn)) == METHOD_TYPE ? mem_args : args, - flags); -} - -/* Returns non-zero iff standard conversion sequence ICS1 is a proper - subsequence of ICS2. */ - -static int -is_subseq (ics1, ics2) - tree ics1, ics2; -{ - /* We can assume that a conversion of the same code - between the same types indicates a subsequence since we only get - here if the types we are converting from are the same. */ - - while (TREE_CODE (ics1) == RVALUE_CONV - || TREE_CODE (ics1) == LVALUE_CONV) - ics1 = TREE_OPERAND (ics1, 0); - - while (1) - { - while (TREE_CODE (ics2) == RVALUE_CONV - || TREE_CODE (ics2) == LVALUE_CONV) - ics2 = TREE_OPERAND (ics2, 0); - - if (TREE_CODE (ics2) == USER_CONV - || TREE_CODE (ics2) == AMBIG_CONV - || TREE_CODE (ics2) == IDENTITY_CONV) - /* At this point, ICS1 cannot be a proper subsequence of - ICS2. We can get a USER_CONV when we are comparing the - second standard conversion sequence of two user conversion - sequences. */ - return 0; - - ics2 = TREE_OPERAND (ics2, 0); - - if (TREE_CODE (ics2) == TREE_CODE (ics1) - && same_type_p (TREE_TYPE (ics2), TREE_TYPE (ics1)) - && same_type_p (TREE_TYPE (TREE_OPERAND (ics2, 0)), - TREE_TYPE (TREE_OPERAND (ics1, 0)))) - return 1; - } -} - -/* Returns non-zero iff DERIVED is derived from BASE. The inputs may - be any _TYPE nodes. */ - -static int -is_properly_derived_from (derived, base) - tree derived; - tree base; -{ - if (!IS_AGGR_TYPE_CODE (TREE_CODE (derived)) - || !IS_AGGR_TYPE_CODE (TREE_CODE (base))) - return 0; - - /* We only allow proper derivation here. The DERIVED_FROM_P macro - considers every class derived from itself. */ - return (!same_type_p (TYPE_MAIN_VARIANT (derived), - TYPE_MAIN_VARIANT (base)) - && DERIVED_FROM_P (base, derived)); -} - -/* We build the ICS for an implicit object parameter as a pointer - conversion sequence. However, such a sequence should be compared - as if it were a reference conversion sequence. If ICS is the - implicit conversion sequence for an implicit object parameter, - modify it accordingly. */ - -static void -maybe_handle_implicit_object (ics) - tree* ics; -{ - if (ICS_THIS_FLAG (*ics)) - { - /* [over.match.funcs] - - For non-static member functions, the type of the - implicit object parameter is "reference to cv X" - where X is the class of which the function is a - member and cv is the cv-qualification on the member - function declaration. */ - tree t = *ics; - if (TREE_CODE (t) == QUAL_CONV) - t = TREE_OPERAND (t, 0); - if (TREE_CODE (t) == PTR_CONV) - t = TREE_OPERAND (t, 0); - t = build1 (IDENTITY_CONV, TREE_TYPE (TREE_TYPE (t)), NULL_TREE); - t = build_conv (REF_BIND, - build_reference_type (TREE_TYPE (TREE_TYPE (*ics))), - t); - ICS_STD_RANK (t) = ICS_STD_RANK (*ics); - *ics = t; - } -} - -/* If ICS is a REF_BIND, modify it appropriately, set TARGET_TYPE - to the type the reference originally referred to, and return 1. - Otherwise, return 0. */ - -static int -maybe_handle_ref_bind (ics, target_type) - tree* ics; - tree* target_type; -{ - if (TREE_CODE (*ics) == REF_BIND) - { - /* [over.ics.rank] - - When a parameter of reference type binds directly - (_dcl.init.ref_) to an argument expression, the implicit - conversion sequence is the identity conversion, unless the - argument expression has a type that is a derived class of the - parameter type, in which case the implicit conversion - sequence is a derived-to-base Conversion. - - If the parameter binds directly to the result of applying a - conversion function to the argument expression, the implicit - conversion sequence is a user-defined conversion sequence - (_over.ics.user_), with the second standard conversion - sequence either an identity conversion or, if the conversion - function returns an entity of a type that is a derived class - of the parameter type, a derived-to-base Conversion. - - When a parameter of reference type is not bound directly to - an argument expression, the conversion sequence is the one - required to convert the argument expression to the underlying - type of the reference according to _over.best.ics_. - Conceptually, this conversion sequence corresponds to - copy-initializing a temporary of the underlying type with the - argument expression. Any difference in top-level - cv-qualification is subsumed by the initialization itself and - does not constitute a conversion. */ - - tree old_ics = *ics; - - *target_type = TREE_TYPE (TREE_TYPE (*ics)); - *ics = TREE_OPERAND (*ics, 0); - if (TREE_CODE (*ics) == IDENTITY_CONV - && is_properly_derived_from (TREE_TYPE (*ics), *target_type)) - *ics = build_conv (BASE_CONV, *target_type, *ics); - ICS_USER_FLAG (*ics) = ICS_USER_FLAG (old_ics); - ICS_BAD_FLAG (*ics) = ICS_BAD_FLAG (old_ics); - - return 1; - } - - return 0; -} - -/* Compare two implicit conversion sequences according to the rules set out in - [over.ics.rank]. Return values: - - 1: ics1 is better than ics2 - -1: ics2 is better than ics1 - 0: ics1 and ics2 are indistinguishable */ - -static int -compare_ics (ics1, ics2) - tree ics1, ics2; -{ - tree from_type1; - tree from_type2; - tree to_type1; - tree to_type2; - tree deref_from_type1 = NULL_TREE; - tree deref_from_type2 = NULL_TREE; - tree deref_to_type1 = NULL_TREE; - tree deref_to_type2 = NULL_TREE; - - /* REF_BINDING is non-zero if the result of the conversion sequence - is a reference type. In that case TARGET_TYPE is the - type referred to by the reference. */ - int ref_binding1; - int ref_binding2; - tree target_type1; - tree target_type2; - - /* Handle implicit object parameters. */ - maybe_handle_implicit_object (&ics1); - maybe_handle_implicit_object (&ics2); - - /* Handle reference parameters. */ - ref_binding1 = maybe_handle_ref_bind (&ics1, &target_type1); - ref_binding2 = maybe_handle_ref_bind (&ics2, &target_type2); - - /* [over.ics.rank] - - When comparing the basic forms of implicit conversion sequences (as - defined in _over.best.ics_) - - --a standard conversion sequence (_over.ics.scs_) is a better - conversion sequence than a user-defined conversion sequence - or an ellipsis conversion sequence, and - - --a user-defined conversion sequence (_over.ics.user_) is a - better conversion sequence than an ellipsis conversion sequence - (_over.ics.ellipsis_). */ - if (ICS_RANK (ics1) > ICS_RANK (ics2)) - return -1; - else if (ICS_RANK (ics1) < ICS_RANK (ics2)) - return 1; - - if (ICS_RANK (ics1) == BAD_RANK) - { - /* Both ICS are bad. We try to make a decision based on what - would have happenned if they'd been good. */ - if (ICS_USER_FLAG (ics1) > ICS_USER_FLAG (ics2) - || ICS_STD_RANK (ics1) > ICS_STD_RANK (ics2)) - return -1; - else if (ICS_USER_FLAG (ics1) < ICS_USER_FLAG (ics2) - || ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2)) - return 1; - - /* We couldn't make up our minds; try to figure it out below. */ - } - - if (ICS_ELLIPSIS_FLAG (ics1)) - /* Both conversions are ellipsis conversions. */ - return 0; - - /* User-defined conversion sequence U1 is a better conversion sequence - than another user-defined conversion sequence U2 if they contain the - same user-defined conversion operator or constructor and if the sec- - ond standard conversion sequence of U1 is better than the second - standard conversion sequence of U2. */ - - if (ICS_USER_FLAG (ics1)) - { - tree t1, t2; - - for (t1 = ics1; TREE_CODE (t1) != USER_CONV; t1 = TREE_OPERAND (t1, 0)) - if (TREE_CODE (t1) == AMBIG_CONV) - return 0; - for (t2 = ics2; TREE_CODE (t2) != USER_CONV; t2 = TREE_OPERAND (t2, 0)) - if (TREE_CODE (t2) == AMBIG_CONV) - return 0; - - if (USER_CONV_FN (t1) != USER_CONV_FN (t2)) - return 0; - - /* We can just fall through here, after setting up - FROM_TYPE1 and FROM_TYPE2. */ - from_type1 = TREE_TYPE (t1); - from_type2 = TREE_TYPE (t2); - } - else - { - /* We're dealing with two standard conversion sequences. - - [over.ics.rank] - - Standard conversion sequence S1 is a better conversion - sequence than standard conversion sequence S2 if - - --S1 is a proper subsequence of S2 (comparing the conversion - sequences in the canonical form defined by _over.ics.scs_, - excluding any Lvalue Transformation; the identity - conversion sequence is considered to be a subsequence of - any non-identity conversion sequence */ - - from_type1 = ics1; - while (TREE_CODE (from_type1) != IDENTITY_CONV) - from_type1 = TREE_OPERAND (from_type1, 0); - from_type1 = TREE_TYPE (from_type1); - - from_type2 = ics2; - while (TREE_CODE (from_type2) != IDENTITY_CONV) - from_type2 = TREE_OPERAND (from_type2, 0); - from_type2 = TREE_TYPE (from_type2); - } - - if (same_type_p (from_type1, from_type2)) - { - if (is_subseq (ics1, ics2)) - return 1; - if (is_subseq (ics2, ics1)) - return -1; - } - /* Otherwise, one sequence cannot be a subsequence of the other; they - don't start with the same type. This can happen when comparing the - second standard conversion sequence in two user-defined conversion - sequences. */ - - /* [over.ics.rank] - - Or, if not that, - - --the rank of S1 is better than the rank of S2 (by the rules - defined below): - - Standard conversion sequences are ordered by their ranks: an Exact - Match is a better conversion than a Promotion, which is a better - conversion than a Conversion. - - Two conversion sequences with the same rank are indistinguishable - unless one of the following rules applies: - - --A conversion that is not a conversion of a pointer, or pointer - to member, to bool is better than another conversion that is such - a conversion. - - The ICS_STD_RANK automatically handles the pointer-to-bool rule, - so that we do not have to check it explicitly. */ - if (ICS_STD_RANK (ics1) < ICS_STD_RANK (ics2)) - return 1; - else if (ICS_STD_RANK (ics2) < ICS_STD_RANK (ics1)) - return -1; - - to_type1 = TREE_TYPE (ics1); - to_type2 = TREE_TYPE (ics2); - - if (TYPE_PTR_P (from_type1) - && TYPE_PTR_P (from_type2) - && TYPE_PTR_P (to_type1) - && TYPE_PTR_P (to_type2)) - { - deref_from_type1 = TREE_TYPE (from_type1); - deref_from_type2 = TREE_TYPE (from_type2); - deref_to_type1 = TREE_TYPE (to_type1); - deref_to_type2 = TREE_TYPE (to_type2); - } - /* The rules for pointers to members A::* are just like the rules - for pointers A*, except opposite: if B is derived from A then - A::* converts to B::*, not vice versa. For that reason, we - switch the from_ and to_ variables here. */ - else if (TYPE_PTRMEM_P (from_type1) - && TYPE_PTRMEM_P (from_type2) - && TYPE_PTRMEM_P (to_type1) - && TYPE_PTRMEM_P (to_type2)) - { - deref_to_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type1)); - deref_to_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (from_type2)); - deref_from_type1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type1)); - deref_from_type2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (to_type2)); - } - else if (TYPE_PTRMEMFUNC_P (from_type1) - && TYPE_PTRMEMFUNC_P (from_type2) - && TYPE_PTRMEMFUNC_P (to_type1) - && TYPE_PTRMEMFUNC_P (to_type2)) - { - deref_to_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type1); - deref_to_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (from_type2); - deref_from_type1 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type1); - deref_from_type2 = TYPE_PTRMEMFUNC_OBJECT_TYPE (to_type2); - } - - if (deref_from_type1 != NULL_TREE - && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type1)) - && IS_AGGR_TYPE_CODE (TREE_CODE (deref_from_type2))) - { - /* This was one of the pointer or pointer-like conversions. - - [over.ics.rank] - - --If class B is derived directly or indirectly from class A, - conversion of B* to A* is better than conversion of B* to - void*, and conversion of A* to void* is better than - conversion of B* to void*. */ - if (TREE_CODE (deref_to_type1) == VOID_TYPE - && TREE_CODE (deref_to_type2) == VOID_TYPE) - { - if (is_properly_derived_from (deref_from_type1, - deref_from_type2)) - return -1; - else if (is_properly_derived_from (deref_from_type2, - deref_from_type1)) - return 1; - } - else if (TREE_CODE (deref_to_type1) == VOID_TYPE - || TREE_CODE (deref_to_type2) == VOID_TYPE) - { - if (same_type_p (deref_from_type1, deref_from_type2)) - { - if (TREE_CODE (deref_to_type2) == VOID_TYPE) - { - if (is_properly_derived_from (deref_from_type1, - deref_to_type1)) - return 1; - } - /* We know that DEREF_TO_TYPE1 is `void' here. */ - else if (is_properly_derived_from (deref_from_type1, - deref_to_type2)) - return -1; - } - } - else if (IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type1)) - && IS_AGGR_TYPE_CODE (TREE_CODE (deref_to_type2))) - { - /* [over.ics.rank] - - --If class B is derived directly or indirectly from class A - and class C is derived directly or indirectly from B, - - --conversion of C* to B* is better than conversion of C* to - A*, - - --conversion of B* to A* is better than conversion of C* to - A* */ - if (same_type_p (deref_from_type1, deref_from_type2)) - { - if (is_properly_derived_from (deref_to_type1, - deref_to_type2)) - return 1; - else if (is_properly_derived_from (deref_to_type2, - deref_to_type1)) - return -1; - } - else if (same_type_p (deref_to_type1, deref_to_type2)) - { - if (is_properly_derived_from (deref_from_type2, - deref_from_type1)) - return 1; - else if (is_properly_derived_from (deref_from_type1, - deref_from_type2)) - return -1; - } - } - } - else if (IS_AGGR_TYPE_CODE (TREE_CODE (from_type1)) - && same_type_p (from_type1, from_type2)) - { - /* [over.ics.rank] - - --binding of an expression of type C to a reference of type - B& is better than binding an expression of type C to a - reference of type A& - - --conversion of C to B is better than conversion of C to A, */ - if (is_properly_derived_from (from_type1, to_type1) - && is_properly_derived_from (from_type1, to_type2)) - { - if (is_properly_derived_from (to_type1, to_type2)) - return 1; - else if (is_properly_derived_from (to_type2, to_type1)) - return -1; - } - } - else if (IS_AGGR_TYPE_CODE (TREE_CODE (to_type1)) - && same_type_p (to_type1, to_type2)) - { - /* [over.ics.rank] - - --binding of an expression of type B to a reference of type - A& is better than binding an expression of type C to a - reference of type A&, - - --onversion of B to A is better than conversion of C to A */ - if (is_properly_derived_from (from_type1, to_type1) - && is_properly_derived_from (from_type2, to_type1)) - { - if (is_properly_derived_from (from_type2, from_type1)) - return 1; - else if (is_properly_derived_from (from_type1, from_type2)) - return -1; - } - } - - /* [over.ics.rank] - - --S1 and S2 differ only in their qualification conversion and yield - similar types T1 and T2 (_conv.qual_), respectively, and the cv- - qualification signature of type T1 is a proper subset of the cv- - qualification signature of type T2 */ - if (TREE_CODE (ics1) == QUAL_CONV - && TREE_CODE (ics2) == QUAL_CONV - && same_type_p (from_type1, from_type2)) - return comp_cv_qual_signature (to_type1, to_type2); - - /* [over.ics.rank] - - --S1 and S2 are reference bindings (_dcl.init.ref_), and the - types to which the references refer are the same type except for - top-level cv-qualifiers, and the type to which the reference - initialized by S2 refers is more cv-qualified than the type to - which the reference initialized by S1 refers */ - - if (ref_binding1 && ref_binding2 - && same_type_p (TYPE_MAIN_VARIANT (to_type1), - TYPE_MAIN_VARIANT (to_type2))) - return comp_cv_qualification (target_type2, target_type1); - - /* Neither conversion sequence is better than the other. */ - return 0; -} - -/* The source type for this standard conversion sequence. */ - -static tree -source_type (t) - tree t; -{ - for (;; t = TREE_OPERAND (t, 0)) - { - if (TREE_CODE (t) == USER_CONV - || TREE_CODE (t) == AMBIG_CONV - || TREE_CODE (t) == IDENTITY_CONV) - return TREE_TYPE (t); - } - my_friendly_abort (1823); -} - -/* Note a warning about preferring WINNER to LOSER. We do this by storing - a pointer to LOSER and re-running joust to produce the warning if WINNER - is actually used. */ - -static void -add_warning (winner, loser) - struct z_candidate *winner, *loser; -{ - winner->warnings = expr_tree_cons (NULL_PTR, - build_expr_ptr_wrapper (loser), - winner->warnings); -} - -/* Compare two candidates for overloading as described in - [over.match.best]. Return values: - - 1: cand1 is better than cand2 - -1: cand2 is better than cand1 - 0: cand1 and cand2 are indistinguishable */ - -static int -joust (cand1, cand2, warn) - struct z_candidate *cand1, *cand2; - int warn; -{ - int winner = 0; - int i, off1 = 0, off2 = 0, len; - - /* Candidates that involve bad conversions are always worse than those - that don't. */ - if (cand1->viable > cand2->viable) - return 1; - if (cand1->viable < cand2->viable) - 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) - return 1; - - /* a viable function F1 - is defined to be a better function than another viable function F2 if - for all arguments i, ICSi(F1) is not a worse conversion sequence than - ICSi(F2), and then */ - - /* for some argument j, ICSj(F1) is a better conversion sequence than - ICSj(F2) */ - - /* For comparing static and non-static member functions, we ignore the - implicit object parameter of the non-static function. The WP says to - pretend that the static function has an object parm, but that won't - work with operator overloading. */ - len = TREE_VEC_LENGTH (cand1->convs); - if (len != TREE_VEC_LENGTH (cand2->convs)) - { - if (DECL_STATIC_FUNCTION_P (cand1->fn) - && ! DECL_STATIC_FUNCTION_P (cand2->fn)) - off2 = 1; - else if (! DECL_STATIC_FUNCTION_P (cand1->fn) - && DECL_STATIC_FUNCTION_P (cand2->fn)) - { - off1 = 1; - --len; - } - else - my_friendly_abort (42); - } - - for (i = 0; i < len; ++i) - { - tree t1 = TREE_VEC_ELT (cand1->convs, i+off1); - tree t2 = TREE_VEC_ELT (cand2->convs, i+off2); - int comp = compare_ics (t1, t2); - - if (comp != 0) - { - if (warn_sign_promo - && ICS_RANK (t1) + ICS_RANK (t2) == STD_RANK + PROMO_RANK - && TREE_CODE (t1) == STD_CONV - && TREE_CODE (t2) == STD_CONV - && TREE_CODE (TREE_TYPE (t1)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (t2)) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (t1)) - == TYPE_PRECISION (TREE_TYPE (t2))) - && (TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (t1, 0))) - || (TREE_CODE (TREE_TYPE (TREE_OPERAND (t1, 0))) - == ENUMERAL_TYPE))) - { - tree type = TREE_TYPE (TREE_OPERAND (t1, 0)); - tree type1, type2; - struct z_candidate *w, *l; - if (comp > 0) - type1 = TREE_TYPE (t1), type2 = TREE_TYPE (t2), - w = cand1, l = cand2; - else - type1 = TREE_TYPE (t2), type2 = TREE_TYPE (t1), - w = cand2, l = cand1; - - if (warn) - { - cp_warning ("passing `%T' chooses `%T' over `%T'", - type, type1, type2); - cp_warning (" in call to `%D'", w->fn); - } - else - add_warning (w, l); - } - - if (winner && comp != winner) - { - winner = 0; - goto tweak; - } - winner = comp; - } - } - - /* warn about confusing overload resolution for user-defined conversions, - either between a constructor and a conversion op, or between two - conversion ops. */ - if (winner && cand1->second_conv - && ((DECL_CONSTRUCTOR_P (cand1->fn) - != DECL_CONSTRUCTOR_P (cand2->fn)) - /* Don't warn if the two conv ops convert to the same type... */ - || (! DECL_CONSTRUCTOR_P (cand1->fn) - && ! same_type_p (TREE_TYPE (cand1->second_conv), - TREE_TYPE (cand2->second_conv))))) - { - int comp = compare_ics (cand1->second_conv, cand2->second_conv); - if (comp != winner) - { - struct z_candidate *w, *l; - if (winner == 1) - w = cand1, l = cand2; - else - w = cand2, l = cand1; - if (warn) - { - tree source = source_type (TREE_VEC_ELT (w->convs, 0)); - if (! DECL_CONSTRUCTOR_P (w->fn)) - source = TREE_TYPE (source); - cp_warning ("choosing `%D' over `%D'", w->fn, l->fn); - cp_warning (" for conversion from `%T' to `%T'", - source, TREE_TYPE (w->second_conv)); - cp_warning (" because conversion sequence for the argument is better"); - } - else - add_warning (w, l); - } - } - - if (winner) - return winner; - - /* or, if not that, - F1 is a non-template function and F2 is a template function */ - - if (! cand1->template && cand2->template) - return 1; - else if (cand1->template && ! cand2->template) - return -1; - else if (cand1->template && cand2->template) - winner = more_specialized - (TI_TEMPLATE (cand1->template), TI_TEMPLATE (cand2->template), - NULL_TREE); - - /* or, if not that, - the context is an initialization by user-defined conversion (see - _dcl.init_ and _over.match.user_) and the standard conversion - sequence from the return type of F1 to the destination type (i.e., - the type of the entity being initialized) is a better conversion - sequence than the standard conversion sequence from the return type - of F2 to the destination type. */ - - if (! winner && cand1->second_conv) - winner = compare_ics (cand1->second_conv, cand2->second_conv); - - /* If the built-in candidates are the same, arbitrarily pick one. */ - if (! winner && cand1->fn == cand2->fn - && TREE_CODE (cand1->fn) == IDENTIFIER_NODE) - { - for (i = 0; i < len; ++i) - if (!same_type_p (TREE_TYPE (TREE_VEC_ELT (cand1->convs, i)), - TREE_TYPE (TREE_VEC_ELT (cand2->convs, i)))) - break; - if (i == TREE_VEC_LENGTH (cand1->convs)) - return 1; - - /* Kludge around broken overloading rules whereby - Integer a, b; test ? a : b; is ambiguous, since there's a builtin - that takes references and another that takes values. */ - if (cand1->fn == ansi_opname[COND_EXPR]) - { - tree c1 = TREE_VEC_ELT (cand1->convs, 1); - tree c2 = TREE_VEC_ELT (cand2->convs, 1); - tree t1 = strip_top_quals (non_reference (TREE_TYPE (c1))); - tree t2 = strip_top_quals (non_reference (TREE_TYPE (c2))); - - if (same_type_p (t1, t2)) - { - if (TREE_CODE (c1) == REF_BIND && TREE_CODE (c2) != REF_BIND) - return 1; - if (TREE_CODE (c1) != REF_BIND && TREE_CODE (c2) == REF_BIND) - return -1; - } - } - } - -tweak: - - /* Extension: If the worst conversion for one candidate is worse than the - worst conversion for the other, take the first. */ - if (! winner && ! pedantic) - { - int rank1 = IDENTITY_RANK, rank2 = IDENTITY_RANK; - - for (i = 0; i < len; ++i) - { - if (ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)) > rank1) - rank1 = ICS_RANK (TREE_VEC_ELT (cand1->convs, i+off1)); - if (ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)) > rank2) - rank2 = ICS_RANK (TREE_VEC_ELT (cand2->convs, i+off2)); - } - - if (rank1 < rank2) - return 1; - if (rank1 > rank2) - return -1; - } - - return winner; -} - -/* Given a list of candidates for overloading, find the best one, if any. - This algorithm has a worst case of O(2n) (winner is last), and a best - case of O(n/2) (totally ambiguous); much better than a sorting - algorithm. */ - -static struct z_candidate * -tourney (candidates) - struct z_candidate *candidates; -{ - struct z_candidate *champ = candidates, *challenger; - int fate; - int champ_compared_to_predecessor = 0; - - /* Walk through the list once, comparing each current champ to the next - candidate, knocking out a candidate or two with each comparison. */ - - for (challenger = champ->next; challenger; ) - { - fate = joust (champ, challenger, 0); - if (fate == 1) - challenger = challenger->next; - else - { - if (fate == 0) - { - champ = challenger->next; - if (champ == 0) - return 0; - champ_compared_to_predecessor = 0; - } - else - { - champ = challenger; - champ_compared_to_predecessor = 1; - } - - challenger = champ->next; - } - } - - /* Make sure the champ is better than all the candidates it hasn't yet - been compared to. */ - - for (challenger = candidates; - challenger != champ - && !(champ_compared_to_predecessor && challenger->next == champ); - challenger = challenger->next) - { - fate = joust (champ, challenger, 0); - if (fate != 1) - return 0; - } - - return champ; -} - -int -can_convert (to, from) - tree to, from; -{ - tree t = implicit_conversion (to, from, NULL_TREE, LOOKUP_NORMAL); - return (t && ! ICS_BAD_FLAG (t)); -} - -int -can_convert_arg (to, from, arg) - tree to, from, arg; -{ - tree t = implicit_conversion (to, from, arg, LOOKUP_NORMAL); - return (t && ! ICS_BAD_FLAG (t)); -} diff --git a/gcc/cp/class.c b/gcc/cp/class.c deleted file mode 100755 index a219b7d..0000000 --- a/gcc/cp/class.c +++ /dev/null @@ -1,5669 +0,0 @@ -/* Functions related to building classes and their related objects. - Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* High-level class interface. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" -#include "rtl.h" -#include "output.h" -#include "toplev.h" - -#include "obstack.h" -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern struct obstack permanent_obstack; - -/* This is how we tell when two virtual member functions are really the - same. */ -#define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL)) - -extern void set_class_shadows PROTO ((tree)); - -/* The number of nested classes being processed. If we are not in the - scope of any class, this is zero. */ - -int current_class_depth; - -/* In order to deal with nested classes, we keep a stack of classes. - The topmost entry is the innermost class, and is the entry at index - CURRENT_CLASS_DEPTH */ - -typedef struct class_stack_node { - /* The name of the class. */ - tree name; - - /* The _TYPE node for the class. */ - tree type; - - /* The access specifier pending for new declarations in the scope of - this class. */ - tree access; -}* class_stack_node_t; - -/* The stack itself. This is an dynamically resized array. The - number of elements allocated is CURRENT_CLASS_STACK_SIZE. */ -static int current_class_stack_size; -static class_stack_node_t current_class_stack; - -/* When we're processing a member function, current_class_ptr is the - PARM_DECL for the `this' pointer. The current_class_ref is an - expression for `*this'. */ -tree current_class_ptr, current_class_ref; - -/* The following two can be derived from the previous one */ -tree current_class_name; /* IDENTIFIER_NODE: name of current class */ -tree current_class_type; /* _TYPE: the type of the current class */ -tree current_access_specifier; -tree previous_class_type; /* _TYPE: the previous type that was a class */ -tree previous_class_values; /* TREE_LIST: copy of the class_shadowed list - when leaving an outermost class scope. */ - -/* The obstack on which the cached class declarations are kept. */ -static struct obstack class_cache_obstack; -/* The first object allocated on that obstack. We can use - obstack_free with tis value to free the entire obstack. */ -static char *class_cache_firstobj; - -struct base_info; - -static tree get_vfield_name PROTO((tree)); -static void finish_struct_anon PROTO((tree)); -static tree build_vbase_pointer PROTO((tree, tree)); -static tree build_vtable_entry PROTO((tree, tree)); -static tree get_vtable_name PROTO((tree)); -static tree get_derived_offset PROTO((tree, tree)); -static tree get_basefndecls PROTO((tree, tree)); -static void set_rtti_entry PROTO((tree, tree, tree)); -static tree build_vtable PROTO((tree, tree)); -static void prepare_fresh_vtable PROTO((tree, tree)); -static void fixup_vtable_deltas1 PROTO((tree, tree)); -static void fixup_vtable_deltas PROTO((tree, int, tree)); -static void finish_vtbls PROTO((tree, int, tree)); -static void modify_vtable_entry PROTO((tree, tree, tree)); -static tree get_vtable_entry_n PROTO((tree, unsigned HOST_WIDE_INT)); -static void add_virtual_function PROTO((tree *, tree *, int *, tree, tree)); -static tree delete_duplicate_fields_1 PROTO((tree, tree)); -static void delete_duplicate_fields PROTO((tree)); -static void finish_struct_bits PROTO((tree, int)); -static int alter_access PROTO((tree, tree, tree, tree)); -static void handle_using_decl PROTO((tree, tree, tree, tree)); -static int overrides PROTO((tree, tree)); -static int strictly_overrides PROTO((tree, tree)); -static void merge_overrides PROTO((tree, tree, int, tree)); -static void override_one_vtable PROTO((tree, tree, tree)); -static void mark_overriders PROTO((tree, tree)); -static void check_for_override PROTO((tree, tree)); -static tree maybe_fixup_vptrs PROTO((tree, tree, tree)); -static tree get_class_offset_1 PROTO((tree, tree, tree, tree, tree)); -static tree get_class_offset PROTO((tree, tree, tree, tree)); -static void modify_one_vtable PROTO((tree, tree, tree, tree)); -static void modify_all_vtables PROTO((tree, tree, tree)); -static void modify_all_direct_vtables PROTO((tree, int, tree, tree, - tree)); -static void modify_all_indirect_vtables PROTO((tree, int, int, tree, - tree, tree)); -static void build_class_init_list PROTO((tree)); -static int finish_base_struct PROTO((tree, struct base_info *)); -static void finish_struct_methods PROTO((tree)); -static void maybe_warn_about_overly_private_class PROTO ((tree)); -static void check_member_decl_is_same_in_complete_scope PROTO((tree, tree)); -static tree make_method_vec PROTO((int)); -static void free_method_vec PROTO((tree)); -static tree add_implicitly_declared_members PROTO((tree, int, int, int)); - -/* Way of stacking language names. */ -tree *current_lang_base, *current_lang_stack; -int current_lang_stacksize; - -/* Names of languages we recognize. */ -tree lang_name_c, lang_name_cplusplus, lang_name_java; -tree current_lang_name; - -/* When layout out an aggregate type, the size of the - basetypes (virtual and non-virtual) is passed to layout_record - via this node. */ -static tree base_layout_decl; - -/* Constants used for access control. */ -tree access_default_node; /* 0 */ -tree access_public_node; /* 1 */ -tree access_protected_node; /* 2 */ -tree access_private_node; /* 3 */ -tree access_default_virtual_node; /* 4 */ -tree access_public_virtual_node; /* 5 */ -tree access_protected_virtual_node; /* 6 */ -tree access_private_virtual_node; /* 7 */ - -/* Variables shared between class.c and call.c. */ - -#ifdef GATHER_STATISTICS -int n_vtables = 0; -int n_vtable_entries = 0; -int n_vtable_searches = 0; -int n_vtable_elems = 0; -int n_convert_harshness = 0; -int n_compute_conversion_costs = 0; -int n_build_method_call = 0; -int n_inner_fields_searched = 0; -#endif - -/* Virtual baseclass things. */ - -static tree -build_vbase_pointer (exp, type) - tree exp, type; -{ - char *name; - FORMAT_VBASE_NAME (name, type); - - return build_component_ref (exp, get_identifier (name), NULL_TREE, 0); -} - -#if 0 -/* Is the type of the EXPR, the complete type of the object? - If we are going to be wrong, we must be conservative, and return 0. */ - -static int -complete_type_p (expr) - tree expr; -{ - tree type = TYPE_MAIN_VARIANT (TREE_TYPE (expr)); - while (1) - { - switch (TREE_CODE (expr)) - { - case SAVE_EXPR: - case INDIRECT_REF: - case ADDR_EXPR: - case NOP_EXPR: - case CONVERT_EXPR: - expr = TREE_OPERAND (expr, 0); - continue; - - case CALL_EXPR: - if (! TREE_HAS_CONSTRUCTOR (expr)) - break; - /* fall through... */ - case VAR_DECL: - case FIELD_DECL: - if (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE - && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (expr))) - && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type) - return 1; - /* fall through... */ - case TARGET_EXPR: - case PARM_DECL: - if (IS_AGGR_TYPE (TREE_TYPE (expr)) - && TYPE_MAIN_VARIANT (TREE_TYPE (expr)) == type) - return 1; - /* fall through... */ - case PLUS_EXPR: - default: - break; - } - break; - } - return 0; -} -#endif - -/* Build multi-level access to EXPR using hierarchy path PATH. - CODE is PLUS_EXPR if we are going with the grain, - and MINUS_EXPR if we are not (in which case, we cannot traverse - virtual baseclass links). - - TYPE is the type we want this path to have on exit. - - NONNULL is non-zero if we know (for any reason) that EXPR is - not, in fact, zero. */ - -tree -build_vbase_path (code, type, expr, path, nonnull) - enum tree_code code; - tree type, expr, path; - int nonnull; -{ - register int changed = 0; - tree last = NULL_TREE, last_virtual = NULL_TREE; - int fixed_type_p; - tree null_expr = 0, nonnull_expr; - tree basetype; - tree offset = integer_zero_node; - - if (BINFO_INHERITANCE_CHAIN (path) == NULL_TREE) - return build1 (NOP_EXPR, type, expr); - - /* If -fthis-is-variable, we might have set nonnull incorrectly. We - don't care enough to get this right, so just clear it. */ - if (flag_this_is_variable > 0) - nonnull = 0; - - /* We could do better if we had additional logic to convert back to the - unconverted type (the static type of the complete object), and then - convert back to the type we want. Until that is done, we only optimize - if the complete type is the same type as expr has. */ - fixed_type_p = resolves_to_fixed_type_p (expr, &nonnull); - - if (!fixed_type_p && TREE_SIDE_EFFECTS (expr)) - expr = save_expr (expr); - nonnull_expr = expr; - - if (BINFO_INHERITANCE_CHAIN (path)) - path = reverse_path (path); - - basetype = BINFO_TYPE (path); - - while (path) - { - if (TREE_VIA_VIRTUAL (path)) - { - last_virtual = BINFO_TYPE (path); - if (code == PLUS_EXPR) - { - changed = ! fixed_type_p; - - if (changed) - { - tree ind; - - /* We already check for ambiguous things in the caller, just - find a path. */ - if (last) - { - tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (nonnull_expr))), 0); - nonnull_expr = convert_pointer_to_real (binfo, nonnull_expr); - } - ind = build_indirect_ref (nonnull_expr, NULL_PTR); - nonnull_expr = build_vbase_pointer (ind, last_virtual); - if (nonnull == 0 - && TREE_CODE (type) == POINTER_TYPE - && null_expr == NULL_TREE) - { - null_expr = build1 (NOP_EXPR, build_pointer_type (last_virtual), integer_zero_node); - expr = build (COND_EXPR, build_pointer_type (last_virtual), - build (EQ_EXPR, boolean_type_node, expr, - integer_zero_node), - null_expr, nonnull_expr); - } - } - /* else we'll figure out the offset below. */ - - /* Happens in the case of parse errors. */ - if (nonnull_expr == error_mark_node) - return error_mark_node; - } - else - { - cp_error ("cannot cast up from virtual baseclass `%T'", - last_virtual); - return error_mark_node; - } - } - last = path; - path = BINFO_INHERITANCE_CHAIN (path); - } - /* LAST is now the last basetype assoc on the path. */ - - /* A pointer to a virtual base member of a non-null object - is non-null. Therefore, we only need to test for zeroness once. - Make EXPR the canonical expression to deal with here. */ - if (null_expr) - { - TREE_OPERAND (expr, 2) = nonnull_expr; - TREE_TYPE (expr) = TREE_TYPE (TREE_OPERAND (expr, 1)) - = TREE_TYPE (nonnull_expr); - } - else - expr = nonnull_expr; - - /* If we go through any virtual base pointers, make sure that - casts to BASETYPE from the last virtual base class use - the right value for BASETYPE. */ - if (changed) - { - tree intype = TREE_TYPE (TREE_TYPE (expr)); - if (TYPE_MAIN_VARIANT (intype) != BINFO_TYPE (last)) - { - tree binfo = get_binfo (last, TYPE_MAIN_VARIANT (intype), 0); - offset = BINFO_OFFSET (binfo); - } - } - else - { - if (last_virtual) - { - offset = BINFO_OFFSET (binfo_member (last_virtual, - CLASSTYPE_VBASECLASSES (basetype))); - offset = size_binop (PLUS_EXPR, offset, BINFO_OFFSET (last)); - } - else - offset = BINFO_OFFSET (last); - } - - if (TREE_INT_CST_LOW (offset)) - { - /* Bash types to make the backend happy. */ - offset = cp_convert (type, offset); -#if 0 - /* This shouldn't be necessary. (mrs) */ - expr = build1 (NOP_EXPR, type, expr); -#endif - - /* If expr might be 0, we need to preserve that zeroness. */ - if (nonnull == 0) - { - if (null_expr) - TREE_TYPE (null_expr) = type; - else - null_expr = build1 (NOP_EXPR, type, integer_zero_node); - if (TREE_SIDE_EFFECTS (expr)) - expr = save_expr (expr); - - return build (COND_EXPR, type, - build (EQ_EXPR, boolean_type_node, expr, integer_zero_node), - null_expr, - build (code, type, expr, offset)); - } - else return build (code, type, expr, offset); - } - - /* Cannot change the TREE_TYPE of a NOP_EXPR here, since it may - be used multiple times in initialization of multiple inheritance. */ - if (null_expr) - { - TREE_TYPE (expr) = type; - return expr; - } - else - return build1 (NOP_EXPR, type, expr); -} - -/* Virtual function things. */ - -/* Build an entry in the virtual function table. - DELTA is the offset for the `this' pointer. - PFN is an ADDR_EXPR containing a pointer to the virtual function. - Note that the index (DELTA2) in the virtual function table - is always 0. */ - -static tree -build_vtable_entry (delta, pfn) - tree delta, pfn; -{ - if (flag_vtable_thunks) - { - HOST_WIDE_INT idelta = TREE_INT_CST_LOW (delta); - if (idelta && ! DECL_ABSTRACT_VIRTUAL_P (TREE_OPERAND (pfn, 0))) - { - pfn = build1 (ADDR_EXPR, vtable_entry_type, - make_thunk (pfn, idelta)); - TREE_READONLY (pfn) = 1; - TREE_CONSTANT (pfn) = 1; - } -#ifdef GATHER_STATISTICS - n_vtable_entries += 1; -#endif - return pfn; - } - else - { - extern int flag_huge_objects; - tree elems = expr_tree_cons (NULL_TREE, delta, - expr_tree_cons (NULL_TREE, integer_zero_node, - build_expr_list (NULL_TREE, pfn))); - tree entry = build (CONSTRUCTOR, vtable_entry_type, NULL_TREE, elems); - - /* DELTA used to be constructed by `size_int' and/or size_binop, - which caused overflow problems when it was negative. That should - be fixed now. */ - - if (! int_fits_type_p (delta, delta_type_node)) - { - if (flag_huge_objects) - sorry ("object size exceeds built-in limit for virtual function table implementation"); - else - sorry ("object size exceeds normal limit for virtual function table implementation, recompile all source and use -fhuge-objects"); - } - - TREE_CONSTANT (entry) = 1; - TREE_STATIC (entry) = 1; - TREE_READONLY (entry) = 1; - -#ifdef GATHER_STATISTICS - n_vtable_entries += 1; -#endif - - return entry; - } -} - -/* We want to give the assembler the vtable identifier as well as - the offset to the function pointer. So we generate - - __asm__ __volatile__ (".vtable_entry %c0, %c1" - : : "s"(&class_vtable), - "i"((long)&vtbl[idx].pfn - (long)&vtbl[0])); */ - -static void -build_vtable_entry_ref (basetype, vtbl, idx) - tree basetype, vtbl, idx; -{ - static char asm_stmt[] = ".vtable_entry %c0, %c1"; - tree s, i, i2; - - s = build_unary_op (ADDR_EXPR, TYPE_BINFO_VTABLE (basetype), 0); - s = build_tree_list (build_string (1, "s"), s); - - i = build_array_ref (vtbl, idx); - if (!flag_vtable_thunks) - i = build_component_ref (i, pfn_identifier, vtable_entry_type, 0); - i = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i, 0)); - i2 = build_array_ref (vtbl, build_int_2(0,0)); - i2 = build_c_cast (ptrdiff_type_node, build_unary_op (ADDR_EXPR, i2, 0)); - i = build_binary_op (MINUS_EXPR, i, i2, 0); - i = build_tree_list (build_string (1, "i"), i); - - expand_asm_operands (build_string (sizeof(asm_stmt)-1, asm_stmt), - NULL_TREE, chainon (s, i), NULL_TREE, 1, NULL, 0); -} - -/* Given an object INSTANCE, return an expression which yields the - virtual function vtable element corresponding to INDEX. There are - many special cases for INSTANCE which we take care of here, mainly - to avoid creating extra tree nodes when we don't have to. */ - -tree -build_vtbl_ref (instance, idx) - tree instance, idx; -{ - tree vtbl, aref; - tree basetype = TREE_TYPE (instance); - - if (TREE_CODE (basetype) == REFERENCE_TYPE) - basetype = TREE_TYPE (basetype); - - if (instance == current_class_ref) - vtbl = build_vfield_ref (instance, basetype); - else - { - if (optimize) - { - /* Try to figure out what a reference refers to, and - access its virtual function table directly. */ - tree ref = NULL_TREE; - - if (TREE_CODE (instance) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (instance, 0))) == REFERENCE_TYPE) - ref = TREE_OPERAND (instance, 0); - else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) - ref = instance; - - if (ref && TREE_CODE (ref) == VAR_DECL - && DECL_INITIAL (ref)) - { - tree init = DECL_INITIAL (ref); - - while (TREE_CODE (init) == NOP_EXPR - || TREE_CODE (init) == NON_LVALUE_EXPR) - init = TREE_OPERAND (init, 0); - if (TREE_CODE (init) == ADDR_EXPR) - { - init = TREE_OPERAND (init, 0); - if (IS_AGGR_TYPE (TREE_TYPE (init)) - && (TREE_CODE (init) == PARM_DECL - || TREE_CODE (init) == VAR_DECL)) - instance = init; - } - } - } - - if (IS_AGGR_TYPE (TREE_TYPE (instance)) - && (TREE_CODE (instance) == RESULT_DECL - || TREE_CODE (instance) == PARM_DECL - || TREE_CODE (instance) == VAR_DECL)) - vtbl = TYPE_BINFO_VTABLE (basetype); - else - vtbl = build_vfield_ref (instance, basetype); - } - - assemble_external (vtbl); - - if (flag_vtable_gc) - build_vtable_entry_ref (basetype, vtbl, idx); - - aref = build_array_ref (vtbl, idx); - - return aref; -} - -/* Given an object INSTANCE, return an expression which yields the - virtual function corresponding to INDEX. There are many special - cases for INSTANCE which we take care of here, mainly to avoid - creating extra tree nodes when we don't have to. */ - -tree -build_vfn_ref (ptr_to_instptr, instance, idx) - tree *ptr_to_instptr, instance; - tree idx; -{ - tree aref = build_vtbl_ref (instance, idx); - - /* When using thunks, there is no extra delta, and we get the pfn - directly. */ - if (flag_vtable_thunks) - return aref; - - if (ptr_to_instptr) - { - /* Save the intermediate result in a SAVE_EXPR so we don't have to - compute each component of the virtual function pointer twice. */ - if (TREE_CODE (aref) == INDIRECT_REF) - TREE_OPERAND (aref, 0) = save_expr (TREE_OPERAND (aref, 0)); - - *ptr_to_instptr - = build (PLUS_EXPR, TREE_TYPE (*ptr_to_instptr), - *ptr_to_instptr, - cp_convert (ptrdiff_type_node, - build_component_ref (aref, delta_identifier, NULL_TREE, 0))); - } - - return build_component_ref (aref, pfn_identifier, NULL_TREE, 0); -} - -/* Return the name of the virtual function table (as an IDENTIFIER_NODE) - for the given TYPE. */ - -static tree -get_vtable_name (type) - tree type; -{ - tree type_id = build_typename_overload (type); - char *buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) - + IDENTIFIER_LENGTH (type_id) + 2); - char *ptr = IDENTIFIER_POINTER (type_id); - int i; - for (i = 0; ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) ; -#if 0 - /* We don't take off the numbers; prepare_fresh_vtable uses the - DECL_ASSEMBLER_NAME for the type, which includes the number - in `3foo'. If we were to pull them off here, we'd end up with - something like `_vt.foo.3bar', instead of a uniform definition. */ - while (ptr[i] >= '0' && ptr[i] <= '9') - i += 1; -#endif - sprintf (buf, VTABLE_NAME_FORMAT, ptr+i); - return get_identifier (buf); -} - -/* Return the offset to the main vtable for a given base BINFO. */ - -tree -get_vfield_offset (binfo) - tree binfo; -{ - tree tmp - = size_binop (FLOOR_DIV_EXPR, - DECL_FIELD_BITPOS (CLASSTYPE_VFIELD (BINFO_TYPE (binfo))), - size_int (BITS_PER_UNIT)); - tmp = convert (sizetype, tmp); - return size_binop (PLUS_EXPR, tmp, BINFO_OFFSET (binfo)); -} - -/* Get the offset to the start of the original binfo that we derived - this binfo from. If we find TYPE first, return the offset only - that far. The shortened search is useful because the this pointer - on method calling is expected to point to a DECL_CONTEXT (fndecl) - object, and not a baseclass of it. */ - -static tree -get_derived_offset (binfo, type) - tree binfo, type; -{ - tree offset1 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); - tree offset2; - int i; - while (BINFO_BASETYPES (binfo) - && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) - { - tree binfos = BINFO_BASETYPES (binfo); - if (BINFO_TYPE (binfo) == type) - break; - binfo = TREE_VEC_ELT (binfos, i); - } - offset2 = get_vfield_offset (TYPE_BINFO (BINFO_TYPE (binfo))); - return size_binop (MINUS_EXPR, offset1, offset2); -} - -/* Update the rtti info for this class. */ - -static void -set_rtti_entry (virtuals, offset, type) - tree virtuals, offset, type; -{ - tree vfn; - - if (flag_rtti) - vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, get_tinfo_fn (type)); - else - vfn = build1 (NOP_EXPR, vfunc_ptr_type_node, size_zero_node); - TREE_CONSTANT (vfn) = 1; - - if (! flag_vtable_thunks) - TREE_VALUE (virtuals) = build_vtable_entry (offset, vfn); - else - { - tree voff = build1 (NOP_EXPR, vfunc_ptr_type_node, offset); - TREE_CONSTANT (voff) = 1; - - TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, voff); - - /* The second slot is for the tdesc pointer when thunks are used. */ - TREE_VALUE (TREE_CHAIN (virtuals)) - = build_vtable_entry (integer_zero_node, vfn); - } -} - -/* Build a virtual function for type TYPE. - If BINFO is non-NULL, build the vtable starting with the initial - approximation that it is the same as the one which is the head of - the association list. */ - -static tree -build_vtable (binfo, type) - tree binfo, type; -{ - tree name = get_vtable_name (type); - tree virtuals, decl; - - if (binfo) - { - tree offset; - - virtuals = copy_list (BINFO_VIRTUALS (binfo)); - decl = build_decl (VAR_DECL, name, TREE_TYPE (BINFO_VTABLE (binfo))); - - /* Now do rtti stuff. */ - offset = get_derived_offset (TYPE_BINFO (type), NULL_TREE); - offset = ssize_binop (MINUS_EXPR, integer_zero_node, offset); - set_rtti_entry (virtuals, offset, type); - } - else - { - virtuals = NULL_TREE; - decl = build_decl (VAR_DECL, name, void_type_node); - } - -#ifdef GATHER_STATISTICS - n_vtables += 1; - n_vtable_elems += list_length (virtuals); -#endif - - /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - import_export_vtable (decl, type, 0); - - decl = pushdecl_top_level (decl); - SET_IDENTIFIER_GLOBAL_VALUE (name, decl); - /* Initialize the association list for this type, based - on our first approximation. */ - TYPE_BINFO_VTABLE (type) = decl; - TYPE_BINFO_VIRTUALS (type) = virtuals; - - DECL_ARTIFICIAL (decl) = 1; - TREE_STATIC (decl) = 1; -#ifndef WRITABLE_VTABLES - /* Make them READONLY by default. (mrs) */ - TREE_READONLY (decl) = 1; -#endif - /* At one time the vtable info was grabbed 2 words at a time. This - fails on sparc unless you have 8-byte alignment. (tiemann) */ - DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (decl)); - - DECL_VIRTUAL_P (decl) = 1; - DECL_CONTEXT (decl) = type; - - binfo = TYPE_BINFO (type); - SET_BINFO_NEW_VTABLE_MARKED (binfo); - return decl; -} - -extern tree signed_size_zero_node; - -/* Give TYPE a new virtual function table which is initialized - with a skeleton-copy of its original initialization. The only - entry that changes is the `delta' entry, so we can really - share a lot of structure. - - FOR_TYPE is the derived type which caused this table to - be needed. - - BINFO is the type association which provided TYPE for FOR_TYPE. - - The order in which vtables are built (by calling this function) for - an object must remain the same, otherwise a binary incompatibility - can result. */ - -static void -prepare_fresh_vtable (binfo, for_type) - tree binfo, for_type; -{ - tree basetype; - tree orig_decl = BINFO_VTABLE (binfo); - tree name; - tree new_decl; - tree offset; - tree path = binfo; - char *buf, *buf2; - char joiner = '_'; - int i; - -#ifdef JOINER - joiner = JOINER; -#endif - - basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (binfo)); - - buf2 = TYPE_ASSEMBLER_NAME_STRING (basetype); - i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1; - - /* We know that the vtable that we are going to create doesn't exist - yet in the global namespace, and when we finish, it will be - pushed into the global namespace. In complex MI hierarchies, we - have to loop while the name we are thinking of adding is globally - defined, adding more name components to the vtable name as we - loop, until the name is unique. This is because in complex MI - cases, we might have the same base more than once. This means - that the order in which this function is called for vtables must - remain the same, otherwise binary compatibility can be - compromised. */ - - while (1) - { - char *buf1 = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (for_type) - + 1 + i); - char *new_buf2; - - sprintf (buf1, "%s%c%s", TYPE_ASSEMBLER_NAME_STRING (for_type), joiner, - buf2); - buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) + strlen (buf1) + 1); - sprintf (buf, VTABLE_NAME_FORMAT, buf1); - name = get_identifier (buf); - - /* If this name doesn't clash, then we can use it, otherwise - we add more to the name until it is unique. */ - - if (! IDENTIFIER_GLOBAL_VALUE (name)) - break; - - /* Set values for next loop through, if the name isn't unique. */ - - path = BINFO_INHERITANCE_CHAIN (path); - - /* We better not run out of stuff to make it unique. */ - my_friendly_assert (path != NULL_TREE, 368); - - basetype = TYPE_MAIN_VARIANT (BINFO_TYPE (path)); - - if (for_type == basetype) - { - /* If we run out of basetypes in the path, we have already - found created a vtable with that name before, we now - resort to tacking on _%d to distinguish them. */ - int j = 2; - i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i + 1 + 3; - buf1 = (char *) alloca (i); - do { - sprintf (buf1, "%s%c%s%c%d", - TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, - buf2, joiner, j); - buf = (char *) alloca (strlen (VTABLE_NAME_FORMAT) - + strlen (buf1) + 1); - sprintf (buf, VTABLE_NAME_FORMAT, buf1); - name = get_identifier (buf); - - /* If this name doesn't clash, then we can use it, - otherwise we add something different to the name until - it is unique. */ - } while (++j <= 999 && IDENTIFIER_GLOBAL_VALUE (name)); - - /* Hey, they really like MI don't they? Increase the 3 - above to 6, and the 999 to 999999. :-) */ - my_friendly_assert (j <= 999, 369); - - break; - } - - i = TYPE_ASSEMBLER_NAME_LENGTH (basetype) + 1 + i; - new_buf2 = (char *) alloca (i); - sprintf (new_buf2, "%s%c%s", - TYPE_ASSEMBLER_NAME_STRING (basetype), joiner, buf2); - buf2 = new_buf2; - } - - new_decl = build_decl (VAR_DECL, name, TREE_TYPE (orig_decl)); - /* Remember which class this vtable is really for. */ - DECL_CONTEXT (new_decl) = for_type; - - DECL_ARTIFICIAL (new_decl) = 1; - TREE_STATIC (new_decl) = 1; - BINFO_VTABLE (binfo) = pushdecl_top_level (new_decl); - DECL_VIRTUAL_P (new_decl) = 1; -#ifndef WRITABLE_VTABLES - /* Make them READONLY by default. (mrs) */ - TREE_READONLY (new_decl) = 1; -#endif - DECL_ALIGN (new_decl) = DECL_ALIGN (orig_decl); - - /* Make fresh virtual list, so we can smash it later. */ - BINFO_VIRTUALS (binfo) = copy_list (BINFO_VIRTUALS (binfo)); - - if (TREE_VIA_VIRTUAL (binfo)) - { - tree binfo1 = binfo_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (for_type)); - - /* XXX - This should never happen, if it does, the caller should - ensure that the binfo is from for_type's binfos, not from any - base type's. We can remove all this code after a while. */ - if (binfo1 != binfo) - warning ("internal inconsistency: binfo offset error for rtti"); - - offset = BINFO_OFFSET (binfo1); - } - else - offset = BINFO_OFFSET (binfo); - - set_rtti_entry (BINFO_VIRTUALS (binfo), - ssize_binop (MINUS_EXPR, integer_zero_node, offset), - for_type); - -#ifdef GATHER_STATISTICS - n_vtables += 1; - n_vtable_elems += list_length (BINFO_VIRTUALS (binfo)); -#endif - - /* Set TREE_PUBLIC and TREE_EXTERN as appropriate. */ - import_export_vtable (new_decl, for_type, 0); - - if (TREE_VIA_VIRTUAL (binfo)) - my_friendly_assert (binfo == binfo_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (current_class_type)), - 170); - SET_BINFO_NEW_VTABLE_MARKED (binfo); -} - -#if 0 -/* Access the virtual function table entry that logically - contains BASE_FNDECL. VIRTUALS is the virtual function table's - initializer. We can run off the end, when dealing with virtual - destructors in MI situations, return NULL_TREE in that case. */ - -static tree -get_vtable_entry (virtuals, base_fndecl) - tree virtuals, base_fndecl; -{ - unsigned HOST_WIDE_INT n = (HOST_BITS_PER_WIDE_INT >= BITS_PER_WORD - ? (TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl)) - & (((unsigned HOST_WIDE_INT)1<<(BITS_PER_WORD-1))-1)) - : TREE_INT_CST_LOW (DECL_VINDEX (base_fndecl))); - -#ifdef GATHER_STATISTICS - n_vtable_searches += n; -#endif - - while (n > 0 && virtuals) - { - --n; - virtuals = TREE_CHAIN (virtuals); - } - return virtuals; -} -#endif - -/* Put new entry ENTRY into virtual function table initializer - VIRTUALS. - - Also update DECL_VINDEX (FNDECL). */ - -static void -modify_vtable_entry (old_entry_in_list, new_entry, fndecl) - tree old_entry_in_list, new_entry, fndecl; -{ - tree base_fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (old_entry_in_list)), 0); - -#ifdef NOTQUITE - cp_warning ("replaced %D with %D", DECL_ASSEMBLER_NAME (base_fndecl), - DECL_ASSEMBLER_NAME (fndecl)); -#endif - TREE_VALUE (old_entry_in_list) = new_entry; - - /* Now assign virtual dispatch information, if unset. */ - /* We can dispatch this, through any overridden base function. */ - if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) - { - DECL_VINDEX (fndecl) = DECL_VINDEX (base_fndecl); - DECL_CONTEXT (fndecl) = DECL_CONTEXT (base_fndecl); - } -} - -/* Access the virtual function table entry N. VIRTUALS is the virtual - function table's initializer. */ - -static tree -get_vtable_entry_n (virtuals, n) - tree virtuals; - unsigned HOST_WIDE_INT n; -{ - while (n > 0) - { - --n; - virtuals = TREE_CHAIN (virtuals); - } - return virtuals; -} - -/* Add a virtual function to all the appropriate vtables for the class - T. DECL_VINDEX(X) should be error_mark_node, if we want to - allocate a new slot in our table. If it is error_mark_node, we - know that no other function from another vtable is overridden by X. - HAS_VIRTUAL keeps track of how many virtuals there are in our main - vtable for the type, and we build upon the PENDING_VIRTUALS list - and return it. */ - -static void -add_virtual_function (pv, phv, has_virtual, fndecl, t) - tree *pv, *phv; - int *has_virtual; - tree fndecl; - tree t; /* Structure type. */ -{ - tree pending_virtuals = *pv; - tree pending_hard_virtuals = *phv; - - /* FUNCTION_TYPEs and OFFSET_TYPEs no longer freely - convert to void *. Make such a conversion here. */ - tree vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); - TREE_CONSTANT (vfn) = 1; - -#ifndef DUMB_USER - if (current_class_type == 0) - cp_warning ("internal problem, current_class_type is zero when adding `%D', please report", - fndecl); - if (current_class_type && t != current_class_type) - cp_warning ("internal problem, current_class_type differs when adding `%D', please report", - fndecl); -#endif - - /* If the virtual function is a redefinition of a prior one, - figure out in which base class the new definition goes, - and if necessary, make a fresh virtual function table - to hold that entry. */ - if (DECL_VINDEX (fndecl) == error_mark_node) - { - tree entry; - - /* We remember that this was the base sub-object for rtti. */ - CLASSTYPE_RTTI (t) = t; - - /* If we are using thunks, use two slots at the front, one - for the offset pointer, one for the tdesc pointer. */ - if (*has_virtual == 0 && flag_vtable_thunks) - { - *has_virtual = 1; - } - - /* Build a new INT_CST for this DECL_VINDEX. */ - { - static tree index_table[256]; - tree idx; - /* We skip a slot for the offset/tdesc entry. */ - int i = ++(*has_virtual); - - if (i >= 256 || index_table[i] == 0) - { - idx = build_int_2 (i, 0); - if (i < 256) - index_table[i] = idx; - } - else - idx = index_table[i]; - - /* Now assign virtual dispatch information. */ - DECL_VINDEX (fndecl) = idx; - DECL_CONTEXT (fndecl) = t; - } - entry = build_vtable_entry (integer_zero_node, vfn); - pending_virtuals = tree_cons (DECL_VINDEX (fndecl), entry, pending_virtuals); - } - /* Might already be INTEGER_CST if declared twice in class. We will - give error later or we've already given it. */ - else if (TREE_CODE (DECL_VINDEX (fndecl)) != INTEGER_CST) - { - /* Need an entry in some other virtual function table. - Deal with this after we have laid out our virtual base classes. */ - pending_hard_virtuals = temp_tree_cons (fndecl, vfn, pending_hard_virtuals); - } - *pv = pending_virtuals; - *phv = pending_hard_virtuals; -} - -/* Obstack on which to build the vector of class methods. */ -struct obstack class_obstack; -extern struct obstack *current_obstack; - -/* These are method vectors that were too small for the number of - methods in some class, and so were abandoned. */ -static tree free_method_vecs; - -/* Returns a method vector with enough room for N methods. N should - be a power of two. */ - -static tree -make_method_vec (n) - int n; -{ - tree new_vec; - tree* t; - - for (t = &free_method_vecs; *t; t = &(TREE_CHAIN (*t))) - /* Note that we don't use >= n here because we don't want to - allocate a very large vector where it isn't needed. */ - if (TREE_VEC_LENGTH (*t) == n) - { - new_vec = *t; - *t = TREE_CHAIN (new_vec); - TREE_CHAIN (new_vec) = NULL_TREE; - bzero ((PTR) &TREE_VEC_ELT (new_vec, 0), n * sizeof (tree)); - return new_vec; - } - - new_vec = make_tree_vec (n); - return new_vec; -} - -/* Free the method vector VEC. */ - -static void -free_method_vec (vec) - tree vec; -{ - TREE_CHAIN (vec) = free_method_vecs; - free_method_vecs = vec; -} - -/* Add method METHOD to class TYPE. - - If non-NULL, FIELDS is the entry in the METHOD_VEC vector entry of - the class type where the method should be added. */ - -void -add_method (type, fields, method) - tree type, *fields, method; -{ - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* Setting the DECL_CONTEXT and DECL_CLASS_CONTEXT here is probably - redundant. */ - DECL_CONTEXT (method) = type; - DECL_CLASS_CONTEXT (method) = type; - - if (fields && *fields) - *fields = build_overload (method, *fields); - else - { - int len; - tree method_vec; - - if (!CLASSTYPE_METHOD_VEC (type)) - /* Make a new method vector. We start with 8 entries. We must - allocate at least two (for constructors and destructors), and - we're going to end up with an assignment operator at some - point as well. - - We could use a TREE_LIST for now, and convert it to a - TREE_VEC in finish_struct, but we would probably waste more - memory making the links in the list than we would by - over-allocating the size of the vector here. Furthermore, - we would complicate all the code that expects this to be a - vector. We keep a free list of vectors that we outgrew so - that we don't really waste any memory. */ - CLASSTYPE_METHOD_VEC (type) = make_method_vec (8); - - method_vec = CLASSTYPE_METHOD_VEC (type); - len = TREE_VEC_LENGTH (method_vec); - - if (DECL_NAME (method) == constructor_name (type)) - { - /* A new constructor or destructor. Constructors go in - slot 0; destructors go in slot 1. */ - int slot - = DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (method)) ? 1 : 0; - - TREE_VEC_ELT (method_vec, slot) - = build_overload (method, TREE_VEC_ELT (method_vec, slot)); - } - else - { - int i; - - /* See if we already have an entry with this name. */ - for (i = 2; i < len; ++i) - if (!TREE_VEC_ELT (method_vec, i) - || (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) - == DECL_NAME (method))) - break; - - if (i == len) - { - /* We need a bigger method vector. */ - tree new_vec = make_method_vec (2 * len); - bcopy ((PTR) &TREE_VEC_ELT (method_vec, 0), - (PTR) &TREE_VEC_ELT (new_vec, 0), - len * sizeof (tree)); - free_method_vec (method_vec); - len = 2 * len; - method_vec = CLASSTYPE_METHOD_VEC (type) = new_vec; - } - else if (template_class_depth (type)) - /* TYPE is a template class. Don't issue any errors now; - wait until instantiation time to complain. */ - ; - else - { - tree fns; - - /* Check to see if we've already got this method. */ - for (fns = TREE_VEC_ELT (method_vec, i); - fns; - fns = OVL_NEXT (fns)) - { - tree fn = OVL_CURRENT (fns); - - if (TREE_CODE (fn) != TREE_CODE (method)) - continue; - - if (TREE_CODE (method) != TEMPLATE_DECL) - { - /* [over.load] Member function declarations with the - same name and the same parameter types cannot be - overloaded if any of them is a static member - function declaration. */ - if (DECL_STATIC_FUNCTION_P (fn) - != DECL_STATIC_FUNCTION_P (method)) - { - tree parms1 = TYPE_ARG_TYPES (TREE_TYPE (fn)); - tree parms2 = TYPE_ARG_TYPES (TREE_TYPE (method)); - - if (! DECL_STATIC_FUNCTION_P (fn)) - parms1 = TREE_CHAIN (parms1); - else - parms2 = TREE_CHAIN (parms2); - - if (compparms (parms1, parms2)) - cp_error ("`%#D' and `%#D' cannot be overloaded", - fn, method); - } - - /* Since this is an ordinary function in a - non-template class, it's mangled name can be - used as a unique identifier. This technique - is only an optimization; we would get the - same results if we just used decls_match - here. */ - if (DECL_ASSEMBLER_NAME (fn) - != DECL_ASSEMBLER_NAME (method)) - continue; - } - else if (!decls_match (fn, method)) - continue; - - /* There has already been a declaration of this - method or member template. */ - cp_error_at ("`%D' has already been declared in `%T'", - method, type); - - /* We don't call duplicate_decls here to merege the - declarations because that will confuse things if - the methods have inline definitions In - particular, we will crash while processing the - definitions. */ - return; - } - } - - if (TREE_VEC_ELT (method_vec, i)) - /* We found a match. */; - else if (DECL_CONV_FN_P (method)) - { - /* Type conversion operators have to come before - ordinary methods; add_conversions depends on this to - speed up looking for conversion operators. So, if - necessary, we slide some of the vector elements up. - In theory, this makes this algorithm O(N^2) but we - don't expect many conversion operators. */ - for (i = 2; i < len; ++i) - { - tree fn = TREE_VEC_ELT (method_vec, i); - - if (!fn) - /* There are no more entries in the vector, so we - can insert the new conversion operator here. */ - break; - - if (! DECL_CONV_FN_P (OVL_CURRENT (fn))) - /* We can insert the new function right at the Ith - position. */ - break; - } - - if (!TREE_VEC_ELT (method_vec, i)) - /* There is nothing in the Ith slot, so we can avoid - moving anything. */ - ; - else - { - /* We know the last slot in the vector is empty - because we know that at this point there's room for - a new function. */ - bcopy ((PTR) &TREE_VEC_ELT (method_vec, i), - (PTR) &TREE_VEC_ELT (method_vec, i + 1), - (len - i - 1) * sizeof (tree)); - TREE_VEC_ELT (method_vec, i) = NULL_TREE; - } - } - - /* Actually insert the new method. */ - TREE_VEC_ELT (method_vec, i) - = build_overload (method, TREE_VEC_ELT (method_vec, i)); - } - - if (TYPE_BINFO_BASETYPES (type) && CLASSTYPE_BASELINK_VEC (type)) - { - /* ??? May be better to know whether these can be extended? */ - tree baselink_vec = CLASSTYPE_BASELINK_VEC (type); - - TREE_VEC_LENGTH (baselink_vec) += 1; - CLASSTYPE_BASELINK_VEC (type) = copy_node (baselink_vec); - TREE_VEC_LENGTH (baselink_vec) -= 1; - - TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), len) = 0; - } - } - pop_obstacks (); -} - -/* Subroutines of finish_struct. */ - -/* Look through the list of fields for this struct, deleting - duplicates as we go. This must be recursive to handle - anonymous unions. - - FIELD is the field which may not appear anywhere in FIELDS. - FIELD_PTR, if non-null, is the starting point at which - chained deletions may take place. - The value returned is the first acceptable entry found - in FIELDS. - - Note that anonymous fields which are not of UNION_TYPE are - not duplicates, they are just anonymous fields. This happens - when we have unnamed bitfields, for example. */ - -static tree -delete_duplicate_fields_1 (field, fields) - tree field, fields; -{ - tree x; - tree prev = 0; - if (DECL_NAME (field) == 0) - { - if (TREE_CODE (TREE_TYPE (field)) != UNION_TYPE) - return fields; - - for (x = TYPE_FIELDS (TREE_TYPE (field)); x; x = TREE_CHAIN (x)) - fields = delete_duplicate_fields_1 (x, fields); - return fields; - } - else - { - for (x = fields; x; prev = x, x = TREE_CHAIN (x)) - { - if (DECL_NAME (x) == 0) - { - if (TREE_CODE (TREE_TYPE (x)) != UNION_TYPE) - continue; - TYPE_FIELDS (TREE_TYPE (x)) - = delete_duplicate_fields_1 (field, TYPE_FIELDS (TREE_TYPE (x))); - if (TYPE_FIELDS (TREE_TYPE (x)) == 0) - { - if (prev == 0) - fields = TREE_CHAIN (fields); - else - TREE_CHAIN (prev) = TREE_CHAIN (x); - } - } - else - { - if (DECL_NAME (field) == DECL_NAME (x)) - { - if (TREE_CODE (field) == CONST_DECL - && TREE_CODE (x) == CONST_DECL) - cp_error_at ("duplicate enum value `%D'", x); - else if (TREE_CODE (field) == CONST_DECL - || TREE_CODE (x) == CONST_DECL) - cp_error_at ("duplicate field `%D' (as enum and non-enum)", - x); - else if (DECL_DECLARES_TYPE_P (field) - && DECL_DECLARES_TYPE_P (x)) - { - if (same_type_p (TREE_TYPE (field), TREE_TYPE (x))) - continue; - cp_error_at ("duplicate nested type `%D'", x); - } - else if (DECL_DECLARES_TYPE_P (field) - || DECL_DECLARES_TYPE_P (x)) - { - /* Hide tag decls. */ - if ((TREE_CODE (field) == TYPE_DECL - && DECL_ARTIFICIAL (field)) - || (TREE_CODE (x) == TYPE_DECL - && DECL_ARTIFICIAL (x))) - continue; - cp_error_at ("duplicate field `%D' (as type and non-type)", - x); - } - else - cp_error_at ("duplicate member `%D'", x); - if (prev == 0) - fields = TREE_CHAIN (fields); - else - TREE_CHAIN (prev) = TREE_CHAIN (x); - } - } - } - } - return fields; -} - -static void -delete_duplicate_fields (fields) - tree fields; -{ - tree x; - for (x = fields; x && TREE_CHAIN (x); x = TREE_CHAIN (x)) - TREE_CHAIN (x) = delete_duplicate_fields_1 (x, TREE_CHAIN (x)); -} - -/* Change the access of FDECL to ACCESS in T. The access to FDECL is - along the path given by BINFO. Return 1 if change was legit, - otherwise return 0. */ - -static int -alter_access (t, binfo, fdecl, access) - tree t; - tree binfo; - tree fdecl; - tree access; -{ - tree elem = purpose_member (t, DECL_ACCESS (fdecl)); - if (elem) - { - if (TREE_VALUE (elem) != access) - { - if (TREE_CODE (TREE_TYPE (fdecl)) == FUNCTION_DECL) - cp_error_at ("conflicting access specifications for method `%D', ignored", TREE_TYPE (fdecl)); - else - error ("conflicting access specifications for field `%s', ignored", - IDENTIFIER_POINTER (DECL_NAME (fdecl))); - } - else - { - /* They're changing the access to the same thing they changed - it to before. That's OK. */ - ; - } - } - else - { - enforce_access (binfo, fdecl); - - DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl)); - return 1; - } - return 0; -} - -/* Process the USING_DECL, which is a member of T. The METHOD_VEC, if - non-NULL, is the methods of T. The FIELDS are the fields of T. */ - -static void -handle_using_decl (using_decl, t, method_vec, fields) - tree using_decl; - tree t; - tree method_vec; - tree fields; -{ - tree ctype = DECL_INITIAL (using_decl); - tree name = DECL_NAME (using_decl); - tree access - = TREE_PRIVATE (using_decl) ? access_private_node - : TREE_PROTECTED (using_decl) ? access_protected_node - : access_public_node; - tree fdecl, binfo; - tree flist = NULL_TREE; - tree tmp; - int i; - int n_methods; - - binfo = binfo_or_else (ctype, t); - if (! binfo) - return; - - if (name == constructor_name (ctype) - || name == constructor_name_full (ctype)) - { - cp_error_at ("using-declaration for constructor", using_decl); - return; - } - - fdecl = lookup_member (binfo, name, 0, 0); - - if (!fdecl) - { - cp_error_at ("no members matching `%D' in `%#T'", using_decl, ctype); - return; - } - - /* Functions are represented as TREE_LIST, with the purpose - being the type and the value the functions. Other members - come as themselves. */ - if (TREE_CODE (fdecl) == TREE_LIST) - /* Ignore base type this came from. */ - fdecl = TREE_VALUE (fdecl); - - if (TREE_CODE (fdecl) == OVERLOAD) - { - /* We later iterate over all functions. */ - flist = fdecl; - fdecl = OVL_FUNCTION (flist); - } - - name = DECL_NAME (fdecl); - n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); i++) - if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) - == name) - { - cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); - cp_error_at (" because of local method `%#D' with same name", - OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); - return; - } - - if (! DECL_LANG_SPECIFIC (fdecl)) - /* We don't currently handle DECL_ACCESS for TYPE_DECLs; just return. */ - return; - - for (tmp = fields; tmp; tmp = TREE_CHAIN (tmp)) - if (DECL_NAME (tmp) == name) - { - cp_error ("cannot adjust access to `%#D' in `%#T'", fdecl, t); - cp_error_at (" because of local field `%#D' with same name", tmp); - return; - } - - /* Make type T see field decl FDECL with access ACCESS.*/ - if (flist) - { - while (flist) - { - if (alter_access (t, binfo, OVL_FUNCTION (flist), - access) == 0) - return; - flist = OVL_CHAIN (flist); - } - } - else - alter_access (t, binfo, fdecl, access); -} - -/* If FOR_TYPE needs to reinitialize virtual function table pointers - for TYPE's sub-objects, add such reinitializations to BASE_INIT_LIST. - Returns BASE_INIT_LIST appropriately modified. */ - -static tree -maybe_fixup_vptrs (for_type, binfo, base_init_list) - tree for_type, binfo, base_init_list; -{ - /* Now reinitialize any slots that don't fall under our virtual - function table pointer. */ - tree vfields = CLASSTYPE_VFIELDS (BINFO_TYPE (binfo)); - while (vfields) - { - tree basetype = VF_NORMAL_VALUE (vfields) - ? TYPE_MAIN_VARIANT (VF_NORMAL_VALUE (vfields)) - : VF_BASETYPE_VALUE (vfields); - - tree base_binfo = get_binfo (basetype, for_type, 0); - /* Punt until this is implemented. */ - if (1 /* BINFO_MODIFIED (base_binfo) */) - { - tree base_offset = get_vfield_offset (base_binfo); - if (! tree_int_cst_equal (base_offset, get_vfield_offset (TYPE_BINFO (for_type))) - && ! tree_int_cst_equal (base_offset, get_vfield_offset (binfo))) - base_init_list = tree_cons (error_mark_node, base_binfo, - base_init_list); - } - vfields = TREE_CHAIN (vfields); - } - return base_init_list; -} - -/* If TYPE does not have a constructor, then the compiler must - manually deal with all of the initialization this type requires. - - If a base initializer exists only to fill in the virtual function - table pointer, then we mark that fact with the TREE_VIRTUAL bit. - This way, we avoid multiple initializations of the same field by - each virtual function table up the class hierarchy. - - Virtual base class pointers are not initialized here. They are - initialized only at the "top level" of object creation. If we - initialized them here, we would have to skip a lot of work. */ - -static void -build_class_init_list (type) - tree type; -{ - tree base_init_list = NULL_TREE; - tree member_init_list = NULL_TREE; - - /* Since we build member_init_list and base_init_list using - tree_cons, backwards fields the all through work. */ - tree x; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (x = TYPE_FIELDS (type); x; x = TREE_CHAIN (x)) - { - if (TREE_CODE (x) != FIELD_DECL) - continue; - - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (x)) - || DECL_INITIAL (x) != NULL_TREE) - member_init_list = tree_cons (x, type, member_init_list); - } - member_init_list = nreverse (member_init_list); - - /* We will end up doing this last. Need special marker - to avoid infinite regress. */ - if (TYPE_VIRTUAL_P (type)) - { - base_init_list = build_tree_list (error_mark_node, TYPE_BINFO (type)); - if (CLASSTYPE_NEEDS_VIRTUAL_REINIT (type) == 0) - TREE_VALUE (base_init_list) = NULL_TREE; - TREE_ADDRESSABLE (base_init_list) = 1; - } - - /* Each base class which needs to have initialization - of some kind gets to make such requests known here. */ - for (i = n_baseclasses-1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree blist; - - /* Don't initialize virtual baseclasses this way. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - if (TYPE_HAS_CONSTRUCTOR (BINFO_TYPE (base_binfo))) - { - /* ...and the last shall come first... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - continue; - } - - if ((blist = CLASSTYPE_BASE_INIT_LIST (BINFO_TYPE (base_binfo))) == NULL_TREE) - /* Nothing to initialize. */ - continue; - - /* ...ditto... */ - base_init_list = maybe_fixup_vptrs (type, base_binfo, base_init_list); - - /* This is normally true for single inheritance. - The win is we can shrink the chain of initializations - to be done by only converting to the actual type - we are interested in. */ - if (TREE_VALUE (blist) - && TREE_CODE (TREE_VALUE (blist)) == TREE_VEC - && tree_int_cst_equal (BINFO_OFFSET (base_binfo), - BINFO_OFFSET (TREE_VALUE (blist)))) - { - if (base_init_list) - { - /* Does it do more than just fill in a - virtual function table pointer? */ - if (! TREE_ADDRESSABLE (blist)) - base_init_list = build_tree_list (blist, base_init_list); - /* Can we get by just with the virtual function table - pointer that it fills in? */ - else if (TREE_ADDRESSABLE (base_init_list) - && TREE_VALUE (base_init_list) == 0) - base_init_list = blist; - /* Maybe, but it is not obvious as the previous case. */ - else if (! CLASSTYPE_NEEDS_VIRTUAL_REINIT (type)) - { - tree last = tree_last (base_init_list); - while (TREE_VALUE (last) - && TREE_CODE (TREE_VALUE (last)) == TREE_LIST) - last = tree_last (TREE_VALUE (last)); - if (TREE_VALUE (last) == 0) - base_init_list = build_tree_list (blist, base_init_list); - } - } - else - base_init_list = blist; - } - else - { - /* The function expand_aggr_init knows how to do the - initialization of `basetype' without getting - an explicit `blist'. */ - if (base_init_list) - base_init_list = tree_cons (NULL_TREE, base_binfo, base_init_list); - else - base_init_list = CLASSTYPE_BINFO_AS_LIST (BINFO_TYPE (base_binfo)); - } - } - - if (base_init_list) - { - if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = - build_tree_list (base_init_list, member_init_list); - else - CLASSTYPE_BASE_INIT_LIST (type) = base_init_list; - } - else if (member_init_list) - CLASSTYPE_BASE_INIT_LIST (type) = member_init_list; -} - -struct base_info -{ - int has_virtual; - int max_has_virtual; - int n_ancestors; - tree vfield; - tree vfields; - tree rtti; - char cant_have_default_ctor; - char cant_have_const_ctor; - char no_const_asn_ref; -}; - -/* Record information about type T derived from its base classes. - Store most of that information in T itself, and place the - remaining information in the struct BASE_INFO. - - Propagate basetype offsets throughout the lattice. Note that the - lattice topped by T is really a pair: it's a DAG that gives the - structure of the derivation hierarchy, and it's a list of the - virtual baseclasses that appear anywhere in the DAG. When a vbase - type appears in the DAG, it's offset is 0, and it's children start - their offsets from that point. When a vbase type appears in the list, - its offset is the offset it has in the hierarchy, and its children's - offsets include that offset in theirs. - - Returns the index of the first base class to have virtual functions, - or -1 if no such base class. */ - -static int -finish_base_struct (t, b) - tree t; - struct base_info *b; -{ - tree binfos = TYPE_BINFO_BASETYPES (t); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int first_vfn_base_index = -1; - bzero ((char *) b, sizeof (struct base_info)); - - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - /* Effective C++ rule 14. We only need to check TYPE_VIRTUAL_P - here because the case of virtual functions but non-virtual - dtor is handled in finish_struct_1. */ - if (warn_ecpp && ! TYPE_VIRTUAL_P (basetype) - && TYPE_HAS_DESTRUCTOR (basetype)) - cp_warning ("base class `%#T' has a non-virtual destructor", basetype); - - /* If the type of basetype is incomplete, then - we already complained about that fact - (and we should have fixed it up as well). */ - if (TYPE_SIZE (basetype) == 0) - { - int j; - /* The base type is of incomplete type. It is - probably best to pretend that it does not - exist. */ - if (i == n_baseclasses-1) - TREE_VEC_ELT (binfos, i) = NULL_TREE; - TREE_VEC_LENGTH (binfos) -= 1; - n_baseclasses -= 1; - for (j = i; j+1 < n_baseclasses; j++) - TREE_VEC_ELT (binfos, j) = TREE_VEC_ELT (binfos, j+1); - } - - if (! TYPE_HAS_CONST_INIT_REF (basetype)) - b->cant_have_const_ctor = 1; - - if (TYPE_HAS_CONSTRUCTOR (basetype) - && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (basetype)) - { - b->cant_have_default_ctor = 1; - if (! TYPE_HAS_CONSTRUCTOR (t)) - { - cp_pedwarn ("base `%T' with only non-default constructor", - basetype); - cp_pedwarn ("in class without a constructor"); - } - } - - if (TYPE_HAS_ASSIGN_REF (basetype) - && !TYPE_HAS_CONST_ASSIGN_REF (basetype)) - b->no_const_asn_ref = 1; - - b->n_ancestors += CLASSTYPE_N_SUPERCLASSES (basetype); - TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (basetype); - TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (basetype); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (basetype); - TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (basetype); - - TYPE_OVERLOADS_CALL_EXPR (t) |= TYPE_OVERLOADS_CALL_EXPR (basetype); - TYPE_OVERLOADS_ARRAY_REF (t) |= TYPE_OVERLOADS_ARRAY_REF (basetype); - TYPE_OVERLOADS_ARROW (t) |= TYPE_OVERLOADS_ARROW (basetype); - - if (! TREE_VIA_VIRTUAL (base_binfo)) - CLASSTYPE_N_SUPERCLASSES (t) += 1; - - if (TYPE_VIRTUAL_P (basetype)) - { - /* Ensure that this is set from at least a virtual base - class. */ - if (b->rtti == NULL_TREE) - b->rtti = CLASSTYPE_RTTI (basetype); - - /* Don't borrow virtuals from virtual baseclasses. */ - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - if (first_vfn_base_index < 0) - { - tree vfields; - first_vfn_base_index = i; - - /* Update these two, now that we know what vtable we are - going to extend. This is so that we can add virtual - functions, and override them properly. */ - TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); - TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); - b->has_virtual = CLASSTYPE_VSIZE (basetype); - b->vfield = CLASSTYPE_VFIELD (basetype); - b->vfields = copy_list (CLASSTYPE_VFIELDS (basetype)); - vfields = b->vfields; - while (vfields) - { - if (VF_BINFO_VALUE (vfields) == NULL_TREE - || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) - { - tree value = VF_BASETYPE_VALUE (vfields); - if (DECL_NAME (CLASSTYPE_VFIELD (value)) - == DECL_NAME (CLASSTYPE_VFIELD (basetype))) - VF_NORMAL_VALUE (b->vfields) = basetype; - else - VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); - } - vfields = TREE_CHAIN (vfields); - } - CLASSTYPE_VFIELD (t) = b->vfield; - } - else - { - /* Only add unique vfields, and flatten them out as we go. */ - tree vfields = CLASSTYPE_VFIELDS (basetype); - while (vfields) - { - if (VF_BINFO_VALUE (vfields) == NULL_TREE - || ! TREE_VIA_VIRTUAL (VF_BINFO_VALUE (vfields))) - { - tree value = VF_BASETYPE_VALUE (vfields); - b->vfields = tree_cons (base_binfo, value, b->vfields); - if (DECL_NAME (CLASSTYPE_VFIELD (value)) - == DECL_NAME (CLASSTYPE_VFIELD (basetype))) - VF_NORMAL_VALUE (b->vfields) = basetype; - else - VF_NORMAL_VALUE (b->vfields) = VF_NORMAL_VALUE (vfields); - } - vfields = TREE_CHAIN (vfields); - } - - if (b->has_virtual == 0) - { - first_vfn_base_index = i; - - /* Update these two, now that we know what vtable we are - going to extend. This is so that we can add virtual - functions, and override them properly. */ - TYPE_BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (basetype); - TYPE_BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (basetype); - b->has_virtual = CLASSTYPE_VSIZE (basetype); - b->vfield = CLASSTYPE_VFIELD (basetype); - CLASSTYPE_VFIELD (t) = b->vfield; - /* When we install the first one, set the VF_NORMAL_VALUE - to be the current class, as this it is the most derived - class. Hopefully, this is not set to something else - later. (mrs) */ - vfields = b->vfields; - while (vfields) - { - if (DECL_NAME (CLASSTYPE_VFIELD (t)) - == DECL_NAME (CLASSTYPE_VFIELD (basetype))) - { - VF_NORMAL_VALUE (vfields) = t; - /* There should only be one of them! And it should - always be found, if we get into here. (mrs) */ - break; - } - vfields = TREE_CHAIN (vfields); - } - } - } - } - } - - { - tree vfields; - /* Find the base class with the largest number of virtual functions. */ - for (vfields = b->vfields; vfields; vfields = TREE_CHAIN (vfields)) - { - if (CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)) > b->max_has_virtual) - b->max_has_virtual = CLASSTYPE_VSIZE (VF_BASETYPE_VALUE (vfields)); - if (VF_DERIVED_VALUE (vfields) - && CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)) > b->max_has_virtual) - b->max_has_virtual = CLASSTYPE_VSIZE (VF_DERIVED_VALUE (vfields)); - } - } - - if (b->vfield == 0) - /* If all virtual functions come only from virtual baseclasses. */ - return -1; - - /* Update the rtti base if we have a non-virtual base class version - of it. */ - b->rtti = CLASSTYPE_RTTI (BINFO_TYPE (TREE_VEC_ELT (binfos, first_vfn_base_index))); - - return first_vfn_base_index; -} - -/* Set memoizing fields and bits of T (and its variants) for later use. - MAX_HAS_VIRTUAL is the largest size of any T's virtual function tables. */ - -static void -finish_struct_bits (t, max_has_virtual) - tree t; - int max_has_virtual; -{ - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - - /* Fix up variants (if any). */ - tree variants = TYPE_NEXT_VARIANT (t); - while (variants) - { - /* These fields are in the _TYPE part of the node, not in - the TYPE_LANG_SPECIFIC component, so they are not shared. */ - TYPE_HAS_CONSTRUCTOR (variants) = TYPE_HAS_CONSTRUCTOR (t); - TYPE_HAS_DESTRUCTOR (variants) = TYPE_HAS_DESTRUCTOR (t); - TYPE_NEEDS_CONSTRUCTING (variants) = TYPE_NEEDS_CONSTRUCTING (t); - TYPE_NEEDS_DESTRUCTOR (variants) = TYPE_NEEDS_DESTRUCTOR (t); - - TYPE_USES_COMPLEX_INHERITANCE (variants) = TYPE_USES_COMPLEX_INHERITANCE (t); - TYPE_VIRTUAL_P (variants) = TYPE_VIRTUAL_P (t); - TYPE_USES_VIRTUAL_BASECLASSES (variants) = TYPE_USES_VIRTUAL_BASECLASSES (t); - /* Copy whatever these are holding today. */ - TYPE_MIN_VALUE (variants) = TYPE_MIN_VALUE (t); - TYPE_MAX_VALUE (variants) = TYPE_MAX_VALUE (t); - TYPE_FIELDS (variants) = TYPE_FIELDS (t); - TYPE_SIZE (variants) = TYPE_SIZE (t); - TYPE_SIZE_UNIT (variants) = TYPE_SIZE_UNIT (t); - variants = TYPE_NEXT_VARIANT (variants); - } - - if (n_baseclasses && max_has_virtual) - { - /* for a class w/o baseclasses, `finish_struct' has set - * CLASS_TYPE_ABSTRACT_VIRTUALS correctly (by definition). Similarly - * for a class who's base classes do not have vtables. When neither of - * these is true, we might have removed abstract virtuals (by - * providing a definition), added some (by declaring new ones), or - * redeclared ones from a base class. We need to recalculate what's - * really an abstract virtual at this point (by looking in the vtables). - */ - CLASSTYPE_ABSTRACT_VIRTUALS (t) = get_abstract_virtuals (t); - } - - if (n_baseclasses) - { - /* Notice whether this class has type conversion functions defined. */ - tree binfo = TYPE_BINFO (t); - tree binfos = BINFO_BASETYPES (binfo); - tree basetype; - - for (i = n_baseclasses-1; i >= 0; i--) - { - basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); - - TYPE_HAS_CONVERSION (t) |= TYPE_HAS_CONVERSION (basetype); - if (CLASSTYPE_MAX_DEPTH (basetype) >= CLASSTYPE_MAX_DEPTH (t)) - CLASSTYPE_MAX_DEPTH (t) = CLASSTYPE_MAX_DEPTH (basetype) + 1; - } - } - - /* If this type has a copy constructor, force its mode to be BLKmode, and - force its TREE_ADDRESSABLE bit to be nonzero. This will cause it to - be passed by invisible reference and prevent it from being returned in - a register. - - Also do this if the class has BLKmode but can still be returned in - registers, since function_cannot_inline_p won't let us inline - functions returning such a type. This affects the HP-PA. */ - if (! TYPE_HAS_TRIVIAL_INIT_REF (t) - || (TYPE_MODE (t) == BLKmode && ! aggregate_value_p (t) - && CLASSTYPE_NON_AGGREGATE (t))) - { - tree variants; - DECL_MODE (TYPE_MAIN_DECL (t)) = BLKmode; - for (variants = t; variants; variants = TYPE_NEXT_VARIANT (variants)) - { - TYPE_MODE (variants) = BLKmode; - TREE_ADDRESSABLE (variants) = 1; - } - } -} - -/* Issue warnings about T having private constructors, but no friends, - and so forth. - - HAS_NONPRIVATE_METHOD is nonzero if T has any non-private methods or - static members. HAS_NONPRIVATE_STATIC_FN is nonzero if T has any - non-private static member functions. */ - -static void -maybe_warn_about_overly_private_class (t) - tree t; -{ - int has_member_fn = 0; - int has_nonprivate_method = 0; - tree fn; - - if (!warn_ctor_dtor_privacy - /* If the class has friends, those entities might create and - access instances, so we should not warn. */ - || (CLASSTYPE_FRIEND_CLASSES (t) - || DECL_FRIENDLIST (TYPE_MAIN_DECL (t))) - /* We will have warned when the template was declared; there's - no need to warn on every instantiation. */ - || CLASSTYPE_TEMPLATE_INSTANTIATION (t)) - /* There's no reason to even consider warning about this - class. */ - return; - - /* We only issue one warning, if more than one applies, because - otherwise, on code like: - - class A { - // Oops - forgot `public:' - A(); - A(const A&); - ~A(); - }; - - we warn several times about essentially the same problem. */ - - /* Check to see if all (non-constructor, non-destructor) member - functions are private. (Since there are no friends or - non-private statics, we can't ever call any of the private member - functions.) */ - for (fn = TYPE_METHODS (t); fn; fn = TREE_CHAIN (fn)) - /* We're not interested in compiler-generated methods; they don't - provide any way to call private members. */ - if (!DECL_ARTIFICIAL (fn)) - { - if (!TREE_PRIVATE (fn)) - { - if (DECL_STATIC_FUNCTION_P (fn)) - /* A non-private static member function is just like a - friend; it can create and invoke private member - functions, and be accessed without a class - instance. */ - return; - - has_nonprivate_method = 1; - break; - } - else if (!DECL_CONSTRUCTOR_P (fn) && !DECL_DESTRUCTOR_P (fn)) - has_member_fn = 1; - } - - if (!has_nonprivate_method && has_member_fn) - { - /* There are no non-private methods, and there's at least one - private member function that isn't a constructor or - destructor. (If all the private members are - constructors/destructors we want to use the code below that - issues error messages specifically referring to - constructors/destructors.) */ - int i; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - for (i = 0; i < CLASSTYPE_N_BASECLASSES (t); i++) - if (TREE_VIA_PUBLIC (TREE_VEC_ELT (binfos, i)) - || TREE_VIA_PROTECTED (TREE_VEC_ELT (binfos, i))) - { - has_nonprivate_method = 1; - break; - } - if (!has_nonprivate_method) - { - cp_warning ("all member functions in class `%T' are private", t); - return; - } - } - - /* Even if some of the member functions are non-private, the class - won't be useful for much if all the constructors or destructors - are private: such an object can never be created or destroyed. */ - if (TYPE_HAS_DESTRUCTOR (t)) - { - tree dtor = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 1); - - if (TREE_PRIVATE (dtor)) - { - cp_warning ("`%#T' only defines a private destructor and has no friends", - t); - return; - } - } - - if (TYPE_HAS_CONSTRUCTOR (t)) - { - int nonprivate_ctor = 0; - - /* If a non-template class does not define a copy - constructor, one is defined for it, enabling it to avoid - this warning. For a template class, this does not - happen, and so we would normally get a warning on: - - template <class T> class C { private: C(); }; - - To avoid this asymmetry, we check TYPE_HAS_INIT_REF. All - complete non-template or fully instantiated classes have this - flag set. */ - if (!TYPE_HAS_INIT_REF (t)) - nonprivate_ctor = 1; - else - for (fn = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (t), 0); - fn; - fn = OVL_NEXT (fn)) - { - tree ctor = OVL_CURRENT (fn); - /* Ideally, we wouldn't count copy constructors (or, in - fact, any constructor that takes an argument of the - class type as a parameter) because such things cannot - be used to construct an instance of the class unless - you already have one. But, for now at least, we're - more generous. */ - if (! TREE_PRIVATE (ctor)) - { - nonprivate_ctor = 1; - break; - } - } - - if (nonprivate_ctor == 0) - { - cp_warning ("`%#T' only defines private constructors and has no friends", - t); - return; - } - } -} - - -/* Warn about duplicate methods in fn_fields. Also compact method - lists so that lookup can be made faster. - - Data Structure: List of method lists. The outer list is a - TREE_LIST, whose TREE_PURPOSE field is the field name and the - TREE_VALUE is the DECL_CHAIN of the FUNCTION_DECLs. TREE_CHAIN - links the entire list of methods for TYPE_METHODS. Friends are - chained in the same way as member functions (? TREE_CHAIN or - DECL_CHAIN), but they live in the TREE_TYPE field of the outer - list. That allows them to be quickly deleted, and requires no - extra storage. - - If there are any constructors/destructors, they are moved to the - front of the list. This makes pushclass more efficient. - - We also link each field which has shares a name with its baseclass - to the head of the list of fields for that base class. This allows - us to reduce search time in places like `build_method_call' to - consider only reasonably likely functions. */ - -static void -finish_struct_methods (t) - tree t; -{ - tree fn_fields; - tree method_vec = CLASSTYPE_METHOD_VEC (t); - tree ctor_name = constructor_name (t); - int i, n_baseclasses = CLASSTYPE_N_BASECLASSES (t); - - /* First fill in entry 0 with the constructors, entry 1 with destructors, - and the next few with type conversion operators (if any). */ - for (fn_fields = TYPE_METHODS (t); fn_fields; - fn_fields = TREE_CHAIN (fn_fields)) - { - tree fn_name = DECL_NAME (fn_fields); - - /* Clear out this flag. - - @@ Doug may figure out how to break - @@ this with nested classes and friends. */ - DECL_IN_AGGR_P (fn_fields) = 0; - - /* Note here that a copy ctor is private, so we don't dare generate - a default copy constructor for a class that has a member - of this type without making sure they have access to it. */ - if (fn_name == ctor_name) - { - tree parmtypes = FUNCTION_ARG_CHAIN (fn_fields); - tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; - - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == t) - { - if (TREE_CHAIN (parmtypes) == NULL_TREE - || TREE_CHAIN (parmtypes) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (parmtypes))) - { - if (TREE_PROTECTED (fn_fields)) - TYPE_HAS_NONPUBLIC_CTOR (t) = 1; - else if (TREE_PRIVATE (fn_fields)) - TYPE_HAS_NONPUBLIC_CTOR (t) = 2; - } - } - } - else if (fn_name == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtype = TREE_VALUE (FUNCTION_ARG_CHAIN (fn_fields)); - - if (copy_assignment_arg_p (parmtype, DECL_VIRTUAL_P (fn_fields))) - { - if (TREE_PROTECTED (fn_fields)) - TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 1; - else if (TREE_PRIVATE (fn_fields)) - TYPE_HAS_NONPUBLIC_ASSIGN_REF (t) = 2; - } - } - } - - if (TYPE_HAS_DESTRUCTOR (t) && !TREE_VEC_ELT (method_vec, 1)) - /* We thought there was a destructor, but there wasn't. Some - parse errors cause this anomalous situation. */ - TYPE_HAS_DESTRUCTOR (t) = 0; - - /* Issue warnings about private constructors and such. If there are - no methods, then some public defaults are generated. */ - maybe_warn_about_overly_private_class (t); - - /* Now for each member function (except for constructors and - destructors), compute where member functions of the same - name reside in base classes. */ - if (n_baseclasses != 0 - && method_vec - && TREE_VEC_LENGTH (method_vec) > 2) - { - int len = TREE_VEC_LENGTH (method_vec); - tree baselink_vec = make_tree_vec (len); - int any_links = 0; - tree baselink_binfo = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - for (i = 2; i < len && TREE_VEC_ELT (method_vec, i); i++) - { - tree ovl = TREE_VEC_ELT (method_vec, i); - - TREE_VEC_ELT (baselink_vec, i) - = get_baselinks (baselink_binfo, t, - DECL_NAME (OVL_CURRENT (ovl))); - if (TREE_VEC_ELT (baselink_vec, i) != 0) - any_links = 1; - } - if (any_links != 0) - CLASSTYPE_BASELINK_VEC (t) = baselink_vec; - else - obstack_free (current_obstack, baselink_vec); - } -} - -/* Emit error when a duplicate definition of a type is seen. Patch up. */ - -void -duplicate_tag_error (t) - tree t; -{ - cp_error ("redefinition of `%#T'", t); - cp_error_at ("previous definition here", t); - - /* Pretend we haven't defined this type. */ - - /* All of the component_decl's were TREE_CHAINed together in the parser. - finish_struct_methods walks these chains and assembles all methods with - the same base name into DECL_CHAINs. Now we don't need the parser chains - anymore, so we unravel them. */ - - /* This used to be in finish_struct, but it turns out that the - TREE_CHAIN is used by dbxout_type_methods and perhaps some other - things... */ - if (CLASSTYPE_METHOD_VEC (t)) - { - tree method_vec = CLASSTYPE_METHOD_VEC (t); - int i, len = TREE_VEC_LENGTH (method_vec); - for (i = 0; i < len; i++) - { - tree unchain = TREE_VEC_ELT (method_vec, i); - while (unchain != NULL_TREE) - { - TREE_CHAIN (OVL_CURRENT (unchain)) = NULL_TREE; - unchain = OVL_NEXT (unchain); - } - } - } - - if (TYPE_LANG_SPECIFIC (t)) - { - tree as_list = CLASSTYPE_AS_LIST (t); - tree binfo = TYPE_BINFO (t); - tree binfo_as_list = CLASSTYPE_BINFO_AS_LIST (t); - int interface_only = CLASSTYPE_INTERFACE_ONLY (t); - int interface_unknown = CLASSTYPE_INTERFACE_UNKNOWN (t); - - bzero ((char *) TYPE_LANG_SPECIFIC (t), sizeof (struct lang_type)); - BINFO_BASETYPES(binfo) = NULL_TREE; - - CLASSTYPE_AS_LIST (t) = as_list; - TYPE_BINFO (t) = binfo; - CLASSTYPE_BINFO_AS_LIST (t) = binfo_as_list; - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); - TYPE_REDEFINED (t) = 1; - } - TYPE_SIZE (t) = NULL_TREE; - TYPE_MODE (t) = VOIDmode; - TYPE_FIELDS (t) = NULL_TREE; - TYPE_METHODS (t) = NULL_TREE; - TYPE_VFIELD (t) = NULL_TREE; - TYPE_CONTEXT (t) = NULL_TREE; -} - -/* finish up all new vtables. */ - -static void -finish_vtbls (binfo, do_self, t) - tree binfo; - int do_self; - tree t; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - if (BINFO_NEW_VTABLE_MARKED (binfo)) - { - tree decl, context; - - decl = BINFO_VTABLE (binfo); - context = DECL_CONTEXT (decl); - DECL_CONTEXT (decl) = 0; - if (DECL_INITIAL (decl) != BINFO_VIRTUALS (binfo)) - DECL_INITIAL (decl) = build_nt (CONSTRUCTOR, NULL_TREE, - BINFO_VIRTUALS (binfo)); - cp_finish_decl (decl, DECL_INITIAL (decl), NULL_TREE, 0, 0); - DECL_CONTEXT (decl) = context; - } - CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); - } - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (TREE_VIA_VIRTUAL (base_binfo)) - { - base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); - } - finish_vtbls (base_binfo, is_not_base_vtable, t); - } -} - -/* True if we should override the given BASE_FNDECL with the given - FNDECL. */ - -static int -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))) - return 1; - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (base_fndecl)) - || DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) - return 0; - if (DECL_NAME (fndecl) == DECL_NAME (base_fndecl)) - { - tree types, base_types; -#if 0 - retypes = TREE_TYPE (TREE_TYPE (fndecl)); - base_retypes = TREE_TYPE (TREE_TYPE (base_fndecl)); -#endif - types = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - base_types = TYPE_ARG_TYPES (TREE_TYPE (base_fndecl)); - if ((TYPE_QUALS (TREE_TYPE (TREE_VALUE (base_types))) - == TYPE_QUALS (TREE_TYPE (TREE_VALUE (types)))) - && compparms (TREE_CHAIN (base_types), TREE_CHAIN (types))) - return 1; - } - return 0; -} - -static tree -get_class_offset_1 (parent, binfo, context, t, fndecl) - tree parent, binfo, context, t, fndecl; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree rval = NULL_TREE; - - if (binfo == parent) - return error_mark_node; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree nrval; - - if (TREE_VIA_VIRTUAL (base_binfo)) - base_binfo = binfo_member (BINFO_TYPE (base_binfo), - CLASSTYPE_VBASECLASSES (t)); - nrval = get_class_offset_1 (parent, base_binfo, context, t, fndecl); - /* See if we have a new value */ - if (nrval && (nrval != error_mark_node || rval==0)) - { - /* Only compare if we have two offsets */ - if (rval && rval != error_mark_node - && ! tree_int_cst_equal (nrval, rval)) - { - /* Only give error if the two offsets are different */ - error ("every virtual function must have a unique final overrider"); - cp_error (" found two (or more) `%T' class subobjects in `%T'", context, t); - cp_error (" with virtual `%D' from virtual base class", fndecl); - return rval; - } - rval = nrval; - } - - if (rval && BINFO_TYPE (binfo) == context) - { - my_friendly_assert (rval == error_mark_node - || tree_int_cst_equal (rval, BINFO_OFFSET (binfo)), 999); - rval = BINFO_OFFSET (binfo); - } - } - return rval; -} - -/* Get the offset to the CONTEXT subobject that is related to the - given BINFO. */ - -static tree -get_class_offset (context, t, binfo, fndecl) - tree context, t, binfo, fndecl; -{ - tree first_binfo = binfo; - tree offset; - int i; - - if (context == t) - return integer_zero_node; - - if (BINFO_TYPE (binfo) == context) - return BINFO_OFFSET (binfo); - - /* Check less derived binfos first. */ - while (BINFO_BASETYPES (binfo) - && (i=CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo))) != -1) - { - tree binfos = BINFO_BASETYPES (binfo); - binfo = TREE_VEC_ELT (binfos, i); - if (BINFO_TYPE (binfo) == context) - return BINFO_OFFSET (binfo); - } - - /* Ok, not found in the less derived binfos, now check the more - derived binfos. */ - offset = get_class_offset_1 (first_binfo, TYPE_BINFO (t), context, t, fndecl); - if (offset==0 || TREE_CODE (offset) != INTEGER_CST) - my_friendly_abort (999); /* we have to find it. */ - return offset; -} - -/* Skip RTTI information at the front of the virtual list. */ - -unsigned HOST_WIDE_INT -skip_rtti_stuff (virtuals) - tree *virtuals; -{ - int n; - - n = 0; - if (*virtuals) - { - /* We always reserve a slot for the offset/tdesc entry. */ - ++n; - *virtuals = TREE_CHAIN (*virtuals); - } - if (flag_vtable_thunks && *virtuals) - { - /* The second slot is reserved for the tdesc pointer when thunks - are used. */ - ++n; - *virtuals = TREE_CHAIN (*virtuals); - } - return n; -} - -static void -modify_one_vtable (binfo, t, fndecl, pfn) - tree binfo, t, fndecl, pfn; -{ - tree virtuals = BINFO_VIRTUALS (binfo); - unsigned HOST_WIDE_INT n; - - /* update rtti entry */ - if (flag_rtti) - { - if (binfo == TYPE_BINFO (t)) - { - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - build_vtable (TYPE_BINFO (DECL_CONTEXT (CLASSTYPE_VFIELD (t))), t); - } - else - { - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - prepare_fresh_vtable (binfo, t); - } - } - if (fndecl == NULL_TREE) - return; - - n = skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree current_fndecl = TREE_VALUE (virtuals); - current_fndecl = FNADDR_FROM_VTABLE_ENTRY (current_fndecl); - current_fndecl = TREE_OPERAND (current_fndecl, 0); - if (current_fndecl && overrides (fndecl, current_fndecl)) - { - tree base_offset, offset; - tree context = DECL_CLASS_CONTEXT (fndecl); - tree vfield = CLASSTYPE_VFIELD (t); - tree this_offset; - - offset = get_class_offset (context, t, binfo, fndecl); - - /* Find the right offset for the this pointer based on the - base class we just found. We have to take into - consideration the virtual base class pointers that we - stick in before the virtual function table pointer. - - Also, we want just the delta between the most base class - that we derived this vfield from and us. */ - base_offset = size_binop (PLUS_EXPR, - get_derived_offset (binfo, DECL_CONTEXT (current_fndecl)), - BINFO_OFFSET (binfo)); - this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); - - if (binfo == TYPE_BINFO (t)) - { - /* In this case, it is *type*'s vtable we are modifying. - We start with the approximation that it's vtable is that - of the immediate base class. */ - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t); - } - else - { - /* This is our very own copy of `basetype' to play with. - Later, we will fill in all the virtual functions - that override the virtual functions in these base classes - which are not defined by the current type. */ - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - prepare_fresh_vtable (binfo, t); - } - -#ifdef NOTQUITE - cp_warning ("in %D", DECL_NAME (BINFO_VTABLE (binfo))); -#endif - modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n), - build_vtable_entry (this_offset, pfn), - fndecl); - } - ++n; - virtuals = TREE_CHAIN (virtuals); - } -} - -/* These are the ones that are not through virtual base classes. */ - -static void -modify_all_direct_vtables (binfo, do_self, t, fndecl, pfn) - tree binfo; - int do_self; - tree t, fndecl, pfn; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - modify_one_vtable (binfo, t, fndecl, pfn); - } - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (! TREE_VIA_VIRTUAL (base_binfo)) - modify_all_direct_vtables (base_binfo, is_not_base_vtable, t, fndecl, pfn); - } -} - -/* Fixup all the delta entries in this one vtable that need updating. */ - -static void -fixup_vtable_deltas1 (binfo, t) - tree binfo, t; -{ - tree virtuals = BINFO_VIRTUALS (binfo); - unsigned HOST_WIDE_INT n; - - n = skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree fndecl = TREE_VALUE (virtuals); - tree pfn = FNADDR_FROM_VTABLE_ENTRY (fndecl); - tree delta = DELTA_FROM_VTABLE_ENTRY (fndecl); - fndecl = TREE_OPERAND (pfn, 0); - if (fndecl) - { - tree base_offset, offset; - tree context = DECL_CLASS_CONTEXT (fndecl); - tree vfield = CLASSTYPE_VFIELD (t); - tree this_offset; - - offset = get_class_offset (context, t, binfo, fndecl); - - /* Find the right offset for the this pointer based on the - base class we just found. We have to take into - consideration the virtual base class pointers that we - stick in before the virtual function table pointer. - - Also, we want just the delta between the most base class - that we derived this vfield from and us. */ - base_offset = size_binop (PLUS_EXPR, - get_derived_offset (binfo, - DECL_CONTEXT (fndecl)), - BINFO_OFFSET (binfo)); - this_offset = ssize_binop (MINUS_EXPR, offset, base_offset); - - if (! tree_int_cst_equal (this_offset, delta)) - { - /* Make sure we can modify the derived association with immunity. */ - if (binfo == TYPE_BINFO (t)) - { - /* In this case, it is *type*'s vtable we are modifying. - We start with the approximation that it's vtable is that - of the immediate base class. */ - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - build_vtable (TYPE_BINFO (DECL_CONTEXT (vfield)), t); - } - else - { - /* This is our very own copy of `basetype' to play with. - Later, we will fill in all the virtual functions - that override the virtual functions in these base classes - which are not defined by the current type. */ - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - prepare_fresh_vtable (binfo, t); - } - - modify_vtable_entry (get_vtable_entry_n (BINFO_VIRTUALS (binfo), n), - build_vtable_entry (this_offset, pfn), - fndecl); - } - } - ++n; - virtuals = TREE_CHAIN (virtuals); - } -} - -/* Fixup all the delta entries in all the direct vtables that need updating. - This happens when we have non-overridden virtual functions from a - virtual base class, that are at a different offset, in the new - hierarchy, because the layout of the virtual bases has changed. */ - -static void -fixup_vtable_deltas (binfo, init_self, t) - tree binfo; - int init_self; - tree t; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (! TREE_VIA_VIRTUAL (base_binfo)) - fixup_vtable_deltas (base_binfo, is_not_base_vtable, t); - } - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - fixup_vtable_deltas1 (binfo, t); - } -} - -/* These are the ones that are through virtual base classes. */ - -static void -modify_all_indirect_vtables (binfo, do_self, via_virtual, t, fndecl, pfn) - tree binfo; - int do_self, via_virtual; - tree t, fndecl, pfn; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && via_virtual && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - modify_one_vtable (binfo, t, fndecl, pfn); - } - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (TREE_VIA_VIRTUAL (base_binfo)) - { - via_virtual = 1; - base_binfo = binfo_member (BINFO_TYPE (base_binfo), CLASSTYPE_VBASECLASSES (t)); - } - modify_all_indirect_vtables (base_binfo, is_not_base_vtable, via_virtual, t, fndecl, pfn); - } -} - -static void -modify_all_vtables (t, fndecl, vfn) - tree t, fndecl, vfn; -{ - /* Do these first, so that we will make use of any non-virtual class's - vtable, over a virtual classes vtable. */ - modify_all_direct_vtables (TYPE_BINFO (t), 1, t, fndecl, vfn); - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - modify_all_indirect_vtables (TYPE_BINFO (t), 1, 0, t, fndecl, vfn); -} - -/* Here, we already know that they match in every respect. - All we have to check is where they had their declarations. */ - -static int -strictly_overrides (fndecl1, fndecl2) - tree fndecl1, fndecl2; -{ - int distance = get_base_distance (DECL_CLASS_CONTEXT (fndecl2), - DECL_CLASS_CONTEXT (fndecl1), - 0, (tree *)0); - if (distance == -2 || distance > 0) - return 1; - return 0; -} - -/* Merge overrides for one vtable. - If we want to merge in same function, we are fine. - else - if one has a DECL_CLASS_CONTEXT that is a parent of the - other, than choose the more derived one - else - potentially ill-formed (see 10.3 [class.virtual]) - we have to check later to see if there was an - override in this class. If there was ok, if not - then it is ill-formed. (mrs) - - We take special care to reuse a vtable, if we can. */ - -static void -override_one_vtable (binfo, old, t) - tree binfo, old, t; -{ - tree virtuals = BINFO_VIRTUALS (binfo); - tree old_virtuals = BINFO_VIRTUALS (old); - enum { REUSE_NEW, REUSE_OLD, UNDECIDED, NEITHER } choose = UNDECIDED; - - /* If we have already committed to modifying it, then don't try and - reuse another vtable. */ - if (BINFO_NEW_VTABLE_MARKED (binfo)) - choose = NEITHER; - - skip_rtti_stuff (&virtuals); - skip_rtti_stuff (&old_virtuals); - - while (virtuals) - { - tree fndecl = TREE_VALUE (virtuals); - tree old_fndecl = TREE_VALUE (old_virtuals); - fndecl = FNADDR_FROM_VTABLE_ENTRY (fndecl); - old_fndecl = FNADDR_FROM_VTABLE_ENTRY (old_fndecl); - fndecl = TREE_OPERAND (fndecl, 0); - old_fndecl = TREE_OPERAND (old_fndecl, 0); - /* First check to see if they are the same. */ - if (DECL_ASSEMBLER_NAME (fndecl) == DECL_ASSEMBLER_NAME (old_fndecl)) - { - /* No need to do anything. */ - } - else if (strictly_overrides (fndecl, old_fndecl)) - { - if (choose == UNDECIDED) - choose = REUSE_NEW; - else if (choose == REUSE_OLD) - { - choose = NEITHER; - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - { - prepare_fresh_vtable (binfo, t); - override_one_vtable (binfo, old, t); - return; - } - } - } - else if (strictly_overrides (old_fndecl, fndecl)) - { - if (choose == UNDECIDED) - choose = REUSE_OLD; - else if (choose == REUSE_NEW) - { - choose = NEITHER; - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - { - prepare_fresh_vtable (binfo, t); - override_one_vtable (binfo, old, t); - return; - } - TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals); - } - else if (choose == NEITHER) - { - TREE_VALUE (virtuals) = TREE_VALUE (old_virtuals); - } - } - else - { - choose = NEITHER; - if (! BINFO_NEW_VTABLE_MARKED (binfo)) - { - prepare_fresh_vtable (binfo, t); - override_one_vtable (binfo, old, t); - return; - } - { - /* This MUST be overridden, or the class is ill-formed. */ - tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); - tree vfn; - - fndecl = copy_node (fndecl); - copy_lang_decl (fndecl); - DECL_NEEDS_FINAL_OVERRIDER_P (fndecl) = 1; - /* Make sure we search for it later. */ - if (! CLASSTYPE_ABSTRACT_VIRTUALS (t)) - CLASSTYPE_ABSTRACT_VIRTUALS (t) = error_mark_node; - - vfn = build1 (ADDR_EXPR, vfunc_ptr_type_node, fndecl); - TREE_CONSTANT (vfn) = 1; - - /* We can use integer_zero_node, as we will core dump - if this is used anyway. */ - TREE_VALUE (virtuals) = build_vtable_entry (integer_zero_node, vfn); - } - } - virtuals = TREE_CHAIN (virtuals); - old_virtuals = TREE_CHAIN (old_virtuals); - } - - /* Let's reuse the old vtable. */ - if (choose == REUSE_OLD) - { - BINFO_VTABLE (binfo) = BINFO_VTABLE (old); - BINFO_VIRTUALS (binfo) = BINFO_VIRTUALS (old); - } -} - -/* Merge in overrides for virtual bases. - BINFO is the hierarchy we want to modify, and OLD has the potential - overrides. */ - -static void -merge_overrides (binfo, old, do_self, t) - tree binfo, old; - int do_self; - tree t; -{ - tree binfos = BINFO_BASETYPES (binfo); - tree old_binfos = BINFO_BASETYPES (old); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - override_one_vtable (binfo, old, t); - } - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree old_base_binfo = TREE_VEC_ELT (old_binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (! TREE_VIA_VIRTUAL (base_binfo)) - merge_overrides (base_binfo, old_base_binfo, is_not_base_vtable, t); - } -} - -/* Get the base virtual function declarations in T that are either - overridden or hidden by FNDECL as a list. We set TREE_PURPOSE with - the overrider/hider. */ - -static tree -get_basefndecls (fndecl, t) - tree fndecl, t; -{ - tree methods = TYPE_METHODS (t); - tree base_fndecls = NULL_TREE; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - while (methods) - { - if (TREE_CODE (methods) == FUNCTION_DECL - && DECL_VINDEX (methods) != NULL_TREE - && DECL_NAME (fndecl) == DECL_NAME (methods)) - base_fndecls = temp_tree_cons (fndecl, methods, base_fndecls); - - methods = TREE_CHAIN (methods); - } - - if (base_fndecls) - return base_fndecls; - - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - base_fndecls = chainon (get_basefndecls (fndecl, basetype), - base_fndecls); - } - - return base_fndecls; -} - -/* Mark the functions that have been hidden with their overriders. - Since we start out with all functions already marked with a hider, - no need to mark functions that are just hidden. */ - -static void -mark_overriders (fndecl, base_fndecls) - tree fndecl, base_fndecls; -{ - while (base_fndecls) - { - if (overrides (TREE_VALUE (base_fndecls), fndecl)) - TREE_PURPOSE (base_fndecls) = fndecl; - - base_fndecls = TREE_CHAIN (base_fndecls); - } -} - -/* If this declaration supersedes the declaration of - a method declared virtual in the base class, then - mark this field as being virtual as well. */ - -static void -check_for_override (decl, ctype) - tree decl, ctype; -{ - tree binfos = BINFO_BASETYPES (TYPE_BINFO (ctype)); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int virtualp = DECL_VIRTUAL_P (decl); - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (TYPE_VIRTUAL_P (BINFO_TYPE (base_binfo))) - { - tree tmp = get_matching_virtual - (base_binfo, decl, - DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl))); - if (tmp) - { - /* If this function overrides some virtual in some base - class, then the function itself is also necessarily - virtual, even if the user didn't explicitly say so. */ - DECL_VIRTUAL_P (decl) = 1; - - /* The TMP we really want is the one from the deepest - baseclass on this path, taking care not to - duplicate if we have already found it (via another - path to its virtual baseclass. */ - if (TREE_CODE (TREE_TYPE (decl)) == FUNCTION_TYPE) - { - cp_error_at ("method `%D' may not be declared static", - decl); - cp_error_at ("(since `%D' declared virtual in base class.)", - tmp); - break; - } - virtualp = 1; - -#if 0 /* The signature of an overriding function is not changed. */ - { - /* The argument types may have changed... */ - tree type = TREE_TYPE (decl); - tree argtypes = TYPE_ARG_TYPES (type); - tree base_variant = TREE_TYPE (TREE_VALUE (argtypes)); - tree raises = TYPE_RAISES_EXCEPTIONS (type); - - argtypes = commonparms (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (tmp))), - TREE_CHAIN (argtypes)); - /* But the return type has not. */ - type = build_cplus_method_type (base_variant, TREE_TYPE (type), argtypes); - if (raises) - type = build_exception_variant (type, raises); - TREE_TYPE (decl) = type; - } -#endif - DECL_VINDEX (decl) - = tree_cons (NULL_TREE, tmp, DECL_VINDEX (decl)); - break; - } - } - } - if (virtualp) - { - if (DECL_VINDEX (decl) == NULL_TREE) - DECL_VINDEX (decl) = error_mark_node; - IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; - } -} - -/* Warn about hidden virtual functions that are not overridden in t. - We know that constructors and destructors don't apply. */ - -void -warn_hidden (t) - tree t; -{ - tree method_vec = CLASSTYPE_METHOD_VEC (t); - int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - int i; - - /* We go through each separately named virtual function. */ - for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) - { - tree fns = TREE_VEC_ELT (method_vec, i); - tree fndecl; - - tree base_fndecls = NULL_TREE; - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - fndecl = OVL_CURRENT (fns); - if (DECL_VINDEX (fndecl) == NULL_TREE) - continue; - - /* First we get a list of all possible functions that might be - hidden from each base class. */ - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - - base_fndecls = chainon (get_basefndecls (fndecl, basetype), - base_fndecls); - } - - fns = OVL_NEXT (fns); - if (fns) - fndecl = OVL_CURRENT (fns); - else - fndecl = NULL_TREE; - - /* ...then mark up all the base functions with overriders, preferring - overriders to hiders. */ - if (base_fndecls) - while (fndecl) - { - mark_overriders (fndecl, base_fndecls); - - fns = OVL_NEXT (fns); - if (fns) - fndecl = OVL_CURRENT (fns); - else - fndecl = NULL_TREE; - } - - /* Now give a warning for all base functions without overriders, - as they are hidden. */ - while (base_fndecls) - { - if (! overrides (TREE_VALUE (base_fndecls), - TREE_PURPOSE (base_fndecls))) - { - /* Here we know it is a hider, and no overrider exists. */ - cp_warning_at ("`%D' was hidden", TREE_VALUE (base_fndecls)); - cp_warning_at (" by `%D'", TREE_PURPOSE (base_fndecls)); - } - - base_fndecls = TREE_CHAIN (base_fndecls); - } - } -} - -/* Check for things that are invalid. There are probably plenty of other - things we should check for also. */ - -static void -finish_struct_anon (t) - tree t; -{ - tree field; - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) - { - if (TREE_STATIC (field)) - continue; - if (TREE_CODE (field) != FIELD_DECL) - continue; - - if (DECL_NAME (field) == NULL_TREE - && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) - { - tree* uelt = &TYPE_FIELDS (TREE_TYPE (field)); - for (; *uelt; uelt = &TREE_CHAIN (*uelt)) - { - if (DECL_ARTIFICIAL (*uelt)) - continue; - - if (DECL_NAME (*uelt) == constructor_name (t)) - cp_pedwarn_at ("ANSI C++ forbids member `%D' with same name as enclosing class", - *uelt); - - if (TREE_CODE (*uelt) != FIELD_DECL) - { - cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members", - *uelt); - continue; - } - - if (TREE_PRIVATE (*uelt)) - cp_pedwarn_at ("private member `%#D' in anonymous union", - *uelt); - else if (TREE_PROTECTED (*uelt)) - cp_pedwarn_at ("protected member `%#D' in anonymous union", - *uelt); - - TREE_PRIVATE (*uelt) = TREE_PRIVATE (field); - TREE_PROTECTED (*uelt) = TREE_PROTECTED (field); - } - } - } -} - -extern int interface_only, interface_unknown; - -/* Create default constructors, assignment operators, and so forth for - the type indicated by T, if they are needed. - CANT_HAVE_DEFAULT_CTOR, CANT_HAVE_CONST_CTOR, and - CANT_HAVE_ASSIGNMENT are nonzero if, for whatever reason, the class - cannot have a default constructor, copy constructor taking a const - reference argument, or an assignment operator, respectively. If a - virtual destructor is created, its DECL is returned; otherwise the - return value is NULL_TREE. */ - -static tree -add_implicitly_declared_members (t, cant_have_default_ctor, - cant_have_const_cctor, - cant_have_assignment) - tree t; - int cant_have_default_ctor; - int cant_have_const_cctor; - int cant_have_assignment; -{ - tree default_fn; - tree implicit_fns = NULL_TREE; - tree name = TYPE_IDENTIFIER (t); - tree virtual_dtor = NULL_TREE; - tree *f; - - /* Destructor. */ - if (TYPE_NEEDS_DESTRUCTOR (t) && !TYPE_HAS_DESTRUCTOR (t) - && !IS_SIGNATURE (t)) - { - default_fn = cons_up_default_function (t, name, 0); - check_for_override (default_fn, t); - - /* If we couldn't make it work, then pretend we didn't need it. */ - if (default_fn == void_type_node) - TYPE_NEEDS_DESTRUCTOR (t) = 0; - else - { - TREE_CHAIN (default_fn) = implicit_fns; - implicit_fns = default_fn; - - if (DECL_VINDEX (default_fn)) - virtual_dtor = default_fn; - } - } - TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_HAS_DESTRUCTOR (t); - - /* Default constructor. */ - if (! TYPE_HAS_CONSTRUCTOR (t) && ! cant_have_default_ctor - && ! IS_SIGNATURE (t)) - { - default_fn = cons_up_default_function (t, name, 2); - TREE_CHAIN (default_fn) = implicit_fns; - implicit_fns = default_fn; - } - - /* Copy constructor. */ - if (! TYPE_HAS_INIT_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) - { - /* ARM 12.18: You get either X(X&) or X(const X&), but - not both. --Chip */ - default_fn = cons_up_default_function (t, name, - 3 + cant_have_const_cctor); - TREE_CHAIN (default_fn) = implicit_fns; - implicit_fns = default_fn; - } - - /* Assignment operator. */ - if (! TYPE_HAS_ASSIGN_REF (t) && ! IS_SIGNATURE (t) && ! TYPE_FOR_JAVA (t)) - { - default_fn = cons_up_default_function (t, name, - 5 + cant_have_assignment); - TREE_CHAIN (default_fn) = implicit_fns; - implicit_fns = default_fn; - } - - /* Now, hook all of the new functions on to TYPE_METHODS, - and add them to the CLASSTYPE_METHOD_VEC. */ - for (f = &implicit_fns; *f; f = &TREE_CHAIN (*f)) - add_method (t, 0, *f); - *f = TYPE_METHODS (t); - TYPE_METHODS (t) = implicit_fns; - - return virtual_dtor; -} - -/* Create a RECORD_TYPE or UNION_TYPE node for a C struct or union declaration - (or C++ class declaration). - - For C++, we must handle the building of derived classes. - Also, C++ allows static class members. The way that this is - handled is to keep the field name where it is (as the DECL_NAME - of the field), and place the overloaded decl in the DECL_FIELD_BITPOS - of the field. layout_record and layout_union will know about this. - - More C++ hair: inline functions have text in their - DECL_PENDING_INLINE_INFO nodes which must somehow be parsed into - meaningful tree structure. After the struct has been laid out, set - things up so that this can happen. - - And still more: virtual functions. In the case of single inheritance, - when a new virtual function is seen which redefines a virtual function - from the base class, the new virtual function is placed into - the virtual function table at exactly the same address that - it had in the base class. When this is extended to multiple - inheritance, the same thing happens, except that multiple virtual - function tables must be maintained. The first virtual function - table is treated in exactly the same way as in the case of single - inheritance. Additional virtual function tables have different - DELTAs, which tell how to adjust `this' to point to the right thing. - - ATTRIBUTES is the set of decl attributes to be applied, if any. */ - -tree -finish_struct_1 (t, warn_anon) - tree t; - int warn_anon; -{ - int old; - enum tree_code code = TREE_CODE (t); - tree fields = TYPE_FIELDS (t); - tree x, last_x, method_vec; - int has_virtual; - int max_has_virtual; - tree pending_virtuals = NULL_TREE; - tree pending_hard_virtuals = NULL_TREE; - tree abstract_virtuals = NULL_TREE; - tree vfield; - tree vfields; - tree virtual_dtor; - int cant_have_default_ctor; - int cant_have_const_ctor; - int no_const_asn_ref; - int has_mutable = 0; - - /* The index of the first base class which has virtual - functions. Only applied to non-virtual baseclasses. */ - int first_vfn_base_index; - - int n_baseclasses; - int any_default_members = 0; - int const_sans_init = 0; - int ref_sans_init = 0; - tree access_decls = NULL_TREE; - int aggregate = 1; - int empty = 1; - int has_pointers = 0; - - if (warn_anon && code != UNION_TYPE && ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) - pedwarn ("anonymous class type not used to declare any objects"); - - if (TYPE_SIZE (t)) - { - if (IS_AGGR_TYPE (t)) - cp_error ("redefinition of `%#T'", t); - else - my_friendly_abort (172); - popclass (0); - return t; - } - - GNU_xref_decl (current_function_decl, t); - - /* If this type was previously laid out as a forward reference, - make sure we lay it out again. */ - - TYPE_SIZE (t) = NULL_TREE; - CLASSTYPE_GOT_SEMICOLON (t) = 0; - -#if 0 - /* This is in general too late to do this. I moved the main case up to - left_curly, what else needs to move? */ - if (! IS_SIGNATURE (t)) - { - my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); - my_friendly_assert (CLASSTYPE_INTERFACE_KNOWN (t) == ! interface_unknown, 999); - } -#endif - - old = suspend_momentary (); - - /* Install struct as DECL_FIELD_CONTEXT of each field decl. - Also process specified field sizes. - Set DECL_FIELD_SIZE to the specified size, or 0 if none specified. - The specified size is found in the DECL_INITIAL. - Store 0 there, except for ": 0" fields (so we can find them - and delete them, below). */ - - if (TYPE_BINFO_BASETYPES (t)) - n_baseclasses = TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (t)); - else - n_baseclasses = 0; - - if (n_baseclasses > 0) - { - struct base_info base_info; - - first_vfn_base_index = finish_base_struct (t, &base_info); - /* Remember where we got our vfield from. */ - CLASSTYPE_VFIELD_PARENT (t) = first_vfn_base_index; - has_virtual = base_info.has_virtual; - max_has_virtual = base_info.max_has_virtual; - CLASSTYPE_N_SUPERCLASSES (t) += base_info.n_ancestors; - vfield = base_info.vfield; - vfields = base_info.vfields; - CLASSTYPE_RTTI (t) = base_info.rtti; - cant_have_default_ctor = base_info.cant_have_default_ctor; - cant_have_const_ctor = base_info.cant_have_const_ctor; - no_const_asn_ref = base_info.no_const_asn_ref; - aggregate = 0; - } - else - { - first_vfn_base_index = -1; - has_virtual = 0; - max_has_virtual = has_virtual; - vfield = NULL_TREE; - vfields = NULL_TREE; - CLASSTYPE_RTTI (t) = NULL_TREE; - cant_have_default_ctor = 0; - cant_have_const_ctor = 0; - no_const_asn_ref = 0; - } - -#if 0 - /* Both of these should be done before now. */ - if (write_virtuals == 3 && CLASSTYPE_INTERFACE_KNOWN (t) - && ! IS_SIGNATURE (t)) - { - my_friendly_assert (CLASSTYPE_INTERFACE_ONLY (t) == interface_only, 999); - my_friendly_assert (CLASSTYPE_VTABLE_NEEDS_WRITING (t) == ! interface_only, 999); - } -#endif - - /* The three of these are approximations which may later be - modified. Needed at this point to make add_virtual_function - and modify_vtable_entries work. */ - CLASSTYPE_VFIELDS (t) = vfields; - CLASSTYPE_VFIELD (t) = vfield; - - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) - { - GNU_xref_member (current_class_name, x); - - /* If this was an evil function, don't keep it in class. */ - if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (x))) - continue; - - /* Do both of these, even though they're in the same union; - if the insn `r' member and the size `i' member are - different sizes, as on the alpha, the larger of the two - will end up with garbage in it. */ - DECL_SAVED_INSNS (x) = NULL_RTX; - DECL_FIELD_SIZE (x) = 0; - - check_for_override (x, t); - if (DECL_ABSTRACT_VIRTUAL_P (x) && ! DECL_VINDEX (x)) - cp_error_at ("initializer specified for non-virtual method `%D'", x); - - /* The name of the field is the original field name - Save this in auxiliary field for later overloading. */ - if (DECL_VINDEX (x)) - { - add_virtual_function (&pending_virtuals, &pending_hard_virtuals, - &has_virtual, x, t); - if (DECL_ABSTRACT_VIRTUAL_P (x)) - abstract_virtuals = tree_cons (NULL_TREE, x, abstract_virtuals); -#if 0 - /* XXX Why did I comment this out? (jason) */ - else - TREE_USED (x) = 1; -#endif - } - } - - if (n_baseclasses) - fields = chainon (build_vbase_pointer_fields (t), fields); - - last_x = NULL_TREE; - for (x = fields; x; x = TREE_CHAIN (x)) - { - GNU_xref_member (current_class_name, x); - - if (TREE_CODE (x) == FIELD_DECL) - { - DECL_PACKED (x) |= TYPE_PACKED (t); - - if (DECL_C_BIT_FIELD (x) && integer_zerop (DECL_INITIAL (x))) - /* A zero-width bitfield doesn't do the trick. */; - else - empty = 0; - } - - if (TREE_CODE (x) == USING_DECL) - { - /* Save access declarations for later. */ - if (last_x) - TREE_CHAIN (last_x) = TREE_CHAIN (x); - else - fields = TREE_CHAIN (x); - - access_decls = scratch_tree_cons (NULL_TREE, x, access_decls); - continue; - } - - last_x = x; - - if (TREE_CODE (x) == TYPE_DECL - || TREE_CODE (x) == TEMPLATE_DECL) - continue; - - /* If we've gotten this far, it's a data member, possibly static, - or an enumerator. */ - - DECL_FIELD_CONTEXT (x) = t; - - /* ``A local class cannot have static data members.'' ARM 9.4 */ - if (current_function_decl && TREE_STATIC (x)) - cp_error_at ("field `%D' in local class cannot be static", x); - - /* Perform error checking that did not get done in - grokdeclarator. */ - if (TREE_CODE (TREE_TYPE (x)) == FUNCTION_TYPE) - { - cp_error_at ("field `%D' invalidly declared function type", - x); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - else if (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE) - { - cp_error_at ("field `%D' invalidly declared method type", x); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - else if (TREE_CODE (TREE_TYPE (x)) == OFFSET_TYPE) - { - cp_error_at ("field `%D' invalidly declared offset type", x); - TREE_TYPE (x) = build_pointer_type (TREE_TYPE (x)); - } - -#if 0 - if (DECL_NAME (x) == constructor_name (t)) - cant_have_default_ctor = 1; -#endif - - if (TREE_TYPE (x) == error_mark_node) - continue; - - DECL_SAVED_INSNS (x) = NULL_RTX; - DECL_FIELD_SIZE (x) = 0; - - /* When this goes into scope, it will be a non-local reference. */ - DECL_NONLOCAL (x) = 1; - - if (TREE_CODE (x) == CONST_DECL) - continue; - - if (TREE_CODE (x) == VAR_DECL) - { - if (TREE_CODE (t) == UNION_TYPE) - /* Unions cannot have static members. */ - cp_error_at ("field `%D' declared static in union", x); - - continue; - } - - /* Now it can only be a FIELD_DECL. */ - - if (TREE_PRIVATE (x) || TREE_PROTECTED (x)) - aggregate = 0; - - /* If this is of reference type, check if it needs an init. - Also do a little ANSI jig if necessary. */ - if (TREE_CODE (TREE_TYPE (x)) == REFERENCE_TYPE) - { - if (DECL_INITIAL (x) == NULL_TREE) - ref_sans_init = 1; - - /* ARM $12.6.2: [A member initializer list] (or, for an - aggregate, initialization by a brace-enclosed list) is the - only way to initialize nonstatic const and reference - members. */ - cant_have_default_ctor = 1; - TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; - - if (! TYPE_HAS_CONSTRUCTOR (t) && extra_warnings) - { - if (DECL_NAME (x)) - cp_warning_at ("non-static reference `%#D' in class without a constructor", x); - else - cp_warning_at ("non-static reference in class without a constructor", x); - } - } - - if (TREE_CODE (TREE_TYPE (x)) == POINTER_TYPE) - has_pointers = 1; - - if (DECL_MUTABLE_P (x) || TYPE_HAS_MUTABLE_P (TREE_TYPE (x))) - has_mutable = 1; - - /* If any field is const, the structure type is pseudo-const. */ - if (TREE_READONLY (x)) - { - C_TYPE_FIELDS_READONLY (t) = 1; - if (DECL_INITIAL (x) == NULL_TREE) - const_sans_init = 1; - - /* ARM $12.6.2: [A member initializer list] (or, for an - aggregate, initialization by a brace-enclosed list) is the - only way to initialize nonstatic const and reference - members. */ - cant_have_default_ctor = 1; - TYPE_HAS_COMPLEX_ASSIGN_REF (t) = 1; - - if (! TYPE_HAS_CONSTRUCTOR (t) && !IS_SIGNATURE (t) - && extra_warnings) - { - if (DECL_NAME (x)) - cp_warning_at ("non-static const member `%#D' in class without a constructor", x); - else - cp_warning_at ("non-static const member in class without a constructor", x); - } - } - else - { - /* A field that is pseudo-const makes the structure - likewise. */ - tree t1 = TREE_TYPE (x); - while (TREE_CODE (t1) == ARRAY_TYPE) - t1 = TREE_TYPE (t1); - if (IS_AGGR_TYPE (t1)) - { - if (C_TYPE_FIELDS_READONLY (t1)) - C_TYPE_FIELDS_READONLY (t) = 1; - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (t1)) - const_sans_init = 1; - } - } - - /* We set DECL_C_BIT_FIELD in grokbitfield. - If the type and width are valid, we'll also set DECL_BIT_FIELD. */ - if (DECL_C_BIT_FIELD (x)) - { - /* Invalid bit-field size done by grokfield. */ - /* Detect invalid bit-field type. */ - if (DECL_INITIAL (x) - && ! INTEGRAL_TYPE_P (TREE_TYPE (x))) - { - cp_error_at ("bit-field `%#D' with non-integral type", x); - DECL_INITIAL (x) = NULL; - } - - /* Detect and ignore out of range field width. */ - if (DECL_INITIAL (x)) - { - tree w = DECL_INITIAL (x); - register int width = 0; - - /* Avoid the non_lvalue wrapper added by fold for PLUS_EXPRs. */ - STRIP_NOPS (w); - - /* detect invalid field size. */ - if (TREE_CODE (w) == CONST_DECL) - w = DECL_INITIAL (w); - else if (TREE_READONLY_DECL_P (w)) - w = decl_constant_value (w); - - if (TREE_CODE (w) != INTEGER_CST) - { - cp_error_at ("bit-field `%D' width not an integer constant", - x); - DECL_INITIAL (x) = NULL_TREE; - } - else if (width = TREE_INT_CST_LOW (w), - width < 0) - { - DECL_INITIAL (x) = NULL; - cp_error_at ("negative width in bit-field `%D'", x); - } - else if (width == 0 && DECL_NAME (x) != 0) - { - DECL_INITIAL (x) = NULL; - cp_error_at ("zero width for bit-field `%D'", x); - } - else if (width - > TYPE_PRECISION (long_long_unsigned_type_node)) - { - /* The backend will dump if you try to use something - too big; avoid that. */ - DECL_INITIAL (x) = NULL; - sorry ("bit-fields larger than %d bits", - TYPE_PRECISION (long_long_unsigned_type_node)); - cp_error_at (" in declaration of `%D'", x); - } - else if (width > TYPE_PRECISION (TREE_TYPE (x)) - && TREE_CODE (TREE_TYPE (x)) != ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (x)) != BOOLEAN_TYPE) - { - cp_warning_at ("width of `%D' exceeds its type", x); - } - else if (TREE_CODE (TREE_TYPE (x)) == ENUMERAL_TYPE - && ((min_precision (TYPE_MIN_VALUE (TREE_TYPE (x)), - TREE_UNSIGNED (TREE_TYPE (x))) > width) - || (min_precision (TYPE_MAX_VALUE (TREE_TYPE (x)), - TREE_UNSIGNED (TREE_TYPE (x))) > width))) - { - cp_warning_at ("`%D' is too small to hold all values of `%#T'", - x, TREE_TYPE (x)); - } - - if (DECL_INITIAL (x)) - { - DECL_INITIAL (x) = NULL_TREE; - DECL_FIELD_SIZE (x) = width; - DECL_BIT_FIELD (x) = 1; - - if (width == 0) - { -#ifdef EMPTY_FIELD_BOUNDARY - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - EMPTY_FIELD_BOUNDARY); -#endif -#ifdef PCC_BITFIELD_TYPE_MATTERS - if (PCC_BITFIELD_TYPE_MATTERS) - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), - TYPE_ALIGN (TREE_TYPE (x))); -#endif - } - } - } - else - /* Non-bit-fields are aligned for their type. */ - DECL_ALIGN (x) = MAX (DECL_ALIGN (x), TYPE_ALIGN (TREE_TYPE (x))); - } - else - { - tree type = TREE_TYPE (x); - - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - if (TYPE_LANG_SPECIFIC (type) && ! ANON_UNION_P (x) - && ! TYPE_PTRMEMFUNC_P (type)) - { - /* Never let anything with uninheritable virtuals - make it through without complaint. */ - if (CLASSTYPE_ABSTRACT_VIRTUALS (type)) - abstract_virtuals_error (x, type); - - /* Don't let signatures make it through either. */ - if (IS_SIGNATURE (type)) - signature_error (x, type); - - if (code == UNION_TYPE) - { - char *fie = NULL; - if (TYPE_NEEDS_CONSTRUCTING (type)) - fie = "constructor"; - else if (TYPE_NEEDS_DESTRUCTOR (type)) - fie = "destructor"; - else if (TYPE_HAS_COMPLEX_ASSIGN_REF (type)) - fie = "copy assignment operator"; - if (fie) - cp_error_at ("member `%#D' with %s not allowed in union", x, - fie); - } - else - { - TYPE_NEEDS_CONSTRUCTING (t) |= TYPE_NEEDS_CONSTRUCTING (type); - TYPE_NEEDS_DESTRUCTOR (t) |= TYPE_NEEDS_DESTRUCTOR (type); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) |= TYPE_HAS_COMPLEX_ASSIGN_REF (type); - TYPE_HAS_COMPLEX_INIT_REF (t) |= TYPE_HAS_COMPLEX_INIT_REF (type); - } - - if (!TYPE_HAS_CONST_INIT_REF (type)) - cant_have_const_ctor = 1; - - if (!TYPE_HAS_CONST_ASSIGN_REF (type)) - no_const_asn_ref = 1; - - if (TYPE_HAS_CONSTRUCTOR (type) - && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) - { - cant_have_default_ctor = 1; -#if 0 - /* This is wrong for aggregates. */ - if (! TYPE_HAS_CONSTRUCTOR (t)) - { - if (DECL_NAME (x)) - cp_pedwarn_at ("member `%#D' with only non-default constructor", x); - else - cp_pedwarn_at ("member with only non-default constructor", x); - cp_pedwarn_at ("in class without a constructor", - x); - } -#endif - } - } - if (DECL_INITIAL (x) != NULL_TREE) - { - /* `build_class_init_list' does not recognize - non-FIELD_DECLs. */ - if (code == UNION_TYPE && any_default_members != 0) - cp_error_at ("multiple fields in union `%T' initialized"); - any_default_members = 1; - } - } - } - - /* If this type has any constant members which did not come - with their own initialization, mark that fact here. It is - not an error here, since such types can be saved either by their - constructors, or by fortuitous initialization. */ - CLASSTYPE_READONLY_FIELDS_NEED_INIT (t) = const_sans_init; - CLASSTYPE_REF_FIELDS_NEED_INIT (t) = ref_sans_init; - CLASSTYPE_ABSTRACT_VIRTUALS (t) = abstract_virtuals; - CLASSTYPE_HAS_MUTABLE (t) = has_mutable; - - /* Effective C++ rule 11. */ - if (has_pointers && warn_ecpp && TYPE_HAS_CONSTRUCTOR (t) - && ! (TYPE_HAS_INIT_REF (t) && TYPE_HAS_ASSIGN_REF (t))) - { - cp_warning ("`%#T' has pointer data members", t); - - if (! TYPE_HAS_INIT_REF (t)) - { - cp_warning (" but does not override `%T(const %T&)'", t, t); - if (! TYPE_HAS_ASSIGN_REF (t)) - cp_warning (" or `operator=(const %T&)'", t); - } - else if (! TYPE_HAS_ASSIGN_REF (t)) - cp_warning (" but does not override `operator=(const %T&)'", t); - } - - /* Do some bookkeeping that will guide the generation of implicitly - declared member functions. */ - TYPE_HAS_COMPLEX_INIT_REF (t) - |= (TYPE_HAS_INIT_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) - || has_virtual || any_default_members); - TYPE_NEEDS_CONSTRUCTING (t) - |= (TYPE_HAS_CONSTRUCTOR (t) || TYPE_USES_VIRTUAL_BASECLASSES (t) - || has_virtual || any_default_members); - if (! IS_SIGNATURE (t)) - CLASSTYPE_NON_AGGREGATE (t) - = ! aggregate || has_virtual || TYPE_HAS_CONSTRUCTOR (t); - TYPE_HAS_REAL_ASSIGNMENT (t) |= TYPE_HAS_ASSIGNMENT (t); - TYPE_HAS_REAL_ASSIGN_REF (t) |= TYPE_HAS_ASSIGN_REF (t); - TYPE_HAS_COMPLEX_ASSIGN_REF (t) - |= TYPE_HAS_ASSIGN_REF (t) || TYPE_USES_VIRTUAL_BASECLASSES (t); - - /* Synthesize any needed methods. Note that methods will be synthesized - for anonymous unions; grok_x_components undoes that. */ - virtual_dtor - = add_implicitly_declared_members (t, cant_have_default_ctor, - cant_have_const_ctor, - no_const_asn_ref); - if (virtual_dtor) - add_virtual_function (&pending_virtuals, &pending_hard_virtuals, - &has_virtual, virtual_dtor, t); - - if (TYPE_METHODS (t)) - { - finish_struct_methods (t); - method_vec = CLASSTYPE_METHOD_VEC (t); - } - else - { - method_vec = 0; - - /* Just in case these got accidentally - filled in by syntax errors. */ - TYPE_HAS_CONSTRUCTOR (t) = 0; - TYPE_HAS_DESTRUCTOR (t) = 0; - } - - for (access_decls = nreverse (access_decls); access_decls; - access_decls = TREE_CHAIN (access_decls)) - handle_using_decl (TREE_VALUE (access_decls), t, method_vec, fields); - - if (vfield == NULL_TREE && has_virtual) - { - /* We build this decl with vtbl_ptr_type_node, which is a - `vtable_entry_type*'. It might seem more precise to use - `vtable_entry_type (*)[N]' where N is the number of firtual - functions. However, that would require the vtable pointer in - base classes to have a different type than the vtable pointer - in derived classes. We could make that happen, but that - still wouldn't solve all the problems. In particular, the - type-based alias analysis code would decide that assignments - to the base class vtable pointer can't alias assignments to - the derived class vtable pointer, since they have different - types. Thus, in an derived class destructor, where the base - class constructor was inlined, we could generate bad code for - setting up the vtable pointer. - - Therefore, we use one type for all vtable pointers. We still - use a type-correct type; it's just doesn't indicate the array - bounds. That's better than using `void*' or some such; it's - cleaner, and it let's the alias analysis code know that these - stores cannot alias stores to void*! */ - vfield = build_lang_field_decl (FIELD_DECL, get_vfield_name (t), - vtbl_ptr_type_node); - /* If you change any of the below, take a look at all the - other VFIELD_BASEs and VTABLE_BASEs in the code, and change - them too. */ - DECL_ASSEMBLER_NAME (vfield) = get_identifier (VFIELD_BASE); - CLASSTYPE_VFIELD (t) = vfield; - DECL_VIRTUAL_P (vfield) = 1; - DECL_ARTIFICIAL (vfield) = 1; - DECL_FIELD_CONTEXT (vfield) = t; - DECL_CLASS_CONTEXT (vfield) = t; - DECL_FCONTEXT (vfield) = t; - DECL_SAVED_INSNS (vfield) = NULL_RTX; - DECL_FIELD_SIZE (vfield) = 0; - DECL_ALIGN (vfield) = TYPE_ALIGN (ptr_type_node); -#if 0 - /* This is more efficient, but breaks binary compatibility, turn - it on sometime when we don't care. If we turn it on, we also - have to enable the code in dfs_init_vbase_pointers. */ - /* vfield is always first entry in structure. */ - TREE_CHAIN (vfield) = fields; - fields = vfield; -#else - if (last_x) - { - my_friendly_assert (TREE_CHAIN (last_x) == NULL_TREE, 175); - TREE_CHAIN (last_x) = vfield; - last_x = vfield; - } - else - fields = vfield; -#endif - empty = 0; - vfields = chainon (vfields, CLASSTYPE_AS_LIST (t)); - } - - /* Now DECL_INITIAL is null on all members except for zero-width bit-fields. - - C++: maybe we will support default field initialization some day... */ - - /* Delete all duplicate fields from the fields */ - delete_duplicate_fields (fields); - - /* Catch function/field name conflict. We don't need to do this for a - signature, since it can only contain the fields constructed in - append_signature_fields. */ - if (! IS_SIGNATURE (t)) - { - int n_methods = method_vec ? TREE_VEC_LENGTH (method_vec) : 0; - for (x = fields; x; x = TREE_CHAIN (x)) - { - tree name = DECL_NAME (x); - int i; - - if (TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x)) - continue; - - for (i = 2; i < n_methods && TREE_VEC_ELT (method_vec, i); ++i) - if (DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (method_vec, i))) - == name) - { - cp_error_at ("data member `%#D' conflicts with", x); - cp_error_at ("function member `%#D'", - OVL_CURRENT (TREE_VEC_ELT (method_vec, i))); - break; - } - } - } - - /* Now we have the nearly final fieldlist for the data fields. Record it, - then lay out the structure or union (including the fields). */ - - TYPE_FIELDS (t) = fields; - - if (n_baseclasses) - { - last_x = build_base_fields (t); - - /* If all our bases are empty, we can be empty too. */ - for (x = last_x; empty && x; x = TREE_CHAIN (x)) - if (DECL_SIZE (x) != integer_zero_node) - empty = 0; - } - if (empty) - { - /* C++: do not let empty structures exist. */ - tree decl = build_lang_field_decl - (FIELD_DECL, NULL_TREE, char_type_node); - TREE_CHAIN (decl) = fields; - TYPE_FIELDS (t) = decl; - } - if (n_baseclasses) - TYPE_FIELDS (t) = chainon (last_x, TYPE_FIELDS (t)); - - layout_type (t); - - /* Remember the size and alignment of the class before adding - the virtual bases. */ - if (empty && flag_new_abi) - CLASSTYPE_SIZE (t) = integer_zero_node; - else if (flag_new_abi && TYPE_HAS_COMPLEX_INIT_REF (t) - && TYPE_HAS_COMPLEX_ASSIGN_REF (t)) - CLASSTYPE_SIZE (t) = TYPE_BINFO_SIZE (t); - else - CLASSTYPE_SIZE (t) = TYPE_SIZE (t); - CLASSTYPE_ALIGN (t) = TYPE_ALIGN (t); - - finish_struct_anon (t); - - /* Set the TYPE_DECL for this type to contain the right - value for DECL_OFFSET, so that we can use it as part - of a COMPONENT_REF for multiple inheritance. */ - - layout_decl (TYPE_MAIN_DECL (t), 0); - - /* Now fix up any virtual base class types that we left lying - around. We must get these done before we try to lay out the - virtual function table. */ - pending_hard_virtuals = nreverse (pending_hard_virtuals); - - if (n_baseclasses) - /* layout_basetypes will remove the base subobject fields. */ - max_has_virtual = layout_basetypes (t, max_has_virtual); - else if (empty) - TYPE_FIELDS (t) = fields; - - my_friendly_assert (TYPE_FIELDS (t) == fields, 981117); - - /* Delete all zero-width bit-fields from the front of the fieldlist */ - while (fields && DECL_C_BIT_FIELD (fields) - && DECL_INITIAL (fields)) - fields = TREE_CHAIN (fields); - /* Delete all such fields from the rest of the fields. */ - for (x = fields; x;) - { - if (TREE_CHAIN (x) && DECL_C_BIT_FIELD (TREE_CHAIN (x)) - && DECL_INITIAL (TREE_CHAIN (x))) - TREE_CHAIN (x) = TREE_CHAIN (TREE_CHAIN (x)); - else - x = TREE_CHAIN (x); - } - TYPE_FIELDS (t) = fields; - - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - { - tree vbases; - - vbases = CLASSTYPE_VBASECLASSES (t); - CLASSTYPE_N_VBASECLASSES (t) = list_length (vbases); - - { - /* Now fixup overrides of all functions in vtables from all - direct or indirect virtual base classes. */ - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree basetype = BINFO_TYPE (base_binfo); - tree vbases; - - vbases = CLASSTYPE_VBASECLASSES (basetype); - while (vbases) - { - merge_overrides (binfo_member (BINFO_TYPE (vbases), - CLASSTYPE_VBASECLASSES (t)), - vbases, 1, t); - vbases = TREE_CHAIN (vbases); - } - } - } - } - - /* Set up the DECL_FIELD_BITPOS of the vfield if we need to, as we - might need to know it for setting up the offsets in the vtable - (or in thunks) below. */ - if (vfield != NULL_TREE - && DECL_FIELD_CONTEXT (vfield) != t) - { - tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); - tree offset = BINFO_OFFSET (binfo); - - vfield = copy_node (vfield); - copy_lang_decl (vfield); - - if (! integer_zerop (offset)) - offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); - DECL_FIELD_CONTEXT (vfield) = t; - DECL_CLASS_CONTEXT (vfield) = t; - DECL_FIELD_BITPOS (vfield) - = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); - CLASSTYPE_VFIELD (t) = vfield; - } - -#ifdef NOTQUITE - cp_warning ("Doing hard virtuals for %T...", t); -#endif - - if (has_virtual > max_has_virtual) - max_has_virtual = has_virtual; - if (max_has_virtual > 0) - TYPE_VIRTUAL_P (t) = 1; - - if (flag_rtti && TYPE_VIRTUAL_P (t) && !pending_hard_virtuals) - modify_all_vtables (t, NULL_TREE, NULL_TREE); - - while (pending_hard_virtuals) - { - modify_all_vtables (t, - TREE_PURPOSE (pending_hard_virtuals), - TREE_VALUE (pending_hard_virtuals)); - pending_hard_virtuals = TREE_CHAIN (pending_hard_virtuals); - } - - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - { - tree vbases; - /* Now fixup any virtual function entries from virtual bases - that have different deltas. This has to come after we do the - pending hard virtuals, as we might have a function that comes - from multiple virtual base instances that is only overridden - by a hard virtual above. */ - vbases = CLASSTYPE_VBASECLASSES (t); - while (vbases) - { - /* We might be able to shorten the amount of work we do by - only doing this for vtables that come from virtual bases - that have differing offsets, but don't want to miss any - entries. */ - fixup_vtable_deltas (vbases, 1, t); - vbases = TREE_CHAIN (vbases); - } - } - - /* Under our model of GC, every C++ class gets its own virtual - function table, at least virtually. */ - if (pending_virtuals) - { - pending_virtuals = nreverse (pending_virtuals); - /* We must enter these virtuals into the table. */ - if (first_vfn_base_index < 0) - { - /* The second slot is for the tdesc pointer when thunks are used. */ - if (flag_vtable_thunks) - pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); - - /* The first slot is for the rtti offset. */ - pending_virtuals = tree_cons (NULL_TREE, NULL_TREE, pending_virtuals); - - set_rtti_entry (pending_virtuals, - convert (ssizetype, integer_zero_node), t); - build_vtable (NULL_TREE, t); - } - else - { - /* Here we know enough to change the type of our virtual - function table, but we will wait until later this function. */ - - if (! BINFO_NEW_VTABLE_MARKED (TYPE_BINFO (t))) - build_vtable (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index), t); - } - - /* If this type has basetypes with constructors, then those - constructors might clobber the virtual function table. But - they don't if the derived class shares the exact vtable of the base - class. */ - - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; - } - else if (first_vfn_base_index >= 0) - { - tree binfo = TREE_VEC_ELT (TYPE_BINFO_BASETYPES (t), first_vfn_base_index); - /* This class contributes nothing new to the virtual function - table. However, it may have declared functions which - went into the virtual function table "inherited" from the - base class. If so, we grab a copy of those updated functions, - and pretend they are ours. */ - - /* See if we should steal the virtual info from base class. */ - if (TYPE_BINFO_VTABLE (t) == NULL_TREE) - TYPE_BINFO_VTABLE (t) = BINFO_VTABLE (binfo); - if (TYPE_BINFO_VIRTUALS (t) == NULL_TREE) - TYPE_BINFO_VIRTUALS (t) = BINFO_VIRTUALS (binfo); - if (TYPE_BINFO_VTABLE (t) != BINFO_VTABLE (binfo)) - CLASSTYPE_NEEDS_VIRTUAL_REINIT (t) = 1; - } - - if (max_has_virtual || first_vfn_base_index >= 0) - { - CLASSTYPE_VSIZE (t) = has_virtual; - if (first_vfn_base_index >= 0) - { - if (pending_virtuals) - TYPE_BINFO_VIRTUALS (t) = chainon (TYPE_BINFO_VIRTUALS (t), - pending_virtuals); - } - else if (has_virtual) - { - TYPE_BINFO_VIRTUALS (t) = pending_virtuals; - DECL_VIRTUAL_P (TYPE_BINFO_VTABLE (t)) = 1; - } - } - - /* Now lay out the virtual function table. */ - if (has_virtual) - { - /* Use size_int so values are memoized in common cases. */ - tree itype = build_index_type (size_int (has_virtual)); - tree atype = build_cplus_array_type (vtable_entry_type, itype); - - layout_type (atype); - - CLASSTYPE_VFIELD (t) = vfield; - - /* We may have to grow the vtable. */ - if (TREE_TYPE (TYPE_BINFO_VTABLE (t)) != atype) - { - TREE_TYPE (TYPE_BINFO_VTABLE (t)) = atype; - DECL_SIZE (TYPE_BINFO_VTABLE (t)) = 0; - layout_decl (TYPE_BINFO_VTABLE (t), 0); - /* At one time the vtable info was grabbed 2 words at a time. This - fails on sparc unless you have 8-byte alignment. (tiemann) */ - DECL_ALIGN (TYPE_BINFO_VTABLE (t)) - = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (TYPE_BINFO_VTABLE (t))); - } - } - else if (first_vfn_base_index >= 0) - CLASSTYPE_VFIELD (t) = vfield; - CLASSTYPE_VFIELDS (t) = vfields; - - finish_struct_bits (t, max_has_virtual); - - /* Complete the rtl for any static member objects of the type we're - working on. */ - for (x = fields; x; x = TREE_CHAIN (x)) - { - if (TREE_CODE (x) == VAR_DECL && TREE_STATIC (x) - && TREE_TYPE (x) == t) - { - DECL_MODE (x) = TYPE_MODE (t); - make_decl_rtl (x, NULL, 0); - } - } - - if (TYPE_HAS_CONSTRUCTOR (t)) - { - tree vfields = CLASSTYPE_VFIELDS (t); - - while (vfields) - { - /* Mark the fact that constructor for T - could affect anybody inheriting from T - who wants to initialize vtables for VFIELDS's type. */ - if (VF_DERIVED_VALUE (vfields)) - TREE_ADDRESSABLE (vfields) = 1; - vfields = TREE_CHAIN (vfields); - } - if (any_default_members != 0) - build_class_init_list (t); - } - else if (TYPE_NEEDS_CONSTRUCTING (t)) - build_class_init_list (t); - - /* Write out inline function definitions. */ - do_inline_function_hair (t, CLASSTYPE_INLINE_FRIENDS (t)); - CLASSTYPE_INLINE_FRIENDS (t) = 0; - - if (CLASSTYPE_VSIZE (t) != 0) - { -#if 0 - /* This is now done above. */ - if (DECL_FIELD_CONTEXT (vfield) != t) - { - tree binfo = get_binfo (DECL_FIELD_CONTEXT (vfield), t, 0); - tree offset = BINFO_OFFSET (binfo); - - vfield = copy_node (vfield); - copy_lang_decl (vfield); - - if (! integer_zerop (offset)) - offset = size_binop (MULT_EXPR, offset, size_int (BITS_PER_UNIT)); - DECL_FIELD_CONTEXT (vfield) = t; - DECL_CLASS_CONTEXT (vfield) = t; - DECL_FIELD_BITPOS (vfield) - = size_binop (PLUS_EXPR, offset, DECL_FIELD_BITPOS (vfield)); - CLASSTYPE_VFIELD (t) = vfield; - } -#endif - - /* In addition to this one, all the other vfields should be listed. */ - /* Before that can be done, we have to have FIELD_DECLs for them, and - a place to find them. */ - TYPE_NONCOPIED_PARTS (t) = build_tree_list (default_conversion (TYPE_BINFO_VTABLE (t)), vfield); - - if (warn_nonvdtor && TYPE_HAS_DESTRUCTOR (t) - && DECL_VINDEX (TREE_VEC_ELT (method_vec, 1)) == NULL_TREE) - cp_warning ("`%#T' has virtual functions but non-virtual destructor", - t); - } - - /* Make the rtl for any new vtables we have created, and unmark - the base types we marked. */ - finish_vtbls (TYPE_BINFO (t), 1, t); - hack_incomplete_structures (t); - -#if 0 - if (TYPE_NAME (t) && TYPE_IDENTIFIER (t)) - undo_template_name_overload (TYPE_IDENTIFIER (t), 1); -#endif - - resume_momentary (old); - - if (warn_overloaded_virtual) - warn_hidden (t); - -#if 0 - /* This has to be done after we have sorted out what to do with - the enclosing type. */ - if (write_symbols != DWARF_DEBUG) - { - /* Be smarter about nested classes here. If a type is nested, - only output it if we would output the enclosing type. */ - if (DECL_CLASS_SCOPE_P (TYPE_MAIN_DECL (t))) - DECL_IGNORED_P (TYPE_MAIN_DECL (t)) = TREE_ASM_WRITTEN (TYPE_MAIN_DECL (t)); - } -#endif - - if (write_symbols != DWARF_DEBUG && write_symbols != DWARF2_DEBUG) - { - /* If the type has methods, we want to think about cutting down - the amount of symbol table stuff we output. The value stored in - the TYPE_DECL's DECL_IGNORED_P slot is a first approximation. - For example, if a member function is seen and we decide to - write out that member function, then we can change the value - of the DECL_IGNORED_P slot, and the type will be output when - that member function's debug info is written out. - - We can't do this with DWARF, which does not support name - references between translation units. */ - if (CLASSTYPE_METHOD_VEC (t)) - { - /* Don't output full info about any type - which does not have its implementation defined here. */ - if (CLASSTYPE_INTERFACE_ONLY (t)) - TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; -#if 0 - /* XXX do something about this. */ - else if (CLASSTYPE_INTERFACE_UNKNOWN (t)) - /* Only a first approximation! */ - TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; -#endif - } - else if (CLASSTYPE_INTERFACE_ONLY (t)) - TYPE_DECL_SUPPRESS_DEBUG (TYPE_MAIN_DECL (t)) = 1; - } - - /* Finish debugging output for this type. */ - rest_of_type_compilation (t, toplevel_bindings_p ()); - - return t; -} - -/* In [basic.scope.class] we have: - - A name N used in a class S shall refer to the same declaration in - its context and when re-evaluated in the completed scope of S. - - This function checks this condition for X, which is a member of - T. */ - -static void -check_member_decl_is_same_in_complete_scope (t, x) - tree t; - tree x; -{ - /* A name N used in a class S shall refer to the same declaration in - its context and when re-evaluated in the completed scope of S. - - Enums, types and static vars have already been checked. */ - if (TREE_CODE (x) != USING_DECL - && TREE_CODE (x) != TYPE_DECL && !DECL_CLASS_TEMPLATE_P (x) - && TREE_CODE (x) != CONST_DECL && TREE_CODE (x) != VAR_DECL) - { - tree name = DECL_NAME (x); - tree icv; - - /* Don't get confused by access decls. */ - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - icv = IDENTIFIER_CLASS_VALUE (name); - else - icv = NULL_TREE; - - /* This should match pushdecl_class_level. */ - if (icv && icv != x - && flag_optional_diags - /* Don't complain about constructors. */ - && name != constructor_name (current_class_type) - /* Or inherited names. */ - && id_in_current_class (name) - /* Or shadowed tags. */ - && !(TREE_CODE (icv) == TYPE_DECL && DECL_CONTEXT (icv) == t)) - { - cp_pedwarn_at ("declaration of identifier `%D' as `%+#D'", - name, x); - cp_pedwarn_at ("conflicts with other use in class as `%#D'", - icv); - } - } -} - -/* When T was built up, the member declarations were added in reverse - order. Rearrange them to declaration order. */ - -void -unreverse_member_declarations (t) - tree t; -{ - tree next; - tree prev; - tree x; - - /* The TYPE_FIELDS, TYPE_METHODS, and CLASSTYPE_TAGS are all in - reverse order. Put them in declaration order now. */ - TYPE_METHODS (t) = nreverse (TYPE_METHODS (t)); - CLASSTYPE_TAGS (t) = nreverse (CLASSTYPE_TAGS (t)); - - /* Actually, for the TYPE_FIELDS, only the non TYPE_DECLs are in - reverse order, so we can't just use nreverse. */ - prev = NULL_TREE; - for (x = TYPE_FIELDS (t); - x && TREE_CODE (x) != TYPE_DECL; - x = next) - { - next = TREE_CHAIN (x); - TREE_CHAIN (x) = prev; - prev = x; - } - if (prev) - { - TREE_CHAIN (TYPE_FIELDS (t)) = x; - if (prev) - TYPE_FIELDS (t) = prev; - } -} - -tree -finish_struct (t, attributes, warn_anon) - tree t, attributes; - int warn_anon; -{ - tree name = TYPE_NAME (t); - tree x; - - if (TREE_CODE (name) == TYPE_DECL) - { - extern int lineno; - - DECL_SOURCE_FILE (name) = input_filename; - /* For TYPE_DECL that are not typedefs (those marked with a line - number of zero, we don't want to mark them as real typedefs. - If this fails one needs to make sure real typedefs have a - previous line number, even if it is wrong, that way the below - will fill in the right line number. (mrs) */ - if (DECL_SOURCE_LINE (name)) - DECL_SOURCE_LINE (name) = lineno; - name = DECL_NAME (name); - } - - /* Append the fields we need for constructing signature tables. */ - if (IS_SIGNATURE (t)) - append_signature_fields (t); - - /* Now that we've got all the field declarations, reverse everything - as necessary. */ - unreverse_member_declarations (t); - - if (flag_optional_diags) - { - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) - check_member_decl_is_same_in_complete_scope (t, x); - for (x = TYPE_FIELDS (t); x; x = TREE_CHAIN (x)) - check_member_decl_is_same_in_complete_scope (t, x); - } - - /* Mark all the tags in the class as class-local. */ - for (x = CLASSTYPE_TAGS (t); x; x = TREE_CHAIN (x)) - TREE_NONLOCAL_FLAG (TREE_VALUE (x)) = 0; - - cplus_decl_attributes (t, attributes, NULL_TREE); - - if (processing_template_decl) - { - tree d = getdecls (); - for (; d; d = TREE_CHAIN (d)) - { - /* If this is the decl for the class or one of the template - parms, we've seen all the injected decls. */ - if ((TREE_CODE (d) == TYPE_DECL - && (TREE_TYPE (d) == t - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_TYPE (d)) == TEMPLATE_TEMPLATE_PARM)) - || TREE_CODE (d) == CONST_DECL) - break; - /* Don't inject cache decls. */ - else if (IDENTIFIER_TEMPLATE (DECL_NAME (d))) - continue; - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t)) - = tree_cons (NULL_TREE, d, - DECL_TEMPLATE_INJECT (CLASSTYPE_TI_TEMPLATE (t))); - } - finish_struct_methods (t); - TYPE_SIZE (t) = integer_zero_node; - } - else - t = finish_struct_1 (t, warn_anon); - - TYPE_BEING_DEFINED (t) = 0; - if (current_class_type) - popclass (0); - else - error ("trying to finish struct, but kicked out due to previous parse errors."); - - return t; -} - -/* Return the dynamic type of INSTANCE, if known. - Used to determine whether the virtual function table is needed - or not. - - *NONNULL is set iff INSTANCE can be known to be nonnull, regardless - of our knowledge of its type. */ - -tree -fixed_type_or_null (instance, nonnull) - tree instance; - int *nonnull; -{ - switch (TREE_CODE (instance)) - { - case INDIRECT_REF: - /* Check that we are not going through a cast of some sort. */ - if (TREE_TYPE (instance) - == TREE_TYPE (TREE_TYPE (TREE_OPERAND (instance, 0)))) - instance = TREE_OPERAND (instance, 0); - /* fall through... */ - case CALL_EXPR: - /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) - { - if (nonnull) - *nonnull = 1; - return TREE_TYPE (instance); - } - return NULL_TREE; - - case SAVE_EXPR: - /* This is a call to a constructor, hence it's never zero. */ - if (TREE_HAS_CONSTRUCTOR (instance)) - { - if (nonnull) - *nonnull = 1; - return TREE_TYPE (instance); - } - return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); - - case RTL_EXPR: - return NULL_TREE; - - case PLUS_EXPR: - case MINUS_EXPR: - if (TREE_CODE (TREE_OPERAND (instance, 1)) == INTEGER_CST) - /* Propagate nonnull. */ - fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); - if (TREE_CODE (TREE_OPERAND (instance, 0)) == ADDR_EXPR) - return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); - return NULL_TREE; - - case NOP_EXPR: - case CONVERT_EXPR: - return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); - - case ADDR_EXPR: - if (nonnull) - *nonnull = 1; - return fixed_type_or_null (TREE_OPERAND (instance, 0), nonnull); - - case COMPONENT_REF: - return fixed_type_or_null (TREE_OPERAND (instance, 1), nonnull); - - case VAR_DECL: - case FIELD_DECL: - if (TREE_CODE (TREE_TYPE (instance)) == ARRAY_TYPE - && IS_AGGR_TYPE (TREE_TYPE (TREE_TYPE (instance)))) - { - if (nonnull) - *nonnull = 1; - return TREE_TYPE (TREE_TYPE (instance)); - } - /* fall through... */ - case TARGET_EXPR: - case PARM_DECL: - if (IS_AGGR_TYPE (TREE_TYPE (instance))) - { - if (nonnull) - *nonnull = 1; - return TREE_TYPE (instance); - } - else if (nonnull) - { - if (instance == current_class_ptr - && flag_this_is_variable <= 0) - { - /* Normally, 'this' must be non-null. */ - if (flag_this_is_variable == 0) - *nonnull = 1; - - /* <0 means we're in a constructor and we know our type. */ - if (flag_this_is_variable < 0) - return TREE_TYPE (TREE_TYPE (instance)); - } - else if (TREE_CODE (TREE_TYPE (instance)) == REFERENCE_TYPE) - /* Reference variables should be references to objects. */ - *nonnull = 1; - } - return NULL_TREE; - - default: - return NULL_TREE; - } -} - -/* Return non-zero if the dynamic type of INSTANCE is known, and equivalent - to the static type. We also handle the case where INSTANCE is really - a pointer. - - Used to determine whether the virtual function table is needed - or not. - - *NONNULL is set iff INSTANCE can be known to be nonnull, regardless - of our knowledge of its type. */ - -int -resolves_to_fixed_type_p (instance, nonnull) - tree instance; - int *nonnull; -{ - tree t = TREE_TYPE (instance); - tree fixed = fixed_type_or_null (instance, nonnull); - if (fixed == NULL_TREE) - return 0; - if (POINTER_TYPE_P (t)) - t = TREE_TYPE (t); - return same_type_p (TYPE_MAIN_VARIANT (t), TYPE_MAIN_VARIANT (fixed)); -} - - -void -init_class_processing () -{ - current_class_depth = 0; - current_class_stack_size = 10; - current_class_stack - = (class_stack_node_t) xmalloc (current_class_stack_size - * sizeof (struct class_stack_node)); - - current_lang_stacksize = 10; - current_lang_base = (tree *)xmalloc(current_lang_stacksize * sizeof (tree)); - current_lang_stack = current_lang_base; - - access_default_node = build_int_2 (0, 0); - access_public_node = build_int_2 (1, 0); - access_protected_node = build_int_2 (2, 0); - access_private_node = build_int_2 (3, 0); - access_default_virtual_node = build_int_2 (4, 0); - access_public_virtual_node = build_int_2 (5, 0); - access_protected_virtual_node = build_int_2 (6, 0); - access_private_virtual_node = build_int_2 (7, 0); - - /* Keep these values lying around. */ - base_layout_decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, error_mark_node); - TREE_TYPE (base_layout_decl) = make_node (RECORD_TYPE); - - gcc_obstack_init (&class_obstack); -} - -/* Set current scope to NAME. CODE tells us if this is a - STRUCT, UNION, or ENUM environment. - - NAME may end up being NULL_TREE if this is an anonymous or - late-bound struct (as in "struct { ... } foo;") */ - -/* Set global variables CURRENT_CLASS_NAME and CURRENT_CLASS_TYPE to - appropriate values, found by looking up the type definition of - NAME (as a CODE). - - If MODIFY is 1, we set IDENTIFIER_CLASS_VALUE's of names - which can be seen locally to the class. They are shadowed by - any subsequent local declaration (including parameter names). - - If MODIFY is 2, we set IDENTIFIER_CLASS_VALUE's of names - which have static meaning (i.e., static members, static - member functions, enum declarations, etc). - - If MODIFY is 3, we set IDENTIFIER_CLASS_VALUE of names - which can be seen locally to the class (as in 1), but - know that we are doing this for declaration purposes - (i.e. friend foo::bar (int)). - - So that we may avoid calls to lookup_name, we cache the _TYPE - nodes of local TYPE_DECLs in the TREE_TYPE field of the name. - - For multiple inheritance, we perform a two-pass depth-first search - of the type lattice. The first pass performs a pre-order search, - marking types after the type has had its fields installed in - the appropriate IDENTIFIER_CLASS_VALUE slot. The second pass merely - unmarks the marked types. If a field or member function name - appears in an ambiguous way, the IDENTIFIER_CLASS_VALUE of - that name becomes `error_mark_node'. */ - -void -pushclass (type, modify) - tree type; - int modify; -{ - type = TYPE_MAIN_VARIANT (type); - - /* Make sure there is enough room for the new entry on the stack. */ - if (current_class_depth + 1 >= current_class_stack_size) - { - current_class_stack_size *= 2; - current_class_stack - = (class_stack_node_t) xrealloc (current_class_stack, - current_class_stack_size - * sizeof (struct class_stack_node)); - } - - /* Insert a new entry on the class stack. */ - current_class_stack[current_class_depth].name = current_class_name; - current_class_stack[current_class_depth].type = current_class_type; - current_class_stack[current_class_depth].access = current_access_specifier; - current_class_depth++; - - /* Now set up the new type. */ - current_class_name = TYPE_NAME (type); - if (TREE_CODE (current_class_name) == TYPE_DECL) - current_class_name = DECL_NAME (current_class_name); - current_class_type = type; - - /* By default, things in classes are private, while things in - structures or unions are public. */ - current_access_specifier = (CLASSTYPE_DECLARED_CLASS (type) - ? access_private_node - : access_public_node); - - if (previous_class_type != NULL_TREE - && (type != previous_class_type || TYPE_SIZE (previous_class_type) == NULL_TREE) - && current_class_depth == 1) - { - /* Forcibly remove any old class remnants. */ - popclass (-1); - previous_class_type = NULL_TREE; - - /* Now, free the obstack on which we cached all the values. */ - obstack_free (&class_cache_obstack, class_cache_firstobj); - class_cache_firstobj - = (char*) obstack_finish (&class_cache_obstack); - } - - pushlevel_class (); - -#if 0 - if (CLASSTYPE_TEMPLATE_INFO (type)) - overload_template_name (type); -#endif - - if (modify) - { - tree tags; - tree this_fndecl = current_function_decl; - - if (current_function_decl - && DECL_CONTEXT (current_function_decl) - && TREE_CODE (DECL_CONTEXT (current_function_decl)) == FUNCTION_DECL) - current_function_decl = DECL_CONTEXT (current_function_decl); - else - current_function_decl = NULL_TREE; - - if (type != previous_class_type || current_class_depth > 1) - { -#ifdef MI_MATRIX - build_mi_matrix (type); - push_class_decls (type); - free_mi_matrix (); -#else - push_class_decls (type); -#endif - } - else - { - tree item; - - /* We are re-entering the same class we just left, so we - don't have to search the whole inheritance matrix to find - all the decls to bind again. Instead, we install the - cached class_shadowed list, and walk through it binding - names and setting up IDENTIFIER_TYPE_VALUEs. */ - set_class_shadows (previous_class_values); - for (item = previous_class_values; item; item = TREE_CHAIN (item)) - { - tree id = TREE_PURPOSE (item); - tree decl = TREE_TYPE (item); - - push_class_binding (id, decl); - if (TREE_CODE (decl) == TYPE_DECL) - set_identifier_type_value (id, TREE_TYPE (decl)); - } - unuse_fields (type); - } - - for (tags = CLASSTYPE_TAGS (type); tags; tags = TREE_CHAIN (tags)) - { - tree tag_type = TREE_VALUE (tags); - - TREE_NONLOCAL_FLAG (tag_type) = 1; - if (! TREE_PURPOSE (tags)) - continue; - if (! (IS_AGGR_TYPE_CODE (TREE_CODE (tag_type)) - && CLASSTYPE_IS_TEMPLATE (tag_type))) - pushtag (TREE_PURPOSE (tags), tag_type, 0); - } - - current_function_decl = this_fndecl; - } -} - -/* Get out of the current class scope. If we were in a class scope - previously, that is the one popped to. The flag MODIFY tells whether - the current scope declarations needs to be modified as a result of - popping to the previous scope. 0 is used for class definitions. */ - -void -popclass (modify) - int modify; -{ - if (modify < 0) - { - /* Back this old class out completely. */ - tree tags = CLASSTYPE_TAGS (previous_class_type); - tree t; - - /* This code can be seen as a cache miss. When we've cached a - class' scope's bindings and we can't use them, we need to reset - them. This is it! */ - for (t = previous_class_values; t; t = TREE_CHAIN (t)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (t)) = NULL_TREE; - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } - - return; - } - - if (modify) - { - /* Just remove from this class what didn't make - it into IDENTIFIER_CLASS_VALUE. */ - tree tags = CLASSTYPE_TAGS (current_class_type); - - while (tags) - { - TREE_NONLOCAL_FLAG (TREE_VALUE (tags)) = 0; - tags = TREE_CHAIN (tags); - } - } - - /* Force clearing of IDENTIFIER_CLASS_VALUEs after a class definition, - since not all class decls make it there currently. */ - poplevel_class (! modify); - - /* Since poplevel_class does the popping of class decls nowadays, - this really only frees the obstack used for these decls. - That's why it had to be moved down here. */ - if (modify) - pop_class_decls (); - - current_class_depth--; - current_class_name = current_class_stack[current_class_depth].name; - current_class_type = current_class_stack[current_class_depth].type; - current_access_specifier = current_class_stack[current_class_depth].access; -} - -/* Returns 1 if current_class_type is either T or a nested type of T. */ - -int -currently_open_class (t) - tree t; -{ - int i; - if (t == current_class_type) - return 1; - for (i = 0; i < current_class_depth; ++i) - if (current_class_stack [i].type == t) - return 1; - return 0; -} - -/* When entering a class scope, all enclosing class scopes' names with - static meaning (static variables, static functions, types and enumerators) - have to be visible. This recursive function calls pushclass for all - enclosing class contexts until global or a local scope is reached. - TYPE is the enclosed class and MODIFY is equivalent with the pushclass - formal of the same name. */ - -void -push_nested_class (type, modify) - tree type; - int modify; -{ - tree context; - - my_friendly_assert (!type || TREE_CODE (type) != NAMESPACE_DECL, 980711); - - if (type == NULL_TREE || type == error_mark_node || ! IS_AGGR_TYPE (type) - || TREE_CODE (type) == TEMPLATE_TYPE_PARM - || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) - return; - - context = DECL_CONTEXT (TYPE_MAIN_DECL (type)); - - if (context && TREE_CODE (context) == RECORD_TYPE) - push_nested_class (context, 2); - pushclass (type, modify); -} - -/* Undoes a push_nested_class call. MODIFY is passed on to popclass. */ - -void -pop_nested_class (modify) - int modify; -{ - tree context = DECL_CONTEXT (TYPE_MAIN_DECL (current_class_type)); - - popclass (modify); - if (context && TREE_CODE (context) == RECORD_TYPE) - pop_nested_class (modify); -} - -/* Set global variables CURRENT_LANG_NAME to appropriate value - so that behavior of name-mangling machinery is correct. */ - -void -push_lang_context (name) - tree name; -{ - *current_lang_stack++ = current_lang_name; - if (current_lang_stack >= current_lang_base + current_lang_stacksize) - { - current_lang_base - = (tree *)xrealloc (current_lang_base, - sizeof (tree) * (current_lang_stacksize + 10)); - current_lang_stack = current_lang_base + current_lang_stacksize; - current_lang_stacksize += 10; - } - - if (name == lang_name_cplusplus || name == lang_name_java) - { - strict_prototype = strict_prototypes_lang_cplusplus; - current_lang_name = name; - } - else if (name == lang_name_c) - { - strict_prototype = strict_prototypes_lang_c; - current_lang_name = name; - } - else - error ("language string `\"%s\"' not recognized", IDENTIFIER_POINTER (name)); -} - -/* Get out of the current language scope. */ - -void -pop_lang_context () -{ - current_lang_name = *--current_lang_stack; - if (current_lang_name == lang_name_cplusplus - || current_lang_name == lang_name_java) - strict_prototype = strict_prototypes_lang_cplusplus; - else if (current_lang_name == lang_name_c) - strict_prototype = strict_prototypes_lang_c; -} - -/* Type instantiation routines. */ - -/* Given an OVERLOAD and a TARGET_TYPE, return the function that - matches the TARGET_TYPE. If there is no satisfactory match, return - error_mark_node, and issue an error message if COMPLAIN is - non-zero. If TEMPLATE_ONLY, the name of the overloaded function - was a template-id, and EXPLICIT_TARGS are the explicitly provided - template arguments. */ - -static tree -resolve_address_of_overloaded_function (target_type, - overload, - complain, - template_only, - explicit_targs) - tree target_type; - tree overload; - int complain; - int template_only; - tree explicit_targs; -{ - /* Here's what the standard says: - - [over.over] - - If the name is a function template, template argument deduction - is done, and if the argument deduction succeeds, the deduced - arguments are used to generate a single template function, which - is added to the set of overloaded functions considered. - - Non-member functions and static member functions match targets of - type "pointer-to-function" or "reference-to-function." Nonstatic - member functions match targets of type "pointer-to-member - function;" the function type of the pointer to member is used to - select the member function from the set of overloaded member - functions. If a nonstatic member function is selected, the - reference to the overloaded function name is required to have the - form of a pointer to member as described in 5.3.1. - - If more than one function is selected, any template functions in - the set are eliminated if the set also contains a non-template - function, and any given template function is eliminated if the - set contains a second template function that is more specialized - than the first according to the partial ordering rules 14.5.5.2. - After such eliminations, if any, there shall remain exactly one - selected function. */ - - int is_ptrmem = 0; - int is_reference = 0; - /* We store the matches in a TREE_LIST rooted here. The functions - are the TREE_PURPOSE, not the TREE_VALUE, in this list, for easy - interoperability with most_specialized_instantiation. */ - tree matches = NULL_TREE; - tree fn; - - /* By the time we get here, we should be seeing only real - pointer-to-member types, not the internal POINTER_TYPE to - METHOD_TYPE representation. */ - my_friendly_assert (!(TREE_CODE (target_type) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (target_type)) - == METHOD_TYPE)), 0); - - /* Check that the TARGET_TYPE is reasonable. */ - if (TYPE_PTRFN_P (target_type)) - /* This is OK. */ - ; - else if (TYPE_PTRMEMFUNC_P (target_type)) - /* This is OK, too. */ - is_ptrmem = 1; - else if (TREE_CODE (target_type) == FUNCTION_TYPE) - { - /* This is OK, too. This comes from a conversion to reference - type. */ - target_type = build_reference_type (target_type); - is_reference = 1; - } - else - { - if (complain) - cp_error("cannot resolve overloaded function `%D' based on conversion to type `%T'", - DECL_NAME (OVL_FUNCTION (overload)), target_type); - return error_mark_node; - } - - /* If we can find a non-template function that matches, we can just - use it. There's no point in generating template instantiations - if we're just going to throw them out anyhow. But, of course, we - can only do this when we don't *need* a template function. */ - if (!template_only) - { - tree fns; - - for (fns = overload; fns; fns = OVL_CHAIN (fns)) - { - tree fn = OVL_FUNCTION (fns); - tree fntype; - - if (TREE_CODE (fn) == TEMPLATE_DECL) - /* We're not looking for templates just yet. */ - continue; - - if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) - != is_ptrmem) - /* We're looking for a non-static member, and this isn't - one, or vice versa. */ - continue; - - /* See if there's a match. */ - fntype = TREE_TYPE (fn); - if (is_ptrmem) - fntype = build_ptrmemfunc_type (build_pointer_type (fntype)); - else if (!is_reference) - fntype = build_pointer_type (fntype); - - if (can_convert_arg (target_type, fntype, fn)) - matches = scratch_tree_cons (fn, NULL_TREE, matches); - } - } - - /* Now, if we've already got a match (or matches), there's no need - to proceed to the template functions. But, if we don't have a - match we need to look at them, too. */ - if (!matches) - { - tree target_fn_type; - tree target_arg_types; - tree fns; - - if (is_ptrmem) - { - target_fn_type - = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (target_type)); - target_arg_types = TREE_CHAIN (TYPE_ARG_TYPES (target_fn_type)); - } - else - { - target_fn_type = TREE_TYPE (target_type); - target_arg_types = TYPE_ARG_TYPES (target_fn_type); - } - - for (fns = overload; fns; fns = OVL_CHAIN (fns)) - { - tree fn = OVL_FUNCTION (fns); - tree fn_arg_types; - tree instantiation; - tree instantiation_type; - tree targs; - - if (TREE_CODE (fn) != TEMPLATE_DECL) - /* We're only looking for templates. */ - continue; - - if ((TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE) - != is_ptrmem) - /* We're looking for a non-static member, and this isn't - one, or vice versa. */ - continue; - - /* We don't use the `this' argument to do argument deduction - since that would prevent us from converting a base class - pointer-to-member to a derived class pointer-to-member. */ - fn_arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); - if (is_ptrmem) - fn_arg_types = TREE_CHAIN (fn_arg_types); - - /* Try to do argument deduction. */ - targs = make_scratch_vec (DECL_NTPARMS (fn)); - if (type_unification (DECL_INNERMOST_TEMPLATE_PARMS (fn), - targs, - fn_arg_types, - target_arg_types, - explicit_targs, - DEDUCE_EXACT, - /*allow_incomplete=*/1) != 0) - /* Argument deduction failed. */ - continue; - - /* Instantiate the template. */ - instantiation = instantiate_template (fn, targs); - if (instantiation == error_mark_node) - /* Instantiation failed. */ - continue; - - /* See if there's a match. */ - instantiation_type = TREE_TYPE (instantiation); - if (is_ptrmem) - instantiation_type = - build_ptrmemfunc_type (build_pointer_type (instantiation_type)); - else if (!is_reference) - instantiation_type = build_pointer_type (instantiation_type); - if (can_convert_arg (target_type, instantiation_type, instantiation)) - matches = scratch_tree_cons (instantiation, fn, matches); - } - - /* Now, remove all but the most specialized of the matches. */ - if (matches) - { - tree match = most_specialized_instantiation (matches, - explicit_targs); - - if (match != error_mark_node) - matches = scratch_tree_cons (match, NULL_TREE, NULL_TREE); - } - } - - /* Now we should have exactly one function in MATCHES. */ - if (matches == NULL_TREE) - { - /* There were *no* matches. */ - if (complain) - { - cp_error ("no matches converting function `%D' to type `%#T'", - DECL_NAME (OVL_FUNCTION (overload)), - target_type); - - /* print_candidates expects a chain with the functions in - TREE_VALUE slots, so we cons one up here (we're losing anyway, - so why be clever?). */ - for (; overload; overload = OVL_NEXT (overload)) - matches = scratch_tree_cons (NULL_TREE, OVL_CURRENT (overload), - matches); - - print_candidates (matches); - } - return error_mark_node; - } - else if (TREE_CHAIN (matches)) - { - /* There were too many matches. */ - - if (complain) - { - tree match; - - cp_error ("converting overloaded function `%D' to type `%#T' is ambiguous", - DECL_NAME (OVL_FUNCTION (overload)), - target_type); - - /* Since print_candidates expects the functions in the - TREE_VALUE slot, we flip them here. */ - for (match = matches; match; match = TREE_CHAIN (match)) - TREE_VALUE (match) = TREE_PURPOSE (match); - - print_candidates (matches); - } - - return error_mark_node; - } - - /* Good, exactly one match. Now, convert it to the correct type. */ - fn = TREE_PURPOSE (matches); - - mark_used (fn); - - if (TYPE_PTRFN_P (target_type) || TYPE_PTRMEMFUNC_P (target_type)) - return build_unary_op (ADDR_EXPR, fn, 0); - else - { - /* The target must be a REFERENCE_TYPE. Above, build_unary_op - will mark the function as addressed, but here we must do it - explicitly. */ - mark_addressable (fn); - - return fn; - } -} - -/* This function will instantiate the type of the expression given in - RHS to match the type of LHSTYPE. If errors exist, then return - error_mark_node. We only complain is COMPLAIN is set. If we are - not complaining, never modify rhs, as overload resolution wants to - try many possible instantiations, in hopes that at least one will - work. - - For non-recursive calls, LHSTYPE should be a function, pointer to - function, or a pointer to member function. */ - -tree -instantiate_type (lhstype, rhs, complain) - tree lhstype, rhs; - int complain; -{ - if (TREE_CODE (lhstype) == UNKNOWN_TYPE) - { - if (complain) - error ("not enough type information"); - return error_mark_node; - } - - if (TREE_TYPE (rhs) != NULL_TREE && ! (type_unknown_p (rhs))) - { - if (same_type_p (lhstype, TREE_TYPE (rhs))) - return rhs; - if (complain) - cp_error ("argument of type `%T' does not match `%T'", - TREE_TYPE (rhs), lhstype); - return error_mark_node; - } - - /* We don't overwrite rhs if it is an overloaded function. - Copying it would destroy the tree link. */ - if (TREE_CODE (rhs) != OVERLOAD) - rhs = copy_node (rhs); - - /* This should really only be used when attempting to distinguish - what sort of a pointer to function we have. For now, any - arithmetic operation which is not supported on pointers - is rejected as an error. */ - - switch (TREE_CODE (rhs)) - { - case TYPE_EXPR: - case CONVERT_EXPR: - case SAVE_EXPR: - case CONSTRUCTOR: - case BUFFER_REF: - my_friendly_abort (177); - return error_mark_node; - - case INDIRECT_REF: - case ARRAY_REF: - { - tree new_rhs; - - new_rhs = instantiate_type (build_pointer_type (lhstype), - TREE_OPERAND (rhs, 0), complain); - if (new_rhs == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - TREE_OPERAND (rhs, 0) = new_rhs; - return rhs; - } - - case NOP_EXPR: - rhs = copy_node (TREE_OPERAND (rhs, 0)); - TREE_TYPE (rhs) = unknown_type_node; - return instantiate_type (lhstype, rhs, complain); - - case COMPONENT_REF: - { - tree field = TREE_OPERAND (rhs, 1); - tree r; - - my_friendly_assert (TREE_CODE (field) == TREE_LIST, 0); - - r = instantiate_type (lhstype, field, complain); - - if (r != error_mark_node && TYPE_PTRMEMFUNC_P (lhstype)) - { - if (complain) - { - tree t = TYPE_PTRMEMFUNC_OBJECT_TYPE (lhstype); - tree fn = TREE_VALUE (field); - if (TREE_CODE (fn) == OVERLOAD) - fn = OVL_FUNCTION (fn); - if (TREE_CODE (fn) == FUNCTION_DECL) - { - cp_error ("object-dependent reference `%E' can only be used in a call", - DECL_NAME (fn)); - cp_error (" to form a pointer to member function, say `&%T::%E'", - t, DECL_NAME (fn)); - } - else - cp_error ("object-dependent reference can only be used in a call"); - } - return error_mark_node; - } - - return r; - } - - case OFFSET_REF: - /* This can happen if we are forming a pointer-to-member for a - member template. */ - rhs = TREE_OPERAND (rhs, 1); - my_friendly_assert (TREE_CODE (rhs) == TEMPLATE_ID_EXPR, 0); - - /* Fall through. */ - - case TEMPLATE_ID_EXPR: - return - resolve_address_of_overloaded_function (lhstype, - TREE_OPERAND (rhs, 0), - complain, - /*template_only=*/1, - TREE_OPERAND (rhs, 1)); - - case OVERLOAD: - return - resolve_address_of_overloaded_function (lhstype, - rhs, - complain, - /*template_only=*/0, - /*explicit_targs=*/NULL_TREE); - - case TREE_LIST: - { - if (TREE_PURPOSE (rhs) == error_mark_node) - { - /* Make sure we don't drop the non-local flag, as the old code - would rely on it. */ - int nl = TREE_NONLOCAL_FLAG (rhs); - /* We don't need the type of this node. */ - rhs = TREE_VALUE (rhs); - my_friendly_assert (TREE_NONLOCAL_FLAG (rhs) == nl, 980331); - } - - /* Now we should have a baselink. */ - my_friendly_assert (TREE_CODE (TREE_PURPOSE (rhs)) == TREE_VEC, - 980331); - my_friendly_assert (TREE_CHAIN (rhs) == NULL_TREE, 181); - my_friendly_assert (TREE_CODE (TREE_VALUE (rhs)) == FUNCTION_DECL - || TREE_CODE (TREE_VALUE (rhs)) == OVERLOAD, - 182); - - return instantiate_type (lhstype, TREE_VALUE (rhs), complain); - } - - case CALL_EXPR: - /* This is too hard for now. */ - my_friendly_abort (183); - return error_mark_node; - - case PLUS_EXPR: - case MINUS_EXPR: - case COMPOUND_EXPR: - TREE_OPERAND (rhs, 0) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - if (TREE_OPERAND (rhs, 0) == error_mark_node) - return error_mark_node; - TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case FLOOR_DIV_EXPR: - case CEIL_DIV_EXPR: - case ROUND_DIV_EXPR: - case RDIV_EXPR: - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - case CEIL_MOD_EXPR: - case ROUND_MOD_EXPR: - case FIX_ROUND_EXPR: - case FIX_FLOOR_EXPR: - case FIX_CEIL_EXPR: - case FIX_TRUNC_EXPR: - case FLOAT_EXPR: - case NEGATE_EXPR: - case ABS_EXPR: - case MAX_EXPR: - case MIN_EXPR: - case FFS_EXPR: - - case BIT_AND_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case LROTATE_EXPR: - case RROTATE_EXPR: - - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - if (complain) - error ("invalid operation on uninstantiated type"); - return error_mark_node; - - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_NOT_EXPR: - if (complain) - error ("not enough type information"); - return error_mark_node; - - case COND_EXPR: - if (type_unknown_p (TREE_OPERAND (rhs, 0))) - { - if (complain) - error ("not enough type information"); - return error_mark_node; - } - TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - TREE_OPERAND (rhs, 2) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 2), complain); - if (TREE_OPERAND (rhs, 2) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case MODIFY_EXPR: - TREE_OPERAND (rhs, 1) - = instantiate_type (lhstype, TREE_OPERAND (rhs, 1), complain); - if (TREE_OPERAND (rhs, 1) == error_mark_node) - return error_mark_node; - - TREE_TYPE (rhs) = lhstype; - return rhs; - - case ADDR_EXPR: - return instantiate_type (lhstype, TREE_OPERAND (rhs, 0), complain); - - case ENTRY_VALUE_EXPR: - my_friendly_abort (184); - return error_mark_node; - - case ERROR_MARK: - return error_mark_node; - - default: - my_friendly_abort (185); - return error_mark_node; - } -} - -/* Return the name of the virtual function pointer field - (as an IDENTIFIER_NODE) for the given TYPE. Note that - this may have to look back through base types to find the - ultimate field name. (For single inheritance, these could - all be the same name. Who knows for multiple inheritance). */ - -static tree -get_vfield_name (type) - tree type; -{ - tree binfo = TYPE_BINFO (type); - char *buf; - - while (BINFO_BASETYPES (binfo) - && TYPE_VIRTUAL_P (BINFO_TYPE (BINFO_BASETYPE (binfo, 0))) - && ! TREE_VIA_VIRTUAL (BINFO_BASETYPE (binfo, 0))) - binfo = BINFO_BASETYPE (binfo, 0); - - type = BINFO_TYPE (binfo); - buf = (char *) alloca (sizeof (VFIELD_NAME_FORMAT) - + TYPE_NAME_LENGTH (type) + 2); - sprintf (buf, VFIELD_NAME_FORMAT, TYPE_NAME_STRING (type)); - return get_identifier (buf); -} - -void -print_class_statistics () -{ -#ifdef GATHER_STATISTICS - fprintf (stderr, "convert_harshness = %d\n", n_convert_harshness); - fprintf (stderr, "compute_conversion_costs = %d\n", n_compute_conversion_costs); - fprintf (stderr, "build_method_call = %d (inner = %d)\n", - n_build_method_call, n_inner_fields_searched); - if (n_vtables) - { - fprintf (stderr, "vtables = %d; vtable searches = %d\n", - n_vtables, n_vtable_searches); - fprintf (stderr, "vtable entries = %d; vtable elems = %d\n", - n_vtable_entries, n_vtable_elems); - } -#endif -} - -/* Push an obstack which is sufficiently long-lived to hold such class - decls that may be cached in the previous_class_values list. The - effect is undone by pop_obstacks. */ - -void -maybe_push_cache_obstack () -{ - static int cache_obstack_initialized; - - if (!cache_obstack_initialized) - { - gcc_obstack_init (&class_cache_obstack); - class_cache_firstobj - = (char*) obstack_finish (&class_cache_obstack); - cache_obstack_initialized = 1; - } - - push_obstacks_nochange (); - current_obstack = &class_cache_obstack; -} - -/* Build a dummy reference to ourselves so Derived::Base (and A::A) works, - according to [class]: - The class-name is also inserted - into the scope of the class itself. For purposes of access checking, - the inserted class name is treated as if it were a public member name. */ - -tree -build_self_reference () -{ - tree name = constructor_name (current_class_type); - tree value = build_lang_decl (TYPE_DECL, name, current_class_type); - DECL_NONLOCAL (value) = 1; - DECL_CONTEXT (value) = current_class_type; - DECL_CLASS_CONTEXT (value) = current_class_type; - DECL_ARTIFICIAL (value) = 1; - - pushdecl_class_level (value); - return value; -} - -/* Returns 1 if TYPE contains only padding bytes. */ - -int -is_empty_class (type) - tree type; -{ - tree t; - - if (type == error_mark_node) - return 0; - - if (! IS_AGGR_TYPE (type)) - return 0; - - if (flag_new_abi) - return CLASSTYPE_SIZE (type) == integer_zero_node; - - if (TYPE_BINFO_BASETYPES (type)) - return 0; - t = TYPE_FIELDS (type); - while (t && TREE_CODE (t) != FIELD_DECL) - t = TREE_CHAIN (t); - return (t == NULL_TREE); -} - -/* Find the enclosing class of the given NODE. NODE can be a *_DECL or - a *_TYPE node. NODE can also be a local class. */ - -tree -get_enclosing_class (type) - tree type; -{ - tree node = type; - - while (node && TREE_CODE (node) != NAMESPACE_DECL) - { - switch (TREE_CODE_CLASS (TREE_CODE (node))) - { - case 'd': - node = DECL_CONTEXT (node); - break; - - case 't': - if (node != type) - return node; - node = TYPE_CONTEXT (node); - break; - - default: - my_friendly_abort (0); - } - } - return NULL_TREE; -} - -/* Return 1 if TYPE or one of its enclosing classes is derived from BASE. */ - -int -is_base_of_enclosing_class (base, type) - tree base, type; -{ - while (type) - { - if (get_binfo (base, type, 0)) - return 1; - - type = get_enclosing_class (type); - } - return 0; -} diff --git a/gcc/cp/config-lang.in b/gcc/cp/config-lang.in deleted file mode 100755 index dd31af4..0000000 --- a/gcc/cp/config-lang.in +++ /dev/null @@ -1,41 +0,0 @@ -# Top level configure fragment for GNU C++. -# Copyright (C) 1994, 1995, 1997, 1998 Free Software Foundation, Inc. - -#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 Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# Configure looks for the existence of this file to auto-config each language. -# We define several parameters used by configure: -# -# language - name of language as it would appear in $(LANGUAGES) -# compilers - value to add to $(COMPILERS) -# stagestuff - files to add to $(STAGESTUFF) -# diff_excludes - files to ignore when building diffs between two versions. - -language="c++" - -compilers="cc1plus\$(exeext)" - -stagestuff="g++\$(exeext) g++-cross\$(exeext) cc1plus\$(exeext)" - -diff_excludes="-x parse.c -x parse.h" - -headers='$(CXX_EXTRA_HEADERS)' - -lib2funcs=cplib2.txt - -outputs=cp/Makefile diff --git a/gcc/cp/cp-tree.def b/gcc/cp/cp-tree.def deleted file mode 100755 index 2fdacfd..0000000 --- a/gcc/cp/cp-tree.def +++ /dev/null @@ -1,257 +0,0 @@ -/* This file contains the definitions and documentation for the - additional tree codes used in the GNU C++ compiler (see tree.def - for the standard codes). - Copyright (C) 1987, 1988, 1990, 1993, 1997, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Reference to the contents of an offset - (a value whose type is an OFFSET_TYPE). - Operand 0 is the object within which the offset is taken. - Operand 1 is the offset. The language independent OFFSET_REF - just won't work for us. */ -DEFTREECODE (OFFSET_REF, "offset_ref", 'r', 2) - -/* A pointer-to-member constant. For a pointer-to-member constant - `X::Y' The PTRMEM_CST_CLASS is the RECORD_TYPE for `X' and the - PTRMEM_CST_MEMBER is the _DECL for `Y'. */ -DEFTREECODE (PTRMEM_CST, "ptrmem_cst", 'c', 1) - -/* For NEW_EXPR, operand 0 is the placement list. - Operand 1 is the new-declarator. - Operand 2 is the initializer. */ -DEFTREECODE (NEW_EXPR, "nw_expr", 'e', 3) -DEFTREECODE (VEC_NEW_EXPR, "vec_nw_expr", 'e', 3) - -/* For DELETE_EXPR, operand 0 is the store to be destroyed. - Operand 1 is the value to pass to the destroying function - saying whether the store should be deallocated as well. */ -DEFTREECODE (DELETE_EXPR, "dl_expr", 'e', 2) -DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2) - -/* Value is reference to particular overloaded class method. - Operand 0 is the class name (an IDENTIFIER_NODE); - operand 1 is the field (also an IDENTIFIER_NODE). - The COMPLEXITY field holds the class level (usually 0). */ -DEFTREECODE (SCOPE_REF, "scope_ref", 'r', 2) - -/* When composing an object with a member, this is the result. - Operand 0 is the object. Operand 1 is the member (usually - a dereferenced pointer to member). */ -DEFTREECODE (MEMBER_REF, "member_ref", 'r', 2) - -/* Type conversion operator in C++. TREE_TYPE is type that this - operator converts to. Operand is expression to be converted. */ -DEFTREECODE (TYPE_EXPR, "type_expr", 'e', 1) - -/* For AGGR_INIT_EXPR, operand 0 is function which performs initialization, - operand 1 is argument list to initialization function, - and operand 2 is the slot which was allocated for this expression. */ -DEFTREECODE (AGGR_INIT_EXPR, "aggr_init_expr", 'e', 3) - -/* A throw expression. operand 0 is the expression, if there was one, - else it is NULL_TREE. */ -DEFTREECODE (THROW_EXPR, "throw_expr", 'e', 1) - -/* Initialization of a vector, used in build_new. Operand 0 is the target - of the initialization, operand 1 is the initializer, and operand 2 is - the number of elements. */ -DEFTREECODE (VEC_INIT_EXPR, "vec_init_expr", 'e', 3) - -/* Template definition. The following fields have the specified uses, - although there are other macros in cp-tree.h that should be used for - accessing this data. - DECL_ARGUMENTS template parm vector - DECL_TEMPLATE_INFO template text &c - DECL_VINDEX list of instantiations already produced; - only done for functions so far - For class template: - DECL_INITIAL associated templates (methods &c) - DECL_RESULT null - For non-class templates: - TREE_TYPE type of object to be constructed - DECL_RESULT decl for object to be created - (e.g., FUNCTION_DECL with tmpl parms used) - */ -DEFTREECODE (TEMPLATE_DECL, "template_decl", 'd', 0) - -/* Index into a template parameter list. The TEMPLATE_PARM_IDX gives - the index (from 0) of the parameter, while the TEMPLATE_PARM_LEVEL - gives the level (from 1) of the parameter. - - Here's an example: - - template <class T> // Index 0, Level 1. - struct S - { - template <class U, // Index 0, Level 2. - class V> // Index 1, Level 2. - void f(); - }; - - The DESCENDANTS will be a chain of TEMPLATE_PARM_INDEXs descended - from this one. The first descendant will have the same IDX, but - its LEVEL will be one less. The TREE_CHAIN field is used to chain - together the descendants. The TEMPLATE_PARM_DECL is the - declaration of this parameter, either a TYPE_DECL or CONST_DECL. - The TEMPLATE_PARM_ORIG_LEVEL is the LEVEL of the most distant - parent, i.e., the LEVEL that the parameter originally had when it - was declared. For example, if we instantiate S<int>, we will have: - - struct S<int> - { - template <class U, // Index 0, Level 1, Orig Level 2 - class V> // Index 1, Level 1, Orig Level 2 - void f(); - }; - - The LEVEL is the level of the parameter when we are worrying about - the types of things; the ORIG_LEVEL is the level when we are - worrying about instantiating things. */ -DEFTREECODE (TEMPLATE_PARM_INDEX, "template_parm_index", 'x', - /* The addition of (sizeof(char*) - 1) in the next - expression is to ensure against the case where - sizeof(char*) does not evenly divide - sizeof(HOST_WIDE_INT). */ - 2 + ((3 * sizeof (HOST_WIDE_INT) + sizeof(char*) - 1) - / sizeof (char*))) - -/* Index into a template parameter list. This parameter must be a type. - The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */ -DEFTREECODE (TEMPLATE_TYPE_PARM, "template_type_parm", 't', 0) - -/* Index into a template parameter list. This parameter must be a type. - If it is used in signature of a template, TEMPLATE_INFO is NULL_TREE. - Otherwise it is used to declare a type like TT<int>. - The TYPE_FIELDS value will be a TEMPLATE_PARM_INDEX. */ -DEFTREECODE (TEMPLATE_TEMPLATE_PARM, "template_template_parm", 't', 0) - -/* A type designated by `typename T::t'. TYPE_CONTEXT is `T', - TYPE_NAME is a TYPE_DECL for `t'. If TREE_TYPE is present, this - type was generated by the implicit typename extension, and the - TREE_TYPE is a _TYPE from a baseclass of `T'. */ -DEFTREECODE (TYPENAME_TYPE, "typename_type", 't', 0) - -/* A type designated by `__typeof (expr)'. TYPE_FIELDS is the - expression in question. */ -DEFTREECODE (TYPEOF_TYPE, "typeof_type", 't', 0) - -/* A thunk is a stub function. - - Thunks are used to implement multiple inheritance: - At run-time, such a thunk subtracts THUNK_DELTA (an int, not a tree) - from the this pointer, and then jumps to DECL_INITIAL - (which is an ADDR_EXPR whose operand is a FUNCTION_DECL). - - Other kinds of thunks may be defined later. */ -DEFTREECODE (THUNK_DECL, "thunk_decl", 'd', 0) - -/* A using declaration. DECL_INITIAL contains the specified scope. - This is not an alias, but is later expanded into multiple aliases. */ -DEFTREECODE (USING_DECL, "using_decl", 'd', 0) - -/* An un-parsed default argument. Looks like an IDENTIFIER_NODE. */ -DEFTREECODE (DEFAULT_ARG, "default_arg", 'c', 2) - -/* A template-id, like foo<int>. The first operand is the template. - The second is the list of explicitly specified arguments. The - template will be a FUNCTION_DECL, TEMPLATE_DECL, or a list of - overloaded functions and templates if the template-id refers to - a global template. If the template-id refers to a member template, - the template may be an IDENTIFIER_NODE. */ -DEFTREECODE (TEMPLATE_ID_EXPR, "template_id_expr", 'e', 2) - -/* An association between name and entity. Parameters are the scope - and the (non-type) value. TREE_TYPE indicates the type bound to - the name. */ -DEFTREECODE (CPLUS_BINDING, "binding", 'x', 2) - -/* A list-like node for chaining overloading candidates. TREE_TYPE is - the original name, and the parameter is the FUNCTION_DECL. */ -DEFTREECODE (OVERLOAD, "overload", 'x', 1) - -/* A generic wrapper for something not tree that we want to include in - tree structure. */ -DEFTREECODE (WRAPPER, "wrapper", 'x', 1) - -/* A node to remember a source position. */ -DEFTREECODE (SRCLOC, "srcloc", 'x', 2) - -/* Used to represent deferred name lookup for dependent names while - parsing a template declaration. The first argument is an - IDENTIFIER_NODE for the name in question. The TREE_TYPE is - unused. */ -DEFTREECODE (LOOKUP_EXPR, "lookup_expr", 'e', 1) - -/* A whole bunch of tree codes for the initial, superficial parsing of - templates. */ -DEFTREECODE (MODOP_EXPR, "modop_expr", 'e', 3) -DEFTREECODE (CAST_EXPR, "cast_expr", '1', 1) -DEFTREECODE (REINTERPRET_CAST_EXPR, "reinterpret_cast_expr", '1', 1) -DEFTREECODE (CONST_CAST_EXPR, "const_cast_expr", '1', 1) -DEFTREECODE (STATIC_CAST_EXPR, "static_cast_expr", '1', 1) -DEFTREECODE (DYNAMIC_CAST_EXPR, "dynamic_cast_expr", '1', 1) -DEFTREECODE (SIZEOF_EXPR, "sizeof_expr", '1', 1) -DEFTREECODE (ALIGNOF_EXPR, "alignof_expr", '1', 1) -DEFTREECODE (ARROW_EXPR, "arrow_expr", 'e', 1) -DEFTREECODE (DOTSTAR_EXPR, "dotstar_expr", 'e', 2) -DEFTREECODE (TYPEID_EXPR, "typeid_expr", 'e', 1) - -DEFTREECODE (EXPR_STMT, "expr_stmt", 'e', 1) -DEFTREECODE (COMPOUND_STMT, "compound_stmt", 'e', 1) -DEFTREECODE (DECL_STMT, "decl_stmt", 'e', 3) -DEFTREECODE (IF_STMT, "if_stmt", 'e', 3) -DEFTREECODE (FOR_STMT, "for_stmt", 'e', 4) -DEFTREECODE (WHILE_STMT, "while_stmt", 'e', 2) -DEFTREECODE (DO_STMT, "do_stmt", 'e', 2) -DEFTREECODE (RETURN_STMT, "return_stmt", 'e', 1) -DEFTREECODE (BREAK_STMT, "break_stmt", 'e', 0) -DEFTREECODE (CONTINUE_STMT, "continue_stmt", 'e', 0) -DEFTREECODE (SWITCH_STMT, "switch_stmt", 'e', 2) -DEFTREECODE (GOTO_STMT, "goto_stmt", 'e', 1) -DEFTREECODE (ASM_STMT, "asm_stmt", 'e', 5) - -DEFTREECODE (CTOR_INITIALIZER, "ctor_initializer", 'e', 2) -DEFTREECODE (CASE_LABEL, "case_label", 'e', 2) -DEFTREECODE (RETURN_INIT, "return_init", 'e', 2) -DEFTREECODE (TRY_BLOCK, "try_stmt", 'e', 2) -DEFTREECODE (HANDLER, "catch_stmt", 'e', 2) - -DEFTREECODE (TAG_DEFN, "tag_defn", 'e', 0) - -/* And some codes for expressing conversions for overload resolution. */ - -DEFTREECODE (IDENTITY_CONV, "identity_conv", 'e', 1) -DEFTREECODE (LVALUE_CONV, "lvalue_conv", 'e', 1) -DEFTREECODE (QUAL_CONV, "qual_conv", 'e', 1) -DEFTREECODE (STD_CONV, "std_conv", 'e', 1) -DEFTREECODE (PTR_CONV, "ptr_conv", 'e', 1) -DEFTREECODE (PMEM_CONV, "pmem_conv", 'e', 1) -DEFTREECODE (BASE_CONV, "base_conv", 'e', 1) -DEFTREECODE (REF_BIND, "ref_bind", 'e', 1) -DEFTREECODE (USER_CONV, "user_conv", 'e', 2) -DEFTREECODE (AMBIG_CONV, "ambig_conv", 'e', 1) -DEFTREECODE (RVALUE_CONV, "rvalue_conv", 'e', 1) - -/* -Local variables: -mode:c -End: -*/ diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h deleted file mode 100755 index 3035a89..0000000 --- a/gcc/cp/cp-tree.h +++ /dev/null @@ -1,3441 +0,0 @@ -/* Definitions for C++ parsing and type checking. - Copyright (C) 1987, 92-97, 1998, 1999 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#ifndef _CP_TREE_H -#define _CP_TREE_H - -/* Usage of TREE_LANG_FLAG_?: - 0: TREE_NONLOCAL_FLAG (in TREE_LIST or _TYPE). - BINFO_MARKED (BINFO nodes). - COMPOUND_STMT_NO_SCOPE (in COMPOUND_STMT). - NEW_EXPR_USE_GLOBAL (in NEW_EXPR). - DELETE_EXPR_USE_GLOBAL (in DELETE_EXPR). - LOOKUP_EXPR_GLOBAL (in LOOKUP_EXPR). - TREE_NEGATED_INT (in INTEGER_CST). - IDENTIFIER_MARKED (used by search routines). - LOCAL_BINDING_P (in CPLUS_BINDING) - 1: IDENTIFIER_VIRTUAL_P. - TI_PENDING_TEMPLATE_FLAG. - TEMPLATE_PARMS_FOR_INLINE. - DELETE_EXPR_USE_VEC (in DELETE_EXPR). - (TREE_CALLS_NEW) (in _EXPR or _REF) (commented-out). - TYPE_USES_COMPLEX_INHERITANCE (in _TYPE). - C_DECLARED_LABEL_FLAG. - 2: IDENTIFIER_OPNAME_P. - BINFO_VBASE_MARKED. - BINFO_FIELDS_MARKED. - TYPE_VIRTUAL_P. - 3: TYPE_USES_VIRTUAL_BASECLASSES (in a class TYPE). - BINFO_VTABLE_PATH_MARKED. - BINFO_PUSHDECLS_MARKED. - (TREE_REFERENCE_EXPR) (in NON_LVALUE_EXPR) (commented-out). - 4: BINFO_NEW_VTABLE_MARKED. - TREE_HAS_CONSTRUCTOR (in INDIRECT_REF, SAVE_EXPR, CONSTRUCTOR, - or FIELD_DECL). - 5: Not used. - 6: Not used. - - Usage of TYPE_LANG_FLAG_?: - 0: C_TYPE_FIELDS_READONLY (in RECORD_TYPE or UNION_TYPE). - 1: TYPE_HAS_CONSTRUCTOR. - 2: TYPE_HAS_DESTRUCTOR. - 3: TYPE_FOR_JAVA. - 4: TYPE_NEEDS_DESTRUCTOR. - 5: IS_AGGR_TYPE. - 6: TYPE_BUILT_IN. - - Usage of DECL_LANG_FLAG_?: - 0: DECL_ERROR_REPORTED (in VAR_DECL). - DECL_TEMPLATE_PARM_P (in CONST_DECL, TYPE_DECL, or TEMPLATE_DECL) - 1: C_TYPEDEF_EXPLICITLY_SIGNED (in TYPE_DECL). - DECL_TEMPLATE_INSTANTIATED (in a VAR_DECL or a FUNCTION_DECL) - 2: DECL_THIS_EXTERN (in VAR_DECL or FUNCTION_DECL). - 3: DECL_IN_AGGR_P. - 4: DECL_MAYBE_TEMPLATE. - 5: DECL_INTERFACE_KNOWN. - 6: DECL_THIS_STATIC (in VAR_DECL or FUNCTION_DECL). - 7: DECL_DEAD_FOR_LOCAL (in VAR_DECL). - - Usage of language-independent fields in a language-dependent manner: - - TYPE_ALIAS_SET - This field is used by TYPENAME_TYPEs, TEMPLATE_TYPE_PARMs, and so - forth as a substitute for the mark bits provided in `lang_type'. - At present, only the six low-order bits are used. - - TYPE_BINFO - For an ENUMERAL_TYPE, this is ENUM_TEMPLATE_INFO. - For a TYPENAME_TYPE, this is TYPENAME_TYPE_FULLNAME. - For a TEMPLATE_TEMPLATE_PARM, this is - TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO. -*/ - -/* Language-dependent contents of an identifier. */ - -struct lang_identifier -{ - struct tree_identifier ignore; - tree namespace_bindings; - tree bindings; - tree class_value; - tree class_template_info; - struct lang_id2 *x; -}; - -struct lang_id2 -{ - tree label_value, implicit_decl; - tree type_desc, as_list, error_locus; -}; - -typedef struct -{ - tree t; - int new_type_flag; -} flagged_type_tree; - -typedef struct -{ - char common[sizeof (struct tree_common)]; - struct rtx_def *rtl; /* Unused, but required to match up with what - the middle-end expects. */ - HOST_WIDE_INT index; - HOST_WIDE_INT level; - HOST_WIDE_INT orig_level; - tree decl; -} template_parm_index; - -typedef struct ptrmem_cst -{ - char common[sizeof (struct tree_common)]; - tree member; -}* ptrmem_cst_t; - -/* Nonzero if this binding is for a local scope, as opposed to a class - or namespace scope. */ -#define LOCAL_BINDING_P(NODE) TREE_LANG_FLAG_0(NODE) - -/* For a binding between a name and an entity at a non-local scope, - defines the scope where the binding is declared. (Either a class - _TYPE node, or a NAMESPACE_DECL.) This macro should be used only - for namespace-level bindings; on the IDENTIFIER_BINDING list - BINDING_LEVEL is used instead. */ -#define BINDING_SCOPE(NODE) (((struct tree_binding*)NODE)->scope.scope) - -/* This is the declaration bound to the name. Possible values: - variable, overloaded function, namespace, template, enumerator. */ -#define BINDING_VALUE(NODE) (((struct tree_binding*)NODE)->value) - -/* If name is bound to a type, this is the type (struct, union, enum). */ -#define BINDING_TYPE(NODE) TREE_TYPE(NODE) - -#define IDENTIFIER_GLOBAL_VALUE(NODE) \ - namespace_binding (NODE, global_namespace) -#define SET_IDENTIFIER_GLOBAL_VALUE(NODE, VAL) \ - set_namespace_binding (NODE, global_namespace, VAL) -#define IDENTIFIER_NAMESPACE_VALUE(NODE) \ - namespace_binding (NODE, current_namespace) -#define SET_IDENTIFIER_NAMESPACE_VALUE(NODE, VAL) \ - set_namespace_binding (NODE, current_namespace, VAL) - -struct tree_binding -{ - char common[sizeof (struct tree_common)]; - union { - tree scope; - struct binding_level *level; - } scope; - tree value; -}; - -/* The overloaded FUNCTION_DECL. */ -#define OVL_FUNCTION(NODE) (((struct tree_overload*)NODE)->function) -#define OVL_CHAIN(NODE) TREE_CHAIN(NODE) -/* Polymorphic access to FUNCTION and CHAIN. */ -#define OVL_CURRENT(NODE) \ - ((TREE_CODE(NODE)==OVERLOAD) ? OVL_FUNCTION(NODE) : NODE) -#define OVL_NEXT(NODE) \ - ((TREE_CODE(NODE)==OVERLOAD) ? TREE_CHAIN(NODE) : NULL_TREE) -/* If set, this was imported in a using declaration. - This is not to confuse with being used somewhere, which - is not important for this node. */ -#define OVL_USED(NODE) TREE_USED(NODE) - -struct tree_overload -{ - char common[sizeof (struct tree_common)]; - tree function; -}; - -#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr) -#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i) - -struct tree_wrapper -{ - char common[sizeof (struct tree_common)]; - union { - void *ptr; - int i; - } u; -}; - -#define SRCLOC_FILE(NODE) (((struct tree_srcloc*)NODE)->filename) -#define SRCLOC_LINE(NODE) (((struct tree_srcloc*)NODE)->linenum) -struct tree_srcloc -{ - char common[sizeof (struct tree_common)]; - char *filename; - int linenum; -}; - -/* To identify to the debug emitters if it should pay attention to the - flag `-Wtemplate-debugging'. */ -#define HAVE_TEMPLATES 1 - -/* Macros for access to language-specific slots in an identifier. */ - -#define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ - (((struct lang_identifier *)(NODE))->namespace_bindings) -#define IDENTIFIER_TEMPLATE(NODE) \ - (((struct lang_identifier *)(NODE))->class_template_info) - -/* The IDENTIFIER_BINDING is the innermost CPLUS_BINDING for the - identifier. It's TREE_CHAIN is the next outermost binding. Each - BINDING_VALUE is a DECL for the associated declaration. Thus, - name lookup consists simply of pulling off the node at the front - of the list (modulo oddities for looking up the names of types, - and such.) You can use BINDING_SCOPE or BINDING_LEVEL to - determine the scope that bound the name. */ -#define IDENTIFIER_BINDING(NODE) \ - (((struct lang_identifier*) (NODE))->bindings) - -/* The IDENTIFIER_VALUE is the value of the IDENTIFIER_BINDING, or - NULL_TREE if there is no binding. */ -#define IDENTIFIER_VALUE(NODE) \ - (IDENTIFIER_BINDING (NODE) \ - ? BINDING_VALUE (IDENTIFIER_BINDING (NODE)) \ - : NULL_TREE) - -/* If we are currently in class scope, then IDENTIFIER_CLASS_VALUE - indicates the class-scoped binding of NODE. This is just a pointer - to the BINDING_VALUE of one of the bindings in the - IDENTIFIER_BINDINGs list, so any time that this is set so is - IDENTIFIER_BINDING. */ -#define IDENTIFIER_CLASS_VALUE(NODE) \ - (((struct lang_identifier *) (NODE))->class_value) - -/* The amount of time used by the file whose special "time identifier" - is NODE, represented as an INTEGER_CST. See get_time_identifier. */ -#define TIME_IDENTIFIER_TIME(NODE) IDENTIFIER_BINDING(NODE) - -/* For a "time identifier" this is a INTEGER_CST. The - TREE_INT_CST_LOW is 1 if the corresponding file is "interface only". - The TRE_INT_CST_HIGH is 1 if it is "interface unknown". */ -#define TIME_IDENTIFIER_FILEINFO(NODE) IDENTIFIER_CLASS_VALUE (NODE) - -/* TREE_TYPE only indicates on local and class scope the current - type. For namespace scope, the presence of a type in any namespace - is indicated with global_type_node, and the real type behind must - be found through lookup. */ -#define IDENTIFIER_TYPE_VALUE(NODE) (identifier_type_value(NODE)) -#define REAL_IDENTIFIER_TYPE_VALUE(NODE) (TREE_TYPE (NODE)) -#define SET_IDENTIFIER_TYPE_VALUE(NODE,TYPE) (TREE_TYPE (NODE) = TYPE) -#define IDENTIFIER_HAS_TYPE_VALUE(NODE) (IDENTIFIER_TYPE_VALUE (NODE) ? 1 : 0) - -#define LANG_ID_FIELD(NAME,NODE) \ - (((struct lang_identifier *)(NODE))->x \ - ? ((struct lang_identifier *)(NODE))->x->NAME : 0) -#define SET_LANG_ID(NODE,VALUE,NAME) \ - (((struct lang_identifier *)(NODE))->x == 0 \ - ? ((struct lang_identifier *)(NODE))->x \ - = (struct lang_id2 *)perm_calloc (1, sizeof (struct lang_id2)) : 0, \ - ((struct lang_identifier *)(NODE))->x->NAME = (VALUE)) - -#define IDENTIFIER_LABEL_VALUE(NODE) LANG_ID_FIELD(label_value, NODE) -#define SET_IDENTIFIER_LABEL_VALUE(NODE,VALUE) \ - SET_LANG_ID(NODE, VALUE, label_value) - -#define IDENTIFIER_IMPLICIT_DECL(NODE) LANG_ID_FIELD(implicit_decl, NODE) -#define SET_IDENTIFIER_IMPLICIT_DECL(NODE,VALUE) \ - SET_LANG_ID(NODE, VALUE, implicit_decl) - -#define IDENTIFIER_AS_DESC(NODE) LANG_ID_FIELD(type_desc, NODE) -#define SET_IDENTIFIER_AS_DESC(NODE,DESC) \ - SET_LANG_ID(NODE, DESC, type_desc) - -#define IDENTIFIER_AS_LIST(NODE) LANG_ID_FIELD(as_list, NODE) -#define SET_IDENTIFIER_AS_LIST(NODE,LIST) \ - SET_LANG_ID(NODE, LIST, as_list) - -#define IDENTIFIER_ERROR_LOCUS(NODE) LANG_ID_FIELD(error_locus, NODE) -#define SET_IDENTIFIER_ERROR_LOCUS(NODE,VALUE) \ - SET_LANG_ID(NODE, VALUE, error_locus) - - -#define IDENTIFIER_VIRTUAL_P(NODE) TREE_LANG_FLAG_1(NODE) - -/* Nonzero if this identifier is the prefix for a mangled C++ operator name. */ -#define IDENTIFIER_OPNAME_P(NODE) TREE_LANG_FLAG_2(NODE) - -/* Nonzero if this identifier is the name of a type-conversion - operator. */ -#define IDENTIFIER_TYPENAME_P(NODE) \ - (! strncmp (IDENTIFIER_POINTER (NODE), \ - OPERATOR_TYPENAME_FORMAT, \ - strlen (OPERATOR_TYPENAME_FORMAT))) - -/* Nonzero means reject anything that ANSI standard C forbids. */ -extern int pedantic; - -/* In a RECORD_TYPE or UNION_TYPE, nonzero if any component is read-only. */ -#define C_TYPE_FIELDS_READONLY(type) TYPE_LANG_FLAG_0 (type) - -/* Record in each node resulting from a binary operator - what operator was specified for it. */ -#define C_EXP_ORIGINAL_CODE(exp) ((enum tree_code) TREE_COMPLEXITY (exp)) - -/* Store a value in that field. */ -#define C_SET_EXP_ORIGINAL_CODE(exp, code) \ - (TREE_COMPLEXITY (exp) = (int)(code)) - -/* If non-zero, a VAR_DECL whose cleanup will cause a throw to the - next exception handler. */ -extern tree exception_throw_decl; - -extern tree double_type_node, long_double_type_node, float_type_node; -extern tree char_type_node, unsigned_char_type_node, signed_char_type_node; -extern tree ptrdiff_type_node; - -extern tree short_integer_type_node, short_unsigned_type_node; -extern tree long_integer_type_node, long_unsigned_type_node; -extern tree long_long_integer_type_node, long_long_unsigned_type_node; -extern tree unsigned_type_node; -extern tree string_type_node, char_array_type_node, int_array_type_node; -extern tree wchar_array_type_node; -extern tree wchar_type_node, signed_wchar_type_node, unsigned_wchar_type_node; - -extern tree complex_integer_type_node; -extern tree complex_float_type_node; -extern tree complex_double_type_node; -extern tree complex_long_double_type_node; - -extern tree intQI_type_node, unsigned_intQI_type_node; -extern tree intHI_type_node, unsigned_intHI_type_node; -extern tree intSI_type_node, unsigned_intSI_type_node; -extern tree intDI_type_node, unsigned_intDI_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 -extern tree intTI_type_node, unsigned_intTI_type_node; -#endif - -extern tree java_byte_type_node; -extern tree java_short_type_node; -extern tree java_int_type_node; -extern tree java_long_type_node; -extern tree java_float_type_node; -extern tree java_double_type_node; -extern tree java_char_type_node; -extern tree java_boolean_type_node; - -extern int current_function_returns_value; -extern int current_function_returns_null; -extern tree current_function_return_value; - -extern tree current_namespace; -extern tree global_namespace; - -extern tree ridpointers[]; -extern tree ansi_opname[]; -extern tree ansi_assopname[]; - -/* Nonzero means `$' can be in an identifier. */ - -extern int dollars_in_ident; - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -extern int flag_cond_mismatch; - -/* Nonzero means don't recognize the keyword `asm'. */ - -extern int flag_no_asm; - -/* For cross referencing. */ - -extern int flag_gnu_xref; - -/* For environments where you can use GNU binutils (as, ld in particular). */ - -extern int flag_gnu_binutils; - -/* Nonzero means ignore `#ident' directives. */ - -extern int flag_no_ident; - -/* Nonzero means warn about implicit declarations. */ - -extern int warn_implicit; - -/* Nonzero means warn about usage of long long when `-pedantic'. */ - -extern int warn_long_long; - -/* Nonzero means warn when all ctors or dtors are private, and the class - has no friends. */ - -extern int warn_ctor_dtor_privacy; - -/* Nonzero means warn about function definitions that default the return type - or that use a null return and have a return-type other than void. */ - -extern int warn_return_type; - -/* Nonzero means give string constants the type `const char *', as mandated - by the standard. */ - -extern int flag_const_strings; - -/* Nonzero means warn about deprecated conversion from string constant to - `char *'. */ - -extern int warn_write_strings; - -/* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - -extern int warn_pointer_arith; - -/* Nonzero means warn about suggesting putting in ()'s. */ - -extern int warn_parentheses; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -extern int warn_redundant_decls; - -/* Warn if initializer is not completely bracketed. */ - -extern int warn_missing_braces; - -/* Warn about comparison of signed and unsigned values. */ - -extern int warn_sign_compare; - -/* Warn about a subscript that has type char. */ - -extern int warn_char_subscripts; - -/* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - -extern int warn_cast_qual; - -/* Warn about *printf or *scanf format/argument anomalies. */ - -extern int warn_format; - -/* Nonzero means warn about non virtual destructors in classes that have - virtual functions. */ - -extern int warn_nonvdtor; - -/* Non-zero means warn when we convert a pointer to member function - into a pointer to (void or function). */ - -extern int warn_pmf2ptr; - -/* Nonzero means warn about violation of some Effective C++ style rules. */ - -extern int warn_ecpp; - -/* Nonzero means warn where overload resolution chooses a promotion from - unsigned to signed over a conversion to an unsigned of the same size. */ - -extern int warn_sign_promo; - -/* Non-zero means warn when a function is declared extern and later inline. */ - -extern int warn_extern_inline; - -/* Non-zero means warn when an old-style cast is used. */ - -extern int warn_old_style_cast; - -/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ - -extern int flag_signed_bitfields; - -/* 3 means write out only virtuals function tables `defined' - in this implementation file. - 2 means write out only specific virtual function tables - and give them (C) public access. - 1 means write out virtual function tables and give them - (C) public access. - 0 means write out virtual function tables and give them - (C) static access (default). - -1 means declare virtual function tables extern. */ - -extern int write_virtuals; - -/* True for more efficient but incompatible (not fully tested) - vtable implementation (using thunks). - 0 is old behavior; 1 is new behavior. */ -extern int flag_vtable_thunks; - -/* INTERFACE_ONLY nonzero means that we are in an "interface" - section of the compiler. INTERFACE_UNKNOWN nonzero means - we cannot trust the value of INTERFACE_ONLY. If INTERFACE_UNKNOWN - is zero and INTERFACE_ONLY is zero, it means that we are responsible - for exporting definitions that others might need. */ -extern int interface_only, interface_unknown; - -/* Nonzero means we should attempt to elide constructors when possible. */ - -extern int flag_elide_constructors; - -/* Nonzero means enable obscure ANSI features and disable GNU extensions - that might cause ANSI-compliant code to be miscompiled. */ - -extern int flag_ansi; - -/* Nonzero means recognize and handle signature language constructs. */ - -extern int flag_handle_signatures; - -/* Nonzero means that member functions defined in class scope are - inline by default. */ - -extern int flag_default_inline; - -/* The name-mangling scheme to use. Versions of gcc before 2.8 use - version 0. */ -extern int name_mangling_version; - -/* Nonzero means that guiding declarations are allowed. */ -extern int flag_guiding_decls; - -/* Nonzero if squashed mangling is to be performed. - This uses the B and K codes to reference previously seen class types - and class qualifiers. */ -extern int flag_do_squangling; - -/* Nonzero if we want to issue diagnostics that the standard says are not - required. */ -extern int flag_optional_diags; - -/* Nonzero means do not consider empty argument prototype to mean function - takes no arguments. */ -extern int flag_strict_prototype; - -/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ -extern int flag_vtable_gc; - -/* Nonzero means make the default pedwarns warnings instead of errors. - The value of this flag is ignored if -pedantic is specified. */ -extern int flag_permissive; - -/* C++ language-specific tree codes. */ -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, -enum cplus_tree_code { - __DUMMY = LAST_AND_UNUSED_TREE_CODE, -#include "cp-tree.def" - LAST_CPLUS_TREE_CODE -}; -#undef DEFTREECODE - -enum languages { lang_c, lang_cplusplus, lang_java }; - -/* Macros to make error reporting functions' lives easier. */ -#define TYPE_IDENTIFIER(NODE) (DECL_NAME (TYPE_NAME (NODE))) -#define TYPE_NAME_STRING(NODE) (IDENTIFIER_POINTER (TYPE_IDENTIFIER (NODE))) -#define TYPE_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (TYPE_IDENTIFIER (NODE))) - -#define TYPE_ASSEMBLER_NAME_STRING(NODE) (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) -#define TYPE_ASSEMBLER_NAME_LENGTH(NODE) (IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (TYPE_NAME (NODE)))) - -/* The _DECL for this _TYPE. */ -#define TYPE_MAIN_DECL(NODE) (TYPE_STUB_DECL (TYPE_MAIN_VARIANT (NODE))) - -/* Nonzero if T is a class (or struct or union) type. Also nonzero - for template type parameters and typename types. Despite its name, - this macro has nothing to do with the definition of aggregate given - in the standard. Think of this macro as MAYBE_CLASS_TYPE_P. */ -#define IS_AGGR_TYPE(t) \ - (TREE_CODE (t) == TEMPLATE_TYPE_PARM \ - || TREE_CODE (t) == TYPENAME_TYPE \ - || TREE_CODE (t) == TYPEOF_TYPE \ - || TYPE_LANG_FLAG_5 (t)) - -/* Set IS_AGGR_TYPE for T to VAL. T must be a class, struct, or - union type. */ -#define SET_IS_AGGR_TYPE(T, VAL) \ - (TYPE_LANG_FLAG_5 (T) = (VAL)) - -/* Nonzero if T is a class type. Zero for template type parameters, - typename types, and so forth. */ -#define CLASS_TYPE_P(t) \ - (IS_AGGR_TYPE_CODE (TREE_CODE (t)) && IS_AGGR_TYPE (t)) - -#define IS_AGGR_TYPE_CODE(t) (t == RECORD_TYPE || t == UNION_TYPE) -#define IS_AGGR_TYPE_2(TYPE1,TYPE2) \ - (TREE_CODE (TYPE1) == TREE_CODE (TYPE2) \ - && IS_AGGR_TYPE (TYPE1)&IS_AGGR_TYPE (TYPE2)) -#define IS_OVERLOAD_TYPE(t) \ - (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE) - -/* In a *_TYPE, nonzero means a built-in type. */ -#define TYPE_BUILT_IN(NODE) TYPE_LANG_FLAG_6(NODE) - -/* True if this a "Java" type, defined in 'extern "Java"'. */ -#define TYPE_FOR_JAVA(NODE) TYPE_LANG_FLAG_3(NODE) - -/* The type qualifiers for this type, including the qualifiers on the - elements for an array type. */ -#define CP_TYPE_QUALS(NODE) \ - ((TREE_CODE (NODE) != ARRAY_TYPE) \ - ? TYPE_QUALS (NODE) : cp_type_quals (NODE)) - -/* Nonzero if this type is const-qualified. */ -#define CP_TYPE_CONST_P(NODE) \ - ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_CONST) != 0) - -/* Nonzero if this type is volatile-qualified. */ -#define CP_TYPE_VOLATILE_P(NODE) \ - ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_VOLATILE) != 0) - -/* Nonzero if this type is restrict-qualified. */ -#define CP_TYPE_RESTRICT_P(NODE) \ - ((CP_TYPE_QUALS (NODE) & TYPE_QUAL_RESTRICT) != 0) - -/* Nonzero if this type is const-qualified, but not - volatile-qualified. Other qualifiers are ignored. This macro is - used to test whether or not it is OK to bind an rvalue to a - reference. */ -#define CP_TYPE_CONST_NON_VOLATILE_P(NODE) \ - ((CP_TYPE_QUALS (NODE) & (TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE)) \ - == TYPE_QUAL_CONST) - -#define DELTA_FROM_VTABLE_ENTRY(ENTRY) \ - (!flag_vtable_thunks ? \ - TREE_VALUE (CONSTRUCTOR_ELTS (ENTRY)) \ - : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? integer_zero_node \ - : build_int_2 (THUNK_DELTA (TREE_OPERAND ((ENTRY), 0)), 0)) - -/* Virtual function addresses can be gotten from a virtual function - table entry using this macro. */ -#define FNADDR_FROM_VTABLE_ENTRY(ENTRY) \ - (!flag_vtable_thunks ? \ - TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) \ - : TREE_CODE (TREE_OPERAND ((ENTRY), 0)) != THUNK_DECL ? (ENTRY) \ - : DECL_INITIAL (TREE_OPERAND ((ENTRY), 0))) -#define SET_FNADDR_FROM_VTABLE_ENTRY(ENTRY,VALUE) \ - (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (CONSTRUCTOR_ELTS (ENTRY)))) = (VALUE)) -#define FUNCTION_ARG_CHAIN(NODE) (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (NODE)))) -#define PROMOTES_TO_AGGR_TYPE(NODE,CODE) \ - (((CODE) == TREE_CODE (NODE) \ - && IS_AGGR_TYPE (TREE_TYPE (NODE))) \ - || IS_AGGR_TYPE (NODE)) - -/* Nonzero iff TYPE is uniquely derived from PARENT. Under MI, PARENT can - be an ambiguous base class of TYPE, and this macro will be false. */ -#define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) >= 0) -#define ACCESSIBLY_DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, -1, (tree *)0) >= 0) -#define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 1, (tree *)0) >= 0) -#define DERIVED_FROM_P(PARENT, TYPE) (get_base_distance (PARENT, TYPE, 0, (tree *)0) != -1) - -/* This structure provides additional information above and beyond - what is provide in the ordinary tree_type. In the past, we used it - for the types of class types, template parameters types, typename - types, and so forth. However, there can be many (tens to hundreds - of thousands) of template parameter types in a compilation, and - there's no need for this additional information in that case. - Therefore, we now use this data structure only for class types. - - In the past, it was thought that there would be relatively few - class types. However, in the presence of heavy use of templates, - many (i.e., thousands) of classes can easily be generated. - Therefore, we should endeavor to keep the size of this structure to - a minimum. */ -struct lang_type -{ - struct - { - unsigned has_type_conversion : 1; - unsigned has_init_ref : 1; - unsigned has_assignment : 1; - unsigned has_default_ctor : 1; - unsigned uses_multiple_inheritance : 1; - unsigned const_needs_init : 1; - unsigned ref_needs_init : 1; - unsigned has_const_assign_ref : 1; - - unsigned has_nonpublic_ctor : 2; - unsigned has_nonpublic_assign_ref : 2; - unsigned vtable_needs_writing : 1; - unsigned has_assign_ref : 1; - unsigned gets_new : 2; - - unsigned gets_delete : 2; - unsigned has_call_overloaded : 1; - unsigned has_array_ref_overloaded : 1; - unsigned has_arrow_overloaded : 1; - unsigned interface_only : 1; - unsigned interface_unknown : 1; - unsigned needs_virtual_reinit : 1; - - unsigned marks: 6; - unsigned vec_delete_takes_size : 1; - unsigned declared_class : 1; - - unsigned being_defined : 1; - unsigned redefined : 1; - unsigned debug_requested : 1; - unsigned use_template : 2; - unsigned got_semicolon : 1; - unsigned ptrmemfunc_flag : 1; - unsigned is_signature : 1; - - unsigned is_signature_pointer : 1; - unsigned is_signature_reference : 1; - unsigned has_opaque_typedecls : 1; - unsigned sigtable_has_been_generated : 1; - unsigned was_anonymous : 1; - unsigned has_real_assignment : 1; - unsigned has_real_assign_ref : 1; - unsigned has_const_init_ref : 1; - - unsigned has_complex_init_ref : 1; - unsigned has_complex_assign_ref : 1; - unsigned has_abstract_assign_ref : 1; - unsigned non_aggregate : 1; - unsigned is_partial_instantiation : 1; - unsigned has_mutable : 1; - - /* The MIPS compiler gets it wrong if this struct also - does not fill out to a multiple of 4 bytes. Add a - member `dummy' with new bits if you go over the edge. */ - unsigned dummy : 10; - } type_flags; - - int n_ancestors; - int n_vancestors; - int vsize; - int max_depth; - int vfield_parent; - - union tree_node *baselink_vec; - union tree_node *vfields; - union tree_node *vbases; - - union tree_node *tags; - - union tree_node *search_slot; - - unsigned char align; - /* Room for another three unsigned chars. */ - - union tree_node *size; - - union tree_node *base_init_list; - union tree_node *abstract_virtuals; - union tree_node *as_list; - union tree_node *id_as_list; - union tree_node *binfo_as_list; - union tree_node *friend_classes; - - union tree_node *rtti; - - union tree_node *methods; - - union tree_node *signature; - union tree_node *signature_pointer_to; - union tree_node *signature_reference_to; - - union tree_node *template_info; -}; - -/* Indicates whether or not (and how) a template was expanded for this class. - 0=no information yet/non-template class - 1=implicit template instantiation - 2=explicit template specialization - 3=explicit template instantiation */ -#define CLASSTYPE_USE_TEMPLATE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.use_template) - -/* Fields used for storing information before the class is defined. - After the class is defined, these fields hold other information. */ - -/* List of friends which were defined inline in this class definition. */ -#define CLASSTYPE_INLINE_FRIENDS(NODE) (TYPE_NONCOPIED_PARTS (NODE)) - -/* Nonzero for _CLASSTYPE means that the _CLASSTYPE either has - a special meaning for the assignment operator ("operator="), - or one of its fields (or base members) has a special meaning - defined. */ -#define TYPE_HAS_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assignment) -#define TYPE_HAS_REAL_ASSIGNMENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assignment) - -/* Nonzero for _CLASSTYPE means that operator new and delete are defined, - respectively. */ -#define TYPE_GETS_NEW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_new) -#define TYPE_GETS_DELETE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.gets_delete) -#define TYPE_GETS_REG_DELETE(NODE) (TYPE_GETS_DELETE (NODE) & 1) - -/* Nonzero for _CLASSTYPE means that operator vec delete is defined and - takes the optional size_t argument. */ -#define TYPE_VEC_DELETE_TAKES_SIZE(NODE) \ - (TYPE_LANG_SPECIFIC(NODE)->type_flags.vec_delete_takes_size) -#define TYPE_VEC_NEW_USES_COOKIE(NODE) \ - (TYPE_NEEDS_DESTRUCTOR (NODE) \ - || (TYPE_LANG_SPECIFIC (NODE) && TYPE_VEC_DELETE_TAKES_SIZE (NODE))) - -/* Nonzero for TREE_LIST or _TYPE node means that this node is class-local. */ -#define TREE_NONLOCAL_FLAG(NODE) (TREE_LANG_FLAG_0 (NODE)) - -/* Nonzero means that this _CLASSTYPE node defines ways of converting - itself to other types. */ -#define TYPE_HAS_CONVERSION(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_type_conversion) - -/* Nonzero means that this _CLASSTYPE node overloads operator=(X&). */ -#define TYPE_HAS_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_assign_ref) -#define TYPE_HAS_CONST_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_const_assign_ref) - -/* Nonzero means that this _CLASSTYPE node has an X(X&) constructor. */ -#define TYPE_HAS_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_init_ref) -#define TYPE_HAS_CONST_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_const_init_ref) - -/* Nonzero means that this type is being defined. I.e., the left brace - starting the definition of this type has been seen. */ -#define TYPE_BEING_DEFINED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.being_defined) -/* Nonzero means that this type has been redefined. In this case, if - convenient, don't reprocess any methods that appear in its redefinition. */ -#define TYPE_REDEFINED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.redefined) - -/* Nonzero means that this type is a signature. */ -# define IS_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)?TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature:0) -# define SET_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature=1) -# define CLEAR_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature=0) - -/* Nonzero means that this type is a signature pointer type. */ -# define IS_SIGNATURE_POINTER(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature_pointer) - -/* Nonzero means that this type is a signature reference type. */ -# define IS_SIGNATURE_REFERENCE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.is_signature_reference) - -/* Nonzero means that this signature contains opaque type declarations. */ -#define SIGNATURE_HAS_OPAQUE_TYPEDECLS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_opaque_typedecls) - -/* Nonzero means that a signature table has been generated - for this signature. */ -#define SIGTABLE_HAS_BEEN_GENERATED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.sigtable_has_been_generated) - -/* If NODE is a class, this is the signature type that contains NODE's - signature after it has been computed using sigof(). */ -#define CLASSTYPE_SIGNATURE(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) - -/* If NODE is a signature pointer or signature reference, this is the - signature type the pointer/reference points to. */ -#define SIGNATURE_TYPE(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) - -/* If NODE is a signature, this is a vector of all methods defined - in the signature or in its base types together with their default - implementations. */ -#define SIGNATURE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature) - -/* If NODE is a signature, this is the _TYPE node that contains NODE's - signature pointer type. */ -#define SIGNATURE_POINTER_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_pointer_to) - -/* If NODE is a signature, this is the _TYPE node that contains NODE's - signature reference type. */ -#define SIGNATURE_REFERENCE_TO(NODE) (TYPE_LANG_SPECIFIC(NODE)->signature_reference_to) - -/* The is the VAR_DECL that contains NODE's rtti. */ -#define CLASSTYPE_RTTI(NODE) (TYPE_LANG_SPECIFIC(NODE)->rtti) - -/* Nonzero means that this _CLASSTYPE node overloads operator(). */ -#define TYPE_OVERLOADS_CALL_EXPR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_call_overloaded) - -/* Nonzero means that this _CLASSTYPE node overloads operator[]. */ -#define TYPE_OVERLOADS_ARRAY_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_array_ref_overloaded) - -/* Nonzero means that this _CLASSTYPE node overloads operator->. */ -#define TYPE_OVERLOADS_ARROW(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_arrow_overloaded) - -/* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses - multiple inheritance. If this is 0 for the root of a type - hierarchy, then we can use more efficient search techniques. */ -#define TYPE_USES_MULTIPLE_INHERITANCE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.uses_multiple_inheritance) - -/* Nonzero means that this _CLASSTYPE (or one of its ancestors) uses - virtual base classes. If this is 0 for the root of a type - hierarchy, then we can use more efficient search techniques. */ -#define TYPE_USES_VIRTUAL_BASECLASSES(NODE) (TREE_LANG_FLAG_3(NODE)) - -/* Vector member functions defined in this class. Each element is - either a FUNCTION_DECL, a TEMPLATE_DECL, or an OVERLOAD. The first - two elements are for constructors, and destructors, respectively. - Any user-defined conversion operators follow these. These are - followed by ordinary member functions. There may be empty entries - at the end of the vector. */ -#define CLASSTYPE_METHOD_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->methods) - -/* The first type conversion operator in the class (the others can be - searched with TREE_CHAIN), or the first non-constructor function if - there are no type conversion operators. */ -#define CLASSTYPE_FIRST_CONVERSION(NODE) \ - TREE_VEC_LENGTH (CLASSTYPE_METHOD_VEC (NODE)) > 2 \ - ? TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (NODE), 2) \ - : NULL_TREE; - -/* Pointer from any member function to the head of the list of - member functions of the type that member function belongs to. */ -#define CLASSTYPE_BASELINK_VEC(NODE) (TYPE_LANG_SPECIFIC(NODE)->baselink_vec) - -/* Mark bits for depth-first and breath-first searches. */ - -/* Get the value of the Nth mark bit. */ -#define CLASSTYPE_MARKED_N(NODE, N) \ - (((CLASS_TYPE_P (NODE) ? TYPE_LANG_SPECIFIC (NODE)->type_flags.marks \ - : TYPE_ALIAS_SET (NODE)) & (1 << N)) != 0) - -/* Set the Nth mark bit. */ -#define SET_CLASSTYPE_MARKED_N(NODE, N) \ - (CLASS_TYPE_P (NODE) \ - ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks |= (1 << (N))) \ - : (TYPE_ALIAS_SET (NODE) |= (1 << (N)))) - -/* Clear the Nth mark bit. */ -#define CLEAR_CLASSTYPE_MARKED_N(NODE, N) \ - (CLASS_TYPE_P (NODE) \ - ? (TYPE_LANG_SPECIFIC (NODE)->type_flags.marks &= ~(1 << (N))) \ - : (TYPE_ALIAS_SET (NODE) &= ~(1 << (N)))) - -/* Get the value of the mark bits. */ -#define CLASSTYPE_MARKED(NODE) CLASSTYPE_MARKED_N(NODE, 0) -#define CLASSTYPE_MARKED2(NODE) CLASSTYPE_MARKED_N(NODE, 1) -#define CLASSTYPE_MARKED3(NODE) CLASSTYPE_MARKED_N(NODE, 2) -#define CLASSTYPE_MARKED4(NODE) CLASSTYPE_MARKED_N(NODE, 3) -#define CLASSTYPE_MARKED5(NODE) CLASSTYPE_MARKED_N(NODE, 4) -#define CLASSTYPE_MARKED6(NODE) CLASSTYPE_MARKED_N(NODE, 5) - -/* Macros to modify the above flags */ -#define SET_CLASSTYPE_MARKED(NODE) SET_CLASSTYPE_MARKED_N(NODE, 0) -#define CLEAR_CLASSTYPE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 0) -#define SET_CLASSTYPE_MARKED2(NODE) SET_CLASSTYPE_MARKED_N(NODE, 1) -#define CLEAR_CLASSTYPE_MARKED2(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 1) -#define SET_CLASSTYPE_MARKED3(NODE) SET_CLASSTYPE_MARKED_N(NODE, 2) -#define CLEAR_CLASSTYPE_MARKED3(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 2) -#define SET_CLASSTYPE_MARKED4(NODE) SET_CLASSTYPE_MARKED_N(NODE, 3) -#define CLEAR_CLASSTYPE_MARKED4(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 3) -#define SET_CLASSTYPE_MARKED5(NODE) SET_CLASSTYPE_MARKED_N(NODE, 4) -#define CLEAR_CLASSTYPE_MARKED5(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 4) -#define SET_CLASSTYPE_MARKED6(NODE) SET_CLASSTYPE_MARKED_N(NODE, 5) -#define CLEAR_CLASSTYPE_MARKED6(NODE) CLEAR_CLASSTYPE_MARKED_N(NODE, 5) - -/* A list of the nested tag-types (class, struct, union, or enum) - found within this class. The TREE_PURPOSE of each node is the name - of the type; the TREE_VALUE is the type itself. This list includes - nested member class templates. */ -#define CLASSTYPE_TAGS(NODE) (TYPE_LANG_SPECIFIC(NODE)->tags) - -/* If this class has any bases, this is the number of the base class from - which our VFIELD is based, -1 otherwise. If this class has no base - classes, this is not used. - In D : B1, B2, PARENT would be 0, if D's vtable came from B1, - 1, if D's vtable came from B2. */ -#define CLASSTYPE_VFIELD_PARENT(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfield_parent) - -/* Remove when done merging. */ -#define CLASSTYPE_VFIELD(NODE) TYPE_VFIELD(NODE) - -/* The number of virtual functions defined for this - _CLASSTYPE node. */ -#define CLASSTYPE_VSIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->vsize) -/* The virtual base classes that this type uses. */ -#define CLASSTYPE_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->vbases) -/* The virtual function pointer fields that this type contains. */ -#define CLASSTYPE_VFIELDS(NODE) (TYPE_LANG_SPECIFIC(NODE)->vfields) - -/* Number of baseclasses defined for this type. - 0 means no base classes. */ -#define CLASSTYPE_N_BASECLASSES(NODE) \ - (TYPE_BINFO_BASETYPES (NODE) ? TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES(NODE)) : 0) - -/* Memoize the number of super classes (base classes) that this node - has. That way we can know immediately (albeit conservatively how - large a multiple-inheritance matrix we need to build to find - derivation information. */ -#define CLASSTYPE_N_SUPERCLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->n_ancestors) -#define CLASSTYPE_N_VBASECLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->n_vancestors) - -/* Record how deep the inheritance is for this class so `void*' conversions - are less favorable than a conversion to the most base type. */ -#define CLASSTYPE_MAX_DEPTH(NODE) (TYPE_LANG_SPECIFIC(NODE)->max_depth) - -/* Used for keeping search-specific information. Any search routine - which uses this must define what exactly this slot is used for. */ -#define CLASSTYPE_SEARCH_SLOT(NODE) (TYPE_LANG_SPECIFIC(NODE)->search_slot) - -/* These are the size, mode and alignment of the type without its - virtual base classes, for when we use this type as a base itself. */ -#define CLASSTYPE_SIZE(NODE) (TYPE_LANG_SPECIFIC(NODE)->size) -#define CLASSTYPE_ALIGN(NODE) (TYPE_LANG_SPECIFIC(NODE)->align) - -/* A cons list of structure elements which either have constructors - to be called, or virtual function table pointers which - need initializing. Depending on what is being initialized, - the TREE_PURPOSE and TREE_VALUE fields have different meanings: - - Member initialization: <FIELD_DECL, TYPE> - Base class construction: <NULL_TREE, BASETYPE> - Base class initialization: <BASE_INITIALIZATION, THESE_INITIALIZATIONS> - Whole type: <MEMBER_INIT, BASE_INIT>. */ -#define CLASSTYPE_BASE_INIT_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->base_init_list) - -/* A cons list of virtual functions which cannot be inherited by - derived classes. When deriving from this type, the derived - class must provide its own definition for each of these functions. */ -#define CLASSTYPE_ABSTRACT_VIRTUALS(NODE) (TYPE_LANG_SPECIFIC(NODE)->abstract_virtuals) - -/* Nonzero means that this aggr type has been `closed' by a semicolon. */ -#define CLASSTYPE_GOT_SEMICOLON(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.got_semicolon) - -/* Nonzero means that the main virtual function table pointer needs to be - set because base constructors have placed the wrong value there. - If this is zero, it means that they placed the right value there, - and there is no need to change it. */ -#define CLASSTYPE_NEEDS_VIRTUAL_REINIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.needs_virtual_reinit) - -/* Nonzero means that if this type has virtual functions, that - the virtual function table will be written out. */ -#define CLASSTYPE_VTABLE_NEEDS_WRITING(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.vtable_needs_writing) - -/* Nonzero means that this type has an X() constructor. */ -#define TYPE_HAS_DEFAULT_CONSTRUCTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_default_ctor) - -/* Nonzero means the type declared a ctor as private or protected. We - use this to make sure we don't try to generate a copy ctor for a - class that has a member of type NODE. */ -#define TYPE_HAS_NONPUBLIC_CTOR(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_ctor) - -/* Ditto, for operator=. */ -#define TYPE_HAS_NONPUBLIC_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_nonpublic_assign_ref) - -/* Nonzero means that this type contains a mutable member */ -#define CLASSTYPE_HAS_MUTABLE(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_mutable) -#define TYPE_HAS_MUTABLE_P(NODE) (cp_has_mutable_p (NODE)) - -/* Many routines need to cons up a list of basetypes for access - checking. This field contains a TREE_LIST node whose TREE_VALUE - is the main variant of the type, and whose TREE_VIA_PUBLIC - and TREE_VIA_VIRTUAL bits are correctly set. */ -#define CLASSTYPE_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->as_list) -/* Same, but cache a list whose value is the name of this type. */ -#define CLASSTYPE_ID_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->id_as_list) -/* Same, but cache a list whose value is the binfo of this type. */ -#define CLASSTYPE_BINFO_AS_LIST(NODE) (TYPE_LANG_SPECIFIC(NODE)->binfo_as_list) - -/* A list of class types with which this type is a friend. The - TREE_VALUE is normally a TYPE, but will be a TEMPLATE_DECL in the - case of a template friend. */ -#define CLASSTYPE_FRIEND_CLASSES(NODE) (TYPE_LANG_SPECIFIC(NODE)->friend_classes) - -/* Say whether this node was declared as a "class" or a "struct". */ -#define CLASSTYPE_DECLARED_CLASS(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.declared_class) - -/* Nonzero if this class has const members which have no specified initialization. */ -#define CLASSTYPE_READONLY_FIELDS_NEED_INIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.const_needs_init) - -/* Nonzero if this class has ref members which have no specified initialization. */ -#define CLASSTYPE_REF_FIELDS_NEED_INIT(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.ref_needs_init) - -/* Nonzero if this class is included from a header file which employs - `#pragma interface', and it is not included in its implementation file. */ -#define CLASSTYPE_INTERFACE_ONLY(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_only) - -/* Same as above, but for classes whose purpose we do not know. */ -#define CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown) -#define CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown == 0) -#define SET_CLASSTYPE_INTERFACE_UNKNOWN_X(NODE,X) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = !!(X)) -#define SET_CLASSTYPE_INTERFACE_UNKNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = 1) -#define SET_CLASSTYPE_INTERFACE_KNOWN(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.interface_unknown = 0) - -/* Nonzero if a _DECL node requires us to output debug info for this class. */ -#define CLASSTYPE_DEBUG_REQUESTED(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.debug_requested) - -/* Additional macros for inheritance information. */ - -/* The BINFO_INHERITANCE_CHAIN is used opposite to the description in - gcc/tree.h. In particular if D is derived from B then the BINFO - for B (in D) will have a BINFO_INHERITANCE_CHAIN pointing to - D. In tree.h, this pointer is described as pointing in other - direction. - - After a call to get_vbase_types, the vbases are chained together in - depth-first order via TREE_CHAIN. Other than that, TREE_CHAIN is - unused. */ - -/* Nonzero means marked by DFS or BFS search, including searches - by `get_binfo' and `get_base_distance'. */ -#define BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED(BINFO_TYPE(NODE)):TREE_LANG_FLAG_0(NODE)) -/* Macros needed because of C compilers that don't allow conditional - expressions to be lvalues. Grr! */ -#define SET_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=1)) -#define CLEAR_BINFO_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_0(NODE)=0)) - -/* Nonzero means marked in search through virtual inheritance hierarchy. */ -#define BINFO_VBASE_MARKED(NODE) CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) -/* Modifier macros */ -#define SET_BINFO_VBASE_MARKED(NODE) SET_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) -#define CLEAR_BINFO_VBASE_MARKED(NODE) CLEAR_CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)) - -/* Nonzero means marked in search for members or member functions. */ -#define BINFO_FIELDS_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED2 (BINFO_TYPE (NODE)):TREE_LANG_FLAG_2(NODE)) -#define SET_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=1)) -#define CLEAR_BINFO_FIELDS_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED2(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_2(NODE)=0)) - -/* Nonzero means that this class is on a path leading to a new vtable. */ -#define BINFO_VTABLE_PATH_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):TREE_LANG_FLAG_3(NODE)) -#define SET_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=1)) -#define CLEAR_BINFO_VTABLE_PATH_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED3(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_3(NODE)=0)) - -/* Nonzero means that this class has a new vtable. */ -#define BINFO_NEW_VTABLE_MARKED(NODE) \ - (TREE_VIA_VIRTUAL(NODE)?CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):TREE_LANG_FLAG_4(NODE)) -#define SET_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?SET_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=1)) -#define CLEAR_BINFO_NEW_VTABLE_MARKED(NODE) (TREE_VIA_VIRTUAL(NODE)?CLEAR_CLASSTYPE_MARKED4(BINFO_TYPE(NODE)):(TREE_LANG_FLAG_4(NODE)=0)) - -/* Nonzero means this class has done dfs_pushdecls. */ -#define BINFO_PUSHDECLS_MARKED(NODE) BINFO_VTABLE_PATH_MARKED (NODE) -#define SET_BINFO_PUSHDECLS_MARKED(NODE) SET_BINFO_VTABLE_PATH_MARKED (NODE) -#define CLEAR_BINFO_PUSHDECLS_MARKED(NODE) CLEAR_BINFO_VTABLE_PATH_MARKED (NODE) - -/* Used by various search routines. */ -#define IDENTIFIER_MARKED(NODE) TREE_LANG_FLAG_0 (NODE) - -/* Accessor macros for the vfield slots in structures. */ - -/* Get the assoc info that caused this vfield to exist. */ -#define VF_BINFO_VALUE(NODE) TREE_PURPOSE (NODE) - -/* Get that same information as a _TYPE. */ -#define VF_BASETYPE_VALUE(NODE) TREE_VALUE (NODE) - -/* Get the value of the top-most type dominating the non-`normal' vfields. */ -#define VF_DERIVED_VALUE(NODE) (VF_BINFO_VALUE (NODE) ? BINFO_TYPE (VF_BINFO_VALUE (NODE)) : NULL_TREE) - -/* Get the value of the top-most type that's `normal' for the vfield. */ -#define VF_NORMAL_VALUE(NODE) TREE_TYPE (NODE) - -/* Nonzero for TREE_LIST node means that this list of things - is a list of parameters, as opposed to a list of expressions. */ -#define TREE_PARMLIST(NODE) ((NODE)->common.unsigned_flag) /* overloaded! */ - -/* For FUNCTION_TYPE or METHOD_TYPE, a list of the exceptions that - this type can raise. Each TREE_VALUE is a _TYPE. The TREE_VALUE - will be NULL_TREE to indicate a throw specification of `(...)', or, - equivalently, no throw specification. */ -#define TYPE_RAISES_EXCEPTIONS(NODE) TYPE_NONCOPIED_PARTS (NODE) - -/* The binding level associated with the namespace. */ -#define NAMESPACE_LEVEL(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.level) - -struct lang_decl_flags -{ -#ifdef ONLY_INT_FIELDS - int language : 8; -#else - enum languages language : 8; -#endif - - unsigned operator_attr : 1; - unsigned constructor_attr : 1; - unsigned returns_first_arg : 1; - unsigned preserves_first_arg : 1; - unsigned friend_attr : 1; - unsigned static_function : 1; - unsigned const_memfunc : 1; - unsigned volatile_memfunc : 1; - - unsigned abstract_virtual : 1; - unsigned permanent_attr : 1 ; - unsigned constructor_for_vbase_attr : 1; - unsigned mutable_flag : 1; - unsigned is_default_implementation : 1; - unsigned saved_inline : 1; - unsigned use_template : 2; - - unsigned nonconverting : 1; - unsigned declared_inline : 1; - unsigned not_really_extern : 1; - unsigned comdat : 1; - unsigned needs_final_overrider : 1; - unsigned bitfield : 1; - unsigned defined_in_class : 1; - unsigned dummy : 1; - - tree access; - tree context; - tree memfunc_pointer_to; - tree template_info; - struct binding_level *level; -}; - -struct lang_decl -{ - struct lang_decl_flags decl_flags; - - tree main_decl_variant; - struct pending_inline *pending_inline_info; -}; - -/* Non-zero if NODE is a _DECL with TREE_READONLY set. */ -#define TREE_READONLY_DECL_P(NODE) \ - (TREE_READONLY (NODE) && TREE_CODE_CLASS (TREE_CODE (NODE)) == 'd') - -/* Non-zero iff DECL is memory-based. The DECL_RTL of - certain const variables might be a CONST_INT, or a REG - in some cases. We cannot use `memory_operand' as a test - here because on most RISC machines, a variable's address - is not, by itself, a legitimate address. */ -#define DECL_IN_MEMORY_P(NODE) \ - (DECL_RTL (NODE) != NULL_RTX && GET_CODE (DECL_RTL (NODE)) == MEM) - -/* For FUNCTION_DECLs: return the language in which this decl - was declared. */ -#define DECL_LANGUAGE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.language) - -/* For FUNCTION_DECLs: nonzero means that this function is a constructor. */ -#define DECL_CONSTRUCTOR_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_attr) - -/* 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) - -#define DECL_CONV_FN_P(NODE) \ - (IDENTIFIER_TYPENAME_P (DECL_NAME (NODE)) && TREE_TYPE (DECL_NAME (NODE))) - -/* For FUNCTION_DECLs: nonzero means that this function is a constructor - for an object with virtual baseclasses. */ -#define DECL_CONSTRUCTOR_FOR_VBASE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.constructor_for_vbase_attr) - -/* For FUNCTION_DECLs: nonzero means that this function is a default - implementation of a signature method. */ -#define IS_DEFAULT_IMPLEMENTATION(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.is_default_implementation) - -/* For FUNCTION_DECLs: nonzero means that the constructor - is known to return a non-zero `this' unchanged. */ -#define DECL_RETURNS_FIRST_ARG(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.returns_first_arg) - -/* Nonzero for FUNCTION_DECL means that this constructor is known to - not make any assignment to `this', and therefore can be trusted - to return it unchanged. Otherwise, we must re-assign `current_class_ptr' - after performing base initializations. */ -#define DECL_PRESERVES_THIS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.preserves_first_arg) - -/* Nonzero for _DECL means that this decl appears in (or will appear - in) as a member in a RECORD_TYPE or UNION_TYPE node. It is also for - detecting circularity in case members are multiply defined. In the - case of a VAR_DECL, it is also used to determine how program storage - should be allocated. */ -#define DECL_IN_AGGR_P(NODE) (DECL_LANG_FLAG_3(NODE)) - -/* Nonzero if the DECL was defined in the class definition itself, - rather than outside the class. */ -#define DECL_DEFINED_IN_CLASS_P(DECL) \ - (DECL_LANG_SPECIFIC (DECL)->decl_flags.defined_in_class) - -/* Nonzero for FUNCTION_DECL means that this decl is just a - friend declaration, and should not be added to the list of - member functions for this class. */ -#define DECL_FRIEND_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.friend_attr) - -/* Nonzero for FUNCTION_DECL means that this decl is a static - member function. */ -#define DECL_STATIC_FUNCTION_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.static_function) - -/* Nonzero for a class member means that it is shared between all objects - of that class. */ -#define SHARED_MEMBER_P(NODE) \ - (TREE_CODE (NODE) == VAR_DECL || TREE_CODE (NODE) == TYPE_DECL \ - || TREE_CODE (NODE) == CONST_DECL) - -/* Nonzero for FUNCTION_DECL means that this decl is a non-static - member function. */ -#define DECL_NONSTATIC_MEMBER_FUNCTION_P(NODE) \ - (TREE_CODE (TREE_TYPE (NODE)) == METHOD_TYPE) - -/* Nonzero for FUNCTION_DECL means that this decl is a member function - (static or non-static). */ -#define DECL_FUNCTION_MEMBER_P(NODE) \ - (DECL_NONSTATIC_MEMBER_FUNCTION_P (NODE) || DECL_STATIC_FUNCTION_P (NODE)) - -/* 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) - -/* Nonzero for _DECL means that this member object type - is mutable. */ -#define DECL_MUTABLE_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.mutable_flag) - -/* Nonzero for _DECL means that this constructor is a non-converting - constructor. */ -#define DECL_NONCONVERTING_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.nonconverting) - -/* Nonzero for FUNCTION_DECL means that this member function - exists as part of an abstract class's interface. */ -#define DECL_ABSTRACT_VIRTUAL_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.abstract_virtual) - -/* Nonzero for FUNCTION_DECL means that this member function - must be overridden by derived classes. */ -#define DECL_NEEDS_FINAL_OVERRIDER_P(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.needs_final_overrider) - -/* Nonzero if allocated on permanent_obstack. */ -#define LANG_DECL_PERMANENT(LANGDECL) ((LANGDECL)->decl_flags.permanent_attr) - -/* The _TYPE context in which this _DECL appears. This field holds the - class where a virtual function instance is actually defined, and the - lexical scope of a friend function defined in a class body. */ -#define DECL_CLASS_CONTEXT(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.context) -#define DECL_REAL_CONTEXT(NODE) \ - ((TREE_CODE (NODE) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (NODE)) \ - ? DECL_CLASS_CONTEXT (NODE) : CP_DECL_CONTEXT (NODE)) - -/* NULL_TREE in DECL_CONTEXT represents the global namespace. */ -#define CP_DECL_CONTEXT(NODE) \ - (DECL_CONTEXT (NODE) ? DECL_CONTEXT (NODE) : global_namespace) -#define FROB_CONTEXT(NODE) ((NODE) == global_namespace ? NULL_TREE : (NODE)) - -/* 1 iff NODE has namespace scope, including the global namespace. */ -#define DECL_NAMESPACE_SCOPE_P(NODE) \ - (DECL_CONTEXT (NODE) == NULL_TREE \ - || TREE_CODE (DECL_CONTEXT (NODE)) == NAMESPACE_DECL) - -/* 1 iff NODE is a class member. */ -#define DECL_CLASS_SCOPE_P(NODE) \ - (DECL_CONTEXT (NODE) \ - && TREE_CODE_CLASS (TREE_CODE (DECL_CONTEXT (NODE))) == 't') - -/* 1 iff NODE is function-local. */ -#define DECL_FUNCTION_SCOPE_P(NODE) \ - (DECL_CONTEXT (NODE) \ - && TREE_CODE (DECL_CONTEXT (NODE)) == FUNCTION_DECL) - -/* For a NAMESPACE_DECL: the list of using namespace directives - The PURPOSE is the used namespace, the value is the namespace - that is the common ancestor. */ -#define DECL_NAMESPACE_USING(NODE) DECL_VINDEX(NODE) - -/* In a NAMESPACE_DECL, the DECL_INITIAL is used to record all users - of a namespace, to record the transitive closure of using namespace. */ -#define DECL_NAMESPACE_USERS(NODE) DECL_INITIAL (NODE) - -/* In a NAMESPACE_DECL, points to the original namespace if this is - a namespace alias. */ -#define DECL_NAMESPACE_ALIAS(NODE) DECL_ABSTRACT_ORIGIN (NODE) -#define ORIGINAL_NAMESPACE(NODE) \ - (DECL_NAMESPACE_ALIAS (NODE) ? DECL_NAMESPACE_ALIAS (NODE) : (NODE)) - -/* In a TREE_LIST concatenating using directives, indicate indirekt - directives */ -#define TREE_INDIRECT_USING(NODE) ((NODE)->common.lang_flag_0) - -/* In a VAR_DECL for a variable declared in a for statement, - this is the shadowed (local) variable. */ -#define DECL_SHADOWED_FOR_VAR(NODE) DECL_RESULT(NODE) - -/* Points back to the decl which caused this lang_decl to be allocated. */ -#define DECL_MAIN_VARIANT(NODE) (DECL_LANG_SPECIFIC(NODE)->main_decl_variant) - -/* For a FUNCTION_DECL: if this function was declared inline inside of - a class declaration, this is where the text for the function is - squirreled away. */ -#define DECL_PENDING_INLINE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->pending_inline_info) - -/* True if on the saved_inlines (see decl2.c) list. */ -#define DECL_SAVED_INLINE(DECL) \ - (DECL_LANG_SPECIFIC(DECL)->decl_flags.saved_inline) - -/* For a FUNCTION_DECL: if this function was declared inside a signature - declaration, this is the corresponding member function pointer that was - created for it. */ -#define DECL_MEMFUNC_POINTER_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) - -/* For a FIELD_DECL: this points to the signature member function from - which this signature member function pointer was created. */ -#define DECL_MEMFUNC_POINTING_TO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.memfunc_pointer_to) - -/* For a VAR_DECL or FUNCTION_DECL: template-specific information. */ -#define DECL_TEMPLATE_INFO(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.template_info) - -/* Template information for a RECORD_TYPE or UNION_TYPE. */ -#define CLASSTYPE_TEMPLATE_INFO(NODE) (TYPE_LANG_SPECIFIC(NODE)->template_info) - -/* Template information for an ENUMERAL_TYPE. Although an enumeration may - not be a primary template, it may be declared within the scope of a - primary template and the enumeration constants may depend on - non-type template parameters. */ -#define ENUM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) - -/* Template information for a template template parameter. */ -#define TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO(NODE) (TYPE_BINFO (NODE)) - -/* Template information for an ENUMERAL_, RECORD_, or UNION_TYPE. */ -#define TYPE_TEMPLATE_INFO(NODE) \ - (TREE_CODE (NODE) == ENUMERAL_TYPE \ - ? ENUM_TEMPLATE_INFO (NODE) : \ - (TREE_CODE (NODE) == TEMPLATE_TEMPLATE_PARM \ - ? TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (NODE) \ - : CLASSTYPE_TEMPLATE_INFO (NODE))) - -/* Set the template information for an ENUMERAL_, RECORD_, or - UNION_TYPE to VAL. */ -#define SET_TYPE_TEMPLATE_INFO(NODE, VAL) \ - (TREE_CODE (NODE) == ENUMERAL_TYPE \ - ? (ENUM_TEMPLATE_INFO (NODE) = VAL) \ - : (CLASSTYPE_TEMPLATE_INFO (NODE) = VAL)) - -#define TI_TEMPLATE(NODE) (TREE_PURPOSE (NODE)) -#define TI_ARGS(NODE) (TREE_VALUE (NODE)) -#define TI_SPEC_INFO(NODE) (TREE_CHAIN (NODE)) -#define TI_PENDING_TEMPLATE_FLAG(NODE) TREE_LANG_FLAG_1 (NODE) - -/* The TEMPLATE_DECL instantiated or specialized by NODE. This - TEMPLATE_DECL will be the immediate parent, not the most general - template. For example, in: - - template <class T> struct S { template <class U> void f(U); } - - the FUNCTION_DECL for S<int>::f<double> will have, as its - DECL_TI_TEMPLATE, `template <class U> S<int>::f<U>'. - - As a special case, for a member friend template of a template - class, this value will not be a TEMPLATE_DECL, but rather a - LOOKUP_EXPR or IDENTIFIER_NODE indicating the name of the template - and any explicit template arguments provided. For example, in: - - template <class T> struct S { friend void f<int>(int, double); } - - the DECL_TI_TEMPLATE will be a LOOKUP_EXPR for `f' and the - DECL_TI_ARGS will be {int}. */ -#define DECL_TI_TEMPLATE(NODE) TI_TEMPLATE (DECL_TEMPLATE_INFO (NODE)) - -/* The template arguments used to obtain this decl from the most - general form of DECL_TI_TEMPLATE. For the example given for - DECL_TI_TEMPLATE, the DECL_TI_ARGS will be {int, double}. These - are always the full set of arguments required to instantiate this - declaration from the most general template specialized here. */ -#define DECL_TI_ARGS(NODE) TI_ARGS (DECL_TEMPLATE_INFO (NODE)) -#define CLASSTYPE_TI_TEMPLATE(NODE) TI_TEMPLATE (CLASSTYPE_TEMPLATE_INFO (NODE)) -#define CLASSTYPE_TI_ARGS(NODE) TI_ARGS (CLASSTYPE_TEMPLATE_INFO (NODE)) -#define CLASSTYPE_TI_SPEC_INFO(NODE) TI_SPEC_INFO (CLASSTYPE_TEMPLATE_INFO (NODE)) -#define ENUM_TI_TEMPLATE(NODE) \ - TI_TEMPLATE (ENUM_TEMPLATE_INFO (NODE)) -#define ENUM_TI_ARGS(NODE) \ - TI_ARGS (ENUM_TEMPLATE_INFO (NODE)) - -/* Like DECL_TI_TEMPLATE, but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ -#define TYPE_TI_TEMPLATE(NODE) \ - (TI_TEMPLATE (TYPE_TEMPLATE_INFO (NODE))) - -/* Like DECL_TI_ARGS, , but for an ENUMERAL_, RECORD_, or UNION_TYPE. */ -#define TYPE_TI_ARGS(NODE) \ - (TI_ARGS (TYPE_TEMPLATE_INFO (NODE))) - -#define INNERMOST_TEMPLATE_PARMS(NODE) TREE_VALUE(NODE) - -/* Nonzero if the NODE corresponds to the template parameters for a - member template, whose inline definition is being processed after - the class definition is complete. */ -#define TEMPLATE_PARMS_FOR_INLINE(NODE) TREE_LANG_FLAG_1 (NODE) - -#define DECL_SAVED_TREE(NODE) DECL_MEMFUNC_POINTER_TO (NODE) -#define COMPOUND_STMT_NO_SCOPE(NODE) TREE_LANG_FLAG_0 (NODE) -#define NEW_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) -#define DELETE_EXPR_USE_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) -#define DELETE_EXPR_USE_VEC(NODE) TREE_LANG_FLAG_1 (NODE) -#define LOOKUP_EXPR_GLOBAL(NODE) TREE_LANG_FLAG_0 (NODE) - -/* The TYPE_MAIN_DECL for a class template type is a TYPE_DECL, not a - TEMPLATE_DECL. This macro determines whether or not a given class - type is really a template type, as opposed to an instantiation or - specialization of one. */ -#define CLASSTYPE_IS_TEMPLATE(NODE) \ - (CLASSTYPE_TEMPLATE_INFO (NODE) \ - && !CLASSTYPE_USE_TEMPLATE (NODE) \ - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (NODE))) - -/* The name used by the user to name the typename type. Typically, - this is an IDENTIFIER_NODE, and the same as the DECL_NAME on the - corresponding TYPE_DECL. However, this may also be a - TEMPLATE_ID_EXPR if we had something like `typename X::Y<T>'. */ -#define TYPENAME_TYPE_FULLNAME(NODE) TYPE_BINFO (NODE) - -/* Nonzero if NODE is an implicit typename. */ -#define IMPLICIT_TYPENAME_P(NODE) \ - (TREE_CODE (NODE) == TYPENAME_TYPE && TREE_TYPE (NODE)) - -/* Nonzero in INTEGER_CST means that this int is negative by dint of - using a twos-complement negated operand. */ -#define TREE_NEGATED_INT(NODE) (TREE_LANG_FLAG_0 (NODE)) - -#if 0 /* UNUSED */ -/* Nonzero in any kind of _EXPR or _REF node means that it is a call - to a storage allocation routine. If, later, alternate storage - is found to hold the object, this call can be ignored. */ -#define TREE_CALLS_NEW(NODE) (TREE_LANG_FLAG_1 (NODE)) -#endif - -/* Nonzero in any kind of _TYPE that uses multiple inheritance - or virtual baseclasses. */ -#define TYPE_USES_COMPLEX_INHERITANCE(NODE) (TREE_LANG_FLAG_1 (NODE)) - -#if 0 /* UNUSED */ -/* Nonzero in IDENTIFIER_NODE means that this name is not the name the user - gave; it's a DECL_NESTED_TYPENAME. Someone may want to set this on - mangled function names, too, but it isn't currently. */ -#define TREE_MANGLED(NODE) (FOO) -#endif - -#if 0 /* UNUSED */ -/* Nonzero in IDENTIFIER_NODE means that this name is overloaded, and - should be looked up in a non-standard way. */ -#define DECL_OVERLOADED(NODE) (FOO) -#endif - -/* Nonzero if this (non-TYPE)_DECL has its virtual attribute set. - For a FUNCTION_DECL, this is when the function is a virtual function. - For a VAR_DECL, this is when the variable is a virtual function table. - For a FIELD_DECL, when the field is the field for the virtual function table. - For an IDENTIFIER_NODE, nonzero if any function with this name - has been declared virtual. - - For a _TYPE if it uses virtual functions (or is derived from - one that does). */ -#define TYPE_VIRTUAL_P(NODE) (TREE_LANG_FLAG_2 (NODE)) - -extern int flag_new_for_scope; - -/* This flag is true of a local VAR_DECL if it was declared in a for - statement, but we are no longer in the scope of the for. */ -#define DECL_DEAD_FOR_LOCAL(NODE) DECL_LANG_FLAG_7 (NODE) - -/* This flag is set on a VAR_DECL that is a DECL_DEAD_FOR_LOCAL - if we already emitted a warning about using it. */ -#define DECL_ERROR_REPORTED(NODE) DECL_LANG_FLAG_0 (NODE) - -/* This _DECL represents a compiler-generated entity. */ -#define SET_DECL_ARTIFICIAL(NODE) (DECL_ARTIFICIAL (NODE) = 1) - -/* Record whether a typedef for type `int' was actually `signed int'. */ -#define C_TYPEDEF_EXPLICITLY_SIGNED(exp) DECL_LANG_FLAG_1 ((exp)) - -/* In a FIELD_DECL, nonzero if the decl was originally a bitfield. */ -#define DECL_C_BIT_FIELD(NODE) \ - (DECL_LANG_SPECIFIC (NODE) && DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield) -#define SET_DECL_C_BIT_FIELD(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.bitfield = 1) - -/* Nonzero if the type T promotes to itself. - ANSI C states explicitly the list of types that promote; - in particular, short promotes to int even if they have the same width. */ -#define C_PROMOTING_INTEGER_TYPE_P(t) \ - (TREE_CODE ((t)) == INTEGER_TYPE \ - && (TYPE_MAIN_VARIANT (t) == char_type_node \ - || TYPE_MAIN_VARIANT (t) == signed_char_type_node \ - || TYPE_MAIN_VARIANT (t) == unsigned_char_type_node \ - || TYPE_MAIN_VARIANT (t) == short_integer_type_node \ - || TYPE_MAIN_VARIANT (t) == short_unsigned_type_node)) - -#define INTEGRAL_CODE_P(CODE) \ - (CODE == INTEGER_TYPE || CODE == ENUMERAL_TYPE || CODE == BOOLEAN_TYPE) -#define ARITHMETIC_TYPE_P(TYPE) (INTEGRAL_TYPE_P (TYPE) || FLOAT_TYPE_P (TYPE)) - -/* Mark which labels are explicitly declared. - These may be shadowed, and may be referenced from nested functions. */ -#define C_DECLARED_LABEL_FLAG(label) TREE_LANG_FLAG_1 (label) - -/* Nonzero for _TYPE means that the _TYPE defines - at least one constructor. */ -#define TYPE_HAS_CONSTRUCTOR(NODE) (TYPE_LANG_FLAG_1(NODE)) - -/* When appearing in an INDIRECT_REF, it means that the tree structure - underneath is actually a call to a constructor. This is needed - when the constructor must initialize local storage (which can - be automatically destroyed), rather than allowing it to allocate - space from the heap. - - When appearing in a SAVE_EXPR, it means that underneath - is a call to a constructor. - - When appearing in a CONSTRUCTOR, it means that it was - a GNU C constructor expression. - - When appearing in a FIELD_DECL, it means that this field - has been duly initialized in its constructor. */ -#define TREE_HAS_CONSTRUCTOR(NODE) (TREE_LANG_FLAG_4(NODE)) - -#define EMPTY_CONSTRUCTOR_P(NODE) (TREE_CODE (NODE) == CONSTRUCTOR \ - && CONSTRUCTOR_ELTS (NODE) == NULL_TREE \ - && ! TREE_HAS_CONSTRUCTOR (NODE)) - -#if 0 -/* Indicates that a NON_LVALUE_EXPR came from a C++ reference. - Used to generate more helpful error message in case somebody - tries to take its address. */ -#define TREE_REFERENCE_EXPR(NODE) (TREE_LANG_FLAG_3(NODE)) -#endif - -/* Nonzero for _TYPE means that the _TYPE defines a destructor. */ -#define TYPE_HAS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_2(NODE)) - -#if 0 -/* Nonzero for _TYPE node means that creating an object of this type - will involve a call to a constructor. This can apply to objects - of ARRAY_TYPE if the type of the elements needs a constructor. */ -#define TYPE_NEEDS_CONSTRUCTING(NODE) ... defined in ../tree.h ... -#endif - -/* Nonzero means that an object of this type can not be initialized using - an initializer list. */ -#define CLASSTYPE_NON_AGGREGATE(NODE) \ - (TYPE_LANG_SPECIFIC (NODE)->type_flags.non_aggregate) -#define TYPE_NON_AGGREGATE_CLASS(NODE) \ - (IS_AGGR_TYPE (NODE) && CLASSTYPE_NON_AGGREGATE (NODE)) - -/* Nonzero if there is a user-defined X::op=(x&) for this class. */ -#define TYPE_HAS_REAL_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_real_assign_ref) -#define TYPE_HAS_COMPLEX_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_assign_ref) -#define TYPE_HAS_ABSTRACT_ASSIGN_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_abstract_assign_ref) -#define TYPE_HAS_COMPLEX_INIT_REF(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.has_complex_init_ref) - -/* Nonzero for _TYPE node means that destroying an object of this type - will involve a call to a destructor. This can apply to objects - of ARRAY_TYPE is the type of the elements needs a destructor. */ -#define TYPE_NEEDS_DESTRUCTOR(NODE) (TYPE_LANG_FLAG_4(NODE)) - -/* Nonzero for class type means that initialization of this type can use - a bitwise copy. */ -#define TYPE_HAS_TRIVIAL_INIT_REF(NODE) \ - (TYPE_HAS_INIT_REF (NODE) && ! TYPE_HAS_COMPLEX_INIT_REF (NODE)) - -/* Nonzero for class type means that assignment of this type can use - a bitwise copy. */ -#define TYPE_HAS_TRIVIAL_ASSIGN_REF(NODE) \ - (TYPE_HAS_ASSIGN_REF (NODE) && ! TYPE_HAS_COMPLEX_ASSIGN_REF (NODE)) - -#define TYPE_PTRMEM_P(NODE) \ - (TREE_CODE (NODE) == POINTER_TYPE \ - && TREE_CODE (TREE_TYPE (NODE)) == OFFSET_TYPE) -#define TYPE_PTR_P(NODE) \ - (TREE_CODE (NODE) == POINTER_TYPE \ - && TREE_CODE (TREE_TYPE (NODE)) != OFFSET_TYPE) -#define TYPE_PTROB_P(NODE) \ - (TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE \ - && TREE_CODE (TREE_TYPE (NODE)) != VOID_TYPE) -#define TYPE_PTROBV_P(NODE) \ - (TYPE_PTR_P (NODE) && TREE_CODE (TREE_TYPE (NODE)) != FUNCTION_TYPE) -#define TYPE_PTRFN_P(NODE) \ - (TREE_CODE (NODE) == POINTER_TYPE \ - && TREE_CODE (TREE_TYPE (NODE)) == FUNCTION_TYPE) - -/* Nonzero for _TYPE node means that this type is a pointer to member - function type. */ -#define TYPE_PTRMEMFUNC_P(NODE) (TREE_CODE(NODE) == RECORD_TYPE && TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) -#define TYPE_PTRMEMFUNC_FLAG(NODE) (TYPE_LANG_SPECIFIC(NODE)->type_flags.ptrmemfunc_flag) -/* Get the POINTER_TYPE to the METHOD_TYPE associated with this - pointer to member function. TYPE_PTRMEMFUNC_P _must_ be true, - before using this macro. */ -#define TYPE_PTRMEMFUNC_FN_TYPE(NODE) (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (TREE_CHAIN (TREE_CHAIN (TYPE_FIELDS (NODE))))))) - -/* Returns `A' for a type like `int (A::*)(double)' */ -#define TYPE_PTRMEMFUNC_OBJECT_TYPE(NODE) \ - TYPE_METHOD_BASETYPE (TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (NODE))) - -/* These are use to manipulate the canonical RECORD_TYPE from the - hashed POINTER_TYPE, and can only be used on the POINTER_TYPE. */ -#define TYPE_GET_PTRMEMFUNC_TYPE(NODE) ((tree)TYPE_LANG_SPECIFIC(NODE)) -#define TYPE_SET_PTRMEMFUNC_TYPE(NODE, VALUE) (TYPE_LANG_SPECIFIC(NODE) = ((struct lang_type *)(void*)(VALUE))) -/* These are to get the delta2 and pfn fields from a TYPE_PTRMEMFUNC_P. */ -#define DELTA2_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), delta2_identifier, NULL_TREE, 0)) -#define PFN_FROM_PTRMEMFUNC(NODE) (build_component_ref (build_component_ref ((NODE), pfn_or_delta2_identifier, NULL_TREE, 0), pfn_identifier, NULL_TREE, 0)) - -/* For a pointer-to-member constant `X::Y' this is the RECORD_TYPE for - `X'. */ -#define PTRMEM_CST_CLASS(NODE) \ - (TYPE_PTRMEM_P (TREE_TYPE (NODE)) \ - ? TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (NODE))) \ - : TYPE_PTRMEMFUNC_OBJECT_TYPE (TREE_TYPE (NODE))) - -/* For a pointer-to-member constant `X::Y' this is the _DECL for - `Y'. */ -#define PTRMEM_CST_MEMBER(NODE) (((ptrmem_cst_t) NODE)->member) - -/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `extern' was - specified in its declaration. */ -#define DECL_THIS_EXTERN(NODE) (DECL_LANG_FLAG_2(NODE)) - -/* Nonzero for VAR_DECL and FUNCTION_DECL node means that `static' was - specified in its declaration. */ -#define DECL_THIS_STATIC(NODE) (DECL_LANG_FLAG_6(NODE)) - -/* Nonzero in FUNCTION_DECL means it is really an operator. - Just used to communicate formatting information to dbxout.c. */ -#define DECL_OPERATOR(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.operator_attr) - -#define ANON_UNION_P(NODE) (DECL_NAME (NODE) == 0) - -/* Nonzero if TYPE is an anonymous union type. */ -#define ANON_UNION_TYPE_P(TYPE) \ - (TREE_CODE (TYPE) == UNION_TYPE \ - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (TYPE))) - -#define UNKNOWN_TYPE LANG_TYPE - -/* Define fields and accessors for nodes representing declared names. */ - -#if 0 -/* C++: A derived class may be able to directly use the virtual - function table of a base class. When it does so, it may - still have a decl node used to access the virtual function - table (so that variables of this type can initialize their - virtual function table pointers by name). When such thievery - is committed, know exactly which base class's virtual function - table is the one being stolen. This effectively computes the - transitive closure. */ -#define DECL_VPARENT(NODE) ((NODE)->decl.arguments) -#endif - -#define TYPE_WAS_ANONYMOUS(NODE) (TYPE_LANG_SPECIFIC (NODE)->type_flags.was_anonymous) - -/* C++: all of these are overloaded! These apply only to TYPE_DECLs. */ - -/* The format of each node in the DECL_FRIENDLIST is as follows: - - The TREE_PURPOSE will be the name of a function, i.e., an - IDENTIFIER_NODE. The TREE_VALUE will be itself a TREE_LIST, the - list of functions with that name which are friends. The - TREE_PURPOSE of each node in this sublist will be error_mark_node, - if the function was declared a friend individually, in which case - the TREE_VALUE will be the function_decl. If, however, all - functions with a given name in a class were declared to be friends, - the TREE_PUROSE will be the class type, and the TREE_VALUE will be - NULL_TREE. */ -#define DECL_FRIENDLIST(NODE) (DECL_INITIAL (NODE)) - -/* The DECL_ACCESS, if non-NULL, is a TREE_LIST. The TREE_PURPOSE of - each node is a type; the TREE_VALUE is the access granted for this - DECL in that type. The DECL_ACCESS is set by access declarations. - For example, if a member that would normally be public in a - derived class is made protected, then the derived class and the - protected_access_node will appear in the DECL_ACCESS for the node. */ -#define DECL_ACCESS(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.access) - -/* C++: all of these are overloaded! - These apply to PARM_DECLs and VAR_DECLs. */ -#define DECL_REFERENCE_SLOT(NODE) ((tree)(NODE)->decl.arguments) -#define SET_DECL_REFERENCE_SLOT(NODE,VAL) ((NODE)->decl.arguments=VAL) - -/* Accessor macros for C++ template decl nodes. */ - -/* The DECL_TEMPLATE_PARMS are a list. The TREE_PURPOSE of each node - is a INT_CST whose TREE_INT_CST_HIGH indicates the level of the - template parameters, with 1 being the outermost set of template - parameters. The TREE_VALUE is a vector, whose elements are the - template parameters at each level. Each element in the vector is a - TREE_LIST, whose TREE_VALUE is a PARM_DECL (if the parameter is a - non-type parameter), or a TYPE_DECL (if the parameter is a type - parameter). The TREE_PURPOSE is the default value, if any. The - TEMPLATE_PARM_INDEX for the parameter is avilable as the - DECL_INITIAL (for a PARM_DECL) or as the TREE_TYPE (for a - TYPE_DECL). */ -#define DECL_TEMPLATE_PARMS(NODE) DECL_ARGUMENTS(NODE) -#define DECL_INNERMOST_TEMPLATE_PARMS(NODE) \ - INNERMOST_TEMPLATE_PARMS (DECL_TEMPLATE_PARMS (NODE)) -#define DECL_NTPARMS(NODE) \ - TREE_VEC_LENGTH (DECL_INNERMOST_TEMPLATE_PARMS (NODE)) -/* For function, method, class-data templates. */ -#define DECL_TEMPLATE_RESULT(NODE) DECL_RESULT(NODE) -/* For a static member variable template, the - DECL_TEMPLATE_INSTANTIATIONS list contains the explicitly and - implicitly generated instantiations of the variable. There are no - partial instantiations of static member variables, so all of these - will be full instantiations. - - For a class template the DECL_TEMPLATE_INSTANTIATIONS lists holds - all instantiations and specializations of the class type, including - partial instantiations and partial specializations. - - In both cases, the TREE_PURPOSE of each node contains the arguments - used; the TREE_VALUE contains the generated variable. The template - arguments are always complete. For example, given: - - template <class T> struct S1 { - template <class U> struct S2 {}; - template <class U> struct S2<U*> {}; - }; - - the record for the partial specialization will contain, as its - argument list, { {T}, {U*} }, and will be on the - DECL_TEMPLATE_INSTANTIATIONS list for `template <class T> template - <class U> struct S1<T>::S2'. - - This list is not used for function templates. */ -#define DECL_TEMPLATE_INSTANTIATIONS(NODE) DECL_VINDEX(NODE) -/* For a function template, the DECL_TEMPLATE_SPECIALIZATIONS lists - contains all instantiations and specializations of the function, - including partial instantiations. For a partial instantiation - which is a specialization, this list holds only full - specializations of the template that are instantiations of the - partial instantiation. For example, given: - - template <class T> struct S { - template <class U> void f(U); - template <> void f(T); - }; - - the `S<int>::f<int>(int)' function will appear on the - DECL_TEMPLATE_SPECIALIZATIONS list for both `template <class T> - template <class U> void S<T>::f(U)' and `template <class T> void - S<int>::f(T)'. In the latter case, however, it will have only the - innermost set of arguments (T, in this case). The DECL_TI_TEMPLATE - for the function declaration will point at the specialization, not - the fully general template. - - For a class template, this list contains the partial - specializations of this template. (Full specializations are not - recorded on this list.) The TREE_PURPOSE holds the innermost - arguments used in the partial specialization (e.g., for `template - <class T> struct S<T*, int>' this will be `T*'.) The TREE_VALUE - holds the innermost template parameters for the specialization - (e.g., `T' in the example above.) The TREE_TYPE is the _TYPE node - for the partial specialization. - - This list is not used for static variable templates. */ -#define DECL_TEMPLATE_SPECIALIZATIONS(NODE) DECL_SIZE(NODE) -#define DECL_TEMPLATE_INJECT(NODE) DECL_INITIAL(NODE) - -/* Nonzero for a DECL which is actually a template parameter. */ -#define DECL_TEMPLATE_PARM_P(NODE) \ - DECL_LANG_FLAG_0 (NODE) - -#define DECL_TEMPLATE_TEMPLATE_PARM_P(NODE) \ - (TREE_CODE (NODE) == TEMPLATE_DECL && DECL_TEMPLATE_PARM_P (NODE)) - -#define DECL_FUNCTION_TEMPLATE_P(NODE) \ - (TREE_CODE (NODE) == TEMPLATE_DECL \ - && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == FUNCTION_DECL) - -/* Nonzero for a DECL that represents a template class. */ -#define DECL_CLASS_TEMPLATE_P(NODE) \ - (TREE_CODE (NODE) == TEMPLATE_DECL \ - && TREE_CODE (DECL_TEMPLATE_RESULT (NODE)) == TYPE_DECL \ - && !DECL_TEMPLATE_TEMPLATE_PARM_P (NODE)) - -/* Nonzero if NODE which declares a type. */ -#define DECL_DECLARES_TYPE_P(NODE) \ - (TREE_CODE (NODE) == TYPE_DECL || DECL_CLASS_TEMPLATE_P (NODE)) - -/* A `primary' template is one that has its own template header. A - member function of a class template is a template, but not primary. - A member template is primary. Friend templates are primary, too. */ - -/* Returns the primary template corresponding to these parameters. */ -#define DECL_PRIMARY_TEMPLATE(NODE) \ - (TREE_TYPE (DECL_INNERMOST_TEMPLATE_PARMS (NODE))) - -/* Returns non-zero if NODE is a primary template. */ -#define PRIMARY_TEMPLATE_P(NODE) (DECL_PRIMARY_TEMPLATE (NODE) == NODE) - -#define CLASSTYPE_TEMPLATE_LEVEL(NODE) \ - (TREE_INT_CST_HIGH (TREE_PURPOSE (CLASSTYPE_TI_TEMPLATE (NODE)))) - -/* Indicates whether or not (and how) a template was expanded for this - FUNCTION_DECL or VAR_DECL. - 0=normal declaration, e.g. int min (int, int); - 1=implicit template instantiation - 2=explicit template specialization, e.g. int min<int> (int, int); - 3=explicit template instantiation, e.g. template int min<int> (int, int); */ -#define DECL_USE_TEMPLATE(NODE) (DECL_LANG_SPECIFIC(NODE)->decl_flags.use_template) - -#define DECL_TEMPLATE_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) & 1) -#define CLASSTYPE_TEMPLATE_INSTANTIATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE (NODE) & 1) - -#define DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) == 2) -#define SET_DECL_TEMPLATE_SPECIALIZATION(NODE) (DECL_USE_TEMPLATE (NODE) = 2) -#define CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE (NODE) == 2) -#define SET_CLASSTYPE_TEMPLATE_SPECIALIZATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE (NODE) = 2) - -#define DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 1) -#define SET_DECL_IMPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 1) -#define CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE(NODE) == 1) -#define SET_CLASSTYPE_IMPLICIT_INSTANTIATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE(NODE) = 1) - -#define DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) == 3) -#define SET_DECL_EXPLICIT_INSTANTIATION(NODE) (DECL_USE_TEMPLATE (NODE) = 3) -#define CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE(NODE) == 3) -#define SET_CLASSTYPE_EXPLICIT_INSTANTIATION(NODE) \ - (CLASSTYPE_USE_TEMPLATE(NODE) = 3) - -/* Non-zero if DECL is a friend function which is an instantiation - from the point of view of the compiler, but not from the point of - view of the language. For example given: - template <class T> struct S { friend void f(T) {}; }; - the declaration of `void f(int)' generated when S<int> is - instantiated will not be a DECL_TEMPLATE_INSTANTIATION, but will be - a DECL_FRIEND_PSUEDO_TEMPLATE_INSTANTIATION. */ -#define DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION(DECL) \ - (DECL_TEMPLATE_INFO (DECL) && !DECL_USE_TEMPLATE (DECL)) - -/* Non-zero if TYPE is a partial instantiation of a template class, - i.e., an instantiation whose instantiation arguments involve - template types. */ -#define PARTIAL_INSTANTIATION_P(TYPE) \ - (TYPE_LANG_SPECIFIC (TYPE)->type_flags.is_partial_instantiation) - -/* Non-zero iff we are currently processing a declaration for an - entity with its own template parameter list, and which is not a - full specialization. */ -#define PROCESSING_REAL_TEMPLATE_DECL_P() \ - (processing_template_decl > template_class_depth (current_class_type)) - -/* This function may be a guiding decl for a template. */ -#define DECL_MAYBE_TEMPLATE(NODE) DECL_LANG_FLAG_4 (NODE) - -/* Nonzero if this VAR_DECL or FUNCTION_DECL has already been - instantiated, i.e. its definition has been generated from the - pattern given in the the template. */ -#define DECL_TEMPLATE_INSTANTIATED(NODE) DECL_LANG_FLAG_1(NODE) - -/* We know what we're doing with this decl now. */ -#define DECL_INTERFACE_KNOWN(NODE) DECL_LANG_FLAG_5 (NODE) - -/* This function was declared inline. This flag controls the linkage - semantics of 'inline'; whether or not the function is inlined is - controlled by DECL_INLINE. */ -#define DECL_THIS_INLINE(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.declared_inline) - -/* DECL_EXTERNAL must be set on a decl until the decl is actually emitted, - so that assemble_external will work properly. So we have this flag to - tell us whether the decl is really not external. */ -#define DECL_NOT_REALLY_EXTERN(NODE) \ - (DECL_LANG_SPECIFIC (NODE)->decl_flags.not_really_extern) - -#define DECL_REALLY_EXTERN(NODE) \ - (DECL_EXTERNAL (NODE) && ! DECL_NOT_REALLY_EXTERN (NODE)) - -/* Used to tell cp_finish_decl that it should approximate comdat linkage - as best it can for this decl. */ -#define DECL_COMDAT(NODE) (DECL_LANG_SPECIFIC (NODE)->decl_flags.comdat) - -#define THUNK_DELTA(DECL) ((DECL)->decl.frame_size.i) - -/* ...and for unexpanded-parameterized-type nodes. */ -#define UPT_TEMPLATE(NODE) TREE_PURPOSE(TYPE_VALUES(NODE)) -#define UPT_PARMS(NODE) TREE_VALUE(TYPE_VALUES(NODE)) - -/* An un-parsed default argument looks like an identifier. */ -#define DEFARG_NODE_CHECK(t) TREE_CHECK(t, DEFAULT_ARG) -#define DEFARG_LENGTH(NODE) (DEFARG_NODE_CHECK(NODE)->identifier.length) -#define DEFARG_POINTER(NODE) (DEFARG_NODE_CHECK(NODE)->identifier.pointer) - -#define builtin_function(NAME, TYPE, CODE, LIBNAME) \ - define_function (NAME, TYPE, CODE, (void (*) PROTO((tree)))pushdecl, LIBNAME) - -/* These macros provide convenient access to the various _STMT nodes - created when parsing template declarations. */ -#define IF_COND(NODE) TREE_OPERAND (NODE, 0) -#define THEN_CLAUSE(NODE) TREE_OPERAND (NODE, 1) -#define ELSE_CLAUSE(NODE) TREE_OPERAND (NODE, 2) -#define WHILE_COND(NODE) TREE_OPERAND (NODE, 0) -#define WHILE_BODY(NODE) TREE_OPERAND (NODE, 1) -#define DO_COND(NODE) TREE_OPERAND (NODE, 0) -#define DO_BODY(NODE) TREE_OPERAND (NODE, 1) -#define RETURN_EXPR(NODE) TREE_OPERAND (NODE, 0) -#define EXPR_STMT_EXPR(NODE) TREE_OPERAND (NODE, 0) -#define FOR_INIT_STMT(NODE) TREE_OPERAND (NODE, 0) -#define FOR_COND(NODE) TREE_OPERAND (NODE, 1) -#define FOR_EXPR(NODE) TREE_OPERAND (NODE, 2) -#define FOR_BODY(NODE) TREE_OPERAND (NODE, 3) -#define SWITCH_COND(NODE) TREE_OPERAND (NODE, 0) -#define SWITCH_BODY(NODE) TREE_OPERAND (NODE, 1) -#define CASE_LOW(NODE) TREE_OPERAND (NODE, 0) -#define CASE_HIGH(NODE) TREE_OPERAND (NODE, 1) -#define GOTO_DESTINATION(NODE) TREE_OPERAND (NODE, 0) -#define TRY_STMTS(NODE) TREE_OPERAND (NODE, 0) -#define TRY_HANDLERS(NODE) TREE_OPERAND (NODE, 1) -#define HANDLER_PARMS(NODE) TREE_OPERAND (NODE, 0) -#define HANDLER_BODY(NODE) TREE_OPERAND (NODE, 1) -#define COMPOUND_BODY(NODE) TREE_OPERAND (NODE, 0) -#define ASM_CV_QUAL(NODE) TREE_OPERAND (NODE, 0) -#define ASM_STRING(NODE) TREE_OPERAND (NODE, 1) -#define ASM_OUTPUTS(NODE) TREE_OPERAND (NODE, 2) -#define ASM_INPUTS(NODE) TREE_OPERAND (NODE, 3) -#define ASM_CLOBBERS(NODE) TREE_OPERAND (NODE, 4) - -/* An enumeration of the kind of tags that C++ accepts. */ -enum tag_types { record_type, class_type, union_type, enum_type, - signature_type }; - -/* Zero means prototype weakly, as in ANSI C (no args means nothing). - Each language context defines how this variable should be set. */ -extern int strict_prototype; -extern int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus; - -/* Non-zero means that if a label exists, and no other identifier - applies, use the value of the label. */ -extern int flag_labels_ok; - -/* Non-zero means to collect statistics which might be expensive - and to print them when we are done. */ -extern int flag_detailed_statistics; - -/* Non-zero means warn in function declared in derived class has the - same name as a virtual in the base class, but fails to match the - type signature of any virtual function in the base class. */ -extern int warn_overloaded_virtual; - -/* Nonzero means warn about use of multicharacter literals. */ -extern int warn_multichar; - -/* Non-zero means warn if a non-templatized friend function is - declared in a templatized class. This behavior is warned about with - flag_guiding_decls in do_friend. */ -extern int warn_nontemplate_friend; - -/* in c-common.c */ -extern void declare_function_name PROTO((void)); -extern void decl_attributes PROTO((tree, tree, tree)); -extern void init_function_format_info PROTO((void)); -extern void record_function_format PROTO((tree, tree, int, int, int)); -extern void check_function_format PROTO((tree, tree, tree)); -/* Print an error message for invalid operands to arith operation CODE. - NOP_EXPR is used as a special case (see truthvalue_conversion). */ -extern void binary_op_error PROTO((enum tree_code)); -extern tree cp_build_qualified_type PROTO((tree, int)); -extern tree canonical_type_variant PROTO((tree)); -extern void c_expand_expr_stmt PROTO((tree)); -/* Validate the expression after `case' and apply default promotions. */ -extern tree check_case_value PROTO((tree)); -/* Concatenate a list of STRING_CST nodes into one STRING_CST. */ -extern tree combine_strings PROTO((tree)); -extern void constant_expression_warning PROTO((tree)); -extern tree convert_and_check PROTO((tree, tree)); -extern void overflow_warning PROTO((tree)); -extern void unsigned_conversion_warning PROTO((tree, tree)); -extern void c_apply_type_quals_to_decl PROTO((int, tree)); - -/* Read the rest of the current #-directive line. */ -#if USE_CPPLIB -extern char *get_directive_line PROTO((void)); -#define GET_DIRECTIVE_LINE() get_directive_line () -#else -extern char *get_directive_line PROTO((FILE *)); -#define GET_DIRECTIVE_LINE() get_directive_line (finput) -#endif -/* Subroutine of build_binary_op, used for comparison operations. - See if the operands have both been converted from subword integer types - and, if so, perhaps change them both back to their original type. */ -extern tree shorten_compare PROTO((tree *, tree *, tree *, enum tree_code *)); -/* Prepare expr to be an argument of a TRUTH_NOT_EXPR, - or validate its data type for an `if' or `while' statement or ?..: exp. */ -extern tree truthvalue_conversion PROTO((tree)); -extern tree type_for_mode PROTO((enum machine_mode, int)); -extern tree type_for_size PROTO((unsigned, int)); -extern int c_get_alias_set PROTO((tree)); - -/* in decl{2}.c */ -extern tree void_list_node; -extern tree void_zero_node; -extern tree default_function_type; -extern tree vtable_entry_type; -extern tree sigtable_entry_type; -extern tree __t_desc_type_node; -#if 0 -extern tree __tp_desc_type_node; -#endif -extern tree __access_mode_type_node; -extern tree __bltn_desc_type_node, __user_desc_type_node; -extern tree __class_desc_type_node, __attr_desc_type_node; -extern tree __ptr_desc_type_node, __func_desc_type_node; -extern tree __ptmf_desc_type_node, __ptmd_desc_type_node; -extern tree type_info_type_node; -extern tree class_star_type_node; -extern tree this_identifier; -extern tree ctor_identifier, dtor_identifier; -extern tree pfn_identifier; -extern tree index_identifier; -extern tree delta_identifier; -extern tree delta2_identifier; -extern tree pfn_or_delta2_identifier; -extern tree tag_identifier; -extern tree vt_off_identifier; - -/* A node that is a list (length 1) of error_mark_nodes. */ -extern tree error_mark_list; - -extern tree ptr_type_node; -extern tree class_type_node, record_type_node, union_type_node, enum_type_node; -extern tree unknown_type_node; -extern tree opaque_type_node, signature_type_node; - -/* Node for "pointer to (virtual) function". - This may be distinct from ptr_type_node so gdb can distinguish them. */ -#define vfunc_ptr_type_node \ - (flag_vtable_thunks ? vtable_entry_type : ptr_type_node) - -/* The type of a vtbl, i.e., an array of vtable entries. */ -extern tree vtbl_type_node; -/* The type of a class vtbl pointer, i.e., a pointer to a vtable entry. */ -extern tree vtbl_ptr_type_node; -extern tree delta_type_node; -extern tree std_node; - -extern tree long_long_integer_type_node, long_long_unsigned_type_node; -/* For building calls to `delete'. */ -extern tree integer_two_node, integer_three_node; -extern tree boolean_type_node, boolean_true_node, boolean_false_node; - -extern tree null_node; - -extern tree anonymous_namespace_name; - -/* The FUNCTION_DECL for the default `::operator delete'. */ - -extern tree global_delete_fndecl; - -/* in pt.c */ - -/* These values are used for the `STRICT' parameter to type_unfication and - fn_type_unification. Their meanings are described with the - documentation for fn_type_unification. */ - -typedef enum unification_kind_t { - DEDUCE_CALL, - DEDUCE_CONV, - DEDUCE_EXACT -} unification_kind_t; - -extern tree current_template_parms; -extern HOST_WIDE_INT processing_template_decl; -extern tree last_tree; - -/* The template currently being instantiated, and where the instantiation - was triggered. */ -struct tinst_level -{ - tree decl; - int line; - char *file; - struct tinst_level *next; -}; - -extern int minimal_parse_mode; - -extern void maybe_print_template_context PROTO ((void)); - -/* in class.c */ - -/* When parsing a class definition, the access specifier most recently - given by the user, or, if no access specifier was given, the - default value appropriate for the kind of class (i.e., struct, - class, or union). */ -extern tree current_access_specifier; - -extern tree current_class_name; -extern tree current_class_type; -extern tree current_class_ptr; -extern tree previous_class_type; -extern tree current_class_ref; -extern int current_class_depth; - -extern tree current_lang_name; -extern tree lang_name_cplusplus, lang_name_c, lang_name_java; - -/* Points to the name of that function. May not be the DECL_NAME - of CURRENT_FUNCTION_DECL due to overloading */ -extern tree original_function_name; - -/* in init.c */ -extern tree global_base_init_list; -extern tree current_base_init_list, current_member_init_list; - -extern int current_function_just_assigned_this; -extern int current_function_parms_stored; - -/* Here's where we control how name mangling takes place. */ - -#define OPERATOR_ASSIGN_FORMAT "__a%s" -#define OPERATOR_FORMAT "__%s" -#define OPERATOR_TYPENAME_FORMAT "__op" - -/* Cannot use '$' up front, because this confuses gdb - (names beginning with '$' are gdb-local identifiers). - - Note that all forms in which the '$' is significant are long enough - for direct indexing (meaning that if we know there is a '$' - at a particular location, we can index into the string at - any other location that provides distinguishing characters). */ - -/* Define NO_DOLLAR_IN_LABEL in your favorite tm file if your assembler - doesn't allow '$' in symbol names. */ -#ifndef NO_DOLLAR_IN_LABEL - -#define JOINER '$' - -#define VPTR_NAME "$v" -#define THROW_NAME "$eh_throw" -#define DESTRUCTOR_DECL_PREFIX "_$_" -#define AUTO_VTABLE_NAME "__vtbl$me__" -#define AUTO_TEMP_NAME "_$tmp_" -#define AUTO_TEMP_FORMAT "_$tmp_%d" -#define VTABLE_BASE "$vb" -#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt$%s") -#define VFIELD_BASE "$vf" -#define VFIELD_NAME "_vptr$" -#define VFIELD_NAME_FORMAT "_vptr$%s" -#define VBASE_NAME "_vb$" -#define VBASE_NAME_FORMAT "_vb$%s" -#define STATIC_NAME_FORMAT "_%s$%s" -#define ANON_AGGRNAME_FORMAT "$_%d" - -#else /* NO_DOLLAR_IN_LABEL */ - -#ifndef NO_DOT_IN_LABEL - -#define JOINER '.' - -#define VPTR_NAME ".v" -#define THROW_NAME ".eh_throw" -#define DESTRUCTOR_DECL_PREFIX "_._" -#define AUTO_VTABLE_NAME "__vtbl.me__" -#define AUTO_TEMP_NAME "_.tmp_" -#define AUTO_TEMP_FORMAT "_.tmp_%d" -#define VTABLE_BASE ".vb" -#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt.%s") -#define VFIELD_BASE ".vf" -#define VFIELD_NAME "_vptr." -#define VFIELD_NAME_FORMAT "_vptr.%s" -#define VBASE_NAME "_vb." -#define VBASE_NAME_FORMAT "_vb.%s" -#define STATIC_NAME_FORMAT "_%s.%s" - -#define ANON_AGGRNAME_FORMAT "._%d" - -#else /* NO_DOT_IN_LABEL */ - -#define VPTR_NAME "__vptr" -#define VPTR_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), VPTR_NAME, sizeof (VPTR_NAME) - 1)) -#define THROW_NAME "__eh_throw" -#define DESTRUCTOR_DECL_PREFIX "__destr_" -#define DESTRUCTOR_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), DESTRUCTOR_DECL_PREFIX, \ - sizeof (DESTRUCTOR_DECL_PREFIX) - 1)) -#define IN_CHARGE_NAME "__in_chrg" -#define AUTO_VTABLE_NAME "__vtbl_me__" -#define AUTO_TEMP_NAME "__tmp_" -#define TEMP_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, \ - sizeof (AUTO_TEMP_NAME) - 1)) -#define AUTO_TEMP_FORMAT "__tmp_%d" -#define VTABLE_BASE "__vtb" -#define VTABLE_NAME "__vt_" -#define VTABLE_NAME_FORMAT (flag_vtable_thunks ? "__vt_%s" : "_vt_%s") -#define VTABLE_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), VTABLE_NAME, \ - sizeof (VTABLE_NAME) - 1)) -#define VFIELD_BASE "__vfb" -#define VFIELD_NAME "__vptr_" -#define VFIELD_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, \ - sizeof (VFIELD_NAME) - 1)) -#define VFIELD_NAME_FORMAT "_vptr_%s" -#define VBASE_NAME "__vb_" -#define VBASE_NAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), VBASE_NAME, \ - sizeof (VBASE_NAME) - 1)) -#define VBASE_NAME_FORMAT "__vb_%s" -#define STATIC_NAME_FORMAT "__static_%s_%s" - -#define ANON_AGGRNAME_PREFIX "__anon_" -#define ANON_AGGRNAME_P(ID_NODE) \ - (!strncmp (IDENTIFIER_POINTER (ID_NODE), ANON_AGGRNAME_PREFIX, \ - sizeof (ANON_AGGRNAME_PREFIX) - 1)) -#define ANON_AGGRNAME_FORMAT "__anon_%d" -#define ANON_PARMNAME_FORMAT "__%d" -#define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ - && IDENTIFIER_POINTER (ID_NODE)[1] == '_' \ - && IDENTIFIER_POINTER (ID_NODE)[2] <= '9') - -#endif /* NO_DOT_IN_LABEL */ -#endif /* NO_DOLLAR_IN_LABEL */ - -#define THIS_NAME "this" -#define DESTRUCTOR_NAME_FORMAT "~%s" -#define FILE_FUNCTION_PREFIX_LEN 9 -#define CTOR_NAME "__ct" -#define DTOR_NAME "__dt" - -#define IN_CHARGE_NAME "__in_chrg" - -#define VTBL_PTR_TYPE "__vtbl_ptr_type" -#define VTABLE_DELTA_NAME "__delta" -#define VTABLE_INDEX_NAME "__index" -#define VTABLE_PFN_NAME "__pfn" -#define VTABLE_DELTA2_NAME "__delta2" - -#define SIGNATURE_FIELD_NAME "__s_" -#define SIGNATURE_FIELD_NAME_FORMAT "__s_%s" -#define SIGNATURE_OPTR_NAME "__optr" -#define SIGNATURE_SPTR_NAME "__sptr" -#define SIGNATURE_POINTER_NAME "__sp_" -#define SIGNATURE_POINTER_NAME_FORMAT "__%s%s%ssp_%s" -#define SIGNATURE_REFERENCE_NAME "__sr_" -#define SIGNATURE_REFERENCE_NAME_FORMAT "__%s%s%ssr_%s" - -#define SIGTABLE_PTR_TYPE "__sigtbl_ptr_type" -#define SIGTABLE_NAME_FORMAT "__st_%s_%s" -#define SIGTABLE_NAME_FORMAT_LONG "__st_%s_%s_%d" -#define SIGTABLE_TAG_NAME "__tag" -#define SIGTABLE_VB_OFF_NAME "__vb_off" -#define SIGTABLE_VT_OFF_NAME "__vt_off" -#define EXCEPTION_CLEANUP_NAME "exception cleanup" - -#define THIS_NAME_P(ID_NODE) (strcmp(IDENTIFIER_POINTER (ID_NODE), "this") == 0) - -#if !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) - -#define VPTR_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == JOINER \ - && IDENTIFIER_POINTER (ID_NODE)[1] == 'v') -#define DESTRUCTOR_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == JOINER \ - && IDENTIFIER_POINTER (ID_NODE)[2] == '_') - -#define VTABLE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \ - && IDENTIFIER_POINTER (ID_NODE)[2] == 't' \ - && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER) - -#define VBASE_NAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[1] == 'v' \ - && IDENTIFIER_POINTER (ID_NODE)[2] == 'b' \ - && IDENTIFIER_POINTER (ID_NODE)[3] == JOINER) - -#define TEMP_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), AUTO_TEMP_NAME, sizeof (AUTO_TEMP_NAME)-1)) -#define VFIELD_NAME_P(ID_NODE) (!strncmp (IDENTIFIER_POINTER (ID_NODE), VFIELD_NAME, sizeof(VFIELD_NAME)-1)) - -/* For anonymous aggregate types, we need some sort of name to - hold on to. In practice, this should not appear, but it should - not be harmful if it does. */ -#define ANON_AGGRNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == JOINER \ - && IDENTIFIER_POINTER (ID_NODE)[1] == '_') -#define ANON_PARMNAME_FORMAT "_%d" -#define ANON_PARMNAME_P(ID_NODE) (IDENTIFIER_POINTER (ID_NODE)[0] == '_' \ - && IDENTIFIER_POINTER (ID_NODE)[1] <= '9') -#endif /* !defined(NO_DOLLAR_IN_LABEL) || !defined(NO_DOT_IN_LABEL) */ - -/* Store the vbase pointer field name for type TYPE into pointer BUF. */ -#define FORMAT_VBASE_NAME(BUF,TYPE) do { \ - BUF = (char *) alloca (TYPE_ASSEMBLER_NAME_LENGTH (TYPE) \ - + sizeof (VBASE_NAME) + 1); \ - sprintf (BUF, VBASE_NAME_FORMAT, TYPE_ASSEMBLER_NAME_STRING (TYPE)); \ -} while (0) - -/* Returns non-zero iff ID_NODE is an IDENTIFIER_NODE whose name is - `main'. */ -#define MAIN_NAME_P(ID_NODE) \ - (strcmp (IDENTIFIER_POINTER (ID_NODE), "main") == 0) - -/* Returns non-zero iff NODE is a declaration for the global function - `main'. */ -#define DECL_MAIN_P(NODE) \ - (TREE_CODE (NODE) == FUNCTION_DECL \ - && DECL_LANGUAGE (NODE) == lang_c \ - && DECL_NAME (NODE) != NULL_TREE \ - && MAIN_NAME_P (DECL_NAME (NODE))) - - -/* Define the sets of attributes that member functions and baseclasses - can have. These are sensible combinations of {public,private,protected} - cross {virtual,non-virtual}. */ - -/* in class.c. */ -extern tree access_default_node; /* 0 */ -extern tree access_public_node; /* 1 */ -extern tree access_protected_node; /* 2 */ -extern tree access_private_node; /* 3 */ -extern tree access_default_virtual_node; /* 4 */ -extern tree access_public_virtual_node; /* 5 */ -extern tree access_protected_virtual_node; /* 6 */ -extern tree access_private_virtual_node; /* 7 */ - -/* Things for handling inline functions. */ - -struct pending_inline -{ - struct pending_inline *next; /* pointer to next in chain */ - int lineno; /* line number we got the text from */ - char *filename; /* name of file we were processing */ - tree fndecl; /* FUNCTION_DECL that brought us here */ - int token; /* token we were scanning */ - int token_value; /* value of token we were scanning (YYSTYPE) */ - - char *buf; /* pointer to character stream */ - int len; /* length of stream */ - unsigned int can_free : 1; /* free this after we're done with it? */ - unsigned int deja_vu : 1; /* set iff we don't want to see it again. */ - unsigned int interface : 2; /* 0=interface 1=unknown 2=implementation */ -}; - -/* in method.c */ -extern struct pending_inline *pending_inlines; - -/* Positive values means that we cannot make optimizing assumptions about - `this'. Negative values means we know `this' to be of static type. */ - -extern int flag_this_is_variable; - -/* Nonzero means generate 'rtti' that give run-time type information. */ - -extern int flag_rtti; - -/* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - -extern int flag_implement_inlines; - -/* Nonzero means templates obey #pragma interface and implementation. */ - -extern int flag_external_templates; - -/* Nonzero means templates are emitted where they are instantiated. */ - -extern int flag_alt_external_templates; - -/* Nonzero means implicit template instantiations are emitted. */ - -extern int flag_implicit_templates; - -/* Nonzero if we want to emit defined symbols with common-like linkage as - weak symbols where possible, in order to conform to C++ semantics. - Otherwise, emit them as local symbols. */ - -extern int flag_weak; - -/* CYGNUS LOCAL Embedded C++ */ -/* Nonzero if we want to adhere to the language rules of the Embedded C++ - specification. */ - -extern int flag_embedded_cxx; -/* END CYGNUS LOCAL Embedded C++ */ - -/* Nonzero to enable experimental ABI changes. */ - -extern int flag_new_abi; - -/* Nonzero to not ignore namespace std. */ - -extern int flag_honor_std; - -/* Nonzero if we're done parsing and into end-of-file activities. */ - -extern int at_eof; - -enum overload_flags { NO_SPECIAL = 0, DTOR_FLAG, OP_FLAG, TYPENAME_FLAG }; - -/* The following two can be derived from the previous one */ -extern tree current_class_name; /* IDENTIFIER_NODE: name of current class */ - -/* Some macros for char-based bitfields. */ -#define B_SET(a,x) (a[x>>3] |= (1 << (x&7))) -#define B_CLR(a,x) (a[x>>3] &= ~(1 << (x&7))) -#define B_TST(a,x) (a[x>>3] & (1 << (x&7))) - -/* These are uses as bits in flags passed to build_method_call - to control its error reporting behavior. - - LOOKUP_PROTECT means flag access violations. - LOOKUP_COMPLAIN mean complain if no suitable member function - matching the arguments is found. - LOOKUP_NORMAL is just a combination of these two. - LOOKUP_NONVIRTUAL means make a direct call to the member function found - LOOKUP_GLOBAL means search through the space of overloaded functions, - as well as the space of member functions. - LOOKUP_HAS_IN_CHARGE means that the "in charge" variable is already - in the parameter list. - LOOKUP_ONLYCONVERTING means that non-conversion constructors are not tried. - DIRECT_BIND means that if a temporary is created, it should be created so - that it lives as long as the current variable bindings; otherwise it - only lives until the end of the complete-expression. - LOOKUP_SPECULATIVELY means return NULL_TREE if we cannot find what we are - after. Note, LOOKUP_COMPLAIN is checked and error messages printed - before LOOKUP_SPECULATIVELY is checked. - LOOKUP_NO_CONVERSION means that user-defined conversions are not - permitted. Built-in conversions are permitted. - LOOKUP_DESTRUCTOR means explicit call to destructor. - LOOKUP_NO_TEMP_BIND means temporaries will not be bound to references. - - These are used in global lookup to support elaborated types and - qualifiers. - - LOOKUP_PREFER_TYPES means not to accept objects, and possibly namespaces. - LOOKUP_PREFER_NAMESPACES means not to accept objects, and possibly types. - LOOKUP_PREFER_BOTH means class-or-namespace-name. - LOOKUP_TEMPLATES_EXPECTED means that class templates also count - as types. */ - -#define LOOKUP_PROTECT (1) -#define LOOKUP_COMPLAIN (2) -#define LOOKUP_NORMAL (3) -/* #define LOOKUP_UNUSED (4) */ -#define LOOKUP_NONVIRTUAL (8) -#define LOOKUP_GLOBAL (16) -#define LOOKUP_HAS_IN_CHARGE (32) -#define LOOKUP_SPECULATIVELY (64) -#define LOOKUP_ONLYCONVERTING (128) -#define DIRECT_BIND (256) -#define LOOKUP_NO_CONVERSION (512) -#define LOOKUP_DESTRUCTOR (512) -#define LOOKUP_NO_TEMP_BIND (1024) -#define LOOKUP_PREFER_TYPES (2048) -#define LOOKUP_PREFER_NAMESPACES (4096) -#define LOOKUP_PREFER_BOTH (6144) -#define LOOKUP_TEMPLATES_EXPECTED (8192) - -#define LOOKUP_NAMESPACES_ONLY(f) \ - (((f) & LOOKUP_PREFER_NAMESPACES) && !((f) & LOOKUP_PREFER_TYPES)) -#define LOOKUP_TYPES_ONLY(f) \ - (!((f) & LOOKUP_PREFER_NAMESPACES) && ((f) & LOOKUP_PREFER_TYPES)) -#define LOOKUP_QUALIFIERS_ONLY(f) ((f) & LOOKUP_PREFER_BOTH) - - -/* These flags are used by the conversion code. - CONV_IMPLICIT : Perform implicit conversions (standard and user-defined). - CONV_STATIC : Perform the explicit conversions for static_cast. - CONV_CONST : Perform the explicit conversions for const_cast. - CONV_REINTERPRET: Perform the explicit conversions for reinterpret_cast. - CONV_PRIVATE : Perform upcasts to private bases. - CONV_FORCE_TEMP : Require a new temporary when converting to the same - aggregate type. */ - -#define CONV_IMPLICIT 1 -#define CONV_STATIC 2 -#define CONV_CONST 4 -#define CONV_REINTERPRET 8 -#define CONV_PRIVATE 16 -/* #define CONV_NONCONVERTING 32 */ -#define CONV_FORCE_TEMP 64 -#define CONV_STATIC_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_FORCE_TEMP) -#define CONV_OLD_CONVERT (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ - | CONV_REINTERPRET) -#define CONV_C_CAST (CONV_IMPLICIT | CONV_STATIC | CONV_CONST \ - | CONV_REINTERPRET | CONV_PRIVATE | CONV_FORCE_TEMP) - -/* Used by build_expr_type_conversion to indicate which types are - acceptable as arguments to the expression under consideration. */ - -#define WANT_INT 1 /* integer types, including bool */ -#define WANT_FLOAT 2 /* floating point types */ -#define WANT_ENUM 4 /* enumerated types */ -#define WANT_POINTER 8 /* pointer types */ -#define WANT_NULL 16 /* null pointer constant */ -#define WANT_ARITH (WANT_INT | WANT_FLOAT) - -/* Used with comptypes, and related functions, to guide type - comparison. */ - -#define COMPARE_STRICT 0 /* Just check if the types are the - same. */ -#define COMPARE_BASE 1 /* Check to see if the second type is - derived from the first, or if both - are pointers (or references) and - the types pointed to by the second - type is derived from the pointed to - by the first. */ -#define COMPARE_RELAXED 2 /* Like COMPARE_DERIVED, but in - reverse. Also treat enmeration - types as the same as integer types - of the same width. */ -#define COMPARE_REDECLARATION 4 /* The comparsion is being done when - another declaration of an existing - entity is seen. */ - -/* Used with push_overloaded_decl. */ -#define PUSH_GLOBAL 0 /* Push the DECL into namespace scope, - regardless of the current scope. */ -#define PUSH_LOCAL 1 /* Push the DECL into the current - scope. */ -#define PUSH_USING 2 /* We are pushing this DECL as the - result of a using declaration. */ - -/* Returns nonzero iff TYPE1 and TYPE2 are the same type, in the usual - sense of `same'. */ -#define same_type_p(type1, type2) \ - comptypes ((type1), (type2), COMPARE_STRICT) - -/* Returns nonzero iff TYPE1 and TYPE2 are the same type, or if TYPE2 - is derived from TYPE1, or if TYPE2 is a pointer (reference) to a - class derived from the type pointed to (referred to) by TYPE1. */ -#define same_or_base_type_p(type1, type2) \ - comptypes ((type1), (type2), COMPARE_BASE) - -#define FRIEND_NAME(LIST) (TREE_PURPOSE (LIST)) -#define FRIEND_DECLS(LIST) (TREE_VALUE (LIST)) - -/* These macros are used to access a TEMPLATE_PARM_INDEX. */ -#define TEMPLATE_PARM_IDX(NODE) (((template_parm_index*) NODE)->index) -#define TEMPLATE_PARM_LEVEL(NODE) (((template_parm_index*) NODE)->level) -#define TEMPLATE_PARM_DESCENDANTS(NODE) (TREE_CHAIN (NODE)) -#define TEMPLATE_PARM_ORIG_LEVEL(NODE) (((template_parm_index*) NODE)->orig_level) -#define TEMPLATE_PARM_DECL(NODE) (((template_parm_index*) NODE)->decl) - -/* These macros are for accessing the fields of TEMPLATE_TYPE_PARM - and TEMPLATE_TEMPLATE_PARM nodes. */ -#define TEMPLATE_TYPE_PARM_INDEX(NODE) (TYPE_FIELDS (NODE)) -#define TEMPLATE_TYPE_IDX(NODE) \ - (TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (NODE))) -#define TEMPLATE_TYPE_LEVEL(NODE) \ - (TEMPLATE_PARM_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) -#define TEMPLATE_TYPE_ORIG_LEVEL(NODE) \ - (TEMPLATE_PARM_ORIG_LEVEL (TEMPLATE_TYPE_PARM_INDEX (NODE))) -#define TEMPLATE_TYPE_DECL(NODE) \ - (TEMPLATE_PARM_DECL (TEMPLATE_TYPE_PARM_INDEX (NODE))) - -/* in lex.c */ -/* Indexed by TREE_CODE, these tables give C-looking names to - operators represented by TREE_CODES. For example, - opname_tab[(int) MINUS_EXPR] == "-". */ -extern char **opname_tab, **assignop_tab; - -/* in call.c */ -extern int check_dtor_name PROTO((tree, tree)); -extern int get_arglist_len_in_bytes PROTO((tree)); - -extern tree build_vfield_ref PROTO((tree, tree)); -extern tree resolve_scope_to_name PROTO((tree, tree)); -extern tree build_scoped_method_call PROTO((tree, tree, tree, tree)); -extern tree build_addr_func PROTO((tree)); -extern tree build_call PROTO((tree, tree, tree)); -extern tree build_method_call PROTO((tree, tree, tree, tree, int)); -extern int null_ptr_cst_p PROTO((tree)); -extern tree type_decays_to PROTO((tree)); -extern tree build_user_type_conversion PROTO((tree, tree, int)); -extern tree build_new_function_call PROTO((tree, tree)); -extern tree build_new_op PROTO((enum tree_code, int, tree, tree, tree)); -extern tree build_op_new_call PROTO((enum tree_code, tree, tree, int)); -extern tree build_op_delete_call PROTO((enum tree_code, tree, tree, int, tree)); -extern int can_convert PROTO((tree, tree)); -extern int can_convert_arg PROTO((tree, tree, tree)); -extern void enforce_access PROTO((tree, tree)); -extern tree convert_default_arg PROTO((tree, tree, tree)); -extern tree convert_arg_to_ellipsis PROTO((tree)); - -/* in class.c */ -extern tree build_vbase_path PROTO((enum tree_code, tree, tree, tree, int)); -extern tree build_vtbl_ref PROTO((tree, tree)); -extern tree build_vfn_ref PROTO((tree *, tree, tree)); -extern void add_method PROTO((tree, tree *, tree)); -extern int currently_open_class PROTO((tree)); -extern tree get_vfield_offset PROTO((tree)); -extern void duplicate_tag_error PROTO((tree)); -extern tree finish_struct PROTO((tree, tree, int)); -extern tree finish_struct_1 PROTO((tree, int)); -extern int resolves_to_fixed_type_p PROTO((tree, int *)); -extern void init_class_processing PROTO((void)); -extern int is_empty_class PROTO((tree)); -extern void pushclass PROTO((tree, int)); -extern void popclass PROTO((int)); -extern void push_nested_class PROTO((tree, int)); -extern void pop_nested_class PROTO((int)); -extern void push_lang_context PROTO((tree)); -extern void pop_lang_context PROTO((void)); -extern tree instantiate_type PROTO((tree, tree, int)); -extern void print_class_statistics PROTO((void)); -extern void maybe_push_cache_obstack PROTO((void)); -extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *)); -extern tree build_self_reference PROTO((void)); -extern void warn_hidden PROTO((tree)); -extern tree get_enclosing_class PROTO((tree)); -int is_base_of_enclosing_class PROTO((tree, tree)); -extern void unreverse_member_declarations PROTO((tree)); - -/* in cvt.c */ -extern tree convert_to_reference PROTO((tree, tree, int, int, tree)); -extern tree convert_from_reference PROTO((tree)); -extern tree convert_pointer_to_real PROTO((tree, tree)); -extern tree convert_pointer_to PROTO((tree, tree)); -extern tree ocp_convert PROTO((tree, tree, int, int)); -extern tree cp_convert PROTO((tree, tree)); -extern tree convert PROTO((tree, tree)); -extern tree convert_force PROTO((tree, tree, int)); -extern tree build_type_conversion PROTO((enum tree_code, tree, tree, int)); -extern tree build_expr_type_conversion PROTO((int, tree, int)); -extern tree type_promotes_to PROTO((tree)); -extern tree perform_qualification_conversions PROTO((tree, tree)); - -/* decl.c */ -/* resume_binding_level */ -extern void set_identifier_local_value PROTO((tree, tree)); -extern int global_bindings_p PROTO((void)); -extern int toplevel_bindings_p PROTO((void)); -extern int namespace_bindings_p PROTO((void)); -extern void keep_next_level PROTO((void)); -extern int kept_level_p PROTO((void)); -extern void declare_parm_level PROTO((void)); -extern void declare_pseudo_global_level PROTO((void)); -extern int pseudo_global_level_p PROTO((void)); -extern void set_class_shadows PROTO((tree)); -extern void pushlevel PROTO((int)); -extern void note_level_for_for PROTO((void)); -extern void pushlevel_temporary PROTO((int)); -extern tree poplevel PROTO((int, int, int)); -extern void resume_level PROTO((struct binding_level *)); -extern void delete_block PROTO((tree)); -extern void insert_block PROTO((tree)); -extern void add_block_current_level PROTO((tree)); -extern void set_block PROTO((tree)); -extern void pushlevel_class PROTO((void)); -extern tree poplevel_class PROTO((int)); -extern void print_binding_stack PROTO((void)); -extern void print_binding_level PROTO((struct binding_level *)); -extern void push_namespace PROTO((tree)); -extern void pop_namespace PROTO((void)); -extern void maybe_push_to_top_level PROTO((int)); -extern void push_to_top_level PROTO((void)); -extern void pop_from_top_level PROTO((void)); -extern tree identifier_type_value PROTO((tree)); -extern void set_identifier_type_value PROTO((tree, tree)); -extern void pop_everything PROTO((void)); -extern void pushtag PROTO((tree, tree, int)); -extern tree make_anon_name PROTO((void)); -extern void clear_anon_tags PROTO((void)); -extern int decls_match PROTO((tree, tree)); -extern int duplicate_decls PROTO((tree, tree)); -extern tree pushdecl PROTO((tree)); -extern tree pushdecl_top_level PROTO((tree)); -extern void pushdecl_class_level PROTO((tree)); -#if 0 -extern void pushdecl_nonclass_level PROTO((tree)); -#endif -extern tree pushdecl_namespace_level PROTO((tree)); -extern tree push_using_decl PROTO((tree, tree)); -extern tree push_using_directive PROTO((tree)); -extern void push_class_level_binding PROTO((tree, tree)); -extern tree push_using_decl PROTO((tree, tree)); -extern tree implicitly_declare PROTO((tree)); -extern tree lookup_label PROTO((tree)); -extern tree shadow_label PROTO((tree)); -extern tree define_label PROTO((char *, int, tree)); -extern void push_switch PROTO((void)); -extern void pop_switch PROTO((void)); -extern void define_case_label PROTO((void)); -extern tree getdecls PROTO((void)); -extern tree gettags PROTO((void)); -#if 0 -extern void set_current_level_tags_transparency PROTO((int)); -#endif -extern tree binding_for_name PROTO((tree, tree)); -extern tree namespace_binding PROTO((tree, tree)); -extern void set_namespace_binding PROTO((tree, tree, tree)); -extern tree lookup_namespace_name PROTO((tree, tree)); -extern tree build_typename_type PROTO((tree, tree, tree, tree)); -extern tree make_typename_type PROTO((tree, tree)); -extern tree lookup_name_nonclass PROTO((tree)); -extern tree lookup_function_nonclass PROTO((tree, tree)); -extern tree lookup_name PROTO((tree, int)); -extern tree lookup_name_current_level PROTO((tree)); -extern tree lookup_type_current_level PROTO((tree)); -extern tree lookup_name_namespace_only PROTO((tree)); -extern void begin_only_namespace_names PROTO((void)); -extern void end_only_namespace_names PROTO((void)); -extern tree namespace_ancestor PROTO((tree, tree)); -extern int lookup_using_namespace PROTO((tree,tree,tree,tree,int)); -extern int qualified_lookup_using_namespace PROTO((tree,tree,tree,int)); -extern tree auto_function PROTO((tree, tree, enum built_in_function)); -extern void init_decl_processing PROTO((void)); -extern int init_type_desc PROTO((void)); -extern tree define_function - PROTO((char *, tree, enum built_in_function, - void (*) (tree), char *)); -extern tree check_tag_decl PROTO((tree)); -extern void shadow_tag PROTO((tree)); -extern tree groktypename PROTO((tree)); -extern tree start_decl PROTO((tree, tree, int, tree, tree)); -extern void start_decl_1 PROTO((tree)); -extern void cp_finish_decl PROTO((tree, tree, tree, int, int)); -extern void finish_decl PROTO((tree, tree, tree)); -extern void expand_static_init PROTO((tree, tree)); -extern int complete_array_type PROTO((tree, tree, int)); -extern tree build_ptrmemfunc_type PROTO((tree)); -/* the grokdeclarator prototype is in decl.h */ -extern int parmlist_is_exprlist PROTO((tree)); -extern int copy_args_p PROTO((tree)); -extern int grok_ctor_properties PROTO((tree, tree)); -extern void grok_op_properties PROTO((tree, int, int)); -extern tree xref_tag PROTO((tree, tree, int)); -extern tree xref_tag_from_type PROTO((tree, tree, int)); -extern void xref_basetypes PROTO((tree, tree, tree, tree)); -extern tree start_enum PROTO((tree)); -extern tree finish_enum PROTO((tree)); -extern tree build_enumerator PROTO((tree, tree, tree)); -extern int start_function PROTO((tree, tree, tree, int)); -extern void expand_start_early_try_stmts PROTO((void)); -extern void store_parm_decls PROTO((void)); -extern void store_return_init PROTO((tree, tree)); -extern void finish_function PROTO((int, int, int)); -extern tree start_method PROTO((tree, tree, tree)); -extern tree finish_method PROTO((tree)); -extern void hack_incomplete_structures PROTO((tree)); -extern tree maybe_build_cleanup_and_delete PROTO((tree)); -extern tree maybe_build_cleanup PROTO((tree)); -extern void cplus_expand_expr_stmt PROTO((tree)); -extern void finish_stmt PROTO((void)); -extern int id_in_current_class PROTO((tree)); -extern void push_cp_function_context PROTO((tree)); -extern void pop_cp_function_context PROTO((tree)); -extern int in_function_p PROTO((void)); -extern void replace_defarg PROTO((tree, tree)); -extern void print_other_binding_stack PROTO((struct binding_level *)); -extern void revert_static_member_fn PROTO((tree*, tree*, tree*)); -extern void cat_namespace_levels PROTO((void)); -extern void fixup_anonymous_union PROTO((tree)); -extern int check_static_variable_definition PROTO((tree, tree)); -extern void push_local_binding PROTO((tree, tree, int)); -extern void push_class_binding PROTO((tree, tree)); -extern tree check_default_argument PROTO((tree, tree)); -extern tree push_overloaded_decl PROTO((tree, int)); - -/* in decl2.c */ -extern int check_java_method PROTO((tree)); -extern int lang_decode_option PROTO((int, char **)); -extern tree grok_method_quals PROTO((tree, tree, tree)); -extern void warn_if_unknown_interface PROTO((tree)); -extern void grok_x_components PROTO((tree)); -extern void maybe_retrofit_in_chrg PROTO((tree)); -extern void maybe_make_one_only PROTO((tree)); -extern void grokclassfn PROTO((tree, tree, enum overload_flags, tree)); -extern tree grok_alignof PROTO((tree)); -extern tree grok_array_decl PROTO((tree, tree)); -extern tree delete_sanity PROTO((tree, tree, int, int)); -extern tree check_classfn PROTO((tree, tree)); -extern void check_member_template PROTO((tree)); -extern tree grokfield PROTO((tree, tree, tree, tree, tree)); -extern tree grokbitfield PROTO((tree, tree, tree)); -extern tree groktypefield PROTO((tree, tree)); -extern tree grokoptypename PROTO((tree, tree)); -extern int copy_assignment_arg_p PROTO((tree, int)); -extern void cplus_decl_attributes PROTO((tree, tree, tree)); -extern tree constructor_name_full PROTO((tree)); -extern tree constructor_name PROTO((tree)); -extern void setup_vtbl_ptr PROTO((void)); -extern void mark_inline_for_output PROTO((tree)); -extern void clear_temp_name PROTO((void)); -extern tree get_temp_name PROTO((tree, int)); -extern tree get_temp_regvar PROTO((tree, tree)); -extern void finish_anon_union PROTO((tree)); -extern tree finish_table PROTO((tree, tree, tree, int)); -extern void finish_builtin_type PROTO((tree, char *, tree *, int, tree)); -extern tree coerce_new_type PROTO((tree)); -extern tree coerce_delete_type PROTO((tree)); -extern void comdat_linkage PROTO((tree)); -extern void import_export_class PROTO((tree)); -extern void import_export_vtable PROTO((tree, tree, int)); -extern int walk_vtables PROTO((void (*)(tree, tree), - int (*)(tree, tree))); -extern void walk_sigtables PROTO((void (*)(tree, tree), - void (*)(tree, tree))); -extern void import_export_decl PROTO((tree)); -extern tree build_cleanup PROTO((tree)); -extern void finish_file PROTO((void)); -extern tree reparse_absdcl_as_expr PROTO((tree, tree)); -extern tree reparse_absdcl_as_casts PROTO((tree, tree)); -extern tree build_expr_from_tree PROTO((tree)); -extern tree reparse_decl_as_expr PROTO((tree, tree)); -extern tree finish_decl_parsing PROTO((tree)); -extern tree check_cp_case_value PROTO((tree)); -extern void set_decl_namespace PROTO((tree, tree)); -extern tree current_decl_namespace PROTO((void)); -extern void push_decl_namespace PROTO((tree)); -extern void pop_decl_namespace PROTO((void)); -extern void push_scope PROTO((tree)); -extern void pop_scope PROTO((tree)); -extern void do_namespace_alias PROTO((tree, tree)); -extern void do_toplevel_using_decl PROTO((tree)); -extern void do_local_using_decl PROTO((tree)); -extern tree do_class_using_decl PROTO((tree)); -extern void do_using_directive PROTO((tree)); -extern void check_default_args PROTO((tree)); -extern void mark_used PROTO((tree)); -extern tree handle_class_head PROTO((tree, tree, tree)); -extern tree lookup_arg_dependent PROTO((tree, tree, tree)); - -/* in errfn.c */ -extern void cp_error (); -extern void cp_error_at (); -extern void cp_warning (); -extern void cp_warning_at (); -extern void cp_pedwarn (); -extern void cp_pedwarn_at (); -extern void cp_compiler_error (); -extern void cp_sprintf (); - -/* in error.c */ -extern void init_error PROTO((void)); -extern char *fndecl_as_string PROTO((tree, int)); -extern char *type_as_string PROTO((tree, int)); -extern char *type_as_string_real PROTO((tree, int, int)); -extern char *args_as_string PROTO((tree, int)); -extern char *decl_as_string PROTO((tree, int)); -extern char *expr_as_string PROTO((tree, int)); -extern char *code_as_string PROTO((enum tree_code, int)); -extern char *language_as_string PROTO((enum languages, int)); -extern char *parm_as_string PROTO((int, int)); -extern char *op_as_string PROTO((enum tree_code, int)); -extern char *assop_as_string PROTO((enum tree_code, int)); -extern char *cv_as_string PROTO((tree, int)); -extern char *lang_decl_name PROTO((tree, int)); -extern char *cp_file_of PROTO((tree)); -extern int cp_line_of PROTO((tree)); - -/* in except.c */ -extern void init_exception_processing PROTO((void)); -extern void expand_start_catch_block PROTO((tree, tree)); -extern void expand_end_catch_block PROTO((void)); -extern void expand_builtin_throw PROTO((void)); -extern void expand_start_eh_spec PROTO((void)); -extern void expand_exception_blocks PROTO((void)); -extern tree start_anon_func PROTO((void)); -extern void end_anon_func PROTO((void)); -extern void expand_throw PROTO((tree)); -extern tree build_throw PROTO((tree)); -extern void mark_all_runtime_matches PROTO((void)); - -/* in expr.c */ -extern void init_cplus_expand PROTO((void)); -extern void fixup_result_decl PROTO((tree, struct rtx_def *)); -extern int extract_init PROTO((tree, tree)); -extern void do_case PROTO((tree, tree)); - -/* friend.c */ -extern int is_friend PROTO((tree, tree)); -extern void make_friend_class PROTO((tree, tree)); -extern tree do_friend PROTO((tree, tree, tree, tree, enum overload_flags, tree, int)); - -/* in init.c */ -extern void init_init_processing PROTO((void)); -extern void expand_direct_vtbls_init PROTO((tree, tree, int, int, tree)); -extern void emit_base_init PROTO((tree, int)); -extern void check_base_init PROTO((tree)); -extern void expand_member_init PROTO((tree, tree, tree)); -extern void expand_aggr_init PROTO((tree, tree, int)); -extern int is_aggr_typedef PROTO((tree, int)); -extern int is_aggr_type PROTO((tree, int)); -extern tree get_aggr_from_typedef PROTO((tree, int)); -extern tree get_type_value PROTO((tree)); -extern tree build_member_call PROTO((tree, tree, tree)); -extern tree build_offset_ref PROTO((tree, tree)); -extern tree resolve_offset_ref PROTO((tree)); -extern tree decl_constant_value PROTO((tree)); -extern tree build_new PROTO((tree, tree, tree, int)); -extern tree build_new_1 PROTO((tree)); -extern tree expand_vec_init PROTO((tree, tree, tree, tree, int)); -extern tree build_x_delete PROTO((tree, int, tree)); -extern tree build_delete PROTO((tree, tree, tree, int, int)); -extern tree build_vbase_delete PROTO((tree, tree)); -extern tree build_vec_delete PROTO((tree, tree, tree, tree, int)); - -/* in input.c */ - -/* in lex.c */ -extern char *file_name_nondirectory PROTO((char *)); -extern tree make_pointer_declarator PROTO((tree, tree)); -extern tree make_reference_declarator PROTO((tree, tree)); -extern tree make_call_declarator PROTO((tree, tree, tree, tree)); -extern void set_quals_and_spec PROTO((tree, tree, tree)); -extern char *operator_name_string PROTO((tree)); -extern void lang_init PROTO((void)); -extern void lang_finish PROTO((void)); -extern void init_filename_times PROTO((void)); -#if 0 -extern void reinit_lang_specific PROTO((void)); -#endif -extern void reinit_parse_for_function PROTO((void)); -extern void print_parse_statistics PROTO((void)); -extern void extract_interface_info PROTO((void)); -extern void do_pending_inlines PROTO((void)); -extern void process_next_inline PROTO((tree)); -extern struct pending_input *save_pending_input PROTO((void)); -extern void restore_pending_input PROTO((struct pending_input *)); -extern void yyungetc PROTO((int, int)); -extern void reinit_parse_for_method PROTO((int, tree)); -extern void reinit_parse_for_block PROTO((int, struct obstack *)); -extern tree cons_up_default_function PROTO((tree, tree, int)); -extern void check_for_missing_semicolon PROTO((tree)); -extern void note_got_semicolon PROTO((tree)); -extern void note_list_got_semicolon PROTO((tree)); -extern void do_pending_lang_change PROTO((void)); -extern int identifier_type PROTO((tree)); -extern void see_typename PROTO((void)); -extern tree do_identifier PROTO((tree, int, tree)); -extern tree do_scoped_id PROTO((tree, int)); -extern tree identifier_typedecl_value PROTO((tree)); -extern int real_yylex PROTO((void)); -extern int is_rid PROTO((tree)); -extern tree build_lang_decl PROTO((enum tree_code, tree, tree)); -extern void retrofit_lang_decl PROTO((tree)); -extern tree build_lang_field_decl PROTO((enum tree_code, tree, tree)); -extern void copy_lang_decl PROTO((tree)); -extern tree make_lang_type PROTO((enum tree_code)); -extern void dump_time_statistics PROTO((void)); -/* extern void compiler_error PROTO((char *, HOST_WIDE_INT, HOST_WIDE_INT)); */ -extern void yyerror PROTO((char *)); -extern void clear_inline_text_obstack PROTO((void)); -extern void maybe_snarf_defarg PROTO((void)); -extern tree snarf_defarg PROTO((void)); -extern void add_defarg_fn PROTO((tree)); -extern void do_pending_defargs PROTO((void)); -extern int identifier_type PROTO((tree)); -extern void yyhook PROTO((int)); -extern int cp_type_qual_from_rid PROTO((tree)); - -/* in method.c */ -extern void init_method PROTO((void)); -extern void do_inline_function_hair PROTO((tree, tree)); -extern char *build_overload_name PROTO((tree, int, int)); -extern tree build_static_name PROTO((tree, tree)); -extern tree build_decl_overload PROTO((tree, tree, int)); -extern tree build_decl_overload_real PROTO((tree, tree, tree, tree, - tree, int)); -extern void set_mangled_name_for_decl PROTO((tree)); -extern tree build_typename_overload PROTO((tree)); -extern tree build_overload_with_type PROTO((tree, tree)); -extern tree build_destructor_name PROTO((tree)); -extern tree build_opfncall PROTO((enum tree_code, int, tree, tree, tree)); -extern tree hack_identifier PROTO((tree, tree)); -extern tree make_thunk PROTO((tree, int)); -extern void emit_thunk PROTO((tree)); -extern void synthesize_method PROTO((tree)); -extern tree get_id_2 PROTO((char *, tree)); - -/* in pt.c */ -extern void check_template_shadow PROTO ((tree)); -extern tree innermost_args PROTO ((tree)); -extern tree tsubst PROTO ((tree, tree, tree)); -extern tree tsubst_expr PROTO ((tree, tree, tree)); -extern tree tsubst_copy PROTO ((tree, tree, tree)); -extern void maybe_begin_member_template_processing PROTO((tree)); -extern void maybe_end_member_template_processing PROTO((void)); -extern tree finish_member_template_decl PROTO((tree)); -extern void begin_template_parm_list PROTO((void)); -extern void begin_specialization PROTO((void)); -extern void reset_specialization PROTO((void)); -extern void end_specialization PROTO((void)); -extern void begin_explicit_instantiation PROTO((void)); -extern void end_explicit_instantiation PROTO((void)); -extern tree determine_specialization PROTO((tree, tree, tree *, int, int)); -extern tree check_explicit_specialization PROTO((tree, tree, int, int)); -extern tree process_template_parm PROTO((tree, tree)); -extern tree end_template_parm_list PROTO((tree)); -extern void end_template_decl PROTO((void)); -extern tree current_template_args PROTO((void)); -extern tree push_template_decl PROTO((tree)); -extern tree push_template_decl_real PROTO((tree, int)); -extern void redeclare_class_template PROTO((tree, tree)); -extern tree lookup_template_class PROTO((tree, tree, tree, tree, int)); -extern tree lookup_template_function PROTO((tree, tree)); -extern int uses_template_parms PROTO((tree)); -extern tree instantiate_class_template PROTO((tree)); -extern tree instantiate_template PROTO((tree, tree)); -extern void overload_template_name PROTO((tree)); -extern int fn_type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, tree)); -extern int type_unification PROTO((tree, tree, tree, tree, tree, unification_kind_t, int)); -struct tinst_level *tinst_for_decl PROTO((void)); -extern void mark_decl_instantiated PROTO((tree, int)); -extern int more_specialized PROTO((tree, tree, tree)); -extern void mark_class_instantiated PROTO((tree, int)); -extern void do_decl_instantiation PROTO((tree, tree, tree)); -extern void do_type_instantiation PROTO((tree, tree)); -extern tree instantiate_decl PROTO((tree)); -extern tree do_poplevel PROTO((void)); -extern tree get_bindings PROTO((tree, tree, tree)); -/* CONT ... */ -extern void add_tree PROTO((tree)); -extern void begin_tree PROTO((void)); -extern void end_tree PROTO((void)); -extern void add_maybe_template PROTO((tree, tree)); -extern void pop_tinst_level PROTO((void)); -extern int more_specialized_class PROTO((tree, tree)); -extern void do_pushlevel PROTO((void)); -extern int is_member_template PROTO((tree)); -extern int template_parms_equal PROTO((tree, tree)); -extern int comp_template_parms PROTO((tree, tree)); -extern int template_class_depth PROTO((tree)); -extern int is_specialization_of PROTO((tree, tree)); -extern int comp_template_args PROTO((tree, tree)); -extern void maybe_process_partial_specialization PROTO((tree)); -extern void maybe_check_template_type PROTO((tree)); -extern tree most_specialized_instantiation PROTO((tree, tree)); -extern void print_candidates PROTO((tree)); - -extern int processing_specialization; -extern int processing_explicit_instantiation; -extern int processing_template_parmlist; - -/* in repo.c */ -extern void repo_template_used PROTO((tree)); -extern void repo_template_instantiated PROTO((tree, int)); -extern void init_repo PROTO((char*)); -extern void finish_repo PROTO((void)); - -/* in rtti.c */ -extern void init_rtti_processing PROTO((void)); -extern tree get_tinfo_fn_dynamic PROTO((tree)); -extern tree build_typeid PROTO((tree)); -extern tree build_x_typeid PROTO((tree)); -extern tree get_tinfo_fn PROTO((tree)); -extern tree get_typeid PROTO((tree)); -extern tree get_typeid_1 PROTO((tree)); -extern tree build_dynamic_cast PROTO((tree, tree)); -extern void synthesize_tinfo_fn PROTO((tree)); - -/* in search.c */ -extern int types_overlap_p PROTO((tree, tree)); -extern tree get_vbase PROTO((tree, tree)); -extern tree get_binfo PROTO((tree, tree, int)); -extern int get_base_distance PROTO((tree, tree, int, tree *)); -extern tree compute_access PROTO((tree, tree)); -extern tree lookup_field PROTO((tree, tree, int, int)); -extern tree lookup_nested_field PROTO((tree, int)); -extern tree lookup_fnfields PROTO((tree, tree, int)); -extern tree lookup_member PROTO((tree, tree, int, int)); -extern tree lookup_nested_tag PROTO((tree, tree)); -extern tree get_matching_virtual PROTO((tree, tree, int)); -extern tree get_abstract_virtuals PROTO((tree)); -extern tree get_baselinks PROTO((tree, tree, tree)); -extern tree next_baselink PROTO((tree)); -extern tree init_vbase_pointers PROTO((tree, tree)); -extern void expand_indirect_vtbls_init PROTO((tree, tree, tree)); -extern void clear_search_slots PROTO((tree)); -extern tree get_vbase_types PROTO((tree)); -extern void note_debug_info_needed PROTO((tree)); -extern void push_class_decls PROTO((tree)); -extern void pop_class_decls PROTO((void)); -extern void unuse_fields PROTO((tree)); -extern void print_search_statistics PROTO((void)); -extern void init_search_processing PROTO((void)); -extern void reinit_search_statistics PROTO((void)); -extern tree current_scope PROTO((void)); -extern tree lookup_conversions PROTO((tree)); -extern tree get_template_base PROTO((tree, tree)); -extern tree binfo_for_vtable PROTO((tree)); - -/* in semantics.c */ -extern void finish_expr_stmt PROTO((tree)); -extern tree begin_if_stmt PROTO((void)); -extern void finish_if_stmt_cond PROTO((tree, tree)); -extern tree finish_then_clause PROTO((tree)); -extern void begin_else_clause PROTO((void)); -extern void finish_else_clause PROTO((tree)); -extern void finish_if_stmt PROTO((void)); -extern tree begin_while_stmt PROTO((void)); -extern void finish_while_stmt_cond PROTO((tree, tree)); -extern void finish_while_stmt PROTO((tree)); -extern tree begin_do_stmt PROTO((void)); -extern void finish_do_body PROTO((tree)); -extern void finish_do_stmt PROTO((tree, tree)); -extern void finish_return_stmt PROTO((tree)); -extern tree begin_for_stmt PROTO((void)); -extern void finish_for_init_stmt PROTO((tree)); -extern void finish_for_cond PROTO((tree, tree)); -extern void finish_for_expr PROTO((tree, tree)); -extern void finish_for_stmt PROTO((tree, tree)); -extern void finish_break_stmt PROTO((void)); -extern void finish_continue_stmt PROTO((void)); -extern void begin_switch_stmt PROTO((void)); -extern tree finish_switch_cond PROTO((tree)); -extern void finish_switch_stmt PROTO((tree, tree)); -extern void finish_case_label PROTO((tree, tree)); -extern void finish_goto_stmt PROTO((tree)); -extern tree begin_try_block PROTO((void)); -extern void finish_try_block PROTO((tree)); -extern void finish_handler_sequence PROTO((tree)); -extern tree begin_handler PROTO((void)); -extern void finish_handler_parms PROTO((tree)); -extern void finish_handler PROTO((tree)); -extern tree begin_compound_stmt PROTO((int)); -extern tree finish_compound_stmt PROTO((int, tree)); -extern void finish_asm_stmt PROTO((tree, tree, tree, tree, tree)); -extern tree finish_parenthesized_expr PROTO((tree)); -extern tree begin_stmt_expr PROTO((void)); -extern tree finish_stmt_expr PROTO((tree, tree)); -extern tree finish_call_expr PROTO((tree, tree, int)); -extern tree finish_increment_expr PROTO((tree, enum tree_code)); -extern tree finish_this_expr PROTO((void)); -extern tree finish_object_call_expr PROTO((tree, tree, tree)); -extern tree finish_qualified_object_call_expr PROTO((tree, tree, tree)); -extern tree finish_pseudo_destructor_call_expr PROTO((tree, tree, tree)); -extern tree finish_qualified_call_expr PROTO ((tree, tree)); -extern tree finish_label_address_expr PROTO((tree)); -extern tree finish_unary_op_expr PROTO((enum tree_code, tree)); -extern tree finish_id_expr PROTO((tree)); -extern int begin_new_placement PROTO((void)); -extern tree finish_new_placement PROTO((tree, int)); -extern int begin_function_definition PROTO((tree, tree)); -extern tree begin_constructor_declarator PROTO((tree, tree)); -extern tree finish_declarator PROTO((tree, tree, tree, tree, int)); -extern void finish_translation_unit PROTO((void)); -extern tree finish_template_type_parm PROTO((tree, tree)); -extern tree finish_template_template_parm PROTO((tree, tree)); -extern tree finish_parmlist PROTO((tree, int)); -extern tree begin_class_definition PROTO((tree)); -extern tree finish_class_definition PROTO((tree, tree, int)); -extern void finish_default_args PROTO((void)); -extern void begin_inline_definitions PROTO((void)); -extern tree finish_member_class_template PROTO((tree)); -extern void finish_template_decl PROTO((tree)); -extern tree finish_template_type PROTO((tree, tree, int)); -extern void enter_scope_of PROTO((tree)); -extern tree finish_base_specifier PROTO((tree, tree, int)); -extern void finish_member_declaration PROTO((tree)); -extern void check_multiple_declarators PROTO((void)); -extern tree finish_typeof PROTO((tree)); - -/* in sig.c */ -extern tree build_signature_pointer_type PROTO((tree)); -extern tree build_signature_reference_type PROTO((tree)); -extern tree build_signature_pointer_constructor PROTO((tree, tree)); -extern tree build_signature_method_call PROTO((tree, tree)); -extern tree build_optr_ref PROTO((tree)); -extern void append_signature_fields PROTO((tree)); - -/* in spew.c */ -extern void init_spew PROTO((void)); -extern int peekyylex PROTO((void)); -extern int yylex PROTO((void)); -extern tree arbitrate_lookup PROTO((tree, tree, tree)); - -/* in tree.c */ -extern int pod_type_p PROTO((tree)); -extern void unshare_base_binfos PROTO((tree)); -extern int member_p PROTO((tree)); -extern int real_lvalue_p PROTO((tree)); -extern tree build_min PVPROTO((enum tree_code, tree, ...)); -extern tree build_min_nt PVPROTO((enum tree_code, ...)); -extern tree min_tree_cons PROTO((tree, tree, tree)); -extern int lvalue_p PROTO((tree)); -extern int lvalue_or_else PROTO((tree, char *)); -extern tree build_cplus_new PROTO((tree, tree)); -extern tree get_target_expr PROTO((tree)); -extern tree break_out_cleanups PROTO((tree)); -extern tree break_out_calls PROTO((tree)); -extern tree build_cplus_method_type PROTO((tree, tree, tree)); -extern tree build_cplus_staticfn_type PROTO((tree, tree, tree)); -extern tree build_cplus_array_type PROTO((tree, tree)); -extern int layout_basetypes PROTO((tree, int)); -extern tree build_vbase_pointer_fields PROTO((tree)); -extern tree build_base_fields PROTO((tree)); -extern tree hash_tree_cons PROTO((int, int, int, tree, tree, tree)); -extern tree hash_tree_chain PROTO((tree, tree)); -extern tree hash_chainon PROTO((tree, tree)); -extern tree get_decl_list PROTO((tree)); -extern tree make_binfo PROTO((tree, tree, tree, tree)); -extern tree binfo_value PROTO((tree, tree)); -extern tree reverse_path PROTO((tree)); -extern int count_functions PROTO((tree)); -extern int is_overloaded_fn PROTO((tree)); -extern tree get_first_fn PROTO((tree)); -extern tree binding_init PROTO((struct tree_binding*)); -extern int bound_pmf_p PROTO((tree)); -extern tree ovl_cons PROTO((tree, tree)); -extern tree scratch_ovl_cons PROTO((tree, tree)); -extern int ovl_member PROTO((tree, tree)); -extern tree build_overload PROTO((tree, tree)); -extern tree fnaddr_from_vtable_entry PROTO((tree)); -extern tree function_arg_chain PROTO((tree)); -extern int promotes_to_aggr_type PROTO((tree, enum tree_code)); -extern int is_aggr_type_2 PROTO((tree, tree)); -extern char *lang_printable_name PROTO((tree, int)); -extern tree build_exception_variant PROTO((tree, tree)); -extern tree copy_template_template_parm PROTO((tree)); -extern tree copy_to_permanent PROTO((tree)); -extern void print_lang_statistics PROTO((void)); -extern void __eprintf - PROTO((const char *, const char *, unsigned, const char *)); -extern tree array_type_nelts_total PROTO((tree)); -extern tree array_type_nelts_top PROTO((tree)); -extern tree break_out_target_exprs PROTO((tree)); -extern tree get_type_decl PROTO((tree)); -extern tree vec_binfo_member PROTO((tree, tree)); -extern tree hack_decl_function_context PROTO((tree)); -extern tree lvalue_type PROTO((tree)); -extern tree error_type PROTO((tree)); -extern tree make_temp_vec PROTO((int)); -extern tree build_ptr_wrapper PROTO((void *)); -extern tree build_expr_ptr_wrapper PROTO((void *)); -extern tree build_int_wrapper PROTO((int)); -extern tree build_srcloc PROTO((char *, int)); -extern tree build_srcloc_here PROTO((void)); -extern int varargs_function_p PROTO((tree)); -extern int really_overloaded_fn PROTO((tree)); -extern int cp_tree_equal PROTO((tree, tree)); -extern int can_free PROTO((struct obstack *, tree)); -extern tree mapcar PROTO((tree, tree (*) (tree))); -extern tree no_linkage_check PROTO((tree)); -extern void debug_binfo PROTO((tree)); -extern void push_expression_obstack PROTO((void)); -extern tree build_dummy_object PROTO((tree)); -extern tree maybe_dummy_object PROTO((tree, tree *)); -extern int is_dummy_object PROTO((tree)); -extern tree search_tree PROTO((tree, tree (*)(tree))); -#define scratchalloc expralloc -#define scratch_tree_cons expr_tree_cons -#define build_scratch_list build_expr_list -#define make_scratch_vec make_temp_vec -#define push_scratch_obstack push_expression_obstack -#define hash_tree_cons_simple(PURPOSE, VALUE, CHAIN) \ - hash_tree_cons (0, 0, 0, (PURPOSE), (VALUE), (CHAIN)) - -/* in typeck.c */ -extern int string_conv_p PROTO((tree, tree, int)); -extern tree condition_conversion PROTO((tree)); -extern tree target_type PROTO((tree)); -extern tree require_complete_type PROTO((tree)); -extern tree complete_type PROTO((tree)); -extern tree complete_type_or_else PROTO((tree)); -extern int type_unknown_p PROTO((tree)); -extern int fntype_p PROTO((tree)); -extern tree commonparms PROTO((tree, tree)); -extern tree original_type PROTO((tree)); -extern tree common_type PROTO((tree, tree)); -extern int compexcepttypes PROTO((tree, tree)); -extern int comptypes PROTO((tree, tree, int)); -extern int comp_target_types PROTO((tree, tree, int)); -extern int compparms PROTO((tree, tree)); -extern int comp_target_types PROTO((tree, tree, int)); -extern int comp_cv_qualification PROTO((tree, tree)); -extern int comp_cv_qual_signature PROTO((tree, tree)); -extern int self_promoting_args_p PROTO((tree)); -extern tree unsigned_type PROTO((tree)); -extern tree signed_type PROTO((tree)); -extern tree signed_or_unsigned_type PROTO((int, tree)); -extern tree expr_sizeof PROTO((tree)); -extern tree c_sizeof PROTO((tree)); -extern tree c_sizeof_nowarn PROTO((tree)); -extern tree c_alignof PROTO((tree)); -extern tree inline_conversion PROTO((tree)); -extern tree decay_conversion PROTO((tree)); -extern tree default_conversion PROTO((tree)); -extern tree build_object_ref PROTO((tree, tree, tree)); -extern tree build_component_ref_1 PROTO((tree, tree, int)); -extern tree build_component_ref PROTO((tree, tree, tree, int)); -extern tree build_x_component_ref PROTO((tree, tree, tree, int)); -extern tree build_x_indirect_ref PROTO((tree, char *)); -extern tree build_indirect_ref PROTO((tree, char *)); -extern tree build_array_ref PROTO((tree, tree)); -extern tree build_x_function_call PROTO((tree, tree, tree)); -extern tree get_member_function_from_ptrfunc PROTO((tree *, tree)); -extern tree build_function_call_real PROTO((tree, tree, int, int)); -extern tree build_function_call PROTO((tree, tree)); -extern tree build_function_call_maybe PROTO((tree, tree)); -extern tree convert_arguments PROTO((tree, tree, tree, int)); -extern tree build_x_binary_op PROTO((enum tree_code, tree, tree)); -extern tree build_binary_op PROTO((enum tree_code, tree, tree, int)); -extern tree build_binary_op_nodefault PROTO((enum tree_code, tree, tree, enum tree_code)); -extern tree build_component_addr PROTO((tree, tree, char *)); -extern tree build_x_unary_op PROTO((enum tree_code, tree)); -extern tree build_unary_op PROTO((enum tree_code, tree, int)); -extern tree unary_complex_lvalue PROTO((enum tree_code, tree)); -extern int mark_addressable PROTO((tree)); -extern tree build_x_conditional_expr PROTO((tree, tree, tree)); -extern tree build_conditional_expr PROTO((tree, tree, tree)); -extern tree build_x_compound_expr PROTO((tree)); -extern tree build_compound_expr PROTO((tree)); -extern tree build_static_cast PROTO((tree, tree)); -extern tree build_reinterpret_cast PROTO((tree, tree)); -extern tree build_const_cast PROTO((tree, tree)); -extern tree build_c_cast PROTO((tree, tree)); -extern tree build_x_modify_expr PROTO((tree, enum tree_code, tree)); -extern tree build_modify_expr PROTO((tree, enum tree_code, tree)); -extern void warn_for_assignment PROTO((char *, char *, char *, tree, int, int)); -extern tree convert_for_initialization PROTO((tree, tree, tree, int, char *, tree, int)); -extern void c_expand_asm_operands PROTO((tree, tree, tree, tree, int, char *, int)); -extern void c_expand_return PROTO((tree)); -extern tree c_expand_start_case PROTO((tree)); -extern int comp_ptr_ttypes PROTO((tree, tree)); -extern int ptr_reasonably_similar PROTO((tree, tree)); -extern tree build_ptrmemfunc PROTO((tree, tree, int)); -extern int cp_type_quals PROTO((tree)); -extern int cp_has_mutable_p PROTO((tree)); -extern int at_least_as_qualified_p PROTO((tree, tree)); -extern int more_qualified_p PROTO((tree, tree)); - -/* in typeck2.c */ -extern tree error_not_base_type PROTO((tree, tree)); -extern tree binfo_or_else PROTO((tree, tree)); -extern void readonly_error PROTO((tree, char *, int)); -extern void abstract_virtuals_error PROTO((tree, tree)); -extern void signature_error PROTO((tree, tree)); -extern void incomplete_type_error PROTO((tree, tree)); -extern void my_friendly_abort PROTO((int)) - ATTRIBUTE_NORETURN; -extern void my_friendly_assert PROTO((int, int)); -extern tree store_init_value PROTO((tree, tree)); -extern tree digest_init PROTO((tree, tree, tree *)); -extern tree build_scoped_ref PROTO((tree, tree)); -extern tree build_x_arrow PROTO((tree)); -extern tree build_m_component_ref PROTO((tree, tree)); -extern tree build_functional_cast PROTO((tree, tree)); -extern char *enum_name_string PROTO((tree, tree)); -extern void report_case_error PROTO((int, tree, tree, tree)); -extern void check_for_new_type PROTO((char *,flagged_type_tree)); -extern tree initializer_constant_valid_p PROTO((tree, tree)); - -/* in xref.c */ -extern void GNU_xref_begin PROTO((char *)); -extern void GNU_xref_end PROTO((int)); -extern void GNU_xref_file PROTO((char *)); -extern void GNU_xref_start_scope PROTO((HOST_WIDE_INT)); -extern void GNU_xref_end_scope PROTO((HOST_WIDE_INT, HOST_WIDE_INT, int, int)); -extern void GNU_xref_ref PROTO((tree, char *)); -extern void GNU_xref_decl PROTO((tree, tree)); -extern void GNU_xref_call PROTO((tree, char *)); -extern void GNU_xref_function PROTO((tree, tree)); -extern void GNU_xref_assign PROTO((tree)); -extern void GNU_xref_hier PROTO((tree, tree, int, int, int)); -extern void GNU_xref_member PROTO((tree, tree)); - -/* -- end of C++ */ - -#endif /* not _CP_TREE_H */ diff --git a/gcc/cp/cvt.c b/gcc/cp/cvt.c deleted file mode 100755 index b73020f..0000000 --- a/gcc/cp/cvt.c +++ /dev/null @@ -1,1143 +0,0 @@ -/* Language-level data type conversion for GNU C++. - Copyright (C) 1987, 88, 92-97, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file contains the functions for converting C expressions - to different data types. The only entry point is `convert'. - Every language front end must have a `convert' function - but what kind of conversions it does will depend on the language. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "flags.h" -#include "cp-tree.h" -#include "convert.h" -#include "toplev.h" -#include "decl.h" - -static tree cp_convert_to_pointer PROTO((tree, tree)); -static tree convert_to_pointer_force PROTO((tree, tree)); -static tree build_up_reference PROTO((tree, tree, int)); - -/* Change of width--truncation and extension of integers or reals-- - is represented with NOP_EXPR. Proper functioning of many things - assumes that no other conversions can be NOP_EXPRs. - - Conversion between integer and pointer is represented with CONVERT_EXPR. - Converting integer to real uses FLOAT_EXPR - and real to integer uses FIX_TRUNC_EXPR. - - Here is a list of all the functions that assume that widening and - narrowing is always done with a NOP_EXPR: - In convert.c, convert_to_integer. - In c-typeck.c, build_binary_op_nodefault (boolean ops), - and truthvalue_conversion. - In expr.c: expand_expr, for operands of a MULT_EXPR. - In fold-const.c: fold. - In tree.c: get_narrower and get_unwidened. - - C++: in multiple-inheritance, converting between pointers may involve - adjusting them by a delta stored within the class definition. */ - -/* Subroutines of `convert'. */ - -/* if converting pointer to pointer - if dealing with classes, check for derived->base or vice versa - else if dealing with method pointers, delegate - else convert blindly - else if converting class, pass off to build_type_conversion - else try C-style pointer conversion */ - -static tree -cp_convert_to_pointer (type, expr) - tree type, expr; -{ - register tree intype = TREE_TYPE (expr); - register enum tree_code form; - tree rval; - - if (IS_AGGR_TYPE (intype)) - { - intype = complete_type (intype); - if (TYPE_SIZE (intype) == NULL_TREE) - { - cp_error ("can't convert from incomplete type `%T' to `%T'", - intype, type); - return error_mark_node; - } - - rval = build_type_conversion (CONVERT_EXPR, type, expr, 1); - if (rval) - { - if (rval == error_mark_node) - cp_error ("conversion of `%E' from `%T' to `%T' is ambiguous", - expr, intype, type); - return rval; - } - } - - /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ - if (TREE_CODE (type) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node)) - { - /* Allow an implicit this pointer for pointer to member - functions. */ - if (TYPE_PTRMEMFUNC_P (intype)) - { - tree fntype = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (intype)); - tree decl = maybe_dummy_object (TYPE_METHOD_BASETYPE (fntype), 0); - expr = build (OFFSET_REF, fntype, decl, expr); - } - - if (TREE_CODE (expr) == OFFSET_REF - && TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE) - expr = resolve_offset_ref (expr); - if (TREE_CODE (TREE_TYPE (expr)) == METHOD_TYPE) - expr = build_addr_func (expr); - if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == METHOD_TYPE) - if (pedantic || warn_pmf2ptr) - cp_pedwarn ("converting from `%T' to `%T'", TREE_TYPE (expr), - type); - return build1 (NOP_EXPR, type, expr); - } - intype = TREE_TYPE (expr); - } - - form = TREE_CODE (intype); - - if (POINTER_TYPE_P (intype)) - { - intype = TYPE_MAIN_VARIANT (intype); - - if (TYPE_MAIN_VARIANT (type) != intype - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE - && IS_AGGR_TYPE (TREE_TYPE (type)) - && IS_AGGR_TYPE (TREE_TYPE (intype)) - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE - /* If EXPR is NULL, then we don't need to do any arithmetic - to convert it: - - [conv.ptr] - - The null pointer value is converted to the null pointer - value of the destination type. */ - && !integer_zerop (expr)) - { - enum tree_code code = PLUS_EXPR; - tree binfo = get_binfo (TREE_TYPE (type), TREE_TYPE (intype), 1); - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == NULL_TREE) - { - binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 1); - if (binfo == error_mark_node) - return error_mark_node; - code = MINUS_EXPR; - } - if (binfo) - { - if (TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (type)) - || TYPE_USES_VIRTUAL_BASECLASSES (TREE_TYPE (intype)) - || ! BINFO_OFFSET_ZEROP (binfo)) - { - /* Need to get the path we took. */ - tree path; - - if (code == PLUS_EXPR) - get_base_distance (TREE_TYPE (type), TREE_TYPE (intype), - 0, &path); - else - get_base_distance (TREE_TYPE (intype), TREE_TYPE (type), - 0, &path); - return build_vbase_path (code, type, expr, path, 0); - } - } - } - - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE - && TREE_CODE (TREE_TYPE (intype)) == OFFSET_TYPE) - { - tree b1 = TYPE_OFFSET_BASETYPE (TREE_TYPE (type)); - tree b2 = TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)); - tree binfo = get_binfo (b2, b1, 1); - enum tree_code code = PLUS_EXPR; - - if (binfo == NULL_TREE) - { - binfo = get_binfo (b1, b2, 1); - code = MINUS_EXPR; - } - - if (binfo == error_mark_node) - return error_mark_node; - if (binfo && ! TREE_VIA_VIRTUAL (binfo)) - expr = size_binop (code, expr, BINFO_OFFSET (binfo)); - } - else if (TYPE_PTRMEMFUNC_P (type)) - { - cp_error ("cannot convert `%E' from type `%T' to type `%T'", - expr, intype, type); - return error_mark_node; - } - - rval = build1 (NOP_EXPR, type, expr); - TREE_CONSTANT (rval) = TREE_CONSTANT (expr); - return rval; - } - else if (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype)) - return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 1); - else if (TYPE_PTRMEMFUNC_P (intype)) - { - cp_error ("cannot convert `%E' from type `%T' to type `%T'", - expr, intype, type); - return error_mark_node; - } - - my_friendly_assert (form != OFFSET_TYPE, 186); - - if (TYPE_LANG_SPECIFIC (intype) - && (IS_SIGNATURE_POINTER (intype) || IS_SIGNATURE_REFERENCE (intype))) - return convert_to_pointer (type, build_optr_ref (expr)); - - if (integer_zerop (expr)) - { - if (TYPE_PTRMEMFUNC_P (type)) - return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), expr, 0); - expr = build_int_2 (0, 0); - TREE_TYPE (expr) = type; - return expr; - } - - if (INTEGRAL_CODE_P (form)) - { - if (TYPE_PRECISION (intype) == POINTER_SIZE) - return build1 (CONVERT_EXPR, type, expr); - expr = cp_convert (type_for_size (POINTER_SIZE, 0), expr); - /* Modes may be different but sizes should be the same. */ - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (expr))) - != GET_MODE_SIZE (TYPE_MODE (type))) - /* There is supposed to be some integral type - that is the same width as a pointer. */ - abort (); - return convert_to_pointer (type, expr); - } - - if (type_unknown_p (expr)) - return instantiate_type (type, expr, 1); - - cp_error ("cannot convert `%E' from type `%T' to type `%T'", - expr, intype, type); - return error_mark_node; -} - -/* Like convert, except permit conversions to take place which - are not normally allowed due to access restrictions - (such as conversion from sub-type to private super-type). */ - -static tree -convert_to_pointer_force (type, expr) - tree type, expr; -{ - register tree intype = TREE_TYPE (expr); - register enum tree_code form = TREE_CODE (intype); - - if (integer_zerop (expr)) - { - expr = build_int_2 (0, 0); - TREE_TYPE (expr) = type; - return expr; - } - - /* Convert signature pointer/reference to `void *' first. */ - if (form == RECORD_TYPE - && (IS_SIGNATURE_POINTER (intype) || IS_SIGNATURE_REFERENCE (intype))) - { - expr = build_optr_ref (expr); - intype = TREE_TYPE (expr); - form = TREE_CODE (intype); - } - - if (form == POINTER_TYPE) - { - intype = TYPE_MAIN_VARIANT (intype); - - if (TYPE_MAIN_VARIANT (type) != intype - && TREE_CODE (TREE_TYPE (type)) == RECORD_TYPE - && IS_AGGR_TYPE (TREE_TYPE (type)) - && IS_AGGR_TYPE (TREE_TYPE (intype)) - && TREE_CODE (TREE_TYPE (intype)) == RECORD_TYPE) - { - enum tree_code code = PLUS_EXPR; - tree path; - int distance = get_base_distance (TREE_TYPE (type), - TREE_TYPE (intype), 0, &path); - if (distance == -2) - { - ambig: - cp_error ("type `%T' is ambiguous baseclass of `%s'", - TREE_TYPE (type), - TYPE_NAME_STRING (TREE_TYPE (intype))); - return error_mark_node; - } - if (distance == -1) - { - distance = get_base_distance (TREE_TYPE (intype), - TREE_TYPE (type), 0, &path); - if (distance == -2) - goto ambig; - if (distance < 0) - /* Doesn't need any special help from us. */ - return build1 (NOP_EXPR, type, expr); - - code = MINUS_EXPR; - } - return build_vbase_path (code, type, expr, path, 0); - } - } - - return cp_convert_to_pointer (type, expr); -} - -/* We are passing something to a function which requires a reference. - The type we are interested in is in TYPE. The initial - value we have to begin with is in ARG. - - FLAGS controls how we manage access checking. - DIRECT_BIND in FLAGS controls how any temporaries are generated. */ - -static tree -build_up_reference (type, arg, flags) - tree type, arg; - int flags; -{ - tree rval; - tree argtype = TREE_TYPE (arg); - tree target_type = TREE_TYPE (type); - - my_friendly_assert (TREE_CODE (type) == REFERENCE_TYPE, 187); - - if ((flags & DIRECT_BIND) && ! real_lvalue_p (arg)) - { - tree targ = arg; - if (toplevel_bindings_p ()) - arg = get_temp_name (argtype, 1); - else - { - arg = pushdecl (build_decl (VAR_DECL, NULL_TREE, argtype)); - DECL_ARTIFICIAL (arg) = 1; - } - DECL_INITIAL (arg) = targ; - cp_finish_decl (arg, targ, NULL_TREE, 0, - LOOKUP_ONLYCONVERTING|DIRECT_BIND); - } - else if (!(flags & DIRECT_BIND) && ! lvalue_p (arg)) - { - tree slot = build_decl (VAR_DECL, NULL_TREE, argtype); - DECL_ARTIFICIAL (slot) = 1; - arg = build (TARGET_EXPR, argtype, slot, arg, NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (arg) = 1; - } - - /* If we had a way to wrap this up, and say, if we ever needed it's - address, transform all occurrences of the register, into a memory - reference we could win better. */ - rval = build_unary_op (ADDR_EXPR, arg, 1); - if (rval == error_mark_node) - return error_mark_node; - - if ((flags & LOOKUP_PROTECT) - && TYPE_MAIN_VARIANT (argtype) != TYPE_MAIN_VARIANT (target_type) - && IS_AGGR_TYPE (argtype) - && IS_AGGR_TYPE (target_type)) - { - /* We go through get_binfo for the access control. */ - tree binfo = get_binfo (target_type, argtype, 1); - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == NULL_TREE) - return error_not_base_type (target_type, argtype); - rval = convert_pointer_to_real (binfo, rval); - } - else - rval - = convert_to_pointer_force (build_pointer_type (target_type), rval); - rval = build1 (NOP_EXPR, type, rval); - TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); - return rval; -} - -/* For C++: Only need to do one-level references, but cannot - get tripped up on signed/unsigned differences. - - DECL is either NULL_TREE or the _DECL node for a reference that is being - initialized. It can be error_mark_node if we don't know the _DECL but - we know it's an initialization. */ - -tree -convert_to_reference (reftype, expr, convtype, flags, decl) - tree reftype, expr; - int convtype, flags; - tree decl; -{ - register tree type = TYPE_MAIN_VARIANT (TREE_TYPE (reftype)); - register tree intype = TREE_TYPE (expr); - tree rval = NULL_TREE; - tree rval_as_conversion = NULL_TREE; - int i; - - if (TREE_CODE (type) == FUNCTION_TYPE && intype == unknown_type_node) - { - expr = instantiate_type (type, expr, - (flags & LOOKUP_COMPLAIN) != 0); - if (expr == error_mark_node) - return error_mark_node; - - intype = TREE_TYPE (expr); - } - - if (TREE_CODE (intype) == REFERENCE_TYPE) - my_friendly_abort (364); - - intype = TYPE_MAIN_VARIANT (intype); - - i = comp_target_types (type, intype, 0); - - if (i <= 0 && (convtype & CONV_IMPLICIT) && IS_AGGR_TYPE (intype) - && ! (flags & LOOKUP_NO_CONVERSION)) - { - /* Look for a user-defined conversion to lvalue that we can use. */ - - rval_as_conversion - = build_type_conversion (CONVERT_EXPR, reftype, expr, 1); - - if (rval_as_conversion && rval_as_conversion != error_mark_node - && real_lvalue_p (rval_as_conversion)) - { - expr = rval_as_conversion; - rval_as_conversion = NULL_TREE; - intype = type; - i = 1; - } - } - - if (((convtype & CONV_STATIC) && i == -1) - || ((convtype & CONV_IMPLICIT) && i == 1)) - { - if (flags & LOOKUP_COMPLAIN) - { - tree ttl = TREE_TYPE (reftype); - tree ttr = lvalue_type (expr); - - /* [dcl.init.ref] says that if an rvalue is used to - initialize a reference, then the reference must be to a - non-volatile const type. */ - if (! real_lvalue_p (expr) - && !CP_TYPE_CONST_NON_VOLATILE_P (ttl)) - { - char* msg; - - if (CP_TYPE_VOLATILE_P (ttl) && decl) - msg = "initialization of volatile reference type `%#T'"; - else if (CP_TYPE_VOLATILE_P (ttl)) - msg = "conversion to volatile reference type `%#T'"; - else if (decl) - msg = "initialization of non-const reference type `%#T'"; - else - msg = "conversion to non-const reference type `%#T'"; - - cp_pedwarn (msg, reftype); - cp_pedwarn ("from rvalue of type `%T'", intype); - } - else if (! (convtype & CONV_CONST) - && !at_least_as_qualified_p (ttl, ttr)) - cp_pedwarn ("conversion from `%T' to `%T' discards qualifiers", - ttr, reftype); - } - - return build_up_reference (reftype, expr, flags); - } - else if ((convtype & CONV_REINTERPRET) && lvalue_p (expr)) - { - /* When casting an lvalue to a reference type, just convert into - a pointer to the new type and deference it. This is allowed - by San Diego WP section 5.2.9 paragraph 12, though perhaps it - should be done directly (jason). (int &)ri ---> *(int*)&ri */ - - /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they - meant. */ - if (TREE_CODE (intype) == POINTER_TYPE - && (comptypes (TREE_TYPE (intype), type, - COMPARE_BASE | COMPARE_RELAXED ))) - cp_warning ("casting `%T' to `%T' does not dereference pointer", - intype, reftype); - - rval = build_unary_op (ADDR_EXPR, expr, 0); - if (rval != error_mark_node) - rval = convert_force (build_pointer_type (TREE_TYPE (reftype)), - rval, 0); - if (rval != error_mark_node) - rval = build1 (NOP_EXPR, reftype, rval); - } - else - { - rval = convert_for_initialization (NULL_TREE, type, expr, flags, - "converting", 0, 0); - if (rval == NULL_TREE || rval == error_mark_node) - return rval; - rval = build_up_reference (reftype, rval, flags); - - if (rval && ! CP_TYPE_CONST_P (TREE_TYPE (reftype))) - cp_pedwarn ("initializing non-const `%T' with `%T' will use a temporary", - reftype, intype); - } - - if (rval) - { - /* If we found a way to convert earlier, then use it. */ - return rval; - } - - my_friendly_assert (TREE_CODE (intype) != OFFSET_TYPE, 189); - - if (flags & LOOKUP_COMPLAIN) - cp_error ("cannot convert type `%T' to type `%T'", intype, reftype); - - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - - return error_mark_node; -} - -/* We are using a reference VAL for its value. Bash that reference all the - way down to its lowest form. */ - -tree -convert_from_reference (val) - tree val; -{ - tree type = TREE_TYPE (val); - - if (TREE_CODE (type) == OFFSET_TYPE) - type = TREE_TYPE (type); - if (TREE_CODE (type) == REFERENCE_TYPE) - return build_indirect_ref (val, NULL_PTR); - return val; -} - -/* Call this when we know (for any reason) that expr is not, in fact, - zero. This routine is like convert_pointer_to, but it pays - attention to which specific instance of what type we want to - convert to. This routine should eventually become - convert_to_pointer after all references to convert_to_pointer - are removed. */ - -tree -convert_pointer_to_real (binfo, expr) - tree binfo, expr; -{ - register tree intype = TREE_TYPE (expr); - tree ptr_type; - tree type, rval; - - if (intype == error_mark_node) - return error_mark_node; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE (binfo)) - { - type = binfo; - } - else - { - type = binfo; - binfo = NULL_TREE; - } - - ptr_type = cp_build_qualified_type (type, - CP_TYPE_QUALS (TREE_TYPE (intype))); - ptr_type = build_pointer_type (ptr_type); - if (ptr_type == TYPE_MAIN_VARIANT (intype)) - return expr; - - my_friendly_assert (!integer_zerop (expr), 191); - - intype = TYPE_MAIN_VARIANT (TREE_TYPE (intype)); - if (TREE_CODE (type) == RECORD_TYPE - && TREE_CODE (intype) == RECORD_TYPE - && type != intype) - { - tree path; - int distance - = get_base_distance (binfo, intype, 0, &path); - - /* This function shouldn't be called with unqualified arguments - but if it is, give them an error message that they can read. */ - if (distance < 0) - { - cp_error ("cannot convert a pointer of type `%T' to a pointer of type `%T'", - intype, type); - - if (distance == -2) - cp_error ("because `%T' is an ambiguous base class", type); - return error_mark_node; - } - - return build_vbase_path (PLUS_EXPR, ptr_type, expr, path, 1); - } - rval = build1 (NOP_EXPR, ptr_type, - TREE_CODE (expr) == NOP_EXPR ? TREE_OPERAND (expr, 0) : expr); - TREE_CONSTANT (rval) = TREE_CONSTANT (expr); - return rval; -} - -/* Call this when we know (for any reason) that expr is - not, in fact, zero. This routine gets a type out of the first - argument and uses it to search for the type to convert to. If there - is more than one instance of that type in the expr, the conversion is - ambiguous. This routine should eventually go away, and all - callers should use convert_to_pointer_real. */ - -tree -convert_pointer_to (binfo, expr) - tree binfo, expr; -{ - tree type; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE (binfo)) - type = binfo; - else - type = binfo; - return convert_pointer_to_real (type, expr); -} - -/* C++ conversions, preference to static cast conversions. */ - -tree -cp_convert (type, expr) - tree type, expr; -{ - return ocp_convert (type, expr, CONV_OLD_CONVERT, LOOKUP_NORMAL); -} - -/* Conversion... - - FLAGS indicates how we should behave. */ - -tree -ocp_convert (type, expr, convtype, flags) - tree type, expr; - int convtype, flags; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (e == error_mark_node - || TREE_TYPE (e) == error_mark_node) - return error_mark_node; - - if (TREE_READONLY_DECL_P (e)) - e = decl_constant_value (e); - - if (IS_AGGR_TYPE (type) && (convtype & CONV_FORCE_TEMP) - /* Some internal structures (vtable_entry_type, sigtbl_ptr_type) - don't go through finish_struct, so they don't have the synthesized - constructors. So don't force a temporary. */ - && TYPE_HAS_CONSTRUCTOR (type)) - /* We need a new temporary; don't take this shortcut. */; - else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) - { - if (same_type_p (type, TREE_TYPE (e))) - /* The call to fold will not always remove the NOP_EXPR as - might be expected, since if one of the types is a typedef; - the comparsion in fold is just equality of pointers, not a - call to comptypes. We don't call fold in this case because - that can result in infinite recursion; fold will call - convert, which will call ocp_convert, etc. */ - return e; - else - return fold (build1 (NOP_EXPR, type, e)); - } - - if (code == VOID_TYPE && (convtype & CONV_STATIC)) - { - if (type_unknown_p (e)) - error ("address of overloaded function with no contextual type information"); - - return build1 (CONVERT_EXPR, type, e); - } - -#if 0 - /* This is incorrect. A truncation can't be stripped this way. - Extensions will be stripped by the use of get_unwidened. */ - if (TREE_CODE (e) == NOP_EXPR) - return cp_convert (type, TREE_OPERAND (e, 0)); -#endif - - /* Just convert to the type of the member. */ - if (code == OFFSET_TYPE) - { - type = TREE_TYPE (type); - code = TREE_CODE (type); - } - -#if 0 - if (code == REFERENCE_TYPE) - return fold (convert_to_reference (type, e, convtype, flags, NULL_TREE)); - else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) - e = convert_from_reference (e); -#endif - - if (TREE_CODE (e) == OFFSET_REF) - e = resolve_offset_ref (e); - - if (INTEGRAL_CODE_P (code)) - { - tree intype = TREE_TYPE (e); - /* enum = enum, enum = int, enum = float, (enum)pointer are all - errors. */ - if (TREE_CODE (type) == ENUMERAL_TYPE - && ((ARITHMETIC_TYPE_P (intype) && ! (convtype & CONV_STATIC)) - || (TREE_CODE (intype) == POINTER_TYPE))) - { - cp_pedwarn ("conversion from `%#T' to `%#T'", intype, type); - - if (flag_pedantic_errors) - return error_mark_node; - } - if (IS_AGGR_TYPE (intype)) - { - tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, e, 1); - if (rval) - return rval; - if (flags & LOOKUP_COMPLAIN) - cp_error ("`%#T' used where a `%T' was expected", intype, type); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; - } - if (code == BOOLEAN_TYPE) - { - /* Common Ada/Pascal programmer's mistake. We always warn - about this since it is so bad. */ - if (TREE_CODE (expr) == FUNCTION_DECL) - cp_warning ("the address of `%D', will always be `true'", expr); - return truthvalue_conversion (e); - } - return fold (convert_to_integer (type, e)); - } - if (code == POINTER_TYPE || code == REFERENCE_TYPE - || TYPE_PTRMEMFUNC_P (type)) - return fold (cp_convert_to_pointer (type, e)); - if (code == REAL_TYPE || code == COMPLEX_TYPE) - { - if (IS_AGGR_TYPE (TREE_TYPE (e))) - { - tree rval; - rval = build_type_conversion (CONVERT_EXPR, type, e, 1); - if (rval) - return rval; - else - if (flags & LOOKUP_COMPLAIN) - cp_error ("`%#T' used where a floating point value was expected", - TREE_TYPE (e)); - } - if (code == REAL_TYPE) - return fold (convert_to_real (type, e)); - else if (code == COMPLEX_TYPE) - return fold (convert_to_complex (type, e)); - } - - /* New C++ semantics: since assignment is now based on - memberwise copying, if the rhs type is derived from the - lhs type, then we may still do a conversion. */ - if (IS_AGGR_TYPE_CODE (code)) - { - tree dtype = TREE_TYPE (e); - tree ctor = NULL_TREE; - - dtype = TYPE_MAIN_VARIANT (dtype); - - /* Conversion of object pointers or signature pointers/references - to signature pointers/references. */ - - if (TYPE_LANG_SPECIFIC (type) - && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))) - { - tree constructor = build_signature_pointer_constructor (type, expr); - tree sig_ty = SIGNATURE_TYPE (type); - tree sig_ptr; - - if (constructor == error_mark_node) - return error_mark_node; - - sig_ptr = get_temp_name (type, 1); - DECL_INITIAL (sig_ptr) = constructor; - CLEAR_SIGNATURE (sig_ty); - cp_finish_decl (sig_ptr, constructor, NULL_TREE, 0, 0); - SET_SIGNATURE (sig_ty); - TREE_READONLY (sig_ptr) = 1; - - return sig_ptr; - } - - /* Conversion between aggregate types. New C++ semantics allow - objects of derived type to be cast to objects of base type. - Old semantics only allowed this between pointers. - - There may be some ambiguity between using a constructor - vs. using a type conversion operator when both apply. */ - - ctor = e; - - if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - { - abstract_virtuals_error (NULL_TREE, type); - return error_mark_node; - } - - if ((flags & LOOKUP_ONLYCONVERTING) - && ! (IS_AGGR_TYPE (dtype) && DERIVED_FROM_P (type, dtype))) - /* For copy-initialization, first we create a temp of the proper type - with a user-defined conversion sequence, then we direct-initialize - the target with the temp (see [dcl.init]). */ - ctor = build_user_type_conversion (type, ctor, flags); - if (ctor) - ctor = build_method_call (NULL_TREE, ctor_identifier, - build_expr_list (NULL_TREE, ctor), - TYPE_BINFO (type), flags); - if (ctor) - return build_cplus_new (type, ctor); - } - - /* If TYPE or TREE_TYPE (E) is not on the permanent_obstack, - then it won't be hashed and hence compare as not equal, - even when it is. */ - if (code == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (e)) == TREE_TYPE (type) - && index_type_equal (TYPE_DOMAIN (TREE_TYPE (e)), TYPE_DOMAIN (type))) - return e; - - if (flags & LOOKUP_COMPLAIN) - cp_error ("conversion from `%T' to non-scalar type `%T' requested", - TREE_TYPE (expr), type); - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - return error_mark_node; -} - -/* Create an expression whose value is that of EXPR, - converted to type TYPE. The TREE_TYPE of the value - is always TYPE. This function implements all reasonable - conversions; callers should filter out those that are - not permitted by the language being compiled. - - Most of this routine is from build_reinterpret_cast. - - The backend cannot call cp_convert (what was convert) because - conversions to/from basetypes may involve memory references - (vbases) and adding or subtracting small values (multiple - inheritance), but it calls convert from the constant folding code - on subtrees of already build trees after it has ripped them apart. - - Also, if we ever support range variables, we'll probably also have to - do a little bit more work. */ - -tree -convert (type, expr) - tree type, expr; -{ - tree intype; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - intype = TREE_TYPE (expr); - - if (POINTER_TYPE_P (type) && POINTER_TYPE_P (intype)) - { - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return fold (build1 (NOP_EXPR, type, expr)); - } - - return ocp_convert (type, expr, CONV_OLD_CONVERT, - LOOKUP_NORMAL|LOOKUP_NO_CONVERSION); -} - -/* Like cp_convert, except permit conversions to take place which - are not normally allowed due to access restrictions - (such as conversion from sub-type to private super-type). */ - -tree -convert_force (type, expr, convtype) - tree type; - tree expr; - int convtype; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (code == REFERENCE_TYPE) - return fold (convert_to_reference (type, e, CONV_C_CAST, LOOKUP_COMPLAIN, - NULL_TREE)); - else if (TREE_CODE (TREE_TYPE (e)) == REFERENCE_TYPE) - e = convert_from_reference (e); - - if (code == POINTER_TYPE) - return fold (convert_to_pointer_force (type, e)); - - /* From typeck.c convert_for_assignment */ - if (((TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE && TREE_CODE (e) == ADDR_EXPR - && TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (e))) == METHOD_TYPE) - || integer_zerop (e) - || TYPE_PTRMEMFUNC_P (TREE_TYPE (e))) - && TYPE_PTRMEMFUNC_P (type)) - { - /* compatible pointer to member functions. */ - return build_ptrmemfunc (TYPE_PTRMEMFUNC_FN_TYPE (type), e, 1); - } - - return ocp_convert (type, e, CONV_C_CAST|convtype, LOOKUP_NORMAL); -} - -/* Convert an aggregate EXPR to type XTYPE. If a conversion - exists, return the attempted conversion. This may - return ERROR_MARK_NODE if the conversion is not - allowed (references private members, etc). - If no conversion exists, NULL_TREE is returned. - - If (FOR_SURE & 1) is non-zero, then we allow this type conversion - to take place immediately. Otherwise, we build a SAVE_EXPR - which can be evaluated if the results are ever needed. - - Changes to this functions should be mirrored in user_harshness. - - FIXME: Ambiguity checking is wrong. Should choose one by the implicit - object parameter, or by the second standard conversion sequence if - that doesn't do it. This will probably wait for an overloading rewrite. - (jason 8/9/95) */ - -tree -build_type_conversion (code, xtype, expr, for_sure) - enum tree_code code ATTRIBUTE_UNUSED; - tree xtype, expr; - int for_sure; -{ - /* C++: check to see if we can convert this aggregate type - into the required type. */ - return build_user_type_conversion - (xtype, expr, for_sure ? LOOKUP_NORMAL : 0); -} - -/* Convert the given EXPR to one of a group of types suitable for use in an - expression. DESIRES is a combination of various WANT_* flags (q.v.) - which indicates which types are suitable. If COMPLAIN is 1, complain - about ambiguity; otherwise, the caller will deal with it. */ - -tree -build_expr_type_conversion (desires, expr, complain) - int desires; - tree expr; - int complain; -{ - tree basetype = TREE_TYPE (expr); - tree conv = NULL_TREE; - tree winner = NULL_TREE; - - if (expr == null_node - && (desires & WANT_INT) - && !(desires & WANT_NULL)) - cp_warning ("converting NULL to non-pointer type"); - - if (TREE_CODE (basetype) == OFFSET_TYPE) - expr = resolve_offset_ref (expr); - expr = convert_from_reference (expr); - basetype = TREE_TYPE (expr); - - if (! IS_AGGR_TYPE (basetype)) - switch (TREE_CODE (basetype)) - { - case INTEGER_TYPE: - if ((desires & WANT_NULL) && null_ptr_cst_p (expr)) - return expr; - /* else fall through... */ - - case BOOLEAN_TYPE: - return (desires & WANT_INT) ? expr : NULL_TREE; - case ENUMERAL_TYPE: - return (desires & WANT_ENUM) ? expr : NULL_TREE; - case REAL_TYPE: - return (desires & WANT_FLOAT) ? expr : NULL_TREE; - case POINTER_TYPE: - return (desires & WANT_POINTER) ? expr : NULL_TREE; - - case FUNCTION_TYPE: - case ARRAY_TYPE: - return (desires & WANT_POINTER) ? default_conversion (expr) - : NULL_TREE; - default: - return NULL_TREE; - } - - /* The code for conversions from class type is currently only used for - delete expressions. Other expressions are handled by build_new_op. */ - - if (! TYPE_HAS_CONVERSION (basetype)) - return NULL_TREE; - - for (conv = lookup_conversions (basetype); conv; conv = TREE_CHAIN (conv)) - { - int win = 0; - tree candidate; - tree cand = TREE_VALUE (conv); - - if (winner && winner == cand) - continue; - - candidate = TREE_TYPE (TREE_TYPE (cand)); - if (TREE_CODE (candidate) == REFERENCE_TYPE) - candidate = TREE_TYPE (candidate); - - switch (TREE_CODE (candidate)) - { - case BOOLEAN_TYPE: - case INTEGER_TYPE: - win = (desires & WANT_INT); break; - case ENUMERAL_TYPE: - win = (desires & WANT_ENUM); break; - case REAL_TYPE: - win = (desires & WANT_FLOAT); break; - case POINTER_TYPE: - win = (desires & WANT_POINTER); break; - - default: - break; - } - - if (win) - { - if (winner) - { - if (complain) - { - cp_error ("ambiguous default type conversion from `%T'", - basetype); - cp_error (" candidate conversions include `%D' and `%D'", - winner, cand); - } - return error_mark_node; - } - else - winner = cand; - } - } - - if (winner) - { - tree type = TREE_TYPE (TREE_TYPE (winner)); - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - return build_user_type_conversion (type, expr, LOOKUP_NORMAL); - } - - return NULL_TREE; -} - -/* Implements integral promotion (4.1) and float->double promotion. */ - -tree -type_promotes_to (type) - tree type; -{ - int type_quals; - - if (type == error_mark_node) - return error_mark_node; - - type_quals = CP_TYPE_QUALS (type); - type = TYPE_MAIN_VARIANT (type); - - /* bool always promotes to int (not unsigned), even if it's the same - size. */ - if (type == boolean_type_node) - type = integer_type_node; - - /* Normally convert enums to int, but convert wide enums to something - wider. */ - else if (TREE_CODE (type) == ENUMERAL_TYPE - || type == wchar_type_node) - { - int precision = MAX (TYPE_PRECISION (type), - TYPE_PRECISION (integer_type_node)); - tree totype = type_for_size (precision, 0); - if (TREE_UNSIGNED (type) - && ! int_fits_type_p (TYPE_MAX_VALUE (type), totype)) - type = type_for_size (precision, 1); - else - type = totype; - } - else if (C_PROMOTING_INTEGER_TYPE_P (type)) - { - /* Retain unsignedness if really not getting bigger. */ - if (TREE_UNSIGNED (type) - && TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - type = unsigned_type_node; - else - type = integer_type_node; - } - else if (type == float_type_node) - type = double_type_node; - - return cp_build_qualified_type (type, type_quals); -} - -/* The routines below this point are carefully written to conform to - the standard. They use the same terminology, and follow the rules - closely. Although they are used only in pt.c at the moment, they - should presumably be used everywhere in the future. */ - -/* Attempt to perform qualification conversions on EXPR to convert it - to TYPE. Return the resulting expression, or error_mark_node if - the conversion was impossible. */ - -tree -perform_qualification_conversions (type, expr) - tree type; - tree expr; -{ - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE - && comp_ptr_ttypes (TREE_TYPE (type), TREE_TYPE (TREE_TYPE (expr)))) - return build1 (NOP_EXPR, type, expr); - else - return error_mark_node; -} diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c deleted file mode 100755 index b023a2f..0000000 --- a/gcc/cp/decl.c +++ /dev/null @@ -1,14623 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "cp-tree.h" -#include "decl.h" -#include "lex.h" -#include <signal.h> -#include "obstack.h" -#include "defaults.h" -#include "output.h" -#include "except.h" -#include "toplev.h" -#include "../hash.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern tree builtin_return_address_fndecl; - -extern struct obstack permanent_obstack; -extern struct obstack* saveable_obstack; - -extern int current_class_depth; - -extern tree static_ctors, static_dtors; - -extern int static_labelno; - -extern tree current_namespace; -extern tree global_namespace; - -extern void (*print_error_function) PROTO((char *)); - -/* Stack of places to restore the search obstack back to. */ - -/* Obstack used for remembering local class declarations (like - enums and static (const) members. */ -#include "stack.h" -struct obstack decl_obstack; -static struct stack_level *decl_stack; - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) -#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 LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef BOOL_TYPE_SIZE -#ifdef SLOW_BYTE_ACCESS -#define BOOL_TYPE_SIZE ((SLOW_BYTE_ACCESS) ? (POINTER_SIZE) : (CHAR_TYPE_SIZE)) -#else -#define BOOL_TYPE_SIZE CHAR_TYPE_SIZE -#endif -#endif - -/* 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. */ - -#ifndef SIZE_TYPE -#define SIZE_TYPE "long unsigned int" -#endif - -#ifndef PTRDIFF_TYPE -#define PTRDIFF_TYPE "long int" -#endif - -#ifndef WCHAR_TYPE -#define WCHAR_TYPE "int" -#endif - -static tree grokparms PROTO((tree, int)); -static tree lookup_nested_type PROTO((tree, tree)); -static char *redeclaration_error_message PROTO((tree, tree)); - -static struct stack_level *push_decl_level PROTO((struct stack_level *, - struct obstack *)); -static void push_binding_level PROTO((struct binding_level *, int, - int)); -static void pop_binding_level PROTO((void)); -static void suspend_binding_level PROTO((void)); -static void resume_binding_level PROTO((struct binding_level *)); -static struct binding_level *make_binding_level PROTO((void)); -static void declare_namespace_level PROTO((void)); -static void signal_catch PROTO((int)) ATTRIBUTE_NORETURN; -static void storedecls PROTO((tree)); -static void storetags PROTO((tree)); -static void require_complete_types_for_parms PROTO((tree)); -static void push_overloaded_decl_1 PROTO((tree)); -static int ambi_op_p PROTO((tree)); -static int unary_op_p PROTO((tree)); -static tree store_bindings PROTO((tree, tree)); -static tree lookup_tag_reverse PROTO((tree, tree)); -static tree obscure_complex_init PROTO((tree, tree)); -static tree maybe_build_cleanup_1 PROTO((tree, tree)); -static tree lookup_name_real PROTO((tree, int, int, int)); -static void warn_extern_redeclared_static PROTO((tree, tree)); -static void grok_reference_init PROTO((tree, tree, tree)); -static tree grokfndecl PROTO((tree, tree, tree, tree, int, - enum overload_flags, tree, - tree, tree, int, int, int, int, int, int, tree)); -static tree grokvardecl PROTO((tree, tree, RID_BIT_TYPE *, int, int, tree)); -static tree lookup_tag PROTO((enum tree_code, tree, - struct binding_level *, int)); -static void set_identifier_type_value_with_scope - PROTO((tree, tree, struct binding_level *)); -static void record_builtin_type PROTO((enum rid, char *, tree)); -static void record_unknown_type PROTO((tree, char *)); -static int member_function_or_else PROTO((tree, tree, char *)); -static void bad_specifiers PROTO((tree, char *, int, int, int, int, - int)); -static void lang_print_error_function PROTO((char *)); -static tree maybe_process_template_type_declaration PROTO((tree, int, struct binding_level*)); -static void check_for_uninitialized_const_var PROTO((tree)); -static unsigned long typename_hash PROTO((hash_table_key)); -static boolean typename_compare PROTO((hash_table_key, hash_table_key)); -static void push_binding PROTO((tree, tree, struct binding_level*)); -static void add_binding PROTO((tree, tree)); -static void pop_binding PROTO((tree, tree)); -static tree local_variable_p PROTO((tree)); - -#if defined (DEBUG_CP_BINDING_LEVELS) -static void indent PROTO((void)); -#endif - -/* A node which has tree code ERROR_MARK, and whose type is itself. - All erroneous expressions are replaced with this node. All functions - that accept nodes as arguments should avoid generating error messages - if this node is one of the arguments, since it is undesirable to get - multiple error messages from one error in the input. */ - -tree error_mark_node; - -/* Erroneous argument lists can use this *IFF* they do not modify it. */ -tree error_mark_list; - -/* INTEGER_TYPE and REAL_TYPE nodes for the standard data types */ - -tree short_integer_type_node; -tree integer_type_node; -tree long_integer_type_node; -tree long_long_integer_type_node; - -tree short_unsigned_type_node; -tree unsigned_type_node; -tree long_unsigned_type_node; -tree long_long_unsigned_type_node; - -tree ptrdiff_type_node; - -tree unsigned_char_type_node; -tree signed_char_type_node; -tree char_type_node; -tree wchar_type_node; -tree signed_wchar_type_node; -tree unsigned_wchar_type_node; - -tree wchar_decl_node; - -tree float_type_node; -tree double_type_node; -tree long_double_type_node; - -tree complex_integer_type_node; -tree complex_float_type_node; -tree complex_double_type_node; -tree complex_long_double_type_node; - -tree intQI_type_node; -tree intHI_type_node; -tree intSI_type_node; -tree intDI_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 -tree intTI_type_node; -#endif - -tree unsigned_intQI_type_node; -tree unsigned_intHI_type_node; -tree unsigned_intSI_type_node; -tree unsigned_intDI_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 -tree unsigned_intTI_type_node; -#endif - -tree java_byte_type_node; -tree java_short_type_node; -tree java_int_type_node; -tree java_long_type_node; -tree java_float_type_node; -tree java_double_type_node; -tree java_char_type_node; -tree java_boolean_type_node; - -/* A VOID_TYPE node, and the same, packaged in a TREE_LIST. */ - -tree void_type_node, void_list_node; -tree void_zero_node; - -/* Nodes for types `void *' and `const void *'. */ - -tree ptr_type_node; -tree const_ptr_type_node; - -/* Nodes for types `char *' and `const char *'. */ - -tree string_type_node, const_string_type_node; - -/* Type `char[256]' or something like it. - Used when an array of char is needed and the size is irrelevant. */ - -tree char_array_type_node; - -/* Type `int[256]' or something like it. - Used when an array of int needed and the size is irrelevant. */ - -tree int_array_type_node; - -/* Type `wchar_t[256]' or something like it. - Used when a wide string literal is created. */ - -tree wchar_array_type_node; - -/* The bool data type, and constants */ -tree boolean_type_node, boolean_true_node, boolean_false_node; - -/* Type `int ()' -- used for implicit declaration of functions. */ - -tree default_function_type; - -/* Function types `double (double)' and `double (double, double)', etc. */ - -static tree double_ftype_double, double_ftype_double_double; -static tree int_ftype_int, long_ftype_long; -static tree float_ftype_float; -static tree ldouble_ftype_ldouble; - -/* Function type `int (const void *, const void *, size_t)' */ -static tree int_ftype_cptr_cptr_sizet; - -/* C++ extensions */ -tree vtable_entry_type; -tree delta_type_node; -#if 0 -/* Old rtti stuff. */ -tree __baselist_desc_type_node; -tree __i_desc_type_node, __m_desc_type_node; -tree __t_desc_array_type, __i_desc_array_type, __m_desc_array_type; -#endif -tree __t_desc_type_node; -#if 0 -tree __tp_desc_type_node; -#endif -tree __access_mode_type_node; -tree __bltn_desc_type_node, __user_desc_type_node, __class_desc_type_node; -tree __ptr_desc_type_node, __attr_desc_type_node, __func_desc_type_node; -tree __ptmf_desc_type_node, __ptmd_desc_type_node; -#if 0 -/* Not needed yet? May be needed one day? */ -tree __bltn_desc_array_type, __user_desc_array_type, __class_desc_array_type; -tree __ptr_desc_array_type, __attr_dec_array_type, __func_desc_array_type; -tree __ptmf_desc_array_type, __ptmd_desc_array_type; -#endif - -/* Indicates that there is a type value in some namespace, although - that is not necessarily in scope at the moment. */ - -static tree global_type_node; - -tree class_star_type_node; -tree class_type_node, record_type_node, union_type_node, enum_type_node; -tree unknown_type_node; -tree opaque_type_node, signature_type_node; -tree sigtable_entry_type; - -/* Array type `vtable_entry_type[]' */ -tree vtbl_type_node; -tree vtbl_ptr_type_node; - -/* namespace std */ -tree std_node; -int in_std = 0; - -/* Expect only namespace names now. */ -static int only_namespace_names; - -/* In a destructor, the point at which all derived class destroying - has been done, just before any base class destroying will be done. */ - -tree dtor_label; - -/* In a destructor, the last insn emitted after the start of the - function and the parms. */ - -static rtx last_dtor_insn; - -/* In a constructor, the last insn emitted after the start of the - function and the parms, the exception specification and any - function-try-block. The constructor initializers are emitted after - this insn. */ - -static rtx last_parm_cleanup_insn; - -/* In a constructor, the point at which we are ready to return - the pointer to the initialized object. */ - -tree ctor_label; - -/* A FUNCTION_DECL which can call `abort'. Not necessarily the - one that the user will declare, but sufficient to be called - by routines that want to abort the program. */ - -tree abort_fndecl; - -/* A FUNCTION_DECL for the default `::operator delete'. */ - -tree global_delete_fndecl; - -extern rtx cleanup_label, return_label; - -/* If original DECL_RESULT of current function was a register, - but due to being an addressable named return value, would up - on the stack, this variable holds the named return value's - original location. */ -static rtx original_result_rtx; - -/* Sequence of insns which represents base initialization. */ -tree base_init_expr; - -/* C++: Keep these around to reduce calls to `get_identifier'. - Identifiers for `this' in member functions and the auto-delete - parameter for destructors. */ -tree this_identifier, in_charge_identifier; -tree ctor_identifier, dtor_identifier; -/* Used in pointer to member functions, in vtables, and in sigtables. */ -tree pfn_identifier, index_identifier, delta_identifier, delta2_identifier; -tree pfn_or_delta2_identifier, tag_identifier; -tree vt_off_identifier; - -struct named_label_list -{ - struct binding_level *binding_level; - tree names_in_scope; - tree label_decl; - char *filename_o_goto; - int lineno_o_goto; - struct named_label_list *next; -}; - -/* A list (chain of TREE_LIST nodes) of named label uses. - The TREE_PURPOSE field is the list of variables defined - in the label's scope defined at the point of use. - The TREE_VALUE field is the LABEL_DECL used. - The TREE_TYPE field holds `current_binding_level' at the - point of the label's use. - - BWAHAHAAHAHahhahahahaah. No, no, no, said the little chicken. - - Look at the pretty struct named_label_list. See the pretty struct - with the pretty named fields that describe what they do. See the - pretty lack of gratuitous casts. Notice the code got a lot cleaner. - - Used only for jumps to as-yet undefined labels, since - jumps to defined labels can have their validity checked - by stmt.c. */ - -static struct named_label_list *named_label_uses = NULL; - -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -tree static_aggregates; - -/* -- end of C++ */ - -/* Two expressions that are constants with value zero. - The first is of type `int', the second of type `void *'. */ - -tree integer_zero_node; -tree null_pointer_node; - -/* The value for __null (NULL), namely, a zero of an integer type with - the same number of bits as a pointer. */ -tree null_node; - -/* A node for the integer constants 1, 2, and 3. */ - -tree integer_one_node, integer_two_node, integer_three_node; - -/* While defining an enum type, this is 1 plus the last enumerator - constant value. */ - -static tree enum_next_value; - -/* Nonzero means that there was overflow computing enum_next_value. */ - -static int enum_overflow; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ - -tree last_function_parms; - -/* Parsing a function declarator leaves here a chain of structure - and enum types declared in the parmlist. */ - -static tree last_function_parm_tags; - -/* After parsing the declarator that starts a function definition, - `start_function' puts here the list of parameter names or chain of decls. - `store_parm_decls' finds it here. */ - -static tree current_function_parms; - -/* Similar, for last_function_parm_tags. */ -static tree current_function_parm_tags; - -/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function - that have names. Here so we can clear out their names' definitions - at the end of the function. */ - -static tree named_labels; - -/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ - -static tree shadowed_labels; - -/* The FUNCTION_DECL for the function currently being compiled, - or 0 if between functions. */ -tree current_function_decl; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement that specifies a return value is seen. */ - -int current_function_returns_value; - -/* Set to 0 at beginning of a function definition, set to 1 if - a return statement with no argument is seen. */ - -int current_function_returns_null; - -/* Set to 0 at beginning of a function definition, and whenever - a label (case or named) is defined. Set to value of expression - returned from function when that value can be transformed into - a named return value. */ - -tree current_function_return_value; - -/* Nonzero means give `double' the same size as `float'. */ - -extern int flag_short_double; - -/* Nonzero means don't recognize any builtin functions. */ - -extern int flag_no_builtin; - -/* Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. */ - -extern int flag_no_nonansi_builtin; - -/* Nonzero means enable obscure ANSI features and disable GNU extensions - that might cause ANSI-compliant code to be miscompiled. */ - -extern int flag_ansi; - -/* 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 - definitions. */ -extern int flag_conserve_space; - -/* Pointers to the base and current top of the language name stack. */ - -extern tree *current_lang_base, *current_lang_stack; - -/* C and C++ flags are in decl2.c. */ - -/* Set to 0 at beginning of a constructor, set to 1 - if that function does an allocation before referencing its - instance variable. */ -static int current_function_assigns_this; -int current_function_just_assigned_this; - -/* Set to 0 at beginning of a function. Set non-zero when - store_parm_decls is called. Don't call store_parm_decls - if this flag is non-zero! */ -int current_function_parms_stored; - -/* Flag used when debugging spew.c */ - -extern int spew_debug; - -/* This is a copy of the class_shadowed list of the previous class binding - contour when at global scope. It's used to reset IDENTIFIER_CLASS_VALUEs - when entering another class scope (i.e. a cache miss). */ -extern tree previous_class_values; - -/* A expression of value 0 with the same precision as a sizetype - node, but signed. */ -tree signed_size_zero_node; - -/* The name of the anonymous namespace, throughout this translation - unit. */ -tree anonymous_namespace_name; - - -/* Allocate a level of searching. */ - -static -struct stack_level * -push_decl_level (stack, obstack) - struct stack_level *stack; - struct obstack *obstack; -{ - struct stack_level tem; - tem.prev = stack; - - return push_stack_level (obstack, (char *)&tem, sizeof (tem)); -} - -/* For each binding contour we allocate a binding_level structure - which records the names defined in that contour. - Contours include: - 0) the global one - 1) one for each function definition, - where internal declarations of the parameters appear. - 2) one for each compound statement, - to record its declarations. - - The current meaning of a name can be found by searching the levels - from the current one out to the global one. - - Off to the side, may be the class_binding_level. This exists only - to catch class-local declarations. It is otherwise nonexistent. - - Also there may be binding levels that catch cleanups that must be - run when exceptions occur. Thus, to see whether a name is bound in - the current scope, it is not enough to look in the - CURRENT_BINDING_LEVEL. You should use lookup_name_current_level - instead. */ - -/* Note that the information in the `names' component of the global contour - is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ - -struct binding_level - { - /* A chain of _DECL nodes for all variables, constants, functions, - and typedef types. These are in the reverse of the order - supplied. There may be OVERLOADs on this list, too, but they - are wrapped in TREE_LISTs; the TREE_VALUE is the OVERLOAD. */ - tree names; - - /* A list of structure, union and enum definitions, for looking up - tag names. - It is a chain of TREE_LIST nodes, each of whose TREE_PURPOSE is a name, - or NULL_TREE; and whose TREE_VALUE is a RECORD_TYPE, UNION_TYPE, - or ENUMERAL_TYPE node. - - C++: the TREE_VALUE nodes can be simple types for - component_bindings. */ - tree tags; - - /* A list of USING_DECL nodes. */ - tree usings; - - /* A list of used namespaces. PURPOSE is the namespace, - VALUE the common ancestor with this binding_level's namespace. */ - tree using_directives; - - /* If this binding level is the binding level for a class, then - class_shadowed is a TREE_LIST. The TREE_PURPOSE of each node - is the name of an entity bound in the class; the TREE_VALUE is - the IDENTIFIER_CLASS_VALUE before we entered the class. Thus, - when leaving class scope, we can restore the - IDENTIFIER_CLASS_VALUE by walking this list. The TREE_TYPE is - the DECL bound by this name in the class. */ - tree class_shadowed; - - /* Similar to class_shadowed, but for IDENTIFIER_TYPE_VALUE, and - is used for all binding levels. */ - tree type_shadowed; - - /* For each level (except not the global one), - a chain of BLOCK nodes for all the levels - that were entered and exited one level down. */ - tree blocks; - - /* The BLOCK node for this level, if one has been preallocated. - If 0, the BLOCK is allocated (if needed) when the level is popped. */ - tree this_block; - - /* The binding level which this one is contained in (inherits from). */ - struct binding_level *level_chain; - - /* List of decls in `names' that have incomplete - structure or union types. */ - tree incomplete; - - /* List of VAR_DECLS saved from a previous for statement. - These would be dead in ANSI-conforming code, but might - be referenced in ARM-era code. These are stored in a - TREE_LIST; the TREE_VALUE is the actual declaration. */ - tree dead_vars_from_for; - - /* 1 for the level that holds the parameters of a function. - 2 for the level that holds a class declaration. - 3 for levels that hold parameter declarations. */ - unsigned parm_flag : 4; - - /* 1 means make a BLOCK for this level regardless of all else. - 2 for temporary binding contours created by the compiler. */ - unsigned keep : 3; - - /* Nonzero if this level "doesn't exist" for tags. */ - unsigned tag_transparent : 1; - - /* Nonzero if this level can safely have additional - cleanup-needing variables added to it. */ - unsigned more_cleanups_ok : 1; - unsigned have_cleanups : 1; - - /* Nonzero if this level is for storing the decls for template - parameters and generic decls; these decls will be discarded and - replaced with a TEMPLATE_DECL. */ - unsigned pseudo_global : 1; - - /* This is set for a namespace binding level. */ - unsigned namespace_p : 1; - - /* True if this level is that of a for-statement where we need to - worry about ambiguous (ARM or ANSI) scope rules. */ - unsigned is_for_scope : 1; - - /* Two bits left for this word. */ - -#if defined(DEBUG_CP_BINDING_LEVELS) - /* Binding depth at which this level began. */ - unsigned binding_depth; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - }; - -#define NULL_BINDING_LEVEL ((struct binding_level *) NULL) - -/* The (non-class) binding level currently in effect. */ - -static struct binding_level *current_binding_level; - -/* The binding level of the current class, if any. */ - -static struct binding_level *class_binding_level; - -/* The current (class or non-class) binding level currently in effect. */ - -#define inner_binding_level \ - (class_binding_level ? class_binding_level : current_binding_level) - -/* A chain of binding_level structures awaiting reuse. */ - -static struct binding_level *free_binding_level; - -/* The outermost binding level, for names of file scope. - This is created when the compiler is started and exists - through the entire run. */ - -static struct binding_level *global_binding_level; - -/* Binding level structures are initialized by copying this one. */ - -static struct binding_level clear_binding_level; - -/* Nonzero means unconditionally make a BLOCK for the next level pushed. */ - -static int keep_next_level_flag; - -#if defined(DEBUG_CP_BINDING_LEVELS) -static int binding_depth = 0; -static int is_class_level = 0; - -static void -indent () -{ - register unsigned i; - - for (i = 0; i < binding_depth*2; i++) - putc (' ', stderr); -} -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - -static tree pushdecl_with_scope PROTO((tree, struct binding_level *)); - -static void -push_binding_level (newlevel, tag_transparent, keep) - struct binding_level *newlevel; - int tag_transparent, keep; -{ - /* Add this level to the front of the chain (stack) of levels that - are active. */ - *newlevel = clear_binding_level; - if (class_binding_level) - { - newlevel->level_chain = class_binding_level; - class_binding_level = (struct binding_level *)0; - } - else - { - newlevel->level_chain = current_binding_level; - } - current_binding_level = newlevel; - newlevel->tag_transparent = tag_transparent; - newlevel->more_cleanups_ok = 1; - newlevel->keep = keep; -#if defined(DEBUG_CP_BINDING_LEVELS) - newlevel->binding_depth = binding_depth; - indent (); - fprintf (stderr, "push %s level 0x%08x line %d\n", - (is_class_level) ? "class" : "block", newlevel, lineno); - is_class_level = 0; - binding_depth++; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ -} - -static void -pop_binding_level () -{ - if (class_binding_level) - current_binding_level = class_binding_level; - - if (global_binding_level) - { - /* Cannot pop a level, if there are none left to pop. */ - if (current_binding_level == global_binding_level) - my_friendly_abort (123); - } - /* Pop the current level, and free the structure for reuse. */ -#if defined(DEBUG_CP_BINDING_LEVELS) - binding_depth--; - indent (); - fprintf (stderr, "pop %s level 0x%08x line %d\n", - (is_class_level) ? "class" : "block", - current_binding_level, lineno); - if (is_class_level != (current_binding_level == class_binding_level)) - { - indent (); - fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); - } - is_class_level = 0; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - { - register struct binding_level *level = current_binding_level; - current_binding_level = current_binding_level->level_chain; - level->level_chain = free_binding_level; -#if 0 /* defined(DEBUG_CP_BINDING_LEVELS) */ - if (level->binding_depth != binding_depth) - abort (); -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - free_binding_level = level; - - class_binding_level = current_binding_level; - if (class_binding_level->parm_flag != 2) - class_binding_level = 0; - while (current_binding_level->parm_flag == 2) - current_binding_level = current_binding_level->level_chain; - } -} - -static void -suspend_binding_level () -{ - if (class_binding_level) - current_binding_level = class_binding_level; - - if (global_binding_level) - { - /* Cannot suspend a level, if there are none left to suspend. */ - if (current_binding_level == global_binding_level) - my_friendly_abort (123); - } - /* Suspend the current level. */ -#if defined(DEBUG_CP_BINDING_LEVELS) - binding_depth--; - indent (); - fprintf (stderr, "suspend %s level 0x%08x line %d\n", - (is_class_level) ? "class" : "block", - current_binding_level, lineno); - if (is_class_level != (current_binding_level == class_binding_level)) - { - indent (); - fprintf (stderr, "XXX is_class_level != (current_binding_level == class_binding_level)\n"); - } - is_class_level = 0; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - { - current_binding_level = current_binding_level->level_chain; - class_binding_level = current_binding_level; - if (class_binding_level->parm_flag != 2) - class_binding_level = 0; - while (current_binding_level->parm_flag == 2) - current_binding_level = current_binding_level->level_chain; - } -} - -static void -resume_binding_level (b) - struct binding_level *b; -{ - /* Resuming binding levels is meant only for namespaces, - and those cannot nest into classes. */ - my_friendly_assert(!class_binding_level, 386); - /* Also, resuming a non-directly nested namespace is a no-no. */ - my_friendly_assert(b->level_chain == current_binding_level, 386); - current_binding_level = b; -#if defined(DEBUG_CP_BINDING_LEVELS) - b->binding_depth = binding_depth; - indent (); - fprintf (stderr, "resume %s level 0x%08x line %d\n", - (is_class_level) ? "class" : "block", b, lineno); - is_class_level = 0; - binding_depth++; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ -} - -/* Create a new `struct binding_level'. */ - -static -struct binding_level * -make_binding_level () -{ - /* NOSTRICT */ - return (struct binding_level *) xmalloc (sizeof (struct binding_level)); -} - -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p () -{ - return current_binding_level == global_binding_level; -} - -/* Nonzero if we are currently in a toplevel binding level. This - means either the global binding level or a namespace in a toplevel - binding level. - Since there are no non-toplevel namespace levels, this really - means any namespace or pseudo-global level. */ - -int -toplevel_bindings_p () -{ - return current_binding_level->namespace_p - || current_binding_level->pseudo_global; -} - -/* Nonzero if this is a namespace scope. */ - -int -namespace_bindings_p () -{ - return current_binding_level->namespace_p; -} - -void -keep_next_level () -{ - keep_next_level_flag = 1; -} - -/* Nonzero if the current level needs to have a BLOCK made. */ - -int -kept_level_p () -{ - return (current_binding_level->blocks != NULL_TREE - || current_binding_level->keep - || current_binding_level->names != NULL_TREE - || (current_binding_level->tags != NULL_TREE - && !current_binding_level->tag_transparent)); -} - -/* Identify this binding level as a level of parameters. */ - -void -declare_parm_level () -{ - current_binding_level->parm_flag = 1; -} - -void -declare_pseudo_global_level () -{ - current_binding_level->pseudo_global = 1; -} - -static void -declare_namespace_level () -{ - current_binding_level->namespace_p = 1; -} - -int -pseudo_global_level_p () -{ - return current_binding_level->pseudo_global; -} - -void -set_class_shadows (shadows) - tree shadows; -{ - class_binding_level->class_shadowed = shadows; -} - -/* Enter a new binding level. - If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, - not for that of tags. */ - -void -pushlevel (tag_transparent) - int tag_transparent; -{ - register struct binding_level *newlevel = NULL_BINDING_LEVEL; - - /* If this is the top level of a function, - just make sure that NAMED_LABELS is 0. - They should have been set to 0 at the end of the previous function. */ - - if (current_binding_level == global_binding_level) - my_friendly_assert (named_labels == NULL_TREE, 134); - - /* Reuse or create a struct for this binding level. */ - -#if defined(DEBUG_CP_BINDING_LEVELS) - if (0) -#else /* !defined(DEBUG_CP_BINDING_LEVELS) */ - if (free_binding_level) -#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - push_binding_level (newlevel, tag_transparent, keep_next_level_flag); - GNU_xref_start_scope ((HOST_WIDE_INT) newlevel); - keep_next_level_flag = 0; -} - -void -note_level_for_for () -{ - current_binding_level->is_for_scope = 1; -} - -void -pushlevel_temporary (tag_transparent) - int tag_transparent; -{ - pushlevel (tag_transparent); - current_binding_level->keep = 2; - clear_last_expr (); - - /* Note we don't call push_momentary() here. Otherwise, it would cause - cleanups to be allocated on the momentary obstack, and they will be - overwritten by the next statement. */ - - expand_start_bindings (0); -} - -/* For a binding between a name and an entity at a block scope, - this is the `struct binding_level' for the block. */ -#define BINDING_LEVEL(NODE) \ - (((struct tree_binding*)NODE)->scope.level) - -/* These are currently unused, but permanent, CPLUS_BINDING nodes. - They are kept here because they are allocated from the permanent - obstack and cannot be easily freed. */ -static tree free_binding_nodes; - -/* Make DECL the innermost binding for ID. The LEVEL is the binding - level at which this declaration is being bound. */ - -static void -push_binding (id, decl, level) - tree id; - tree decl; - struct binding_level* level; -{ - tree binding; - - if (!free_binding_nodes) - { - /* There are no free nodes, so we must build one here. */ - push_obstacks_nochange (); - end_temporary_allocation (); - binding = make_node (CPLUS_BINDING); - pop_obstacks (); - } - else - { - /* There are nodes on the free list. Grab the first one. */ - binding = free_binding_nodes; - - /* And update the free list. */ - free_binding_nodes = TREE_CHAIN (free_binding_nodes); - } - - /* Now, fill in the binding information. */ - BINDING_VALUE (binding) = decl; - BINDING_TYPE (binding) = NULL_TREE; - BINDING_LEVEL (binding) = level; - LOCAL_BINDING_P (binding) = (level != class_binding_level); - - /* And put it on the front of the ilst of bindings for ID. */ - TREE_CHAIN (binding) = IDENTIFIER_BINDING (id); - IDENTIFIER_BINDING (id) = binding; -} - -/* ID is already bound in the current scope. But, DECL is an - additional binding for ID in the same scope. This is the `struct - stat' hack whereby a non-typedef class-name or enum-name can be - bound at the same level as some other kind of entity. It's the - responsibility of the caller to check that inserting this name is - legal here. */ -static void -add_binding (id, decl) - tree id; - tree decl; -{ - tree binding = IDENTIFIER_BINDING (id); - - if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) - /* The new name is the type name. */ - BINDING_TYPE (binding) = decl; - else - { - /* The old name must be the type name. It was placed in - IDENTIFIER_VALUE because it was thought, at the point it - was declared, to be the only entity with such a name. */ - my_friendly_assert (TREE_CODE (BINDING_VALUE (binding)) == TYPE_DECL - && DECL_ARTIFICIAL (BINDING_VALUE (binding)), - 0); - - /* Move the type name into the type slot; it is now hidden by - the new binding. */ - BINDING_TYPE (binding) = BINDING_VALUE (binding); - BINDING_VALUE (binding) = decl; - } -} - -/* Bind DECL to ID in the current_binding_level. - If PUSH_USING is set in FLAGS, we know that DECL doesn't really belong - to this binding level, that it got here through a using-declaration. */ - -void -push_local_binding (id, decl, flags) - tree id; - tree decl; - int flags; -{ - tree d = decl; - - if (lookup_name_current_level (id)) - /* Supplement the existing binding. */ - add_binding (id, d); - else - /* Create a new binding. */ - push_binding (id, d, current_binding_level); - - if (TREE_CODE (decl) == OVERLOAD || (flags & PUSH_USING)) - /* We must put the OVERLOAD into a TREE_LIST since the - TREE_CHAIN of an OVERLOAD is already used. Similarly for - decls that got here through a using-declaration. */ - decl = build_tree_list (NULL_TREE, decl); - - /* And put DECL on the list of things declared by the current - binding level. */ - TREE_CHAIN (decl) = current_binding_level->names; - current_binding_level->names = decl; -} - -/* Bind DECL to ID in the class_binding_level. */ - -void -push_class_binding (id, decl) - tree id; - tree decl; -{ - if (IDENTIFIER_BINDING (id) - && BINDING_LEVEL (IDENTIFIER_BINDING (id)) == class_binding_level) - /* Supplement the existing binding. */ - add_binding (id, decl); - else - /* Create a new binding. */ - push_binding (id, decl, class_binding_level); - - /* Update the IDENTIFIER_CLASS_VALUE for this ID to be the - class-level declaration. Note that we do not use DECL here - because of the possibility of the `struct stat' hack; if DECL is - a class-name or enum-name we might prefer a field-name, or some - such. */ - IDENTIFIER_CLASS_VALUE (id) = BINDING_VALUE (IDENTIFIER_BINDING (id)); -} - -/* Remove the binding for DECL which should be the innermost binding - for ID. */ - -static void -pop_binding (id, decl) - tree id; - tree decl; -{ - tree binding; - - if (id == NULL_TREE) - /* It's easiest to write the loops that call this function without - checking whether or not the entities involved have names. We - get here for such an entity. */ - return; - - /* Get the innermost binding for ID. */ - binding = IDENTIFIER_BINDING (id); - - /* The name should be bound. */ - my_friendly_assert (binding != NULL_TREE, 0); - - /* The DECL will be either the ordinary binding or the type - binding for this identifier. Remove that binding. */ - if (BINDING_VALUE (binding) == decl) - BINDING_VALUE (binding) = NULL_TREE; - else if (BINDING_TYPE (binding) == decl) - BINDING_TYPE (binding) = NULL_TREE; - else - my_friendly_abort (0); - - if (!BINDING_VALUE (binding) && !BINDING_TYPE (binding)) - { - /* We're completely done with the innermost binding for this - identifier. Unhook it from the list of bindings. */ - IDENTIFIER_BINDING (id) = TREE_CHAIN (binding); - - /* And place it on the free list. */ - TREE_CHAIN (binding) = free_binding_nodes; - free_binding_nodes = binding; - } -} - -/* Exit a binding level. - Pop the level off, and restore the state of the identifier-decl mappings - that were in effect when this level was entered. - - If KEEP == 1, this level had explicit declarations, so - and create a "block" (a BLOCK node) for the level - to record its declarations and subblocks for symbol table output. - - If FUNCTIONBODY is nonzero, this level is the body of a function, - so create a block as if KEEP were set and also clear out all - label names. - - If REVERSE is nonzero, reverse the order of decls before putting - them into the BLOCK. */ - -tree -poplevel (keep, reverse, functionbody) - int keep; - int reverse; - int functionbody; -{ - register tree link; - /* The chain of decls was accumulated in reverse order. - Put it into forward order, just for cleanliness. */ - tree decls; - int tmp = functionbody; - int real_functionbody = current_binding_level->keep == 2 - ? ((functionbody = 0), tmp) : functionbody; - tree tags = functionbody >= 0 ? current_binding_level->tags : 0; - tree subblocks = functionbody >= 0 ? current_binding_level->blocks : 0; - tree block = NULL_TREE; - tree decl; - int block_previously_created; - int leaving_for_scope; - - if (current_binding_level->parm_flag == 2 - || current_binding_level->class_shadowed) - /* We should not be using poplevel to pop a class binding level. - Use poplevel_class instead. */ - my_friendly_abort (0); - - /* We used to use KEEP == 2 to indicate that the new block should go - at the beginning of the list of blocks at this binding level, - rather than the end. This hack is no longer used. */ - my_friendly_assert (keep == 0 || keep == 1, 0); - - GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, - (HOST_WIDE_INT) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep); - - if (current_binding_level->keep == 1) - keep = 1; - - /* Get the decls in the order they were written. - Usually current_binding_level->names is in reverse order. - But parameter decls were previously put in forward order. */ - - if (reverse) - current_binding_level->names - = decls = nreverse (current_binding_level->names); - else - decls = current_binding_level->names; - - /* Output any nested inline functions within this block - if they weren't already output. */ - - for (decl = decls; decl; decl = TREE_CHAIN (decl)) - if (TREE_CODE (decl) == FUNCTION_DECL - && ! TREE_ASM_WRITTEN (decl) - && DECL_INITIAL (decl) != NULL_TREE - && TREE_ADDRESSABLE (decl) - && decl_function_context (decl) == current_function_decl) - { - /* If this decl was copied from a file-scope decl - on account of a block-scope extern decl, - propagate TREE_ADDRESSABLE to the file-scope decl. */ - if (DECL_ABSTRACT_ORIGIN (decl) != NULL_TREE) - TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else - { - push_function_context (); - output_inline_function (decl); - pop_function_context (); - } - } - - /* If there were any declarations or structure tags in that level, - or if this level is a function body, - create a BLOCK to record them for the life of this function. */ - - block = NULL_TREE; - block_previously_created = (current_binding_level->this_block != NULL_TREE); - if (block_previously_created) - block = current_binding_level->this_block; - else if (keep == 1 || functionbody) - block = make_node (BLOCK); - if (block != NULL_TREE) - { - if (block_previously_created) - { - if (decls || tags || subblocks) - { - if (BLOCK_VARS (block) || BLOCK_TYPE_TAGS (block)) - warning ("internal compiler error: debugging info corrupted"); - - BLOCK_VARS (block) = decls; - BLOCK_TYPE_TAGS (block) = tags; - - /* We can have previous subblocks and new subblocks when - doing fixup_gotos with complex cleanups. We chain the new - subblocks onto the end of any pre-existing subblocks. */ - BLOCK_SUBBLOCKS (block) = chainon (BLOCK_SUBBLOCKS (block), - subblocks); - } - /* If we created the block earlier on, and we are just - diddling it now, then it already should have a proper - BLOCK_END_NOTE value associated with it. */ - } - else - { - BLOCK_VARS (block) = decls; - BLOCK_TYPE_TAGS (block) = tags; - BLOCK_SUBBLOCKS (block) = subblocks; - /* Otherwise, for a new block, install a new BLOCK_END_NOTE - value. */ - remember_end_note (block); - } - } - - /* In each subblock, record that this is its superior. */ - - if (keep >= 0) - for (link = subblocks; link; link = TREE_CHAIN (link)) - BLOCK_SUPERCONTEXT (link) = block; - - /* We still support the old for-scope rules, whereby the variables - in a for-init statement were in scope after the for-statement - ended. We only use the new rules in flag_new_for_scope is - nonzero. */ - leaving_for_scope - = current_binding_level->is_for_scope && flag_new_for_scope == 1; - - /* Remove declarations for all the DECLs in this level. */ - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (leaving_for_scope && TREE_CODE (link) == VAR_DECL) - { - tree outer_binding - = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (link))); - tree ns_binding; - - if (!outer_binding) - ns_binding = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (link)); - else - ns_binding = NULL_TREE; - - if (outer_binding - && (BINDING_LEVEL (outer_binding) - == current_binding_level->level_chain)) - /* We have something like: - - int i; - for (int i; ;); - - and we are leaving the `for' scope. There's no reason to - keep the binding of the inner `i' in this case. */ - pop_binding (DECL_NAME (link), link); - else if ((outer_binding - && (TREE_CODE (BINDING_VALUE (outer_binding)) - == TYPE_DECL)) - || (ns_binding - && TREE_CODE (ns_binding) == TYPE_DECL)) - /* Here, we have something like: - - typedef int I; - - void f () { - for (int I; ;); - } - - We must pop the for-scope binding so we know what's a - type and what isn't. */ - pop_binding (DECL_NAME (link), link); - else - { - /* Mark this VAR_DECL as dead so that we can tell we left it - there only for backward compatibility. */ - DECL_DEAD_FOR_LOCAL (link) = 1; - - /* Keep track of what should of have happenned when we - popped the binding. */ - if (outer_binding && BINDING_VALUE (outer_binding)) - DECL_SHADOWED_FOR_VAR (link) - = BINDING_VALUE (outer_binding); - - /* Add it to the list of dead variables in the next - outermost binding to that we can remove these when we - leave that binding. */ - current_binding_level->level_chain->dead_vars_from_for - = tree_cons (NULL_TREE, link, - current_binding_level->level_chain-> - dead_vars_from_for); - - /* Although we don't pop the CPLUS_BINDING, we do clear - its BINDING_LEVEL since the level is going away now. */ - BINDING_LEVEL (IDENTIFIER_BINDING (DECL_NAME (link))) - = 0; - } - } - else - { - /* Remove the binding. */ - decl = link; - if (TREE_CODE (decl) == TREE_LIST) - decl = TREE_VALUE (decl); - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd') - pop_binding (DECL_NAME (decl), decl); - else if (TREE_CODE (decl) == OVERLOAD) - pop_binding (DECL_NAME (OVL_FUNCTION (decl)), decl); - else - my_friendly_abort (0); - } - } - - /* Remove declarations for any `for' variables from inner scopes - that we kept around. */ - for (link = current_binding_level->dead_vars_from_for; - link; link = TREE_CHAIN (link)) - pop_binding (DECL_NAME (TREE_VALUE (link)), TREE_VALUE (link)); - - /* Restore the IDENTIFIER_TYPE_VALUEs. */ - for (link = current_binding_level->type_shadowed; - link; link = TREE_CHAIN (link)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (link), TREE_VALUE (link)); - - /* There may be OVERLOADs (wrapped in TREE_LISTs) on the BLOCK_VARs - list if a `using' declaration put them there. The debugging - back-ends won't understand OVERLOAD, so we remove them here. - Because the BLOCK_VARS are (temporarily) shared with - CURRENT_BINDING_LEVEL->NAMES we must do this fixup after we have - popped all the bindings. */ - if (block) - { - tree* d; - - for (d = &BLOCK_VARS (block); *d; ) - { - if (TREE_CODE (*d) == TREE_LIST) - *d = TREE_CHAIN (*d); - else - d = &TREE_CHAIN (*d); - } - } - - /* If the level being exited is the top level of a function, - check over all the labels. */ - - if (functionbody) - { - /* If this is the top level block of a function, - the vars are the function's parameters. - Don't leave them in the BLOCK because they are - found in the FUNCTION_DECL instead. */ - - BLOCK_VARS (block) = 0; - - /* Clear out the definitions of all label names, - since their scopes end here. */ - - for (link = named_labels; link; link = TREE_CHAIN (link)) - { - register tree label = TREE_VALUE (link); - - if (DECL_INITIAL (label) == NULL_TREE) - { - cp_error_at ("label `%D' used but not defined", label); - /* Avoid crashing later. */ - define_label (input_filename, 1, DECL_NAME (label)); - } - else if (warn_unused && !TREE_USED (label)) - cp_warning_at ("label `%D' defined but not used", label); - SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (label), NULL_TREE); - - /* Put the labels into the "variables" of the - top-level block, so debugger can see them. */ - TREE_CHAIN (label) = BLOCK_VARS (block); - BLOCK_VARS (block) = label; - } - - named_labels = NULL_TREE; - } - - /* Any uses of undefined labels now operate under constraints - of next binding contour. */ - { - struct binding_level *level_chain; - level_chain = current_binding_level->level_chain; - if (level_chain) - { - struct named_label_list *labels; - for (labels = named_label_uses; labels; labels = labels->next) - if (labels->binding_level == current_binding_level) - { - labels->binding_level = level_chain; - labels->names_in_scope = level_chain->names; - } - } - } - - tmp = current_binding_level->keep; - - pop_binding_level (); - if (functionbody) - DECL_INITIAL (current_function_decl) = block; - else if (block) - { - if (!block_previously_created) - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); - } - /* If we did not make a block for the level just exited, - any blocks made for inner levels - (since they cannot be recorded as subblocks in that level) - must be carried forward so they will later become subblocks - of something else. */ - else if (subblocks) - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - /* Take care of compiler's internal binding structures. */ - if (tmp == 2) - { - expand_end_bindings (getdecls (), keep, 1); - /* Each and every BLOCK node created here in `poplevel' is important - (e.g. for proper debugging information) so if we created one - earlier, mark it as "used". */ - if (block) - TREE_USED (block) = 1; - block = poplevel (keep, reverse, real_functionbody); - } - - /* Each and every BLOCK node created here in `poplevel' is important - (e.g. for proper debugging information) so if we created one - earlier, mark it as "used". */ - if (block) - TREE_USED (block) = 1; - return block; -} - -/* Delete the node BLOCK from the current binding level. - This is used for the block inside a stmt expr ({...}) - so that the block can be reinserted where appropriate. */ - -void -delete_block (block) - tree block; -{ - tree t; - if (current_binding_level->blocks == block) - current_binding_level->blocks = TREE_CHAIN (block); - for (t = current_binding_level->blocks; t;) - { - if (TREE_CHAIN (t) == block) - TREE_CHAIN (t) = TREE_CHAIN (block); - else - t = TREE_CHAIN (t); - } - TREE_CHAIN (block) = NULL_TREE; - /* Clear TREE_USED which is always set by poplevel. - The flag is set again if insert_block is called. */ - TREE_USED (block) = 0; -} - -/* Insert BLOCK at the end of the list of subblocks of the - current binding level. This is used when a BIND_EXPR is expanded, - to handle the BLOCK node inside the BIND_EXPR. */ - -void -insert_block (block) - tree block; -{ - TREE_USED (block) = 1; - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -/* Set the BLOCK node for the innermost scope - (the one we are currently in). */ - -void -set_block (block) - register tree block; -{ - current_binding_level->this_block = block; -} - -/* Do a pushlevel for class declarations. */ - -void -pushlevel_class () -{ - register struct binding_level *newlevel; - - /* Reuse or create a struct for this binding level. */ -#if defined(DEBUG_CP_BINDING_LEVELS) - if (0) -#else /* !defined(DEBUG_CP_BINDING_LEVELS) */ - if (free_binding_level) -#endif /* !defined(DEBUG_CP_BINDING_LEVELS) */ - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - newlevel = make_binding_level (); - -#if defined(DEBUG_CP_BINDING_LEVELS) - is_class_level = 1; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - - push_binding_level (newlevel, 0, 0); - - decl_stack = push_decl_level (decl_stack, &decl_obstack); - class_binding_level = current_binding_level; - class_binding_level->parm_flag = 2; - /* We have just pushed into a new binding level. Now, fake out the rest - of the compiler. Set the `current_binding_level' back to point to - the most closely containing non-class binding level. */ - do - { - current_binding_level = current_binding_level->level_chain; - } - while (current_binding_level->parm_flag == 2); -} - -/* ...and a poplevel for class declarations. FORCE is used to force - clearing out of CLASS_VALUEs after a class definition. */ - -tree -poplevel_class (force) - int force; -{ - register struct binding_level *level = class_binding_level; - tree block = NULL_TREE; - tree shadowed; - - my_friendly_assert (level != 0, 354); - - decl_stack = pop_stack_level (decl_stack); - /* If we're leaving a toplevel class, don't bother to do the setting - of IDENTIFIER_CLASS_VALUE to NULL_TREE, since first of all this slot - shouldn't even be used when current_class_type isn't set, and second, - if we don't touch it here, we're able to use the cache effect if the - next time we're entering a class scope, it is the same class. */ - if (current_class_depth != 1 || force) - for (shadowed = level->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (shadowed)) = TREE_VALUE (shadowed); - else - /* Remember to save what IDENTIFIER's were bound in this scope so we - can recover from cache misses. */ - { - previous_class_type = current_class_type; - previous_class_values = class_binding_level->class_shadowed; - } - for (shadowed = level->type_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (shadowed), TREE_VALUE (shadowed)); - - /* Remove the bindings for all of the class-level declarations. */ - for (shadowed = level->class_shadowed; - shadowed; - shadowed = TREE_CHAIN (shadowed)) - pop_binding (TREE_PURPOSE (shadowed), TREE_TYPE (shadowed)); - - GNU_xref_end_scope ((HOST_WIDE_INT) class_binding_level, - (HOST_WIDE_INT) class_binding_level->level_chain, - class_binding_level->parm_flag, - class_binding_level->keep); - - if (class_binding_level->parm_flag != 2) - class_binding_level = (struct binding_level *)0; - - /* Now, pop out of the binding level which we created up in the - `pushlevel_class' routine. */ -#if defined(DEBUG_CP_BINDING_LEVELS) - is_class_level = 1; -#endif /* defined(DEBUG_CP_BINDING_LEVELS) */ - - pop_binding_level (); - - return block; -} - -/* For debugging. */ -static int no_print_functions = 0; -static int no_print_builtins = 0; - -void -print_binding_level (lvl) - struct binding_level *lvl; -{ - tree t; - int i = 0, len; - fprintf (stderr, " blocks="); - fprintf (stderr, HOST_PTR_PRINTF, lvl->blocks); - fprintf (stderr, " n_incomplete=%d parm_flag=%d keep=%d", - list_length (lvl->incomplete), lvl->parm_flag, lvl->keep); - if (lvl->tag_transparent) - fprintf (stderr, " tag-transparent"); - if (lvl->more_cleanups_ok) - fprintf (stderr, " more-cleanups-ok"); - if (lvl->have_cleanups) - fprintf (stderr, " have-cleanups"); - fprintf (stderr, "\n"); - if (lvl->names) - { - fprintf (stderr, " names:\t"); - /* We can probably fit 3 names to a line? */ - for (t = lvl->names; t; t = TREE_CHAIN (t)) - { - if (no_print_functions && (TREE_CODE (t) == FUNCTION_DECL)) - continue; - if (no_print_builtins - && (TREE_CODE (t) == TYPE_DECL) - && (!strcmp (DECL_SOURCE_FILE (t),"<built-in>"))) - continue; - - /* Function decls tend to have longer names. */ - if (TREE_CODE (t) == FUNCTION_DECL) - len = 3; - else - len = 2; - i += len; - if (i > 6) - { - fprintf (stderr, "\n\t"); - i = len; - } - print_node_brief (stderr, "", t, 0); - if (t == error_mark_node) - break; - } - if (i) - fprintf (stderr, "\n"); - } - if (lvl->tags) - { - fprintf (stderr, " tags:\t"); - i = 0; - for (t = lvl->tags; t; t = TREE_CHAIN (t)) - { - if (TREE_PURPOSE (t) == NULL_TREE) - len = 3; - else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) - len = 2; - else - len = 4; - i += len; - if (i > 5) - { - fprintf (stderr, "\n\t"); - i = len; - } - if (TREE_PURPOSE (t) == NULL_TREE) - { - print_node_brief (stderr, "<unnamed-typedef", TREE_VALUE (t), 0); - fprintf (stderr, ">"); - } - else if (TREE_PURPOSE (t) == TYPE_IDENTIFIER (TREE_VALUE (t))) - print_node_brief (stderr, "", TREE_VALUE (t), 0); - else - { - print_node_brief (stderr, "<typedef", TREE_PURPOSE (t), 0); - print_node_brief (stderr, "", TREE_VALUE (t), 0); - fprintf (stderr, ">"); - } - } - if (i) - fprintf (stderr, "\n"); - } - if (lvl->class_shadowed) - { - fprintf (stderr, " class-shadowed:"); - for (t = lvl->class_shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } - if (lvl->type_shadowed) - { - fprintf (stderr, " type-shadowed:"); - for (t = lvl->type_shadowed; t; t = TREE_CHAIN (t)) - { - fprintf (stderr, " %s ", IDENTIFIER_POINTER (TREE_PURPOSE (t))); - } - fprintf (stderr, "\n"); - } -} - -void -print_other_binding_stack (stack) - struct binding_level *stack; -{ - struct binding_level *level; - for (level = stack; level != global_binding_level; level = level->level_chain) - { - fprintf (stderr, "binding level "); - fprintf (stderr, HOST_PTR_PRINTF, level); - fprintf (stderr, "\n"); - print_binding_level (level); - } -} - -void -print_binding_stack () -{ - struct binding_level *b; - fprintf (stderr, "current_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, current_binding_level); - fprintf (stderr, "\nclass_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, class_binding_level); - fprintf (stderr, "\nglobal_binding_level="); - fprintf (stderr, HOST_PTR_PRINTF, global_binding_level); - fprintf (stderr, "\n"); - if (class_binding_level) - { - for (b = class_binding_level; b; b = b->level_chain) - if (b == current_binding_level) - break; - if (b) - b = class_binding_level; - else - b = current_binding_level; - } - else - b = current_binding_level; - print_other_binding_stack (b); - fprintf (stderr, "global:\n"); - print_binding_level (global_binding_level); -} - -/* Namespace binding access routines: The namespace_bindings field of - the identifier is polymorphic, with three possible values: - NULL_TREE, a list of CPLUS_BINDINGS, or any other tree_node - indicating the BINDING_VALUE of global_namespace. */ - -/* Check whether the a binding for the name to scope is known. - Assumes that the bindings of the name are already a list - of bindings. Returns the binding found, or NULL_TREE. */ - -static tree -find_binding (name, scope) - tree name; - tree scope; -{ - tree iter, prev = NULL_TREE; - - scope = ORIGINAL_NAMESPACE (scope); - - for (iter = IDENTIFIER_NAMESPACE_BINDINGS (name); iter; - iter = TREE_CHAIN (iter)) - { - my_friendly_assert (TREE_CODE (iter) == CPLUS_BINDING, 374); - if (BINDING_SCOPE (iter) == scope) - { - /* Move binding found to the fron of the list, so - subsequent lookups will find it faster. */ - if (prev) - { - TREE_CHAIN (prev) = TREE_CHAIN (iter); - TREE_CHAIN (iter) = IDENTIFIER_NAMESPACE_BINDINGS (name); - IDENTIFIER_NAMESPACE_BINDINGS (name) = iter; - } - return iter; - } - prev = iter; - } - return NULL_TREE; -} - -/* Always returns a binding for name in scope. If the - namespace_bindings is not a list, convert it to one first. - If no binding is found, make a new one. */ - -tree -binding_for_name (name, scope) - tree name; - tree scope; -{ - tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); - tree result; - - scope = ORIGINAL_NAMESPACE (scope); - - if (b && TREE_CODE (b) != CPLUS_BINDING) - { - /* Get rid of optimization for global scope. */ - IDENTIFIER_NAMESPACE_BINDINGS (name) = NULL_TREE; - BINDING_VALUE (binding_for_name (name, global_namespace)) = b; - b = IDENTIFIER_NAMESPACE_BINDINGS (name); - } - if (b && (result = find_binding (name, scope))) - return result; - /* Not found, make a new permanent one. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - result = make_node (CPLUS_BINDING); - TREE_CHAIN (result) = b; - IDENTIFIER_NAMESPACE_BINDINGS (name) = result; - BINDING_SCOPE (result) = scope; - BINDING_TYPE (result) = NULL_TREE; - BINDING_VALUE (result) = NULL_TREE; - pop_obstacks (); - return result; -} - -/* Return the binding value for name in scope, considering that - namespace_binding may or may not be a list of CPLUS_BINDINGS. */ - -tree -namespace_binding (name, scope) - tree name; - tree scope; -{ - tree b = IDENTIFIER_NAMESPACE_BINDINGS (name); - if (b == NULL_TREE) - return NULL_TREE; - if (scope == NULL_TREE) - scope = global_namespace; - if (TREE_CODE (b) != CPLUS_BINDING) - return (scope == global_namespace) ? b : NULL_TREE; - name = find_binding (name,scope); - if (name == NULL_TREE) - return name; - return BINDING_VALUE (name); -} - -/* Set the binding value for name in scope. If modifying the binding - of global_namespace is attempted, try to optimize it. */ - -void -set_namespace_binding (name, scope, val) - tree name; - tree scope; - tree val; -{ - tree b; - - if (scope == NULL_TREE) - scope = global_namespace; - - if (scope == global_namespace) - { - b = IDENTIFIER_NAMESPACE_BINDINGS (name); - if (b == NULL_TREE || TREE_CODE (b) != CPLUS_BINDING) - { - IDENTIFIER_NAMESPACE_BINDINGS (name) = val; - return; - } - } - b = binding_for_name (name, scope); - BINDING_VALUE (b) = val; -} - -/* Push into the scope of the NAME namespace. If NAME is NULL_TREE, then we - select a name that is unique to this compilation unit. */ - -void -push_namespace (name) - tree name; -{ - tree d = NULL_TREE; - int need_new = 1; - int implicit_use = 0; - int global = 0; - if (!global_namespace) - { - /* This must be ::. */ - my_friendly_assert (name == get_identifier ("::"), 377); - global = 1; - } - else if (!name) - { - /* The name of anonymous namespace is unique for the translation - unit. */ - if (!anonymous_namespace_name) - anonymous_namespace_name = get_file_function_name ('N'); - name = anonymous_namespace_name; - d = IDENTIFIER_NAMESPACE_VALUE (name); - if (d) - /* Reopening anonymous namespace. */ - need_new = 0; - implicit_use = 1; - } - else if (current_namespace == global_namespace - && name == DECL_NAME (std_node)) - { - in_std++; - return; - } - else - { - /* Check whether this is an extended namespace definition. */ - d = IDENTIFIER_NAMESPACE_VALUE (name); - if (d != NULL_TREE && TREE_CODE (d) == NAMESPACE_DECL) - { - need_new = 0; - if (DECL_NAMESPACE_ALIAS (d)) - { - cp_error ("namespace alias `%D' not allowed here, assuming `%D'", - d, DECL_NAMESPACE_ALIAS (d)); - d = DECL_NAMESPACE_ALIAS (d); - } - } - } - - if (need_new) - { - /* Make a new namespace, binding the name to it. */ - d = build_lang_decl (NAMESPACE_DECL, name, void_type_node); - /* The global namespace is not pushed, and the global binding - level is set elsewhere. */ - if (!global) - { - d = pushdecl (d); - pushlevel (0); - declare_namespace_level (); - NAMESPACE_LEVEL (d) = current_binding_level; - } - } - else - resume_binding_level (NAMESPACE_LEVEL (d)); - - if (implicit_use) - do_using_directive (d); - /* Enter the name space. */ - current_namespace = d; -} - -/* Pop from the scope of the current namespace. */ - -void -pop_namespace () -{ - if (current_namespace == global_namespace) - { - my_friendly_assert (in_std>0, 980421); - in_std--; - return; - } - current_namespace = CP_DECL_CONTEXT (current_namespace); - /* The binding level is not popped, as it might be re-opened later. */ - suspend_binding_level (); -} - -/* Concatenate the binding levels of all namespaces. */ - -void -cat_namespace_levels() -{ - tree current; - tree last; - struct binding_level *b; - - last = NAMESPACE_LEVEL (global_namespace) -> names; - /* The nested namespaces appear in the names list of their ancestors. */ - for (current = last; current; current = TREE_CHAIN (current)) - { - /* Catch simple infinite loops. */ - if (TREE_CHAIN (current) == current) - my_friendly_abort (990126); - - if (TREE_CODE (current) != NAMESPACE_DECL - || DECL_NAMESPACE_ALIAS (current)) - continue; - if (!DECL_LANG_SPECIFIC (current)) - { - /* Hmm. std. */ - my_friendly_assert (current == std_node, 393); - continue; - } - b = NAMESPACE_LEVEL (current); - while (TREE_CHAIN (last)) - last = TREE_CHAIN (last); - TREE_CHAIN (last) = NAMESPACE_LEVEL (current) -> names; - } -} - -/* Subroutines for reverting temporarily to top-level for instantiation - of templates and such. We actually need to clear out the class- and - local-value slots of all identifiers, so that only the global values - are at all visible. Simply setting current_binding_level to the global - scope isn't enough, because more binding levels may be pushed. */ -struct saved_scope { - struct binding_level *old_binding_level; - tree old_bindings; - tree old_namespace; - struct saved_scope *prev; - tree class_name, class_type; - tree access_specifier; - tree function_decl; - struct binding_level *class_bindings; - tree *lang_base, *lang_stack, lang_name; - int lang_stacksize; - int minimal_parse_mode; - tree last_function_parms; - tree template_parms; - HOST_WIDE_INT processing_template_decl; - tree previous_class_type, previous_class_values; - int processing_specialization; - int processing_explicit_instantiation; -}; -static struct saved_scope *current_saved_scope; - -/* A chain of the binding vecs created by store_bindings. We create a - whole bunch of these during compilation, on permanent_obstack, so we - can't just throw them away. */ -static tree free_binding_vecs; - -static tree -store_bindings (names, old_bindings) - tree names, old_bindings; -{ - tree t; - for (t = names; t; t = TREE_CHAIN (t)) - { - tree binding, t1, id; - - if (TREE_CODE (t) == TREE_LIST) - id = TREE_PURPOSE (t); - else - id = DECL_NAME (t); - - if (!id - /* Note that we may have an IDENTIFIER_CLASS_VALUE even when - we have no IDENTIFIER_BINDING if we have left the class - scope, but cached the class-level declarations. */ - || !(IDENTIFIER_BINDING (id) || IDENTIFIER_CLASS_VALUE (id))) - continue; - - for (t1 = old_bindings; t1; t1 = TREE_CHAIN (t1)) - if (TREE_VEC_ELT (t1, 0) == id) - goto skip_it; - - if (free_binding_vecs) - { - binding = free_binding_vecs; - free_binding_vecs = TREE_CHAIN (free_binding_vecs); - } - else - binding = make_tree_vec (4); - - if (id) - { - my_friendly_assert (TREE_CODE (id) == IDENTIFIER_NODE, 135); - TREE_VEC_ELT (binding, 0) = id; - TREE_VEC_ELT (binding, 1) = REAL_IDENTIFIER_TYPE_VALUE (id); - TREE_VEC_ELT (binding, 2) = IDENTIFIER_BINDING (id); - TREE_VEC_ELT (binding, 3) = IDENTIFIER_CLASS_VALUE (id); - IDENTIFIER_BINDING (id) = NULL_TREE; - IDENTIFIER_CLASS_VALUE (id) = NULL_TREE; - } - TREE_CHAIN (binding) = old_bindings; - old_bindings = binding; - skip_it: - ; - } - return old_bindings; -} - -void -maybe_push_to_top_level (pseudo) - int pseudo; -{ - extern int current_lang_stacksize; - struct saved_scope *s - = (struct saved_scope *) xmalloc (sizeof (struct saved_scope)); - struct binding_level *b = inner_binding_level; - tree old_bindings = NULL_TREE; - - if (current_function_decl) - push_cp_function_context (NULL_TREE); - - if (previous_class_type) - old_bindings = store_bindings (previous_class_values, old_bindings); - - /* Have to include global_binding_level, because class-level decls - aren't listed anywhere useful. */ - for (; b; b = b->level_chain) - { - tree t; - - /* Template IDs are inserted into the global level. If they were - inserted into namespace level, finish_file wouldn't find them - when doing pending instantiations. Therefore, don't stop at - namespace level, but continue until :: . */ - if (b == global_binding_level || (pseudo && b->pseudo_global)) - break; - - old_bindings = store_bindings (b->names, old_bindings); - /* We also need to check class_shadowed to save class-level type - bindings, since pushclass doesn't fill in b->names. */ - if (b->parm_flag == 2) - old_bindings = store_bindings (b->class_shadowed, old_bindings); - - /* Unwind type-value slots back to top level. */ - for (t = b->type_shadowed; t; t = TREE_CHAIN (t)) - SET_IDENTIFIER_TYPE_VALUE (TREE_PURPOSE (t), TREE_VALUE (t)); - } - - s->old_binding_level = current_binding_level; - current_binding_level = b; - - s->old_namespace = current_namespace; - s->class_name = current_class_name; - s->class_type = current_class_type; - s->access_specifier = current_access_specifier; - s->function_decl = current_function_decl; - s->class_bindings = class_binding_level; - s->lang_stack = current_lang_stack; - s->lang_base = current_lang_base; - s->lang_stacksize = current_lang_stacksize; - s->lang_name = current_lang_name; - s->minimal_parse_mode = minimal_parse_mode; - s->last_function_parms = last_function_parms; - s->template_parms = current_template_parms; - s->processing_template_decl = processing_template_decl; - s->previous_class_type = previous_class_type; - s->previous_class_values = previous_class_values; - s->processing_specialization = processing_specialization; - s->processing_explicit_instantiation = processing_explicit_instantiation; - - current_class_name = current_class_type = NULL_TREE; - current_function_decl = NULL_TREE; - class_binding_level = (struct binding_level *)0; - current_lang_stacksize = 10; - current_lang_stack = current_lang_base - = (tree *) xmalloc (current_lang_stacksize * sizeof (tree)); - current_lang_name = lang_name_cplusplus; - strict_prototype = strict_prototypes_lang_cplusplus; - named_labels = NULL_TREE; - shadowed_labels = NULL_TREE; - minimal_parse_mode = 0; - previous_class_type = previous_class_values = NULL_TREE; - processing_specialization = 0; - processing_explicit_instantiation = 0; - current_template_parms = NULL_TREE; - processing_template_decl = 0; - current_namespace = global_namespace; - - s->prev = current_saved_scope; - s->old_bindings = old_bindings; - current_saved_scope = s; - - push_obstacks (&permanent_obstack, &permanent_obstack); -} - -void -push_to_top_level () -{ - maybe_push_to_top_level (0); -} - -void -pop_from_top_level () -{ - extern int current_lang_stacksize; - struct saved_scope *s = current_saved_scope; - tree t; - - /* Clear out class-level bindings cache. */ - if (previous_class_type) - { - popclass (-1); - previous_class_type = NULL_TREE; - } - - pop_obstacks (); - - current_binding_level = s->old_binding_level; - current_saved_scope = s->prev; - for (t = s->old_bindings; t; ) - { - tree save = t; - tree id = TREE_VEC_ELT (t, 0); - if (id) - { - SET_IDENTIFIER_TYPE_VALUE (id, TREE_VEC_ELT (t, 1)); - IDENTIFIER_BINDING (id) = TREE_VEC_ELT (t, 2); - IDENTIFIER_CLASS_VALUE (id) = TREE_VEC_ELT (t, 3); - } - t = TREE_CHAIN (t); - TREE_CHAIN (save) = free_binding_vecs; - free_binding_vecs = save; - } - current_namespace = s->old_namespace; - current_class_name = s->class_name; - current_class_type = s->class_type; - current_access_specifier = s->access_specifier; - current_function_decl = s->function_decl; - class_binding_level = s->class_bindings; - free (current_lang_base); - current_lang_base = s->lang_base; - current_lang_stack = s->lang_stack; - current_lang_name = s->lang_name; - current_lang_stacksize = s->lang_stacksize; - if (current_lang_name == lang_name_cplusplus) - strict_prototype = strict_prototypes_lang_cplusplus; - else if (current_lang_name == lang_name_c) - strict_prototype = strict_prototypes_lang_c; - minimal_parse_mode = s->minimal_parse_mode; - last_function_parms = s->last_function_parms; - current_template_parms = s->template_parms; - processing_template_decl = s->processing_template_decl; - previous_class_type = s->previous_class_type; - previous_class_values = s->previous_class_values; - processing_specialization = s->processing_specialization; - processing_explicit_instantiation = s->processing_explicit_instantiation; - - free (s); - - if (current_function_decl) - pop_cp_function_context (NULL_TREE); -} - -/* Push a definition of struct, union or enum tag "name". - into binding_level "b". "type" should be the type node, - We assume that the tag "name" is not already defined. - - Note that the definition may really be just a forward reference. - In that case, the TYPE_SIZE will be a NULL_TREE. - - C++ gratuitously puts all these tags in the name space. */ - -/* When setting the IDENTIFIER_TYPE_VALUE field of an identifier ID, - record the shadowed value for this binding contour. TYPE is - the type that ID maps to. */ - -static void -set_identifier_type_value_with_scope (id, type, b) - tree id; - tree type; - struct binding_level *b; -{ - if (!b->namespace_p) - { - /* Shadow the marker, not the real thing, so that the marker - gets restored later. */ - tree old_type_value = REAL_IDENTIFIER_TYPE_VALUE (id); - b->type_shadowed - = tree_cons (id, old_type_value, b->type_shadowed); - } - else - { - tree binding = binding_for_name (id, current_namespace); - BINDING_TYPE (binding) = type; - /* Store marker instead of real type. */ - type = global_type_node; - } - SET_IDENTIFIER_TYPE_VALUE (id, type); -} - -/* As set_identifier_type_value_with_scope, but using inner_binding_level. */ - -void -set_identifier_type_value (id, type) - tree id; - tree type; -{ - set_identifier_type_value_with_scope (id, type, inner_binding_level); -} - -/* Return the type associated with id. */ - -tree -identifier_type_value (id) - tree id; -{ - /* There is no type with that name, anywhere. */ - if (REAL_IDENTIFIER_TYPE_VALUE (id) == NULL_TREE) - return NULL_TREE; - /* This is not the type marker, but the real thing. */ - if (REAL_IDENTIFIER_TYPE_VALUE (id) != global_type_node) - return REAL_IDENTIFIER_TYPE_VALUE (id); - /* Have to search for it. It must be on the global level, now. - Ask lookup_name not to return non-types. */ - id = lookup_name_real (id, 2, 1, 0); - if (id) - return TREE_TYPE (id); - return NULL_TREE; -} - -/* Pop off extraneous binding levels left over due to syntax errors. - - We don't pop past namespaces, as they might be valid. */ - -void -pop_everything () -{ -#ifdef DEBUG_CP_BINDING_LEVELS - fprintf (stderr, "XXX entering pop_everything ()\n"); -#endif - while (! toplevel_bindings_p () && ! pseudo_global_level_p ()) - { - if (class_binding_level) - pop_nested_class (1); - else - poplevel (0, 0, 0); - } -#ifdef DEBUG_CP_BINDING_LEVELS - fprintf (stderr, "XXX leaving pop_everything ()\n"); -#endif -} - -/* The type TYPE is being declared. If it is a class template, or a - specialization of a class template, do any processing required and - perform error-checking. If IS_FRIEND is non-zero, this TYPE is - being declared a friend. B is the binding level at which this TYPE - should be bound. - - Returns the TYPE_DECL for TYPE, which may have been altered by this - processing. */ - -static tree -maybe_process_template_type_declaration (type, globalize, b) - tree type; - int globalize; - struct binding_level* b; -{ - tree decl = TYPE_NAME (type); - - if (processing_template_parmlist) - /* You can't declare a new template type in a template parameter - list. But, you can declare a non-template type: - - template <class A*> struct S; - - is a forward-declaration of `A'. */ - ; - else - { - maybe_check_template_type (type); - - my_friendly_assert (IS_AGGR_TYPE (type) - || TREE_CODE (type) == ENUMERAL_TYPE, 0); - - - if (/* If !GLOBALIZE then we are looking at a definition. - It may not be a primary template. (For example, in: - - template <class T> - struct S1 { class S2 {}; } - - we have to push_template_decl for S2.) */ - (processing_template_decl && !globalize) - /* If we are declaring a friend template class, we will - have GLOBALIZE set, since something like: - - template <class T> - struct S1 { - template <class U> - friend class S2; - }; - - declares S2 to be at global scope. */ - || PROCESSING_REAL_TEMPLATE_DECL_P ()) - { - /* This may change after the call to - push_template_decl_real, but we want the original value. */ - tree name = DECL_NAME (decl); - - decl = push_template_decl_real (decl, globalize); - /* If the current binding level is the binding level for the - template parameters (see the comment in - begin_template_parm_list) and the enclosing level is a class - scope, and we're not looking at a friend, push the - declaration of the member class into the class scope. In the - friend case, push_template_decl will already have put the - friend into global scope, if appropriate. */ - if (TREE_CODE (type) != ENUMERAL_TYPE - && !globalize && b->pseudo_global - && b->level_chain->parm_flag == 2) - { - pushdecl_with_scope (CLASSTYPE_TI_TEMPLATE (type), - b->level_chain); - finish_member_declaration (CLASSTYPE_TI_TEMPLATE (type)); - /* Put this tag on the list of tags for the class, since - that won't happen below because B is not the class - binding level, but is instead the pseudo-global level. */ - b->level_chain->tags = - saveable_tree_cons (name, type, b->level_chain->tags); - TREE_NONLOCAL_FLAG (type) = 1; - if (TYPE_SIZE (current_class_type) == NULL_TREE) - CLASSTYPE_TAGS (current_class_type) = b->level_chain->tags; - } - } - } - - return decl; -} - -/* Push a tag name NAME for struct/class/union/enum type TYPE. - Normally put it into the inner-most non-tag-transparent scope, - but if GLOBALIZE is true, put it in the inner-most non-class scope. - The latter is needed for implicit declarations. */ - -void -pushtag (name, type, globalize) - tree name, type; - int globalize; -{ - register struct binding_level *b; - tree context = 0; - tree c_decl = 0; - - b = inner_binding_level; - while (b->tag_transparent - || (globalize && b->parm_flag == 2)) - b = b->level_chain; - - if (toplevel_bindings_p ()) - b->tags = perm_tree_cons (name, type, b->tags); - else - b->tags = saveable_tree_cons (name, type, b->tags); - - if (name) - { - context = type ? TYPE_CONTEXT (type) : NULL_TREE; - if (! context) - { - tree cs = current_scope (); - - if (! globalize) - context = cs; - else if (cs != NULL_TREE - && TREE_CODE_CLASS (TREE_CODE (cs)) == 't') - /* When declaring a friend class of a local class, we want - to inject the newly named class into the scope - containing the local class, not the namespace scope. */ - context = hack_decl_function_context (get_type_decl (cs)); - } - if (context) - c_decl = TREE_CODE (context) == FUNCTION_DECL - ? context : TYPE_MAIN_DECL (context); - - if (!context) - context = current_namespace; - - /* Do C++ gratuitous typedefing. */ - if (IDENTIFIER_TYPE_VALUE (name) != type) - { - register tree d = NULL_TREE; - int newdecl = 0, in_class = 0; - - if ((b->pseudo_global && b->level_chain->parm_flag == 2) - || b->parm_flag == 2) - in_class = 1; - else - d = lookup_nested_type (type, c_decl); - - if (d == NULL_TREE) - { - newdecl = 1; - d = build_decl (TYPE_DECL, name, type); - if (current_lang_name == lang_name_java) - TYPE_FOR_JAVA (type) = 1; - SET_DECL_ARTIFICIAL (d); - if (! in_class) - set_identifier_type_value_with_scope (name, type, b); - } - else - d = TYPE_MAIN_DECL (d); - - TYPE_NAME (type) = d; - DECL_CONTEXT (d) = FROB_CONTEXT (context); - - d = maybe_process_template_type_declaration (type, - globalize, b); - - if (b->parm_flag == 2) - { - pushdecl_class_level (d); - if (newdecl && !PROCESSING_REAL_TEMPLATE_DECL_P ()) - /* Put this TYPE_DECL on the TYPE_FIELDS list for the - class. But if it's a member template class, we - want the TEMPLATE_DECL, not the TYPE_DECL, so this - is done later. */ - finish_member_declaration (d); - } - else - d = pushdecl_with_scope (d, b); - - if (newdecl) - { - if (ANON_AGGRNAME_P (name)) - DECL_IGNORED_P (d) = 1; - - TYPE_CONTEXT (type) = DECL_CONTEXT (d); - DECL_ASSEMBLER_NAME (d) = DECL_NAME (d); - if (!uses_template_parms (type)) - DECL_ASSEMBLER_NAME (d) - = get_identifier (build_overload_name (type, 1, 1)); - } - } - if (b->parm_flag == 2) - { - TREE_NONLOCAL_FLAG (type) = 1; - if (TYPE_SIZE (current_class_type) == NULL_TREE) - CLASSTYPE_TAGS (current_class_type) = b->tags; - } - } - - if (TREE_CODE (TYPE_NAME (type)) == TYPE_DECL) - /* Use the canonical TYPE_DECL for this node. */ - TYPE_STUB_DECL (type) = TYPE_NAME (type); - else - { - /* Create a fake NULL-named TYPE_DECL node whose TREE_TYPE - will be the tagged type we just added to the current - binding level. This fake NULL-named TYPE_DECL node helps - dwarfout.c to know when it needs to output a - representation of a tagged type, and it also gives us a - convenient place to record the "scope start" address for - the tagged type. */ - - tree d = build_decl (TYPE_DECL, NULL_TREE, type); - TYPE_STUB_DECL (type) = pushdecl_with_scope (d, b); - } -} - -/* Counter used to create anonymous type names. */ - -static int anon_cnt = 0; - -/* Return an IDENTIFIER which can be used as a name for - anonymous structs and unions. */ - -tree -make_anon_name () -{ - char buf[32]; - - sprintf (buf, ANON_AGGRNAME_FORMAT, anon_cnt++); - return get_identifier (buf); -} - -/* Clear the TREE_PURPOSE slot of tags which have anonymous typenames. - This keeps dbxout from getting confused. */ - -void -clear_anon_tags () -{ - register struct binding_level *b; - register tree tags; - static int last_cnt = 0; - - /* Fast out if no new anon names were declared. */ - if (last_cnt == anon_cnt) - return; - - b = current_binding_level; - while (b->tag_transparent) - b = b->level_chain; - tags = b->tags; - while (tags) - { - /* A NULL purpose means we have already processed all tags - from here to the end of the list. */ - if (TREE_PURPOSE (tags) == NULL_TREE) - break; - if (ANON_AGGRNAME_P (TREE_PURPOSE (tags))) - TREE_PURPOSE (tags) = NULL_TREE; - tags = TREE_CHAIN (tags); - } - last_cnt = anon_cnt; -} - -/* Subroutine of duplicate_decls: return truthvalue of whether - or not types of these decls match. - - For C++, we must compare the parameter list so that `int' can match - `int&' in a parameter position, but `int&' is not confused with - `const int&'. */ - -int -decls_match (newdecl, olddecl) - tree newdecl, olddecl; -{ - int types_match; - - if (newdecl == olddecl) - return 1; - - if (TREE_CODE (newdecl) != TREE_CODE (olddecl)) - /* If the two DECLs are not even the same kind of thing, we're not - interested in their types. */ - return 0; - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - tree f1 = TREE_TYPE (newdecl); - tree f2 = TREE_TYPE (olddecl); - tree p1 = TYPE_ARG_TYPES (f1); - tree p2 = TYPE_ARG_TYPES (f2); - - if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl) - && ! (DECL_LANGUAGE (newdecl) == lang_c - && DECL_LANGUAGE (olddecl) == lang_c)) - return 0; - - /* When we parse a static member function definition, - we put together a FUNCTION_DECL which thinks its type - is METHOD_TYPE. Change that to FUNCTION_TYPE, and - proceed. */ - if (TREE_CODE (f1) == METHOD_TYPE && DECL_STATIC_FUNCTION_P (olddecl)) - revert_static_member_fn (&newdecl, &f1, &p1); - else if (TREE_CODE (f2) == METHOD_TYPE - && DECL_STATIC_FUNCTION_P (newdecl)) - revert_static_member_fn (&olddecl, &f2, &p2); - - /* Here we must take care of the case where new default - parameters are specified. Also, warn if an old - declaration becomes ambiguous because default - parameters may cause the two to be ambiguous. */ - if (TREE_CODE (f1) != TREE_CODE (f2)) - { - if (TREE_CODE (f1) == OFFSET_TYPE) - cp_compiler_error ("`%D' redeclared as member function", newdecl); - else - cp_compiler_error ("`%D' redeclared as non-member function", newdecl); - return 0; - } - - if (same_type_p (TREE_TYPE (f1), TREE_TYPE (f2))) - { - if (! strict_prototypes_lang_c && DECL_LANGUAGE (olddecl) == lang_c - && p2 == NULL_TREE) - { - types_match = self_promoting_args_p (p1); - if (p1 == void_list_node) - TREE_TYPE (newdecl) = TREE_TYPE (olddecl); - } - else if (!strict_prototypes_lang_c && DECL_LANGUAGE (olddecl)==lang_c - && DECL_LANGUAGE (newdecl) == lang_c && p1 == NULL_TREE) - { - types_match = self_promoting_args_p (p2); - TREE_TYPE (newdecl) = TREE_TYPE (olddecl); - } - else - types_match = compparms (p1, p2); - } - else - types_match = 0; - } - else if (TREE_CODE (newdecl) == TEMPLATE_DECL) - { - if (!comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), - DECL_TEMPLATE_PARMS (olddecl))) - return 0; - - if (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) - types_match = 1; - else - types_match = decls_match (DECL_TEMPLATE_RESULT (olddecl), - DECL_TEMPLATE_RESULT (newdecl)); - } - else - { - if (TREE_TYPE (newdecl) == error_mark_node) - types_match = TREE_TYPE (olddecl) == error_mark_node; - else if (TREE_TYPE (olddecl) == NULL_TREE) - types_match = TREE_TYPE (newdecl) == NULL_TREE; - else if (TREE_TYPE (newdecl) == NULL_TREE) - types_match = 0; - else - types_match = comptypes (TREE_TYPE (newdecl), - TREE_TYPE (olddecl), - COMPARE_REDECLARATION); - } - - return types_match; -} - -/* If NEWDECL is `static' and an `extern' was seen previously, - warn about it. (OLDDECL may be NULL_TREE; NAME contains - information about previous usage as an `extern'.) - - Note that this does not apply to the C++ case of declaring - a variable `extern const' and then later `const'. - - Don't complain about built-in functions, since they are beyond - the user's control. */ - -static void -warn_extern_redeclared_static (newdecl, olddecl) - tree newdecl, olddecl; -{ - tree name; - - static char *explicit_extern_static_warning - = "`%D' was declared `extern' and later `static'"; - static char *implicit_extern_static_warning - = "`%D' was declared implicitly `extern' and later `static'"; - - if (TREE_CODE (newdecl) == TYPE_DECL) - return; - - name = DECL_ASSEMBLER_NAME (newdecl); - if (TREE_PUBLIC (name) && DECL_THIS_STATIC (newdecl)) - { - /* It's okay to redeclare an ANSI built-in function as static, - or to declare a non-ANSI built-in function as anything. */ - if (! (TREE_CODE (newdecl) == FUNCTION_DECL - && olddecl != NULL_TREE - && TREE_CODE (olddecl) == FUNCTION_DECL - && (DECL_BUILT_IN (olddecl) - || DECL_BUILT_IN_NONANSI (olddecl)))) - { - cp_pedwarn (IDENTIFIER_IMPLICIT_DECL (name) - ? implicit_extern_static_warning - : explicit_extern_static_warning, newdecl); - if (olddecl != NULL_TREE) - cp_pedwarn_at ("previous declaration of `%D'", olddecl); - } - } -} - -/* Handle when a new declaration NEWDECL has the same name as an old - one OLDDECL in the same binding contour. Prints an error message - if appropriate. - - If safely possible, alter OLDDECL to look like NEWDECL, and return 1. - Otherwise, return 0. */ - -int -duplicate_decls (newdecl, olddecl) - tree newdecl, olddecl; -{ - extern struct obstack permanent_obstack; - unsigned olddecl_uid = DECL_UID (olddecl); - int olddecl_friend = 0, types_match = 0; - int new_defines_function = 0; - - if (newdecl == olddecl) - return 1; - - types_match = decls_match (newdecl, olddecl); - - /* If either the type of the new decl or the type of the old decl is an - error_mark_node, then that implies that we have already issued an - error (earlier) for some bogus type specification, and in that case, - it is rather pointless to harass the user with yet more error message - about the same declaration, so just pretend the types match here. */ - if (TREE_TYPE (newdecl) == error_mark_node - || TREE_TYPE (olddecl) == error_mark_node) - types_match = 1; - - /* Check for redeclaration and other discrepancies. */ - if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_ARTIFICIAL (olddecl) - && (DECL_BUILT_IN (olddecl) || DECL_BUILT_IN_NONANSI (olddecl))) - { - /* If you declare a built-in or predefined function name as static, - the old definition is overridden, but optionally warn this was a - bad choice of name. Ditto for overloads. */ - if (! TREE_PUBLIC (newdecl) - || (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl))) - { - if (warn_shadow) - cp_warning ("shadowing %s function `%#D'", - DECL_BUILT_IN (olddecl) ? "built-in" : "library", - olddecl); - /* Discard the old built-in function. */ - return 0; - } - else if (! types_match) - { - if (TREE_CODE (newdecl) != FUNCTION_DECL) - { - /* If the built-in is not ansi, then programs can override - it even globally without an error. */ - if (! DECL_BUILT_IN (olddecl)) - cp_warning ("library function `%#D' redeclared as non-function `%#D'", - olddecl, newdecl); - else - { - cp_error ("declaration of `%#D'", newdecl); - cp_error ("conflicts with built-in declaration `%#D'", - olddecl); - } - return 0; - } - - cp_warning ("declaration of `%#D'", newdecl); - cp_warning ("conflicts with built-in declaration `%#D'", - olddecl); - } - } - else if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) - { - if ((TREE_CODE (olddecl) == TYPE_DECL && DECL_ARTIFICIAL (olddecl) - && TREE_CODE (newdecl) != TYPE_DECL - && ! (TREE_CODE (newdecl) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL)) - || (TREE_CODE (newdecl) == TYPE_DECL && DECL_ARTIFICIAL (newdecl) - && TREE_CODE (olddecl) != TYPE_DECL - && ! (TREE_CODE (olddecl) == TEMPLATE_DECL - && (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) - == TYPE_DECL)))) - { - /* We do nothing special here, because C++ does such nasty - things with TYPE_DECLs. Instead, just let the TYPE_DECL - get shadowed, and know that if we need to find a TYPE_DECL - for a given name, we can look in the IDENTIFIER_TYPE_VALUE - slot of the identifier. */ - return 0; - } - - if ((TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_FUNCTION_TEMPLATE_P (olddecl)) - || (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_FUNCTION_TEMPLATE_P (newdecl))) - return 0; - - cp_error ("`%#D' redeclared as different kind of symbol", newdecl); - if (TREE_CODE (olddecl) == TREE_LIST) - olddecl = TREE_VALUE (olddecl); - cp_error_at ("previous declaration of `%#D'", olddecl); - - /* New decl is completely inconsistent with the old one => - tell caller to replace the old one. */ - - return 0; - } - else if (!types_match) - { - if (DECL_REAL_CONTEXT (newdecl) != DECL_REAL_CONTEXT (olddecl)) - /* These are certainly not duplicate declarations; they're - from different scopes. */ - return 0; - - if (TREE_CODE (newdecl) == TEMPLATE_DECL) - { - /* The name of a class template may not be declared to refer to - any other template, class, function, object, namespace, value, - or type in the same scope. */ - if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == TYPE_DECL - || TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL) - { - cp_error ("declaration of template `%#D'", newdecl); - cp_error_at ("conflicts with previous declaration `%#D'", - olddecl); - } - else if (TREE_CODE (DECL_TEMPLATE_RESULT (olddecl)) == FUNCTION_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL - && compparms (TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl))), - TYPE_ARG_TYPES (TREE_TYPE (DECL_TEMPLATE_RESULT (newdecl)))) - && comp_template_parms (DECL_TEMPLATE_PARMS (newdecl), - DECL_TEMPLATE_PARMS (olddecl))) - { - cp_error ("new declaration `%#D'", newdecl); - cp_error_at ("ambiguates old declaration `%#D'", olddecl); - } - return 0; - } - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - if (DECL_LANGUAGE (newdecl) == lang_c - && DECL_LANGUAGE (olddecl) == lang_c) - { - cp_error ("declaration of C function `%#D' conflicts with", - newdecl); - cp_error_at ("previous declaration `%#D' here", olddecl); - } - else if (compparms (TYPE_ARG_TYPES (TREE_TYPE (newdecl)), - TYPE_ARG_TYPES (TREE_TYPE (olddecl)))) - { - cp_error ("new declaration `%#D'", newdecl); - cp_error_at ("ambiguates old declaration `%#D'", olddecl); - } - else - return 0; - } - - /* Already complained about this, so don't do so again. */ - else if (current_class_type == NULL_TREE - || IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (newdecl)) != current_class_type) - { - cp_error ("conflicting types for `%#D'", newdecl); - cp_error_at ("previous declaration as `%#D'", olddecl); - } - } - else if (TREE_CODE (newdecl) == FUNCTION_DECL - && ((DECL_TEMPLATE_SPECIALIZATION (olddecl) - && (!DECL_TEMPLATE_INFO (newdecl) - || (DECL_TI_TEMPLATE (newdecl) - != DECL_TI_TEMPLATE (olddecl)))) - || (DECL_TEMPLATE_SPECIALIZATION (newdecl) - && (!DECL_TEMPLATE_INFO (olddecl) - || (DECL_TI_TEMPLATE (olddecl) - != DECL_TI_TEMPLATE (newdecl)))))) - /* It's OK to have a template specialization and a non-template - with the same type, or to have specializations of two - different templates with the same type. Note that if one is a - specialization, and the other is an instantiation of the same - template, that we do not exit at this point. That situation - can occur if we instantiate a template class, and then - specialize one of its methods. This situation is legal, but - the declarations must be merged in the usual way. */ - return 0; - else if (TREE_CODE (newdecl) == FUNCTION_DECL - && ((DECL_TEMPLATE_INSTANTIATION (olddecl) - && !DECL_USE_TEMPLATE (newdecl)) - || (DECL_TEMPLATE_INSTANTIATION (newdecl) - && !DECL_USE_TEMPLATE (olddecl)))) - /* One of the declarations is a template instantiation, and the - other is not a template at all. That's OK. */ - return 0; - else if (TREE_CODE (newdecl) == NAMESPACE_DECL - && DECL_NAMESPACE_ALIAS (newdecl) - && DECL_NAMESPACE_ALIAS (newdecl) == DECL_NAMESPACE_ALIAS (olddecl)) - /* Redeclaration of namespace alias, ignore it. */ - return 1; - else - { - char *errmsg = redeclaration_error_message (newdecl, olddecl); - if (errmsg) - { - cp_error (errmsg, newdecl); - if (DECL_NAME (olddecl) != NULL_TREE) - cp_error_at ((DECL_INITIAL (olddecl) - && namespace_bindings_p ()) - ? "`%#D' previously defined here" - : "`%#D' previously declared here", olddecl); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_INITIAL (olddecl) != NULL_TREE - && TYPE_ARG_TYPES (TREE_TYPE (olddecl)) == NULL_TREE - && TYPE_ARG_TYPES (TREE_TYPE (newdecl)) != NULL_TREE) - { - /* Prototype decl follows defn w/o prototype. */ - cp_warning_at ("prototype for `%#D'", newdecl); - cp_warning_at ("follows non-prototype definition here", olddecl); - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_LANGUAGE (newdecl) != DECL_LANGUAGE (olddecl)) - { - /* extern "C" int foo (); - int foo () { bar (); } - is OK. */ - if (current_lang_stack == current_lang_base) - DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); - else - { - cp_error_at ("previous declaration of `%#D' with %L linkage", - olddecl, DECL_LANGUAGE (olddecl)); - cp_error ("conflicts with new declaration with %L linkage", - DECL_LANGUAGE (newdecl)); - } - } - - if (DECL_LANG_SPECIFIC (olddecl) && DECL_USE_TEMPLATE (olddecl)) - ; - else if (TREE_CODE (olddecl) == FUNCTION_DECL) - { - tree t1 = TYPE_ARG_TYPES (TREE_TYPE (olddecl)); - tree t2 = TYPE_ARG_TYPES (TREE_TYPE (newdecl)); - int i = 1; - - if (TREE_CODE (TREE_TYPE (newdecl)) == METHOD_TYPE) - t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2); - - for (; t1 && t1 != void_list_node; - t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2), i++) - if (TREE_PURPOSE (t1) && TREE_PURPOSE (t2)) - { - if (1 == simple_cst_equal (TREE_PURPOSE (t1), - TREE_PURPOSE (t2))) - { - if (pedantic) - { - cp_pedwarn ("default argument given for parameter %d of `%#D'", - i, newdecl); - cp_pedwarn_at ("after previous specification in `%#D'", - olddecl); - } - } - else - { - cp_error ("default argument given for parameter %d of `%#D'", - i, newdecl); - cp_error_at ("after previous specification in `%#D'", - olddecl); - } - } - - if (DECL_THIS_INLINE (newdecl) && ! DECL_THIS_INLINE (olddecl) - && TREE_ADDRESSABLE (olddecl) && warn_inline) - { - cp_warning ("`%#D' was used before it was declared inline", - newdecl); - cp_warning_at ("previous non-inline declaration here", - olddecl); - } - } - } - - /* If new decl is `static' and an `extern' was seen previously, - warn about it. */ - warn_extern_redeclared_static (newdecl, olddecl); - - /* We have committed to returning 1 at this point. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* Now that functions must hold information normally held - by field decls, there is extra work to do so that - declaration information does not get destroyed during - definition. */ - if (DECL_VINDEX (olddecl)) - DECL_VINDEX (newdecl) = DECL_VINDEX (olddecl); - if (DECL_CONTEXT (olddecl)) - DECL_CONTEXT (newdecl) = DECL_CONTEXT (olddecl); - if (DECL_CLASS_CONTEXT (olddecl)) - DECL_CLASS_CONTEXT (newdecl) = DECL_CLASS_CONTEXT (olddecl); - if (DECL_PENDING_INLINE_INFO (newdecl) == (struct pending_inline *)0) - DECL_PENDING_INLINE_INFO (newdecl) = DECL_PENDING_INLINE_INFO (olddecl); - DECL_STATIC_CONSTRUCTOR (newdecl) |= DECL_STATIC_CONSTRUCTOR (olddecl); - DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); - DECL_ABSTRACT_VIRTUAL_P (newdecl) |= DECL_ABSTRACT_VIRTUAL_P (olddecl); - DECL_VIRTUAL_P (newdecl) |= DECL_VIRTUAL_P (olddecl); - DECL_NEEDS_FINAL_OVERRIDER_P (newdecl) |= DECL_NEEDS_FINAL_OVERRIDER_P (olddecl); - new_defines_function = DECL_INITIAL (newdecl) != NULL_TREE; - - /* Optionally warn about more than one declaration for the same - name, but don't warn about a function declaration followed by a - definition. */ - if (warn_redundant_decls && ! DECL_ARTIFICIAL (olddecl) - && !(new_defines_function && DECL_INITIAL (olddecl) == NULL_TREE) - /* Don't warn about extern decl followed by definition. */ - && !(DECL_EXTERNAL (olddecl) && ! DECL_EXTERNAL (newdecl)) - /* Don't warn about friends, let add_friend take care of it. */ - && ! DECL_FRIEND_P (newdecl)) - { - cp_warning ("redundant redeclaration of `%D' in same scope", newdecl); - cp_warning_at ("previous declaration of `%D'", olddecl); - } - } - - /* Deal with C++: must preserve virtual function table size. */ - if (TREE_CODE (olddecl) == TYPE_DECL) - { - register tree newtype = TREE_TYPE (newdecl); - register tree oldtype = TREE_TYPE (olddecl); - - if (newtype != error_mark_node && oldtype != error_mark_node - && TYPE_LANG_SPECIFIC (newtype) && TYPE_LANG_SPECIFIC (oldtype)) - { - CLASSTYPE_VSIZE (newtype) = CLASSTYPE_VSIZE (oldtype); - CLASSTYPE_FRIEND_CLASSES (newtype) - = CLASSTYPE_FRIEND_CLASSES (oldtype); - } - } - - /* Copy all the DECL_... slots specified in the new decl - except for any that we copy here from the old type. */ - DECL_MACHINE_ATTRIBUTES (newdecl) - = merge_machine_decl_attributes (olddecl, newdecl); - - if (TREE_CODE (newdecl) == TEMPLATE_DECL) - { - if (! duplicate_decls (DECL_TEMPLATE_RESULT (newdecl), - DECL_TEMPLATE_RESULT (olddecl))) - cp_error ("invalid redeclaration of %D", newdecl); - TREE_TYPE (olddecl) = TREE_TYPE (DECL_TEMPLATE_RESULT (olddecl)); - DECL_TEMPLATE_SPECIALIZATIONS (olddecl) - = chainon (DECL_TEMPLATE_SPECIALIZATIONS (olddecl), - DECL_TEMPLATE_SPECIALIZATIONS (newdecl)); - - return 1; - } - - if (types_match) - { - /* Automatically handles default parameters. */ - tree oldtype = TREE_TYPE (olddecl); - tree newtype; - - /* Make sure we put the new type in the same obstack as the old one. */ - if (oldtype) - push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); - else - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - /* Merge the data types specified in the two decls. */ - newtype = common_type (TREE_TYPE (newdecl), TREE_TYPE (olddecl)); - - if (TREE_CODE (newdecl) == VAR_DECL) - DECL_THIS_EXTERN (newdecl) |= DECL_THIS_EXTERN (olddecl); - /* Do this after calling `common_type' so that default - parameters don't confuse us. */ - else if (TREE_CODE (newdecl) == FUNCTION_DECL - && (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl)) - != TYPE_RAISES_EXCEPTIONS (TREE_TYPE (olddecl)))) - { - TREE_TYPE (newdecl) = build_exception_variant (newtype, - TYPE_RAISES_EXCEPTIONS (TREE_TYPE (newdecl))); - TREE_TYPE (olddecl) = build_exception_variant (newtype, - TYPE_RAISES_EXCEPTIONS (oldtype)); - - if ((pedantic || ! DECL_IN_SYSTEM_HEADER (olddecl)) - && DECL_SOURCE_LINE (olddecl) != 0 - && flag_exceptions - && ! compexcepttypes (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) - { - cp_pedwarn ("declaration of `%D' throws different exceptions", - newdecl); - cp_pedwarn_at ("previous declaration here", olddecl); - } - } - TREE_TYPE (newdecl) = TREE_TYPE (olddecl) = newtype; - - /* Lay the type out, unless already done. */ - if (newtype != canonical_type_variant (oldtype) - && TREE_TYPE (newdecl) != error_mark_node - && !(processing_template_decl && uses_template_parms (newdecl))) - layout_type (TREE_TYPE (newdecl)); - - if ((TREE_CODE (newdecl) == VAR_DECL - || TREE_CODE (newdecl) == PARM_DECL - || TREE_CODE (newdecl) == RESULT_DECL - || TREE_CODE (newdecl) == FIELD_DECL - || TREE_CODE (newdecl) == TYPE_DECL) - && !(processing_template_decl && uses_template_parms (newdecl))) - layout_decl (newdecl, 0); - - /* Merge the type qualifiers. */ - if (TREE_READONLY (newdecl)) - TREE_READONLY (olddecl) = 1; - if (TREE_THIS_VOLATILE (newdecl)) - TREE_THIS_VOLATILE (olddecl) = 1; - - /* Merge the initialization information. */ - if (DECL_INITIAL (newdecl) == NULL_TREE - && DECL_INITIAL (olddecl) != NULL_TREE) - { - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); - DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); - if (DECL_LANG_SPECIFIC (newdecl) - && DECL_LANG_SPECIFIC (olddecl)) - DECL_SAVED_TREE (newdecl) = DECL_SAVED_TREE (olddecl); - } - - /* Merge the section attribute. - We want to issue an error if the sections conflict but that must be - done later in decl_attributes since we are called before attributes - are assigned. */ - if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - - /* Keep the old rtl since we can safely use it, unless it's the - call to abort() used for abstract virtuals. */ - if ((DECL_LANG_SPECIFIC (olddecl) - && !DECL_ABSTRACT_VIRTUAL_P (olddecl)) - || DECL_RTL (olddecl) != DECL_RTL (abort_fndecl)) - DECL_RTL (newdecl) = DECL_RTL (olddecl); - - pop_obstacks (); - } - /* If cannot merge, then use the new type and qualifiers, - and don't preserve the old rtl. */ - else - { - /* Clean out any memory we had of the old declaration. */ - tree oldstatic = value_member (olddecl, static_aggregates); - if (oldstatic) - TREE_VALUE (oldstatic) = error_mark_node; - - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - TREE_READONLY (olddecl) = TREE_READONLY (newdecl); - TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); - TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl); - } - - /* Merge the storage class information. */ - DECL_WEAK (newdecl) |= DECL_WEAK (olddecl); - DECL_ONE_ONLY (newdecl) |= DECL_ONE_ONLY (olddecl); - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); - TREE_STATIC (olddecl) = TREE_STATIC (newdecl) |= TREE_STATIC (olddecl); - if (! DECL_EXTERNAL (olddecl)) - DECL_EXTERNAL (newdecl) = 0; - - if (DECL_LANG_SPECIFIC (newdecl) && DECL_LANG_SPECIFIC (olddecl)) - { - DECL_INTERFACE_KNOWN (newdecl) |= DECL_INTERFACE_KNOWN (olddecl); - DECL_NOT_REALLY_EXTERN (newdecl) |= DECL_NOT_REALLY_EXTERN (olddecl); - DECL_COMDAT (newdecl) |= DECL_COMDAT (olddecl); - /* Don't really know how much of the language-specific - values we should copy from old to new. */ - DECL_IN_AGGR_P (newdecl) = DECL_IN_AGGR_P (olddecl); - DECL_ACCESS (newdecl) = DECL_ACCESS (olddecl); - DECL_NONCONVERTING_P (newdecl) = DECL_NONCONVERTING_P (olddecl); - DECL_TEMPLATE_INFO (newdecl) = DECL_TEMPLATE_INFO (olddecl); - olddecl_friend = DECL_FRIEND_P (olddecl); - } - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - if (DECL_TEMPLATE_INSTANTIATION (olddecl) - && !DECL_TEMPLATE_INSTANTIATION (newdecl)) - { - /* If newdecl is not a specialization, then it is not a - template-related function at all. And that means that we - shoud have exited above, returning 0. */ - my_friendly_assert (DECL_TEMPLATE_SPECIALIZATION (newdecl), - 0); - - if (TREE_USED (olddecl)) - /* From [temp.expl.spec]: - - If a template, a member template or the member of a class - template is explicitly specialized then that - specialization shall be declared before the first use of - that specialization that would cause an implicit - instantiation to take place, in every translation unit in - which such a use occurs. */ - cp_error ("explicit specialization of %D after first use", - olddecl); - - SET_DECL_TEMPLATE_SPECIALIZATION (olddecl); - } - DECL_THIS_INLINE (newdecl) |= DECL_THIS_INLINE (olddecl); - - /* If either decl says `inline', this fn is inline, unless its - definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == NULL_TREE) - DECL_INLINE (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); - - if (! types_match) - { - DECL_LANGUAGE (olddecl) = DECL_LANGUAGE (newdecl); - DECL_ASSEMBLER_NAME (olddecl) = DECL_ASSEMBLER_NAME (newdecl); - DECL_RTL (olddecl) = DECL_RTL (newdecl); - } - if (! types_match || new_defines_function) - { - /* These need to be copied so that the names are available. */ - DECL_ARGUMENTS (olddecl) = DECL_ARGUMENTS (newdecl); - DECL_RESULT (olddecl) = DECL_RESULT (newdecl); - } - if (new_defines_function) - /* If defining a function declared with other language - linkage, use the previously declared language linkage. */ - DECL_LANGUAGE (newdecl) = DECL_LANGUAGE (olddecl); - else - { - /* If redeclaring a builtin function, and not a definition, - it stays built in. */ - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN (newdecl) = 1; - DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); - /* If we're keeping the built-in definition, keep the rtl, - regardless of declaration matches. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); - } - else - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); - - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - if ((DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl))) - /* Previously saved insns go together with - the function's previous definition. */ - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - /* Don't clear out the arguments if we're redefining a function. */ - if (DECL_ARGUMENTS (olddecl)) - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - } - if (DECL_LANG_SPECIFIC (olddecl)) - DECL_MAIN_VARIANT (newdecl) = DECL_MAIN_VARIANT (olddecl); - } - - if (TREE_CODE (newdecl) == NAMESPACE_DECL) - { - NAMESPACE_LEVEL (newdecl) = NAMESPACE_LEVEL (olddecl); - } - - /* Now preserve various other info from the definition. */ - TREE_ADDRESSABLE (newdecl) = TREE_ADDRESSABLE (olddecl); - TREE_ASM_WRITTEN (newdecl) = TREE_ASM_WRITTEN (olddecl); - DECL_COMMON (newdecl) = DECL_COMMON (olddecl); - DECL_ASSEMBLER_NAME (newdecl) = DECL_ASSEMBLER_NAME (olddecl); - - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - int function_size; - struct lang_decl *ol = DECL_LANG_SPECIFIC (olddecl); - struct lang_decl *nl = DECL_LANG_SPECIFIC (newdecl); - - function_size = sizeof (struct tree_decl); - - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - function_size - sizeof (struct tree_common)); - - /* Can we safely free the storage used by newdecl? */ - -#define ROUND(x) ((x + obstack_alignment_mask (&permanent_obstack)) \ - & ~ obstack_alignment_mask (&permanent_obstack)) - - if (DECL_TEMPLATE_INSTANTIATION (newdecl)) - { - /* If newdecl is a template instantiation, it is possible that - the following sequence of events has occurred: - - o A friend function was declared in a class template. The - class template was instantiated. - - o The instantiation of the friend declaration was - recorded on the instantiation list, and is newdecl. - - o Later, however, instantiate_class_template called pushdecl - on the newdecl to perform name injection. But, pushdecl in - turn called duplicate_decls when it discovered that another - declaration of a global function with the same name already - existed. - - o Here, in duplicate_decls, we decided to clobber newdecl. - - If we're going to do that, we'd better make sure that - olddecl, and not newdecl, is on the list of - instantiations so that if we try to do the instantiation - again we won't get the clobbered declaration. */ - - tree tmpl = DECL_TI_TEMPLATE (newdecl); - tree decls = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - - for (; decls; decls = TREE_CHAIN (decls)) - if (TREE_VALUE (decls) == newdecl) - TREE_VALUE (decls) = olddecl; - } - - if (((char *)newdecl + ROUND (function_size) == (char *)nl - && ((char *)newdecl + ROUND (function_size) - + ROUND (sizeof (struct lang_decl)) - == obstack_next_free (&permanent_obstack))) - || ((char *)newdecl + ROUND (function_size) - == obstack_next_free (&permanent_obstack))) - { - DECL_MAIN_VARIANT (newdecl) = olddecl; - DECL_LANG_SPECIFIC (olddecl) = ol; - bcopy ((char *)nl, (char *)ol, sizeof (struct lang_decl)); - - obstack_free (&permanent_obstack, newdecl); - } - else if (LANG_DECL_PERMANENT (ol) && ol != nl) - { - if (DECL_MAIN_VARIANT (olddecl) == olddecl) - { - /* Save these lang_decls that would otherwise be lost. */ - extern tree free_lang_decl_chain; - tree free_lang_decl = (tree) ol; - - if (DECL_LANG_SPECIFIC (olddecl) == ol) - abort (); - - TREE_CHAIN (free_lang_decl) = free_lang_decl_chain; - free_lang_decl_chain = free_lang_decl; - } - else - { - /* Storage leak. */; - } - } - } - else - { - bcopy ((char *) newdecl + sizeof (struct tree_common), - (char *) olddecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common) - + tree_code_length [(int)TREE_CODE (newdecl)] * sizeof (char *)); - } - - DECL_UID (olddecl) = olddecl_uid; - if (olddecl_friend) - DECL_FRIEND_P (olddecl) = 1; - - /* NEWDECL contains the merged attribute lists. - Update OLDDECL to be the same. */ - DECL_MACHINE_ATTRIBUTES (olddecl) = DECL_MACHINE_ATTRIBUTES (newdecl); - - return 1; -} - -/* Record a decl-node X as belonging to the current lexical scope. - Check for errors (such as an incompatible declaration for the same - name already seen in the same scope). - - Returns either X or an old decl for the same name. - If an old decl is returned, it may have been smashed - to agree with what X says. */ - -tree -pushdecl (x) - tree x; -{ - register tree t; - register tree name = DECL_ASSEMBLER_NAME (x); - int need_new_binding = 1; - - if (DECL_TEMPLATE_PARM_P (x)) - /* Template parameters have no context; they are not X::T even - when declared within a class or namespace. */ - ; - else - { - if (current_function_decl && x != current_function_decl - /* A local declaration for a function doesn't constitute - nesting. */ - && (TREE_CODE (x) != FUNCTION_DECL || DECL_INITIAL (x)) - /* Don't change DECL_CONTEXT of virtual methods. */ - && (TREE_CODE (x) != FUNCTION_DECL || !DECL_VIRTUAL_P (x)) - && !DECL_CONTEXT (x)) - DECL_CONTEXT (x) = current_function_decl; - if (!DECL_CONTEXT (x)) - DECL_CONTEXT (x) = FROB_CONTEXT (current_namespace); - } - - /* Type are looked up using the DECL_NAME, as that is what the rest of the - compiler wants to use. */ - if (TREE_CODE (x) == TYPE_DECL || TREE_CODE (x) == VAR_DECL - || TREE_CODE (x) == NAMESPACE_DECL || TREE_CODE (x) == TEMPLATE_TYPE_PARM - || TREE_CODE (x) == TEMPLATE_TEMPLATE_PARM) - name = DECL_NAME (x); - - if (name) - { -#if 0 - /* Not needed...see below. */ - char *file; - int line; -#endif - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - name = TREE_OPERAND (name, 0); - - /* Namespace-scoped variables are not found in the current level. */ - if (TREE_CODE (x) == VAR_DECL && DECL_NAMESPACE_SCOPE_P (x)) - t = namespace_binding (name, DECL_CONTEXT (x)); - else - t = lookup_name_current_level (name); - if (t == error_mark_node) - { - /* error_mark_node is 0 for a while during initialization! */ - t = NULL_TREE; - cp_error_at ("`%#D' used prior to declaration", x); - } - - else if (t != NULL_TREE) - { -#if 0 - /* This is turned off until I have time to do it right (bpk). */ - /* With the code below that uses it... */ - file = DECL_SOURCE_FILE (t); - line = DECL_SOURCE_LINE (t); -#endif - if (TREE_CODE (t) == PARM_DECL) - { - if (DECL_CONTEXT (t) == NULL_TREE) - fatal ("parse errors have confused me too much"); - - /* Check for duplicate params. */ - if (duplicate_decls (x, t)) - return t; - } - else if (((TREE_CODE (x) == FUNCTION_DECL && DECL_LANGUAGE (x) == lang_c) - || DECL_FUNCTION_TEMPLATE_P (x)) - && is_overloaded_fn (t)) - /* Don't do anything just yet. */; - else if (t == wchar_decl_node) - { - if (pedantic && ! DECL_IN_SYSTEM_HEADER (x)) - cp_pedwarn ("redeclaration of wchar_t as `%T'", TREE_TYPE (x)); - - /* Throw away the redeclaration. */ - return t; - } - else if (TREE_CODE (t) != TREE_CODE (x)) - { - if (duplicate_decls (x, t)) - return t; - } - else if (duplicate_decls (x, t)) - { -#if 0 - /* This is turned off until I have time to do it right (bpk). */ - - /* Also warn if they did a prototype with `static' on it, but - then later left the `static' off. */ - if (! TREE_PUBLIC (name) && TREE_PUBLIC (x)) - { - if (DECL_LANG_SPECIFIC (t) && DECL_FRIEND_P (t)) - return t; - - if (extra_warnings) - { - cp_warning ("`static' missing from declaration of `%D'", - t); - warning_with_file_and_line (file, line, - "previous declaration of `%s'", - decl_as_string (t, 0)); - } - - /* Now fix things so it'll do what they expect. */ - if (current_function_decl) - TREE_PUBLIC (current_function_decl) = 0; - } - /* Due to interference in memory reclamation (X may be - obstack-deallocated at this point), we must guard against - one really special case. [jason: This should be handled - by start_function] */ - if (current_function_decl == x) - current_function_decl = t; -#endif - if (TREE_CODE (t) == TYPE_DECL) - SET_IDENTIFIER_TYPE_VALUE (name, TREE_TYPE (t)); - else if (TREE_CODE (t) == FUNCTION_DECL) - check_default_args (t); - - return t; - } - else if (DECL_MAIN_P (x)) - { - /* A redeclaration of main, but not a duplicate of the - previous one. - - [basic.start.main] - - This function shall not be overloaded. */ - cp_error_at ("invalid redeclaration of `%D'", t); - cp_error ("as `%D'", x); - /* We don't try to push this declaration since that - causes a crash. */ - return x; - } - } - - check_template_shadow (x); - - /* If this is a function conjured up by the backend, massage it - so it looks friendly. */ - if (TREE_CODE (x) == FUNCTION_DECL - && ! DECL_LANG_SPECIFIC (x)) - { - retrofit_lang_decl (x); - DECL_LANGUAGE (x) = lang_c; - } - - if (TREE_CODE (x) == FUNCTION_DECL && ! DECL_FUNCTION_MEMBER_P (x)) - { - t = push_overloaded_decl (x, PUSH_LOCAL); - if (t != x || DECL_LANGUAGE (x) == lang_c) - return t; - if (!namespace_bindings_p ()) - /* We do not need to create a binding for this name; - push_overloaded_decl will have already done so if - necessary. */ - need_new_binding = 0; - } - else if (DECL_FUNCTION_TEMPLATE_P (x) && DECL_NAMESPACE_SCOPE_P (x)) - return push_overloaded_decl (x, PUSH_GLOBAL); - - /* If declaring a type as a typedef, copy the type (unless we're - at line 0), and install this TYPE_DECL as the new type's typedef - name. See the extensive comment in ../c-decl.c (pushdecl). */ - if (TREE_CODE (x) == TYPE_DECL) - { - tree type = TREE_TYPE (x); - if (DECL_SOURCE_LINE (x) == 0) - { - if (TYPE_NAME (type) == 0) - TYPE_NAME (type) = x; - } - else if (type != error_mark_node && TYPE_NAME (type) != x - /* We don't want to copy the type when all we're - doing is making a TYPE_DECL for the purposes of - inlining. */ - && (!TYPE_NAME (type) - || TYPE_NAME (type) != DECL_ABSTRACT_ORIGIN (x))) - { - push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); - - DECL_ORIGINAL_TYPE (x) = type; - type = build_type_copy (type); - TYPE_STUB_DECL (type) = TYPE_STUB_DECL (DECL_ORIGINAL_TYPE (x)); - TYPE_NAME (type) = x; - TREE_TYPE (x) = type; - - pop_obstacks (); - } - - if (type != error_mark_node - && TYPE_NAME (type) - && TYPE_IDENTIFIER (type)) - set_identifier_type_value_with_scope (DECL_NAME (x), type, - current_binding_level); - - } - - /* Multiple external decls of the same identifier ought to match. - - We get warnings about inline functions where they are defined. - We get warnings about other functions from push_overloaded_decl. - - Avoid duplicate warnings where they are used. */ - if (TREE_PUBLIC (x) && TREE_CODE (x) != FUNCTION_DECL) - { - tree decl; - - if (IDENTIFIER_NAMESPACE_VALUE (name) != NULL_TREE - && (DECL_EXTERNAL (IDENTIFIER_NAMESPACE_VALUE (name)) - || TREE_PUBLIC (IDENTIFIER_NAMESPACE_VALUE (name)))) - decl = IDENTIFIER_NAMESPACE_VALUE (name); - else - decl = NULL_TREE; - - if (decl - /* If different sort of thing, we already gave an error. */ - && TREE_CODE (decl) == TREE_CODE (x) - && !same_type_p (TREE_TYPE (x), TREE_TYPE (decl))) - { - cp_pedwarn ("type mismatch with previous external decl", x); - cp_pedwarn_at ("previous external decl of `%#D'", decl); - } - } - - /* This name is new in its binding level. - Install the new declaration and return it. */ - if (namespace_bindings_p ()) - { - /* Install a global value. */ - - /* If the first global decl has external linkage, - warn if we later see static one. */ - if (IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE && TREE_PUBLIC (x)) - TREE_PUBLIC (name) = 1; - - if (!(TREE_CODE (x) == TYPE_DECL && DECL_ARTIFICIAL (x) - && t != NULL_TREE)) - { - if (TREE_CODE (x) == FUNCTION_DECL) - my_friendly_assert - ((IDENTIFIER_GLOBAL_VALUE (name) == NULL_TREE) - || (IDENTIFIER_GLOBAL_VALUE (name) == x), 378); - SET_IDENTIFIER_NAMESPACE_VALUE (name, x); - } - - /* Don't forget if the function was used via an implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_USED (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_USED (x) = 1; - - /* Don't forget if its address was taken in that way. */ - if (IDENTIFIER_IMPLICIT_DECL (name) - && TREE_ADDRESSABLE (IDENTIFIER_IMPLICIT_DECL (name))) - TREE_ADDRESSABLE (x) = 1; - - /* Warn about mismatches against previous implicit decl. */ - if (IDENTIFIER_IMPLICIT_DECL (name) != NULL_TREE - /* If this real decl matches the implicit, don't complain. */ - && ! (TREE_CODE (x) == FUNCTION_DECL - && TREE_TYPE (TREE_TYPE (x)) == integer_type_node)) - cp_warning - ("`%D' was previously implicitly declared to return `int'", x); - - /* If new decl is `static' and an `extern' was seen previously, - warn about it. */ - if (x != NULL_TREE && t != NULL_TREE && decls_match (x, t)) - warn_extern_redeclared_static (x, t); - } - else - { - /* Here to install a non-global value. */ - tree oldlocal = IDENTIFIER_VALUE (name); - tree oldglobal = IDENTIFIER_NAMESPACE_VALUE (name); - - if (need_new_binding) - { - push_local_binding (name, x, 0); - /* Because push_local_binding will hook X on to the - current_binding_level's name list, we don't want to - do that again below. */ - need_new_binding = 0; - } - - /* If this is a TYPE_DECL, push it into the type value slot. */ - if (TREE_CODE (x) == TYPE_DECL) - set_identifier_type_value_with_scope (name, TREE_TYPE (x), - current_binding_level); - - /* Clear out any TYPE_DECL shadowed by a namespace so that - we won't think this is a type. The C struct hack doesn't - go through namespaces. */ - if (TREE_CODE (x) == NAMESPACE_DECL) - set_identifier_type_value_with_scope (name, NULL_TREE, - current_binding_level); - - /* If this is an extern function declaration, see if we - have a global definition or declaration for the function. */ - if (oldlocal == NULL_TREE - && DECL_EXTERNAL (x) - && oldglobal != NULL_TREE - && TREE_CODE (x) == FUNCTION_DECL - && TREE_CODE (oldglobal) == FUNCTION_DECL) - { - /* We have one. Their types must agree. */ - if (decls_match (x, oldglobal)) - /* OK */; - else - { - cp_warning ("extern declaration of `%#D' doesn't match", x); - cp_warning_at ("global declaration `%#D'", oldglobal); - } - } - /* If we have a local external declaration, - and no file-scope declaration has yet been seen, - then if we later have a file-scope decl it must not be static. */ - if (oldlocal == NULL_TREE - && oldglobal == NULL_TREE - && DECL_EXTERNAL (x) - && TREE_PUBLIC (x)) - TREE_PUBLIC (name) = 1; - - if (DECL_FROM_INLINE (x)) - /* Inline decls shadow nothing. */; - - /* Warn if shadowing an argument at the top level of the body. */ - else if (oldlocal != NULL_TREE && !DECL_EXTERNAL (x) - && TREE_CODE (oldlocal) == PARM_DECL - && TREE_CODE (x) != PARM_DECL) - { - /* Go to where the parms should be and see if we - find them there. */ - struct binding_level *b = current_binding_level->level_chain; - - if (cleanup_label) - b = b->level_chain; - - /* ARM $8.3 */ - if (b->parm_flag == 1) - cp_error ("declaration of `%#D' shadows a parameter", name); - } - else if (warn_shadow && oldlocal != NULL_TREE - && current_binding_level->is_for_scope - && !DECL_DEAD_FOR_LOCAL (oldlocal)) - { - warning ("variable `%s' shadows local", - IDENTIFIER_POINTER (name)); - cp_warning_at (" this is the shadowed declaration", oldlocal); - } - /* Maybe warn if shadowing something else. */ - else if (warn_shadow && !DECL_EXTERNAL (x) - /* No shadow warnings for internally generated vars. */ - && ! DECL_ARTIFICIAL (x) - /* No shadow warnings for vars made for inlining. */ - && ! DECL_FROM_INLINE (x)) - { - char *warnstring = NULL; - - if (oldlocal != NULL_TREE && TREE_CODE (oldlocal) == PARM_DECL) - warnstring = "declaration of `%s' shadows a parameter"; - else if (IDENTIFIER_CLASS_VALUE (name) != NULL_TREE - && current_class_ptr - && !TREE_STATIC (name)) - warnstring = "declaration of `%s' shadows a member of `this'"; - else if (oldlocal != NULL_TREE) - warnstring = "declaration of `%s' shadows previous local"; - else if (oldglobal != NULL_TREE) - /* XXX shadow warnings in outer-more namespaces */ - warnstring = "declaration of `%s' shadows global declaration"; - - if (warnstring) - warning (warnstring, IDENTIFIER_POINTER (name)); - } - } - - if (TREE_CODE (x) == FUNCTION_DECL) - check_default_args (x); - - /* Keep count of variables in this level with incomplete type. */ - if (TREE_CODE (x) == VAR_DECL - && TREE_TYPE (x) != error_mark_node - && ((TYPE_SIZE (TREE_TYPE (x)) == NULL_TREE - && PROMOTES_TO_AGGR_TYPE (TREE_TYPE (x), ARRAY_TYPE)) - /* RTTI TD entries are created while defining the type_info. */ - || (TYPE_LANG_SPECIFIC (TREE_TYPE (x)) - && TYPE_BEING_DEFINED (TREE_TYPE (x))))) - current_binding_level->incomplete - = tree_cons (NULL_TREE, x, current_binding_level->incomplete); - } - - if (need_new_binding) - { - /* Put decls on list in reverse order. - We will reverse them later if necessary. */ - TREE_CHAIN (x) = current_binding_level->names; - current_binding_level->names = x; - if (! (current_binding_level != global_binding_level - || TREE_PERMANENT (x))) - my_friendly_abort (124); - } - - return x; -} - -/* Same as pushdecl, but define X in binding-level LEVEL. We rely on the - caller to set DECL_CONTEXT properly. */ - -static tree -pushdecl_with_scope (x, level) - tree x; - struct binding_level *level; -{ - register struct binding_level *b; - tree function_decl = current_function_decl; - - current_function_decl = NULL_TREE; - if (level->parm_flag == 2) - { - b = class_binding_level; - class_binding_level = level; - pushdecl_class_level (x); - class_binding_level = b; - } - else - { - b = current_binding_level; - current_binding_level = level; - x = pushdecl (x); - current_binding_level = b; - } - current_function_decl = function_decl; - return x; -} - -/* Like pushdecl, only it places X in the current namespace, - if appropriate. */ - -tree -pushdecl_namespace_level (x) - tree x; -{ - register struct binding_level *b = inner_binding_level; - register tree t; - - t = pushdecl_with_scope (x, NAMESPACE_LEVEL (current_namespace)); - - /* Now, the type_shadowed stack may screw us. Munge it so it does - what we want. */ - if (TREE_CODE (x) == TYPE_DECL) - { - tree name = DECL_NAME (x); - tree newval; - tree *ptr = (tree *)0; - for (; b != global_binding_level; b = b->level_chain) - { - tree shadowed = b->type_shadowed; - for (; shadowed; shadowed = TREE_CHAIN (shadowed)) - if (TREE_PURPOSE (shadowed) == name) - { - ptr = &TREE_VALUE (shadowed); - /* Can't break out of the loop here because sometimes - a binding level will have duplicate bindings for - PT names. It's gross, but I haven't time to fix it. */ - } - } - newval = TREE_TYPE (x); - if (ptr == (tree *)0) - { - /* @@ This shouldn't be needed. My test case "zstring.cc" trips - up here if this is changed to an assertion. --KR */ - SET_IDENTIFIER_TYPE_VALUE (name, newval); - } - else - { - *ptr = newval; - } - } - return t; -} - -/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, - if appropriate. */ - -tree -pushdecl_top_level (x) - tree x; -{ - tree cur_namespace = current_namespace; - current_namespace = global_namespace; - x = pushdecl_namespace_level (x); - current_namespace = cur_namespace; - return x; -} - -/* Make the declaration of X appear in CLASS scope. */ - -void -pushdecl_class_level (x) - tree x; -{ - /* Don't use DECL_ASSEMBLER_NAME here! Everything that looks in class - scope looks for the pre-mangled name. */ - register tree name = DECL_NAME (x); - - if (name) - { - if (TYPE_BEING_DEFINED (current_class_type)) - { - /* A name N used in a class S shall refer to the same declaration - in its context and when re-evaluated in the completed scope of S. - Types, enums, and static vars are checked here; other - members are checked in finish_struct. */ - tree icv = IDENTIFIER_CLASS_VALUE (name); - - /* This should match check_member_decl_is_same_in_complete_scope. */ - if (icv && icv != x - && flag_optional_diags - /* Don't complain about inherited names. */ - && id_in_current_class (name) - /* Or shadowed tags. */ - && !(DECL_DECLARES_TYPE_P (icv) - && DECL_CONTEXT (icv) == current_class_type)) - { - cp_pedwarn ("declaration of identifier `%D' as `%#D'", name, x); - cp_pedwarn_at ("conflicts with previous use in class as `%#D'", - icv); - } - - check_template_shadow (x); - } - - push_class_level_binding (name, x); - if (TREE_CODE (x) == TYPE_DECL) - set_identifier_type_value (name, TREE_TYPE (x)); - } -} - -#if 0 -/* This function is used to push the mangled decls for nested types into - the appropriate scope. Previously pushdecl_top_level was used, but that - is incorrect for members of local classes. */ - -void -pushdecl_nonclass_level (x) - tree x; -{ - struct binding_level *b = current_binding_level; - - my_friendly_assert (b->parm_flag != 2, 180); - -#if 0 - /* Get out of template binding levels */ - while (b->pseudo_global) - b = b->level_chain; -#endif - - pushdecl_with_scope (x, b); -} -#endif - -/* Make the declaration(s) of X appear in CLASS scope - under the name NAME. */ - -void -push_class_level_binding (name, x) - tree name; - tree x; -{ - /* The class_binding_level will be NULL if x is a template - parameter name in a member template. */ - if (!class_binding_level) - return; - - /* If this declaration shadows a declaration from an enclosing - class, then we will need to restore IDENTIFIER_CLASS_VALUE when - we leave this class. Record the shadowed declaration here. */ - maybe_push_cache_obstack (); - class_binding_level->class_shadowed - = tree_cons (name, IDENTIFIER_CLASS_VALUE (name), - class_binding_level->class_shadowed); - TREE_TYPE (class_binding_level->class_shadowed) - = x; - pop_obstacks (); - - /* Put the binding on the stack of bindings for the identifier, and - update IDENTIFIER_CLASS_VALUE. */ - push_class_binding (name, x); - - obstack_ptr_grow (&decl_obstack, x); -} - -/* Insert another USING_DECL into the current binding level, - returning this declaration. If this is a redeclaration, - do nothing and return NULL_TREE. */ - -tree -push_using_decl (scope, name) - tree scope; - tree name; -{ - tree decl; - - my_friendly_assert (TREE_CODE (scope) == NAMESPACE_DECL, 383); - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 384); - for (decl = current_binding_level->usings; decl; decl = TREE_CHAIN (decl)) - if (DECL_INITIAL (decl) == scope && DECL_NAME (decl) == name) - break; - if (decl) - return NULL_TREE; - decl = build_lang_decl (USING_DECL, name, void_type_node); - DECL_INITIAL (decl) = scope; - TREE_CHAIN (decl) = current_binding_level->usings; - current_binding_level->usings = decl; - return decl; -} - -/* Add namespace to using_directives. Return NULL_TREE if nothing was - changed (i.e. there was already a directive), or the fresh - TREE_LIST otherwise. */ - -tree -push_using_directive (used) - tree used; -{ - tree ud = current_binding_level->using_directives; - tree iter, ancestor; - - /* Check if we already have this. */ - if (purpose_member (used, ud) != NULL_TREE) - return NULL_TREE; - - /* Recursively add all namespaces used. */ - for (iter = DECL_NAMESPACE_USING (used); iter; iter = TREE_CHAIN (iter)) - push_using_directive (TREE_PURPOSE (iter)); - - ancestor = namespace_ancestor (current_decl_namespace (), used); - ud = current_binding_level->using_directives; - ud = perm_tree_cons (used, ancestor, ud); - current_binding_level->using_directives = ud; - return ud; -} - -/* DECL is a FUNCTION_DECL for a non-member function, which may have - other definitions already in place. We get around this by making - the value of the identifier point to a list of all the things that - want to be referenced by that name. It is then up to the users of - that name to decide what to do with that list. - - DECL may also be a TEMPLATE_DECL, with a FUNCTION_DECL in its DECL_RESULT - slot. It is dealt with the same way. - - FLAGS is a bitwise-or of the following values: - PUSH_LOCAL: Bind DECL in the current scope, rather than at - namespace scope. - PUSH_USING: DECL is being pushed as the result of a using - declaration. - - The value returned may be a previous declaration if we guessed wrong - about what language DECL should belong to (C or C++). Otherwise, - it's always DECL (and never something that's not a _DECL). */ - -tree -push_overloaded_decl (decl, flags) - tree decl; - int flags; -{ - tree name = DECL_NAME (decl); - tree old; - tree new_binding; - int doing_global = (namespace_bindings_p () || !(flags & PUSH_LOCAL)); - - if (doing_global) - { - old = namespace_binding (name, DECL_CONTEXT (decl)); - if (old && TREE_CODE (old) == FUNCTION_DECL - && DECL_ARTIFICIAL (old) - && (DECL_BUILT_IN (old) || DECL_BUILT_IN_NONANSI (old))) - { - if (duplicate_decls (decl, old)) - return old; - old = NULL_TREE; - } - } - else - old = lookup_name_current_level (name); - - if (old) - { - if (TREE_CODE (old) == TYPE_DECL && DECL_ARTIFICIAL (old)) - { - tree t = TREE_TYPE (old); - if (IS_AGGR_TYPE (t) && warn_shadow - && (! DECL_IN_SYSTEM_HEADER (decl) - || ! DECL_IN_SYSTEM_HEADER (old))) - cp_warning ("`%#D' hides constructor for `%#T'", decl, t); - old = NULL_TREE; - } - else if (is_overloaded_fn (old)) - { - tree tmp; - - for (tmp = old; tmp; tmp = OVL_NEXT (tmp)) - { - tree fn = OVL_CURRENT (tmp); - - if (TREE_CODE (tmp) == OVERLOAD && OVL_USED (tmp) - && !(flags & PUSH_USING) - && compparms (TYPE_ARG_TYPES (TREE_TYPE (fn)), - TYPE_ARG_TYPES (TREE_TYPE (decl)))) - cp_error ("`%#D' conflicts with previous using declaration `%#D'", - decl, fn); - - if (duplicate_decls (decl, fn)) - return fn; - } - } - else - { - cp_error_at ("previous non-function declaration `%#D'", old); - cp_error ("conflicts with function declaration `%#D'", decl); - return decl; - } - } - - if (old || TREE_CODE (decl) == TEMPLATE_DECL) - { - if (old && TREE_CODE (old) != OVERLOAD) - new_binding = ovl_cons (decl, ovl_cons (old, NULL_TREE)); - else - new_binding = ovl_cons (decl, old); - if (flags & PUSH_USING) - OVL_USED (new_binding) = 1; - } - else - /* NAME is not ambiguous. */ - new_binding = decl; - - if (doing_global) - set_namespace_binding (name, current_namespace, new_binding); - else - { - /* We only create an OVERLOAD if there was a previous binding at - this level. In that case, we need to remove the old binding - and replace it with the new binding. We must also run - through the NAMES on the binding level where the name was - bound to update the chain. */ - if (TREE_CODE (new_binding) == OVERLOAD) - { - tree *d; - - for (d = &BINDING_LEVEL (IDENTIFIER_BINDING (name))->names; - *d; - d = &TREE_CHAIN (*d)) - if (*d == old - || (TREE_CODE (*d) == TREE_LIST - && TREE_VALUE (*d) == old)) - { - if (TREE_CODE (*d) == TREE_LIST) - /* Just replace the old binding with the new. */ - TREE_VALUE (*d) = new_binding; - else - /* Build a TREE_LIST to wrap the OVERLOAD. */ - *d = build_tree_list (NULL_TREE, new_binding); - - /* And update the CPLUS_BINDING node. */ - BINDING_VALUE (IDENTIFIER_BINDING (name)) - = new_binding; - return decl; - } - - /* We should always find a previous binding in this case. */ - my_friendly_abort (0); - } - - /* Install the new binding. */ - push_local_binding (name, new_binding, flags); - } - - return decl; -} - -/* Generate an implicit declaration for identifier FUNCTIONID - as a function of type int (). Print a warning if appropriate. */ - -tree -implicitly_declare (functionid) - tree functionid; -{ - register tree decl; - int temp = allocation_temporary_p (); - - push_obstacks_nochange (); - - /* Save the decl permanently so we can warn if definition follows. - In ANSI C, warn_implicit is usually false, so the saves little space. - But in C++, it's usually true, hence the extra code. */ - if (temp && (! warn_implicit || toplevel_bindings_p ())) - end_temporary_allocation (); - - /* We used to reuse an old implicit decl here, - but this loses with inline functions because it can clobber - the saved decl chains. */ - decl = build_lang_decl (FUNCTION_DECL, functionid, default_function_type); - - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - /* ANSI standard says implicit declarations are in the innermost block. - So we record the decl in the standard fashion. */ - pushdecl (decl); - rest_of_decl_compilation (decl, NULL_PTR, 0, 0); - - if (warn_implicit - /* Only one warning per identifier. */ - && IDENTIFIER_IMPLICIT_DECL (functionid) == NULL_TREE) - { - cp_pedwarn ("implicit declaration of function `%#D'", decl); - } - - SET_IDENTIFIER_IMPLICIT_DECL (functionid, decl); - - pop_obstacks (); - - return decl; -} - -/* Return zero if the declaration NEWDECL is valid - when the declaration OLDDECL (assumed to be for the same name) - has already been seen. - Otherwise return an error message format string with a %s - where the identifier should go. */ - -static char * -redeclaration_error_message (newdecl, olddecl) - tree newdecl, olddecl; -{ - if (TREE_CODE (newdecl) == TYPE_DECL) - { - /* Because C++ can put things into name space for free, - constructs like "typedef struct foo { ... } foo" - would look like an erroneous redeclaration. */ - if (same_type_p (TREE_TYPE (newdecl), TREE_TYPE (olddecl))) - return 0; - else - return "redefinition of `%#D'"; - } - else if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - /* If this is a pure function, its olddecl will actually be - the original initialization to `0' (which we force to call - abort()). Don't complain about redefinition in this case. */ - if (DECL_LANG_SPECIFIC (olddecl) && DECL_ABSTRACT_VIRTUAL_P (olddecl)) - return 0; - - /* If both functions come from different namespaces, this is not - a redeclaration - this is a conflict with a used function. */ - if (DECL_NAMESPACE_SCOPE_P (olddecl) - && DECL_CONTEXT (olddecl) != DECL_CONTEXT (newdecl)) - return "`%D' conflicts with used function"; - - /* We'll complain about linkage mismatches in - warn_extern_redeclared_static. */ - - /* Defining the same name twice is no good. */ - if (DECL_INITIAL (olddecl) != NULL_TREE - && DECL_INITIAL (newdecl) != NULL_TREE) - { - if (DECL_NAME (olddecl) == NULL_TREE) - return "`%#D' not declared in class"; - else - return "redefinition of `%#D'"; - } - return 0; - } - else if (TREE_CODE (newdecl) == TEMPLATE_DECL) - { - if ((TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == FUNCTION_DECL - && DECL_INITIAL (DECL_TEMPLATE_RESULT (newdecl)) - && DECL_INITIAL (DECL_TEMPLATE_RESULT (olddecl))) - || (TREE_CODE (DECL_TEMPLATE_RESULT (newdecl)) == TYPE_DECL - && TYPE_SIZE (TREE_TYPE (newdecl)) - && TYPE_SIZE (TREE_TYPE (olddecl)))) - return "redefinition of `%#D'"; - return 0; - } - else if (toplevel_bindings_p ()) - { - /* Objects declared at top level: */ - /* If at least one is a reference, it's ok. */ - if (DECL_EXTERNAL (newdecl) || DECL_EXTERNAL (olddecl)) - return 0; - /* Reject two definitions. */ - return "redefinition of `%#D'"; - } - else - { - /* Objects declared with block scope: */ - /* Reject two definitions, and reject a definition - together with an external reference. */ - if (!(DECL_EXTERNAL (newdecl) && DECL_EXTERNAL (olddecl))) - return "redeclaration of `%#D'"; - return 0; - } -} - -/* Get the LABEL_DECL corresponding to identifier ID as a label. - Create one if none exists so far for the current function. - This function is called for both label definitions and label references. */ - -tree -lookup_label (id) - tree id; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (id); - - if (current_function_decl == NULL_TREE) - { - error ("label `%s' referenced outside of any function", - IDENTIFIER_POINTER (id)); - return NULL_TREE; - } - - if ((decl == NULL_TREE - || DECL_SOURCE_LINE (decl) == 0) - && (named_label_uses == NULL - || named_label_uses->names_in_scope != current_binding_level->names - || named_label_uses->label_decl != decl)) - { - struct named_label_list *new_ent; - new_ent - = (struct named_label_list*)oballoc (sizeof (struct named_label_list)); - new_ent->label_decl = decl; - new_ent->names_in_scope = current_binding_level->names; - new_ent->binding_level = current_binding_level; - new_ent->lineno_o_goto = lineno; - new_ent->filename_o_goto = input_filename; - new_ent->next = named_label_uses; - named_label_uses = new_ent; - } - - /* Use a label already defined or ref'd with this name. */ - if (decl != NULL_TREE) - { - /* But not if it is inherited and wasn't declared to be inheritable. */ - if (DECL_CONTEXT (decl) != current_function_decl - && ! C_DECLARED_LABEL_FLAG (decl)) - return shadow_label (id); - return decl; - } - - decl = build_decl (LABEL_DECL, id, void_type_node); - - /* Make sure every label has an rtx. */ - label_rtx (decl); - - /* A label not explicitly declared must be local to where it's ref'd. */ - DECL_CONTEXT (decl) = current_function_decl; - - DECL_MODE (decl) = VOIDmode; - - /* Say where one reference is to the label, - for the sake of the error if it is not defined. */ - DECL_SOURCE_LINE (decl) = lineno; - DECL_SOURCE_FILE (decl) = input_filename; - - SET_IDENTIFIER_LABEL_VALUE (id, decl); - - named_labels = tree_cons (NULL_TREE, decl, named_labels); - named_label_uses->label_decl = decl; - - return decl; -} - -/* Make a label named NAME in the current function, - shadowing silently any that may be inherited from containing functions - or containing scopes. - - Note that valid use, if the label being shadowed - comes from another scope in the same function, - requires calling declare_nonlocal_label right away. */ - -tree -shadow_label (name) - tree name; -{ - register tree decl = IDENTIFIER_LABEL_VALUE (name); - - if (decl != NULL_TREE) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); - } - - return lookup_label (name); -} - -/* Define a label, specifying the location in the source file. - Return the LABEL_DECL node for the label, if the definition is valid. - Otherwise return 0. */ - -tree -define_label (filename, line, name) - char *filename; - int line; - tree name; -{ - tree decl; - - if (minimal_parse_mode) - { - push_obstacks (&permanent_obstack, &permanent_obstack); - decl = build_decl (LABEL_DECL, name, void_type_node); - pop_obstacks (); - DECL_SOURCE_LINE (decl) = line; - DECL_SOURCE_FILE (decl) = filename; - add_tree (decl); - return decl; - } - - decl = lookup_label (name); - - /* After labels, make any new cleanups go into their - own new (temporary) binding contour. */ - current_binding_level->more_cleanups_ok = 0; - - /* If label with this name is known from an outer context, shadow it. */ - if (decl != NULL_TREE && DECL_CONTEXT (decl) != current_function_decl) - { - shadowed_labels = tree_cons (NULL_TREE, decl, shadowed_labels); - SET_IDENTIFIER_LABEL_VALUE (name, NULL_TREE); - decl = lookup_label (name); - } - - if (name == get_identifier ("wchar_t")) - cp_pedwarn ("label named wchar_t"); - - if (DECL_INITIAL (decl) != NULL_TREE) - { - cp_error ("duplicate label `%D'", decl); - return 0; - } - else - { - struct named_label_list *uses, *prev; - int identified = 0; - - /* Mark label as having been defined. */ - DECL_INITIAL (decl) = error_mark_node; - /* Say where in the source. */ - DECL_SOURCE_FILE (decl) = filename; - DECL_SOURCE_LINE (decl) = line; - - prev = NULL; - uses = named_label_uses; - while (uses != NULL) - if (uses->label_decl == decl) - { - struct binding_level *b = current_binding_level; - while (b) - { - tree new_decls = b->names; - tree old_decls = (b == uses->binding_level) - ? uses->names_in_scope : NULL_TREE; - while (new_decls != old_decls) - { - if (TREE_CODE (new_decls) == VAR_DECL - /* Don't complain about crossing initialization - of internal entities. They can't be accessed, - and they should be cleaned up - by the time we get to the label. */ - && ! DECL_ARTIFICIAL (new_decls) - && !(DECL_INITIAL (new_decls) == NULL_TREE - && pod_type_p (TREE_TYPE (new_decls)))) - { - if (! identified) - { - cp_error ("jump to label `%D'", decl); - error_with_file_and_line (uses->filename_o_goto, - uses->lineno_o_goto, - " from here"); - identified = 1; - } - if (DECL_INITIAL (new_decls) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls))) - cp_error_at (" crosses initialization of `%#D'", - new_decls); - else - cp_error_at (" enters scope of non-POD `%#D'", - new_decls); - } - new_decls = TREE_CHAIN (new_decls); - } - if (b == uses->binding_level) - break; - b = b->level_chain; - } - - if (prev != NULL) - prev->next = uses->next; - else - named_label_uses = uses->next; - - uses = uses->next; - } - else - { - prev = uses; - uses = uses->next; - } - current_function_return_value = NULL_TREE; - return decl; - } -} - -struct cp_switch -{ - struct binding_level *level; - struct cp_switch *next; -}; - -static struct cp_switch *switch_stack; - -void -push_switch () -{ - struct cp_switch *p - = (struct cp_switch *) oballoc (sizeof (struct cp_switch)); - p->level = current_binding_level; - p->next = switch_stack; - switch_stack = p; -} - -void -pop_switch () -{ - switch_stack = switch_stack->next; -} - -/* Same, but for CASE labels. If DECL is NULL_TREE, it's the default. */ -/* XXX Note decl is never actually used. (bpk) */ - -void -define_case_label () -{ - tree cleanup = last_cleanup_this_contour (); - struct binding_level *b = current_binding_level; - int identified = 0; - - if (cleanup) - { - static int explained = 0; - cp_warning_at ("destructor needed for `%#D'", TREE_PURPOSE (cleanup)); - warning ("where case label appears here"); - if (!explained) - { - warning ("(enclose actions of previous case statements requiring"); - warning ("destructors in their own binding contours.)"); - explained = 1; - } - } - - for (; b && b != switch_stack->level; b = b->level_chain) - { - tree new_decls = b->names; - for (; new_decls; new_decls = TREE_CHAIN (new_decls)) - { - if (TREE_CODE (new_decls) == VAR_DECL - /* Don't complain about crossing initialization - of internal entities. They can't be accessed, - and they should be cleaned up - by the time we get to the label. */ - && ! DECL_ARTIFICIAL (new_decls) - && ((DECL_INITIAL (new_decls) != NULL_TREE - && DECL_INITIAL (new_decls) != error_mark_node) - || TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (new_decls)))) - { - if (! identified) - error ("jump to case label"); - identified = 1; - cp_error_at (" crosses initialization of `%#D'", - new_decls); - } - } - } - - /* After labels, make any new cleanups go into their - own new (temporary) binding contour. */ - - current_binding_level->more_cleanups_ok = 0; - current_function_return_value = NULL_TREE; -} - -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls () -{ - return current_binding_level->names; -} - -/* Return the list of type-tags (for structs, etc) of the current level. */ - -tree -gettags () -{ - return current_binding_level->tags; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static void -storedecls (decls) - tree decls; -{ - current_binding_level->names = decls; -} - -/* Similarly, store the list of tags of the current level. */ - -static void -storetags (tags) - tree tags; -{ - current_binding_level->tags = tags; -} - -/* Given NAME, an IDENTIFIER_NODE, - return the structure (or union or enum) definition for that name. - Searches binding levels from BINDING_LEVEL up to the global level. - If THISLEVEL_ONLY is nonzero, searches only the specified context - (but skips any tag-transparent contexts to find one that is - meaningful for tags). - FORM says which kind of type the caller wants; - it is RECORD_TYPE or UNION_TYPE or ENUMERAL_TYPE. - If the wrong kind of type is found, and it's not a template, an error is - reported. */ - -static tree -lookup_tag (form, name, binding_level, thislevel_only) - enum tree_code form; - tree name; - struct binding_level *binding_level; - int thislevel_only; -{ - register struct binding_level *level; - /* Non-zero if, we should look past a pseudo-global level, even if - THISLEVEL_ONLY. */ - int allow_pseudo_global = 1; - - for (level = binding_level; level; level = level->level_chain) - { - register tree tail; - if (ANON_AGGRNAME_P (name)) - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - /* There's no need for error checking here, because - anon names are unique throughout the compilation. */ - if (TYPE_IDENTIFIER (TREE_VALUE (tail)) == name) - return TREE_VALUE (tail); - } - else if (level->namespace_p) - /* Do namespace lookup. */ - for (tail = current_namespace; 1; tail = CP_DECL_CONTEXT (tail)) - { - tree old = binding_for_name (name, tail); - - /* If we just skipped past a pseudo global level, even - though THISLEVEL_ONLY, and we find a template class - declaration, then we use the _TYPE node for the - template. See the example below. */ - if (thislevel_only && !allow_pseudo_global - && old && BINDING_VALUE (old) - && DECL_CLASS_TEMPLATE_P (BINDING_VALUE (old))) - old = TREE_TYPE (BINDING_VALUE (old)); - else - old = BINDING_TYPE (old); - - /* If it has an original type, it is a typedef, and we - should not return it. */ - if (old && DECL_ORIGINAL_TYPE (TYPE_NAME (old))) - old = NULL_TREE; - if (old && TREE_CODE (old) != form - && !(form != ENUMERAL_TYPE && TREE_CODE (old) == TEMPLATE_DECL)) - { - cp_error ("`%#D' redeclared as %C", old, form); - return NULL_TREE; - } - if (old) - return old; - if (thislevel_only || tail == global_namespace) - return NULL_TREE; - } - else - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_PURPOSE (tail) == name) - { - enum tree_code code = TREE_CODE (TREE_VALUE (tail)); - /* Should tighten this up; it'll probably permit - UNION_TYPE and a struct template, for example. */ - if (code != form - && !(form != ENUMERAL_TYPE && code == TEMPLATE_DECL)) - { - /* Definition isn't the kind we were looking for. */ - cp_error ("`%#D' redeclared as %C", TREE_VALUE (tail), - form); - return NULL_TREE; - } - return TREE_VALUE (tail); - } - } - if (thislevel_only && ! level->tag_transparent) - { - if (level->pseudo_global && allow_pseudo_global) - { - /* We must deal with cases like this: - - template <class T> struct S; - template <class T> struct S {}; - - When looking up `S', for the second declaration, we - would like to find the first declaration. But, we - are in the pseudo-global level created for the - template parameters, rather than the (surrounding) - namespace level. Thus, we keep going one more level, - even though THISLEVEL_ONLY is non-zero. */ - allow_pseudo_global = 0; - continue; - } - else - return NULL_TREE; - } - if (current_class_type && level->level_chain->namespace_p) - { - /* Try looking in this class's tags before heading into - global binding level. */ - tree context = current_class_type; - while (context) - { - switch (TREE_CODE_CLASS (TREE_CODE (context))) - { - tree these_tags; - case 't': - these_tags = CLASSTYPE_TAGS (context); - if (ANON_AGGRNAME_P (name)) - while (these_tags) - { - if (TYPE_IDENTIFIER (TREE_VALUE (these_tags)) - == name) - return TREE_VALUE (tail); - these_tags = TREE_CHAIN (these_tags); - } - else - while (these_tags) - { - if (TREE_PURPOSE (these_tags) == name) - { - if (TREE_CODE (TREE_VALUE (these_tags)) != form) - { - cp_error ("`%#D' redeclared as %C in class scope", - TREE_VALUE (tail), form); - return NULL_TREE; - } - return TREE_VALUE (tail); - } - these_tags = TREE_CHAIN (these_tags); - } - /* If this type is not yet complete, then don't - look at its context. */ - if (TYPE_SIZE (context) == NULL_TREE) - goto no_context; - /* Go to next enclosing type, if any. */ - context = DECL_CONTEXT (TYPE_MAIN_DECL (context)); - break; - case 'd': - context = DECL_CONTEXT (context); - break; - default: - my_friendly_abort (10); - } - continue; - no_context: - break; - } - } - } - return NULL_TREE; -} - -#if 0 -void -set_current_level_tags_transparency (tags_transparent) - int tags_transparent; -{ - current_binding_level->tag_transparent = tags_transparent; -} -#endif - -/* Given a type, find the tag that was defined for it and return the tag name. - Otherwise return 0. However, the value can never be 0 - in the cases in which this is used. - - C++: If NAME is non-zero, this is the new name to install. This is - done when replacing anonymous tags with real tag names. */ - -static tree -lookup_tag_reverse (type, name) - tree type; - tree name; -{ - register struct binding_level *level; - - for (level = current_binding_level; level; level = level->level_chain) - { - register tree tail; - for (tail = level->tags; tail; tail = TREE_CHAIN (tail)) - { - if (TREE_VALUE (tail) == type) - { - if (name) - TREE_PURPOSE (tail) = name; - return TREE_PURPOSE (tail); - } - } - } - return NULL_TREE; -} - -/* Lookup TYPE in CONTEXT (a chain of nested types or a FUNCTION_DECL). - Return the type value, or NULL_TREE if not found. */ - -static tree -lookup_nested_type (type, context) - tree type; - tree context; -{ - if (context == NULL_TREE) - return NULL_TREE; - while (context) - { - switch (TREE_CODE (context)) - { - case TYPE_DECL: - { - tree ctype = TREE_TYPE (context); - tree match = value_member (type, CLASSTYPE_TAGS (ctype)); - if (match) - return TREE_VALUE (match); - context = DECL_CONTEXT (context); - - /* When we have a nested class whose member functions have - local types (e.g., a set of enums), we'll arrive here - with the DECL_CONTEXT as the actual RECORD_TYPE node for - the enclosing class. Instead, we want to make sure we - come back in here with the TYPE_DECL, not the RECORD_TYPE. */ - if (context && TREE_CODE (context) == RECORD_TYPE) - context = TREE_CHAIN (context); - } - break; - case FUNCTION_DECL: - if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) - return lookup_name (TYPE_IDENTIFIER (type), 1); - return NULL_TREE; - default: - my_friendly_abort (12); - } - } - return NULL_TREE; -} - -/* Look up NAME in the NAMESPACE. */ - -tree -lookup_namespace_name (namespace, name) - tree namespace, name; -{ - struct tree_binding _b; - tree val; - - my_friendly_assert (TREE_CODE (namespace) == NAMESPACE_DECL, 370); - - if (TREE_CODE (name) == NAMESPACE_DECL) - /* This happens for A::B<int> when B is a namespace. */ - return name; - else if (TREE_CODE (name) == TEMPLATE_DECL) - { - /* This happens for A::B where B is a template, and there are no - template arguments. */ - cp_error ("invalid use of `%D'", name); - return error_mark_node; - } - - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 373); - - val = binding_init (&_b); - if (!qualified_lookup_using_namespace (name, namespace, val, 0)) - return error_mark_node; - - if (BINDING_VALUE (val)) - { - val = BINDING_VALUE (val); - - /* If we have a single function from a using decl, pull it out. */ - if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) - val = OVL_FUNCTION (val); - return val; - } - - cp_error ("`%D' undeclared in namespace `%D'", name, namespace); - return error_mark_node; -} - -/* Hash a TYPENAME_TYPE. K is really of type `tree'. */ - -static unsigned long -typename_hash (k) - hash_table_key k; -{ - unsigned long hash; - tree t; - - t = (tree) k; - hash = (((unsigned long) TYPE_CONTEXT (t)) - ^ ((unsigned long) DECL_NAME (TYPE_NAME (t)))); - - return hash; -} - -/* Compare two TYPENAME_TYPEs. K1 and K2 are really of type `tree'. */ - -static boolean -typename_compare (k1, k2) - hash_table_key k1; - hash_table_key k2; -{ - tree t1; - tree t2; - tree d1; - tree d2; - - t1 = (tree) k1; - t2 = (tree) k2; - d1 = TYPE_NAME (t1); - d2 = TYPE_NAME (t2); - - return (DECL_NAME (d1) == DECL_NAME (d2) - && same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)) - && ((TREE_TYPE (t1) != NULL_TREE) - == (TREE_TYPE (t2) != NULL_TREE)) - && same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - && TYPENAME_TYPE_FULLNAME (t1) == TYPENAME_TYPE_FULLNAME (t2)); -} - -/* Build a TYPENAME_TYPE. If the type is `typename T::t', CONTEXT is - the type of `T', NAME is the IDENTIFIER_NODE for `t'. If BASE_TYPE - is non-NULL, this type is being created by the implicit typename - extension, and BASE_TYPE is a type named `t' in some base class of - `T' which depends on template parameters. - - Returns the new TYPENAME_TYPE. */ - -tree -build_typename_type (context, name, fullname, base_type) - tree context; - tree name; - tree fullname; - tree base_type; -{ - tree t; - tree d; - struct hash_entry* e; - - static struct hash_table ht; - - push_obstacks (&permanent_obstack, &permanent_obstack); - - if (!ht.table - && !hash_table_init (&ht, &hash_newfunc, &typename_hash, - &typename_compare)) - fatal ("virtual memory exhausted"); - - /* Build the TYPENAME_TYPE. */ - t = make_lang_type (TYPENAME_TYPE); - TYPE_CONTEXT (t) = FROB_CONTEXT (context); - TYPENAME_TYPE_FULLNAME (t) = fullname; - TREE_TYPE (t) = base_type; - - /* Build the corresponding TYPE_DECL. */ - d = build_decl (TYPE_DECL, name, t); - TYPE_NAME (TREE_TYPE (d)) = d; - TYPE_STUB_DECL (TREE_TYPE (d)) = d; - DECL_CONTEXT (d) = FROB_CONTEXT (context); - DECL_ARTIFICIAL (d) = 1; - - /* See if we already have this type. */ - e = hash_lookup (&ht, t, /*create=*/false, /*copy=*/0); - if (e) - { - /* This will free not only TREE_TYPE, but the lang-specific data - and the TYPE_DECL as well. */ - obstack_free (&permanent_obstack, t); - t = (tree) e->key; - } - else - /* Insert the type into the table. */ - hash_lookup (&ht, t, /*create=*/true, /*copy=*/0); - - pop_obstacks (); - - return t; -} - -tree -make_typename_type (context, name) - tree context, name; -{ - tree t; - tree fullname; - - if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') - name = TYPE_IDENTIFIER (name); - else if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - fullname = name; - - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - name = TREE_OPERAND (name, 0); - if (TREE_CODE (name) == TEMPLATE_DECL) - name = TREE_OPERAND (fullname, 0) = DECL_NAME (name); - } - if (TREE_CODE (name) != IDENTIFIER_NODE) - my_friendly_abort (2000); - - if (TREE_CODE (context) == NAMESPACE_DECL) - { - /* We can get here from typename_sub0 in the explicit_template_type - expansion. Just fail. */ - cp_error ("no class template named `%#T' in `%#T'", - name, context); - return error_mark_node; - } - - if (! uses_template_parms (context) - || currently_open_class (context)) - { - if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR) - { - if (IS_AGGR_TYPE (context)) - t = lookup_field (context, name, 0, 0); - else - t = NULL_TREE; - - if (t == NULL_TREE || TREE_CODE (t) != TEMPLATE_DECL - || TREE_CODE (DECL_RESULT (t)) != TYPE_DECL) - { - cp_error ("no class template named `%#T' in `%#T'", - name, context); - return error_mark_node; - } - - return lookup_template_class (t, TREE_OPERAND (fullname, 1), - NULL_TREE, context, - /*entering_scope=*/0); - } - else - { - if (IS_AGGR_TYPE (context)) - t = lookup_field (context, name, 0, 1); - else - t = NULL_TREE; - - if (t == NULL_TREE) - { - cp_error ("no type named `%#T' in `%#T'", name, context); - return error_mark_node; - } - - return TREE_TYPE (t); - } - } - - return build_typename_type (context, name, fullname, NULL_TREE); -} - -/* Select the right _DECL from multiple choices. */ - -static tree -select_decl (binding, flags) - tree binding; - int flags; -{ - tree val; - val = BINDING_VALUE (binding); - if (LOOKUP_NAMESPACES_ONLY (flags)) - { - /* We are not interested in types. */ - if (val && TREE_CODE (val) == NAMESPACE_DECL) - return val; - return NULL_TREE; - } - - /* If we could have a type and - we have nothing or we need a type and have none. */ - if (BINDING_TYPE (binding) - && (!val || ((flags & LOOKUP_PREFER_TYPES) - && TREE_CODE (val) != TYPE_DECL))) - val = TYPE_STUB_DECL (BINDING_TYPE (binding)); - /* Don't return non-types if we really prefer types. */ - else if (val && LOOKUP_TYPES_ONLY (flags) && TREE_CODE (val) != TYPE_DECL - && (!looking_for_template || TREE_CODE (val) != TEMPLATE_DECL)) - val = NULL_TREE; - - return val; -} - -/* Unscoped lookup of a global, iterate over namespaces, considering - using namespace statements. */ - -static tree -unqualified_namespace_lookup (name, flags) - tree name; - int flags; -{ - struct tree_binding _binding; - tree b = binding_init (&_binding); - tree initial = current_decl_namespace(); - tree scope = initial; - tree siter; - struct binding_level *level; - tree val = NULL_TREE; - - while (!val) - { - val = binding_for_name (name, scope); - - /* Initialize binding for this context. */ - BINDING_VALUE (b) = BINDING_VALUE (val); - BINDING_TYPE (b) = BINDING_TYPE (val); - - /* Add all _DECLs seen through local using-directives. */ - for (level = current_binding_level; - !level->namespace_p; - level = level->level_chain) - if (!lookup_using_namespace (name, b, level->using_directives, - scope, flags)) - /* Give up because of error. */ - return NULL_TREE; - - /* Add all _DECLs seen through global using-directives. */ - /* XXX local and global using lists should work equally. */ - siter = initial; - while (1) - { - if (!lookup_using_namespace (name, b, DECL_NAMESPACE_USING (siter), - scope, flags)) - /* Give up because of error. */ - return NULL_TREE; - if (siter == scope) break; - siter = CP_DECL_CONTEXT (siter); - } - - val = select_decl (b, flags); - if (scope == global_namespace) - break; - scope = CP_DECL_CONTEXT (scope); - } - return val; -} - -/* Combine prefer_type and namespaces_only into flags. */ - -static int -lookup_flags (prefer_type, namespaces_only) - int prefer_type, namespaces_only; -{ - if (namespaces_only) - return LOOKUP_PREFER_NAMESPACES; - if (prefer_type > 1) - return LOOKUP_PREFER_TYPES; - if (prefer_type > 0) - return LOOKUP_PREFER_BOTH; - return 0; -} - -/* Given a lookup that returned VAL, use FLAGS to decide if we want to - ignore it or not. Subroutine of lookup_name_real. */ - -static tree -qualify_lookup (val, flags) - tree val; - int flags; -{ - if (val == NULL_TREE) - return val; - if ((flags & LOOKUP_PREFER_NAMESPACES) && TREE_CODE (val) == NAMESPACE_DECL) - return val; - if ((flags & LOOKUP_PREFER_TYPES) - && (TREE_CODE (val) == TYPE_DECL - || ((flags & LOOKUP_TEMPLATES_EXPECTED) - && DECL_CLASS_TEMPLATE_P (val)))) - return val; - if (flags & (LOOKUP_PREFER_NAMESPACES | LOOKUP_PREFER_TYPES)) - return NULL_TREE; - return val; -} - -/* Look up NAME in the current binding level and its superiors in the - namespace of variables, functions and typedefs. Return a ..._DECL - node of some kind representing its definition if there is only one - such declaration, or return a TREE_LIST with all the overloaded - definitions if there are many, or return 0 if it is undefined. - - If PREFER_TYPE is > 0, we prefer TYPE_DECLs or namespaces. - If PREFER_TYPE is > 1, we reject non-type decls (e.g. namespaces). - If PREFER_TYPE is -2, we're being called from yylex(). (UGLY) - Otherwise we prefer non-TYPE_DECLs. - - If NONCLASS is non-zero, we don't look for the NAME in class scope, - using IDENTIFIER_CLASS_VALUE. */ - -static tree -lookup_name_real (name, prefer_type, nonclass, namespaces_only) - tree name; - int prefer_type, nonclass, namespaces_only; -{ - register tree val; - int yylex = 0; - tree from_obj = NULL_TREE; - int flags; - - /* Hack: copy flag set by parser, if set. */ - if (only_namespace_names) - namespaces_only = 1; - - if (prefer_type == -2) - { - extern int looking_for_typename; - tree type = NULL_TREE; - - yylex = 1; - prefer_type = looking_for_typename; - - flags = lookup_flags (prefer_type, namespaces_only); - /* During parsing, we need to complain. */ - flags |= LOOKUP_COMPLAIN; - /* If the next thing is '<', class templates are types. */ - if (looking_for_template) - flags |= LOOKUP_TEMPLATES_EXPECTED; - - /* std:: becomes :: for now. */ - if (got_scope == std_node) - got_scope = void_type_node; - - if (got_scope) - type = got_scope; - else if (got_object != error_mark_node) - type = got_object; - - if (type) - { - if (type == error_mark_node) - return error_mark_node; - if (TREE_CODE (type) == TYPENAME_TYPE && TREE_TYPE (type)) - type = TREE_TYPE (type); - - if (TYPE_P (type)) - type = complete_type (type); - - if (TREE_CODE (type) == VOID_TYPE) - type = global_namespace; - if (TREE_CODE (type) == NAMESPACE_DECL) - { - struct tree_binding b; - val = binding_init (&b); - if (!qualified_lookup_using_namespace (name, type, val, flags)) - return NULL_TREE; - val = select_decl (val, flags); - } - else if (! IS_AGGR_TYPE (type) - || TREE_CODE (type) == TEMPLATE_TYPE_PARM - || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM - || TREE_CODE (type) == TYPENAME_TYPE) - /* Someone else will give an error about this if needed. */ - val = NULL_TREE; - else if (TYPE_BEING_DEFINED (type)) - { - val = IDENTIFIER_CLASS_VALUE (name); - if (val && DECL_CONTEXT (val) != type) - { - struct binding_level *b = class_binding_level; - for (val = NULL_TREE; b; b = b->level_chain) - { - tree t = purpose_member (name, b->class_shadowed); - if (t && TREE_VALUE (t) - && DECL_CONTEXT (TREE_VALUE (t)) == type) - { - val = TREE_VALUE (t); - break; - } - } - } - if (val == NULL_TREE) - val = lookup_field (type, name, 0, 1); - } - else if (type == current_class_type) - val = IDENTIFIER_CLASS_VALUE (name); - else - val = lookup_member (type, name, 0, prefer_type); - } - else - val = NULL_TREE; - - if (got_scope) - goto done; - else if (got_object && val) - from_obj = val; - } - else - flags = lookup_flags (prefer_type, namespaces_only); - - /* First, look in non-namespace scopes. */ - for (val = IDENTIFIER_BINDING (name); val; val = TREE_CHAIN (val)) - { - if (!LOCAL_BINDING_P (val) && nonclass) - /* We're not looking for class-scoped bindings, so keep going. */ - continue; - - /* If this is the kind of thing we're looking for, we're done. */ - if (qualify_lookup (BINDING_VALUE (val), flags)) - { - val = BINDING_VALUE (val); - break; - } - else if ((flags & LOOKUP_PREFER_TYPES) - && qualify_lookup (BINDING_TYPE (val), flags)) - { - val = BINDING_TYPE (val); - break; - } - } - - /* If VAL is a type from a dependent base, we're not really supposed - to be able to see it; the fact that we can is the "implicit - typename" extension. We call lookup_field here to turn VAL into - a TYPE_DECL for a TYPENAME_TYPE. */ - if (processing_template_decl && val - && val == IDENTIFIER_CLASS_VALUE (name) - && TREE_CODE (val) == TYPE_DECL - && !currently_open_class (DECL_CONTEXT (val)) - && uses_template_parms (current_class_type)) - val = lookup_field (current_class_type, name, 0, 1); - - /* We don't put names from baseclasses onto the IDENTIFIER_BINDING - list when we're defining a type. It would probably be simpler to - do this, but we don't. So, we must lookup names from base - classes explicitly. */ - if (!val && !nonclass - && current_class_type && TYPE_BEING_DEFINED (current_class_type)) - { - val = qualify_lookup (lookup_field (current_class_type, name, 0, 0), - flags); - if (!val) - val = qualify_lookup (lookup_nested_field (name, !yylex), - flags); - } - - /* If we found a type from a dependent base class (using the - implicit typename extension) make sure that there's not some - global name which should be chosen instead. */ - if (val && TREE_CODE (val) == TYPE_DECL - && IMPLICIT_TYPENAME_P (TREE_TYPE (val))) - { - tree global_val; - - /* Any other name takes precedence over an implicit typename. Warn the - user about this potentially confusing lookup. */ - global_val = unqualified_namespace_lookup (name, flags); - - if (global_val) - { - tree subtype; - - /* Only warn when not lexing; we don't want to warn if they - use this name as a declarator. */ - subtype = TREE_TYPE (TREE_TYPE (val)); - if (! yylex - && ! (TREE_CODE (global_val) == TEMPLATE_DECL - && CLASSTYPE_TEMPLATE_INFO (subtype) - && CLASSTYPE_TI_TEMPLATE (subtype) == global_val) - && ! (TREE_CODE (global_val) == TYPE_DECL - && same_type_p (TREE_TYPE (global_val), subtype))) - { - cp_warning ("lookup of `%D' finds `%#D'", name, global_val); - cp_warning (" instead of `%D' from dependent base class", - val); - cp_warning (" (use `typename %T::%D' if that's what you meant)", - constructor_name (current_class_type), name); - } - - /* Use the global value instead of the implicit typename. */ - val = global_val; - } - } - else if (!val) - /* No local, or class-scoped binding. Look for a namespace-scope - declaration. */ - val = unqualified_namespace_lookup (name, flags); - - done: - if (val) - { - /* This should only warn about types used in qualified-ids. */ - if (from_obj && from_obj != val) - { - if (looking_for_typename && TREE_CODE (from_obj) == TYPE_DECL - && TREE_CODE (val) == TYPE_DECL - && TREE_TYPE (from_obj) != TREE_TYPE (val)) - { - cp_pedwarn ("lookup of `%D' in the scope of `%#T' (`%#T')", - name, got_object, TREE_TYPE (from_obj)); - cp_pedwarn (" does not match lookup in the current scope (`%#T')", - TREE_TYPE (val)); - } - - /* We don't change val to from_obj if got_object depends on - template parms because that breaks implicit typename for - destructor calls. */ - if (! uses_template_parms (got_object)) - val = from_obj; - } - - /* If we have a single function from a using decl, pull it out. */ - if (TREE_CODE (val) == OVERLOAD && ! really_overloaded_fn (val)) - val = OVL_FUNCTION (val); - } - else if (from_obj) - val = from_obj; - - return val; -} - -tree -lookup_name_nonclass (name) - tree name; -{ - return lookup_name_real (name, 0, 1, 0); -} - -tree -lookup_function_nonclass (name, args) - tree name; - tree args; -{ - return lookup_arg_dependent (name, lookup_name_nonclass (name), args); -} - -tree -lookup_name_namespace_only (name) - tree name; -{ - /* type-or-namespace, nonclass, namespace_only */ - return lookup_name_real (name, 1, 1, 1); -} - -tree -lookup_name (name, prefer_type) - tree name; - int prefer_type; -{ - return lookup_name_real (name, prefer_type, 0, 0); -} - -/* Similar to `lookup_name' but look only at current binding level. */ - -tree -lookup_name_current_level (name) - tree name; -{ - register tree t = NULL_TREE; - - if (current_binding_level->namespace_p) - { - t = IDENTIFIER_NAMESPACE_VALUE (name); - - /* extern "C" function() */ - if (t != NULL_TREE && TREE_CODE (t) == TREE_LIST) - t = TREE_VALUE (t); - } - else if (IDENTIFIER_BINDING (name) - && LOCAL_BINDING_P (IDENTIFIER_BINDING (name))) - { - struct binding_level *b = current_binding_level; - - while (1) - { - if (BINDING_LEVEL (IDENTIFIER_BINDING (name)) == b) - return IDENTIFIER_VALUE (name); - - if (b->keep == 2) - b = b->level_chain; - else - break; - } - } - - return t; -} - -/* Like lookup_name_current_level, but for types. */ - -tree -lookup_type_current_level (name) - tree name; -{ - register tree t = NULL_TREE; - - my_friendly_assert (! current_binding_level->namespace_p, 980716); - - if (REAL_IDENTIFIER_TYPE_VALUE (name) != NULL_TREE - && REAL_IDENTIFIER_TYPE_VALUE (name) != global_type_node) - { - struct binding_level *b = current_binding_level; - while (1) - { - if (purpose_member (name, b->type_shadowed)) - return REAL_IDENTIFIER_TYPE_VALUE (name); - if (b->keep == 2) - b = b->level_chain; - else - break; - } - } - - return t; -} - -void -begin_only_namespace_names () -{ - only_namespace_names = 1; -} - -void -end_only_namespace_names () -{ - only_namespace_names = 0; -} - -/* Arrange for the user to get a source line number, even when the - compiler is going down in flames, so that she at least has a - chance of working around problems in the compiler. We used to - call error(), but that let the segmentation fault continue - through; now, it's much more passive by asking them to send the - maintainers mail about the problem. */ - -static void -signal_catch (sig) - int sig ATTRIBUTE_UNUSED; -{ - signal (SIGSEGV, SIG_DFL); -#ifdef SIGIOT - signal (SIGIOT, SIG_DFL); -#endif -#ifdef SIGILL - signal (SIGILL, SIG_DFL); -#endif -#ifdef SIGABRT - signal (SIGABRT, SIG_DFL); -#endif -#ifdef SIGBUS - signal (SIGBUS, SIG_DFL); -#endif - my_friendly_abort (0); -} - -#if 0 -/* Unused -- brendan 970107 */ -/* Array for holding types considered "built-in". These types - are output in the module in which `main' is defined. */ -static tree *builtin_type_tdescs_arr; -static int builtin_type_tdescs_len, builtin_type_tdescs_max; -#endif - -/* Push the declarations of builtin types into the namespace. - RID_INDEX, if < RID_MAX is the index of the builtin type - in the array RID_POINTERS. NAME is the name used when looking - up the builtin type. TYPE is the _TYPE node for the builtin type. */ - -static void -record_builtin_type (rid_index, name, type) - enum rid rid_index; - char *name; - tree type; -{ - tree rname = NULL_TREE, tname = NULL_TREE; - tree tdecl = NULL_TREE; - - if ((int) rid_index < (int) RID_MAX) - rname = ridpointers[(int) rid_index]; - if (name) - tname = get_identifier (name); - - TYPE_BUILT_IN (type) = 1; - - if (tname) - { - tdecl = pushdecl (build_decl (TYPE_DECL, tname, type)); - set_identifier_type_value (tname, NULL_TREE); - if ((int) rid_index < (int) RID_MAX) - /* Built-in types live in the global namespace. */ - SET_IDENTIFIER_GLOBAL_VALUE (tname, tdecl); - } - if (rname != NULL_TREE) - { - if (tname != NULL_TREE) - { - set_identifier_type_value (rname, NULL_TREE); - SET_IDENTIFIER_GLOBAL_VALUE (rname, tdecl); - } - else - { - tdecl = pushdecl (build_decl (TYPE_DECL, rname, type)); - set_identifier_type_value (rname, NULL_TREE); - } - } -} - -/* Record one of the standard Java types. - * Declare it as having the given NAME. - * If SIZE > 0, it is the size of one of the integral types; - * otherwise it is the negative of the size of one of the other types. */ - -static tree -record_builtin_java_type (name, size) - char *name; - int size; -{ - tree type, decl; - if (size > 0) - type = make_signed_type (size); - else if (size > -32) - { /* "__java_char" or ""__java_boolean". */ - type = make_unsigned_type (-size); - /*if (size == -1) TREE_SET_CODE (type, BOOLEAN_TYPE);*/ - } - else - { /* "__java_float" or ""__java_double". */ - type = make_node (REAL_TYPE); - TYPE_PRECISION (type) = - size; - layout_type (type); - } - record_builtin_type (RID_MAX, name, type); - decl = TYPE_NAME (type); - DECL_IGNORED_P (decl) = 1; - TYPE_FOR_JAVA (type) = 1; - return type; -} - -/* Push a type into the namespace so that the back-ends ignore it. */ - -static void -record_unknown_type (type, name) - tree type; - char *name; -{ - tree decl = pushdecl (build_decl (TYPE_DECL, get_identifier (name), type)); - /* Make sure the "unknown type" typedecl gets ignored for debug info. */ - DECL_IGNORED_P (decl) = 1; - TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; - TYPE_SIZE (type) = TYPE_SIZE (void_type_node); - TYPE_ALIGN (type) = 1; - TYPE_MODE (type) = TYPE_MODE (void_type_node); -} - -/* Push overloaded decl, in global scope, with one argument so it - can be used as a callback from define_function. */ - -static void -push_overloaded_decl_1 (x) - tree x; -{ - push_overloaded_decl (x, PUSH_GLOBAL); -} - -#ifdef __GNUC__ -__inline -#endif -tree -auto_function (name, type, code) - tree name, type; - enum built_in_function code; -{ - return define_function - (IDENTIFIER_POINTER (name), type, code, push_overloaded_decl_1, - IDENTIFIER_POINTER (build_decl_overload (name, TYPE_ARG_TYPES (type), - 0))); -} - -/* Create the predefined scalar types of C, - and some nodes representing standard constants (0, 1, (void *)0). - Initialize the global binding level. - Make definitions for built-in primitive functions. */ - -void -init_decl_processing () -{ - register tree endlink, int_endlink, double_endlink, unsigned_endlink; - tree fields[20]; - /* Data type of memcpy. */ - tree memcpy_ftype, strlen_ftype; - int wchar_type_size; - tree temp; - tree array_domain_type; - tree vb_off_identifier = NULL_TREE; - /* Function type `char *(char *, char *)' and similar ones */ - tree string_ftype_ptr_ptr, int_ftype_string_string; - tree sizetype_endlink; - tree ptr_ftype, ptr_ftype_unsigned, ptr_ftype_sizetype; - tree void_ftype, void_ftype_int, void_ftype_ptr; - - /* Have to make these distinct before we try using them. */ - lang_name_cplusplus = get_identifier ("C++"); - lang_name_c = get_identifier ("C"); - lang_name_java = get_identifier ("Java"); - - /* Enter the global namespace. */ - my_friendly_assert (global_namespace == NULL_TREE, 375); - my_friendly_assert (current_lang_name == NULL_TREE, 375); - current_lang_name = lang_name_cplusplus; - push_namespace (get_identifier ("::")); - global_namespace = current_namespace; - current_lang_name = NULL_TREE; - - if (flag_strict_prototype == 2) - flag_strict_prototype = pedantic; - if (! flag_permissive && ! pedantic) - flag_pedantic_errors = 1; - - strict_prototypes_lang_c = flag_strict_prototype; - - /* Initially, C. */ - current_lang_name = lang_name_c; - - current_function_decl = NULL_TREE; - named_labels = NULL_TREE; - named_label_uses = NULL; - current_binding_level = NULL_BINDING_LEVEL; - free_binding_level = NULL_BINDING_LEVEL; - - /* Because most segmentation signals can be traced back into user - code, catch them and at least give the user a chance of working - around compiler bugs. */ - signal (SIGSEGV, signal_catch); - - /* We will also catch aborts in the back-end through signal_catch and - give the user a chance to see where the error might be, and to defeat - aborts in the back-end when there have been errors previously in their - code. */ -#ifdef SIGIOT - signal (SIGIOT, signal_catch); -#endif -#ifdef SIGILL - signal (SIGILL, signal_catch); -#endif -#ifdef SIGABRT - signal (SIGABRT, signal_catch); -#endif -#ifdef SIGBUS - signal (SIGBUS, signal_catch); -#endif - - gcc_obstack_init (&decl_obstack); - - /* Must lay these out before anything else gets laid out. */ - error_mark_node = make_node (ERROR_MARK); - TREE_PERMANENT (error_mark_node) = 1; - TREE_TYPE (error_mark_node) = error_mark_node; - error_mark_list = build_tree_list (error_mark_node, error_mark_node); - TREE_TYPE (error_mark_list) = error_mark_node; - - /* Make the binding_level structure for global names. */ - pushlevel (0); - global_binding_level = current_binding_level; - /* The global level is the namespace level of ::. */ - NAMESPACE_LEVEL (global_namespace) = global_binding_level; - declare_namespace_level (); - - this_identifier = get_identifier (THIS_NAME); - in_charge_identifier = get_identifier (IN_CHARGE_NAME); - ctor_identifier = get_identifier (CTOR_NAME); - dtor_identifier = get_identifier (DTOR_NAME); - pfn_identifier = get_identifier (VTABLE_PFN_NAME); - index_identifier = get_identifier (VTABLE_INDEX_NAME); - delta_identifier = get_identifier (VTABLE_DELTA_NAME); - delta2_identifier = get_identifier (VTABLE_DELTA2_NAME); - pfn_or_delta2_identifier = get_identifier ("__pfn_or_delta2"); - if (flag_handle_signatures) - { - tag_identifier = get_identifier (SIGTABLE_TAG_NAME); - vb_off_identifier = get_identifier (SIGTABLE_VB_OFF_NAME); - vt_off_identifier = get_identifier (SIGTABLE_VT_OFF_NAME); - } - - /* Define `int' and `char' first so that dbx will output them first. */ - - integer_type_node = make_signed_type (INT_TYPE_SIZE); - record_builtin_type (RID_INT, NULL_PTR, integer_type_node); - - /* Define `char', which is like either `signed char' or `unsigned char' - but not the same as either. */ - - char_type_node - = (flag_signed_char - ? make_signed_type (CHAR_TYPE_SIZE) - : make_unsigned_type (CHAR_TYPE_SIZE)); - record_builtin_type (RID_CHAR, "char", char_type_node); - - long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); - record_builtin_type (RID_LONG, "long int", long_integer_type_node); - - unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); - record_builtin_type (RID_UNSIGNED, "unsigned int", unsigned_type_node); - - long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long unsigned int", long_unsigned_type_node); - record_builtin_type (RID_MAX, "unsigned long", long_unsigned_type_node); - - long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long long int", long_long_integer_type_node); - - long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); - record_builtin_type (RID_MAX, "long long unsigned int", - long_long_unsigned_type_node); - record_builtin_type (RID_MAX, "long long unsigned", - long_long_unsigned_type_node); - - short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); - record_builtin_type (RID_SHORT, "short int", short_integer_type_node); - short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); - record_builtin_type (RID_MAX, "short unsigned int", short_unsigned_type_node); - record_builtin_type (RID_MAX, "unsigned short", short_unsigned_type_node); - - /* `unsigned long' is the standard type for sizeof. - Note that stddef.h uses `unsigned long', - and this must agree, even if long and int are the same size. */ - set_sizetype - (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (SIZE_TYPE)))); - - ptrdiff_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (PTRDIFF_TYPE))); - - /* Define both `signed char' and `unsigned char'. */ - signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); - record_builtin_type (RID_MAX, "signed char", signed_char_type_node); - unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - record_builtin_type (RID_MAX, "unsigned char", unsigned_char_type_node); - - /* These are types that type_for_size and type_for_mode use. */ - intQI_type_node = make_signed_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intQI_type_node)); - intHI_type_node = make_signed_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intHI_type_node)); - intSI_type_node = make_signed_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intSI_type_node)); - intDI_type_node = make_signed_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - intTI_type_node = make_signed_type (GET_MODE_BITSIZE (TImode)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("__int128_t"), intTI_type_node)); -#endif - unsigned_intQI_type_node = make_unsigned_type (GET_MODE_BITSIZE (QImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intQI_type_node)); - unsigned_intHI_type_node = make_unsigned_type (GET_MODE_BITSIZE (HImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intHI_type_node)); - unsigned_intSI_type_node = make_unsigned_type (GET_MODE_BITSIZE (SImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intSI_type_node)); - unsigned_intDI_type_node = make_unsigned_type (GET_MODE_BITSIZE (DImode)); - pushdecl (build_decl (TYPE_DECL, NULL_TREE, unsigned_intDI_type_node)); -#if HOST_BITS_PER_WIDE_INT >= 64 - unsigned_intTI_type_node = make_unsigned_type (GET_MODE_BITSIZE (TImode)); - pushdecl (build_decl (TYPE_DECL, get_identifier ("__uint128_t"), unsigned_intTI_type_node)); -#endif - - float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; - record_builtin_type (RID_FLOAT, NULL_PTR, float_type_node); - layout_type (float_type_node); - - double_type_node = make_node (REAL_TYPE); - if (flag_short_double) - TYPE_PRECISION (double_type_node) = FLOAT_TYPE_SIZE; - else - TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; - record_builtin_type (RID_DOUBLE, NULL_PTR, double_type_node); - layout_type (double_type_node); - - long_double_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; - record_builtin_type (RID_MAX, "long double", long_double_type_node); - layout_type (long_double_type_node); - - complex_integer_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), - complex_integer_type_node)); - TREE_TYPE (complex_integer_type_node) = integer_type_node; - layout_type (complex_integer_type_node); - - complex_float_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), - complex_float_type_node)); - TREE_TYPE (complex_float_type_node) = float_type_node; - layout_type (complex_float_type_node); - - complex_double_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), - complex_double_type_node)); - TREE_TYPE (complex_double_type_node) = double_type_node; - layout_type (complex_double_type_node); - - complex_long_double_type_node = make_node (COMPLEX_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), - complex_long_double_type_node)); - TREE_TYPE (complex_long_double_type_node) = long_double_type_node; - layout_type (complex_long_double_type_node); - - java_byte_type_node = record_builtin_java_type ("__java_byte", 8); - java_short_type_node = record_builtin_java_type ("__java_short", 16); - java_int_type_node = record_builtin_java_type ("__java_int", 32); - java_long_type_node = record_builtin_java_type ("__java_long", 64); - java_float_type_node = record_builtin_java_type ("__java_float", -32); - java_double_type_node = record_builtin_java_type ("__java_double", -64); - java_char_type_node = record_builtin_java_type ("__java_char", -16); - java_boolean_type_node = record_builtin_java_type ("__java_boolean", -1); - - integer_zero_node = build_int_2 (0, 0); - TREE_TYPE (integer_zero_node) = integer_type_node; - integer_one_node = build_int_2 (1, 0); - TREE_TYPE (integer_one_node) = integer_type_node; - integer_two_node = build_int_2 (2, 0); - TREE_TYPE (integer_two_node) = integer_type_node; - integer_three_node = build_int_2 (3, 0); - TREE_TYPE (integer_three_node) = integer_type_node; - - boolean_type_node = make_unsigned_type (BOOL_TYPE_SIZE); - TREE_SET_CODE (boolean_type_node, BOOLEAN_TYPE); - TYPE_MAX_VALUE (boolean_type_node) = build_int_2 (1, 0); - TREE_TYPE (TYPE_MAX_VALUE (boolean_type_node)) = boolean_type_node; - TYPE_PRECISION (boolean_type_node) = 1; - record_builtin_type (RID_BOOL, "bool", boolean_type_node); - boolean_false_node = build_int_2 (0, 0); - TREE_TYPE (boolean_false_node) = boolean_type_node; - boolean_true_node = build_int_2 (1, 0); - TREE_TYPE (boolean_true_node) = boolean_type_node; - - /* These are needed by stor-layout.c. */ - size_zero_node = size_int (0); - size_one_node = size_int (1); - - signed_size_zero_node = build_int_2 (0, 0); - TREE_TYPE (signed_size_zero_node) = make_signed_type (TYPE_PRECISION (sizetype)); - - void_type_node = make_node (VOID_TYPE); - record_builtin_type (RID_VOID, NULL_PTR, void_type_node); - layout_type (void_type_node); /* Uses integer_zero_node. */ - void_list_node = build_tree_list (NULL_TREE, void_type_node); - TREE_PARMLIST (void_list_node) = 1; - - null_pointer_node = build_int_2 (0, 0); - TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); - layout_type (TREE_TYPE (null_pointer_node)); - - /* Used for expressions that do nothing, but are not errors. */ - void_zero_node = build_int_2 (0, 0); - TREE_TYPE (void_zero_node) = void_type_node; - - string_type_node = build_pointer_type (char_type_node); - const_string_type_node - = build_pointer_type (build_qualified_type (char_type_node, - TYPE_QUAL_CONST)); -#if 0 - record_builtin_type (RID_MAX, NULL_PTR, string_type_node); -#endif - - /* Make a type to be the domain of a few array types - whose domains don't really matter. - 200 is small enough that it always fits in size_t - and large enough that it can hold most function names for the - initializations of __FUNCTION__ and __PRETTY_FUNCTION__. */ - array_domain_type = build_index_type (build_int_2 (200, 0)); - - /* Make a type for arrays of characters. - With luck nothing will ever really depend on the length of this - array type. */ - char_array_type_node - = build_array_type (char_type_node, array_domain_type); - /* Likewise for arrays of ints. */ - int_array_type_node - = build_array_type (integer_type_node, array_domain_type); - - /* This is just some anonymous class type. Nobody should ever - need to look inside this envelope. */ - class_star_type_node = build_pointer_type (make_lang_type (RECORD_TYPE)); - - default_function_type - = build_function_type (integer_type_node, NULL_TREE); - - ptr_type_node = build_pointer_type (void_type_node); - const_ptr_type_node - = build_pointer_type (build_qualified_type (void_type_node, - TYPE_QUAL_CONST)); -#if 0 - record_builtin_type (RID_MAX, NULL_PTR, ptr_type_node); -#endif - endlink = void_list_node; - int_endlink = tree_cons (NULL_TREE, integer_type_node, endlink); - double_endlink = tree_cons (NULL_TREE, double_type_node, endlink); - unsigned_endlink = tree_cons (NULL_TREE, unsigned_type_node, endlink); - - ptr_ftype = build_function_type (ptr_type_node, NULL_TREE); - ptr_ftype_unsigned = build_function_type (ptr_type_node, unsigned_endlink); - sizetype_endlink = tree_cons (NULL_TREE, sizetype, endlink); - /* We realloc here because sizetype could be int or unsigned. S'ok. */ - ptr_ftype_sizetype = build_function_type (ptr_type_node, sizetype_endlink); - - void_ftype = build_function_type (void_type_node, endlink); - void_ftype_int = build_function_type (void_type_node, int_endlink); - void_ftype_ptr - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, endlink)); - void_ftype_ptr - = build_exception_variant (void_ftype_ptr, - tree_cons (NULL_TREE, NULL_TREE, NULL_TREE)); - - float_ftype_float - = build_function_type (float_type_node, - tree_cons (NULL_TREE, float_type_node, endlink)); - - double_ftype_double - = build_function_type (double_type_node, double_endlink); - - ldouble_ftype_ldouble - = build_function_type (long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, - endlink)); - - double_ftype_double_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, double_type_node, - double_endlink)); - - int_ftype_int - = build_function_type (integer_type_node, int_endlink); - - long_ftype_long - = build_function_type (long_integer_type_node, - tree_cons (NULL_TREE, long_integer_type_node, - endlink)); - - int_ftype_cptr_cptr_sizet - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, - sizetype, - endlink)))); - - string_ftype_ptr_ptr /* strcpy prototype */ - = build_function_type (string_type_node, - tree_cons (NULL_TREE, string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - int_ftype_string_string /* strcmp prototype */ - = build_function_type (integer_type_node, - tree_cons (NULL_TREE, const_string_type_node, - tree_cons (NULL_TREE, - const_string_type_node, - endlink))); - - strlen_ftype /* strlen prototype */ - = build_function_type (sizetype, - tree_cons (NULL_TREE, const_string_type_node, - endlink)); - - memcpy_ftype /* memcpy prototype */ - = build_function_type (ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - sizetype_endlink))); - - if (flag_huge_objects) - delta_type_node = long_integer_type_node; - else - delta_type_node = short_integer_type_node; - - builtin_function ("__builtin_constant_p", default_function_type, - BUILT_IN_CONSTANT_P, NULL_PTR); - - builtin_return_address_fndecl - = builtin_function ("__builtin_return_address", ptr_ftype_unsigned, - BUILT_IN_RETURN_ADDRESS, NULL_PTR); - - builtin_function ("__builtin_frame_address", ptr_ftype_unsigned, - BUILT_IN_FRAME_ADDRESS, NULL_PTR); - - builtin_function ("__builtin_alloca", ptr_ftype_sizetype, - BUILT_IN_ALLOCA, "alloca"); - builtin_function ("__builtin_ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); - /* Define alloca, ffs as builtins. - Declare _exit just to mark it as volatile. */ - if (! flag_no_builtin && !flag_no_nonansi_builtin) - { - temp = builtin_function ("alloca", ptr_ftype_sizetype, - BUILT_IN_ALLOCA, NULL_PTR); - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("ffs", int_ftype_int, BUILT_IN_FFS, NULL_PTR); - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("_exit", void_ftype_int, - NOT_BUILT_IN, NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - /* Suppress error if redefined as a non-function. */ - DECL_BUILT_IN_NONANSI (temp) = 1; - } - - builtin_function ("__builtin_abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("__builtin_fabsf", float_ftype_float, BUILT_IN_FABS, - NULL_PTR); - builtin_function ("__builtin_fabs", double_ftype_double, BUILT_IN_FABS, - NULL_PTR); - builtin_function ("__builtin_fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS, - NULL_PTR); - builtin_function ("__builtin_labs", long_ftype_long, - BUILT_IN_LABS, NULL_PTR); - builtin_function ("__builtin_saveregs", ptr_ftype, - BUILT_IN_SAVEREGS, NULL_PTR); - builtin_function ("__builtin_classify_type", default_function_type, - BUILT_IN_CLASSIFY_TYPE, NULL_PTR); - builtin_function ("__builtin_next_arg", ptr_ftype, - BUILT_IN_NEXT_ARG, NULL_PTR); - builtin_function ("__builtin_args_info", int_ftype_int, - BUILT_IN_ARGS_INFO, NULL_PTR); - builtin_function ("__builtin_setjmp", - build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - endlink)), - BUILT_IN_SETJMP, NULL_PTR); - builtin_function ("__builtin_longjmp", - build_function_type (integer_type_node, - tree_cons (NULL_TREE, ptr_type_node, - tree_cons (NULL_TREE, - integer_type_node, - endlink))), - BUILT_IN_LONGJMP, NULL_PTR); - - /* Untyped call and return. */ - builtin_function ("__builtin_apply_args", ptr_ftype, - BUILT_IN_APPLY_ARGS, NULL_PTR); - - temp = tree_cons (NULL_TREE, - build_pointer_type (build_function_type (void_type_node, - NULL_TREE)), - tree_cons (NULL_TREE, ptr_ftype_sizetype, NULL_TREE)); - builtin_function ("__builtin_apply", - build_function_type (ptr_type_node, temp), - BUILT_IN_APPLY, NULL_PTR); - builtin_function ("__builtin_return", void_ftype_ptr, - BUILT_IN_RETURN, NULL_PTR); - - /* CYGNUS LOCAL -- branch prediction */ - builtin_function ("__builtin_expect", - build_function_type (integer_type_node, - tree_cons (NULL_TREE, integer_type_node, - int_endlink)), - BUILT_IN_EXPECT, NULL_PTR); - - /* END CYGNUS LOCAL -- branch prediction */ - - /* Currently under experimentation. */ - builtin_function ("__builtin_memcpy", memcpy_ftype, - BUILT_IN_MEMCPY, "memcpy"); - builtin_function ("__builtin_memcmp", int_ftype_cptr_cptr_sizet, - BUILT_IN_MEMCMP, "memcmp"); - builtin_function ("__builtin_strcmp", int_ftype_string_string, - BUILT_IN_STRCMP, "strcmp"); - builtin_function ("__builtin_strcpy", string_ftype_ptr_ptr, - BUILT_IN_STRCPY, "strcpy"); - builtin_function ("__builtin_strlen", strlen_ftype, - BUILT_IN_STRLEN, "strlen"); - builtin_function ("__builtin_sqrtf", float_ftype_float, - BUILT_IN_FSQRT, "sqrtf"); - builtin_function ("__builtin_fsqrt", double_ftype_double, - BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble, - BUILT_IN_FSQRT, "sqrtl"); - builtin_function ("__builtin_sinf", float_ftype_float, - BUILT_IN_SIN, "sinf"); - builtin_function ("__builtin_sin", double_ftype_double, - BUILT_IN_SIN, "sin"); - builtin_function ("__builtin_sinl", ldouble_ftype_ldouble, - BUILT_IN_SIN, "sinl"); - builtin_function ("__builtin_cosf", float_ftype_float, - BUILT_IN_COS, "cosf"); - builtin_function ("__builtin_cos", double_ftype_double, - BUILT_IN_COS, "cos"); - builtin_function ("__builtin_cosl", ldouble_ftype_ldouble, - BUILT_IN_COS, "cosl"); - - if (!flag_no_builtin) - { - builtin_function ("abs", int_ftype_int, BUILT_IN_ABS, NULL_PTR); - builtin_function ("fabs", double_ftype_double, BUILT_IN_FABS, NULL_PTR); - builtin_function ("labs", long_ftype_long, BUILT_IN_LABS, NULL_PTR); - builtin_function ("fabsf", float_ftype_float, BUILT_IN_FABS, NULL_PTR); - builtin_function ("fabsl", ldouble_ftype_ldouble, BUILT_IN_FABS, - NULL_PTR); - builtin_function ("memcpy", memcpy_ftype, BUILT_IN_MEMCPY, NULL_PTR); - builtin_function ("memcmp", int_ftype_cptr_cptr_sizet, BUILT_IN_MEMCMP, - NULL_PTR); - builtin_function ("strcmp", int_ftype_string_string, BUILT_IN_STRCMP, - NULL_PTR); - builtin_function ("strcpy", string_ftype_ptr_ptr, BUILT_IN_STRCPY, - NULL_PTR); - builtin_function ("strlen", strlen_ftype, BUILT_IN_STRLEN, NULL_PTR); - builtin_function ("sqrtf", float_ftype_float, BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("sqrt", double_ftype_double, BUILT_IN_FSQRT, NULL_PTR); - builtin_function ("sqrtl", ldouble_ftype_ldouble, BUILT_IN_FSQRT, - NULL_PTR); - builtin_function ("sinf", float_ftype_float, BUILT_IN_SIN, NULL_PTR); - builtin_function ("sin", double_ftype_double, BUILT_IN_SIN, NULL_PTR); - builtin_function ("sinl", ldouble_ftype_ldouble, BUILT_IN_SIN, NULL_PTR); - builtin_function ("cosf", float_ftype_float, BUILT_IN_COS, NULL_PTR); - builtin_function ("cos", double_ftype_double, BUILT_IN_COS, NULL_PTR); - builtin_function ("cosl", ldouble_ftype_ldouble, BUILT_IN_COS, NULL_PTR); - - /* Declare these functions volatile - to avoid spurious "control drops through" warnings. */ - temp = builtin_function ("abort", void_ftype, - NOT_BUILT_IN, NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - /* Well, these are actually ANSI, but we can't set DECL_BUILT_IN on - them... */ - DECL_BUILT_IN_NONANSI (temp) = 1; - temp = builtin_function ("exit", void_ftype_int, - NOT_BUILT_IN, NULL_PTR); - TREE_THIS_VOLATILE (temp) = 1; - TREE_SIDE_EFFECTS (temp) = 1; - DECL_BUILT_IN_NONANSI (temp) = 1; - } - -#if 0 - /* Support for these has not been written in either expand_builtin - or build_function_call. */ - builtin_function ("__builtin_div", default_ftype, BUILT_IN_DIV, NULL_PTR); - builtin_function ("__builtin_ldiv", default_ftype, BUILT_IN_LDIV, NULL_PTR); - builtin_function ("__builtin_ffloor", double_ftype_double, BUILT_IN_FFLOOR, - NULL_PTR); - builtin_function ("__builtin_fceil", double_ftype_double, BUILT_IN_FCEIL, - NULL_PTR); - builtin_function ("__builtin_fmod", double_ftype_double_double, - BUILT_IN_FMOD, NULL_PTR); - builtin_function ("__builtin_frem", double_ftype_double_double, - BUILT_IN_FREM, NULL_PTR); - builtin_function ("__builtin_memset", ptr_ftype_ptr_int_int, - BUILT_IN_MEMSET, NULL_PTR); - builtin_function ("__builtin_getexp", double_ftype_double, BUILT_IN_GETEXP, - NULL_PTR); - builtin_function ("__builtin_getman", double_ftype_double, BUILT_IN_GETMAN, - NULL_PTR); -#endif - - /* C++ extensions */ - - unknown_type_node = make_node (UNKNOWN_TYPE); - record_unknown_type (unknown_type_node, "unknown type"); - - /* Indirecting an UNKNOWN_TYPE node yields an UNKNOWN_TYPE node. */ - TREE_TYPE (unknown_type_node) = unknown_type_node; - - TREE_TYPE (null_node) = type_for_size (POINTER_SIZE, 0); - - /* Looking up TYPE_POINTER_TO and TYPE_REFERENCE_TO yield the same - result. */ - TYPE_POINTER_TO (unknown_type_node) = unknown_type_node; - TYPE_REFERENCE_TO (unknown_type_node) = unknown_type_node; - - /* This is for handling opaque types in signatures. */ - opaque_type_node = copy_node (ptr_type_node); - TYPE_MAIN_VARIANT (opaque_type_node) = opaque_type_node; - record_builtin_type (RID_MAX, 0, opaque_type_node); - - /* This is special for C++ so functions can be overloaded. */ - wchar_type_node - = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (get_identifier (WCHAR_TYPE))); - wchar_type_size = TYPE_PRECISION (wchar_type_node); - signed_wchar_type_node = make_signed_type (wchar_type_size); - unsigned_wchar_type_node = make_unsigned_type (wchar_type_size); - wchar_type_node - = TREE_UNSIGNED (wchar_type_node) - ? unsigned_wchar_type_node - : signed_wchar_type_node; - record_builtin_type (RID_WCHAR, "__wchar_t", wchar_type_node); - - /* Artificial declaration of wchar_t -- can be bashed */ - wchar_decl_node = build_decl (TYPE_DECL, get_identifier ("wchar_t"), - wchar_type_node); - pushdecl (wchar_decl_node); - - /* This is for wide string constants. */ - wchar_array_type_node - = build_array_type (wchar_type_node, array_domain_type); - - if (flag_vtable_thunks) - { - /* Make sure we get a unique function type, so we can give - its pointer type a name. (This wins for gdb.) */ - tree vfunc_type = make_node (FUNCTION_TYPE); - TREE_TYPE (vfunc_type) = integer_type_node; - TYPE_ARG_TYPES (vfunc_type) = NULL_TREE; - layout_type (vfunc_type); - - vtable_entry_type = build_pointer_type (vfunc_type); - } - else - { - vtable_entry_type = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, - delta_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, - delta_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, pfn_identifier, - ptr_type_node); - finish_builtin_type (vtable_entry_type, VTBL_PTR_TYPE, fields, 2, - double_type_node); - - /* Make this part of an invisible union. */ - fields[3] = copy_node (fields[2]); - TREE_TYPE (fields[3]) = delta_type_node; - DECL_NAME (fields[3]) = delta2_identifier; - DECL_MODE (fields[3]) = TYPE_MODE (delta_type_node); - DECL_SIZE (fields[3]) = TYPE_SIZE (delta_type_node); - TREE_UNSIGNED (fields[3]) = 0; - TREE_CHAIN (fields[2]) = fields[3]; - vtable_entry_type = build_qualified_type (vtable_entry_type, - TYPE_QUAL_CONST); - } - record_builtin_type (RID_MAX, VTBL_PTR_TYPE, vtable_entry_type); - - vtbl_type_node - = build_cplus_array_type (vtable_entry_type, NULL_TREE); - layout_type (vtbl_type_node); - vtbl_type_node = build_qualified_type (vtbl_type_node, TYPE_QUAL_CONST); - record_builtin_type (RID_MAX, NULL_PTR, vtbl_type_node); - vtbl_ptr_type_node = build_pointer_type (vtable_entry_type); - layout_type (vtbl_ptr_type_node); - record_builtin_type (RID_MAX, NULL_PTR, vtbl_ptr_type_node); - - /* Simplify life by making a "sigtable_entry_type". Give its - fields names so that the debugger can use them. */ - - if (flag_handle_signatures) - { - sigtable_entry_type = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, tag_identifier, - delta_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, vb_off_identifier, - delta_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, delta_identifier, - delta_type_node); - fields[3] = build_lang_field_decl (FIELD_DECL, index_identifier, - delta_type_node); - fields[4] = build_lang_field_decl (FIELD_DECL, pfn_identifier, - ptr_type_node); - - /* Set the alignment to the max of the alignment of ptr_type_node and - delta_type_node. Double alignment wastes a word on the Sparc. */ - finish_builtin_type (sigtable_entry_type, SIGTABLE_PTR_TYPE, fields, 4, - (TYPE_ALIGN (ptr_type_node) > TYPE_ALIGN (delta_type_node)) - ? ptr_type_node - : delta_type_node); - - /* Make this part of an invisible union. */ - fields[5] = copy_node (fields[4]); - TREE_TYPE (fields[5]) = delta_type_node; - DECL_NAME (fields[5]) = vt_off_identifier; - DECL_MODE (fields[5]) = TYPE_MODE (delta_type_node); - DECL_SIZE (fields[5]) = TYPE_SIZE (delta_type_node); - TREE_UNSIGNED (fields[5]) = 0; - TREE_CHAIN (fields[4]) = fields[5]; - - sigtable_entry_type = build_qualified_type (sigtable_entry_type, - TYPE_QUAL_CONST); - record_builtin_type (RID_MAX, SIGTABLE_PTR_TYPE, sigtable_entry_type); - } - - std_node = build_decl (NAMESPACE_DECL, - get_identifier (flag_honor_std ? "fake std":"std"), - void_type_node); - pushdecl (std_node); - - global_type_node = make_node (LANG_TYPE); - record_unknown_type (global_type_node, "global type"); - - /* Now, C++. */ - current_lang_name = lang_name_cplusplus; - - { - tree bad_alloc_type_node, newtype, deltype; - if (flag_honor_std) - push_namespace (get_identifier ("std")); - bad_alloc_type_node = xref_tag - (class_type_node, get_identifier ("bad_alloc"), 1); - if (flag_honor_std) - pop_namespace (); - newtype = build_exception_variant - (ptr_ftype_sizetype, build_tree_list (NULL_TREE, bad_alloc_type_node)); - deltype = build_exception_variant - (void_ftype_ptr, build_tree_list (NULL_TREE, NULL_TREE)); - auto_function (ansi_opname[(int) NEW_EXPR], newtype, NOT_BUILT_IN); - auto_function (ansi_opname[(int) VEC_NEW_EXPR], newtype, NOT_BUILT_IN); - global_delete_fndecl - = auto_function (ansi_opname[(int) DELETE_EXPR], deltype, NOT_BUILT_IN); - auto_function (ansi_opname[(int) VEC_DELETE_EXPR], deltype, NOT_BUILT_IN); - } - - abort_fndecl - = define_function ("__pure_virtual", void_ftype, - NOT_BUILT_IN, 0, 0); - - /* Perform other language dependent initializations. */ - init_class_processing (); - init_init_processing (); - init_search_processing (); - if (flag_rtti) - init_rtti_processing (); - - if (flag_exceptions) - init_exception_processing (); - if (flag_no_inline) - { - flag_inline_functions = 0; - } - - if (! supports_one_only ()) - flag_weak = 0; - - /* Create the global bindings for __FUNCTION__ and __PRETTY_FUNCTION__. */ - declare_function_name (); - - /* Prepare to check format strings against argument lists. */ - init_function_format_info (); - - /* Show we use EH for cleanups. */ - using_eh_for_cleanups (); - - print_error_function = lang_print_error_function; - lang_get_alias_set = &c_get_alias_set; - - /* Maintain consistency. Perhaps we should just complain if they - say -fwritable-strings? */ - if (flag_writable_strings) - flag_const_strings = 0; -} - -/* Function to print any language-specific context for an error message. */ - -static void -lang_print_error_function (file) - char *file; -{ - default_print_error_function (file); - maybe_print_template_context (); -} - -/* Make a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. - FUNCTION_CODE tells later passes how to compile calls to this function. - See tree.h for its possible values. - - If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, - the name to be called if we can't opencode the function. */ - -tree -define_function (name, type, function_code, pfn, library_name) - char *name; - tree type; - enum built_in_function function_code; - void (*pfn) PROTO((tree)); - char *library_name; -{ - tree decl = build_lang_decl (FUNCTION_DECL, get_identifier (name), type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - - my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 392); - DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); - - /* Since `pushdecl' relies on DECL_ASSEMBLER_NAME instead of DECL_NAME, - we cannot change DECL_ASSEMBLER_NAME until we have installed this - function in the namespace. */ - if (pfn) (*pfn) (decl); - if (library_name) - DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); - make_function_rtl (decl); - if (function_code != NOT_BUILT_IN) - { - DECL_BUILT_IN (decl) = 1; - DECL_FUNCTION_CODE (decl) = function_code; - } - return decl; -} - -/* When we call finish_struct for an anonymous union, we create - default copy constructors and such. But, an anonymous union - shouldn't have such things; this function undoes the damage to the - anonymous union type T. - - (The reason that we create the synthesized methods is that we don't - distinguish `union { int i; }' from `typedef union { int i; } U'. - The first is an anonymous union; the second is just an ordinary - union type.) */ - -void -fixup_anonymous_union (t) - tree t; -{ - tree *q; - - /* Wipe out memory of synthesized methods */ - TYPE_HAS_CONSTRUCTOR (t) = 0; - TYPE_HAS_DEFAULT_CONSTRUCTOR (t) = 0; - TYPE_HAS_INIT_REF (t) = 0; - TYPE_HAS_CONST_INIT_REF (t) = 0; - TYPE_HAS_ASSIGN_REF (t) = 0; - TYPE_HAS_ASSIGNMENT (t) = 0; - TYPE_HAS_CONST_ASSIGN_REF (t) = 0; - - /* Splice the implicitly generated functions out of the TYPE_METHODS - list. */ - q = &TYPE_METHODS (t); - while (*q) - { - if (DECL_ARTIFICIAL (*q)) - *q = TREE_CHAIN (*q); - else - q = &TREE_CHAIN (*q); - } - - /* ANSI C++ June 5 1992 WP 9.5.3. Anonymous unions may not have - function members. */ - if (TYPE_METHODS (t)) - error ("an anonymous union cannot have function members"); -} - -/* Make sure that a declaration with no declarator is well-formed, i.e. - just defines a tagged type or anonymous union. - - Returns the type defined, if any. */ - -tree -check_tag_decl (declspecs) - tree declspecs; -{ - int found_type = 0; - tree ob_modifier = NULL_TREE; - register tree link; - register tree t = NULL_TREE; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - register tree value = TREE_VALUE (link); - - if (TYPE_P (value)) - { - ++found_type; - - if (IS_AGGR_TYPE (value) || TREE_CODE (value) == ENUMERAL_TYPE) - { - my_friendly_assert (TYPE_MAIN_DECL (value) != NULL_TREE, 261); - t = value; - } - } - else if (value == ridpointers[(int) RID_FRIEND]) - { - if (current_class_type == NULL_TREE - || current_scope () != current_class_type) - ob_modifier = value; - } - else if (value == ridpointers[(int) RID_STATIC] - || value == ridpointers[(int) RID_EXTERN] - || value == ridpointers[(int) RID_AUTO] - || value == ridpointers[(int) RID_REGISTER] - || value == ridpointers[(int) RID_INLINE] - || value == ridpointers[(int) RID_VIRTUAL] - || value == ridpointers[(int) RID_CONST] - || value == ridpointers[(int) RID_VOLATILE] - || value == ridpointers[(int) RID_EXPLICIT]) - ob_modifier = value; - } - - if (found_type > 1) - error ("multiple types in one declaration"); - - /* Inside a class, we might be in a friend or access declaration. - Until we have a good way of detecting the latter, don't warn. */ - if (t == NULL_TREE && ! current_class_type) - pedwarn ("declaration does not declare anything"); - else if (t && ANON_UNION_TYPE_P (t)) - /* Anonymous unions are objects, so they can have specifiers. */; - else if (ob_modifier) - { - if (ob_modifier == ridpointers[(int) RID_INLINE] - || ob_modifier == ridpointers[(int) RID_VIRTUAL]) - cp_error ("`%D' can only be specified for functions", ob_modifier); - else if (ob_modifier == ridpointers[(int) RID_FRIEND]) - cp_error ("`%D' can only be specified inside a class", ob_modifier); - else if (ob_modifier == ridpointers[(int) RID_EXPLICIT]) - cp_error ("`%D' can only be specified for constructors", - ob_modifier); - else - cp_error ("`%D' can only be specified for objects and functions", - ob_modifier); - } - - return t; -} - -/* Called when a declaration is seen that contains no names to declare. - If its type is a reference to a structure, union or enum inherited - from a containing scope, shadow that tag name for the current scope - with a forward reference. - If its type defines a new named structure or union - or defines an enum, it is valid but we need not do anything here. - Otherwise, it is an error. - - C++: may have to grok the declspecs to learn about static, - complain for anonymous unions. */ - -void -shadow_tag (declspecs) - tree declspecs; -{ - tree t = check_tag_decl (declspecs); - - if (t) - maybe_process_partial_specialization (t); - - /* This is where the variables in an anonymous union are - declared. An anonymous union declaration looks like: - union { ... } ; - because there is no declarator after the union, the parser - sends that declaration here. */ - if (t && ANON_UNION_TYPE_P (t)) - { - fixup_anonymous_union (t); - - if (TYPE_FIELDS (t)) - { - tree decl = grokdeclarator (NULL_TREE, declspecs, NORMAL, 0, - NULL_TREE); - finish_anon_union (decl); - } - } -} - -/* Decode a "typename", such as "int **", returning a ..._TYPE node. */ - -tree -groktypename (typename) - tree typename; -{ - if (TREE_CODE (typename) != TREE_LIST) - return typename; - return grokdeclarator (TREE_VALUE (typename), - TREE_PURPOSE (typename), - TYPENAME, 0, NULL_TREE); -} - -/* Decode a declarator in an ordinary declaration or data definition. - This is called as soon as the type information and variable name - have been parsed, before parsing the initializer if any. - Here we create the ..._DECL node, fill in its type, - and put it on the list of decls for the current context. - The ..._DECL node is returned as the value. - - Exception: for arrays where the length is not specified, - the type is left null, to be filled in by `cp_finish_decl'. - - Function definitions do not come here; they go to start_function - instead. However, external and forward declarations of functions - do go through here. Structure field declarations are done by - grokfield and not through here. */ - -/* Set this to zero to debug not using the temporary obstack - to parse initializers. */ -int debug_temp_inits = 1; - -tree -start_decl (declarator, declspecs, initialized, attributes, prefix_attributes) - tree declarator, declspecs; - int initialized; - tree attributes, prefix_attributes; -{ - register tree decl; - register tree type, tem; - tree context; - extern int have_extern_spec; - extern int used_extern_spec; - tree attrlist; - -#if 0 - /* See code below that used this. */ - int init_written = initialized; -#endif - - /* This should only be done once on the top most decl. */ - if (have_extern_spec && !used_extern_spec) - { - declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), - declspecs); - used_extern_spec = 1; - } - - if (attributes || prefix_attributes) - attrlist = build_scratch_list (attributes, prefix_attributes); - else - attrlist = NULL_TREE; - - decl = grokdeclarator (declarator, declspecs, NORMAL, initialized, - attrlist); - - if (decl == NULL_TREE || TREE_CODE (decl) == VOID_TYPE) - return NULL_TREE; - - type = TREE_TYPE (decl); - - /* Don't lose if destructors must be executed at file-level. */ - if (! processing_template_decl && TREE_STATIC (decl) - && TYPE_NEEDS_DESTRUCTOR (complete_type (type)) - && !TREE_PERMANENT (decl)) - { - push_obstacks (&permanent_obstack, &permanent_obstack); - decl = copy_node (decl); - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree itype = TYPE_DOMAIN (type); - if (itype && ! TREE_PERMANENT (itype)) - { - itype = build_index_type (copy_to_permanent (TYPE_MAX_VALUE (itype))); - type = build_cplus_array_type (TREE_TYPE (type), itype); - TREE_TYPE (decl) = type; - } - } - pop_obstacks (); - } - - context - = (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) - ? DECL_CLASS_CONTEXT (decl) - : DECL_CONTEXT (decl); - - if (initialized && context && TREE_CODE (context) == NAMESPACE_DECL - && context != current_namespace && TREE_CODE (decl) == VAR_DECL) - { - /* When parsing the initializer, lookup should use the object's - namespace. */ - push_decl_namespace (context); - } - - /* We are only interested in class contexts, later. */ - if (context && TREE_CODE (context) == NAMESPACE_DECL) - context = NULL_TREE; - - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `cp_finish_decl' to ignore the initializer once it is parsed. */ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - /* typedef foo = bar means give foo the same type as bar. - We haven't parsed bar yet, so `cp_finish_decl' will fix that up. - Any other case of an initialization in a TYPE_DECL is an error. */ - if (pedantic || list_length (declspecs) > 1) - { - cp_error ("typedef `%D' is initialized", decl); - initialized = 0; - } - break; - - case FUNCTION_DECL: - cp_error ("function `%#D' is initialized like a variable", decl); - initialized = 0; - break; - - default: - if (! processing_template_decl) - { - if (type != error_mark_node) - { - if (TYPE_SIZE (type) != NULL_TREE - && ! TREE_CONSTANT (TYPE_SIZE (type))) - { - cp_error - ("variable-sized object `%D' may not be initialized", - decl); - initialized = 0; - } - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) - { - cp_error - ("elements of array `%#D' have incomplete type", decl); - initialized = 0; - } - } - } - } - - if (initialized) - { - if (! toplevel_bindings_p () - && DECL_EXTERNAL (decl)) - cp_warning ("declaration of `%#D' has `extern' and is initialized", - decl); - DECL_EXTERNAL (decl) = 0; - if (toplevel_bindings_p ()) - TREE_STATIC (decl) = 1; - - /* Tell `pushdecl' this is an initialized decl - even though we don't yet have the initializer expression. - Also tell `cp_finish_decl' it may store the real initializer. */ - DECL_INITIAL (decl) = error_mark_node; - } - - if (context && TYPE_SIZE (complete_type (context)) != NULL_TREE) - { - pushclass (context, 2); - - if (TREE_CODE (decl) == VAR_DECL) - { - tree field = lookup_field (context, DECL_NAME (decl), 0, 0); - if (field == NULL_TREE || TREE_CODE (field) != VAR_DECL) - cp_error ("`%#D' is not a static member of `%#T'", decl, context); - else - { - if (DECL_CONTEXT (field) != context) - { - cp_pedwarn ("ANSI C++ does not permit `%T::%D' to be defined as `%T::%D'", - DECL_CONTEXT (field), DECL_NAME (decl), - context, DECL_NAME (decl)); - DECL_CONTEXT (decl) = DECL_CONTEXT (field); - } - /* Static data member are tricky; an in-class initialization - still doesn't provide a definition, so the in-class - declaration will have DECL_EXTERNAL set, but will have an - initialization. Thus, duplicate_decls won't warn - about this situation, and so we check here. */ - if (DECL_INITIAL (decl) && DECL_INITIAL (field)) - cp_error ("duplicate initialization of %D", decl); - if (duplicate_decls (decl, field)) - decl = field; - } - } - else - { - tree field = check_classfn (context, decl); - if (field && duplicate_decls (decl, field)) - decl = field; - } - - /* cp_finish_decl sets DECL_EXTERNAL if DECL_IN_AGGR_P is set. */ - DECL_IN_AGGR_P (decl) = 0; - if ((DECL_LANG_SPECIFIC (decl) && DECL_USE_TEMPLATE (decl)) - || CLASSTYPE_USE_TEMPLATE (context)) - { - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - /* [temp.expl.spec] An explicit specialization of a static data - member of a template is a definition if the declaration - includes an initializer; otherwise, it is a declaration. - - We check for processing_specialization so this only applies - to the new specialization syntax. */ - if (DECL_INITIAL (decl) == NULL_TREE && processing_specialization) - DECL_EXTERNAL (decl) = 1; - } - - if (DECL_EXTERNAL (decl) && ! DECL_TEMPLATE_SPECIALIZATION (decl)) - cp_pedwarn ("declaration of `%#D' outside of class is not definition", - decl); - } - -#ifdef SET_DEFAULT_DECL_ATTRIBUTES - SET_DEFAULT_DECL_ATTRIBUTES (decl, attributes); -#endif - - /* Set attributes here so if duplicate decl, will have proper attributes. */ - cplus_decl_attributes (decl, attributes, prefix_attributes); - - /* Add this decl to the current binding level, but not if it - comes from another scope, e.g. a static member variable. - TEM may equal DECL or it may be a previous decl of the same name. */ - - if ((TREE_CODE (decl) != PARM_DECL && DECL_CONTEXT (decl) != NULL_TREE - /* Definitions of namespace members outside their namespace are - possible. */ - && TREE_CODE (DECL_CONTEXT (decl)) != NAMESPACE_DECL) - || (TREE_CODE (decl) == TEMPLATE_DECL && !namespace_bindings_p ()) - || TREE_CODE (type) == LANG_TYPE - /* The declaration of template specializations does not affect - the functions available for overload resolution, so we do not - call pushdecl. */ - || (TREE_CODE (decl) == FUNCTION_DECL - && DECL_TEMPLATE_SPECIALIZATION (decl))) - tem = decl; - else - tem = pushdecl (decl); - - if (processing_template_decl) - { - if (! current_function_decl) - tem = push_template_decl (tem); - else if (minimal_parse_mode) - DECL_VINDEX (tem) - = build_min_nt (DECL_STMT, copy_to_permanent (declarator), - copy_to_permanent (declspecs), - NULL_TREE); - } - - -#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) - /* Tell the back-end to use or not use .common as appropriate. If we say - -fconserve-space, we want this to save .data space, at the expense of - wrong semantics. If we say -fno-conserve-space, we want this to - produce errors about redefs; to do this we force variables into the - data segment. */ - DECL_COMMON (tem) = flag_conserve_space || ! TREE_PUBLIC (tem); -#endif - - if (! processing_template_decl) - start_decl_1 (tem); - - /* Corresponding pop_obstacks is done in `cp_finish_decl'. */ - push_obstacks_nochange (); - -#if 0 - /* We have no way of knowing whether the initializer will need to be - evaluated at run-time or not until we've parsed it, so let's just put - it in the permanent obstack. (jason) */ - if (init_written - && ! (TREE_CODE (tem) == PARM_DECL - || (TREE_READONLY (tem) - && (TREE_CODE (tem) == VAR_DECL - || TREE_CODE (tem) == FIELD_DECL)))) - { - /* When parsing and digesting the initializer, - use temporary storage. Do this even if we will ignore the value. */ - if (toplevel_bindings_p () && debug_temp_inits) - { - if (processing_template_decl - || TYPE_NEEDS_CONSTRUCTING (type) - || TREE_CODE (type) == REFERENCE_TYPE) - /* In this case, the initializer must lay down in permanent - storage, since it will be saved until `finish_file' is run. */ - ; - else - temporary_allocation (); - } - } -#endif - - return tem; -} - -void -start_decl_1 (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - int initialized = (DECL_INITIAL (decl) != NULL_TREE); - - /* If this type of object needs a cleanup, and control may - jump past it, make a new binding level so that it is cleaned - up only when it is initialized first. */ - if (TYPE_NEEDS_DESTRUCTOR (type) - && current_binding_level->more_cleanups_ok == 0) - pushlevel_temporary (1); - - if (initialized) - /* Is it valid for this decl to have an initializer at all? - If not, set INITIALIZED to zero, which will indirectly - tell `cp_finish_decl' to ignore the initializer once it is parsed. */ - { - /* Don't allow initializations for incomplete types except for - arrays which might be completed by the initialization. */ - if (type == error_mark_node) - ; /* Don't complain again. */ - else if (TYPE_SIZE (complete_type (type)) != NULL_TREE) - ; /* A complete type is ok. */ - else if (TREE_CODE (type) != ARRAY_TYPE) - { - cp_error ("variable `%#D' has initializer but incomplete type", - decl); - initialized = 0; - type = TREE_TYPE (decl) = error_mark_node; - } - else if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) - { - if (DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl)) - cp_error ("elements of array `%#D' have incomplete type", decl); - /* else we already gave an error in start_decl. */ - initialized = 0; - } - } - - if (!initialized - && TREE_CODE (decl) != TYPE_DECL - && TREE_CODE (decl) != TEMPLATE_DECL - && IS_AGGR_TYPE (type) && ! DECL_EXTERNAL (decl)) - { - if ((! processing_template_decl || ! uses_template_parms (type)) - && TYPE_SIZE (complete_type (type)) == NULL_TREE) - { - cp_error ("aggregate `%#D' has incomplete type and cannot be initialized", - decl); - /* Change the type so that assemble_variable will give - DECL an rtl we can live with: (mem (const_int 0)). */ - type = TREE_TYPE (decl) = error_mark_node; - } - else - { - /* If any base type in the hierarchy of TYPE needs a constructor, - then we set initialized to 1. This way any nodes which are - created for the purposes of initializing this aggregate - will live as long as it does. This is necessary for global - aggregates which do not have their initializers processed until - the end of the file. */ - initialized = TYPE_NEEDS_CONSTRUCTING (type); - } - } - -#if 0 - /* We don't do this yet for GNU C++. */ - /* For a local variable, define the RTL now. */ - if (! toplevel_bindings_p () - /* But not if this is a duplicate decl - and we preserved the rtl from the previous one - (which may or may not happen). */ - && DECL_RTL (tem) == NULL_RTX) - { - if (TYPE_SIZE (TREE_TYPE (tem)) != NULL_TREE) - expand_decl (tem); - else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE - && DECL_INITIAL (tem) != NULL_TREE) - expand_decl (tem); - } -#endif - - if (! initialized) - DECL_INITIAL (decl) = NULL_TREE; -} - -/* Handle initialization of references. - These three arguments are from `cp_finish_decl', and have the - same meaning here that they do there. - - Quotes on semantics can be found in ARM 8.4.3. */ - -static void -grok_reference_init (decl, type, init) - tree decl, type, init; -{ - tree tmp; - - if (init == NULL_TREE) - { - if ((DECL_LANG_SPECIFIC (decl) == 0 - || DECL_IN_AGGR_P (decl) == 0) - && ! DECL_THIS_EXTERN (decl)) - { - cp_error ("`%D' declared as reference but not initialized", decl); - if (TREE_CODE (decl) == VAR_DECL) - SET_DECL_REFERENCE_SLOT (decl, error_mark_node); - } - return; - } - - if (init == error_mark_node) - return; - - if (TREE_CODE (type) == REFERENCE_TYPE - && TREE_CODE (init) == CONSTRUCTOR) - { - cp_error ("ANSI C++ forbids use of initializer list to initialize reference `%D'", decl); - return; - } - - if (TREE_CODE (init) == TREE_LIST) - init = build_compound_expr (init); - - if (TREE_CODE (TREE_TYPE (init)) == REFERENCE_TYPE) - init = convert_from_reference (init); - - if (TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE - && TREE_CODE (TREE_TYPE (init)) == ARRAY_TYPE) - { - /* Note: default conversion is only called in very special cases. */ - init = default_conversion (init); - } - - tmp = convert_to_reference - (type, init, CONV_IMPLICIT, - LOOKUP_SPECULATIVELY|LOOKUP_NORMAL|DIRECT_BIND, decl); - - if (tmp == error_mark_node) - goto fail; - else if (tmp != NULL_TREE) - { - init = tmp; - DECL_INITIAL (decl) = save_expr (init); - } - else - { - cp_error ("cannot initialize `%T' from `%T'", type, TREE_TYPE (init)); - goto fail; - } - - /* ?? Can this be optimized in some cases to - hand back the DECL_INITIAL slot?? */ - if (TYPE_SIZE (TREE_TYPE (type))) - { - init = convert_from_reference (decl); - if (TREE_PERMANENT (decl)) - init = copy_to_permanent (init); - SET_DECL_REFERENCE_SLOT (decl, init); - } - - if (TREE_STATIC (decl) && ! TREE_CONSTANT (DECL_INITIAL (decl))) - { - expand_static_init (decl, DECL_INITIAL (decl)); - DECL_INITIAL (decl) = NULL_TREE; - } - return; - - fail: - if (TREE_CODE (decl) == VAR_DECL) - SET_DECL_REFERENCE_SLOT (decl, error_mark_node); - return; -} - -/* Fill in DECL_INITIAL with some magical value to prevent expand_decl from - mucking with forces it does not comprehend (i.e. initialization with a - constructor). If we are at global scope and won't go into COMMON, fill - it in with a dummy CONSTRUCTOR to force the variable into .data; - otherwise we can use error_mark_node. */ - -static tree -obscure_complex_init (decl, init) - tree decl, init; -{ - if (! flag_no_inline && TREE_STATIC (decl)) - { - if (extract_init (decl, init)) - return NULL_TREE; - } - -#if ! defined (ASM_OUTPUT_BSS) && ! defined (ASM_OUTPUT_ALIGNED_BSS) - if (toplevel_bindings_p () && ! DECL_COMMON (decl)) - DECL_INITIAL (decl) = build (CONSTRUCTOR, TREE_TYPE (decl), NULL_TREE, - NULL_TREE); - else -#endif - DECL_INITIAL (decl) = error_mark_node; - - return init; -} - -/* Issue an error message if DECL is an uninitialized const variable. */ - -static void -check_for_uninitialized_const_var (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - - /* ``Unless explicitly declared extern, a const object does not have - external linkage and must be initialized. ($8.4; $12.1)'' ARM - 7.1.6 */ - if (TREE_CODE (decl) == VAR_DECL - && TREE_CODE (type) != REFERENCE_TYPE - && CP_TYPE_CONST_P (type) - && !TYPE_NEEDS_CONSTRUCTING (type) - && !DECL_INITIAL (decl)) - cp_error ("uninitialized const `%D'", decl); -} - -/* Finish processing of a declaration; - install its line number and initial value. - If the length of an array type is not known before, - it must be determined now, from the initial value, or it is an error. - - Call `pop_obstacks' iff NEED_POP is nonzero. - - For C++, `cp_finish_decl' must be fairly evasive: it must keep initializers - for aggregates that have constructors alive on the permanent obstack, - so that the global initializing functions can be written at the end. - - INIT0 holds the value of an initializer that should be allowed to escape - the normal rules. - - FLAGS is LOOKUP_ONLYCONVERTING is the = init syntax was used, else 0 - if the (init) syntax was used. - - For functions that take default parameters, DECL points to its - "maximal" instantiation. `cp_finish_decl' must then also declared its - subsequently lower and lower forms of instantiation, checking for - ambiguity as it goes. This can be sped up later. */ - -void -cp_finish_decl (decl, init, asmspec_tree, need_pop, flags) - tree decl, init; - tree asmspec_tree; - int need_pop; - int flags; -{ - register tree type; - tree cleanup = NULL_TREE, ttype = NULL_TREE; - int was_incomplete; - int temporary = allocation_temporary_p (); - char *asmspec = NULL; - int was_readonly = 0; - int already_used = 0; - - /* If this is 0, then we did not change obstacks. */ - if (! decl) - { - if (init) - error ("assignment (not initialization) in declaration"); - return; - } - - /* If a name was specified, get the string. */ - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - if (init && TREE_CODE (init) == NAMESPACE_DECL) - { - cp_error ("Cannot initialize `%D' to namespace `%D'", - decl, init); - init = NULL_TREE; - } - - if (current_class_type - && DECL_REAL_CONTEXT (decl) == current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && (DECL_INITIAL (decl) || init)) - DECL_DEFINED_IN_CLASS_P (decl) = 1; - - if (TREE_CODE (decl) == VAR_DECL - && DECL_CONTEXT (decl) - && TREE_CODE (DECL_CONTEXT (decl)) == NAMESPACE_DECL - && DECL_CONTEXT (decl) != current_namespace - && init) - { - /* Leave the namespace of the object. */ - pop_decl_namespace (); - } - - /* If the type of the thing we are declaring either has - a constructor, or has a virtual function table pointer, - AND its initialization was accepted by `start_decl', - then we stayed on the permanent obstack through the - declaration, otherwise, changed obstacks as GCC would. */ - - type = TREE_TYPE (decl); - - if (type == error_mark_node) - { - if (toplevel_bindings_p () && temporary) - end_temporary_allocation (); - - return; - } - - if (TYPE_HAS_MUTABLE_P (type)) - TREE_READONLY (decl) = 0; - - if (processing_template_decl) - { - if (init && DECL_INITIAL (decl)) - DECL_INITIAL (decl) = init; - if (minimal_parse_mode && ! DECL_ARTIFICIAL (decl)) - { - tree stmt = DECL_VINDEX (decl); - /* If the decl is declaring a member of a local class (in a - template function), the DECL_VINDEX will either be NULL, - or it will be an actual virtual function index, not a - DECL_STMT. */ - if (stmt != NULL_TREE && TREE_CODE (stmt) == DECL_STMT) - { - DECL_VINDEX (decl) = NULL_TREE; - TREE_OPERAND (stmt, 2) = copy_to_permanent (init); - add_tree (stmt); - } - } - - goto finish_end0; - } - /* Take care of TYPE_DECLs up front. */ - if (TREE_CODE (decl) == TYPE_DECL) - { - if (init && DECL_INITIAL (decl)) - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = type = TREE_TYPE (init); - DECL_INITIAL (decl) = init = NULL_TREE; - } - if (type != error_mark_node - && IS_AGGR_TYPE (type) && DECL_NAME (decl)) - { - if (TREE_TYPE (DECL_NAME (decl)) && TREE_TYPE (decl) != type) - cp_warning ("shadowing previous type declaration of `%#D'", decl); - set_identifier_type_value (DECL_NAME (decl), type); - CLASSTYPE_GOT_SEMICOLON (type) = 1; - } - GNU_xref_decl (current_function_decl, decl); - - /* If we have installed this as the canonical typedef for this - type, and that type has not been defined yet, delay emitting - the debug information for it, as we will emit it later. */ - if (TYPE_MAIN_DECL (TREE_TYPE (decl)) == decl - && TYPE_SIZE (TREE_TYPE (decl)) == NULL_TREE) - TYPE_DECL_SUPPRESS_DEBUG (decl) = 1; - - rest_of_decl_compilation (decl, NULL_PTR, - DECL_CONTEXT (decl) == NULL_TREE, at_eof); - goto finish_end; - } - if (TREE_CODE (decl) != FUNCTION_DECL) - { - ttype = target_type (type); - } - - if (! DECL_EXTERNAL (decl) && TREE_READONLY (decl) - && TYPE_NEEDS_CONSTRUCTING (type)) - { - - /* Currently, GNU C++ puts constants in text space, making them - impossible to initialize. In the future, one would hope for - an operating system which understood the difference between - initialization and the running of a program. */ - was_readonly = 1; - TREE_READONLY (decl) = 0; - } - - if (TREE_CODE (decl) == FIELD_DECL) - { - if (init && init != error_mark_node) - my_friendly_assert (TREE_PERMANENT (init), 147); - - if (asmspec) - { - /* This must override the asm specifier which was placed - by grokclassfn. Lay this out fresh. */ - DECL_RTL (TREE_TYPE (decl)) = NULL_RTX; - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); - make_decl_rtl (decl, asmspec, 0); - } - } - /* If `start_decl' didn't like having an initialization, ignore it now. */ - else if (init != NULL_TREE && DECL_INITIAL (decl) == NULL_TREE) - init = NULL_TREE; - else if (DECL_EXTERNAL (decl)) - ; - else if (TREE_CODE (type) == REFERENCE_TYPE - || (TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE_REFERENCE (type))) - { - if (TREE_STATIC (decl)) - make_decl_rtl (decl, NULL_PTR, - toplevel_bindings_p () - || pseudo_global_level_p ()); - grok_reference_init (decl, type, init); - init = NULL_TREE; - } - - GNU_xref_decl (current_function_decl, decl); - - if (TREE_CODE (decl) == FIELD_DECL) - ; - else if (TREE_CODE (decl) == CONST_DECL) - { - my_friendly_assert (TREE_CODE (decl) != REFERENCE_TYPE, 148); - - DECL_INITIAL (decl) = init; - - /* This will keep us from needing to worry about our obstacks. */ - my_friendly_assert (init != NULL_TREE, 149); - init = NULL_TREE; - } - else if (init) - { - if (TYPE_HAS_CONSTRUCTOR (type) || TYPE_NEEDS_CONSTRUCTING (type)) - { - if (TREE_CODE (type) == ARRAY_TYPE) - init = digest_init (type, init, (tree *) 0); - else if (TREE_CODE (init) == CONSTRUCTOR - && TREE_HAS_CONSTRUCTOR (init)) - { - if (TYPE_NON_AGGREGATE_CLASS (type)) - { - cp_error ("`%D' must be initialized by constructor, not by `{...}'", - decl); - init = error_mark_node; - } - else - goto dont_use_constructor; - } - } - else - { - dont_use_constructor: - if (TREE_CODE (init) != TREE_VEC) - init = store_init_value (decl, init); - } - - if (init) - /* We must hide the initializer so that expand_decl - won't try to do something it does not understand. */ - init = obscure_complex_init (decl, init); - } - else if (DECL_EXTERNAL (decl)) - ; - else if (TREE_CODE_CLASS (TREE_CODE (type)) == 't' - && (IS_AGGR_TYPE (type) || TYPE_NEEDS_CONSTRUCTING (type))) - { - tree ctype = type; - while (TREE_CODE (ctype) == ARRAY_TYPE) - ctype = TREE_TYPE (ctype); - if (! TYPE_NEEDS_CONSTRUCTING (ctype)) - { - if (CLASSTYPE_READONLY_FIELDS_NEED_INIT (ctype)) - cp_error ("structure `%D' with uninitialized const members", decl); - if (CLASSTYPE_REF_FIELDS_NEED_INIT (ctype)) - cp_error ("structure `%D' with uninitialized reference members", - decl); - } - - check_for_uninitialized_const_var (decl); - - if (TYPE_SIZE (type) != NULL_TREE - && TYPE_NEEDS_CONSTRUCTING (type)) - init = obscure_complex_init (decl, NULL_TREE); - - } - else - check_for_uninitialized_const_var (decl); - - /* For top-level declaration, the initial value was read in - the temporary obstack. MAXINDEX, rtl, etc. to be made below - must go in the permanent obstack; but don't discard the - temporary data yet. */ - - if (toplevel_bindings_p () && temporary) - end_temporary_allocation (); - - /* Deduce size of array from initialization, if not already known. */ - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == NULL_TREE - && TREE_CODE (decl) != TYPE_DECL) - { - int do_default - = (TREE_STATIC (decl) - /* Even if pedantic, an external linkage array - may have incomplete type at first. */ - ? pedantic && ! DECL_EXTERNAL (decl) - : !DECL_EXTERNAL (decl)); - tree initializer = init ? init : DECL_INITIAL (decl); - int failure = complete_array_type (type, initializer, do_default); - - if (failure == 1) - cp_error ("initializer fails to determine size of `%D'", decl); - - if (failure == 2) - { - if (do_default) - cp_error ("array size missing in `%D'", decl); - /* If a `static' var's size isn't known, make it extern as - well as static, so it does not get allocated. If it's not - `static', then don't mark it extern; finish_incomplete_decl - will give it a default size and it will get allocated. */ - else if (!pedantic && TREE_STATIC (decl) && !TREE_PUBLIC (decl)) - DECL_EXTERNAL (decl) = 1; - } - - if (pedantic && TYPE_DOMAIN (type) != NULL_TREE - && tree_int_cst_lt (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), - integer_zero_node)) - cp_error ("zero-size array `%D'", decl); - - layout_decl (decl, 0); - } - - if (TREE_CODE (decl) == VAR_DECL) - { - if (DECL_SIZE (decl) == NULL_TREE - && TYPE_SIZE (complete_type (TREE_TYPE (decl))) != NULL_TREE) - layout_decl (decl, 0); - - if (TREE_STATIC (decl) && DECL_SIZE (decl) == NULL_TREE) - { - /* A static variable with an incomplete type: - that is an error if it is initialized. - Otherwise, let it through, but if it is not `extern' - then it may cause an error message later. */ - if (DECL_INITIAL (decl) != NULL_TREE) - cp_error ("storage size of `%D' isn't known", decl); - init = NULL_TREE; - } - else if (!DECL_EXTERNAL (decl) && DECL_SIZE (decl) == NULL_TREE) - { - /* An automatic variable with an incomplete type: that is an error. - Don't talk about array types here, since we took care of that - message in grokdeclarator. */ - cp_error ("storage size of `%D' isn't known", decl); - TREE_TYPE (decl) = error_mark_node; - } - else if (!DECL_EXTERNAL (decl) && IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - - if (TREE_STATIC (decl) && DECL_CLASS_SCOPE_P (decl)) - note_debug_info_needed (DECL_CONTEXT (decl)); - - if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) - && DECL_SIZE (decl) != NULL_TREE - && ! TREE_CONSTANT (DECL_SIZE (decl))) - { - if (TREE_CODE (DECL_SIZE (decl)) == INTEGER_CST) - constant_expression_warning (DECL_SIZE (decl)); - else - cp_error ("storage size of `%D' isn't constant", decl); - } - - if (! DECL_EXTERNAL (decl) && TYPE_NEEDS_DESTRUCTOR (type) - /* Cleanups for static variables are handled by `finish_file'. */ - && ! TREE_STATIC (decl)) - { - int yes = suspend_momentary (); - cleanup = maybe_build_cleanup (decl); - resume_momentary (yes); - } - } - /* PARM_DECLs get cleanups, too. */ - else if (TREE_CODE (decl) == PARM_DECL && TYPE_NEEDS_DESTRUCTOR (type)) - { - if (temporary) - end_temporary_allocation (); - cleanup = maybe_build_cleanup (decl); - if (temporary) - resume_temporary_allocation (); - } - - /* Output the assembler code and/or RTL code for variables and functions, - unless the type is an undefined structure or union. - If not, it will get done when the type is completed. */ - - was_incomplete = (DECL_SIZE (decl) == NULL_TREE); - - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL - || TREE_CODE (decl) == RESULT_DECL) - { - /* ??? FIXME: What about nested classes? */ - int toplev = toplevel_bindings_p () || pseudo_global_level_p (); - int was_temp - = (TREE_STATIC (decl) && TYPE_NEEDS_DESTRUCTOR (type) - && allocation_temporary_p ()); - - if (was_temp) - end_temporary_allocation (); - - /* Static data in a function with comdat linkage also has comdat - linkage. */ - if (TREE_CODE (decl) == VAR_DECL - && TREE_STATIC (decl) - /* Don't mess with __FUNCTION__. */ - && ! TREE_ASM_WRITTEN (decl) - && current_function_decl - && DECL_CONTEXT (decl) == current_function_decl - && (DECL_THIS_INLINE (current_function_decl) - || DECL_TEMPLATE_INSTANTIATION (current_function_decl)) - && TREE_PUBLIC (current_function_decl)) - { - /* Rather than try to get this right with inlining, we suppress - inlining of such functions. */ - current_function_cannot_inline - = "function with static variable cannot be inline"; - - /* If flag_weak, we don't need to mess with this, as we can just - make the function weak, and let it refer to its unique local - copy. This works because we don't allow the function to be - inlined. */ - if (! flag_weak) - { - if (DECL_INTERFACE_KNOWN (current_function_decl)) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = DECL_EXTERNAL (current_function_decl); - } - else if (DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node) - { - TREE_PUBLIC (decl) = 1; - DECL_COMMON (decl) = 1; - } - /* else we lose. We can only do this if we can use common, - which we can't if it has been initialized. */ - - if (TREE_PUBLIC (decl)) - DECL_ASSEMBLER_NAME (decl) - = build_static_name (current_function_decl, DECL_NAME (decl)); - else if (! DECL_ARTIFICIAL (decl)) - { - cp_warning_at ("sorry: semantics of inline function static data `%#D' are wrong (you'll wind up with multiple copies)", decl); - cp_warning_at (" you can work around this by removing the initializer"), decl; - } - } - } - - else if (TREE_CODE (decl) == VAR_DECL - && DECL_LANG_SPECIFIC (decl) - && DECL_COMDAT (decl)) - { - /* Dynamically initialized vars go into common. */ - if (DECL_INITIAL (decl) == NULL_TREE - || DECL_INITIAL (decl) == error_mark_node) - DECL_COMMON (decl) = 1; - else if (EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) - { - DECL_COMMON (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; - } - else - { - /* Statically initialized vars are weak or comdat, if - supported. */ - if (flag_weak) - make_decl_one_only (decl); - else - { - /* We can't do anything useful; leave vars for explicit - instantiation. */ - DECL_EXTERNAL (decl) = 1; - DECL_NOT_REALLY_EXTERN (decl) = 0; - } - } - } - - if (TREE_CODE (decl) == VAR_DECL && DECL_VIRTUAL_P (decl)) - make_decl_rtl (decl, NULL_PTR, toplev); - else if (TREE_CODE (decl) == VAR_DECL - && TREE_READONLY (decl) - && DECL_INITIAL (decl) != NULL_TREE - && DECL_INITIAL (decl) != error_mark_node - && ! EMPTY_CONSTRUCTOR_P (DECL_INITIAL (decl))) - { - DECL_INITIAL (decl) = save_expr (DECL_INITIAL (decl)); - - if (asmspec) - DECL_ASSEMBLER_NAME (decl) = get_identifier (asmspec); - - if (! toplev - && TREE_STATIC (decl) - && ! TREE_SIDE_EFFECTS (decl) - && ! TREE_PUBLIC (decl) - && ! DECL_EXTERNAL (decl) - && ! TYPE_NEEDS_DESTRUCTOR (type) - && DECL_MODE (decl) != BLKmode) - { - /* If this variable is really a constant, then fill its DECL_RTL - slot with something which won't take up storage. - If something later should take its address, we can always give - it legitimate RTL at that time. */ - DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); - store_expr (DECL_INITIAL (decl), DECL_RTL (decl), 0); - TREE_ASM_WRITTEN (decl) = 1; - } - else if (toplev && ! TREE_PUBLIC (decl)) - { - /* If this is a static const, change its apparent linkage - if it belongs to a #pragma interface. */ - if (!interface_unknown) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = interface_only; - } - make_decl_rtl (decl, asmspec, toplev); - } - else - rest_of_decl_compilation (decl, asmspec, toplev, at_eof); - } - else if (TREE_CODE (decl) == VAR_DECL - && DECL_LANG_SPECIFIC (decl) - && DECL_IN_AGGR_P (decl)) - { - if (TREE_STATIC (decl)) - { - if (init == NULL_TREE -#ifdef DEFAULT_STATIC_DEFS - /* If this code is dead, then users must - explicitly declare static member variables - outside the class def'n as well. */ - && TYPE_NEEDS_CONSTRUCTING (type) -#endif - ) - { - DECL_EXTERNAL (decl) = 1; - make_decl_rtl (decl, asmspec, 1); - } - else - rest_of_decl_compilation (decl, asmspec, toplev, at_eof); - } - else - /* Just a constant field. Should not need any rtl. */ - goto finish_end0; - } - else - rest_of_decl_compilation (decl, asmspec, toplev, at_eof); - - if (was_temp) - resume_temporary_allocation (); - - if (type != error_mark_node - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - abstract_virtuals_error (decl, type); - else if ((TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) - && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (type))) - abstract_virtuals_error (decl, TREE_TYPE (type)); - - if (TYPE_LANG_SPECIFIC (type) && IS_SIGNATURE (type)) - signature_error (decl, type); - else if ((TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - && TYPE_LANG_SPECIFIC (TREE_TYPE (type)) - && IS_SIGNATURE (TREE_TYPE (type))) - signature_error (decl, TREE_TYPE (type)); - - if (TREE_CODE (decl) == FUNCTION_DECL) - ; - else if (DECL_EXTERNAL (decl) - && ! (DECL_LANG_SPECIFIC (decl) - && DECL_NOT_REALLY_EXTERN (decl))) - { - if (init) - DECL_INITIAL (decl) = init; - } - else if (TREE_STATIC (decl) && type != error_mark_node) - { - /* Cleanups for static variables are handled by `finish_file'. */ - if (TYPE_NEEDS_CONSTRUCTING (type) || init != NULL_TREE - || TYPE_NEEDS_DESTRUCTOR (type)) - expand_static_init (decl, init); - } - else if (! toplev) - { - /* This is a declared decl which must live until the - end of the binding contour. It may need a cleanup. */ - - /* Recompute the RTL of a local array now - if it used to be an incomplete type. */ - if (was_incomplete && ! TREE_STATIC (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == NULL_TREE) - DECL_INITIAL (decl) = NULL_TREE; - expand_decl (decl); - } - else if (! TREE_ASM_WRITTEN (decl) - && (TYPE_SIZE (type) != NULL_TREE - || TREE_CODE (type) == ARRAY_TYPE)) - { - /* Do this here, because we did not expand this decl's - rtl in start_decl. */ - if (DECL_RTL (decl) == NULL_RTX) - expand_decl (decl); - else if (cleanup) - { - /* XXX: Why don't we use decl here? */ - /* Ans: Because it was already expanded? */ - if (! expand_decl_cleanup (NULL_TREE, cleanup)) - cp_error ("parser lost in parsing declaration of `%D'", - decl); - /* Cleanup used up here. */ - cleanup = NULL_TREE; - } - } - - if (current_binding_level->is_for_scope) - { - struct binding_level *outer - = current_binding_level->level_chain; - - /* Check to see if the same name is already bound at - the outer level, either because it was directly declared, - or because a dead for-decl got preserved. In either case, - the code would not have been valid under the ARM - scope rules, so clear is_for_scope for the - current_binding_level. - - Otherwise, we need to preserve the temp slot for decl - to last into the outer binding level. */ - - tree outer_binding - = TREE_CHAIN (IDENTIFIER_BINDING (DECL_NAME (decl))); - - if (outer_binding && BINDING_LEVEL (outer_binding) == outer - && (TREE_CODE (BINDING_VALUE (outer_binding)) - == VAR_DECL) - && DECL_DEAD_FOR_LOCAL (BINDING_VALUE (outer_binding))) - { - BINDING_VALUE (outer_binding) - = DECL_SHADOWED_FOR_VAR (BINDING_VALUE (outer_binding)); - current_binding_level->is_for_scope = 0; - } - else if (DECL_IN_MEMORY_P (decl)) - preserve_temp_slots (DECL_RTL (decl)); - } - - expand_start_target_temps (); - - if (DECL_SIZE (decl) && type != error_mark_node) - { - /* Compute and store the initial value. */ - expand_decl_init (decl); - already_used = TREE_USED (decl) || TREE_USED (type); - - if (init || TYPE_NEEDS_CONSTRUCTING (type)) - { - emit_line_note (DECL_SOURCE_FILE (decl), - DECL_SOURCE_LINE (decl)); - expand_aggr_init (decl, init, flags); - } - - /* Set this to 0 so we can tell whether an aggregate which - was initialized was ever used. Don't do this if it has a - destructor, so we don't complain about the 'resource - allocation is initialization' idiom. */ - /* Now set attribute((unused)) on types so decls of - that type will be marked used. (see TREE_USED, above.) - This avoids the warning problems this particular code - tried to work around. */ - - if (TYPE_NEEDS_CONSTRUCTING (type) - && ! already_used - && cleanup == NULL_TREE - && DECL_NAME (decl)) - TREE_USED (decl) = 0; - - if (already_used) - TREE_USED (decl) = 1; - } - - /* Cleanup any temporaries needed for the initial value. */ - expand_end_target_temps (); - - if (DECL_SIZE (decl) && type != error_mark_node) - { - /* Store the cleanup, if there was one. */ - if (cleanup) - { - if (! expand_decl_cleanup (decl, cleanup)) - cp_error ("parser lost in parsing declaration of `%D'", - decl); - } - } - } - finish_end0: - - /* Undo call to `pushclass' that was done in `start_decl' - due to initialization of qualified member variable. - I.e., Foo::x = 10; */ - { - tree context = DECL_REAL_CONTEXT (decl); - if (context - && TREE_CODE_CLASS (TREE_CODE (context)) == 't' - && (TREE_CODE (decl) == VAR_DECL - /* We also have a pushclass done that we need to undo here - if we're at top level and declare a method. */ - || TREE_CODE (decl) == FUNCTION_DECL) - /* If size hasn't been set, we're still defining it, - and therefore inside the class body; don't pop - the binding level.. */ - && TYPE_SIZE (context) != NULL_TREE - && context == current_class_type) - popclass (1); - } - } - - finish_end: - - /* If requested, warn about definitions of large data objects. */ - - if (warn_larger_than - && ! processing_template_decl - && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - && !DECL_EXTERNAL (decl)) - { - register tree decl_size = DECL_SIZE (decl); - - if (decl_size && TREE_CODE (decl_size) == INTEGER_CST) - { - unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT; - - if (units > larger_than_size) - warning_with_decl (decl, "size of `%s' is %u bytes", units); - } - } - - if (need_pop) - { - /* Resume permanent allocation, if not within a function. */ - /* The corresponding push_obstacks_nochange is in start_decl, - start_method, groktypename, and in grokfield. */ - pop_obstacks (); - } - - if (was_readonly) - TREE_READONLY (decl) = 1; -} - -/* This is here for a midend callback from c-common.c */ - -void -finish_decl (decl, init, asmspec_tree) - tree decl, init; - tree asmspec_tree; -{ - cp_finish_decl (decl, init, asmspec_tree, 1, 0); -} - -void -expand_static_init (decl, init) - tree decl; - tree init; -{ - tree oldstatic = value_member (decl, static_aggregates); - - if (oldstatic) - { - if (TREE_PURPOSE (oldstatic) && init != NULL_TREE) - cp_error ("multiple initializations given for `%D'", decl); - } - else if (! toplevel_bindings_p () && ! pseudo_global_level_p ()) - { - /* Emit code to perform this initialization but once. */ - tree temp; - - /* Remember this information until end of file. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* Emit code to perform this initialization but once. This code - looks like: - - static int temp = 0; - if (!temp) { - // Do initialization. - temp = 1; - // Register variable for destruction at end of program. - } - - Note that the `temp' variable is only set to 1 *after* the - initialization is complete. This ensures that an exception, - thrown during the construction, will cause the variable to - reinitialized when we pass through this code again, as per: - - [stmt.dcl] - - If the initialization exits by throwing an exception, the - initialization is not complete, so it will be tried again - the next time control enters the declaration. - - In theory, this process should be thread-safe, too; multiple - threads should not be able to initialize the variable more - than once. We don't yet attempt to ensure thread-safety. */ - temp = get_temp_name (integer_type_node, 1); - rest_of_decl_compilation (temp, NULL_PTR, 0, 0); - - /* Begin the conditional initialization. */ - expand_start_cond (build_binary_op (EQ_EXPR, temp, - integer_zero_node, 1), 0); - expand_start_target_temps (); - - /* Do the initialization itself. */ - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl)) - || (init && TREE_CODE (init) == TREE_LIST)) - { - expand_aggr_init (decl, init, 0); - do_pending_stack_adjust (); - } - else if (init) - expand_assignment (decl, init, 0, 0); - - /* Set TEMP to 1. */ - expand_assignment (temp, integer_one_node, 0, 0); - - /* Cleanup any temporaries needed for the initial value. If - destroying one of the temporaries causes an exception to be - thrown, then the object itself has still been fully - constructed. */ - expand_end_target_temps (); - - /* Use atexit to register a function for destroying this static - variable. */ - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) - { - tree cleanup, fcall; - static tree Atexit = 0; - if (Atexit == 0) - { - tree atexit_fndecl, PFV, pfvlist; - /* Remember this information until end of file. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - PFV = build_pointer_type (build_function_type - (void_type_node, void_list_node)); - - pfvlist = tree_cons (NULL_TREE, PFV, void_list_node); - - push_lang_context (lang_name_c); - atexit_fndecl - = builtin_function ("atexit", - build_function_type (void_type_node, - pfvlist), - NOT_BUILT_IN, NULL_PTR); - mark_used (atexit_fndecl); - Atexit = default_conversion (atexit_fndecl); - pop_lang_context (); - pop_obstacks (); - } - - /* Call build_cleanup before we enter the anonymous function - so that any access checks will be done relative to the - current scope, rather than the scope of the anonymous - function. */ - fcall = build_cleanup (decl); - cleanup = start_anon_func (); - expand_expr_stmt (fcall); - end_anon_func (); - mark_addressable (cleanup); - cleanup = build_unary_op (ADDR_EXPR, cleanup, 0); - fcall = build_function_call (Atexit, expr_tree_cons (NULL_TREE, cleanup, NULL_TREE)); - expand_expr_stmt (fcall); - } - - expand_end_cond (); - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (decl))) - { - static_aggregates = perm_tree_cons (temp, decl, static_aggregates); - TREE_STATIC (static_aggregates) = 1; - } - - /* Resume old (possibly temporary) allocation. */ - pop_obstacks (); - } - else - { - /* This code takes into account memory allocation - policy of `start_decl'. Namely, if TYPE_NEEDS_CONSTRUCTING - does not hold for this object, then we must make permanent - the storage currently in the temporary obstack. */ - if (! TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - preserve_initializer (); - static_aggregates = perm_tree_cons (init, decl, static_aggregates); - } -} - -/* Make TYPE a complete type based on INITIAL_VALUE. - Return 0 if successful, 1 if INITIAL_VALUE can't be deciphered, - 2 if there was no information (in which case assume 1 if DO_DEFAULT). */ - -int -complete_array_type (type, initial_value, do_default) - tree type, initial_value; - int do_default; -{ - register tree maxindex = NULL_TREE; - int value = 0; - - if (initial_value) - { - /* Note MAXINDEX is really the maximum index, - one less than the size. */ - if (TREE_CODE (initial_value) == STRING_CST) - { - int eltsize - = int_size_in_bytes (TREE_TYPE (TREE_TYPE (initial_value))); - maxindex = build_int_2 ((TREE_STRING_LENGTH (initial_value) - / eltsize) - 1, 0); - } - else if (TREE_CODE (initial_value) == CONSTRUCTOR) - { - tree elts = CONSTRUCTOR_ELTS (initial_value); - maxindex = size_binop (MINUS_EXPR, integer_zero_node, size_one_node); - for (; elts; elts = TREE_CHAIN (elts)) - { - if (TREE_PURPOSE (elts)) - maxindex = TREE_PURPOSE (elts); - else - maxindex = size_binop (PLUS_EXPR, maxindex, size_one_node); - } - maxindex = copy_node (maxindex); - } - else - { - /* Make an error message unless that happened already. */ - if (initial_value != error_mark_node) - value = 1; - - /* Prevent further error messages. */ - maxindex = build_int_2 (0, 0); - } - } - - if (!maxindex) - { - if (do_default) - maxindex = build_int_2 (0, 0); - value = 2; - } - - if (maxindex) - { - tree itype; - - TYPE_DOMAIN (type) = build_index_type (maxindex); - if (! TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (type); - if (initial_value) - itype = TREE_TYPE (initial_value); - else - itype = NULL; - if (itype && !TYPE_DOMAIN (itype)) - TYPE_DOMAIN (itype) = TYPE_DOMAIN (type); - /* The type of the main variant should never be used for arrays - of different sizes. It should only ever be completed with the - size of the array. */ - if (! TYPE_DOMAIN (TYPE_MAIN_VARIANT (type))) - TYPE_DOMAIN (TYPE_MAIN_VARIANT (type)) = TYPE_DOMAIN (type); - } - - /* Lay out the type now that we can get the real answer. */ - - layout_type (type); - - return value; -} - -/* Return zero if something is declared to be a member of type - CTYPE when in the context of CUR_TYPE. STRING is the error - message to print in that case. Otherwise, quietly return 1. */ - -static int -member_function_or_else (ctype, cur_type, string) - tree ctype, cur_type; - char *string; -{ - if (ctype && ctype != cur_type) - { - error (string, TYPE_NAME_STRING (ctype)); - return 0; - } - return 1; -} - -/* Subroutine of `grokdeclarator'. */ - -/* Generate errors possibly applicable for a given set of specifiers. - This is for ARM $7.1.2. */ - -static void -bad_specifiers (object, type, virtualp, quals, inlinep, friendp, raises) - tree object; - char *type; - int virtualp, quals, friendp, raises, inlinep; -{ - if (virtualp) - cp_error ("`%D' declared as a `virtual' %s", object, type); - if (inlinep) - cp_error ("`%D' declared as an `inline' %s", object, type); - if (quals) - cp_error ("`const' and `volatile' function specifiers on `%D' invalid in %s declaration", - object, type); - if (friendp) - cp_error_at ("invalid friend declaration", object); - if (raises) - cp_error_at ("invalid exception specifications", object); -} - -/* CTYPE is class type, or null if non-class. - TYPE is type this FUNCTION_DECL should have, either FUNCTION_TYPE - or METHOD_TYPE. - DECLARATOR is the function's name. - VIRTUALP is truthvalue of whether the function is virtual or not. - FLAGS are to be passed through to `grokclassfn'. - QUALS are qualifiers indicating whether the function is `const' - or `volatile'. - RAISES is a list of exceptions that this function can raise. - CHECK is 1 if we must find this method in CTYPE, 0 if we should - not look, and -1 if we should not call `grokclassfn' at all. - - Returns `error_mark_node' if something goes wrong, after issuing - applicable error messages. */ - -static tree -grokfndecl (ctype, type, declarator, orig_declarator, virtualp, flags, quals, - raises, attrlist, check, friendp, publicp, inlinep, funcdef_flag, - template_count, in_namespace) - tree ctype, type; - tree declarator; - tree orig_declarator; - int virtualp; - enum overload_flags flags; - tree quals, raises, attrlist; - int check, friendp, publicp, inlinep, funcdef_flag, template_count; - tree in_namespace; -{ - tree cname, decl; - int staticp = ctype && TREE_CODE (type) == FUNCTION_TYPE; - tree t; - - if (ctype) - cname = TREE_CODE (TYPE_NAME (ctype)) == TYPE_DECL - ? TYPE_IDENTIFIER (ctype) : TYPE_NAME (ctype); - else - cname = NULL_TREE; - - if (raises) - { - type = build_exception_variant (type, raises); - } - - decl = build_lang_decl (FUNCTION_DECL, declarator, type); - /* Propagate volatile out from type to decl. */ - if (TYPE_VOLATILE (type)) - TREE_THIS_VOLATILE (decl) = 1; - - /* If this decl has namespace scope, set that up. */ - if (in_namespace) - set_decl_namespace (decl, in_namespace); - else if (publicp && ! ctype) - DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); - - /* `main' and builtins have implicit 'C' linkage. */ - if ((MAIN_NAME_P (declarator) - || (IDENTIFIER_LENGTH (declarator) > 10 - && IDENTIFIER_POINTER (declarator)[0] == '_' - && IDENTIFIER_POINTER (declarator)[1] == '_' - && strncmp (IDENTIFIER_POINTER (declarator)+2, "builtin_", 8) == 0)) - && current_lang_name == lang_name_cplusplus - && ctype == NULL_TREE - /* NULL_TREE means global namespace. */ - && DECL_CONTEXT (decl) == NULL_TREE) - DECL_LANGUAGE (decl) = lang_c; - - /* Should probably propagate const out from type to decl I bet (mrs). */ - if (staticp) - { - DECL_STATIC_FUNCTION_P (decl) = 1; - DECL_CONTEXT (decl) = ctype; - } - - if (ctype) - DECL_CLASS_CONTEXT (decl) = ctype; - - if (ctype == NULL_TREE && DECL_MAIN_P (decl)) - { - if (processing_template_decl) - error ("cannot declare `main' to be a template"); - if (inlinep) - error ("cannot declare `main' to be inline"); - else if (! publicp) - error ("cannot declare `main' to be static"); - inlinep = 0; - publicp = 1; - } - - /* Members of anonymous types and local classes have no linkage; make - them internal. */ - if (ctype && (ANON_AGGRNAME_P (TYPE_IDENTIFIER (ctype)) - || hack_decl_function_context (TYPE_MAIN_DECL (ctype)))) - publicp = 0; - - if (publicp) - { - /* [basic.link]: A name with no linkage (notably, the name of a class - or enumeration declared in a local scope) shall not be used to - declare an entity with linkage. - - Only check this for public decls for now. */ - t = no_linkage_check (TREE_TYPE (decl)); - if (t) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) - { - if (DECL_LANGUAGE (decl) == lang_c) - /* Allow this; it's pretty common in C. */; - else - cp_pedwarn ("non-local function `%#D' uses anonymous type", - decl); - } - else - cp_pedwarn ("non-local function `%#D' uses local type `%T'", - decl, t); - } - } - - TREE_PUBLIC (decl) = publicp; - if (! publicp) - { - DECL_INTERFACE_KNOWN (decl) = 1; - DECL_NOT_REALLY_EXTERN (decl) = 1; - } - - if (inlinep) - DECL_THIS_INLINE (decl) = DECL_INLINE (decl) = 1; - - DECL_EXTERNAL (decl) = 1; - if (quals != NULL_TREE && TREE_CODE (type) == FUNCTION_TYPE) - { - cp_error ("%smember function `%D' cannot have `%T' method qualifier", - (ctype ? "static " : "non-"), decl, TREE_VALUE (quals)); - quals = NULL_TREE; - } - - if (IDENTIFIER_OPNAME_P (DECL_NAME (decl))) - grok_op_properties (decl, virtualp, check < 0); - - if (ctype && hack_decl_function_context (decl)) - DECL_NO_STATIC_CHAIN (decl) = 1; - - for (t = TYPE_ARG_TYPES (TREE_TYPE (decl)); t; t = TREE_CHAIN (t)) - if (TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) - { - add_defarg_fn (decl); - break; - } - - if (friendp - && TREE_CODE (orig_declarator) == TEMPLATE_ID_EXPR) - { - if (funcdef_flag) - cp_error - ("defining explicit specialization `%D' in friend declaration", - orig_declarator); - else - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - { - /* Something like `template <class T> friend void f<T>()'. */ - cp_error ("template-id `%D' in declaration of primary template", - orig_declarator); - return error_mark_node; - } - - /* A friend declaration of the form friend void f<>(). Record - the information in the TEMPLATE_ID_EXPR. */ - SET_DECL_IMPLICIT_INSTANTIATION (decl); - DECL_TEMPLATE_INFO (decl) - = perm_tree_cons (TREE_OPERAND (orig_declarator, 0), - TREE_OPERAND (orig_declarator, 1), - NULL_TREE); - } - } - - /* Plain overloading: will not be grok'd by grokclassfn. */ - if (! ctype && ! processing_template_decl - && DECL_LANGUAGE (decl) != lang_c - && (! DECL_USE_TEMPLATE (decl) || name_mangling_version < 1)) - set_mangled_name_for_decl (decl); - - if (funcdef_flag) - /* Make the init_value nonzero so pushdecl knows this is not - tentative. error_mark_node is replaced later with the BLOCK. */ - DECL_INITIAL (decl) = error_mark_node; - - /* Caller will do the rest of this. */ - if (check < 0) - return decl; - - if (check && funcdef_flag) - DECL_INITIAL (decl) = error_mark_node; - - if (flags == NO_SPECIAL && ctype && constructor_name (cname) == declarator) - { - tree tmp; - /* Just handle constructors here. We could do this - inside the following if stmt, but I think - that the code is more legible by breaking this - case out. See comments below for what each of - the following calls is supposed to do. */ - DECL_CONSTRUCTOR_P (decl) = 1; - - grokclassfn (ctype, decl, flags, quals); - - decl = check_explicit_specialization (orig_declarator, decl, - template_count, - 2 * (funcdef_flag != 0) + - 4 * (friendp != 0)); - if (decl == error_mark_node) - return error_mark_node; - - if ((! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) - && check) - { - tmp = check_classfn (ctype, decl); - - if (tmp && TREE_CODE (tmp) == TEMPLATE_DECL) - tmp = DECL_TEMPLATE_RESULT(tmp); - - if (tmp && DECL_ARTIFICIAL (tmp)) - cp_error ("definition of implicitly-declared `%D'", tmp); - if (tmp && duplicate_decls (decl, tmp)) - return tmp; - } - if (! grok_ctor_properties (ctype, decl)) - return error_mark_node; - } - else - { - tree tmp; - - /* Function gets the ugly name, field gets the nice one. - This call may change the type of the function (because - of default parameters)! */ - if (ctype != NULL_TREE) - grokclassfn (ctype, decl, flags, quals); - - decl = check_explicit_specialization (orig_declarator, decl, - template_count, - 2 * (funcdef_flag != 0) + - 4 * (friendp != 0)); - if (decl == error_mark_node) - return error_mark_node; - - if (ctype != NULL_TREE - && (! TYPE_FOR_JAVA (ctype) || check_java_method (decl)) - && check) - { - tmp = check_classfn (ctype, decl); - - if (tmp && TREE_CODE (tmp) == TEMPLATE_DECL) - tmp = DECL_TEMPLATE_RESULT (tmp); - - if (tmp && DECL_STATIC_FUNCTION_P (tmp) - && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - { - /* Remove the `this' parm added by grokclassfn. - XXX Isn't this done in start_function, too? */ - revert_static_member_fn (&decl, NULL, NULL); - last_function_parms = TREE_CHAIN (last_function_parms); - } - if (tmp && DECL_ARTIFICIAL (tmp)) - cp_error ("definition of implicitly-declared `%D'", tmp); - if (tmp) - { - if (!duplicate_decls (decl, tmp)) - my_friendly_abort (892); - return tmp; - } - } - - if (ctype == NULL_TREE || check) - return decl; - - if (attrlist) - cplus_decl_attributes (decl, TREE_PURPOSE (attrlist), - TREE_VALUE (attrlist)); - make_decl_rtl (decl, NULL_PTR, 1); - - if (virtualp) - { - DECL_VIRTUAL_P (decl) = 1; - if (DECL_VINDEX (decl) == NULL_TREE) - DECL_VINDEX (decl) = error_mark_node; - IDENTIFIER_VIRTUAL_P (DECL_NAME (decl)) = 1; - } - } - return decl; -} - -static tree -grokvardecl (type, declarator, specbits_in, initialized, constp, in_namespace) - tree type; - tree declarator; - RID_BIT_TYPE *specbits_in; - int initialized; - int constp; - tree in_namespace; -{ - tree decl; - RID_BIT_TYPE specbits; - - specbits = *specbits_in; - - if (TREE_CODE (type) == OFFSET_TYPE) - { - /* If you declare a static member so that it - can be initialized, the code will reach here. */ - tree basetype = TYPE_OFFSET_BASETYPE (type); - type = TREE_TYPE (type); - decl = build_lang_field_decl (VAR_DECL, declarator, type); - DECL_CONTEXT (decl) = basetype; - DECL_CLASS_CONTEXT (decl) = basetype; - DECL_ASSEMBLER_NAME (decl) = build_static_name (basetype, declarator); - } - else - { - tree context; - - if (in_namespace) - context = in_namespace; - else if (namespace_bindings_p () || RIDBIT_SETP (RID_EXTERN, specbits)) - context = current_namespace; - else - context = NULL_TREE; - - decl = build_decl (VAR_DECL, declarator, complete_type (type)); - - if (context) - set_decl_namespace (decl, context); - - context = DECL_CONTEXT (decl); - if (declarator && context && current_lang_name != lang_name_c) - DECL_ASSEMBLER_NAME (decl) = build_static_name (context, declarator); - } - - if (in_namespace) - set_decl_namespace (decl, in_namespace); - - if (RIDBIT_SETP (RID_EXTERN, specbits)) - { - DECL_THIS_EXTERN (decl) = 1; - DECL_EXTERNAL (decl) = !initialized; - } - - /* In class context, static means one per class, - public access, and static storage. */ - if (DECL_CLASS_SCOPE_P (decl)) - { - TREE_PUBLIC (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_EXTERNAL (decl) = 0; - } - /* At top level, either `static' or no s.c. makes a definition - (perhaps tentative), and absence of `static' makes it public. */ - else if (toplevel_bindings_p ()) - { - TREE_PUBLIC (decl) = (RIDBIT_NOTSETP (RID_STATIC, specbits) - && (DECL_THIS_EXTERN (decl) || ! constp)); - TREE_STATIC (decl) = ! DECL_EXTERNAL (decl); - } - /* Not at top level, only `static' makes a static definition. */ - else - { - TREE_STATIC (decl) = !! RIDBIT_SETP (RID_STATIC, specbits); - TREE_PUBLIC (decl) = DECL_EXTERNAL (decl); - } - - if (TREE_PUBLIC (decl)) - { - /* [basic.link]: A name with no linkage (notably, the name of a class - or enumeration declared in a local scope) shall not be used to - declare an entity with linkage. - - Only check this for public decls for now. */ - tree t = no_linkage_check (TREE_TYPE (decl)); - if (t) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) - /* Ignore for now; `enum { foo } e' is pretty common. */; - else - cp_pedwarn ("non-local variable `%#D' uses local type `%T'", - decl, t); - } - } - - return decl; -} - -/* Create and return a canonical pointer to member function type, for - TYPE, which is a POINTER_TYPE to a METHOD_TYPE. */ - -tree -build_ptrmemfunc_type (type) - tree type; -{ - tree fields[4]; - tree t; - tree u; - - /* If a canonical type already exists for this type, use it. We use - this method instead of type_hash_canon, because it only does a - simple equality check on the list of field members. */ - - if ((t = TYPE_GET_PTRMEMFUNC_TYPE (type))) - return t; - - push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); - - u = make_lang_type (UNION_TYPE); - SET_IS_AGGR_TYPE (u, 0); - fields[0] = build_lang_field_decl (FIELD_DECL, pfn_identifier, type); - fields[1] = build_lang_field_decl (FIELD_DECL, delta2_identifier, - delta_type_node); - finish_builtin_type (u, "__ptrmemfunc_type", fields, 1, ptr_type_node); - TYPE_NAME (u) = NULL_TREE; - - t = make_lang_type (RECORD_TYPE); - - /* Let the front-end know this is a pointer to member function... */ - TYPE_PTRMEMFUNC_FLAG (t) = 1; - /* ... and not really an aggregate. */ - SET_IS_AGGR_TYPE (t, 0); - - fields[0] = build_lang_field_decl (FIELD_DECL, delta_identifier, - delta_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, index_identifier, - delta_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, pfn_or_delta2_identifier, u); - finish_builtin_type (t, "__ptrmemfunc_type", fields, 2, ptr_type_node); - - pop_obstacks (); - - /* Zap out the name so that the back-end will give us the debugging - information for this anonymous RECORD_TYPE. */ - TYPE_NAME (t) = NULL_TREE; - - TYPE_SET_PTRMEMFUNC_TYPE (type, t); - - /* Seems to be wanted. */ - CLASSTYPE_GOT_SEMICOLON (t) = 1; - return t; -} - -/* Given declspecs and a declarator, - determine the name and type of the object declared - and construct a ..._DECL node for it. - (In one case we can return a ..._TYPE node instead. - For invalid input we sometimes return 0.) - - DECLSPECS is a chain of tree_list nodes whose value fields - are the storage classes and type specifiers. - - DECL_CONTEXT says which syntactic context this declaration is in: - NORMAL for most contexts. Make a VAR_DECL or FUNCTION_DECL or TYPE_DECL. - FUNCDEF for a function definition. Like NORMAL but a few different - error messages in each case. Return value may be zero meaning - this definition is too screwy to try to parse. - MEMFUNCDEF for a function definition. Like FUNCDEF but prepares to - handle member functions (which have FIELD context). - Return value may be zero meaning this definition is too screwy to - try to parse. - PARM for a parameter declaration (either within a function prototype - or before a function body). Make a PARM_DECL, or return void_type_node. - CATCHPARM for a parameter declaration before a catch clause. - TYPENAME if for a typename (in a cast or sizeof). - Don't make a DECL node; just return the ..._TYPE node. - FIELD for a struct or union field; make a FIELD_DECL. - BITFIELD for a field with specified width. - INITIALIZED is 1 if the decl has an initializer. - - ATTRLIST is a TREE_LIST node with prefix attributes in TREE_VALUE and - normal attributes in TREE_PURPOSE, or NULL_TREE. - - In the TYPENAME case, DECLARATOR is really an absolute declarator. - It may also be so in the PARM case, for a prototype where the - argument type is specified but not the name. - - This function is where the complicated C meanings of `static' - and `extern' are interpreted. - - For C++, if there is any monkey business to do, the function which - calls this one must do it, i.e., prepending instance variables, - renaming overloaded function names, etc. - - Note that for this C++, it is an error to define a method within a class - which does not belong to that class. - - Except in the case where SCOPE_REFs are implicitly known (such as - methods within a class being redundantly qualified), - declarations which involve SCOPE_REFs are returned as SCOPE_REFs - (class_name::decl_name). The caller must also deal with this. - - If a constructor or destructor is seen, and the context is FIELD, - then the type gains the attribute TREE_HAS_x. If such a declaration - is erroneous, NULL_TREE is returned. - - QUALS is used only for FUNCDEF and MEMFUNCDEF cases. For a member - function, these are the qualifiers to give to the `this' pointer. - - May return void_type_node if the declarator turned out to be a friend. - See grokfield for details. */ - -enum return_types { return_normal, return_ctor, return_dtor, return_conversion }; - -/* DECL is a VAR_DECL defined in-class, whose TYPE is also given. - Check to see that the definition is valid. Issue appropriate error - messages. Return 1 if the definition is particularly bad, or 0 - otherwise. */ - -int -check_static_variable_definition (decl, type) - tree decl; - tree type; -{ - /* Motion 10 at San Diego: If a static const integral data member is - initialized with an integral constant expression, the initializer - may appear either in the declaration (within the class), or in - the definition, but not both. If it appears in the class, the - member is a member constant. The file-scope definition is always - required. */ - if (CLASS_TYPE_P (type) || TREE_CODE (type) == REFERENCE_TYPE) - { - cp_error ("in-class initialization of static data member of non-integral type `%T'", - type); - /* If we just return the declaration, crashes will sometimes - occur. We therefore return void_type_node, as if this was a - friend declaration, to cause callers to completely ignore - this declaration. */ - return 1; - } - else if (!CP_TYPE_CONST_P (type)) - cp_error ("ANSI C++ forbids in-class initialization of non-const static member `%D'", - decl); - else if (pedantic && !INTEGRAL_TYPE_P (type)) - cp_pedwarn ("ANSI C++ forbids initialization of member constant `%D' of non-integral type `%T'", decl, type); - - return 0; -} - -tree -grokdeclarator (declarator, declspecs, decl_context, initialized, attrlist) - tree declspecs; - tree declarator; - enum decl_context decl_context; - int initialized; - tree attrlist; -{ - RID_BIT_TYPE specbits; - int nclasses = 0; - tree spec; - tree type = NULL_TREE; - int longlong = 0; - int constp; - int restrictp; - int volatilep; - int type_quals; - int virtualp, explicitp, friendp, inlinep, staticp; - int explicit_int = 0; - int explicit_char = 0; - int defaulted_int = 0; - int opaque_typedef = 0; - tree typedef_decl = NULL_TREE; - char *name; - tree typedef_type = NULL_TREE; - int funcdef_flag = 0; - enum tree_code innermost_code = ERROR_MARK; - int bitfield = 0; -#if 0 - /* See the code below that used this. */ - tree decl_machine_attr = NULL_TREE; -#endif - /* Set this to error_mark_node for FIELD_DECLs we could not handle properly. - All FIELD_DECLs we build here have `init' put into their DECL_INITIAL. */ - tree init = NULL_TREE; - - /* Keep track of what sort of function is being processed - so that we can warn about default return values, or explicit - return values which do not match prescribed defaults. */ - enum return_types return_type = return_normal; - - tree dname = NULL_TREE; - tree ctype = current_class_type; - tree ctor_return_type = NULL_TREE; - enum overload_flags flags = NO_SPECIAL; - tree quals = NULL_TREE; - tree raises = NULL_TREE; - int template_count = 0; - tree in_namespace = NULL_TREE; - tree inner_attrs; - int ignore_attrs; - - RIDBIT_RESET_ALL (specbits); - if (decl_context == FUNCDEF) - funcdef_flag = 1, decl_context = NORMAL; - else if (decl_context == MEMFUNCDEF) - funcdef_flag = -1, decl_context = FIELD; - else if (decl_context == BITFIELD) - bitfield = 1, decl_context = FIELD; - - /* Look inside a declarator for the name being declared - and get it as a string, for an error message. */ - { - tree *next = &declarator; - register tree decl; - name = NULL; - - while (next && *next) - { - decl = *next; - switch (TREE_CODE (decl)) - { - case TREE_LIST: - /* For attributes. */ - next = &TREE_VALUE (decl); - break; - - case COND_EXPR: - ctype = NULL_TREE; - next = &TREE_OPERAND (decl, 0); - break; - - case BIT_NOT_EXPR: /* For C++ destructors! */ - { - tree name = TREE_OPERAND (decl, 0); - tree rename = NULL_TREE; - - my_friendly_assert (flags == NO_SPECIAL, 152); - flags = DTOR_FLAG; - return_type = return_dtor; - if (TREE_CODE (name) == TYPE_DECL) - TREE_OPERAND (decl, 0) = name = constructor_name (name); - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 153); - if (ctype == NULL_TREE) - { - if (current_class_type == NULL_TREE) - { - error ("destructors must be member functions"); - flags = NO_SPECIAL; - } - else - { - tree t = constructor_name (current_class_name); - if (t != name) - rename = t; - } - } - else - { - tree t = constructor_name (ctype); - if (t != name) - rename = t; - } - - if (rename) - { - cp_error ("destructor `%T' must match class name `%T'", - name, rename); - TREE_OPERAND (decl, 0) = rename; - } - next = &name; - } - break; - - case ADDR_EXPR: /* C++ reference declaration */ - /* Fall through. */ - case ARRAY_REF: - case INDIRECT_REF: - ctype = NULL_TREE; - innermost_code = TREE_CODE (decl); - next = &TREE_OPERAND (decl, 0); - break; - - case CALL_EXPR: - if (parmlist_is_exprlist (TREE_OPERAND (decl, 1))) - { - /* This is actually a variable declaration using - constructor syntax. We need to call start_decl and - cp_finish_decl so we can get the variable - initialized... */ - - tree attributes, prefix_attributes; - - *next = TREE_OPERAND (decl, 0); - init = TREE_OPERAND (decl, 1); - - if (attrlist) - { - attributes = TREE_PURPOSE (attrlist); - prefix_attributes = TREE_VALUE (attrlist); - } - else - { - attributes = NULL_TREE; - prefix_attributes = NULL_TREE; - } - - decl = start_decl (declarator, declspecs, 1, - attributes, prefix_attributes); - if (decl) - { - /* Look for __unused__ attribute */ - if (TREE_USED (TREE_TYPE (decl))) - TREE_USED (decl) = 1; - finish_decl (decl, init, NULL_TREE); - } - else - cp_error ("invalid declarator"); - return 0; - } - innermost_code = TREE_CODE (decl); - if (decl_context == FIELD && ctype == NULL_TREE) - ctype = current_class_type; - if (ctype - && TREE_OPERAND (decl, 0) - && (TREE_CODE (TREE_OPERAND (decl, 0)) == TYPE_DECL - && ((DECL_NAME (TREE_OPERAND (decl, 0)) - == constructor_name_full (ctype)) - || (DECL_NAME (TREE_OPERAND (decl, 0)) - == constructor_name (ctype))))) - TREE_OPERAND (decl, 0) = constructor_name (ctype); - next = &TREE_OPERAND (decl, 0); - decl = *next; - if (ctype != NULL_TREE - && decl != NULL_TREE && flags != DTOR_FLAG - && decl == constructor_name (ctype)) - { - return_type = return_ctor; - ctor_return_type = ctype; - } - ctype = NULL_TREE; - break; - - case TEMPLATE_ID_EXPR: - { - tree fns = TREE_OPERAND (decl, 0); - - if (TREE_CODE (fns) == LOOKUP_EXPR) - fns = TREE_OPERAND (fns, 0); - - if (TREE_CODE (fns) == IDENTIFIER_NODE) - dname = fns; - else if (is_overloaded_fn (fns)) - dname = DECL_NAME (get_first_fn (fns)); - else - my_friendly_abort (0); - } - /* Fall through. */ - - case IDENTIFIER_NODE: - if (TREE_CODE (decl) == IDENTIFIER_NODE) - dname = decl; - - next = 0; - - if (is_rid (dname)) - { - cp_error ("declarator-id missing; using reserved word `%D'", - dname); - name = IDENTIFIER_POINTER (dname); - } - if (! IDENTIFIER_OPNAME_P (dname) - /* GNU/Linux headers use '__op'. Arrgh. */ - || (IDENTIFIER_TYPENAME_P (dname) && ! TREE_TYPE (dname))) - name = IDENTIFIER_POINTER (dname); - else - { - if (IDENTIFIER_TYPENAME_P (dname)) - { - my_friendly_assert (flags == NO_SPECIAL, 154); - flags = TYPENAME_FLAG; - ctor_return_type = TREE_TYPE (dname); - return_type = return_conversion; - } - name = operator_name_string (dname); - } - break; - - /* C++ extension */ - case SCOPE_REF: - { - /* Perform error checking, and decide on a ctype. */ - tree cname = TREE_OPERAND (decl, 0); - if (cname == NULL_TREE) - ctype = NULL_TREE; - else if (TREE_CODE (cname) == NAMESPACE_DECL) - { - ctype = NULL_TREE; - in_namespace = TREE_OPERAND (decl, 0); - TREE_OPERAND (decl, 0) = NULL_TREE; - } - else if (! is_aggr_type (cname, 1)) - TREE_OPERAND (decl, 0) = NULL_TREE; - /* Must test TREE_OPERAND (decl, 1), in case user gives - us `typedef (class::memfunc)(int); memfunc *memfuncptr;' */ - else if (TREE_OPERAND (decl, 1) - && TREE_CODE (TREE_OPERAND (decl, 1)) == INDIRECT_REF) - ctype = cname; - else if (TREE_CODE (cname) == TEMPLATE_TYPE_PARM - || TREE_CODE (cname) == TEMPLATE_TEMPLATE_PARM) - { - cp_error ("`%T::%D' is not a valid declarator", cname, - TREE_OPERAND (decl, 1)); - cp_error (" perhaps you want `typename %T::%D' to make it a type", - cname, TREE_OPERAND (decl, 1)); - return void_type_node; - } - else if (ctype == NULL_TREE) - ctype = cname; - else if (TREE_COMPLEXITY (decl) == current_class_depth) - TREE_OPERAND (decl, 0) = ctype; - else - { - if (! UNIQUELY_DERIVED_FROM_P (cname, ctype)) - { - cp_error ("type `%T' is not derived from type `%T'", - cname, ctype); - TREE_OPERAND (decl, 0) = NULL_TREE; - } - else - ctype = cname; - } - - if (ctype && TREE_CODE (TREE_OPERAND (decl, 1)) == TYPE_DECL - && ((DECL_NAME (TREE_OPERAND (decl, 1)) - == constructor_name_full (ctype)) - || (DECL_NAME (TREE_OPERAND (decl, 1)) - == constructor_name (ctype)))) - TREE_OPERAND (decl, 1) = constructor_name (ctype); - next = &TREE_OPERAND (decl, 1); - decl = *next; - if (ctype) - { - if (TREE_CODE (decl) == IDENTIFIER_NODE - && constructor_name (ctype) == decl) - { - return_type = return_ctor; - ctor_return_type = ctype; - } - else if (TREE_CODE (decl) == BIT_NOT_EXPR - && TREE_CODE (TREE_OPERAND (decl, 0)) == IDENTIFIER_NODE - && (constructor_name (ctype) == TREE_OPERAND (decl, 0) - || constructor_name_full (ctype) == TREE_OPERAND (decl, 0))) - { - return_type = return_dtor; - ctor_return_type = ctype; - flags = DTOR_FLAG; - TREE_OPERAND (decl, 0) = constructor_name (ctype); - next = &TREE_OPERAND (decl, 0); - } - } - } - break; - - case ERROR_MARK: - next = 0; - break; - - case TYPE_DECL: - /* Parse error puts this typespec where - a declarator should go. */ - cp_error ("`%T' specified as declarator-id", DECL_NAME (decl)); - if (TREE_TYPE (decl) == current_class_type) - cp_error (" perhaps you want `%T' for a constructor", - current_class_name); - dname = DECL_NAME (decl); - name = IDENTIFIER_POINTER (dname); - - /* Avoid giving two errors for this. */ - IDENTIFIER_CLASS_VALUE (dname) = NULL_TREE; - - declspecs = temp_tree_cons (NULL_TREE, integer_type_node, - declspecs); - *next = dname; - next = 0; - break; - - default: - cp_compiler_error ("`%D' as declarator", decl); - return 0; /* We used to do a 155 abort here. */ - } - } - if (name == NULL) - name = "type name"; - } - - /* A function definition's declarator must have the form of - a function declarator. */ - - if (funcdef_flag && innermost_code != CALL_EXPR) - return 0; - - if (((dname && IDENTIFIER_OPNAME_P (dname)) || flags == TYPENAME_FLAG) - && innermost_code != CALL_EXPR - && ! (ctype && declspecs == NULL_TREE)) - { - cp_error ("declaration of `%D' as non-function", dname); - return void_type_node; - } - - /* Anything declared one level down from the top level - must be one of the parameters of a function - (because the body is at least two levels down). */ - - /* This heuristic cannot be applied to C++ nodes! Fixed, however, - by not allowing C++ class definitions to specify their parameters - with xdecls (must be spec.d in the parmlist). - - Since we now wait to push a class scope until we are sure that - we are in a legitimate method context, we must set oldcname - explicitly (since current_class_name is not yet alive). - - We also want to avoid calling this a PARM if it is in a namespace. */ - - if (decl_context == NORMAL && ! namespace_bindings_p () - && ! pseudo_global_level_p ()) - { - struct binding_level *b = current_binding_level; - current_binding_level = b->level_chain; - if (current_binding_level != 0 && toplevel_bindings_p ()) - decl_context = PARM; - current_binding_level = b; - } - - /* Look through the decl specs and record which ones appear. - Some typespecs are defined as built-in typenames. - Others, the ones that are modifiers of other types, - are represented by bits in SPECBITS: set the bits for - the modifiers that appear. Storage class keywords are also in SPECBITS. - - If there is a typedef name or a type, store the type in TYPE. - This includes builtin typedefs such as `int'. - - Set EXPLICIT_INT if the type is `int' or `char' and did not - come from a user typedef. - - Set LONGLONG if `long' is mentioned twice. - - For C++, constructors and destructors have their own fast treatment. */ - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - register int i; - register tree id; - - /* Certain parse errors slip through. For example, - `int class;' is not caught by the parser. Try - weakly to recover here. */ - if (TREE_CODE (spec) != TREE_LIST) - return 0; - - id = TREE_VALUE (spec); - - if (TREE_CODE (id) == IDENTIFIER_NODE) - { - if (id == ridpointers[(int) RID_INT] - || id == ridpointers[(int) RID_CHAR] - || id == ridpointers[(int) RID_BOOL] - || id == ridpointers[(int) RID_WCHAR]) - { - if (type) - { - if (id == ridpointers[(int) RID_BOOL]) - error ("`bool' is now a keyword"); - else - cp_error ("extraneous `%T' ignored", id); - } - else - { - if (id == ridpointers[(int) RID_INT]) - explicit_int = 1; - else if (id == ridpointers[(int) RID_CHAR]) - explicit_char = 1; - type = TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (id)); - } - goto found; - } - /* C++ aggregate types. */ - if (IDENTIFIER_HAS_TYPE_VALUE (id)) - { - if (type) - cp_error ("multiple declarations `%T' and `%T'", type, id); - else - type = IDENTIFIER_TYPE_VALUE (id); - goto found; - } - - for (i = (int) RID_FIRST_MODIFIER; i <= (int) RID_LAST_MODIFIER; i++) - { - if (ridpointers[i] == id) - { - if (i == (int) RID_LONG && RIDBIT_SETP (i, specbits)) - { - if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ANSI C++ does not support `long long'"); - if (longlong) - error ("`long long long' is too long for GCC"); - else - longlong = 1; - } - else if (RIDBIT_SETP (i, specbits)) - pedwarn ("duplicate `%s'", IDENTIFIER_POINTER (id)); - RIDBIT_SET (i, specbits); - goto found; - } - } - } - /* C++ aggregate types. */ - else if (TREE_CODE (id) == TYPE_DECL || TREE_CODE (id) == TEMPLATE_DECL) - { - if (type) - cp_error ("multiple declarations `%T' and `%T'", type, - TREE_TYPE (id)); - else - { - type = TREE_TYPE (id); - TREE_VALUE (spec) = type; - } - goto found; - } - if (type) - error ("two or more data types in declaration of `%s'", name); - else if (TREE_CODE (id) == IDENTIFIER_NODE) - { - register tree t = lookup_name (id, 1); - if (!t || TREE_CODE (t) != TYPE_DECL) - error ("`%s' fails to be a typedef or built in type", - IDENTIFIER_POINTER (id)); - else - { - type = TREE_TYPE (t); -#if 0 - /* See the code below that used this. */ - decl_machine_attr = DECL_MACHINE_ATTRIBUTES (id); -#endif - typedef_decl = t; - } - } - else if (id != error_mark_node) - /* Can't change CLASS nodes into RECORD nodes here! */ - type = id; - - found: ; - } - - typedef_type = type; - - /* No type at all: default to `int', and set DEFAULTED_INT - because it was not a user-defined typedef. - Except when we have a `typedef' inside a signature, in - which case the type defaults to `unknown type' and is - instantiated when assigning to a signature pointer or ref. */ - - if (type == NULL_TREE - && (RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_UNSIGNED, specbits) - || RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits))) - { - /* These imply 'int'. */ - type = integer_type_node; - defaulted_int = 1; - } - - if (type == NULL_TREE) - { - explicit_int = -1; - if (return_type == return_dtor) - type = void_type_node; - else if (return_type == return_ctor) - type = build_pointer_type (ctor_return_type); - else if (return_type == return_conversion) - type = ctor_return_type; - else if (current_class_type - && IS_SIGNATURE (current_class_type) - && RIDBIT_SETP (RID_TYPEDEF, specbits) - && (decl_context == FIELD || decl_context == NORMAL)) - { - explicit_int = 0; - opaque_typedef = 1; - type = copy_node (opaque_type_node); - } - else - { - /* We handle `main' specially here, because 'main () { }' is so - common. With no options, it is allowed. With -Wreturn-type, - it is a warning. It is only an error with -pedantic-errors. */ - int is_main = (funcdef_flag - && MAIN_NAME_P (dname) - && ctype == NULL_TREE - && in_namespace == NULL_TREE - && current_namespace == global_namespace); - - if (in_system_header) - /* Allow it, sigh. */; - else if (pedantic || ! is_main) - cp_pedwarn ("ANSI C++ forbids declaration `%D' with no type", - dname); - else if (warn_return_type) - cp_warning ("ANSI C++ forbids declaration `%D' with no type", - dname); - - type = integer_type_node; - } - } - else if (return_type == return_dtor) - { - error ("return type specification for destructor invalid"); - type = void_type_node; - } - else if (return_type == return_ctor) - { - error ("return type specification for constructor invalid"); - type = build_pointer_type (ctor_return_type); - } - else if (return_type == return_conversion) - { - if (!same_type_p (type, ctor_return_type)) - cp_error ("operator `%T' declared to return `%T'", - ctor_return_type, type); - else - cp_pedwarn ("return type specified for `operator %T'", - ctor_return_type); - - type = ctor_return_type; - } - - ctype = NULL_TREE; - - /* Now process the modifiers that were specified - and check for invalid combinations. */ - - /* Long double is a special combination. */ - - if (RIDBIT_SETP (RID_LONG, specbits) - && TYPE_MAIN_VARIANT (type) == double_type_node) - { - RIDBIT_RESET (RID_LONG, specbits); - type = build_qualified_type (long_double_type_node, - CP_TYPE_QUALS (type)); - } - - /* Check all other uses of type modifiers. */ - - if (RIDBIT_SETP (RID_UNSIGNED, specbits) - || RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) - { - int ok = 0; - - if (TREE_CODE (type) == REAL_TYPE) - error ("short, signed or unsigned invalid for `%s'", name); - else if (TREE_CODE (type) != INTEGER_TYPE) - error ("long, short, signed or unsigned invalid for `%s'", name); - else if (RIDBIT_SETP (RID_LONG, specbits) - && RIDBIT_SETP (RID_SHORT, specbits)) - error ("long and short specified together for `%s'", name); - else if ((RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) - && explicit_char) - error ("long or short specified with char for `%s'", name); - else if ((RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits)) - && TREE_CODE (type) == REAL_TYPE) - error ("long or short specified with floating type for `%s'", name); - else if (RIDBIT_SETP (RID_SIGNED, specbits) - && RIDBIT_SETP (RID_UNSIGNED, specbits)) - error ("signed and unsigned given together for `%s'", name); - else - { - ok = 1; - if (!explicit_int && !defaulted_int && !explicit_char && pedantic) - { - pedwarn ("long, short, signed or unsigned used invalidly for `%s'", - name); - if (flag_pedantic_errors) - ok = 0; - } - } - - /* Discard the type modifiers if they are invalid. */ - if (! ok) - { - RIDBIT_RESET (RID_UNSIGNED, specbits); - RIDBIT_RESET (RID_SIGNED, specbits); - RIDBIT_RESET (RID_LONG, specbits); - RIDBIT_RESET (RID_SHORT, specbits); - longlong = 0; - } - } - - if (RIDBIT_SETP (RID_COMPLEX, specbits) - && TREE_CODE (type) != INTEGER_TYPE && TREE_CODE (type) != REAL_TYPE) - { - error ("complex invalid for `%s'", name); - RIDBIT_RESET (RID_COMPLEX, specbits); - } - - /* Decide whether an integer type is signed or not. - Optionally treat bitfields as signed by default. */ - if (RIDBIT_SETP (RID_UNSIGNED, specbits) - || (bitfield && ! flag_signed_bitfields - && (explicit_int || defaulted_int || explicit_char - /* A typedef for plain `int' without `signed' - can be controlled just like plain `int'. */ - || ! (typedef_decl != NULL_TREE - && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) - && TREE_CODE (type) != ENUMERAL_TYPE - && RIDBIT_NOTSETP (RID_SIGNED, specbits))) - { - if (longlong) - type = long_long_unsigned_type_node; - else if (RIDBIT_SETP (RID_LONG, specbits)) - type = long_unsigned_type_node; - else if (RIDBIT_SETP (RID_SHORT, specbits)) - type = short_unsigned_type_node; - else if (type == char_type_node) - type = unsigned_char_type_node; - else if (typedef_decl) - type = unsigned_type (type); - else - type = unsigned_type_node; - } - else if (RIDBIT_SETP (RID_SIGNED, specbits) - && type == char_type_node) - type = signed_char_type_node; - else if (longlong) - type = long_long_integer_type_node; - else if (RIDBIT_SETP (RID_LONG, specbits)) - type = long_integer_type_node; - else if (RIDBIT_SETP (RID_SHORT, specbits)) - type = short_integer_type_node; - - if (RIDBIT_SETP (RID_COMPLEX, specbits)) - { - /* If we just have "complex", it is equivalent to - "complex double", but if any modifiers at all are specified it is - the complex form of TYPE. E.g, "complex short" is - "complex short int". */ - - if (defaulted_int && ! longlong - && ! (RIDBIT_SETP (RID_LONG, specbits) - || RIDBIT_SETP (RID_SHORT, specbits) - || RIDBIT_SETP (RID_SIGNED, specbits) - || RIDBIT_SETP (RID_UNSIGNED, specbits))) - type = complex_double_type_node; - else if (type == integer_type_node) - type = complex_integer_type_node; - else if (type == float_type_node) - type = complex_float_type_node; - else if (type == double_type_node) - type = complex_double_type_node; - else if (type == long_double_type_node) - type = complex_long_double_type_node; - else - type = build_complex_type (type); - } - - if (return_type == return_conversion - && (RIDBIT_SETP (RID_CONST, specbits) - || RIDBIT_SETP (RID_VOLATILE, specbits) - || RIDBIT_SETP (RID_RESTRICT, specbits))) - cp_error ("qualifiers are not allowed on declaration of `operator %T'", - ctor_return_type); - - /* Set CONSTP if this declaration is `const', whether by - explicit specification or via a typedef. - Likewise for VOLATILEP. */ - - constp = !! RIDBIT_SETP (RID_CONST, specbits) + CP_TYPE_CONST_P (type); - restrictp = - !! RIDBIT_SETP (RID_RESTRICT, specbits) + CP_TYPE_RESTRICT_P (type); - volatilep = - !! RIDBIT_SETP (RID_VOLATILE, specbits) + CP_TYPE_VOLATILE_P (type); - type_quals = ((constp ? TYPE_QUAL_CONST : 0) - | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); - type = cp_build_qualified_type (type, type_quals); - staticp = 0; - inlinep = !! RIDBIT_SETP (RID_INLINE, specbits); - virtualp = RIDBIT_SETP (RID_VIRTUAL, specbits); - RIDBIT_RESET (RID_VIRTUAL, specbits); - explicitp = RIDBIT_SETP (RID_EXPLICIT, specbits) != 0; - RIDBIT_RESET (RID_EXPLICIT, specbits); - - if (RIDBIT_SETP (RID_STATIC, specbits)) - staticp = 1 + (decl_context == FIELD); - - if (virtualp && staticp == 2) - { - cp_error ("member `%D' cannot be declared both virtual and static", - dname); - staticp = 0; - } - friendp = RIDBIT_SETP (RID_FRIEND, specbits); - RIDBIT_RESET (RID_FRIEND, specbits); - - /* $7.1.2, Function specifiers */ - if (friendp && explicitp) - error ("only declarations of constructors can be `explicit'"); - - if (RIDBIT_SETP (RID_MUTABLE, specbits)) - { -/* CYGNUS LOCAL Embedded C++ */ - if (flag_embedded_cxx) - pedwarn ("Embedded C++ prohibits use of mutable"); -/* END CYGNUS LOCAL Embedded C++ */ - if (decl_context == PARM) - { - error ("non-member `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); - } - else if (friendp || decl_context == TYPENAME) - { - error ("non-object member `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); - } - } - - /* Warn if two storage classes are given. Default to `auto'. */ - - if (RIDBIT_ANY_SET (specbits)) - { - if (RIDBIT_SETP (RID_STATIC, specbits)) nclasses++; - if (RIDBIT_SETP (RID_EXTERN, specbits)) nclasses++; - if (decl_context == PARM && nclasses > 0) - error ("storage class specifiers invalid in parameter declarations"); - if (RIDBIT_SETP (RID_TYPEDEF, specbits)) - { - if (decl_context == PARM) - error ("typedef declaration invalid in parameter declaration"); - nclasses++; - } - if (RIDBIT_SETP (RID_AUTO, specbits)) nclasses++; - if (RIDBIT_SETP (RID_REGISTER, specbits)) nclasses++; - } - - /* Give error if `virtual' is used outside of class declaration. */ - if (virtualp - && (current_class_name == NULL_TREE || decl_context != FIELD)) - { - error ("virtual outside class declaration"); - virtualp = 0; - } - if (current_class_name == NULL_TREE && RIDBIT_SETP (RID_MUTABLE, specbits)) - { - error ("only members can be declared mutable"); - RIDBIT_RESET (RID_MUTABLE, specbits); - } - - /* Static anonymous unions are dealt with here. */ - if (staticp && decl_context == TYPENAME - && TREE_CODE (declspecs) == TREE_LIST - && ANON_UNION_TYPE_P (TREE_VALUE (declspecs))) - decl_context = FIELD; - - /* Give error if `const,' `volatile,' `inline,' `friend,' or `virtual' - is used in a signature member function declaration. */ - if (decl_context == FIELD - && IS_SIGNATURE (current_class_type) - && RIDBIT_NOTSETP (RID_TYPEDEF, specbits)) - { - if (type_quals != TYPE_UNQUALIFIED) - { - error ("type qualifiers specified for signature member function `%s'", name); - type_quals = TYPE_UNQUALIFIED; - } - if (inlinep) - { - error ("`inline' specified for signature member function `%s'", name); - /* Later, we'll make signature member functions inline. */ - inlinep = 0; - } - if (friendp) - { - error ("`friend' declaration in signature definition"); - friendp = 0; - } - if (virtualp) - { - error ("`virtual' specified for signature member function `%s'", - name); - /* Later, we'll make signature member functions virtual. */ - virtualp = 0; - } - } - - /* Warn about storage classes that are invalid for certain - kinds of declarations (parameters, typenames, etc.). */ - - if (nclasses > 1) - error ("multiple storage classes in declaration of `%s'", name); - else if (decl_context != NORMAL && nclasses > 0) - { - if ((decl_context == PARM || decl_context == CATCHPARM) - && (RIDBIT_SETP (RID_REGISTER, specbits) - || RIDBIT_SETP (RID_AUTO, specbits))) - ; - else if (RIDBIT_SETP (RID_TYPEDEF, specbits)) - ; - else if (decl_context == FIELD - && ! IS_SIGNATURE (current_class_type) - /* C++ allows static class elements */ - && RIDBIT_SETP (RID_STATIC, specbits)) - /* C++ also allows inlines and signed and unsigned elements, - but in those cases we don't come in here. */ - ; - else - { - if (decl_context == FIELD) - { - tree tmp = NULL_TREE; - register int op = 0; - - if (declarator) - { - /* Avoid trying to get an operand off an identifier node. */ - if (TREE_CODE (declarator) == IDENTIFIER_NODE) - tmp = declarator; - else - tmp = TREE_OPERAND (declarator, 0); - op = IDENTIFIER_OPNAME_P (tmp); - } - error ("storage class specified for %s `%s'", - IS_SIGNATURE (current_class_type) - ? (op - ? "signature member operator" - : "signature member function") - : (op ? "member operator" : "field"), - op ? operator_name_string (tmp) : name); - } - else - error (((decl_context == PARM || decl_context == CATCHPARM) - ? "storage class specified for parameter `%s'" - : "storage class specified for typename"), name); - RIDBIT_RESET (RID_REGISTER, specbits); - RIDBIT_RESET (RID_AUTO, specbits); - RIDBIT_RESET (RID_EXTERN, specbits); - - if (decl_context == FIELD && IS_SIGNATURE (current_class_type)) - { - RIDBIT_RESET (RID_STATIC, specbits); - staticp = 0; - } - } - } - else if (RIDBIT_SETP (RID_EXTERN, specbits) && initialized && !funcdef_flag) - { - if (toplevel_bindings_p ()) - { - /* It's common practice (and completely valid) to have a const - be initialized and declared extern. */ - if (!(type_quals & TYPE_QUAL_CONST)) - warning ("`%s' initialized and declared `extern'", name); - } - else - error ("`%s' has both `extern' and initializer", name); - } - else if (RIDBIT_SETP (RID_EXTERN, specbits) && funcdef_flag - && ! toplevel_bindings_p ()) - error ("nested function `%s' declared `extern'", name); - else if (toplevel_bindings_p ()) - { - if (RIDBIT_SETP (RID_AUTO, specbits)) - error ("top-level declaration of `%s' specifies `auto'", name); - } - - if (nclasses > 0 && friendp) - error ("storage class specifiers invalid in friend function declarations"); - - /* Now figure out the structure of the declarator proper. - Descend through it, creating more complex types, until we reach - the declared identifier (or NULL_TREE, in an absolute declarator). */ - - inner_attrs = NULL_TREE; - ignore_attrs = 0; - - while (declarator && TREE_CODE (declarator) != IDENTIFIER_NODE - && TREE_CODE (declarator) != TEMPLATE_ID_EXPR) - { - /* Each level of DECLARATOR is either an ARRAY_REF (for ...[..]), - an INDIRECT_REF (for *...), - a CALL_EXPR (for ...(...)), - an identifier (for the name being declared) - or a null pointer (for the place in an absolute declarator - where the name was omitted). - For the last two cases, we have just exited the loop. - - For C++ it could also be - a SCOPE_REF (for class :: ...). In this case, we have converted - sensible names to types, and those are the values we use to - qualify the member name. - an ADDR_EXPR (for &...), - a BIT_NOT_EXPR (for destructors) - - At this point, TYPE is the type of elements of an array, - or for a function to return, or for a pointer to point to. - After this sequence of ifs, TYPE is the type of the - array or function or pointer, and DECLARATOR has had its - outermost layer removed. */ - - if (type == error_mark_node) - { - if (TREE_CODE (declarator) == SCOPE_REF) - declarator = TREE_OPERAND (declarator, 1); - else - declarator = TREE_OPERAND (declarator, 0); - continue; - } - if (quals != NULL_TREE - && (declarator == NULL_TREE - || TREE_CODE (declarator) != SCOPE_REF)) - { - if (ctype == NULL_TREE && TREE_CODE (type) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (type); - if (ctype != NULL_TREE) - { - tree dummy = build_decl (TYPE_DECL, NULL_TREE, type); - ctype = grok_method_quals (ctype, dummy, quals); - type = TREE_TYPE (dummy); - quals = NULL_TREE; - } - } - - /* See the comment for the TREE_LIST case, below. */ - if (ignore_attrs) - ignore_attrs = 0; - else if (inner_attrs) - { - decl_attributes (type, inner_attrs, NULL_TREE); - inner_attrs = NULL_TREE; - } - - switch (TREE_CODE (declarator)) - { - case TREE_LIST: - { - /* We encode a declarator with embedded attributes using - a TREE_LIST. The attributes apply to the declarator - directly inside them, so we have to skip an iteration - before applying them to the type. If the declarator just - inside is the declarator-id, we apply the attrs to the - decl itself. */ - inner_attrs = TREE_PURPOSE (declarator); - ignore_attrs = 1; - declarator = TREE_VALUE (declarator); - } - break; - - case ARRAY_REF: - { - register tree itype = NULL_TREE; - register tree size = TREE_OPERAND (declarator, 1); - /* The index is a signed object `sizetype' bits wide. */ - tree index_type = signed_type (sizetype); - - declarator = TREE_OPERAND (declarator, 0); - - /* Check for some types that there cannot be arrays of. */ - - if (TREE_CODE (type) == VOID_TYPE) - { - cp_error ("declaration of `%D' as array of voids", dname); - type = error_mark_node; - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - cp_error ("declaration of `%D' as array of functions", dname); - type = error_mark_node; - } - - /* ARM $8.4.3: Since you can't have a pointer to a reference, - you can't have arrays of references. If we allowed them, - then we'd be saying x[i] is valid for an array x, but - then you'd have to ask: what does `*(x + i)' mean? */ - if (TREE_CODE (type) == REFERENCE_TYPE) - { - if (decl_context == TYPENAME) - cp_error ("cannot make arrays of references"); - else - cp_error ("declaration of `%D' as array of references", - dname); - type = error_mark_node; - } - - if (TREE_CODE (type) == OFFSET_TYPE) - { - cp_error ("declaration of `%D' as array of data members", - dname); - type = error_mark_node; - } - - if (TREE_CODE (type) == METHOD_TYPE) - { - cp_error ("declaration of `%D' as array of function members", - dname); - type = error_mark_node; - } - - if (size == error_mark_node) - type = error_mark_node; - else if (TREE_CODE (type) == ARRAY_TYPE && !TYPE_DOMAIN (type)) - { - /* [dcl.array] - - the constant expressions that specify the bounds of - the arrays can be omitted only for the first member - of the sequence. */ - cp_error ("declaration of `%D' as multidimensional array", - dname); - cp_error ("must have bounds for all dimensions except the first"); - type = error_mark_node; - } - - if (type == error_mark_node) - continue; - - if (size) - { - /* Must suspend_momentary here because the index - type may need to live until the end of the function. - For example, it is used in the declaration of a - variable which requires destructing at the end of - the function; then build_vec_delete will need this - value. */ - int yes = suspend_momentary (); - /* Might be a cast. */ - if (TREE_CODE (size) == NOP_EXPR - && TREE_TYPE (size) == TREE_TYPE (TREE_OPERAND (size, 0))) - size = TREE_OPERAND (size, 0); - - /* If this involves a template parameter, it will be a - constant at instantiation time, but we don't know - what the value is yet. Even if no template - parameters are involved, we may an expression that - is not a constant; we don't even simplify `1 + 2' - when processing a template. */ - if (processing_template_decl) - { - /* Resolve a qualified reference to an enumerator or - static const data member of ours. */ - if (TREE_CODE (size) == SCOPE_REF - && TREE_OPERAND (size, 0) == current_class_type) - { - tree t = lookup_field (current_class_type, - TREE_OPERAND (size, 1), 0, 0); - if (t) - size = t; - } - - itype = make_node (INTEGER_TYPE); - TYPE_MIN_VALUE (itype) = size_zero_node; - TYPE_MAX_VALUE (itype) = build_min - (MINUS_EXPR, sizetype, size, integer_one_node); - goto dont_grok_size; - } - - if (TREE_CODE (TREE_TYPE (size)) != INTEGER_TYPE - && TREE_CODE (TREE_TYPE (size)) != ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (size)) != BOOLEAN_TYPE) - { - cp_error ("size of array `%D' has non-integer type", - dname); - size = integer_one_node; - } - if (TREE_READONLY_DECL_P (size)) - size = decl_constant_value (size); - if (pedantic && integer_zerop (size)) - cp_pedwarn ("ANSI C++ forbids zero-size array `%D'", dname); - if (TREE_CONSTANT (size)) - { - int old_flag_pedantic_errors = flag_pedantic_errors; - int old_pedantic = pedantic; - pedantic = flag_pedantic_errors = 1; - /* Always give overflow errors on array subscripts. */ - constant_expression_warning (size); - pedantic = old_pedantic; - flag_pedantic_errors = old_flag_pedantic_errors; - if (INT_CST_LT (size, integer_zero_node)) - { - cp_error ("size of array `%D' is negative", dname); - size = integer_one_node; - } - } - else - { - if (pedantic) - { - if (dname) - cp_pedwarn ("ANSI C++ forbids variable-size array `%D'", - dname); - else - cp_pedwarn ("ANSI C++ forbids variable-size array"); - } - } - - itype - = fold (build_binary_op (MINUS_EXPR, - cp_convert (index_type, size), - cp_convert (index_type, - integer_one_node), 1)); - if (! TREE_CONSTANT (itype)) - itype = variable_size (itype); - else if (TREE_OVERFLOW (itype)) - { - error ("overflow in array dimension"); - TREE_OVERFLOW (itype) = 0; - } - - /* If we're a parm, we need to have a permanent type so - mangling checks for re-use will work right. If both the - element and index types are permanent, the array type - will be, too. */ - if (decl_context == PARM - && allocation_temporary_p () && TREE_PERMANENT (type)) - { - push_obstacks (&permanent_obstack, &permanent_obstack); - itype = build_index_type (itype); - pop_obstacks (); - } - else - itype = build_index_type (itype); - - dont_grok_size: - resume_momentary (yes); - } - - type = build_cplus_array_type (type, itype); - ctype = NULL_TREE; - } - break; - - case CALL_EXPR: - { - tree arg_types; - int funcdecl_p; - tree inner_parms = TREE_OPERAND (declarator, 1); - tree inner_decl = TREE_OPERAND (declarator, 0); - - /* Declaring a function type. - Make sure we have a valid type for the function to return. */ - - /* We now know that the TYPE_QUALS don't apply to the - decl, but to its return type. */ - type_quals = TYPE_UNQUALIFIED; - - /* Warn about some types functions can't return. */ - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("`%s' declared as function returning a function", name); - type = integer_type_node; - } - if (TREE_CODE (type) == ARRAY_TYPE) - { - error ("`%s' declared as function returning an array", name); - type = integer_type_node; - } - - if (inner_decl && TREE_CODE (inner_decl) == SCOPE_REF) - inner_decl = TREE_OPERAND (inner_decl, 1); - - if (inner_decl && TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR) - inner_decl = dname; - - /* Pick up type qualifiers which should be applied to `this'. */ - quals = TREE_OPERAND (declarator, 2); - - /* Pick up the exception specifications. */ - raises = TREE_TYPE (declarator); - - /* Say it's a definition only for the CALL_EXPR - closest to the identifier. */ - funcdecl_p - = inner_decl - && (TREE_CODE (inner_decl) == IDENTIFIER_NODE - || TREE_CODE (inner_decl) == TEMPLATE_ID_EXPR - || TREE_CODE (inner_decl) == BIT_NOT_EXPR); - - if (ctype == NULL_TREE - && decl_context == FIELD - && funcdecl_p - && (friendp == 0 || dname == current_class_name)) - ctype = current_class_type; - - if (ctype && return_type == return_conversion) - TYPE_HAS_CONVERSION (ctype) = 1; - if (ctype && constructor_name (ctype) == dname) - { - /* We are within a class's scope. If our declarator name - is the same as the class name, and we are defining - a function, then it is a constructor/destructor, and - therefore returns a void type. */ - - if (flags == DTOR_FLAG) - { - /* ANSI C++ June 5 1992 WP 12.4.1. A destructor may - not be declared const or volatile. A destructor - may not be static. */ - if (staticp == 2) - error ("destructor cannot be static member function"); - if (quals) - { - cp_error ("destructors may not be `%s'", - IDENTIFIER_POINTER (TREE_VALUE (quals))); - quals = NULL_TREE; - } - if (decl_context == FIELD) - { - if (! member_function_or_else (ctype, current_class_type, - "destructor for alien class `%s' cannot be a member")) - return void_type_node; - } - } - else /* It's a constructor. */ - { - if (explicitp == 1) - explicitp = 2; - /* ANSI C++ June 5 1992 WP 12.1.2. A constructor may - not be declared const or volatile. A constructor may - not be virtual. A constructor may not be static. */ - if (staticp == 2) - error ("constructor cannot be static member function"); - if (virtualp) - { - pedwarn ("constructors cannot be declared virtual"); - virtualp = 0; - } - if (quals) - { - cp_error ("constructors may not be `%s'", - IDENTIFIER_POINTER (TREE_VALUE (quals))); - quals = NULL_TREE; - } - { - RID_BIT_TYPE tmp_bits; - bcopy ((void*)&specbits, (void*)&tmp_bits, sizeof (RID_BIT_TYPE)); - RIDBIT_RESET (RID_INLINE, tmp_bits); - RIDBIT_RESET (RID_STATIC, tmp_bits); - if (RIDBIT_ANY_SET (tmp_bits)) - error ("return value type specifier for constructor ignored"); - } - type = build_pointer_type (ctype); - if (decl_context == FIELD - && IS_SIGNATURE (current_class_type)) - { - error ("constructor not allowed in signature"); - return void_type_node; - } - else if (decl_context == FIELD) - { - if (! member_function_or_else (ctype, current_class_type, - "constructor for alien class `%s' cannot be member")) - return void_type_node; - TYPE_HAS_CONSTRUCTOR (ctype) = 1; - if (return_type != return_ctor) - return NULL_TREE; - } - } - if (decl_context == FIELD) - staticp = 0; - } - else if (friendp) - { - if (initialized) - error ("can't initialize friend function `%s'", name); - if (virtualp) - { - /* Cannot be both friend and virtual. */ - error ("virtual functions cannot be friends"); - RIDBIT_RESET (RID_FRIEND, specbits); - friendp = 0; - } - if (decl_context == NORMAL) - error ("friend declaration not in class definition"); - if (current_function_decl && funcdef_flag) - cp_error ("can't define friend function `%s' in a local class definition", - name); - } - - /* Construct the function type and go to the next - inner layer of declarator. */ - - declarator = TREE_OPERAND (declarator, 0); - - /* FIXME: This is where default args should be fully - processed. */ - - arg_types = grokparms (inner_parms, funcdecl_p ? funcdef_flag : 0); - - if (declarator && flags == DTOR_FLAG) - { - /* A destructor declared in the body of a class will - be represented as a BIT_NOT_EXPR. But, we just - want the underlying IDENTIFIER. */ - if (TREE_CODE (declarator) == BIT_NOT_EXPR) - declarator = TREE_OPERAND (declarator, 0); - - if (strict_prototype == 0 && arg_types == NULL_TREE) - arg_types = void_list_node; - else if (arg_types == NULL_TREE - || arg_types != void_list_node) - { - cp_error ("destructors may not have parameters"); - arg_types = void_list_node; - last_function_parms = NULL_TREE; - } - } - - /* ANSI says that `const int foo ();' - does not make the function foo const. */ - type = build_function_type (type, arg_types); - - { - tree t; - for (t = arg_types; t; t = TREE_CHAIN (t)) - if (TREE_PURPOSE (t) - && TREE_CODE (TREE_PURPOSE (t)) == DEFAULT_ARG) - { - add_defarg_fn (type); - break; - } - } - } - break; - - case ADDR_EXPR: - case INDIRECT_REF: - /* Filter out pointers-to-references and references-to-references. - We can get these if a TYPE_DECL is used. */ - - if (TREE_CODE (type) == REFERENCE_TYPE) - { - error ("cannot declare %s to references", - TREE_CODE (declarator) == ADDR_EXPR - ? "references" : "pointers"); - declarator = TREE_OPERAND (declarator, 0); - continue; - } - - if (TREE_CODE (type) == OFFSET_TYPE - && (TREE_CODE (TREE_TYPE (type)) == VOID_TYPE - || TREE_CODE (TREE_TYPE (type)) == REFERENCE_TYPE)) - { - cp_error ("cannot declare pointer to `%#T' member", - TREE_TYPE (type)); - type = TREE_TYPE (type); - } - - /* Merge any constancy or volatility into the target type - for the pointer. */ - - /* We now know that the TYPE_QUALS don't apply to the decl, - but to the target of the pointer. */ - type_quals = TYPE_UNQUALIFIED; - - if (IS_SIGNATURE (type)) - { - if (TREE_CODE (declarator) == ADDR_EXPR) - { - if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE - && TYPE_SIZE (type)) - cp_warning ("empty signature `%T' used in signature reference declaration", - type); -#if 0 - type = build_signature_reference_type (type); -#else - sorry ("signature reference"); - return NULL_TREE; -#endif - } - else - { - if (CLASSTYPE_METHOD_VEC (type) == NULL_TREE - && TYPE_SIZE (type)) - cp_warning ("empty signature `%T' used in signature pointer declaration", - type); - type = build_signature_pointer_type (type); - } - } - else if (TREE_CODE (declarator) == ADDR_EXPR) - { - if (TREE_CODE (type) == VOID_TYPE) - error ("invalid type: `void &'"); - else - type = build_reference_type (type); - } - else if (TREE_CODE (type) == METHOD_TYPE) - type = build_ptrmemfunc_type (build_pointer_type (type)); - else - type = build_pointer_type (type); - - /* Process a list of type modifier keywords (such as - const or volatile) that were given inside the `*' or `&'. */ - - if (TREE_TYPE (declarator)) - { - register tree typemodlist; - int erred = 0; - - constp = 0; - volatilep = 0; - restrictp = 0; - for (typemodlist = TREE_TYPE (declarator); typemodlist; - typemodlist = TREE_CHAIN (typemodlist)) - { - tree qualifier = TREE_VALUE (typemodlist); - - if (qualifier == ridpointers[(int) RID_CONST]) - constp++; - else if (qualifier == ridpointers[(int) RID_VOLATILE]) - volatilep++; - else if (qualifier == ridpointers[(int) RID_RESTRICT]) - restrictp++; - else if (!erred) - { - erred = 1; - error ("invalid type modifier within pointer declarator"); - } - } - if (constp > 1) - pedwarn ("duplicate `const'"); - if (volatilep > 1) - pedwarn ("duplicate `volatile'"); - if (restrictp > 1) - pedwarn ("duplicate `restrict'"); - - type_quals = ((constp ? TYPE_QUAL_CONST : 0) - | (restrictp ? TYPE_QUAL_RESTRICT : 0) - | (volatilep ? TYPE_QUAL_VOLATILE : 0)); - if (TREE_CODE (declarator) == ADDR_EXPR - && (constp || volatilep)) - { - if (constp) - pedwarn ("discarding `const' applied to a reference"); - if (volatilep) - pedwarn ("discarding `volatile' applied to a reference"); - type_quals &= ~(TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE); - } - type = cp_build_qualified_type (type, type_quals); - } - declarator = TREE_OPERAND (declarator, 0); - ctype = NULL_TREE; - break; - - case SCOPE_REF: - { - /* We have converted type names to NULL_TREE if the - name was bogus, or to a _TYPE node, if not. - - The variable CTYPE holds the type we will ultimately - resolve to. The code here just needs to build - up appropriate member types. */ - tree sname = TREE_OPERAND (declarator, 1); - tree t; - - /* Destructors can have their visibilities changed as well. */ - if (TREE_CODE (sname) == BIT_NOT_EXPR) - sname = TREE_OPERAND (sname, 0); - - if (TREE_COMPLEXITY (declarator) == 0) - /* This needs to be here, in case we are called - multiple times. */ ; - else if (TREE_COMPLEXITY (declarator) == -1) - /* Namespace member. */ - pop_decl_namespace (); - else if (friendp && (TREE_COMPLEXITY (declarator) < 2)) - /* Don't fall out into global scope. Hides real bug? --eichin */ ; - else if (! IS_AGGR_TYPE_CODE - (TREE_CODE (TREE_OPERAND (declarator, 0)))) - ; - else if (TREE_COMPLEXITY (declarator) == current_class_depth) - { - /* Resolve any TYPENAME_TYPEs from the decl-specifier-seq - that refer to ctype. They couldn't be resolved earlier - because we hadn't pushed into the class yet. - Example: resolve 'B<T>::type' in - 'B<typename B<T>::type> B<T>::f () { }'. */ - if (current_template_parms - && uses_template_parms (type) - && uses_template_parms (current_class_type)) - { - tree args = current_template_args (); - type = tsubst (type, args, NULL_TREE); - } - - /* This pop_nested_class corresponds to the - push_nested_class used to push into class scope for - parsing the argument list of a function decl, in - qualified_id. */ - pop_nested_class (1); - TREE_COMPLEXITY (declarator) = current_class_depth; - } - else - my_friendly_abort (16); - - if (TREE_OPERAND (declarator, 0) == NULL_TREE) - { - /* We had a reference to a global decl, or - perhaps we were given a non-aggregate typedef, - in which case we cleared this out, and should just - keep going as though it wasn't there. */ - declarator = sname; - continue; - } - ctype = TREE_OPERAND (declarator, 0); - - t = ctype; - while (t != NULL_TREE && CLASS_TYPE_P (t)) - { - if (CLASSTYPE_TEMPLATE_INFO (t) && - !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) - template_count += 1; - t = TYPE_MAIN_DECL (t); - if (DECL_LANG_SPECIFIC (t)) - t = DECL_CLASS_CONTEXT (t); - else - t = NULL_TREE; - } - - if (sname == NULL_TREE) - goto done_scoping; - - if (TREE_CODE (sname) == IDENTIFIER_NODE) - { - /* This is the `standard' use of the scoping operator: - basetype :: member . */ - - if (ctype == current_class_type) - { - /* class A { - void A::f (); - }; - - Is this ill-formed? */ - - if (pedantic) - cp_pedwarn ("extra qualification `%T::' on member `%s' ignored", - ctype, name); - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - if (current_class_type == NULL_TREE - || friendp) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - else - { - cp_error ("cannot declare member function `%T::%s' within `%T'", - ctype, name, current_class_type); - return void_type_node; - } - } - else if (RIDBIT_SETP (RID_TYPEDEF, specbits) - || TYPE_SIZE (complete_type (ctype)) != NULL_TREE) - { - /* Have to move this code elsewhere in this function. - this code is used for i.e., typedef int A::M; M *pm; - - It is? How? jason 10/2/94 */ - - if (current_class_type) - { - cp_error ("cannot declare member `%T::%s' within `%T'", - ctype, name, current_class_type); - return void_type_node; - } - type = build_offset_type (ctype, type); - } - else if (uses_template_parms (ctype)) - { - if (TREE_CODE (type) == FUNCTION_TYPE) - type - = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - } - else - { - cp_error ("structure `%T' not yet defined", ctype); - return error_mark_node; - } - - declarator = sname; - } - else if (TREE_CODE (sname) == SCOPE_REF) - my_friendly_abort (17); - else - { - done_scoping: - declarator = TREE_OPERAND (declarator, 1); - if (declarator && TREE_CODE (declarator) == CALL_EXPR) - /* In this case, we will deal with it later. */ - ; - else - { - if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - else - type = build_offset_type (ctype, type); - } - } - } - break; - - case BIT_NOT_EXPR: - declarator = TREE_OPERAND (declarator, 0); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - declarator = NULL_TREE; - break; - - case ERROR_MARK: - declarator = NULL_TREE; - break; - - default: - my_friendly_abort (158); - } - } - - /* See the comment for the TREE_LIST case, above. */ - if (inner_attrs) - { - if (! ignore_attrs) - decl_attributes (type, inner_attrs, NULL_TREE); - else if (attrlist) - TREE_VALUE (attrlist) = chainon (inner_attrs, TREE_VALUE (attrlist)); - else - attrlist = build_decl_list (NULL_TREE, inner_attrs); - } - - if (explicitp == 1) - { - error ("only constructors can be declared `explicit'"); - explicitp = 0; - } - - /* Now TYPE has the actual type. */ - - /* If this is declaring a typedef name, return a TYPE_DECL. */ - - if (RIDBIT_SETP (RID_MUTABLE, specbits)) - { - if (type_quals & TYPE_QUAL_CONST) - { - error ("const `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); - } - else if (staticp) - { - error ("static `%s' cannot be declared `mutable'", name); - RIDBIT_RESET (RID_MUTABLE, specbits); - } - } - - if (RIDBIT_SETP (RID_TYPEDEF, specbits) && decl_context != TYPENAME) - { - tree decl; - - /* Note that the grammar rejects storage classes - in typenames, fields or parameters. */ - if (current_lang_name == lang_name_java) - TYPE_FOR_JAVA (type) = 1; - - if (decl_context == FIELD) - { - if (declarator == constructor_name (current_class_type)) - cp_pedwarn ("ANSI C++ forbids nested type `%D' with same name as enclosing class", - declarator); - decl = build_lang_decl (TYPE_DECL, declarator, type); - if (IS_SIGNATURE (current_class_type) && opaque_typedef) - SIGNATURE_HAS_OPAQUE_TYPEDECLS (current_class_type) = 1; - } - else - { - /* Make sure this typedef lives as long as its type, - since it might be used as a template parameter. */ - if (type != error_mark_node) - push_obstacks (TYPE_OBSTACK (type), TYPE_OBSTACK (type)); - decl = build_decl (TYPE_DECL, declarator, type); - if (type != error_mark_node) - pop_obstacks (); - } - - /* If the user declares "struct {...} foo" then `foo' will have - an anonymous name. Fill that name in now. Nothing can - refer to it, so nothing needs know about the name change. - The TYPE_NAME field was filled in by build_struct_xref. */ - if (type != error_mark_node - && TYPE_NAME (type) - && TREE_CODE (TYPE_NAME (type)) == TYPE_DECL - && ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - { - /* FIXME: This is bogus; we should not be doing this for - cv-qualified types. */ - - /* For anonymous structs that are cv-qualified, need to use - TYPE_MAIN_VARIANT so that name will mangle correctly. As - type not referenced after this block, don't bother - resetting type to original type, ie. TREE_TYPE (decl). */ - type = TYPE_MAIN_VARIANT (type); - - /* Replace the anonymous name with the real name everywhere. */ - lookup_tag_reverse (type, declarator); - TYPE_NAME (type) = decl; - - if (TYPE_LANG_SPECIFIC (type)) - TYPE_WAS_ANONYMOUS (type) = 1; - - /* If this is a typedef within a template class, the nested - type is a (non-primary) template. The name for the - template needs updating as well. */ - if (TYPE_LANG_SPECIFIC (type) && CLASSTYPE_TEMPLATE_INFO (type)) - DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)) - = TYPE_IDENTIFIER (type); - - /* XXX Temporarily set the scope. - When returning, start_decl expects it as NULL_TREE, - and will then then set it using pushdecl. */ - my_friendly_assert (DECL_CONTEXT (decl) == NULL_TREE, 980404); - if (current_class_type) - DECL_CONTEXT (decl) = current_class_type; - else - DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); - - DECL_ASSEMBLER_NAME (decl) = DECL_NAME (decl); - DECL_ASSEMBLER_NAME (decl) - = get_identifier (build_overload_name (type, 1, 1)); - DECL_CONTEXT (decl) = NULL_TREE; - - /* FIXME remangle member functions; member functions of a - type with external linkage have external linkage. */ - } - - if (TREE_CODE (type) == OFFSET_TYPE || TREE_CODE (type) == METHOD_TYPE) - { - cp_error_at ("typedef name may not be class-qualified", decl); - return NULL_TREE; - } - else if (quals) - { - if (ctype == NULL_TREE) - { - if (TREE_CODE (type) != METHOD_TYPE) - cp_error_at ("invalid type qualifier for non-method type", decl); - else - ctype = TYPE_METHOD_BASETYPE (type); - } - if (ctype != NULL_TREE) - grok_method_quals (ctype, decl, quals); - } - - if (RIDBIT_SETP (RID_SIGNED, specbits) - || (typedef_decl && C_TYPEDEF_EXPLICITLY_SIGNED (typedef_decl))) - C_TYPEDEF_EXPLICITLY_SIGNED (decl) = 1; - - if (RIDBIT_SETP (RID_MUTABLE, specbits)) - error ("non-object member `%s' cannot be declared mutable", name); - - bad_specifiers (decl, "type", virtualp, quals != NULL_TREE, - inlinep, friendp, raises != NULL_TREE); - - if (initialized) - error ("typedef declaration includes an initializer"); - - return decl; - } - - /* Detect the case of an array type of unspecified size - which came, as such, direct from a typedef name. - We must copy the type, so that each identifier gets - a distinct type, so that each identifier's size can be - controlled separately by its own initializer. */ - - if (type == typedef_type && TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == NULL_TREE) - { - type = build_cplus_array_type (TREE_TYPE (type), TYPE_DOMAIN (type)); - } - - /* If this is a type name (such as, in a cast or sizeof), - compute the type and return it now. */ - - if (decl_context == TYPENAME) - { - /* Note that the grammar rejects storage classes - in typenames, fields or parameters. */ - if (type_quals != TYPE_UNQUALIFIED) - { - if (IS_SIGNATURE (type)) - error ("type qualifiers specified for signature type"); - type_quals = TYPE_UNQUALIFIED; - } - - /* Special case: "friend class foo" looks like a TYPENAME context. */ - if (friendp) - { - if (type_quals != TYPE_UNQUALIFIED) - { - cp_error ("type qualifiers specified for friend class declaration"); - type_quals = TYPE_UNQUALIFIED; - } - if (inlinep) - { - cp_error ("`inline' specified for friend class declaration"); - inlinep = 0; - } - - /* Only try to do this stuff if we didn't already give up. */ - if (type != integer_type_node) - { - /* A friendly class? */ - if (current_class_type) - make_friend_class (current_class_type, TYPE_MAIN_VARIANT (type)); - else - error ("trying to make class `%s' a friend of global scope", - TYPE_NAME_STRING (type)); - type = void_type_node; - } - } - else if (quals) - { - tree dummy = build_decl (TYPE_DECL, declarator, type); - if (ctype == NULL_TREE) - { - my_friendly_assert (TREE_CODE (type) == METHOD_TYPE, 159); - ctype = TYPE_METHOD_BASETYPE (type); - } - grok_method_quals (ctype, dummy, quals); - type = TREE_TYPE (dummy); - } - - return type; - } - else if (declarator == NULL_TREE && decl_context != PARM - && decl_context != CATCHPARM - && TREE_CODE (type) != UNION_TYPE - && ! bitfield) - { - cp_error ("abstract declarator `%T' used as declaration", type); - declarator = make_anon_name (); - } - - /* `void' at top level (not within pointer) - is allowed only in typedefs or type names. - We don't complain about parms either, but that is because - a better error message can be made later. */ - - if (TREE_CODE (type) == VOID_TYPE && decl_context != PARM) - { - if (! declarator) - error ("unnamed variable or field declared void"); - else if (TREE_CODE (declarator) == IDENTIFIER_NODE) - { - if (IDENTIFIER_OPNAME_P (declarator)) - my_friendly_abort (356); - else - error ("variable or field `%s' declared void", name); - } - else - error ("variable or field declared void"); - type = integer_type_node; - } - - /* Now create the decl, which may be a VAR_DECL, a PARM_DECL - or a FUNCTION_DECL, depending on DECL_CONTEXT and TYPE. */ - - if (decl_context == PARM || decl_context == CATCHPARM) - { - if (ctype || in_namespace) - error ("cannot use `::' in parameter declaration"); - - /* A parameter declared as an array of T is really a pointer to T. - One declared as a function is really a pointer to a function. - One declared as a member is really a pointer to member. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Transfer const-ness of array into that of type pointed to. */ - type = build_pointer_type (TREE_TYPE (type)); - type_quals = TYPE_UNQUALIFIED; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == OFFSET_TYPE) - type = build_pointer_type (type); - else if (TREE_CODE (type) == VOID_TYPE && declarator) - { - error ("declaration of `%s' as void", name); - return NULL_TREE; - } - } - - { - register tree decl; - - if (decl_context == PARM) - { - decl = build_decl (PARM_DECL, declarator, type); - - bad_specifiers (decl, "parameter", virtualp, quals != NULL_TREE, - inlinep, friendp, raises != NULL_TREE); - if (current_class_type - && IS_SIGNATURE (current_class_type)) - { - if (inlinep) - error ("parameter of signature member function declared `inline'"); - if (RIDBIT_SETP (RID_AUTO, specbits)) - error ("parameter of signature member function declared `auto'"); - if (RIDBIT_SETP (RID_REGISTER, specbits)) - error ("parameter of signature member function declared `register'"); - } - - /* Compute the type actually passed in the parmlist, - for the case where there is no prototype. - (For example, shorts and chars are passed as ints.) - When there is a prototype, this is overridden later. */ - - DECL_ARG_TYPE (decl) = type_promotes_to (type); - } - else if (decl_context == FIELD) - { - if (type == error_mark_node) - { - /* Happens when declaring arrays of sizes which - are error_mark_node, for example. */ - decl = NULL_TREE; - } - else if (in_namespace && !friendp) - { - /* Something like struct S { int N::j; }; */ - cp_error ("invalid use of `::'"); - decl = NULL_TREE; - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - int publicp = 0; - tree function_context; - - /* We catch the others as conflicts with the builtin - typedefs. */ - if (friendp && declarator == ridpointers[(int) RID_SIGNED]) - { - cp_error ("function `%D' cannot be declared friend", - declarator); - friendp = 0; - } - - if (friendp == 0) - { - if (ctype == NULL_TREE) - ctype = current_class_type; - - if (ctype == NULL_TREE) - { - cp_error ("can't make `%D' into a method -- not in a class", - declarator); - return void_type_node; - } - - /* ``A union may [ ... ] not [ have ] virtual functions.'' - ARM 9.5 */ - if (virtualp && TREE_CODE (ctype) == UNION_TYPE) - { - cp_error ("function `%D' declared virtual inside a union", - declarator); - return void_type_node; - } - - if (declarator == ansi_opname[(int) NEW_EXPR] - || declarator == ansi_opname[(int) VEC_NEW_EXPR] - || declarator == ansi_opname[(int) DELETE_EXPR] - || declarator == ansi_opname[(int) VEC_DELETE_EXPR]) - { - if (virtualp) - { - cp_error ("`%D' cannot be declared virtual, since it is always static", - declarator); - virtualp = 0; - } - } - else if (staticp < 2) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - } - - /* Tell grokfndecl if it needs to set TREE_PUBLIC on the node. */ - function_context = (ctype != NULL_TREE) ? - hack_decl_function_context (TYPE_MAIN_DECL (ctype)) : NULL_TREE; - publicp = (! friendp || ! staticp) - && function_context == NULL_TREE; - decl = grokfndecl (ctype, type, - TREE_CODE (declarator) != TEMPLATE_ID_EXPR - ? declarator : dname, - declarator, - virtualp, flags, quals, raises, attrlist, - friendp ? -1 : 0, friendp, publicp, inlinep, - funcdef_flag, template_count, in_namespace); - if (decl == NULL_TREE || decl == error_mark_node) - return decl; -#if 0 - /* This clobbers the attrs stored in `decl' from `attrlist'. */ - /* The decl and setting of decl_machine_attr is also turned off. */ - decl = build_decl_attribute_variant (decl, decl_machine_attr); -#endif - - /* [class.conv.ctor] - - A constructor declared without the function-specifier - explicit that can be called with a single parameter - specifies a conversion from the type of its first - parameter to the type of its class. Such a constructor - is called a converting constructor. */ - if (explicitp == 2) - DECL_NONCONVERTING_P (decl) = 1; - else if (DECL_CONSTRUCTOR_P (decl)) - { - /* The constructor can be called with exactly one - parameter if there is at least one parameter, and - any subsequent parameters have default arguments. - We don't look at the first parameter, which is - really just the `this' parameter for the new - object. */ - tree arg_types = - TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))); - - /* Skip the `in_chrg' argument too, if present. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (decl))) - arg_types = TREE_CHAIN (arg_types); - - if (arg_types == void_list_node - || (arg_types - && TREE_CHAIN (arg_types) - && TREE_CHAIN (arg_types) != void_list_node - && !TREE_PURPOSE (TREE_CHAIN (arg_types)))) - DECL_NONCONVERTING_P (decl) = 1; - } - } - else if (TREE_CODE (type) == METHOD_TYPE) - { - /* We only get here for friend declarations of - members of other classes. */ - /* All method decls are public, so tell grokfndecl to set - TREE_PUBLIC, also. */ - decl = grokfndecl (ctype, type, declarator, declarator, - virtualp, flags, quals, raises, attrlist, - friendp ? -1 : 0, friendp, 1, 0, funcdef_flag, - template_count, in_namespace); - if (decl == NULL_TREE) - return NULL_TREE; - } - else if (!staticp && ! processing_template_decl - && TYPE_SIZE (complete_type (type)) == NULL_TREE - && (TREE_CODE (type) != ARRAY_TYPE || initialized == 0)) - { - if (declarator) - cp_error ("field `%D' has incomplete type", declarator); - else - cp_error ("name `%T' has incomplete type", type); - - /* If we're instantiating a template, tell them which - instantiation made the field's type be incomplete. */ - if (current_class_type - && TYPE_NAME (current_class_type) - && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (current_class_type)) - && declspecs && TREE_VALUE (declspecs) - && TREE_TYPE (TREE_VALUE (declspecs)) == type) - cp_error (" in instantiation of template `%T'", - current_class_type); - - type = error_mark_node; - decl = NULL_TREE; - } - else - { - if (friendp) - { - error ("`%s' is neither function nor method; cannot be declared friend", - IDENTIFIER_POINTER (declarator)); - friendp = 0; - } - decl = NULL_TREE; - } - - if (friendp) - { - /* Friends are treated specially. */ - if (ctype == current_class_type) - warning ("member functions are implicitly friends of their class"); - else - { - tree t = NULL_TREE; - if (decl && DECL_NAME (decl)) - { - if (template_class_depth (current_class_type) == 0) - { - decl - = check_explicit_specialization - (declarator, decl, - template_count, 2 * (funcdef_flag != 0) + 4); - if (decl == error_mark_node) - return error_mark_node; - } - - t = do_friend (ctype, declarator, decl, - last_function_parms, flags, quals, - funcdef_flag); - } - if (t && funcdef_flag) - return t; - - return void_type_node; - } - } - - /* Structure field. It may not be a function, except for C++ */ - - if (decl == NULL_TREE) - { - if (initialized) - { - if (!staticp) - { - /* An attempt is being made to initialize a non-static - member. But, from [class.mem]: - - 4 A member-declarator can contain a - constant-initializer only if it declares a static - member (_class.static_) of integral or enumeration - type, see _class.static.data_. - - This used to be relatively common practice, but - the rest of the compiler does not correctly - handle the initialization unless the member is - static so we make it static below. */ - cp_pedwarn ("ANSI C++ forbids initialization of member `%D'", - declarator); - cp_pedwarn ("making `%D' static", declarator); - staticp = 1; - } - - if (uses_template_parms (type)) - /* We'll check at instantiation time. */ - ; - else if (check_static_variable_definition (declarator, - type)) - /* If we just return the declaration, crashes - will sometimes occur. We therefore return - void_type_node, as if this was a friend - declaration, to cause callers to completely - ignore this declaration. */ - return void_type_node; - } - - /* 9.2p13 [class.mem] */ - if (declarator == constructor_name (current_class_type) - /* Divergence from the standard: In extern "C", we - allow non-static data members here, because C does - and /usr/include/netinet/in.h uses that. */ - && (staticp || ! in_system_header)) - cp_pedwarn ("ANSI C++ forbids data member `%D' with same name as enclosing class", - declarator); - - if (staticp) - { - /* C++ allows static class members. - All other work for this is done by grokfield. - This VAR_DCL is built by build_lang_field_decl. - All other VAR_DECLs are built by build_decl. */ - decl = build_lang_field_decl (VAR_DECL, declarator, type); - TREE_STATIC (decl) = 1; - /* In class context, 'static' means public access. */ - TREE_PUBLIC (decl) = DECL_EXTERNAL (decl) = 1; - } - else - { - decl = build_lang_field_decl (FIELD_DECL, declarator, type); - if (RIDBIT_SETP (RID_MUTABLE, specbits)) - { - DECL_MUTABLE_P (decl) = 1; - RIDBIT_RESET (RID_MUTABLE, specbits); - } - } - - bad_specifiers (decl, "field", virtualp, quals != NULL_TREE, - inlinep, friendp, raises != NULL_TREE); - } - } - else if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE) - { - tree original_name; - int publicp = 0; - - if (! declarator) - return NULL_TREE; - - if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) - original_name = dname; - else - original_name = declarator; - - if (RIDBIT_SETP (RID_AUTO, specbits)) - error ("storage class `auto' invalid for function `%s'", name); - else if (RIDBIT_SETP (RID_REGISTER, specbits)) - error ("storage class `register' invalid for function `%s'", name); - - /* Function declaration not at top level. - Storage classes other than `extern' are not allowed - and `extern' makes no difference. */ - if (! toplevel_bindings_p () - && (RIDBIT_SETP (RID_STATIC, specbits) - || RIDBIT_SETP (RID_INLINE, specbits)) - && pedantic) - { - if (RIDBIT_SETP (RID_STATIC, specbits)) - pedwarn ("storage class `static' invalid for function `%s' declared out of global scope", name); - else - pedwarn ("storage class `inline' invalid for function `%s' declared out of global scope", name); - } - - if (ctype == NULL_TREE) - { - if (virtualp) - { - error ("virtual non-class function `%s'", name); - virtualp = 0; - } - } - else if (TREE_CODE (type) == FUNCTION_TYPE && staticp < 2) - type = build_cplus_method_type (ctype, TREE_TYPE (type), - TYPE_ARG_TYPES (type)); - - /* Record presence of `static'. */ - publicp = (ctype != NULL_TREE - || RIDBIT_SETP (RID_EXTERN, specbits) - || !RIDBIT_SETP (RID_STATIC, specbits)); - - decl = grokfndecl (ctype, type, original_name, declarator, - virtualp, flags, quals, raises, attrlist, - 1, friendp, - publicp, inlinep, funcdef_flag, - template_count, in_namespace); - if (decl == NULL_TREE) - return NULL_TREE; - - /* Among other times, could occur from check_explicit_specialization - returning an error_mark_node. */ - if (decl == error_mark_node) - return error_mark_node; - - if (staticp == 1) - { - int illegal_static = 0; - - /* Don't allow a static member function in a class, and forbid - declaring main to be static. */ - if (TREE_CODE (type) == METHOD_TYPE) - { - cp_pedwarn ("cannot declare member function `%D' to have static linkage", decl); - illegal_static = 1; - } - else if (current_function_decl) - { - /* FIXME need arm citation */ - error ("cannot declare static function inside another function"); - illegal_static = 1; - } - - if (illegal_static) - { - staticp = 0; - RIDBIT_RESET (RID_STATIC, specbits); - } - } - } - else - { - /* It's a variable. */ - - /* An uninitialized decl with `extern' is a reference. */ - decl = grokvardecl (type, declarator, &specbits, - initialized, - (type_quals & TYPE_QUAL_CONST) != 0, - in_namespace); - bad_specifiers (decl, "variable", virtualp, quals != NULL_TREE, - inlinep, friendp, raises != NULL_TREE); - - if (ctype) - { - DECL_CONTEXT (decl) = ctype; - if (staticp == 1) - { - cp_pedwarn ("static member `%D' re-declared as static", decl); - staticp = 0; - RIDBIT_RESET (RID_STATIC, specbits); - } - if (RIDBIT_SETP (RID_REGISTER, specbits) && TREE_STATIC (decl)) - { - cp_error ("static member `%D' declared `register'", decl); - RIDBIT_RESET (RID_REGISTER, specbits); - } - if (RIDBIT_SETP (RID_EXTERN, specbits) && pedantic) - { - cp_pedwarn ("cannot explicitly declare member `%#D' to have extern linkage", - decl); - RIDBIT_RESET (RID_EXTERN, specbits); - } - } - } - - if (RIDBIT_SETP (RID_MUTABLE, specbits)) - { - error ("`%s' cannot be declared mutable", name); - } - - /* Record `register' declaration for warnings on & - and in case doing stupid register allocation. */ - - if (RIDBIT_SETP (RID_REGISTER, specbits)) - DECL_REGISTER (decl) = 1; - - if (RIDBIT_SETP (RID_EXTERN, specbits)) - DECL_THIS_EXTERN (decl) = 1; - - if (RIDBIT_SETP (RID_STATIC, specbits)) - DECL_THIS_STATIC (decl) = 1; - - /* Record constancy and volatility. */ - /* FIXME: Disallow `restrict' pointer-to-member declarations. */ - c_apply_type_quals_to_decl (type_quals, decl); - - return decl; - } -} - -/* Tell if a parmlist/exprlist looks like an exprlist or a parmlist. - An empty exprlist is a parmlist. An exprlist which - contains only identifiers at the global level - is a parmlist. Otherwise, it is an exprlist. */ - -int -parmlist_is_exprlist (exprs) - tree exprs; -{ - if (exprs == NULL_TREE || TREE_PARMLIST (exprs)) - return 0; - - if (toplevel_bindings_p ()) - { - /* At the global level, if these are all identifiers, - then it is a parmlist. */ - while (exprs) - { - if (TREE_CODE (TREE_VALUE (exprs)) != IDENTIFIER_NODE) - return 1; - exprs = TREE_CHAIN (exprs); - } - return 0; - } - return 1; -} - -/* Subroutine of start_function. Ensure that each of the parameter - types (as listed in PARMS) is complete, as is required for a - function definition. */ - -static void -require_complete_types_for_parms (parms) - tree parms; -{ - while (parms) - { - tree type = TREE_TYPE (parms); - if (TYPE_SIZE (complete_type (type)) == NULL_TREE) - { - if (DECL_NAME (parms)) - error ("parameter `%s' has incomplete type", - IDENTIFIER_POINTER (DECL_NAME (parms))); - else - error ("parameter has incomplete type"); - TREE_TYPE (parms) = error_mark_node; - } - else - layout_decl (parms, 0); - - parms = TREE_CHAIN (parms); - } -} - -/* Returns DECL if DECL is a local variable (or parameter). Returns - NULL_TREE otherwise. */ - -static tree -local_variable_p (t) - tree t; -{ - if ((TREE_CODE (t) == VAR_DECL - /* A VAR_DECL with a context that is a _TYPE is a static data - member. */ - && !TYPE_P (CP_DECL_CONTEXT (t)) - /* Any other non-local variable must be at namespace scope. */ - && TREE_CODE (CP_DECL_CONTEXT (t)) != NAMESPACE_DECL) - || (TREE_CODE (t) == PARM_DECL)) - return t; - - return NULL_TREE; -} - -/* Check that ARG, which is a default-argument expression for a - parameter DECL, is legal. Returns ARG, or ERROR_MARK_NODE, if - something goes wrong. DECL may also be a _TYPE node, rather than a - DECL, if there is no DECL available. */ - -tree -check_default_argument (decl, arg) - tree decl; - tree arg; -{ - tree var; - tree decl_type; - - if (TREE_CODE (arg) == DEFAULT_ARG) - /* We get a DEFAULT_ARG when looking at an in-class declaration - with a default argument. Ignore the argument for now; we'll - deal with it after the class is complete. */ - return arg; - - if (processing_template_decl || uses_template_parms (arg)) - /* We don't do anything checking until instantiation-time. Note - that there may be uninstantiated arguments even for an - instantiated function, since default arguments are not - instantiated until they are needed. */ - return arg; - - if (TYPE_P (decl)) - { - decl_type = decl; - decl = NULL_TREE; - } - else - decl_type = TREE_TYPE (decl); - - if (arg == error_mark_node - || decl == error_mark_node - || TREE_TYPE (arg) == error_mark_node - || decl_type == error_mark_node) - /* Something already went wrong. There's no need to check - further. */ - return error_mark_node; - - /* [dcl.fct.default] - - A default argument expression is implicitly converted to the - parameter type. */ - if (!TREE_TYPE (arg) - || !can_convert_arg (decl_type, TREE_TYPE (arg), arg)) - { - if (decl) - cp_error ("default argument for `%#D' has type `%T'", - decl, TREE_TYPE (arg)); - else - cp_error ("default argument for paramter of type `%T' has type `%T'", - decl_type, TREE_TYPE (arg)); - - return error_mark_node; - } - - /* [dcl.fct.default] - - Local variables shall not be used in default argument - expressions. - - The keyword `this' shall not be used in a default argument of a - member function. */ - var = search_tree (arg, local_variable_p); - if (var) - { - cp_error ("default argument `%E' uses local variable `%D'", - arg, var); - return error_mark_node; - } - - /* All is well. */ - return arg; -} - -/* Decode the list of parameter types for a function type. - Given the list of things declared inside the parens, - return a list of types. - - The list we receive can have three kinds of elements: - an IDENTIFIER_NODE for names given without types, - a TREE_LIST node for arguments given as typespecs or names with typespecs, - or void_type_node, to mark the end of an argument list - when additional arguments are not permitted (... was not used). - - FUNCDEF_FLAG is nonzero for a function definition, 0 for - a mere declaration. A nonempty identifier-list gets an error message - when FUNCDEF_FLAG is zero. - If FUNCDEF_FLAG is 1, then parameter types must be complete. - If FUNCDEF_FLAG is -1, then parameter types may be incomplete. - - If all elements of the input list contain types, - we return a list of the types. - If all elements contain no type (except perhaps a void_type_node - at the end), we return a null list. - If some have types and some do not, it is an error, and we - return a null list. - - Also set last_function_parms to either - a list of names (IDENTIFIER_NODEs) or a chain of PARM_DECLs. - A list of names is converted to a chain of PARM_DECLs - by store_parm_decls so that ultimately it is always a chain of decls. - - Note that in C++, parameters can take default values. These default - values are in the TREE_PURPOSE field of the TREE_LIST. It is - an error to specify default values which are followed by parameters - that have no default values, or an ELLIPSES. For simplicities sake, - only parameters which are specified with their types can take on - default values. */ - -static tree -grokparms (first_parm, funcdef_flag) - tree first_parm; - int funcdef_flag; -{ - tree result = NULL_TREE; - tree decls = NULL_TREE; - - if (first_parm != NULL_TREE - && TREE_CODE (TREE_VALUE (first_parm)) == IDENTIFIER_NODE) - { - if (! funcdef_flag) - pedwarn ("parameter names (without types) in function declaration"); - last_function_parms = first_parm; - return NULL_TREE; - } - else if (first_parm != NULL_TREE - && TREE_CODE (TREE_VALUE (first_parm)) != TREE_LIST - && TREE_CODE (TREE_VALUE (first_parm)) != VOID_TYPE) - my_friendly_abort (145); - else - { - /* Types were specified. This is a list of declarators - each represented as a TREE_LIST node. */ - register tree parm, chain; - int any_init = 0, any_error = 0; - - if (first_parm != NULL_TREE) - { - tree last_result = NULL_TREE; - tree last_decl = NULL_TREE; - - for (parm = first_parm; parm != NULL_TREE; parm = chain) - { - tree type = NULL_TREE, list_node = parm; - register tree decl = TREE_VALUE (parm); - tree init = TREE_PURPOSE (parm); - - chain = TREE_CHAIN (parm); - /* @@ weak defense against parse errors. */ - if (TREE_CODE (decl) != VOID_TYPE - && TREE_CODE (decl) != TREE_LIST) - { - /* Give various messages as the need arises. */ - if (TREE_CODE (decl) == STRING_CST) - cp_error ("invalid string constant `%E'", decl); - else if (TREE_CODE (decl) == INTEGER_CST) - error ("invalid integer constant in parameter list, did you forget to give parameter name?"); - continue; - } - - if (TREE_CODE (decl) != VOID_TYPE) - { - decl = grokdeclarator (TREE_VALUE (decl), - TREE_PURPOSE (decl), - PARM, init != NULL_TREE, - NULL_TREE); - if (! decl || TREE_TYPE (decl) == error_mark_node) - continue; - - /* Top-level qualifiers on the parameters are - ignored for function types. */ - type = TYPE_MAIN_VARIANT (TREE_TYPE (decl)); - - if (TREE_CODE (type) == VOID_TYPE) - decl = void_type_node; - else if (TREE_CODE (type) == METHOD_TYPE) - { - if (DECL_NAME (decl)) - /* Cannot use the decl here because - we don't have DECL_CONTEXT set up yet. */ - cp_error ("parameter `%D' invalidly declared method type", - DECL_NAME (decl)); - else - error ("parameter invalidly declared method type"); - type = build_pointer_type (type); - TREE_TYPE (decl) = type; - } - else if (TREE_CODE (type) == OFFSET_TYPE) - { - if (DECL_NAME (decl)) - cp_error ("parameter `%D' invalidly declared offset type", - DECL_NAME (decl)); - else - error ("parameter invalidly declared offset type"); - type = build_pointer_type (type); - TREE_TYPE (decl) = type; - } - else if (TREE_CODE (type) == RECORD_TYPE - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - { - abstract_virtuals_error (decl, type); - any_error = 1; /* Seems like a good idea. */ - } - else if (TREE_CODE (type) == RECORD_TYPE - && TYPE_LANG_SPECIFIC (type) - && IS_SIGNATURE (type)) - { - signature_error (decl, type); - any_error = 1; /* Seems like a good idea. */ - } - else if (POINTER_TYPE_P (type)) - { - tree t = type; - while (POINTER_TYPE_P (t) - || (TREE_CODE (t) == ARRAY_TYPE - && TYPE_DOMAIN (t) != NULL_TREE)) - t = TREE_TYPE (t); - if (TREE_CODE (t) == ARRAY_TYPE) - cp_error ("parameter type `%T' includes %s to array of unknown bound", - type, - TYPE_PTR_P (type) ? "pointer" : "reference"); - } - } - - if (TREE_CODE (decl) == VOID_TYPE) - { - if (result == NULL_TREE) - { - result = void_list_node; - last_result = result; - } - else - { - TREE_CHAIN (last_result) = void_list_node; - last_result = void_list_node; - } - if (chain - && (chain != void_list_node || TREE_CHAIN (chain))) - error ("`void' in parameter list must be entire list"); - break; - } - - /* Since there is a prototype, args are passed in their own types. */ - DECL_ARG_TYPE (decl) = TREE_TYPE (decl); -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (decl) = integer_type_node; -#endif - if (!any_error && init) - { - any_init++; - init = check_default_argument (decl, init); - } - else - init = NULL_TREE; - - if (decls == NULL_TREE) - { - decls = decl; - last_decl = decls; - } - else - { - TREE_CHAIN (last_decl) = decl; - last_decl = decl; - } - if (! current_function_decl && TREE_PERMANENT (list_node)) - { - TREE_PURPOSE (list_node) = init; - TREE_VALUE (list_node) = type; - TREE_CHAIN (list_node) = NULL_TREE; - } - else - list_node = saveable_tree_cons (init, type, NULL_TREE); - if (result == NULL_TREE) - { - result = list_node; - last_result = result; - } - else - { - TREE_CHAIN (last_result) = list_node; - last_result = list_node; - } - } - if (last_result) - TREE_CHAIN (last_result) = NULL_TREE; - /* If there are no parameters, and the function does not end - with `...', then last_decl will be NULL_TREE. */ - if (last_decl != NULL_TREE) - TREE_CHAIN (last_decl) = NULL_TREE; - } - } - - last_function_parms = decls; - - return result; -} - -/* Called from the parser to update an element of TYPE_ARG_TYPES for some - FUNCTION_TYPE with the newly parsed version of its default argument, which - was previously digested as text. See snarf_defarg et al in lex.c. */ - -void -replace_defarg (arg, init) - tree arg, init; -{ - if (! processing_template_decl - && ! can_convert_arg (TREE_VALUE (arg), TREE_TYPE (init), init)) - cp_pedwarn ("invalid type `%T' for default argument to `%T'", - TREE_TYPE (init), TREE_VALUE (arg)); - TREE_PURPOSE (arg) = init; -} - -int -copy_args_p (d) - tree d; -{ - tree t = FUNCTION_ARG_CHAIN (d); - if (DECL_CONSTRUCTOR_P (d) - && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CONTEXT (d))) - t = TREE_CHAIN (t); - if (t && TREE_CODE (TREE_VALUE (t)) == REFERENCE_TYPE - && (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_VALUE (t))) - == DECL_CLASS_CONTEXT (d)) - && (TREE_CHAIN (t) == NULL_TREE - || TREE_CHAIN (t) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (t)))) - return 1; - return 0; -} - -/* These memoizing functions keep track of special properties which - a class may have. `grok_ctor_properties' notices whether a class - has a constructor of the form X(X&), and also complains - if the class has a constructor of the form X(X). - `grok_op_properties' takes notice of the various forms of - operator= which are defined, as well as what sorts of type conversion - may apply. Both functions take a FUNCTION_DECL as an argument. */ - -int -grok_ctor_properties (ctype, decl) - tree ctype, decl; -{ - tree parmtypes = FUNCTION_ARG_CHAIN (decl); - tree parmtype = parmtypes ? TREE_VALUE (parmtypes) : void_type_node; - - /* When a type has virtual baseclasses, a magical first int argument is - added to any ctor so we can tell if the class has been initialized - yet. This could screw things up in this function, so we deliberately - ignore the leading int if we're in that situation. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (ctype)) - { - my_friendly_assert (parmtypes - && TREE_VALUE (parmtypes) == integer_type_node, - 980529); - parmtypes = TREE_CHAIN (parmtypes); - parmtype = TREE_VALUE (parmtypes); - } - - /* [class.copy] - - A non-template constructor for class X is a copy constructor if - its first parameter is of type X&, const X&, volatile X& or const - volatile X&, and either there are no other parameters or else all - other parameters have default arguments. */ - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (parmtype)) == ctype - && (TREE_CHAIN (parmtypes) == NULL_TREE - || TREE_CHAIN (parmtypes) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (parmtypes))) - && !(DECL_TEMPLATE_INSTANTIATION (decl) - && is_member_template (DECL_TI_TEMPLATE (decl)))) - { - TYPE_HAS_INIT_REF (ctype) = 1; - if (CP_TYPE_CONST_P (TREE_TYPE (parmtype))) - TYPE_HAS_CONST_INIT_REF (ctype) = 1; - } - /* [class.copy] - - A declaration of a constructor for a class X is ill-formed if its - first parameter is of type (optionally cv-qualified) X and either - there are no other parameters or else all other parameters have - default arguments. - - We *don't* complain about member template instantiations that - have this form, though; they can occur as we try to decide what - constructor to use during overload resolution. Since overload - resolution will never prefer such a constructor to the - non-template copy constructor (which is either explicitly or - implicitly defined), there's no need to worry about their - existence. Theoretically, they should never even be - instantiated, but that's hard to forestall. */ - else if (TYPE_MAIN_VARIANT (parmtype) == ctype - && (TREE_CHAIN (parmtypes) == NULL_TREE - || TREE_CHAIN (parmtypes) == void_list_node - || TREE_PURPOSE (TREE_CHAIN (parmtypes))) - && !(DECL_TEMPLATE_INSTANTIATION (decl) - && is_member_template (DECL_TI_TEMPLATE (decl)))) - { - cp_error ("invalid constructor; you probably meant `%T (const %T&)'", - ctype, ctype); - SET_IDENTIFIER_ERROR_LOCUS (DECL_NAME (decl), ctype); - return 0; - } - else if (TREE_CODE (parmtype) == VOID_TYPE - || TREE_PURPOSE (parmtypes) != NULL_TREE) - TYPE_HAS_DEFAULT_CONSTRUCTOR (ctype) = 1; - - return 1; -} - -/* An operator with this name can be either unary or binary. */ - -static int -ambi_op_p (name) - tree name; -{ - return (name == ansi_opname [(int) INDIRECT_REF] - || name == ansi_opname [(int) ADDR_EXPR] - || name == ansi_opname [(int) NEGATE_EXPR] - || name == ansi_opname[(int) POSTINCREMENT_EXPR] - || name == ansi_opname[(int) POSTDECREMENT_EXPR] - || name == ansi_opname [(int) CONVERT_EXPR]); -} - -/* An operator with this name can only be unary. */ - -static int -unary_op_p (name) - tree name; -{ - return (name == ansi_opname [(int) TRUTH_NOT_EXPR] - || name == ansi_opname [(int) BIT_NOT_EXPR] - || name == ansi_opname [(int) COMPONENT_REF] - || IDENTIFIER_TYPENAME_P (name)); -} - -/* Do a little sanity-checking on how they declared their operator. */ - -void -grok_op_properties (decl, virtualp, friendp) - tree decl; - int virtualp, friendp; -{ - tree argtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - int methodp = (TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE); - tree name = DECL_NAME (decl); - - if (current_class_type == NULL_TREE) - friendp = 1; - - if (! friendp) - { - /* [class.copy] - - A user-declared copy assignment operator X::operator= is a - non-static non-template member function of class X with - exactly one parameter of type X, X&, const X&, volatile X& or - const volatile X&. */ - if (name == ansi_opname[(int) MODIFY_EXPR] - && !(DECL_TEMPLATE_INSTANTIATION (decl) - && is_member_template (DECL_TI_TEMPLATE (decl)))) - TYPE_HAS_ASSIGNMENT (current_class_type) = 1; - else if (name == ansi_opname[(int) CALL_EXPR]) - TYPE_OVERLOADS_CALL_EXPR (current_class_type) = 1; - else if (name == ansi_opname[(int) ARRAY_REF]) - TYPE_OVERLOADS_ARRAY_REF (current_class_type) = 1; - else if (name == ansi_opname[(int) COMPONENT_REF] - || name == ansi_opname[(int) MEMBER_REF]) - TYPE_OVERLOADS_ARROW (current_class_type) = 1; - else if (name == ansi_opname[(int) NEW_EXPR]) - TYPE_GETS_NEW (current_class_type) |= 1; - else if (name == ansi_opname[(int) DELETE_EXPR]) - TYPE_GETS_DELETE (current_class_type) |= 1; - else if (name == ansi_opname[(int) VEC_NEW_EXPR]) - TYPE_GETS_NEW (current_class_type) |= 2; - else if (name == ansi_opname[(int) VEC_DELETE_EXPR]) - TYPE_GETS_DELETE (current_class_type) |= 2; - } - - if (name == ansi_opname[(int) NEW_EXPR] - || name == ansi_opname[(int) VEC_NEW_EXPR]) - { - /* When the compiler encounters the definition of A::operator new, it - doesn't look at the class declaration to find out if it's static. */ - if (methodp) - revert_static_member_fn (&decl, NULL, NULL); - - /* Take care of function decl if we had syntax errors. */ - if (argtypes == NULL_TREE) - TREE_TYPE (decl) - = build_function_type (ptr_type_node, - hash_tree_chain (integer_type_node, - void_list_node)); - else - TREE_TYPE (decl) = coerce_new_type (TREE_TYPE (decl)); - } - else if (name == ansi_opname[(int) DELETE_EXPR] - || name == ansi_opname[(int) VEC_DELETE_EXPR]) - { - if (methodp) - revert_static_member_fn (&decl, NULL, NULL); - - if (argtypes == NULL_TREE) - TREE_TYPE (decl) - = build_function_type (void_type_node, - hash_tree_chain (ptr_type_node, - void_list_node)); - else - { - TREE_TYPE (decl) = coerce_delete_type (TREE_TYPE (decl)); - - if (! friendp && name == ansi_opname[(int) VEC_DELETE_EXPR] - && (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl))) - != void_list_node)) - TYPE_VEC_DELETE_TAKES_SIZE (current_class_type) = 1; - } - } - else - { - /* An operator function must either be a non-static member function - or have at least one parameter of a class, a reference to a class, - an enumeration, or a reference to an enumeration. 13.4.0.6 */ - if (! methodp || DECL_STATIC_FUNCTION_P (decl)) - { - if (IDENTIFIER_TYPENAME_P (name) - || name == ansi_opname[(int) CALL_EXPR] - || name == ansi_opname[(int) MODIFY_EXPR] - || name == ansi_opname[(int) COMPONENT_REF] - || name == ansi_opname[(int) ARRAY_REF]) - cp_error ("`%D' must be a nonstatic member function", decl); - else - { - tree p = argtypes; - - if (DECL_STATIC_FUNCTION_P (decl)) - cp_error ("`%D' must be either a non-static member function or a non-member function", decl); - - if (p) - for (; TREE_CODE (TREE_VALUE (p)) != VOID_TYPE ; p = TREE_CHAIN (p)) - { - tree arg = TREE_VALUE (p); - if (TREE_CODE (arg) == REFERENCE_TYPE) - arg = TREE_TYPE (arg); - - /* This lets bad template code slip through. */ - if (IS_AGGR_TYPE (arg) - || TREE_CODE (arg) == ENUMERAL_TYPE - || TREE_CODE (arg) == TEMPLATE_TYPE_PARM - || TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - goto foundaggr; - } - cp_error - ("`%D' must have an argument of class or enumerated type", - decl); - foundaggr: - ; - } - } - - if (name == ansi_opname[(int) CALL_EXPR]) - return; /* No restrictions on args. */ - - if (IDENTIFIER_TYPENAME_P (name) && ! DECL_TEMPLATE_INFO (decl)) - { - tree t = TREE_TYPE (name); - if (TREE_CODE (t) == VOID_TYPE) - pedwarn ("void is not a valid type conversion operator"); - else if (! friendp) - { - int ref = (TREE_CODE (t) == REFERENCE_TYPE); - char *what = 0; - if (ref) - t = TYPE_MAIN_VARIANT (TREE_TYPE (t)); - - if (t == current_class_type) - what = "the same type"; - /* Don't force t to be complete here. */ - else if (IS_AGGR_TYPE (t) - && TYPE_SIZE (t) - && DERIVED_FROM_P (t, current_class_type)) - what = "a base class"; - - if (what) - warning ("conversion to %s%s will never use a type conversion operator", - ref ? "a reference to " : "", what); - } - } - - if (name == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtype; - - if (list_length (argtypes) != 3 && methodp) - { - cp_error ("`%D' must take exactly one argument", decl); - return; - } - parmtype = TREE_VALUE (TREE_CHAIN (argtypes)); - - if (copy_assignment_arg_p (parmtype, virtualp) - && ! friendp) - { - TYPE_HAS_ASSIGN_REF (current_class_type) = 1; - if (TREE_CODE (parmtype) != REFERENCE_TYPE - || CP_TYPE_CONST_P (TREE_TYPE (parmtype))) - TYPE_HAS_CONST_ASSIGN_REF (current_class_type) = 1; - } - } - else if (name == ansi_opname[(int) COND_EXPR]) - { - /* 13.4.0.3 */ - pedwarn ("ANSI C++ prohibits overloading operator ?:"); - if (list_length (argtypes) != 4) - cp_error ("`%D' must take exactly three arguments", decl); - } - else if (ambi_op_p (name)) - { - if (list_length (argtypes) == 2) - /* prefix */; - else if (list_length (argtypes) == 3) - { - if ((name == ansi_opname[(int) POSTINCREMENT_EXPR] - || name == ansi_opname[(int) POSTDECREMENT_EXPR]) - && ! processing_template_decl - && ! same_type_p (TREE_VALUE (TREE_CHAIN (argtypes)), integer_type_node)) - { - if (methodp) - cp_error ("postfix `%D' must take `int' as its argument", - decl); - else - cp_error - ("postfix `%D' must take `int' as its second argument", - decl); - } - } - else - { - if (methodp) - cp_error ("`%D' must take either zero or one argument", decl); - else - cp_error ("`%D' must take either one or two arguments", decl); - } - - /* More Effective C++ rule 6. */ - if (warn_ecpp - && (name == ansi_opname[(int) POSTINCREMENT_EXPR] - || name == ansi_opname[(int) POSTDECREMENT_EXPR])) - { - tree arg = TREE_VALUE (argtypes); - tree ret = TREE_TYPE (TREE_TYPE (decl)); - if (methodp || TREE_CODE (arg) == REFERENCE_TYPE) - arg = TREE_TYPE (arg); - arg = TYPE_MAIN_VARIANT (arg); - if (list_length (argtypes) == 2) - { - if (TREE_CODE (ret) != REFERENCE_TYPE - || !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (ret)), - arg)) - cp_warning ("prefix `%D' should return `%T'", decl, - build_reference_type (arg)); - } - else - { - if (!same_type_p (TYPE_MAIN_VARIANT (ret), arg)) - cp_warning ("postfix `%D' should return `%T'", decl, arg); - } - } - } - else if (unary_op_p (name)) - { - if (list_length (argtypes) != 2) - { - if (methodp) - cp_error ("`%D' must take `void'", decl); - else - cp_error ("`%D' must take exactly one argument", decl); - } - } - else /* if (binary_op_p (name)) */ - { - if (list_length (argtypes) != 3) - { - if (methodp) - cp_error ("`%D' must take exactly one argument", decl); - else - cp_error ("`%D' must take exactly two arguments", decl); - } - - /* More Effective C++ rule 7. */ - if (warn_ecpp - && (name == ansi_opname [TRUTH_ANDIF_EXPR] - || name == ansi_opname [TRUTH_ORIF_EXPR] - || name == ansi_opname [COMPOUND_EXPR])) - cp_warning ("user-defined `%D' always evaluates both arguments", - decl); - } - - /* Effective C++ rule 23. */ - if (warn_ecpp - && list_length (argtypes) == 3 - && (name == ansi_opname [PLUS_EXPR] - || name == ansi_opname [MINUS_EXPR] - || name == ansi_opname [TRUNC_DIV_EXPR] - || name == ansi_opname [MULT_EXPR]) - && TREE_CODE (TREE_TYPE (TREE_TYPE (decl))) == REFERENCE_TYPE) - cp_warning ("`%D' should return by value", decl); - - /* 13.4.0.8 */ - if (argtypes) - for (; argtypes != void_list_node ; argtypes = TREE_CHAIN (argtypes)) - if (TREE_PURPOSE (argtypes)) - { - TREE_PURPOSE (argtypes) = NULL_TREE; - if (name == ansi_opname[(int) POSTINCREMENT_EXPR] - || name == ansi_opname[(int) POSTDECREMENT_EXPR]) - { - if (pedantic) - cp_pedwarn ("`%D' cannot have default arguments", decl); - } - else - cp_error ("`%D' cannot have default arguments", decl); - } - } -} - -static char * -tag_name (code) - enum tag_types code; -{ - switch (code) - { - case record_type: - return "struct"; - case class_type: - return "class"; - case union_type: - return "union "; - case enum_type: - return "enum"; - case signature_type: - return "signature"; - default: - my_friendly_abort (981122); - } -} - -/* Get the struct, enum or union (CODE says which) with tag NAME. - Define the tag as a forward-reference if it is not defined. - - C++: If a class derivation is given, process it here, and report - an error if multiple derivation declarations are not identical. - - If this is a definition, come in through xref_tag and only look in - the current frame for the name (since C++ allows new names in any - scope.) */ - -tree -xref_tag (code_type_node, name, globalize) - tree code_type_node; - tree name; - int globalize; -{ - enum tag_types tag_code; - enum tree_code code; - int temp = 0; - register tree ref, t; - struct binding_level *b = inner_binding_level; - int got_type = 0; - tree attributes = NULL_TREE; - - /* If we are called from the parser, code_type_node will sometimes be a - TREE_LIST. This indicates that the user wrote - "class __attribute__ ((foo)) bar". Extract the attributes so we can - use them later. */ - if (TREE_CODE (code_type_node) == TREE_LIST) - { - attributes = TREE_PURPOSE (code_type_node); - code_type_node = TREE_VALUE (code_type_node); - } - - tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); - switch (tag_code) - { - case record_type: - case class_type: - case signature_type: - code = RECORD_TYPE; - break; - case union_type: - code = UNION_TYPE; - break; - case enum_type: - code = ENUMERAL_TYPE; - break; - default: - my_friendly_abort (18); - } - - /* If a cross reference is requested, look up the type - already defined for this tag and return it. */ - if (TREE_CODE_CLASS (TREE_CODE (name)) == 't') - { - t = name; - name = TYPE_IDENTIFIER (t); - got_type = 1; - } - else - t = IDENTIFIER_TYPE_VALUE (name); - - if (t && TREE_CODE (t) != code && TREE_CODE (t) != TEMPLATE_TYPE_PARM - && TREE_CODE (t) != TEMPLATE_TEMPLATE_PARM) - t = NULL_TREE; - - if (! globalize) - { - /* If we know we are defining this tag, only look it up in - this scope and don't try to find it as a type. */ - ref = lookup_tag (code, name, b, 1); - } - else - { - if (current_class_type - && template_class_depth (current_class_type) - && PROCESSING_REAL_TEMPLATE_DECL_P ()) - /* Since GLOBALIZE is non-zero, we are not looking at a - definition of this tag. Since, in addition, we are currently - processing a (member) template declaration of a template - class, we don't want to do any lookup at all; consider: - - template <class X> - struct S1 - - template <class U> - struct S2 - { template <class V> - friend struct S1; }; - - Here, the S2::S1 declaration should not be confused with the - outer declaration. In particular, the inner version should - have a template parameter of level 2, not level 1. This - would be particularly important if the member declaration - were instead: - - template <class V = U> friend struct S1; - - say, when we should tsubst into `U' when instantiating S2. */ - ref = NULL_TREE; - else - { - if (t) - { - if (t != TYPE_MAIN_VARIANT (t)) - cp_pedwarn ("using typedef-name `%D' after `%s'", - TYPE_NAME (t), tag_name (tag_code)); - ref = t; - } - else - ref = lookup_tag (code, name, b, 0); - - if (! ref) - { - /* Try finding it as a type declaration. If that wins, - use it. */ - ref = lookup_name (name, 1); - - if (ref != NULL_TREE - && processing_template_decl - && DECL_CLASS_TEMPLATE_P (ref) - && template_class_depth (current_class_type) == 0) - /* Since GLOBALIZE is true, we're declaring a global - template, so we want this type. */ - ref = DECL_RESULT (ref); - - if (ref && TREE_CODE (ref) == TYPE_DECL - && TREE_CODE (TREE_TYPE (ref)) == code) - ref = TREE_TYPE (ref); - else - ref = NULL_TREE; - } - } - } - - push_obstacks_nochange (); - - if (! ref) - { - /* If no such tag is yet defined, create a forward-reference node - and record it as the "definition". - When a real declaration of this type is found, - the forward-reference will be altered into a real type. */ - - /* In C++, since these migrate into the global scope, we must - build them on the permanent obstack. */ - - temp = allocation_temporary_p (); - if (temp) - end_temporary_allocation (); - - if (code == ENUMERAL_TYPE) - { - cp_error ("use of enum `%#D' without previous declaration", name); - - ref = make_node (ENUMERAL_TYPE); - - /* Give the type a default layout like unsigned int - to avoid crashing if it does not get defined. */ - TYPE_MODE (ref) = TYPE_MODE (unsigned_type_node); - TYPE_ALIGN (ref) = TYPE_ALIGN (unsigned_type_node); - TREE_UNSIGNED (ref) = 1; - TYPE_PRECISION (ref) = TYPE_PRECISION (unsigned_type_node); - TYPE_MIN_VALUE (ref) = TYPE_MIN_VALUE (unsigned_type_node); - TYPE_MAX_VALUE (ref) = TYPE_MAX_VALUE (unsigned_type_node); - - /* Enable us to recognize when a type is created in class context. - To do nested classes correctly, this should probably be cleared - out when we leave this classes scope. Currently this in only - done in `start_enum'. */ - - pushtag (name, ref, globalize); - } - else - { - struct binding_level *old_b = class_binding_level; - - ref = make_lang_type (code); - - if (tag_code == signature_type) - { - SET_SIGNATURE (ref); - /* Since a signature type will be turned into the type - of signature tables, it's not only an interface. */ - CLASSTYPE_INTERFACE_ONLY (ref) = 0; - SET_CLASSTYPE_INTERFACE_KNOWN (ref); - /* A signature doesn't have a vtable. */ - CLASSTYPE_VTABLE_NEEDS_WRITING (ref) = 0; - } - -#ifdef NONNESTED_CLASSES - /* Class types don't nest the way enums do. */ - class_binding_level = (struct binding_level *)0; -#endif - pushtag (name, ref, globalize); - class_binding_level = old_b; - } - } - else - { - /* If it no longer looks like a nested type, make sure it's - in global scope. - If it is not an IDENTIFIER, this is not a declaration */ - if (b->namespace_p && !class_binding_level - && TREE_CODE (name) == IDENTIFIER_NODE) - { - if (IDENTIFIER_NAMESPACE_VALUE (name) == NULL_TREE) - SET_IDENTIFIER_NAMESPACE_VALUE (name, TYPE_NAME (ref)); - } - - if (!globalize && processing_template_decl && IS_AGGR_TYPE (ref)) - redeclare_class_template (ref, current_template_parms); - } - - /* Until the type is defined, tentatively accept whatever - structure tag the user hands us. */ - if (TYPE_SIZE (ref) == NULL_TREE - && ref != current_class_type - /* Have to check this, in case we have contradictory tag info. */ - && IS_AGGR_TYPE_CODE (TREE_CODE (ref))) - { - if (tag_code == class_type) - CLASSTYPE_DECLARED_CLASS (ref) = 1; - else if (tag_code == record_type || tag_code == signature_type) - CLASSTYPE_DECLARED_CLASS (ref) = 0; - } - - pop_obstacks (); - - TREE_TYPE (ref) = attributes; - - if (ref && TYPE_P (ref)) - { - /* [dcl.type.elab] - - If the identifier resolves to a typedef-name or a template - type-parameter, the elaborated-type-specifier is - ill-formed. */ - if (TYPE_LANG_SPECIFIC (ref) && TYPE_WAS_ANONYMOUS (ref)) - cp_error ("`%T' is a typedef name", ref); - else if (TREE_CODE (ref) == TEMPLATE_TYPE_PARM) - cp_error ("`%T' is a template type paramter", ref); - } - - return ref; -} - -tree -xref_tag_from_type (old, id, globalize) - tree old, id; - int globalize; -{ - tree code_type_node; - - if (TREE_CODE (old) == RECORD_TYPE) - code_type_node = (CLASSTYPE_DECLARED_CLASS (old) - ? class_type_node : record_type_node); - else - code_type_node = union_type_node; - - if (id == NULL_TREE) - id = TYPE_IDENTIFIER (old); - - return xref_tag (code_type_node, id, globalize); -} - -void -xref_basetypes (code_type_node, name, ref, binfo) - tree code_type_node; - tree name, ref; - tree binfo; -{ - /* In the declaration `A : X, Y, ... Z' we mark all the types - (A, X, Y, ..., Z) so we can check for duplicates. */ - tree binfos; - int i, len; - enum tag_types tag_code = (enum tag_types) TREE_INT_CST_LOW (code_type_node); - - if (tag_code == union_type) - { - cp_error ("derived union `%T' invalid", ref); - return; - } - - len = list_length (binfo); - push_obstacks (TYPE_OBSTACK (ref), TYPE_OBSTACK (ref)); - - SET_CLASSTYPE_MARKED (ref); - BINFO_BASETYPES (TYPE_BINFO (ref)) = binfos = make_tree_vec (len); - - for (i = 0; binfo; binfo = TREE_CHAIN (binfo)) - { - /* The base of a derived struct is public by default. */ - int via_public - = (TREE_PURPOSE (binfo) == access_public_node - || TREE_PURPOSE (binfo) == access_public_virtual_node - || (tag_code != class_type - && (TREE_PURPOSE (binfo) == access_default_node - || TREE_PURPOSE (binfo) == access_default_virtual_node))); - int via_protected - = (TREE_PURPOSE (binfo) == access_protected_node - || TREE_PURPOSE (binfo) == access_protected_virtual_node); - int via_virtual - = (TREE_PURPOSE (binfo) == access_private_virtual_node - || TREE_PURPOSE (binfo) == access_protected_virtual_node - || TREE_PURPOSE (binfo) == access_public_virtual_node - || TREE_PURPOSE (binfo) == access_default_virtual_node); - tree basetype = TREE_VALUE (binfo); - tree base_binfo; - - if (basetype && TREE_CODE (basetype) == TYPE_DECL) - basetype = TREE_TYPE (basetype); - if (!basetype - || (TREE_CODE (basetype) != RECORD_TYPE - && TREE_CODE (basetype) != TYPENAME_TYPE - && TREE_CODE (basetype) != TEMPLATE_TYPE_PARM - && TREE_CODE (basetype) != TEMPLATE_TEMPLATE_PARM)) - { - cp_error ("base type `%T' fails to be a struct or class type", - TREE_VALUE (binfo)); - continue; - } - - GNU_xref_hier (name, basetype, via_public, via_virtual, 0); - -#if 1 - /* This code replaces similar code in layout_basetypes. - We put the complete_type first for implicit `typename'. */ - if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE - && ! (current_template_parms && uses_template_parms (basetype))) - { - cp_error ("base class `%T' has incomplete type", basetype); - continue; - } -#endif - else - { - if (CLASSTYPE_MARKED (basetype)) - { - if (basetype == ref) - cp_error ("recursive type `%T' undefined", basetype); - else - cp_error ("duplicate base type `%T' invalid", basetype); - continue; - } - - if (TYPE_FOR_JAVA (basetype) - && current_lang_stack == current_lang_base) - TYPE_FOR_JAVA (ref) = 1; - - /* Note that the BINFO records which describe individual - inheritances are *not* shared in the lattice! They - cannot be shared because a given baseclass may be - inherited with different `accessibility' by different - derived classes. (Each BINFO record describing an - individual inheritance contains flags which say what - the `accessibility' of that particular inheritance is.) */ - - base_binfo - = make_binfo (integer_zero_node, basetype, - CLASS_TYPE_P (basetype) - ? TYPE_BINFO_VTABLE (basetype) : NULL_TREE, - CLASS_TYPE_P (basetype) - ? TYPE_BINFO_VIRTUALS (basetype) : NULL_TREE); - - TREE_VEC_ELT (binfos, i) = base_binfo; - TREE_VIA_PUBLIC (base_binfo) = via_public; - TREE_VIA_PROTECTED (base_binfo) = via_protected; - TREE_VIA_VIRTUAL (base_binfo) = via_virtual; - BINFO_INHERITANCE_CHAIN (base_binfo) = TYPE_BINFO (ref); - - /* We need to unshare the binfos now so that lookups during class - definition work. */ - unshare_base_binfos (base_binfo); - - SET_CLASSTYPE_MARKED (basetype); - - /* We are free to modify these bits because they are meaningless - at top level, and BASETYPE is a top-level type. */ - if (via_virtual || TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - TYPE_USES_VIRTUAL_BASECLASSES (ref) = 1; - TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; - } - - if (CLASS_TYPE_P (basetype)) - { - TYPE_GETS_NEW (ref) |= TYPE_GETS_NEW (basetype); - TYPE_GETS_DELETE (ref) |= TYPE_GETS_DELETE (basetype); - } - - i += 1; - } - } - if (i) - TREE_VEC_LENGTH (binfos) = i; - else - BINFO_BASETYPES (TYPE_BINFO (ref)) = NULL_TREE; - - if (i > 1) - TYPE_USES_MULTIPLE_INHERITANCE (ref) = 1; - else if (i == 1) - { - tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, 0)); - - if (CLASS_TYPE_P (basetype)) - TYPE_USES_MULTIPLE_INHERITANCE (ref) - = TYPE_USES_MULTIPLE_INHERITANCE (basetype); - } - - if (TYPE_USES_MULTIPLE_INHERITANCE (ref)) - TYPE_USES_COMPLEX_INHERITANCE (ref) = 1; - - /* Unmark all the types. */ - while (--i >= 0) - CLEAR_CLASSTYPE_MARKED (BINFO_TYPE (TREE_VEC_ELT (binfos, i))); - CLEAR_CLASSTYPE_MARKED (ref); - - pop_obstacks (); -} - - -/* Begin compiling the definition of an enumeration type. - NAME is its name (or null if anonymous). - Returns the type object, as yet incomplete. - Also records info about it so that build_enumerator - may be used to declare the individual values as they are read. */ - -tree -start_enum (name) - tree name; -{ - register tree enumtype = NULL_TREE; - struct binding_level *b = inner_binding_level; - - /* We are wasting space here and putting these on the permanent_obstack so - that typeid(local enum) will work correctly. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* If this is the real definition for a previous forward reference, - fill in the contents in the same object that used to be the - forward reference. */ - - if (name != NULL_TREE) - enumtype = lookup_tag (ENUMERAL_TYPE, name, b, 1); - - if (enumtype != NULL_TREE && TREE_CODE (enumtype) == ENUMERAL_TYPE) - cp_error ("multiple definition of `%#T'", enumtype); - else - { - enumtype = make_node (ENUMERAL_TYPE); - pushtag (name, enumtype, 0); - } - - if (current_class_type) - TREE_ADDRESSABLE (b->tags) = 1; - - /* We don't copy this value because build_enumerator needs to do it. */ - enum_next_value = integer_zero_node; - enum_overflow = 0; - - GNU_xref_decl (current_function_decl, enumtype); - return enumtype; -} - -/* After processing and defining all the values of an enumeration type, - install their decls in the enumeration type and finish it off. - ENUMTYPE is the type object and VALUES a list of name-value pairs. - Returns ENUMTYPE. */ - -tree -finish_enum (enumtype) - tree enumtype; -{ - register tree minnode = NULL_TREE, maxnode = NULL_TREE; - /* Calculate the maximum value of any enumerator in this type. */ - - tree values = TYPE_VALUES (enumtype); - if (values) - { - tree pair; - - for (pair = values; pair; pair = TREE_CHAIN (pair)) - { - tree decl; - tree value; - - /* The TREE_VALUE is a CONST_DECL for this enumeration - constant. */ - decl = TREE_VALUE (pair); - - /* The DECL_INITIAL will be NULL if we are processing a - template declaration and this enumeration constant had no - explicit initializer. */ - value = DECL_INITIAL (decl); - if (value && !processing_template_decl) - { - /* Set the TREE_TYPE for the VALUE as well. That's so - that when we call decl_constant_value we get an - entity of the right type (but with the constant - value). Since we shouldn't ever call - decl_constant_value on a template type, there's no - reason to do that when processing_template_decl. - And, if the expression is something like a - TEMPLATE_PARM_INDEX or a CAST_EXPR doing so will - wreak havoc on the intended type of the expression. - - Of course, there's also no point in trying to compute - minimum or maximum values if we're in a template. */ - TREE_TYPE (value) = enumtype; - - if (!minnode) - minnode = maxnode = value; - else if (tree_int_cst_lt (maxnode, value)) - maxnode = value; - else if (tree_int_cst_lt (value, minnode)) - minnode = value; - } - - if (processing_template_decl) - /* If this is just a template, leave the CONST_DECL - alone. That way tsubst_copy will find CONST_DECLs for - CONST_DECLs, and not INTEGER_CSTs. */ - ; - else - /* In the list we're building up, we want the enumeration - values, not the CONST_DECLs. */ - TREE_VALUE (pair) = value; - } - } - else - maxnode = minnode = integer_zero_node; - - TYPE_VALUES (enumtype) = nreverse (values); - - if (processing_template_decl) - { - tree scope = current_scope (); - if (scope && TREE_CODE (scope) == FUNCTION_DECL) - add_tree (build_min (TAG_DEFN, enumtype)); - } - else - { - int unsignedp = tree_int_cst_sgn (minnode) >= 0; - int lowprec = min_precision (minnode, unsignedp); - int highprec = min_precision (maxnode, unsignedp); - int precision = MAX (lowprec, highprec); - tree tem; - - TYPE_SIZE (enumtype) = NULL_TREE; - - /* Set TYPE_MIN_VALUE and TYPE_MAX_VALUE according to `precision'. */ - - TYPE_PRECISION (enumtype) = precision; - if (unsignedp) - fixup_unsigned_type (enumtype); - else - fixup_signed_type (enumtype); - - if (flag_short_enums || (precision > TYPE_PRECISION (integer_type_node))) - /* Use the width of the narrowest normal C type which is wide - enough. */ - TYPE_PRECISION (enumtype) = TYPE_PRECISION (type_for_size - (precision, 1)); - else - TYPE_PRECISION (enumtype) = TYPE_PRECISION (integer_type_node); - - TYPE_SIZE (enumtype) = 0; - layout_type (enumtype); - - /* Fix up all variant types of this enum type. */ - for (tem = TYPE_MAIN_VARIANT (enumtype); tem; - tem = TYPE_NEXT_VARIANT (tem)) - { - TYPE_VALUES (tem) = TYPE_VALUES (enumtype); - TYPE_MIN_VALUE (tem) = TYPE_MIN_VALUE (enumtype); - TYPE_MAX_VALUE (tem) = TYPE_MAX_VALUE (enumtype); - TYPE_SIZE (tem) = TYPE_SIZE (enumtype); - TYPE_SIZE_UNIT (tem) = TYPE_SIZE_UNIT (enumtype); - TYPE_MODE (tem) = TYPE_MODE (enumtype); - TYPE_PRECISION (tem) = TYPE_PRECISION (enumtype); - TYPE_ALIGN (tem) = TYPE_ALIGN (enumtype); - TREE_UNSIGNED (tem) = TREE_UNSIGNED (enumtype); - } - - /* Finish debugging output for this type. */ - rest_of_type_compilation (enumtype, namespace_bindings_p ()); - } - - /* In start_enum we pushed obstacks. Here, we must pop them. */ - pop_obstacks (); - - return enumtype; -} - -/* Build and install a CONST_DECL for an enumeration constant of the - enumeration type TYPE whose NAME and VALUE (if any) are provided. - Assignment of sequential values by default is handled here. */ - -tree -build_enumerator (name, value, type) - tree name; - tree value; - tree type; -{ - tree decl, result; - tree context; - - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); - - if (! processing_template_decl) - { - /* Validate and default VALUE. */ - if (value != NULL_TREE) - { - if (TREE_READONLY_DECL_P (value)) - value = decl_constant_value (value); - - if (TREE_CODE (value) == INTEGER_CST) - { - value = default_conversion (value); - constant_expression_warning (value); - } - else - { - cp_error ("enumerator value for `%D' not integer constant", name); - value = NULL_TREE; - } - } - - /* Default based on previous value. */ - if (value == NULL_TREE && ! processing_template_decl) - { - value = enum_next_value; - if (enum_overflow) - cp_error ("overflow in enumeration values at `%D'", name); - } - - /* Remove no-op casts from the value. */ - if (value) - STRIP_TYPE_NOPS (value); -#if 0 - /* To fix MAX_VAL enum consts. (bkoz) */ - TREE_TYPE (value) = integer_type_node; -#endif - } - - /* We always have to copy here; not all INTEGER_CSTs are unshared. - Even in other cases, we will later (in finish_enum) be setting the - type of VALUE. */ - if (value != NULL_TREE) - value = copy_node (value); - - /* C++ associates enums with global, function, or class declarations. */ - - context = current_scope (); - if (context && context == current_class_type) - /* This enum declaration is local to the class. */ - decl = build_lang_field_decl (CONST_DECL, name, type); - else - /* It's a global enum, or it's local to a function. (Note local to - a function could mean local to a class method. */ - decl = build_decl (CONST_DECL, name, type); - - DECL_CONTEXT (decl) = FROB_CONTEXT (context); - DECL_INITIAL (decl) = value; - TREE_READONLY (decl) = 1; - - if (context && context == current_class_type) - { - pushdecl_class_level (decl); - /* In something like `struct S { enum E { i = 7 }; };' we put `i' - on the TYPE_FIELDS list for `S'. (That's so that you can say - things like `S::i' later.) */ - finish_member_declaration (decl); - } - else - { - pushdecl (decl); - GNU_xref_decl (current_function_decl, decl); - } - - if (! processing_template_decl) - { - /* Set basis for default for next value. */ - enum_next_value = build_binary_op_nodefault (PLUS_EXPR, value, - integer_one_node, PLUS_EXPR); - enum_overflow = tree_int_cst_lt (enum_next_value, value); - } - - result = saveable_tree_cons (name, decl, NULL_TREE); - return result; -} - - -static int function_depth; - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - If PRE_PARSED_P is non-zero then DECLARATOR is really the DECL for - the function we are about to process; DECLSPECS are ignored. For - example, we set PRE_PARSED_P when processing the definition of - inline function that was defined in-class; the definition is - actually processed when the class is complete. In this case, - PRE_PARSED_P is 2. We also set PRE_PARSED_P when instanting the - body of a template function, and when constructing thunk functions - and such; in these cases PRE_PARSED_P is 1. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. - - For C++, we must first check whether that datum makes any sense. - For example, "class A local_a(1,2);" means that variable local_a - is an aggregate of type A, which should have a constructor - applied to it with the argument list [1, 2]. - - @@ There is currently no way to retrieve the storage - @@ allocated to FUNCTION (or all of its parms) if we return - @@ something we had previously. */ - -int -start_function (declspecs, declarator, attrs, pre_parsed_p) - tree declspecs, declarator, attrs; - int pre_parsed_p; -{ - tree decl1; - tree ctype = NULL_TREE; - tree fntype; - tree restype; - extern int have_extern_spec; - extern int used_extern_spec; - int doing_friend = 0; - - /* Sanity check. */ - my_friendly_assert (TREE_CODE (TREE_VALUE (void_list_node)) == VOID_TYPE, 160); - my_friendly_assert (TREE_CHAIN (void_list_node) == NULL_TREE, 161); - - /* Assume, until we see it does. */ - current_function_returns_value = 0; - current_function_returns_null = 0; - named_labels = 0; - shadowed_labels = 0; - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - current_function_parms_stored = 0; - original_result_rtx = NULL_RTX; - base_init_expr = NULL_TREE; - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - ctor_label = dtor_label = NULL_TREE; - static_labelno = 0; - - clear_temp_name (); - - /* This should only be done once on the top most decl. */ - if (have_extern_spec && !used_extern_spec) - { - declspecs = decl_tree_cons (NULL_TREE, get_identifier ("extern"), declspecs); - used_extern_spec = 1; - } - - if (pre_parsed_p) - { - decl1 = declarator; - -#if 0 - /* What was this testing for, exactly? */ - if (! DECL_ARGUMENTS (decl1) - && !DECL_STATIC_FUNCTION_P (decl1) - && !DECL_ARTIFICIAL (decl1) - && DECL_CLASS_SCOPE_P (decl1) - && TYPE_IDENTIFIER (DECL_CONTEXT (decl1)) - && IDENTIFIER_TEMPLATE (TYPE_IDENTIFIER (DECL_CONTEXT (decl1)))) - { - tree binding = binding_for_name (DECL_NAME (decl1), - current_namespace); - cp_error ("redeclaration of `%#D'", decl1); - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))) - cp_error_at ("previous declaration here", IDENTIFIER_CLASS_VALUE (DECL_NAME (decl1))); - else if (BINDING_VALUE (binding)) - cp_error_at ("previous declaration here", BINDING_VALUE (binding)); - } -#endif - - fntype = TREE_TYPE (decl1); - if (TREE_CODE (fntype) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (fntype); - - /* ANSI C++ June 5 1992 WP 11.4.5. A friend function defined in a - class is in the (lexical) scope of the class in which it is - defined. */ - if (!ctype && DECL_FRIEND_P (decl1)) - { - ctype = DECL_CLASS_CONTEXT (decl1); - - /* CTYPE could be null here if we're dealing with a template; - for example, `inline friend float foo()' inside a template - will have no CTYPE set. */ - if (ctype && TREE_CODE (ctype) != RECORD_TYPE) - ctype = NULL_TREE; - else - doing_friend = 1; - } - - last_function_parms = DECL_ARGUMENTS (decl1); - last_function_parm_tags = NULL_TREE; - } - else - { - decl1 = grokdeclarator (declarator, declspecs, FUNCDEF, 1, NULL_TREE); - /* If the declarator is not suitable for a function definition, - cause a syntax error. */ - if (decl1 == NULL_TREE || TREE_CODE (decl1) != FUNCTION_DECL) return 0; - - fntype = TREE_TYPE (decl1); - - restype = TREE_TYPE (fntype); - if (CLASS_TYPE_P (restype) && !CLASSTYPE_GOT_SEMICOLON (restype)) - { - cp_error ("semicolon missing after declaration of `%#T'", restype); - shadow_tag (build_expr_list (NULL_TREE, restype)); - CLASSTYPE_GOT_SEMICOLON (restype) = 1; - if (TREE_CODE (fntype) == FUNCTION_TYPE) - fntype = build_function_type (integer_type_node, - TYPE_ARG_TYPES (fntype)); - else - fntype = build_cplus_method_type (build_type_variant (TYPE_METHOD_BASETYPE (fntype), TREE_READONLY (decl1), TREE_SIDE_EFFECTS (decl1)), - integer_type_node, - TYPE_ARG_TYPES (fntype)); - TREE_TYPE (decl1) = fntype; - } - - if (TREE_CODE (fntype) == METHOD_TYPE) - ctype = TYPE_METHOD_BASETYPE (fntype); - else if (DECL_MAIN_P (decl1)) - { - /* If this doesn't return integer_type, complain. */ - if (TREE_TYPE (TREE_TYPE (decl1)) != integer_type_node) - { - if (pedantic || warn_return_type) - pedwarn ("return type for `main' changed to `int'"); - TREE_TYPE (decl1) = fntype = default_function_type; - } - } - } - - /* Warn if function was previously implicitly declared - (but not if we warned then). */ - if (! warn_implicit - && IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1)) != NULL_TREE) - cp_warning_at ("`%D' implicitly declared before its definition", IDENTIFIER_IMPLICIT_DECL (DECL_NAME (decl1))); - - announce_function (decl1); - - /* Set up current_class_type, and enter the scope of the class, if - appropriate. */ - if (ctype) - push_nested_class (ctype, 1); - else if (DECL_STATIC_FUNCTION_P (decl1)) - push_nested_class (DECL_CONTEXT (decl1), 2); - - /* Now that we have entered the scope of the class, we must restore - the bindings for any template parameters surrounding DECL1, if it - is an inline member template. (Order is important; consider the - case where a template parameter has the same name as a field of - the class.) It is not until after this point that - PROCESSING_TEMPLATE_DECL is guaranteed to be set up correctly. */ - if (pre_parsed_p == 2) - maybe_begin_member_template_processing (decl1); - - /* We are now in the scope of the function being defined. */ - current_function_decl = decl1; - - /* Save the parm names or decls from this function's declarator - where store_parm_decls will find them. */ - current_function_parms = last_function_parms; - current_function_parm_tags = last_function_parm_tags; - - if (! processing_template_decl) - { - /* In a function definition, arg types must be complete. */ - require_complete_types_for_parms (current_function_parms); - - if (TYPE_SIZE (complete_type (TREE_TYPE (fntype))) == NULL_TREE) - { - cp_error ("return-type `%#T' is an incomplete type", - TREE_TYPE (fntype)); - - /* Make it return void instead, but don't change the - type of the DECL_RESULT, in case we have a named return value. */ - if (ctype) - TREE_TYPE (decl1) - = build_cplus_method_type (build_type_variant (ctype, - TREE_READONLY (decl1), - TREE_SIDE_EFFECTS (decl1)), - void_type_node, - FUNCTION_ARG_CHAIN (decl1)); - else - TREE_TYPE (decl1) - = build_function_type (void_type_node, - TYPE_ARG_TYPES (TREE_TYPE (decl1))); - DECL_RESULT (decl1) - = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (TREE_TYPE (fntype))); - TREE_READONLY (DECL_RESULT (decl1)) - = CP_TYPE_CONST_P (TREE_TYPE (fntype)); - TREE_THIS_VOLATILE (DECL_RESULT (decl1)) - = CP_TYPE_VOLATILE_P (TREE_TYPE (fntype)); - } - - if (TYPE_LANG_SPECIFIC (TREE_TYPE (fntype)) - && CLASSTYPE_ABSTRACT_VIRTUALS (TREE_TYPE (fntype))) - abstract_virtuals_error (decl1, TREE_TYPE (fntype)); - } - - /* Effective C++ rule 15. See also c_expand_return. */ - if (warn_ecpp - && DECL_NAME (decl1) == ansi_opname[(int) MODIFY_EXPR] - && TREE_CODE (TREE_TYPE (fntype)) == VOID_TYPE) - cp_warning ("`operator=' should return a reference to `*this'"); - - /* Make the init_value nonzero so pushdecl knows this is not tentative. - error_mark_node is replaced below (in poplevel) with the BLOCK. */ - DECL_INITIAL (decl1) = error_mark_node; - -#ifdef SET_DEFAULT_DECL_ATTRIBUTES - SET_DEFAULT_DECL_ATTRIBUTES (decl1, attrs); -#endif - - /* This function exists in static storage. - (This does not mean `static' in the C sense!) */ - TREE_STATIC (decl1) = 1; - - /* We must call push_template_decl after current_class_type is set - up. (If we are processing inline definitions after exiting a - class scope, current_class_type will be NULL_TREE until set above - by push_nested_class.) */ - if (processing_template_decl) - decl1 = push_template_decl (decl1); - - /* Record the decl so that the function name is defined. - If we already have a decl for this name, and it is a FUNCTION_DECL, - use the old decl. */ - if (!processing_template_decl && pre_parsed_p == 0) - { - /* A specialization is not used to guide overload resolution. */ - if ((flag_guiding_decls - || !DECL_TEMPLATE_SPECIALIZATION (decl1)) - && ! DECL_FUNCTION_MEMBER_P (decl1)) - decl1 = pushdecl (decl1); - else - { - /* We need to set the DECL_CONTEXT. */ - if (!DECL_CONTEXT (decl1) && DECL_TEMPLATE_INFO (decl1)) - DECL_CONTEXT (decl1) = DECL_CONTEXT (DECL_TI_TEMPLATE (decl1)); - /* And make sure we have enough default args. */ - check_default_args (decl1); - } - DECL_MAIN_VARIANT (decl1) = decl1; - fntype = TREE_TYPE (decl1); - } - - current_function_decl = decl1; - - if (DECL_INTERFACE_KNOWN (decl1)) - { - tree ctx = hack_decl_function_context (decl1); - - if (DECL_NOT_REALLY_EXTERN (decl1)) - DECL_EXTERNAL (decl1) = 0; - - if (ctx != NULL_TREE && DECL_THIS_INLINE (ctx) - && TREE_PUBLIC (ctx)) - /* This is a function in a local class in an extern inline - function. */ - comdat_linkage (decl1); - } - /* If this function belongs to an interface, it is public. - If it belongs to someone else's interface, it is also external. - This only affects inlines and template instantiations. */ - else if (interface_unknown == 0 - && (! DECL_TEMPLATE_INSTANTIATION (decl1) - || flag_alt_external_templates)) - { - if (DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1) - || processing_template_decl) - { - DECL_EXTERNAL (decl1) - = (interface_only - || (DECL_THIS_INLINE (decl1) && ! flag_implement_inlines)); - - /* For WIN32 we also want to put these in linkonce sections. */ - maybe_make_one_only (decl1); - } - else - DECL_EXTERNAL (decl1) = 0; - DECL_NOT_REALLY_EXTERN (decl1) = 0; - DECL_INTERFACE_KNOWN (decl1) = 1; - } - else - { - /* This is a definition, not a reference. - So clear DECL_EXTERNAL. */ - DECL_EXTERNAL (decl1) = 0; - - if ((DECL_THIS_INLINE (decl1) || DECL_TEMPLATE_INSTANTIATION (decl1)) - && ! DECL_INTERFACE_KNOWN (decl1) - /* Don't try to defer nested functions for now. */ - && ! hack_decl_function_context (decl1)) - DECL_DEFER_OUTPUT (decl1) = 1; - else - DECL_INTERFACE_KNOWN (decl1) = 1; - } - - if (ctype != NULL_TREE && DECL_STATIC_FUNCTION_P (decl1)) - { - if (TREE_CODE (fntype) == METHOD_TYPE) - TREE_TYPE (decl1) = fntype - = build_function_type (TREE_TYPE (fntype), - TREE_CHAIN (TYPE_ARG_TYPES (fntype))); - current_function_parms = TREE_CHAIN (current_function_parms); - DECL_ARGUMENTS (decl1) = current_function_parms; - ctype = NULL_TREE; - } - restype = TREE_TYPE (fntype); - - if (ctype) - { - /* If we're compiling a friend function, neither of the variables - current_class_ptr nor current_class_type will have values. */ - if (! doing_friend) - { - /* We know that this was set up by `grokclassfn'. - We do not wait until `store_parm_decls', since evil - parse errors may never get us to that point. Here - we keep the consistency between `current_class_type' - and `current_class_ptr'. */ - tree t = current_function_parms; - - my_friendly_assert (t != NULL_TREE - && TREE_CODE (t) == PARM_DECL, 162); - - if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE) - { - int i; - - if (! hack_decl_function_context (decl1)) - temporary_allocation (); - i = suspend_momentary (); - - /* Normally, build_indirect_ref returns - current_class_ref whenever current_class_ptr is - dereferenced. This time, however, we want it to - *create* current_class_ref, so we temporarily clear - current_class_ptr to fool it. */ - current_class_ptr = NULL_TREE; - current_class_ref = build_indirect_ref (t, NULL_PTR); - current_class_ptr = t; - - resume_momentary (i); - if (! hack_decl_function_context (decl1)) - end_temporary_allocation (); - } - else - /* We're having a signature pointer here. */ - current_class_ref = current_class_ptr = t; - - } - } - else - current_class_ptr = current_class_ref = NULL_TREE; - - pushlevel (0); - current_binding_level->parm_flag = 1; - - GNU_xref_function (decl1, current_function_parms); - - if (attrs) - cplus_decl_attributes (decl1, NULL_TREE, attrs); - - make_function_rtl (decl1); - - /* Promote the value to int before returning it. */ - if (C_PROMOTING_INTEGER_TYPE_P (restype)) - restype = type_promotes_to (restype); - - /* If this fcn was already referenced via a block-scope `extern' decl - (or an implicit decl), propagate certain information about the usage. */ - if (TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (decl1))) - TREE_ADDRESSABLE (decl1) = 1; - - if (DECL_RESULT (decl1) == NULL_TREE) - { - DECL_RESULT (decl1) - = build_decl (RESULT_DECL, 0, TYPE_MAIN_VARIANT (restype)); - TREE_READONLY (DECL_RESULT (decl1)) = CP_TYPE_CONST_P (restype); - TREE_THIS_VOLATILE (DECL_RESULT (decl1)) = CP_TYPE_VOLATILE_P (restype); - } - - /* Allocate further tree nodes temporarily during compilation - of this function only. Tiemann moved up here from bottom of fn. */ - /* If this is a nested function, then we must continue to allocate RTL - on the permanent obstack in case we need to inline it later. */ - if (! hack_decl_function_context (decl1)) - temporary_allocation (); - - if (processing_template_decl) - { - ++minimal_parse_mode; - last_tree = DECL_SAVED_TREE (decl1) - = build_nt (EXPR_STMT, void_zero_node); - } - - ++function_depth; - - if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (decl1)) - && DECL_LANGUAGE (decl1) == lang_cplusplus) - { - dtor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - ctor_label = NULL_TREE; - } - else - { - dtor_label = NULL_TREE; - if (DECL_CONSTRUCTOR_P (decl1)) - ctor_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - } - - return 1; -} - -/* Called after store_parm_decls for a function-try-block. We need to update - last_parm_cleanup_insn so that the base initializers for a constructor - are run within this block, not before it. */ - -void -expand_start_early_try_stmts () -{ - expand_start_try_stmts (); - last_parm_cleanup_insn = get_last_insn (); -} - -/* Store the parameter declarations into the current function declaration. - This is called after parsing the parameter declarations, before - digesting the body of the function. - - Also install to binding contour return value identifier, if any. */ - -void -store_parm_decls () -{ - register tree fndecl = current_function_decl; - register tree parm; - int parms_have_cleanups = 0; - tree cleanups = NULL_TREE; - - /* This is either a chain of PARM_DECLs (when a prototype is used). */ - tree specparms = current_function_parms; - - /* This is a list of types declared among parms in a prototype. */ - tree parmtags = current_function_parm_tags; - - /* This is a chain of any other decls that came in among the parm - declarations. If a parm is declared with enum {foo, bar} x; - then CONST_DECLs for foo and bar are put here. */ - tree nonparms = NULL_TREE; - - if (toplevel_bindings_p ()) - fatal ("parse errors have confused me too much"); - - /* Initialize RTL machinery. */ - init_function_start (fndecl, input_filename, lineno); - - /* Create a binding level for the parms. */ - expand_start_bindings (0); - - if (specparms != NULL_TREE) - { - /* This case is when the function was defined with an ANSI prototype. - The parms already have decls, so we need not do anything here - except record them as in effect - and complain if any redundant old-style parm decls were written. */ - - register tree next; - - /* Must clear this because it might contain TYPE_DECLs declared - at class level. */ - storedecls (NULL_TREE); - - for (parm = nreverse (specparms); parm; parm = next) - { - next = TREE_CHAIN (parm); - if (TREE_CODE (parm) == PARM_DECL) - { - tree cleanup; - if (DECL_NAME (parm) == NULL_TREE) - { - pushdecl (parm); - } - else if (TREE_CODE (TREE_TYPE (parm)) == VOID_TYPE) - cp_error ("parameter `%D' declared void", parm); - else - { - /* Now fill in DECL_REFERENCE_SLOT for any of the parm decls. - A parameter is assumed not to have any side effects. - If this should change for any reason, then this - will have to wrap the bashed reference type in a save_expr. - - Also, if the parameter type is declared to be an X - and there is an X(X&) constructor, we cannot lay it - into the stack (any more), so we make this parameter - look like it is really of reference type. Functions - which pass parameters to this function will know to - create a temporary in their frame, and pass a reference - to that. */ - - if (TREE_CODE (TREE_TYPE (parm)) == REFERENCE_TYPE - && TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm)))) - SET_DECL_REFERENCE_SLOT (parm, convert_from_reference (parm)); - - pushdecl (parm); - } - if (! processing_template_decl - && (cleanup = maybe_build_cleanup (parm), cleanup)) - { - expand_decl (parm); - parms_have_cleanups = 1; - - /* Keep track of the cleanups. */ - cleanups = tree_cons (parm, cleanup, cleanups); - } - } - else - { - /* If we find an enum constant or a type tag, - put it aside for the moment. */ - TREE_CHAIN (parm) = NULL_TREE; - nonparms = chainon (nonparms, parm); - } - } - - /* Get the decls in their original chain order - and record in the function. This is all and only the - PARM_DECLs that were pushed into scope by the loop above. */ - DECL_ARGUMENTS (fndecl) = getdecls (); - - storetags (chainon (parmtags, gettags ())); - } - else - DECL_ARGUMENTS (fndecl) = NULL_TREE; - - /* Now store the final chain of decls for the arguments - as the decl-chain of the current lexical scope. - Put the enumerators in as well, at the front so that - DECL_ARGUMENTS is not modified. */ - - storedecls (chainon (nonparms, DECL_ARGUMENTS (fndecl))); - - /* Declare __FUNCTION__ and __PRETTY_FUNCTION__ for this function. */ - declare_function_name (); - - /* Initialize the RTL code for the function. */ - DECL_SAVED_INSNS (fndecl) = NULL_RTX; - if (! processing_template_decl) - expand_function_start (fndecl, parms_have_cleanups); - - current_function_parms_stored = 1; - - /* If this function is `main', emit a call to `__main' - to run global initializers, etc. */ - if (DECL_MAIN_P (fndecl)) - expand_main_function (); - - /* Now that we have initialized the parms, we can start their - cleanups. We cannot do this before, since expand_decl_cleanup - should not be called before the parm can be used. */ - if (cleanups - && ! processing_template_decl) - { - for (cleanups = nreverse (cleanups); cleanups; cleanups = TREE_CHAIN (cleanups)) - { - if (! expand_decl_cleanup (TREE_PURPOSE (cleanups), TREE_VALUE (cleanups))) - cp_error ("parser lost in parsing declaration of `%D'", - TREE_PURPOSE (cleanups)); - } - } - - /* Create a binding contour which can be used to catch - cleanup-generated temporaries. Also, if the return value needs or - has initialization, deal with that now. */ - if (parms_have_cleanups) - { - pushlevel (0); - expand_start_bindings (0); - } - - if (! processing_template_decl && flag_exceptions) - { - /* Do the starting of the exception specifications, if we have any. */ - if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) - expand_start_eh_spec (); - } - - last_parm_cleanup_insn = get_last_insn (); - last_dtor_insn = get_last_insn (); -} - -/* Bind a name and initialization to the return value of - the current function. */ - -void -store_return_init (return_id, init) - tree return_id, init; -{ - tree decl = DECL_RESULT (current_function_decl); - - if (pedantic) - /* Give this error as many times as there are occurrences, - so that users can use Emacs compilation buffers to find - and fix all such places. */ - pedwarn ("ANSI C++ does not permit named return values"); - - if (return_id != NULL_TREE) - { - if (DECL_NAME (decl) == NULL_TREE) - { - DECL_NAME (decl) = return_id; - DECL_ASSEMBLER_NAME (decl) = return_id; - } - else - cp_error ("return identifier `%D' already in place", decl); - } - - /* Can't let this happen for constructors. */ - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - error ("can't redefine default return value for constructors"); - return; - } - - /* If we have a named return value, put that in our scope as well. */ - if (DECL_NAME (decl) != NULL_TREE) - { - /* If this named return value comes in a register, - put it in a pseudo-register. */ - if (DECL_REGISTER (decl)) - { - original_result_rtx = DECL_RTL (decl); - DECL_RTL (decl) = gen_reg_rtx (DECL_MODE (decl)); - } - - /* Let `cp_finish_decl' know that this initializer is ok. */ - DECL_INITIAL (decl) = init; - pushdecl (decl); - - if (minimal_parse_mode) - add_tree (build_min_nt (RETURN_INIT, return_id, - copy_to_permanent (init))); - else - cp_finish_decl (decl, init, NULL_TREE, 0, 0); - } -} - - -/* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage - for the function definition. - - This is called after parsing the body of the function definition. - LINENO is the current line number. - - FLAGS is a bitwise or of the following values: - 1 - CALL_POPLEVEL - An extra call to poplevel (and expand_end_bindings) must be - made to take care of the binding contour for the base - initializers. This is only relevant for constructors. - 2 - INCLASS_INLINE - We just finished processing the body of an in-class inline - function definition. (This processing will have taken place - after the class definition is complete.) - - NESTED is nonzero if we were in the middle of compiling another function - when we started on this one. */ - -void -finish_function (lineno, flags, nested) - int lineno; - int flags; - int nested; -{ - register tree fndecl = current_function_decl; - tree fntype, ctype = NULL_TREE; - rtx last_parm_insn, insns; - /* Label to use if this function is supposed to return a value. */ - tree no_return_label = NULL_TREE; - tree decls = NULL_TREE; - int call_poplevel = (flags & 1) != 0; - int inclass_inline = (flags & 2) != 0; - int in_template; - - /* When we get some parse errors, we can end up without a - current_function_decl, so cope. */ - if (fndecl == NULL_TREE) - return; - - if (! nested && function_depth > 1) - nested = 1; - - fntype = TREE_TYPE (fndecl); - -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ - - /* This happens on strange parse errors. */ - if (! current_function_parms_stored) - { - call_poplevel = 0; - store_parm_decls (); - } - - if (processing_template_decl) - { - if (DECL_CONSTRUCTOR_P (fndecl) && call_poplevel) - { - decls = getdecls (); - expand_end_bindings (decls, decls != NULL_TREE, 0); - poplevel (decls != NULL_TREE, 0, 0); - } - } - else - { - if (write_symbols != NO_DEBUG /*&& TREE_CODE (fntype) != METHOD_TYPE*/) - { - tree ttype = target_type (fntype); - tree parmdecl; - - if (IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - - for (parmdecl = DECL_ARGUMENTS (fndecl); parmdecl; parmdecl = TREE_CHAIN (parmdecl)) - { - ttype = target_type (TREE_TYPE (parmdecl)); - if (IS_AGGR_TYPE (ttype)) - /* Let debugger know it should output info for this type. */ - note_debug_info_needed (ttype); - } - } - - /* Clean house because we will need to reorder insns here. */ - do_pending_stack_adjust (); - - if (dtor_label) - { - tree binfo = TYPE_BINFO (current_class_type); - tree cond = integer_one_node; - tree exprstmt; - tree in_charge_node = lookup_name (in_charge_identifier, 0); - tree virtual_size; - int ok_to_optimize_dtor = 0; - int empty_dtor = get_last_insn () == last_dtor_insn; - - if (current_function_assigns_this) - cond = build (NE_EXPR, boolean_type_node, - current_class_ptr, integer_zero_node); - else - { - int n_baseclasses = CLASSTYPE_N_BASECLASSES (current_class_type); - - /* If this destructor is empty, then we don't need to check - whether `this' is NULL in some cases. */ - if ((flag_this_is_variable & 1) == 0) - ok_to_optimize_dtor = 1; - else if (empty_dtor) - ok_to_optimize_dtor - = (n_baseclasses == 0 - || (n_baseclasses == 1 - && TYPE_HAS_DESTRUCTOR (TYPE_BINFO_BASETYPE (current_class_type, 0)))); - } - - /* These initializations might go inline. Protect - the binding level of the parms. */ - pushlevel (0); - expand_start_bindings (0); - - if (current_function_assigns_this) - { - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } - - /* Generate the code to call destructor on base class. - If this destructor belongs to a class with virtual - functions, then set the virtual function table - pointer to represent the type of our base class. */ - - /* This side-effect makes call to `build_delete' generate the - code we have to have at the end of this destructor. - `build_delete' will set the flag again. */ - TYPE_HAS_DESTRUCTOR (current_class_type) = 0; - - /* These are two cases where we cannot delegate deletion. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type) - || TYPE_GETS_REG_DELETE (current_class_type)) - exprstmt = build_delete (current_class_type, current_class_ref, integer_zero_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); - else - exprstmt = build_delete (current_class_type, current_class_ref, in_charge_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR|LOOKUP_NORMAL, 0); - - /* If we did not assign to this, then `this' is non-zero at - the end of a destructor. As a special optimization, don't - emit test if this is an empty destructor. If it does nothing, - it does nothing. If it calls a base destructor, the base - destructor will perform the test. */ - - if (exprstmt != error_mark_node - && (TREE_CODE (exprstmt) != NOP_EXPR - || TREE_OPERAND (exprstmt, 0) != integer_zero_node - || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type))) - { - expand_label (dtor_label); - if (cond != integer_one_node) - expand_start_cond (cond, 0); - if (exprstmt != void_zero_node) - /* Don't call `expand_expr_stmt' if we're not going to do - anything, since -Wall will give a diagnostic. */ - expand_expr_stmt (exprstmt); - - /* Run destructor on all virtual baseclasses. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - { - tree vbases = nreverse (copy_list (CLASSTYPE_VBASECLASSES (current_class_type))); - expand_start_cond (build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_two_node), 0); - while (vbases) - { - if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (vbases))) - { - tree vb = get_vbase - (BINFO_TYPE (vbases), - TYPE_BINFO (current_class_type)); - expand_expr_stmt - (build_scoped_method_call - (current_class_ref, vb, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node))); - } - vbases = TREE_CHAIN (vbases); - } - expand_end_cond (); - } - - do_pending_stack_adjust (); - if (cond != integer_one_node) - expand_end_cond (); - } - - virtual_size = c_sizeof (current_class_type); - - /* At the end, call delete if that's what's requested. */ - - /* FDIS sez: At the point of definition of a virtual destructor - (including an implicit definition), non-placement operator - delete shall be looked up in the scope of the destructor's - class and if found shall be accessible and unambiguous. - - This is somewhat unclear, but I take it to mean that if the - class only defines placement deletes we don't do anything here. - So we pass LOOKUP_SPECULATIVELY; delete_sanity will complain - for us if they ever try to delete one of these. */ - - if (TYPE_GETS_REG_DELETE (current_class_type) - || TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - exprstmt = build_op_delete_call - (DELETE_EXPR, current_class_ptr, virtual_size, - LOOKUP_NORMAL | LOOKUP_SPECULATIVELY, NULL_TREE); - else - exprstmt = NULL_TREE; - - if (exprstmt) - { - cond = build (BIT_AND_EXPR, integer_type_node, - in_charge_node, integer_one_node); - expand_start_cond (cond, 0); - expand_expr_stmt (exprstmt); - expand_end_cond (); - } - - /* End of destructor. */ - expand_end_bindings (NULL_TREE, getdecls () != NULL_TREE, 0); - poplevel (getdecls () != NULL_TREE, 0, 0); - - /* Back to the top of destructor. */ - /* Don't execute destructor code if `this' is NULL. */ - - start_sequence (); - - /* If the dtor is empty, and we know there is not possible way we - could use any vtable entries, before they are possibly set by - a base class dtor, we don't have to setup the vtables, as we - know that any base class dtoring will set up any vtables it - needs. We avoid MI, because one base class dtor can do a - virtual dispatch to an overridden function that would need to - have a non-related vtable set up, we cannot avoid setting up - vtables in that case. We could change this to see if there is - just one vtable. */ - if (! empty_dtor || TYPE_USES_COMPLEX_INHERITANCE (current_class_type)) - { - /* Make all virtual function table pointers in non-virtual base - classes point to CURRENT_CLASS_TYPE's virtual function - tables. */ - expand_direct_vtbls_init (binfo, binfo, 1, 0, current_class_ptr); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - expand_indirect_vtbls_init (binfo, current_class_ref, current_class_ptr); - } - - if (! ok_to_optimize_dtor) - { - cond = build_binary_op (NE_EXPR, - current_class_ptr, integer_zero_node, 1); - expand_start_cond (cond, 0); - } - - insns = get_insns (); - end_sequence (); - - last_parm_insn = get_first_nonparm_insn (); - if (last_parm_insn == NULL_RTX) - last_parm_insn = get_last_insn (); - else - last_parm_insn = previous_insn (last_parm_insn); - - emit_insns_after (insns, last_parm_insn); - - if (! ok_to_optimize_dtor) - expand_end_cond (); - } - else if (current_function_assigns_this) - { - /* Does not need to call emit_base_init, because - that is done (if needed) just after assignment to this - is seen. */ - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - end_protect_partials (); - expand_label (ctor_label); - ctor_label = NULL_TREE; - - if (call_poplevel) - { - decls = getdecls (); - expand_end_bindings (decls, decls != NULL_TREE, 0); - poplevel (decls != NULL_TREE, 0, 0); - } - /* c_expand_return knows to return 'this' from a constructor. */ - c_expand_return (NULL_TREE); - } - else if (TREE_CODE (TREE_TYPE (DECL_RESULT (current_function_decl))) != VOID_TYPE - && return_label != NULL_RTX) - no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - base_init_expr = NULL_TREE; - } - else if (DECL_CONSTRUCTOR_P (fndecl)) - { - tree cond = NULL_TREE, thenclause = NULL_TREE; - /* Allow constructor for a type to get a new instance of the object - using `build_new'. */ - tree abstract_virtuals = CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type); - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = NULL_TREE; - - DECL_RETURNS_FIRST_ARG (fndecl) = 1; - - if (flag_this_is_variable > 0) - { - cond = build_binary_op (EQ_EXPR, - current_class_ptr, integer_zero_node, 1); - thenclause = build_modify_expr (current_class_ptr, NOP_EXPR, - build_new (NULL_TREE, current_class_type, void_type_node, 0)); - } - - CLASSTYPE_ABSTRACT_VIRTUALS (current_class_type) = abstract_virtuals; - - start_sequence (); - - if (flag_this_is_variable > 0) - { - expand_start_cond (cond, 0); - expand_expr_stmt (thenclause); - expand_end_cond (); - } - - /* Emit insns from `emit_base_init' which sets up virtual - function table pointer(s). */ - if (base_init_expr) - { - expand_expr_stmt (base_init_expr); - base_init_expr = NULL_TREE; - } - - insns = get_insns (); - end_sequence (); - - /* This is where the body of the constructor begins. */ - - emit_insns_after (insns, last_parm_cleanup_insn); - - end_protect_partials (); - - /* This is where the body of the constructor ends. */ - expand_label (ctor_label); - ctor_label = NULL_TREE; - - if (call_poplevel) - { - decls = getdecls (); - expand_end_bindings (decls, decls != NULL_TREE, 0); - poplevel (decls != NULL_TREE, 1, 0); - } - - /* c_expand_return knows to return 'this' from a constructor. */ - c_expand_return (NULL_TREE); - - current_function_assigns_this = 0; - current_function_just_assigned_this = 0; - } - else if (DECL_MAIN_P (fndecl)) - { - /* Make it so that `main' always returns 0 by default. */ -#ifdef VMS - c_expand_return (integer_one_node); -#else - c_expand_return (integer_zero_node); -#endif - } - else if (return_label != NULL_RTX - && current_function_return_value == NULL_TREE - && ! DECL_NAME (DECL_RESULT (current_function_decl))) - no_return_label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - if (flag_exceptions) - expand_exception_blocks (); - - /* If this function is supposed to return a value, ensure that - we do not fall into the cleanups by mistake. The end of our - function will look like this: - - user code (may have return stmt somewhere) - goto no_return_label - cleanup_label: - cleanups - goto return_label - no_return_label: - NOTE_INSN_FUNCTION_END - return_label: - things for return - - If the user omits a return stmt in the USER CODE section, we - will have a control path which reaches NOTE_INSN_FUNCTION_END. - Otherwise, we won't. */ - if (no_return_label) - { - DECL_CONTEXT (no_return_label) = fndecl; - DECL_INITIAL (no_return_label) = error_mark_node; - DECL_SOURCE_FILE (no_return_label) = input_filename; - DECL_SOURCE_LINE (no_return_label) = lineno; - expand_goto (no_return_label); - } - - if (cleanup_label) - { - /* Remove the binding contour which is used - to catch cleanup-generated temporaries. */ - expand_end_bindings (0, 0, 0); - poplevel (0, 0, 0); - - /* Emit label at beginning of cleanup code for parameters. */ - emit_label (cleanup_label); - } - - /* Get return value into register if that's where it's supposed to be. */ - if (original_result_rtx) - fixup_result_decl (DECL_RESULT (fndecl), original_result_rtx); - - /* Finish building code that will trigger warnings if users forget - to make their functions return values. */ - if (no_return_label || cleanup_label) - emit_jump (return_label); - if (no_return_label) - { - /* We don't need to call `expand_*_return' here because we - don't need any cleanups here--this path of code is only - for error checking purposes. */ - expand_label (no_return_label); - } - - /* Generate rtl for function exit. */ - expand_function_end (input_filename, lineno, 1); - } - - /* If we're processing a template, squirrel away the definition - until we do an instantiation. */ - if (processing_template_decl) - { - --minimal_parse_mode; - DECL_SAVED_TREE (fndecl) = TREE_CHAIN (DECL_SAVED_TREE (fndecl)); - /* We have to save this value here in case - maybe_end_member_template_processing decides to pop all the - template parameters. */ - in_template = 1; - } - else - in_template = 0; - - /* This must come after expand_function_end because cleanups might - have declarations (from inline functions) that need to go into - this function's blocks. */ - if (current_binding_level->parm_flag != 1) - my_friendly_abort (122); - poplevel (1, 0, 1); - - /* If this is a in-class inline definition, we may have to pop the - bindings for the template parameters that we added in - maybe_begin_member_template_processing when start_function was - called. */ - if (inclass_inline) - maybe_end_member_template_processing (); - - /* Reset scope for C++: if we were in the scope of a class, - then when we finish this function, we are not longer so. - This cannot be done until we know for sure that no more - class members will ever be referenced in this function - (i.e., calls to destructors). */ - if (current_class_name) - { - ctype = current_class_type; - pop_nested_class (1); - } - - /* Must mark the RESULT_DECL as being in this function. */ - DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; - - /* Set the BLOCK_SUPERCONTEXT of the outermost function scope to point - to the FUNCTION_DECL node itself. */ - BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - - if (!in_template) - { - int saved_flag_keep_inline_functions = - flag_keep_inline_functions; - - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - - if (DECL_CONTEXT (fndecl) != NULL_TREE - && hack_decl_function_context (fndecl)) - /* Trick rest_of_compilation into not deferring output of this - function, even if it is inline, since the rtl_obstack for - this function is the function_obstack of the enclosing - function and will be deallocated when the enclosing - function is gone. See save_tree_status. */ - flag_keep_inline_functions = 1; - - /* Run the optimizers and output the assembler code for this - function. */ - - if (DECL_ARTIFICIAL (fndecl)) - { - /* Do we really *want* to inline this synthesized method? */ - - int save_fif = flag_inline_functions; - flag_inline_functions = 1; - - /* Turn off DECL_INLINE for the moment so function_cannot_inline_p - will check our size. */ - DECL_INLINE (fndecl) = 0; - - rest_of_compilation (fndecl); - flag_inline_functions = save_fif; - } - else - rest_of_compilation (fndecl); - - flag_keep_inline_functions = saved_flag_keep_inline_functions; - - if (DECL_SAVED_INSNS (fndecl) && ! TREE_ASM_WRITTEN (fndecl)) - { - /* Set DECL_EXTERNAL so that assemble_external will be called as - necessary. We'll clear it again in finish_file. */ - if (! DECL_EXTERNAL (fndecl)) - DECL_NOT_REALLY_EXTERN (fndecl) = 1; - DECL_EXTERNAL (fndecl) = 1; - mark_inline_for_output (fndecl); - } - - if (ctype && TREE_ASM_WRITTEN (fndecl)) - note_debug_info_needed (ctype); - - current_function_returns_null |= can_reach_end; - - /* Since we don't normally go through c_expand_return for constructors, - this normally gets the wrong value. - Also, named return values have their return codes emitted after - NOTE_INSN_FUNCTION_END, confusing jump.c. */ - if (DECL_CONSTRUCTOR_P (fndecl) - || DECL_NAME (DECL_RESULT (fndecl)) != NULL_TREE) - current_function_returns_null = 0; - - if (TREE_THIS_VOLATILE (fndecl) && current_function_returns_null) - cp_warning ("`noreturn' function `%D' does return", fndecl); - else if ((warn_return_type || pedantic) - && current_function_returns_null - && TREE_CODE (TREE_TYPE (fntype)) != VOID_TYPE) - { - /* If this function returns non-void and control can drop through, - complain. */ - cp_warning ("control reaches end of non-void function `%D'", fndecl); - } - /* With just -W, complain only if function returns both with - and without a value. */ - else if (extra_warnings - && current_function_returns_value && current_function_returns_null) - warning ("this function may return with or without a value"); - } - - --function_depth; - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently - until we start another function. */ - if (! nested) - permanent_allocation (1); - - if (DECL_SAVED_INSNS (fndecl) == NULL_RTX) - { - tree t; - - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this - was an actual function definition. */ - DECL_INITIAL (fndecl) = error_mark_node; - for (t = DECL_ARGUMENTS (fndecl); t; t = TREE_CHAIN (t)) - DECL_RTL (t) = DECL_INCOMING_RTL (t) = NULL_RTX; - } - - if (DECL_STATIC_CONSTRUCTOR (fndecl)) - static_ctors = perm_tree_cons (NULL_TREE, fndecl, static_ctors); - if (DECL_STATIC_DESTRUCTOR (fndecl)) - static_dtors = perm_tree_cons (NULL_TREE, fndecl, static_dtors); - - if (! nested) - { - /* Let the error reporting routines know that we're outside a - function. For a nested function, this value is used in - pop_cp_function_context and then reset via pop_function_context. */ - current_function_decl = NULL_TREE; - } - - named_label_uses = NULL; - current_class_ptr = NULL_TREE; - current_class_ref = NULL_TREE; -} - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the return type and the name of the function, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns a FUNCTION_DECL on success. - - If the DECLARATOR is not suitable for a function (it defines a datum - instead), we return 0, which tells yyparse to report a parse error. - - May return void_type_node indicating that this method is actually - a friend. See grokfield for more details. - - Came here with a `.pushlevel' . - - DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING - CHANGES TO CODE IN `grokfield'. */ - -tree -start_method (declspecs, declarator, attrlist) - tree declarator, declspecs, attrlist; -{ - tree fndecl = grokdeclarator (declarator, declspecs, MEMFUNCDEF, 0, - attrlist); - - /* Something too ugly to handle. */ - if (fndecl == NULL_TREE) - return NULL_TREE; - - /* Pass friends other than inline friend functions back. */ - if (fndecl == void_type_node) - return fndecl; - - if (TREE_CODE (fndecl) != FUNCTION_DECL) - /* Not a function, tell parser to report parse error. */ - return NULL_TREE; - - if (IS_SIGNATURE (current_class_type)) - IS_DEFAULT_IMPLEMENTATION (fndecl) = 1; - - if (DECL_IN_AGGR_P (fndecl)) - { - if (IDENTIFIER_ERROR_LOCUS (DECL_ASSEMBLER_NAME (fndecl)) != current_class_type) - { - if (DECL_CONTEXT (fndecl) - && TREE_CODE( DECL_CONTEXT (fndecl)) != NAMESPACE_DECL) - cp_error ("`%D' is already defined in class %s", fndecl, - TYPE_NAME_STRING (DECL_CONTEXT (fndecl))); - } - return void_type_node; - } - - check_template_shadow (fndecl); - - DECL_THIS_INLINE (fndecl) = 1; - - if (flag_default_inline) - DECL_INLINE (fndecl) = 1; - - /* We process method specializations in finish_struct_1. */ - if (processing_template_decl && !DECL_TEMPLATE_SPECIALIZATION (fndecl)) - fndecl = push_template_decl (fndecl); - - /* We read in the parameters on the maybepermanent_obstack, - but we won't be getting back to them until after we - may have clobbered them. So the call to preserve_data - will keep them safe. */ - preserve_data (); - - if (! DECL_FRIEND_P (fndecl)) - { - if (TREE_CHAIN (fndecl)) - { - fndecl = copy_node (fndecl); - TREE_CHAIN (fndecl) = NULL_TREE; - } - - if (DECL_CONSTRUCTOR_P (fndecl)) - { - if (! grok_ctor_properties (current_class_type, fndecl)) - return void_type_node; - } - else if (IDENTIFIER_OPNAME_P (DECL_NAME (fndecl))) - grok_op_properties (fndecl, DECL_VIRTUAL_P (fndecl), 0); - } - - cp_finish_decl (fndecl, NULL_TREE, NULL_TREE, 0, 0); - - /* Make a place for the parms */ - pushlevel (0); - current_binding_level->parm_flag = 1; - - DECL_IN_AGGR_P (fndecl) = 1; - return fndecl; -} - -/* Go through the motions of finishing a function definition. - We don't compile this method until after the whole class has - been processed. - - FINISH_METHOD must return something that looks as though it - came from GROKFIELD (since we are defining a method, after all). - - This is called after parsing the body of the function definition. - STMTS is the chain of statements that makes up the function body. - - DECL is the ..._DECL that `start_method' provided. */ - -tree -finish_method (decl) - tree decl; -{ - register tree fndecl = decl; - tree old_initial; - - register tree link; - - if (decl == void_type_node) - return decl; - - old_initial = DECL_INITIAL (fndecl); - - /* Undo the level for the parms (from start_method). - This is like poplevel, but it causes nothing to be - saved. Saving information here confuses symbol-table - output routines. Besides, this information will - be correctly output when this method is actually - compiled. */ - - /* Clear out the meanings of the local variables of this level; - also record in each decl which block it belongs to. */ - - for (link = current_binding_level->names; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != NULL_TREE) - pop_binding (DECL_NAME (link), link); - my_friendly_assert (TREE_CODE (link) != FUNCTION_DECL, 163); - DECL_CONTEXT (link) = NULL_TREE; - } - - GNU_xref_end_scope ((HOST_WIDE_INT) current_binding_level, - (HOST_WIDE_INT) current_binding_level->level_chain, - current_binding_level->parm_flag, - current_binding_level->keep); - - poplevel (0, 0, 0); - - DECL_INITIAL (fndecl) = old_initial; - - /* We used to check if the context of FNDECL was different from - current_class_type as another way to get inside here. This didn't work - for String.cc in libg++. */ - if (DECL_FRIEND_P (fndecl)) - { - CLASSTYPE_INLINE_FRIENDS (current_class_type) - = tree_cons (NULL_TREE, fndecl, CLASSTYPE_INLINE_FRIENDS (current_class_type)); - decl = void_type_node; - } - - return decl; -} - -/* Called when a new struct TYPE is defined. - If this structure or union completes the type of any previous - variable declaration, lay it out and output its rtl. */ - -void -hack_incomplete_structures (type) - tree type; -{ - tree *list; - - if (current_binding_level->incomplete == NULL_TREE) - return; - - if (!type) /* Don't do this for class templates. */ - return; - - for (list = ¤t_binding_level->incomplete; *list; ) - { - tree decl = TREE_VALUE (*list); - if ((decl && TREE_TYPE (decl) == type) - || (TREE_TYPE (decl) - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type)) - { - int toplevel = toplevel_bindings_p (); - if (TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE - && TREE_TYPE (TREE_TYPE (decl)) == type) - layout_type (TREE_TYPE (decl)); - layout_decl (decl, 0); - rest_of_decl_compilation (decl, NULL_PTR, toplevel, 0); - if (! toplevel) - { - tree cleanup; - expand_decl (decl); - cleanup = maybe_build_cleanup (decl); - expand_decl_init (decl); - if (! expand_decl_cleanup (decl, cleanup)) - cp_error ("parser lost in parsing declaration of `%D'", - decl); - } - *list = TREE_CHAIN (*list); - } - else - list = &TREE_CHAIN (*list); - } -} - -/* If DECL is of a type which needs a cleanup, build that cleanup here. - See build_delete for information about AUTO_DELETE. - - Don't build these on the momentary obstack; they must live - the life of the binding contour. */ - -static tree -maybe_build_cleanup_1 (decl, auto_delete) - tree decl, auto_delete; -{ - tree type = TREE_TYPE (decl); - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - int temp = 0, flags = LOOKUP_NORMAL|LOOKUP_DESTRUCTOR; - tree rval; - - if (TREE_CODE (decl) != PARM_DECL) - temp = suspend_momentary (); - - if (TREE_CODE (type) == ARRAY_TYPE) - rval = decl; - else - { - mark_addressable (decl); - rval = build_unary_op (ADDR_EXPR, decl, 0); - } - - /* Optimize for space over speed here. */ - if (! TYPE_USES_VIRTUAL_BASECLASSES (type) - || flag_expensive_optimizations) - flags |= LOOKUP_NONVIRTUAL; - - rval = build_delete (TREE_TYPE (rval), rval, auto_delete, flags, 0); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type) - && ! TYPE_HAS_DESTRUCTOR (type)) - rval = build_compound_expr (expr_tree_cons (NULL_TREE, rval, - build_expr_list (NULL_TREE, build_vbase_delete (type, decl)))); - - if (TREE_CODE (decl) != PARM_DECL) - resume_momentary (temp); - - return rval; - } - return 0; -} - -/* If DECL is of a type which needs a cleanup, build that cleanup - here. The cleanup does free the storage with a call to delete. */ - -tree -maybe_build_cleanup_and_delete (decl) - tree decl; -{ - return maybe_build_cleanup_1 (decl, integer_three_node); -} - -/* If DECL is of a type which needs a cleanup, build that cleanup - here. The cleanup does not free the storage with a call a delete. */ - -tree -maybe_build_cleanup (decl) - tree decl; -{ - return maybe_build_cleanup_1 (decl, integer_two_node); -} - -/* Expand a C++ expression at the statement level. - This is needed to ferret out nodes which have UNKNOWN_TYPE. - The C++ type checker should get all of these out when - expressions are combined with other, type-providing, expressions, - leaving only orphan expressions, such as: - - &class::bar; / / takes its address, but does nothing with it. */ - -void -cplus_expand_expr_stmt (exp) - tree exp; -{ - if (processing_template_decl) - { - add_tree (build_min_nt (EXPR_STMT, exp)); - return; - } - - /* Arrange for all temps to disappear. */ - expand_start_target_temps (); - - if (TREE_TYPE (exp) == unknown_type_node) - { - if (TREE_CODE (exp) == COMPONENT_REF) - error ("invalid reference to a member function name, did you forget the ()?"); - else - error ("address of overloaded function with no contextual type information"); - } - else - { - if (TREE_CODE (exp) == FUNCTION_DECL) - { - cp_warning ("reference, not call, to function `%D'", exp); - warning ("at this point in file"); - } - -#if 0 - /* We should do this eventually, but right now this causes regex.o from - libg++ to miscompile, and tString to core dump. */ - exp = build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp); -#endif - - /* Strip unused implicit INDIRECT_REFs of references. */ - if (TREE_CODE (exp) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == REFERENCE_TYPE) - exp = TREE_OPERAND (exp, 0); - - /* If we don't do this, we end up down inside expand_expr - trying to do TYPE_MODE on the ERROR_MARK, and really - go outside the bounds of the type. */ - if (exp != error_mark_node) - expand_expr_stmt (break_out_cleanups (exp)); - } - - /* Clean up any pending cleanups. This happens when a function call - returns a cleanup-needing value that nobody uses. */ - expand_end_target_temps (); -} - -/* When a stmt has been parsed, this function is called. - - Currently, this function only does something within a - constructor's scope: if a stmt has just assigned to this, - and we are in a derived class, we call `emit_base_init'. */ - -void -finish_stmt () -{ - extern struct nesting *cond_stack, *loop_stack, *case_stack; - - - if (current_function_assigns_this - || ! current_function_just_assigned_this) - return; - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Constructors must wait until we are out of control - zones before calling base constructors. */ - if (cond_stack || loop_stack || case_stack) - return; - expand_expr_stmt (base_init_expr); - check_base_init (current_class_type); - } - current_function_assigns_this = 1; -} - -/* Change a static member function definition into a FUNCTION_TYPE, instead - of the METHOD_TYPE that we create when it's originally parsed. - - WARNING: DO NOT pass &TREE_TYPE (decl) to FN or &TYPE_ARG_TYPES - (TREE_TYPE (decl)) to ARGTYPES, as doing so will corrupt the types of - other decls. Either pass the addresses of local variables or NULL. */ - -void -revert_static_member_fn (decl, fn, argtypes) - tree *decl, *fn, *argtypes; -{ - tree tmp; - tree function = fn ? *fn : TREE_TYPE (*decl); - tree args = argtypes ? *argtypes : TYPE_ARG_TYPES (function); - - if (CP_TYPE_QUALS (TREE_TYPE (TREE_VALUE (args))) - != TYPE_UNQUALIFIED) - cp_error ("static member function `%#D' declared with type qualifiers", - *decl); - - args = TREE_CHAIN (args); - tmp = build_function_type (TREE_TYPE (function), args); - tmp = build_qualified_type (tmp, CP_TYPE_QUALS (function)); - tmp = build_exception_variant (tmp, - TYPE_RAISES_EXCEPTIONS (function)); - TREE_TYPE (*decl) = tmp; - if (DECL_ARGUMENTS (*decl)) - DECL_ARGUMENTS (*decl) = TREE_CHAIN (DECL_ARGUMENTS (*decl)); - DECL_STATIC_FUNCTION_P (*decl) = 1; - if (fn) - *fn = tmp; - if (argtypes) - *argtypes = args; -} - -int -id_in_current_class (id) - tree id; -{ - return !!purpose_member (id, class_binding_level->class_shadowed); -} - -struct cp_function -{ - int returns_value; - int returns_null; - int assigns_this; - int just_assigned_this; - int parms_stored; - int temp_name_counter; - tree named_labels; - struct named_label_list *named_label_uses; - tree shadowed_labels; - tree ctor_label; - tree dtor_label; - rtx last_dtor_insn; - rtx last_parm_cleanup_insn; - tree base_init_list; - tree member_init_list; - tree base_init_expr; - tree current_class_ptr; - tree current_class_ref; - rtx result_rtx; - struct cp_function *next; - struct binding_level *binding_level; - int static_labelno; -}; - -static struct cp_function *cp_function_chain; - -extern int temp_name_counter; - -/* Save and reinitialize the variables - used during compilation of a C++ function. */ - -void -push_cp_function_context (context) - tree context; -{ - struct cp_function *p - = (struct cp_function *) xmalloc (sizeof (struct cp_function)); - - push_function_context_to (context); - - p->next = cp_function_chain; - cp_function_chain = p; - - p->named_labels = named_labels; - p->named_label_uses = named_label_uses; - p->shadowed_labels = shadowed_labels; - p->returns_value = current_function_returns_value; - p->returns_null = current_function_returns_null; - p->binding_level = current_binding_level; - p->ctor_label = ctor_label; - p->dtor_label = dtor_label; - p->last_dtor_insn = last_dtor_insn; - p->last_parm_cleanup_insn = last_parm_cleanup_insn; - p->assigns_this = current_function_assigns_this; - p->just_assigned_this = current_function_just_assigned_this; - p->parms_stored = current_function_parms_stored; - p->result_rtx = original_result_rtx; - p->base_init_expr = base_init_expr; - p->temp_name_counter = temp_name_counter; - p->base_init_list = current_base_init_list; - p->member_init_list = current_member_init_list; - p->current_class_ptr = current_class_ptr; - p->current_class_ref = current_class_ref; - p->static_labelno = static_labelno; -} - -/* Restore the variables used during compilation of a C++ function. */ - -void -pop_cp_function_context (context) - tree context; -{ - struct cp_function *p = cp_function_chain; - tree link; - - /* Bring back all the labels that were shadowed. */ - for (link = shadowed_labels; link; link = TREE_CHAIN (link)) - if (DECL_NAME (TREE_VALUE (link)) != 0) - SET_IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link)), - TREE_VALUE (link)); - - pop_function_context_from (context); - - cp_function_chain = p->next; - - named_labels = p->named_labels; - named_label_uses = p->named_label_uses; - shadowed_labels = p->shadowed_labels; - current_function_returns_value = p->returns_value; - current_function_returns_null = p->returns_null; - current_binding_level = p->binding_level; - ctor_label = p->ctor_label; - dtor_label = p->dtor_label; - last_dtor_insn = p->last_dtor_insn; - last_parm_cleanup_insn = p->last_parm_cleanup_insn; - current_function_assigns_this = p->assigns_this; - current_function_just_assigned_this = p->just_assigned_this; - current_function_parms_stored = p->parms_stored; - original_result_rtx = p->result_rtx; - base_init_expr = p->base_init_expr; - temp_name_counter = p->temp_name_counter; - current_base_init_list = p->base_init_list; - current_member_init_list = p->member_init_list; - current_class_ptr = p->current_class_ptr; - current_class_ref = p->current_class_ref; - static_labelno = p->static_labelno; - - free (p); -} - -int -in_function_p () -{ - return function_depth != 0; -} diff --git a/gcc/cp/decl.h b/gcc/cp/decl.h deleted file mode 100755 index f55dca5..0000000 --- a/gcc/cp/decl.h +++ /dev/null @@ -1,59 +0,0 @@ -/* Variables and structures for declaration processing. - Copyright (C) 1993 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* In grokdeclarator, distinguish syntactic contexts of declarators. */ -enum decl_context -{ NORMAL, /* Ordinary declaration */ - FUNCDEF, /* Function definition */ - PARM, /* Declaration of parm before function body */ - CATCHPARM, /* Declaration of catch parm */ - FIELD, /* Declaration inside struct or union */ - BITFIELD, /* Likewise but with specified width */ - TYPENAME, /* Typename (inside cast or sizeof) */ - MEMFUNCDEF /* Member function definition */ -}; - -/* We need this in here to get the decl_context definition. */ -extern tree grokdeclarator PROTO((tree, tree, enum decl_context, int, tree)); - -/* C++: Keep these around to reduce calls to `get_identifier'. - Identifiers for `this' in member functions and the auto-delete - parameter for destructors. */ -extern tree this_identifier, in_charge_identifier; - -/* Parsing a function declarator leaves a list of parameter names - or a chain or parameter decls here. */ -extern tree last_function_parms; - -/* A list of static class variables. This is needed, because a - static class variable can be declared inside the class without - an initializer, and then initialized, staticly, outside the class. */ -extern tree pending_statics; - -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -extern tree static_aggregates; - -#ifdef DEBUG_CP_BINDING_LEVELS -/* Purely for debugging purposes. */ -extern int debug_bindings_indentation; -#endif diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c deleted file mode 100755 index 91c38da..0000000 --- a/gcc/cp/decl2.c +++ /dev/null @@ -1,5040 +0,0 @@ -/* Process declarations and variables for C compiler. - Copyright (C) 1988, 92-98, 1999 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Process declarations and symbol lookup for C front end. - Also constructs types; the standard scalar types at initialization, - and structure, union, array and enum types when they are declared. */ - -/* ??? not all decl nodes are given the most useful possible - line numbers. For example, the CONST_DECLs for enum values. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "flags.h" -#include "cp-tree.h" -#include "decl.h" -#include "lex.h" -#include "output.h" -#include "except.h" -#include "expr.h" -#include "defaults.h" -#include "toplev.h" -#include "dwarf2out.h" -#include "dwarfout.h" - -#if USE_CPPLIB -#include "cpplib.h" -extern cpp_reader parse_in; -#endif - -static tree get_sentry PROTO((tree)); -static void mark_vtable_entries PROTO((tree)); -static void grok_function_init PROTO((tree, tree)); -static int finish_vtable_vardecl PROTO((tree, tree)); -static int prune_vtable_vardecl PROTO((tree, tree)); -static void finish_sigtable_vardecl PROTO((tree, tree)); -static int is_namespace_ancestor PROTO((tree, tree)); -static void add_using_namespace PROTO((tree, tree, int)); -static tree ambiguous_decl PROTO((tree, tree, tree,int)); -static tree build_anon_union_vars PROTO((tree, tree*, int, int)); -static void check_decl_namespace PROTO((void)); - -extern int current_class_depth; - -/* A list of virtual function tables we must make sure to write out. */ -tree pending_vtables; - -/* A list of static class variables. This is needed, because a - static class variable can be declared inside the class without - an initializer, and then initialized, staticly, outside the class. */ -tree pending_statics; - -/* A list of functions which were declared inline, but which we - may need to emit outline anyway. */ -static tree saved_inlines; - -/* Used to help generate temporary names which are unique within - a function. Reset to 0 by start_function. */ - -int temp_name_counter; - -/* Same, but not reset. Local temp variables and global temp variables - can have the same name. */ -static int global_temp_name_counter; - -/* Flag used when debugging spew.c */ - -extern int spew_debug; - -/* Nonzero if we're done parsing and into end-of-file activities. */ - -int at_eof; - -/* Functions called along with real static constructors and destructors. */ - -tree static_ctors, static_dtors; - -/* The current open namespace, and ::. */ - -tree current_namespace; -tree global_namespace; - -/* The stack for namespaces of current declarations. */ - -static tree decl_namespace_list; - - -/* C (and C++) language-specific option variables. */ - -/* Nonzero means allow type mismatches in conditional expressions; - just make their values `void'. */ - -int flag_cond_mismatch; - -/* Nonzero means give `double' the same size as `float'. */ - -int flag_short_double; - -/* Nonzero means don't recognize the keyword `asm'. */ - -int flag_no_asm; - -/* Nonzero means don't recognize any extension keywords. */ - -int flag_no_gnu_keywords; - -/* Nonzero means don't recognize the non-ANSI builtin functions. */ - -int flag_no_builtin; - -/* Nonzero means don't recognize the non-ANSI builtin functions. - -ansi sets this. */ - -int flag_no_nonansi_builtin; - -/* Nonzero means do some things the same way PCC does. Only provided so - the compiler will link. */ - -int flag_traditional; - -/* Nonzero means to treat bitfields as unsigned unless they say `signed'. */ - -int flag_signed_bitfields = 1; - -/* Nonzero means handle `#ident' directives. 0 means ignore them. */ - -int flag_no_ident; - -/* Nonzero means enable obscure ANSI features and disable GNU extensions - that might cause ANSI-compliant code to be miscompiled. */ - -int flag_ansi; - -/* Nonzero means do emit exported implementations of functions even if - they can be inlined. */ - -int flag_implement_inlines = 1; - -/* Nonzero means do emit exported implementations of templates, instead of - multiple static copies in each file that needs a definition. */ - -int flag_external_templates; - -/* Nonzero means that the decision to emit or not emit the implementation of a - template depends on where the template is instantiated, rather than where - it is defined. */ - -int flag_alt_external_templates; - -/* Nonzero means that implicit instantiations will be emitted if needed. */ - -int flag_implicit_templates = 1; - -/* Nonzero means that implicit instantiations of inline templates will be - emitted if needed, even if instantiations of non-inline templates - aren't. */ - -int flag_implicit_inline_templates = 1; - -/* Nonzero means warn about implicit declarations. */ - -int warn_implicit = 1; - -/* Nonzero means warn about usage of long long when `-pedantic'. */ - -int warn_long_long = 1; - -/* Nonzero means warn when all ctors or dtors are private, and the class - has no friends. */ - -int warn_ctor_dtor_privacy = 1; - -/* True if we want to implement vtables using "thunks". - The default is off. */ - -#ifndef DEFAULT_VTABLE_THUNKS -#define DEFAULT_VTABLE_THUNKS 0 -#endif -int flag_vtable_thunks = DEFAULT_VTABLE_THUNKS; - -/* True if we want to deal with repository information. */ - -int flag_use_repository; - -/* Nonzero if we want to issue diagnostics that the standard says are not - required. */ - -int flag_optional_diags = 1; - -/* Nonzero means give string constants the type `const char *', as mandated - by the standard. */ - -int flag_const_strings = 1; - -/* Nonzero means warn about deprecated conversion from string constant to - `char *'. */ - -int warn_write_strings; - -/* Nonzero means warn about pointer casts that can drop a type qualifier - from the pointer target type. */ - -int warn_cast_qual; - -/* Nonzero means warn about sizeof(function) or addition/subtraction - of function pointers. */ - -int warn_pointer_arith = 1; - -/* Nonzero means warn for any function def without prototype decl. */ - -int warn_missing_prototypes; - -/* Nonzero means warn about multiple (redundant) decls for the same single - variable or function. */ - -int warn_redundant_decls; - -/* Warn if initializer is not completely bracketed. */ - -int warn_missing_braces; - -/* Warn about comparison of signed and unsigned values. */ - -int warn_sign_compare; - -/* Warn about *printf or *scanf format/argument anomalies. */ - -int warn_format; - -/* Warn about a subscript that has type char. */ - -int warn_char_subscripts; - -/* Warn if a type conversion is done that might have confusing results. */ - -int warn_conversion; - -/* Warn if adding () is suggested. */ - -int warn_parentheses; - -/* Non-zero means warn in function declared in derived class has the - same name as a virtual in the base class, but fails to match the - type signature of any virtual function in the base class. */ -int warn_overloaded_virtual; - -/* Non-zero means warn when declaring a class that has a non virtual - destructor, when it really ought to have a virtual one. */ -int warn_nonvdtor; - -/* Non-zero means warn when a function is declared extern and later inline. */ -int warn_extern_inline; - -/* Non-zero means warn when the compiler will reorder code. */ -int warn_reorder; - -/* Non-zero means warn when synthesis behavior differs from Cfront's. */ -int warn_synth; - -/* Non-zero means warn when we convert a pointer to member function - into a pointer to (void or function). */ -int warn_pmf2ptr = 1; - -/* Nonzero means warn about violation of some Effective C++ style rules. */ - -int warn_ecpp; - -/* Nonzero means warn where overload resolution chooses a promotion from - unsigned to signed over a conversion to an unsigned of the same size. */ - -int warn_sign_promo; - -/* Nonzero means warn when an old-style cast is used. */ - -int warn_old_style_cast; - -/* Warn about #pragma directives that are not recognised. */ - -int warn_unknown_pragmas; /* Tri state variable. */ - -/* Nonzero means warn about use of multicharacter literals. */ - -int warn_multichar = 1; - -/* Nonzero means warn when non-templatized friend functions are - declared within a template */ - -int warn_nontemplate_friend = 1; - -/* Nonzero means `$' can be in an identifier. */ - -#ifndef DOLLARS_IN_IDENTIFIERS -#define DOLLARS_IN_IDENTIFIERS 1 -#endif -int dollars_in_ident = DOLLARS_IN_IDENTIFIERS; - -/* Nonzero for -fno-strict-prototype switch: do not consider empty - argument prototype to mean function takes no arguments. */ - -int flag_strict_prototype = 2; -int strict_prototype = 1; -int strict_prototypes_lang_c, strict_prototypes_lang_cplusplus = 1; - -/* Nonzero means that labels can be used as first-class objects */ - -int flag_labels_ok; - -/* Non-zero means to collect statistics which might be expensive - and to print them when we are done. */ -int flag_detailed_statistics; - -/* C++ specific flags. */ -/* Zero means that `this' is a *const. This gives nice behavior in the - 2.0 world. 1 gives 1.2-compatible behavior. 2 gives Spring behavior. - -2 means we're constructing an object and it has fixed type. */ - -int flag_this_is_variable; - -/* 3 means write out only virtuals function tables `defined' - in this implementation file. - 0 means write out virtual function tables and give them - (C) static access (default). */ - -int write_virtuals; - -/* Nonzero means we should attempt to elide constructors when possible. */ - -int flag_elide_constructors = 1; - -/* Nonzero means recognize and handle signature language constructs. */ - -int flag_handle_signatures; - -/* Nonzero means that member functions defined in class scope are - inline by default. */ - -int flag_default_inline = 1; - -/* Controls whether compiler generates 'type descriptor' that give - run-time type information. */ -int flag_rtti = 1; - -/* Nonzero if we wish to output cross-referencing information - for the GNU class browser. */ -extern int flag_gnu_xref; - -/* Nonzero if we want to support huge (> 2^(sizeof(short)*8-1) bytes) - objects. */ - -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 - definitions. */ - -int flag_conserve_space; - -/* Nonzero if we want to obey access control semantics. */ - -int flag_access_control = 1; - -/* Nonzero if we want to understand the operator names, i.e. 'bitand'. */ - -int flag_operator_names; - -/* Nonzero if we want to check the return value of new and avoid calling - constructors if it is a null pointer. */ - -int flag_check_new; - -/* Nonzero if we want the new ANSI rules for pushing a new scope for `for' - initialization variables. - 0: Old rules, set by -fno-for-scope. - 2: New ANSI rules, set by -ffor-scope. - 1: Try to implement new ANSI rules, but with backup compatibility - (and warnings). This is the default, for now. */ - -int flag_new_for_scope = 1; - -/* Nonzero if we want to emit defined symbols with common-like linkage as - weak symbols where possible, in order to conform to C++ semantics. - Otherwise, emit them as local symbols. */ - -int flag_weak = 1; - -/* CYGNUS LOCAL Embedded C++ */ -/* Nonzero if we want to adhere to the language rules of the Embedded C++ - specification. */ - -int flag_embedded_cxx = 0; -/* END CYGNUS LOCAL Embedded C++ */ - -/* Nonzero to enable experimental ABI changes. */ - -int flag_new_abi; - -/* Nonzero to not ignore namespace std. */ - -int flag_honor_std; - -/* Maximum template instantiation depth. Must be at least 17 for ANSI - compliance. */ - -int max_tinst_depth = 17; - -/* The name-mangling scheme to use. Must be 1 or greater to support - template functions with identical types, but different template - arguments. */ -int name_mangling_version = 2; - -/* Nonzero means that guiding declarations are allowed. */ -int flag_guiding_decls; - -/* Nonzero if squashed mangling is to be performed. - This uses the B and K codes to reference previously seen class types - and class qualifiers. */ -int flag_do_squangling; - -/* Nonzero means output .vtable_{entry,inherit} for use in doing vtable gc. */ - -int flag_vtable_gc; - -/* Nonzero means make the default pedwarns warnings instead of errors. - The value of this flag is ignored if -pedantic is specified. */ - -int flag_permissive; - -/* Table of language-dependent -f options. - STRING is the option name. VARIABLE is the address of the variable. - ON_VALUE is the value to store in VARIABLE - if `-fSTRING' is seen as an option. - (If `-fno-STRING' is seen as an option, the opposite value is stored.) */ - -static struct { char *string; int *variable; int on_value;} lang_f_options[] = -{ - /* C/C++ options. */ - {"signed-char", &flag_signed_char, 1}, - {"unsigned-char", &flag_signed_char, 0}, - {"signed-bitfields", &flag_signed_bitfields, 1}, - {"unsigned-bitfields", &flag_signed_bitfields, 0}, - {"short-enums", &flag_short_enums, 1}, - {"short-double", &flag_short_double, 1}, - {"cond-mismatch", &flag_cond_mismatch, 1}, - {"asm", &flag_no_asm, 0}, - {"builtin", &flag_no_builtin, 0}, - {"ident", &flag_no_ident, 0}, - -/* CYGNUS LOCAL Embedded C++ */ - {"embedded-cxx", &flag_embedded_cxx, 1}, -/* END CYGNUS LOCAL Embedded C++ */ - - /* C++-only options. */ - {"access-control", &flag_access_control, 1}, - {"check-new", &flag_check_new, 1}, - {"conserve-space", &flag_conserve_space, 1}, - {"const-strings", &flag_const_strings, 1}, - {"default-inline", &flag_default_inline, 1}, - {"dollars-in-identifiers", &dollars_in_ident, 1}, - {"elide-constructors", &flag_elide_constructors, 1}, - {"external-templates", &flag_external_templates, 1}, - {"for-scope", &flag_new_for_scope, 2}, - {"gnu-keywords", &flag_no_gnu_keywords, 0}, - {"handle-exceptions", &flag_exceptions, 1}, - {"handle-signatures", &flag_handle_signatures, 1}, - {"honor-std", &flag_honor_std, 1}, - {"huge-objects", &flag_huge_objects, 1}, - {"implement-inlines", &flag_implement_inlines, 1}, - {"implicit-inline-templates", &flag_implicit_inline_templates, 1}, - {"implicit-templates", &flag_implicit_templates, 1}, - {"labels-ok", &flag_labels_ok, 1}, - {"nonansi-builtins", &flag_no_nonansi_builtin, 0}, - {"operator-names", &flag_operator_names, 1}, - {"optional-diags", &flag_optional_diags, 1}, - {"permissive", &flag_permissive, 1}, - {"repo", &flag_use_repository, 1}, - {"rtti", &flag_rtti, 1}, - {"squangle", &flag_do_squangling, 1}, - {"stats", &flag_detailed_statistics, 1}, - {"strict-prototype", &flag_strict_prototype, 1}, - {"this-is-variable", &flag_this_is_variable, 1}, - {"vtable-gc", &flag_vtable_gc, 1}, - {"vtable-thunks", &flag_vtable_thunks, 1}, - {"weak", &flag_weak, 1}, - {"xref", &flag_gnu_xref, 1} -}; - -/* Decode the string P as a language-specific option. - Return the number of strings consumed for a valid option. - Otherwise return 0. */ - -int -lang_decode_option (argc, argv) - int argc -#if !USE_CPPLIB - ATTRIBUTE_UNUSED -#endif - ; - char **argv; - -{ - int strings_processed; - char *p = argv[0]; -#if USE_CPPLIB - strings_processed = cpp_handle_option (&parse_in, argc, argv); -#else - strings_processed = 0; -#endif /* ! USE_CPPLIB */ - - if (!strcmp (p, "-ftraditional") || !strcmp (p, "-traditional")) - /* ignore */; - else if (p[0] == '-' && p[1] == 'f') - { - /* Some kind of -f option. - P's value is the option sans `-f'. - Search for it in the table of options. */ - int found = 0; - size_t j; - - p += 2; - /* Try special -f options. */ - - if (!strcmp (p, "handle-exceptions") - || !strcmp (p, "no-handle-exceptions")) - warning ("-fhandle-exceptions has been renamed to -fexceptions (and is now on by default)"); - - if (!strcmp (p, "memoize-lookups") - || !strcmp (p, "no-memoize-lookups") - || !strcmp (p, "save-memoized") - || !strcmp (p, "no-save-memoized") - || !strcmp (p, "no-all-virtual") - || !strcmp (p, "no-enum-int-equiv") - || !strcmp (p, "nonnull-objects") - || !strcmp (p, "ansi-overloading")) - { - /* ignore */ - found = 1; - } - else if (!strcmp (p, "all-virtual") - || !strcmp (p, "enum-int-equiv") - || !strcmp (p, "no-nonnull-objects") - || !strcmp (p, "no-ansi-overloading")) - { - warning ("-f%s is no longer supported", p); - found = 1; - } - else if (! strcmp (p, "alt-external-templates")) - { - flag_external_templates = 1; - flag_alt_external_templates = 1; - found = 1; - } - else if (! strcmp (p, "no-alt-external-templates")) - { - flag_alt_external_templates = 0; - found = 1; - } - else if (!strcmp (p, "repo")) - { - flag_use_repository = 1; - flag_implicit_templates = 0; - found = 1; - } - else if (!strcmp (p, "guiding-decls")) - { - flag_guiding_decls = 1; - name_mangling_version = 0; - found = 1; - } - else if (!strcmp (p, "no-guiding-decls")) - { - flag_guiding_decls = 0; - found = 1; - } -/* CYGNUS LOCAL Embedded C++ */ - else if (!strcmp (p, "embedded-cxx")) - { - flag_embedded_cxx = 1; - flag_rtti = flag_exceptions = 0; - flag_vtable_thunks = 1; - found = 1; - } - else if (!strcmp (p, "no-embedded-cxx")) - { - flag_embedded_cxx = 0; - found = 1; - } -/* END CYGNUS LOCAL Embedded C++ */ - else if (!strcmp (p, "new-abi")) - { - flag_new_abi = 1; - flag_do_squangling = 1; - flag_honor_std = 1; - flag_vtable_thunks = 1; - } - else if (!strcmp (p, "no-new-abi")) - { - flag_new_abi = 0; - flag_do_squangling = 0; - flag_honor_std = 0; - } - else if (!strncmp (p, "template-depth-", 15)) - { - char *endp = p + 15; - while (*endp) - { - if (*endp >= '0' && *endp <= '9') - endp++; - else - { - error ("Invalid option `%s'", p - 2); - goto template_depth_lose; - } - } - max_tinst_depth = atoi (p + 15); - template_depth_lose: ; - } - else if (!strncmp (p, "name-mangling-version-", 22)) - { - char *endp = p + 22; - while (*endp) - { - if (*endp >= '0' && *endp <= '9') - endp++; - else - { - error ("Invalid option `%s'", p - 2); - goto mangling_version_lose; - } - } - name_mangling_version = atoi (p + 22); - mangling_version_lose: ; - } - else for (j = 0; - !found && j < sizeof (lang_f_options) / sizeof (lang_f_options[0]); - j++) - { - if (!strcmp (p, lang_f_options[j].string)) - { - *lang_f_options[j].variable = lang_f_options[j].on_value; - /* A goto here would be cleaner, - but breaks the vax pcc. */ - found = 1; - } - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-' - && ! strcmp (p+3, lang_f_options[j].string)) - { - *lang_f_options[j].variable = ! lang_f_options[j].on_value; - found = 1; - } - } - return found; - } - else if (p[0] == '-' && p[1] == 'W') - { - int setting = 1; - - /* The -W options control the warning behavior of the compiler. */ - p += 2; - - if (p[0] == 'n' && p[1] == 'o' && p[2] == '-') - setting = 0, p += 3; - - if (!strcmp (p, "implicit")) - warn_implicit = setting; - else if (!strcmp (p, "long-long")) - warn_long_long = setting; - else if (!strcmp (p, "return-type")) - warn_return_type = setting; - else if (!strcmp (p, "ctor-dtor-privacy")) - warn_ctor_dtor_privacy = setting; - else if (!strcmp (p, "write-strings")) - warn_write_strings = setting; - else if (!strcmp (p, "cast-qual")) - warn_cast_qual = setting; - else if (!strcmp (p, "char-subscripts")) - warn_char_subscripts = setting; - else if (!strcmp (p, "pointer-arith")) - warn_pointer_arith = setting; - else if (!strcmp (p, "missing-prototypes")) - warn_missing_prototypes = setting; - else if (!strcmp (p, "redundant-decls")) - warn_redundant_decls = setting; - else if (!strcmp (p, "missing-braces")) - warn_missing_braces = setting; - else if (!strcmp (p, "sign-compare")) - warn_sign_compare = setting; - else if (!strcmp (p, "format")) - warn_format = setting; - else if (!strcmp (p, "conversion")) - warn_conversion = setting; - else if (!strcmp (p, "parentheses")) - warn_parentheses = setting; - else if (!strcmp (p, "non-virtual-dtor")) - warn_nonvdtor = setting; - else if (!strcmp (p, "extern-inline")) - warn_extern_inline = setting; - else if (!strcmp (p, "reorder")) - warn_reorder = setting; - else if (!strcmp (p, "synth")) - warn_synth = setting; - else if (!strcmp (p, "pmf-conversions")) - warn_pmf2ptr = setting; - else if (!strcmp (p, "effc++")) - warn_ecpp = setting; - else if (!strcmp (p, "sign-promo")) - warn_sign_promo = setting; - else if (!strcmp (p, "old-style-cast")) - warn_old_style_cast = setting; - else if (!strcmp (p, "overloaded-virtual")) - warn_overloaded_virtual = setting; - else if (!strcmp (p, "multichar")) - warn_multichar = setting; - else if (!strcmp (p, "unknown-pragmas")) - /* Set to greater than 1, so that even unknown pragmas in - system headers will be warned about. */ - warn_unknown_pragmas = setting * 2; - else if (!strcmp (p, "non-template-friend")) - warn_nontemplate_friend = setting; - else if (!strcmp (p, "comment")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "comments")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "import")) - ; /* cpp handles this one. */ - else if (!strcmp (p, "all")) - { - warn_return_type = setting; - warn_unused = setting; - warn_implicit = setting; - warn_ctor_dtor_privacy = setting; - warn_switch = setting; - warn_format = setting; - warn_parentheses = setting; - warn_missing_braces = setting; - warn_sign_compare = setting; - warn_extern_inline = setting; - warn_nonvdtor = setting; - warn_multichar = setting; - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = (setting ? 2 : 0); - warn_reorder = setting; - warn_sign_promo = setting; - /* Only warn about unknown pragmas that are not in system - headers. */ - warn_unknown_pragmas = 1; - warn_nontemplate_friend = setting; - } - else return strings_processed; - } - else if (!strcmp (p, "-ansi")) - flag_no_nonansi_builtin = 1, flag_ansi = 1, - flag_no_gnu_keywords = 1, flag_operator_names = 1; -#ifdef SPEW_DEBUG - /* Undocumented, only ever used when you're invoking cc1plus by hand, since - it's probably safe to assume no sane person would ever want to use this - under normal circumstances. */ - else if (!strcmp (p, "-spew-debug")) - spew_debug = 1; -#endif - else - return strings_processed; - - return 1; -} - -/* Incorporate `const' and `volatile' qualifiers for member functions. - FUNCTION is a TYPE_DECL or a FUNCTION_DECL. - QUALS is a list of qualifiers. */ - -tree -grok_method_quals (ctype, function, quals) - tree ctype, function, quals; -{ - tree fntype = TREE_TYPE (function); - tree raises = TYPE_RAISES_EXCEPTIONS (fntype); - int type_quals = TYPE_UNQUALIFIED; - int dup_quals = TYPE_UNQUALIFIED; - - do - { - int tq = cp_type_qual_from_rid (TREE_VALUE (quals)); - - if (type_quals & tq) - dup_quals |= tq; - else - type_quals |= tq; - quals = TREE_CHAIN (quals); - } - while (quals); - - if (dup_quals != TYPE_UNQUALIFIED) - cp_error ("duplicate type qualifiers in %s declaration", - TREE_CODE (function) == FUNCTION_DECL - ? "member function" : "type"); - - ctype = cp_build_qualified_type (ctype, type_quals); - fntype = build_cplus_method_type (ctype, TREE_TYPE (fntype), - (TREE_CODE (fntype) == METHOD_TYPE - ? TREE_CHAIN (TYPE_ARG_TYPES (fntype)) - : TYPE_ARG_TYPES (fntype))); - if (raises) - fntype = build_exception_variant (fntype, raises); - - TREE_TYPE (function) = fntype; - return ctype; -} - -/* Warn when -fexternal-templates is used and #pragma - interface/implementation is not used all the times it should be, - inform the user. */ - -void -warn_if_unknown_interface (decl) - tree decl; -{ - static int already_warned = 0; - if (already_warned++) - return; - - if (flag_alt_external_templates) - { - struct tinst_level *til = tinst_for_decl (); - int sl = lineno; - char *sf = input_filename; - - if (til) - { - lineno = til->line; - input_filename = til->file; - } - cp_warning ("template `%#D' instantiated in file without #pragma interface", - decl); - lineno = sl; - input_filename = sf; - } - else - cp_warning_at ("template `%#D' defined in file without #pragma interface", - decl); -} - -/* A subroutine of the parser, to handle a component list. */ - -void -grok_x_components (specs) - tree specs; -{ - struct pending_inline **p; - tree t; - - specs = strip_attrs (specs); - - check_tag_decl (specs); - t = groktypename (build_decl_list (specs, NULL_TREE)); - - /* The only case where we need to do anything additional here is an - anonymous union field, e.g.: `struct S { union { int i; }; };'. */ - if (t == NULL_TREE || !ANON_UNION_TYPE_P (t)) - return; - - fixup_anonymous_union (t); - finish_member_declaration (build_lang_field_decl (FIELD_DECL, - NULL_TREE, - t)); - - /* Ignore any inline function definitions in the anonymous union - since an anonymous union may not have function members. */ - p = &pending_inlines; - for (; *p; *p = (*p)->next) - if (DECL_CONTEXT ((*p)->fndecl) != t) - break; -} - -/* Constructors for types with virtual baseclasses need an "in-charge" flag - saying whether this constructor is responsible for initialization of - virtual baseclasses or not. All destructors also need this "in-charge" - flag, which additionally determines whether or not the destructor should - free the memory for the object. - - This function adds the "in-charge" flag to member function FN if - appropriate. It is called from grokclassfn and tsubst. - FN must be either a constructor or destructor. */ - -void -maybe_retrofit_in_chrg (fn) - tree fn; -{ - tree basetype, arg_types, parms, parm, fntype; - - if (DECL_CONSTRUCTOR_P (fn) - && TYPE_USES_VIRTUAL_BASECLASSES (DECL_CLASS_CONTEXT (fn)) - && ! DECL_CONSTRUCTOR_FOR_VBASE_P (fn)) - /* OK */; - else if (! DECL_CONSTRUCTOR_P (fn) - && TREE_CHAIN (DECL_ARGUMENTS (fn)) == NULL_TREE) - /* OK */; - else - return; - - if (DECL_CONSTRUCTOR_P (fn)) - DECL_CONSTRUCTOR_FOR_VBASE_P (fn) = 1; - - /* First add it to DECL_ARGUMENTS... */ - parm = build_decl (PARM_DECL, in_charge_identifier, integer_type_node); - /* Mark the artificial `__in_chrg' parameter as "artificial". */ - SET_DECL_ARTIFICIAL (parm); - DECL_ARG_TYPE (parm) = integer_type_node; - TREE_READONLY (parm) = 1; - parms = DECL_ARGUMENTS (fn); - TREE_CHAIN (parm) = TREE_CHAIN (parms); - TREE_CHAIN (parms) = parm; - - /* ...and then to TYPE_ARG_TYPES. */ - arg_types = TYPE_ARG_TYPES (TREE_TYPE (fn)); - basetype = TREE_TYPE (TREE_VALUE (arg_types)); - arg_types = hash_tree_chain (integer_type_node, TREE_CHAIN (arg_types)); - fntype = build_cplus_method_type (basetype, TREE_TYPE (TREE_TYPE (fn)), - arg_types); - if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))) - fntype = build_exception_variant (fntype, - TYPE_RAISES_EXCEPTIONS (TREE_TYPE (fn))); - TREE_TYPE (fn) = fntype; -} - -/* Classes overload their constituent function names automatically. - When a function name is declared in a record structure, - its name is changed to it overloaded name. Since names for - constructors and destructors can conflict, we place a leading - '$' for destructors. - - CNAME is the name of the class we are grokking for. - - FUNCTION is a FUNCTION_DECL. It was created by `grokdeclarator'. - - FLAGS contains bits saying what's special about today's - arguments. 1 == DESTRUCTOR. 2 == OPERATOR. - - If FUNCTION is a destructor, then we must add the `auto-delete' field - as a second parameter. There is some hair associated with the fact - that we must "declare" this variable in the manner consistent with the - way the rest of the arguments were declared. - - QUALS are the qualifiers for the this pointer. */ - -void -grokclassfn (ctype, function, flags, quals) - tree ctype, function; - enum overload_flags flags; - tree quals; -{ - tree fn_name = DECL_NAME (function); - tree arg_types; - tree parm; - tree qualtype; - - if (fn_name == NULL_TREE) - { - error ("name missing for member function"); - fn_name = get_identifier ("<anonymous>"); - DECL_NAME (function) = fn_name; - } - - if (quals) - qualtype = grok_method_quals (ctype, function, quals); - else - qualtype = ctype; - - arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); - if (TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) - { - /* Must add the class instance variable up front. */ - /* Right now we just make this a pointer. But later - we may wish to make it special. */ - tree type = TREE_VALUE (arg_types); - int constp = 1; - - if ((flag_this_is_variable > 0) - && (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function))) - constp = 0; - - parm = build_decl (PARM_DECL, this_identifier, type); - /* Mark the artificial `this' parameter as "artificial". */ - SET_DECL_ARTIFICIAL (parm); - DECL_ARG_TYPE (parm) = type; - /* We can make this a register, so long as we don't - accidentally complain if someone tries to take its address. */ - DECL_REGISTER (parm) = 1; - if (constp) - TREE_READONLY (parm) = 1; - TREE_CHAIN (parm) = last_function_parms; - last_function_parms = parm; - } - - DECL_ARGUMENTS (function) = last_function_parms; - /* First approximations. */ - DECL_CONTEXT (function) = ctype; - DECL_CLASS_CONTEXT (function) = ctype; - - if (flags == DTOR_FLAG || DECL_CONSTRUCTOR_P (function)) - { - maybe_retrofit_in_chrg (function); - arg_types = TYPE_ARG_TYPES (TREE_TYPE (function)); - } - - if (flags == DTOR_FLAG) - { - DECL_ASSEMBLER_NAME (function) = build_destructor_name (ctype); - TYPE_HAS_DESTRUCTOR (ctype) = 1; - } - else - set_mangled_name_for_decl (function); -} - -/* Work on the expr used by alignof (this is only called by the parser). */ - -tree -grok_alignof (expr) - tree expr; -{ - tree best, t; - int bestalign; - - if (processing_template_decl) - return build_min (ALIGNOF_EXPR, sizetype, expr); - - if (TREE_CODE (expr) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND (expr, 1))) - error ("`__alignof__' applied to a bit-field"); - - if (TREE_CODE (expr) == INDIRECT_REF) - { - best = t = TREE_OPERAND (expr, 0); - bestalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - - while (TREE_CODE (t) == NOP_EXPR - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == POINTER_TYPE) - { - int thisalign; - t = TREE_OPERAND (t, 0); - thisalign = TYPE_ALIGN (TREE_TYPE (TREE_TYPE (t))); - if (thisalign > bestalign) - best = t, bestalign = thisalign; - } - return c_alignof (TREE_TYPE (TREE_TYPE (best))); - } - else - { - /* ANSI says arrays and fns are converted inside comma. - But we can't convert them in build_compound_expr - because that would break commas in lvalues. - So do the conversion here if operand was a comma. */ - if (TREE_CODE (expr) == COMPOUND_EXPR - && (TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE)) - expr = default_conversion (expr); - return c_alignof (TREE_TYPE (expr)); - } -} - -/* Create an ARRAY_REF, checking for the user doing things backwards - along the way. */ - -tree -grok_array_decl (array_expr, index_exp) - tree array_expr, index_exp; -{ - tree type = TREE_TYPE (array_expr); - tree p1, p2, i1, i2; - - if (type == error_mark_node || index_exp == error_mark_node) - return error_mark_node; - if (processing_template_decl) - return build_min (ARRAY_REF, type ? TREE_TYPE (type) : NULL_TREE, - array_expr, index_exp); - - if (type == NULL_TREE) - { - /* Something has gone very wrong. Assume we are mistakenly reducing - an expression instead of a declaration. */ - error ("parser may be lost: is there a '{' missing somewhere?"); - return NULL_TREE; - } - - if (TREE_CODE (type) == OFFSET_TYPE - || TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* If they have an `operator[]', use that. */ - if (IS_AGGR_TYPE (type) || IS_AGGR_TYPE (TREE_TYPE (index_exp))) - return build_opfncall (ARRAY_REF, LOOKUP_NORMAL, - array_expr, index_exp, NULL_TREE); - - /* Otherwise, create an ARRAY_REF for a pointer or array type. It - is a little-known fact that, if `a' is an array and `i' is an - int, you can write `i[a]', which means the same thing as `a[i]'. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - p1 = array_expr; - else - p1 = build_expr_type_conversion (WANT_POINTER, array_expr, 0); - - if (TREE_CODE (TREE_TYPE (index_exp)) == ARRAY_TYPE) - p2 = index_exp; - else - p2 = build_expr_type_conversion (WANT_POINTER, index_exp, 0); - - i1 = build_expr_type_conversion (WANT_INT | WANT_ENUM, array_expr, 0); - i2 = build_expr_type_conversion (WANT_INT | WANT_ENUM, index_exp, 0); - - if ((p1 && i2) && (i1 && p2)) - error ("ambiguous conversion for array subscript"); - - if (p1 && i2) - array_expr = p1, index_exp = i2; - else if (i1 && p2) - array_expr = p2, index_exp = i1; - else - { - cp_error ("invalid types `%T[%T]' for array subscript", - type, TREE_TYPE (index_exp)); - return error_mark_node; - } - - if (array_expr == error_mark_node || index_exp == error_mark_node) - error ("ambiguous conversion for array subscript"); - - return build_array_ref (array_expr, index_exp); -} - -/* Given the cast expression EXP, checking out its validity. Either return - an error_mark_node if there was an unavoidable error, return a cast to - void for trying to delete a pointer w/ the value 0, or return the - call to delete. If DOING_VEC is 1, we handle things differently - for doing an array delete. If DOING_VEC is 2, they gave us the - array size as an argument to delete. - Implements ARM $5.3.4. This is called from the parser. */ - -tree -delete_sanity (exp, size, doing_vec, use_global_delete) - tree exp, size; - int doing_vec, use_global_delete; -{ - tree t, type; - /* For a regular vector delete (aka, no size argument) we will pass - this down as a NULL_TREE into build_vec_delete. */ - tree maxindex = NULL_TREE; - - if (exp == error_mark_node) - return exp; - - if (processing_template_decl) - { - t = build_min (DELETE_EXPR, void_type_node, exp, size); - DELETE_EXPR_USE_GLOBAL (t) = use_global_delete; - DELETE_EXPR_USE_VEC (t) = doing_vec; - return t; - } - - if (TREE_CODE (exp) == OFFSET_REF) - exp = resolve_offset_ref (exp); - exp = convert_from_reference (exp); - t = stabilize_reference (exp); - t = build_expr_type_conversion (WANT_POINTER, t, 1); - - if (t == NULL_TREE || t == error_mark_node) - { - cp_error ("type `%#T' argument given to `delete', expected pointer", - TREE_TYPE (exp)); - return error_mark_node; - } - - if (doing_vec == 2) - { - maxindex = build_binary_op (MINUS_EXPR, size, integer_one_node, 1); - pedwarn ("anachronistic use of array size in vector delete"); - } - - type = TREE_TYPE (t); - - /* As of Valley Forge, you can delete a pointer to const. */ - - /* You can't delete functions. */ - if (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE) - { - error ("cannot delete a function"); - return error_mark_node; - } - - /* An array can't have been allocated by new, so complain. */ - if (TREE_CODE (t) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL - && TREE_CODE (TREE_TYPE (TREE_OPERAND (t, 0))) == ARRAY_TYPE) - cp_warning ("deleting array `%#D'", TREE_OPERAND (t, 0)); - - /* Deleting a pointer with the value zero is valid and has no effect. */ - if (integer_zerop (t)) - return build1 (NOP_EXPR, void_type_node, t); - - if (doing_vec) - return build_vec_delete (t, maxindex, integer_one_node, - integer_zero_node, use_global_delete); - else - { - if (IS_AGGR_TYPE (TREE_TYPE (type)) - && TYPE_GETS_REG_DELETE (TREE_TYPE (type))) - { - /* Only do access checking here; we'll be calling op delete - from the destructor. */ - tree tmp = build_op_delete_call (DELETE_EXPR, t, size_zero_node, - LOOKUP_NORMAL, NULL_TREE); - if (tmp == error_mark_node) - return error_mark_node; - } - - return build_delete (type, t, integer_three_node, - LOOKUP_NORMAL, use_global_delete); - } -} - -/* Report an error if the indicated template declaration is not the - sort of thing that should be a member template. */ - -void -check_member_template (tmpl) - tree tmpl; -{ - tree decl; - - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); - decl = DECL_TEMPLATE_RESULT (tmpl); - - if (TREE_CODE (decl) == FUNCTION_DECL - || (TREE_CODE (decl) == TYPE_DECL - && IS_AGGR_TYPE (TREE_TYPE (decl)))) - { - if (current_function_decl) - /* 14.5.2.2 [temp.mem] - - A local class shall not have member templates. */ - cp_error ("declaration of member template `%#D' in local class", - decl); - - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_VIRTUAL_P (decl)) - { - /* 14.5.2.3 [temp.mem] - - A member function template shall not be virtual. */ - cp_error - ("invalid use of `virtual' in template declaration of `%#D'", - decl); - DECL_VIRTUAL_P (decl) = 0; - } - - /* The debug-information generating code doesn't know what to do - with member templates. */ - DECL_IGNORED_P (tmpl) = 1; - } - else - cp_error ("template declaration of `%#D'", decl); -} - -/* Return true iff TYPE is a valid Java parameter or return type. */ - -int -acceptable_java_type (type) - tree type; -{ - if (TREE_CODE (type) == VOID_TYPE || TYPE_FOR_JAVA (type)) - return 1; - if (TREE_CODE (type) == POINTER_TYPE) - { - type = TREE_TYPE (type); - if (TREE_CODE (type) == RECORD_TYPE) - { - tree args; int i; - if (! TYPE_FOR_JAVA (type)) - return 0; - if (! CLASSTYPE_TEMPLATE_INFO (type)) - return 1; - args = CLASSTYPE_TI_ARGS (type); - i = TREE_VEC_LENGTH (args); - while (--i >= 0) - { - type = TREE_VEC_ELT (args, i); - if (TREE_CODE (type) == POINTER_TYPE) - type = TREE_TYPE (type); - if (! TYPE_FOR_JAVA (type)) - return 0; - } - return 1; - } - } - return 0; -} - -/* For a METHOD in a Java class CTYPE, return 1 if - the parameter and return types are valid Java types. - Otherwise, print appropriate error messages, and return 0. */ - -int -check_java_method (method) - tree method; -{ - int jerr = 0; - tree arg_types = TYPE_ARG_TYPES (TREE_TYPE (method)); - tree ret_type = TREE_TYPE (TREE_TYPE (method)); - if (! acceptable_java_type (ret_type)) - { - cp_error ("Java method '%D' has non-Java return type `%T'", - method, ret_type); - jerr++; - } - for (; arg_types != NULL_TREE; arg_types = TREE_CHAIN (arg_types)) - { - tree type = TREE_VALUE (arg_types); - if (! acceptable_java_type (type)) - { - cp_error ("Java method '%D' has non-Java parameter type `%T'", - method, type); - jerr++; - } - } - return jerr ? 0 : 1; -} - -/* Sanity check: report error if this function FUNCTION is not - really a member of the class (CTYPE) it is supposed to belong to. - CNAME is the same here as it is for grokclassfn above. */ - -tree -check_classfn (ctype, function) - tree ctype, function; -{ - tree fn_name = DECL_NAME (function); - tree fndecl, fndecls; - tree method_vec = CLASSTYPE_METHOD_VEC (complete_type (ctype)); - tree *methods = 0; - tree *end = 0; - tree templates = NULL_TREE; - - if (method_vec != 0) - { - methods = &TREE_VEC_ELT (method_vec, 0); - end = TREE_VEC_END (method_vec); - - /* First suss out ctors and dtors. */ - if (*methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) - && DECL_CONSTRUCTOR_P (function)) - goto got_it; - if (*++methods && fn_name == DECL_NAME (OVL_CURRENT (*methods)) - && DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (function))) - goto got_it; - - while (++methods != end && *methods) - { - fndecl = *methods; - if (fn_name == DECL_NAME (OVL_CURRENT (*methods))) - { - got_it: - for (fndecls = *methods; fndecls != NULL_TREE; - fndecls = OVL_NEXT (fndecls)) - { - fndecl = OVL_CURRENT (fndecls); - /* The DECL_ASSEMBLER_NAME for a TEMPLATE_DECL, or - for a for member function of a template class, is - not mangled, so the check below does not work - correctly in that case. Since mangled destructor - names do not include the type of the arguments, - 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)) - && (DECL_ASSEMBLER_NAME (function) - != DECL_NAME (function)) - && (DECL_ASSEMBLER_NAME (fndecl) - != DECL_NAME (fndecl)) - && (DECL_ASSEMBLER_NAME (function) - == DECL_ASSEMBLER_NAME (fndecl))) - return fndecl; - - /* We cannot simply call decls_match because this - doesn't work for static member functions that are - pretending to be methods, and because the name - may have been changed by asm("new_name"). */ - if (DECL_NAME (function) == DECL_NAME (fndecl)) - { - tree p1 = TYPE_ARG_TYPES (TREE_TYPE (function)); - tree p2 = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - - /* Get rid of the this parameter on functions that become - static. */ - if (DECL_STATIC_FUNCTION_P (fndecl) - && TREE_CODE (TREE_TYPE (function)) == METHOD_TYPE) - p1 = TREE_CHAIN (p1); - - if (same_type_p (TREE_TYPE (TREE_TYPE (function)), - TREE_TYPE (TREE_TYPE (fndecl))) - && compparms (p1, p2) - && (DECL_TEMPLATE_SPECIALIZATION (function) - == DECL_TEMPLATE_SPECIALIZATION (fndecl)) - && (!DECL_TEMPLATE_SPECIALIZATION (function) - || (DECL_TI_TEMPLATE (function) - == DECL_TI_TEMPLATE (fndecl)))) - return fndecl; - - if (is_member_template (fndecl)) - /* This function might be an instantiation - or specialization of fndecl. */ - templates = - scratch_tree_cons (NULL_TREE, fndecl, templates); - } - } - break; /* loser */ - } - else if (TREE_CODE (OVL_CURRENT (fndecl)) == TEMPLATE_DECL - && DECL_CONV_FN_P (OVL_CURRENT (fndecl)) - && DECL_CONV_FN_P (function)) - /* The method in the class is a member template - conversion operator. We are declaring another - conversion operator. It is possible that even though - the names don't match, there is some specialization - occurring. */ - templates = - scratch_tree_cons (NULL_TREE, fndecl, templates); - } - } - - if (templates) - /* This function might be an instantiation or a specialization. - We should verify that this is possible. For now, we simply - return NULL_TREE, which lets the caller know that this function - is new, but we don't print an error message. */ - return NULL_TREE; - - if (methods != end && *methods) - { - tree fndecl = *methods; - cp_error ("prototype for `%#D' does not match any in class `%T'", - function, ctype); - cp_error_at ("candidate%s: %+#D", OVL_NEXT (fndecl) ? "s are" : " is", - OVL_CURRENT (fndecl)); - while (fndecl = OVL_NEXT (fndecl), fndecl) - cp_error_at (" %#D", OVL_CURRENT(fndecl)); - } - else - { - methods = 0; - if (TYPE_SIZE (ctype) == 0) - incomplete_type_error (function, ctype); - else - cp_error ("no `%#D' member function declared in class `%T'", - function, ctype); - } - - /* If we did not find the method in the class, add it to avoid - spurious errors (unless the CTYPE is not yet defined, in which - case we'll only confuse ourselves when the function is declared - properly within the class. */ - if (TYPE_SIZE (ctype)) - add_method (ctype, methods, function); - return NULL_TREE; -} - -/* Process the specs, declarator (NULL if omitted) and width (NULL if omitted) - of a structure component, returning a FIELD_DECL node. - QUALS is a list of type qualifiers for this decl (such as for declaring - const member functions). - - This is done during the parsing of the struct declaration. - The FIELD_DECL nodes are chained together and the lot of them - are ultimately passed to `build_struct' to make the RECORD_TYPE node. - - C++: - - If class A defines that certain functions in class B are friends, then - the way I have set things up, it is B who is interested in permission - granted by A. However, it is in A's context that these declarations - are parsed. By returning a void_type_node, class A does not attempt - to incorporate the declarations of the friends within its structure. - - DO NOT MAKE ANY CHANGES TO THIS CODE WITHOUT MAKING CORRESPONDING - CHANGES TO CODE IN `start_method'. */ - -tree -grokfield (declarator, declspecs, init, asmspec_tree, attrlist) - tree declarator, declspecs, init, asmspec_tree, attrlist; -{ - register tree value; - char *asmspec = 0; - int flags = LOOKUP_ONLYCONVERTING; - - /* Convert () initializers to = initializers. */ - if (init == NULL_TREE && declarator != NULL_TREE - && TREE_CODE (declarator) == CALL_EXPR - && TREE_OPERAND (declarator, 0) - && (TREE_CODE (TREE_OPERAND (declarator, 0)) == IDENTIFIER_NODE - || TREE_CODE (TREE_OPERAND (declarator, 0)) == SCOPE_REF) - && parmlist_is_exprlist (TREE_OPERAND (declarator, 1))) - { - init = TREE_OPERAND (declarator, 1); - declarator = TREE_OPERAND (declarator, 0); - flags = 0; - } - - if (declspecs == NULL_TREE - && TREE_CODE (declarator) == SCOPE_REF - && TREE_CODE (TREE_OPERAND (declarator, 1)) == IDENTIFIER_NODE) - { - /* Access declaration */ - if (! IS_AGGR_TYPE_CODE (TREE_CODE (TREE_OPERAND (declarator, 0)))) - ; - else if (TREE_COMPLEXITY (declarator) == current_class_depth) - pop_nested_class (1); - return do_class_using_decl (declarator); - } - - if (init - && TREE_CODE (init) == TREE_LIST - && TREE_VALUE (init) == error_mark_node - && TREE_CHAIN (init) == NULL_TREE) - init = NULL_TREE; - - value = grokdeclarator (declarator, declspecs, FIELD, init != 0, NULL_TREE); - if (! value || value == error_mark_node) - /* friend or constructor went bad. */ - return value; - - /* Pass friendly classes back. */ - if (TREE_CODE (value) == VOID_TYPE) - return void_type_node; - - if (DECL_NAME (value) != NULL_TREE - && IDENTIFIER_POINTER (DECL_NAME (value))[0] == '_' - && ! strcmp (IDENTIFIER_POINTER (DECL_NAME (value)), "_vptr")) - cp_error ("member `%D' conflicts with virtual function table field name", - value); - - /* Stash away type declarations. */ - if (TREE_CODE (value) == TYPE_DECL) - { - DECL_NONLOCAL (value) = 1; - DECL_CONTEXT (value) = current_class_type; - DECL_CLASS_CONTEXT (value) = current_class_type; - - /* Now that we've updated the context, we need to remangle the - name for this TYPE_DECL. */ - DECL_ASSEMBLER_NAME (value) = DECL_NAME (value); - if (!uses_template_parms (value)) - DECL_ASSEMBLER_NAME (value) = - get_identifier (build_overload_name (TREE_TYPE (value), 1, 1)); - - pushdecl_class_level (value); - return value; - } - - if (IS_SIGNATURE (current_class_type) - && TREE_CODE (value) != FUNCTION_DECL) - { - error ("field declaration not allowed in signature"); - return void_type_node; - } - - if (DECL_IN_AGGR_P (value)) - { - cp_error ("`%D' is already defined in `%T'", value, - DECL_CONTEXT (value)); - return void_type_node; - } - - if (asmspec_tree) - asmspec = TREE_STRING_POINTER (asmspec_tree); - - if (init) - { - if (IS_SIGNATURE (current_class_type) - && TREE_CODE (value) == FUNCTION_DECL) - { - error ("function declarations cannot have initializers in signature"); - init = NULL_TREE; - } - else if (TREE_CODE (value) == FUNCTION_DECL) - { - grok_function_init (value, init); - init = NULL_TREE; - } - else if (pedantic && TREE_CODE (value) != VAR_DECL) - /* Already complained in grokdeclarator. */ - init = NULL_TREE; - else - { - /* We allow initializers to become parameters to base - initializers. */ - if (TREE_CODE (init) == TREE_LIST) - { - if (TREE_CHAIN (init) == NULL_TREE) - init = TREE_VALUE (init); - else - init = digest_init (TREE_TYPE (value), init, (tree *)0); - } - - if (TREE_CODE (init) == CONST_DECL) - init = DECL_INITIAL (init); - else if (TREE_READONLY_DECL_P (init)) - init = decl_constant_value (init); - else if (TREE_CODE (init) == CONSTRUCTOR) - init = digest_init (TREE_TYPE (value), init, (tree *)0); - my_friendly_assert (TREE_PERMANENT (init), 192); - if (init == error_mark_node) - /* We must make this look different than `error_mark_node' - because `decl_const_value' would mis-interpret it - as only meaning that this VAR_DECL is defined. */ - init = build1 (NOP_EXPR, TREE_TYPE (value), init); - else if (processing_template_decl) - ; - else if (! TREE_CONSTANT (init)) - { - /* We can allow references to things that are effectively - static, since references are initialized with the address. */ - if (TREE_CODE (TREE_TYPE (value)) != REFERENCE_TYPE - || (TREE_STATIC (init) == 0 - && (TREE_CODE_CLASS (TREE_CODE (init)) != 'd' - || DECL_EXTERNAL (init) == 0))) - { - error ("field initializer is not constant"); - init = error_mark_node; - } - } - } - } - - /* The corresponding pop_obstacks is in cp_finish_decl. */ - push_obstacks_nochange (); - - if (processing_template_decl && ! current_function_decl - && (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == FUNCTION_DECL)) - value = push_template_decl (value); - - check_template_shadow (value); - - if (attrlist) - cplus_decl_attributes (value, TREE_PURPOSE (attrlist), - TREE_VALUE (attrlist)); - - if (TREE_CODE (value) == VAR_DECL) - { - my_friendly_assert (TREE_PUBLIC (value), 0); - - /* We cannot call pushdecl here, because that would - fill in the value of our TREE_CHAIN. Instead, we - modify cp_finish_decl to do the right thing, namely, to - put this decl out straight away. */ - /* current_class_type can be NULL_TREE in case of error. */ - if (asmspec == 0 && current_class_type) - { - TREE_PUBLIC (value) = 1; - DECL_INITIAL (value) = error_mark_node; - DECL_ASSEMBLER_NAME (value) - = build_static_name (current_class_type, DECL_NAME (value)); - } - if (! processing_template_decl) - pending_statics = perm_tree_cons (NULL_TREE, value, pending_statics); - - /* Static consts need not be initialized in the class definition. */ - if (init != NULL_TREE && TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (value))) - { - static int explanation = 0; - - error ("initializer invalid for static member with constructor"); - if (explanation++ == 0) - error ("(you really want to initialize it separately)"); - init = 0; - } - /* Force the compiler to know when an uninitialized static - const member is being used. */ - if (CP_TYPE_CONST_P (TREE_TYPE (value)) && init == 0) - TREE_USED (value) = 1; - DECL_INITIAL (value) = init; - DECL_IN_AGGR_P (value) = 1; - DECL_CONTEXT (value) = current_class_type; - DECL_CLASS_CONTEXT (value) = current_class_type; - - cp_finish_decl (value, init, asmspec_tree, 1, flags); - pushdecl_class_level (value); - return value; - } - if (TREE_CODE (value) == FIELD_DECL) - { - if (asmspec) - { - /* This must override the asm specifier which was placed - by grokclassfn. Lay this out fresh. */ - DECL_RTL (value) = NULL_RTX; - DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); - } - if (DECL_INITIAL (value) == error_mark_node) - init = error_mark_node; - cp_finish_decl (value, init, asmspec_tree, 1, flags); - DECL_INITIAL (value) = init; - DECL_IN_AGGR_P (value) = 1; - return value; - } - if (TREE_CODE (value) == FUNCTION_DECL) - { - if (asmspec) - { - /* This must override the asm specifier which was placed - by grokclassfn. Lay this out fresh. */ - DECL_RTL (value) = NULL_RTX; - DECL_ASSEMBLER_NAME (value) = get_identifier (asmspec); - } - cp_finish_decl (value, init, asmspec_tree, 1, flags); - - /* Pass friends back this way. */ - if (DECL_FRIEND_P (value)) - return void_type_node; - -#if 0 /* Just because a fn is declared doesn't mean we'll try to define it. */ - if (current_function_decl && ! IS_SIGNATURE (current_class_type)) - cp_error ("method `%#D' of local class must be defined in class body", - value); -#endif - - DECL_IN_AGGR_P (value) = 1; - return value; - } - my_friendly_abort (21); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Like `grokfield', but for bitfields. - WIDTH is non-NULL for bit fields only, and is an INTEGER_CST node. */ - -tree -grokbitfield (declarator, declspecs, width) - tree declarator, declspecs, width; -{ - register tree value = grokdeclarator (declarator, declspecs, BITFIELD, - 0, NULL_TREE); - - if (! value) return NULL_TREE; /* friends went bad. */ - - /* Pass friendly classes back. */ - if (TREE_CODE (value) == VOID_TYPE) - return void_type_node; - - if (TREE_CODE (value) == TYPE_DECL) - { - cp_error ("cannot declare `%D' to be a bitfield type", value); - return NULL_TREE; - } - - /* Usually, finish_struct_1 catches bitifields with invalid types. - But, in the case of bitfields with function type, we confuse - ourselves into thinking they are member functions, so we must - check here. */ - if (TREE_CODE (value) == FUNCTION_DECL) - { - cp_error ("cannot declare bitfield `%D' with funcion type", - DECL_NAME (value)); - return NULL_TREE; - } - - if (IS_SIGNATURE (current_class_type)) - { - error ("field declaration not allowed in signature"); - return void_type_node; - } - - if (DECL_IN_AGGR_P (value)) - { - cp_error ("`%D' is already defined in the class %T", value, - DECL_CONTEXT (value)); - return void_type_node; - } - - GNU_xref_member (current_class_name, value); - - if (TREE_STATIC (value)) - { - cp_error ("static member `%D' cannot be a bitfield", value); - return NULL_TREE; - } - cp_finish_decl (value, NULL_TREE, NULL_TREE, 0, 0); - - if (width != error_mark_node) - { - constant_expression_warning (width); - DECL_INITIAL (value) = width; - SET_DECL_C_BIT_FIELD (value); - } - - DECL_IN_AGGR_P (value) = 1; - return value; -} - -tree -grokoptypename (declspecs, declarator) - tree declspecs, declarator; -{ - tree t = grokdeclarator (declarator, declspecs, TYPENAME, 0, NULL_TREE); - return build_typename_overload (t); -} - -/* When a function is declared with an initializer, - do the right thing. Currently, there are two possibilities: - - class B - { - public: - // initialization possibility #1. - virtual void f () = 0; - int g (); - }; - - class D1 : B - { - public: - int d1; - // error, no f (); - }; - - class D2 : B - { - public: - int d2; - void f (); - }; - - class D3 : B - { - public: - int d3; - // initialization possibility #2 - void f () = B::f; - }; - -*/ - -int -copy_assignment_arg_p (parmtype, virtualp) - tree parmtype; - int virtualp ATTRIBUTE_UNUSED; -{ - if (current_class_type == NULL_TREE) - return 0; - - if (TREE_CODE (parmtype) == REFERENCE_TYPE) - parmtype = TREE_TYPE (parmtype); - - if ((TYPE_MAIN_VARIANT (parmtype) == current_class_type) -#if 0 - /* Non-standard hack to support old Booch components. */ - || (! virtualp && DERIVED_FROM_P (parmtype, current_class_type)) -#endif - ) - return 1; - - return 0; -} - -static void -grok_function_init (decl, init) - tree decl; - tree init; -{ - /* An initializer for a function tells how this function should - be inherited. */ - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == FUNCTION_TYPE) - cp_error ("initializer specified for non-member function `%D'", decl); -#if 0 - /* We'll check for this in finish_struct_1. */ - else if (DECL_VINDEX (decl) == NULL_TREE) - cp_error ("initializer specified for non-virtual method `%D'", decl); -#endif - else if (integer_zerop (init)) - { -#if 0 - /* Mark this function as being "defined". */ - DECL_INITIAL (decl) = error_mark_node; - /* 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))) - { - extern tree abort_fndecl; - /* Give this node rtl from `abort'. */ - DECL_RTL (decl) = DECL_RTL (abort_fndecl); - } -#endif - DECL_ABSTRACT_VIRTUAL_P (decl) = 1; - if (DECL_NAME (decl) == ansi_opname [(int) MODIFY_EXPR]) - { - tree parmtype - = TREE_VALUE (TREE_CHAIN (TYPE_ARG_TYPES (TREE_TYPE (decl)))); - - if (copy_assignment_arg_p (parmtype, 1)) - TYPE_HAS_ABSTRACT_ASSIGN_REF (current_class_type) = 1; - } - } - else - cp_error ("invalid initializer for virtual method `%D'", decl); -} - -void -cplus_decl_attributes (decl, attributes, prefix_attributes) - tree decl, attributes, prefix_attributes; -{ - if (decl == NULL_TREE || decl == void_type_node) - return; - - if (TREE_CODE (decl) == TEMPLATE_DECL) - decl = DECL_TEMPLATE_RESULT (decl); - - decl_attributes (decl, attributes, prefix_attributes); - - if (TREE_CODE (decl) == TYPE_DECL) - SET_IDENTIFIER_TYPE_VALUE (DECL_NAME (decl), TREE_TYPE (decl)); -} - -/* CONSTRUCTOR_NAME: - Return the name for the constructor (or destructor) for the - specified class. Argument can be RECORD_TYPE, TYPE_DECL, or - IDENTIFIER_NODE. When given a template, this routine doesn't - lose the specialization. */ - -tree -constructor_name_full (thing) - tree thing; -{ - if (TREE_CODE (thing) == TEMPLATE_TYPE_PARM - || TREE_CODE (thing) == TEMPLATE_TEMPLATE_PARM - || TREE_CODE (thing) == TYPENAME_TYPE) - thing = TYPE_NAME (thing); - else if (IS_AGGR_TYPE_CODE (TREE_CODE (thing))) - { - if (TYPE_WAS_ANONYMOUS (thing) && TYPE_HAS_CONSTRUCTOR (thing)) - thing = DECL_NAME (OVL_CURRENT (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (thing), 0))); - else - thing = TYPE_NAME (thing); - } - if (TREE_CODE (thing) == TYPE_DECL - || (TREE_CODE (thing) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (thing)) == TYPE_DECL)) - thing = DECL_NAME (thing); - my_friendly_assert (TREE_CODE (thing) == IDENTIFIER_NODE, 197); - return thing; -} - -/* CONSTRUCTOR_NAME: - Return the name for the constructor (or destructor) for the - specified class. Argument can be RECORD_TYPE, TYPE_DECL, or - IDENTIFIER_NODE. When given a template, return the plain - unspecialized name. */ - -tree -constructor_name (thing) - tree thing; -{ - tree t; - thing = constructor_name_full (thing); - t = IDENTIFIER_TEMPLATE (thing); - if (!t) - return thing; - return t; -} - -/* Cache the value of this class's main virtual function table pointer - in a register variable. This will save one indirection if a - more than one virtual function call is made this function. */ - -void -setup_vtbl_ptr () -{ - extern tree base_init_expr; - - if (base_init_expr == 0 - && DECL_CONSTRUCTOR_P (current_function_decl)) - { - if (processing_template_decl) - add_tree (build_min_nt - (CTOR_INITIALIZER, - current_member_init_list, current_base_init_list)); - else - emit_base_init (current_class_type, 0); - } -} - -/* Record the existence of an addressable inline function. */ - -void -mark_inline_for_output (decl) - tree decl; -{ - decl = DECL_MAIN_VARIANT (decl); - if (DECL_SAVED_INLINE (decl)) - return; - my_friendly_assert (TREE_PERMANENT (decl), 363); - DECL_SAVED_INLINE (decl) = 1; -#if 0 - if (DECL_PENDING_INLINE_INFO (decl) != 0 - && ! DECL_PENDING_INLINE_INFO (decl)->deja_vu) - { - struct pending_inline *t = pending_inlines; - my_friendly_assert (DECL_SAVED_INSNS (decl) == 0, 198); - while (t) - { - if (t == DECL_PENDING_INLINE_INFO (decl)) - break; - t = t->next; - } - if (t == 0) - { - t = DECL_PENDING_INLINE_INFO (decl); - t->next = pending_inlines; - pending_inlines = t; - } - DECL_PENDING_INLINE_INFO (decl) = 0; - } -#endif - saved_inlines = perm_tree_cons (NULL_TREE, decl, saved_inlines); -} - -void -clear_temp_name () -{ - temp_name_counter = 0; -} - -/* Hand off a unique name which can be used for variable we don't really - want to know about anyway, for example, the anonymous variables which - are needed to make references work. Declare this thing so we can use it. - The variable created will be of type TYPE. - - STATICP is nonzero if this variable should be static. */ - -tree -get_temp_name (type, staticp) - tree type; - int staticp; -{ - char buf[sizeof (AUTO_TEMP_FORMAT) + 20]; - tree decl; - int toplev = toplevel_bindings_p (); - - push_obstacks_nochange (); - if (toplev || staticp) - { - end_temporary_allocation (); - sprintf (buf, AUTO_TEMP_FORMAT, global_temp_name_counter++); - decl = pushdecl_top_level (build_decl (VAR_DECL, get_identifier (buf), type)); - } - else - { - sprintf (buf, AUTO_TEMP_FORMAT, temp_name_counter++); - decl = pushdecl (build_decl (VAR_DECL, get_identifier (buf), type)); - } - TREE_USED (decl) = 1; - TREE_STATIC (decl) = staticp; - DECL_ARTIFICIAL (decl) = 1; - - /* If this is a local variable, then lay out its rtl now. - Otherwise, callers of this function are responsible for dealing - with this variable's rtl. */ - if (! toplev) - { - expand_decl (decl); - expand_decl_init (decl); - } - pop_obstacks (); - - return decl; -} - -/* Get a variable which we can use for multiple assignments. - It is not entered into current_binding_level, because - that breaks things when it comes time to do final cleanups - (which take place "outside" the binding contour of the function). */ - -tree -get_temp_regvar (type, init) - tree type, init; -{ - tree decl; - - decl = build_decl (VAR_DECL, NULL_TREE, type); - TREE_USED (decl) = 1; - DECL_REGISTER (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - - DECL_RTL (decl) = assign_temp (type, 2, 0, 1); - /* We can expand these without fear, since they cannot need - constructors or destructors. */ - expand_expr (build_modify_expr (decl, INIT_EXPR, init), - NULL_RTX, VOIDmode, 0); - - return decl; -} - -/* Hunts through the global anonymous union ANON_DECL, building - appropriate VAR_DECLs. Stores cleanups on the list of ELEMS, and - returns a VAR_DECL whose size is the same as the size of the - ANON_DECL, if one is available. */ - -static tree -build_anon_union_vars (anon_decl, elems, static_p, external_p) - tree anon_decl; - tree* elems; - int static_p; - int external_p; -{ - tree type = TREE_TYPE (anon_decl); - tree main_decl = NULL_TREE; - tree field; - - for (field = TYPE_FIELDS (type); - field != NULL_TREE; - field = TREE_CHAIN (field)) - { - tree decl; - - if (DECL_ARTIFICIAL (field)) - continue; - if (TREE_CODE (field) != FIELD_DECL) - { - cp_pedwarn_at ("`%#D' invalid; an anonymous union can only have non-static data members", - field); - continue; - } - - if (TREE_PRIVATE (field)) - cp_pedwarn_at ("private member `%#D' in anonymous union", field); - else if (TREE_PROTECTED (field)) - cp_pedwarn_at ("protected member `%#D' in anonymous union", field); - - if (DECL_NAME (field) == NULL_TREE - && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) - { - decl = build_anon_union_vars (field, elems, static_p, external_p); - if (!decl) - continue; - } - else if (DECL_NAME (field) == NULL_TREE) - continue; - else - { - decl = build_decl (VAR_DECL, DECL_NAME (field), TREE_TYPE (field)); - /* tell `pushdecl' that this is not tentative. */ - DECL_INITIAL (decl) = error_mark_node; - TREE_PUBLIC (decl) = 0; - TREE_STATIC (decl) = static_p; - DECL_EXTERNAL (decl) = external_p; - decl = pushdecl (decl); - DECL_INITIAL (decl) = NULL_TREE; - } - - /* Only write out one anon union element--choose the one that - can hold them all. */ - if (main_decl == NULL_TREE - && simple_cst_equal (DECL_SIZE (decl), - DECL_SIZE (anon_decl)) == 1) - main_decl = decl; - else - /* ??? This causes there to be no debug info written out - about this decl. */ - TREE_ASM_WRITTEN (decl) = 1; - - if (DECL_NAME (field) == NULL_TREE - && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) - /* The remainder of the processing was already done in the - recursive call. */ - continue; - - /* If there's a cleanup to do, it belongs in the - TREE_PURPOSE of the following TREE_LIST. */ - *elems = scratch_tree_cons (NULL_TREE, decl, *elems); - TREE_TYPE (*elems) = type; - } - - return main_decl; -} - -/* Finish off the processing of a UNION_TYPE structure. - If there are static members, then all members are - static, and must be laid out together. If the - union is an anonymous union, we arrange for that - as well. PUBLIC_P is nonzero if this union is - not declared static. */ - -void -finish_anon_union (anon_union_decl) - tree anon_union_decl; -{ - tree type = TREE_TYPE (anon_union_decl); - tree elems = NULL_TREE; - tree main_decl; - int public_p = TREE_PUBLIC (anon_union_decl); - int static_p = TREE_STATIC (anon_union_decl); - int external_p = DECL_EXTERNAL (anon_union_decl); - - if (TYPE_FIELDS (type) == NULL_TREE) - return; - - if (public_p) - { - error ("global anonymous unions must be declared static"); - return; - } - - main_decl = build_anon_union_vars (anon_union_decl, &elems, - static_p, external_p); - - if (main_decl == NULL_TREE) - { - warning ("anonymous union with no members"); - return; - } - - if (static_p) - { - make_decl_rtl (main_decl, 0, toplevel_bindings_p ()); - DECL_RTL (anon_union_decl) = DECL_RTL (main_decl); - } - - /* The following call assumes that there are never any cleanups - for anonymous unions--a reasonable assumption. */ - expand_anon_union_decl (anon_union_decl, NULL_TREE, elems); -} - -/* Finish processing a builtin type TYPE. It's name is NAME, - its fields are in the array FIELDS. LEN is the number of elements - in FIELDS minus one, or put another way, it is the maximum subscript - used in FIELDS. - - It is given the same alignment as ALIGN_TYPE. */ - -void -finish_builtin_type (type, name, fields, len, align_type) - tree type; - char *name; - tree fields[]; - int len; - tree align_type; -{ - register int i; - - TYPE_FIELDS (type) = fields[0]; - for (i = 0; i < len; i++) - { - layout_type (TREE_TYPE (fields[i])); - DECL_FIELD_CONTEXT (fields[i]) = type; - TREE_CHAIN (fields[i]) = fields[i+1]; - } - DECL_FIELD_CONTEXT (fields[i]) = type; - DECL_CLASS_CONTEXT (fields[i]) = type; - TYPE_ALIGN (type) = TYPE_ALIGN (align_type); - layout_type (type); -#if 0 /* not yet, should get fixed properly later */ - TYPE_NAME (type) = make_type_decl (get_identifier (name), type); -#else - TYPE_NAME (type) = build_decl (TYPE_DECL, get_identifier (name), type); -#endif - TYPE_STUB_DECL (type) = TYPE_NAME (type); - layout_decl (TYPE_NAME (type), 0); -} - -/* Auxiliary functions to make type signatures for - `operator new' and `operator delete' correspond to - what compiler will be expecting. */ - -tree -coerce_new_type (type) - tree type; -{ - int e1 = 0, e2 = 0; - - if (TREE_CODE (type) == METHOD_TYPE) - type = build_function_type (TREE_TYPE (type), TREE_CHAIN (TYPE_ARG_TYPES (type))); - if (! same_type_p (TREE_TYPE (type), ptr_type_node)) - e1 = 1, error ("`operator new' must return type `void *'"); - - /* Technically the type must be `size_t', but we may not know - what that is. */ - if (TYPE_ARG_TYPES (type) == NULL_TREE) - e1 = 1, error ("`operator new' takes type `size_t' parameter"); - else if (! same_type_p (TREE_VALUE (TYPE_ARG_TYPES (type)), sizetype)) - e2 = 1, error ("`operator new' takes type `size_t' as first parameter"); - if (e2) - type = build_function_type (ptr_type_node, tree_cons (NULL_TREE, sizetype, TREE_CHAIN (TYPE_ARG_TYPES (type)))); - else if (e1) - type = build_function_type (ptr_type_node, TYPE_ARG_TYPES (type)); - return type; -} - -tree -coerce_delete_type (type) - tree type; -{ - int e1 = 0, e2 = 0; -#if 0 - e3 = 0; -#endif - tree arg_types = TYPE_ARG_TYPES (type); - - if (TREE_CODE (type) == METHOD_TYPE) - { - type = build_function_type (TREE_TYPE (type), TREE_CHAIN (arg_types)); - arg_types = TREE_CHAIN (arg_types); - } - - if (TREE_TYPE (type) != void_type_node) - e1 = 1, error ("`operator delete' must return type `void'"); - - if (arg_types == NULL_TREE - || ! same_type_p (TREE_VALUE (arg_types), ptr_type_node)) - e2 = 1, error ("`operator delete' takes type `void *' as first parameter"); - -#if 0 - if (arg_types - && TREE_CHAIN (arg_types) - && TREE_CHAIN (arg_types) != void_list_node) - { - /* Again, technically this argument must be `size_t', but again - we may not know what that is. */ - tree t2 = TREE_VALUE (TREE_CHAIN (arg_types)); - if (! same_type_p (t2, sizetype)) - e3 = 1, error ("second argument to `operator delete' must be of type `size_t'"); - else if (TREE_CHAIN (TREE_CHAIN (arg_types)) != void_list_node) - { - e3 = 1; - if (TREE_CHAIN (TREE_CHAIN (arg_types))) - error ("too many arguments in declaration of `operator delete'"); - else - error ("`...' invalid in specification of `operator delete'"); - } - } - - if (e3) - arg_types = tree_cons (NULL_TREE, ptr_type_node, - build_tree_list (NULL_TREE, sizetype)); - else if (e3 |= e2) - { - if (arg_types == NULL_TREE) - arg_types = tree_cons (NULL_TREE, ptr_type_node, void_list_node); - else - arg_types = tree_cons (NULL_TREE, ptr_type_node, TREE_CHAIN (arg_types)); - } - else e3 |= e1; -#endif - - if (e2) - arg_types = tree_cons (NULL_TREE, ptr_type_node, - arg_types ? TREE_CHAIN (arg_types): NULL_TREE); - if (e2 || e1) - type = build_function_type (void_type_node, arg_types); - - return type; -} - -extern tree abort_fndecl; - -static void -mark_vtable_entries (decl) - tree decl; -{ - tree entries = CONSTRUCTOR_ELTS (DECL_INITIAL (decl)); - - if (flag_rtti) - { - tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (TREE_CHAIN (entries)) - : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); - tree fn = TREE_OPERAND (fnaddr, 0); - TREE_ADDRESSABLE (fn) = 1; - mark_used (fn); - } - skip_rtti_stuff (&entries); - - for (; entries; entries = TREE_CHAIN (entries)) - { - tree fnaddr = (flag_vtable_thunks ? TREE_VALUE (entries) - : FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (entries))); - tree fn = TREE_OPERAND (fnaddr, 0); - TREE_ADDRESSABLE (fn) = 1; - if (DECL_LANG_SPECIFIC (fn) && DECL_ABSTRACT_VIRTUAL_P (fn)) - { - TREE_OPERAND (fnaddr, 0) = fn = copy_node (fn); - DECL_RTL (fn) = DECL_RTL (abort_fndecl); - mark_used (abort_fndecl); - } - if (TREE_CODE (fn) == THUNK_DECL && DECL_EXTERNAL (fn)) - { - DECL_EXTERNAL (fn) = 0; - emit_thunk (fn); - } - mark_used (fn); - } -} - -/* Set DECL up to have the closest approximation of "initialized common" - linkage available. */ - -void -comdat_linkage (decl) - tree decl; -{ - if (flag_weak) - make_decl_one_only (decl); - else - TREE_PUBLIC (decl) = 0; - - if (DECL_LANG_SPECIFIC (decl)) - DECL_COMDAT (decl) = 1; -} - -/* For win32 we also want to put explicit instantiations in - linkonce sections, so that they will be merged with implicit - instantiations; otherwise we get duplicate symbol errors. */ - -void -maybe_make_one_only (decl) - tree decl; -{ - /* This is not necessary on targets that support weak symbols, because - the implicit instantiations will defer to the explicit one. */ - if (! supports_one_only () || SUPPORTS_WEAK) - return; - - /* We can't set DECL_COMDAT on functions, or finish_file will think - we can get away with not emitting them if they aren't used. - We can't use make_decl_one_only for variables, because their - DECL_INITIAL may not have been set properly yet. */ - - if (TREE_CODE (decl) == FUNCTION_DECL) - make_decl_one_only (decl); - else - comdat_linkage (decl); -} - -/* Set TREE_PUBLIC and/or DECL_EXTERN on the vtable DECL, - based on TYPE and other static flags. - - Note that anything public is tagged TREE_PUBLIC, whether - it's public in this file or in another one. */ - -void -import_export_vtable (decl, type, final) - tree decl, type; - int final; -{ - if (DECL_INTERFACE_KNOWN (decl)) - return; - - if (TYPE_FOR_JAVA (type)) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = 1; - DECL_INTERFACE_KNOWN (decl) = 1; - } - else if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = ! CLASSTYPE_VTABLE_NEEDS_WRITING (type); - DECL_INTERFACE_KNOWN (decl) = 1; - } - else - { - /* We can only wait to decide if we have real non-inline virtual - functions in our class, or if we come from a template. */ - - int found = CLASSTYPE_TEMPLATE_INSTANTIATION (type); - - if (! found && ! final) - { - tree method; - for (method = TYPE_METHODS (type); method != NULL_TREE; - method = TREE_CHAIN (method)) - if (DECL_VINDEX (method) != NULL_TREE - && ! DECL_THIS_INLINE (method) - && ! DECL_ABSTRACT_VIRTUAL_P (method)) - { - found = 1; - break; - } - } - - if (final || ! found) - { - comdat_linkage (decl); - DECL_EXTERNAL (decl) = 0; - } - else - { - TREE_PUBLIC (decl) = 1; - DECL_EXTERNAL (decl) = 1; - } - } -} - -/* Determine whether or not we want to specifically import or export CTYPE, - using various heuristics. */ - -void -import_export_class (ctype) - tree ctype; -{ - /* -1 for imported, 1 for exported. */ - int import_export = 0; - - if (CLASSTYPE_INTERFACE_KNOWN (ctype)) - return; - -#ifdef VALID_MACHINE_TYPE_ATTRIBUTE - /* FIXME this should really use some sort of target-independent macro. */ - if (lookup_attribute ("dllimport", TYPE_ATTRIBUTES (ctype))) - import_export = -1; - else if (lookup_attribute ("dllexport", TYPE_ATTRIBUTES (ctype))) - import_export = 1; -#endif - - /* If we got -fno-implicit-templates, we import template classes that - weren't explicitly instantiated. */ - if (import_export == 0 - && CLASSTYPE_IMPLICIT_INSTANTIATION (ctype) - && ! flag_implicit_templates) - import_export = -1; - - /* Base our import/export status on that of the first non-inline, - non-abstract virtual function, if any. */ - if (import_export == 0 - && TYPE_VIRTUAL_P (ctype) - && ! CLASSTYPE_TEMPLATE_INSTANTIATION (ctype)) - { - tree method; - for (method = TYPE_METHODS (ctype); method != NULL_TREE; - method = TREE_CHAIN (method)) - { - if (DECL_VINDEX (method) != NULL_TREE - && !DECL_THIS_INLINE (method) - && !DECL_ABSTRACT_VIRTUAL_P (method)) - { - import_export = (DECL_REALLY_EXTERN (method) ? -1 : 1); - break; - } - } - } - -#ifdef MULTIPLE_SYMBOL_SPACES - if (import_export == -1) - import_export = 0; -#endif - - if (import_export) - { - SET_CLASSTYPE_INTERFACE_KNOWN (ctype); - CLASSTYPE_VTABLE_NEEDS_WRITING (ctype) = (import_export > 0); - CLASSTYPE_INTERFACE_ONLY (ctype) = (import_export < 0); - } -} - -/* We need to describe to the assembler the relationship between - a vtable and the vtable of the parent class. */ - -static void -output_vtable_inherit (vars) - tree vars; -{ - tree parent; - rtx op[2]; - - op[0] = XEXP (DECL_RTL (vars), 0); /* strip the mem ref */ - - parent = binfo_for_vtable (vars); - - if (parent == TYPE_BINFO (DECL_CONTEXT (vars))) - op[1] = const0_rtx; - else if (parent) - { - parent = TYPE_BINFO_VTABLE (BINFO_TYPE (parent)); - op[1] = XEXP (DECL_RTL (parent), 0); /* strip the mem ref */ - } - else - my_friendly_abort (980826); - - output_asm_insn (".vtable_inherit %c0, %c1", op); -} - -static int -finish_vtable_vardecl (prev, vars) - tree prev, vars; -{ - tree ctype = DECL_CONTEXT (vars); - import_export_class (ctype); - import_export_vtable (vars, ctype, 1); - - if (! DECL_EXTERNAL (vars) - && (DECL_INTERFACE_KNOWN (vars) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars)) - || (hack_decl_function_context (vars) && TREE_USED (vars))) - && ! TREE_ASM_WRITTEN (vars)) - { - /* Write it out. */ - mark_vtable_entries (vars); - if (TREE_TYPE (DECL_INITIAL (vars)) == 0) - store_init_value (vars, DECL_INITIAL (vars)); - - if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) - { - /* Mark the VAR_DECL node representing the vtable itself as a - "gratuitous" one, thereby forcing dwarfout.c to ignore it. - It is rather important that such things be ignored because - any effort to actually generate DWARF for them will run - into trouble when/if we encounter code like: - - #pragma interface - struct S { virtual void member (); }; - - because the artificial declaration of the vtable itself (as - manufactured by the g++ front end) will say that the vtable - is a static member of `S' but only *after* the debug output - for the definition of `S' has already been output. This causes - grief because the DWARF entry for the definition of the vtable - will try to refer back to an earlier *declaration* of the - vtable as a static member of `S' and there won't be one. - We might be able to arrange to have the "vtable static member" - attached to the member list for `S' before the debug info for - `S' get written (which would solve the problem) but that would - require more intrusive changes to the g++ front end. */ - - DECL_IGNORED_P (vars) = 1; - } - - /* Always make vtables weak. */ - if (flag_weak) - comdat_linkage (vars); - - rest_of_decl_compilation (vars, NULL_PTR, 1, 1); - - if (flag_vtable_gc) - output_vtable_inherit (vars); - - return 1; - } - else if (! TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (vars))) - /* We don't know what to do with this one yet. */ - return 0; - - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); - return 0; -} - -static int -prune_vtable_vardecl (prev, vars) - tree prev, vars; -{ - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); - return 1; -} - -int -walk_vtables (typedecl_fn, vardecl_fn) - register void (*typedecl_fn) PROTO ((tree, tree)); - register int (*vardecl_fn) PROTO ((tree, tree)); -{ - tree prev, vars; - int flag = 0; - - for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) - { - register tree type = TREE_TYPE (vars); - - if (TREE_CODE (vars) == VAR_DECL && DECL_VIRTUAL_P (vars)) - { - if (vardecl_fn) - flag |= (*vardecl_fn) (prev, vars); - - if (prev && TREE_CHAIN (prev) != vars) - continue; - } - else if (TREE_CODE (vars) == TYPE_DECL - && type != error_mark_node - && TYPE_LANG_SPECIFIC (type) - && CLASSTYPE_VSIZE (type)) - { - if (typedecl_fn) (*typedecl_fn) (prev, vars); - } - - prev = vars; - } - - return flag; -} - -static void -finish_sigtable_vardecl (prev, vars) - tree prev, vars; -{ - /* We don't need to mark sigtable entries as addressable here as is done - for vtables. Since sigtables, unlike vtables, are always written out, - that was already done in build_signature_table_constructor. */ - - rest_of_decl_compilation (vars, NULL_PTR, 1, 1); - - /* We know that PREV must be non-zero here. */ - TREE_CHAIN (prev) = TREE_CHAIN (vars); -} - -void -walk_sigtables (typedecl_fn, vardecl_fn) - register void (*typedecl_fn) PROTO((tree, tree)); - register void (*vardecl_fn) PROTO((tree, tree)); -{ - tree prev, vars; - - for (prev = 0, vars = getdecls (); vars; vars = TREE_CHAIN (vars)) - { - register tree type = TREE_TYPE (vars); - - if (TREE_CODE (vars) == TYPE_DECL - && type != error_mark_node - && IS_SIGNATURE (type)) - { - if (typedecl_fn) (*typedecl_fn) (prev, vars); - } - else if (TREE_CODE (vars) == VAR_DECL - && TREE_TYPE (vars) != error_mark_node - && IS_SIGNATURE (TREE_TYPE (vars))) - { - if (vardecl_fn) (*vardecl_fn) (prev, vars); - } - else - prev = vars; - } -} - -/* Determines the proper settings of TREE_PUBLIC and DECL_EXTERNAL for an - inline function or template instantiation at end-of-file. */ - -void -import_export_decl (decl) - tree decl; -{ - if (DECL_INTERFACE_KNOWN (decl)) - return; - - if (DECL_TEMPLATE_INSTANTIATION (decl) - || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) - { - DECL_NOT_REALLY_EXTERN (decl) = 1; - if ((DECL_IMPLICIT_INSTANTIATION (decl) - || DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (decl)) - && (flag_implicit_templates - || (flag_implicit_inline_templates && DECL_THIS_INLINE (decl)))) - { - if (!TREE_PUBLIC (decl)) - /* Templates are allowed to have internal linkage. See - [basic.link]. */ - ; - else if (TREE_CODE (decl) == FUNCTION_DECL) - comdat_linkage (decl); - else - DECL_COMDAT (decl) = 1; - } - else - DECL_NOT_REALLY_EXTERN (decl) = 0; - } - else if (DECL_FUNCTION_MEMBER_P (decl)) - { - tree ctype = DECL_CLASS_CONTEXT (decl); - import_export_class (ctype); - if (CLASSTYPE_INTERFACE_KNOWN (ctype) - && (! DECL_ARTIFICIAL (decl) || DECL_VINDEX (decl))) - { - DECL_NOT_REALLY_EXTERN (decl) - = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); - - /* Always make artificials weak. */ - if (DECL_ARTIFICIAL (decl) && flag_weak) - comdat_linkage (decl); - else - maybe_make_one_only (decl); - } - else - comdat_linkage (decl); - } - /* tinfo function */ - else if (DECL_ARTIFICIAL (decl) && DECL_MUTABLE_P (decl)) - { - tree ctype = TREE_TYPE (DECL_NAME (decl)); - - if (IS_AGGR_TYPE (ctype)) - import_export_class (ctype); - - if (IS_AGGR_TYPE (ctype) && CLASSTYPE_INTERFACE_KNOWN (ctype) - && TYPE_VIRTUAL_P (ctype) - /* If the type is a cv-qualified variant of a type, then we - must emit the tinfo function in this translation unit - since it will not be emitted when the vtable for the type - is output (which is when the unqualified version is - generated). */ - && ctype == TYPE_MAIN_VARIANT (ctype)) - { - DECL_NOT_REALLY_EXTERN (decl) - = ! (CLASSTYPE_INTERFACE_ONLY (ctype) - || (DECL_THIS_INLINE (decl) && ! flag_implement_inlines)); - - /* Always make artificials weak. */ - if (flag_weak) - comdat_linkage (decl); - } - else if (TYPE_BUILT_IN (ctype) && ctype == TYPE_MAIN_VARIANT (ctype)) - DECL_NOT_REALLY_EXTERN (decl) = 0; - else - comdat_linkage (decl); - } - else - comdat_linkage (decl); - - DECL_INTERFACE_KNOWN (decl) = 1; -} - -tree -build_cleanup (decl) - tree decl; -{ - tree temp; - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == ARRAY_TYPE) - temp = decl; - else - { - mark_addressable (decl); - temp = build1 (ADDR_EXPR, build_pointer_type (type), decl); - } - temp = build_delete (TREE_TYPE (temp), temp, - integer_two_node, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); - return temp; -} - -extern int parse_time, varconst_time; -extern tree pending_templates; -extern tree maybe_templates; - -static tree -get_sentry (base) - tree base; -{ - tree sname = get_id_2 ("__sn", base); - /* For struct X foo __attribute__((weak)), there is a counter - __snfoo. Since base is already an assembler name, sname should - be globally unique */ - tree sentry = IDENTIFIER_GLOBAL_VALUE (sname); - if (! sentry) - { - push_obstacks_nochange (); - end_temporary_allocation (); - sentry = build_decl (VAR_DECL, sname, integer_type_node); - TREE_PUBLIC (sentry) = 1; - DECL_ARTIFICIAL (sentry) = 1; - TREE_STATIC (sentry) = 1; - TREE_USED (sentry) = 1; - DECL_COMMON (sentry) = 1; - pushdecl_top_level (sentry); - cp_finish_decl (sentry, NULL_TREE, NULL_TREE, 0, 0); - pop_obstacks (); - } - return sentry; -} - -/* A list of objects which have constructors or destructors - which reside in the global scope. The decl is stored in - the TREE_VALUE slot and the initializer is stored - in the TREE_PURPOSE slot. */ -extern tree static_aggregates_initp; - -/* Set up the static_aggregates* lists for processing. Subroutine of - finish_file. Note that this function changes the format of - static_aggregates_initp, from (priority . decl) to - (priority . ((initializer . decl) ...)). */ - -static void -setup_initp () -{ - tree t, *p, next_t; - - /* First, remove any entries from static_aggregates that are also in - static_aggregates_initp, and update the entries in _initp to - include the initializer. */ - p = &static_aggregates; - for (; *p; ) - { - /* We check for symbol equivalence rather than identical decls - because decl_attributes is run before duplicate_decls. */ - for (t = static_aggregates_initp; t; t = TREE_CHAIN (t)) - if (DECL_ASSEMBLER_NAME (TREE_VALUE (t)) - == DECL_ASSEMBLER_NAME (TREE_VALUE (*p))) - break; - - if (t) - { - TREE_VALUE (t) = *p; - *p = TREE_CHAIN (*p); - TREE_CHAIN (TREE_VALUE (t)) = NULL_TREE; - } - else - p = &TREE_CHAIN (*p); - } - - /* Then, group static_aggregates_initp. After this step, there will only - be one entry for each priority, with a chain coming off it. */ - t = static_aggregates_initp; - static_aggregates_initp = NULL_TREE; - - for (; t; t = next_t) - { - next_t = TREE_CHAIN (t); - - for (p = &static_aggregates_initp; ; p = &TREE_CHAIN (*p)) - { - if (*p == NULL_TREE - || tree_int_cst_lt (TREE_PURPOSE (*p), TREE_PURPOSE (t))) - { - TREE_CHAIN (t) = *p; - *p = t; - break; - } - else if (tree_int_cst_equal (TREE_PURPOSE (*p), TREE_PURPOSE (t))) - { - TREE_CHAIN (TREE_VALUE (t)) = TREE_VALUE (*p); - TREE_VALUE (*p) = TREE_VALUE (t); - break; - } - } - } - - /* Reverse each list to preserve the order (currently reverse declaration - order, for destructors). */ - for (t = static_aggregates_initp; t; t = TREE_CHAIN (t)) - TREE_VALUE (t) = nreverse (TREE_VALUE (t)); -} - -/* Start the process of running a particular set of global constructors - or destructors. Subroutine of do_[cd]tors. */ - -static void -start_objects (method_type, initp) - int method_type, initp; -{ - tree fnname; - char type[10]; - - /* Make ctor or dtor function. METHOD_TYPE may be 'I' or 'D'. */ - - if (initp != DEFAULT_INIT_PRIORITY) - { - char joiner; - -#ifdef JOINER - joiner = JOINER; -#else - joiner = '_'; -#endif - - sprintf (type, "%c%c%.5u", method_type, joiner, initp); - } - else - sprintf (type, "%c", method_type); - - fnname = get_file_function_name_long (type); - - start_function (void_list_node, - make_call_declarator (fnname, void_list_node, NULL_TREE, - NULL_TREE), - NULL_TREE, 0); - - store_parm_decls (); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); -} - -/* Finish the process of running a particular set of global constructors - or destructors. Subroutine of do_[cd]tors. */ - -static void -finish_objects (method_type, initp) - int method_type, initp; -{ - char *fnname; - - if (! initp) - { - tree list = (method_type == 'I' ? static_ctors : static_dtors); - - if (! current_function_decl && list) - start_objects (method_type, initp); - - for (; list; list = TREE_CHAIN (list)) - expand_expr_stmt (build_function_call (TREE_VALUE (list), NULL_TREE)); - } - - if (! current_function_decl) - return; - - fnname = XSTR (XEXP (DECL_RTL (current_function_decl), 0), 0); - - /* Finish up. */ - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - finish_function (lineno, 0, 0); - - if (initp == DEFAULT_INIT_PRIORITY) - { - if (method_type == 'I') - assemble_constructor (fnname); - else - assemble_destructor (fnname); - } - -#ifdef ASM_OUTPUT_SECTION_NAME - /* If we're using init priority we can't use assemble_*tor, but on ELF - targets we can stick the references into named sections for GNU ld - to collect. */ - else - { - char buf[15]; - sprintf (buf, ".%ctors.%.5u", method_type == 'I' ? 'c' : 'd', - /* invert the numbering so the linker puts us in the proper - order; constructors are run from right to left, and the - linker sorts in increasing order. */ - MAX_INIT_PRIORITY - initp); - named_section (NULL_TREE, buf, 0); - assemble_integer (gen_rtx_SYMBOL_REF (Pmode, fnname), - POINTER_SIZE / BITS_PER_UNIT, 1); - } -#endif -} - -/* Generate a function to run a set of global destructors. START is either - NULL_TREE or a node indicating a set of destructors with the same - init priority. Subroutine of finish_file. */ - -static void -do_dtors (start) - tree start; -{ - tree vars; - int initp; - - if (start) - { - initp = TREE_INT_CST_LOW (TREE_PURPOSE (start)); - vars = TREE_VALUE (start); - } - else - { - initp = DEFAULT_INIT_PRIORITY; - vars = static_aggregates; - } - - for (; vars; vars = TREE_CHAIN (vars)) - { - tree decl = TREE_VALUE (vars); - tree type = TREE_TYPE (decl); - tree temp; - - if (TYPE_NEEDS_DESTRUCTOR (type) && ! TREE_STATIC (vars) - && ! DECL_EXTERNAL (decl)) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); - - if (! current_function_decl) - start_objects ('D', initp); - - /* Set these global variables so that GDB at least puts - us near the declaration which required the initialization. */ - input_filename = DECL_SOURCE_FILE (decl); - lineno = DECL_SOURCE_LINE (decl); - emit_note (input_filename, lineno); - - /* Because of: - - [class.access.spec] - - Access control for implicit calls to the constructors, - the conversion functions, or the destructor called to - create and destroy a static data member is performed as - if these calls appeared in the scope of the member's - class. - - we must convince enforce_access to let us access the - DECL. */ - if (member_p (decl)) - { - DECL_CLASS_CONTEXT (current_function_decl) - = DECL_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (current_function_decl) = 1; - } - - temp = build_cleanup (decl); - - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREDECREMENT_EXPR, sentry, 0); - sentry = build_binary_op (EQ_EXPR, sentry, integer_zero_node, 1); - expand_start_cond (sentry, 0); - } - - expand_expr_stmt (temp); - - if (protect) - expand_end_cond (); - - /* Now that we're done with DECL we don't need to pretend to - be a member of its class any longer. */ - DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; - DECL_STATIC_FUNCTION_P (current_function_decl) = 0; - } - } - - finish_objects ('D', initp); -} - -/* Generate a function to run a set of global constructors. START is - either NULL_TREE or a node indicating a set of constructors with the - same init priority. Subroutine of finish_file. */ - -static void -do_ctors (start) - tree start; -{ - tree vars; - int initp; - - if (start) - { - initp = TREE_INT_CST_LOW (TREE_PURPOSE (start)); - vars = TREE_VALUE (start); - } - else - { - initp = DEFAULT_INIT_PRIORITY; - vars = static_aggregates; - } - - /* Reverse the list so it's in the right order for ctors. */ - vars = nreverse (vars); - - for (; vars; vars = TREE_CHAIN (vars)) - { - tree decl = TREE_VALUE (vars); - tree init = TREE_PURPOSE (vars); - - /* If this was a static attribute within some function's scope, - then don't initialize it here. Also, don't bother - with initializers that contain errors. */ - if (TREE_STATIC (vars) - || DECL_EXTERNAL (decl) - || (init && TREE_CODE (init) == TREE_LIST - && value_member (error_mark_node, init))) - continue; - - if (TREE_CODE (decl) == VAR_DECL) - { - int protect = (TREE_PUBLIC (decl) && (DECL_COMMON (decl) - || DECL_ONE_ONLY (decl) - || DECL_WEAK (decl))); - - if (! current_function_decl) - start_objects ('I', initp); - - /* Set these global variables so that GDB at least puts - us near the declaration which required the initialization. */ - input_filename = DECL_SOURCE_FILE (decl); - lineno = DECL_SOURCE_LINE (decl); - emit_note (input_filename, lineno); - - /* 9.5p5: The initializer of a static member of a class has - the same access rights as a member function. */ - if (member_p (decl)) - { - DECL_CLASS_CONTEXT (current_function_decl) - = DECL_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (current_function_decl) = 1; - } - - if (protect) - { - tree sentry = get_sentry (DECL_ASSEMBLER_NAME (decl)); - sentry = build_unary_op (PREINCREMENT_EXPR, sentry, 0); - sentry = build_binary_op - (EQ_EXPR, sentry, integer_one_node, 1); - expand_start_cond (sentry, 0); - } - - expand_start_target_temps (); - - if (IS_AGGR_TYPE (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - expand_aggr_init (decl, init, 0); - else if (TREE_CODE (init) == TREE_VEC) - { - expand_expr (expand_vec_init (decl, TREE_VEC_ELT (init, 0), - TREE_VEC_ELT (init, 1), - TREE_VEC_ELT (init, 2), 0), - const0_rtx, VOIDmode, EXPAND_NORMAL); - } - else - expand_assignment (decl, init, 0, 0); - - /* The expression might have involved increments and - decrements. */ - emit_queue (); - - /* Cleanup any temporaries needed for the initial value. */ - expand_end_target_temps (); - - if (protect) - expand_end_cond (); - - DECL_CLASS_CONTEXT (current_function_decl) = NULL_TREE; - DECL_STATIC_FUNCTION_P (current_function_decl) = 0; - } - else if (decl == error_mark_node) - /* OK */; - else - my_friendly_abort (22); - } - - finish_objects ('I', initp); -} - -/* This routine is called from the last rule in yyparse (). - Its job is to create all the code needed to initialize and - destroy the global aggregates. We do the destruction - first, since that way we only need to reverse the decls once. */ - -void -finish_file () -{ - extern int lineno; - int start_time, this_time; - - tree fnname; - tree vars; - int needs_cleaning = 0, needs_messing_up = 0; - - at_eof = 1; - - /* Bad parse errors. Just forget about it. */ - if (! global_bindings_p () || current_class_type) - return; - - check_decl_namespace (); - - start_time = get_run_time (); - - /* Otherwise, GDB can get confused, because in only knows - about source for LINENO-1 lines. */ - lineno -= 1; - - interface_unknown = 1; - interface_only = 0; - - for (fnname = pending_templates; fnname; fnname = TREE_CHAIN (fnname)) - { - tree srcloc = TREE_PURPOSE (fnname); - tree decl = TREE_VALUE (fnname); - - input_filename = SRCLOC_FILE (srcloc); - lineno = SRCLOC_LINE (srcloc); - - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') - { - instantiate_class_template (decl); - if (CLASSTYPE_TEMPLATE_INSTANTIATION (decl)) - for (vars = TYPE_METHODS (decl); vars; vars = TREE_CHAIN (vars)) - if (! DECL_ARTIFICIAL (vars)) - instantiate_decl (vars); - } - else - instantiate_decl (decl); - } - - for (fnname = maybe_templates; fnname; fnname = TREE_CHAIN (fnname)) - { - tree args, fn, decl = TREE_VALUE (fnname); - - if (DECL_INITIAL (decl)) - continue; - - fn = TREE_PURPOSE (fnname); - args = get_bindings (fn, decl, NULL_TREE); - fn = instantiate_template (fn, args); - instantiate_decl (fn); - } - - cat_namespace_levels(); - - /* Push into C language context, because that's all - we'll need here. */ - push_lang_context (lang_name_c); - -#if 1 - /* The reason for pushing garbage onto the global_binding_level is to - ensure that we can slice out _DECLs which pertain to virtual function - tables. If the last thing pushed onto the global_binding_level was a - virtual function table, then slicing it out would slice away all the - decls (i.e., we lose the head of the chain). - - There are several ways of getting the same effect, from changing the - way that iterators over the chain treat the elements that pertain to - virtual function tables, moving the implementation of this code to - decl.c (where we can manipulate global_binding_level directly), - popping the garbage after pushing it and slicing away the vtable - stuff, or just leaving it alone. */ - - /* Make last thing in global scope not be a virtual function table. */ -#if 0 /* not yet, should get fixed properly later */ - vars = make_type_decl (get_identifier (" @%$#@!"), integer_type_node); -#else - vars = build_decl (TYPE_DECL, get_identifier (" @%$#@!"), integer_type_node); -#endif - DECL_IGNORED_P (vars) = 1; - SET_DECL_ARTIFICIAL (vars); - pushdecl (vars); -#endif - - for (vars = static_aggregates; vars; vars = TREE_CHAIN (vars)) - if (! TREE_ASM_WRITTEN (TREE_VALUE (vars))) - rest_of_decl_compilation (TREE_VALUE (vars), 0, 1, 1); - vars = static_aggregates; - - if (static_ctors || vars) - needs_messing_up = 1; - if (static_dtors || vars) - needs_cleaning = 1; - - setup_initp (); - - /* After setup_initp, the aggregates are listed in reverse declaration - order, for cleaning. */ - if (needs_cleaning) - { - do_dtors (NULL_TREE); - - for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars)) - do_dtors (vars); - } - - /* do_ctors will reverse the lists for messing up. */ - if (needs_messing_up) - { - do_ctors (NULL_TREE); - - for (vars = static_aggregates_initp; vars; vars = TREE_CHAIN (vars)) - do_ctors (vars); - } - - permanent_allocation (1); - - /* Done with C language context needs. */ - pop_lang_context (); - - /* Now write out any static class variables (which may have since - learned how to be initialized). */ - while (pending_statics) - { - tree decl = TREE_VALUE (pending_statics); - - /* Output DWARF debug information. */ -#ifdef DWARF_DEBUGGING_INFO - if (write_symbols == DWARF_DEBUG) - dwarfout_file_scope_decl (decl, 1); -#endif -#ifdef DWARF2_DEBUGGING_INFO - if (write_symbols == DWARF2_DEBUG) - dwarf2out_decl (decl); -#endif - - DECL_DEFER_OUTPUT (decl) = 0; - rest_of_decl_compilation - (decl, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)), 1, 1); - - pending_statics = TREE_CHAIN (pending_statics); - } - - this_time = get_run_time (); - parse_time -= this_time - start_time; - varconst_time += this_time - start_time; - - start_time = get_run_time (); - - if (flag_handle_signatures) - walk_sigtables ((void (*) PROTO ((tree, tree))) 0, - finish_sigtable_vardecl); - - for (fnname = saved_inlines; fnname; fnname = TREE_CHAIN (fnname)) - { - tree decl = TREE_VALUE (fnname); - import_export_decl (decl); - } - - mark_all_runtime_matches (); - - /* Now write out inline functions which had their addresses taken and - which were not declared virtual and which were not declared `extern - inline'. */ - { - int reconsider = 1; /* More may be referenced; check again */ - - while (reconsider) - { - tree *p = &saved_inlines; - reconsider = 0; - - /* We need to do this each time so that newly completed template - types don't wind up at the front of the list. Sigh. */ - vars = build_decl (TYPE_DECL, make_anon_name (), integer_type_node); - DECL_IGNORED_P (vars) = 1; - SET_DECL_ARTIFICIAL (vars); - pushdecl (vars); - - reconsider |= walk_vtables ((void (*) PROTO((tree, tree))) 0, - finish_vtable_vardecl); - - while (*p) - { - tree decl = TREE_VALUE (*p); - - if (DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) - && TREE_USED (decl) - && (! DECL_REALLY_EXTERN (decl) || DECL_INLINE (decl))) - { - if (DECL_MUTABLE_P (decl)) - synthesize_tinfo_fn (decl); - else - synthesize_method (decl); - reconsider = 1; - } - - /* Catch new template instantiations. */ - if (decl != TREE_VALUE (*p)) - continue; - - if (TREE_ASM_WRITTEN (decl) - || (DECL_SAVED_INSNS (decl) == 0 && ! DECL_ARTIFICIAL (decl))) - *p = TREE_CHAIN (*p); - else if (DECL_INITIAL (decl) == 0) - p = &TREE_CHAIN (*p); - else if ((TREE_PUBLIC (decl) && ! DECL_COMDAT (decl)) - || TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)) - || flag_keep_inline_functions) - { - if (DECL_NOT_REALLY_EXTERN (decl)) - { - DECL_EXTERNAL (decl) = 0; - reconsider = 1; - /* We can't inline this function after it's been - emitted. We want a variant of - output_inline_function that doesn't prevent - subsequent integration... */ - DECL_INLINE (decl) = 0; - output_inline_function (decl); - permanent_allocation (1); - } - - *p = TREE_CHAIN (*p); - } - else - p = &TREE_CHAIN (*p); - } - } - - /* It's possible that some of the remaining inlines will still be - needed. For example, a static inline whose address is used in - the initializer for a file-scope static variable will be - needed. Code in compile_file will handle this, but we mustn't - pretend that there are no definitions for the inlines, or it - won't be able to. - - FIXME: This won't catch member functions. We should really - unify this stuff with the compile_file stuff. */ - for (vars = saved_inlines; vars != NULL_TREE; vars = TREE_CHAIN (vars)) - { - tree decl = TREE_VALUE (vars); - - if (DECL_NOT_REALLY_EXTERN (decl) - && !DECL_COMDAT (decl) - && DECL_INITIAL (decl) != NULL_TREE) - DECL_EXTERNAL (decl) = 0; - } - } - - /* Now delete from the chain of variables all virtual function tables. - We output them all ourselves, because each will be treated specially. */ - - walk_vtables ((void (*) PROTO((tree, tree))) 0, - prune_vtable_vardecl); - - finish_repo (); - - this_time = get_run_time (); - parse_time -= this_time - start_time; - varconst_time += this_time - start_time; - - if (flag_detailed_statistics) - { - dump_tree_statistics (); - dump_time_statistics (); - } -} - -/* This is something of the form 'A()()()()()+1' that has turned out to be an - expr. Since it was parsed like a type, we need to wade through and fix - that. Unfortunately, since operator() is left-associative, we can't use - tail recursion. In the above example, TYPE is `A', and DECL is - `()()()()()'. - - Maybe this shouldn't be recursive, but how often will it actually be - used? (jason) */ - -tree -reparse_absdcl_as_expr (type, decl) - tree type, decl; -{ - /* do build_functional_cast (type, NULL_TREE) at bottom */ - if (TREE_OPERAND (decl, 0) == NULL_TREE) - return build_functional_cast (type, NULL_TREE); - - /* recurse */ - decl = reparse_absdcl_as_expr (type, TREE_OPERAND (decl, 0)); - - decl = build_x_function_call (decl, NULL_TREE, current_class_ref); - - if (TREE_CODE (decl) == CALL_EXPR && TREE_TYPE (decl) != void_type_node) - decl = require_complete_type (decl); - - return decl; -} - -/* This is something of the form `int ((int)(int)(int)1)' that has turned - out to be an expr. Since it was parsed like a type, we need to wade - through and fix that. Since casts are right-associative, we are - reversing the order, so we don't have to recurse. - - In the above example, DECL is the `(int)(int)(int)', and EXPR is the - `1'. */ - -tree -reparse_absdcl_as_casts (decl, expr) - tree decl, expr; -{ - tree type; - - if (TREE_CODE (expr) == CONSTRUCTOR - && TREE_TYPE (expr) == 0) - { - type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1))); - decl = TREE_OPERAND (decl, 0); - - if (IS_SIGNATURE (type)) - { - error ("cast specifies signature type"); - return error_mark_node; - } - - expr = digest_init (type, expr, (tree *) 0); - if (TREE_CODE (type) == ARRAY_TYPE && TYPE_SIZE (type) == 0) - { - int failure = complete_array_type (type, expr, 1); - if (failure) - my_friendly_abort (78); - } - } - - while (decl) - { - type = groktypename (TREE_VALUE (TREE_OPERAND (decl, 1))); - decl = TREE_OPERAND (decl, 0); - expr = build_c_cast (type, expr); - } - - if (warn_old_style_cast) - warning ("use of old-style cast"); - - return expr; -} - -/* Given plain tree nodes for an expression, build up the full semantics. */ - -tree -build_expr_from_tree (t) - tree t; -{ - if (t == NULL_TREE || t == error_mark_node) - return t; - - switch (TREE_CODE (t)) - { - case IDENTIFIER_NODE: - return do_identifier (t, 0, NULL_TREE); - - case LOOKUP_EXPR: - if (LOOKUP_EXPR_GLOBAL (t)) - return do_scoped_id (TREE_OPERAND (t, 0), 0); - else - return do_identifier (TREE_OPERAND (t, 0), 0, NULL_TREE); - - case TEMPLATE_ID_EXPR: - return (lookup_template_function - (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1)))); - - case INDIRECT_REF: - return build_x_indirect_ref - (build_expr_from_tree (TREE_OPERAND (t, 0)), "unary *"); - - case CAST_EXPR: - return build_functional_cast - (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); - - case REINTERPRET_CAST_EXPR: - return build_reinterpret_cast - (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); - - case CONST_CAST_EXPR: - return build_const_cast - (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); - - case DYNAMIC_CAST_EXPR: - return build_dynamic_cast - (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); - - case STATIC_CAST_EXPR: - return build_static_cast - (TREE_TYPE (t), build_expr_from_tree (TREE_OPERAND (t, 0))); - - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case ABS_EXPR: - case TRUTH_NOT_EXPR: - case ADDR_EXPR: - case CONVERT_EXPR: /* Unary + */ - if (TREE_TYPE (t)) - return t; - return build_x_unary_op (TREE_CODE (t), - build_expr_from_tree (TREE_OPERAND (t, 0))); - - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case EXACT_DIV_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case RSHIFT_EXPR: - case LSHIFT_EXPR: - case RROTATE_EXPR: - case LROTATE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case MAX_EXPR: - case MIN_EXPR: - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - case MEMBER_REF: - return build_x_binary_op - (TREE_CODE (t), - build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1))); - - case DOTSTAR_EXPR: - return build_m_component_ref - (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1))); - - case SCOPE_REF: - return build_offset_ref (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1)); - - case ARRAY_REF: - if (TREE_OPERAND (t, 0) == NULL_TREE) - /* new-type-id */ - return build_parse_node (ARRAY_REF, NULL_TREE, - build_expr_from_tree (TREE_OPERAND (t, 1))); - return grok_array_decl (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1))); - - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - { - tree r = build_expr_from_tree (TREE_OPERAND (t, 0)); - if (TREE_CODE_CLASS (TREE_CODE (r)) != 't') - r = TREE_TYPE (r); - return TREE_CODE (t) == SIZEOF_EXPR ? c_sizeof (r) : c_alignof (r); - } - - case MODOP_EXPR: - return build_x_modify_expr - (build_expr_from_tree (TREE_OPERAND (t, 0)), - TREE_CODE (TREE_OPERAND (t, 1)), - build_expr_from_tree (TREE_OPERAND (t, 2))); - - case ARROW_EXPR: - return build_x_arrow - (build_expr_from_tree (TREE_OPERAND (t, 0))); - - case NEW_EXPR: - return build_new - (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1)), - build_expr_from_tree (TREE_OPERAND (t, 2)), - NEW_EXPR_USE_GLOBAL (t)); - - case DELETE_EXPR: - return delete_sanity - (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1)), - DELETE_EXPR_USE_VEC (t), DELETE_EXPR_USE_GLOBAL (t)); - - case COMPOUND_EXPR: - if (TREE_OPERAND (t, 1) == NULL_TREE) - return build_x_compound_expr - (build_expr_from_tree (TREE_OPERAND (t, 0))); - else - my_friendly_abort (42); - - case METHOD_CALL_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF) - { - tree ref = TREE_OPERAND (t, 0); - return build_scoped_method_call - (build_expr_from_tree (TREE_OPERAND (t, 1)), - build_expr_from_tree (TREE_OPERAND (ref, 0)), - TREE_OPERAND (ref, 1), - build_expr_from_tree (TREE_OPERAND (t, 2))); - } - else - { - tree fn = TREE_OPERAND (t, 0); - - /* We can get a TEMPLATE_ID_EXPR here on code like: - - x->f<2>(); - - so we must resolve that. However, we can also get things - like a BIT_NOT_EXPR here, when referring to a destructor, - and things like that are not correctly resolved by - build_expr_from_tree. So, just use build_expr_from_tree - when we really need it. */ - if (TREE_CODE (fn) == TEMPLATE_ID_EXPR) - fn = build_expr_from_tree (fn); - - return build_method_call - (build_expr_from_tree (TREE_OPERAND (t, 1)), - fn, - build_expr_from_tree (TREE_OPERAND (t, 2)), - NULL_TREE, LOOKUP_NORMAL); - } - - case CALL_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 0)) == SCOPE_REF) - { - tree ref = TREE_OPERAND (t, 0); - return build_member_call - (build_expr_from_tree (TREE_OPERAND (ref, 0)), - TREE_OPERAND (ref, 1), - build_expr_from_tree (TREE_OPERAND (t, 1))); - } - else - { - tree name = TREE_OPERAND (t, 0); - tree id; - tree args = build_expr_from_tree (TREE_OPERAND (t, 1)); - if (args != NULL_TREE && TREE_CODE (name) == LOOKUP_EXPR - && !LOOKUP_EXPR_GLOBAL (name) - && TREE_CODE ((id = TREE_OPERAND (name, 0))) == IDENTIFIER_NODE - && (!current_class_type - || !lookup_member (current_class_type, id, 0, 0))) - { - /* Do Koenig lookup if there are no class members. */ - name = do_identifier (id, 0, args); - } - else if (TREE_CODE (name) == TEMPLATE_ID_EXPR - || ! really_overloaded_fn (name)) - name = build_expr_from_tree (name); - return build_x_function_call (name, args, current_class_ref); - } - - case COND_EXPR: - return build_x_conditional_expr - (build_expr_from_tree (TREE_OPERAND (t, 0)), - build_expr_from_tree (TREE_OPERAND (t, 1)), - build_expr_from_tree (TREE_OPERAND (t, 2))); - - case TREE_LIST: - { - tree purpose, value, chain; - - if (t == void_list_node) - return t; - - purpose = TREE_PURPOSE (t); - if (purpose) - purpose = build_expr_from_tree (purpose); - value = TREE_VALUE (t); - if (value) - value = build_expr_from_tree (value); - chain = TREE_CHAIN (t); - if (chain && chain != void_type_node) - chain = build_expr_from_tree (chain); - return expr_tree_cons (purpose, value, chain); - } - - case COMPONENT_REF: - return build_x_component_ref - (build_expr_from_tree (TREE_OPERAND (t, 0)), - TREE_OPERAND (t, 1), NULL_TREE, 1); - - case THROW_EXPR: - return build_throw (build_expr_from_tree (TREE_OPERAND (t, 0))); - - case CONSTRUCTOR: - { - tree r; - - /* digest_init will do the wrong thing if we let it. */ - if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) - return t; - - r = build_nt (CONSTRUCTOR, NULL_TREE, - build_expr_from_tree (CONSTRUCTOR_ELTS (t))); - TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); - - if (TREE_TYPE (t)) - return digest_init (TREE_TYPE (t), r, 0); - return r; - } - - case TYPEID_EXPR: - if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') - return get_typeid (TREE_OPERAND (t, 0)); - return build_x_typeid (build_expr_from_tree (TREE_OPERAND (t, 0))); - - case VAR_DECL: - return convert_from_reference (t); - - default: - return t; - } -} - -/* This is something of the form `int (*a)++' that has turned out to be an - expr. It was only converted into parse nodes, so we need to go through - and build up the semantics. Most of the work is done by - build_expr_from_tree, above. - - In the above example, TYPE is `int' and DECL is `*a'. */ - -tree -reparse_decl_as_expr (type, decl) - tree type, decl; -{ - decl = build_expr_from_tree (decl); - if (type) - return build_functional_cast (type, build_expr_list (NULL_TREE, decl)); - else - return decl; -} - -/* This is something of the form `int (*a)' that has turned out to be a - decl. It was only converted into parse nodes, so we need to do the - checking that make_{pointer,reference}_declarator do. */ - -tree -finish_decl_parsing (decl) - tree decl; -{ - extern int current_class_depth; - - switch (TREE_CODE (decl)) - { - case IDENTIFIER_NODE: - return decl; - case INDIRECT_REF: - return make_pointer_declarator - (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0))); - case ADDR_EXPR: - return make_reference_declarator - (NULL_TREE, finish_decl_parsing (TREE_OPERAND (decl, 0))); - case BIT_NOT_EXPR: - TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0)); - return decl; - case SCOPE_REF: - push_nested_class (TREE_TYPE (TREE_OPERAND (decl, 0)), 3); - TREE_COMPLEXITY (decl) = current_class_depth; - return decl; - case ARRAY_REF: - TREE_OPERAND (decl, 0) = finish_decl_parsing (TREE_OPERAND (decl, 0)); - return decl; - case TREE_LIST: - /* For attribute handling. */ - TREE_VALUE (decl) = finish_decl_parsing (TREE_VALUE (decl)); - return decl; - default: - my_friendly_abort (5); - return NULL_TREE; - } -} - -tree -check_cp_case_value (value) - tree value; -{ - if (value == NULL_TREE) - return value; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (value); - - if (TREE_READONLY_DECL_P (value)) - { - value = decl_constant_value (value); - STRIP_TYPE_NOPS (value); - } - value = fold (value); - - if (TREE_CODE (value) != INTEGER_CST - && value != error_mark_node) - { - cp_error ("case label `%E' does not reduce to an integer constant", - value); - value = error_mark_node; - } - else - /* Promote char or short to int. */ - value = default_conversion (value); - - constant_expression_warning (value); - - return value; -} - -/* Return 1 if root encloses child. */ - -static int -is_namespace_ancestor (root, child) - tree root, child; -{ - if (root == child) - return 1; - if (root == global_namespace) - return 1; - if (child == global_namespace) - return 0; - return is_namespace_ancestor (root, CP_DECL_CONTEXT (child)); -} - - -/* Return the namespace that is the common ancestor - of two given namespaces. */ - -tree -namespace_ancestor (ns1, ns2) - tree ns1, ns2; -{ - if (is_namespace_ancestor (ns1, ns2)) - return ns1; - return namespace_ancestor (CP_DECL_CONTEXT (ns1), ns2); -} - -/* Insert used into the using list of user. Set indirect_flag if this - directive is not directly from the source. Also find the common - ancestor and let our users know about the new namespace */ -static void -add_using_namespace (user, used, indirect) - tree user; - tree used; - int indirect; -{ - tree t; - /* Using oneself is a no-op. */ - if (user == used) - return; - my_friendly_assert (TREE_CODE (user) == NAMESPACE_DECL, 380); - my_friendly_assert (TREE_CODE (used) == NAMESPACE_DECL, 380); - /* Check if we already have this. */ - t = purpose_member (used, DECL_NAMESPACE_USING (user)); - if (t != NULL_TREE) - { - if (!indirect) - /* Promote to direct usage. */ - TREE_INDIRECT_USING (t) = 0; - return; - } - - /* Add used to the user's using list. */ - DECL_NAMESPACE_USING (user) - = perm_tree_cons (used, namespace_ancestor (user, used), - DECL_NAMESPACE_USING (user)); - - TREE_INDIRECT_USING (DECL_NAMESPACE_USING (user)) = indirect; - - /* Add user to the used's users list. */ - DECL_NAMESPACE_USERS (used) - = perm_tree_cons (user, 0, DECL_NAMESPACE_USERS (used)); - - /* Recursively add all namespaces used. */ - for (t = DECL_NAMESPACE_USING (used); t; t = TREE_CHAIN (t)) - /* indirect usage */ - add_using_namespace (user, TREE_PURPOSE (t), 1); - - /* Tell everyone using us about the new used namespaces. */ - for (t = DECL_NAMESPACE_USERS (user); t; t = TREE_CHAIN (t)) - add_using_namespace (TREE_PURPOSE (t), used, 1); -} - -/* Combines two sets of overloaded functions into an OVERLOAD chain, removing - duplicates. The first list becomes the tail of the result. - - The algorithm is O(n^2). We could get this down to O(n log n) by - doing a sort on the addresses of the functions, if that becomes - necessary. */ - -static tree -merge_functions (s1, s2) - tree s1; - tree s2; -{ - for (; s2; s2 = OVL_NEXT (s2)) - { - tree fn = OVL_CURRENT (s2); - if (! ovl_member (fn, s1)) - s1 = build_overload (fn, s1); - } - return s1; -} - -/* This should return an error not all definitions define functions. - It is not an error if we find two functions with exactly the - same signature, only if these are selected in overload resolution. - old is the current set of bindings, new the freshly-found binding. - XXX Do we want to give *all* candidates in case of ambiguity? - XXX In what way should I treat extern declarations? - XXX I don't want to repeat the entire duplicate_decls here */ - -static tree -ambiguous_decl (name, old, new, flags) - tree name; - tree old; - tree new; - int flags; -{ - tree val, type; - my_friendly_assert (old != NULL_TREE, 393); - /* Copy the value. */ - val = BINDING_VALUE (new); - if (val) - switch (TREE_CODE (val)) - { - case TEMPLATE_DECL: - /* If we expect types or namespaces, and not templates, - or this is not a template class. */ - if (LOOKUP_QUALIFIERS_ONLY (flags) - && (!(flags & LOOKUP_TEMPLATES_EXPECTED) - || !DECL_CLASS_TEMPLATE_P (val))) - val = NULL_TREE; - break; - case TYPE_DECL: - if (LOOKUP_NAMESPACES_ONLY (flags)) - val = NULL_TREE; - break; - case NAMESPACE_DECL: - if (LOOKUP_TYPES_ONLY (flags)) - val = NULL_TREE; - break; - default: - if (LOOKUP_QUALIFIERS_ONLY (flags)) - val = NULL_TREE; - } - - if (!BINDING_VALUE (old)) - BINDING_VALUE (old) = val; - else if (val && val != BINDING_VALUE (old)) - { - if (is_overloaded_fn (BINDING_VALUE (old)) - && is_overloaded_fn (val)) - { - BINDING_VALUE (old) = merge_functions (BINDING_VALUE (old), - val); - } - else - { - /* Some declarations are functions, some are not. */ - if (flags & LOOKUP_COMPLAIN) - { - /* If we've already given this error for this lookup, - BINDING_VALUE (old) is error_mark_node, so let's not - repeat ourselves. */ - if (BINDING_VALUE (old) != error_mark_node) - { - cp_error ("use of `%D' is ambiguous", name); - cp_error_at (" first declared as `%#D' here", - BINDING_VALUE (old)); - } - cp_error_at (" also declared as `%#D' here", val); - } - return error_mark_node; - } - } - /* ... and copy the type. */ - type = BINDING_TYPE (new); - if (LOOKUP_NAMESPACES_ONLY (flags)) - type = NULL_TREE; - if (!BINDING_TYPE (old)) - BINDING_TYPE (old) = type; - else if (type && BINDING_TYPE (old) != type) - { - if (flags & LOOKUP_COMPLAIN) - { - cp_error ("`%D' denotes an ambiguous type",name); - cp_error_at (" first type here", BINDING_TYPE (old)); - cp_error_at (" other type here", type); - } - } - return old; -} - -/* Add the bindings of name in used namespaces to val. - The using list is defined by usings, and the lookup goes to scope. - Returns zero on errors. */ - -int -lookup_using_namespace (name, val, usings, scope, flags) - tree name, val, usings, scope; - int flags; -{ - tree iter; - tree val1; - /* Iterate over all used namespaces in current, searching for using - directives of scope. */ - for (iter = usings; iter; iter = TREE_CHAIN (iter)) - if (TREE_VALUE (iter) == scope) - { - val1 = binding_for_name (name, TREE_PURPOSE (iter)); - /* Resolve ambiguities. */ - val = ambiguous_decl (name, val, val1, flags); - } - return val != error_mark_node; -} - -/* [namespace.qual] - Excepts the name to lookup and its qualifying scope. - Returns the name/type pair found into the CPLUS_BINDING result, - or 0 on error. */ - -int -qualified_lookup_using_namespace (name, scope, result, flags) - tree name; - tree scope; - tree result; - int flags; -{ - /* Maintain a list of namespaces visited... */ - tree seen = NULL_TREE; - /* ... and a list of namespace yet to see. */ - tree todo = NULL_TREE; - tree usings; - while (scope && (result != error_mark_node)) - { - seen = temp_tree_cons (scope, NULL_TREE, seen); - result = ambiguous_decl (name, result, - binding_for_name (name, scope), flags); - if (!BINDING_VALUE (result) && !BINDING_TYPE (result)) - /* Consider using directives. */ - for (usings = DECL_NAMESPACE_USING (scope); usings; - usings = TREE_CHAIN (usings)) - /* If this was a real directive, and we have not seen it. */ - if (!TREE_INDIRECT_USING (usings) - && !purpose_member (TREE_PURPOSE (usings), seen)) - todo = temp_tree_cons (TREE_PURPOSE (usings), NULL_TREE, todo); - if (todo) - { - scope = TREE_PURPOSE (todo); - todo = TREE_CHAIN (todo); - } - else - scope = NULL_TREE; /* If there never was a todo list. */ - } - return result != error_mark_node; -} - -/* [namespace.memdef]/2 */ - -/* Set the context of a declaration to scope. Complain if we are not - outside scope. */ - -void -set_decl_namespace (decl, scope) - tree decl; - tree scope; -{ - tree old; - if (scope == std_node) - scope = global_namespace; - /* Get rid of namespace aliases. */ - scope = ORIGINAL_NAMESPACE (scope); - - if (!is_namespace_ancestor (current_namespace, scope)) - cp_error ("declaration of `%D' not in a namespace surrounding `%D'", - decl, scope); - DECL_CONTEXT (decl) = FROB_CONTEXT (scope); - if (scope != current_namespace) - { - /* See whether this has been declared in the namespace. */ - old = namespace_binding (DECL_NAME (decl), scope); - if (!old) - /* No old declaration at all. */ - goto complain; - if (!is_overloaded_fn (decl)) - /* Don't compare non-function decls with decls_match here, - since it can't check for the correct constness at this - point. pushdecl will find those errors later. */ - return; - /* Since decl is a function, old should contain a function decl. */ - if (!is_overloaded_fn (old)) - goto complain; - for (; old; old = OVL_NEXT (old)) - if (decls_match (decl, OVL_CURRENT (old))) - return; - } - else - return; - complain: - cp_error ("`%D' should have been declared inside `%D'", - decl, scope); -} - -/* Compute the namespace where a declaration is defined. */ - -tree -decl_namespace (decl) - tree decl; -{ - while (DECL_CONTEXT (decl)) - { - decl = DECL_CONTEXT (decl); - if (TREE_CODE (decl) == NAMESPACE_DECL) - return decl; - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') - decl = TYPE_STUB_DECL (decl); - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 390); - } - - return global_namespace; -} - -/* Return the namespace where the current declaration is declared. */ - -tree -current_decl_namespace () -{ - tree result; - /* If we have been pushed into a different namespace, use it. */ - if (decl_namespace_list) - return TREE_PURPOSE (decl_namespace_list); - - if (current_class_type) - result = decl_namespace (TYPE_STUB_DECL (current_class_type)); - else if (current_function_decl) - result = decl_namespace (current_function_decl); - else - result = current_namespace; - return result; -} - -/* Temporarily set the namespace for the current declaration. */ - -void -push_decl_namespace (decl) - tree decl; -{ - if (TREE_CODE (decl) != NAMESPACE_DECL) - decl = decl_namespace (decl); - decl_namespace_list = tree_cons (decl, NULL_TREE, decl_namespace_list); -} - -void -pop_decl_namespace () -{ - decl_namespace_list = TREE_CHAIN (decl_namespace_list); -} - -static void -check_decl_namespace () -{ - my_friendly_assert (decl_namespace_list == NULL_TREE, 980711); -} - -/* Enter a class or namespace scope. */ - -void -push_scope (t) - tree t; -{ - if (TREE_CODE (t) == NAMESPACE_DECL) - push_decl_namespace (t); - else - pushclass (t, 2); -} - -/* Leave scope pushed by push_scope. */ - -void -pop_scope (t) - tree t; -{ - if (TREE_CODE (t) == NAMESPACE_DECL) - pop_decl_namespace (); - else - popclass (1); -} - -/* [basic.lookup.koenig] */ -/* A non-zero return value in the functions below indicates an error. - All nodes allocated in the procedure are on the scratch obstack. */ - -struct arg_lookup -{ - tree name; - tree namespaces; - tree classes; - tree functions; -}; - -static int arg_assoc PROTO((struct arg_lookup*, tree)); -static int arg_assoc_args PROTO((struct arg_lookup*, tree)); -static int arg_assoc_type PROTO((struct arg_lookup*, tree)); - -/* Add a function to the lookup structure. - Returns 1 on error. */ - -static int -add_function (k, fn) - struct arg_lookup *k; - tree fn; -{ - if (ovl_member (fn, k->functions)) - return 0; - /* We must find only functions, or exactly one non-function. */ - if (k->functions && is_overloaded_fn (k->functions) - && is_overloaded_fn (fn)) - k->functions = build_overload (fn, k->functions); - else - if(k->functions) - { - tree f1 = OVL_CURRENT (k->functions); - tree f2 = fn; - if (is_overloaded_fn (f1)) - { - fn = f1; f1 = f2; f2 = fn; - } - cp_error_at ("`%D' is not a function,", f1); - cp_error_at (" conflict with `%D'", f2); - cp_error (" in call to `%D'", k->name); - return 1; - } - else - k->functions = fn; - return 0; -} - -/* Add functions of a namespace to the lookup structure. - Returns 1 on error. */ - -static int -arg_assoc_namespace (k, scope) - struct arg_lookup *k; - tree scope; -{ - tree value; - - if (purpose_member (scope, k->namespaces)) - return 0; - k->namespaces = tree_cons (scope, NULL_TREE, k->namespaces); - - value = namespace_binding (k->name, scope); - if (!value) - return 0; - - for (; value; value = OVL_NEXT (value)) - if (add_function (k, OVL_CURRENT (value))) - return 1; - - return 0; -} - -/* Adds everything associated with class to the lookup structure. - Returns 1 on error. */ - -static int -arg_assoc_class (k, type) - struct arg_lookup* k; - tree type; -{ - tree list, friends, context; - int i; - - if (purpose_member (type, k->classes)) - return 0; - k->classes = tree_cons (type, NULL_TREE, k->classes); - - context = decl_namespace (TYPE_MAIN_DECL (type)); - if (arg_assoc_namespace (k, context)) - return 1; - - /* Process baseclasses. */ - for (i = 0; i < CLASSTYPE_N_BASECLASSES (type); i++) - if (arg_assoc_class (k, TYPE_BINFO_BASETYPE (type, i))) - return 1; - - /* Process friends. */ - for (list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); list; - list = TREE_CHAIN (list)) - if (k->name == TREE_PURPOSE (list)) - for (friends = TREE_VALUE (list); friends; - friends = TREE_CHAIN (friends)) - /* Only interested in global functions with potentially hidden - (i.e. unqualified) declarations. */ - if (TREE_PURPOSE (list) == error_mark_node && TREE_VALUE (list) - && decl_namespace (TREE_VALUE (list)) == context) - if (add_function (k, TREE_VALUE (list))) - return 1; - - /* Process template arguments. */ - if (CLASSTYPE_TEMPLATE_INFO (type)) - { - list = innermost_args (CLASSTYPE_TI_ARGS (type)); - for (i = 0; i < TREE_VEC_LENGTH (list); ++i) - arg_assoc (k, TREE_VEC_ELT (list, i)); - } - - return 0; -} - -/* Adds everything associated with a given type. - Returns 1 on error. */ - -static int -arg_assoc_type (k, type) - struct arg_lookup *k; - tree type; -{ - switch (TREE_CODE (type)) - { - case VOID_TYPE: - case INTEGER_TYPE: - case REAL_TYPE: - case COMPLEX_TYPE: - case CHAR_TYPE: - case BOOLEAN_TYPE: - return 0; - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (type)) - return arg_assoc_type (k, TYPE_PTRMEMFUNC_FN_TYPE (type)); - return arg_assoc_class (k, type); - case POINTER_TYPE: - case REFERENCE_TYPE: - case ARRAY_TYPE: - return arg_assoc_type (k, TREE_TYPE (type)); - case UNION_TYPE: - case ENUMERAL_TYPE: - return arg_assoc_namespace (k, decl_namespace (TYPE_MAIN_DECL (type))); - case OFFSET_TYPE: - /* Pointer to member: associate class type and value type. */ - if (arg_assoc_type (k, TYPE_OFFSET_BASETYPE (type))) - return 1; - return arg_assoc_type (k, TREE_TYPE (type)); - case METHOD_TYPE: - /* The basetype is referenced in the first arg type, so just - fall through. */ - case FUNCTION_TYPE: - /* Associate the parameter types. */ - if (arg_assoc_args (k, TYPE_ARG_TYPES (type))) - return 1; - /* Associate the return type. */ - return arg_assoc_type (k, TREE_TYPE (type)); - case TEMPLATE_TYPE_PARM: - return 0; - case LANG_TYPE: - if (type == unknown_type_node) - return 0; - /* else fall through */ - default: - my_friendly_abort (390); - } - return 0; -} - -/* Adds everything associated with arguments. Returns 1 on error. */ - -static int -arg_assoc_args (k, args) - struct arg_lookup* k; - tree args; -{ - for (; args; args = TREE_CHAIN (args)) - if (arg_assoc (k, TREE_VALUE (args))) - return 1; - return 0; -} - -/* Adds everything associated with a given tree_node. Returns 1 on error. */ - -static int -arg_assoc (k, n) - struct arg_lookup* k; - tree n; -{ - if (n == error_mark_node) - return 0; - - if (TREE_CODE_CLASS (TREE_CODE (n)) == 't') - return arg_assoc_type (k, n); - - if (! type_unknown_p (n)) - return arg_assoc_type (k, TREE_TYPE (n)); - - if (TREE_CODE (n) == ADDR_EXPR) - n = TREE_OPERAND (n, 0); - if (TREE_CODE (n) == COMPONENT_REF) - n = TREE_OPERAND (n, 1); - while (TREE_CODE (n) == TREE_LIST) - n = TREE_VALUE (n); - - if (TREE_CODE (n) == FUNCTION_DECL) - return arg_assoc_type (k, TREE_TYPE (n)); - if (TREE_CODE (n) == TEMPLATE_ID_EXPR) - { - /* [basic.lookup.koenig] - - If T is a template-id, its associated namespaces and classes - are the namespace in which the template is defined; for - member templates, the member template's class; the namespaces - and classes associated with the types of the template - arguments provided for template type parameters (excluding - template template parameters); the namespaces in which any - template template arguments are defined; and the classes in - which any member templates used as template template - arguments are defined. [Note: non-type template arguments do - not contribute to the set of associated namespaces. ] */ - tree template = TREE_OPERAND (n, 0); - tree args = TREE_OPERAND (n, 1); - tree ctx; - tree arg; - - /* First, the template. There may actually be more than one if - this is an overloaded function template. But, in that case, - we only need the first; all the functions will be in the same - namespace. */ - template = OVL_CURRENT (template); - - ctx = CP_DECL_CONTEXT (template); - - if (TREE_CODE (ctx) == NAMESPACE_DECL) - { - if (arg_assoc_namespace (k, ctx) == 1) - return 1; - } - /* It must be a member template. */ - else if (arg_assoc_class (k, ctx) == 1) - return 1; - - /* Now the arguments. */ - for (arg = args; arg != NULL_TREE; arg = TREE_CHAIN (arg)) - { - tree t = TREE_VALUE (arg); - - if (TREE_CODE (t) == TEMPLATE_DECL) - { - ctx = CP_DECL_CONTEXT (t); - if (TREE_CODE (ctx) == NAMESPACE_DECL) - { - if (arg_assoc_namespace (k, ctx) == 1) - return 1; - } - else if (arg_assoc_class (k, ctx) == 1) - return 1; - } - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't' - && arg_assoc_type (k, t) == 1) - return 1; - } - } - else - { - my_friendly_assert (TREE_CODE (n) == OVERLOAD, 980715); - - for (; n; n = OVL_CHAIN (n)) - if (arg_assoc_type (k, TREE_TYPE (OVL_FUNCTION (n)))) - return 1; - } - - return 0; -} - -/* Performs Koenig lookup depending on arguments, where fns - are the functions found in normal lookup. */ - -tree -lookup_arg_dependent (name, fns, args) - tree name; - tree fns; - tree args; -{ - struct arg_lookup k; - k.name = name; - k.functions = fns; - k.namespaces = NULL_TREE; - k.classes = NULL_TREE; - - push_scratch_obstack (); - arg_assoc_args (&k, args); - pop_obstacks (); - return k.functions; -} - -/* Process a namespace-alias declaration. */ - -void -do_namespace_alias (alias, namespace) - tree alias, namespace; -{ - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - /* The parser did not find it, so it's not there. */ - cp_error ("unknown namespace `%D'", namespace); - return; - } - - namespace = ORIGINAL_NAMESPACE (namespace); - - /* Build the alias. */ - alias = build_lang_decl (NAMESPACE_DECL, alias, void_type_node); - DECL_NAMESPACE_ALIAS (alias) = namespace; - pushdecl (alias); -} - -/* Check a non-member using-declaration. Return the name and scope - being used, and the USING_DECL, or NULL_TREE on failure. */ - -static tree -validate_nonmember_using_decl (decl, scope, name) - tree decl; - tree *scope; - tree *name; -{ - if (TREE_CODE (decl) == SCOPE_REF - && TREE_OPERAND (decl, 0) == std_node) - { - if (namespace_bindings_p () - && current_namespace == global_namespace) - /* There's no need for a using declaration at all, here, - since `std' is the same as `::'. We can't just pass this - on because we'll complain later about declaring something - in the same scope as a using declaration with the same - name. We return NULL_TREE which indicates to the caller - that there's no need to do any further processing. */ - return NULL_TREE; - - *scope = global_namespace; - *name = TREE_OPERAND (decl, 1); - } - else if (TREE_CODE (decl) == SCOPE_REF) - { - *scope = TREE_OPERAND (decl, 0); - *name = TREE_OPERAND (decl, 1); - - /* [namespace.udecl] - - A using-declaration for a class member shall be a - member-declaration. */ - if (TREE_CODE (*scope) != NAMESPACE_DECL) - { - cp_error ("`%D' is not a namespace", *scope); - return NULL_TREE; - } - } - else if (TREE_CODE (decl) == IDENTIFIER_NODE - || TREE_CODE (decl) == TYPE_DECL - || TREE_CODE (decl) == TEMPLATE_DECL) - { - *scope = global_namespace; - *name = decl; - } - else - my_friendly_abort (382); - if (TREE_CODE_CLASS (TREE_CODE (*name)) == 'd') - *name = DECL_NAME (*name); - /* Make a USING_DECL. */ - return push_using_decl (*scope, *name); -} - -/* Process local and global using-declarations. */ - -static void -do_nonmember_using_decl (scope, name, oldval, oldtype, newval, newtype) - tree scope, name; - tree oldval, oldtype; - tree *newval, *newtype; -{ - tree decls; - struct tree_binding _decls; - - *newval = *newtype = NULL_TREE; - decls = binding_init (&_decls); - if (!qualified_lookup_using_namespace (name, scope, decls, 0)) - /* Lookup error */ - return; - - if (!BINDING_VALUE (decls) && !BINDING_TYPE (decls)) - { - cp_error ("`%D' not declared", name); - return; - } - - /* Check for using functions. */ - if (BINDING_VALUE (decls) && is_overloaded_fn (BINDING_VALUE (decls))) - { - tree tmp, tmp1; - - if (oldval && !is_overloaded_fn (oldval)) - { - duplicate_decls (OVL_CURRENT (BINDING_VALUE (decls)), oldval); - oldval = NULL_TREE; - } - - *newval = oldval; - for (tmp = BINDING_VALUE (decls); tmp; tmp = OVL_NEXT (tmp)) - { - tree new_fn = OVL_CURRENT (tmp); - - /* [namespace.udecl] - - If a function declaration in namespace scope or block - scope has the same name and the same parameter types as a - function introduced by a using declaration the program is - ill-formed. */ - for (tmp1 = oldval; tmp1; tmp1 = OVL_NEXT (tmp1)) - { - tree old_fn = OVL_CURRENT (tmp1); - - if (!OVL_USED (tmp1) - && compparms (TYPE_ARG_TYPES (TREE_TYPE (new_fn)), - TYPE_ARG_TYPES (TREE_TYPE (old_fn)))) - { - /* There was already a non-using declaration in - this scope with the same parameter types. */ - cp_error ("`%D' is already declared in this scope", - name); - break; - } - else if (duplicate_decls (new_fn, old_fn)) - /* We're re-using something we already used - before. We don't need to add it again. */ - break; - } - - /* If we broke out of the loop, there's no reason to add - this function to the using declarations for this - scope. */ - if (tmp1) - continue; - - *newval = build_overload (OVL_CURRENT (tmp), *newval); - if (TREE_CODE (*newval) != OVERLOAD) - *newval = ovl_cons (*newval, NULL_TREE); - OVL_USED (*newval) = 1; - } - } - else - { - *newval = BINDING_VALUE (decls); - if (oldval) - duplicate_decls (*newval, oldval); - } - - *newtype = BINDING_TYPE (decls); - if (oldtype && *newtype && oldtype != *newtype) - { - cp_error ("using directive `%D' introduced ambiguous type `%T'", - name, oldtype); - return; - } -} - -/* Process a using-declaration not appearing in class or local scope. */ - -void -do_toplevel_using_decl (decl) - tree decl; -{ - tree scope, name, binding; - tree oldval, oldtype, newval, newtype; - - decl = validate_nonmember_using_decl (decl, &scope, &name); - if (decl == NULL_TREE) - return; - - binding = binding_for_name (name, current_namespace); - - oldval = BINDING_VALUE (binding); - oldtype = BINDING_TYPE (binding); - - do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); - - /* Copy declarations found. */ - if (newval) - BINDING_VALUE (binding) = newval; - if (newtype) - BINDING_TYPE (binding) = newtype; - return; -} - -/* Process a using-declaration at function scope. */ - -void -do_local_using_decl (decl) - tree decl; -{ - tree scope, name; - tree oldval, oldtype, newval, newtype; - - decl = validate_nonmember_using_decl (decl, &scope, &name); - if (decl == NULL_TREE) - return; - - oldval = lookup_name_current_level (name); - oldtype = lookup_type_current_level (name); - - do_nonmember_using_decl (scope, name, oldval, oldtype, &newval, &newtype); - - if (newval) - { - if (is_overloaded_fn (newval)) - { - tree fn; - - /* We only need to push declarations for those functions - that were not already bound in the current level. */ - for (fn = newval; fn != oldval; fn = OVL_NEXT (fn)) - push_overloaded_decl (OVL_CURRENT (fn), - PUSH_LOCAL | PUSH_USING); - } - else - push_local_binding (name, newval, PUSH_USING); - } - if (newtype) - set_identifier_type_value (name, newtype); -} - -tree -do_class_using_decl (decl) - tree decl; -{ - tree name, value; - - if (TREE_CODE (decl) != SCOPE_REF - || TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (decl, 0))) != 't') - { - cp_error ("using-declaration for non-member at class scope"); - return NULL_TREE; - } - name = TREE_OPERAND (decl, 1); - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - cp_error ("using-declaration for destructor"); - return NULL_TREE; - } - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 980716); - - value = build_lang_field_decl (USING_DECL, name, void_type_node); - DECL_INITIAL (value) = TREE_OPERAND (decl, 0); - return value; -} - -/* Process a using-directive. */ - -void -do_using_directive (namespace) - tree namespace; -{ - if (namespace == std_node) - return; - /* using namespace A::B::C; */ - if (TREE_CODE (namespace) == SCOPE_REF) - namespace = TREE_OPERAND (namespace, 1); - if (TREE_CODE (namespace) == IDENTIFIER_NODE) - { - /* Lookup in lexer did not find a namespace. */ - cp_error ("namespace `%T' undeclared", namespace); - return; - } - if (TREE_CODE (namespace) != NAMESPACE_DECL) - { - cp_error ("`%T' is not a namespace", namespace); - return; - } - namespace = ORIGINAL_NAMESPACE (namespace); - if (!toplevel_bindings_p ()) - push_using_directive (namespace); - else - /* direct usage */ - add_using_namespace (current_namespace, namespace, 0); -} - -void -check_default_args (x) - tree x; -{ - tree arg = TYPE_ARG_TYPES (TREE_TYPE (x)); - int saw_def = 0, i = 0 - (TREE_CODE (TREE_TYPE (x)) == METHOD_TYPE); - for (; arg && arg != void_list_node; arg = TREE_CHAIN (arg), ++i) - { - if (TREE_PURPOSE (arg)) - saw_def = 1; - else if (saw_def) - { - cp_error_at ("default argument missing for parameter %P of `%+#D'", - i, x); - break; - } - } -} - -void -mark_used (decl) - tree decl; -{ - TREE_USED (decl) = 1; - if (processing_template_decl) - return; - assemble_external (decl); - - /* Is it a synthesized method that needs to be synthesized? */ - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_CLASS_CONTEXT (decl) - && DECL_ARTIFICIAL (decl) && ! DECL_INITIAL (decl) - /* Kludge: don't synthesize for default args. */ - && current_function_decl) - synthesize_method (decl); - - /* If this is a function or variable that is an instance of some - template, we now know that we will need to actually do the - instantiation. A TEMPLATE_DECL may also have DECL_TEMPLATE_INFO, - if it's a partial instantiation, but there's no need to - instantiate such a thing. We check that DECL is not an explicit - instantiation because that is not checked in instantiate_decl. */ - if (TREE_CODE (decl) != TEMPLATE_DECL - && DECL_LANG_SPECIFIC (decl) && DECL_TEMPLATE_INFO (decl) - && !DECL_EXPLICIT_INSTANTIATION (decl)) - instantiate_decl (decl); -} - -/* Helper function for named_class_head_sans_basetype nonterminal. */ - -tree -handle_class_head (aggr, scope, id) - tree aggr, scope, id; -{ - if (TREE_CODE (id) == TYPE_DECL) - return id; - if (DECL_CLASS_TEMPLATE_P (id)) - return DECL_TEMPLATE_RESULT (id); - - if (scope) - cp_error ("`%T' does not have a nested type named `%D'", scope, id); - else - cp_error ("no file-scope type named `%D'", id); - - id = xref_tag - (aggr, make_anon_name (), 1); - return TYPE_MAIN_DECL (id); -} diff --git a/gcc/cp/errfn.c b/gcc/cp/errfn.c deleted file mode 100755 index fd8a6d4..0000000 --- a/gcc/cp/errfn.c +++ /dev/null @@ -1,343 +0,0 @@ -/* Provide a call-back mechanism for handling error output. - Copyright (C) 1993, 94-98, 1999 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "toplev.h" - -/* cp_printer is the type of a function which converts an argument into - a string for digestion by printf. The cp_printer function should deal - with all memory management; the functions in this file will not free - the char*s returned. See error.c for an example use of this code. */ - -typedef char* cp_printer PROTO((tree, int)); -extern cp_printer * cp_printers[256]; - -/* Whether or not we should try to be quiet for errors and warnings; this is - used to avoid being too talkative about problems with tentative choices - when we're computing the conversion costs for a method call. */ -int cp_silent = 0; - -typedef void errorfn (); /* deliberately vague */ - -extern char* cp_file_of PROTO((tree)); -extern int cp_line_of PROTO((tree)); - -#define STRDUP(f) (ap = (char *) alloca (strlen (f) +1), strcpy (ap, (f)), ap) - -/* This function supports only `%s', `%d', `%%', and the C++ print - codes. */ - -static void -cp_thing (errfn, atarg1, format, ap) - errorfn *errfn; - int atarg1; - const char *format; - va_list ap; -{ - static char *buf; - static long buflen; - int nargs = 0; - long len; - long offset; - const char *f; - tree atarg = 0; - - len = strlen (format) + 1; - if (len > buflen) - { - buflen = len; - buf = xrealloc (buf, buflen); - } - offset = 0; - - for (f = format; *f; ++f) - { - cp_printer * function; - int alternate; - int maybe_here; - - /* ignore text */ - if (*f != '%') - { - buf[offset++] = *f; - continue; - } - - ++f; - - alternate = 0; - maybe_here = 0; - - /* Check for '+' and '#' (in that order). */ - if (*f == '+') - { - maybe_here = 1; - ++f; - } - if (*f == '#') - { - alternate = 1; - ++f; - } - - /* no field width or precision */ - - function = cp_printers[(int)*f]; - - if (function || *f == 's') - { - char *p; - int plen; - - if (*f == 's') - { - p = va_arg (ap, char *); - nargs++; - } - else - { - tree t = va_arg (ap, tree); - nargs++; - - /* This indicates that ATARG comes from a different - location than normal. */ - if (maybe_here && atarg1) - atarg = t; - - /* If atarg1 is set and this is the first argument, then - set ATARG appropriately. */ - if (atarg1 && nargs == 1) - atarg = t; - - p = (*function) (t, alternate); - } - - plen = strlen (p); - len += plen; - if (len > buflen) - { - buflen = len; - buf = xrealloc (buf, len); - } - strcpy (buf + offset, p); - offset += plen; - } - else if (*f == '%') - { - /* A `%%' has occurred in the input string. Replace it with - a `%' in the formatted message buf. */ - - if (++len > buflen) - { - buflen = len; - buf = xrealloc (buf, len); - } - buf[offset++] = '%'; - } - else - { - if (*f != 'd') - abort (); - len += HOST_BITS_PER_INT / 2; - if (len > buflen) - { - buflen = len; - buf = xrealloc (buf, len); - } - sprintf (buf + offset, "%d", va_arg (ap, int)); - nargs++; - offset += strlen (buf + offset); - /* With an ANSI C library one could write - out += sprintf (...); */ - } - } - buf[offset] = '\0'; - - /* If ATARG1 is set, but we haven't extracted any arguments, then - extract one tree argument for ATARG. */ - if (nargs == 0 && atarg1) - atarg = va_arg (ap, tree); - - if (atarg) - { - char *file = cp_file_of (atarg); - int line = cp_line_of (atarg); - (*errfn) (file, line, "%s", buf); - } - else - (*errfn) ("%s", buf); - -} - -void -cp_error VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) error, 0, format, ap); - va_end (ap); -} - -void -cp_warning VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) warning, 0, format, ap); - va_end (ap); -} - -void -cp_pedwarn VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) pedwarn, 0, format, ap); - va_end (ap); -} - -extern errorfn compiler_error; - -void -cp_compiler_error VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing (compiler_error, 0, format, ap); - va_end (ap); -} - -void -cp_sprintf VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - cp_thing ((errorfn *) sprintf, 0, format, ap); - va_end (ap); -} - -void -cp_error_at VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) error_with_file_and_line, 1, format, ap); - va_end (ap); -} - -void -cp_warning_at VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) warning_with_file_and_line, 1, format, ap); - va_end (ap); -} - -void -cp_pedwarn_at VPROTO((const char *format, ...)) -{ -#ifndef ANSI_PROTOTYPES - char *format; -#endif - va_list ap; - - VA_START (ap, format); - -#ifndef ANSI_PROTOTYPES - format = va_arg (ap, char *); -#endif - - if (! cp_silent) - cp_thing ((errorfn *) pedwarn_with_file_and_line, 1, format, ap); - va_end (ap); -} diff --git a/gcc/cp/error.c b/gcc/cp/error.c deleted file mode 100755 index ec3bf71..0000000 --- a/gcc/cp/error.c +++ /dev/null @@ -1,2007 +0,0 @@ -/* Call-backs for C++ error reporting. - This code is non-reentrant. - Copyright (C) 1993, 94-97, 1998 Free Software Foundation, Inc. - - 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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "obstack.h" -#include "toplev.h" - -typedef char* cp_printer (); - -#define A args_as_string -#define C code_as_string -#define D decl_as_string -#define E expr_as_string -#define L language_as_string -#define O op_as_string -#define P parm_as_string -#define Q assop_as_string -#define T type_as_string -#define V cv_as_string - -#define o (cp_printer *) 0 -cp_printer * cp_printers[256] = -{ -/*0 1 2 3 4 5 6 7 8 9 A B C D E F */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x00 */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x10 */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x20 */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x30 */ - o, A, o, C, D, E, o, o, o, o, o, o, L, o, o, O, /* 0x40 */ - P, Q, o, o, T, o, V, o, o, o, o, o, o, o, o, o, /* 0x50 */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x60 */ - o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, o, /* 0x70 */ -}; -#undef C -#undef D -#undef E -#undef L -#undef O -#undef P -#undef Q -#undef T -#undef V -#undef o - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Obstack where we build text strings for overloading, etc. */ -static struct obstack scratch_obstack; -static char *scratch_firstobj; - -# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) -# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) -# define OB_PUTC2(C1,C2) \ - (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) -# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) -# define OB_PUTID(ID) \ - (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ - IDENTIFIER_LENGTH (ID))) -# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) -# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) -# define OB_PUTI(CST) do { sprintf (digit_buffer, HOST_WIDE_INT_PRINT_DEC, (HOST_WIDE_INT)(CST)); \ - OB_PUTCP (digit_buffer); } while (0) -# define OB_UNPUT(N) obstack_blank (&scratch_obstack, - (N)); - -# define NEXT_CODE(t) (TREE_CODE (TREE_TYPE (t))) - -enum pad { none, before, after }; - -static void dump_type PROTO((tree, int)); -static void dump_type_real PROTO((tree, int, int)); -static void dump_simple_decl PROTO((tree, tree, int)); -static void dump_decl PROTO((tree, int)); -static void dump_function_decl PROTO((tree, int)); -static void dump_expr PROTO((tree, int)); -static void dump_unary_op PROTO((char *, tree, int)); -static void dump_binary_op PROTO((char *, tree)); -static void dump_aggr_type PROTO((tree, int, int)); -static void dump_type_prefix PROTO((tree, int, int)); -static void dump_type_suffix PROTO((tree, int, int)); -static void dump_function_name PROTO((tree)); -static void dump_expr_list PROTO((tree)); -static void dump_global_iord PROTO((tree)); -static void dump_qualifiers PROTO((tree, enum pad)); -static void dump_char PROTO((int)); -static char *aggr_variety PROTO((tree)); -static tree ident_fndecl PROTO((tree)); - -void -init_error () -{ - gcc_obstack_init (&scratch_obstack); - scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); -} - -/* Returns nonzero if SCOPE is something we want to print for random decls. */ - -static int -interesting_scope_p (scope) - tree scope; -{ - if (scope == NULL_TREE - || scope == global_namespace) - return 0; - - return (TREE_CODE (scope) == NAMESPACE_DECL - || AGGREGATE_TYPE_P (scope)); -} - -static void -dump_qualifiers (t, p) - tree t; - enum pad p; -{ - if (TYPE_QUALS (t)) - { - if (p == before) OB_PUTC (' '); - switch (TYPE_QUALS (t)) - { - case TYPE_QUAL_CONST: - OB_PUTS ("const"); - break; - - case TYPE_QUAL_VOLATILE: - OB_PUTS ("volatile"); - break; - - case TYPE_QUAL_RESTRICT: - OB_PUTS ("__restrict"); - break; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: - OB_PUTS ("const volatile"); - break; - - case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: - OB_PUTS ("const __restrict"); - break; - - case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - OB_PUTS ("volatile __restrict"); - break; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - OB_PUTS ("const volatile __restrict"); - break; - - default: - my_friendly_abort (0); - } - if (p == after) OB_PUTC (' '); - } -} - -/* This must be large enough to hold any printed integer or floating-point - value. */ -static char digit_buffer[128]; - -/* Dump into the obstack a human-readable equivalent of TYPE. */ - -static void -dump_type_real (t, v, canonical_name) - tree t; - int v; /* verbose? */ - int canonical_name; -{ - if (t == NULL_TREE) - return; - - if (TYPE_PTRMEMFUNC_P (t)) - goto offset_type; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - OB_PUTS ("{error}"); - break; - - case UNKNOWN_TYPE: - OB_PUTS ("{unknown type}"); - break; - - case TREE_LIST: - /* i.e. function taking no arguments */ - if (t != void_list_node) - { - dump_type_real (TREE_VALUE (t), v, canonical_name); - /* Can this happen other than for default arguments? */ - if (TREE_PURPOSE (t) && v) - { - OB_PUTS (" = "); - dump_expr (TREE_PURPOSE (t), 0); - } - if (TREE_CHAIN (t)) - { - if (TREE_CHAIN (t) != void_list_node) - { - OB_PUTC2 (',', ' '); - dump_type_real (TREE_CHAIN (t), v, canonical_name); - } - } - else OB_PUTS (" ..."); - } - break; - - case IDENTIFIER_NODE: - OB_PUTID (t); - break; - - case TREE_VEC: - dump_type_real (BINFO_TYPE (t), v, canonical_name); - break; - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - if (TYPE_LANG_SPECIFIC (t) - && (IS_SIGNATURE_POINTER (t) || IS_SIGNATURE_REFERENCE (t))) - { - dump_qualifiers (t, after); - dump_type_real (SIGNATURE_TYPE (t), v, canonical_name); - if (IS_SIGNATURE_POINTER (t)) - OB_PUTC ('*'); - else - OB_PUTC ('&'); - } - else - dump_aggr_type (t, v, canonical_name); - break; - - case TYPE_DECL: - case TEMPLATE_DECL: - case NAMESPACE_DECL: - dump_decl (t, v); - break; - - case COMPLEX_TYPE: - OB_PUTS ("complex "); - dump_type_real (TREE_TYPE (t), v, canonical_name); - break; - - case INTEGER_TYPE: - if (!TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && TREE_UNSIGNED (t)) - OB_PUTS ("unsigned "); - else if (TREE_UNSIGNED (TYPE_MAIN_VARIANT (t)) && !TREE_UNSIGNED (t)) - OB_PUTS ("signed "); - - /* fall through. */ - case REAL_TYPE: - case VOID_TYPE: - case BOOLEAN_TYPE: - { - tree type; - dump_qualifiers (t, after); - type = canonical_name ? TYPE_MAIN_VARIANT (t) : t; - if (TYPE_NAME (type) && TYPE_IDENTIFIER (type)) - OB_PUTID (TYPE_IDENTIFIER (type)); - else - /* Types like intQI_type_node and friends have no names. - These don't come up in user error messages, but it's nice - to be able to print them from the debugger. */ - OB_PUTS ("{anonymous}"); - } - break; - - case TEMPLATE_TEMPLATE_PARM: - if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)) - { - /* For parameters inside template signature. */ - if (TYPE_IDENTIFIER (t)) - OB_PUTID (TYPE_IDENTIFIER (t)); - else - OB_PUTS ("{anonymous template template parm}"); - } - else - { - int i; - tree args = TYPE_TI_ARGS (t); - OB_PUTID (TYPE_IDENTIFIER (t)); - OB_PUTC ('<'); - for (i = 0; i < TREE_VEC_LENGTH (args); i++) - { - tree arg = TREE_VEC_ELT (args, i); - if (TREE_CODE_CLASS (TREE_CODE (arg)) == 't' - || TREE_CODE (arg) == TEMPLATE_DECL) - dump_type_real (arg, 0, canonical_name); - else - dump_expr (arg, 0); - if (i < TREE_VEC_LENGTH (args)-1) - OB_PUTC2 (',', ' '); - } - OB_PUTC ('>'); - } - break; - - case TEMPLATE_TYPE_PARM: - dump_qualifiers (t, after); - if (TYPE_IDENTIFIER (t)) - OB_PUTID (TYPE_IDENTIFIER (t)); - else - OB_PUTS ("{anonymous template type parm}"); - break; - - /* This is not always necessary for pointers and such, but doing this - reduces code size. */ - case ARRAY_TYPE: - case POINTER_TYPE: - case REFERENCE_TYPE: - case OFFSET_TYPE: - offset_type: - case FUNCTION_TYPE: - case METHOD_TYPE: - dump_type_prefix (t, v, canonical_name); - dump_type_suffix (t, v, canonical_name); - break; - - case TYPENAME_TYPE: - OB_PUTS ("typename "); - dump_type_real (TYPE_CONTEXT (t), 0, canonical_name); - OB_PUTS ("::"); - OB_PUTID (TYPE_IDENTIFIER (t)); - break; - - case TYPEOF_TYPE: - OB_PUTS ("__typeof ("); - dump_expr (TYPE_FIELDS (t), 1); - OB_PUTC (')'); - break; - - default: - sorry ("`%s' not supported by dump_type", - tree_code_name[(int) TREE_CODE (t)]); - } -} - -static char * -aggr_variety (t) - tree t; -{ - if (TREE_CODE (t) == ENUMERAL_TYPE) - return "enum"; - else if (TREE_CODE (t) == UNION_TYPE) - return "union"; - else if (TYPE_LANG_SPECIFIC (t) && CLASSTYPE_DECLARED_CLASS (t)) - return "class"; - else if (TYPE_LANG_SPECIFIC (t) && IS_SIGNATURE (t)) - return "signature"; - else - return "struct"; -} - -static void -dump_type (t, v) - tree t; - int v; /* verbose? */ -{ - dump_type_real (t, v, 0); -} - -/* Print out a class declaration, in the form `class foo'. */ - -static void -dump_aggr_type (t, v, canonical_name) - tree t; - int v; /* verbose? */ - int canonical_name; -{ - tree name; - char *variety = aggr_variety (t); - - dump_qualifiers (t, after); - - if (v > 0) - { - OB_PUTCP (variety); - OB_PUTC (' '); - } - - name = TYPE_NAME (canonical_name ? TYPE_MAIN_VARIANT (t) : t); - - if (name && CP_DECL_CONTEXT (name) != global_namespace) - { - /* FUNCTION_DECL or RECORD_TYPE */ - dump_decl (DECL_CONTEXT (name), 0); - OB_PUTC2 (':', ':'); - } - - /* kludge around weird behavior on g++.brendan/line1.C */ - if (name && TREE_CODE (name) != IDENTIFIER_NODE) - name = DECL_NAME (name); - - if (name == 0 || ANON_AGGRNAME_P (name)) - { - OB_PUTS ("{anonymous"); - if (!v) - { - OB_PUTC (' '); - OB_PUTCP (variety); - } - OB_PUTC ('}'); - } - else - OB_PUTID (name); -} - -/* Dump into the obstack the initial part of the output for a given type. - This is necessary when dealing with things like functions returning - functions. Examples: - - return type of `int (* fee ())()': pointer -> function -> int. Both - pointer (and reference and offset) and function (and member) types must - deal with prefix and suffix. - - Arrays must also do this for DECL nodes, like int a[], and for things like - int *[]&. */ - -static void -dump_type_prefix (t, v, canonical_name) - tree t; - int v; /* verbosity */ - int canonical_name; -{ - if (TYPE_PTRMEMFUNC_P (t)) - { - t = TYPE_PTRMEMFUNC_FN_TYPE (t); - goto offset_type; - } - - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - case REFERENCE_TYPE: - { - tree sub = TREE_TYPE (t); - - dump_type_prefix (sub, v, canonical_name); - /* A tree for a member pointer looks like pointer to offset, - so let the OFFSET_TYPE case handle it. */ - if (!TYPE_PTRMEM_P (t)) - { - switch (TREE_CODE (sub)) - { - /* We don't want int ( *)() */ - case FUNCTION_TYPE: - case METHOD_TYPE: - break; - - case ARRAY_TYPE: - OB_PUTC2 (' ', '('); - break; - - case POINTER_TYPE: - /* We don't want "char * *" */ - if (TYPE_QUALS (sub) == TYPE_UNQUALIFIED) - break; - /* But we do want "char *const *" */ - - default: - OB_PUTC (' '); - } - if (TREE_CODE (t) == POINTER_TYPE) - OB_PUTC ('*'); - else - OB_PUTC ('&'); - dump_qualifiers (t, none); - } - } - break; - - case OFFSET_TYPE: - offset_type: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); - if (TREE_CODE (t) == OFFSET_TYPE) /* pmfs deal with this in d_t_p */ - { - OB_PUTC (' '); - dump_type_real (TYPE_OFFSET_BASETYPE (t), 0, canonical_name); - OB_PUTC2 (':', ':'); - } - OB_PUTC ('*'); - dump_qualifiers (t, none); - break; - - /* Can only be reached through function pointer -- this would not be - correct if FUNCTION_DECLs used it. */ - case FUNCTION_TYPE: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); - OB_PUTC2 (' ', '('); - break; - - case METHOD_TYPE: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); - OB_PUTC2 (' ', '('); - dump_aggr_type (TYPE_METHOD_BASETYPE (t), 0, canonical_name); - OB_PUTC2 (':', ':'); - break; - - case ARRAY_TYPE: - dump_type_prefix (TREE_TYPE (t), v, canonical_name); - break; - - case ENUMERAL_TYPE: - case ERROR_MARK: - case IDENTIFIER_NODE: - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case REAL_TYPE: - case RECORD_TYPE: - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - case TREE_LIST: - case TYPE_DECL: - case TREE_VEC: - case UNION_TYPE: - case UNKNOWN_TYPE: - case VOID_TYPE: - case TYPENAME_TYPE: - case COMPLEX_TYPE: - dump_type_real (t, v, canonical_name); - break; - - default: - sorry ("`%s' not supported by dump_type_prefix", - tree_code_name[(int) TREE_CODE (t)]); - } -} - -static void -dump_type_suffix (t, v, canonical_name) - tree t; - int v; /* verbose? */ - int canonical_name; -{ - if (TYPE_PTRMEMFUNC_P (t)) - t = TYPE_PTRMEMFUNC_FN_TYPE (t); - - switch (TREE_CODE (t)) - { - case POINTER_TYPE: - case REFERENCE_TYPE: - case OFFSET_TYPE: - if (TREE_CODE (TREE_TYPE (t)) == ARRAY_TYPE) - OB_PUTC (')'); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); - break; - - /* Can only be reached through function pointer */ - case FUNCTION_TYPE: - case METHOD_TYPE: - { - tree arg; - OB_PUTC2 (')', '('); - arg = TYPE_ARG_TYPES (t); - if (TREE_CODE (t) == METHOD_TYPE) - arg = TREE_CHAIN (arg); - - if (arg) - dump_type (arg, v); - else - OB_PUTS ("..."); - OB_PUTC (')'); - if (TREE_CODE (t) == METHOD_TYPE) - dump_qualifiers - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), before); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); - break; - } - - case ARRAY_TYPE: - OB_PUTC ('['); - if (TYPE_DOMAIN (t)) - { - if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == INTEGER_CST) - OB_PUTI (TREE_INT_CST_LOW (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) + 1); - else if (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (t))) == MINUS_EXPR) - dump_expr (TREE_OPERAND (TYPE_MAX_VALUE (TYPE_DOMAIN (t)), 0), 0); - else - dump_expr (fold (build_binary_op - (PLUS_EXPR, TYPE_MAX_VALUE (TYPE_DOMAIN (t)), - integer_one_node, 1)), 0); - } - OB_PUTC (']'); - dump_type_suffix (TREE_TYPE (t), v, canonical_name); - break; - - case ENUMERAL_TYPE: - case ERROR_MARK: - case IDENTIFIER_NODE: - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case REAL_TYPE: - case RECORD_TYPE: - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - case TREE_LIST: - case TYPE_DECL: - case TREE_VEC: - case UNION_TYPE: - case UNKNOWN_TYPE: - case VOID_TYPE: - case TYPENAME_TYPE: - case COMPLEX_TYPE: - break; - - default: - sorry ("`%s' not supported by dump_type_suffix", - tree_code_name[(int) TREE_CODE (t)]); - } -} - -/* Return a function declaration which corresponds to the IDENTIFIER_NODE - argument. */ - -static tree -ident_fndecl (t) - tree t; -{ - tree n = lookup_name (t, 0); - - if (n == NULL_TREE) - return NULL_TREE; - - if (TREE_CODE (n) == FUNCTION_DECL) - return n; - else if (TREE_CODE (n) == TREE_LIST - && TREE_CODE (TREE_VALUE (n)) == FUNCTION_DECL) - return TREE_VALUE (n); - - my_friendly_abort (66); - return NULL_TREE; -} - -#ifndef NO_DOLLAR_IN_LABEL -# define GLOBAL_THING "_GLOBAL_$" -#else -# ifndef NO_DOT_IN_LABEL -# define GLOBAL_THING "_GLOBAL_." -# else -# define GLOBAL_THING "_GLOBAL__" -# endif -#endif - -#define GLOBAL_IORD_P(NODE) \ - ! strncmp (IDENTIFIER_POINTER(NODE), GLOBAL_THING, sizeof (GLOBAL_THING) - 1) - -static void -dump_global_iord (t) - tree t; -{ - char *name = IDENTIFIER_POINTER (t); - - OB_PUTS ("(static "); - if (name [sizeof (GLOBAL_THING) - 1] == 'I') - OB_PUTS ("initializers"); - else if (name [sizeof (GLOBAL_THING) - 1] == 'D') - OB_PUTS ("destructors"); - else - my_friendly_abort (352); - - OB_PUTS (" for "); - OB_PUTCP (input_filename); - OB_PUTC (')'); -} - -static void -dump_simple_decl (t, type, v) - tree t; - tree type; - int v; -{ - if (v > 0) - { - dump_type_prefix (type, v, 0); - OB_PUTC (' '); - } - if (interesting_scope_p (DECL_CONTEXT (t))) - { - dump_decl (DECL_CONTEXT (t), 0); - OB_PUTC2 (':',':'); - } - if (DECL_NAME (t)) - dump_decl (DECL_NAME (t), v); - else - OB_PUTS ("{anon}"); - if (v > 0) - dump_type_suffix (type, v, 0); -} - -static void -dump_decl (t, v) - tree t; - int v; /* verbosity */ -{ - if (t == NULL_TREE) - return; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - OB_PUTS (" /* decl error */ "); - break; - - case TYPE_DECL: - { - /* Don't say 'typedef class A' */ - if (DECL_ARTIFICIAL (t)) - { - if (v > 0 && TREE_CODE (TREE_TYPE (t)) == TEMPLATE_TYPE_PARM) - /* Say `class T' not just `T'. */ - OB_PUTS ("class "); - - dump_type (TREE_TYPE (t), v); - break; - } - } - if (v > 0) - OB_PUTS ("typedef "); - dump_simple_decl (t, DECL_ORIGINAL_TYPE (t) - ? DECL_ORIGINAL_TYPE (t) : TREE_TYPE (t), v); - break; - - case VAR_DECL: - if (DECL_NAME (t) && VTABLE_NAME_P (DECL_NAME (t))) - { - OB_PUTS ("vtable for "); - if (TYPE_P (DECL_CONTEXT (t))) - dump_type (DECL_CONTEXT (t), v); - else - /* This case can arise with -fno-vtable-thunks. See - expand_upcast_fixups. It's not clear what to print - here. */ - OB_PUTS ("{unknown type}"); - break; - } - /* else fall through */ - case FIELD_DECL: - case PARM_DECL: - dump_simple_decl (t, TREE_TYPE (t), v); - break; - - case NAMESPACE_DECL: - if (CP_DECL_CONTEXT (t) != global_namespace) - { - dump_decl (DECL_CONTEXT (t), v); - OB_PUTC2 (':',':'); - } - if (DECL_NAME (t) == anonymous_namespace_name) - OB_PUTS ("{anonymous}"); - else - OB_PUTID (DECL_NAME (t)); - break; - - case SCOPE_REF: - dump_decl (TREE_OPERAND (t, 0), 0); - OB_PUTS ("::"); - dump_decl (TREE_OPERAND (t, 1), 0); - break; - - case ARRAY_REF: - dump_decl (TREE_OPERAND (t, 0), v); - OB_PUTC ('['); - dump_decl (TREE_OPERAND (t, 1), v); - OB_PUTC (']'); - break; - - /* So that we can do dump_decl in dump_aggr_type and have it work for - both class and function scope. */ - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - dump_type (t, v); - break; - - case TYPE_EXPR: - my_friendly_abort (69); - break; - - /* These special cases are duplicated here so that other functions - can feed identifiers to cp_error and get them demangled properly. */ - case IDENTIFIER_NODE: - { tree f; - if (DESTRUCTOR_NAME_P (t) - && (f = ident_fndecl (t)) - && DECL_LANGUAGE (f) == lang_cplusplus) - { - OB_PUTC ('~'); - dump_decl (DECL_NAME (f), 0); - } - else if (IDENTIFIER_TYPENAME_P (t)) - { - OB_PUTS ("operator "); - /* Not exactly IDENTIFIER_TYPE_VALUE. */ - dump_type (TREE_TYPE (t), 0); - break; - } - else if (IDENTIFIER_OPNAME_P (t)) - { - char *name_string = operator_name_string (t); - OB_PUTS ("operator "); - OB_PUTCP (name_string); - } - else - OB_PUTID (t); - } - break; - - case FUNCTION_DECL: - if (GLOBAL_IORD_P (DECL_ASSEMBLER_NAME (t))) - dump_global_iord (DECL_ASSEMBLER_NAME (t)); - else if (! DECL_LANG_SPECIFIC (t)) - OB_PUTS ("{internal}"); - else - dump_function_decl (t, v); - break; - - case TEMPLATE_DECL: - { - tree orig_args = DECL_TEMPLATE_PARMS (t); - tree args; - int i; - for (args = orig_args = nreverse (orig_args); - args; - args = TREE_CHAIN (args)) - { - int len = TREE_VEC_LENGTH (TREE_VALUE (args)); - - OB_PUTS ("template <"); - for (i = 0; i < len; i++) - { - tree arg = TREE_VEC_ELT (TREE_VALUE (args), i); - tree defval = TREE_PURPOSE (arg); - arg = TREE_VALUE (arg); - if (TREE_CODE (arg) == TYPE_DECL) - { - if (DECL_NAME (arg)) - { - OB_PUTS ("class "); - OB_PUTID (DECL_NAME (arg)); - } - else - OB_PUTS ("class"); - } - else - dump_decl (arg, 1); - - if (defval) - { - OB_PUTS (" = "); - if (TREE_CODE (arg) == TYPE_DECL - || TREE_CODE (arg) == TEMPLATE_DECL) - dump_type (defval, 1); - else - dump_expr (defval, 1); - } - - OB_PUTC2 (',', ' '); - } - if (len != 0) - OB_UNPUT (2); - OB_PUTC2 ('>', ' '); - } - nreverse(orig_args); - - if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == TYPE_DECL) - dump_type (TREE_TYPE (t), v); - else if (TREE_CODE (DECL_TEMPLATE_RESULT (t)) == VAR_DECL) - dump_decl (DECL_TEMPLATE_RESULT (t), v); - else if (TREE_TYPE (t) == NULL_TREE) - my_friendly_abort (353); - else switch (NEXT_CODE (t)) - { - case METHOD_TYPE: - case FUNCTION_TYPE: - dump_function_decl (t, v); - break; - - default: - /* This case can occur with some illegal code. */ - dump_type (TREE_TYPE (t), v); - } - } - break; - - case TEMPLATE_ID_EXPR: - { - tree args; - tree name = TREE_OPERAND (t, 0); - if (is_overloaded_fn (name)) - name = DECL_NAME (get_first_fn (name)); - dump_decl (name, v); - OB_PUTC ('<'); - for (args = TREE_OPERAND (t, 1); args; args = TREE_CHAIN (args)) - { - if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (args))) == 't' - || TREE_CODE (TREE_VALUE (args)) == TEMPLATE_DECL) - dump_type (TREE_VALUE (args), 0); - else - dump_expr (TREE_VALUE (args), 0); - if (TREE_CHAIN (args)) - OB_PUTC2 (',', ' '); - } - OB_PUTC ('>'); - } - break; - - case LOOKUP_EXPR: - dump_decl (TREE_OPERAND (t, 0), v); - break; - - case LABEL_DECL: - OB_PUTID (DECL_NAME (t)); - break; - - case CONST_DECL: - if ((TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == ENUMERAL_TYPE) - || (DECL_INITIAL (t) && - TREE_CODE (DECL_INITIAL (t)) == TEMPLATE_PARM_INDEX)) - dump_simple_decl (t, TREE_TYPE (t), v); - else if (DECL_NAME (t)) - dump_decl (DECL_NAME (t), v); - else if (DECL_INITIAL (t)) - dump_expr (DECL_INITIAL (t), 0); - else - OB_PUTS ("enumerator"); - break; - - case USING_DECL: - OB_PUTS ("using "); - dump_type (DECL_INITIAL (t), 0); - OB_PUTS ("::"); - OB_PUTID (DECL_NAME (t)); - break; - - default: - sorry ("`%s' not supported by dump_decl", - tree_code_name[(int) TREE_CODE (t)]); - } -} - -/* Pretty printing for announce_function. T is the declaration of the - function we are interested in seeing. If V is zero, we print the - argument types. If V is positive, we also print the return types. - If V is negative, we do not even print the argument types. */ - -static void -dump_function_decl (t, v) - tree t; - int v; -{ - tree name; - tree fntype; - tree parmtypes; - tree cname = NULL_TREE; - - if (TREE_CODE (t) == TEMPLATE_DECL) - t = DECL_TEMPLATE_RESULT (t); - - name = DECL_ASSEMBLER_NAME (t); - fntype = TREE_TYPE (t); - parmtypes = TYPE_ARG_TYPES (fntype); - - /* Friends have DECL_CLASS_CONTEXT set, but not DECL_CONTEXT. */ - if (DECL_CLASS_SCOPE_P (t)) - cname = DECL_CLASS_CONTEXT (t); - /* this is for partially instantiated template methods */ - else if (TREE_CODE (fntype) == METHOD_TYPE) - cname = TREE_TYPE (TREE_VALUE (parmtypes)); - - /* Print the return type. */ - if (v > 0) - { - if (DECL_STATIC_FUNCTION_P (t)) - OB_PUTS ("static "); - - if (! DECL_CONV_FN_P (t) - && ! DECL_CONSTRUCTOR_P (t) - && ! DECL_DESTRUCTOR_P (t)) - { - dump_type_prefix (TREE_TYPE (fntype), 1, 0); - OB_PUTC (' '); - } - } - - /* Print the function name. */ - if (cname) - { - dump_type (cname, 0); - OB_PUTC2 (':', ':'); - if (TREE_CODE (fntype) == METHOD_TYPE && parmtypes) - parmtypes = TREE_CHAIN (parmtypes); - if (DECL_CONSTRUCTOR_FOR_VBASE_P (t)) - /* Skip past "in_charge" identifier. */ - parmtypes = TREE_CHAIN (parmtypes); - } - else if (CP_DECL_CONTEXT (t) != global_namespace) - { - dump_decl (DECL_CONTEXT (t), 0); - OB_PUTC2 (':',':'); - } - - if (DESTRUCTOR_NAME_P (name) && DECL_LANGUAGE (t) == lang_cplusplus) - parmtypes = TREE_CHAIN (parmtypes); - - dump_function_name (t); - - /* If V is negative, we don't print the argument types. */ - if (v < 0) - return; - - OB_PUTC ('('); - - if (parmtypes) - dump_type (parmtypes, v); - else - OB_PUTS ("..."); - - OB_PUTC (')'); - - if (v && ! DECL_CONV_FN_P (t)) - dump_type_suffix (TREE_TYPE (fntype), 1, 0); - - if (TREE_CODE (fntype) == METHOD_TYPE) - { - if (IS_SIGNATURE (cname)) - /* We look at the type pointed to by the `optr' field of `this.' */ - dump_qualifiers - (TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (TYPE_ARG_TYPES (fntype))))), before); - else - dump_qualifiers - (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (fntype))), before); - } -} - -/* Handle the function name for a FUNCTION_DECL node, grokking operators - and destructors properly. */ - -static void -dump_function_name (t) - tree t; -{ - tree name = DECL_NAME (t); - - if (DECL_DESTRUCTOR_P (t)) - { - OB_PUTC ('~'); - dump_decl (name, 0); - } - else if (DECL_CONV_FN_P (t)) - { - /* This cannot use the hack that the operator's return - type is stashed off of its name because it may be - used for error reporting. In the case of conflicting - declarations, both will have the same name, yet - the types will be different, hence the TREE_TYPE field - of the first name will be clobbered by the second. */ - OB_PUTS ("operator "); - dump_type (TREE_TYPE (TREE_TYPE (t)), 0); - } - else if (IDENTIFIER_OPNAME_P (name)) - { - char *name_string = operator_name_string (name); - OB_PUTS ("operator "); - OB_PUTCP (name_string); - } - else - dump_decl (name, 0); - - if (DECL_LANG_SPECIFIC (t) && DECL_USE_TEMPLATE (t) - && DECL_TEMPLATE_INFO (t) - && (DECL_TEMPLATE_SPECIALIZATION (t) - || TREE_CODE (DECL_TI_TEMPLATE (t)) != TEMPLATE_DECL - || DECL_TEMPLATE_SPECIALIZATION (DECL_TI_TEMPLATE (t)) - || PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (t)))) - { - tree args = DECL_TEMPLATE_INFO (t) ? DECL_TI_ARGS (t) : NULL_TREE; - OB_PUTC ('<'); - - /* Be careful only to print things when we have them, so as not - to crash producing error messages. */ - if (args) - { - if (TREE_CODE (args) == TREE_LIST) - { - tree arg; - int need_comma = 0; - - for (arg = args; arg; arg = TREE_CHAIN (arg)) - { - tree a = TREE_VALUE (arg); - - if (need_comma) - OB_PUTS (", "); - - if (a) - { - if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' - || TREE_CODE (a) == TEMPLATE_DECL) - dump_type (a, 0); - else - dump_expr (a, 0); - } - - need_comma = 1; - } - } - else if (TREE_CODE (args) == TREE_VEC) - { - int i; - int need_comma = 0; - - if (TREE_VEC_LENGTH (args) > 0 - && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC) - args = TREE_VEC_ELT (args, - TREE_VEC_LENGTH (args) - 1); - - for (i = 0; i < TREE_VEC_LENGTH (args); i++) - { - tree a = TREE_VEC_ELT (args, i); - - if (need_comma) - OB_PUTS (", "); - - if (a) - { - if (TREE_CODE_CLASS (TREE_CODE (a)) == 't' - || TREE_CODE (a) == TEMPLATE_DECL) - dump_type (a, 0); - else - dump_expr (a, 0); - } - - need_comma = 1; - } - } - } - OB_PUTC ('>'); - } -} - -static void -dump_char (c) - int c; -{ - switch (c) - { - case TARGET_NEWLINE: - OB_PUTS ("\\n"); - break; - case TARGET_TAB: - OB_PUTS ("\\t"); - break; - case TARGET_VT: - OB_PUTS ("\\v"); - break; - case TARGET_BS: - OB_PUTS ("\\b"); - break; - case TARGET_CR: - OB_PUTS ("\\r"); - break; - case TARGET_FF: - OB_PUTS ("\\f"); - break; - case TARGET_BELL: - OB_PUTS ("\\a"); - break; - case '\\': - OB_PUTS ("\\\\"); - break; - case '\'': - OB_PUTS ("\\'"); - break; - case '\"': - OB_PUTS ("\\\""); - break; - default: - if (ISPRINT (c)) - OB_PUTC (c); - else - { - sprintf (digit_buffer, "\\%03o", (int) c); - OB_PUTCP (digit_buffer); - } - } -} - -/* Print out a list of initializers (subr of dump_expr) */ - -static void -dump_expr_list (l) - tree l; -{ - while (l) - { - dump_expr (TREE_VALUE (l), 0); - if (TREE_CHAIN (l)) - OB_PUTC2 (',', ' '); - l = TREE_CHAIN (l); - } -} - -/* Print out an expression */ - -static void -dump_expr (t, nop) - tree t; - int nop; /* suppress parens */ -{ - switch (TREE_CODE (t)) - { - case VAR_DECL: - case PARM_DECL: - case FIELD_DECL: - case CONST_DECL: - case FUNCTION_DECL: - case TEMPLATE_DECL: - case NAMESPACE_DECL: - dump_decl (t, -1); - break; - - case INTEGER_CST: - { - tree type = TREE_TYPE (t); - my_friendly_assert (type != 0, 81); - - /* If it's an enum, output its tag, rather than its value. */ - if (TREE_CODE (type) == ENUMERAL_TYPE) - { - char *p = enum_name_string (t, type); - OB_PUTCP (p); - } - else if (type == boolean_type_node) - { - if (t == boolean_false_node - || (TREE_INT_CST_LOW (t) == 0 - && TREE_INT_CST_HIGH (t) == 0)) - OB_PUTS ("false"); - else if (t == boolean_true_node) - OB_PUTS ("true"); - } - else if (type == char_type_node) - { - OB_PUTC ('\''); - dump_char (TREE_INT_CST_LOW (t)); - OB_PUTC ('\''); - } - else if (TREE_INT_CST_HIGH (t) - != (TREE_INT_CST_LOW (t) >> (HOST_BITS_PER_WIDE_INT - 1))) - { - tree val = t; - if (TREE_INT_CST_HIGH (val) < 0) - { - OB_PUTC ('-'); - val = build_int_2 (~TREE_INT_CST_LOW (val), - -TREE_INT_CST_HIGH (val)); - } - /* Would "%x%0*x" or "%x%*0x" get zero-padding on all - systems? */ - { - static char format[10]; /* "%x%09999x\0" */ - if (!format[0]) - sprintf (format, "%%x%%0%dx", HOST_BITS_PER_INT / 4); - sprintf (digit_buffer, format, TREE_INT_CST_HIGH (val), - TREE_INT_CST_LOW (val)); - OB_PUTCP (digit_buffer); - } - } - else - OB_PUTI (TREE_INT_CST_LOW (t)); - } - break; - - case REAL_CST: -#ifndef REAL_IS_NOT_DOUBLE - sprintf (digit_buffer, "%g", TREE_REAL_CST (t)); -#else - { - unsigned char *p = (unsigned char *) &TREE_REAL_CST (t); - size_t i; - strcpy (digit_buffer, "0x"); - for (i = 0; i < sizeof TREE_REAL_CST (t); i++) - sprintf (digit_buffer + 2 + 2*i, "%02x", *p++); - } -#endif - OB_PUTCP (digit_buffer); - break; - - case PTRMEM_CST: - OB_PUTC ('&'); - dump_type (PTRMEM_CST_CLASS (t), 0); - OB_PUTS ("::"); - OB_PUTID (DECL_NAME (PTRMEM_CST_MEMBER (t))); - break; - - case STRING_CST: - { - char *p = TREE_STRING_POINTER (t); - int len = TREE_STRING_LENGTH (t) - 1; - int i; - - OB_PUTC ('\"'); - for (i = 0; i < len; i++) - dump_char (p[i]); - OB_PUTC ('\"'); - } - break; - - case COMPOUND_EXPR: - dump_binary_op (",", t); - break; - - case COND_EXPR: - OB_PUTC ('('); - dump_expr (TREE_OPERAND (t, 0), 0); - OB_PUTS (" ? "); - dump_expr (TREE_OPERAND (t, 1), 0); - OB_PUTS (" : "); - dump_expr (TREE_OPERAND (t, 2), 0); - OB_PUTC (')'); - break; - - case SAVE_EXPR: - if (TREE_HAS_CONSTRUCTOR (t)) - { - OB_PUTS ("new "); - dump_type (TREE_TYPE (TREE_TYPE (t)), 0); - } - else - { - dump_expr (TREE_OPERAND (t, 0), 0); - } - break; - - case AGGR_INIT_EXPR: - OB_PUTID (TYPE_IDENTIFIER (TREE_TYPE (t))); - OB_PUTC ('('); - if (TREE_OPERAND (t, 1)) - dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); - OB_PUTC (')'); - break; - - case CALL_EXPR: - { - tree fn = TREE_OPERAND (t, 0); - tree args = TREE_OPERAND (t, 1); - - if (TREE_CODE (fn) == ADDR_EXPR) - fn = TREE_OPERAND (fn, 0); - - if (TREE_TYPE (fn) != NULL_TREE && NEXT_CODE (fn) == METHOD_TYPE) - { - tree ob = TREE_VALUE (args); - if (TREE_CODE (ob) == ADDR_EXPR) - { - dump_expr (TREE_OPERAND (ob, 0), 0); - OB_PUTC ('.'); - } - else if (TREE_CODE (ob) != PARM_DECL - || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) - { - dump_expr (ob, 0); - OB_PUTC2 ('-', '>'); - } - args = TREE_CHAIN (args); - } - dump_expr (fn, 0); - OB_PUTC ('('); - dump_expr_list (args); - OB_PUTC (')'); - } - break; - - case NEW_EXPR: - { - tree type = TREE_OPERAND (t, 1); - if (NEW_EXPR_USE_GLOBAL (t)) - OB_PUTS ("::"); - OB_PUTS ("new "); - if (TREE_OPERAND (t, 0)) - { - OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 0)); - OB_PUTS (") "); - } - if (TREE_CODE (type) == ARRAY_REF) - type = build_cplus_array_type - (TREE_OPERAND (type, 0), - build_index_type (size_binop (MINUS_EXPR, TREE_OPERAND (type, 1), - integer_one_node))); - dump_type (type, 0); - if (TREE_OPERAND (t, 2)) - { - OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 2)); - OB_PUTC (')'); - } - } - break; - - case TARGET_EXPR: - /* Note that this only works for G++ target exprs. If somebody - builds a general TARGET_EXPR, there's no way to represent that - it initializes anything other that the parameter slot for the - default argument. Note we may have cleared out the first - operand in expand_expr, so don't go killing ourselves. */ - if (TREE_OPERAND (t, 1)) - dump_expr (TREE_OPERAND (t, 1), 0); - break; - - case MODIFY_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - dump_binary_op (opname_tab[(int) TREE_CODE (t)], t); - break; - - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - dump_binary_op ("/", t); - break; - - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - dump_binary_op ("%", t); - break; - - case COMPONENT_REF: - { - tree ob = TREE_OPERAND (t, 0); - if (TREE_CODE (ob) == INDIRECT_REF) - { - ob = TREE_OPERAND (ob, 0); - if (TREE_CODE (ob) != PARM_DECL - || strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")) - { - dump_expr (ob, 0); - OB_PUTC2 ('-', '>'); - } - } - else - { - dump_expr (ob, 0); - OB_PUTC ('.'); - } - dump_expr (TREE_OPERAND (t, 1), 1); - } - break; - - case ARRAY_REF: - dump_expr (TREE_OPERAND (t, 0), 0); - OB_PUTC ('['); - dump_expr (TREE_OPERAND (t, 1), 0); - OB_PUTC (']'); - break; - - case CONVERT_EXPR: - dump_unary_op ("+", t, nop); - break; - - case ADDR_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL - || TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST) - dump_expr (TREE_OPERAND (t, 0), 0); - else - dump_unary_op ("&", t, nop); - break; - - case INDIRECT_REF: - if (TREE_HAS_CONSTRUCTOR (t)) - { - t = TREE_OPERAND (t, 0); - my_friendly_assert (TREE_CODE (t) == CALL_EXPR, 237); - dump_expr (TREE_OPERAND (t, 0), 0); - OB_PUTC ('('); - dump_expr_list (TREE_CHAIN (TREE_OPERAND (t, 1))); - OB_PUTC (')'); - } - else - { - if (TREE_OPERAND (t,0) != NULL_TREE - && NEXT_CODE (TREE_OPERAND (t, 0)) == REFERENCE_TYPE) - dump_expr (TREE_OPERAND (t, 0), nop); - else - dump_unary_op ("*", t, nop); - } - break; - - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - dump_unary_op (opname_tab [(int)TREE_CODE (t)], t, nop); - break; - - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - OB_PUTC ('('); - dump_expr (TREE_OPERAND (t, 0), 0); - OB_PUTCP (opname_tab[(int)TREE_CODE (t)]); - OB_PUTC (')'); - break; - - case NON_LVALUE_EXPR: - /* FIXME: This is a KLUDGE workaround for a parsing problem. There - should be another level of INDIRECT_REF so that I don't have to do - this. */ - if (TREE_TYPE (t) != NULL_TREE && NEXT_CODE (t) == POINTER_TYPE) - { - tree next = TREE_TYPE (TREE_TYPE (t)); - - while (TREE_CODE (next) == POINTER_TYPE) - next = TREE_TYPE (next); - - if (TREE_CODE (next) == FUNCTION_TYPE) - { - if (!nop) OB_PUTC ('('); - OB_PUTC ('*'); - dump_expr (TREE_OPERAND (t, 0), 1); - if (!nop) OB_PUTC (')'); - break; - } - /* else FALLTHRU */ - } - dump_expr (TREE_OPERAND (t, 0), 0); - break; - - case NOP_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); - break; - - case CONSTRUCTOR: - if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) - { - tree idx = build_component_ref (t, index_identifier, NULL_TREE, 0); - - if (integer_all_onesp (idx)) - { - tree pfn = PFN_FROM_PTRMEMFUNC (t); - dump_unary_op ("&", pfn, 0); - break; - } - if (TREE_CODE (idx) == INTEGER_CST - && TREE_INT_CST_HIGH (idx) == 0) - { - tree virtuals; - unsigned HOST_WIDE_INT n; - - t = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (t))); - t = TYPE_METHOD_BASETYPE (t); - virtuals = BINFO_VIRTUALS (TYPE_BINFO (TYPE_MAIN_VARIANT (t))); - - n = TREE_INT_CST_LOW (idx); - - /* Map vtable index back one, to allow for the null pointer to - member. */ - --n; - - while (n > 0 && virtuals) - { - --n; - virtuals = TREE_CHAIN (virtuals); - } - if (virtuals) - { - dump_expr (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); - break; - } - } - } - OB_PUTC ('{'); - dump_expr_list (CONSTRUCTOR_ELTS (t)); - OB_PUTC ('}'); - break; - - case OFFSET_REF: - { - tree ob = TREE_OPERAND (t, 0); - if (is_dummy_object (ob)) - { - if (TREE_CODE (TREE_OPERAND (t, 1)) == FUNCTION_DECL) - /* A::f */ - dump_expr (TREE_OPERAND (t, 1), 0); - else - dump_decl (TREE_OPERAND (t, 1), 0); - } - else - { - if (TREE_CODE (ob) == INDIRECT_REF) - { - dump_expr (TREE_OPERAND (ob, 0), 0); - OB_PUTS (" ->* "); - } - else - { - dump_expr (ob, 0); - OB_PUTS (" .* "); - } - dump_expr (TREE_OPERAND (t, 1), 0); - } - break; - } - - case TEMPLATE_PARM_INDEX: - dump_decl (TEMPLATE_PARM_DECL (t), -1); - break; - - case IDENTIFIER_NODE: - OB_PUTID (t); - break; - - case SCOPE_REF: - dump_type (TREE_OPERAND (t, 0), 0); - OB_PUTS ("::"); - dump_expr (TREE_OPERAND (t, 1), 0); - break; - - case CAST_EXPR: - if (TREE_OPERAND (t, 0) == NULL_TREE - || TREE_CHAIN (TREE_OPERAND (t, 0))) - { - dump_type (TREE_TYPE (t), 0); - OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 0)); - OB_PUTC (')'); - } - else - { - OB_PUTC ('('); - dump_type (TREE_TYPE (t), 0); - OB_PUTC (')'); - OB_PUTC ('('); - dump_expr_list (TREE_OPERAND (t, 0)); - OB_PUTC (')'); - } - break; - - case LOOKUP_EXPR: - OB_PUTID (TREE_OPERAND (t, 0)); - break; - - case ARROW_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); - OB_PUTS ("->"); - break; - - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - if (TREE_CODE (t) == SIZEOF_EXPR) - OB_PUTS ("sizeof ("); - else - { - my_friendly_assert (TREE_CODE (t) == ALIGNOF_EXPR, 0); - OB_PUTS ("__alignof__ ("); - } - if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t, 0))) == 't') - dump_type (TREE_OPERAND (t, 0), 0); - else - dump_unary_op ("*", t, 0); - OB_PUTC (')'); - break; - - case DEFAULT_ARG: - OB_PUTS ("{unparsed}"); - break; - - case TRY_CATCH_EXPR: - case WITH_CLEANUP_EXPR: - case CLEANUP_POINT_EXPR: - dump_expr (TREE_OPERAND (t, 0), nop); - break; - - case TREE_LIST: - if (TREE_VALUE (t) && TREE_CODE (TREE_VALUE (t)) == FUNCTION_DECL) - { - OB_PUTID (DECL_NAME (TREE_VALUE (t))); - break; - } - /* else fall through */ - - /* This list is incomplete, but should suffice for now. - It is very important that `sorry' does not call - `report_error_function'. That could cause an infinite loop. */ - default: - sorry ("`%s' not supported by dump_expr", - tree_code_name[(int) TREE_CODE (t)]); - - /* fall through to ERROR_MARK... */ - case ERROR_MARK: - OB_PUTCP ("{error}"); - break; - } -} - -static void -dump_binary_op (opstring, t) - char *opstring; - tree t; -{ - OB_PUTC ('('); - dump_expr (TREE_OPERAND (t, 0), 1); - OB_PUTC (' '); - OB_PUTCP (opstring); - OB_PUTC (' '); - dump_expr (TREE_OPERAND (t, 1), 1); - OB_PUTC (')'); -} - -static void -dump_unary_op (opstring, t, nop) - char *opstring; - tree t; - int nop; -{ - if (!nop) OB_PUTC ('('); - OB_PUTCP (opstring); - dump_expr (TREE_OPERAND (t, 0), 1); - if (!nop) OB_PUTC (')'); -} - -char * -fndecl_as_string (fndecl, print_ret_type_p) - tree fndecl; - int print_ret_type_p; -{ - return decl_as_string (fndecl, print_ret_type_p); -} - -/* Same, but handle a _TYPE. - Called from convert_to_reference, mangle_class_name_for_template, - build_unary_op, and GNU_xref_decl. If CANONICAL_NAME is non-zero, - when describing a typedef, we use the name of the type described, - rather than the name of the typedef. */ - -char * -type_as_string_real (typ, v, canonical_name) - tree typ; - int v; - int canonical_name; -{ - OB_INIT (); - - dump_type_real (typ, v, canonical_name); - - OB_FINISH (); - - return (char *)obstack_base (&scratch_obstack); -} - - -char * -type_as_string (typ, v) - tree typ; - int v; -{ - return type_as_string_real (typ, v, 0); -} - -char * -expr_as_string (decl, v) - tree decl; - int v ATTRIBUTE_UNUSED; -{ - OB_INIT (); - - dump_expr (decl, 1); - - OB_FINISH (); - - return (char *)obstack_base (&scratch_obstack); -} - -/* A cross between type_as_string and fndecl_as_string. - Only called from substitute_nice_name. */ - -char * -decl_as_string (decl, v) - tree decl; - int v; -{ - OB_INIT (); - - dump_decl (decl, v); - - OB_FINISH (); - - return (char *)obstack_base (&scratch_obstack); -} - -/* Generate the three forms of printable names for lang_printable_name. */ - -char * -lang_decl_name (decl, v) - tree decl; - int v; -{ - if (v >= 2) - return decl_as_string (decl, 1); - - OB_INIT (); - - if (v == 1 && DECL_CLASS_SCOPE_P (decl)) - { - tree cname; - if (TREE_CODE (decl) == FUNCTION_DECL) - cname = DECL_CLASS_CONTEXT (decl); - else - cname = DECL_CONTEXT (decl); - dump_type (cname, 0); - OB_PUTC2 (':', ':'); - } - - if (TREE_CODE (decl) == FUNCTION_DECL) - dump_function_name (decl); - else - dump_decl (DECL_NAME (decl), 0); - - OB_FINISH (); - - return (char *)obstack_base (&scratch_obstack); -} - - -char * -cp_file_of (t) - tree t; -{ - if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) - return DECL_SOURCE_FILE (DECL_CONTEXT (t)); - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - return DECL_SOURCE_FILE (TYPE_MAIN_DECL (t)); - else - return DECL_SOURCE_FILE (t); -} - -int -cp_line_of (t) - tree t; -{ - int line = 0; - if (TREE_CODE (t) == PARM_DECL && DECL_CONTEXT (t)) - line = DECL_SOURCE_LINE (DECL_CONTEXT (t)); - if (TREE_CODE (t) == TYPE_DECL && DECL_ARTIFICIAL (t) - && TYPE_MAIN_DECL (TREE_TYPE (t))) - t = TREE_TYPE (t); - - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - line = DECL_SOURCE_LINE (TYPE_MAIN_DECL (t)); - else - line = DECL_SOURCE_LINE (t); - - if (line == 0) - return lineno; - - return line; -} - -char * -code_as_string (c, v) - enum tree_code c; - int v ATTRIBUTE_UNUSED; -{ - return tree_code_name [c]; -} - -char * -language_as_string (c, v) - enum languages c; - int v ATTRIBUTE_UNUSED; -{ - switch (c) - { - case lang_c: - return "C"; - - case lang_cplusplus: - return "C++"; - - case lang_java: - return "Java"; - - default: - my_friendly_abort (355); - return 0; - } -} - -/* Return the proper printed version of a parameter to a C++ function. */ - -char * -parm_as_string (p, v) - int p; - int v ATTRIBUTE_UNUSED; -{ - if (p < 0) - return "`this'"; - - sprintf (digit_buffer, "%d", p+1); - return digit_buffer; -} - -char * -op_as_string (p, v) - enum tree_code p; - int v ATTRIBUTE_UNUSED; -{ - static char buf[] = "operator "; - - if (p == 0) - return "{unknown}"; - - strcpy (buf + 9, opname_tab [p]); - return buf; -} - -char * -assop_as_string (p, v) - enum tree_code p; - int v ATTRIBUTE_UNUSED; -{ - static char buf[] = "operator "; - - if (p == 0) - return "{unknown}"; - - strcpy (buf + 9, assignop_tab [p]); - return buf; -} - -char * -args_as_string (p, v) - tree p; - int v; -{ - if (p == NULL_TREE) - return ""; - - if (TREE_CODE_CLASS (TREE_CODE (TREE_VALUE (p))) == 't') - return type_as_string (p, v); - - OB_INIT (); - for (; p; p = TREE_CHAIN (p)) - { - if (TREE_VALUE (p) == null_node) - OB_PUTS ("NULL"); - else - dump_type (error_type (TREE_VALUE (p)), v); - if (TREE_CHAIN (p)) - OB_PUTS (", "); - } - OB_FINISH (); - return (char *)obstack_base (&scratch_obstack); -} - -char * -cv_as_string (p, v) - tree p; - int v ATTRIBUTE_UNUSED; -{ - OB_INIT (); - - dump_qualifiers (p, before); - - OB_FINISH (); - - return (char *)obstack_base (&scratch_obstack); -} diff --git a/gcc/cp/except.c b/gcc/cp/except.c deleted file mode 100755 index aa1ff92..0000000 --- a/gcc/cp/except.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* Handle exceptional things in C++. - Copyright (C) 1989, 92-97, 1998, 1999 Free Software Foundation, Inc. - Contributed by Michael Tiemann <tiemann@cygnus.com> - Rewritten by Mike Stump <mrs@cygnus.com>, based upon an - initial re-implementation courtesy Tad Hunt. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" -#include "obstack.h" -#include "expr.h" -#include "output.h" -#include "except.h" -#include "function.h" -#include "defaults.h" -#include "toplev.h" -#include "eh-common.h" - -rtx expand_builtin_return_addr PROTO((enum built_in_function, int, rtx)); - -/* Holds the fndecl for __builtin_return_address. */ -tree builtin_return_address_fndecl; - -/* A couple of backend routines from m88k.c */ - -static void push_eh_cleanup PROTO((void)); -static tree build_eh_type_type PROTO((tree)); -static tree build_eh_type PROTO((tree)); -static void expand_end_eh_spec PROTO((tree)); -static tree call_eh_info PROTO((void)); -static void push_eh_info PROTO((void)); -static tree get_eh_info PROTO((void)); -static tree get_eh_value PROTO((void)); -#if 0 -static tree get_eh_type PROTO((void)); -static tree get_eh_caught PROTO((void)); -static tree get_eh_handlers PROTO((void)); -#endif -static tree do_pop_exception PROTO((void)); -static void process_start_catch_block PROTO((tree, tree)); -static tree build_eh_type_type_ref PROTO((tree)); -static tree build_terminate_handler PROTO((void)); -static tree alloc_eh_object PROTO((tree)); - -#if 0 -/* This is the startup, and finish stuff per exception table. */ - -/* XXX - Tad: exception handling section */ -#ifndef EXCEPT_SECTION_ASM_OP -#define EXCEPT_SECTION_ASM_OP "section\t.gcc_except_table,\"a\",@progbits" -#endif - -#ifdef EXCEPT_SECTION_ASM_OP - - /* on machines which support it, the exception table lives in another section, - but it needs a label so we can reference it... This sets up that - label! */ -asm (EXCEPT_SECTION_ASM_OP); -exception_table __EXCEPTION_TABLE__[1] = { (void*)0, (void*)0, (void*)0 }; -asm (TEXT_SECTION_ASM_OP); - -#endif /* EXCEPT_SECTION_ASM_OP */ - -#ifdef EXCEPT_SECTION_ASM_OP - - /* we need to know where the end of the exception table is... so this - is how we do it! */ - -asm (EXCEPT_SECTION_ASM_OP); -exception_table __EXCEPTION_END__[1] = { (void*)-1, (void*)-1, (void*)-1 }; -asm (TEXT_SECTION_ASM_OP); - -#endif /* EXCEPT_SECTION_ASM_OP */ - -#endif - -#include "decl.h" -#include "insn-flags.h" -#include "obstack.h" - -/* ====================================================================== - Briefly the algorithm works like this: - - When a constructor or start of a try block is encountered, - push_eh_entry (&eh_stack) is called. Push_eh_entry () creates a - new entry in the unwind protection stack and returns a label to - output to start the protection for that block. - - When a destructor or end try block is encountered, pop_eh_entry - (&eh_stack) is called. Pop_eh_entry () returns the eh_entry it - created when push_eh_entry () was called. The eh_entry structure - contains three things at this point. The start protect label, - the end protect label, and the exception handler label. The end - protect label should be output before the call to the destructor - (if any). If it was a destructor, then its parse tree is stored - in the finalization variable in the eh_entry structure. Otherwise - the finalization variable is set to NULL to reflect the fact that - it is the end of a try block. Next, this modified eh_entry node - is enqueued in the finalizations queue by calling - enqueue_eh_entry (&queue,entry). - - +---------------------------------------------------------------+ - |XXX: Will need modification to deal with partially | - | constructed arrays of objects | - | | - | Basically, this consists of keeping track of how many | - | of the objects have been constructed already (this | - | should be in a register though, so that shouldn't be a | - | problem. | - +---------------------------------------------------------------+ - - When a catch block is encountered, there is a lot of work to be - done. - - Since we don't want to generate the catch block inline with the - regular flow of the function, we need to have some way of doing - so. Luckily, we can use sequences to defer the catch sections. - When the start of a catch block is encountered, we start the - sequence. After the catch block is generated, we end the - sequence. - - Next we must insure that when the catch block is executed, all - finalizations for the matching try block have been completed. If - any of those finalizations throw an exception, we must call - terminate according to the ARM (section r.15.6.1). What this - means is that we need to dequeue and emit finalizations for each - entry in the eh_queue until we get to an entry with a NULL - finalization field. For any of the finalization entries, if it - is not a call to terminate (), we must protect it by giving it - another start label, end label, and exception handler label, - setting its finalization tree to be a call to terminate (), and - enqueue'ing this new eh_entry to be output at an outer level. - Finally, after all that is done, we can get around to outputting - the catch block which basically wraps all the "catch (...) {...}" - statements in a big if/then/else construct that matches the - correct block to call. - - ===================================================================== */ - -/* local globals for function calls - ====================================================================== */ - -/* Used to cache "terminate" and "__throw_type_match*". */ -static tree Terminate, CatchMatch; - -/* Used to cache __find_first_exception_table_match for throw. */ -static tree FirstExceptionMatch; - -/* Used to cache a call to __unwind_function. */ -static tree Unwind; - -/* ====================================================================== */ - - -/* ========================================================================= */ - - - -/* local globals - these local globals are for storing data necessary for - generating the exception table and code in the correct order. - - ========================================================================= */ - -extern rtx catch_clauses; -extern tree const_ptr_type_node; - -/* ========================================================================= */ - -/* sets up all the global eh stuff that needs to be initialized at the - start of compilation. - - This includes: - - Setting up all the function call trees. */ - -void -init_exception_processing () -{ - /* void vtype () */ - tree vtype = build_function_type (void_type_node, void_list_node); - - if (flag_honor_std) - push_namespace (get_identifier ("std")); - Terminate = auto_function (get_identifier ("terminate"), - vtype, NOT_BUILT_IN); - TREE_THIS_VOLATILE (Terminate) = 1; - if (flag_honor_std) - pop_namespace (); - - push_lang_context (lang_name_c); - - set_exception_lang_code (EH_LANG_C_plus_plus); - set_exception_version_code (1); - - CatchMatch - = builtin_function (flag_rtti - ? "__throw_type_match_rtti" - : "__throw_type_match", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, const_ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)))), - NOT_BUILT_IN, NULL_PTR); - FirstExceptionMatch - = builtin_function ("__find_first_exception_table_match", - build_function_type (ptr_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)), - NOT_BUILT_IN, NULL_PTR); - Unwind - = builtin_function ("__unwind_function", - build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)), - NOT_BUILT_IN, NULL_PTR); - - pop_lang_context (); - - /* If we use setjmp/longjmp EH, arrange for all cleanup actions to - be protected with __terminate. */ - protect_cleanup_actions_with_terminate = 1; -} - -/* Retrieve a pointer to the cp_eh_info node for the current exception. */ - -static tree -call_eh_info () -{ - tree fn; - - fn = get_identifier ("__start_cp_handler"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree t1, t, fields[7]; - - /* Declare cp_eh_info * __start_cp_handler (void), - as defined in exception.cc. */ - push_obstacks_nochange (); - end_temporary_allocation (); - - /* struct cp_eh_info. This must match exception.cc. Note that this - type is not pushed anywhere. */ - t1= make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, - get_identifier ("handler_label"), ptr_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, - get_identifier ("dynamic_handler_chain"), ptr_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, - get_identifier ("info"), ptr_type_node); - fields[3] = build_lang_field_decl (FIELD_DECL, - get_identifier ("table_index"), ptr_type_node); - /* N.B.: The fourth field LEN is expected to be - the number of fields - 1, not the total number of fields. */ - finish_builtin_type (t1, "eh_context", fields, 3, ptr_type_node); - t1 = build_pointer_type (t1); - - t1= make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, - get_identifier ("match_function"), ptr_type_node); - fields[1] = build_lang_field_decl (FIELD_DECL, - get_identifier ("language"), short_integer_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, - get_identifier ("version"), short_integer_type_node); - /* N.B.: The fourth field LEN is expected to be - the number of fields - 1, not the total number of fields. */ - finish_builtin_type (t1, "__eh_info", fields, 2, ptr_type_node); - t = make_lang_type (RECORD_TYPE); - fields[0] = build_lang_field_decl (FIELD_DECL, - get_identifier ("eh_info"), t1); - fields[1] = build_lang_field_decl (FIELD_DECL, get_identifier ("value"), - ptr_type_node); - fields[2] = build_lang_field_decl (FIELD_DECL, get_identifier ("type"), - ptr_type_node); - fields[3] = build_lang_field_decl - (FIELD_DECL, get_identifier ("cleanup"), - build_pointer_type (build_function_type - (ptr_type_node, tree_cons - (NULL_TREE, ptr_type_node, void_list_node)))); - fields[4] = build_lang_field_decl (FIELD_DECL, get_identifier ("caught"), - boolean_type_node); - fields[5] = build_lang_field_decl (FIELD_DECL, get_identifier ("next"), - build_pointer_type (t)); - fields[6] = build_lang_field_decl - (FIELD_DECL, get_identifier ("handlers"), long_integer_type_node); - /* N.B.: The fourth field LEN is expected to be - the number of fields - 1, not the total number of fields. */ - finish_builtin_type (t, "cp_eh_info", fields, 6, ptr_type_node); - t = build_pointer_type (t); - - /* And now the function. */ - fn = build_lang_decl (FUNCTION_DECL, fn, - build_function_type (t, void_list_node)); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - mark_used (fn); - return build_function_call (fn, NULL_TREE); -} - -/* Retrieve a pointer to the cp_eh_info node for the current exception - and save it in the current binding level. */ - -static void -push_eh_info () -{ - tree decl, fn = call_eh_info (); - - /* Remember the pointer to the current exception info; it won't change - during this catch block. */ - decl = build_decl (VAR_DECL, get_identifier ("__exception_info"), - TREE_TYPE (fn)); - DECL_ARTIFICIAL (decl) = 1; - DECL_INITIAL (decl) = fn; - decl = pushdecl (decl); - cp_finish_decl (decl, fn, NULL_TREE, 0, 0); -} - -/* Returns a reference to the cp_eh_info node for the current exception. */ - -static tree -get_eh_info () -{ - /* Look for the pointer pushed in push_eh_info. */ - tree t = lookup_name (get_identifier ("__exception_info"), 0); - return build_indirect_ref (t, NULL_PTR); -} - -/* Returns a reference to the current exception object. */ - -static tree -get_eh_value () -{ - return build_component_ref (get_eh_info (), get_identifier ("value"), - NULL_TREE, 0); -} - -/* Returns a reference to the current exception type. */ - -#if 0 -static tree -get_eh_type () -{ - return build_component_ref (get_eh_info (), get_identifier ("type"), - NULL_TREE, 0); -} - -/* Returns a reference to whether or not the current exception - has been caught. */ - -static tree -get_eh_caught () -{ - return build_component_ref (get_eh_info (), get_identifier ("caught"), - NULL_TREE, 0); -} - -/* Returns a reference to whether or not the current exception - has been caught. */ - -static tree -get_eh_handlers () -{ - return build_component_ref (get_eh_info (), get_identifier ("handlers"), - NULL_TREE, 0); -} -#endif - -/* Build a type value for use at runtime for a type that is matched - against by the exception handling system. */ - -static tree -build_eh_type_type (type) - tree type; -{ - char *typestring; - tree exp; - - if (type == error_mark_node) - return error_mark_node; - - /* peel back references, so they match. */ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* Peel off cv qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - - if (flag_rtti) - return build1 (ADDR_EXPR, ptr_type_node, get_typeid_1 (type)); - - typestring = build_overload_name (type, 1, 1); - exp = combine_strings (build_string (strlen (typestring)+1, typestring)); - return build1 (ADDR_EXPR, ptr_type_node, exp); -} - -/* Build the address of a runtime type for use in the runtime matching - field of the new exception model */ - -static tree -build_eh_type_type_ref (type) - tree type; -{ - char *typestring; - tree exp; - - if (type == error_mark_node) - return error_mark_node; - - /* peel back references, so they match. */ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* Peel off cv qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - - push_obstacks_nochange (); - end_temporary_allocation (); - - if (flag_rtti) - { - exp = get_tinfo_fn (type); - TREE_USED (exp) = 1; - mark_inline_for_output (exp); - exp = build1 (ADDR_EXPR, ptr_type_node, exp); - } - else - { - typestring = build_overload_name (type, 1, 1); - exp = combine_strings (build_string (strlen (typestring)+1, typestring)); - exp = build1 (ADDR_EXPR, ptr_type_node, exp); - } - pop_obstacks (); - return (exp); -} - - -/* Build a type value for use at runtime for a exp that is thrown or - matched against by the exception handling system. */ - -static tree -build_eh_type (exp) - tree exp; -{ - if (flag_rtti) - { - exp = build_typeid (exp); - return build1 (ADDR_EXPR, ptr_type_node, exp); - } - return build_eh_type_type (TREE_TYPE (exp)); -} - -/* This routine is called to mark all the symbols representing runtime - type functions in the exception table as haveing been referenced. - This will make sure code is emitted for them. Called from finish_file. */ -void -mark_all_runtime_matches () -{ - int x,num; - void **ptr; - tree exp; - - num = find_all_handler_type_matches (&ptr); - if (num == 0 || ptr == NULL) - return; - - for (x=0; x <num; x++) - { - exp = (tree) ptr[x]; - if (TREE_CODE (exp) == ADDR_EXPR) - { - exp = TREE_OPERAND (exp, 0); - if (TREE_CODE (exp) == FUNCTION_DECL) - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (exp)) = 1; - } - } - - free (ptr); -} - -/* Build up a call to __cp_pop_exception, to destroy the exception object - for the current catch block. HANDLER is either true or false, telling - the library whether or not it is being called from an exception handler; - if it is, it avoids destroying the object on rethrow. */ - -static tree -do_pop_exception () -{ - tree fn, cleanup; - fn = get_identifier ("__cp_pop_exception"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - /* Declare void __cp_pop_exception (void *), - as defined in exception.cc. */ - push_obstacks_nochange (); - end_temporary_allocation (); - fn = build_lang_decl - (FUNCTION_DECL, fn, - build_function_type (void_type_node, tree_cons - (NULL_TREE, ptr_type_node, void_list_node))); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - /* Arrange to do a dynamically scoped cleanup upon exit from this region. */ - cleanup = lookup_name (get_identifier ("__exception_info"), 0); - cleanup = build_function_call (fn, expr_tree_cons - (NULL_TREE, cleanup, NULL_TREE)); - return cleanup; -} - -/* This routine creates the cleanup for the current exception. */ - -static void -push_eh_cleanup () -{ - int yes; - - yes = suspend_momentary (); - /* All cleanups must last longer than normal. */ - expand_decl_cleanup (NULL_TREE, do_pop_exception ()); - resume_momentary (yes); -} - -/* Build up a call to terminate on the function obstack, for use as an - exception handler. */ - -static tree -build_terminate_handler () -{ - int yes = suspend_momentary (); - tree term = build_function_call (Terminate, NULL_TREE); - resume_momentary (yes); - return term; -} - -/* Call this to start a catch block. Typename is the typename, and identifier - is the variable to place the object in or NULL if the variable doesn't - matter. If typename is NULL, that means its a "catch (...)" or catch - everything. In that case we don't need to do any type checking. - (ie: it ends up as the "else" clause rather than an "else if" clause) */ - -void -expand_start_catch_block (declspecs, declarator) - tree declspecs, declarator; -{ - tree decl; - - if (processing_template_decl) - { - if (declspecs) - { - decl = grokdeclarator (declarator, declspecs, CATCHPARM, - 1, NULL_TREE); - pushdecl (decl); - decl = build_min_nt (DECL_STMT, copy_to_permanent (declarator), - copy_to_permanent (declspecs), - NULL_TREE); - add_tree (decl); - } - return; - } - - if (! doing_eh (1)) - return; - - process_start_catch_block (declspecs, declarator); -} - - -/* This function performs the expand_start_catch_block functionality for - exceptions implemented in the new style. __throw determines whether - a handler needs to be called or not, so the handler itself has to do - nothing additional. */ - -static void -process_start_catch_block (declspecs, declarator) - tree declspecs, declarator; -{ - tree decl = NULL_TREE; - tree init; - - /* Create a binding level for the eh_info and the exception object - cleanup. */ - pushlevel (0); - expand_start_bindings (0); - - - if (declspecs) - { - decl = grokdeclarator (declarator, declspecs, CATCHPARM, 1, NULL_TREE); - - if (decl == NULL_TREE) - error ("invalid catch parameter"); - } - - if (decl) - start_catch_handler (build_eh_type_type_ref (TREE_TYPE (decl))); - else - start_catch_handler (CATCH_ALL_TYPE); - - emit_line_note (input_filename, lineno); - - push_eh_info (); - - if (decl) - { - tree exp; - tree init_type; - - /* Make sure we mark the catch param as used, otherwise we'll get - a warning about an unused ((anonymous)). */ - TREE_USED (decl) = 1; - - /* Figure out the type that the initializer is. */ - init_type = TREE_TYPE (decl); - if (TREE_CODE (init_type) != REFERENCE_TYPE - && TREE_CODE (init_type) != POINTER_TYPE) - init_type = build_reference_type (init_type); - - exp = get_eh_value (); - - /* Since pointers are passed by value, initialize a reference to - pointer catch parm with the address of the value slot. */ - if (TREE_CODE (init_type) == REFERENCE_TYPE - && TREE_CODE (TREE_TYPE (init_type)) == POINTER_TYPE) - exp = build_unary_op (ADDR_EXPR, exp, 1); - - exp = ocp_convert (init_type , exp, CONV_IMPLICIT|CONV_FORCE_TEMP, 0); - - push_eh_cleanup (); - - /* Create a binding level for the parm. */ - pushlevel (0); - expand_start_bindings (0); - - init = convert_from_reference (exp); - - /* If the constructor for the catch parm exits via an exception, we - must call terminate. See eh23.C. */ - if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (decl))) - { - /* Generate the copy constructor call directly so we can wrap it. - See also expand_default_init. */ - init = ocp_convert (TREE_TYPE (decl), init, - CONV_IMPLICIT|CONV_FORCE_TEMP, 0); - init = build (TRY_CATCH_EXPR, TREE_TYPE (init), init, - build_terminate_handler ()); - } - - /* Let `cp_finish_decl' know that this initializer is ok. */ - DECL_INITIAL (decl) = init; - decl = pushdecl (decl); - - start_decl_1 (decl); - cp_finish_decl (decl, init, NULL_TREE, 0, - LOOKUP_ONLYCONVERTING|DIRECT_BIND); - } - else - { - push_eh_cleanup (); - - /* Create a binding level for the parm. */ - pushlevel (0); - expand_start_bindings (0); - - /* Fall into the catch all section. */ - } - - emit_line_note (input_filename, lineno); -} - - -/* Call this to end a catch block. Its responsible for emitting the - code to handle jumping back to the correct place, and for emitting - the label to jump to if this catch block didn't match. */ - -void -expand_end_catch_block () -{ - if (! doing_eh (1)) - return; - - /* Cleanup the EH parameter. */ - expand_end_bindings (getdecls (), kept_level_p (), 0); - poplevel (kept_level_p (), 1, 0); - - /* Cleanup the EH object. */ - expand_end_bindings (getdecls (), kept_level_p (), 0); - poplevel (kept_level_p (), 1, 0); - - /* Fall to outside the try statement when done executing handler and - we fall off end of handler. This is jump Lresume in the - documentation. */ - expand_goto (top_label_entry (&caught_return_label_stack)); - - end_catch_handler (); -} - -/* An exception spec is implemented more or less like: - - try { - function body; - } catch (...) { - void *p[] = { typeid(raises) }; - __check_eh_spec (p, count); - } - - __check_eh_spec in exception.cc handles all the details. */ - -void -expand_start_eh_spec () -{ - expand_start_try_stmts (); -} - -static void -expand_end_eh_spec (raises) - tree raises; -{ - tree tmp, fn, decl, types = NULL_TREE; - int count = 0; - - expand_start_all_catch (); - expand_start_catch_block (NULL_TREE, NULL_TREE); - - /* Build up an array of type_infos. */ - for (; raises && TREE_VALUE (raises); raises = TREE_CHAIN (raises)) - { - types = expr_tree_cons - (NULL_TREE, build_eh_type_type (TREE_VALUE (raises)), types); - ++count; - } - - types = build_nt (CONSTRUCTOR, NULL_TREE, types); - TREE_HAS_CONSTRUCTOR (types) = 1; - - /* We can't pass the CONSTRUCTOR directly, so stick it in a variable. */ - tmp = build_cplus_array_type (const_ptr_type_node, NULL_TREE); - decl = build_decl (VAR_DECL, NULL_TREE, tmp); - DECL_ARTIFICIAL (decl) = 1; - DECL_INITIAL (decl) = types; - cp_finish_decl (decl, types, NULL_TREE, 0, 0); - - decl = decay_conversion (decl); - - fn = get_identifier ("__check_eh_spec"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - push_obstacks_nochange (); - end_temporary_allocation (); - - tmp = tree_cons - (NULL_TREE, integer_type_node, tree_cons - (NULL_TREE, TREE_TYPE (decl), void_list_node)); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - TREE_THIS_VOLATILE (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - tmp = expr_tree_cons (NULL_TREE, build_int_2 (count, 0), expr_tree_cons - (NULL_TREE, decl, NULL_TREE)); - tmp = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), tmp); - expand_expr (tmp, const0_rtx, VOIDmode, EXPAND_NORMAL); - - expand_end_catch_block (); - expand_end_all_catch (); -} - -/* This is called to expand all the toplevel exception handling - finalization for a function. It should only be called once per - function. */ - -void -expand_exception_blocks () -{ - do_pending_stack_adjust (); - push_to_sequence (catch_clauses); - expand_leftover_cleanups (); - do_pending_stack_adjust (); - catch_clauses = get_insns (); - end_sequence (); - - /* Do this after we expand leftover cleanups, so that the - expand_eh_region_end that expand_end_eh_spec does will match the - right expand_eh_region_start, and make sure it comes out before - the terminate protected region. */ - if (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))) - { - expand_end_eh_spec (TYPE_RAISES_EXCEPTIONS (TREE_TYPE (current_function_decl))); - do_pending_stack_adjust (); - push_to_sequence (catch_clauses); - expand_leftover_cleanups (); - do_pending_stack_adjust (); - catch_clauses = get_insns (); - end_sequence (); - } - - if (catch_clauses) - { - rtx funcend = gen_label_rtx (); - emit_jump (funcend); - - /* We cannot protect n regions this way if we must flow into the - EH region through the top of the region, as we have to with - the setjmp/longjmp approach. */ - if (exceptions_via_longjmp == 0) - expand_eh_region_start (); - - emit_insns (catch_clauses); - catch_clauses = NULL_RTX; - - if (exceptions_via_longjmp == 0) - expand_eh_region_end (build_terminate_handler ()); - - expand_leftover_cleanups (); - - emit_label (funcend); - } -} - -tree -start_anon_func () -{ - static int counter = 0; - int old_interface_unknown = interface_unknown; - char name[32]; - tree params; - tree t; - - push_cp_function_context (NULL_TREE); - push_to_top_level (); - - /* No need to mangle this. */ - push_lang_context (lang_name_c); - - interface_unknown = 1; - - params = void_list_node; - /* tcf stands for throw clean function. */ - sprintf (name, "__tcf_%d", counter++); - t = make_call_declarator (get_identifier (name), params, NULL_TREE, - NULL_TREE); - start_function (decl_tree_cons (NULL_TREE, get_identifier ("static"), - void_list_node), - t, NULL_TREE, 0); - store_parm_decls (); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); - emit_line_note (input_filename, lineno); - - interface_unknown = old_interface_unknown; - - pop_lang_context (); - - return current_function_decl; -} - -void -end_anon_func () -{ - expand_end_bindings (getdecls (), 1, 0); - poplevel (1, 0, 0); - pop_momentary (); - - finish_function (lineno, 0, 0); - - pop_from_top_level (); - pop_cp_function_context (NULL_TREE); -} - -/* Return a pointer to a buffer for an exception object of type TYPE. */ - -static tree -alloc_eh_object (type) - tree type; -{ - tree fn, exp; - - fn = get_identifier ("__eh_alloc"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - /* Declare __eh_alloc (size_t), as defined in exception.cc. */ - tree tmp; - push_obstacks_nochange (); - end_temporary_allocation (); - tmp = tree_cons (NULL_TREE, sizetype, void_list_node); - fn = build_lang_decl (FUNCTION_DECL, fn, - build_function_type (ptr_type_node, tmp)); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - exp = build_function_call (fn, expr_tree_cons - (NULL_TREE, size_in_bytes (type), NULL_TREE)); - exp = build1 (NOP_EXPR, build_pointer_type (type), exp); - return exp; -} - -/* Expand a throw statement. This follows the following - algorithm: - - 1. Allocate space to save the current PC onto the stack. - 2. Generate and emit a label and save its address into the - newly allocated stack space since we can't save the pc directly. - 3. If this is the first call to throw in this function: - generate a label for the throw block - 4. jump to the throw block label. */ - -void -expand_throw (exp) - tree exp; -{ - tree fn; - static tree cleanup_type; - - if (! doing_eh (1)) - return; - - if (exp) - { - tree throw_type; - tree cleanup = NULL_TREE, e; - - /* throw expression */ - /* First, decay it. */ - exp = decay_conversion (exp); - - /* cleanup_type is void (*)(void *, int), - the internal type of a destructor. */ - if (cleanup_type == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - cleanup_type = build_pointer_type - (build_function_type - (void_type_node, tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, integer_type_node, void_list_node)))); - pop_obstacks (); - } - - if (TYPE_PTR_P (TREE_TYPE (exp))) - throw_type = build_eh_type (exp); - else - { - tree object, ptr; - - /* OK, this is kind of wacky. The WP says that we call - terminate - - when the exception handling mechanism, after completing - evaluation of the expression to be thrown but before the - exception is caught (_except.throw_), calls a user function - that exits via an uncaught exception. - - So we have to protect the actual initialization of the - exception object with terminate(), but evaluate the expression - first. We also expand the call to __eh_alloc - first. Since there could be temps in the expression, we need - to handle that, too. */ - - expand_start_target_temps (); - -#if 0 - /* Unfortunately, this doesn't work. */ - preexpand_calls (exp); -#else - /* Store the throw expression into a temp. This can be less - efficient than storing it into the allocated space directly, but - oh well. To do this efficiently we would need to insinuate - ourselves into expand_call. */ - if (TREE_SIDE_EFFECTS (exp)) - { - tree temp = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (exp)); - DECL_ARTIFICIAL (temp) = 1; - DECL_RTL (temp) = assign_temp (TREE_TYPE (exp), 2, 0, 1); - DECL_INITIAL (temp) = exp; - cp_finish_decl (temp, exp, NULL_TREE, 0, LOOKUP_ONLYCONVERTING); - exp = temp; - } -#endif - - /* Allocate the space for the exception. */ - ptr = save_expr (alloc_eh_object (TREE_TYPE (exp))); - expand_expr (ptr, const0_rtx, VOIDmode, 0); - - expand_eh_region_start (); - - object = build_indirect_ref (ptr, NULL_PTR); - exp = build_modify_expr (object, INIT_EXPR, exp); - - if (exp == error_mark_node) - error (" in thrown expression"); - - expand_expr (exp, const0_rtx, VOIDmode, 0); - expand_eh_region_end (build_terminate_handler ()); - expand_end_target_temps (); - - throw_type = build_eh_type (object); - - if (TYPE_HAS_DESTRUCTOR (TREE_TYPE (object))) - { - cleanup = lookup_fnfields (TYPE_BINFO (TREE_TYPE (object)), - dtor_identifier, 0); - cleanup = TREE_VALUE (cleanup); - mark_used (cleanup); - mark_addressable (cleanup); - /* Pretend it's a normal function. */ - cleanup = build1 (ADDR_EXPR, cleanup_type, cleanup); - } - - exp = ptr; - } - - /* Cast EXP to `void *' so that it will match the prototype for - __cp_push_exception. */ - exp = convert (ptr_type_node, exp); - - if (cleanup == NULL_TREE) - { - cleanup = build_int_2 (0, 0); - TREE_TYPE (cleanup) = cleanup_type; - } - - fn = get_identifier ("__cp_push_exception"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - /* Declare __cp_push_exception (void*, void*, void (*)(void*, int)), - as defined in exception.cc. */ - tree tmp; - push_obstacks_nochange (); - end_temporary_allocation (); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, cleanup_type, void_list_node))); - fn = build_lang_decl (FUNCTION_DECL, fn, - build_function_type (void_type_node, tmp)); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - e = expr_tree_cons (NULL_TREE, exp, expr_tree_cons - (NULL_TREE, throw_type, expr_tree_cons - (NULL_TREE, cleanup, NULL_TREE))); - e = build_function_call (fn, e); - expand_expr (e, const0_rtx, VOIDmode, 0); - } - else - { - /* rethrow current exception; note that it's no longer caught. */ - - tree fn = get_identifier ("__uncatch_exception"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - /* Declare void __uncatch_exception (void) - as defined in exception.cc. */ - push_obstacks_nochange (); - end_temporary_allocation (); - fn = build_lang_decl (FUNCTION_DECL, fn, - build_function_type (void_type_node, - void_list_node)); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - exp = build_function_call (fn, NULL_TREE); - expand_expr (exp, const0_rtx, VOIDmode, EXPAND_NORMAL); - } - - expand_internal_throw (); -} - -/* Build a throw expression. */ - -tree -build_throw (e) - tree e; -{ - if (e == error_mark_node) - return e; - - if (processing_template_decl) - return build_min (THROW_EXPR, void_type_node, e); - - if (e == null_node) - cp_warning ("throwing NULL, which has integral, not pointer type"); - - e = build1 (THROW_EXPR, void_type_node, e); - TREE_SIDE_EFFECTS (e) = 1; - TREE_USED (e) = 1; - - return e; -} diff --git a/gcc/cp/exception.cc b/gcc/cp/exception.cc deleted file mode 100755 index 0aeb5ab..0000000 --- a/gcc/cp/exception.cc +++ /dev/null @@ -1,345 +0,0 @@ -// Functions for Exception Support for -*- C++ -*- -// Copyright (C) 1994, 95-97, 1998 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -#pragma implementation "exception" - -#ifndef __EMBEDDED_CXX__ -#include "typeinfo" -#include "exception" -#include <stddef.h> -#include "gansidecl.h" /* Needed to support macros used in eh-common.h. */ -#include "eh-common.h" - -/* Define terminate, unexpected, set_terminate, set_unexpected as - well as the default terminate func and default unexpected func. */ - -extern std::terminate_handler __terminate_func __attribute__((__noreturn__)); -using std::terminate; - -void -std::terminate () -{ - __terminate_func (); -} - -void -__default_unexpected () -{ - terminate (); -} - -static std::unexpected_handler __unexpected_func __attribute__((__noreturn__)) - = __default_unexpected; - -std::terminate_handler -std::set_terminate (std::terminate_handler func) -{ - std::terminate_handler old = __terminate_func; - - __terminate_func = func; - return old; -} - -std::unexpected_handler -std::set_unexpected (std::unexpected_handler func) -{ - std::unexpected_handler old = __unexpected_func; - - __unexpected_func = func; - return old; -} - -void -std::unexpected () -{ - __unexpected_func (); -} - -/* C++-specific state about the current exception. - This must match init_exception_processing(). - - Note that handlers and caught are not redundant; when rethrown, an - exception can have multiple active handlers and still be considered - uncaught. */ - -struct cp_eh_info -{ - __eh_info eh_info; - void *value; - void *type; - void (*cleanup)(void *, int); - bool caught; - cp_eh_info *next; - long handlers; - void *original_value; -}; - -/* Language-specific EH info pointer, defined in libgcc2. */ - -extern "C" cp_eh_info **__get_eh_info (); // actually void ** - -/* Is P the type_info node for a pointer of some kind? */ - -extern bool __is_pointer (void *); - - -/* OLD Compiler hook to return a pointer to the info for the current exception. - Used by get_eh_info (). This fudges the actualy returned value to - point to the beginning of what USE to be the cp_eh_info structure. - THis is so that old code that dereferences this pointer will find - things where it expects it to be.*/ -extern "C" void * -__cp_exception_info (void) -{ - return &((*__get_eh_info ())->value); -} - -#define CP_EH_INFO ((cp_eh_info *) *__get_eh_info ()) - -/* Old Compiler hook to return a pointer to the info for the current exception. - Used by get_eh_info (). */ - -extern "C" cp_eh_info * -__cp_eh_info (void) -{ - cp_eh_info *p = CP_EH_INFO; - return p; -} - -/* Compiler hook to return a pointer to the info for the current exception, - Set the caught bit, and increment the number of handlers that are - looking at this exception. This makes handlers smaller. */ - -extern "C" cp_eh_info * -__start_cp_handler (void) -{ - cp_eh_info *p = CP_EH_INFO; - p->caught = 1; - p->handlers++; - return p; -} - -/* Allocate a buffer for a cp_eh_info and an exception object of size SIZE, - and return a pointer to the beginning of the object's space. */ - -extern "C" void * malloc (size_t); -extern "C" void * -__eh_alloc (size_t size) -{ - void *p = malloc (size); - if (p == 0) - terminate (); - return p; -} - -/* Free the memory for an cp_eh_info and associated exception, given - a pointer to the cp_eh_info. */ - -extern "C" void free (void *); -extern "C" void -__eh_free (void *p) -{ - free (p); -} - - -typedef void * (* rtimetype) (void); - -extern "C" void * -__cplus_type_matcher (cp_eh_info *info, rtimetype match_info, - exception_descriptor *exception_table) -{ - void *ret; - - /* No exception table implies the old style mechanism, so don't check. */ - if (exception_table != NULL - && exception_table->lang.language != EH_LANG_C_plus_plus) - return NULL; - - if (match_info == CATCH_ALL_TYPE) - return info->value; - - /* we don't worry about version info yet, there is only one version! */ - - void *match_type = match_info (); - ret = __throw_type_match_rtti (match_type, info->type, info->original_value); - /* change value of exception */ - if (ret) - info->value = ret; - return ret; -} - - -/* Compiler hook to push a new exception onto the stack. - Used by expand_throw(). */ - -extern "C" void -__cp_push_exception (void *value, void *type, void (*cleanup)(void *, int)) -{ - cp_eh_info *p = (cp_eh_info *) __eh_alloc (sizeof (cp_eh_info)); - - p->value = value; - p->type = type; - p->cleanup = cleanup; - p->handlers = 0; - p->caught = false; - p->original_value = value; - - p->eh_info.match_function = __cplus_type_matcher; - p->eh_info.language = EH_LANG_C_plus_plus; - p->eh_info.version = 1; - - cp_eh_info **q = __get_eh_info (); - - p->next = *q; - *q = p; -} - -/* Compiler hook to pop an exception that has been finalized. Used by - push_eh_cleanup(). P is the info for the exception caught by the - current catch block. */ - -extern "C" void -__cp_pop_exception (cp_eh_info *p) -{ - cp_eh_info **q = __get_eh_info (); - - --p->handlers; - - /* Don't really pop if there are still active handlers for our exception, - or if our exception is being rethrown (i.e. if the active exception is - our exception and it is uncaught). */ - if (p->handlers != 0 - || (p == *q && !p->caught)) - return; - - for (; *q; q = &((*q)->next)) - if (*q == p) - break; - - if (! *q) - terminate (); - - *q = p->next; - - if (p->cleanup) - /* 2 is a magic value for destructors; see build_delete(). */ - p->cleanup (p->value, 2); - - if (! __is_pointer (p->type)) - __eh_free (p->original_value); // value may have been co-erced. - - __eh_free (p); -} - -extern "C" void -__uncatch_exception (void) -{ - cp_eh_info *p = CP_EH_INFO; - if (p == 0) - terminate (); - p->caught = false; -} - -/* As per [except.unexpected]: - If an exception is thrown, we check it against the spec. If it doesn't - match, we call unexpected (). If unexpected () throws, we check that - exception against the spec. If it doesn't match, if the spec allows - bad_exception we throw that; otherwise we call terminate (). - - The compiler treats an exception spec as a try block with a generic - handler that just calls this function with a list of the allowed - exception types, so we have an active exception that can be rethrown. - - This function does not return. */ - -extern "C" void -__check_eh_spec (int n, const void **spec) -{ - cp_eh_info *p = CP_EH_INFO; - - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti (spec[i], p->type, p->value)) - throw; - } - - try - { - std::unexpected (); - } - catch (...) - { - // __exception_info is an artificial var pushed into each catch block. - if (p != __exception_info) - { - p = __exception_info; - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti (spec[i], p->type, p->value)) - throw; - } - } - - const std::type_info &bad_exc = typeid (std::bad_exception); - for (int i = 0; i < n; ++i) - { - if (__throw_type_match_rtti (spec[i], &bad_exc, p->value)) - throw std::bad_exception (); - } - - terminate (); - } -} - -extern "C" void -__throw_bad_cast (void) -{ - throw std::bad_cast (); -} - -extern "C" void -__throw_bad_typeid (void) -{ - throw std::bad_typeid (); -} - -/* Has the current exception been caught? */ - -bool -std::uncaught_exception () -{ - cp_eh_info *p = CP_EH_INFO; - return p && ! p->caught; -} - -const char * std::exception:: -what () const -{ - return typeid (*this).name (); -} -#endif diff --git a/gcc/cp/expr.c b/gcc/cp/expr.c deleted file mode 100755 index 3dc8eae..0000000 --- a/gcc/cp/expr.c +++ /dev/null @@ -1,433 +0,0 @@ -/* Convert language-specific tree expression to rtl instructions, - for GNU compiler. - Copyright (C) 1988, 92-97, 1998 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "rtl.h" -#include "tree.h" -#include "flags.h" -#include "expr.h" -#include "cp-tree.h" -#include "toplev.h" - -#if 0 -static tree extract_aggr_init PROTO((tree, tree)); -static tree extract_scalar_init PROTO((tree, tree)); -#endif -static rtx cplus_expand_expr PROTO((tree, rtx, enum machine_mode, - enum expand_modifier)); - -/* Hook used by expand_expr to expand language-specific tree codes. */ - -static rtx -cplus_expand_expr (exp, target, tmode, modifier) - tree exp; - rtx target; - enum machine_mode tmode; - enum expand_modifier modifier; -{ - tree type = TREE_TYPE (exp); - register enum machine_mode mode = TYPE_MODE (type); - register enum tree_code code = TREE_CODE (exp); - int ignore = target == const0_rtx; - - if (ignore) - target = 0; - - /* No sense saving up arithmetic to be done - if it's all in the wrong mode to form part of an address. - And force_operand won't know whether to sign-extend or zero-extend. */ - - if (mode != Pmode && modifier == EXPAND_SUM) - modifier = EXPAND_NORMAL; - - switch (code) - { - case AGGR_INIT_EXPR: - { - /* Something needs to be initialized, but we didn't know - where that thing was when building the tree. For example, - it could be the return value of a function, or a parameter - to a function which lays down in the stack, or a temporary - variable which must be passed by reference. - - Cleanups are handled in a language-specific way: they - might be run by the called function (true in GNU C++ - for parameters with cleanups), or they might be - run by the caller, after the call (true in GNU C++ - for other cleanup needs). */ - - tree func = TREE_OPERAND (exp, 0); - tree args = TREE_OPERAND (exp, 1); - tree type = TREE_TYPE (exp), slot; - tree call_exp; - rtx call_target, return_target; - int pcc_struct_return = 0; - - /* The expression `init' wants to initialize what - `target' represents. SLOT holds the slot for TARGET. */ - slot = TREE_OPERAND (exp, 2); - - /* Should always be called with a target. */ - my_friendly_assert (target != NULL_RTX, 205); - - /* The target the initializer will initialize (CALL_TARGET) - must now be directed to initialize the target we are - supposed to initialize (TARGET). The semantics for - choosing what CALL_TARGET is is language-specific, - as is building the call which will perform the - initialization. It is left here to show the choices that - exist for C++. */ - - if (TREE_CODE (func) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (func, 0)) == FUNCTION_DECL - && DECL_CONSTRUCTOR_P (TREE_OPERAND (func, 0))) - { - type = build_pointer_type (type); - /* Don't clobber a value that might be part of a default - parameter value. */ - mark_addressable (slot); - if (TREE_PERMANENT (args)) - args = expr_tree_cons (0, build1 (ADDR_EXPR, type, slot), - TREE_CHAIN (args)); - else - TREE_VALUE (args) = build1 (ADDR_EXPR, type, slot); - call_target = 0; - } - else - { - call_target = target; -#ifdef PCC_STATIC_STRUCT_RETURN - if (aggregate_value_p (type)) - { - pcc_struct_return = 1; - call_target = 0; - } -#endif - } - - call_exp = build (CALL_EXPR, type, func, args, NULL_TREE); - TREE_SIDE_EFFECTS (call_exp) = 1; - return_target = expand_call (call_exp, call_target, ignore); - - if (call_target) - /* Trust that the right thing has been done; it's too hard to - verify. */ - return return_target; - - /* If we're suffering under the ancient PCC_STATIC_STRUCT_RETURN - calling convention, we need to copy the return value out of - the static return buffer into slot. */ - if (pcc_struct_return) - { - extern int flag_access_control; - int old_ac = flag_access_control; - - tree init = build_decl (VAR_DECL, NULL_TREE, - build_reference_type (type)); - DECL_RTL (init) = XEXP (return_target, 0); - init = convert_from_reference (init); - - flag_access_control = 0; - expand_aggr_init (slot, init, LOOKUP_ONLYCONVERTING); - flag_access_control = old_ac; - - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - init = maybe_build_cleanup (init); - if (init != NULL_TREE) - expand_expr (init, const0_rtx, VOIDmode, 0); - } - } - - return DECL_RTL (slot); - } - - case PTRMEM_CST: - { - tree member; - tree offset; - - /* Find the member. */ - member = PTRMEM_CST_MEMBER (exp); - - if (TREE_CODE (member) == FIELD_DECL) - { - /* Find the offset for the field. */ - offset = convert (sizetype, - size_binop (EASY_DIV_EXPR, - DECL_FIELD_BITPOS (member), - size_int (BITS_PER_UNIT))); - - /* We offset all pointer to data members by 1 so that we - can distinguish between a null pointer to data member - and the first data member of a structure. */ - offset = size_binop (PLUS_EXPR, offset, size_int (1)); - - return expand_expr (cp_convert (type, offset), target, tmode, - modifier); - } - else - { - /* We don't yet handle pointer-to-member functions this - way. */ - my_friendly_abort (0); - return 0; - } - } - - case OFFSET_REF: - { - return expand_expr (default_conversion (resolve_offset_ref (exp)), - target, tmode, EXPAND_NORMAL); - } - - case THUNK_DECL: - return DECL_RTL (exp); - - case THROW_EXPR: - expand_throw (TREE_OPERAND (exp, 0)); - return NULL; - - case VEC_INIT_EXPR: - return expand_expr - (expand_vec_init - (NULL_TREE, TREE_OPERAND (exp, 0), - build_binary_op (MINUS_EXPR, TREE_OPERAND (exp, 2), - integer_one_node, 1), - TREE_OPERAND (exp, 1), 0), target, tmode, modifier); - - case NEW_EXPR: - return expand_expr (build_new_1 (exp), target, tmode, modifier); - - default: - break; - } - my_friendly_abort (40); - /* NOTREACHED */ - return NULL; -} - -void -init_cplus_expand () -{ - lang_expand_expr = cplus_expand_expr; -} - -/* If DECL had its rtl moved from where callers expect it - to be, fix it up. RESULT is the nominal rtl for the RESULT_DECL, - which may be a pseudo instead of a hard register. */ - -void -fixup_result_decl (decl, result) - tree decl; - rtx result; -{ - if (REG_P (result)) - { - if (REGNO (result) >= FIRST_PSEUDO_REGISTER) - { - rtx real_decl_result; - -#ifdef FUNCTION_OUTGOING_VALUE - real_decl_result - = FUNCTION_OUTGOING_VALUE (TREE_TYPE (decl), current_function_decl); -#else - real_decl_result - = FUNCTION_VALUE (TREE_TYPE (decl), current_function_decl); -#endif - REG_FUNCTION_VALUE_P (real_decl_result) = 1; - result = real_decl_result; - } - store_expr (decl, result, 0); - emit_insn (gen_rtx (USE, VOIDmode, result)); - } -} - -#if 0 -/* Expand this initialization inline and see if it's simple enough that - it can be done at compile-time. */ - -static tree -extract_aggr_init (decl, init) - tree decl, init; -{ - return 0; -} - -static tree -extract_scalar_init (decl, init) - tree decl, init; -{ - rtx value, insns, insn; - extern struct obstack temporary_obstack; - tree t = NULL_TREE; - - push_obstacks (&temporary_obstack, &temporary_obstack); - start_sequence (); - value = expand_expr (init, NULL_RTX, VOIDmode, 0); - insns = get_insns (); - end_sequence (); - reg_scan (insns, max_reg_num (), 0); - jump_optimize (insns, 0, 0, 1); - pop_obstacks (); - - for (insn = insns; insn; insn = NEXT_INSN (insn)) - { - rtx r, to; - - if (GET_CODE (insn) == NOTE) - continue; - else if (GET_CODE (insn) != INSN) - return 0; - - r = PATTERN (insn); - if (GET_CODE (r) != SET) - return 0; - - to = XEXP (r, 0); - - if (! (to == value - || (GET_CODE (to) == SUBREG && XEXP (to, 0) == value))) - return 0; - - r = XEXP (r, 1); - - switch (GET_CODE (r)) - { - case CONST_INT: - t = build_int_2 (XEXP (r, 0), 0); - break; - default: - return 0; - } - } - - return t; -} -#endif - -int -extract_init (decl, init) - tree decl ATTRIBUTE_UNUSED, init ATTRIBUTE_UNUSED; -{ - return 0; - -#if 0 - if (IS_AGGR_TYPE (TREE_TYPE (decl)) - || TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - init = extract_aggr_init (decl, init); - else - init = extract_scalar_init (decl, init); - - if (init == NULL_TREE) - return 0; - - DECL_INITIAL (decl) = init; - return 1; -#endif -} - -void -do_case (start, end) - tree start, end; -{ - tree value1 = NULL_TREE, value2 = NULL_TREE, label; - - if (start != NULL_TREE && TREE_TYPE (start) != NULL_TREE - && POINTER_TYPE_P (TREE_TYPE (start))) - error ("pointers are not permitted as case values"); - - if (end && pedantic) - pedwarn ("ANSI C++ forbids range expressions in switch statement"); - - if (processing_template_decl) - { - add_tree (build_min_nt (CASE_LABEL, start, end)); - return; - } - - if (start) - value1 = check_cp_case_value (start); - if (end) - value2 = check_cp_case_value (end); - - label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - if (value1 != error_mark_node - && value2 != error_mark_node) - { - tree duplicate; - int success; - - if (end) - success = pushcase_range (value1, value2, convert_and_check, - label, &duplicate); - else if (start) - success = pushcase (value1, convert_and_check, label, &duplicate); - else - success = pushcase (NULL_TREE, 0, label, &duplicate); - - if (success == 1) - { - if (end) - error ("case label not within a switch statement"); - else if (start) - cp_error ("case label `%E' not within a switch statement", start); - else - error ("default label not within a switch statement"); - } - else if (success == 2) - { - if (end) - { - error ("duplicate (or overlapping) case value"); - cp_error_at ("this is the first entry overlapping that value", - duplicate); - } - else if (start) - { - cp_error ("duplicate case value `%E'", start); - cp_error_at ("previously used here", duplicate); - } - else - { - error ("multiple default labels in one switch"); - cp_error_at ("this is the first default label", duplicate); - } - } - else if (success == 3) - warning ("case value out of range"); - else if (success == 4) - warning ("empty range specified"); - else if (success == 5) - { - if (end) - error ("case label within scope of cleanup or variable array"); - else if (! start) - error ("`default' label within scope of cleanup or variable array"); - else - cp_error ("case label `%E' within scope of cleanup or variable array", start); - } - } - define_case_label (); -} diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c deleted file mode 100755 index c26d695..0000000 --- a/gcc/cp/friend.c +++ /dev/null @@ -1,490 +0,0 @@ -/* Help friends in C++. - Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" -#include "output.h" -#include "toplev.h" - -static void add_friend PROTO((tree, tree)); -static void add_friends PROTO((tree, tree, tree)); - -/* Friend data structures are described in cp-tree.h. */ - -int -is_friend (type, supplicant) - tree type, supplicant; -{ - int declp; - register tree list; - tree context; - - if (supplicant == NULL_TREE || type == NULL_TREE) - return 0; - - declp = (TREE_CODE_CLASS (TREE_CODE (supplicant)) == 'd'); - - if (declp) - /* It's a function decl. */ - { - tree list = DECL_FRIENDLIST (TYPE_MAIN_DECL (type)); - tree name = DECL_NAME (supplicant); - tree ctype; - - if (DECL_FUNCTION_MEMBER_P (supplicant)) - ctype = DECL_CLASS_CONTEXT (supplicant); - else - ctype = NULL_TREE; - - for (; list ; list = TREE_CHAIN (list)) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - for (; friends ; friends = TREE_CHAIN (friends)) - { - if (same_type_p (ctype, TREE_PURPOSE (friends))) - return 1; - - if (TREE_VALUE (friends) == NULL_TREE) - continue; - - if (supplicant == TREE_VALUE (friends)) - return 1; - - /* With -fguiding-decls we are more lenient about - friendship. This is bogus in general since two - specializations of a template with non-type - template parameters may have the same type, but - be different. - - Temporarily, we are also more lenient to deal - with nested friend functions, for which there can - be more than one FUNCTION_DECL, despite being the - same function. When that's fixed, the - FUNCTION_MEMBER_P bit can go. */ - if ((flag_guiding_decls - || DECL_FUNCTION_MEMBER_P (supplicant)) - && same_type_p (TREE_TYPE (supplicant), - TREE_TYPE (TREE_VALUE (friends)))) - return 1; - - if (TREE_CODE (TREE_VALUE (friends)) == TEMPLATE_DECL - && is_specialization_of (supplicant, - TREE_VALUE (friends))) - return 1; - } - break; - } - } - } - else - /* It's a type. */ - { - if (type == supplicant) - return 1; - - list = CLASSTYPE_FRIEND_CLASSES (TREE_TYPE (TYPE_MAIN_DECL (type))); - for (; list ; list = TREE_CHAIN (list)) - { - tree t = TREE_VALUE (list); - - if (TREE_CODE (t) == TEMPLATE_DECL ? - is_specialization_of (TYPE_MAIN_DECL (supplicant), t) : - same_type_p (supplicant, t)) - return 1; - } - } - - if (declp && DECL_FUNCTION_MEMBER_P (supplicant)) - context = DECL_CLASS_CONTEXT (supplicant); - else if (! declp) - /* Local classes have the same access as the enclosing function. */ - context = hack_decl_function_context (TYPE_MAIN_DECL (supplicant)); - else - context = NULL_TREE; - - /* A namespace is not friend to anybody. */ - if (context && TREE_CODE (context) == NAMESPACE_DECL) - context = NULL_TREE; - - if (context) - return is_friend (type, context); - - return 0; -} - -/* Add a new friend to the friends of the aggregate type TYPE. - DECL is the FUNCTION_DECL of the friend being added. */ - -static void -add_friend (type, decl) - tree type, decl; -{ - tree typedecl = TYPE_MAIN_DECL (type); - tree list = DECL_FRIENDLIST (typedecl); - tree name = DECL_NAME (decl); - - while (list) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - for (; friends ; friends = TREE_CHAIN (friends)) - { - if (decl == TREE_VALUE (friends)) - { - cp_warning ("`%D' is already a friend of class `%T'", - decl, type); - cp_warning_at ("previous friend declaration of `%D'", - TREE_VALUE (friends)); - return; - } - } - TREE_VALUE (list) = tree_cons (error_mark_node, decl, - TREE_VALUE (list)); - return; - } - list = TREE_CHAIN (list); - } - DECL_FRIENDLIST (typedecl) - = tree_cons (DECL_NAME (decl), build_tree_list (error_mark_node, decl), - DECL_FRIENDLIST (typedecl)); - if (DECL_NAME (decl) == ansi_opname[(int) MODIFY_EXPR]) - { - tree parmtypes = TYPE_ARG_TYPES (TREE_TYPE (decl)); - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - if (parmtypes && TREE_CHAIN (parmtypes)) - { - tree parmtype = TREE_VALUE (TREE_CHAIN (parmtypes)); - if (TREE_CODE (parmtype) == REFERENCE_TYPE - && TREE_TYPE (parmtypes) == TREE_TYPE (typedecl)) - TYPE_HAS_ASSIGN_REF (TREE_TYPE (typedecl)) = 1; - } - } -} - -/* Declare that every member function NAME in FRIEND_TYPE - (which may be NULL_TREE) is a friend of type TYPE. */ - -static void -add_friends (type, name, friend_type) - tree type, name, friend_type; -{ - tree typedecl = TYPE_MAIN_DECL (type); - tree list = DECL_FRIENDLIST (typedecl); - - while (list) - { - if (name == TREE_PURPOSE (list)) - { - tree friends = TREE_VALUE (list); - while (friends && TREE_PURPOSE (friends) != friend_type) - friends = TREE_CHAIN (friends); - if (friends) - { - if (friend_type) - warning ("method `%s::%s' is already a friend of class", - TYPE_NAME_STRING (friend_type), - IDENTIFIER_POINTER (name)); - else - warning ("function `%s' is already a friend of class `%s'", - IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (DECL_NAME (typedecl))); - } - else - TREE_VALUE (list) = tree_cons (friend_type, NULL_TREE, - TREE_VALUE (list)); - return; - } - list = TREE_CHAIN (list); - } - DECL_FRIENDLIST (typedecl) - = tree_cons (name, - build_tree_list (friend_type, NULL_TREE), - DECL_FRIENDLIST (typedecl)); - if (! strncmp (IDENTIFIER_POINTER (name), - IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR]), - strlen (IDENTIFIER_POINTER (ansi_opname[(int) MODIFY_EXPR])))) - { - TYPE_HAS_ASSIGNMENT (TREE_TYPE (typedecl)) = 1; - sorry ("declaring \"friend operator =\" will not find \"operator = (X&)\" if it exists"); - } -} - -/* Make FRIEND_TYPE a friend class to TYPE. If FRIEND_TYPE has already - been defined, we make all of its member functions friends of - TYPE. If not, we make it a pending friend, which can later be added - when its definition is seen. If a type is defined, then its TYPE_DECL's - DECL_UNDEFINED_FRIENDS contains a (possibly empty) list of friend - classes that are not defined. If a type has not yet been defined, - then the DECL_WAITING_FRIENDS contains a list of types - waiting to make it their friend. Note that these two can both - be in use at the same time! */ - -void -make_friend_class (type, friend_type) - tree type, friend_type; -{ - tree classes; - int is_template_friend; - - if (IS_SIGNATURE (type)) - { - error ("`friend' declaration in signature definition"); - return; - } - if (IS_SIGNATURE (friend_type) || ! IS_AGGR_TYPE (friend_type)) - { - cp_error ("invalid type `%T' declared `friend'", friend_type); - return; - } - - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (friend_type) - && uses_template_parms (friend_type)) - { - /* [temp.friend] - - Friend declarations shall not declare partial - specializations. */ - cp_error ("partial specialization `%T' declared `friend'", - friend_type); - return; - } - - if (processing_template_decl > template_class_depth (type)) - /* If the TYPE is a template then it makes sense for it to be - friends with itself; this means that each instantiation is - friends with all other instantiations. */ - is_template_friend = 1; - else if (same_type_p (type, friend_type)) - { - pedwarn ("class `%s' is implicitly friends with itself", - TYPE_NAME_STRING (type)); - return; - } - else - is_template_friend = 0; - - GNU_xref_hier (type, friend_type, 0, 0, 1); - - if (is_template_friend) - friend_type = CLASSTYPE_TI_TEMPLATE (friend_type); - - classes = CLASSTYPE_FRIEND_CLASSES (type); - while (classes - /* Stop if we find the same type on the list. */ - && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ? - friend_type == TREE_VALUE (classes) : - same_type_p (TREE_VALUE (classes), friend_type))) - classes = TREE_CHAIN (classes); - if (classes) - cp_warning ("`%T' is already a friend of `%T'", - TREE_VALUE (classes), type); - else - { - CLASSTYPE_FRIEND_CLASSES (type) - = tree_cons (NULL_TREE, friend_type, CLASSTYPE_FRIEND_CLASSES (type)); - } -} - -/* Main friend processor. This is large, and for modularity purposes, - has been removed from grokdeclarator. It returns `void_type_node' - to indicate that something happened, though a FIELD_DECL is - not returned. - - CTYPE is the class this friend belongs to. - - DECLARATOR is the name of the friend. - - DECL is the FUNCTION_DECL that the friend is. - - In case we are parsing a friend which is part of an inline - definition, we will need to store PARM_DECL chain that comes - with it into the DECL_ARGUMENTS slot of the FUNCTION_DECL. - - FLAGS is just used for `grokclassfn'. - - QUALS say what special qualifies should apply to the object - pointed to by `this'. */ - -tree -do_friend (ctype, declarator, decl, parmdecls, flags, quals, funcdef_flag) - tree ctype, declarator, decl, parmdecls; - enum overload_flags flags; - tree quals; - int funcdef_flag; -{ - int is_friend_template = 0; - - /* Every decl that gets here is a friend of something. */ - DECL_FRIEND_P (decl) = 1; - - if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) - { - declarator = TREE_OPERAND (declarator, 0); - if (TREE_CODE (declarator) == LOOKUP_EXPR) - declarator = TREE_OPERAND (declarator, 0); - if (is_overloaded_fn (declarator)) - declarator = DECL_NAME (get_first_fn (declarator)); - } - - if (TREE_CODE (decl) == FUNCTION_DECL) - is_friend_template = PROCESSING_REAL_TEMPLATE_DECL_P (); - - if (ctype) - { - tree cname = TYPE_NAME (ctype); - if (TREE_CODE (cname) == TYPE_DECL) - cname = DECL_NAME (cname); - - /* A method friend. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - if (flags == NO_SPECIAL && ctype && declarator == cname) - DECL_CONSTRUCTOR_P (decl) = 1; - - /* This will set up DECL_ARGUMENTS for us. */ - grokclassfn (ctype, decl, flags, quals); - - if (is_friend_template) - decl = DECL_TI_TEMPLATE (push_template_decl (decl)); - else if (template_class_depth (current_class_type)) - decl = push_template_decl_real (decl, /*is_friend=*/1); - - /* We can't do lookup in a type that involves template - parameters. Instead, we rely on tsubst_friend_function - to check the validity of the declaration later. */ - if (uses_template_parms (ctype)) - add_friend (current_class_type, decl); - /* A nested class may declare a member of an enclosing class - to be a friend, so we do lookup here even if CTYPE is in - the process of being defined. */ - else if (TYPE_SIZE (ctype) != 0 || TYPE_BEING_DEFINED (ctype)) - { - decl = check_classfn (ctype, decl); - - if (decl) - add_friend (current_class_type, decl); - } - else - cp_error ("member `%D' declared as friend before type `%T' defined", - decl, ctype); - } - else - { - /* Possibly a bunch of method friends. */ - - /* Get the class they belong to. */ - tree ctype = IDENTIFIER_TYPE_VALUE (cname); - tree fields = lookup_fnfields (TYPE_BINFO (ctype), declarator, 0); - - if (fields) - add_friends (current_class_type, declarator, ctype); - else - cp_error ("method `%D' is not a member of class `%T'", - declarator, ctype); - decl = void_type_node; - } - } - /* A global friend. - @@ or possibly a friend from a base class ?!? */ - else if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Friends must all go through the overload machinery, - even though they may not technically be overloaded. - - Note that because classes all wind up being top-level - in their scope, their friend wind up in top-level scope as well. */ - DECL_ARGUMENTS (decl) = parmdecls; - if (funcdef_flag) - DECL_CLASS_CONTEXT (decl) = current_class_type; - - if (! DECL_USE_TEMPLATE (decl)) - { - /* We can call pushdecl here, because the TREE_CHAIN of this - FUNCTION_DECL is not needed for other purposes. Don't do - this for a template instantiation. However, we don't - call pushdecl() for a friend function of a template - class, since in general, such a declaration depends on - template parameters. Instead, we call pushdecl when the - class is instantiated. */ - if (!is_friend_template - && template_class_depth (current_class_type) == 0) - decl = pushdecl (decl); - else - decl = push_template_decl_real (decl, /*is_friend=*/1); - - if (warn_nontemplate_friend - && ! funcdef_flag && ! flag_guiding_decls && ! is_friend_template - && current_template_parms && uses_template_parms (decl)) - { - static int explained; - cp_warning ("friend declaration `%#D'", decl); - warning (" declares a non-template function"); - if (! explained) - { - warning (" (if this is not what you intended, make sure"); - warning (" the function template has already been declared,"); - warning (" and add <> after the function name here)"); - warning (" -Wno-non-template-friend disables this warning."); - explained = 1; - } - } - } - - make_decl_rtl (decl, NULL_PTR, 1); - add_friend (current_class_type, - is_friend_template ? DECL_TI_TEMPLATE (decl) : decl); - DECL_FRIEND_P (decl) = 1; - } - else - { - /* @@ Should be able to ingest later definitions of this function - before use. */ - tree decl = lookup_name_nonclass (declarator); - if (decl == NULL_TREE) - { - cp_warning ("implicitly declaring `%T' as struct", declarator); - decl = xref_tag (record_type_node, declarator, 1); - decl = TYPE_MAIN_DECL (decl); - } - - /* Allow abbreviated declarations of overloaded functions, - but not if those functions are really class names. */ - if (TREE_CODE (decl) == TREE_LIST && TREE_TYPE (TREE_PURPOSE (decl))) - { - cp_warning ("`friend %T' archaic, use `friend class %T' instead", - declarator, declarator); - decl = TREE_TYPE (TREE_PURPOSE (decl)); - } - - if (TREE_CODE (decl) == TREE_LIST) - add_friends (current_class_type, TREE_PURPOSE (decl), NULL_TREE); - else - make_friend_class (current_class_type, TREE_TYPE (decl)); - decl = void_type_node; - } - return decl; -} diff --git a/gcc/cp/g++.1 b/gcc/cp/g++.1 deleted file mode 100755 index 5101d5f..0000000 --- a/gcc/cp/g++.1 +++ /dev/null @@ -1,642 +0,0 @@ -.\" Copyright (c) 1991, 1992 Free Software Foundation -*-Text-*- -.\" See section COPYING for conditions for redistribution -.\" FIXME: no info here on predefines. Should there be? extra for C++... -.TH G++ 1 "30apr1993" "GNU Tools" "GNU Tools" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -g++ \- GNU project C++ Compiler -.SH SYNOPSIS -.RB g++ " [" \c -.IR option " | " filename " ].\|.\|. -.SH DESCRIPTION -The C and C++ compilers are integrated; -.B g++ -is a script to call -.B gcc with options to recognize C++. -.B gcc -processes input files -through one or more of four stages: preprocessing, compilation, -assembly, and linking. This man page contains full descriptions for -.I only -C++ specific aspects of the compiler, though it also contains -summaries of some general-purpose options. For a fuller explanation -of the compiler, see -.BR gcc ( 1 ). - -C++ source files use one of the suffixes `\|\c -.B .C\c -\&\|', `\|\c -.B .cc\c -\&\|', `\|\c -.B .cxx\c -\&\|', `\|\c -.B .cpp\c -\&\|', or `\|\c -.B .c++\c -\&\|'; preprocessed C++ files use the suffix `\|\c -.B .ii\c -\&\|'. -.SH OPTIONS -There are many command-line options, including options to control -details of optimization, warnings, and code generation, which are -common to both -.B gcc -and -.B g++\c -\&. For full information on all options, see -.BR gcc ( 1 ). - -Options must be separate: `\|\c -.B \-dr\c -\&\|' is quite different from `\|\c -.B \-d \-r -\&\|'. - -Most `\|\c -.B \-f\c -\&\|' and `\|\c -.B \-W\c -\&\|' options have two contrary forms: -.BI \-f name -and -.BI \-fno\- name\c -\& (or -.BI \-W name -and -.BI \-Wno\- name\c -\&). Only the non-default forms are shown here. - -.TP -.B \-c -Compile or assemble the source files, but do not link. The compiler -output is an object file corresponding to each source file. -.TP -.BI \-D macro -Define macro \c -.I macro\c -\& with the string `\|\c -.B 1\c -\&\|' as its definition. -.TP -.BI \-D macro = defn -Define macro \c -.I macro\c -\& as \c -.I defn\c -\&. -.TP -.B \-E -Stop after the preprocessing stage; do not run the compiler proper. The -output is preprocessed source code, which is sent to the -standard output. -.TP -.B \-fall\-virtual -Treat all possible member functions as virtual, implicitly. All -member functions (except for constructor functions and -.B new -or -.B delete -member operators) are treated as virtual functions of the class where -they appear. - -This does not mean that all calls to these member functions will be -made through the internal table of virtual functions. Under some -circumstances, the compiler can determine that a call to a given -virtual function can be made directly; in these cases the calls are -direct in any case. -.TP -.B \-fdollars\-in\-identifiers -Permit the use of `\|\c -.B $\c -\&\|' in identifiers. -Traditional C allowed the character `\|\c -.B $\c -\&\|' to form part of identifiers; by default, GNU C also -allows this. However, ANSI C forbids `\|\c -.B $\c -\&\|' in identifiers, and GNU C++ also forbids it by default on most -platforms (though on some platforms it's enabled by default for GNU -C++ as well). -.TP -.B \-felide\-constructors -Use this option to instruct the compiler to be smarter about when it can -elide constructors. Without this flag, GNU C++ and cfront both -generate effectively the same code for: -.sp -.br -A\ foo\ (); -.br -A\ x\ (foo\ ());\ \ \ //\ x\ initialized\ by\ `foo\ ()',\ no\ ctor\ called -.br -A\ y\ =\ foo\ ();\ \ \ //\ call\ to\ `foo\ ()'\ heads\ to\ temporary, -.br -\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ //\ y\ is\ initialized\ from\ the\ temporary. -.br -.sp -Note the difference! With this flag, GNU C++ initializes `\|\c -.B y\c -\&\|' directly -from the call to -.B foo () -without going through a temporary. -.TP -.B \-fenum\-int\-equiv -Normally GNU C++ allows conversion of -.B enum -to -.B int\c -\&, but not the other way around. Use this option if you want GNU C++ -to allow conversion of -.B int -to -.B enum -as well. -.TP -.B \-fexternal\-templates -Produce smaller code for template declarations, by generating only a -single copy of each template function where it is defined. -To use this option successfully, you must also mark all files that -use templates with either `\|\c -.B #pragma implementation\c -\&\|' (the definition) or -`\|\c -.B #pragma interface\c -\&\|' (declarations). - -When your code is compiled with `\|\c -.B \-fexternal\-templates\c -\&\|', all -template instantiations are external. You must arrange for all -necessary instantiations to appear in the implementation file; you can -do this with a \c -.B typedef\c -\& that references each instantiation needed. -Conversely, when you compile using the default option -`\|\c -.B \-fno\-external\-templates\c -\&\|', all template instantiations are -explicitly internal. -.TP -.B \-fno\-gnu\-linker -Do not output global initializations (such as C++ constructors and -destructors) in the form used by the GNU linker (on systems where the GNU -linker is the standard method of handling them). Use this option when -you want to use a non-GNU linker, which also requires using the -.B collect2 -program to make sure the system linker includes -constructors and destructors. (\c -.B collect2 -is included in the GNU CC distribution.) For systems which -.I must -use -.B collect2\c -\&, the compiler driver -.B gcc -is configured to do this automatically. -.TP -.B \-fmemoize\-lookups -.TP -.B \-fsave\-memoized -These flags are used to get the compiler to compile programs faster -using heuristics. They are not on by default since they are only effective -about half the time. The other half of the time programs compile more -slowly (and take more memory). - -The first time the compiler must build a call to a member function (or -reference to a data member), it must (1) determine whether the class -implements member functions of that name; (2) resolve which member -function to call (which involves figuring out what sorts of type -conversions need to be made); and (3) check the visibility of the member -function to the caller. All of this adds up to slower compilation. -Normally, the second time a call is made to that member function (or -reference to that data member), it must go through the same lengthy -process again. This means that code like this -.sp -.br -\ \ cout\ <<\ "This\ "\ <<\ p\ <<\ "\ has\ "\ <<\ n\ <<\ "\ legs.\en"; -.br -.sp -makes six passes through all three steps. By using a software cache, -a ``hit'' significantly reduces this cost. Unfortunately, using the -cache introduces another layer of mechanisms which must be implemented, -and so incurs its own overhead. `\|\c -.B \-fmemoize\-lookups\c -\&\|' enables -the software cache. - -Because access privileges (visibility) to members and member functions -may differ from one function context to the next, -.B g++ -may need to flush the cache. With the `\|\c -.B \-fmemoize\-lookups\c -\&\|' flag, the cache is flushed after every -function that is compiled. The `\|\c -\-fsave\-memoized\c -\&\|' flag enables the same software cache, but when the compiler -determines that the context of the last function compiled would yield -the same access privileges of the next function to compile, it -preserves the cache. -This is most helpful when defining many member functions for the same -class: with the exception of member functions which are friends of -other classes, each member function has exactly the same access -privileges as every other, and the cache need not be flushed. -.TP -.B \-fno\-default\-inline -Do not make member functions inline by default merely because they are -defined inside the class scope. Otherwise, when you specify -.B \-O\c -\&, member functions defined inside class scope are compiled -inline by default; i.e., you don't need to add `\|\c -.B inline\c -\&\|' in front of -the member function name. -.TP -.B \-fno\-strict\-prototype -Consider the declaration \c -.B int foo ();\c -\&. In C++, this means that the -function \c -.B foo\c -\& takes no arguments. In ANSI C, this is declared -.B int foo(void);\c -\&. With the flag `\|\c -.B \-fno\-strict\-prototype\c -\&\|', -declaring functions with no arguments is equivalent to declaring its -argument list to be untyped, i.e., \c -.B int foo ();\c -\& is equivalent to -saying \c -.B int foo (...);\c -\&. -.TP -.B \-fnonnull\-objects -Normally, GNU C++ makes conservative assumptions about objects reached -through references. For example, the compiler must check that `\|\c -.B a\c -\&\|' is not null in code like the following: -.br -\ \ \ \ obj\ &a\ =\ g\ (); -.br -\ \ \ \ a.f\ (2); -.br -Checking that references of this sort have non-null values requires -extra code, however, and it is unnecessary for many programs. You can -use `\|\c -.B \-fnonnull\-objects\c -\&\|' to omit the checks for null, if your program doesn't require the -default checking. -.TP -.B \-fhandle\-signatures -.TP -.B \-fno\-handle\-signatures -These options control the recognition of the \c -.B signature\c -\& and \c -.B sigof\c -\& constructs for specifying abstract types. By default, these -constructs are not recognized. -.TP -.B \-fthis\-is\-variable -The incorporation of user-defined free store management into C++ has -made assignment to \c -.B this\c -\& an anachronism. Therefore, by default GNU -C++ treats the type of \c -.B this\c -\& in a member function of \c -.B class X\c -\& -to be \c -.B X *const\c -\&. In other words, it is illegal to assign to -\c -.B this\c -\& within a class member function. However, for backwards -compatibility, you can invoke the old behavior by using -\&`\|\c -.B \-fthis\-is\-variable\c -\&\|'. -.TP -.B \-g -Produce debugging information in the operating system's native format -(for DBX or SDB or DWARF). GDB also can work with this debugging -information. On most systems that use DBX format, `\|\c -.B \-g\c -\&\|' enables use -of extra debugging information that only GDB can use. - -Unlike most other C compilers, GNU CC allows you to use `\|\c -.B \-g\c -\&\|' with -`\|\c -.B \-O\c -\&\|'. The shortcuts taken by optimized code may occasionally -produce surprising results: some variables you declared may not exist -at all; flow of control may briefly move where you did not expect it; -some statements may not be executed because they compute constant -results or their values were already at hand; some statements may -execute in different places because they were moved out of loops. - -Nevertheless it proves possible to debug optimized output. This makes -it reasonable to use the optimizer for programs that might have bugs. -.TP -.BI "\-I" "dir"\c -\& -Append directory \c -.I dir\c -\& to the list of directories searched for include files. -.TP -.BI "\-L" "dir"\c -\& -Add directory \c -.I dir\c -\& to the list of directories to be searched -for `\|\c -.B \-l\c -\&\|'. -.TP -.BI \-l library\c -\& -Use the library named \c -.I library\c -\& when linking. (C++ programs often require `\|\c -\-lg++\c -\&\|' for successful linking.) -.TP -.B \-nostdinc -Do not search the standard system directories for header files. Only -the directories you have specified with -.B \-I -options (and the current directory, if appropriate) are searched. -.TP -.B \-nostdinc++ -Do not search for header files in the standard directories specific to -C++, but do still search the other standard directories. (This option -is used when building libg++.) -.TP -.B \-O -Optimize. Optimizing compilation takes somewhat more time, and a lot -more memory for a large function. -.TP -.BI "\-o " file\c -\& -Place output in file \c -.I file\c -\&. -.TP -.B \-S -Stop after the stage of compilation proper; do not assemble. The output -is an assembler code file for each non-assembler input -file specified. -.TP -.B \-traditional -Attempt to support some aspects of traditional C compilers. - -Specifically, for both C and C++ programs: -.TP -\ \ \ \(bu -In the preprocessor, comments convert to nothing at all, rather than -to a space. This allows traditional token concatenation. -.TP -\ \ \ \(bu -In the preprocessor, macro arguments are recognized within string -constants in a macro definition (and their values are stringified, -though without additional quote marks, when they appear in such a -context). The preprocessor always considers a string constant to end -at a newline. -.TP -\ \ \ \(bu -The preprocessor does not predefine the macro \c -.B __STDC__\c -\& when you use -`\|\c -.B \-traditional\c -\&\|', but still predefines\c -.B __GNUC__\c -\& (since the GNU extensions indicated by -.B __GNUC__\c -\& are not affected by -`\|\c -.B \-traditional\c -\&\|'). If you need to write header files that work -differently depending on whether `\|\c -.B \-traditional\c -\&\|' is in use, by -testing both of these predefined macros you can distinguish four -situations: GNU C, traditional GNU C, other ANSI C compilers, and -other old C compilers. -.PP -.TP -\ \ \ \(bu -String ``constants'' are not necessarily constant; they are stored in -writable space, and identical looking constants are allocated -separately. - -For C++ programs only (not C), `\|\c -.B \-traditional\c -\&\|' has one additional effect: assignment to -.B this -is permitted. This is the same as the effect of `\|\c -.B \-fthis\-is\-variable\c -\&\|'. -.TP -.BI \-U macro -Undefine macro \c -.I macro\c -\&. -.TP -.B \-Wall -Issue warnings for conditions which pertain to usage that we recommend -avoiding and that we believe is easy to avoid, even in conjunction -with macros. -.TP -.B \-Wenum\-clash -Warn when converting between different enumeration types. -.TP -.B \-Woverloaded\-virtual -In a derived class, the definitions of virtual functions must match -the type signature of a virtual function declared in the base class. -Use this option to request warnings when a derived class declares a -function that may be an erroneous attempt to define a virtual -function: that is, warn when a function with the same name as a -virtual function in the base class, but with a type signature that -doesn't match any virtual functions from the base class. -.TP -.B \-Wtemplate\-debugging -When using templates in a C++ program, warn if debugging is not yet -fully available. -.TP -.B \-w -Inhibit all warning messages. -.TP -.BI +e N -Control how virtual function definitions are used, in a fashion -compatible with -.B cfront -1.x. -.PP - -.SH PRAGMAS -Two `\|\c -.B #pragma\c -\&\|' directives are supported for GNU C++, to permit using the same -header file for two purposes: as a definition of interfaces to a given -object class, and as the full definition of the contents of that object class. -.TP -.B #pragma interface -Use this directive in header files that define object classes, to save -space in most of the object files that use those classes. Normally, -local copies of certain information (backup copies of inline member -functions, debugging information, and the internal tables that -implement virtual functions) must be kept in each object file that -includes class definitions. You can use this pragma to avoid such -duplication. When a header file containing `\|\c -.B #pragma interface\c -\&\|' is included in a compilation, this auxiliary information -will not be generated (unless the main input source file itself uses -`\|\c -.B #pragma implementation\c -\&\|'). Instead, the object files will contain references to be -resolved at link time. -.tr !" -.TP -.B #pragma implementation -.TP -.BI "#pragma implementation !" objects .h! -Use this pragma in a main input file, when you want full output from -included header files to be generated (and made globally visible). -The included header file, in turn, should use `\|\c -.B #pragma interface\c -\&\|'. -Backup copies of inline member functions, debugging information, and -the internal tables used to implement virtual functions are all -generated in implementation files. - -If you use `\|\c -.B #pragma implementation\c -\&\|' with no argument, it applies to an include file with the same -basename as your source file; for example, in `\|\c -.B allclass.cc\c -\&\|', `\|\c -.B #pragma implementation\c -\&\|' by itself is equivalent to `\|\c -.B -#pragma implementation "allclass.h"\c -\&\|'. Use the string argument if you want a single implementation -file to include code from multiple header files. - -There is no way to split up the contents of a single header file into -multiple implementation files. -.SH FILES -.ta \w'LIBDIR/g++\-include 'u -file.h C header (preprocessor) file -.br -file.i preprocessed C source file -.br -file.C C++ source file -.br -file.cc C++ source file -.br -file.cxx C++ source file -.br -file.s assembly language file -.br -file.o object file -.br -a.out link edited output -.br -\fITMPDIR\fR/cc\(** temporary files -.br -\fILIBDIR\fR/cpp preprocessor -.br -\fILIBDIR\fR/cc1plus compiler -.br -\fILIBDIR\fR/collect linker front end needed on some machines -.br -\fILIBDIR\fR/libgcc.a GCC subroutine library -.br -/lib/crt[01n].o start-up routine -.br -\fILIBDIR\fR/ccrt0 additional start-up routine for C++ -.br -/lib/libc.a standard C library, see -.IR intro (3) -.br -/usr/include standard directory for -.B #include -files -.br -\fILIBDIR\fR/include standard gcc directory for -.B #include -files -.br -\fILIBDIR\fR/g++\-include additional g++ directory for -.B #include -.sp -.I LIBDIR -is usually -.B /usr/local/lib/\c -.IR machine / version . -.br -.I TMPDIR -comes from the environment variable -.B TMPDIR -(default -.B /usr/tmp -if available, else -.B /tmp\c -\&). -.SH "SEE ALSO" -gcc(1), cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). -.br -.RB "`\|" gcc "\|', `\|" cpp \|', -.RB `\| as \|', `\| ld \|', -and -.RB `\| gdb \|' -entries in -.B info\c -\&. -.br -.I -Using and Porting GNU CC (for version 2.0)\c -, Richard M. Stallman; -.I -The C Preprocessor\c -, Richard M. Stallman; -.I -Debugging with GDB: the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch; -.I -Using as: the GNU Assembler\c -, Dean Elsner, Jay Fenlason & friends; -.I -gld: the GNU linker\c -, Steve Chamberlain and Roland Pesch. - -.SH BUGS -For instructions on how to report bugs, see the GCC manual. - -.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. -.SH AUTHORS -See the GNU CC Manual for the contributors to GNU CC. diff --git a/gcc/cp/g++FAQ.texi b/gcc/cp/g++FAQ.texi deleted file mode 100755 index 3cbec50..0000000 --- a/gcc/cp/g++FAQ.texi +++ /dev/null @@ -1,2423 +0,0 @@ -\input texinfo.tex @c -*-texinfo-*- -@c %**start of header -@setfilename g++FAQ.info -@settitle Frequently asked questions about the GNU C++ compiler -@setchapternewpage off -@c version: %W% %G% -@c %**end of header - -@iftex -@finalout -@end iftex -@titlepage -@title G++ FAQ -@subtitle Frequently asked questions about the GNU C++ compiler -@subtitle June 8, 1998 -@sp 1 -@author Joe Buck -@page -@end titlepage - -@ifinfo -@node Top, basics, (dir), (dir) -@top -@unnumbered FAQ for g++ and libg++, by Joe Buck (jbuck@@synopsys.com) -@end ifinfo - -@cindex FAQ for g++, latest version -@cindex Archive site for FAQ lists -@cindex rtfm.mit.edu -@cindex Joe Buck <jbuck@@synopsys.com> -@cindex FAQ for C++ - -This is a list of frequently asked questions (FAQ) for g++ users; thanks to -all those who sent suggestions for improvements. Thanks to Marcus Speh -for doing the index. A hypertext version is available on the World Wide -Web at @file{http://www.cygnus.com/misc/g++FAQ_toc.html}. - -Please send updates and corrections to the FAQ to -@code{jbuck@@synopsys.com}. Please do @emph{not} use me as a resource -to get your questions answered; that's what @file{gnu.g++.help} is for and I -don't have the time to support the net's use of g++. If you ignore this -request your message to me may be deleted without a reply. Sorry. - -Many FAQs, including this one, are available on the archive site -``rtfm.mit.edu''; see @* -@file{ftp://rtfm.mit.edu/pub/usenet/news.answers}. -This FAQ may be found in the subdirectory g++-FAQ. - -@cindex Marshall Cline -@cindex comp.lang.c++ -@cindex C++ FAQ -This FAQ is intended to supplement, not replace, Marshall Cline's -excellent FAQ for the C++ language and for the newsgroup -@file{comp.lang.c++}. Especially if g++ is the first C++ -compiler you've ever used, the question ``How do I do <X> with g++?'' -is probably really ``How do I do <X> in C++?''. -You can find this FAQ at -@file{ftp://rtfm.mit.edu/pub/usenet/comp.lang.c++}, -or in HTML form at @file{http://www.cerfnet.com/~mpcline/On-Line-C++-FAQs/}. - -@menu -* basics:: What is g++? How do I get it? -* egcs and 2.8.x:: The next generation(s) of g++ -* installation:: How to install, installation problems -* evolution:: The Evolution of g++ -* User Problems:: Commonly reported problems and bugs -* legalities:: Lawyer stuff, GPL, LGPL, etc. -* index:: Index of terms - - --- The Detailed Node Listing --- - -The basics: what is g++? - -* latest versions:: What are the latest versions of g++ and libraries? -* g++ for Unix:: How do I get g++ for Unix? -* getting-egcs:: How do I get egcs? -* g++ for HP:: -* g++ for Solaris 2.x:: -* g++ for other platforms:: -* 1.x vs 2.x versions:: - -The Next Generation(s) of g++ - -* new-in-2.8.x:: What's new in gcc 2.8.x? -* egcs-intro:: What is egcs? -* egcs-whats-new:: What's new in egcs vs 2.7.2? -* egcs-bug-fixes:: What was fixed in the latest egcs releases? -* egcs-linux:: If I install on Linux, will it overwrite my libraries? -* egcs-run-both:: How can I run both egcs and an FSF release? -* egcs-vs-2.8.x:: How will egcs affect 2.8.x? -* egcs-robustness:: How robust is egcs? - -Installation Issues and Problems - -* gcc-2 + g++-1:: -* what else do I need?:: -* use GNU linker?:: -* Use GNU assembler?:: -* shared libraries:: -* repository:: -* repo bugs:: -* Use GNU C library?:: -* Global constructor problems:: -* Strange assembler errors:: -* Other problems building libg++:: -* More size_t problems:: -* Rebuild libg++?:: -* co-existing versions:: -* Installing on Linux:: -* Linux Slackware 3.0:: - -The Evolution of g++ - -* version 2.7.x:: What's changed in 2.7.x from earlier versions -* libstdc++:: - -User Problems - -* missing virtual table:: -* for scope:: -* const constructor:: -* unused parameter warnings:: -* jump crosses initialization:: -* Demangler:: -* static data members:: -* internal compiler error:: -* bug reports:: -* porting to g++:: -* name mangling:: -* problems linking with other libraries:: -* documentation:: -* templates:: -* undefined templates:: -* redundant templates:: -* Standard Template Library:: -* STL and string:: -* exceptions:: -* namespaces:: -* agreement with standards:: -* compiling standard libraries:: -* debugging on SVR4 systems:: -* debugging problems on Solaris:: -* X11 conflicts with libg++:: -* assignment to streams:: -@end menu - -@node basics, egcs and 2.8.x, Top, Top -@chapter The basics: what is g++? - -@cindex Free Software Foundation -@cindex GNU Public License -@cindex GPL - -g++ is the traditional nickname of GNU C++, a freely redistributable -C++ compiler produced by the Free Software Foundation plus dozens of -skilled volunteers. I say ``traditional nickname'' because the GNU -compiler suite, gcc, bundles together compilers for C, Objective-C, -and C++ in one package. - -While the source code to gcc/g++ can be downloaded for free, -it is not public domain, but is protected by the GNU Public License, -or GPL (@pxref{legalities}). - -@menu -* latest versions:: What is the latest version of gcc/g++/libg++? -* g++ for Unix:: How do I get a copy of g++ for Unix? -* getting-egcs:: How do I get egcs? -* g++ for HP:: Getting g++ for the HP precision architecture -* g++ for Solaris 2.x:: Getting g++ for Solaris -* g++ for other platforms:: -* 1.x vs 2.x versions:: -@end menu - -@node latest versions, g++ for Unix, basics, basics -@section What is the latest version of gcc, g++, and libg++? - -@cindex egcs release - -The newest release from the egcs project (on the Web: -@file{http://www.cygnus.com/egcs/}) is egcs-1.0.3, released May 15, -1998. - -@cindex gcc/g++, version date -The current version of gcc/g++ is 2.8.1, released March 4, 1998. -This release fixes some bugs in the 2.8.x release from January. -It is a huge improvement over the 2.7.x releases. - -libg++ has now been deprecated (that is, it is no longer really -supported), so gcc2.8.1 users need to grab libstdc++-2.8.1 from -their favorite GNU site (egcs users don't need to get this separately -as it is bundled with egcs). However, there is an 'add-on' libg++ 2.8.1 -mini-release. If you want to use it, you need to combine it with -libstdc++ 2.8.1. - -I would strongly recommend that anyone using a g++ version earlier -than 2.7.2 should upgrade if at all possible (@pxref{version 2.7.x}). -Folks who need modern C++ features should upgrade to 2.8.1 or egcs. - -For some non-Unix platforms, the latest port of gcc may be an earlier -version (2.7.2, say). You'll need to use a version of libg++ that -has the same first two digits as the compiler version, e.g. use libg++ -2.7.x (for the latest x you can find) with gcc version 2.7.2.1. - -From version 2.8.0 on, you don't need libg++, you only need libstdc++ -(again, the latest version with the same two leading digits as the -version of g++ you use). - -The latest "1.x" version of gcc is 1.42, and the latest "1.x" version of -g++ is 1.42.0. -While gcc 1.42 is quite usable for C programs, g++ 1.x is only of -historical interest (since the C++ language has changed so much). - -@node g++ for Unix, getting-egcs, latest versions, basics -@section How do I get a copy of g++ for Unix? - -First, you may already have it if you have gcc for your platform; -g++ and gcc are combined now (as of gcc version 2.0). -@cindex GNU gcc, version -@cindex GNU g++ and gcc - -You can get g++ from a friend who has a copy, by anonymous FTP or -UUCP, or by ordering a tape or CD-ROM from the Free Software -Foundation. -@cindex g++, ordering -@cindex g++, getting a copy - -The Free Software Foundation is a nonprofit organization that -distributes software and manuals to raise funds for more GNU -development. Getting your copy from the FSF contributes directly to -paying staff to develop GNU software. CD-ROMs cost $400 if an -organization is buying, or $100 if an individual is buying. Tapes -cost around $200 depending on media type. I recommend asking for -version 2, not version 1, of g++. -@cindex FSF [Free Software Foundation] -@cindex GNU [GNU's not unix] - -For more information about ordering from the FSF, contact -gnu@@prep.ai.mit.edu, phone (617) 542-5942 or anonymous ftp file -@file{ftp://prep.ai.mit.edu/pub/gnu/GNUinfo/ORDERS} (you can -also use one of the sites listed below if you can't get into ``prep''). - -@cindex FSF, contact <gnu@@prep.ai.mit.edu> - -Here is a list of anonymous FTP archive sites for GNU software. -If no directory is given, look in @file{/pub/gnu}. - -@cindex GNUware, anonymous FTP sites - -@example -ASIA: ftp.cs.titech.ac.jp, tron.um.u-tokyo.ac.jp:/pub/GNU/prep -cair-archive.kaist.ac.kr, ftp.nectec.or.th:/pub/mirrors/gnu - -AUSTRALIA: archie.au:/gnu (archie.oz or archie.oz.au for ACSnet) - -AFRICA: ftp.sun.ac.za - -MIDDLE-EAST: ftp.technion.ac.il:/pub/unsupported/gnu - -EUROPE: irisa.irisa.fr, ftp.univ-lyon1.fr, -ftp.mcc.ac.uk, unix.hensa.ac.uk:/mirrors/uunet/systems/gnu, -src.doc.ic.ac.uk:/gnu, ftp.ieunet.ie, ftp.eunet.ch, -nic.switch.ch:/mirror/gnu, ftp.informatik.rwth-aachen.de, -ftp.informatik.tu-muenchen.de, ftp.win.tue.nl, ftp.nl.net, -ftp.etsimo.uniovi.es, ftp.funet.fi, ftp.denet.dk, -ftp.stacken.kth.se, isy.liu.se, ftp.luth.se:/pub/unix/gnu, -ftp.sunet.se, archive.eu.net - -SOUTH AMERICA: ftp.inf.utfsm.cl, ftp.unicamp.br - -WESTERN CANADA: ftp.cs.ubc.ca:/mirror2/gnu - -USA: wuarchive.wustl.edu:/systems/gnu, labrea.stanford.edu, -ftp.digex.net, ftp.kpc.com:/pub/mirror/gnu, f.ms.uky.edu:/pub3/gnu, -jaguar.utah.edu:/gnustuff, ftp.hawaii.edu:/mirrors/gnu, -uiarchive.cso.uiuc.edu, ftp.cs.columbia.edu:/archives/gnu/prep, -gatekeeper.dec.com:/pub/GNU, ftp.uu.net:/systems/gnu -@end example - -The ``official site'' is prep.ai.mit.edu, but your transfer will probably -go faster if you use one of the above machines. - -@cindex gzip -Most GNU utilities are compressed with ``gzip'', the GNU compression -utility. All GNU archive sites should have a copy of this program, -which you will need to uncompress the distributions. - -@cindex libstdc++ -Don't forget to retrieve libstdc++ as well! - -@node getting-egcs, g++ for HP, g++ for Unix, basics -@section How do I get egcs? - -See @xref{egcs-intro} to find out what egcs is. - -You can obtain egcs either by FTP or with a Web browser. To do the -latter, start from @file{http://egcs.cygnus.com/}. The master -FTP site is @file{ftp://ftp.cygnus.com/pub/egcs/releases}, however -you'll probably get a faster download if you use a mirror site. -Mirror sites also have egcs snapshots unless otherwise noted. -@itemize @bullet -@item -US (west coast): @file{ftp://go.cygnus.com/pub/ftp.cygnus.com/egcs/} -@item -US (east coast): @file{ftp://ftp.goof.com/pub/pcg/egcs/} -or (for releases only): @file{ftp://cambridge.cygnus.com/pub/egcs/} -@item -US (Arizona): @file{ftp://ftp.ninemoons.com/pub/mirrors/egcs/} -@item -UK: @file{ftp://sunsite.doc.ic.ac.uk/Mirrors/egcs.cygnus.com/pub/egcs/} -@item -Austria: @file{ftp://gd.tuwien.ac.at/gnu/egcs} -@item -France: @file{ftp://ftp.ilog.fr/pub/mirrors/egcs/} or -@file{ftp://ftp.lip6.fr/pub/egcs} -@item -Czech Republic: @file{ftp://sunsite.mff.cuni.cz/pub/GNU/egcs/} -@item -Denmark: @file{ftp://sunsite.auc.dk/pub/egcs/} -@item -Germany @file{ftp://ftp.fu-berlin.de/unix/languages/egcs/} or -@file{ftp://ftp.gwdg.de/pub/cygnus/egcs/} -@item -Poland: @file{ftp://sunsite.icm.edu.pl/pub/programming/egcs/} -@item -Sweden: @file{ftp://ftp.sunet.se/pub/gnu/egcs/} -@item -Brasil (releases only, no snapshots): -@file{ftp://ftp.unicamp.br/pub/gnu/=EXTRA=/cygnus/egcs/} -@item -Portugal: @file{ftp://ftp.lca.uevora.pt/pub/egcs/} -@item -Romania: @file{ftp://ftp.lbi.ro/pub/egcs/} -@item -Australia/NZ (release only): @file{ftp://moshpit.cygnus.com/pub/egcs/} -@end itemize - -@node g++ for HP, g++ for Solaris 2.x, getting-egcs, basics -@section Getting gcc/g++ for the HP Precision Architecture - -@cindex HP Precision Architecture -@cindex Hewlett-Packard -@cindex GNU GAS -@cindex GNU gdb - -If you use the HP Precision Architecture (HP-9000/7xx and HP-9000/8xx) -and you want to use debugging, you'll need to use the GNU assembler, GAS -(version 2.3 or later). If you build from source, you must tell the -configure program that you are using GAS or you won't get debugging -support. A non-standard debug format is used, since until recently HP -considered their debug format a trade secret. Thanks to the work of -lots of good folks both inside and outside HP, the company has seen the -error of its ways and has now released the required information. The -team at the University of Utah that did the gcc port now has code that -understands the native HP format. - -There are binaries for GNU tools in -@file{ftp://jaguar.cs.utah.edu/dist/}, -but these are older versions. - -Jeff Law has left the University of Utah, so the Utah prebuilt -binaries may be discontinued. - -@node g++ for Solaris 2.x, g++ for other platforms, g++ for HP, basics -@section Getting gcc/g++ binaries for Solaris 2.x - -``Sun took the C compiler out of Solaris 2.x. Am I stuck?'' - -@cindex Solaris -@cindex gcc/g++ binaries for Solaris - -You can obtain and install prebuilt binaries of gcc. - - -@cindex Solaris pkgadd utility -The WWW site @file{http://smc.vnet.net/} -contains various -GNU and freeware programs for Solaris 2.5 or 2.6, for either the Sparc -or Intel platforms. These are -packaged to enable easy installation using the Solaris ``pkgadd'' utility. -These include GNU emacs, gcc, gdb, perl, and others. - -You can find also find prebuilt binaries of many GNU tools, including the -compiler, at @file{http://sunsite.unc.edu/pub/solaris/}. - -@node g++ for other platforms, 1.x vs 2.x versions, g++ for Solaris 2.x, basics -@section How do I get a copy of g++ for (some other platform)? - -@cindex Windows NT support -As of gcc-2.7.x, there is Windows NT support in gcc. Some special -utilities are required. See the INSTALL file from the distribution. -If you're interested in GNU tools on Windows NT, see -@file{http://www.cygnus.com/misc/gnu-win32/} on the WWW, or the -anonymous FTP directory -@file{ftp://ftp.cygnus.com/pub/gnu-win32/}. - -@cindex VMS support -@cindex VAX -@cindex VMS, g++/libg++ precompiled - -The standard gcc/g++ distribution includes VMS support for the Vax. -Since the FSF people don't use VMS, it's likely to be somewhat less -solid than the Unix version. Precompiled copies of g++ and libg++ in -VMS-installable form for the Vax are available by FTP from -@file{ftp://mango.rsmas.miami.edu/pub/VMS-gcc/}. - -@cindex OpenVMS/Alpha -Klaus Kaempf (kkaempf@@progis.de) -has done a port to OpenVMS for the Alpha; this is not yet a -part of the official gcc/g++. -The port includes g++ and all libraries from the libg++ distribution. See -@file{http://www.progis.de} for more details. - -@cindex MS-DOS support -@cindex Delorie's gcc/g++ -@cindex DJGPP -@cindex EMX -There are two different versions of gcc/g++ for MS-DOS: EMX and DJGPP. -EMX also works for OS/2 and is described later. -DJGPP is DJ Delorie's port. It can be found on many FTP archive -sites; try -@file{ftp://ftp.coast.net/SimTel/vendors/djgpp/} -or, for a complete list, see -@file{http://www.delorie.com/djgpp/getting.html}. - - -The latest version of DJGPP is 2.00. See -@file{http://www.delorie.com/djgpp/v2/} for information on this version. - -FSF sells floppies with DJGPP on them; see above for ordering software -from the FSF. - -DJGPP has its own newsgroup: @file{comp.os.msdos.djgpp}. - -@cindex Amiga support -Development and porting efforts for GNU tools, including gcc/g++, for -the Amiga are maintained by an initiative named ADE (Amiga Developers -Environment. More information about ADE is available at -@file{http://www.ninemoons.com/}. - -For more information on Amiga ports of gcc/g++, retrieve the file -@file{ftp://prep.ai.mit.edu/pub/gnu/MicrosPorts/Amiga}. - -@cindex Atari ST support -A port of gcc to the Atari ST can be found at @* -@file{ftp://atari.archive.umich.edu/atari/Gnustuff/Tos} -along with many -other GNU programs. This version is usually the same as the latest FSF -release. See the ``Software FAQ'' for the Usenet group -@file{comp.sys.atari.st} for more information. - -@cindex EMX port -@cindex OS/2 support - -EMX is a port of gcc to OS/2; it can also be used on MS-DOS. In addition to -the compiler port, the EMX port's C library attempts to provide a -Unix-like environment. For more information ask around on -@file{comp.os.os2.programmer.porting}. Version 0.9c, based on gcc-2.7.2.1, -was released in -November 1996. It is available by FTP and the WWW from, among other -places - -@example -@file{http://www.os2ss.com/unix/emx09c/} -@file{ftp://ftp.cdrom.com/pub/os2/emx09c/} (US) -@file{ftp://ftp.leo.org/pub/comp/os/os2/leo/devtools/emx+gcc/} (Germany) -@end example - -Eberhard Mattes did the EMX port. His address is -mattes@@azu.informatik.uni-stuttgart.de. -Read the FAQ file included with the distribution before harrassing the author. - -@cindex Apple support -@cindex Macintosh support - -I'm looking for more information on gcc/g++ support on the Apple -Macintosh. Until recently, this FAQ did not provide such information, -but FSF is no longer boycotting Apple as the League for Programming -Freedom boycott has been dropped. - -Versions 1.37.1 and 2.3.3 of gcc were ported by Stan Shebs and are available -at @* -@file{ftp://ftp.cygnus.com/pub/mac} - -They are both interfaced to MPW. -Stan is working on a version using the current (post-2.7) sources, contact -him directly (shebs@@cygnus.com) for more information. - -@node 1.x vs 2.x versions, , g++ for other platforms, basics -@section But I can only find g++-1.42! - -``I keep hearing people talking about g++ 2.8.1 (or some other number -starting with 2), but the latest version I can find is g++ 1.42. Where -is it?'' - -@cindex Objective-C -@cindex g++, version number -As of gcc 2.0, C, C++, and Objective-C as well are all combined into a -single distribution called gcc. If you get gcc you already have g++. The -standard installation procedure for any gcc version 2 compiler will -install the C++ compiler as well. - -One could argue that we shouldn't even refer to "g++-2.x.y" but it's a -convention. It means ``the C++ compiler included with gcc-2.x.y.'' - -@node egcs and 2.8.x, installation, basics, Top -@chapter The Next Generation(s) of g++ - -@menu -* new-in-2.8.x:: What's new in gcc 2.8.x? -* egcs-intro:: What is egcs? -* egcs-whats-new:: What's new in egcs vs 2.7.2? -* egcs-bug-fixes:: What was fixed in the latest egcs releases? -* egcs-linux:: If I install on Linux, will it overwrite my libraries? -* egcs-run-both:: How can I run both egcs and an FSF release? -* egcs-vs-2.8.x:: How will egcs affect 2.8.x? -* egcs-robustness:: How robust is egcs? -@end menu - -@node new-in-2.8.x, egcs-intro, egcs and 2.8.x, egcs and 2.8.x -@section What's new in gcc/g++ 2.8.x? - -After a two-year wait, gcc 2.8.0 was released in January 1998, along -with libstdc++-2.8.0 and libg++-2.8.0. This has been followed up in -March by the 2.8.1 release of all three packages, though libg++-2.8.1 -is an "add-on" (it does not contain libstdc++ anymore). Note that -libstdc++ is required. - -For those familiar with egcs, the most obvious difference between -gcc-2.8.x and egcs is the packaging: egcs is bundled with -libstdc++, and gcc-2.8.x does not contain the class library. Otherwise, -except for the lack of the @code{-frepo} option and some bug fixes -that have not yet made it into gcc-2.8.x, C++ users will find the -two compilers to be almost the same at this stage, other than that 2.8.x -users may get more bogus warnings with -Wall and optimization because -some fixes to flow analysis in the presence of exceptions that egcs made -are not yet present in gcc 2.8.x (as of 2.8.1). - -The flow analysis problem in 2.8.1 produces bad code in some cases, not -just spurious errors. It only affects code that actually throws an -exception, and only the path corresponding to a thrown exception gets -misoptimized. If this happens, you can try reducing the level of -optimization. - -Because the new feature lists for egcs and gcc 2.8 are almost the same, -please see @xref{egcs-whats-new} for a list of new features. It is a -fairly long list. - -@node egcs-intro, egcs-whats-new, new-in-2.8.x, egcs and 2.8.x -@section What is egcs? - -egcs is the experimental GNU compiler system (see -@file{http://www.cygnus.com/egcs} on the Web). It is an effort to -accelerate development of new gcc features by providing a more open -development model than gcc has traditionally used. - -The first egcs release, egcs-1.0, came out on December 3, 1997. -The current release is egcs-1.0.3, released May 15, 1998. - -Questions not addressed here may be answered in the egcs FAQ -(@file{http://www.cygnus.com/egcs/faq.html}). - -@node egcs-whats-new, egcs-bug-fixes, egcs-intro, egcs and 2.8.x -@section What new C++ features are in egcs? - -@strong{Note}: unless indicated otherwise, these features are also -present in g++ 2.8.x. - -@itemize @bullet -@item -@cindex integrated libstdc++ - -The standard C++ classes are integrated with the egcs release (but -@strong{not} for gcc-2.8.x, which does not include the class libraries). -libg++ is not being -supported, though an add-on version that will work with egcs can be found at -@file{ftp://ftp.yggdrasil.com/private/hjl/libg++-2.8.0b6.6.tar.gz}, -thanks to H.J. Lu. The compiler and library are configured and built -in one step. - -@item -@cindex new template implementation -A completely new template implementation, much closer to the draft -standard. Limitations in 2.7.2.x concerning inlining template functions -are eliminated. Static template data members, template class member -functions, partial specification, and default template arguments are -supported. An instantiation method resembling that used in Borland C++ -(instantiating functions possibly in multiple .o files and using weak -symbols to link correctly) is provided, in addition to other -options. The SGI version of STL is shipped verbatim with libstdc++ -(libstdc++ is included with egcs, separate with gcc-2.8.x). - -@item -@cindex redundant template elimination -@cindex templates: removing redundancy -On ELF platforms (Linux/ELF, Solaris, SVR4), if the GNU linker is used, -duplicated template functions and virtual function tables are eliminated -at link time. - -@item -@cindex repository -@cindex -frepo -The @code{-frepo} flag is supported in egcs (it is not in 2.8.x). -However, because of the previous item, I don't recommend its use on ELF -systems, as the default method is better. - -@item -@cindex new exception implementation -Exception handling has been re-worked; exceptions will work together -with optimization. -Actually, there are two separate implementations: one based on setjmp/longjmp -and designed to be highly portable, and one designed to be more efficient but -requiring more processor-specific support (getting exceptions right has proven -to be extremely difficult and has been the chief obstacle to getting a new -release out). - -@item -@cindex RTTI -RTTI has been re-done to work correctly and is on by default. - -@item -@cindex overloading -Overloading has been re-worked to conform to the latest draft of the -standard. - -@item -There are many more changes: see @file{http://www.cygnus.com/egcs/c++features.html} for a list. -@end itemize - -Features that are still missing include namespaces and templates as -template arguments, though there is support for the latter feature -in the egcs snapshots (which has not yet made it into a release). - -@node egcs-bug-fixes, egcs-linux, egcs-whats-new, egcs and 2.8.x -@section What was fixed in the latest egcs releases? - -@itemize @bullet - -@item -Add support for Red Hat 5.0 Linux and better support for Linux -systems using glibc2. (1.0.3 was specifically done to fix some -remaining problems detected when building Red Hat 5.1). - -@item -Compatibility with both egcs-1.0 and gcc-2.8 libgcc exception handling -interfaces (see below). - -@item -Various bugfixes in the x86, hppa, mips, and rs6000/ppc backends. - -@item -A few machine independent bugfixes, mostly to fix code generation bugs -when building Linux kernels or glibc. - -@item -Fix a few critical exception handling and template bugs in the C++ -compiler. - -@item -Fix build problems on x86-solaris systems. -@end itemize - -To avoid future compatibility problems, we strongly urge anyone who is -planning on distributing shared libraries that contain C++ code to -upgrade to at least egcs-1.0.1 first (and preferably to 1.0.3). See -@file{http://www.cygnus.com/egcs/egcs-1.0.1.html} for details about the -compatibility issues as well as additional information about the -bugfixes since the egcs-1.0 release. - -@node egcs-linux, egcs-run-both, egcs-bug-fixes, egcs and 2.8.x -@section If I install egcs on Linux, will it overwrite my libraries? - -No. If you build from sources, by default, egcs installs executables in -@code{/usr/local/bin} and libraries in @code{/usr/local/lib}, and you -can change this default if desired (see next section). - -If, however, you install a package (e.g. Debian or Red Hat) that wants -to put egcs in @code{/usr/bin} and @code{/usr/lib}, then yes, you are -replacing your system compiler and C++ library (I don't know if anyone -has provided such packages yet -- proceed with caution). - -@node egcs-run-both, egcs-vs-2.8.x, egcs-linux, egcs and 2.8.x -@section How can I run both egcs and an FSF release of g++ on the same machine? - -The recommended approach is to provide a different argument to the -@code{--prefix} flag when you configure egcs. For example, say -@code{--prefix=/usr/local/egcs} and then, after installation, you -can make symbolic links from @file{/usr/local/egcs/bin} to whereever -you want, for example - -@example -ln -s /usr/local/egcs/bin/gcc /usr/local/bin/egcc -ln -s /usr/local/egcs/bin/g++ /usr/local/bin/eg++ -@end example - -@node egcs-vs-2.8.x, egcs-robustness, egcs-run-both, egcs and 2.8.x -@section What about 2.8.x? How does egcs affect the 2.8.x development? - -2.8.0 has now been released (followed up by 2.8.1), with essentially the -same C++ front end as egcs. - -Bug fixes generated in egcs will be passed to the 2.8.x releases for -inclusion; the reverse is also taking place, though a bug fix may -appear in one before it does in the other. egcs development is currently -proceeding much more quickly than gcc 2.8.x development. However, there -is essentially only one C++ front end, which is shared by the two -distinct compiler back ends (however, since egcs-1.0.3 is newer than -gcc 2.8.1, it has more bug fixes). - -@node egcs-robustness, , egcs-vs-2.8.x, egcs and 2.8.x -@section How robust is egcs? - -While the 'e' stands for 'experimental', egcs has been tested thoroughly -and should be of high quality. The author considers egcs 1.0.3 the -most robust GNU C++ compiler ever produced. - -@node installation, evolution, egcs and 2.8.x, Top -@chapter Installation Issues and Problems - -@menu -* gcc-2 + g++-1:: -* what else do I need?:: -* use GNU linker?:: -* Use GNU assembler?:: -* shared libraries:: -* repository:: -* repo bugs:: -* Use GNU C library?:: -* Global constructor problems:: -* Strange assembler errors:: -* Other problems building libg++:: -* More size_t problems:: -* Rebuild libg++?:: -* co-existing versions:: -* Installing on Linux:: -* Linux Slackware 3.0:: -@end menu - -@node gcc-2 + g++-1, what else do I need?, installation, installation -@section I can't build g++ 1.x.y with gcc-2.x.y! - -``I obtained gcc-2.x.y and g++ 1.x.y and I'm trying to build it, but -I'm having major problems. What's going on?'' - -@cindex g++, building -If you wish to build g++-1.42, you must obtain gcc-1.42 first. The -installation instructions for g++ version 1 leave a lot to be desired, -unfortunately, and I would recommend that, unless you have a special -reason for needing the 1.x compiler, that C++ users use the latest -g++-2.x version, as it -is the version that is being actively maintained. - -@cindex g++, template support -@cindex Templates -@cindex ANSI draft standard -There is no template support in g++-1.x, and it is generally much further -away from the ANSI draft standard than g++-2.x is. - -@node what else do I need?, use GNU linker?, gcc-2 + g++-1, installation -@section OK, I've obtained gcc; what else do I need? - -@cindex libg++ -First off, you'll want libg++ as you can do almost nothing without it -(unless you replace it with some other class library). - -@cindex GNU GAS -@cindex GNU GAS [assembler] -Second, depending on your platform, you may need "GAS", the GNU assembler, -or the GNU linker (see next question). - -@cindex GNU gdb -Finally, while it is not required, you'll almost certainly want the GNU -debugger, gdb. The latest version is -4.17, released April 27, 1997. -Other debuggers (like dbx, for example) will normally not be able to -understand at least some of the debug information produced by g++. - -@node use GNU linker?, Use GNU assembler?, what else do I need?, installation -@section Should I use the GNU linker, or should I use "collect"? - -@cindex Linker -@cindex System VR3, linker -@cindex System VR4, linker -First off, for novices: special measures must be taken with C++ to arrange -for the calling of constructors for global or static objects before the -execution of your program, and for the calling of destructors at the end. -(Exception: System VR3 and System VR4 linkers, Linux/ELF, and some other -systems support user-defined -segments; g++ on these systems requires neither the GNU linker nor -collect. So if you have such a system, the answer is that you don't -need either one, though using GNU ld does have some advantages over -the native linker in some cases). - -@cindex AT&T cfront -@cindex Cfront-end -@cindex collect program -@cindex GNU linker -@cindex GNU binutils -If you have experience with AT&T's "cfront", this function is performed -there by programs named "patch" or "munch". With GNU C++, it is performed -either by the GNU linker or by a program known as "collect". The collect -program is part of the gcc-2.x distribution; you can obtain the GNU linker -separately as part of the "binutils" package. The latest version of -binutils is 2.9.1, released May 1, 1998. - -Note that if you want to use exceptions on Intel-like platforms and use -gas (e.g. you run Linux), you need binutils version 2.8.1 or newer for -exceptions to work correctly! - -(To be technical, it's "collect2"; there were originally several -alternative versions of collect, and this is the one that survived). - -There are advantages and disadvantages to either choice. - -Advantages of the GNU linker: -@cindex GNU linker, advantages -@cindex GNU ld -@cindex ld [GNU linker] - -It's faster than using collect -- collect basically runs the standard Unix -linker on your program twice, inserting some extra code after the first -pass to call the constructors. This is a sizable time penalty for large -programs. The GNU linker does not require this extra pass. - -GNU ld reports undefined symbols using their true names, not the mangled -names (but as of 2.7.0 so does collect). - -If there are undefined symbols, GNU ld reports which object file(s) refer to -the undefined symbol(s). On some OSes (e.g. SunOS, Solaris) the native -linker does not do this, so you have to track down who's referring to -the missing symbols yourself. - -As of binutils version 2.2, on systems that use the so-called "a.out" -debug format (e.g. Suns running SunOS 4.x), the GNU linker compresses -the debug symbol table considerably. The 2.7 version adds some symbol -table compression for ELF and Solaris targets. - -Users of egcs or 2.8.x on ELF systems should definitely -use GNU ld (2.8 or later), as it will automatically remove duplicate -instantiations of templates, virtual function tables, or ``outlined'' -copies of inline functions. - -@cindex collect linker, advantages -Advantages of collect: - -@cindex Shared libraries -If your native linker supports shared libraries, you can use shared -libraries with collect. This used to be a strong reason @emph{not} -to use the GNU linker, but recent versions of GNU ld support linking -with shared libraries on many platforms, and creating shared libraries -on a few (such as Intel x86 systems that use ELF object format as well -as SunOS and Solaris). - -@xref{shared libraries} - -@cindex GNU linker, porting -The GNU linker has not been ported to as many platforms as g++ has, so you -may be forced to use collect. - -If you use collect, you don't need to get something extra and figure out -how to install it; the standard gcc installation procedure will do it for you. - -I used to say at this point that I don't see a clear win for either -linking alternative, but with all the improvements in the GNU linker -I think that it is now the better choice. Take your pick. - -If you run Linux, the only available linker is the GNU linker. - -@node Use GNU assembler?, shared libraries, use GNU linker?, installation -@section Should I use the GNU assembler, or my vendor's assembler? - -@cindex Assembler -@cindex GNU GAS -This depends on your platform and your decision about the GNU linker. For -most platforms, you'll need to use GAS if you use the GNU linker. For -some platforms, you have no choice; check the gcc installation notes to -see whether you must use GAS. But you can usually use the vendor's -assembler if you don't use the GNU linker. - -The GNU assembler assembles faster than many native assemblers; however, -on many platforms it cannot support the local debugging format. - -It used to be that the GNU assembler couldn't handle -position-independent code on SunOS. This is no longer true if you -have version 2.6 or newer. - -On HPUX or IRIX, you must use GAS (and configure gcc with the -@code{--with-gnu-as} option) to debug your programs. GAS is -strongly recommended particularly on the HP platform because of -limitations in the HP assembler. - -The GNU assembler has been merged with the binutils -distribution, so the GNU assembler and linker are now together in -this package (as of binutils version 2.5.1). - -On Linux the assembler is the GNU assembler. - -@node shared libraries, repository, Use GNU assembler?, installation -@section How do I build shared libraries with g++? - -For gcc-2.7.0 and later, building C++ shared libraries should work fine -on supported platforms (HPUX 9+, IRIX 5+, DEC UNIX (formerly OSF/1), -SGI/IRIX, AIX, SunOS 4, Linux/ELF and all targets using SVR4-style ELF shared -libraries). There are two separate issues: building libg++ as a shared -library, and making your own shared libraries. For libg++ it is simply -a matter of giving the @code{--enable-shared} option to the configure -program. When compiling your own code for shared libraries you -generally -must use the @code{-fPIC} flag to get position-independent code. - -@cindex -shared flag of gcc - -If your shared library contains global or static objects with -constructors, then make sure to use @code{gcc -shared}, not -@code{ld}, to create the shared library. This will make sure -that any processor-specific magic needed to execute the constructors -is included. - -In theory, constructors for objects in your shared library should be -called when the library is opened (by dlopen or equivalent). This -does not work on some platforms (e.g. SunOS4; it does work on Solaris -and ELF systems such as Linux): on the broken platforms, the -constructors are not called correctly. - -David Nilsen has suggested the following workaround: - -The thing to realize is that if you link your dynamic module with the -@code{-shared} flag, the collect program nicely groups all the static -ctors/dtors for you into a list and sets up a function that will call -them (Note: this means that this trick won't work if you use the GNU -linker without collect (@pxref{use GNU linker?}). - -The magic is knowing these function names. Currently, they're called: - -@example -_GLOBAL__DI <-- calls all module constructors -_GLOBAL__DD <-- calls all module destructors -@end example - -[ possibly the leading underscore will differ between platforms: jbuck ] - -Therefore, if you make a wrapper around dlopen that looks up the -symbol @code{_GLOBAL__DI} (or @code{__GLOBAL__DI} on SunOS4 machines), and -calls it, you'll simulate getting the constructors called. - -You also need to set up the destructors to be called as well, so you -need to put a wrapper around dlclose, which will call the -@code{_GLOBAL__DD} function in the module when/if it's unloaded. - -Lastly, to get things 100% correct, you need to set up the destructors -to also be called if the module is not unloaded, but the main program -exits. I do this by registering a single function with @code{atexit()} that -calls all the destructors left in dynamically loaded modules. - -@cindex Shared version of libg++ -Check the file @file{README.SHLIB} from the libg++ distribution for more -about making and using shared libraries. - -@cindex Shared libraries with HP - -A patch is needed to build shared versions of version 2.7.2 of libg++ -and libstdc++ on the HP-PA architecture. You can find the patch at -@file{ftp://ftp.cygnus.com/pub/g++/libg++-2.7.2-hppa-gcc-fix}. - -@node repository, repo bugs, shared libraries, installation -@section How do I use the new repository code? - -@cindex repo patch -Because there is some disagreement about the details of the template -repository mechanism, you'll need to obtain a patch from Cygnus Support -to enable the 2.7.2 repository code. You can obtain the patch by -anonymous FTP: @file{ftp://ftp.cygnus.com/pub/g++/gcc-2.7.2-repo.gz}. - -There are patches for 2.7.0 and 2.7.1 in the same directory, though -if you're going to rebuild the compiler you should use the latest one. - -@cindex repo patch for BSD -If you're running NetBSD or BSDI, the Cygnus repo patch is not quite -correct. Tim Liddelow has made an alternate version available at -@file{ftp://ftp.cst.com.au/pub/gcc-2.7.2-repo-bsd.gz}. - -After you've applied the patch, the @code{-frepo} flag will enable the -repository mechanism. The flag works much like the existing -@code{-fno-implicit-templates} flag, except that auxiliary files, with -an @file{.rpo} extension, are built that specify what template -expansions are needed. At link time, the (patched) collect program -detects missing templates and recompiles some of the object files -so that the required templates are expanded. - -Note that the mechanism differs from that of cfront in that template -definitions still must be visible at the point where they are to be -expanded. No assumption is made that @file{foo.C} contains template -definitions corresponding to template declarations in @file{foo.h}. - -@cindex closure with repo -@cindex template closure -Jason Merrill writes: ``To perform closure on a set of objects, just try -to link them together. It will fail, but as a side effect all needed -instances will be generated in the objects.'' - -@node repo bugs, Use GNU C library?, repository, installation -@section Known bugs and problems with the repo patch - -``The @code{-frepo} won't expand templated friend functions!'' - -This is a known bug; currently you'll have to explicitly instantiate -friend functions when using @code{-frepo} due to this bug (in 2.7.0 -through 2.7.2 at least). - -With earlier versions of the repo patch, there was a bug that happens -when you have given a quoted command line switch, something like - -@example --D'MESSAGE="hello there"' -@end example - -The repo code tries to recompile files using the same flags you -originally specified, but doesn't quote arguments that need quoting, -resulting in failures in some cases. This is no longer a problem -with the 2.7.2 patch. - -@node Use GNU C library?, Global constructor problems, repo bugs, installation -@section Should I use the GNU C library? - -@cindex GNU C library -@cindex libg++ -At this point in time, no (unless you are running Linux or the GNU Hurd -system). The GNU C library is still very young, and -libg++ still conflicts with it in some places. Use your native C library -unless you know a lot about the gory details of libg++ and gnu-libc. This -will probably change in the future. - -@node Global constructor problems, Strange assembler errors, Use GNU C library?, installation -@section Global constructors aren't being called - -@cindex global constructors -``I've installed gcc and it almost works, but constructors and -destructors for global objects and objects at file scope aren't being -called. What did I do wrong?'' - -@cindex collect program -It appears that you are running on a platform that requires you to -install either "collect2" or the GNU linker, and you have done neither. -For more information, see the section discussing the GNU linker -(@pxref{use GNU linker?}). - -@cindex constructor problems on Solaris -@cindex Solaris, constructor problems -On Solaris 2.x, you shouldn't need a collect program and GNU ld doesn't run. -If your global constructors aren't being called, you may need to install -a patch, available from Sun, to fix your linker. The number of the -``jumbo patch'' that applies is 101409-03. Thanks to Russell Street -(r.street@@auckland.ac.nz) for this info. - -@cindex IRIX, installing collect -It appears that on IRIX, the collect2 program is not being installed -by default during the installation process, though it is required; -you can install it manually by executing - -@example -make install-collect2 -@end example - -from the gcc source directory after installing the compiler. (I'm -not certain for which versions of gcc this problem occurs, and whether -it is still present). - -@node Strange assembler errors, Other problems building libg++, Global constructor problems, installation -@section Strange assembler errors when linking C++ programs - -``I've installed gcc and it seemed to go OK, but when I attempt to link -any C++ program, I'm getting strange errors from the assembler! How -can that be?'' - -The messages in question might look something like - -@example -as: "/usr/tmp/cca14605.s", line 8: error: statement syntax -as: "/usr/tmp/cca14605.s", line 14: error: statement syntax -@end example - -(on a Sun, different on other platforms). The important thing is that -the errors come out at the link step, @emph{not} when a C++ file is -being compiled. - -@cindex nm program -@cindex GNU nm program -Here's what's going on: the collect2 program uses the Unix ``nm'' -program to obtain a list of symbols for the global constructors and -destructors, and it builds a little assembly language module that -will permit them all to be called. If you're seeing this symptom, -you have an old version of GNU nm somewhere on your path. This old -version prints out symbol names in a format that the collect2 program -does not expect, so bad assembly code is generated. - -The solution is either to remove the old version of GNU nm from your -path (and that of everyone else who uses g++), or to install a newer -version (it is part of the GNU "binutils" package). Recent versions -of GNU nm do not have this problem. - -@node Other problems building libg++, More size_t problems, Strange assembler errors, installation -@section Other problems building libg++ -@cindex libg++ on Ultrix -@cindex libg++ on SunOS - -``I am having trouble building libg++. Help!'' - -On some platforms (for example, Ultrix), you may see errors complaining -about being unable to open dummy.o. On other platforms (for example, -SunOS), you may see problems having to do with the type of size_t. -The fix for these problems is to make libg++ by saying "make CC=gcc". -According to Per Bothner, it should no longer be necessary to specify -"CC=gcc" for libg++-2.3.1 or later. - -``I built and installed libg++, but g++ can't find it. Help!'' - -The string given to @file{configure} that identifies your system must -be the same when you install libg++ as it was when you installed gcc. -Also, if you used the @code{--prefix} option to install gcc somewhere -other than @file{/usr/local}, you must use the same value for -@code{--prefix} when installing libg++, or else g++ will not be able -to find libg++. - -@cindex patch for libg++-2.6.2 - -The toplevel Makefile in the libg++ 2.6.2 distribution is broken, which -along with a bug in g++ 2.6.3 causes problems linking programs that use the -libstdc++ complex classes. A patch for this is available from -@file{ftp://ftp.cygnus.com//pub/g++/libg++-2.6.2-fix.gz}. - -@node More size_t problems, Rebuild libg++?, Other problems building libg++, installation -@section But I'm @emph{still} having problems with @code{size_t}! - -@cindex Type of size_t -``I did all that, and I'm @emph{still} having problems with disagreeing -definitions of size_t, SIZE_TYPE, and the type of functions like -@code{strlen}.'' - -@cindex _G_config.h -The problem may be that you have an old version of @file{_G_config.h} -lying around. As of libg++ version 2.4, @file{_G_config.h}, since it is -platform-specific, is inserted into a different directory; most include -files are in @file{$prefix/lib/g++-include}, but this file now lives in -@file{$prefix/$arch/include}. If, after upgrading your libg++, you find that -there is an old copy of @file{_G_config.h} left around, remove it, -otherwise g++ will find the old one first. - -@node Rebuild libg++?, co-existing versions, More size_t problems, installation -@section Do I need to rebuild libg++ to go with my new g++? - -``After I upgraded g++ to the latest version, I'm seeing undefined -symbols.'' - -or - -``If I upgrade to a new version of g++, do I need to reinstall libg++?'' - -@cindex Incompatibilities between g++ versions - -As a rule, the first two digits of your g++ and libg++ should be the -same. Normally when you do an upgrade in the ``minor version number'' -(2.5.7 to 2.5.8, say) there isn't a need to rebuild libg++, but there -have been a couple of exceptions in the past. - -@node co-existing versions, Installing on Linux, Rebuild libg++?, installation -@section I want several versions of g++ and libg++ to co-exist. - -I recommend against using the @code{-V} flag to make multiple versions -of gcc/g++ co-exist, unless they are different minor releases that can use -the same compiled version of libg++. The reason is that all these -versions will try to use the same libg++ version, which usually will -not work. - -Instead, use the @code{--prefix} flag when configuring gcc. Use a -different value of @code{--prefix} for each gcc version. Use the -same value of @code{--prefix} when configuring libg++. You can then -have any number of co-existing gcc/libg++ pairs. Symbolic links can -be used so that users don't need to put all these different directories -on their paths. - -One possible system to use is to set @code{--prefix} to -@file{/usr/local/gcc-2.x.y} for version 2.x.y of gcc, and to link -whichever version of gcc you wish to be the default into -@file{/usr/local/bin/gcc} and @file{/usr/local/bin/g++}. - -@node Installing on Linux, Linux Slackware 3.0, co-existing versions, installation -@section Trouble installing g++ and libg++ on Linux - -``I've downloaded the latest g++ and libg++ and I'm trying to install -them on Linux, and I'm having lots of problems.'' - -@cindex Linux -FSF releases of libg++ won't install on Linux unchanged, since Linux -uses are part of the libio library from libg++ for its standard C -library, only this is changed in a way that it clashes with libg++. -This means that you'll need a patched version of libg++ for it to -work. - -If you want to upgrade to a new gcc/libg++ combination, the easiest -thing to do is to grab the prebuilt versions of gcc and libg++ for Linux -from @file{ftp://tsx-11.mit.edu/pub/linux/packages/GCC}. Follow the -directions carefully. If you want to build from source, you'll need -a patch for libg++; the Linux developers have named the patched libg++ -version libg++-2.7.1.3 and there is a patch file in the above-named -directory. - -See @file{http://sunsite.unc.edu/LDP/HOWTO/GCC-HOWTO.html}, -the Linux GCC HOWTO, for more on gcc/g++ and Linux. - -Linux is in the process of switching over to the GNU C library, version -2, which will become Linux libc version 6. Once this process is -complete, there's a good chance that the installation process on Linux -will be smoother, but only experts should try making this new library -work at this point. - -@node Linux Slackware 3.0, , Installing on Linux, installation -@section Problems with g++ on Linux Slackware 3.0 - -@cindex Slackware -@cindex Linux Slackware -``When I try to compile the traditional Hello, world program on Linux, -the compiler can't find @file{iostream.h}. What's the deal?'' - -You probably have the Slackware 3.0 release. There's an error in the -setup. It's easy to fix, though; log in as root, and make a symbolic -link: - -@example -ln -s /usr/lib/g++-include /usr/include/g++ -@end example - -@node evolution, User Problems, installation, Top -@chapter The Evolution of g++ - -This chapter discusses the evolution of g++ and describes what can be expected -in the future. - -@menu -* version 2.7.x:: What's changed in 2.7.x from earlier versions -* libstdc++:: -@end menu - -@node version 2.7.x, libstdc++, evolution, evolution -@section What's new in version 2.7.x of gcc/g++ - -[ This section is old now, since 2.8.x/egcs is the new stuff ] The -latest 2.7.x version was 2.7.2.2, released February 10, 1997. The only -change between 2.7.2.1 and 2.7.2.2 is that support was added for using -the GNU C library, version 2, on Linux; users not interested in that -functionality have no reason to upgrade. The previous version of -gcc/g++ was 2.7.2.1, released August 14, 1996. The libg++ version that -should be used with any 2.7.x gcc/g++ is 2.7.2, released July 4, 1996. - -Note that gcc 2.7.2.1 just consists of several small patches to -gcc-2.7.2. The release is mainly -intended to fix platform-specific bugs and does not affect the C++ -``front end'' of the compiler (the part that parses your C++ code). - -The 2.7.x releases represent a great deal of work on the part of the g++ -maintainers to fix outstanding bugs and move the compiler closer to the -current ANSI/ISO standards committee's working paper, including -supporting many of the new features that have been added to the -language. I recommend that everyone read the NEWS file contained in the -distribution (and that system administrators make the file available to -their users). I've borrowed liberally from this file here. - -@cindex C++ working paper -If any features seem unfamiliar, you will probably want to -look at the recently-released public review copy of the C++ Working -Paper. A new draft, dated 2 December 1996, has been released for -public comment. You can find it on the web at -@file{http://www.cygnus.com/misc/wp/} or -@file{http://www.maths.warwick.ac.uk/c++/pub/wp/html/cd2/}. -See -@file{http://www.setech.com/x3.html} -or -@file{http://www.maths.warwick.ac.uk/c++/pub/} to download the -document in PostScript, PDF (Adobe Acrobat), HTML, or ASCII -form. - -Here are the main points: - -@itemize @bullet -@item -@cindex for scope -As described above, the scope of variables declared in the -initialization part of a for statement has been changed; such variables -are now visible only in the loop body. Use @code{-fno-for-scope} to get -the old behavior. You'll need this flag to build groff version 1.09, -Ptolemy, and many other free software packages. - -@item -@cindex vtable duplication -Code that does not use #pragma interface/implementation will most -likely shrink dramatically, as g++ now only emits the vtable for a -class in the translation unit where its first non-inline, non-abstract -virtual function is defined. - -@item -@cindex automatic template instantiation -Support for automatic template instantiation has @emph{not} been enabled -in the official distribution, due to a disagreement over design philosophies. -But you can get a patch from Cygnus to turn it on; retrieve the patch -from @file{ftp://ftp.cygnus.com/pub/g++/gcc-2.7.2-repo.gz} to patch -gcc-2.7.2 (there are also patches for earlier gcc versions). - -@item -@cindex exception handling, 2.7.0 - -@xref{exceptions} - -@item -@cindex run-time type identification -Support for Run-Time Type Identification has been added with @code{-frtti}. -This support is still in alpha; one major restriction is that any file -compiled with @code{-frtti} must include @code{<typeinfo>} (@emph{not} -@code{typeinfo.h} as the NEWS file says). -Also, all C++ code you link with (including libg++) has to be built with -@code{-frtti}, so it's still tricky to use. - -@item -@cindex compiler-generated operators -Synthesis of compiler-generated constructors, destructors and -assignment operators is now deferred until the functions are used. - -@item -@cindex assignment in conditional expressions -The parsing of expressions such as @code{a ? b : c = 1} -has changed from -@code{(a ? b : c) = 1} to @code{a ? b : (c = 1)}. This is a new C/C++ -incompatibility brought to you by the ANSI/ISO standards committee. - -@item -@cindex new operator keywords -The operator keywords and, and_eq, bitand, bitor, compl, not, not_eq, -or, or_eq, xor and xor_eq are now supported. Use @code{-ansi} or -@code{-foperator-names} to enable them. - -@item -@cindex explicit keyword -The @code{explicit} keyword is now supported. @code{explicit} is used to mark -constructors and type conversion operators that should not be used -implicitly. - -@item -@cindex user-defined type conversion -Handling of user-defined type conversion has been improved. - -@item -@cindex explicit template instantiation -Explicit instantiation of template methods is now supported. Also, -@code{inline template class foo<int>;} -can be used to emit only the vtable -for a template class. - -@item -@cindex -fcheck-new -With -fcheck-new, g++ will check the return value of all calls to -operator new, and not attempt to modify a returned null pointer. - -@item -collect2 now demangles linker output, and c++filt has become part of -the gcc distribution. - -@item -Improvements to template instantiation: only members actually used -are instantiated. (Actually this is not quite true: some inline -templates that are not successfully inlined may be expanded even -though they are not needed). - -@end itemize - -@node libstdc++, , version 2.7.x, evolution -@section The GNU Standard C++ Library - -The GNU Standard C++ Library (also called the ``GNU ANSI C++ Library'' -in places in the code) is not libg++, though it is included in the -libg++ distribution. Rather, it contains classes and functions -required by the ANSI/ISO standard. The copyright conditions are the -same as those for for the iostreams classes; the LGPL is not used -(@pxref{legalities}). - -This library, libstdc++, is in the libg++ distribution in versions 2.6.2 -and later. It requires at least gcc 2.6.3 to build the libg++-2.6.2 -version; use at least gcc 2.7.0 to build the libg++ 2.7.0 version. It -contains a hacked-up version of HP's implementation of the Standard -Template Library (@pxref{Standard Template Library}). I've -successfully used this Standard Template Library version to build -a number of the demos you'll see on various web pages. - -As of version 2.7.0, the streams classes are now in libstdc++ instead of -libg++, and libiostream is being phased out (don't use it). The g++ -program searches this library. - -The maintainers of libg++ have de-emphasized work on the older libg++ classes -in favor of enhancing libstdc++ to cover the full language, so while libg++ -will always be available, enhancements to it should not be expected. - -@node User Problems, legalities, evolution, Top -@chapter User Problems - -@menu -* missing virtual table:: -* for scope:: -* const constructor:: -* unused parameter warnings:: -* jump crosses initialization:: -* Demangler:: -* static data members:: -* internal compiler error:: -* bug reports:: -* porting to g++:: -* name mangling:: -* problems linking with other libraries:: -* documentation:: -* templates:: -* undefined templates:: -* redundant templates:: -* Standard Template Library:: -* STL and string:: -* exceptions:: -* namespaces:: -* agreement with standards:: -* compiling standard libraries:: -* debugging on SVR4 systems:: -* debugging problems on Solaris:: -* X11 conflicts with libg++:: -* assignment to streams:: -@end menu - -@node missing virtual table, for scope, User Problems, User Problems -@section Linker complains about missing virtual table - -``I'm getting a message complaining about an undefined virtual table. Is -this a compiler bug?'' - -(On platforms that run neither collect nor the GNU linker, like Solaris, -you may see an odd undefined symbol like "_vt.3foo", where foo is a -class name). - -This is probably because you are missing a definition for the first -(non-inline) virtual function of the class. Since gcc-2.7.0, g++ uses -a trick borrowed from cfront: the .o file containing the definition for -the first non-inline virtual function for the class will also contain -the virtual function table. - -@node for scope, const constructor, missing virtual table, User Problems -@section gcc-2.7.0 breaks declarations in "for" statements! - -@cindex declarations in for statements -@cindex for statements: declarations - -gcc-2.7.0 implements the new ANSI/ISO rule on the scope of variables -declared in for loops. - -@example -for (int i = 1; i <= 10; i++) @{ - // do something here -@} -foo(i); -@end example - -In the above example, most existing C++ compilers would pass the -value 11 to the function @code{foo}. In gcc 2.7 and in the ANSI/ISO -working paper, the scope of @code{i} is only the for loop body, so -this is an error. So that old code can be compiled, the new gcc has -a flag @code{-fno-for-scope} that causes the old rule to be used. -@cindex -fno-for-scope - -As of 2.7.1, the compiler attempts to issue warnings about code that -has different meanings under the two sets of rules, but the code is -not perfect: the intent was that code that has valid, but different, -meanings under the ARM rules and the working paper rules would give -warnings but have the new behavior, and this doesn't seem to happen. - -The @code{-ffor-scope} flag under 2.7.1 and 2.7.2 gives the 2.7.0 behavior. - -@node const constructor, unused parameter warnings, for scope, User Problems -@section g++ seems to want a const constructor. What's that? - -gcc-2.7.1 introduced a bug that causes the compiler to ask for a -const constructor (there's no such thing in C++) in certain situations -where a const object appears in a template class. Most cases have been -fixed in gcc-2.7.2, but unfortunately not all. Still, if you're running -gcc-2.7.1 and have this problem, upgrade to 2.7.2; it is a vast improvement. - -@cindex ObjectSpace<STL> - -The default constructor for the template @code{pair} in ObjectSpace's -implementation of STL triggers the bug in one place, for gcc 2.7.2. If -you're using ObjectSpace<STL> and having this problem, simply -change the default constructor from - -@example -os_pair () : first (T1 ()), second (T2 ()) @{@} -@end example - -to just - -@example -os_pair () @{@} -@end example - -Once this is done, ObjectSpace<STL> works fairly well. - -@node unused parameter warnings, jump crosses initialization, const constructor, User Problems -@section How to silence ``unused parameter'' warnings - -@cindex -Wall -@cindex -Wunused - -``When I use @code{-Wall} (or @code{-Wunused}), g++ warns about -unused parameters. But the parameters have to be there, for use -in derived class functions. How do I get g++ to stop complaining?'' - -The answer is to simply omit the names of the unused parameters when -defining the function. This makes clear, both to g++ and to readers -of your code, that the parameter is unused. For example: - -@example -int Foo::bar(int arg) @{ return 0; @} -@end example - -will give a warning for the unused parameter @code{arg}. To suppress -the warning write - -@example -int Foo::bar(int) @{ return 0; @} -@end example - -@node jump crosses initialization, Demangler, unused parameter warnings, User Problems -@section g++ objects to a declaration in a case statement - -``The compiler objects to my declaring a variable in one of the branches -of a case statement. Earlier versions used to accept this code. Why?'' - -The draft standard does not allow a goto or a jump to a case label to -skip over an initialization of a variable or a class object. For -example: - -@example -switch ( i ) @{ - case 1: - Object obj(0); - ... - break; - case 2: - ... - break; -@} -@end example - -The reason is that @code{obj} is also in scope in the rest of the switch -statement. - -As of version 2.7.0, the compiler will object that the jump to the -second case level crosses the initialization of @code{obj}. Older -compiler versions would object only if class Object has a destructor. -In either case, the solution is to add a set of curly braces around -the case branch: - -@example - case 1: - @{ - Object obj(0); - ... - break; - @} -@end example - -@node Demangler, static data members, jump crosses initialization, User Problems -@section Where can I find a demangler? - -@cindex demangler program -A g++-compatible demangler named @code{c++filt} can be found in the -@file{binutils} distribution. This distribution (which also contains -the GNU linker) can be found at any GNU archive site. - -As of version 2.7.0, @code{c++filt} is included with gcc and is -installed automatically. Even better, it is used by the @code{collect} -linker, so you don't see mangled symbols anymore (except on platforms -that use neither collect nor the GNU linker, like Solaris). - -@node static data members, internal compiler error, Demangler, User Problems -@section Linker reports undefined symbols for static data members - -@cindex Static data members -``g++ reports undefined symbols for all my static data members when I link, -even though the program works correctly for compiler XYZ. What's going on?'' - -The problem is almost certainly that you don't give definitions for -your static data members. If you have - -@example -class Foo @{ - ... - void method(); - static int bar; -@}; -@end example - -you have only declared that there is an int named Foo::bar and a member -function named Foo::method that is defined somewhere. You still need to -define @emph{both} method() and bar in some source file. According to -the draft ANSI standard, you must supply an initializer, such as - -@example -int Foo::bar = 0; -@end example - -@noindent -in one (and only one) source file. - -@node internal compiler error, bug reports, static data members, User Problems -@section What does ``Internal compiler error'' mean? - -It means that the compiler has detected a bug in itself. Unfortunately, -g++ still has many bugs, though it is a lot better than it used to be. -If you see this message, please send in a complete bug report (see next -section). - -@node bug reports, porting to g++, internal compiler error, User Problems -@section I think I have found a bug in g++. - -@cindex Bug in g++, newly found -``I think I have found a bug in g++, but I'm not sure. How do I know, -and who should I tell?'' - -@cindex Manual, for gcc -First, see the excellent section on bugs and bug reports in the gcc manual -(which is included in the gcc distribution). As a short summary of that -section: if the compiler gets a fatal signal, for any input, it's a bug -(newer versions of g++ will ask you to send in a bug report when they -detect an error in themselves). Same thing for producing invalid -assembly code. - -When you report a bug, make sure to describe your platform (the type of -computer, and the version of the operating system it is running) and the -version of the compiler that you are running. See the output of the -command @code{g++ -v} if you aren't sure. Also provide enough code -so that the g++ maintainers can duplicate your bug. Remember that the -maintainers won't have your header files; one possibility is to send -the output of the preprocessor (use @code{g++ -E} to get this). This -is what a ``complete bug report'' means. - -I will add some extra notes that are C++-specific, since the notes from -the gcc documentation are generally C-specific. - -@cindex g++ bug report -First, mail your bug report to "bug-g++@@prep.ai.mit.edu". You may also -post to @file{gnu.g++.bug}, but it's better to use mail, particularly if you -have any doubt as to whether your news software generates correct reply -addresses. Don't mail C++ bugs to bug-gcc@@prep.ai.mit.edu. - -@strong{News:} as I write this (late February 1996) the gateway -connecting the bug-g++ mailing list and the @file{gnu.g++.bug} newsgroup -is (temporarily?) broken. Please mail, do not post bug reports. - -@cindex libg++ bug report -If your bug involves libg++ rather than the compiler, mail to -bug-lib-g++@@prep.ai.mit.edu. If you're not sure, choose one, and if you -guessed wrong, the maintainers will forward it to the other list. - -@cindex C++, reference books -@cindex ARM [Annotated C++ Ref Manual] -Second, if your program does one thing, and you think it should do -something else, it is best to consult a good reference if in doubt. -The standard reference is the draft working paper from the ANSI/ISO -C++ standardization committee, which you can get on the net. -For PostScript and PDF (Adobe Acrobat) versions, see the -archive at @file{ftp://research.att.com/dist/stdc++/WP}. For HTML and ASCII -versions, see @file{ftp://ftp.cygnus.com/pub/g++}. On the World Wide Web, see -@file{http://www.cygnus.com/misc/wp/}. - -An older -standard reference is "The Annotated C++ Reference Manual", by Ellis and -Stroustrup (copyright 1990, ISBN #0-201-51459-1). This is what they're -talking about on the net when they refer to ``the ARM''. But you should -know that vast changes have been made to the language since then. - -The ANSI/ISO C++ standards committee have adopted some changes to the -C++ language since the publication of the original ARM, and newer -versions of g++ (2.5.x and later) support some of these changes, notably -the mutable keyword (added in 2.5.0), the bool type (added in 2.6.0), -and changes in the scope of variables defined in for statements (added -in 2.7.0). -You can obtain an addendum to the ARM explaining many of these changes by FTP -from @file{ftp://ftp.std.com/AW/stroustrup2e/new_iso.ps}. - -@cindex AT&T cfront -Note that the behavior of (any version of) AT&T's "cfront" compiler is -NOT the standard for the language. - -@node porting to g++, name mangling, bug reports, User Problems -@section Porting programs from other compilers to g++ - -``I have a program that runs on <some other C++ compiler>, and I want -to get it running under g++. Is there anything I should watch out -for?'' - -@cindex Porting to g++ - -Note that g++ supports many of the newer keywords that have recently -been added to the language. Your other C++ compiler may not support -them, so you may need to rename variables and members that conflict -with these keywords. - -There are two other reasons why a program that worked under one compiler -might fail under another: your program may depend on the order of -evaluation of side effects in an expression, or it may depend on the -lifetime of a temporary (you may be assuming that a temporary object -"lives" longer than the standard guarantees). As an example of the -first: - -@example -void func(int,int); - -int i = 3; -func(i++,i++); -@end example - -@cindex Order of evaluation, problems in porting -Novice programmers think that the increments will be evaluated in strict -left-to-right order. Neither C nor C++ guarantees this; the second -increment might happen first, for example. func might get 3,4, or it -might get 4,3. - -@cindex Classes, problems in porting -@cindex Problems in porting, class -The second problem often happens with classes like the libg++ String -class. Let's say I have - -@example -String func1(); -void func2(const char*); -@end example - -and I say - -@example -func2(func1()); -@end example - -because I know that class String has an "operator const char*". So what -really happens is - -@example -func2(func1().convert()); -@end example - -@cindex temporaries -where I'm pretending I have a convert() method that is the same as the -cast. This is unsafe in g++ versions before 2.6.0, because the -temporary String object may be deleted after its last use (the call to -the conversion function), leaving the pointer pointing to garbage, so by -the time func2 is called, it gets an invalid argument. - -@cindex ANSI draft standard -Both the cfront and the old g++ behaviors are legal according to the ARM, -but the powers that be have decided that compiler writers were given -too much freedom here. - -The ANSI C++ committee has now come to a resolution of the lifetime of -temporaries problem: they specify that temporaries should be deleted at -end-of-statement (and at a couple of other points). This means that g++ -versions before 2.6.0 now delete temporaries too early, and cfront -deletes temporaries too late. As of version 2.6.0, g++ does things -according to the new standard. - -@cindex Scope, problems in porting -@cindex Problems in porting, scope -For now, the safe way to write such code is to give the temporary a name, -which forces it to live until the end of the scope of the name. For -example: - -@example -String& tmp = func1(); -func2(tmp); -@end example - -Finally, like all compilers (but especially C++ compilers, it seems), -g++ has bugs, and you may have tweaked one. If so, please file a bug -report (after checking the above issues). - -@node name mangling, problems linking with other libraries, porting to g++, User Problems -@section Why does g++ mangle names differently from other C++ compilers? - -See the answer to the next question. -@cindex Mangling names - -@node problems linking with other libraries, documentation, name mangling, User Problems -@section Why can't g++ code link with code from other C++ compilers? - -``Why can't I link g++-compiled programs against libraries compiled by -some other C++ compiler?'' - -@cindex Mangling names -@cindex Cygnus Support -Some people think that, -if only the FSF and Cygnus Support folks would stop being -stubborn and mangle names the same way that, say, cfront does, then any -g++-compiled program would link successfully against any cfront-compiled -library and vice versa. Name mangling is the least of the problems. -Compilers differ as to how objects are laid out, how multiple inheritance -is implemented, how virtual function calls are handled, and so on, so if -the name mangling were made the same, your programs would link against -libraries provided from other compilers but then crash when run. For this -reason, the ARM @emph{encourages} compiler writers to make their name mangling -different from that of other compilers for the same platform. -Incompatible libraries are then detected at link time, rather than at run -time. -@cindex ARM [Annotated C++ Ref Manual] -@cindex Compiler differences - -@node documentation, templates, problems linking with other libraries, User Problems -@section What documentation exists for g++ 2.x? - -@cindex g++, documentation -Relatively little. -While the gcc manual that comes with the distribution has some coverage -of the C++ part of the compiler, it focuses mainly on the C compiler -(though the information on the ``back end'' pertains to C++ as well). -Still, there is useful information on the command line options and the -#pragma interface and #pragma implementation directives in the manual, -and there is a useful section on template instantiation in the 2.6 version. -There is a Unix-style manual entry, "g++.1", in the gcc-2.x -distribution; the information here is a subset of what is in the manual. - -You can buy a nicely printed and bound copy of this manual from the FSF; -see above for ordering information. - -A draft of a document describing the g++ internals appears in the gcc -distribution (called g++int.texi); it is incomplete but gives lots of -information. - -For class libraries, there are several resources available: - -@itemize @bullet -@item -The libg++ distribution has a manual -@file{libg++/libg++.texi} describing the old libg++ classes, and -another manual @file{libio/iostream.texi} describing the iostreams -implementation. -@item -While there is no libg++-specific document describing the STL -implementation, SGI's web site, at -@file{http://www.sgi.com/Technology/STL/}, is an excellent resource. -Note that the SGI version of STL is the one that is included with the -egcs and 2.8.x releases of g++/libstdc++. - -@end itemize - -@node templates, undefined templates, documentation, User Problems -@section Problems with the template implementation - -@cindex g++, template support -@cindex Templates - -g++ does not implement a separate pass to instantiate template functions -and classes at this point; for this reason, it will not work, for the most -part, to declare your template functions in one file and define them in -another. The compiler will need to see the entire definition of the -function, and will generate a static copy of the function in each file -in which it is used. - -(The experimental template repository code (@pxref{repository}) that -can be added to 2.7.0 or later does implement a separate pass, but there -is still no searching of files that the compiler never saw). - -As of 2.8.x and egcs-1.0.x, the template implementation has most -of the features specified in the draft standard. Still missing are -template arguments that are themselves templates; however, template -class member functions work, and most of the limitations of the older -g++ versions are fixed. - -I think that given this new implementation, it should not be necessary -for users to mess around with switches like @code{-fno-implicit-templates} -and @code{#pragma} directives; most of the time, the default behavior -will work OK. Users of older versions might want to read on. - -@cindex -fno-implicit-templates -For version 2.6.0, however, a new switch @code{-fno-implicit-templates} -was added; with this switch, templates are expanded only under user -control. I recommend that all g++ users that use templates read the -section ``Template Instantiation'' in the gcc manual (version 2.6.x -and newer). g++ now supports explicit template expansion using the -syntax from the latest C++ working paper: - -@example -template class A<int>; -template ostream& operator << (ostream&, const A<int>&); -@end example - -@cindex template limitations -As of version 2.7.2, there are still a few limitations in the template -implementation besides the above (thanks to Jason Merrill for this info): - -@strong{Note}: these problems are eliminated in egcs and in gcc-2.8.x. - -@enumerate 1 -@item -Static data member templates are not supported in compiler versions older -than 2.8.0. You can work around -this by explicitly declaring the static variable for each template -specialization: - -@example -template <class T> struct A @{ - static T t; -@}; - -template <class T> T A<T>::t = 0; // gets bogus error -int A<int>::t = 0; // OK (workaround) -@end example - -@item -Template member names are not available when defining member function -templates. - -@example -template <class T> struct A @{ - typedef T foo; - void f (foo); - void g (foo arg) @{ ... @}; // this works -@}; - -template <class T> void A<T>::f (foo) @{ @} // gets bogus error -@end example - -@item -Templates are instantiated using the parser. This results in two -problems (again, these problems are fixed in 2.8.0 and egcs): - -a) Class templates are instantiated in some situations where such -instantiation should not occur. - -@example -template <class T> class A @{ @}; -A<int> *aip = 0; // should not instantiate A<int> (but does) -@end example - -b) Function templates cannot be inlined at the site of their -instantiation. - -@example -template <class T> inline T min (T a, T b) @{ return a < b ? a : b; @} - -void f () @{ - int i = min (1, 0); // not inlined -@} - -void g () @{ - int j = min (1, 0); // inlined -@} -@end example - -A workaround that works in version 2.6.1 through 2.7.2.x is to specify - -@example -extern template int min (int, int); -@end example - -before @code{f()}; this will force it to be instantiated (though not -emitted). - -@strong{Note:} this kind of ``guiding declaration'' is not standard and -isn't supported by egcs or gcc-2.8.x, as the standard says that this -declares a ``normal'' @code{min} function which has no relation to -the template function @code{min<int>(int,int)}. But then the new -compilers have no problem inlining template functions. - -@item -Member function templates are always instantiated when their containing -class is. This is wrong (fixed in egcs/2.8). -@end enumerate - -@node undefined templates, redundant templates, templates, User Problems -@section I get undefined symbols when using templates - -(Thanks to Jason Merrill for this section). - -@cindex template instantiation -g++ does not automatically instantiate templates defined in other files. -Because of this, code written for cfront will often produce undefined -symbol errors when compiled with g++. You need to tell g++ which template -instances you want, by explicitly instantiating them in the file where they -are defined. For instance, given the files - -@file{templates.h}: -@example -template <class T> -class A @{ -public: - void f (); - T t; -@}; - -template <class T> void g (T a); -@end example - -@file{templates.cc}: -@example -#include "templates.h" - -template <class T> -void A<T>::f () @{ @} - -template <class T> -void g (T a) @{ @} -@end example - - -main.cc: -@example -#include "templates.h" - -main () -@{ - A<int> a; - a.f (); - g (a); -@} -@end example - -compiling everything with @code{g++ main.cc templates.cc} will result in -undefined symbol errors for @samp{A<int>::f ()} and @samp{g (A<int>)}. To -fix these errors, add the lines - -@example -template class A<int>; -template void g (A<int>); -@end example - -to the bottom of @samp{templates.cc} and recompile. - -@node redundant templates, Standard Template Library, undefined templates, User Problems -@section I get multiply defined symbols using templates - -You may be running into a bug that was introduced in version 2.6.1 -(and is still present in 2.6.3) that generated external linkage -for templates even when neither @code{-fexternal-templates} nor -@code{-fno-implicit-templates} is specified. There is a patch for -this problem at @* -@file{ftp://ftp.cygnus.com/pub/g++/gcc-2.6.3-template-fix}. - -I recommend either applying the patch or -using @code{-fno-implicit-templates} -together with explicit template instantiation as described in previous -sections. - -This bug is fixed in 2.7.0. - -@node Standard Template Library, STL and string, redundant templates, User Problems -@section Does g++ support the Standard Template Library? - -If you want to use the Standard Template Library, do not pass go, -upgrade immediately to gcc-2.8.x or to egcs. The new C++ front end -handles STL very well, and the high-quality implementation of STL -from SGI is included verbatim as part of the libstdc++ class library. - -If for some reason you must use 2.7.2, you can probably get by with -the hacked-up version of the old implementation from HP that is -included with libg++-2.7.2, but it is definitely inferior and has more -problems. Alternatively, g++ 2.7.2.x users might try the following: -a group at the Moscow Center for Sparc Technology has -a port of the SGI STL implementation that mostly works with gcc-2.7.2. -See -@file{http://www.ipmce.su/people/fbp/stl/stlport.html}. - -Mumit Khan has produced an ``STL newbie guide'' with lots of information -on using STL with gcc. See - -@file{http://www.xraylith.wisc.edu/~khan/software/stl/STL.newbie.html} - -@node STL and string, exceptions, Standard Template Library, User Problems -@section I'm having problems mixing STL and the standard string class - -[ This section is for g++ 2.7.2.x users only ] - -This is due to a bug in g++ version 2.7.2 and 2.7.2.1; the compiler -is confused by the operator declarations. There is an easy workaround, -however; just make sure that the @code{<string>} header is included -before any STL headers. That is, just say - -@example -#include <string> -@end example - -before any other @code{#include} directives. - -Unfortunately, this doesn't solve all problems; you may still have -difficulty with the relational operators !=, <=, >, and >=, thanks -to a conflict with the very general definition of these operators -in function.h. One trick that sometimes works is to try to use == -and < in your code instead of the other operators. Another is to -use a derived class of <string>. The only completely satisfactory -solution, I'm afraid, is to wait for the new release. - -@node exceptions, namespaces, STL and string, User Problems -@section Problems and limitations with exceptions - -The first really usable exceptions implementations are in 2.8.x and -egcs. With these versions, exceptions are enabled by default; use --fno-exceptions to disable exceptions. - -However, 2.8.1 still has not integrated egcs work that computes an -accurate control flow graph in the presence of exceptions. For this -reason, you will sometimes get bogus warnings when compiling with 2.8.1, --O, and -Wall, about uninitialized variables and the like. - -2.7.2.x has very limited and partially broken support for exceptions. -With that compiler, you must -provide the @code{-fhandle-exceptions} flag to enable exception -handling. In version 2.7.2 and older, exceptions may not work properly -(and you may get odd error messages when compiling) if you turn -on optimization (the @code{-O} flag). If you care about exceptions, -please upgrade to a newer compiler! - -In 2.7.2, you must give the @code{-frtti} switch to enable catching -of derived exception objects with handlers for the base exception class; -if @code{-frtti} is not given, only exact type matching works. - -For exception handling to work with 2.7.0 your CPU must be a SPARC, -RS6000/PowerPC, 386/486/Pentium, or ARM. Release 2.7.1 added support -for the Alpha, and ``m68k is rumored to work on some platforms'' -and ``VAX may also work'' (according to Mike Stump). -@emph{It still doesn't work on HP-PA or MIPS platforms.} - -Exception handling adds space overhead (the size of the executable -grows); the problem is worse on the ix86 (Intel-like) architecture -than on RISC architectures. The extra exceptions code is generated -in a separate program section and is only paged in if an exception -is thrown, so the cost is in disk, not in RAM or CPU. - -Exception overhead is much lower on ix86 if you use binutils 2.9 or -later, as gas (the GNU assembler) can now compress the information. - -@node namespaces, agreement with standards, exceptions, User Problems -@section Does g++ support namespaces? - -As of version 2.7.2, g++ recognizes the keywords @code{namespace} and -@code{using}, and there is some rudimentary code present, but almost -nothing connected with namespaces works yet. -The new versions (2.8.x/egcs) still lack namespace support, but to help -compile standard programs they make - -@example -using namespace std; -@end example - -a no-op. There is namespace implementation work going on in the egcs -snapshots (but it hasn't been released yet). - -@node agreement with standards, compiling standard libraries, namespaces, User Problems -@section What are the differences between g++ and the ARM specification of C++? - -@cindex ARM [Annotated C++ Ref Manual] -@cindex exceptions - -Up until recently, there was no really usable exception support. If you -need exceptions, you want gcc-2.8.x or egcs. The implementation works -fairly well. The 2.7.x version was strictly alpha quality and quite -fragile. - -@cindex mutable -Some features that the ANSI/ISO standardization committee has voted in -that don't appear in the ARM are supported, notably the @code{mutable} -keyword, in version 2.5.x. 2.6.x added support for the built-in boolean -type @code{bool}, with constants @code{true} and @code{false}. Run-time -type identification was rudimentary in 2.7.x but is fully supported in -2.8.x, so there are -more reserved words: @code{typeid}, @code{static_cast}, -@code{reinterpret_cast}, @code{const_cast}, and @code{dynamic_cast}. - -@cindex g++ bugs -As with any beta-test compiler, there are bugs. You can help improve -the compiler by submitting detailed bug reports. - -[ This paragraph obsoleted by 2.8.x/egcs: ] -One of the weakest areas of g++ other than templates is the resolution -of overloaded functions and operators in complex cases. The usual -symptom is that in a case where the ARM says that it is ambiguous which -function should be chosen, g++ chooses one (often the first one -declared). This is usually not a problem when porting C++ code from -other compilers to g++, but shows up as errors when code developed under -g++ is ported to other compilers. (I believe this is no longer a -significant problem in 2.7.0 or later). - -[A full bug list would be very long indeed, so I won't put one here; -the sheer complexity of the C++ language means that every compiler I've -tried has some problems. 2.8.x and egcs are a big improvement] - -@node compiling standard libraries, debugging on SVR4 systems, agreement with standards, User Problems -@section Will g++ compile InterViews? The NIH class library? Rogue Wave? - -@cindex NIH class library -@cindex NIHCL with g++ -The NIH class library uses a non-portable, compiler-dependent hack -to initialize itself, which makes life difficult for g++ users. -It will not work without modification, and I don't know what modifications -are required or whether anyone has done them successfully. - -In short, it's not going to happen any time soon (previous FAQs referred -to patches that a new NIHCL release would hopefully contain, but this -hasn't happened). - -@strong{Note:} I thought I saw an item indicating that someone -@emph{had} patched NIHCL to work with g++. Any pointers? - -@cindex InterViews -I think that as of version 2.5.6, the standard g++ will compile the -standard 3.1 InterViews completely successfully. -Note that you'll need the @code{-fno-for-scope} flag -if you use gcc-2.7.0; with 2.7.2 you may be able to omit this flag -but you'll get warnings. - -@cindex Rogue Wave -According to Jason Merrill, gcc-2.7.0 and newer works with Rogue -Wave's @code{tools.h++} class library, but you may want to grab -@file{ftp://ftp.cygnus.com/pub/g++/Tools.h++-6.1-patch}. Again, -you'll need the @code{-fno-for-scope} flag since Rogue Wave hasn't -fixed their code to comply with the new standard yet. - -@node debugging on SVR4 systems, debugging problems on Solaris, compiling standard libraries, User Problems -@section Debugging on SVR4 systems -@cindex System VR4, debugging - -``How do I get debugging to work on my System V Release 4 system?'' - -@cindex DWARF debug format - -Most systems based on System V Release 4 (except Solaris) encode symbolic -debugging information in a format known as `DWARF'. There are two forms -of DWARF, DWARF 1 and DWARF 2. The default is often DWARF 1, which is -not really expressive enough to do C++ correctly. - -Now that we have gdb 4.17, DWARF debugging is finally supported (if -you use gcc 2.8.1 or egcs-1.0.x or newer). - -@cindex stabs -@cindex --with-stabs - -For users of older versions of the tools, you @emph{can} get g++ debugging under SVR4 systems by -configuring gcc with the @code{--with-stabs} option. This causes gcc to -use an alternate debugging format, one more like that used under SunOS4. -You won't need to do anything special to GDB; it will always understand -the ``stabs'' format. - -To specify DWARF 2 output on Unixware, you can give the @code{-ggdb} -switch; alternatively, @code{-gstabs} produces ``stabs'' format. - -@node debugging problems on Solaris, X11 conflicts with libg++, debugging on SVR4 systems, User Problems -@section debugging problems on Solaris - -``I'm on Solaris, and gdb says it doesn't know about some of my local -symbols. Help!'' - -This problem was introduced in gcc 2.7.2; debug symbols for -locals that aren't declared at the beginning of a block come out in the -wrong order, and gdb can't find such symbols. - -This problem is fixed in gcc-2.7.2.1. - -@node X11 conflicts with libg++, assignment to streams, debugging problems on Solaris, User Problems -@section X11 conflicts with libg++ in definition of String -@cindex String, conflicts in definition - -``X11 and Motif define String, and this conflicts with the String class -in libg++. How can I use both together?'' - -One possible method is the following: - -@example -#define String XString -#include <X11/Intrinsic.h> -/* include other X11 and Motif headers */ -#undef String -@end example - -and remember to use the correct @code{String} or @code{XString} when -you declare things later. - -@node assignment to streams, , X11 conflicts with libg++, User Problems -@section Why can't I assign one stream to another? - -[ Thanks to Per Bothner and Jerry Schwarz for this section. ] - -Assigning one stream to another seems like a reasonable thing to do, but -it's a bad idea. Usually, this comes up because people want to assign -to @code{cout}. This is poor style, especially for libraries, and is -contrary to good object-oriented design. (Libraries that write directly -to @code{cout} are less flexible, modular, and object-oriented). - -The iostream classes do not allow assigning to arbitrary streams, because -this can violate typing: - -@example -ifstream foo ("foo"); -istrstream str(...); -foo = str; -foo->close (); /* Oops! Not defined for istrstream! */ -@end example - -@cindex assignment to cout - -The original cfront implementation of iostreams by Jerry Schwarz allows -you to assign to @code{cin}, @code{cout}, @code{cerr}, and @code{clog}, -but this is not part of the draft standard for iostreams and generally -isn't considered a good idea, so standard-conforming code shouldn't use -this technique. - -The GNU implementation of iostream did not support assigning to -@code{cin}, @code{cout}, @code{cerr}, and @code{clog} -for quite a while, but it now does, for backward -compatibility with cfront iostream (versions 2.6.1 and later of libg++). - -The ANSI/ISO C++ Working Paper does provide ways of changing the -streambuf associated with a stream. Assignment isn't allowed; -there is an explicit named member that must be used. - -However, it is not wise to do this, and the results are confusing. For -example: @code{fstream::rdbuf} is supposed to return the @emph{original} -filebuf, not the one you assigned. (This is not yet implemented in GNU -iostream.) This must be so because @code{fstream::rdbuf} is defined to -return a @code{filebuf *}. - -@node legalities, index, User Problems, Top -@chapter What are the rules for shipping code built with g++ and libg++? -@cindex Shipping rules -@cindex GPL [GNU Public License] - -``Is it is possible to distribute programs for profit that are created -with g++ and use the g++ libraries?'' - -I am not a lawyer, and this is not legal advice. In any case, I have -little interest in telling people how to violate the spirit of the -GNU licenses without violating the letter. This section tells you -how to comply with the intention of the GNU licenses as best I understand -them. - -@cindex FSF [Free Software Foundation] -The FSF has no objection to your making money. Its only interest is that -source code to their programs, and libraries, and to modified versions of -their programs and libraries, is always available. - -The short answer is that you do not need to release the source to -your program, but you can't just ship a stripped executable either, -unless you use only the subset of libg++ that includes the iostreams -classes (see discussion below) or the new libstdc++ library (available -in libg++ 2.6.2 and later). - -Compiling your code with a GNU compiler does not affect its copyright; -it is still yours. However, in order to ship code that links in a GNU -library such as libg++ there are certain rules you must follow. The -rules are described in the file COPYING.LIB that accompanies gcc -distributions; it is also included in the libg++ distribution. -See that file for the exact rules. The agreement is called the -Library GNU Public License or LGPL. It is much "looser" than the -GNU Public License, or GPL, that covers must GNU programs. - -@cindex libg++, shipping code -Here's the deal: let's say that you use some version of libg++, -completely unchanged, in your software, and you want to ship only -a binary form of your code. You can do this, but there are several -special requirements. If you want to use libg++ but ship only object -code for your code, you have to ship source for libg++ (or ensure -somehow that your customer already has the source for the exact -version you are using), and ship your application in linkable form. -You cannot forbid your customer from reverse-engineering or extending -your program by exploiting its linkable form. - -@cindex libg++, modifying -Furthermore, if you modify libg++ itself, you must provide source -for your modifications (making a derived class does not count as -modifying the library -- that is "a work that uses the library"). - -@cindex special copying conditions for iostreams -For certain portions of libg++ that implement required parts of the C++ -language (such as iostreams and other standard classes), the FSF has -loosened the copyright requirement still more by adding the ``special -exception'' clause, which reads as follows: - -@quotation -As a special exception, if you link this library with files -compiled with GCC to produce an executable, this does not cause -the resulting executable to be covered by the GNU General Public License. -This exception does not however invalidate any other reasons why -the executable file might be covered by the GNU General Public License. -@end quotation - -If your only use of libg++ uses code with this exception, you may ship -stripped executables or license your executables under different -conditions without fear of violating an FSF copyright. It is the intent -of FSF and Cygnus that, as the other classes required by the ANSI/ISO -draft standard are developed, these will also be placed under this -``special exception'' license. -The code in the new libstdc++ library, intended to implement standard -classes as defined by ANSI/ISO, is also licensed this way. - -To avoid coming under the influence of the LGPL, you can link with -@file{-liostream} rather than @file{-lg++} (for version 2.6.x and -earlier), or @file{-lstdc++} now that it is available. In version 2.7.0 -all the standard classes are in @file{-lstdc++}; you can do the link -step with @code{c++} instead of @code{g++} to search only the -@file{-lstdc++} library and avoid the LGPL'ed code in @file{-lg++}. - -Note that in egcs and in gcc-2.8.x, if you do not -specify any libraries the @code{g++} command will only link in -@file{-lstdc++}, so your executable will not be affected by the LGPL -(unless you link in some other LGPLed library: the GNU C library used -on GNU/Linux systems is one such library). - -If you wish to discuss legal issues connected with GNU software on the -net, please use @file{gnu.misc.discuss}, not the technical newsgroups. - -@node index, , legalities, Top -@comment node-name, next, previous, up -@appendix Concept Index - -@printindex cp - -@page -@contents -@bye diff --git a/gcc/cp/g++spec.c b/gcc/cp/g++spec.c deleted file mode 100755 index 806b90e..0000000 --- a/gcc/cp/g++spec.c +++ /dev/null @@ -1,266 +0,0 @@ -/* Specific flags and argument handling of the C++ front-end. - Copyright (C) 1996, 1997, 1998, 1999 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" - -/* This bit is set if we saw a `-xfoo' language specification. */ -#define LANGSPEC (1<<1) -/* This bit is set if they did `-lm' or `-lmath'. */ -#define MATHLIB (1<<2) -/* This bit is set if they did `-lc'. */ -#define WITHLIBC (1<<3) - -#ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" -#endif - -#ifndef LIBSTDCXX -#define LIBSTDCXX "-lstdc++" -#endif - -void -lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) - void (*fn)(); - int *in_argc; - char ***in_argv; - int *in_added_libraries; -{ - int i, j; - - /* If non-zero, the user gave us the `-v' flag. */ - int saw_verbose_flag = 0; - - /* This will be 0 if we encounter a situation where we should not - link in libstdc++. */ - int library = 1; - - /* The number of arguments being added to what's in argv, other than - libraries. We use this to track the number of times we've inserted - -xc++/-xnone. */ - int added = 2; - - /* Used to track options that take arguments, so we don't go wrapping - those with -xc++/-xnone. */ - char *quote = NULL; - - /* The new argument list will be contained in this. */ - char **arglist; - - /* Non-zero if we saw a `-xfoo' language specification on the - command line. Used to avoid adding our own -xc++ if the user - already gave a language for the file. */ - int saw_speclang = 0; - - /* "-lm" or "-lmath" if it appears on the command line. */ - char *saw_math = 0; - - /* "-lc" if it appears on the command line. */ - char *saw_libc = 0; - - /* An array used to flag each argument that needs a bit set for - LANGSPEC, MATHLIB, or WITHLIBC. */ - int *args; - - /* By default, we throw on the math library if we have one. */ - int need_math = (MATH_LIBRARY[0] != '\0'); - - /* The total number of arguments with the new stuff. */ - int argc; - - /* The argument list. */ - char **argv; - - /* The number of libraries added in. */ - int added_libraries; - - /* The total number of arguments with the new stuff. */ - int num_args = 1; - - argc = *in_argc; - argv = *in_argv; - added_libraries = *in_added_libraries; - - args = (int *) xmalloc (argc * sizeof (int)); - bzero ((char *) args, argc * sizeof (int)); - - for (i = 1; i < argc; i++) - { - /* If the previous option took an argument, we swallow it here. */ - if (quote) - { - quote = NULL; - continue; - } - - /* We don't do this anymore, since we don't get them with minus - signs on them. */ - if (argv[i][0] == '\0' || argv[i][1] == '\0') - continue; - - if (argv[i][0] == '-') - { - if (library != 0 && (strcmp (argv[i], "-nostdlib") == 0 - || strcmp (argv[i], "-nodefaultlibs") == 0)) - { - library = 0; - } - else if (strcmp (argv[i], "-lm") == 0 - || strcmp (argv[i], "-lmath") == 0 - || strcmp (argv[i], MATH_LIBRARY) == 0 -#ifdef ALT_LIBM - || strcmp (argv[i], ALT_LIBM) == 0 -#endif - ) - { - args[i] |= MATHLIB; - need_math = 0; - } - else if (strcmp (argv[i], "-lc") == 0) - args[i] |= WITHLIBC; - else if (strcmp (argv[i], "-v") == 0) - { - saw_verbose_flag = 1; - if (argc == 2) - { - /* If they only gave us `-v', don't try to link - in libg++. */ - library = 0; - } - } - else if (strncmp (argv[i], "-x", 2) == 0) - saw_speclang = 1; - else if (((argv[i][2] == '\0' - && (char *)strchr ("bBVDUoeTuIYmLiA", argv[i][1]) != NULL) - || strcmp (argv[i], "-Tdata") == 0)) - quote = argv[i]; - else if (library != 0 && ((argv[i][2] == '\0' - && (char *) strchr ("cSEM", argv[i][1]) != NULL) - || strcmp (argv[i], "-MM") == 0)) - { - /* Don't specify libraries if we won't link, since that would - cause a warning. */ - library = 0; - added -= 2; - } - else - /* Pass other options through. */ - continue; - } - else - { - int len; - - if (saw_speclang) - { - saw_speclang = 0; - continue; - } - - /* If the filename ends in .c or .i, put options around it. - But not if a specified -x option is currently active. */ - len = strlen (argv[i]); - if (len > 2 - && (argv[i][len - 1] == 'c' || argv[i][len - 1] == 'i') - && argv[i][len - 2] == '.') - { - args[i] |= LANGSPEC; - added += 2; - } - } - } - - if (quote) - (*fn) ("argument to `%s' missing\n", quote); - - /* If we know we don't have to do anything, bail now. */ - if (! added && ! library) - { - free (args); - return; - } - - num_args = argc + added + need_math; - arglist = (char **) xmalloc (num_args * sizeof (char *)); - - /* NOTE: We start at 1 now, not 0. */ - for (i = 0, j = 0; i < argc; i++, j++) - { - arglist[j] = argv[i]; - - /* Make sure -lstdc++ is before the math library, since libstdc++ - itself uses those math routines. */ - if (!saw_math && (args[i] & MATHLIB) && library) - { - --j; - saw_math = argv[i]; - } - - if (!saw_libc && (args[i] & WITHLIBC) && library) - { - --j; - saw_libc = argv[i]; - } - - /* Wrap foo.c and foo.i files in a language specification to - force the gcc compiler driver to run cc1plus on them. */ - if (args[i] & LANGSPEC) - { - int len = strlen (argv[i]); - if (argv[i][len - 1] == 'i') - arglist[j++] = "-xc++-cpp-output"; - else - arglist[j++] = "-xc++"; - arglist[j++] = argv[i]; - arglist[j] = "-xnone"; - } - } - - /* Add `-lstdc++' if we haven't already done so. */ - if (library) - { - arglist[j++] = LIBSTDCXX; - added_libraries++; - } - if (saw_math) - arglist[j++] = saw_math; - else if (library && need_math) - { - arglist[j++] = MATH_LIBRARY; - added_libraries++; - } - if (saw_libc) - arglist[j++] = saw_libc; - - arglist[j] = NULL; - - *in_argc = j; - *in_argv = arglist; - *in_added_libraries = added_libraries; -} - -/* Called before linking. Returns 0 on success and -1 on failure. */ -int lang_specific_pre_link () /* Not used for C++. */ -{ - return 0; -} - -/* Number of extra output files that lang_specific_pre_link may generate. */ -int lang_specific_extra_outfiles = 0; /* Not used for C++. */ diff --git a/gcc/cp/gxx.gperf b/gcc/cp/gxx.gperf deleted file mode 100755 index 5632f7f..0000000 --- a/gcc/cp/gxx.gperf +++ /dev/null @@ -1,111 +0,0 @@ -%{ -/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -%} -struct resword { char *name; short token; enum rid rid;}; -%% -__alignof, ALIGNOF, NORID -__alignof__, ALIGNOF, NORID -__asm, ASM_KEYWORD, NORID -__asm__, ASM_KEYWORD, NORID -__attribute, ATTRIBUTE, NORID -__attribute__, ATTRIBUTE, NORID -__complex, TYPESPEC, RID_COMPLEX -__complex__, TYPESPEC, RID_COMPLEX -__const, CV_QUALIFIER, RID_CONST -__const__, CV_QUALIFIER, RID_CONST -__extension__, EXTENSION, NORID -__imag, IMAGPART, NORID -__imag__, IMAGPART, NORID -__inline, SCSPEC, RID_INLINE -__inline__, SCSPEC, RID_INLINE -__label__, LABEL, NORID -__null, CONSTANT, RID_NULL -__real, REALPART, NORID -__real__, REALPART, NORID -__restrict, CV_QUALIFIER, RID_RESTRICT -__restrict__, CV_QUALIFIER, RID_RESTRICT -__signature__, AGGR, RID_SIGNATURE /* Extension */, -__signed, TYPESPEC, RID_SIGNED -__signed__, TYPESPEC, RID_SIGNED -__sigof__, SIGOF, NORID /* Extension */, -__typeof, TYPEOF, NORID -__typeof__, TYPEOF, NORID -__volatile, CV_QUALIFIER, RID_VOLATILE -__volatile__, CV_QUALIFIER, RID_VOLATILE -__wchar_t, TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */, -asm, ASM_KEYWORD, NORID, -and, ANDAND, NORID, -and_eq, ASSIGN, NORID, -auto, SCSPEC, RID_AUTO, -bitand, '&', NORID, -bitor, '|', NORID, -bool, TYPESPEC, RID_BOOL, -break, BREAK, NORID, -case, CASE, NORID, -catch, CATCH, NORID, -char, TYPESPEC, RID_CHAR, -class, AGGR, RID_CLASS, -compl, '~', NORID, -const, CV_QUALIFIER, RID_CONST, -const_cast, CONST_CAST, NORID, -continue, CONTINUE, NORID, -default, DEFAULT, NORID, -delete, DELETE, NORID, -do, DO, NORID, -double, TYPESPEC, RID_DOUBLE, -dynamic_cast, DYNAMIC_CAST, NORID, -else, ELSE, NORID, -enum, ENUM, NORID, -explicit, SCSPEC, RID_EXPLICIT, -export, SCSPEC, RID_EXPORT, -extern, SCSPEC, RID_EXTERN, -false, CXX_FALSE, NORID, -float, TYPESPEC, RID_FLOAT, -for, FOR, NORID, -friend, SCSPEC, RID_FRIEND, -goto, GOTO, NORID, -if, IF, NORID, -inline, SCSPEC, RID_INLINE, -int, TYPESPEC, RID_INT, -long, TYPESPEC, RID_LONG, -mutable, SCSPEC, RID_MUTABLE, -namespace, NAMESPACE, NORID, -new, NEW, NORID, -not, '!', NORID, -not_eq, EQCOMPARE, NORID, -operator, OPERATOR, NORID, -or, OROR, NORID, -or_eq, ASSIGN, NORID, -private, VISSPEC, RID_PRIVATE, -protected, VISSPEC, RID_PROTECTED, -public, VISSPEC, RID_PUBLIC, -register, SCSPEC, RID_REGISTER, -reinterpret_cast, REINTERPRET_CAST, NORID, -return, RETURN, NORID, -short, TYPESPEC, RID_SHORT, -signature, AGGR, RID_SIGNATURE /* Extension */, -signed, TYPESPEC, RID_SIGNED, -sigof, SIGOF, NORID /* Extension */, -sizeof, SIZEOF, NORID, -static, SCSPEC, RID_STATIC, -static_cast, STATIC_CAST, NORID, -struct, AGGR, RID_RECORD, -switch, SWITCH, NORID, -template, TEMPLATE, RID_TEMPLATE, -this, THIS, NORID, -throw, THROW, NORID, -true, CXX_TRUE, NORID, -try, TRY, NORID, -typedef, SCSPEC, RID_TYPEDEF, -typename, TYPENAME_KEYWORD, NORID, -typeid, TYPEID, NORID, -typeof, TYPEOF, NORID, -union, AGGR, RID_UNION, -unsigned, TYPESPEC, RID_UNSIGNED, -using, USING, NORID, -virtual, SCSPEC, RID_VIRTUAL, -void, TYPESPEC, RID_VOID, -volatile, CV_QUALIFIER, RID_VOLATILE, -while, WHILE, NORID, -xor, '^', NORID, -xor_eq, ASSIGN, NORID, diff --git a/gcc/cp/gxxint.texi b/gcc/cp/gxxint.texi deleted file mode 100755 index 3b8242d..0000000 --- a/gcc/cp/gxxint.texi +++ /dev/null @@ -1,1867 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename g++int.info -@settitle G++ internals -@setchapternewpage odd -@c %**end of header - -@node Top, Limitations of g++, (dir), (dir) -@chapter Internal Architecture of the Compiler - -This is meant to describe the C++ front-end for gcc in detail. -Questions and comments to Benjamin Kosnik @code{<bkoz@@cygnus.com>}. - -@menu -* Limitations of g++:: -* Routines:: -* Implementation Specifics:: -* Glossary:: -* Macros:: -* Typical Behavior:: -* Coding Conventions:: -* Templates:: -* Access Control:: -* Error Reporting:: -* Parser:: -* Copying Objects:: -* Exception Handling:: -* Free Store:: -* Mangling:: Function name mangling for C++ and Java -* Concept Index:: -@end menu - -@node Limitations of g++, Routines, Top, Top -@section Limitations of g++ - -@itemize @bullet -@item -Limitations on input source code: 240 nesting levels with the parser -stacksize (YYSTACKSIZE) set to 500 (the default), and requires around -16.4k swap space per nesting level. The parser needs about 2.09 * -number of nesting levels worth of stackspace. - -@cindex pushdecl_class_level -@item -I suspect there are other uses of pushdecl_class_level that do not call -set_identifier_type_value in tandem with the call to -pushdecl_class_level. It would seem to be an omission. - -@cindex access checking -@item -Access checking is unimplemented for nested types. - -@cindex @code{volatile} -@item -@code{volatile} is not implemented in general. - -@end itemize - -@node Routines, Implementation Specifics, Limitations of g++, Top -@section Routines - -This section describes some of the routines used in the C++ front-end. - -@code{build_vtable} and @code{prepare_fresh_vtable} is used only within -the @file{cp-class.c} file, and only in @code{finish_struct} and -@code{modify_vtable_entries}. - -@code{build_vtable}, @code{prepare_fresh_vtable}, and -@code{finish_struct} are the only routines that set @code{DECL_VPARENT}. - -@code{finish_struct} can steal the virtual function table from parents, -this prohibits related_vslot from working. When finish_struct steals, -we know that - -@example -get_binfo (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (t)), t, 0) -@end example - -@noindent -will get the related binfo. - -@code{layout_basetypes} does something with the VIRTUALS. - -Supposedly (according to Tiemann) most of the breadth first searching -done, like in @code{get_base_distance} and in @code{get_binfo} was not -because of any design decision. I have since found out the at least one -part of the compiler needs the notion of depth first binfo searching, I -am going to try and convert the whole thing, it should just work. The -term left-most refers to the depth first left-most node. It uses -@code{MAIN_VARIANT == type} as the condition to get left-most, because -the things that have @code{BINFO_OFFSET}s of zero are shared and will -have themselves as their own @code{MAIN_VARIANT}s. The non-shared right -ones, are copies of the left-most one, hence if it is its own -@code{MAIN_VARIANT}, we know it IS a left-most one, if it is not, it is -a non-left-most one. - -@code{get_base_distance}'s path and distance matters in its use in: - -@itemize @bullet -@item -@code{prepare_fresh_vtable} (the code is probably wrong) -@item -@code{init_vfields} Depends upon distance probably in a safe way, -build_offset_ref might use partial paths to do further lookups, -hack_identifier is probably not properly checking access. - -@item -@code{get_first_matching_virtual} probably should check for -@code{get_base_distance} returning -2. - -@item -@code{resolve_offset_ref} should be called in a more deterministic -manner. Right now, it is called in some random contexts, like for -arguments at @code{build_method_call} time, @code{default_conversion} -time, @code{convert_arguments} time, @code{build_unary_op} time, -@code{build_c_cast} time, @code{build_modify_expr} time, -@code{convert_for_assignment} time, and -@code{convert_for_initialization} time. - -But, there are still more contexts it needs to be called in, one was the -ever simple: - -@example -if (obj.*pmi != 7) - @dots{} -@end example - -Seems that the problems were due to the fact that @code{TREE_TYPE} of -the @code{OFFSET_REF} was not a @code{OFFSET_TYPE}, but rather the type -of the referent (like @code{INTEGER_TYPE}). This problem was fixed by -changing @code{default_conversion} to check @code{TREE_CODE (x)}, -instead of only checking @code{TREE_CODE (TREE_TYPE (x))} to see if it -was @code{OFFSET_TYPE}. - -@end itemize - -@node Implementation Specifics, Glossary, Routines, Top -@section Implementation Specifics - -@itemize @bullet -@item Explicit Initialization - -The global list @code{current_member_init_list} contains the list of -mem-initializers specified in a constructor declaration. For example: - -@example -foo::foo() : a(1), b(2) @{@} -@end example - -@noindent -will initialize @samp{a} with 1 and @samp{b} with 2. -@code{expand_member_init} places each initialization (a with 1) on the -global list. Then, when the fndecl is being processed, -@code{emit_base_init} runs down the list, initializing them. It used to -be the case that g++ first ran down @code{current_member_init_list}, -then ran down the list of members initializing the ones that weren't -explicitly initialized. Things were rewritten to perform the -initializations in order of declaration in the class. So, for the above -example, @samp{a} and @samp{b} will be initialized in the order that -they were declared: - -@example -class foo @{ public: int b; int a; foo (); @}; -@end example - -@noindent -Thus, @samp{b} will be initialized with 2 first, then @samp{a} will be -initialized with 1, regardless of how they're listed in the mem-initializer. - -@item The Explicit Keyword - -The use of @code{explicit} on a constructor is used by @code{grokdeclarator} -to set the field @code{DECL_NONCONVERTING_P}. That value is used by -@code{build_method_call} and @code{build_user_type_conversion_1} to decide -if a particular constructor should be used as a candidate for conversions. - -@end itemize - -@node Glossary, Macros, Implementation Specifics, Top -@section Glossary - -@table @r -@item binfo -The main data structure in the compiler used to represent the -inheritance relationships between classes. The data in the binfo can be -accessed by the BINFO_ accessor macros. - -@item vtable -@itemx virtual function table - -The virtual function table holds information used in virtual function -dispatching. In the compiler, they are usually referred to as vtables, -or vtbls. The first index is not used in the normal way, I believe it -is probably used for the virtual destructor. - -@item vfield - -vfields can be thought of as the base information needed to build -vtables. For every vtable that exists for a class, there is a vfield. -See also vtable and virtual function table pointer. When a type is used -as a base class to another type, the virtual function table for the -derived class can be based upon the vtable for the base class, just -extended to include the additional virtual methods declared in the -derived class. The virtual function table from a virtual base class is -never reused in a derived class. @code{is_normal} depends upon this. - -@item virtual function table pointer - -These are @code{FIELD_DECL}s that are pointer types that point to -vtables. See also vtable and vfield. -@end table - -@node Macros, Typical Behavior, Glossary, Top -@section Macros - -This section describes some of the macros used on trees. The list -should be alphabetical. Eventually all macros should be documented -here. - -@table @code -@item BINFO_BASETYPES -A vector of additional binfos for the types inherited by this basetype. -The binfos are fully unshared (except for virtual bases, in which -case the binfo structure is shared). - - If this basetype describes type D as inherited in C, - and if the basetypes of D are E anf F, - then this vector contains binfos for inheritance of E and F by C. - -Has values of: - - TREE_VECs - - -@item BINFO_INHERITANCE_CHAIN -Temporarily used to represent specific inheritances. It usually points -to the binfo associated with the lesser derived type, but it can be -reversed by reverse_path. For example: - -@example - Z ZbY least derived - | - Y YbX - | - X Xb most derived - -TYPE_BINFO (X) == Xb -BINFO_INHERITANCE_CHAIN (Xb) == YbX -BINFO_INHERITANCE_CHAIN (Yb) == ZbY -BINFO_INHERITANCE_CHAIN (Zb) == 0 -@end example - -Not sure is the above is really true, get_base_distance has is point -towards the most derived type, opposite from above. - -Set by build_vbase_path, recursive_bounded_basetype_p, -get_base_distance, lookup_field, lookup_fnfields, and reverse_path. - -What things can this be used on: - - TREE_VECs that are binfos - - -@item BINFO_OFFSET -The offset where this basetype appears in its containing type. -BINFO_OFFSET slot holds the offset (in bytes) from the base of the -complete object to the base of the part of the object that is allocated -on behalf of this `type'. This is always 0 except when there is -multiple inheritance. - -Used on TREE_VEC_ELTs of the binfos BINFO_BASETYPES (...) for example. - - -@item BINFO_VIRTUALS -A unique list of functions for the virtual function table. See also -TYPE_BINFO_VIRTUALS. - -What things can this be used on: - - TREE_VECs that are binfos - - -@item BINFO_VTABLE -Used to find the VAR_DECL that is the virtual function table associated -with this binfo. See also TYPE_BINFO_VTABLE. To get the virtual -function table pointer, see CLASSTYPE_VFIELD. - -What things can this be used on: - - TREE_VECs that are binfos - -Has values of: - - VAR_DECLs that are virtual function tables - - -@item BLOCK_SUPERCONTEXT -In the outermost scope of each function, it points to the FUNCTION_DECL -node. It aids in better DWARF support of inline functions. - - -@item CLASSTYPE_TAGS -CLASSTYPE_TAGS is a linked (via TREE_CHAIN) list of member classes of a -class. TREE_PURPOSE is the name, TREE_VALUE is the type (pushclass scans -these and calls pushtag on them.) - -finish_struct scans these to produce TYPE_DECLs to add to the -TYPE_FIELDS of the type. - -It is expected that name found in the TREE_PURPOSE slot is unique, -resolve_scope_to_name is one such place that depends upon this -uniqueness. - - -@item CLASSTYPE_METHOD_VEC -The following is true after finish_struct has been called (on the -class?) but not before. Before finish_struct is called, things are -different to some extent. Contains a TREE_VEC of methods of the class. -The TREE_VEC_LENGTH is the number of differently named methods plus one -for the 0th entry. The 0th entry is always allocated, and reserved for -ctors and dtors. If there are none, TREE_VEC_ELT(N,0) == NULL_TREE. -Each entry of the TREE_VEC is a FUNCTION_DECL. For each FUNCTION_DECL, -there is a DECL_CHAIN slot. If the FUNCTION_DECL is the last one with a -given name, the DECL_CHAIN slot is NULL_TREE. Otherwise it is the next -method that has the same name (but a different signature). It would -seem that it is not true that because the DECL_CHAIN slot is used in -this way, we cannot call pushdecl to put the method in the global scope -(cause that would overwrite the TREE_CHAIN slot), because they use -different _CHAINs. finish_struct_methods setups up one version of the -TREE_CHAIN slots on the FUNCTION_DECLs. - -friends are kept in TREE_LISTs, so that there's no need to use their -TREE_CHAIN slot for anything. - -Has values of: - - TREE_VECs - - -@item CLASSTYPE_VFIELD -Seems to be in the process of being renamed TYPE_VFIELD. Use on types -to get the main virtual function table pointer. To get the virtual -function table use BINFO_VTABLE (TYPE_BINFO ()). - -Has values of: - - FIELD_DECLs that are virtual function table pointers - -What things can this be used on: - - RECORD_TYPEs - - -@item DECL_CLASS_CONTEXT -Identifies the context that the _DECL was found in. For virtual function -tables, it points to the type associated with the virtual function -table. See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_FCONTEXT. - -The difference between this and DECL_CONTEXT, is that for virtuals -functions like: - -@example -struct A -@{ - virtual int f (); -@}; - -struct B : A -@{ - int f (); -@}; - -DECL_CONTEXT (A::f) == A -DECL_CLASS_CONTEXT (A::f) == A - -DECL_CONTEXT (B::f) == A -DECL_CLASS_CONTEXT (B::f) == B -@end example - -Has values of: - - RECORD_TYPEs, or UNION_TYPEs - -What things can this be used on: - - TYPE_DECLs, _DECLs - - -@item DECL_CONTEXT -Identifies the context that the _DECL was found in. Can be used on -virtual function tables to find the type associated with the virtual -function table, but since they are FIELD_DECLs, DECL_FIELD_CONTEXT is a -better access method. Internally the same as DECL_FIELD_CONTEXT, so -don't us both. See also DECL_FIELD_CONTEXT, DECL_FCONTEXT and -DECL_CLASS_CONTEXT. - -Has values of: - - RECORD_TYPEs - - -What things can this be used on: - -@display -VAR_DECLs that are virtual function tables -_DECLs -@end display - - -@item DECL_FIELD_CONTEXT -Identifies the context that the FIELD_DECL was found in. Internally the -same as DECL_CONTEXT, so don't us both. See also DECL_CONTEXT, -DECL_FCONTEXT and DECL_CLASS_CONTEXT. - -Has values of: - - RECORD_TYPEs - -What things can this be used on: - -@display -FIELD_DECLs that are virtual function pointers -FIELD_DECLs -@end display - - -@item DECL_NAME - -Has values of: - -@display -0 for things that don't have names -IDENTIFIER_NODEs for TYPE_DECLs -@end display - -@item DECL_IGNORED_P -A bit that can be set to inform the debug information output routines in -the back-end that a certain _DECL node should be totally ignored. - -Used in cases where it is known that the debugging information will be -output in another file, or where a sub-type is known not to be needed -because the enclosing type is not needed. - -A compiler constructed virtual destructor in derived classes that do not -define an explicit destructor that was defined explicit in a base class -has this bit set as well. Also used on __FUNCTION__ and -__PRETTY_FUNCTION__ to mark they are ``compiler generated.'' c-decl and -c-lex.c both want DECL_IGNORED_P set for ``internally generated vars,'' -and ``user-invisible variable.'' - -Functions built by the C++ front-end such as default destructors, -virtual destructors and default constructors want to be marked that -they are compiler generated, but unsure why. - -Currently, it is used in an absolute way in the C++ front-end, as an -optimization, to tell the debug information output routines to not -generate debugging information that will be output by another separately -compiled file. - - -@item DECL_VIRTUAL_P -A flag used on FIELD_DECLs and VAR_DECLs. (Documentation in tree.h is -wrong.) Used in VAR_DECLs to indicate that the variable is a vtable. -It is also used in FIELD_DECLs for vtable pointers. - -What things can this be used on: - - FIELD_DECLs and VAR_DECLs - - -@item DECL_VPARENT -Used to point to the parent type of the vtable if there is one, else it -is just the type associated with the vtable. Because of the sharing of -virtual function tables that goes on, this slot is not very useful, and -is in fact, not used in the compiler at all. It can be removed. - -What things can this be used on: - - VAR_DECLs that are virtual function tables - -Has values of: - - RECORD_TYPEs maybe UNION_TYPEs - - -@item DECL_FCONTEXT -Used to find the first baseclass in which this FIELD_DECL is defined. -See also DECL_CONTEXT, DECL_FIELD_CONTEXT and DECL_CLASS_CONTEXT. - -How it is used: - - Used when writing out debugging information about vfield and - vbase decls. - -What things can this be used on: - - FIELD_DECLs that are virtual function pointers - FIELD_DECLs - - -@item DECL_REFERENCE_SLOT -Used to hold the initialize for the reference. - -What things can this be used on: - - PARM_DECLs and VAR_DECLs that have a reference type - - -@item DECL_VINDEX -Used for FUNCTION_DECLs in two different ways. Before the structure -containing the FUNCTION_DECL is laid out, DECL_VINDEX may point to a -FUNCTION_DECL in a base class which is the FUNCTION_DECL which this -FUNCTION_DECL will replace as a virtual function. When the class is -laid out, this pointer is changed to an INTEGER_CST node which is -suitable to find an index into the virtual function table. See -get_vtable_entry as to how one can find the right index into the virtual -function table. The first index 0, of a virtual function table it not -used in the normal way, so the first real index is 1. - -DECL_VINDEX may be a TREE_LIST, that would seem to be a list of -overridden FUNCTION_DECLs. add_virtual_function has code to deal with -this when it uses the variable base_fndecl_list, but it would seem that -somehow, it is possible for the TREE_LIST to pursist until method_call, -and it should not. - - -What things can this be used on: - - FUNCTION_DECLs - - -@item DECL_SOURCE_FILE -Identifies what source file a particular declaration was found in. - -Has values of: - - "<built-in>" on TYPE_DECLs to mean the typedef is built in - - -@item DECL_SOURCE_LINE -Identifies what source line number in the source file the declaration -was found at. - -Has values of: - -@display -0 for an undefined label - -0 for TYPE_DECLs that are internally generated - -0 for FUNCTION_DECLs for functions generated by the compiler - (not yet, but should be) - -0 for ``magic'' arguments to functions, that the user has no - control over -@end display - - -@item TREE_USED - -Has values of: - - 0 for unused labels - - -@item TREE_ADDRESSABLE -A flag that is set for any type that has a constructor. - - -@item TREE_COMPLEXITY -They seem a kludge way to track recursion, poping, and pushing. They only -appear in cp-decl.c and cp-decl2.c, so the are a good candidate for -proper fixing, and removal. - - -@item TREE_HAS_CONSTRUCTOR -A flag to indicate when a CALL_EXPR represents a call to a constructor. -If set, we know that the type of the object, is the complete type of the -object, and that the value returned is nonnull. When used in this -fashion, it is an optimization. Can also be used on SAVE_EXPRs to -indicate when they are of fixed type and nonnull. Can also be used on -INDIRECT_EXPRs on CALL_EXPRs that represent a call to a constructor. - - -@item TREE_PRIVATE -Set for FIELD_DECLs by finish_struct. But not uniformly set. - -The following routines do something with PRIVATE access: -build_method_call, alter_access, finish_struct_methods, -finish_struct, convert_to_aggr, CWriteLanguageDecl, CWriteLanguageType, -CWriteUseObject, compute_access, lookup_field, dfs_pushdecl, -GNU_xref_member, dbxout_type_fields, dbxout_type_method_1 - - -@item TREE_PROTECTED -The following routines do something with PROTECTED access: -build_method_call, alter_access, finish_struct, convert_to_aggr, -CWriteLanguageDecl, CWriteLanguageType, CWriteUseObject, -compute_access, lookup_field, GNU_xref_member, dbxout_type_fields, -dbxout_type_method_1 - - -@item TYPE_BINFO -Used to get the binfo for the type. - -Has values of: - - TREE_VECs that are binfos - -What things can this be used on: - - RECORD_TYPEs - - -@item TYPE_BINFO_BASETYPES -See also BINFO_BASETYPES. - -@item TYPE_BINFO_VIRTUALS -A unique list of functions for the virtual function table. See also -BINFO_VIRTUALS. - -What things can this be used on: - - RECORD_TYPEs - - -@item TYPE_BINFO_VTABLE -Points to the virtual function table associated with the given type. -See also BINFO_VTABLE. - -What things can this be used on: - - RECORD_TYPEs - -Has values of: - - VAR_DECLs that are virtual function tables - - -@item TYPE_NAME -Names the type. - -Has values of: - -@display -0 for things that don't have names. -should be IDENTIFIER_NODE for RECORD_TYPEs UNION_TYPEs and - ENUM_TYPEs. -TYPE_DECL for RECORD_TYPEs, UNION_TYPEs and ENUM_TYPEs, but - shouldn't be. -TYPE_DECL for typedefs, unsure why. -@end display - -What things can one use this on: - -@display -TYPE_DECLs -RECORD_TYPEs -UNION_TYPEs -ENUM_TYPEs -@end display - -History: - - It currently points to the TYPE_DECL for RECORD_TYPEs, - UNION_TYPEs and ENUM_TYPEs, but it should be history soon. - - -@item TYPE_METHODS -Synonym for @code{CLASSTYPE_METHOD_VEC}. Chained together with -@code{TREE_CHAIN}. @file{dbxout.c} uses this to get at the methods of a -class. - - -@item TYPE_DECL -Used to represent typedefs, and used to represent bindings layers. - -Components: - - DECL_NAME is the name of the typedef. For example, foo would - be found in the DECL_NAME slot when @code{typedef int foo;} is - seen. - - DECL_SOURCE_LINE identifies what source line number in the - source file the declaration was found at. A value of 0 - indicates that this TYPE_DECL is just an internal binding layer - marker, and does not correspond to a user supplied typedef. - - DECL_SOURCE_FILE - -@item TYPE_FIELDS -A linked list (via @code{TREE_CHAIN}) of member types of a class. The -list can contain @code{TYPE_DECL}s, but there can also be other things -in the list apparently. See also @code{CLASSTYPE_TAGS}. - - -@item TYPE_VIRTUAL_P -A flag used on a @code{FIELD_DECL} or a @code{VAR_DECL}, indicates it is -a virtual function table or a pointer to one. When used on a -@code{FUNCTION_DECL}, indicates that it is a virtual function. When -used on an @code{IDENTIFIER_NODE}, indicates that a function with this -same name exists and has been declared virtual. - -When used on types, it indicates that the type has virtual functions, or -is derived from one that does. - -Not sure if the above about virtual function tables is still true. See -also info on @code{DECL_VIRTUAL_P}. - -What things can this be used on: - - FIELD_DECLs, VAR_DECLs, FUNCTION_DECLs, IDENTIFIER_NODEs - - -@item VF_BASETYPE_VALUE -Get the associated type from the binfo that caused the given vfield to -exist. This is the least derived class (the most parent class) that -needed a virtual function table. It is probably the case that all uses -of this field are misguided, but they need to be examined on a -case-by-case basis. See history for more information on why the -previous statement was made. - -Set at @code{finish_base_struct} time. - -What things can this be used on: - - TREE_LISTs that are vfields - -History: - - This field was used to determine if a virtual function table's - slot should be filled in with a certain virtual function, by - checking to see if the type returned by VF_BASETYPE_VALUE was a - parent of the context in which the old virtual function existed. - This incorrectly assumes that a given type _could_ not appear as - a parent twice in a given inheritance lattice. For single - inheritance, this would in fact work, because a type could not - possibly appear more than once in an inheritance lattice, but - with multiple inheritance, a type can appear more than once. - - -@item VF_BINFO_VALUE -Identifies the binfo that caused this vfield to exist. If this vfield -is from the first direct base class that has a virtual function table, -then VF_BINFO_VALUE is NULL_TREE, otherwise it will be the binfo of the -direct base where the vfield came from. Can use @code{TREE_VIA_VIRTUAL} -on result to find out if it is a virtual base class. Related to the -binfo found by - -@example -get_binfo (VF_BASETYPE_VALUE (vfield), t, 0) -@end example - -@noindent -where @samp{t} is the type that has the given vfield. - -@example -get_binfo (VF_BASETYPE_VALUE (vfield), t, 0) -@end example - -@noindent -will return the binfo for the given vfield. - -May or may not be set at @code{modify_vtable_entries} time. Set at -@code{finish_base_struct} time. - -What things can this be used on: - - TREE_LISTs that are vfields - - -@item VF_DERIVED_VALUE -Identifies the type of the most derived class of the vfield, excluding -the class this vfield is for. - -Set at @code{finish_base_struct} time. - -What things can this be used on: - - TREE_LISTs that are vfields - - -@item VF_NORMAL_VALUE -Identifies the type of the most derived class of the vfield, including -the class this vfield is for. - -Set at @code{finish_base_struct} time. - -What things can this be used on: - - TREE_LISTs that are vfields - - -@item WRITABLE_VTABLES -This is a option that can be defined when building the compiler, that -will cause the compiler to output vtables into the data segment so that -the vtables maybe written. This is undefined by default, because -normally the vtables should be unwritable. People that implement object -I/O facilities may, or people that want to change the dynamic type of -objects may want to have the vtables writable. Another way of achieving -this would be to make a copy of the vtable into writable memory, but the -drawback there is that that method only changes the type for one object. - -@end table - -@node Typical Behavior, Coding Conventions, Macros, Top -@section Typical Behavior - -@cindex parse errors - -Whenever seemingly normal code fails with errors like -@code{syntax error at `\@{'}, it's highly likely that grokdeclarator is -returning a NULL_TREE for whatever reason. - -@node Coding Conventions, Templates, Typical Behavior, Top -@section Coding Conventions - -It should never be that case that trees are modified in-place by the -back-end, @emph{unless} it is guaranteed that the semantics are the same -no matter how shared the tree structure is. @file{fold-const.c} still -has some cases where this is not true, but rms hypothesizes that this -will never be a problem. - -@node Templates, Access Control, Coding Conventions, Top -@section Templates - -A template is represented by a @code{TEMPLATE_DECL}. The specific -fields used are: - -@table @code -@item DECL_TEMPLATE_RESULT -The generic decl on which instantiations are based. This looks just -like any other decl. - -@item DECL_TEMPLATE_PARMS -The parameters to this template. -@end table - -The generic decl is parsed as much like any other decl as possible, -given the parameterization. The template decl is not built up until the -generic decl has been completed. For template classes, a template decl -is generated for each member function and static data member, as well. - -Template members of template classes are represented by a TEMPLATE_DECL -for the class' parameters around another TEMPLATE_DECL for the member's -parameters. - -All declarations that are instantiations or specializations of templates -refer to their template and parameters through DECL_TEMPLATE_INFO. - -How should I handle parsing member functions with the proper param -decls? Set them up again or try to use the same ones? Currently we do -the former. We can probably do this without any extra machinery in -store_pending_inline, by deducing the parameters from the decl in -do_pending_inlines. PRE_PARSED_TEMPLATE_DECL? - -If a base is a parm, we can't check anything about it. If a base is not -a parm, we need to check it for name binding. Do finish_base_struct if -no bases are parameterized (only if none, including indirect, are -parms). Nah, don't bother trying to do any of this until instantiation --- we only need to do name binding in advance. - -Always set up method vec and fields, inc. synthesized methods. Really? -We can't know the types of the copy folks, or whether we need a -destructor, or can have a default ctor, until we know our bases and -fields. Otherwise, we can assume and fix ourselves later. Hopefully. - -@node Access Control, Error Reporting, Templates, Top -@section Access Control -The function compute_access returns one of three values: - -@table @code -@item access_public -means that the field can be accessed by the current lexical scope. - -@item access_protected -means that the field cannot be accessed by the current lexical scope -because it is protected. - -@item access_private -means that the field cannot be accessed by the current lexical scope -because it is private. -@end table - -DECL_ACCESS is used for access declarations; alter_access creates a list -of types and accesses for a given decl. - -Formerly, DECL_@{PUBLIC,PROTECTED,PRIVATE@} corresponded to the return -codes of compute_access and were used as a cache for compute_access. -Now they are not used at all. - -TREE_PROTECTED and TREE_PRIVATE are used to record the access levels -granted by the containing class. BEWARE: TREE_PUBLIC means something -completely unrelated to access control! - -@node Error Reporting, Parser, Access Control, Top -@section Error Reporting - -The C++ front-end uses a call-back mechanism to allow functions to print -out reasonable strings for types and functions without putting extra -logic in the functions where errors are found. The interface is through -the @code{cp_error} function (or @code{cp_warning}, etc.). The -syntax is exactly like that of @code{error}, except that a few more -conversions are supported: - -@itemize @bullet -@item -%C indicates a value of `enum tree_code'. -@item -%D indicates a *_DECL node. -@item -%E indicates a *_EXPR node. -@item -%L indicates a value of `enum languages'. -@item -%P indicates the name of a parameter (i.e. "this", "1", "2", ...) -@item -%T indicates a *_TYPE node. -@item -%O indicates the name of an operator (MODIFY_EXPR -> "operator ="). - -@end itemize - -There is some overlap between these; for instance, any of the node -options can be used for printing an identifier (though only @code{%D} -tries to decipher function names). - -For a more verbose message (@code{class foo} as opposed to just @code{foo}, -including the return type for functions), use @code{%#c}. -To have the line number on the error message indicate the line of the -DECL, use @code{cp_error_at} and its ilk; to indicate which argument you want, -use @code{%+D}, or it will default to the first. - -@node Parser, Copying Objects, Error Reporting, Top -@section Parser - -Some comments on the parser: - -The @code{after_type_declarator} / @code{notype_declarator} hack is -necessary in order to allow redeclarations of @code{TYPENAME}s, for -instance - -@example -typedef int foo; -class A @{ - char *foo; -@}; -@end example - -In the above, the first @code{foo} is parsed as a @code{notype_declarator}, -and the second as a @code{after_type_declarator}. - -Ambiguities: - -There are currently four reduce/reduce ambiguities in the parser. They are: - -1) Between @code{template_parm} and -@code{named_class_head_sans_basetype}, for the tokens @code{aggr -identifier}. This situation occurs in code looking like - -@example -template <class T> class A @{ @}; -@end example - -It is ambiguous whether @code{class T} should be parsed as the -declaration of a template type parameter named @code{T} or an unnamed -constant parameter of type @code{class T}. Section 14.6, paragraph 3 of -the January '94 working paper states that the first interpretation is -the correct one. This ambiguity results in two reduce/reduce conflicts. - -2) Between @code{primary} and @code{type_id} for code like @samp{int()} -in places where both can be accepted, such as the argument to -@code{sizeof}. Section 8.1 of the pre-San Diego working paper specifies -that these ambiguous constructs will be interpreted as @code{typename}s. -This ambiguity results in six reduce/reduce conflicts between -@samp{absdcl} and @samp{functional_cast}. - -3) Between @code{functional_cast} and -@code{complex_direct_notype_declarator}, for various token strings. -This situation occurs in code looking like - -@example -int (*a); -@end example - -This code is ambiguous; it could be a declaration of the variable -@samp{a} as a pointer to @samp{int}, or it could be a functional cast of -@samp{*a} to @samp{int}. Section 6.8 specifies that the former -interpretation is correct. This ambiguity results in 7 reduce/reduce -conflicts. Another aspect of this ambiguity is code like 'int (x[2]);', -which is resolved at the '[' and accounts for 6 reduce/reduce conflicts -between @samp{direct_notype_declarator} and -@samp{primary}/@samp{overqualified_id}. Finally, there are 4 r/r -conflicts between @samp{expr_or_declarator} and @samp{primary} over code -like 'int (a);', which could probably be resolved but would also -probably be more trouble than it's worth. In all, this situation -accounts for 17 conflicts. Ack! - -The second case above is responsible for the failure to parse 'LinppFile -ppfile (String (argv[1]), &outs, argc, argv);' (from Rogue Wave -Math.h++) as an object declaration, and must be fixed so that it does -not resolve until later. - -4) Indirectly between @code{after_type_declarator} and @code{parm}, for -type names. This occurs in (as one example) code like - -@example -typedef int foo, bar; -class A @{ - foo (bar); -@}; -@end example - -What is @code{bar} inside the class definition? We currently interpret -it as a @code{parm}, as does Cfront, but IBM xlC interprets it as an -@code{after_type_declarator}. I believe that xlC is correct, in light -of 7.1p2, which says "The longest sequence of @i{decl-specifiers} that -could possibly be a type name is taken as the @i{decl-specifier-seq} of -a @i{declaration}." However, it seems clear that this rule must be -violated in the case of constructors. This ambiguity accounts for 8 -conflicts. - -Unlike the others, this ambiguity is not recognized by the Working Paper. - -@node Copying Objects, Exception Handling, Parser, Top -@section Copying Objects - -The generated copy assignment operator in g++ does not currently do the -right thing for multiple inheritance involving virtual bases; it just -calls the copy assignment operators for its direct bases. What it -should probably do is: - -1) Split up the copy assignment operator for all classes that have -vbases into "copy my vbases" and "copy everything else" parts. Or do -the trickiness that the constructors do to ensure that vbases don't get -initialized by intermediate bases. - -2) Wander through the class lattice, find all vbases for which no -intermediate base has a user-defined copy assignment operator, and call -their "copy everything else" routines. If not all of my vbases satisfy -this criterion, warn, because this may be surprising behavior. - -3) Call the "copy everything else" routine for my direct bases. - -If we only have one direct base, we can just foist everything off onto -them. - -This issue is currently under discussion in the core reflector -(2/28/94). - -@node Exception Handling, Free Store, Copying Objects, Top -@section Exception Handling - -Note, exception handling in g++ is still under development. - -This section describes the mapping of C++ exceptions in the C++ -front-end, into the back-end exception handling framework. - -The basic mechanism of exception handling in the back-end is -unwind-protect a la elisp. This is a general, robust, and language -independent representation for exceptions. - -The C++ front-end exceptions are mapping into the unwind-protect -semantics by the C++ front-end. The mapping is describe below. - -When -frtti is used, rtti is used to do exception object type checking, -when it isn't used, the encoded name for the type of the object being -thrown is used instead. All code that originates exceptions, even code -that throws exceptions as a side effect, like dynamic casting, and all -code that catches exceptions must be compiled with either -frtti, or --fno-rtti. It is not possible to mix rtti base exception handling -objects with code that doesn't use rtti. The exceptions to this, are -code that doesn't catch or throw exceptions, catch (...), and code that -just rethrows an exception. - -Currently we use the normal mangling used in building functions names -(int's are "i", const char * is PCc) to build the non-rtti base type -descriptors for exception handling. These descriptors are just plain -NULL terminated strings, and internally they are passed around as char -*. - -In C++, all cleanups should be protected by exception regions. The -region starts just after the reason why the cleanup is created has -ended. For example, with an automatic variable, that has a constructor, -it would be right after the constructor is run. The region ends just -before the finalization is expanded. Since the backend may expand the -cleanup multiple times along different paths, once for normal end of the -region, once for non-local gotos, once for returns, etc, the backend -must take special care to protect the finalization expansion, if the -expansion is for any other reason than normal region end, and it is -`inline' (it is inside the exception region). The backend can either -choose to move them out of line, or it can created an exception region -over the finalization to protect it, and in the handler associated with -it, it would not run the finalization as it otherwise would have, but -rather just rethrow to the outer handler, careful to skip the normal -handler for the original region. - -In Ada, they will use the more runtime intensive approach of having -fewer regions, but at the cost of additional work at run time, to keep a -list of things that need cleanups. When a variable has finished -construction, they add the cleanup to the list, when the come to the end -of the lifetime of the variable, the run the list down. If the take a -hit before the section finishes normally, they examine the list for -actions to perform. I hope they add this logic into the back-end, as it -would be nice to get that alternative approach in C++. - -On an rs6000, xlC stores exception objects on that stack, under the try -block. When is unwinds down into a handler, the frame pointer is -adjusted back to the normal value for the frame in which the handler -resides, and the stack pointer is left unchanged from the time at which -the object was thrown. This is so that there is always someplace for -the exception object, and nothing can overwrite it, once we start -throwing. The only bad part, is that the stack remains large. - -The below points out some things that work in g++'s exception handling. - -All completely constructed temps and local variables are cleaned up in -all unwinded scopes. Completely constructed parts of partially -constructed objects are cleaned up. This includes partially built -arrays. Exception specifications are now handled. Thrown objects are -now cleaned up all the time. We can now tell if we have an active -exception being thrown or not (__eh_type != 0). We use this to call -terminate if someone does a throw; without there being an active -exception object. uncaught_exception () works. Exception handling -should work right if you optimize. Exception handling should work with --fpic or -fPIC. - -The below points out some flaws in g++'s exception handling, as it now -stands. - -Only exact type matching or reference matching of throw types works when --fno-rtti is used. Only works on a SPARC (like Suns) (both -mflat and --mno-flat models work), SPARClite, Hitachi SH, i386, arm, rs6000, -PowerPC, Alpha, mips, VAX, m68k and z8k machines. SPARC v9 may not -work. HPPA is mostly done, but throwing between a shared library and -user code doesn't yet work. Some targets have support for data-driven -unwinding. Partial support is in for all other machines, but a stack -unwinder called __unwind_function has to be written, and added to -libgcc2 for them. The new EH code doesn't rely upon the -__unwind_function for C++ code, instead it creates per function -unwinders right inside the function, unfortunately, on many platforms -the definition of RETURN_ADDR_RTX in the tm.h file for the machine port -is wrong. See below for details on __unwind_function. RTL_EXPRs for EH -cond variables for && and || exprs should probably be wrapped in -UNSAVE_EXPRs, and RTL_EXPRs tweaked so that they can be unsaved. - -We only do pointer conversions on exception matching a la 15.3 p2 case -3: `A handler with type T, const T, T&, or const T& is a match for a -throw-expression with an object of type E if [3]T is a pointer type and -E is a pointer type that can be converted to T by a standard pointer -conversion (_conv.ptr_) not involving conversions to pointers to private -or protected base classes.' when -frtti is given. - -We don't call delete on new expressions that die because the ctor threw -an exception. See except/18 for a test case. - -15.2 para 13: The exception being handled should be rethrown if control -reaches the end of a handler of the function-try-block of a constructor -or destructor, right now, it is not. - -15.2 para 12: If a return statement appears in a handler of -function-try-block of a constructor, the program is ill-formed, but this -isn't diagnosed. - -15.2 para 11: If the handlers of a function-try-block contain a jump -into the body of a constructor or destructor, the program is ill-formed, -but this isn't diagnosed. - -15.2 para 9: Check that the fully constructed base classes and members -of an object are destroyed before entering the handler of a -function-try-block of a constructor or destructor for that object. - -build_exception_variant should sort the incoming list, so that it -implements set compares, not exact list equality. Type smashing should -smash exception specifications using set union. - -Thrown objects are usually allocated on the heap, in the usual way. If -one runs out of heap space, throwing an object will probably never work. -This could be relaxed some by passing an __in_chrg parameter to track -who has control over the exception object. Thrown objects are not -allocated on the heap when they are pointer to object types. We should -extend it so that all small (<4*sizeof(void*)) objects are stored -directly, instead of allocated on the heap. - -When the backend returns a value, it can create new exception regions -that need protecting. The new region should rethrow the object in -context of the last associated cleanup that ran to completion. - -The structure of the code that is generated for C++ exception handling -code is shown below: - -@example -Ln: throw value; - copy value onto heap - jump throw (Ln, id, address of copy of value on heap) - - try @{ -+Lstart: the start of the main EH region -|... ... -+Lend: the end of the main EH region - @} catch (T o) @{ - ...1 - @} -Lresume: - nop used to make sure there is something before - the next region ends, if there is one -... ... - - jump Ldone -[ -Lmainhandler: handler for the region Lstart-Lend - cleanup -] zero or more, depending upon automatic vars with dtors -+Lpartial: -| jump Lover -+Lhere: - rethrow (Lhere, same id, same obj); -Lterm: handler for the region Lpartial-Lhere - call terminate -Lover: -[ - [ - call throw_type_match - if (eq) @{ - ] these lines disappear when there is no catch condition -+Lsregion2: -| ...1 -| jump Lresume -|Lhandler: handler for the region Lsregion2-Leregion2 -| rethrow (Lresume, same id, same obj); -+Leregion2 - @} -] there are zero or more of these sections, depending upon how many - catch clauses there are ------------------------------ expand_end_all_catch -------------------------- - here we have fallen off the end of all catch - clauses, so we rethrow to outer - rethrow (Lresume, same id, same obj); ------------------------------ expand_end_all_catch -------------------------- -[ -L1: maybe throw routine -] depending upon if we have expanded it or not -Ldone: - ret - -start_all_catch emits labels: Lresume, - -@end example - -The __unwind_function takes a pointer to the throw handler, and is -expected to pop the stack frame that was built to call it, as well as -the frame underneath and then jump to the throw handler. It must -restore all registers to their proper values as well as all other -machine state as determined by the context in which we are unwinding -into. The way I normally start is to compile: - - void *g; - foo(void* a) @{ g = a; @} - -with -S, and change the thing that alters the PC (return, or ret -usually) to not alter the PC, making sure to leave all other semantics -(like adjusting the stack pointer, or frame pointers) in. After that, -replicate the prologue once more at the end, again, changing the PC -altering instructions, and finally, at the very end, jump to `g'. - -It takes about a week to write this routine, if someone wants to -volunteer to write this routine for any architecture, exception support -for that architecture will be added to g++. Please send in those code -donations. One other thing that needs to be done, is to double check -that __builtin_return_address (0) works. - -@subsection Specific Targets - -For the alpha, the __unwind_function will be something resembling: - -@example -void -__unwind_function(void *ptr) -@{ - /* First frame */ - asm ("ldq $15, 8($30)"); /* get the saved frame ptr; 15 is fp, 30 is sp */ - asm ("bis $15, $15, $30"); /* reload sp with the fp we found */ - - /* Second frame */ - asm ("ldq $15, 8($30)"); /* fp */ - asm ("bis $15, $15, $30"); /* reload sp with the fp we found */ - - /* Return */ - asm ("ret $31, ($16), 1"); /* return to PTR, stored in a0 */ -@} -@end example - -@noindent -However, there are a few problems preventing it from working. First of -all, the gcc-internal function @code{__builtin_return_address} needs to -work given an argument of 0 for the alpha. As it stands as of August -30th, 1995, the code for @code{BUILT_IN_RETURN_ADDRESS} in @file{expr.c} -will definitely not work on the alpha. Instead, we need to define -the macros @code{DYNAMIC_CHAIN_ADDRESS} (maybe), -@code{RETURN_ADDR_IN_PREVIOUS_FRAME}, and definitely need a new -definition for @code{RETURN_ADDR_RTX}. - -In addition (and more importantly), we need a way to reliably find the -frame pointer on the alpha. The use of the value 8 above to restore the -frame pointer (register 15) is incorrect. On many systems, the frame -pointer is consistently offset to a specific point on the stack. On the -alpha, however, the frame pointer is pushed last. First the return -address is stored, then any other registers are saved (e.g., @code{s0}), -and finally the frame pointer is put in place. So @code{fp} could have -an offset of 8, but if the calling function saved any registers at all, -they add to the offset. - -The only places the frame size is noted are with the @samp{.frame} -directive, for use by the debugger and the OSF exception handling model -(useless to us), and in the initial computation of the new value for -@code{sp}, the stack pointer. For example, the function may start with: - -@example -lda $30,-32($30) -.frame $15,32,$26,0 -@end example - -@noindent -The 32 above is exactly the value we need. With this, we can be sure -that the frame pointer is stored 8 bytes less---in this case, at 24(sp)). -The drawback is that there is no way that I (Brendan) have found to let -us discover the size of a previous frame @emph{inside} the definition -of @code{__unwind_function}. - -So to accomplish exception handling support on the alpha, we need two -things: first, a way to figure out where the frame pointer was stored, -and second, a functional @code{__builtin_return_address} implementation -for except.c to be able to use it. - -Or just support DWARF 2 unwind info. - -@subsection New Backend Exception Support - -This subsection discusses various aspects of the design of the -data-driven model being implemented for the exception handling backend. - -The goal is to generate enough data during the compilation of user code, -such that we can dynamically unwind through functions at run time with a -single routine (@code{__throw}) that lives in libgcc.a, built by the -compiler, and dispatch into associated exception handlers. - -This information is generated by the DWARF 2 debugging backend, and -includes all of the information __throw needs to unwind an arbitrary -frame. It specifies where all of the saved registers and the return -address can be found at any point in the function. - -Major disadvantages when enabling exceptions are: - -@itemize @bullet -@item -Code that uses caller saved registers, can't, when flow can be -transferred into that code from an exception handler. In high performance -code this should not usually be true, so the effects should be minimal. - -@end itemize - -@subsection Backend Exception Support - -The backend must be extended to fully support exceptions. Right now -there are a few hooks into the alpha exception handling backend that -resides in the C++ frontend from that backend that allows exception -handling to work in g++. An exception region is a segment of generated -code that has a handler associated with it. The exception regions are -denoted in the generated code as address ranges denoted by a starting PC -value and an ending PC value of the region. Some of the limitations -with this scheme are: - -@itemize @bullet -@item -The backend replicates insns for such things as loop unrolling and -function inlining. Right now, there are no hooks into the frontend's -exception handling backend to handle the replication of insns. When -replication happens, a new exception region descriptor needs to be -generated for the new region. - -@item -The backend expects to be able to rearrange code, for things like jump -optimization. Any rearranging of the code needs have exception region -descriptors updated appropriately. - -@item -The backend can eliminate dead code. Any associated exception region -descriptor that refers to fully contained code that has been eliminated -should also be removed, although not doing this is harmless in terms of -semantics. - -@end itemize - -The above is not meant to be exhaustive, but does include all things I -have thought of so far. I am sure other limitations exist. - -Below are some notes on the migration of the exception handling code -backend from the C++ frontend to the backend. - -NOTEs are to be used to denote the start of an exception region, and the -end of the region. I presume that the interface used to generate these -notes in the backend would be two functions, start_exception_region and -end_exception_region (or something like that). The frontends are -required to call them in pairs. When marking the end of a region, an -argument can be passed to indicate the handler for the marked region. -This can be passed in many ways, currently a tree is used. Another -possibility would be insns for the handler, or a label that denotes a -handler. I have a feeling insns might be the best way to pass it. -Semantics are, if an exception is thrown inside the region, control is -transferred unconditionally to the handler. If control passes through -the handler, then the backend is to rethrow the exception, in the -context of the end of the original region. The handler is protected by -the conventional mechanisms; it is the frontend's responsibility to -protect the handler, if special semantics are required. - -This is a very low level view, and it would be nice is the backend -supported a somewhat higher level view in addition to this view. This -higher level could include source line number, name of the source file, -name of the language that threw the exception and possibly the name of -the exception. Kenner may want to rope you into doing more than just -the basics required by C++. You will have to resolve this. He may want -you to do support for non-local gotos, first scan for exception handler, -if none is found, allow the debugger to be entered, without any cleanups -being done. To do this, the backend would have to know the difference -between a cleanup-rethrower, and a real handler, if would also have to -have a way to know if a handler `matches' a thrown exception, and this -is frontend specific. - -The stack unwinder is one of the hardest parts to do. It is highly -machine dependent. The form that kenner seems to like was a couple of -macros, that would do the machine dependent grunt work. One preexisting -function that might be of some use is __builtin_return_address (). One -macro he seemed to want was __builtin_return_address, and the other -would do the hard work of fixing up the registers, adjusting the stack -pointer, frame pointer, arg pointer and so on. - - -@node Free Store, Mangling, Exception Handling, Top -@section Free Store - -@code{operator new []} adds a magic cookie to the beginning of arrays -for which the number of elements will be needed by @code{operator delete -[]}. These are arrays of objects with destructors and arrays of objects -that define @code{operator delete []} with the optional size_t argument. -This cookie can be examined from a program as follows: - -@example -typedef unsigned long size_t; -extern "C" int printf (const char *, ...); - -size_t nelts (void *p) -@{ - struct cookie @{ - size_t nelts __attribute__ ((aligned (sizeof (double)))); - @}; - - cookie *cp = (cookie *)p; - --cp; - - return cp->nelts; -@} - -struct A @{ - ~A() @{ @} -@}; - -main() -@{ - A *ap = new A[3]; - printf ("%ld\n", nelts (ap)); -@} -@end example - -@section Linkage -The linkage code in g++ is horribly twisted in order to meet two design goals: - -1) Avoid unnecessary emission of inlines and vtables. - -2) Support pedantic assemblers like the one in AIX. - -To meet the first goal, we defer emission of inlines and vtables until -the end of the translation unit, where we can decide whether or not they -are needed, and how to emit them if they are. - -@node Mangling, Concept Index, Free Store, Top -@section Function name mangling for C++ and Java - -Both C++ and Jave provide overloaded function and methods, -which are methods with the same types but different parameter lists. -Selecting the correct version is done at compile time. -Though the overloaded functions have the same name in the source code, -they need to be translated into different assembler-level names, -since typical assemblers and linkers cannot handle overloading. -This process of encoding the parameter types with the method name -into a unique name is called @dfn{name mangling}. The inverse -process is called @dfn{demangling}. - -It is convenient that C++ and Java use compatible mangling schemes, -since the makes life easier for tools such as gdb, and it eases -integration between C++ and Java. - -Note there is also a standard "Jave Native Interface" (JNI) which -implements a different calling convention, and uses a different -mangling scheme. The JNI is a rather abstract ABI so Java can call methods -written in C or C++; -we are concerned here about a lower-level interface primarily -intended for methods written in Java, but that can also be used for C++ -(and less easily C). - -Note that on systems that follow BSD tradition, a C identifier @code{var} -would get "mangled" into the assembler name @samp{_var}. On such -systems, all other mangled names are also prefixed by a @samp{_} -which is not shown in the following examples. - -@subsection Method name mangling - -C++ mangles a method by emitting the function name, followed by @code{__}, -followed by encodings of any method qualifiers (such as @code{const}), -followed by the mangling of the method's class, -followed by the mangling of the parameters, in order. - -For example @code{Foo::bar(int, long) const} is mangled -as @samp{bar__C3Fooil}. - -For a constructor, the method name is left out. -That is @code{Foo::Foo(int, long) const} is mangled -as @samp{__C3Fooil}. - -GNU Java does the same. - -@subsection Primitive types - -The C++ types @code{int}, @code{long}, @code{short}, @code{char}, -and @code{long long} are mangled as @samp{i}, @samp{l}, -@samp{s}, @samp{c}, and @samp{x}, respectively. -The corresponding unsigned types have @samp{U} prefixed -to the mangling. The type @code{signed char} is mangled @samp{Sc}. - -The C++ and Java floating-point types @code{float} and @code{double} -are mangled as @samp{f} and @samp{d} respectively. - -The C++ @code{bool} type and the Java @code{boolean} type are -mangled as @samp{b}. - -The C++ @code{wchar_t} and the Java @code{char} types are -mangled as @samp{w}. - -The Java integral types @code{byte}, @code{short}, @code{int} -and @code{long} are mangled as @samp{c}, @samp{s}, @samp{i}, -and @samp{x}, respectively. - -C++ code that has included @code{javatypes.h} will mangle -the typedefs @code{jbyte}, @code{jshort}, @code{jint} -and @code{jlong} as respectively @samp{c}, @samp{s}, @samp{i}, -and @samp{x}. (This has not been implemented yet.) - -@subsection Mangling of simple names - -A simple class, package, template, or namespace name is -encoded as the number of characters in the name, followed by -the actual characters. Thus the class @code{Foo} -is encoded as @samp{3Foo}. - -If any of the characters in the name are not alphanumeric -(i.e not one of the standard ASCII letters, digits, or '_'), -or the initial character is a digit, then the name is -mangled as a sequence of encoded Unicode letters. -A Unicode encoding starts with a @samp{U} to indicate -that Unicode escapes are used, followed by the number of -bytes used by the Unicode encoding, followed by the bytes -representing the encoding. ASSCI letters and -non-initial digits are encoded without change. However, all -other characters (including underscore and initial digits) are -translated into a sequence starting with an underscore, -followed by the big-endian 4-hex-digit lower-case encoding of the character. - -If a method name contains Unicode-escaped characters, the -entire mangled method name is followed by a @samp{U}. - -For example, the method @code{X\u0319::M\u002B(int)} is encoded as -@samp{M_002b__U6X_0319iU}. - - -@subsection Pointer and reference types - -A C++ pointer type is mangled as @samp{P} followed by the -mangling of the type pointed to. - -A C++ reference type as mangled as @samp{R} followed by the -mangling of the type referenced. - -A Java object reference type is equivalent -to a C++ pointer parameter, so we mangle such an parameter type -as @samp{P} followed by the mangling of the class name. - -@subsection Squangled type compression - -Squangling (enabled with the @samp{-fsquangle} option), utilizes the -@samp{B} code to indicate reuse of a previously seen type within an -indentifier. Types are recognized in a left to right manner and given -increasing values, which are appended to the code in the standard -manner. Ie, multiple digit numbers are delimited by @samp{_} -characters. A type is considered to be any non primitive type, -regardless of whether its a parameter, template parameter, or entire -template. Certain codes are considered modifiers of a type, and are not -included as part of the type. These are the @samp{C}, @samp{V}, -@samp{P}, @samp{A}, @samp{R}, @samp{U} and @samp{u} codes, denoting -constant, volatile, pointer, array, reference, unsigned, and restrict. -These codes may precede a @samp{B} type in order to make the required -modifications to the type. - -For example: -@example -template <class T> class class1 @{ @}; - -template <class T> class class2 @{ @}; - -class class3 @{ @}; - -int f(class2<class1<class3> > a ,int b, const class1<class3>&c, class3 *d) @{ @} - - B0 -> class2<class1<class3> - B1 -> class1<class3> - B2 -> class3 -@end example -Produces the mangled name @samp{f__FGt6class21Zt6class11Z6class3iRCB1PB2}. -The int parameter is a basic type, and does not receive a B encoding... - -@subsection Qualified names - -Both C++ and Java allow a class to be lexically nested inside another -class. C++ also supports namespaces (not yet implemented by G++). -Java also supports packages. - -These are all mangled the same way: First the letter @samp{Q} -indicates that we are emitting a qualified name. -That is followed by the number of parts in the qualified name. -If that number is 9 or less, it is emitted with no delimiters. -Otherwise, an underscore is written before and after the count. -Then follows each part of the qualified name, as described above. - -For example @code{Foo::\u0319::Bar} is encoded as -@samp{Q33FooU5_03193Bar}. - -Squangling utilizes the the letter @samp{K} to indicate a -remembered portion of a qualified name. As qualified names are processed -for an identifier, the names are numbered and remembered in a -manner similar to the @samp{B} type compression code. -Names are recognized left to right, and given increasing values, which are -appended to the code in the standard manner. ie, multiple digit numbers -are delimited by @samp{_} characters. - -For example -@example -class Andrew -@{ - class WasHere - @{ - class AndHereToo - @{ - @}; - @}; -@}; - -f(Andrew&r1, Andrew::WasHere& r2, Andrew::WasHere::AndHereToo& r3) @{ @} - - K0 -> Andrew - K1 -> Andrew::WasHere - K2 -> Andrew::WasHere::AndHereToo -@end example -Function @samp{f()} would be mangled as : -@samp{f__FR6AndrewRQ2K07WasHereRQ2K110AndHereToo} - -There are some occasions when either a @samp{B} or @samp{K} code could -be chosen, preference is always given to the @samp{B} code. Ie, the example -in the section on @samp{B} mangling could have used a @samp{K} code -instead of @samp{B2}. - -@subsection Templates - -A class template instantiation is encoded as the letter @samp{t}, -followed by the encoding of the template name, followed -the number of template parameters, followed by encoding of the template -parameters. If a template parameter is a type, it is written -as a @samp{Z} followed by the encoding of the type. - -A function template specialization (either an instantiation or an -explicit specialization) is encoded by an @samp{H} followed by the -encoding of the template parameters, as described above, followed by an -@samp{_}, the encoding of the argument types to the template function -(not the specialization), another @samp{_}, and the return type. (Like -the argument types, the return type is the return type of the function -template, not the specialization.) Template parameters in the argument -and return types are encoded by an @samp{X} for type parameters, or a -@samp{Y} for constant parameters, an index indicating their position -in the template parameter list declaration, and their template depth. - -@subsection Arrays - -C++ array types are mangled by emitting @samp{A}, followed by -the length of the array, followed by an @samp{_}, followed by -the mangling of the element type. Of course, normally -array parameter types decay into a pointer types, so you -don't see this. - -Java arrays are objects. A Java type @code{T[]} is mangled -as if it were the C++ type @code{JArray<T>}. -For example @code{java.lang.String[]} is encoded as -@samp{Pt6JArray1ZPQ34java4lang6String}. - -@subsection Static fields - -Both C++ and Java classes can have static fields. -These are allocated statically, and are shared among all instances. - -The mangling starts with a prefix (@samp{_} in most systems), which is -followed by the mangling -of the class name, followed by the "joiner" and finally the field name. -The joiner (see @code{JOINER} in @code{cp-tree.h}) is a special -separator character. For historical reasons (and idiosyncracies -of assembler syntax) it can @samp{$} or @samp{.} (or even -@samp{_} on a few systems). If the joiner is @samp{_} then the prefix -is @samp{__static_} instead of just @samp{_}. - -For example @code{Foo::Bar::var} (or @code{Foo.Bar.var} in Java syntax) -would be encoded as @samp{_Q23Foo3Bar$var} or @samp{_Q23Foo3Bar.var} -(or rarely @samp{__static_Q23Foo3Bar_var}). - -If the name of a static variable needs Unicode escapes, -the Unicode indicator @samp{U} comes before the "joiner". -This @code{\u1234Foo::var\u3445} becomes @code{_U8_1234FooU.var_3445}. - -@subsection Table of demangling code characters - -The following special characters are used in mangling: - -@table @samp -@item A -Indicates a C++ array type. - -@item b -Encodes the C++ @code{bool} type, -and the Java @code{boolean} type. - -@item B -Used for squangling. Similar in concept to the 'T' non-squangled code. - -@item c -Encodes the C++ @code{char} type, and the Java @code{byte} type. - -@item C -A modifier to indicate a @code{const} type. -Also used to indicate a @code{const} member function -(in which cases it precedes the encoding of the method's class). - -@item d -Encodes the C++ and Java @code{double} types. - -@item e -Indicates extra unknown arguments @code{...}. - -@item E -Indicates the opening parenthesis of an expression. - -@item f -Encodes the C++ and Java @code{float} types. - -@item F -Used to indicate a function type. - -@item H -Used to indicate a template function. - -@item i -Encodes the C++ and Java @code{int} types. - -@item J -Indicates a complex type. - -@item K -Used by squangling to compress qualified names. - -@item l -Encodes the C++ @code{long} type. - -@item n -Immediate repeated type. Followed by the repeat count. - -@item N -Repeated type. Followed by the repeat count of the repeated type, -followed by the type index of the repeated type. Due to a bug in -g++ 2.7.2, this is only generated if index is 0. Superceded by -@samp{n} when squangling. - -@item P -Indicates a pointer type. Followed by the type pointed to. - -@item Q -Used to mangle qualified names, which arise from nested classes. -Also used for namespaces. -In Java used to mangle package-qualified names, and inner classes. - -@item r -Encodes the GNU C++ @code{long double} type. - -@item R -Indicates a reference type. Followed by the referenced type. - -@item s -Encodes the C++ and java @code{short} types. - -@item S -A modifier that indicates that the following integer type is signed. -Only used with @code{char}. - -Also used as a modifier to indicate a static member function. - -@item t -Indicates a template instantiation. - -@item T -A back reference to a previously seen type. - -@item U -A modifier that indicates that the following integer type is unsigned. -Also used to indicate that the following class or namespace name -is encoded using Unicode-mangling. - -@item u -The @code{restrict} type qualifier. - -@item v -Encodes the C++ and Java @code{void} types. - -@item V -A modifier for a @code{volatile} type or method. - -@item w -Encodes the C++ @code{wchar_t} type, and the Java @code{char} types. - -@item W -Indicates the closing parenthesis of an expression. - -@item x -Encodes the GNU C++ @code{long long} type, and the Java @code{long} type. - -@item X -Encodes a template type parameter, when part of a function type. - -@item Y -Encodes a template constant parameter, when part of a function type. - -@item Z -Used for template type parameters. - -@end table - -The letters @samp{G}, @samp{M}, @samp{O}, and @samp{p} -also seem to be used for obscure purposes ... - -@node Concept Index, , Mangling, Top - -@section Concept Index - -@printindex cp - -@bye diff --git a/gcc/cp/hash.h b/gcc/cp/hash.h deleted file mode 100755 index ced034e..0000000 --- a/gcc/cp/hash.h +++ /dev/null @@ -1,231 +0,0 @@ -/* KR-C code produced by gperf version 2.7.1 (19981006 egcs) */ -/* Command-line: gperf -L KR-C -F , 0, 0 -p -j1 -g -o -t -N is_reserved_word -k1,4,7,$ ../../../gcc/cp/gxx.gperf */ -/* Command-line: gperf -L KR-C -F ', 0, 0' -p -j1 -g -o -t -N is_reserved_word -k1,4,$,7 gplus.gperf */ -struct resword { char *name; short token; enum rid rid;}; - -#define TOTAL_KEYWORDS 106 -#define MIN_WORD_LENGTH 2 -#define MAX_WORD_LENGTH 16 -#define MIN_HASH_VALUE 4 -#define MAX_HASH_VALUE 250 -/* maximum key range = 247, duplicates = 0 */ - -static inline unsigned int -hash (str, len) - register char *str; - register unsigned int len; -{ - static unsigned char asso_values[] = - { - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 0, 251, 64, 93, 3, - 0, 0, 74, 35, 0, 26, 251, 2, 31, 65, - 23, 76, 7, 19, 45, 37, 6, 64, 12, 38, - 14, 4, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251, 251, 251, 251, 251, - 251, 251, 251, 251, 251, 251 - }; - register int hval = len; - - switch (hval) - { - default: - case 7: - hval += asso_values[(unsigned char)str[6]]; - case 6: - case 5: - case 4: - hval += asso_values[(unsigned char)str[3]]; - case 3: - case 2: - case 1: - hval += asso_values[(unsigned char)str[0]]; - break; - } - return hval + asso_values[(unsigned char)str[len - 1]]; -} - -static inline struct resword * -is_reserved_word (str, len) - register char *str; - register unsigned int len; -{ - static struct resword wordlist[] = - { - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"else", ELSE, NORID,}, - {"", 0, 0}, - {"delete", DELETE, NORID,}, - {"case", CASE, NORID,}, - {"__real__", REALPART, NORID}, - {"", 0, 0}, - {"true", CXX_TRUE, NORID,}, - {"catch", CATCH, NORID,}, - {"typeid", TYPEID, NORID,}, - {"try", TRY, NORID,}, - {"", 0, 0}, {"", 0, 0}, - {"void", TYPESPEC, RID_VOID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"private", VISSPEC, RID_PRIVATE,}, - {"template", TEMPLATE, RID_TEMPLATE,}, - {"protected", VISSPEC, RID_PROTECTED,}, - {"extern", SCSPEC, RID_EXTERN,}, - {"", 0, 0}, {"", 0, 0}, - {"not", '!', NORID,}, - {"", 0, 0}, - {"__signed", TYPESPEC, RID_SIGNED}, - {"int", TYPESPEC, RID_INT,}, - {"__signed__", TYPESPEC, RID_SIGNED}, - {"__real", REALPART, NORID}, - {"", 0, 0}, - {"xor_eq", ASSIGN, NORID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"__attribute", ATTRIBUTE, NORID}, - {"__asm__", ASM_KEYWORD, NORID}, - {"__attribute__", ATTRIBUTE, NORID}, - {"compl", '~', NORID,}, - {"public", VISSPEC, RID_PUBLIC,}, - {"not_eq", EQCOMPARE, NORID,}, - {"switch", SWITCH, NORID,}, - {"__extension__", EXTENSION, NORID}, - {"const", CV_QUALIFIER, RID_CONST,}, - {"static", SCSPEC, RID_STATIC,}, - {"", 0, 0}, - {"__inline", SCSPEC, RID_INLINE}, - {"", 0, 0}, - {"__inline__", SCSPEC, RID_INLINE}, - {"__restrict__", CV_QUALIFIER, RID_RESTRICT}, - {"inline", SCSPEC, RID_INLINE,}, - {"const_cast", CONST_CAST, NORID,}, - {"static_cast", STATIC_CAST, NORID,}, - {"__restrict", CV_QUALIFIER, RID_RESTRICT}, - {"xor", '^', NORID,}, - {"__wchar_t", TYPESPEC, RID_WCHAR /* Unique to ANSI C++ */,}, - {"new", NEW, NORID,}, - {"__alignof__", ALIGNOF, NORID}, - {"signed", TYPESPEC, RID_SIGNED,}, - {"and", ANDAND, NORID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"explicit", SCSPEC, RID_EXPLICIT,}, - {"", 0, 0}, - {"__imag__", IMAGPART, NORID}, - {"while", WHILE, NORID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"do", DO, NORID,}, - {"typename", TYPENAME_KEYWORD, NORID,}, - {"friend", SCSPEC, RID_FRIEND,}, - {"continue", CONTINUE, NORID,}, - {"class", AGGR, RID_CLASS,}, - {"default", DEFAULT, NORID,}, - {"this", THIS, NORID,}, - {"dynamic_cast", DYNAMIC_CAST, NORID,}, - {"typeof", TYPEOF, NORID,}, - {"virtual", SCSPEC, RID_VIRTUAL,}, - {"export", SCSPEC, RID_EXPORT,}, - {"and_eq", ASSIGN, NORID,}, - {"__typeof__", TYPEOF, NORID}, - {"__const__", CV_QUALIFIER, RID_CONST}, - {"__volatile", CV_QUALIFIER, RID_VOLATILE}, - {"short", TYPESPEC, RID_SHORT,}, - {"__volatile__", CV_QUALIFIER, RID_VOLATILE}, - {"__const", CV_QUALIFIER, RID_CONST}, - {"namespace", NAMESPACE, NORID,}, - {"char", TYPESPEC, RID_CHAR,}, - {"unsigned", TYPESPEC, RID_UNSIGNED,}, - {"double", TYPESPEC, RID_DOUBLE,}, - {"or_eq", ASSIGN, NORID,}, - {"__null", CONSTANT, RID_NULL}, - {"if", IF, NORID,}, - {"__signature__", AGGR, RID_SIGNATURE /* Extension */,}, - {"__label__", LABEL, NORID}, - {"long", TYPESPEC, RID_LONG,}, - {"__imag", IMAGPART, NORID}, - {"__asm", ASM_KEYWORD, NORID}, - {"", 0, 0}, - {"__sigof__", SIGOF, NORID /* Extension */,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"struct", AGGR, RID_RECORD,}, - {"", 0, 0}, - {"volatile", CV_QUALIFIER, RID_VOLATILE,}, - {"false", CXX_FALSE, NORID,}, - {"sizeof", SIZEOF, NORID,}, - {"__complex__", TYPESPEC, RID_COMPLEX}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"for", FOR, NORID,}, - {"or", OROR, NORID,}, - {"register", SCSPEC, RID_REGISTER,}, - {"throw", THROW, NORID,}, - {"", 0, 0}, - {"using", USING, NORID,}, - {"", 0, 0}, {"", 0, 0}, - {"__complex", TYPESPEC, RID_COMPLEX}, - {"", 0, 0}, - {"asm", ASM_KEYWORD, NORID,}, - {"signature", AGGR, RID_SIGNATURE /* Extension */,}, - {"enum", ENUM, NORID,}, - {"reinterpret_cast", REINTERPRET_CAST, NORID,}, - {"mutable", SCSPEC, RID_MUTABLE,}, - {"__alignof", ALIGNOF, NORID}, - {"return", RETURN, NORID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, - {"float", TYPESPEC, RID_FLOAT,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"bool", TYPESPEC, RID_BOOL,}, - {"", 0, 0}, - {"typedef", SCSPEC, RID_TYPEDEF,}, - {"__typeof", TYPEOF, NORID}, - {"bitand", '&', NORID,}, - {"break", BREAK, NORID,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"union", AGGR, RID_UNION,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"goto", GOTO, NORID,}, - {"sigof", SIGOF, NORID /* Extension */,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"bitor", '|', NORID,}, - {"auto", SCSPEC, RID_AUTO,}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, {"", 0, 0}, - {"", 0, 0}, {"", 0, 0}, - {"operator", OPERATOR, NORID,} - }; - - if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH) - { - register int key = hash (str, len); - - if (key <= MAX_HASH_VALUE && key >= 0) - { - register char *s = wordlist[key].name; - - if (*str == *s && !strcmp (str + 1, s + 1)) - return &wordlist[key]; - } - } - return 0; -} diff --git a/gcc/cp/inc/exception b/gcc/cp/inc/exception deleted file mode 100755 index 32efb9f..0000000 --- a/gcc/cp/inc/exception +++ /dev/null @@ -1,39 +0,0 @@ -// Exception Handling support header for -*- C++ -*- -// Copyright (C) 1995, 96-97, 1998 Free Software Foundation - -#ifndef __EXCEPTION__ -#define __EXCEPTION__ - -#pragma interface "exception" - -extern "C++" { - -namespace std { - -class exception { -public: - exception () { } - virtual ~exception () { } - virtual const char* what () const; -}; - -class bad_exception : public exception { -public: - bad_exception () { } - virtual ~bad_exception () { } -}; - -typedef void (*terminate_handler) (); -typedef void (*unexpected_handler) (); - -terminate_handler set_terminate (terminate_handler); -void terminate () __attribute__ ((__noreturn__)); -unexpected_handler set_unexpected (unexpected_handler); -void unexpected () __attribute__ ((__noreturn__)); -bool uncaught_exception (); - -} // namespace std - -} // extern "C++" - -#endif diff --git a/gcc/cp/inc/new b/gcc/cp/inc/new deleted file mode 100755 index c19205b..0000000 --- a/gcc/cp/inc/new +++ /dev/null @@ -1,60 +0,0 @@ -/* CYGNUS LOCAL Embedded C++ whole file */ -// The -*- C++ -*- dynamic memory management header. -// Copyright (C) 1994, 96-97, 1998 Free Software Foundation - -#ifndef __NEW__ -#define __NEW__ - -#pragma interface "new" -#include <stddef.h> - -#ifndef __EMBEDDED_CXX__ -// Exception Handling is forbidden in Embedded C++. -#include <exception> -#define __GCC_THROW(what) throw (what) -#define __GCC_nothing -#else -#define __GCC_THROW(what) -#endif - -extern "C++" { - -namespace std { - -#ifndef __EMBEDDED_CXX__ - class bad_alloc : public exception { - public: - virtual const char* what() const throw() { return "bad_alloc"; } - }; -#endif - - struct nothrow_t {}; - extern const nothrow_t nothrow; - - typedef void (*new_handler)(); - new_handler set_new_handler (new_handler); - -} // namespace std - -// replaceable signatures -void *operator new (size_t) __GCC_THROW (std::bad_alloc); -void *operator new[] (size_t) __GCC_THROW (std::bad_alloc); -void operator delete (void *) __GCC_THROW(__GCC_nothing); -void operator delete[] (void *) __GCC_THROW(__GCC_nothing); -void *operator new (size_t, const nothrow_t&) __GCC_THROW(__GCC_nothing); -void *operator new[] (size_t, const nothrow_t&) __GCC_THROW(__GCC_nothing); -void operator delete (void *, const nothrow_t&) __GCC_THROW(__GCC_nothing); -void operator delete[] (void *, const nothrow_t&) __GCC_THROW(__GCC_nothing); - -// default placement versions of operator new -inline void *operator new(size_t, void *place) __GCC_THROW(__GCC_nothing) { - return place; -} -inline void *operator new[](size_t, void *place) __GCC_THROW(__GCC_nothing) { - return place; -} - -} // extern "C++" - -#endif -/* END CYGNUS LOCAL */ diff --git a/gcc/cp/inc/new.h b/gcc/cp/inc/new.h deleted file mode 100755 index 006be7e..0000000 --- a/gcc/cp/inc/new.h +++ /dev/null @@ -1,11 +0,0 @@ -// -*- C++ -*- forwarding header. - -#ifndef __NEW_H__ -#define __NEW_H__ - -#include <new> - -using std::new_handler; -using std::set_new_handler; - -#endif // __NEW_H__ diff --git a/gcc/cp/inc/typeinfo b/gcc/cp/inc/typeinfo deleted file mode 100755 index 9347849..0000000 --- a/gcc/cp/inc/typeinfo +++ /dev/null @@ -1,58 +0,0 @@ -// RTTI support for -*- C++ -*- -// Copyright (C) 1994, 95-97, 1998 Free Software Foundation - -#ifndef __TYPEINFO__ -#define __TYPEINFO__ - -#pragma interface "typeinfo" - -#include <exception> - -extern "C++" { - -namespace std { - -class type_info { -private: - // assigning type_info is not supported. made private. - type_info& operator= (const type_info&); - type_info (const type_info&); - -protected: - explicit type_info (const char *n): _name (n) { } - - const char *_name; - -public: - // destructor - virtual ~type_info (); - - bool before (const type_info& arg) const; - const char* name () const - { return _name; } - bool operator== (const type_info& arg) const; - bool operator!= (const type_info& arg) const; -}; - -inline bool type_info:: -operator!= (const type_info& arg) const -{ - return !operator== (arg); -} - -class bad_cast : public exception { -public: - bad_cast() { } - virtual ~bad_cast() { } -}; - -class bad_typeid : public exception { - public: - bad_typeid () { } - virtual ~bad_typeid () { } -}; - -} // namespace std - -} // extern "C++" -#endif diff --git a/gcc/cp/init.c b/gcc/cp/init.c deleted file mode 100755 index 847222f..0000000 --- a/gcc/cp/init.c +++ /dev/null @@ -1,3298 +0,0 @@ -/* Handle initialization things in C++. - Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* High-level class interface. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" -#include "output.h" -#include "except.h" -#include "expr.h" -#include "toplev.h" - -extern void compiler_error (); - -/* In C++, structures with well-defined constructors are initialized by - those constructors, unasked. CURRENT_BASE_INIT_LIST - holds a list of stmts for a BASE_INIT term in the grammar. - This list has one element for each base class which must be - initialized. The list elements are [basename, init], with - type basetype. This allows the possibly anachronistic form - (assuming d : a, b, c) "d (int a) : c(a+5), b (a-4), a (a+3)" - where each successive term can be handed down the constructor - line. Perhaps this was not intended. */ -tree current_base_init_list, current_member_init_list; - -static void expand_aggr_vbase_init_1 PROTO((tree, tree, tree, tree)); -static void expand_aggr_vbase_init PROTO((tree, tree, tree, tree)); -static void expand_aggr_init_1 PROTO((tree, tree, tree, tree, int)); -static void expand_default_init PROTO((tree, tree, tree, tree, int)); -static tree build_vec_delete_1 PROTO((tree, tree, tree, tree, tree, - int)); -static void perform_member_init PROTO((tree, tree, tree, int)); -static void sort_base_init PROTO((tree, tree *, tree *)); -static tree build_builtin_delete_call PROTO((tree)); -static int member_init_ok_or_else PROTO((tree, tree, char *)); -static void expand_virtual_init PROTO((tree, tree)); -static tree sort_member_init PROTO((tree)); -static tree build_partial_cleanup_for PROTO((tree)); -static tree initializing_context PROTO((tree)); -static void expand_vec_init_try_block PROTO((tree)); -static void expand_vec_init_catch_clause PROTO((tree, tree, tree, tree)); - -/* Cache the identifier nodes for the magic field of a new cookie. */ -static tree nc_nelts_field_id; - -static tree minus_one; - -/* Set up local variable for this file. MUST BE CALLED AFTER - INIT_DECL_PROCESSING. */ - -static tree BI_header_type, BI_header_size; - -void init_init_processing () -{ - tree fields[1]; - - minus_one = build_int_2 (-1, -1); - - /* Define the structure that holds header information for - arrays allocated via operator new. */ - BI_header_type = make_lang_type (RECORD_TYPE); - nc_nelts_field_id = get_identifier ("nelts"); - fields[0] = build_lang_field_decl (FIELD_DECL, nc_nelts_field_id, sizetype); - finish_builtin_type (BI_header_type, "__new_cookie", fields, - 0, double_type_node); - BI_header_size = size_in_bytes (BI_header_type); -} - -/* Subroutine of emit_base_init. For BINFO, initialize all the - virtual function table pointers, except those that come from - virtual base classes. Initialize binfo's vtable pointer, if - INIT_SELF is true. CAN_ELIDE is true when we know that all virtual - function table pointers in all bases have been initialized already, - probably because their constructors have just be run. ADDR is the - pointer to the object whos vtables we are going to initialize. - - REAL_BINFO is usually the same as BINFO, except when addr is not of - pointer to the type of the real derived type that we want to - initialize for. This is the case when addr is a pointer to a sub - object of a complete object, and we only want to do part of the - complete object's initialization of vtable pointers. This is done - for all virtual table pointers in virtual base classes. REAL_BINFO - is used to find the BINFO_VTABLE that we initialize with. BINFO is - used for conversions of addr to subobjects. - - BINFO_TYPE (real_binfo) must be BINFO_TYPE (binfo). - - Relies upon binfo being inside TYPE_BINFO (TREE_TYPE (TREE_TYPE - (addr))). */ - -void -expand_direct_vtbls_init (real_binfo, binfo, init_self, can_elide, addr) - tree real_binfo, binfo, addr; - int init_self, can_elide; -{ - tree real_binfos = BINFO_BASETYPES (real_binfo); - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree real_base_binfo = TREE_VEC_ELT (real_binfos, i); - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); - if (! TREE_VIA_VIRTUAL (real_base_binfo)) - expand_direct_vtbls_init (real_base_binfo, base_binfo, - is_not_base_vtable, can_elide, addr); - } -#if 0 - /* Before turning this on, make sure it is correct. */ - if (can_elide && ! BINFO_MODIFIED (binfo)) - return; -#endif - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) - { - tree base_ptr = convert_pointer_to_real (binfo, addr); - expand_virtual_init (real_binfo, base_ptr); - } -} - -/* 348 - 351 */ -/* Subroutine of emit_base_init. */ - -static void -perform_member_init (member, name, init, explicit) - tree member, name, init; - int explicit; -{ - tree decl; - tree type = TREE_TYPE (member); - - expand_start_target_temps (); - - if (TYPE_NEEDS_CONSTRUCTING (type) - || (init && TYPE_HAS_CONSTRUCTOR (type))) - { - /* Since `init' is already a TREE_LIST on the current_member_init_list, - only build it into one if we aren't already a list. */ - if (init != NULL_TREE && TREE_CODE (init) != TREE_LIST) - init = build_expr_list (NULL_TREE, init); - - decl = build_component_ref (current_class_ref, name, NULL_TREE, explicit); - - if (explicit - && TREE_CODE (type) == ARRAY_TYPE - && init != NULL_TREE - && TREE_CHAIN (init) == NULL_TREE - && TREE_CODE (TREE_TYPE (TREE_VALUE (init))) == ARRAY_TYPE) - { - /* Initialization of one array from another. */ - expand_vec_init (TREE_OPERAND (decl, 1), decl, - array_type_nelts (type), TREE_VALUE (init), 1); - } - else - expand_aggr_init (decl, init, 0); - } - else - { - if (init == NULL_TREE) - { - if (explicit) - { - /* default-initialization. */ - if (AGGREGATE_TYPE_P (type)) - init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); - else if (TREE_CODE (type) == REFERENCE_TYPE) - { - cp_error ("default-initialization of `%#D', which has reference type", - member); - init = error_mark_node; - } - else - init = integer_zero_node; - } - /* member traversal: note it leaves init NULL */ - else if (TREE_CODE (TREE_TYPE (member)) == REFERENCE_TYPE) - cp_pedwarn ("uninitialized reference member `%D'", member); - } - else if (TREE_CODE (init) == TREE_LIST) - { - /* There was an explicit member initialization. Do some - work in that case. */ - if (TREE_CHAIN (init)) - { - warning ("initializer list treated as compound expression"); - init = build_compound_expr (init); - } - else - init = TREE_VALUE (init); - } - - /* We only build this with a null init if we got it from the - current_member_init_list. */ - if (init || explicit) - { - decl = build_component_ref (current_class_ref, name, NULL_TREE, - explicit); - expand_expr_stmt (build_modify_expr (decl, INIT_EXPR, init)); - } - } - - expand_end_target_temps (); - free_temp_slots (); - - if (TYPE_NEEDS_DESTRUCTOR (type)) - { - tree expr; - - /* All cleanups must be on the function_obstack. */ - push_obstacks_nochange (); - resume_temporary_allocation (); - - expr = build_component_ref (current_class_ref, name, NULL_TREE, - explicit); - expr = build_delete (type, expr, integer_zero_node, - LOOKUP_NONVIRTUAL|LOOKUP_DESTRUCTOR, 0); - - if (expr != error_mark_node) - add_partial_entry (expr); - - pop_obstacks (); - } -} - -extern int warn_reorder; - -/* Subroutine of emit_member_init. */ - -static tree -sort_member_init (t) - tree t; -{ - tree x, member, name, field; - tree init_list = NULL_TREE; - int last_pos = 0; - tree last_field = NULL_TREE; - - for (member = TYPE_FIELDS (t); member ; member = TREE_CHAIN (member)) - { - int pos; - - /* member could be, for example, a CONST_DECL for an enumerated - tag; we don't want to try to initialize that, since it already - has a value. */ - if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member)) - continue; - - for (x = current_member_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) - { - /* If we cleared this out, then pay no attention to it. */ - if (TREE_PURPOSE (x) == NULL_TREE) - continue; - name = TREE_PURPOSE (x); - -#if 0 - /* This happens in templates, since the IDENTIFIER is replaced - with the COMPONENT_REF in tsubst_expr. */ - field = (TREE_CODE (name) == COMPONENT_REF - ? TREE_OPERAND (name, 1) : IDENTIFIER_CLASS_VALUE (name)); -#else - /* Let's find out when this happens. */ - my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 348); - field = IDENTIFIER_CLASS_VALUE (name); -#endif - - /* If one member shadows another, get the outermost one. */ - if (TREE_CODE (field) == TREE_LIST) - field = TREE_VALUE (field); - - if (field == member) - { - if (warn_reorder) - { - if (pos < last_pos) - { - cp_warning_at ("member initializers for `%#D'", last_field); - cp_warning_at (" and `%#D'", field); - warning (" will be re-ordered to match declaration order"); - } - last_pos = pos; - last_field = field; - } - - /* Make sure we won't try to work on this init again. */ - TREE_PURPOSE (x) = NULL_TREE; - x = build_tree_list (name, TREE_VALUE (x)); - goto got_it; - } - } - - /* If we didn't find MEMBER in the list, create a dummy entry - so the two lists (INIT_LIST and the list of members) will be - symmetrical. */ - x = build_tree_list (NULL_TREE, NULL_TREE); - got_it: - init_list = chainon (init_list, x); - } - - /* Initializers for base members go at the end. */ - for (x = current_member_init_list ; x ; x = TREE_CHAIN (x)) - { - name = TREE_PURPOSE (x); - if (name) - { - if (purpose_member (name, init_list)) - { - cp_error ("multiple initializations given for member `%D'", - IDENTIFIER_CLASS_VALUE (name)); - continue; - } - - init_list = chainon (init_list, - build_tree_list (name, TREE_VALUE (x))); - TREE_PURPOSE (x) = NULL_TREE; - } - } - - return init_list; -} - -static void -sort_base_init (t, rbase_ptr, vbase_ptr) - tree t, *rbase_ptr, *vbase_ptr; -{ - tree binfos = BINFO_BASETYPES (TYPE_BINFO (t)); - int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - int i; - tree x; - tree last; - - /* For warn_reorder. */ - int last_pos = 0; - tree last_base = NULL_TREE; - - tree rbases = NULL_TREE; - tree vbases = NULL_TREE; - - /* First walk through and splice out vbase and invalid initializers. - Also replace names with binfos. */ - - last = tree_cons (NULL_TREE, NULL_TREE, current_base_init_list); - for (x = TREE_CHAIN (last); x; x = TREE_CHAIN (x)) - { - tree basetype = TREE_PURPOSE (x); - tree binfo = NULL_TREE; - - if (basetype == NULL_TREE) - { - /* Initializer for single base class. Must not - use multiple inheritance or this is ambiguous. */ - switch (n_baseclasses) - { - case 0: - cp_error ("`%T' does not have a base class to initialize", - current_class_type); - return; - case 1: - break; - default: - cp_error ("unnamed initializer ambiguous for `%T' which uses multiple inheritance", - current_class_type); - return; - } - binfo = TREE_VEC_ELT (binfos, 0); - } - else if (is_aggr_type (basetype, 1)) - { - binfo = binfo_or_else (basetype, t); - if (binfo == NULL_TREE) - continue; - - /* Virtual base classes are special cases. Their initializers - are recorded with this constructor, and they are used when - this constructor is the top-level constructor called. */ - if (TREE_VIA_VIRTUAL (binfo)) - { - tree v = CLASSTYPE_VBASECLASSES (t); - while (BINFO_TYPE (v) != BINFO_TYPE (binfo)) - v = TREE_CHAIN (v); - - vbases = tree_cons (v, TREE_VALUE (x), vbases); - continue; - } - else - { - /* Otherwise, if it is not an immediate base class, complain. */ - for (i = n_baseclasses-1; i >= 0; i--) - if (BINFO_TYPE (binfo) == BINFO_TYPE (TREE_VEC_ELT (binfos, i))) - break; - if (i < 0) - { - cp_error ("`%T' is not an immediate base class of `%T'", - basetype, current_class_type); - continue; - } - } - } - else - my_friendly_abort (365); - - TREE_PURPOSE (x) = binfo; - TREE_CHAIN (last) = x; - last = x; - } - TREE_CHAIN (last) = NULL_TREE; - - /* Now walk through our regular bases and make sure they're initialized. */ - - for (i = 0; i < n_baseclasses; ++i) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int pos; - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - for (x = current_base_init_list, pos = 0; x; x = TREE_CHAIN (x), ++pos) - { - tree binfo = TREE_PURPOSE (x); - - if (binfo == NULL_TREE) - continue; - - if (binfo == base_binfo) - { - if (warn_reorder) - { - if (pos < last_pos) - { - cp_warning_at ("base initializers for `%#T'", last_base); - cp_warning_at (" and `%#T'", BINFO_TYPE (binfo)); - warning (" will be re-ordered to match inheritance order"); - } - last_pos = pos; - last_base = BINFO_TYPE (binfo); - } - - /* Make sure we won't try to work on this init again. */ - TREE_PURPOSE (x) = NULL_TREE; - x = build_tree_list (binfo, TREE_VALUE (x)); - goto got_it; - } - } - - /* If we didn't find BASE_BINFO in the list, create a dummy entry - so the two lists (RBASES and the list of bases) will be - symmetrical. */ - x = build_tree_list (NULL_TREE, NULL_TREE); - got_it: - rbases = chainon (rbases, x); - } - - *rbase_ptr = rbases; - *vbase_ptr = vbases; -} - -/* Perform partial cleanups for a base for exception handling. */ - -static tree -build_partial_cleanup_for (binfo) - tree binfo; -{ - return build_scoped_method_call - (current_class_ref, binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node)); -} - -/* Perform whatever initializations have yet to be done on the base - class of the class variable. These actions are in the global - variable CURRENT_BASE_INIT_LIST. Such an action could be - NULL_TREE, meaning that the user has explicitly called the base - class constructor with no arguments. - - If there is a need for a call to a constructor, we must surround - that call with a pushlevel/poplevel pair, since we are technically - at the PARM level of scope. - - Argument IMMEDIATELY, if zero, forces a new sequence to be - generated to contain these new insns, so it can be emitted later. - This sequence is saved in the global variable BASE_INIT_EXPR. - Otherwise, the insns are emitted into the current sequence. - - Note that emit_base_init does *not* initialize virtual base - classes. That is done specially, elsewhere. */ - -extern tree base_init_expr, rtl_expr_chain; - -void -emit_base_init (t, immediately) - tree t; - int immediately; -{ - tree member; - tree mem_init_list; - tree rbase_init_list, vbase_init_list; - tree t_binfo = TYPE_BINFO (t); - tree binfos = BINFO_BASETYPES (t_binfo); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree expr = NULL_TREE; - - if (! immediately) - { - int momentary; - do_pending_stack_adjust (); - /* Make the RTL_EXPR node temporary, not momentary, - so that rtl_expr_chain doesn't become garbage. */ - momentary = suspend_momentary (); - expr = make_node (RTL_EXPR); - resume_momentary (momentary); - start_sequence_for_rtl_expr (expr); - } - - if (write_symbols == NO_DEBUG) - /* As a matter of principle, `start_sequence' should do this. */ - emit_note (0, -1); - else - /* Always emit a line number note so we can step into constructors. */ - emit_line_note_force (DECL_SOURCE_FILE (current_function_decl), - DECL_SOURCE_LINE (current_function_decl)); - - mem_init_list = sort_member_init (t); - current_member_init_list = NULL_TREE; - - sort_base_init (t, &rbase_init_list, &vbase_init_list); - current_base_init_list = NULL_TREE; - - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - { - tree first_arg = TREE_CHAIN (DECL_ARGUMENTS (current_function_decl)); - - expand_start_cond (first_arg, 0); - expand_aggr_vbase_init (t_binfo, current_class_ref, current_class_ptr, - vbase_init_list); - expand_end_cond (); - } - - /* Now, perform initialization of non-virtual base classes. */ - for (i = 0; i < n_baseclasses; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree init = void_list_node; - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - my_friendly_assert (BINFO_INHERITANCE_CHAIN (base_binfo) == t_binfo, - 999); - - if (TREE_PURPOSE (rbase_init_list)) - init = TREE_VALUE (rbase_init_list); - else if (TYPE_NEEDS_CONSTRUCTING (BINFO_TYPE (base_binfo))) - { - init = NULL_TREE; - if (extra_warnings && copy_args_p (current_function_decl)) - cp_warning ("base class `%#T' should be explicitly initialized in the copy constructor", - BINFO_TYPE (base_binfo)); - } - - if (init != void_list_node) - { - expand_start_target_temps (); - - member = convert_pointer_to_real (base_binfo, current_class_ptr); - expand_aggr_init_1 (base_binfo, NULL_TREE, - build_indirect_ref (member, NULL_PTR), init, - LOOKUP_NORMAL); - - expand_end_target_temps (); - free_temp_slots (); - } - - if (TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - tree expr; - - /* All cleanups must be on the function_obstack. */ - push_obstacks_nochange (); - resume_temporary_allocation (); - expr = build_partial_cleanup_for (base_binfo); - pop_obstacks (); - add_partial_entry (expr); - } - - rbase_init_list = TREE_CHAIN (rbase_init_list); - } - - /* Initialize all the virtual function table fields that - do come from virtual base classes. */ - if (TYPE_USES_VIRTUAL_BASECLASSES (t)) - expand_indirect_vtbls_init (t_binfo, current_class_ref, current_class_ptr); - - /* Initialize all the virtual function table fields that - do not come from virtual base classes. */ - expand_direct_vtbls_init (t_binfo, t_binfo, 1, 1, current_class_ptr); - - for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) - { - tree init, name; - int from_init_list; - - /* member could be, for example, a CONST_DECL for an enumerated - tag; we don't want to try to initialize that, since it already - has a value. */ - if (TREE_CODE (member) != FIELD_DECL || !DECL_NAME (member)) - continue; - - /* See if we had a user-specified member initialization. */ - if (TREE_PURPOSE (mem_init_list)) - { - name = TREE_PURPOSE (mem_init_list); - init = TREE_VALUE (mem_init_list); - from_init_list = 1; - -#if 0 - if (TREE_CODE (name) == COMPONENT_REF) - name = DECL_NAME (TREE_OPERAND (name, 1)); -#else - /* Also see if it's ever a COMPONENT_REF here. If it is, we - need to do `expand_assignment (name, init, 0, 0);' and - a continue. */ - my_friendly_assert (TREE_CODE (name) != COMPONENT_REF, 349); -#endif - } - else - { - name = DECL_NAME (member); - init = DECL_INITIAL (member); - - from_init_list = 0; - - /* Effective C++ rule 12. */ - if (warn_ecpp && init == NULL_TREE - && !DECL_ARTIFICIAL (member) - && TREE_CODE (TREE_TYPE (member)) != ARRAY_TYPE) - cp_warning ("`%D' should be initialized in the member initialization list", member); - } - - perform_member_init (member, name, init, from_init_list); - mem_init_list = TREE_CHAIN (mem_init_list); - } - - /* Now initialize any members from our bases. */ - while (mem_init_list) - { - tree name, init, field; - - if (TREE_PURPOSE (mem_init_list)) - { - name = TREE_PURPOSE (mem_init_list); - init = TREE_VALUE (mem_init_list); - /* XXX: this may need the COMPONENT_REF operand 0 check if - it turns out we actually get them. */ - field = IDENTIFIER_CLASS_VALUE (name); - - /* If one member shadows another, get the outermost one. */ - if (TREE_CODE (field) == TREE_LIST) - { - field = TREE_VALUE (field); - if (decl_type_context (field) != current_class_type) - cp_error ("field `%D' not in immediate context", field); - } - -#if 0 - /* It turns out if you have an anonymous union in the - class, a member from it can end up not being on the - list of fields (rather, the type is), and therefore - won't be seen by the for loop above. */ - - /* The code in this for loop is derived from a general loop - which had this check in it. Theoretically, we've hit - every initialization for the list of members in T, so - we shouldn't have anything but these left in this list. */ - my_friendly_assert (DECL_FIELD_CONTEXT (field) != t, 351); -#endif - - perform_member_init (field, name, init, 1); - } - mem_init_list = TREE_CHAIN (mem_init_list); - } - - if (! immediately) - { - do_pending_stack_adjust (); - my_friendly_assert (base_init_expr == 0, 207); - base_init_expr = expr; - TREE_TYPE (expr) = void_type_node; - RTL_EXPR_RTL (expr) = const0_rtx; - RTL_EXPR_SEQUENCE (expr) = get_insns (); - rtl_expr_chain = tree_cons (NULL_TREE, expr, rtl_expr_chain); - end_sequence (); - TREE_SIDE_EFFECTS (expr) = 1; - } - - /* All the implicit try blocks we built up will be zapped - when we come to a real binding contour boundary. */ -} - -/* Check that all fields are properly initialized after - an assignment to `this'. */ - -void -check_base_init (t) - tree t; -{ - tree member; - for (member = TYPE_FIELDS (t); member; member = TREE_CHAIN (member)) - if (DECL_NAME (member) && TREE_USED (member)) - cp_error ("field `%D' used before initialized (after assignment to `this')", - member); -} - -/* This code sets up the virtual function tables appropriate for - the pointer DECL. It is a one-ply initialization. - - BINFO is the exact type that DECL is supposed to be. In - multiple inheritance, this might mean "C's A" if C : A, B. */ - -static void -expand_virtual_init (binfo, decl) - tree binfo, decl; -{ - tree type = BINFO_TYPE (binfo); - tree vtbl, vtbl_ptr; - tree vtype, vtype_binfo; - - /* This code is crusty. Should be simple, like: - vtbl = BINFO_VTABLE (binfo); - */ - vtype = DECL_CONTEXT (CLASSTYPE_VFIELD (type)); - vtype_binfo = get_binfo (vtype, TREE_TYPE (TREE_TYPE (decl)), 0); - vtbl = BINFO_VTABLE (binfo_value (DECL_FIELD_CONTEXT (CLASSTYPE_VFIELD (type)), binfo)); - assemble_external (vtbl); - TREE_USED (vtbl) = 1; - vtbl = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (vtbl)), vtbl); - decl = convert_pointer_to_real (vtype_binfo, decl); - vtbl_ptr = build_vfield_ref (build_indirect_ref (decl, NULL_PTR), vtype); - if (vtbl_ptr == error_mark_node) - return; - - /* Have to convert VTBL since array sizes may be different. */ - vtbl = convert_force (TREE_TYPE (vtbl_ptr), vtbl, 0); - expand_expr_stmt (build_modify_expr (vtbl_ptr, NOP_EXPR, vtbl)); -} - -/* Subroutine of `expand_aggr_vbase_init'. - BINFO is the binfo of the type that is being initialized. - INIT_LIST is the list of initializers for the virtual baseclass. */ - -static void -expand_aggr_vbase_init_1 (binfo, exp, addr, init_list) - tree binfo, exp, addr, init_list; -{ - tree init = purpose_member (binfo, init_list); - tree ref = build_indirect_ref (addr, NULL_PTR); - - expand_start_target_temps (); - - if (init) - init = TREE_VALUE (init); - /* Call constructors, but don't set up vtables. */ - expand_aggr_init_1 (binfo, exp, ref, init, LOOKUP_COMPLAIN); - - expand_end_target_temps (); - free_temp_slots (); -} - -/* Initialize this object's virtual base class pointers. This must be - done only at the top-level of the object being constructed. - - INIT_LIST is list of initialization for constructor to perform. */ - -static void -expand_aggr_vbase_init (binfo, exp, addr, init_list) - tree binfo; - tree exp; - tree addr; - tree init_list; -{ - tree type = BINFO_TYPE (binfo); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - tree result = init_vbase_pointers (type, addr); - tree vbases; - - if (result) - expand_expr_stmt (build_compound_expr (result)); - - for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; - vbases = TREE_CHAIN (vbases)) - { - tree tmp = purpose_member (vbases, result); - expand_aggr_vbase_init_1 (vbases, exp, - TREE_OPERAND (TREE_VALUE (tmp), 0), - init_list); - } - } -} - -/* Find the context in which this FIELD can be initialized. */ - -static tree -initializing_context (field) - tree field; -{ - tree t = DECL_CONTEXT (field); - - /* Anonymous union members can be initialized in the first enclosing - non-anonymous union context. */ - while (t && ANON_UNION_TYPE_P (t)) - t = TYPE_CONTEXT (t); - return t; -} - -/* Function to give error message if member initialization specification - is erroneous. FIELD is the member we decided to initialize. - TYPE is the type for which the initialization is being performed. - FIELD must be a member of TYPE. - - MEMBER_NAME is the name of the member. */ - -static int -member_init_ok_or_else (field, type, member_name) - tree field; - tree type; - char *member_name; -{ - if (field == error_mark_node) - return 0; - if (field == NULL_TREE || initializing_context (field) != type) - { - cp_error ("class `%T' does not have any field named `%s'", type, - member_name); - return 0; - } - if (TREE_STATIC (field)) - { - cp_error ("field `%#D' is static; only point of initialization is its declaration", - field); - return 0; - } - - return 1; -} - -/* If NAME is a viable field name for the aggregate DECL, - and PARMS is a viable parameter list, then expand an _EXPR - which describes this initialization. - - Note that we do not need to chase through the class's base classes - to look for NAME, because if it's in that list, it will be handled - by the constructor for that base class. - - We do not yet have a fixed-point finder to instantiate types - being fed to overloaded constructors. If there is a unique - constructor, then argument types can be got from that one. - - If INIT is non-NULL, then it the initialization should - be placed in `current_base_init_list', where it will be processed - by `emit_base_init'. */ - -void -expand_member_init (exp, name, init) - tree exp, name, init; -{ - tree basetype = NULL_TREE, field; - tree type; - - if (exp == NULL_TREE) - return; /* complain about this later */ - - type = TYPE_MAIN_VARIANT (TREE_TYPE (exp)); - - if (name && TREE_CODE (name) == TYPE_DECL) - { - basetype = TYPE_MAIN_VARIANT (TREE_TYPE (name)); - name = DECL_NAME (name); - } - - if (name == NULL_TREE && IS_AGGR_TYPE (type)) - switch (CLASSTYPE_N_BASECLASSES (type)) - { - case 0: - error ("base class initializer specified, but no base class to initialize"); - return; - case 1: - basetype = TYPE_BINFO_BASETYPE (type, 0); - break; - default: - error ("initializer for unnamed base class ambiguous"); - cp_error ("(type `%T' uses multiple inheritance)", type); - return; - } - - my_friendly_assert (init != NULL_TREE, 0); - - /* The grammar should not allow fields which have names that are - TYPENAMEs. Therefore, if the field has a non-NULL TREE_TYPE, we - may assume that this is an attempt to initialize a base class - member of the current type. Otherwise, it is an attempt to - initialize a member field. */ - - if (init == void_type_node) - init = NULL_TREE; - - if (name == NULL_TREE || basetype) - { - tree base_init; - - if (name == NULL_TREE) - { -#if 0 - if (basetype) - name = TYPE_IDENTIFIER (basetype); - else - { - error ("no base class to initialize"); - return; - } -#endif - } - else if (basetype != type - && ! current_template_parms - && ! vec_binfo_member (basetype, - TYPE_BINFO_BASETYPES (type)) - && ! binfo_member (basetype, CLASSTYPE_VBASECLASSES (type))) - { - if (IDENTIFIER_CLASS_VALUE (name)) - goto try_member; - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - cp_error ("type `%T' is not an immediate or virtual basetype for `%T'", - basetype, type); - else - cp_error ("type `%T' is not an immediate basetype for `%T'", - basetype, type); - return; - } - - if (purpose_member (basetype, current_base_init_list)) - { - cp_error ("base class `%T' already initialized", basetype); - return; - } - - if (warn_reorder && current_member_init_list) - { - cp_warning ("base initializer for `%T'", basetype); - warning (" will be re-ordered to precede member initializations"); - } - - base_init = build_tree_list (basetype, init); - current_base_init_list = chainon (current_base_init_list, base_init); - } - else - { - tree member_init; - - try_member: - field = lookup_field (type, name, 1, 0); - - if (! member_init_ok_or_else (field, type, IDENTIFIER_POINTER (name))) - return; - - if (purpose_member (name, current_member_init_list)) - { - cp_error ("field `%D' already initialized", field); - return; - } - - member_init = build_tree_list (name, init); - current_member_init_list = chainon (current_member_init_list, member_init); - } -} - -/* This is like `expand_member_init', only it stores one aggregate - value into another. - - INIT comes in two flavors: it is either a value which - is to be stored in EXP, or it is a parameter list - to go to a constructor, which will operate on EXP. - If INIT is not a parameter list for a constructor, then set - LOOKUP_ONLYCONVERTING. - If FLAGS is LOOKUP_ONLYCONVERTING then it is the = init form of - the initializer, if FLAGS is 0, then it is the (init) form. - If `init' is a CONSTRUCTOR, then we emit a warning message, - explaining that such initializations are invalid. - - ALIAS_THIS is nonzero iff we are initializing something which is - essentially an alias for current_class_ref. In this case, the base - constructor may move it on us, and we must keep track of such - deviations. - - If INIT resolves to a CALL_EXPR which happens to return - something of the type we are looking for, then we know - that we can safely use that call to perform the - initialization. - - The virtual function table pointer cannot be set up here, because - we do not really know its type. - - Virtual baseclass pointers are also set up here. - - This never calls operator=(). - - When initializing, nothing is CONST. - - A default copy constructor may have to be used to perform the - initialization. - - A constructor or a conversion operator may have to be used to - perform the initialization, but not both, as it would be ambiguous. */ - -void -expand_aggr_init (exp, init, flags) - tree exp, init; - int flags; -{ - tree type = TREE_TYPE (exp); - int was_const = TREE_READONLY (exp); - int was_volatile = TREE_THIS_VOLATILE (exp); - - if (init == error_mark_node) - return; - - TREE_READONLY (exp) = 0; - TREE_THIS_VOLATILE (exp) = 0; - - if (init && TREE_CODE (init) != TREE_LIST) - flags |= LOOKUP_ONLYCONVERTING; - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Must arrange to initialize each element of EXP - from elements of INIT. */ - tree itype = init ? TREE_TYPE (init) : NULL_TREE; - if (CP_TYPE_QUALS (type) != TYPE_UNQUALIFIED) - { - TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); - if (init) - TREE_TYPE (init) = TYPE_MAIN_VARIANT (itype); - } - if (init && TREE_TYPE (init) == NULL_TREE) - { - /* Handle bad initializers like: - class COMPLEX { - public: - double re, im; - COMPLEX(double r = 0.0, double i = 0.0) {re = r; im = i;}; - ~COMPLEX() {}; - }; - - int main(int argc, char **argv) { - COMPLEX zees(1.0, 0.0)[10]; - } - */ - error ("bad array initializer"); - return; - } - expand_vec_init (exp, exp, array_type_nelts (type), init, - init && same_type_p (TREE_TYPE (init), - TREE_TYPE (exp))); - TREE_READONLY (exp) = was_const; - TREE_THIS_VOLATILE (exp) = was_volatile; - TREE_TYPE (exp) = type; - if (init) - TREE_TYPE (init) = itype; - return; - } - - if (TREE_CODE (exp) == VAR_DECL || TREE_CODE (exp) == PARM_DECL) - /* just know that we've seen something for this node */ - TREE_USED (exp) = 1; - -#if 0 - /* If initializing from a GNU C CONSTRUCTOR, consider the elts in the - constructor as parameters to an implicit GNU C++ constructor. */ - if (init && TREE_CODE (init) == CONSTRUCTOR - && TYPE_HAS_CONSTRUCTOR (type) - && TREE_TYPE (init) == type) - init = CONSTRUCTOR_ELTS (init); -#endif - - TREE_TYPE (exp) = TYPE_MAIN_VARIANT (type); - expand_aggr_init_1 (TYPE_BINFO (type), exp, exp, - init, LOOKUP_NORMAL|flags); - TREE_TYPE (exp) = type; - TREE_READONLY (exp) = was_const; - TREE_THIS_VOLATILE (exp) = was_volatile; -} - -static void -expand_default_init (binfo, true_exp, exp, init, flags) - tree binfo; - tree true_exp, exp; - tree init; - int flags; -{ - tree type = TREE_TYPE (exp); - - /* It fails because there may not be a constructor which takes - its own type as the first (or only parameter), but which does - take other types via a conversion. So, if the thing initializing - the expression is a unit element of type X, first try X(X&), - followed by initialization by X. If neither of these work - out, then look hard. */ - tree rval; - tree parms; - - if (init && TREE_CODE (init) != TREE_LIST - && (flags & LOOKUP_ONLYCONVERTING)) - { - /* Base subobjects should only get direct-initialization. */ - if (true_exp != exp) - abort (); - - if (flags & DIRECT_BIND) - /* Do nothing. We hit this in two cases: Reference initialization, - where we aren't initializing a real variable, so we don't want - to run a new constructor; and catching an exception, where we - have already built up the constructor call so we could wrap it - in an exception region. */; - else - init = ocp_convert (type, init, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); - - if (TREE_CODE (init) == TRY_CATCH_EXPR) - /* We need to protect the initialization of a catch parm - with a call to terminate(), which shows up as a TRY_CATCH_EXPR - around the TARGET_EXPR for the copy constructor. See - expand_start_catch_block. */ - TREE_OPERAND (init, 0) = build (INIT_EXPR, TREE_TYPE (exp), exp, - TREE_OPERAND (init, 0)); - else - init = build (INIT_EXPR, TREE_TYPE (exp), exp, init); - TREE_SIDE_EFFECTS (init) = 1; - expand_expr_stmt (init); - return; - } - - if (init == NULL_TREE - || (TREE_CODE (init) == TREE_LIST && ! TREE_TYPE (init))) - { - parms = init; - if (parms) - init = TREE_VALUE (parms); - } - else - parms = build_expr_list (NULL_TREE, init); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - if (true_exp == exp) - parms = expr_tree_cons (NULL_TREE, integer_one_node, parms); - else - parms = expr_tree_cons (NULL_TREE, integer_zero_node, parms); - flags |= LOOKUP_HAS_IN_CHARGE; - } - - rval = build_method_call (exp, ctor_identifier, - parms, binfo, flags); - if (TREE_SIDE_EFFECTS (rval)) - expand_expr_stmt (rval); -} - -/* This function is responsible for initializing EXP with INIT - (if any). - - BINFO is the binfo of the type for who we are performing the - initialization. For example, if W is a virtual base class of A and B, - and C : A, B. - If we are initializing B, then W must contain B's W vtable, whereas - were we initializing C, W must contain C's W vtable. - - TRUE_EXP is nonzero if it is the true expression being initialized. - In this case, it may be EXP, or may just contain EXP. The reason we - need this is because if EXP is a base element of TRUE_EXP, we - don't necessarily know by looking at EXP where its virtual - baseclass fields should really be pointing. But we do know - from TRUE_EXP. In constructors, we don't know anything about - the value being initialized. - - ALIAS_THIS serves the same purpose it serves for expand_aggr_init. - - FLAGS is just passes to `build_method_call'. See that function for - its description. */ - -static void -expand_aggr_init_1 (binfo, true_exp, exp, init, flags) - tree binfo; - tree true_exp, exp; - tree init; - int flags; -{ - tree type = TREE_TYPE (exp); - - my_friendly_assert (init != error_mark_node && type != error_mark_node, 211); - - /* Use a function returning the desired type to initialize EXP for us. - If the function is a constructor, and its first argument is - NULL_TREE, know that it was meant for us--just slide exp on - in and expand the constructor. Constructors now come - as TARGET_EXPRs. */ - - if (init && TREE_CODE (exp) == VAR_DECL - && TREE_CODE (init) == CONSTRUCTOR - && TREE_HAS_CONSTRUCTOR (init)) - { - tree t = store_init_value (exp, init); - if (!t) - { - expand_decl_init (exp); - return; - } - t = build (INIT_EXPR, type, exp, init); - TREE_SIDE_EFFECTS (t) = 1; - expand_expr_stmt (t); - return; - } - - /* We know that expand_default_init can handle everything we want - at this point. */ - expand_default_init (binfo, true_exp, exp, init, flags); -} - -/* Report an error if NAME is not the name of a user-defined, - aggregate type. If OR_ELSE is nonzero, give an error message. */ - -int -is_aggr_typedef (name, or_else) - tree name; - int or_else; -{ - tree type; - - if (name == error_mark_node) - return 0; - - if (IDENTIFIER_HAS_TYPE_VALUE (name)) - type = IDENTIFIER_TYPE_VALUE (name); - else - { - if (or_else) - cp_error ("`%T' is not an aggregate typedef", name); - return 0; - } - - if (! IS_AGGR_TYPE (type) - && TREE_CODE (type) != TEMPLATE_TYPE_PARM - && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) - { - if (or_else) - cp_error ("`%T' is not an aggregate type", type); - return 0; - } - return 1; -} - -/* Report an error if TYPE is not a user-defined, aggregate type. If - OR_ELSE is nonzero, give an error message. */ - -int -is_aggr_type (type, or_else) - tree type; - int or_else; -{ - if (type == error_mark_node) - return 0; - - if (! IS_AGGR_TYPE (type) - && TREE_CODE (type) != TEMPLATE_TYPE_PARM - && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) - { - if (or_else) - cp_error ("`%T' is not an aggregate type", type); - return 0; - } - return 1; -} - -/* Like is_aggr_typedef, but returns typedef if successful. */ - -tree -get_aggr_from_typedef (name, or_else) - tree name; - int or_else; -{ - tree type; - - if (name == error_mark_node) - return NULL_TREE; - - if (IDENTIFIER_HAS_TYPE_VALUE (name)) - type = IDENTIFIER_TYPE_VALUE (name); - else - { - if (or_else) - cp_error ("`%T' fails to be an aggregate typedef", name); - return NULL_TREE; - } - - if (! IS_AGGR_TYPE (type) - && TREE_CODE (type) != TEMPLATE_TYPE_PARM - && TREE_CODE (type) != TEMPLATE_TEMPLATE_PARM) - { - if (or_else) - cp_error ("type `%T' is of non-aggregate type", type); - return NULL_TREE; - } - return type; -} - -tree -get_type_value (name) - tree name; -{ - if (name == error_mark_node) - return NULL_TREE; - - if (IDENTIFIER_HAS_TYPE_VALUE (name)) - return IDENTIFIER_TYPE_VALUE (name); - else - return NULL_TREE; -} - - -/* This code could just as well go in `class.c', but is placed here for - modularity. */ - -/* For an expression of the form TYPE :: NAME (PARMLIST), build - the appropriate function call. */ - -tree -build_member_call (type, name, parmlist) - tree type, name, parmlist; -{ - tree t; - tree method_name; - int dtor = 0; - tree basetype_path, decl; - - if (TREE_CODE (name) == TEMPLATE_ID_EXPR - && TREE_CODE (type) == NAMESPACE_DECL) - { - /* 'name' already refers to the decls from the namespace, since we - hit do_identifier for template_ids. */ - my_friendly_assert (is_overloaded_fn (TREE_OPERAND (name, 0)), 980519); - return build_x_function_call (name, parmlist, current_class_ref); - } - - if (type == std_node) - return build_x_function_call (do_scoped_id (name, 0), parmlist, - current_class_ref); - if (TREE_CODE (type) == NAMESPACE_DECL) - return build_x_function_call (lookup_namespace_name (type, name), - parmlist, current_class_ref); - - if (TREE_CODE (name) != TEMPLATE_ID_EXPR) - method_name = name; - else - method_name = TREE_OPERAND (name, 0); - - if (TREE_CODE (method_name) == BIT_NOT_EXPR) - { - method_name = TREE_OPERAND (method_name, 0); - dtor = 1; - } - - /* This shouldn't be here, and build_member_call shouldn't appear in - parse.y! (mrs) */ - if (type && TREE_CODE (type) == IDENTIFIER_NODE - && get_aggr_from_typedef (type, 0) == 0) - { - tree ns = lookup_name (type, 0); - if (ns && TREE_CODE (ns) == NAMESPACE_DECL) - { - return build_x_function_call (build_offset_ref (type, name), parmlist, current_class_ref); - } - } - - if (type == NULL_TREE || ! is_aggr_type (type, 1)) - return error_mark_node; - - /* An operator we did not like. */ - if (name == NULL_TREE) - return error_mark_node; - - if (dtor) - { - cp_error ("cannot call destructor `%T::~%T' without object", type, - method_name); - return error_mark_node; - } - - decl = maybe_dummy_object (type, &basetype_path); - - /* Convert 'this' to the specified type to disambiguate conversion - to the function's context. Apparently Standard C++ says that we - shouldn't do this. */ - if (decl == current_class_ref - && ! pedantic - && ACCESSIBLY_UNIQUELY_DERIVED_P (type, current_class_type)) - { - tree olddecl = current_class_ptr; - tree oldtype = TREE_TYPE (TREE_TYPE (olddecl)); - if (oldtype != type) - { - tree newtype = build_qualified_type (type, TYPE_QUALS (oldtype)); - decl = convert_force (build_pointer_type (newtype), olddecl, 0); - decl = build_indirect_ref (decl, NULL_PTR); - } - } - - if (method_name == constructor_name (type) - || method_name == constructor_name_full (type)) - return build_functional_cast (type, parmlist); - if ((t = lookup_fnfields (basetype_path, method_name, 0))) - return build_method_call (decl, - TREE_CODE (name) == TEMPLATE_ID_EXPR - ? name : method_name, - parmlist, basetype_path, - LOOKUP_NORMAL|LOOKUP_NONVIRTUAL); - if (TREE_CODE (name) == IDENTIFIER_NODE - && ((t = lookup_field (TYPE_BINFO (type), name, 1, 0)))) - { - if (t == error_mark_node) - return error_mark_node; - if (TREE_CODE (t) == FIELD_DECL) - { - if (is_dummy_object (decl)) - { - cp_error ("invalid use of non-static field `%D'", t); - return error_mark_node; - } - decl = build (COMPONENT_REF, TREE_TYPE (t), decl, t); - } - else if (TREE_CODE (t) == VAR_DECL) - decl = t; - else - { - cp_error ("invalid use of member `%D'", t); - return error_mark_node; - } - if (TYPE_LANG_SPECIFIC (TREE_TYPE (decl))) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, decl, - parmlist, NULL_TREE); - return build_function_call (decl, parmlist); - } - else - { - cp_error ("no method `%T::%D'", type, name); - return error_mark_node; - } -} - -/* Build a reference to a member of an aggregate. This is not a - C++ `&', but really something which can have its address taken, - and then act as a pointer to member, for example TYPE :: FIELD - can have its address taken by saying & TYPE :: FIELD. - - @@ Prints out lousy diagnostics for operator <typename> - @@ fields. - - @@ This function should be rewritten and placed in search.c. */ - -tree -build_offset_ref (type, name) - tree type, name; -{ - tree decl, fnfields, fields, t = error_mark_node; - tree basebinfo = NULL_TREE; - tree orig_name = name; - - /* class templates can come in as TEMPLATE_DECLs here. */ - if (TREE_CODE (name) == TEMPLATE_DECL) - return name; - - if (type == std_node) - return do_scoped_id (name, 0); - - if (processing_template_decl || uses_template_parms (type)) - return build_min_nt (SCOPE_REF, type, name); - - /* Handle namespace names fully here. */ - if (TREE_CODE (type) == NAMESPACE_DECL) - { - t = lookup_namespace_name (type, name); - if (t != error_mark_node && ! type_unknown_p (t)) - { - mark_used (t); - t = convert_from_reference (t); - } - return t; - } - - if (type == NULL_TREE || ! is_aggr_type (type, 1)) - return error_mark_node; - - if (TREE_CODE (name) == TEMPLATE_ID_EXPR) - { - /* If the NAME is a TEMPLATE_ID_EXPR, we are looking at - something like `a.template f<int>' or the like. For the most - part, we treat this just like a.f. We do remember, however, - the template-id that was used. */ - name = TREE_OPERAND (orig_name, 0); - - if (TREE_CODE (name) == LOOKUP_EXPR) - /* This can happen during tsubst'ing. */ - name = TREE_OPERAND (name, 0); - - my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 0); - } - - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - if (! check_dtor_name (type, name)) - cp_error ("qualified type `%T' does not match destructor name `~%T'", - type, TREE_OPERAND (name, 0)); - name = dtor_identifier; - } -#if 0 - /* I think this is wrong, but the draft is unclear. --jason 6/15/98 */ - else if (name == constructor_name_full (type) - || name == constructor_name (type)) - name = ctor_identifier; -#endif - - if (TYPE_SIZE (complete_type (type)) == 0 - && !TYPE_BEING_DEFINED (type)) - { - cp_error ("incomplete type `%T' does not have member `%D'", type, - name); - return error_mark_node; - } - - decl = maybe_dummy_object (type, &basebinfo); - - fnfields = lookup_fnfields (basebinfo, name, 1); - fields = lookup_field (basebinfo, name, 0, 0); - - if (fields == error_mark_node || fnfields == error_mark_node) - return error_mark_node; - - /* A lot of this logic is now handled in lookup_field and - lookup_fnfield. */ - if (fnfields) - { - /* Go from the TREE_BASELINK to the member function info. */ - t = TREE_VALUE (fnfields); - - if (TREE_CODE (orig_name) == TEMPLATE_ID_EXPR) - { - /* The FNFIELDS are going to contain functions that aren't - necessarily templates, and templates that don't - necessarily match the explicit template parameters. We - save all the functions, and the explicit parameters, and - then figure out exactly what to instantiate with what - arguments in instantiate_type. */ - - if (TREE_CODE (t) != OVERLOAD) - /* The code in instantiate_type which will process this - expects to encounter OVERLOADs, not raw functions. */ - t = ovl_cons (t, NULL_TREE); - - return build (OFFSET_REF, - build_offset_type (type, unknown_type_node), - decl, - build (TEMPLATE_ID_EXPR, - TREE_TYPE (t), - t, - TREE_OPERAND (orig_name, 1))); - } - - if (!really_overloaded_fn (t)) - { - tree access; - - /* Get rid of a potential OVERLOAD around it */ - t = OVL_CURRENT (t); - - /* unique functions are handled easily. */ - basebinfo = TREE_PURPOSE (fnfields); - access = compute_access (basebinfo, t); - if (access == access_protected_node) - { - cp_error_at ("member function `%#D' is protected", t); - error ("in this context"); - return error_mark_node; - } - if (access == access_private_node) - { - cp_error_at ("member function `%#D' is private", t); - error ("in this context"); - return error_mark_node; - } - mark_used (t); - if (DECL_STATIC_FUNCTION_P (t)) - return t; - return build (OFFSET_REF, TREE_TYPE (t), decl, t); - } - - /* FNFIELDS is most likely allocated on the search_obstack, - which will go away after this class scope. If we need - to save this value for later (i.e. for use as an initializer - for a static variable), then do so here. - - ??? The smart thing to do for the case of saving initializers - is to resolve them before we're done with this scope. */ - if (!TREE_PERMANENT (fnfields) - && ! allocation_temporary_p ()) - fnfields = copy_list (fnfields); - - t = build_tree_list (error_mark_node, fnfields); - TREE_TYPE (t) = build_offset_type (type, unknown_type_node); - return t; - } - - /* Now that we know we are looking for a field, see if we - have access to that field. Lookup_field will give us the - error message. */ - - t = lookup_field (basebinfo, name, 1, 0); - - if (t == error_mark_node) - return error_mark_node; - - if (t == NULL_TREE) - { - cp_error ("`%D' is not a member of type `%T'", name, type); - return error_mark_node; - } - - if (TREE_CODE (t) == TYPE_DECL) - { - TREE_USED (t) = 1; - return t; - } - /* static class members and class-specific enum - values can be returned without further ado. */ - if (TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == CONST_DECL) - { - mark_used (t); - return convert_from_reference (t); - } - - if (TREE_CODE (t) == FIELD_DECL && DECL_C_BIT_FIELD (t)) - { - cp_error ("illegal pointer to bit field `%D'", t); - return error_mark_node; - } - - /* static class functions too. */ - if (TREE_CODE (t) == FUNCTION_DECL - && TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE) - my_friendly_abort (53); - - /* In member functions, the form `type::name' is no longer - equivalent to `this->type::name', at least not until - resolve_offset_ref. */ - return build (OFFSET_REF, build_offset_type (type, TREE_TYPE (t)), decl, t); -} - -/* If a OFFSET_REF made it through to here, then it did - not have its address taken. */ - -tree -resolve_offset_ref (exp) - tree exp; -{ - tree type = TREE_TYPE (exp); - tree base = NULL_TREE; - tree member; - tree basetype, addr; - - if (TREE_CODE (exp) == TREE_LIST) - { - cp_pedwarn ("assuming & on overloaded member function"); - return build_unary_op (ADDR_EXPR, exp, 0); - } - - if (TREE_CODE (exp) == OFFSET_REF) - { - member = TREE_OPERAND (exp, 1); - base = TREE_OPERAND (exp, 0); - } - else - { - my_friendly_assert (TREE_CODE (type) == OFFSET_TYPE, 214); - if (TYPE_OFFSET_BASETYPE (type) != current_class_type) - { - error ("object missing in use of pointer-to-member construct"); - return error_mark_node; - } - member = exp; - type = TREE_TYPE (type); - base = current_class_ref; - } - - if ((TREE_CODE (member) == VAR_DECL - && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (member)) - && ! TYPE_PTRMEM_P (TREE_TYPE (member))) - || TREE_CODE (TREE_TYPE (member)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (member)) == METHOD_TYPE) - { - /* These were static members. */ - if (mark_addressable (member) == 0) - return error_mark_node; - return member; - } - - if (TREE_CODE (TREE_TYPE (member)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_TYPE (member))) == METHOD_TYPE) - return member; - - /* Syntax error can cause a member which should - have been seen as static to be grok'd as non-static. */ - if (TREE_CODE (member) == FIELD_DECL && current_class_ref == NULL_TREE) - { - if (TREE_ADDRESSABLE (member) == 0) - { - cp_error_at ("member `%D' is non-static but referenced as a static member", - member); - error ("at this point in file"); - TREE_ADDRESSABLE (member) = 1; - } - return error_mark_node; - } - - /* The first case is really just a reference to a member of `this'. */ - if (TREE_CODE (member) == FIELD_DECL - && (base == current_class_ref || is_dummy_object (base))) - { - tree basetype_path; - tree access; - tree expr; - - if (TREE_CODE (exp) == OFFSET_REF && TREE_CODE (type) == OFFSET_TYPE) - basetype = TYPE_OFFSET_BASETYPE (type); - else - basetype = DECL_CONTEXT (member); - - base = current_class_ptr; - - if (get_base_distance (basetype, TREE_TYPE (TREE_TYPE (base)), 0, &basetype_path) < 0) - { - error_not_base_type (basetype, TREE_TYPE (TREE_TYPE (base))); - return error_mark_node; - } - /* Kludge: we need to use basetype_path now, because - convert_pointer_to will bash it. */ - access = compute_access (basetype_path, member); - addr = convert_pointer_to (basetype, base); - - /* Issue errors if there was an access violation. */ - if (access != access_public_node) - { - cp_error_at ("member `%D' is %s", - access == access_private_node - ? "private" : "protected", - member); - cp_error ("in this context"); - } - - /* Even in the case of illegal access, we form the - COMPONENT_REF; that will allow better error recovery than - just feeding back error_mark_node. */ - expr = build (COMPONENT_REF, TREE_TYPE (member), - build_indirect_ref (addr, NULL_PTR), member); - return convert_from_reference (expr); - } - - /* Ensure that we have an object. */ - if (is_dummy_object (base)) - addr = error_mark_node; - else - /* If this is a reference to a member function, then return the - address of the member function (which may involve going - through the object's vtable), otherwise, return an expression - for the dereferenced pointer-to-member construct. */ - addr = build_unary_op (ADDR_EXPR, base, 0); - - if (TYPE_PTRMEM_P (TREE_TYPE (member))) - { - if (addr == error_mark_node) - { - cp_error ("object missing in `%E'", exp); - return error_mark_node; - } - - basetype = TYPE_OFFSET_BASETYPE (TREE_TYPE (TREE_TYPE (member))); - addr = convert_pointer_to (basetype, addr); - member = cp_convert (ptrdiff_type_node, member); - - /* Pointer to data members are offset by one, so that a null - pointer with a real value of 0 is distinguishable from an - offset of the first member of a structure. */ - member = build_binary_op (MINUS_EXPR, member, - cp_convert (ptrdiff_type_node, integer_one_node), - 0); - - return build1 (INDIRECT_REF, type, - build (PLUS_EXPR, build_pointer_type (type), - addr, member)); - } - else if (TYPE_PTRMEMFUNC_P (TREE_TYPE (member))) - { - return get_member_function_from_ptrfunc (&addr, member); - } - my_friendly_abort (56); - /* NOTREACHED */ - return NULL_TREE; -} - -/* Return either DECL or its known constant value (if it has one). */ - -tree -decl_constant_value (decl) - tree decl; -{ - if (! TREE_THIS_VOLATILE (decl) - && DECL_INITIAL (decl) - && DECL_INITIAL (decl) != error_mark_node - /* This is invalid if initial value is not constant. - If it has either a function call, a memory reference, - or a variable, then re-evaluating it could give different results. */ - && TREE_CONSTANT (DECL_INITIAL (decl)) - /* Check for cases where this is sub-optimal, even though valid. */ - && TREE_CODE (DECL_INITIAL (decl)) != CONSTRUCTOR) - return DECL_INITIAL (decl); - return decl; -} - -/* Common subroutines of build_new and build_vec_delete. */ - -/* Call the global __builtin_delete to delete ADDR. */ - -static tree -build_builtin_delete_call (addr) - tree addr; -{ - mark_used (global_delete_fndecl); - return build_call (global_delete_fndecl, - void_type_node, build_expr_list (NULL_TREE, addr)); -} - -/* Generate a C++ "new" expression. DECL is either a TREE_LIST - (which needs to go through some sort of groktypename) or it - is the name of the class we are newing. INIT is an initialization value. - It is either an EXPRLIST, an EXPR_NO_COMMAS, or something in braces. - If INIT is void_type_node, it means do *not* call a constructor - for this instance. - - For types with constructors, the data returned is initialized - by the appropriate constructor. - - Whether the type has a constructor or not, if it has a pointer - to a virtual function table, then that pointer is set up - here. - - Unless I am mistaken, a call to new () will return initialized - data regardless of whether the constructor itself is private or - not. NOPE; new fails if the constructor is private (jcm). - - Note that build_new does nothing to assure that any special - alignment requirements of the type are met. Rather, it leaves - it up to malloc to do the right thing. Otherwise, folding to - the right alignment cal cause problems if the user tries to later - free the memory returned by `new'. - - PLACEMENT is the `placement' list for user-defined operator new (). */ - -extern int flag_check_new; - -tree -build_new (placement, decl, init, use_global_new) - tree placement; - tree decl, init; - int use_global_new; -{ - tree type, rval; - tree nelts = NULL_TREE, t; - int has_array = 0; - - tree pending_sizes = NULL_TREE; - - if (decl == error_mark_node) - return error_mark_node; - - if (TREE_CODE (decl) == TREE_LIST) - { - tree absdcl = TREE_VALUE (decl); - tree last_absdcl = NULL_TREE; - int old_immediate_size_expand = 0; - - if (current_function_decl - && DECL_CONSTRUCTOR_P (current_function_decl)) - { - old_immediate_size_expand = immediate_size_expand; - immediate_size_expand = 0; - } - - nelts = integer_one_node; - - if (absdcl && TREE_CODE (absdcl) == CALL_EXPR) - my_friendly_abort (215); - while (absdcl && TREE_CODE (absdcl) == INDIRECT_REF) - { - last_absdcl = absdcl; - absdcl = TREE_OPERAND (absdcl, 0); - } - - if (absdcl && TREE_CODE (absdcl) == ARRAY_REF) - { - /* probably meant to be a vec new */ - tree this_nelts; - - while (TREE_OPERAND (absdcl, 0) - && TREE_CODE (TREE_OPERAND (absdcl, 0)) == ARRAY_REF) - { - last_absdcl = absdcl; - absdcl = TREE_OPERAND (absdcl, 0); - } - - has_array = 1; - this_nelts = TREE_OPERAND (absdcl, 1); - if (this_nelts != error_mark_node) - { - if (this_nelts == NULL_TREE) - error ("new of array type fails to specify size"); - else if (processing_template_decl) - { - nelts = this_nelts; - absdcl = TREE_OPERAND (absdcl, 0); - } - else - { - int flags = pedantic ? WANT_INT : (WANT_INT | WANT_ENUM); - if (build_expr_type_conversion (flags, this_nelts, 0) - == NULL_TREE) - pedwarn ("size in array new must have integral type"); - - this_nelts = save_expr (cp_convert (sizetype, this_nelts)); - absdcl = TREE_OPERAND (absdcl, 0); - if (this_nelts == integer_zero_node) - { - warning ("zero size array reserves no space"); - nelts = integer_zero_node; - } - else - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); - } - } - else - nelts = integer_zero_node; - } - - if (last_absdcl) - TREE_OPERAND (last_absdcl, 0) = absdcl; - else - TREE_VALUE (decl) = absdcl; - - type = groktypename (decl); - if (! type || type == error_mark_node) - { - immediate_size_expand = old_immediate_size_expand; - return error_mark_node; - } - - if (current_function_decl - && DECL_CONSTRUCTOR_P (current_function_decl)) - { - pending_sizes = get_pending_sizes (); - immediate_size_expand = old_immediate_size_expand; - } - } - else if (TREE_CODE (decl) == IDENTIFIER_NODE) - { - if (IDENTIFIER_HAS_TYPE_VALUE (decl)) - { - /* An aggregate type. */ - type = IDENTIFIER_TYPE_VALUE (decl); - decl = TYPE_MAIN_DECL (type); - } - else - { - /* A builtin type. */ - decl = lookup_name (decl, 1); - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 215); - type = TREE_TYPE (decl); - } - } - else if (TREE_CODE (decl) == TYPE_DECL) - { - type = TREE_TYPE (decl); - } - else - { - type = decl; - decl = TYPE_MAIN_DECL (type); - } - - if (processing_template_decl) - { - if (has_array) - t = min_tree_cons (min_tree_cons (NULL_TREE, type, NULL_TREE), - build_min_nt (ARRAY_REF, NULL_TREE, nelts), - NULL_TREE); - else - t = type; - - rval = build_min_nt (NEW_EXPR, placement, t, init); - NEW_EXPR_USE_GLOBAL (rval) = use_global_new; - return rval; - } - - /* ``A reference cannot be created by the new operator. A reference - is not an object (8.2.2, 8.4.3), so a pointer to it could not be - returned by new.'' ARM 5.3.3 */ - if (TREE_CODE (type) == REFERENCE_TYPE) - { - error ("new cannot be applied to a reference type"); - type = TREE_TYPE (type); - } - - if (TREE_CODE (type) == FUNCTION_TYPE) - { - error ("new cannot be applied to a function type"); - return error_mark_node; - } - - /* When the object being created is an array, the new-expression yields a - pointer to the initial element (if any) of the array. For example, - both new int and new int[10] return an int*. 5.3.4. */ - if (TREE_CODE (type) == ARRAY_TYPE && has_array == 0) - { - nelts = array_type_nelts_top (type); - has_array = 1; - type = TREE_TYPE (type); - } - - if (has_array) - t = build_nt (ARRAY_REF, type, nelts); - else - t = type; - - rval = build (NEW_EXPR, build_pointer_type (type), placement, t, init); - NEW_EXPR_USE_GLOBAL (rval) = use_global_new; - TREE_SIDE_EFFECTS (rval) = 1; - - /* Wrap it in a NOP_EXPR so warn_if_unused_value doesn't complain. */ - rval = build1 (NOP_EXPR, TREE_TYPE (rval), rval); - TREE_NO_UNUSED_WARNING (rval) = 1; - - if (pending_sizes) - rval = build_compound_expr (chainon (pending_sizes, - build_expr_list (NULL_TREE, rval))); - - return rval; -} - -/* If non-NULL, a POINTER_TYPE equivalent to (java::lang::Class*). */ - -static tree jclass_node = NULL_TREE; - -/* Given a Java class, return a decl for the corresponding java.lang.Class. */ - -tree -build_java_class_ref (type) - tree type; -{ - tree name, class_decl; - static tree CL_prefix = NULL_TREE; - if (CL_prefix == NULL_TREE) - CL_prefix = get_identifier("_CL_"); - if (jclass_node == NULL_TREE) - { - jclass_node = IDENTIFIER_GLOBAL_VALUE (get_identifier("jclass")); - if (jclass_node == NULL_TREE) - fatal("call to Java constructor, while `jclass' undefined"); - jclass_node = TREE_TYPE (jclass_node); - } - name = build_overload_with_type (CL_prefix, type); - class_decl = IDENTIFIER_GLOBAL_VALUE (name); - if (class_decl == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - class_decl = build_decl (VAR_DECL, name, TREE_TYPE (jclass_node)); - TREE_STATIC (class_decl) = 1; - DECL_EXTERNAL (class_decl) = 1; - TREE_PUBLIC (class_decl) = 1; - DECL_ARTIFICIAL (class_decl) = 1; - DECL_IGNORED_P (class_decl) = 1; - pushdecl_top_level (class_decl); - make_decl_rtl (class_decl, NULL_PTR, 1); - pop_obstacks (); - } - return class_decl; -} - -/* Called from cplus_expand_expr when expanding a NEW_EXPR. The return - value is immediately handed to expand_expr. */ - -tree -build_new_1 (exp) - tree exp; -{ - tree placement, init; - tree type, true_type, size, rval; - tree nelts = NULL_TREE; - tree alloc_expr, alloc_node = NULL_TREE; - int has_array = 0; - enum tree_code code = NEW_EXPR; - int use_cookie, nothrow, check_new; - int use_global_new; - int use_java_new = 0; - - placement = TREE_OPERAND (exp, 0); - type = TREE_OPERAND (exp, 1); - init = TREE_OPERAND (exp, 2); - use_global_new = NEW_EXPR_USE_GLOBAL (exp); - - if (TREE_CODE (type) == ARRAY_REF) - { - has_array = 1; - nelts = TREE_OPERAND (type, 1); - type = TREE_OPERAND (type, 0); - } - true_type = type; - - if (CP_TYPE_QUALS (type)) - type = TYPE_MAIN_VARIANT (type); - - /* If our base type is an array, then make sure we know how many elements - it has. */ - while (TREE_CODE (true_type) == ARRAY_TYPE) - { - tree this_nelts = array_type_nelts_top (true_type); - nelts = build_binary_op (MULT_EXPR, nelts, this_nelts, 1); - true_type = TREE_TYPE (true_type); - } - - if (!complete_type_or_else (true_type)) - return error_mark_node; - - if (has_array) - size = fold (build_binary_op (MULT_EXPR, size_in_bytes (true_type), - nelts, 1)); - else - size = size_in_bytes (type); - - if (TREE_CODE (true_type) == VOID_TYPE) - { - error ("invalid type `void' for new"); - return error_mark_node; - } - - if (TYPE_LANG_SPECIFIC (true_type) - && CLASSTYPE_ABSTRACT_VIRTUALS (true_type)) - { - abstract_virtuals_error (NULL_TREE, true_type); - return error_mark_node; - } - - if (TYPE_LANG_SPECIFIC (true_type) && IS_SIGNATURE (true_type)) - { - signature_error (NULL_TREE, true_type); - return error_mark_node; - } - -#if 1 - /* Get a little extra space to store a couple of things before the new'ed - array, if this isn't the default placement new. */ - - use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) - && ! (placement && ! TREE_CHAIN (placement) - && TREE_TYPE (TREE_VALUE (placement)) == ptr_type_node)); -#else - /* Get a little extra space to store a couple of things before the new'ed - array, if this is either non-placement new or new (nothrow). */ - - use_cookie = (has_array && TYPE_VEC_NEW_USES_COOKIE (true_type) - && (! placement || nothrow)); -#endif - - if (use_cookie) - { - tree extra = BI_header_size; - - size = size_binop (PLUS_EXPR, size, extra); - } - - if (has_array) - { - code = VEC_NEW_EXPR; - - if (init && pedantic) - cp_pedwarn ("initialization in array new"); - } - - /* Allocate the object. */ - - if (! has_array && ! placement && flag_this_is_variable > 0 - && TYPE_NEEDS_CONSTRUCTING (true_type) && init != void_type_node) - { - if (init == NULL_TREE || TREE_CODE (init) == TREE_LIST) - rval = NULL_TREE; - else - { - error ("constructors take parameter lists"); - return error_mark_node; - } - } - else if (! placement && TYPE_FOR_JAVA (true_type)) - { - tree class_addr, alloc_decl; - tree class_decl = build_java_class_ref (true_type); - tree class_size = size_in_bytes (true_type); - static char alloc_name[] = "_Jv_AllocObject"; - use_java_new = 1; - alloc_decl = IDENTIFIER_GLOBAL_VALUE (get_identifier (alloc_name)); - if (alloc_decl == NULL_TREE) - fatal("call to Java constructor, while `%s' undefined", alloc_name); - class_addr = build1 (ADDR_EXPR, jclass_node, class_decl); - rval = build_function_call (alloc_decl, - tree_cons (NULL_TREE, class_addr, - build_tree_list (NULL_TREE, - class_size))); - rval = cp_convert (build_pointer_type (true_type), rval); - } - else - { - int susp = 0; - - if (flag_exceptions) - /* We will use RVAL when generating an exception handler for - this new-expression, so we must save it. */ - susp = suspend_momentary (); - - rval = build_op_new_call - (code, true_type, expr_tree_cons (NULL_TREE, size, placement), - LOOKUP_NORMAL | (use_global_new * LOOKUP_GLOBAL)); - rval = cp_convert (build_pointer_type (true_type), rval); - - if (flag_exceptions) - resume_momentary (susp); - } - - /* unless an allocation function is declared with an empty excep- - tion-specification (_except.spec_), throw(), it indicates failure to - allocate storage by throwing a bad_alloc exception (clause _except_, - _lib.bad.alloc_); it returns a non-null pointer otherwise If the allo- - cation function is declared with an empty exception-specification, - throw(), it returns null to indicate failure to allocate storage and a - non-null pointer otherwise. - - So check for a null exception spec on the op new we just called. */ - - nothrow = 0; - if (rval) - { - /* The CALL_EXPR. */ - tree t = TREE_OPERAND (rval, 0); - /* The function. */ - t = TREE_OPERAND (TREE_OPERAND (t, 0), 0); - t = TYPE_RAISES_EXCEPTIONS (TREE_TYPE (t)); - - if (t && TREE_VALUE (t) == NULL_TREE) - nothrow = 1; - } - check_new = (flag_check_new || nothrow) && ! use_java_new; - - if ((check_new || flag_exceptions) && rval) - { - alloc_expr = get_target_expr (rval); - alloc_node = rval = TREE_OPERAND (alloc_expr, 0); - } - else - alloc_expr = NULL_TREE; - - /* if rval is NULL_TREE I don't have to allocate it, but are we totally - sure we have some extra bytes in that case for the BI_header_size - cookies? And how does that interact with the code below? (mrs) */ - /* Finish up some magic for new'ed arrays */ - if (use_cookie && rval != NULL_TREE) - { - tree extra = BI_header_size; - tree cookie, exp1; - rval = convert (string_type_node, rval); /* for ptr arithmetic */ - rval = save_expr (build_binary_op (PLUS_EXPR, rval, extra, 1)); - /* Store header info. */ - cookie = build_indirect_ref (build (MINUS_EXPR, - build_pointer_type (BI_header_type), - rval, extra), NULL_PTR); - exp1 = build (MODIFY_EXPR, void_type_node, - build_component_ref (cookie, nc_nelts_field_id, - NULL_TREE, 0), - nelts); - TREE_SIDE_EFFECTS (exp1) = 1; - rval = cp_convert (build_pointer_type (true_type), rval); - rval = build_compound_expr - (expr_tree_cons (NULL_TREE, exp1, - build_expr_list (NULL_TREE, rval))); - } - - if (rval == error_mark_node) - return error_mark_node; - - /* Don't call any constructors or do any initialization. */ - if (init == void_type_node) - goto done; - - if (TYPE_NEEDS_CONSTRUCTING (type) || init) - { - if (! TYPE_NEEDS_CONSTRUCTING (type) - && ! IS_AGGR_TYPE (type) && ! has_array) - { - /* We are processing something like `new int (10)', which - means allocate an int, and initialize it with 10. */ - tree deref; - tree deref_type; - - /* At present RVAL is a temporary variable, created to hold - the value from the call to `operator new'. We transform - it to (*RVAL = INIT, RVAL). */ - rval = save_expr (rval); - deref = build_indirect_ref (rval, NULL_PTR); - - /* Even for something like `new const int (10)' we must - allow the expression to be non-const while we do the - initialization. */ - deref_type = TREE_TYPE (deref); - if (CP_TYPE_CONST_P (deref_type)) - TREE_TYPE (deref) - = cp_build_qualified_type (deref_type, - CP_TYPE_QUALS (deref_type) - & ~TYPE_QUAL_CONST); - TREE_READONLY (deref) = 0; - - if (TREE_CHAIN (init) != NULL_TREE) - pedwarn ("initializer list being treated as compound expression"); - else if (TREE_CODE (init) == CONSTRUCTOR) - { - pedwarn ("initializer list appears where operand should be used"); - init = TREE_OPERAND (init, 1); - } - init = build_compound_expr (init); - - init = convert_for_initialization (deref, type, init, LOOKUP_NORMAL, - "new", NULL_TREE, 0); - rval = build (COMPOUND_EXPR, TREE_TYPE (rval), - build_modify_expr (deref, NOP_EXPR, init), - rval); - TREE_NO_UNUSED_WARNING (rval) = 1; - TREE_SIDE_EFFECTS (rval) = 1; - } - else if (! has_array) - { - tree newrval; - /* Constructors are never virtual. If it has an initialization, we - need to complain if we aren't allowed to use the ctor that took - that argument. */ - int flags = LOOKUP_NORMAL|LOOKUP_NONVIRTUAL|LOOKUP_COMPLAIN; - - if (rval && TYPE_USES_VIRTUAL_BASECLASSES (true_type)) - { - init = expr_tree_cons (NULL_TREE, integer_one_node, init); - flags |= LOOKUP_HAS_IN_CHARGE; - } - - if (use_java_new) - rval = save_expr (rval); - newrval = rval; - - if (newrval && TREE_CODE (TREE_TYPE (newrval)) == POINTER_TYPE) - newrval = build_indirect_ref (newrval, NULL_PTR); - - newrval = build_method_call (newrval, ctor_identifier, - init, TYPE_BINFO (true_type), flags); - - if (newrval == NULL_TREE || newrval == error_mark_node) - return error_mark_node; - - /* Java constructors compiled by jc1 do not return this. */ - if (use_java_new) - newrval = build (COMPOUND_EXPR, TREE_TYPE (newrval), - newrval, rval); - rval = newrval; - TREE_HAS_CONSTRUCTOR (rval) = 1; - } - else - rval = build (VEC_INIT_EXPR, TREE_TYPE (rval), - save_expr (rval), init, nelts); - - /* If any part of the object initialization terminates by throwing - an exception and the new-expression does not contain a - new-placement, then the deallocation function is called to free - the memory in which the object was being constructed. */ - if (flag_exceptions && alloc_expr && ! use_java_new) - { - enum tree_code dcode = has_array ? VEC_DELETE_EXPR : DELETE_EXPR; - tree cleanup, fn = NULL_TREE; - int flags = LOOKUP_NORMAL | (use_global_new * LOOKUP_GLOBAL); - - /* All cleanups must last longer than normal. */ - int yes = suspend_momentary (); - - if (placement) - { - flags |= LOOKUP_SPECULATIVELY; - - /* We expect alloc_expr to look like a TARGET_EXPR around - a NOP_EXPR around the CALL_EXPR we want. */ - fn = TREE_OPERAND (alloc_expr, 1); - fn = TREE_OPERAND (fn, 0); - } - - /* Copy size to the saveable obstack. */ - size = copy_node (size); - - cleanup = build_op_delete_call (dcode, alloc_node, size, flags, fn); - - resume_momentary (yes); - - /* Ack! First we allocate the memory. Then we set our sentry - variable to true, and expand a cleanup that deletes the memory - if sentry is true. Then we run the constructor and store the - returned pointer in buf. Then we clear sentry and return buf. */ - - if (cleanup) - { - tree end, sentry, begin, buf, t = TREE_TYPE (rval); - - begin = get_target_expr (boolean_true_node); - sentry = TREE_OPERAND (begin, 0); - - yes = suspend_momentary (); - TREE_OPERAND (begin, 2) - = build (COND_EXPR, void_type_node, sentry, - cleanup, void_zero_node); - resume_momentary (yes); - - rval = get_target_expr (rval); - - end = build (MODIFY_EXPR, TREE_TYPE (sentry), - sentry, boolean_false_node); - TREE_SIDE_EFFECTS (end) = 1; - - buf = TREE_OPERAND (rval, 0); - - rval = build (COMPOUND_EXPR, t, begin, - build (COMPOUND_EXPR, t, rval, - build (COMPOUND_EXPR, t, end, buf))); - } - } - } - else if (CP_TYPE_CONST_P (true_type)) - cp_error ("uninitialized const in `new' of `%#T'", true_type); - - done: - - if (alloc_expr && rval == alloc_node) - { - rval = TREE_OPERAND (alloc_expr, 1); - alloc_expr = NULL_TREE; - } - - if (check_new && alloc_expr) - { - /* Did we modify the storage? */ - tree ifexp = build_binary_op (NE_EXPR, alloc_node, - integer_zero_node, 1); - rval = build_conditional_expr (ifexp, rval, alloc_node); - } - - if (alloc_expr) - rval = build (COMPOUND_EXPR, TREE_TYPE (rval), alloc_expr, rval); - - if (rval && TREE_TYPE (rval) != build_pointer_type (type)) - { - /* The type of new int [3][3] is not int *, but int [3] * */ - rval = build_c_cast (build_pointer_type (type), rval); - } - - return rval; -} - -static tree -build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, - use_global_delete) - tree base, maxindex, type; - tree auto_delete_vec, auto_delete; - int use_global_delete; -{ - tree virtual_size; - tree ptype = build_pointer_type (type = complete_type (type)); - tree size_exp = size_in_bytes (type); - - /* Temporary variables used by the loop. */ - tree tbase, tbase_init; - - /* This is the body of the loop that implements the deletion of a - single element, and moves temp variables to next elements. */ - tree body; - - /* This is the LOOP_EXPR that governs the deletion of the elements. */ - tree loop; - - /* This is the thing that governs what to do after the loop has run. */ - tree deallocate_expr = 0; - - /* This is the BIND_EXPR which holds the outermost iterator of the - loop. It is convenient to set this variable up and test it before - executing any other code in the loop. - This is also the containing expression returned by this function. */ - tree controller = NULL_TREE; - - if (! IS_AGGR_TYPE (type) || ! TYPE_NEEDS_DESTRUCTOR (type)) - { - loop = integer_zero_node; - goto no_destructor; - } - - /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); - - tbase = build_decl (VAR_DECL, NULL_TREE, ptype); - tbase_init = build_modify_expr (tbase, NOP_EXPR, - fold (build (PLUS_EXPR, ptype, - base, - virtual_size))); - DECL_REGISTER (tbase) = 1; - controller = build (BIND_EXPR, void_type_node, tbase, NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (controller) = 1; - - if (auto_delete != integer_zero_node - && auto_delete != integer_two_node) - { - tree base_tbd = cp_convert (ptype, - build_binary_op (MINUS_EXPR, - cp_convert (ptr_type_node, base), - BI_header_size, - 1)); - /* This is the real size */ - virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); - body = build_expr_list (NULL_TREE, - build_x_delete (base_tbd, - 2 | use_global_delete, - virtual_size)); - body = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, - auto_delete, integer_one_node), - body, integer_zero_node); - } - else - body = NULL_TREE; - - body = expr_tree_cons (NULL_TREE, - build_delete (ptype, tbase, auto_delete, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 1), - body); - - body = expr_tree_cons (NULL_TREE, - build_modify_expr (tbase, NOP_EXPR, build (MINUS_EXPR, ptype, tbase, size_exp)), - body); - - body = expr_tree_cons (NULL_TREE, - build (EXIT_EXPR, void_type_node, - build (EQ_EXPR, boolean_type_node, base, tbase)), - body); - - loop = build (LOOP_EXPR, void_type_node, build_compound_expr (body)); - - loop = expr_tree_cons (NULL_TREE, tbase_init, - expr_tree_cons (NULL_TREE, loop, NULL_TREE)); - loop = build_compound_expr (loop); - - no_destructor: - /* If the delete flag is one, or anything else with the low bit set, - delete the storage. */ - if (auto_delete_vec == integer_zero_node) - deallocate_expr = integer_zero_node; - else - { - tree base_tbd; - - /* The below is short by BI_header_size */ - virtual_size = fold (size_binop (MULT_EXPR, size_exp, maxindex)); - - if (! TYPE_VEC_NEW_USES_COOKIE (type)) - /* no header */ - base_tbd = base; - else - { - base_tbd = cp_convert (ptype, - build_binary_op (MINUS_EXPR, - cp_convert (string_type_node, base), - BI_header_size, - 1)); - /* True size with header. */ - virtual_size = size_binop (PLUS_EXPR, virtual_size, BI_header_size); - } - deallocate_expr = build_x_delete (base_tbd, - 2 | use_global_delete, - virtual_size); - if (auto_delete_vec != integer_one_node) - deallocate_expr = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, - auto_delete_vec, integer_one_node), - deallocate_expr, integer_zero_node); - } - - if (loop && deallocate_expr != integer_zero_node) - { - body = expr_tree_cons (NULL_TREE, loop, - expr_tree_cons (NULL_TREE, deallocate_expr, NULL_TREE)); - body = build_compound_expr (body); - } - else - body = loop; - - /* Outermost wrapper: If pointer is null, punt. */ - body = build (COND_EXPR, void_type_node, - build (NE_EXPR, boolean_type_node, base, integer_zero_node), - body, integer_zero_node); - body = build1 (NOP_EXPR, void_type_node, body); - - if (controller) - { - TREE_OPERAND (controller, 1) = body; - return controller; - } - else - return cp_convert (void_type_node, body); -} - -/* Protect the vector initialization with a try-block so that we can - destroy the first few elements if constructing a later element - causes an exception to be thrown. TYPE is the type of the array - elements. */ - -static void -expand_vec_init_try_block (type) - tree type; -{ - if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) - return; - - /* The code we generate looks like: - - try { - // Initialize the vector. - } catch (...) { - // Destory the elements that need destroying. - throw; - } - - Here we're just beginning the `try'. */ - - expand_eh_region_start (); -} - -/* Add code to destroy the array elements constructed so far if the - construction of some element in the array causes an exception to be - thrown. RVAL is the address of the last element in the array. - TYPE is the type of the array elements. MAXINDEX is the maximum - allowable index into the array. ITERATOR is an integer variable - indicating how many elements remain to be constructed. */ - -static void -expand_vec_init_catch_clause (rval, type, maxindex, iterator) - tree rval; - tree type; - tree maxindex; - tree iterator; -{ - tree e; - tree cleanup; - - if (!TYPE_NEEDS_DESTRUCTOR (type) || !flag_exceptions) - return; - - /* We have to ensure that this can live to the cleanup expansion - time, since we know it is only ever needed once, generate code - now. */ - push_obstacks_nochange (); - resume_temporary_allocation (); - - cleanup = make_node (RTL_EXPR); - TREE_TYPE (cleanup) = void_type_node; - RTL_EXPR_RTL (cleanup) = const0_rtx; - TREE_SIDE_EFFECTS (cleanup) = 1; - do_pending_stack_adjust (); - start_sequence_for_rtl_expr (cleanup); - - e = build_vec_delete_1 (rval, - build_binary_op (MINUS_EXPR, maxindex, - iterator, 1), - type, - /*auto_delete_vec=*/integer_zero_node, - /*auto_delete=*/integer_zero_node, - /*use_global_delete=*/0); - expand_expr (e, const0_rtx, VOIDmode, EXPAND_NORMAL); - - do_pending_stack_adjust (); - RTL_EXPR_SEQUENCE (cleanup) = get_insns (); - end_sequence (); - cleanup = protect_with_terminate (cleanup); - expand_eh_region_end (cleanup); - pop_obstacks (); -} - -/* `expand_vec_init' performs initialization of a vector of aggregate - types. - - DECL is passed only for error reporting, and provides line number - and source file name information. - BASE is the space where the vector will be. - MAXINDEX is the maximum index of the array (one less than the - number of elements). - INIT is the (possibly NULL) initializer. - - FROM_ARRAY is 0 if we should init everything with INIT - (i.e., every element initialized from INIT). - FROM_ARRAY is 1 if we should index into INIT in parallel - with initialization of DECL. - FROM_ARRAY is 2 if we should index into INIT in parallel, - but use assignment instead of initialization. */ - -tree -expand_vec_init (decl, base, maxindex, init, from_array) - tree decl, base, maxindex, init; - int from_array; -{ - tree rval; - tree base2 = NULL_TREE; - tree type = TREE_TYPE (TREE_TYPE (base)); - tree size; - tree itype = NULL_TREE; - tree iterator; - int num_initialized_elts = 0; - - maxindex = cp_convert (ptrdiff_type_node, maxindex); - if (maxindex == error_mark_node) - return error_mark_node; - - if (current_function_decl == NULL_TREE) - { - rval = make_tree_vec (3); - TREE_VEC_ELT (rval, 0) = base; - TREE_VEC_ELT (rval, 1) = maxindex; - TREE_VEC_ELT (rval, 2) = init; - return rval; - } - - size = size_in_bytes (type); - - base = default_conversion (base); - base = cp_convert (build_pointer_type (type), base); - rval = get_temp_regvar (build_pointer_type (type), base); - base = get_temp_regvar (build_pointer_type (type), base); - iterator = get_temp_regvar (ptrdiff_type_node, maxindex); - - /* Protect the entire array initialization so that we can destroy - the partially constructed array if an exception is thrown. */ - expand_vec_init_try_block (type); - - if (init != NULL_TREE && TREE_CODE (init) == CONSTRUCTOR - && (!decl || same_type_p (TREE_TYPE (init), TREE_TYPE (decl)))) - { - /* Do non-default initialization resulting from brace-enclosed - initializers. */ - - tree elts; - tree baseref = build1 (INDIRECT_REF, type, base); - - from_array = 0; - - for (elts = CONSTRUCTOR_ELTS (init); elts; elts = TREE_CHAIN (elts)) - { - tree elt = TREE_VALUE (elts); - - num_initialized_elts++; - - if (IS_AGGR_TYPE (type) || TREE_CODE (type) == ARRAY_TYPE) - expand_aggr_init (baseref, elt, 0); - else - expand_assignment (baseref, elt, 0, 0); - - expand_assignment (base, - build (PLUS_EXPR, build_pointer_type (type), - base, size), - 0, 0); - expand_assignment (iterator, - build (MINUS_EXPR, ptrdiff_type_node, - iterator, integer_one_node), - 0, 0); - } - - /* Clear out INIT so that we don't get confused below. */ - init = NULL_TREE; - - if (obey_regdecls) - use_variable (DECL_RTL (base)); - } - else if (from_array) - { - /* If initializing one array from another, initialize element by - element. We rely upon the below calls the do argument - checking. */ - if (decl == NULL_TREE) - { - sorry ("initialization of array from dissimilar array type"); - return error_mark_node; - } - if (init) - { - base2 = default_conversion (init); - itype = TREE_TYPE (base2); - base2 = get_temp_regvar (itype, base2); - itype = TREE_TYPE (itype); - } - else if (TYPE_LANG_SPECIFIC (type) - && TYPE_NEEDS_CONSTRUCTING (type) - && ! TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) - { - error ("initializer ends prematurely"); - return error_mark_node; - } - } - - /* Now, default-initialize any remaining elements. We don't need to - do that if a) the type does not need constructing, or b) we've - already initialized all the elements. - - We do need to keep going if we're copying an array. */ - - if (from_array - || (TYPE_NEEDS_CONSTRUCTING (type) - && !(TREE_CODE (maxindex) == INTEGER_CST - && num_initialized_elts == TREE_INT_CST_LOW (maxindex) + 1))) - { - /* If the ITERATOR is equal to -1, then we don't have to loop; - we've already initialized all the elements. */ - expand_start_cond (build (NE_EXPR, boolean_type_node, - iterator, minus_one), - 0); - - /* Otherwise, loop through the elements. */ - expand_start_loop_continue_elsewhere (1); - - /* The initialization of each array element is a full-expression. */ - expand_start_target_temps (); - - if (from_array) - { - tree to = build1 (INDIRECT_REF, type, base); - tree from; - - if (base2) - from = build1 (INDIRECT_REF, itype, base2); - else - from = NULL_TREE; - - if (from_array == 2) - expand_expr_stmt (build_modify_expr (to, NOP_EXPR, from)); - else if (TYPE_NEEDS_CONSTRUCTING (type)) - expand_aggr_init (to, from, 0); - else if (from) - expand_assignment (to, from, 0, 0); - else - my_friendly_abort (57); - } - else if (TREE_CODE (type) == ARRAY_TYPE) - { - if (init != 0) - sorry ("cannot initialize multi-dimensional array with initializer"); - expand_vec_init (decl, - build1 (NOP_EXPR, - build_pointer_type (TREE_TYPE - (type)), - base), - array_type_nelts (type), 0, 0); - } - else - expand_aggr_init (build1 (INDIRECT_REF, type, base), init, 0); - - expand_assignment (base, - build (PLUS_EXPR, build_pointer_type (type), - base, size), 0, 0); - if (base2) - expand_assignment (base2, - build (PLUS_EXPR, build_pointer_type (type), - base2, size), 0, 0); - - /* Cleanup any temporaries needed for the initial value. */ - expand_end_target_temps (); - - expand_loop_continue_here (); - expand_exit_loop_if_false (0, build (NE_EXPR, boolean_type_node, - build (PREDECREMENT_EXPR, - ptrdiff_type_node, - iterator, - integer_one_node), - minus_one)); - - if (obey_regdecls) - { - use_variable (DECL_RTL (base)); - if (base2) - use_variable (DECL_RTL (base2)); - } - - expand_end_loop (); - expand_end_cond (); - } - - /* Make sure to cleanup any partially constructed elements. */ - expand_vec_init_catch_clause (rval, type, maxindex, iterator); - - if (obey_regdecls) - { - use_variable (DECL_RTL (iterator)); - use_variable (DECL_RTL (rval)); - } - - return rval; -} - -/* Free up storage of type TYPE, at address ADDR. - - TYPE is a POINTER_TYPE and can be ptr_type_node for no special type - of pointer. - - VIRTUAL_SIZE is the amount of storage that was allocated, and is - used as the second argument to operator delete. It can include - things like padding and magic size cookies. It has virtual in it, - because if you have a base pointer and you delete through a virtual - destructor, it should be the size of the dynamic object, not the - static object, see Free Store 12.5 ANSI C++ WP. - - This does not call any destructors. */ - -tree -build_x_delete (addr, which_delete, virtual_size) - tree addr; - int which_delete; - tree virtual_size; -{ - int use_global_delete = which_delete & 1; - int use_vec_delete = !!(which_delete & 2); - enum tree_code code = use_vec_delete ? VEC_DELETE_EXPR : DELETE_EXPR; - int flags = LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL); - - return build_op_delete_call (code, addr, virtual_size, flags, NULL_TREE); -} - -/* Generate a call to a destructor. TYPE is the type to cast ADDR to. - ADDR is an expression which yields the store to be destroyed. - AUTO_DELETE is nonzero if a call to DELETE should be made or not. - If in the program, (AUTO_DELETE & 2) is non-zero, we tear down the - virtual baseclasses. - If in the program, (AUTO_DELETE & 1) is non-zero, then we deallocate. - - FLAGS is the logical disjunction of zero or more LOOKUP_ - flags. See cp-tree.h for more info. - - This function does not delete an object's virtual base classes. */ - -tree -build_delete (type, addr, auto_delete, flags, use_global_delete) - tree type, addr; - tree auto_delete; - int flags; - int use_global_delete; -{ - tree member; - tree expr; - tree ref; - - if (addr == error_mark_node) - return error_mark_node; - - /* Can happen when CURRENT_EXCEPTION_OBJECT gets its type - set to `error_mark_node' before it gets properly cleaned up. */ - if (type == error_mark_node) - return error_mark_node; - - type = TYPE_MAIN_VARIANT (type); - - if (TREE_CODE (type) == POINTER_TYPE) - { - type = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if (!complete_type_or_else (type)) - return error_mark_node; - if (TREE_CODE (type) == ARRAY_TYPE) - goto handle_array; - if (! IS_AGGR_TYPE (type)) - { - /* Call the builtin operator delete. */ - return build_builtin_delete_call (addr); - } - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - - /* throw away const and volatile on target type of addr */ - addr = convert_force (build_pointer_type (type), addr, 0); - ref = build_indirect_ref (addr, NULL_PTR); - } - else if (TREE_CODE (type) == ARRAY_TYPE) - { - handle_array: - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - if (TYPE_DOMAIN (type) == NULL_TREE) - { - error ("unknown array size in delete"); - return error_mark_node; - } - return build_vec_delete (addr, array_type_nelts (type), - auto_delete, integer_zero_node, - use_global_delete); - } - else - { - /* Don't check PROTECT here; leave that decision to the - destructor. If the destructor is accessible, call it, - else report error. */ - addr = build_unary_op (ADDR_EXPR, addr, 0); - if (TREE_SIDE_EFFECTS (addr)) - addr = save_expr (addr); - - if (TREE_CONSTANT (addr)) - addr = convert_pointer_to (type, addr); - else - addr = convert_force (build_pointer_type (type), addr, 0); - - ref = build_indirect_ref (addr, NULL_PTR); - } - - my_friendly_assert (IS_AGGR_TYPE (type), 220); - - if (! TYPE_NEEDS_DESTRUCTOR (type)) - { - if (auto_delete == integer_zero_node) - return void_zero_node; - - return build_op_delete_call - (DELETE_EXPR, addr, c_sizeof_nowarn (type), - LOOKUP_NORMAL | (use_global_delete * LOOKUP_GLOBAL), - NULL_TREE); - } - - /* Below, we will reverse the order in which these calls are made. - If we have a destructor, then that destructor will take care - of the base classes; otherwise, we must do that here. */ - if (TYPE_HAS_DESTRUCTOR (type)) - { - tree passed_auto_delete; - tree do_delete = NULL_TREE; - tree ifexp; - - if (use_global_delete) - { - tree cond = fold (build (BIT_AND_EXPR, integer_type_node, - auto_delete, integer_one_node)); - tree call = build_builtin_delete_call (addr); - - cond = fold (build (COND_EXPR, void_type_node, cond, - call, void_zero_node)); - if (cond != void_zero_node) - do_delete = cond; - - passed_auto_delete = fold (build (BIT_AND_EXPR, integer_type_node, - auto_delete, integer_two_node)); - } - else - passed_auto_delete = auto_delete; - - expr = build_method_call - (ref, dtor_identifier, build_expr_list (NULL_TREE, passed_auto_delete), - NULL_TREE, flags); - - if (do_delete) - expr = build (COMPOUND_EXPR, void_type_node, expr, do_delete); - - if (flags & LOOKUP_DESTRUCTOR) - /* Explicit destructor call; don't check for null pointer. */ - ifexp = integer_one_node; - else - /* Handle deleting a null pointer. */ - ifexp = fold (build_binary_op (NE_EXPR, addr, integer_zero_node, 1)); - - if (ifexp != integer_one_node) - expr = build (COND_EXPR, void_type_node, - ifexp, expr, void_zero_node); - - return expr; - } - else - { - /* We only get here from finish_function for a destructor. */ - tree binfos = BINFO_BASETYPES (TYPE_BINFO (type)); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree base_binfo = n_baseclasses > 0 ? TREE_VEC_ELT (binfos, 0) : NULL_TREE; - tree exprstmt = NULL_TREE; - tree parent_auto_delete = auto_delete; - tree cond; - - /* Set this again before we call anything, as we might get called - recursively. */ - TYPE_HAS_DESTRUCTOR (type) = 1; - - /* If we have member delete or vbases, we call delete in - finish_function. */ - if (auto_delete == integer_zero_node) - cond = NULL_TREE; - else if (base_binfo == NULL_TREE - || ! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - cond = build (COND_EXPR, void_type_node, - build (BIT_AND_EXPR, integer_type_node, auto_delete, integer_one_node), - build_builtin_delete_call (addr), - void_zero_node); - } - else - cond = NULL_TREE; - - if (cond) - exprstmt = build_expr_list (NULL_TREE, cond); - - if (base_binfo - && ! TREE_VIA_VIRTUAL (base_binfo) - && TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo))) - { - tree this_auto_delete; - - if (BINFO_OFFSET_ZEROP (base_binfo)) - this_auto_delete = parent_auto_delete; - else - this_auto_delete = integer_zero_node; - - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, this_auto_delete)); - exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); - } - - /* Take care of the remaining baseclasses. */ - for (i = 1; i < n_baseclasses; i++) - { - base_binfo = TREE_VEC_ELT (binfos, i); - if (! TYPE_NEEDS_DESTRUCTOR (BINFO_TYPE (base_binfo)) - || TREE_VIA_VIRTUAL (base_binfo)) - continue; - - expr = build_scoped_method_call - (ref, base_binfo, dtor_identifier, - build_expr_list (NULL_TREE, integer_zero_node)); - - exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); - } - - for (member = TYPE_FIELDS (type); member; member = TREE_CHAIN (member)) - { - if (TREE_CODE (member) != FIELD_DECL) - continue; - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (member))) - { - tree this_member = build_component_ref (ref, DECL_NAME (member), NULL_TREE, 0); - tree this_type = TREE_TYPE (member); - expr = build_delete (this_type, this_member, integer_two_node, flags, 0); - exprstmt = expr_tree_cons (NULL_TREE, expr, exprstmt); - } - } - - if (exprstmt) - return build_compound_expr (exprstmt); - /* Virtual base classes make this function do nothing. */ - return void_zero_node; - } -} - -/* For type TYPE, delete the virtual baseclass objects of DECL. */ - -tree -build_vbase_delete (type, decl) - tree type, decl; -{ - tree vbases = CLASSTYPE_VBASECLASSES (type); - tree result = NULL_TREE; - tree addr = build_unary_op (ADDR_EXPR, decl, 0); - - my_friendly_assert (addr != error_mark_node, 222); - - while (vbases) - { - tree this_addr = convert_force (build_pointer_type (BINFO_TYPE (vbases)), - addr, 0); - result = expr_tree_cons (NULL_TREE, - build_delete (TREE_TYPE (this_addr), this_addr, - integer_zero_node, - LOOKUP_NORMAL|LOOKUP_DESTRUCTOR, 0), - result); - vbases = TREE_CHAIN (vbases); - } - return build_compound_expr (nreverse (result)); -} - -/* Build a C++ vector delete expression. - MAXINDEX is the number of elements to be deleted. - ELT_SIZE is the nominal size of each element in the vector. - BASE is the expression that should yield the store to be deleted. - This function expands (or synthesizes) these calls itself. - AUTO_DELETE_VEC says whether the container (vector) should be deallocated. - AUTO_DELETE say whether each item in the container should be deallocated. - - This also calls delete for virtual baseclasses of elements of the vector. - - Update: MAXINDEX is no longer needed. The size can be extracted from the - start of the vector for pointers, and from the type for arrays. We still - use MAXINDEX for arrays because it happens to already have one of the - values we'd have to extract. (We could use MAXINDEX with pointers to - confirm the size, and trap if the numbers differ; not clear that it'd - be worth bothering.) */ - -tree -build_vec_delete (base, maxindex, auto_delete_vec, auto_delete, - use_global_delete) - tree base, maxindex; - tree auto_delete_vec, auto_delete; - int use_global_delete; -{ - tree type; - - if (TREE_CODE (base) == OFFSET_REF) - base = resolve_offset_ref (base); - - type = TREE_TYPE (base); - - base = stabilize_reference (base); - - /* Since we can use base many times, save_expr it. */ - if (TREE_SIDE_EFFECTS (base)) - base = save_expr (base); - - if (TREE_CODE (type) == POINTER_TYPE) - { - /* Step back one from start of vector, and read dimension. */ - tree cookie_addr = build (MINUS_EXPR, build_pointer_type (BI_header_type), - base, BI_header_size); - tree cookie = build_indirect_ref (cookie_addr, NULL_PTR); - maxindex = build_component_ref (cookie, nc_nelts_field_id, NULL_TREE, 0); - do - type = TREE_TYPE (type); - while (TREE_CODE (type) == ARRAY_TYPE); - } - else if (TREE_CODE (type) == ARRAY_TYPE) - { - /* get the total number of things in the array, maxindex is a bad name */ - maxindex = array_type_nelts_total (type); - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - base = build_unary_op (ADDR_EXPR, base, 1); - } - else - { - if (base != error_mark_node) - error ("type to vector delete is neither pointer or array type"); - return error_mark_node; - } - - return build_vec_delete_1 (base, maxindex, type, auto_delete_vec, auto_delete, - use_global_delete); -} diff --git a/gcc/cp/input.c b/gcc/cp/input.c deleted file mode 100755 index 376546b..0000000 --- a/gcc/cp/input.c +++ /dev/null @@ -1,213 +0,0 @@ -/* Input handling for G++. - Copyright (C) 1992, 93-98, 1999 Free Software Foundation, Inc. - Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* G++ needs to do enough saving and re-parsing of text that it is - necessary to abandon the simple FILE* model and use a mechanism where - we can pre-empt one input stream with another derived from saved text; - we may need to do this arbitrarily often, and cannot depend on having - the GNU library available, so FILE objects just don't cut it. - - This file is written as a separate module, but can be included by - lex.c for very minor efficiency gains (primarily in function - inlining). */ - -#include "system.h" - -extern FILE *finput; - -struct input_source { - /* saved string */ - char *str; - int length; - /* current position, when reading as input */ - int offset; - /* linked list maintenance */ - struct input_source *next; - /* values to restore after reading all of current string */ - char *filename; - int lineno; - struct pending_input *input; - int putback_char; -}; - -static struct input_source *input, *free_inputs; - -extern char *input_filename; -extern int lineno; - -#ifdef __GNUC__ -#define inline __inline__ -#else -#define inline -#endif - -#if USE_CPPLIB -extern unsigned char *yy_cur, *yy_lim; -extern int yy_get_token (); -#define GETC() (yy_cur < yy_lim ? *yy_cur++ : yy_get_token ()) -#else -#define GETC() getc (finput) -#endif - -extern void feed_input PROTO((char *, int)); -extern void put_input PROTO((int)); -extern void put_back PROTO((int)); -extern int getch PROTO((void)); -extern int input_redirected PROTO((void)); - -static inline struct input_source * allocate_input PROTO((void)); -static inline void free_input PROTO((struct input_source *)); -static inline void end_input PROTO((void)); -static inline int sub_getch PROTO((void)); - -static inline struct input_source * -allocate_input () -{ - struct input_source *inp; - if (free_inputs) - { - inp = free_inputs; - free_inputs = inp->next; - inp->next = 0; - return inp; - } - inp = (struct input_source *) xmalloc (sizeof (struct input_source)); - inp->next = 0; - return inp; -} - -static inline void -free_input (inp) - struct input_source *inp; -{ - inp->str = 0; - inp->length = 0; - inp->next = free_inputs; - free_inputs = inp; -} - -static int putback_char = -1; - -/* Some of these external functions are declared inline in case this file - is included in lex.c. */ - -inline -void -feed_input (str, len) - char *str; - int len; -{ - struct input_source *inp = allocate_input (); - - /* This shouldn't be necessary. */ - while (len && !str[len-1]) - len--; - - inp->str = str; - inp->length = len; - inp->offset = 0; - inp->next = input; - inp->filename = input_filename; - inp->lineno = lineno; - inp->input = save_pending_input (); - inp->putback_char = putback_char; - putback_char = -1; - input = inp; -} - -struct pending_input *to_be_restored; /* XXX */ -extern int end_of_file; - -static inline void -end_input () -{ - struct input_source *inp = input; - - end_of_file = 0; - input = inp->next; - input_filename = inp->filename; - lineno = inp->lineno; - /* Get interface/implementation back in sync. */ - extract_interface_info (); - putback_char = inp->putback_char; - restore_pending_input (inp->input); - free_input (inp); -} - -static inline int -sub_getch () -{ - if (putback_char != -1) - { - int ch = putback_char; - putback_char = -1; - return ch; - } - if (input) - { - if (input->offset >= input->length) - { - my_friendly_assert (putback_char == -1, 223); - ++(input->offset); - if (input->offset - input->length < 64) - return EOF; - - /* We must be stuck in an error-handling rule; give up. */ - end_input (); - return getch (); - } - return (unsigned char)input->str[input->offset++]; - } - return GETC (); -} - -inline -void -put_back (ch) - int ch; -{ - if (ch != EOF) - { - my_friendly_assert (putback_char == -1, 224); - putback_char = ch; - } -} - -extern int linemode; - -int -getch () -{ - int ch = sub_getch (); - if (linemode && ch == '\n') - { - put_back (ch); - ch = EOF; - } - return ch; -} - -inline -int -input_redirected () -{ - return input != 0; -} diff --git a/gcc/cp/lang-options.h b/gcc/cp/lang-options.h deleted file mode 100755 index 2ae409b..0000000 --- a/gcc/cp/lang-options.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Definitions for switches for C++. - Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -DEFINE_LANG_NAME ("C++") - -/* This is the contribution to the `lang_options' array in gcc.c for - g++. */ - - { "-faccess-control", "" }, - { "-fno-access-control", "Do not obey access control semantics" }, - { "-fall-virtual", "Make all member functions virtual" }, - { "-fno-all-virtual", "" }, - { "-falt-external-templates", "Change when template instances are emitted" }, - { "-fno-alt-external-templates", "" }, - { "-fansi-overloading", "" }, - { "-fno-ansi-overloading", "" }, - { "-fcheck-new", "Check the return value of new" }, - { "-fno-check-new", "" }, - { "-fconserve-space", "Reduce size of object files" }, - { "-fno-conserve-space", "" }, - { "-fconst-strings", "" }, - { "-fno-const-strings", "Make string literals `char[]' instead of `const char[]'" }, - { "-fdefault-inline", "" }, - { "-fno-default-inline", "Do not inline member functions by default"}, - { "-frtti", "" }, - { "-fno-rtti", "Do not generate run time type descriptor information" }, - { "-felide-constructors", "" }, - { "-fno-elide-constructors", "" }, -/* CYGNUS LOCAL Embedded C++ */ - { "-fembedded-cxx", "Implement Embedded C++ specification" }, - { "-fno-embedded-cxx", "" }, -/* END CYGNUS LOCAL Embedded C++ */ - { "-fenum-int-equiv", "" }, - { "-fno-enum-int-equiv", "" }, - { "-fexternal-templates", "" }, - { "-fno-external-templates", "" }, - { "-ffor-scope", "" }, - { "-fno-for-scope", "Scope of for-init-statement vars extends outside" }, - { "-fguiding-decls", "Implement guiding declarations" }, - { "-fno-guiding-decls", "" }, - { "-fgnu-keywords", "" }, - { "-fno-gnu-keywords", "Do not recognise GNU defined keywords" }, - { "-fhandle-exceptions", "" }, - { "-fno-handle-exceptions", "" }, - { "-fhandle-signatures", "Handle signature language constructs" }, - { "-fno-handle-signatures", "" }, - { "-fhonor-std", "Treat the namespace `std' as a normal namespace" }, - { "-fno-honor-std", "" }, - { "-fhuge-objects", "Enable support for huge objects" }, - { "-fno-huge-objects", "" }, - { "-fimplement-inlines", "" }, - { "-fno-implement-inlines", "Export functions even if they can be inlined" }, - { "-fimplicit-templates", "" }, - { "-fno-implicit-templates", "Only emit explicit template instatiations" }, - { "-fimplicit-inline-templates", "" }, - { "-fno-implicit-inline-templates", "Only emit explicit instatiations of inline templates" }, - { "-finit-priority", "Handle the init_priority attribute" }, - { "-fno-init-priority", "" }, - { "-flabels-ok", "Labels can be used as first class objects" }, - { "-fno-labels-ok", "" }, - { "-fmemoize-lookups", "" }, - { "-fno-memoize-lookups", "" }, - { "-fname-mangling-version-", "" }, - { "-fnew-abi", "Enable experimental ABI changes" }, - { "-fno-new-abi", "" }, - { "-fnonnull-objects", "" }, - { "-fno-nonnull-objects", "Do not assume that a reference is always valid" }, - { "-foperator-names", "Recognise and/bitand/bitor/compl/not/or/xor" }, - { "-fno-operator-names", "" }, - { "-foptional-diags", "" }, - { "-fno-optional-diags", "Disable optional diagnostics" }, - { "-fpermissive", "Downgrade conformance errors to warnings" }, - { "-fno-permissive", "" }, - { "-frepo", "Enable automatic template instantiation" }, - { "-fno-repo", "" }, - { "-fsave-memoized", "" }, - { "-fno-save-memoized", "" }, - { "-fsquangle", "Enable squashed name mangling" }, - { "-fno-squangle", "" }, - { "-fstats", "Display statistics accumulated during compilation" }, - { "-fno-stats", "" }, - { "-fstrict-prototype", "" }, - { "-fno-strict-prototype", "Do not assume that empty prototype means no args" }, - { "-ftemplate-depth-", "Specify maximum template instantiation depth"}, - { "-fthis-is-variable", "Make 'this' not be type '* const'" }, - { "-fno-this-is-variable", "" }, - { "-fvtable-gc", "Discard unused virtual functions" }, - { "-fno-vtable-gc", "" }, - { "-fvtable-thunks", "Implement vtables using thunks" }, - { "-fno-vtable-thunks", "" }, - { "-fweak", "Emit common-like symbols as weak symbols" }, - { "-fno-weak", "" }, - { "-fxref", "Emit cross referencing information" }, - { "-fno-xref", "" }, - - { "-Wreturn-type", "Warn about inconsistent return types" }, - { "-Wno-return-type", "" }, - { "-Woverloaded-virtual", "Warn about overloaded virtual function names" }, - { "-Wno-overloaded-virtual", "" }, - { "-Wctor-dtor-privacy", "" }, - { "-Wno-ctor-dtor-privacy", "Don't warn when all ctors/dtors are private" }, - { "-Wnon-virtual-dtor", "Warn about non virtual destructors" }, - { "-Wno-non-virtual-dtor", "" }, - { "-Wextern-inline", "Warn when a function is declared extern, then inline" }, - { "-Wno-extern-inline", "" }, - { "-Wreorder", "Warn when the compiler reorders code" }, - { "-Wno-reorder", "" }, - { "-Wsynth", "Warn when synthesis behaviour differs from Cfront" }, - { "-Wno-synth", "" }, - { "-Wpmf-conversions", "" }, - { "-Wno-pmf-conversions", "Don't warn when type converting pointers to member functions" }, - { "-Weffc++", "Warn about violations of Effective C++ style rules" }, - { "-Wno-effc++", "" }, - { "-Wsign-promo", "Warn when overload promotes from unsigned to signed" }, - { "-Wno-sign-promo", "" }, - { "-Wold-style-cast", "Warn if a C style cast is used in a program" }, - { "-Wno-old-style-cast", "" }, - { "-Wnon-template-friend", "" }, - { "-Wno-non-template-friend", "Don't warn when non-templatized friend functions are declared within a template" }, - diff --git a/gcc/cp/lang-specs.h b/gcc/cp/lang-specs.h deleted file mode 100755 index 13c90ab..0000000 --- a/gcc/cp/lang-specs.h +++ /dev/null @@ -1,99 +0,0 @@ -/* Definitions for specs for C++. - Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is the contribution to the `default_compilers' array in gcc.c for - g++. */ - - {".cc", {"@c++"}}, - {".cp", {"@c++"}}, - {".cxx", {"@c++"}}, - {".cpp", {"@c++"}}, - {".c++", {"@c++"}}, - {".C", {"@c++"}}, - {"@c++", -#if USE_CPPLIB -/* CYGNUS LOCAL Embedded C++ */ - { - "%{E|M|MM:cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ - %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fembedded-cxx:-D__EMBEDDED_CXX__} \ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n}\ - %{!E:%{!M:%{!MM:cc1plus %i %1 %2\ - -lang-c++ %{nostdinc*} %{C} %{A*} %{I*} %{P} %I\ - %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus\ - -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ - %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fembedded-cxx:-D__EMBEDDED_CXX__} \ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{trigraphs}\ - %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ - %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, -/* END CYGNUS LOCAL Embedded C++ */ -#else /* ! USE_CPPLIB */ -/* CYGNUS LOCAL Embedded C++ */ - {"cpp -lang-c++ %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C++ does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUG__=%v1 -D__cplusplus -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -D__STRICT_ANSI__} %{!undef:%{!ansi:%p} %P}\ - %{!fno-exceptions:-D__EXCEPTIONS}\ - %{fembedded-cxx:-D__EMBEDDED_CXX__} \ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} %{trigraphs}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.ii}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", -/* END CYGNUS LOCAL Embedded C++ */ - "%{!M:%{!MM:%{!E:cc1plus %{!pipe:%g.ii} %1 %2\ - %{!Q:-quiet} -dumpbase %b.cc %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ - %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}}|\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, -#endif /* ! USE_CPPLIB */ - {".ii", {"@c++-cpp-output"}}, - {"@c++-cpp-output", - {"%{!M:%{!MM:%{!E:cc1plus %i %1 %2 %{!Q:-quiet} %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi}\ - %{v:-version} %{pg:-p} %{p}\ - %{f*} %{+e*} %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, diff --git a/gcc/cp/lex.c b/gcc/cp/lex.c deleted file mode 100755 index daa61b1..0000000 --- a/gcc/cp/lex.c +++ /dev/null @@ -1,5157 +0,0 @@ -/* Separate lexical analyzer for GNU C++. - Copyright (C) 1987, 89, 92-98, 1999, 2002 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file is the lexical analyzer for GNU C++. */ - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#include "config.h" -#include "system.h" -#include <setjmp.h> -#include "input.h" -#include "tree.h" -#include "lex.h" -#include "cp-tree.h" -#include "parse.h" -#include "flags.h" -#include "obstack.h" -#include "c-pragma.h" -#include "toplev.h" -#include "output.h" - -#ifdef MULTIBYTE_CHARS -#include "mbchar.h" -#include <locale.h> -#endif - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -extern struct obstack permanent_obstack; -extern struct obstack *current_obstack, *saveable_obstack; - -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern void compiler_error PROTO((char *, HOST_WIDE_INT, - HOST_WIDE_INT)); - -static tree get_time_identifier PROTO((char *)); -static int check_newline PROTO((void)); -static int skip_white_space PROTO((int)); -static void finish_defarg PROTO((void)); -static int my_get_run_time PROTO((void)); -static int get_last_nonwhite_on_line PROTO((void)); -static int interface_strcmp PROTO((char *)); -static int readescape PROTO((int *)); -static char *extend_token_buffer PROTO((char *)); -static void consume_string PROTO((struct obstack *, int)); -static void set_typedecl_interface_info PROTO((tree, tree)); -static void feed_defarg PROTO((tree, tree)); -static int set_vardecl_interface_info PROTO((tree, tree)); -static void store_pending_inline PROTO((tree, struct pending_inline *)); -static void reinit_parse_for_expr PROTO((struct obstack *)); -static int *init_cpp_parse PROTO((void)); -static int handle_cp_pragma PROTO((char *)); -#ifdef HANDLE_GENERIC_PRAGMAS -static int handle_generic_pragma PROTO((int)); -#endif -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -static int reduce_cmp PROTO((int *, int *)); -static int token_cmp PROTO((int *, int *)); -#endif -#endif -static void begin_definition_of_inclass_inline PROTO((struct pending_inline*)); - -/* Given a file name X, return the nondirectory portion. - Keep in mind that X can be computed more than once. */ -char * -file_name_nondirectory (x) - char *x; -{ - char *tmp = (char *) rindex (x, '/'); - if (DIR_SEPARATOR != '/' && ! tmp) - tmp = (char *) rindex (x, DIR_SEPARATOR); - if (tmp) - return (char *) (tmp + 1); - else - return x; -} - -/* This obstack is needed to hold text. It is not safe to use - TOKEN_BUFFER because `check_newline' calls `yylex'. */ -struct obstack inline_text_obstack; -char *inline_text_firstobj; - -#if USE_CPPLIB -#include "cpplib.h" -extern cpp_reader parse_in; -extern cpp_options parse_options; -extern unsigned char *yy_cur, *yy_lim; -#else -FILE *finput; -#endif -int end_of_file; - -/* CYGNUS LOCAL Embedded C++ */ -/* If non-zero, we gave an error about namespaces not being allowed by - Embedded C++. */ -static int embedded_namespace_error = 0; - -/* If non-zero, we gave an error about templates not being allowed by - Embedded C++. */ -static int embedded_template_error = 0; - -/* If non-zero, we gave an error about exception handling not being allowed by - Embedded C++. */ -static int embedded_eh_error = 0; -/* END CYGNUS LOCAL Embedded C++ */ - -/* Pending language change. - Positive is push count, negative is pop count. */ -int pending_lang_change = 0; - -/* Wrap the current header file in extern "C". */ -static int c_header_level = 0; - -extern int first_token; -extern struct obstack token_obstack; - -/* ??? Don't really know where this goes yet. */ -#if 1 -#include "input.c" -#else -extern void put_back (/* int */); -extern int input_redirected (); -extern void feed_input (/* char *, int */); -#endif - -/* Holds translations from TREE_CODEs to operator name strings, - i.e., opname_tab[PLUS_EXPR] == "+". */ -char **opname_tab; -char **assignop_tab; - -extern int yychar; /* the lookahead symbol */ -extern YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#if 0 -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -tree lastiddecl; - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -tree ridpointers[(int) RID_MAX]; - -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static tree filename_times; -static tree this_filename_time; - -/* Array for holding counts of the numbers of tokens seen. */ -extern int *token_count; - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - CV_QUALIFIERS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (cv_qualifiers, target) - tree cv_qualifiers, target; -{ - if (target && TREE_CODE (target) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (target)) - error ("type name expected before `*'"); - target = build_parse_node (INDIRECT_REF, target); - TREE_TYPE (target) = cv_qualifiers; - return target; -} - -/* Return something to represent absolute declarators containing a &. - TARGET is the absolute declarator that the & contains. - CV_QUALIFIERS is a list of modifiers such as const or volatile - to apply to the reference type, represented as identifiers. - - We return an ADDR_EXPR whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_reference_declarator (cv_qualifiers, target) - tree cv_qualifiers, target; -{ - if (target) - { - if (TREE_CODE (target) == ADDR_EXPR) - { - error ("cannot declare references to references"); - return target; - } - if (TREE_CODE (target) == INDIRECT_REF) - { - error ("cannot declare pointers to references"); - return target; - } - if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target)) - error ("type name expected before `&'"); - } - target = build_parse_node (ADDR_EXPR, target); - TREE_TYPE (target) = cv_qualifiers; - return target; -} - -tree -make_call_declarator (target, parms, cv_qualifiers, exception_specification) - tree target, parms, cv_qualifiers, exception_specification; -{ - target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers); - TREE_TYPE (target) = exception_specification; - return target; -} - -void -set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification) - tree call_declarator, cv_qualifiers, exception_specification; -{ - TREE_OPERAND (call_declarator, 2) = cv_qualifiers; - TREE_TYPE (call_declarator) = exception_specification; -} - -/* Build names and nodes for overloaded operators. */ - -tree ansi_opname[LAST_CPLUS_TREE_CODE]; -tree ansi_assopname[LAST_CPLUS_TREE_CODE]; - -char * -operator_name_string (name) - tree name; -{ - char *opname = IDENTIFIER_POINTER (name) + 2; - tree *opname_table; - int i, assign; - - /* Works for builtin and user defined types. */ - if (IDENTIFIER_GLOBAL_VALUE (name) - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL) - return IDENTIFIER_POINTER (name); - - if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_') - { - opname += 1; - assign = 1; - opname_table = ansi_assopname; - } - else - { - assign = 0; - opname_table = ansi_opname; - } - - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign] - && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign]) - break; - } - - if (i == LAST_CPLUS_TREE_CODE) - return "<invalid operator>"; - - if (assign) - return assignop_tab[i]; - else - return opname_tab[i]; -} - -int interface_only; /* whether or not current file is only for - interface definitions. */ -int interface_unknown; /* whether or not we know this class - to behave according to #pragma interface. */ - -/* lexical analyzer */ - -#ifndef WCHAR_TYPE_SIZE -#ifdef INT_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#else -#define WCHAR_TYPE_SIZE BITS_PER_WORD -#endif -#endif - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. */ - -#include "hash.h" - - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag = 0; - -static tree -get_time_identifier (name) - char *name; -{ - tree time_identifier; - int len = strlen (name); - char *buf = (char *) alloca (len + 6); - strcpy (buf, "file "); - bcopy (name, buf+5, len); - buf[len+5] = '\0'; - time_identifier = get_identifier (buf); - if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0); - TIME_IDENTIFIER_FILEINFO (time_identifier) - = build_int_2 (0, 1); - SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); - filename_times = time_identifier; - pop_obstacks (); - } - return time_identifier; -} - -#ifdef __GNUC__ -__inline -#endif -static int -my_get_run_time () -{ - int old_quiet_flag = quiet_flag; - int this_time; - quiet_flag = 0; - this_time = get_run_time (); - quiet_flag = old_quiet_flag; - return this_time; -} - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See cp/cp-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char cplus_tree_code_type[] = { - 'x', -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int cplus_tree_code_length[] = { - 0, -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *cplus_tree_code_name[] = { - "@@dummy", -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* toplev.c needs to call these. */ - -void -lang_init_options () -{ -#if USE_CPPLIB - cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); -#endif - - /* Default exceptions on. */ - flag_exceptions = 1; -} - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ -#if ! USE_CPPLIB - put_back (check_newline ()); -#else - check_newline (); - yy_cur--; -#endif - if (flag_gnu_xref) GNU_xref_begin (input_filename); - init_repo (input_filename); -} - -void -lang_finish () -{ - extern int errorcount, sorrycount; - if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount); -} - -char * -lang_identify () -{ - return "cplusplus"; -} - -void -init_filename_times () -{ - this_filename_time = get_time_identifier ("<top level>"); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = my_get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - = body_time; - } -} - -/* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989. - Stuck this hack in to get the files open correctly; this is called - in place of init_parse if we are an unexec'd binary. */ - -#if 0 -void -reinit_lang_specific () -{ - init_filename_times (); - reinit_search_statistics (); -} -#endif - -static int * -init_cpp_parse () -{ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1)); - bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1)); - reduce_count += 1; - token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1)); - bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1)); - token_count += 1; -#endif -#endif - return token_count; -} - -char * -init_parse (filename) - char *filename; -{ - extern int flag_no_gnu_keywords; - extern int flag_operator_names; - - int i; - -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); - literal_codeset = getenv ("LANG"); -#endif - -#if USE_CPPLIB - parse_in.show_column = 1; - if (! cpp_start_read (&parse_in, filename)) - abort (); - - /* cpp_start_read always puts at least one line directive into the - token buffer. We must arrange to read it out here. */ - yy_cur = parse_in.token_buffer; - yy_lim = CPP_PWRITTEN (&parse_in); - -#else - /* Open input file. */ - if (filename == 0 || !strcmp (filename, "-")) - { - finput = stdin; - filename = "stdin"; - } - else - finput = fopen (filename, "r"); - if (finput == 0) - pfatal_with_name (filename); - -#ifdef IO_BUFFER_SIZE - setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); -#endif -#endif /* !USE_CPPLIB */ - - /* Initialize the lookahead machinery. */ - init_spew (); - - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - decl_printable_name = lang_printable_name; - - init_cplus_expand (); - - bcopy (cplus_tree_code_type, - tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE, - (int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE); - bcopy ((char *)cplus_tree_code_length, - (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int)); - bcopy ((char *)cplus_tree_code_name, - (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); - - opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - - ansi_opname[0] = get_identifier ("<invalid operator>"); - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - ansi_opname[i] = ansi_opname[0]; - ansi_assopname[i] = ansi_opname[0]; - } - - ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1; - ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR]; - ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1; - ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR]; - ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1; - ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR]; - ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1; - ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR]; - ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1; - ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1; - ansi_opname[(int) NE_EXPR] = get_identifier ("__ne"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1; - ansi_opname[(int) GT_EXPR] = get_identifier ("__gt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1; - ansi_opname[(int) GE_EXPR] = get_identifier ("__ge"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1; - ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1; - ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1; - ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1; - ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1; - ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR]; - ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1; - ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR]; - ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1; - ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1; - ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1; - ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl"); - ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1; - ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1; - ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR]; - ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR]; - ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1; - ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1; - ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1; - ansi_opname[(int) LT_EXPR] = get_identifier ("__lt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1; - ansi_opname[(int) LE_EXPR] = get_identifier ("__le"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1; - ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1; - ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1; - ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR]; - ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR]; - ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1; - ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1; - ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1; - ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1; - ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR]; - ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1; - ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1; - ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1; - ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1; - ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1; - ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1; - ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1; - ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1; - ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; - - /* This is not true: these operators are not defined in ANSI, - but we need them anyway. */ - ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1; - ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1; - ansi_opname[(int) COND_EXPR] = get_identifier ("__cn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1; - ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1; - - init_method (); - init_error (); - gcc_obstack_init (&inline_text_obstack); - inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - input_filename = "<internal>"; - current_function_decl = NULL; - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers[(int) RID_INT] = get_identifier ("int"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INT])); - ridpointers[(int) RID_BOOL] = get_identifier ("bool"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL])); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR])); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID])); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT])); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE])); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT])); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG], - build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG])); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED])); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED])); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE])); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST])); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE])); - ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT])); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO], - build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO])); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN])); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF])); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], - build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); - ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX], - build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX])); - - /* C++ extensions. These are probably not correctly named. */ - ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR])); - class_type_node = build_int_2 (class_type, 0); - TREE_TYPE (class_type_node) = class_type_node; - ridpointers[(int) RID_CLASS] = class_type_node; - - record_type_node = build_int_2 (record_type, 0); - TREE_TYPE (record_type_node) = record_type_node; - ridpointers[(int) RID_RECORD] = record_type_node; - - union_type_node = build_int_2 (union_type, 0); - TREE_TYPE (union_type_node) = union_type_node; - ridpointers[(int) RID_UNION] = union_type_node; - - enum_type_node = build_int_2 (enum_type, 0); - TREE_TYPE (enum_type_node) = enum_type_node; - ridpointers[(int) RID_ENUM] = enum_type_node; - - ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); - ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT])); - ridpointers[(int) RID_EXPORT] = get_identifier ("export"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPORT])); - ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); - - ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC])); - ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE])); - ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); - ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE])); - /* This is for ANSI C++. */ - ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE])); - - /* Signature handling extensions. */ - signature_type_node = build_int_2 (signature_type, 0); - TREE_TYPE (signature_type_node) = signature_type_node; - ridpointers[(int) RID_SIGNATURE] = signature_type_node; - - /* Create the built-in __null node. Note that we can't yet call for - type_for_size here because integer_type_node and so forth are not - set up. Therefore, we don't set the type of these nodes until - init_decl_processing. */ - null_node = build_int_2 (0, 0); - ridpointers[RID_NULL] = null_node; - - opname_tab[(int) COMPONENT_REF] = "->"; - opname_tab[(int) MEMBER_REF] = "->*"; - opname_tab[(int) INDIRECT_REF] = "*"; - opname_tab[(int) ARRAY_REF] = "[]"; - opname_tab[(int) MODIFY_EXPR] = "="; - opname_tab[(int) NEW_EXPR] = "new"; - opname_tab[(int) DELETE_EXPR] = "delete"; - opname_tab[(int) VEC_NEW_EXPR] = "new []"; - opname_tab[(int) VEC_DELETE_EXPR] = "delete []"; - opname_tab[(int) COND_EXPR] = "?:"; - opname_tab[(int) CALL_EXPR] = "()"; - opname_tab[(int) PLUS_EXPR] = "+"; - opname_tab[(int) MINUS_EXPR] = "-"; - opname_tab[(int) MULT_EXPR] = "*"; - opname_tab[(int) TRUNC_DIV_EXPR] = "/"; - opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)"; - opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)"; - opname_tab[(int) ROUND_DIV_EXPR] = "(round /)"; - opname_tab[(int) TRUNC_MOD_EXPR] = "%"; - opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; - opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; - opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; - opname_tab[(int) NEGATE_EXPR] = "-"; - opname_tab[(int) MIN_EXPR] = "<?"; - opname_tab[(int) MAX_EXPR] = ">?"; - opname_tab[(int) ABS_EXPR] = "abs"; - opname_tab[(int) FFS_EXPR] = "ffs"; - opname_tab[(int) LSHIFT_EXPR] = "<<"; - opname_tab[(int) RSHIFT_EXPR] = ">>"; - opname_tab[(int) BIT_IOR_EXPR] = "|"; - opname_tab[(int) BIT_XOR_EXPR] = "^"; - opname_tab[(int) BIT_AND_EXPR] = "&"; - opname_tab[(int) BIT_ANDTC_EXPR] = "&~"; - opname_tab[(int) BIT_NOT_EXPR] = "~"; - opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&"; - opname_tab[(int) TRUTH_ORIF_EXPR] = "||"; - opname_tab[(int) TRUTH_AND_EXPR] = "strict &&"; - opname_tab[(int) TRUTH_OR_EXPR] = "strict ||"; - opname_tab[(int) TRUTH_NOT_EXPR] = "!"; - opname_tab[(int) LT_EXPR] = "<"; - opname_tab[(int) LE_EXPR] = "<="; - opname_tab[(int) GT_EXPR] = ">"; - opname_tab[(int) GE_EXPR] = ">="; - opname_tab[(int) EQ_EXPR] = "=="; - opname_tab[(int) NE_EXPR] = "!="; - opname_tab[(int) IN_EXPR] = "in"; - opname_tab[(int) RANGE_EXPR] = "..."; - opname_tab[(int) CONVERT_EXPR] = "+"; - opname_tab[(int) ADDR_EXPR] = "&"; - opname_tab[(int) PREDECREMENT_EXPR] = "--"; - opname_tab[(int) PREINCREMENT_EXPR] = "++"; - opname_tab[(int) POSTDECREMENT_EXPR] = "--"; - opname_tab[(int) POSTINCREMENT_EXPR] = "++"; - opname_tab[(int) COMPOUND_EXPR] = ","; - - assignop_tab[(int) NOP_EXPR] = "="; - assignop_tab[(int) PLUS_EXPR] = "+="; - assignop_tab[(int) CONVERT_EXPR] = "+="; - assignop_tab[(int) MINUS_EXPR] = "-="; - assignop_tab[(int) NEGATE_EXPR] = "-="; - assignop_tab[(int) MULT_EXPR] = "*="; - assignop_tab[(int) INDIRECT_REF] = "*="; - assignop_tab[(int) TRUNC_DIV_EXPR] = "/="; - assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)"; - assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)"; - assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)"; - assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)"; - assignop_tab[(int) TRUNC_MOD_EXPR] = "%="; - assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)"; - assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)"; - assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)"; - assignop_tab[(int) MIN_EXPR] = "<?="; - assignop_tab[(int) MAX_EXPR] = ">?="; - assignop_tab[(int) LSHIFT_EXPR] = "<<="; - assignop_tab[(int) RSHIFT_EXPR] = ">>="; - assignop_tab[(int) BIT_IOR_EXPR] = "|="; - assignop_tab[(int) BIT_XOR_EXPR] = "^="; - assignop_tab[(int) BIT_AND_EXPR] = "&="; - assignop_tab[(int) ADDR_EXPR] = "&="; - - init_filename_times (); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - -#if 0 - /* let's parse things, and if they use it, then give them an error. */ - if (!flag_exceptions) - { - UNSET_RESERVED_WORD ("throw"); - UNSET_RESERVED_WORD ("try"); - UNSET_RESERVED_WORD ("catch"); - } -#endif - - if (!flag_rtti || flag_no_gnu_keywords) - { - UNSET_RESERVED_WORD ("classof"); - UNSET_RESERVED_WORD ("headof"); - } - - if (! flag_handle_signatures || flag_no_gnu_keywords) - { - /* Easiest way to not recognize signature - handling extensions... */ - UNSET_RESERVED_WORD ("signature"); - UNSET_RESERVED_WORD ("sigof"); - } - if (flag_no_asm || flag_no_gnu_keywords) - UNSET_RESERVED_WORD ("typeof"); - if (! flag_operator_names) - { - /* These are new ANSI keywords that may break code. */ - UNSET_RESERVED_WORD ("and"); - UNSET_RESERVED_WORD ("and_eq"); - UNSET_RESERVED_WORD ("bitand"); - UNSET_RESERVED_WORD ("bitor"); - UNSET_RESERVED_WORD ("compl"); - UNSET_RESERVED_WORD ("not"); - UNSET_RESERVED_WORD ("not_eq"); - UNSET_RESERVED_WORD ("or"); - UNSET_RESERVED_WORD ("or_eq"); - UNSET_RESERVED_WORD ("xor"); - UNSET_RESERVED_WORD ("xor_eq"); - } - - token_count = init_cpp_parse (); - interface_unknown = 1; - - return filename; -} - -void -finish_parse () -{ -#if USE_CPPLIB - cpp_finish (&parse_in); -#else - fclose (finput); -#endif -} - -void -reinit_parse_for_function () -{ - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; -} - -#ifdef __GNUC__ -__inline -#endif -void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; -{ - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case TYPESPEC: - case PTYPENAME: - case IDENTIFIER_DEFN: - case TYPENAME_DEFN: - case PTYPENAME_DEFN: - case SCSPEC: - case PRE_PARSED_CLASS_DECL: - t = yylval.ttype; - if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL) - { - fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t))); - break; - } - my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224); - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - case AGGR: - if (yylval.ttype == class_type_node) - fprintf (file, " `class'"); - else if (yylval.ttype == record_type_node) - fprintf (file, " `struct'"); - else if (yylval.ttype == union_type_node) - fprintf (file, " `union'"); - else if (yylval.ttype == enum_type_node) - fprintf (file, " `enum'"); - else if (yylval.ttype == signature_type_node) - fprintf (file, " `signature'"); - else - my_friendly_abort (80); - break; - } -} - -#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH) -static int *reduce_count; -#endif - -int *token_count; - -#if 0 -#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) -#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) -#endif - -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -void -yyhook (yyn) - int yyn; -{ - reduce_count[yyn] += 1; -} - -static int -reduce_cmp (p, q) - int *p, *q; -{ - return reduce_count[*q] - reduce_count[*p]; -} - -static int -token_cmp (p, q) - int *p, *q; -{ - return token_count[*q] - token_count[*p]; -} -#endif -#endif - -void -print_parse_statistics () -{ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -#if YYDEBUG != 0 - int i; - int maxlen = REDUCE_LENGTH; - unsigned *sorted; - - if (reduce_count[-1] == 0) - return; - - if (TOKEN_LENGTH > REDUCE_LENGTH) - maxlen = TOKEN_LENGTH; - sorted = (unsigned *) alloca (sizeof (int) * maxlen); - - for (i = 0; i < TOKEN_LENGTH; i++) - sorted[i] = i; - qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp); - for (i = 0; i < TOKEN_LENGTH; i++) - { - int idx = sorted[i]; - if (token_count[idx] == 0) - break; - if (token_count[idx] < token_count[-1]) - break; - fprintf (stderr, "token %d, `%s', count = %d\n", - idx, yytname[YYTRANSLATE (idx)], token_count[idx]); - } - fprintf (stderr, "\n"); - for (i = 0; i < REDUCE_LENGTH; i++) - sorted[i] = i; - qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp); - for (i = 0; i < REDUCE_LENGTH; i++) - { - int idx = sorted[i]; - if (reduce_count[idx] == 0) - break; - if (reduce_count[idx] < reduce_count[-1]) - break; - fprintf (stderr, "rule %d, line %d, count = %d\n", - idx, yyrline[idx], reduce_count[idx]); - } - fprintf (stderr, "\n"); -#endif -#endif -#endif -} - -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - -void -set_yydebug (value) - int value; -{ -#if YYDEBUG != 0 - extern int yydebug; - yydebug = value; -#else - warning ("YYDEBUG not defined."); -#endif -} - - -/* Functions and data structures for #pragma interface. - - `#pragma implementation' means that the main file being compiled - is considered to implement (provide) the classes that appear in - its main body. I.e., if this is file "foo.cc", and class `bar' - is defined in "foo.cc", then we say that "foo.cc implements bar". - - All main input files "implement" themselves automagically. - - `#pragma interface' means that unless this file (of the form "foo.h" - is not presently being included by file "foo.cc", the - CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none - of the vtables nor any of the inline functions defined in foo.h - will ever be output. - - There are cases when we want to link files such as "defs.h" and - "main.cc". In this case, we give "defs.h" a `#pragma interface', - and "main.cc" has `#pragma implementation "defs.h"'. */ - -struct impl_files -{ - char *filename; - struct impl_files *next; -}; - -static struct impl_files *impl_file_chain; - -/* Helper function to load global variables with interface - information. */ - -void -extract_interface_info () -{ - tree fileinfo = 0; - - if (flag_alt_external_templates) - { - struct tinst_level *til = tinst_for_decl (); - - if (til) - fileinfo = get_time_identifier (til->file); - } - if (!fileinfo) - fileinfo = get_time_identifier (input_filename); - fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo); - interface_only = TREE_INT_CST_LOW (fileinfo); - interface_unknown = TREE_INT_CST_HIGH (fileinfo); -} - -/* Return nonzero if S is not considered part of an - INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ - -static int -interface_strcmp (s) - char *s; -{ - /* Set the interface/implementation bits for this scope. */ - struct impl_files *ifiles; - char *s1; - - for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) - { - char *t1 = ifiles->filename; - s1 = s; - - if (*s1 != *t1 || *s1 == 0) - continue; - - while (*s1 == *t1 && *s1 != 0) - s1++, t1++; - - /* A match. */ - if (*s1 == *t1) - return 0; - - /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ - if (index (s1, '.') || index (t1, '.')) - continue; - - if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') - continue; - - /* A match. */ - return 0; - } - - /* No matches. */ - return 1; -} - -static void -set_typedecl_interface_info (prev, vars) - tree prev ATTRIBUTE_UNUSED, vars; -{ - tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); - tree fileinfo = TIME_IDENTIFIER_FILEINFO (id); - tree type = TREE_TYPE (vars); - - CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) - = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars))); -} - -static int -set_vardecl_interface_info (prev, vars) - tree prev, vars; -{ - tree type = DECL_CONTEXT (vars); - - if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - if (CLASSTYPE_INTERFACE_ONLY (type)) - set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type)); - else - CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; - DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); - TREE_PUBLIC (vars) = 1; - return 1; - } - return 0; -} - -/* Set up the state required to correctly handle the definition of the - inline function whose preparsed state has been saved in PI. */ - -static void -begin_definition_of_inclass_inline (pi) - struct pending_inline* pi; -{ - tree context; - - if (!pi->fndecl) - return; - - /* If this is an inline function in a local class, we must make sure - that we save all pertinent information about the function - surrounding the local class. */ - context = hack_decl_function_context (pi->fndecl); - if (context) - push_cp_function_context (context); - - feed_input (pi->buf, pi->len); - lineno = pi->lineno; - input_filename = pi->filename; - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.ttype = build_tree_list ((tree) pi, pi->fndecl); - /* Pass back a handle to the rest of the inline functions, so that they - can be processed later. */ - DECL_PENDING_INLINE_INFO (pi->fndecl) = 0; - interface_unknown = pi->interface == 1; - interface_only = pi->interface == 0; -} - -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. This function sets up the first function - to be parsed; after it has been, the rule for fndef in parse.y will - call process_next_inline to start working on the next one. */ - -void -do_pending_inlines () -{ - struct pending_inline *t; - - /* Oops, we're still dealing with the last batch. */ - if (yychar == PRE_PARSED_FUNCTION_DECL) - return; - - /* Reverse the pending inline functions, since - they were cons'd instead of appended. */ - { - struct pending_inline *prev = 0, *tail; - t = pending_inlines; - pending_inlines = 0; - - for (; t; t = tail) - { - tail = t->next; - t->next = prev; - t->deja_vu = 1; - prev = t; - } - t = prev; - } - - if (t == 0) - return; - - /* Now start processing the first inline function. */ - begin_definition_of_inclass_inline (t); -} - -static int nextchar = -1; - -/* Called from the fndecl rule in the parser when the function just parsed - was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from - do_pending_inlines). */ - -void -process_next_inline (t) - tree t; -{ - tree context; - struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); - context = hack_decl_function_context (i->fndecl); - if (context) - pop_cp_function_context (context); - i = i->next; - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. We also need to discard nextchar, - since that may have gotten set as well. */ - nextchar = -1; - } - yychar = YYEMPTY; - end_input (); - if (i) - begin_definition_of_inclass_inline (i); - else - extract_interface_info (); -} - -/* Since inline methods can refer to text which has not yet been seen, - we store the text of the method in a structure which is placed in the - DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. - After parsing the body of the class definition, the FUNCTION_DECL's are - scanned to see which ones have this field set. Those are then digested - one at a time. - - This function's FUNCTION_DECL will have a bit set in its common so - that we know to watch out for it. */ - -#ifdef MULTIBYTE_CHARS -static int consume_string_buffer_max = 0; -static int consume_string_buffer_size = 0; -static char *consume_string_buffer = 0; - -static void -consume_string_buffer_add (c) - char c; -{ - if (consume_string_buffer_size >= consume_string_buffer_max) - { - consume_string_buffer_max += 10; /* arbitrary */ - consume_string_buffer = (char *) xrealloc (consume_string_buffer, - consume_string_buffer_max); - } - consume_string_buffer[consume_string_buffer_size++] = c; -} -#endif - -static void -consume_string (this_obstack, matching_char) - register struct obstack *this_obstack; - int matching_char; -{ - register int c; - int starting_lineno = lineno; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - do - { - c = getch (); - try_again: - if (c == EOF) - { - int save_lineno = lineno; - lineno = starting_lineno; - if (matching_char == '"') - error ("end of file encountered inside string constant"); - else - error ("end of file encountered inside character constant"); - lineno = save_lineno; - return; - } - if (c == '\\') - { - obstack_1grow (this_obstack, c); - c = getch (); - obstack_1grow (this_obstack, c); - - /* Make sure we continue the loop */ - c = 0; - continue; - } - if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } -#ifdef MULTIBYTE_CHARS - { - wchar_t wc; - int i; - int char_len = -1; - - consume_string_buffer_size = 0; - for (i = 1; i <= longest_char; ++i) - { - consume_string_buffer_add(c); - char_len = local_mbtowc (& wc, - consume_string_buffer, - i); - if (char_len != -1) - break; - c = getch (); - } - - if (char_len > 0) - { - obstack_grow (this_obstack, consume_string_buffer, char_len - 1); - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - goto try_again; - } - else - warning ("Ignoring invalid multibyte character"); - } -#endif /* MULTIBYTE_CHARS */ - obstack_1grow (this_obstack, c); - } - while (c != matching_char); -} - -static int nextyychar = YYEMPTY; -static YYSTYPE nextyylval; - -struct pending_input { - int nextchar, yychar, nextyychar, eof; - YYSTYPE yylval, nextyylval; - struct obstack token_obstack; - int first_token; -}; - -struct pending_input * -save_pending_input () -{ - struct pending_input *p; - p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); - p->nextchar = nextchar; - p->yychar = yychar; - p->nextyychar = nextyychar; - p->yylval = yylval; - p->nextyylval = nextyylval; - p->eof = end_of_file; - yychar = nextyychar = YYEMPTY; - nextchar = -1; - p->first_token = first_token; - p->token_obstack = token_obstack; - - first_token = 0; - gcc_obstack_init (&token_obstack); - end_of_file = 0; - return p; -} - -void -restore_pending_input (p) - struct pending_input *p; -{ - my_friendly_assert (nextchar == -1, 229); - nextchar = p->nextchar; - my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); - yychar = p->yychar; - my_friendly_assert (nextyychar == YYEMPTY, 231); - nextyychar = p->nextyychar; - yylval = p->yylval; - nextyylval = p->nextyylval; - first_token = p->first_token; - obstack_free (&token_obstack, (char *) 0); - token_obstack = p->token_obstack; - end_of_file = p->eof; - free (p); -} - -/* Unget character CH from the input stream. - If RESCAN is non-zero, then we want to `see' this - character as the next input token. */ - -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - if (nextchar >= 0) - put_back (nextchar); - nextchar = ch; - } - else - { - my_friendly_assert (nextyychar == YYEMPTY, 232); - nextyychar = yychar; - nextyylval = yylval; - yychar = ch; - } -} - -void -clear_inline_text_obstack () -{ - obstack_free (&inline_text_obstack, inline_text_firstobj); -} - -/* This function stores away the text for an inline function that should - be processed later. It decides how much later, and may need to move - the info between obstacks; therefore, the caller should not refer to - the T parameter after calling this function. */ - -static void -store_pending_inline (decl, t) - tree decl; - struct pending_inline *t; -{ - t->fndecl = decl; - DECL_PENDING_INLINE_INFO (decl) = t; - - /* Because we use obstacks, we must process these in precise order. */ - t->next = pending_inlines; - pending_inlines = t; -} - -void -reinit_parse_for_method (yychar, decl) - int yychar; - tree decl; -{ - int len; - int starting_lineno = lineno; - char *starting_filename = input_filename; - - reinit_parse_for_block (yychar, &inline_text_obstack); - - len = obstack_object_size (&inline_text_obstack); - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - if (decl == void_type_node - || (current_class_type && TYPE_REDEFINED (current_class_type))) - { - /* Happens when we get two declarations of the same - function in the same scope. */ - char *buf = obstack_finish (&inline_text_obstack); - obstack_free (&inline_text_obstack, buf); - return; - } - else - { - struct pending_inline *t; - char *buf = obstack_finish (&inline_text_obstack); - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->lineno = starting_lineno; - t->filename = starting_filename; - t->token = YYEMPTY; - t->token_value = 0; - t->buf = buf; - t->len = len; - t->deja_vu = 0; -#if 0 - if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) - warn_if_unknown_interface (decl); -#endif - t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); - store_pending_inline (decl, t); - } -} - -/* Consume a block -- actually, a method beginning - with `:' or `{' -- and save it away on the specified obstack. */ - -void -reinit_parse_for_block (pyychar, obstackp) - int pyychar; - struct obstack *obstackp; -{ - register int c = 0; - int blev = 1; - int starting_lineno = lineno; - char *starting_filename = input_filename; - int len; - int look_for_semicolon = 0; - int look_for_lbrac = 0; - - if (pyychar == '{') - obstack_1grow (obstackp, '{'); - else if (pyychar == '=') - look_for_semicolon = 1; - else if (pyychar == ':') - { - obstack_1grow (obstackp, pyychar); - /* Add a space so we don't get confused by ': ::A(20)'. */ - obstack_1grow (obstackp, ' '); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == RETURN) - { - obstack_grow (obstackp, "return", 6); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == TRY) - { - obstack_grow (obstackp, "try", 3); - look_for_lbrac = 1; - blev = 0; - } - else - { - yyerror ("parse error in method specification"); - obstack_1grow (obstackp, '{'); - } - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - c = skip_white_space (c); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; i--) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - obstack_1grow (obstackp, c); - if (c == '{') - { - look_for_lbrac = 0; - blev++; - } - else if (c == '}') - { - blev--; - if (blev == 0 && !look_for_semicolon) - { - if (pyychar == TRY) - { - if (peekyylex () == CATCH) - { - yylex (); - obstack_grow (obstackp, " catch ", 7); - look_for_lbrac = 1; - } - else - { - yychar = '{'; - goto done; - } - } - else - { - goto done; - } - } - } - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - else if (c == ';') - { - if (look_for_lbrac) - { - error ("function body for constructor missing"); - obstack_1grow (obstackp, '{'); - obstack_1grow (obstackp, '}'); - len += 2; - goto done; - } - else if (look_for_semicolon && blev == 0) - goto done; - } - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -/* Consume a no-commas expression -- actually, a default argument -- and - save it away on the specified obstack. */ - -static void -reinit_parse_for_expr (obstackp) - struct obstack *obstackp; -{ - register int c = 0; - int starting_lineno = lineno; - char *starting_filename = input_filename; - int len; - int plev = 0; - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - c = skip_white_space (c); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; --i) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - if (plev <= 0 && (c == ')' || c == ',')) - { - put_back (c); - goto done; - } - obstack_1grow (obstackp, c); - if (c == '(' || c == '[') - ++plev; - else if (c == ']' || c == ')') - --plev; - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -int do_snarf_defarg; - -/* Decide whether the default argument we are about to see should be - gobbled up as text for later parsing. */ - -void -maybe_snarf_defarg () -{ - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - do_snarf_defarg = 1; -} - -/* When we see a default argument in a method declaration, we snarf it as - text using snarf_defarg. When we get up to namespace scope, we then go - through and parse all of them using do_pending_defargs. Since yacc - parsers are not reentrant, we retain defargs state in these two - variables so that subsequent calls to do_pending_defargs can resume - where the previous call left off. */ - -tree defarg_fns; -tree defarg_parm; - -tree -snarf_defarg () -{ - int len; - char *buf; - tree arg; - - reinit_parse_for_expr (&inline_text_obstack); - len = obstack_object_size (&inline_text_obstack); - buf = obstack_finish (&inline_text_obstack); - - push_obstacks (&inline_text_obstack, &inline_text_obstack); - arg = make_node (DEFAULT_ARG); - DEFARG_LENGTH (arg) = len - 1; - DEFARG_POINTER (arg) = buf; - pop_obstacks (); - - return arg; -} - -/* Called from grokfndecl to note a function decl with unparsed default - arguments for later processing. Also called from grokdeclarator - for function types with unparsed defargs; the call from grokfndecl - will always come second, so we can overwrite the entry from the type. */ - -void -add_defarg_fn (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - TREE_VALUE (defarg_fns) = decl; - else - { - push_obstacks (&inline_text_obstack, &inline_text_obstack); - defarg_fns = tree_cons (current_class_type, decl, defarg_fns); - pop_obstacks (); - } -} - -/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ - -static void -feed_defarg (f, p) - tree f, p; -{ - tree d = TREE_PURPOSE (p); - feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d)); - if (TREE_CODE (f) == FUNCTION_DECL) - { - lineno = DECL_SOURCE_LINE (f); - input_filename = DECL_SOURCE_FILE (f); - } - yychar = DEFARG_MARKER; - yylval.ttype = p; -} - -/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ - -static void -finish_defarg () -{ - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. We also need to discard nextchar, - since that may have gotten set as well. */ - nextchar = -1; - } - yychar = YYEMPTY; - end_input (); -} - -/* Main function for deferred parsing of default arguments. Called from - the parser. */ - -void -do_pending_defargs () -{ - if (defarg_parm) - finish_defarg (); - - for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns)) - { - tree defarg_fn = TREE_VALUE (defarg_fns); - if (defarg_parm == NULL_TREE) - { - push_nested_class (TREE_PURPOSE (defarg_fns), 1); - pushlevel (0); - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - maybe_begin_member_template_processing (defarg_fn); - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { -#if 0 - tree p; - for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p)) - pushdecl (copy_node (p)); -#endif - defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); - } - else - defarg_parm = TYPE_ARG_TYPES (defarg_fn); - } - else - defarg_parm = TREE_CHAIN (defarg_parm); - - for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm)) - if (TREE_PURPOSE (defarg_parm) - && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG) - { - feed_defarg (defarg_fn, defarg_parm); - - /* Return to the parser, which will process this defarg - and call us again. */ - return; - } - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { - maybe_end_member_template_processing (); - check_default_args (defarg_fn); - } - - poplevel (0, 0, 0); - pop_nested_class (1); - } -} - -/* Build a default function named NAME for type TYPE. - KIND says what to build. - - When KIND == 0, build default destructor. - When KIND == 1, build virtual destructor. - When KIND == 2, build default constructor. - When KIND == 3, build default X(const X&) constructor. - When KIND == 4, build default X(X&) constructor. - When KIND == 5, build default operator = (const X&). - When KIND == 6, build default operator = (X&). */ - -tree -cons_up_default_function (type, full_name, kind) - tree type, full_name; - int kind; -{ - extern tree void_list_node; - tree declspecs = NULL_TREE; - tree fn, args = NULL_TREE; - tree argtype; - int retref = 0; - tree name = constructor_name (full_name); - - switch (kind) - { - /* Destructors. */ - case 1: - declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]); - /* Fall through... */ - case 0: - name = build_parse_node (BIT_NOT_EXPR, name); - args = void_list_node; - break; - - case 2: - /* Default constructor. */ - args = void_list_node; - break; - - case 3: - type = build_qualified_type (type, TYPE_QUAL_CONST); - /* Fall through... */ - case 4: - /* According to ARM $12.8, the default copy ctor will be declared, but - not defined, unless it's needed. */ - argtype = build_reference_type (type); - args = tree_cons (NULL_TREE, - build_tree_list (hash_tree_chain (argtype, NULL_TREE), - get_identifier ("_ctor_arg")), - void_list_node); - break; - - case 5: - case 6: - retref = 1; - declspecs = build_decl_list (NULL_TREE, type); - - if (kind == 5) - type = build_qualified_type (type, TYPE_QUAL_CONST); - - name = ansi_opname [(int) MODIFY_EXPR]; - - argtype = build_reference_type (type); - args = tree_cons (NULL_TREE, - build_tree_list (hash_tree_chain (argtype, NULL_TREE), - get_identifier ("_ctor_arg")), - void_list_node); - break; - - default: - my_friendly_abort (59); - } - - declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE], - declspecs); - - TREE_PARMLIST (args) = 1; - - { - tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE); - if (retref) - declarator = build_parse_node (ADDR_EXPR, declarator); - - fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE); - } - - if (fn == void_type_node) - return fn; - - if (kind > 2) - SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn))); - -#if 0 - if (processing_template_defn) - { - SET_DECL_IMPLICIT_INSTANTIATION (fn); - repo_template_used (fn); - } -#endif - -#if 0 - if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - DECL_INTERFACE_KNOWN (fn) = 1; - DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type) - && flag_implement_inlines); - } - else -#endif - DECL_NOT_REALLY_EXTERN (fn) = 1; - - mark_inline_for_output (fn); - -#ifdef DEBUG_DEFAULT_FUNCTIONS - { char *fn_type = NULL; - tree t = name; - switch (kind) - { - case 0: fn_type = "default destructor"; break; - case 1: fn_type = "virtual destructor"; break; - case 2: fn_type = "default constructor"; break; - case 3: fn_type = "default X(const X&)"; break; - case 4: fn_type = "default X(X&)"; break; - } - if (fn_type) - { - if (TREE_CODE (name) == BIT_NOT_EXPR) - t = TREE_OPERAND (name, 0); - fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type, - IDENTIFIER_POINTER (t), func_buf); - } - } -#endif /* DEBUG_DEFAULT_FUNCTIONS */ - - /* Show that this function was generated by the compiler. */ - SET_DECL_ARTIFICIAL (fn); - - return fn; -} - -/* Heuristic to tell whether the user is missing a semicolon - after a struct or enum declaration. Emit an error message - if we know the user has blown it. */ - -void -check_for_missing_semicolon (type) - tree type; -{ - if (yychar < 0) - yychar = yylex (); - - if ((yychar > 255 - && yychar != SCSPEC - && yychar != IDENTIFIER - && yychar != TYPENAME - && yychar != CV_QUALIFIER - && yychar != SELFNAME) - || end_of_file) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - error ("semicolon missing after %s declaration", - TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); - else - cp_error ("semicolon missing after declaration of `%T'", type); - shadow_tag (build_tree_list (0, type)); - } - /* Could probably also hack cases where class { ... } f (); appears. */ - clear_anon_tags (); -} - -void -note_got_semicolon (type) - tree type; -{ - if (TREE_CODE_CLASS (TREE_CODE (type)) != 't') - my_friendly_abort (60); - if (CLASS_TYPE_P (type)) - CLASSTYPE_GOT_SEMICOLON (type) = 1; -} - -void -note_list_got_semicolon (declspecs) - tree declspecs; -{ - tree link; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - tree type = TREE_VALUE (link); - if (TREE_CODE_CLASS (TREE_CODE (type)) == 't') - note_got_semicolon (type); - } - clear_anon_tags (); -} - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - for (;;) - { - switch (c) - { - case '\n': - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\r': - case '\v': - case '\b': - do - c = getch (); - while (c == ' ' || c == '\t'); - break; - - case '\\': - c = getch (); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = getch (); - break; - - default: - return (c); - } - } -} - - - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static char * -extend_token_buffer (p) - char *p; -{ - int offset = p - token_buffer; - - maxtoken = maxtoken * 2 + 10; - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); - - return token_buffer + offset; -} - -static int -get_last_nonwhite_on_line () -{ - register int c; - - /* Is this the last nonwhite stuff on the line? */ - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - while (c == ' ' || c == '\t') - c = getch (); - return c; -} - -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - int c; - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - return c; -} - -static void -pragma_ungetc (arg) - int arg; -{ - yyungetc (arg, 0); -} -#endif /* HANDLE_PRAGMA */ - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. */ - -int linemode; - -static int handle_cp_pragma PROTO((char *)); - -static int -check_newline () -{ - register int c; - register int token; - int saw_line = 0; - - /* Read first nonwhite char on the line. Do this before incrementing the - line number, in case we're at the end of saved text. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - lineno++; - - if (c != '#') - { - /* If not #, return it so caller will use it. */ - return c; - } - - /* Don't read beyond this line. */ - linemode = 1; - - /* Read first nonwhite char after the `#'. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma'. */ - - if (ISALPHA (c)) - { - if (c == 'p') - { - if (getch () == 'r' - && getch () == 'a' - && getch () == 'g' - && getch () == 'm' - && getch () == 'a') - { - token = real_yylex (); - if (token == IDENTIFIER - && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) - { - /* If this is 1, we handled it; if it's -1, it was one we - wanted but had something wrong with it. Only if it's - 0 was it not handled. */ - if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; - } - else if (token == END_OF_LINE) - goto skipline; - -#ifdef HANDLE_PRAGMA - /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS - (if both are defined), in order to give the back - end a chance to override the interpretation of - SYSV style pragmas. */ - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, - IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; -#endif /* HANDLE_PRAGMA */ - -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (token)) - goto skipline; -#endif /* HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); - } - - goto skipline; - } - else if (c == 'd') - { - if (getch () == 'e' - && getch () == 'f' - && getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t')) - { - debug_define (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - } - else if (c == 'u') - { - if (getch () == 'n' - && getch () == 'd' - && getch () == 'e' - && getch () == 'f' - && ((c = getch ()) == ' ' || c == '\t')) - { - debug_undef (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - } - else if (c == 'l') - { - if (getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t')) - { - saw_line = 1; - goto linenum; - } - } - else if (c == 'i') - { - if (getch () == 'd' - && getch () == 'e' - && getch () == 'n' - && getch () == 't' - && ((c = getch ()) == ' ' || c == '\t')) - { - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - token = real_yylex (); - if (token == END_OF_LINE) - goto skipline; - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (! flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - else if (c == 'n') - { - if (getch () == 'e' - && getch () == 'w' - && getch () == 'w' - && getch () == 'o' - && getch () == 'r' - && getch () == 'l' - && getch () == 'd' - && ((c = getch ()) == ' ' || c == '\t')) - { - /* Used to test incremental compilation. */ - sorry ("#pragma newworld"); - goto skipline; - } - } - error ("undefined or invalid # directive"); - goto skipline; - } - -linenum: - /* Here we have either `#line' or `# <nonletter>'. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = getch (); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == EOF) - goto skipline; - - /* Something follows the #; read a token. */ - - put_back (c); - token = real_yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - int old_lineno = lineno; - enum { act_none, act_push, act_pop } action = act_none; - int entering_system_header = 0; - int entering_c_header = 0; - - /* subtract one, because it is the following line that - gets the specified number */ - - int l = TREE_INT_CST_LOW (yylval.ttype) - 1; - c = get_last_nonwhite_on_line (); - if (c == EOF) - { - /* No more: store the line number and check following line. */ - lineno = l; - goto skipline; - } - put_back (c); - - /* More follows: it must be a string constant (filename). */ - - if (saw_line) - { - /* Don't treat \ as special if we are processing #line 1 "...". - If you want it to be treated specially, use # 1 "...". */ - ignore_escape_flag = 1; - } - - /* Read the string constant. */ - token = real_yylex (); - - ignore_escape_flag = 0; - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back - at 0. */ - if (flag_detailed_statistics) - { - int this_time = my_get_run_time (); - tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); - header_time += this_time - body_time; - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - this_filename_time = time_identifier; - body_time = this_time; - } - - input_filename - = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); - strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); - lineno = l; - GNU_xref_file (input_filename); - - if (main_input_filename == 0) - { - struct impl_files *ifiles = impl_file_chain; - - if (ifiles) - { - while (ifiles->next) - ifiles = ifiles->next; - ifiles->filename = file_name_nondirectory (input_filename); - } - - main_input_filename = input_filename; - if (write_virtuals == 3) - walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); - } - - extract_interface_info (); - - c = get_last_nonwhite_on_line (); - if (c == EOF) - { - /* Update the name in the top element of input_file_stack. */ - if (input_file_stack) - input_file_stack->name = input_filename; - } - else - { - put_back (c); - - token = real_yylex (); - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - if (TREE_INT_CST_LOW (yylval.ttype) == 1) - action = act_push; - else if (TREE_INT_CST_LOW (yylval.ttype) == 2) - action = act_pop; - - if (action) - { - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - } - - /* `3' after file name means this is a system header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 3) - { - entering_system_header = 1; - - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - - /* `4' after file name means this is a C header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 4) - { - entering_c_header = 1; - - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - - /* Do the actions implied by the preceding numbers. */ - - if (action == act_push) - { - /* Pushing to a new file. */ - struct file_stack *p; - - p = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; - debug_start_source_file (input_filename); - in_system_header = entering_system_header; - if (c_header_level) - ++c_header_level; - else if (entering_c_header) - { - c_header_level = 1; - ++pending_lang_change; - } - } - else if (action == act_pop) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - struct file_stack *p; - - if (c_header_level && --c_header_level == 0) - { - if (entering_c_header) - warning ("badly nested C headers from preprocessor"); - --pending_lang_change; - } - in_system_header = entering_system_header; - - p = input_file_stack; - input_file_stack = p->next; - free (p); - input_file_stack_tick++; - debug_end_source_file (input_file_stack->line); - } - else - error ("#-lines for entering and leaving files don't match"); - } - else - in_system_header = entering_system_header; - } - - /* If NEXTCHAR is not end of line, we don't care what it is. */ - if (nextchar == EOF) - c = EOF; - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - linemode = 0; - end_of_file = 0; - nextchar = -1; - while ((c = getch ()) != EOF && c != '\n'); - return c; -} - -void -do_pending_lang_change () -{ - for (; pending_lang_change > 0; --pending_lang_change) - push_lang_context (lang_name_c); - for (; pending_lang_change < 0; ++pending_lang_change) - pop_lang_context (); -} - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getch (); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - switch (c) - { - case 'x': - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getch (); - if (! ISXDIGIT (c)) - { - put_back (c); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && (((unsigned)1 << - (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getch (); - } - put_back (c); - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - return TARGET_BELL; - - case 'v': - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; - } - if (ISGRAPH (c)) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -int looking_for_typename; - -#ifdef __GNUC__ -__inline -#endif -int -identifier_type (decl) - tree decl; -{ - tree t; - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL) - return PTYPENAME; - else if (looking_for_template) - return PFUNCNAME; - } - if (looking_for_template && really_overloaded_fn (decl)) - { - /* See through a baselink. */ - if (TREE_CODE (decl) == TREE_LIST) - decl = TREE_VALUE (decl); - - for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) - if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) - return PFUNCNAME; - } - if (TREE_CODE (decl) == NAMESPACE_DECL) - return NSNAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) - return SELFNAME; - - /* A constructor declarator for a template type will get here as an - implicit typename, a TYPENAME_TYPE with a type. */ - t = got_scope; - if (t && TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - decl = TREE_TYPE (decl); - if (TREE_CODE (decl) == TYPENAME_TYPE) - decl = TREE_TYPE (decl); - if (t && t == decl) - return SELFNAME; - - return TYPENAME; -} - -void -see_typename () -{ - /* Only types expected, not even namespaces. */ - looking_for_typename = 2; - if (yychar < 0) - if ((yychar = yylex ()) < 0) yychar = 0; - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -2); - if (lastiddecl == 0) - { - if (flag_labels_ok) - lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); - } - else - yychar = identifier_type (lastiddecl); - } -} - -/* Return true if d is in a global scope. */ - -static int -is_global (d) - tree d; -{ - while (1) - switch (TREE_CODE (d)) - { - case ERROR_MARK: - return 1; - - case OVERLOAD: d = OVL_FUNCTION (d); continue; - case TREE_LIST: d = TREE_VALUE (d); continue; - default: - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629); - d = CP_DECL_CONTEXT (d); - return TREE_CODE (d) == NAMESPACE_DECL; - } -} - -tree -do_identifier (token, parsing, args) - register tree token; - int parsing; - tree args; -{ - register tree id; - int lexing = (parsing == 1); - int in_call = (parsing == 2); - - if (! lexing || IDENTIFIER_OPNAME_P (token)) - id = lookup_name (token, 0); - else - id = lastiddecl; - - /* Scope class declarations before global - declarations. */ - if ((!id || is_global (id)) - && current_class_type != 0 - && TYPE_SIZE (current_class_type) == 0) - { - /* Could be from one of the base classes. */ - tree field = lookup_field (current_class_type, token, 1, 0); - if (field == 0) - ; - else if (field == error_mark_node) - /* We have already generated the error message. - But we still want to return this value. */ - id = lookup_field (current_class_type, token, 0, 0); - else if (TREE_CODE (field) == VAR_DECL - || TREE_CODE (field) == CONST_DECL - || TREE_CODE (field) == TEMPLATE_DECL) - id = field; - else if (TREE_CODE (field) != FIELD_DECL) - my_friendly_abort (61); - else - { - cp_error ("invalid use of member `%D'", field); - id = error_mark_node; - return id; - } - } - - /* Do Koenig lookup if appropriate (inside templates we build lookup - expressions instead). */ - if (args && !current_template_parms && (!id || is_global (id))) - /* If we have arguments and we only found global names, do Koenig - lookup. */ - id = lookup_arg_dependent (token, id, args); - - /* Remember that this name has been used in the class definition, as per - [class.scope0] */ - if (id && current_class_type && parsing - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE (token) - /* Avoid breaking if we get called for a default argument that - refers to an overloaded method. Eventually this will not be - necessary, since default arguments shouldn't be parsed until - after the class is complete. (jason 3/12/97) */ - && TREE_CODE (id) != OVERLOAD) - pushdecl_class_level (id); - - if (!id || id == error_mark_node) - { - if (id == error_mark_node && current_class_type != NULL_TREE) - { - id = lookup_nested_field (token, 1); - /* In lookup_nested_field(), we marked this so we can gracefully - leave this whole mess. */ - if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) - return id; - } - - if (current_template_parms) - return build_min_nt (LOOKUP_EXPR, token); - else if (IDENTIFIER_OPNAME_P (token)) - { - if (token != ansi_opname[ERROR_MARK]) - cp_error ("`%D' not defined", token); - id = error_mark_node; - } - else if (in_call && ! flag_strict_prototype) - { - id = implicitly_declare (token); - } - else if (current_function_decl == 0) - { - cp_error ("`%D' was not declared in this scope", token); - id = error_mark_node; - } - else - { - if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) - { - static int undeclared_variable_notice; - - cp_error ("`%D' undeclared (first use this function)", token); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - id = error_mark_node; - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); - SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); - } - } - - if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) - { - tree shadowed = DECL_SHADOWED_FOR_VAR (id); - while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL - && DECL_DEAD_FOR_LOCAL (shadowed)) - shadowed = DECL_SHADOWED_FOR_VAR (shadowed); - if (!shadowed) - shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id)); - if (shadowed) - { - if (!DECL_ERROR_REPORTED (id)) - { - warning ("name lookup of `%s' changed", - IDENTIFIER_POINTER (token)); - cp_warning_at (" matches this `%D' under current ANSI rules", - shadowed); - cp_warning_at (" matches this `%D' under old rules", id); - DECL_ERROR_REPORTED (id) = 1; - } - id = shadowed; - } - else if (!DECL_ERROR_REPORTED (id)) - { - static char msg[] - = "name lookup of `%s' changed for new ANSI `for' scoping"; - DECL_ERROR_REPORTED (id) = 1; - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id))) - { - error (msg, IDENTIFIER_POINTER (token)); - cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id); - id = error_mark_node; - } - else - { - pedwarn (msg, IDENTIFIER_POINTER (token)); - cp_pedwarn_at (" using obsolete binding at `%D'", id); - } - } - } - /* TREE_USED is set in `hack_identifier'. */ - if (TREE_CODE (id) == CONST_DECL) - { - if (IDENTIFIER_CLASS_VALUE (token) == id) - { - /* Check access. */ - tree access = compute_access (TYPE_BINFO (current_class_type), id); - if (access == access_private_node) - cp_error ("enum `%D' is private", id); - /* protected is OK, since it's an enum of `this'. */ - } - if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) - id = DECL_INITIAL (id); - } - else - id = hack_identifier (id, token); - - /* We must look up dependent names when the template is - instantiated, not while parsing it. For now, we don't - distinguish between dependent and independent names. So, for - example, we look up all overloaded functions at - instantiation-time, even though in some cases we should just use - the DECL we have here. We also use LOOKUP_EXPRs to find things - like local variables, rather than creating TEMPLATE_DECLs for the - local variables and then finding matching instantiations. */ - if (current_template_parms - && (is_overloaded_fn (id) - /* If it's not going to be around at instantiation time, we - look it up then. This is a hack, and should go when we - really get dependent/independent name lookup right. */ - || !TREE_PERMANENT (id) - /* Some local VAR_DECLs (such as those for local variables - in member functions of local classes) are built on the - permanent obstack. */ - || (TREE_CODE (id) == VAR_DECL - && CP_DECL_CONTEXT (id) - && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL) - || TREE_CODE (id) == PARM_DECL - || TREE_CODE (id) == RESULT_DECL - || TREE_CODE (id) == USING_DECL)) - id = build_min_nt (LOOKUP_EXPR, token); - - return id; -} - -tree -do_scoped_id (token, parsing) - tree token; - int parsing; -{ - tree id; - /* during parsing, this is ::name. Otherwise, it is black magic. */ - if (parsing) - { - struct tree_binding _b; - id = binding_init (&_b); - if (!qualified_lookup_using_namespace (token, global_namespace, id, 0)) - id = NULL_TREE; - else - id = BINDING_VALUE (id); - } - else - id = IDENTIFIER_GLOBAL_VALUE (token); - if (parsing && yychar == YYEMPTY) - yychar = yylex (); - if (! id) - { - if (processing_template_decl) - { - id = build_min_nt (LOOKUP_EXPR, token); - LOOKUP_EXPR_GLOBAL (id) = 1; - return id; - } - if (parsing && (yychar == '(' || yychar == LEFT_RIGHT) - && ! flag_strict_prototype) - id = implicitly_declare (token); - else - { - if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) - cp_error ("`::%D' undeclared (first use here)", token); - id = error_mark_node; - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); - } - } - else - { - if (TREE_CODE (id) == ADDR_EXPR) - mark_used (TREE_OPERAND (id, 0)); - else if (TREE_CODE (id) != OVERLOAD) - mark_used (id); - } - if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl) - { - /* XXX CHS - should we set TREE_USED of the constant? */ - id = DECL_INITIAL (id); - /* This is to prevent an enum whose value is 0 - from being considered a null pointer constant. */ - id = build1 (NOP_EXPR, TREE_TYPE (id), id); - TREE_CONSTANT (id) = 1; - } - - if (processing_template_decl) - { - if (is_overloaded_fn (id)) - { - id = build_min_nt (LOOKUP_EXPR, token); - LOOKUP_EXPR_GLOBAL (id) = 1; - return id; - } - /* else just use the decl */ - } - return convert_from_reference (id); -} - -tree -identifier_typedecl_value (node) - tree node; -{ - tree t, type; - type = IDENTIFIER_TYPE_VALUE (node); - if (type == NULL_TREE) - return NULL_TREE; - - if (IDENTIFIER_BINDING (node)) - { - t = IDENTIFIER_VALUE (node); - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) - return t; - } - if (IDENTIFIER_NAMESPACE_VALUE (node)) - { - t = IDENTIFIER_NAMESPACE_VALUE (node); - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) - return t; - } - - /* Will this one ever happen? */ - if (TYPE_MAIN_DECL (type)) - return TYPE_MAIN_DECL (type); - - /* We used to do an internal error of 62 here, but instead we will - handle the return of a null appropriately in the callers. */ - return NULL_TREE; -} - -/* CYGNUS LOCAL Embedded C++ */ - -static inline void -embedded_pedwarn (s) - char *s; -{ - pedwarn ("Embedded C++ prohibits use of %s", s); -} -/* END CYGNUS LOCAL Embedded C++ */ - -int -real_yylex () -{ - register int c; - register int value; - int wide_flag = 0; - int dollar_seen = 0; - int i; - - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getch (); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - token_buffer[0] = '\0'; - end_of_file = 1; - if (input_redirected ()) - value = END_OF_SAVED_INPUT; - else if (linemode) - value = END_OF_LINE; - else - value = ENDFILE; - break; - - case '$': - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - dollar_seen = 1; - goto letter; - - case 'L': - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = getch (); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - put_back (c); - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': 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': - case '_': - letter: - { - register char *p; - - p = token_buffer; - if (input == 0) - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. - We may have to read the value in `putback_char', so call - `getch' once. */ - *p++ = c; - c = getch (); - - /* Make this run fast. We know that we are reading straight - from FINPUT in this case (since identifiers cannot straddle - input sources. */ - while (ISALNUM (c) || (c == '_') || c == '$') - { - if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getch (); - } - - if (linemode && c == '\n') - { - put_back (c); - c = EOF; - } - } - else - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. */ - *p++ = c; - c = getch (); - - while (ISALNUM (c) || (c == '_') || c == '$') - { - if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getch (); - } - } - - *p = 0; - nextchar = c; - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if ((ptr = is_reserved_word (token_buffer, p - token_buffer))) - { - if (ptr->rid) - { - tree old_ttype = ridpointers[(int) ptr->rid]; - - /* If this provides a type for us, then revert lexical - state to standard state. */ - if (TREE_CODE (old_ttype) == IDENTIFIER_NODE - && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0 - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL) - looking_for_typename = 0; - else if (ptr->token == AGGR || ptr->token == ENUM) - looking_for_typename = 2; - - /* Check if this is a language-type declaration. - Just glimpse the next non-white character. */ - nextchar = skip_white_space (nextchar); - if (nextchar == '"') - { - /* We are looking at a string. Complain - if the token before the string is no `extern'. - - Could cheat some memory by placing this string - on the temporary_, instead of the saveable_ - obstack. */ - - if (ptr->rid != RID_EXTERN) - error ("invalid modifier `%s' for language string", - ptr->name); - real_yylex (); - value = EXTERN_LANG_STRING; - yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype)); - break; - } - if (ptr->token == VISSPEC) - { - switch (ptr->rid) - { - case RID_PUBLIC: - yylval.ttype = access_public_node; - break; - case RID_PRIVATE: - yylval.ttype = access_private_node; - break; - case RID_PROTECTED: - yylval.ttype = access_protected_node; - break; - default: - my_friendly_abort (63); - } - } - else - yylval.ttype = old_ttype; - } - else if (ptr->token == EQCOMPARE) - { - yylval.code = NE_EXPR; - token_buffer[0] = '!'; - token_buffer[1] = '='; - token_buffer[2] = 0; - } - else if (ptr->token == ASSIGN) - { - if (strcmp ("and_eq", token_buffer) == 0) - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - } - else if (strcmp ("or_eq", token_buffer) == 0) - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - } - else if (strcmp ("xor_eq", token_buffer) == 0) - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - } - token_buffer[1] = '='; - token_buffer[2] = 0; - } - else if (ptr->token == '&') - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - token_buffer[1] = 0; - } - else if (ptr->token == '|') - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - token_buffer[1] = 0; - } - else if (ptr->token == '^') - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - token_buffer[1] = 0; - } - - value = (int) ptr->token; - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER || value == TYPESPEC) - GNU_xref_ref (current_function_decl, token_buffer); - - if (value == IDENTIFIER) - { - register tree tmp = get_identifier (token_buffer); - -#if !defined(VMS) && defined(JOINER) - /* Make sure that user does not collide with our internal - naming scheme. */ - if (JOINER == '$' - && dollar_seen - && (THIS_NAME_P (tmp) - || VPTR_NAME_P (tmp) - || DESTRUCTOR_NAME_P (tmp) - || VTABLE_NAME_P (tmp) - || TEMP_NAME_P (tmp) - || ANON_AGGRNAME_P (tmp) - || ANON_PARMNAME_P (tmp))) - warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", - token_buffer); -#endif - - yylval.ttype = tmp; - } - if (value == NEW && ! global_bindings_p ()) - { - value = NEW; - goto done; - } - } - -/* CYGNUS LOCAL Embedded C++ */ - if (flag_embedded_cxx) - { - if (value == USING || value == NAMESPACE) - { - if (! embedded_namespace_error) - { - embedded_namespace_error = 1; - embedded_pedwarn ("namespaces"); - } - else - pedwarn ("further uses of namespaces with Embedded C++ enabled"); - } - else if (value == TEMPLATE || value == TYPENAME) - { - if (! embedded_namespace_error) - { - embedded_namespace_error = 1; - embedded_pedwarn ("templates"); - } - else - pedwarn ("further uses of templates with Embedded C++ enabled"); - } - else if (value == CATCH || value == THROW || value == TRY) - { - if (! embedded_eh_error) - { - embedded_eh_error = 1; - embedded_pedwarn ("exception handling"); - } - else - pedwarn ("further uses of exception handling with Embedded C++ enabled"); - } - else if (value == DYNAMIC_CAST) - embedded_pedwarn ("dynamic_cast"); - else if (value == STATIC_CAST) - embedded_pedwarn ("static_cast"); - else if (value == REINTERPRET_CAST) - embedded_pedwarn ("reinterpret_cast"); - else if (value == CONST_CAST) - embedded_pedwarn ("const_cast"); - else if (value == TYPEID) - embedded_pedwarn ("typeid"); - } -/* END CYGNUS LOCAL Embedded C++ */ - - break; - - case '.': - { - register int c1 = getch (); - token_buffer[0] = c; - token_buffer[1] = c1; - if (c1 == '*') - { - value = DOT_STAR; - token_buffer[2] = 0; - goto done; - } - if (c1 == '.') - { - c1 = getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - if (ISDIGIT (c1)) - { - put_back (c1); - goto resume_numerical_scan; - } - nextchar = c1; - value = '.'; - token_buffer[1] = 0; - goto done; - } - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int c1 = getch (); - if (! ISALNUM (c1) && c1 != '.') - { - /* Terminate string. */ - token_buffer[0] = c; - token_buffer[1] = 0; - if (c == '0') - yylval.ttype = integer_zero_node; - else - yylval.ttype = integer_one_node; - nextchar = c1; - value = CONSTANT; - goto done; - } - put_back (c1); - } - /* fall through... */ - case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - resume_numerical_scan: - { - register char *p; - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - /* for multi-precision arithmetic, - we actually store only HOST_BITS_PER_CHAR bits in each part. - The number of parts is chosen so as to be sufficient to hold - the enough bits to fit into the two HOST_WIDE_INTs that contain - the integer value (this is always at least as many bits as are - in a target `long long' value, but may be wider). */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) - int parts[TOTAL_PARTS]; - int overflow = 0; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = getch ()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = getch ()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (ISALNUM (c) && (c != 'l') && (c != 'L') - && (c != 'u') && (c != 'U') - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) - { - if (c == '.') - { - if (base == 16) - error ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - base = 10; - *p++ = c = getch (); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. - Otherwise, unread the following non-digit - and use the '.' as a structural token. */ - if (p == token_buffer + 2 && !ISDIGIT (c)) - { - if (c == '.') - { - c = getch (); - if (c == '.') - { - *p++ = '.'; - *p = '\0'; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - nextchar = c; - token_buffer[1] = '\0'; - value = '.'; - goto done; - } - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (ISDIGIT (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_POINT; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the extra highest-order part ever gets anything in it, - the number is certainly too big. */ - if (parts[TOTAL_PARTS - 1] != 0) - overflow = 1; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = getch ()); - } - } - - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the string */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type = double_type_node; - int exceeds_double = 0; - int imag = 0; - REAL_VALUE_TYPE value; - jmp_buf handler; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((c == 'e') || (c == 'E')) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = getch (); - } - if (! ISDIGIT (c)) - error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - } - - *p = 0; - errno = 0; - - /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) - { - error ("floating constant out of range"); - value = dconst0; - } - else - { - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (p - token_buffer + 1); - bcopy (token_buffer, copy, p - token_buffer + 1); - - set_float_handler (handler); - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids imaginary numeric constants"); - imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - *p = 0; - c = getch (); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - type = float_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, become some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - type = long_double_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } - - set_float_handler (NULL_PTR); - } -#ifdef ERANGE - if (errno == ERANGE && pedantic) - { - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1)) - { - pedwarn ("floating point number exceeds range of `%s'", - IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))); - exceeds_double = 1; - } - } -#endif - - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (NULL_TREE, - cp_convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - } - else - { - tree type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int bytes, warn; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ANSI C++ forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids imaginary numeric constants"); - spec_imag = 1; - } - else - break; - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - - /* If the constant is not long long and it won't fit in an - unsigned long, or if the constant is long long and won't fit - in an unsigned long long, then warn that the constant is out - of range. */ - - /* ??? This assumes that long long and long integer types are - a multiple of 8 bits. This better than the original code - though which assumed that long was exactly 32 bits and long - long was exactly 64 bits. */ - - if (spec_long_long) - bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; - else - bytes = TYPE_PRECISION (long_integer_type_node) / 8; - - warn = overflow; - for (i = bytes; i < TOTAL_PARTS; i++) - if (parts[i]) - warn = 1; - if (warn) - pedwarn ("integer constant out of range"); - - /* This is simplified by the fact that our constant - is always positive. */ - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* Calculate the ANSI type. */ - if (!spec_long && !spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - type = integer_type_node; - else if (!spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - /* Nondecimal constants try unsigned even in traditional C. */ - type = unsigned_type_node; - else if (!spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - type = long_integer_type_node; - else if (! spec_long_long) - type = long_unsigned_type_node; - else if (! spec_unsigned - /* Verify value does not overflow into sign bit. */ - && TREE_INT_CST_HIGH (yylval.ttype) >= 0 - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - type = long_long_integer_type_node; - else - type = long_long_unsigned_type_node; - - if (!int_fits_type_p (yylval.ttype, type) && !warn) - pedwarn ("integer constant out of range"); - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal integer constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (NULL_TREE, integer_zero_node, - cp_convert (integer_type_node, - yylval.ttype)); - else - error ("complex integer constant is too wide for `__complex int'"); - } - else - TREE_TYPE (yylval.ttype) = type; - } - - put_back (c); - *p = 0; - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - int chars_seen = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - max_chars = TYPE_PRECISION (integer_type_node) / width; - if (wide_flag) - width = WCHAR_TYPE_SIZE; - - while (1) - { - tryagain: - c = getch (); - - if (c == '\'' || c == EOF) - break; - - ++chars_seen; - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (ISPRINT (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in character constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 1; i <= longest_char; ++i) - { - if (i > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[i] = c; - char_len = local_mbtowc (& wc, - token_buffer + 1, - i); - if (char_len != -1) - break; - c = getch (); - } - if (char_len > 1) - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - put_back (c); - 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 << width) - 1)); - else - result = token_buffer[i]; - } - num_chars += char_len; - goto tryagain; - } - c = wc; - } - else - { - if (char_len == -1) - warning ("Ignoring invalid multibyte character"); - if (wide_flag) - c = wc; -#ifdef MAP_CHARACTER - else - c = MAP_CHARACTER (c); -#endif - } -#else /* ! MULTIBYTE_CHARS */ -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (c); -#endif -#endif /* ! MULTIBYTE_CHARS */ - } - - if (wide_flag) - { - if (chars_seen == 1) /* only keep the first one */ - result = c; - goto tryagain; - } - - /* Merge character into result; ignore excess chars. */ - num_chars++; - if (num_chars < max_chars + 1) - { - 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 && warn_multichar) - 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.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - if (chars_seen <= 1) - TREE_TYPE (yylval.ttype) = char_type_node; - else - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - register char *p; - unsigned width = wide_flag ? WCHAR_TYPE_SIZE - : TYPE_PRECISION (char_type_node); -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - c = getch (); - p = token_buffer + 1; - - while (c != '"' && c >= 0) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - warning ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 0; i < longest_char; ++i) - { - if (p + i >= token_buffer + maxtoken) - p = extend_token_buffer (p); - p[i] = c; - - char_len = local_mbtowc (& wc, p, i + 1); - if (char_len != -1) - break; - c = getch (); - } - if (char_len == -1) - warning ("Ignoring invalid multibyte character"); - else - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len <= i) - put_back (c); - if (! wide_flag) - { - p += (i + 1); - c = getch (); - continue; - } - c = wc; - } -#endif /* MULTIBYTE_CHARS */ - } - - /* Add this single character into the buffer either as a wchar_t - or as a single byte. */ - if (wide_flag) - { - unsigned width = TYPE_PRECISION (char_type_node); - unsigned bytemask = (1 << width) - 1; - int byte; - - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - - for (byte = 0; byte < WCHAR_BYTES; ++byte) - { - int value; - if (byte >= (int) sizeof(c)) - value = 0; - else - value = (c >> (byte * width)) & bytemask; - if (BYTES_BIG_ENDIAN) - p[WCHAR_BYTES - byte - 1] = value; - else - p[byte] = value; - } - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - } - - skipnewline: - c = getch (); - if (c == EOF) { - error ("Unterminated string"); - break; - } - } - - /* Terminate the string value, either with a single byte zero - or with a wide zero. */ - if (wide_flag) - { - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - bzero (p, WCHAR_BYTES); - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = 0; - } - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); - if (processing_template_decl) - pop_obstacks (); - - if (wide_flag) - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - else - TREE_TYPE (yylval.ttype) = char_array_type_node; - - value = STRING; break; - } - - case '+': - case '-': - case '&': - case '|': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = getch (); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else if ((c == '-') && (c1 == '>')) - { - nextchar = getch (); - if (nextchar == '*') - { - nextchar = -1; - value = POINTSAT_STAR; - } - else - value = POINTSAT; - goto done; - } - else if (c1 == '?' && (c == '<' || c == '>')) - { - token_buffer[3] = 0; - - c1 = getch (); - yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); - if (c1 == '=') - { - /* <?= or >?= expression. */ - token_buffer[2] = c1; - value = ASSIGN; - } - else - { - value = MIN_MAX; - nextchar = c1; - } - if (pedantic) - pedwarn ("use of `operator %s' is not standard C++", - token_buffer); - goto done; - } - /* digraphs */ - else if (c == '<' && c1 == '%') - { value = '{'; goto done; } - else if (c == '<' && c1 == ':') - { value = '['; goto done; } - else if (c == '%' && c1 == '>') - { value = '}'; goto done; } - else if (c == '%' && c1 == ':') - { value = '#'; goto done; } - - nextchar = c1; - token_buffer[1] = 0; - - value = c; - goto done; - } - - case ':': - c = getch (); - if (c == ':') - { - token_buffer[1] = ':'; - token_buffer[2] = '\0'; - value = SCOPE; - yylval.itype = 1; - } - else if (c == '>') - { - value = ']'; - goto done; - } - else - { - nextchar = c; - value = ':'; - } - break; - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - case '(': - /* try, weakly, to handle casts to pointers to functions. */ - nextchar = skip_white_space (getch ()); - if (nextchar == '*') - { - int next_c = skip_white_space (getch ()); - if (next_c == ')') - { - nextchar = -1; - yylval.ttype = build1 (INDIRECT_REF, 0, 0); - value = PAREN_STAR_PAREN; - } - else - { - put_back (next_c); - value = c; - } - } - else if (nextchar == ')') - { - nextchar = -1; - yylval.ttype = NULL_TREE; - value = LEFT_RIGHT; - } - else value = c; - break; - - default: - value = c; - } - -done: -/* yylloc.last_line = lineno; */ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - token_count[value] += 1; -#endif -#endif - - return value; -} - -int -is_rid (t) - tree t; -{ - return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); -} - -#ifdef GATHER_STATISTICS -/* The original for tree_node_kind is in the toplevel tree.c; changes there - need to be brought into here, unless this were actually put into a header - instead. */ -/* Statistics-gathering stuff. */ -typedef enum -{ - d_kind, - t_kind, - b_kind, - s_kind, - r_kind, - e_kind, - c_kind, - id_kind, - op_id_kind, - perm_list_kind, - temp_list_kind, - vec_kind, - x_kind, - lang_decl, - lang_type, - all_kinds -} tree_node_kind; - -extern int tree_node_counts[]; -extern int tree_node_sizes[]; -#endif - -/* Place to save freed lang_decls which were allocated on the - permanent_obstack. @@ Not currently used. */ -tree free_lang_decl_chain; - -tree -build_lang_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - register tree t = build_decl (code, name, type); - retrofit_lang_decl (t); - return t; -} - -/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl - and pushdecl (for functions generated by the backend). */ - -void -retrofit_lang_decl (t) - tree t; -{ - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl) / sizeof (int); - register int *pi; - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - /* Could be that saveable is permanent and current is not. */ - obstack = &permanent_obstack; - - if (free_lang_decl_chain && obstack == &permanent_obstack) - { - pi = (int *)free_lang_decl_chain; - free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain); - } - else - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); - - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - LANG_DECL_PERMANENT ((struct lang_decl *) pi) - = obstack == &permanent_obstack; - my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi) - == TREE_PERMANENT (t), 234); - DECL_MAIN_VARIANT (t) = t; - if (current_lang_name == lang_name_cplusplus) - DECL_LANGUAGE (t) = lang_cplusplus; - else if (current_lang_name == lang_name_c) - DECL_LANGUAGE (t) = lang_c; - else if (current_lang_name == lang_name_java) - DECL_LANGUAGE (t) = lang_java; - else my_friendly_abort (64); - -#if 0 /* not yet, should get fixed properly later */ - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } - -#endif -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_decl] += 1; - tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl); -#endif -} - -tree -build_lang_field_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = build_decl (code, name, type); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl_flags) / sizeof (int); - register int *pi; -#if 0 /* not yet, should get fixed properly later */ - - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } -#endif - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 235); - - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags)); - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - return t; -} - -void -copy_lang_decl (node) - tree node; -{ - int size; - int *pi; - - if (! DECL_LANG_SPECIFIC (node)) - return; - - if (TREE_CODE (node) == FIELD_DECL) - size = sizeof (struct lang_decl_flags); - else - size = sizeof (struct lang_decl); - pi = (int *)obstack_alloc (&permanent_obstack, size); - bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size); - DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi; -} - -tree -make_lang_type (code) - enum tree_code code; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = make_node (code); - - /* Set up some flags that give proper default behavior. */ - if (IS_AGGR_TYPE_CODE (code)) - { - struct obstack *obstack = current_obstack; - struct lang_type *pi; - - SET_IS_AGGR_TYPE (t, 1); - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 236); - - pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type)); - bzero ((char *) pi, (int) sizeof (struct lang_type)); - - TYPE_LANG_SPECIFIC (t) = pi; - CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t); - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE); - CLASSTYPE_BINFO_AS_LIST (t) - = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - /* Make sure this is laid out, for ease of use later. In the - presence of parse errors, the normal was of assuring this - might not ever get executed, so we lay it out *immediately*. */ - build_pointer_type (t); - -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); -#endif - } - else - /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, - TYPE_ALIAS_SET is initialized to -1 by default, so we must - clear it here. */ - TYPE_ALIAS_SET (t) = 0; - - return t; -} - -void -dump_time_statistics () -{ - register tree prev = 0, decl, next; - int this_time = my_get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double)header_time / (double)(this_time - body_time)); - fprintf (stderr, "\n******\n"); - - for (decl = filename_times; decl; decl = next) - { - next = IDENTIFIER_GLOBAL_VALUE (decl); - SET_IDENTIFIER_GLOBAL_VALUE (decl, prev); - prev = decl; - } - - for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) - print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl))); -} - -void -compiler_error (s, v, v2) - char *s; - HOST_WIDE_INT v, v2; /* @@also used as pointer */ -{ - char buf[1024]; - sprintf (buf, s, v, v2); - error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); -} - -void -yyerror (string) - char *string; -{ - extern int end_of_file; - char buf[200]; - - strcpy (buf, string); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - strcat (buf, input_redirected () - ? " at end of saved text" - : " at end of input"); - else if (token_buffer[0] == 0) - strcat (buf, " at null character"); - else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); - else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); - else if (!ISGRAPH ((unsigned char)token_buffer[0])) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); - else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); -} - -static int -handle_cp_pragma (pname) - char *pname; -{ - register int token; - - if (! strcmp (pname, "vtable")) - { - extern tree pending_vtables; - - /* More follows: it must be a string constant (class name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma vtable"); - return -1; - } - - if (write_virtuals != 2) - { - warning ("use `+e2' option to enable #pragma vtable"); - return -1; - } - pending_vtables - = perm_tree_cons (NULL_TREE, - get_identifier (TREE_STRING_POINTER (yylval.ttype)), - pending_vtables); - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "unit")) - { - /* More follows: it must be a string constant (unit name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma unit"); - return -1; - } - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "interface")) - { - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); - char *main_filename = input_filename; - - main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma interface'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma interface' ignored"); - - write_virtuals = 3; - - if (impl_file_chain == 0) - { - /* If this is zero at this point, then we are - auto-implementing. */ - if (main_input_filename == 0) - main_input_filename = input_filename; - -#ifdef AUTO_IMPLEMENT - filename = file_name_nondirectory (main_input_filename); - fi = get_time_identifier (filename); - fi = TIME_IDENTIFIER_FILEINFO (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = filename; - impl_file_chain->next = 0; -#endif - } - - interface_only = interface_strcmp (main_filename); -#ifdef MULTIPLE_SYMBOL_SPACES - if (! interface_only) - interface_unknown = 0; -#else /* MULTIPLE_SYMBOL_SPACES */ - interface_unknown = 0; -#endif /* MULTIPLE_SYMBOL_SPACES */ - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - - return 1; - } - else if (! strcmp (pname, "implementation")) - { - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); - char *main_filename = main_input_filename ? main_input_filename : input_filename; - - main_filename = file_name_nondirectory (main_filename); - token = real_yylex (); - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma implementation'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma implementation' ignored"); - - if (write_virtuals == 3) - { - struct impl_files *ifiles = impl_file_chain; - while (ifiles) - { - if (! strcmp (ifiles->filename, main_filename)) - break; - ifiles = ifiles->next; - } - if (ifiles == 0) - { - ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files)); - ifiles->filename = main_filename; - ifiles->next = impl_file_chain; - impl_file_chain = ifiles; - } - } - else if ((main_input_filename != 0 - && ! strcmp (main_input_filename, input_filename)) - || ! strcmp (input_filename, main_filename)) - { - write_virtuals = 3; - if (impl_file_chain == 0) - { - impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = main_filename; - impl_file_chain->next = 0; - } - } - else - error ("`#pragma implementation' can only appear at top-level"); - interface_only = 0; -#if 1 - /* We make this non-zero so that we infer decl linkage - in the impl file only for variables first declared - in the interface file. */ - interface_unknown = 1; -#else - /* We make this zero so that templates in the impl - file will be emitted properly. */ - interface_unknown = 0; -#endif - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - - return 1; - } - - return 0; -} - -/* Return the type-qualifier corresponding to the identifier given by - RID. */ - -int -cp_type_qual_from_rid (rid) - tree rid; -{ - if (rid == ridpointers[(int) RID_CONST]) - return TYPE_QUAL_CONST; - else if (rid == ridpointers[(int) RID_VOLATILE]) - return TYPE_QUAL_VOLATILE; - else if (rid == ridpointers[(int) RID_RESTRICT]) - return TYPE_QUAL_RESTRICT; - - my_friendly_abort (0); - return TYPE_UNQUALIFIED; -} - - -#ifdef HANDLE_GENERIC_PRAGMAS - -/* Handle a #pragma directive. TOKEN is the type of the word following - the #pragma directive on the line. Process the entire input line and - return non-zero iff the directive successfully parsed. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -static int -handle_generic_pragma (token) - register int token; -{ - for (;;) - { - switch (token) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - - case LEFT_RIGHT: - handle_pragma_token ("(", NULL_TREE); - handle_pragma_token (")", NULL_TREE); - break; - - case END_OF_LINE: - return handle_pragma_token (NULL_PTR, NULL_TREE); - - default: - handle_pragma_token (token_buffer, NULL); - } - - token = real_yylex (); - } -} -#endif /* HANDLE_GENERIC_PRAGMAS */ diff --git a/gcc/cp/lex.h b/gcc/cp/lex.h deleted file mode 100755 index 249eef9..0000000 --- a/gcc/cp/lex.h +++ /dev/null @@ -1,137 +0,0 @@ -/* Define constants and variables for communication with parse.y. - Copyright (C) 1987, 92-97, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@cygnus.com) - and by Brendan Kehoe (brendan@cygnus.com). - -This file is part of GNU CC. - -GNU CC is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY. No author or distributor -accepts responsibility to anyone for the consequences of using it -or for whether it serves any particular purpose or works at all, -unless he says so in writing. Refer to the GNU CC General Public -License for full details. - -Everyone is granted permission to copy, modify and redistribute -GNU CC, but only under the conditions described in the -GNU CC General Public License. A copy of this license is -supposed to have been given to you along with GNU CC so you -can know your rights and responsibilities. It should be in a -file named COPYING. Among other things, the copyright notice -and this notice must be preserved on all copies. */ - - - -enum rid -{ - RID_UNUSED, - RID_INT, - RID_BOOL, - RID_CHAR, - RID_WCHAR, - RID_FLOAT, - RID_DOUBLE, - RID_VOID, - - /* C++ extension */ - RID_CLASS, - RID_RECORD, - RID_UNION, - RID_ENUM, - RID_LONGLONG, - - /* This is where grokdeclarator starts its search when setting the specbits. - The first seven are in the order of most frequently used, as found - building libg++. */ - - RID_EXTERN, - RID_CONST, - RID_LONG, - RID_TYPEDEF, - RID_UNSIGNED, - RID_SHORT, - RID_INLINE, - - RID_STATIC, - - RID_REGISTER, - RID_VOLATILE, - RID_FRIEND, - RID_VIRTUAL, - RID_EXPLICIT, - RID_EXPORT, - RID_SIGNED, - RID_AUTO, - RID_MUTABLE, - RID_COMPLEX, - RID_RESTRICT, - - /* This is where grokdeclarator ends its search when setting the - specbits. */ - - RID_PUBLIC, - RID_PRIVATE, - RID_PROTECTED, - RID_EXCEPTION, - RID_TEMPLATE, - RID_SIGNATURE, - RID_NULL, - /* Before adding enough to get up to 64, the RIDBIT_* macros - will have to be changed a little. */ - RID_MAX -}; - -#define NORID RID_UNUSED - -#define RID_FIRST_MODIFIER RID_EXTERN -#define RID_LAST_MODIFIER RID_COMPLEX - -/* The type that can represent all values of RIDBIT. */ -/* We assume that we can stick in at least 32 bits into this. */ -typedef struct { unsigned long idata[2]; } - RID_BIT_TYPE; - -/* Be careful, all these modify N twice. */ -#define RIDBIT_SETP(N, V) (((unsigned long)1 << (int) ((N)%32)) \ - & (V).idata[(N)/32]) -#define RIDBIT_NOTSETP(NN, VV) (! RIDBIT_SETP (NN, VV)) -#define RIDBIT_SET(N, V) do { \ - (V).idata[(N)/32] \ - |= ((unsigned long)1 << (int) ((N)%32)); \ - } while (0) -#define RIDBIT_RESET(N, V) do { \ - (V).idata[(N)/32] \ - &= ~((unsigned long)1 << (int) ((N)%32)); \ - } while (0) -#define RIDBIT_RESET_ALL(V) do { \ - (V).idata[0] = 0; \ - (V).idata[1] = 0; \ - } while (0) -#define RIDBIT_ANY_SET(V) ((V).idata[0] || (V).idata[1]) - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -extern tree ridpointers[(int) RID_MAX]; - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -extern tree lastiddecl; - -extern char *token_buffer; /* Pointer to token buffer. */ - -/* Back-door communication channel to the lexer. */ -extern int looking_for_typename; -extern int looking_for_template; - -/* Tell the lexer where to look for names. */ -extern tree got_scope; -extern tree got_object; - -/* Pending language change. - Positive is push count, negative is pop count. */ -extern int pending_lang_change; - -extern int yylex PROTO((void)); diff --git a/gcc/cp/lex_990205.c b/gcc/cp/lex_990205.c deleted file mode 100755 index f5e8e67..0000000 --- a/gcc/cp/lex_990205.c +++ /dev/null @@ -1,5105 +0,0 @@ -/* Separate lexical analyzer for GNU C++. - Copyright (C) 1987, 89, 92-98, 1999 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file is the lexical analyzer for GNU C++. */ - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#include "config.h" -#include "system.h" -#include <setjmp.h> -#include "input.h" -#include "tree.h" -#include "lex.h" -#include "cp-tree.h" -#include "parse.h" -#include "flags.h" -#include "obstack.h" -#include "c-pragma.h" -#include "toplev.h" -#include "output.h" - -#ifdef MULTIBYTE_CHARS -#include "mbchar.h" -#include <locale.h> -#endif - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -#ifndef DIR_SEPARATOR -#define DIR_SEPARATOR '/' -#endif - -extern struct obstack permanent_obstack; -extern struct obstack *current_obstack, *saveable_obstack; - -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern void compiler_error PROTO((char *, HOST_WIDE_INT, - HOST_WIDE_INT)); - -static tree get_time_identifier PROTO((char *)); -static int check_newline PROTO((void)); -static int skip_white_space PROTO((int)); -static void finish_defarg PROTO((void)); -static int my_get_run_time PROTO((void)); -static int get_last_nonwhite_on_line PROTO((void)); -static int interface_strcmp PROTO((char *)); -static int readescape PROTO((int *)); -static char *extend_token_buffer PROTO((char *)); -static void consume_string PROTO((struct obstack *, int)); -static void set_typedecl_interface_info PROTO((tree, tree)); -static void feed_defarg PROTO((tree, tree)); -static int set_vardecl_interface_info PROTO((tree, tree)); -static void store_pending_inline PROTO((tree, struct pending_inline *)); -static void reinit_parse_for_expr PROTO((struct obstack *)); -static int *init_cpp_parse PROTO((void)); -static int handle_cp_pragma PROTO((char *)); -#ifdef HANDLE_GENERIC_PRAGMAS -static int handle_generic_pragma PROTO((int)); -#endif -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -static int reduce_cmp PROTO((int *, int *)); -static int token_cmp PROTO((int *, int *)); -#endif -#endif -static void begin_definition_of_inclass_inline PROTO((struct pending_inline*)); - -/* Given a file name X, return the nondirectory portion. - Keep in mind that X can be computed more than once. */ -char * -file_name_nondirectory (x) - char *x; -{ - char *tmp = (char *) rindex (x, '/'); - if (DIR_SEPARATOR != '/' && ! tmp) - tmp = (char *) rindex (x, DIR_SEPARATOR); - if (tmp) - return (char *) (tmp + 1); - else - return x; -} - -/* This obstack is needed to hold text. It is not safe to use - TOKEN_BUFFER because `check_newline' calls `yylex'. */ -struct obstack inline_text_obstack; -char *inline_text_firstobj; - -#if USE_CPPLIB -#include "cpplib.h" -extern cpp_reader parse_in; -extern cpp_options parse_options; -extern unsigned char *yy_cur, *yy_lim; -#else -FILE *finput; -#endif -int end_of_file; - -/* CYGNUS LOCAL Embedded C++ */ -/* If non-zero, we gave an error about namespaces not being allowed by - Embedded C++. */ -static int embedded_namespace_error = 0; - -/* If non-zero, we gave an error about templates not being allowed by - Embedded C++. */ -static int embedded_template_error = 0; - -/* If non-zero, we gave an error about exception handling not being allowed by - Embedded C++. */ -static int embedded_eh_error = 0; -/* END CYGNUS LOCAL Embedded C++ */ - -/* Pending language change. - Positive is push count, negative is pop count. */ -int pending_lang_change = 0; - -/* Wrap the current header file in extern "C". */ -static int c_header_level = 0; - -extern int first_token; -extern struct obstack token_obstack; - -/* ??? Don't really know where this goes yet. */ -#if 1 -#include "input.c" -#else -extern void put_back (/* int */); -extern int input_redirected (); -extern void feed_input (/* char *, int */); -#endif - -/* Holds translations from TREE_CODEs to operator name strings, - i.e., opname_tab[PLUS_EXPR] == "+". */ -char **opname_tab; -char **assignop_tab; - -extern int yychar; /* the lookahead symbol */ -extern YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ - -#if 0 -YYLTYPE yylloc; /* location data for the lookahead */ - /* symbol */ -#endif - - -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -tree lastiddecl; - -/* The elements of `ridpointers' are identifier nodes - for the reserved type names and storage classes. - It is indexed by a RID_... value. */ -tree ridpointers[(int) RID_MAX]; - -/* We may keep statistics about how long which files took to compile. */ -static int header_time, body_time; -static tree filename_times; -static tree this_filename_time; - -/* Array for holding counts of the numbers of tokens seen. */ -extern int *token_count; - -/* Return something to represent absolute declarators containing a *. - TARGET is the absolute declarator that the * contains. - CV_QUALIFIERS is a list of modifiers such as const or volatile - to apply to the pointer type, represented as identifiers. - - We return an INDIRECT_REF whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_pointer_declarator (cv_qualifiers, target) - tree cv_qualifiers, target; -{ - if (target && TREE_CODE (target) == IDENTIFIER_NODE - && ANON_AGGRNAME_P (target)) - error ("type name expected before `*'"); - target = build_parse_node (INDIRECT_REF, target); - TREE_TYPE (target) = cv_qualifiers; - return target; -} - -/* Return something to represent absolute declarators containing a &. - TARGET is the absolute declarator that the & contains. - CV_QUALIFIERS is a list of modifiers such as const or volatile - to apply to the reference type, represented as identifiers. - - We return an ADDR_EXPR whose "contents" are TARGET - and whose type is the modifier list. */ - -tree -make_reference_declarator (cv_qualifiers, target) - tree cv_qualifiers, target; -{ - if (target) - { - if (TREE_CODE (target) == ADDR_EXPR) - { - error ("cannot declare references to references"); - return target; - } - if (TREE_CODE (target) == INDIRECT_REF) - { - error ("cannot declare pointers to references"); - return target; - } - if (TREE_CODE (target) == IDENTIFIER_NODE && ANON_AGGRNAME_P (target)) - error ("type name expected before `&'"); - } - target = build_parse_node (ADDR_EXPR, target); - TREE_TYPE (target) = cv_qualifiers; - return target; -} - -tree -make_call_declarator (target, parms, cv_qualifiers, exception_specification) - tree target, parms, cv_qualifiers, exception_specification; -{ - target = build_parse_node (CALL_EXPR, target, parms, cv_qualifiers); - TREE_TYPE (target) = exception_specification; - return target; -} - -void -set_quals_and_spec (call_declarator, cv_qualifiers, exception_specification) - tree call_declarator, cv_qualifiers, exception_specification; -{ - TREE_OPERAND (call_declarator, 2) = cv_qualifiers; - TREE_TYPE (call_declarator) = exception_specification; -} - -/* Build names and nodes for overloaded operators. */ - -tree ansi_opname[LAST_CPLUS_TREE_CODE]; -tree ansi_assopname[LAST_CPLUS_TREE_CODE]; - -char * -operator_name_string (name) - tree name; -{ - char *opname = IDENTIFIER_POINTER (name) + 2; - tree *opname_table; - int i, assign; - - /* Works for builtin and user defined types. */ - if (IDENTIFIER_GLOBAL_VALUE (name) - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (name)) == TYPE_DECL) - return IDENTIFIER_POINTER (name); - - if (opname[0] == 'a' && opname[2] != '\0' && opname[2] != '_') - { - opname += 1; - assign = 1; - opname_table = ansi_assopname; - } - else - { - assign = 0; - opname_table = ansi_opname; - } - - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - if (opname[0] == IDENTIFIER_POINTER (opname_table[i])[2+assign] - && opname[1] == IDENTIFIER_POINTER (opname_table[i])[3+assign]) - break; - } - - if (i == LAST_CPLUS_TREE_CODE) - return "<invalid operator>"; - - if (assign) - return assignop_tab[i]; - else - return opname_tab[i]; -} - -int interface_only; /* whether or not current file is only for - interface definitions. */ -int interface_unknown; /* whether or not we know this class - to behave according to #pragma interface. */ - -/* lexical analyzer */ - -#ifndef WCHAR_TYPE_SIZE -#ifdef INT_TYPE_SIZE -#define WCHAR_TYPE_SIZE INT_TYPE_SIZE -#else -#define WCHAR_TYPE_SIZE BITS_PER_WORD -#endif -#endif - -/* Number of bytes in a wide character. */ -#define WCHAR_BYTES (WCHAR_TYPE_SIZE / BITS_PER_UNIT) - -static int maxtoken; /* Current nominal length of token buffer. */ -char *token_buffer; /* Pointer to token buffer. - Actual allocated length is maxtoken + 2. */ - -#include "hash.h" - - -/* Nonzero tells yylex to ignore \ in string constants. */ -static int ignore_escape_flag = 0; - -static tree -get_time_identifier (name) - char *name; -{ - tree time_identifier; - int len = strlen (name); - char *buf = (char *) alloca (len + 6); - strcpy (buf, "file "); - bcopy (name, buf+5, len); - buf[len+5] = '\0'; - time_identifier = get_identifier (buf); - if (TIME_IDENTIFIER_TIME (time_identifier) == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - TIME_IDENTIFIER_TIME (time_identifier) = build_int_2 (0, 0); - TIME_IDENTIFIER_FILEINFO (time_identifier) - = build_int_2 (0, 1); - SET_IDENTIFIER_GLOBAL_VALUE (time_identifier, filename_times); - filename_times = time_identifier; - pop_obstacks (); - } - return time_identifier; -} - -#ifdef __GNUC__ -__inline -#endif -static int -my_get_run_time () -{ - int old_quiet_flag = quiet_flag; - int this_time; - quiet_flag = 0; - this_time = get_run_time (); - quiet_flag = old_quiet_flag; - return this_time; -} - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See cp/cp-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char cplus_tree_code_type[] = { - 'x', -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int cplus_tree_code_length[] = { - 0, -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *cplus_tree_code_name[] = { - "@@dummy", -#include "cp-tree.def" -}; -#undef DEFTREECODE - -/* toplev.c needs to call these. */ - -void -lang_init_options () -{ -#if USE_CPPLIB - cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); -#endif - - /* Default exceptions on. */ - flag_exceptions = 1; -} - -void -lang_init () -{ - /* the beginning of the file is a new line; check for # */ - /* With luck, we discover the real source file's name from that - and put it in input_filename. */ -#if ! USE_CPPLIB - put_back (check_newline ()); -#else - check_newline (); - yy_cur--; -#endif - if (flag_gnu_xref) GNU_xref_begin (input_filename); - init_repo (input_filename); -} - -void -lang_finish () -{ - extern int errorcount, sorrycount; - if (flag_gnu_xref) GNU_xref_end (errorcount+sorrycount); -} - -char * -lang_identify () -{ - return "cplusplus"; -} - -void -init_filename_times () -{ - this_filename_time = get_time_identifier ("<top level>"); - if (flag_detailed_statistics) - { - header_time = 0; - body_time = my_get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - = body_time; - } -} - -/* Change by Bryan Boreham, Kewill, Thu Jul 27 09:46:05 1989. - Stuck this hack in to get the files open correctly; this is called - in place of init_parse if we are an unexec'd binary. */ - -#if 0 -void -reinit_lang_specific () -{ - init_filename_times (); - reinit_search_statistics (); -} -#endif - -static int * -init_cpp_parse () -{ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - reduce_count = (int *)malloc (sizeof (int) * (REDUCE_LENGTH + 1)); - bzero (reduce_count, sizeof (int) * (REDUCE_LENGTH + 1)); - reduce_count += 1; - token_count = (int *)malloc (sizeof (int) * (TOKEN_LENGTH + 1)); - bzero (token_count, sizeof (int) * (TOKEN_LENGTH + 1)); - token_count += 1; -#endif -#endif - return token_count; -} - -char * -init_parse (filename) - char *filename; -{ - extern int flag_no_gnu_keywords; - extern int flag_operator_names; - - int i; - -#ifdef MULTIBYTE_CHARS - /* Change to the native locale for multibyte conversions. */ - setlocale (LC_CTYPE, ""); - literal_codeset = getenv ("LANG"); -#endif - -#if USE_CPPLIB - parse_in.show_column = 1; - if (! cpp_start_read (&parse_in, filename)) - abort (); - - /* cpp_start_read always puts at least one line directive into the - token buffer. We must arrange to read it out here. */ - yy_cur = parse_in.token_buffer; - yy_lim = CPP_PWRITTEN (&parse_in); - -#else - /* Open input file. */ - if (filename == 0 || !strcmp (filename, "-")) - { - finput = stdin; - filename = "stdin"; - } - else - finput = fopen (filename, "r"); - if (finput == 0) - pfatal_with_name (filename); - -#ifdef IO_BUFFER_SIZE - setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); -#endif -#endif /* !USE_CPPLIB */ - - /* Initialize the lookahead machinery. */ - init_spew (); - - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - decl_printable_name = lang_printable_name; - - init_cplus_expand (); - - bcopy (cplus_tree_code_type, - tree_code_type + (int) LAST_AND_UNUSED_TREE_CODE, - (int)LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE); - bcopy ((char *)cplus_tree_code_length, - (char *)(tree_code_length + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (int)); - bcopy ((char *)cplus_tree_code_name, - (char *)(tree_code_name + (int) LAST_AND_UNUSED_TREE_CODE), - (LAST_CPLUS_TREE_CODE - (int)LAST_AND_UNUSED_TREE_CODE) * sizeof (char *)); - - opname_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)opname_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - assignop_tab = (char **)oballoc ((int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - bzero ((char *)assignop_tab, (int)LAST_CPLUS_TREE_CODE * sizeof (char *)); - - ansi_opname[0] = get_identifier ("<invalid operator>"); - for (i = 0; i < (int) LAST_CPLUS_TREE_CODE; i++) - { - ansi_opname[i] = ansi_opname[0]; - ansi_assopname[i] = ansi_opname[0]; - } - - ansi_opname[(int) MULT_EXPR] = get_identifier ("__ml"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MULT_EXPR]) = 1; - ansi_opname[(int) INDIRECT_REF] = ansi_opname[(int) MULT_EXPR]; - ansi_assopname[(int) MULT_EXPR] = get_identifier ("__aml"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MULT_EXPR]) = 1; - ansi_assopname[(int) INDIRECT_REF] = ansi_assopname[(int) MULT_EXPR]; - ansi_opname[(int) TRUNC_MOD_EXPR] = get_identifier ("__md"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_assopname[(int) TRUNC_MOD_EXPR] = get_identifier ("__amd"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) TRUNC_MOD_EXPR]) = 1; - ansi_opname[(int) CEIL_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) FLOOR_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) ROUND_MOD_EXPR] = ansi_opname[(int) TRUNC_MOD_EXPR]; - ansi_opname[(int) MINUS_EXPR] = get_identifier ("__mi"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MINUS_EXPR]) = 1; - ansi_opname[(int) NEGATE_EXPR] = ansi_opname[(int) MINUS_EXPR]; - ansi_assopname[(int) MINUS_EXPR] = get_identifier ("__ami"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) MINUS_EXPR]) = 1; - ansi_assopname[(int) NEGATE_EXPR] = ansi_assopname[(int) MINUS_EXPR]; - ansi_opname[(int) RSHIFT_EXPR] = get_identifier ("__rs"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) RSHIFT_EXPR]) = 1; - ansi_assopname[(int) RSHIFT_EXPR] = get_identifier ("__ars"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) RSHIFT_EXPR]) = 1; - ansi_opname[(int) NE_EXPR] = get_identifier ("__ne"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NE_EXPR]) = 1; - ansi_opname[(int) GT_EXPR] = get_identifier ("__gt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GT_EXPR]) = 1; - ansi_opname[(int) GE_EXPR] = get_identifier ("__ge"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) GE_EXPR]) = 1; - ansi_opname[(int) BIT_IOR_EXPR] = get_identifier ("__or"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_IOR_EXPR]) = 1; - ansi_assopname[(int) BIT_IOR_EXPR] = get_identifier ("__aor"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_IOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ANDIF_EXPR] = get_identifier ("__aa"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ANDIF_EXPR]) = 1; - ansi_opname[(int) TRUTH_NOT_EXPR] = get_identifier ("__nt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_NOT_EXPR]) = 1; - ansi_opname[(int) PREINCREMENT_EXPR] = get_identifier ("__pp"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREINCREMENT_EXPR]) = 1; - ansi_opname[(int) POSTINCREMENT_EXPR] = ansi_opname[(int) PREINCREMENT_EXPR]; - ansi_opname[(int) MODIFY_EXPR] = get_identifier ("__as"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MODIFY_EXPR]) = 1; - ansi_assopname[(int) NOP_EXPR] = ansi_opname[(int) MODIFY_EXPR]; - ansi_opname[(int) COMPOUND_EXPR] = get_identifier ("__cm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPOUND_EXPR]) = 1; - ansi_opname[(int) EXACT_DIV_EXPR] = get_identifier ("__dv"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EXACT_DIV_EXPR]) = 1; - ansi_assopname[(int) EXACT_DIV_EXPR] = get_identifier ("__adv"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) EXACT_DIV_EXPR]) = 1; - ansi_opname[(int) TRUNC_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) CEIL_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) FLOOR_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) ROUND_DIV_EXPR] = ansi_opname[(int) EXACT_DIV_EXPR]; - ansi_opname[(int) PLUS_EXPR] = get_identifier ("__pl"); - ansi_assopname[(int) TRUNC_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) CEIL_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) FLOOR_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - ansi_assopname[(int) ROUND_DIV_EXPR] = ansi_assopname[(int) EXACT_DIV_EXPR]; - IDENTIFIER_OPNAME_P (ansi_opname[(int) PLUS_EXPR]) = 1; - ansi_assopname[(int) PLUS_EXPR] = get_identifier ("__apl"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) PLUS_EXPR]) = 1; - ansi_opname[(int) CONVERT_EXPR] = ansi_opname[(int) PLUS_EXPR]; - ansi_assopname[(int) CONVERT_EXPR] = ansi_assopname[(int) PLUS_EXPR]; - ansi_opname[(int) LSHIFT_EXPR] = get_identifier ("__ls"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LSHIFT_EXPR]) = 1; - ansi_assopname[(int) LSHIFT_EXPR] = get_identifier ("__als"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) LSHIFT_EXPR]) = 1; - ansi_opname[(int) EQ_EXPR] = get_identifier ("__eq"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) EQ_EXPR]) = 1; - ansi_opname[(int) LT_EXPR] = get_identifier ("__lt"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LT_EXPR]) = 1; - ansi_opname[(int) LE_EXPR] = get_identifier ("__le"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) LE_EXPR]) = 1; - ansi_opname[(int) BIT_AND_EXPR] = get_identifier ("__ad"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_AND_EXPR]) = 1; - ansi_assopname[(int) BIT_AND_EXPR] = get_identifier ("__aad"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_AND_EXPR]) = 1; - ansi_opname[(int) ADDR_EXPR] = ansi_opname[(int) BIT_AND_EXPR]; - ansi_assopname[(int) ADDR_EXPR] = ansi_assopname[(int) BIT_AND_EXPR]; - ansi_opname[(int) BIT_XOR_EXPR] = get_identifier ("__er"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_XOR_EXPR]) = 1; - ansi_assopname[(int) BIT_XOR_EXPR] = get_identifier ("__aer"); - IDENTIFIER_OPNAME_P (ansi_assopname[(int) BIT_XOR_EXPR]) = 1; - ansi_opname[(int) TRUTH_ORIF_EXPR] = get_identifier ("__oo"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TRUTH_ORIF_EXPR]) = 1; - ansi_opname[(int) BIT_NOT_EXPR] = get_identifier ("__co"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) BIT_NOT_EXPR]) = 1; - ansi_opname[(int) PREDECREMENT_EXPR] = get_identifier ("__mm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) PREDECREMENT_EXPR]) = 1; - ansi_opname[(int) POSTDECREMENT_EXPR] = ansi_opname[(int) PREDECREMENT_EXPR]; - ansi_opname[(int) COMPONENT_REF] = get_identifier ("__rf"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COMPONENT_REF]) = 1; - ansi_opname[(int) MEMBER_REF] = get_identifier ("__rm"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MEMBER_REF]) = 1; - ansi_opname[(int) CALL_EXPR] = get_identifier ("__cl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) CALL_EXPR]) = 1; - ansi_opname[(int) ARRAY_REF] = get_identifier ("__vc"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) ARRAY_REF]) = 1; - ansi_opname[(int) NEW_EXPR] = get_identifier ("__nw"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) NEW_EXPR]) = 1; - ansi_opname[(int) DELETE_EXPR] = get_identifier ("__dl"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) DELETE_EXPR]) = 1; - ansi_opname[(int) VEC_NEW_EXPR] = get_identifier ("__vn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_NEW_EXPR]) = 1; - ansi_opname[(int) VEC_DELETE_EXPR] = get_identifier ("__vd"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) VEC_DELETE_EXPR]) = 1; - ansi_opname[(int) TYPE_EXPR] = get_identifier (OPERATOR_TYPENAME_FORMAT); - IDENTIFIER_OPNAME_P (ansi_opname[(int) TYPE_EXPR]) = 1; - - /* This is not true: these operators are not defined in ANSI, - but we need them anyway. */ - ansi_opname[(int) MIN_EXPR] = get_identifier ("__mn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MIN_EXPR]) = 1; - ansi_opname[(int) MAX_EXPR] = get_identifier ("__mx"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) MAX_EXPR]) = 1; - ansi_opname[(int) COND_EXPR] = get_identifier ("__cn"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) COND_EXPR]) = 1; - ansi_opname[(int) SIZEOF_EXPR] = get_identifier ("__sz"); - IDENTIFIER_OPNAME_P (ansi_opname[(int) SIZEOF_EXPR]) = 1; - - init_method (); - init_error (); - gcc_obstack_init (&inline_text_obstack); - inline_text_firstobj = (char *) obstack_alloc (&inline_text_obstack, 0); - - /* Start it at 0, because check_newline is called at the very beginning - and will increment it to 1. */ - lineno = 0; - input_filename = "<internal>"; - current_function_decl = NULL; - - maxtoken = 40; - token_buffer = (char *) xmalloc (maxtoken + 2); - - ridpointers[(int) RID_INT] = get_identifier ("int"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INT])); - ridpointers[(int) RID_BOOL] = get_identifier ("bool"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_BOOL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_BOOL])); - ridpointers[(int) RID_CHAR] = get_identifier ("char"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR])); - ridpointers[(int) RID_VOID] = get_identifier ("void"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOID], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID])); - ridpointers[(int) RID_FLOAT] = get_identifier ("float"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FLOAT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FLOAT])); - ridpointers[(int) RID_DOUBLE] = get_identifier ("double"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_DOUBLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_DOUBLE])); - ridpointers[(int) RID_SHORT] = get_identifier ("short"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SHORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SHORT])); - ridpointers[(int) RID_LONG] = get_identifier ("long"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_LONG], - build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG])); - ridpointers[(int) RID_UNSIGNED] = get_identifier ("unsigned"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_UNSIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED])); - ridpointers[(int) RID_SIGNED] = get_identifier ("signed"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_SIGNED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_SIGNED])); - ridpointers[(int) RID_INLINE] = get_identifier ("inline"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_INLINE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_INLINE])); - ridpointers[(int) RID_CONST] = get_identifier ("const"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_CONST], - build_tree_list (NULL_TREE, ridpointers[(int) RID_CONST])); - ridpointers[(int) RID_VOLATILE] = get_identifier ("volatile"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VOLATILE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VOLATILE])); - ridpointers[(int) RID_RESTRICT] = get_identifier ("__restrict"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_RESTRICT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_RESTRICT])); - ridpointers[(int) RID_AUTO] = get_identifier ("auto"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_AUTO], - build_tree_list (NULL_TREE, ridpointers[(int) RID_AUTO])); - ridpointers[(int) RID_STATIC] = get_identifier ("static"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_STATIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC])); - ridpointers[(int) RID_EXTERN] = get_identifier ("extern"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXTERN], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN])); - ridpointers[(int) RID_TYPEDEF] = get_identifier ("typedef"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TYPEDEF], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TYPEDEF])); - ridpointers[(int) RID_REGISTER] = get_identifier ("register"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_REGISTER], - build_tree_list (NULL_TREE, ridpointers[(int) RID_REGISTER])); - ridpointers[(int) RID_COMPLEX] = get_identifier ("__complex"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_COMPLEX], - build_tree_list (NULL_TREE, ridpointers[(int) RID_COMPLEX])); - - /* C++ extensions. These are probably not correctly named. */ - ridpointers[(int) RID_WCHAR] = get_identifier ("__wchar_t"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_WCHAR], - build_tree_list (NULL_TREE, ridpointers[(int) RID_WCHAR])); - class_type_node = build_int_2 (class_type, 0); - TREE_TYPE (class_type_node) = class_type_node; - ridpointers[(int) RID_CLASS] = class_type_node; - - record_type_node = build_int_2 (record_type, 0); - TREE_TYPE (record_type_node) = record_type_node; - ridpointers[(int) RID_RECORD] = record_type_node; - - union_type_node = build_int_2 (union_type, 0); - TREE_TYPE (union_type_node) = union_type_node; - ridpointers[(int) RID_UNION] = union_type_node; - - enum_type_node = build_int_2 (enum_type, 0); - TREE_TYPE (enum_type_node) = enum_type_node; - ridpointers[(int) RID_ENUM] = enum_type_node; - - ridpointers[(int) RID_VIRTUAL] = get_identifier ("virtual"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_VIRTUAL], - build_tree_list (NULL_TREE, ridpointers[(int) RID_VIRTUAL])); - ridpointers[(int) RID_EXPLICIT] = get_identifier ("explicit"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPLICIT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPLICIT])); - ridpointers[(int) RID_EXPORT] = get_identifier ("export"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_EXPORT], - build_tree_list (NULL_TREE, ridpointers[(int) RID_EXPORT])); - ridpointers[(int) RID_FRIEND] = get_identifier ("friend"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_FRIEND], - build_tree_list (NULL_TREE, ridpointers[(int) RID_FRIEND])); - - ridpointers[(int) RID_PUBLIC] = get_identifier ("public"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PUBLIC], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PUBLIC])); - ridpointers[(int) RID_PRIVATE] = get_identifier ("private"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PRIVATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PRIVATE])); - ridpointers[(int) RID_PROTECTED] = get_identifier ("protected"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_PROTECTED], - build_tree_list (NULL_TREE, ridpointers[(int) RID_PROTECTED])); - ridpointers[(int) RID_TEMPLATE] = get_identifier ("template"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_TEMPLATE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_TEMPLATE])); - /* This is for ANSI C++. */ - ridpointers[(int) RID_MUTABLE] = get_identifier ("mutable"); - SET_IDENTIFIER_AS_LIST (ridpointers[(int) RID_MUTABLE], - build_tree_list (NULL_TREE, ridpointers[(int) RID_MUTABLE])); - - /* Signature handling extensions. */ - signature_type_node = build_int_2 (signature_type, 0); - TREE_TYPE (signature_type_node) = signature_type_node; - ridpointers[(int) RID_SIGNATURE] = signature_type_node; - - /* Create the built-in __null node. Note that we can't yet call for - type_for_size here because integer_type_node and so forth are not - set up. Therefore, we don't set the type of these nodes until - init_decl_processing. */ - null_node = build_int_2 (0, 0); - ridpointers[RID_NULL] = null_node; - - opname_tab[(int) COMPONENT_REF] = "->"; - opname_tab[(int) MEMBER_REF] = "->*"; - opname_tab[(int) INDIRECT_REF] = "*"; - opname_tab[(int) ARRAY_REF] = "[]"; - opname_tab[(int) MODIFY_EXPR] = "="; - opname_tab[(int) NEW_EXPR] = "new"; - opname_tab[(int) DELETE_EXPR] = "delete"; - opname_tab[(int) VEC_NEW_EXPR] = "new []"; - opname_tab[(int) VEC_DELETE_EXPR] = "delete []"; - opname_tab[(int) COND_EXPR] = "?:"; - opname_tab[(int) CALL_EXPR] = "()"; - opname_tab[(int) PLUS_EXPR] = "+"; - opname_tab[(int) MINUS_EXPR] = "-"; - opname_tab[(int) MULT_EXPR] = "*"; - opname_tab[(int) TRUNC_DIV_EXPR] = "/"; - opname_tab[(int) CEIL_DIV_EXPR] = "(ceiling /)"; - opname_tab[(int) FLOOR_DIV_EXPR] = "(floor /)"; - opname_tab[(int) ROUND_DIV_EXPR] = "(round /)"; - opname_tab[(int) TRUNC_MOD_EXPR] = "%"; - opname_tab[(int) CEIL_MOD_EXPR] = "(ceiling %)"; - opname_tab[(int) FLOOR_MOD_EXPR] = "(floor %)"; - opname_tab[(int) ROUND_MOD_EXPR] = "(round %)"; - opname_tab[(int) NEGATE_EXPR] = "-"; - opname_tab[(int) MIN_EXPR] = "<?"; - opname_tab[(int) MAX_EXPR] = ">?"; - opname_tab[(int) ABS_EXPR] = "abs"; - opname_tab[(int) FFS_EXPR] = "ffs"; - opname_tab[(int) LSHIFT_EXPR] = "<<"; - opname_tab[(int) RSHIFT_EXPR] = ">>"; - opname_tab[(int) BIT_IOR_EXPR] = "|"; - opname_tab[(int) BIT_XOR_EXPR] = "^"; - opname_tab[(int) BIT_AND_EXPR] = "&"; - opname_tab[(int) BIT_ANDTC_EXPR] = "&~"; - opname_tab[(int) BIT_NOT_EXPR] = "~"; - opname_tab[(int) TRUTH_ANDIF_EXPR] = "&&"; - opname_tab[(int) TRUTH_ORIF_EXPR] = "||"; - opname_tab[(int) TRUTH_AND_EXPR] = "strict &&"; - opname_tab[(int) TRUTH_OR_EXPR] = "strict ||"; - opname_tab[(int) TRUTH_NOT_EXPR] = "!"; - opname_tab[(int) LT_EXPR] = "<"; - opname_tab[(int) LE_EXPR] = "<="; - opname_tab[(int) GT_EXPR] = ">"; - opname_tab[(int) GE_EXPR] = ">="; - opname_tab[(int) EQ_EXPR] = "=="; - opname_tab[(int) NE_EXPR] = "!="; - opname_tab[(int) IN_EXPR] = "in"; - opname_tab[(int) RANGE_EXPR] = "..."; - opname_tab[(int) CONVERT_EXPR] = "+"; - opname_tab[(int) ADDR_EXPR] = "&"; - opname_tab[(int) PREDECREMENT_EXPR] = "--"; - opname_tab[(int) PREINCREMENT_EXPR] = "++"; - opname_tab[(int) POSTDECREMENT_EXPR] = "--"; - opname_tab[(int) POSTINCREMENT_EXPR] = "++"; - opname_tab[(int) COMPOUND_EXPR] = ","; - - assignop_tab[(int) NOP_EXPR] = "="; - assignop_tab[(int) PLUS_EXPR] = "+="; - assignop_tab[(int) CONVERT_EXPR] = "+="; - assignop_tab[(int) MINUS_EXPR] = "-="; - assignop_tab[(int) NEGATE_EXPR] = "-="; - assignop_tab[(int) MULT_EXPR] = "*="; - assignop_tab[(int) INDIRECT_REF] = "*="; - assignop_tab[(int) TRUNC_DIV_EXPR] = "/="; - assignop_tab[(int) EXACT_DIV_EXPR] = "(exact /=)"; - assignop_tab[(int) CEIL_DIV_EXPR] = "(ceiling /=)"; - assignop_tab[(int) FLOOR_DIV_EXPR] = "(floor /=)"; - assignop_tab[(int) ROUND_DIV_EXPR] = "(round /=)"; - assignop_tab[(int) TRUNC_MOD_EXPR] = "%="; - assignop_tab[(int) CEIL_MOD_EXPR] = "(ceiling %=)"; - assignop_tab[(int) FLOOR_MOD_EXPR] = "(floor %=)"; - assignop_tab[(int) ROUND_MOD_EXPR] = "(round %=)"; - assignop_tab[(int) MIN_EXPR] = "<?="; - assignop_tab[(int) MAX_EXPR] = ">?="; - assignop_tab[(int) LSHIFT_EXPR] = "<<="; - assignop_tab[(int) RSHIFT_EXPR] = ">>="; - assignop_tab[(int) BIT_IOR_EXPR] = "|="; - assignop_tab[(int) BIT_XOR_EXPR] = "^="; - assignop_tab[(int) BIT_AND_EXPR] = "&="; - assignop_tab[(int) ADDR_EXPR] = "&="; - - init_filename_times (); - - /* Some options inhibit certain reserved words. - Clear those words out of the hash table so they won't be recognized. */ -#define UNSET_RESERVED_WORD(STRING) \ - do { struct resword *s = is_reserved_word (STRING, sizeof (STRING) - 1); \ - if (s) s->name = ""; } while (0) - -#if 0 - /* let's parse things, and if they use it, then give them an error. */ - if (!flag_exceptions) - { - UNSET_RESERVED_WORD ("throw"); - UNSET_RESERVED_WORD ("try"); - UNSET_RESERVED_WORD ("catch"); - } -#endif - - if (!flag_rtti || flag_no_gnu_keywords) - { - UNSET_RESERVED_WORD ("classof"); - UNSET_RESERVED_WORD ("headof"); - } - - if (! flag_handle_signatures || flag_no_gnu_keywords) - { - /* Easiest way to not recognize signature - handling extensions... */ - UNSET_RESERVED_WORD ("signature"); - UNSET_RESERVED_WORD ("sigof"); - } - if (flag_no_asm || flag_no_gnu_keywords) - UNSET_RESERVED_WORD ("typeof"); - if (! flag_operator_names) - { - /* These are new ANSI keywords that may break code. */ - UNSET_RESERVED_WORD ("and"); - UNSET_RESERVED_WORD ("and_eq"); - UNSET_RESERVED_WORD ("bitand"); - UNSET_RESERVED_WORD ("bitor"); - UNSET_RESERVED_WORD ("compl"); - UNSET_RESERVED_WORD ("not"); - UNSET_RESERVED_WORD ("not_eq"); - UNSET_RESERVED_WORD ("or"); - UNSET_RESERVED_WORD ("or_eq"); - UNSET_RESERVED_WORD ("xor"); - UNSET_RESERVED_WORD ("xor_eq"); - } - - token_count = init_cpp_parse (); - interface_unknown = 1; - - return filename; -} - -void -finish_parse () -{ -#if USE_CPPLIB - cpp_finish (&parse_in); -#else - fclose (finput); -#endif -} - -void -reinit_parse_for_function () -{ - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; -} - -#ifdef __GNUC__ -__inline -#endif -void -yyprint (file, yychar, yylval) - FILE *file; - int yychar; - YYSTYPE yylval; -{ - tree t; - switch (yychar) - { - case IDENTIFIER: - case TYPENAME: - case TYPESPEC: - case PTYPENAME: - case IDENTIFIER_DEFN: - case TYPENAME_DEFN: - case PTYPENAME_DEFN: - case SCSPEC: - case PRE_PARSED_CLASS_DECL: - t = yylval.ttype; - if (TREE_CODE (t) == TYPE_DECL || TREE_CODE (t) == TEMPLATE_DECL) - { - fprintf (file, " `%s'", IDENTIFIER_POINTER (DECL_NAME (t))); - break; - } - my_friendly_assert (TREE_CODE (t) == IDENTIFIER_NODE, 224); - if (IDENTIFIER_POINTER (t)) - fprintf (file, " `%s'", IDENTIFIER_POINTER (t)); - break; - case AGGR: - if (yylval.ttype == class_type_node) - fprintf (file, " `class'"); - else if (yylval.ttype == record_type_node) - fprintf (file, " `struct'"); - else if (yylval.ttype == union_type_node) - fprintf (file, " `union'"); - else if (yylval.ttype == enum_type_node) - fprintf (file, " `enum'"); - else if (yylval.ttype == signature_type_node) - fprintf (file, " `signature'"); - else - my_friendly_abort (80); - break; - } -} - -#if defined(GATHER_STATISTICS) && defined(REDUCE_LENGTH) -static int *reduce_count; -#endif - -int *token_count; - -#if 0 -#define REDUCE_LENGTH (sizeof (yyr2) / sizeof (yyr2[0])) -#define TOKEN_LENGTH (256 + sizeof (yytname) / sizeof (yytname[0])) -#endif - -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -void -yyhook (yyn) - int yyn; -{ - reduce_count[yyn] += 1; -} - -static int -reduce_cmp (p, q) - int *p, *q; -{ - return reduce_count[*q] - reduce_count[*p]; -} - -static int -token_cmp (p, q) - int *p, *q; -{ - return token_count[*q] - token_count[*p]; -} -#endif -#endif - -void -print_parse_statistics () -{ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH -#if YYDEBUG != 0 - int i; - int maxlen = REDUCE_LENGTH; - unsigned *sorted; - - if (reduce_count[-1] == 0) - return; - - if (TOKEN_LENGTH > REDUCE_LENGTH) - maxlen = TOKEN_LENGTH; - sorted = (unsigned *) alloca (sizeof (int) * maxlen); - - for (i = 0; i < TOKEN_LENGTH; i++) - sorted[i] = i; - qsort (sorted, TOKEN_LENGTH, sizeof (int), token_cmp); - for (i = 0; i < TOKEN_LENGTH; i++) - { - int idx = sorted[i]; - if (token_count[idx] == 0) - break; - if (token_count[idx] < token_count[-1]) - break; - fprintf (stderr, "token %d, `%s', count = %d\n", - idx, yytname[YYTRANSLATE (idx)], token_count[idx]); - } - fprintf (stderr, "\n"); - for (i = 0; i < REDUCE_LENGTH; i++) - sorted[i] = i; - qsort (sorted, REDUCE_LENGTH, sizeof (int), reduce_cmp); - for (i = 0; i < REDUCE_LENGTH; i++) - { - int idx = sorted[i]; - if (reduce_count[idx] == 0) - break; - if (reduce_count[idx] < reduce_count[-1]) - break; - fprintf (stderr, "rule %d, line %d, count = %d\n", - idx, yyrline[idx], reduce_count[idx]); - } - fprintf (stderr, "\n"); -#endif -#endif -#endif -} - -/* Sets the value of the 'yydebug' variable to VALUE. - This is a function so we don't have to have YYDEBUG defined - in order to build the compiler. */ - -void -set_yydebug (value) - int value; -{ -#if YYDEBUG != 0 - extern int yydebug; - yydebug = value; -#else - warning ("YYDEBUG not defined."); -#endif -} - - -/* Functions and data structures for #pragma interface. - - `#pragma implementation' means that the main file being compiled - is considered to implement (provide) the classes that appear in - its main body. I.e., if this is file "foo.cc", and class `bar' - is defined in "foo.cc", then we say that "foo.cc implements bar". - - All main input files "implement" themselves automagically. - - `#pragma interface' means that unless this file (of the form "foo.h" - is not presently being included by file "foo.cc", the - CLASSTYPE_INTERFACE_ONLY bit gets set. The effect is that none - of the vtables nor any of the inline functions defined in foo.h - will ever be output. - - There are cases when we want to link files such as "defs.h" and - "main.cc". In this case, we give "defs.h" a `#pragma interface', - and "main.cc" has `#pragma implementation "defs.h"'. */ - -struct impl_files -{ - char *filename; - struct impl_files *next; -}; - -static struct impl_files *impl_file_chain; - -/* Helper function to load global variables with interface - information. */ - -void -extract_interface_info () -{ - tree fileinfo = 0; - - if (flag_alt_external_templates) - { - struct tinst_level *til = tinst_for_decl (); - - if (til) - fileinfo = get_time_identifier (til->file); - } - if (!fileinfo) - fileinfo = get_time_identifier (input_filename); - fileinfo = TIME_IDENTIFIER_FILEINFO (fileinfo); - interface_only = TREE_INT_CST_LOW (fileinfo); - interface_unknown = TREE_INT_CST_HIGH (fileinfo); -} - -/* Return nonzero if S is not considered part of an - INTERFACE/IMPLEMENTATION pair. Otherwise, return 0. */ - -static int -interface_strcmp (s) - char *s; -{ - /* Set the interface/implementation bits for this scope. */ - struct impl_files *ifiles; - char *s1; - - for (ifiles = impl_file_chain; ifiles; ifiles = ifiles->next) - { - char *t1 = ifiles->filename; - s1 = s; - - if (*s1 != *t1 || *s1 == 0) - continue; - - while (*s1 == *t1 && *s1 != 0) - s1++, t1++; - - /* A match. */ - if (*s1 == *t1) - return 0; - - /* Don't get faked out by xxx.yyy.cc vs xxx.zzz.cc. */ - if (index (s1, '.') || index (t1, '.')) - continue; - - if (*s1 == '\0' || s1[-1] != '.' || t1[-1] != '.') - continue; - - /* A match. */ - return 0; - } - - /* No matches. */ - return 1; -} - -static void -set_typedecl_interface_info (prev, vars) - tree prev ATTRIBUTE_UNUSED, vars; -{ - tree id = get_time_identifier (DECL_SOURCE_FILE (vars)); - tree fileinfo = TIME_IDENTIFIER_FILEINFO (id); - tree type = TREE_TYPE (vars); - - CLASSTYPE_INTERFACE_ONLY (type) = TREE_INT_CST_LOW (fileinfo) - = interface_strcmp (file_name_nondirectory (DECL_SOURCE_FILE (vars))); -} - -static int -set_vardecl_interface_info (prev, vars) - tree prev, vars; -{ - tree type = DECL_CONTEXT (vars); - - if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - if (CLASSTYPE_INTERFACE_ONLY (type)) - set_typedecl_interface_info (prev, TYPE_MAIN_DECL (type)); - else - CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; - DECL_EXTERNAL (vars) = CLASSTYPE_INTERFACE_ONLY (type); - TREE_PUBLIC (vars) = 1; - return 1; - } - return 0; -} - -/* Set up the state required to correctly handle the definition of the - inline function whose preparsed state has been saved in PI. */ - -static void -begin_definition_of_inclass_inline (pi) - struct pending_inline* pi; -{ - tree context; - - if (!pi->fndecl) - return; - - /* If this is an inline function in a local class, we must make sure - that we save all pertinent information about the function - surrounding the local class. */ - context = hack_decl_function_context (pi->fndecl); - if (context) - push_cp_function_context (context); - - feed_input (pi->buf, pi->len); - lineno = pi->lineno; - input_filename = pi->filename; - yychar = PRE_PARSED_FUNCTION_DECL; - yylval.ttype = build_tree_list ((tree) pi, pi->fndecl); - /* Pass back a handle to the rest of the inline functions, so that they - can be processed later. */ - DECL_PENDING_INLINE_INFO (pi->fndecl) = 0; - interface_unknown = pi->interface == 1; - interface_only = pi->interface == 0; -} - -/* Called from the top level: if there are any pending inlines to - do, set up to process them now. This function sets up the first function - to be parsed; after it has been, the rule for fndef in parse.y will - call process_next_inline to start working on the next one. */ - -void -do_pending_inlines () -{ - struct pending_inline *t; - - /* Oops, we're still dealing with the last batch. */ - if (yychar == PRE_PARSED_FUNCTION_DECL) - return; - - /* Reverse the pending inline functions, since - they were cons'd instead of appended. */ - { - struct pending_inline *prev = 0, *tail; - t = pending_inlines; - pending_inlines = 0; - - for (; t; t = tail) - { - tail = t->next; - t->next = prev; - t->deja_vu = 1; - prev = t; - } - t = prev; - } - - if (t == 0) - return; - - /* Now start processing the first inline function. */ - begin_definition_of_inclass_inline (t); -} - -static int nextchar = -1; - -/* Called from the fndecl rule in the parser when the function just parsed - was declared using a PRE_PARSED_FUNCTION_DECL (i.e. came from - do_pending_inlines). */ - -void -process_next_inline (t) - tree t; -{ - tree context; - struct pending_inline *i = (struct pending_inline *) TREE_PURPOSE (t); - context = hack_decl_function_context (i->fndecl); - if (context) - pop_cp_function_context (context); - i = i->next; - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. We also need to discard nextchar, - since that may have gotten set as well. */ - nextchar = -1; - } - yychar = YYEMPTY; - end_input (); - if (i) - begin_definition_of_inclass_inline (i); - else - extract_interface_info (); -} - -/* Since inline methods can refer to text which has not yet been seen, - we store the text of the method in a structure which is placed in the - DECL_PENDING_INLINE_INFO field of the FUNCTION_DECL. - After parsing the body of the class definition, the FUNCTION_DECL's are - scanned to see which ones have this field set. Those are then digested - one at a time. - - This function's FUNCTION_DECL will have a bit set in its common so - that we know to watch out for it. */ - -static void -consume_string (this_obstack, matching_char) - register struct obstack *this_obstack; - int matching_char; -{ - register int c; - int starting_lineno = lineno; - do - { - c = getch (); - if (c == EOF) - { - int save_lineno = lineno; - lineno = starting_lineno; - if (matching_char == '"') - error ("end of file encountered inside string constant"); - else - error ("end of file encountered inside character constant"); - lineno = save_lineno; - return; - } - if (c == '\\') - { - obstack_1grow (this_obstack, c); - c = getch (); - obstack_1grow (this_obstack, c); - - /* Make sure we continue the loop */ - c = 0; - continue; - } - if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } - obstack_1grow (this_obstack, c); - } - while (c != matching_char); -} - -static int nextyychar = YYEMPTY; -static YYSTYPE nextyylval; - -struct pending_input { - int nextchar, yychar, nextyychar, eof; - YYSTYPE yylval, nextyylval; - struct obstack token_obstack; - int first_token; -}; - -struct pending_input * -save_pending_input () -{ - struct pending_input *p; - p = (struct pending_input *) xmalloc (sizeof (struct pending_input)); - p->nextchar = nextchar; - p->yychar = yychar; - p->nextyychar = nextyychar; - p->yylval = yylval; - p->nextyylval = nextyylval; - p->eof = end_of_file; - yychar = nextyychar = YYEMPTY; - nextchar = -1; - p->first_token = first_token; - p->token_obstack = token_obstack; - - first_token = 0; - gcc_obstack_init (&token_obstack); - end_of_file = 0; - return p; -} - -void -restore_pending_input (p) - struct pending_input *p; -{ - my_friendly_assert (nextchar == -1, 229); - nextchar = p->nextchar; - my_friendly_assert (yychar == YYEMPTY || yychar == END_OF_SAVED_INPUT, 230); - yychar = p->yychar; - my_friendly_assert (nextyychar == YYEMPTY, 231); - nextyychar = p->nextyychar; - yylval = p->yylval; - nextyylval = p->nextyylval; - first_token = p->first_token; - obstack_free (&token_obstack, (char *) 0); - token_obstack = p->token_obstack; - end_of_file = p->eof; - free (p); -} - -/* Unget character CH from the input stream. - If RESCAN is non-zero, then we want to `see' this - character as the next input token. */ - -void -yyungetc (ch, rescan) - int ch; - int rescan; -{ - /* Unget a character from the input stream. */ - if (yychar == YYEMPTY || rescan == 0) - { - if (nextchar >= 0) - put_back (nextchar); - nextchar = ch; - } - else - { - my_friendly_assert (nextyychar == YYEMPTY, 232); - nextyychar = yychar; - nextyylval = yylval; - yychar = ch; - } -} - -void -clear_inline_text_obstack () -{ - obstack_free (&inline_text_obstack, inline_text_firstobj); -} - -/* This function stores away the text for an inline function that should - be processed later. It decides how much later, and may need to move - the info between obstacks; therefore, the caller should not refer to - the T parameter after calling this function. */ - -static void -store_pending_inline (decl, t) - tree decl; - struct pending_inline *t; -{ - t->fndecl = decl; - DECL_PENDING_INLINE_INFO (decl) = t; - - /* Because we use obstacks, we must process these in precise order. */ - t->next = pending_inlines; - pending_inlines = t; -} - -void -reinit_parse_for_method (yychar, decl) - int yychar; - tree decl; -{ - int len; - int starting_lineno = lineno; - char *starting_filename = input_filename; - - reinit_parse_for_block (yychar, &inline_text_obstack); - - len = obstack_object_size (&inline_text_obstack); - current_base_init_list = NULL_TREE; - current_member_init_list = NULL_TREE; - if (decl == void_type_node - || (current_class_type && TYPE_REDEFINED (current_class_type))) - { - /* Happens when we get two declarations of the same - function in the same scope. */ - char *buf = obstack_finish (&inline_text_obstack); - obstack_free (&inline_text_obstack, buf); - return; - } - else - { - struct pending_inline *t; - char *buf = obstack_finish (&inline_text_obstack); - - t = (struct pending_inline *) obstack_alloc (&inline_text_obstack, - sizeof (struct pending_inline)); - t->lineno = starting_lineno; - t->filename = starting_filename; - t->token = YYEMPTY; - t->token_value = 0; - t->buf = buf; - t->len = len; - t->deja_vu = 0; -#if 0 - if (interface_unknown && processing_template_defn && flag_external_templates && ! DECL_IN_SYSTEM_HEADER (decl)) - warn_if_unknown_interface (decl); -#endif - t->interface = (interface_unknown ? 1 : (interface_only ? 0 : 2)); - store_pending_inline (decl, t); - } -} - -/* Consume a block -- actually, a method beginning - with `:' or `{' -- and save it away on the specified obstack. */ - -void -reinit_parse_for_block (pyychar, obstackp) - int pyychar; - struct obstack *obstackp; -{ - register int c = 0; - int blev = 1; - int starting_lineno = lineno; - char *starting_filename = input_filename; - int len; - int look_for_semicolon = 0; - int look_for_lbrac = 0; - - if (pyychar == '{') - obstack_1grow (obstackp, '{'); - else if (pyychar == '=') - look_for_semicolon = 1; - else if (pyychar == ':') - { - obstack_1grow (obstackp, pyychar); - /* Add a space so we don't get confused by ': ::A(20)'. */ - obstack_1grow (obstackp, ' '); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == RETURN) - { - obstack_grow (obstackp, "return", 6); - look_for_lbrac = 1; - blev = 0; - } - else if (pyychar == TRY) - { - obstack_grow (obstackp, "try", 3); - look_for_lbrac = 1; - blev = 0; - } - else - { - yyerror ("parse error in method specification"); - obstack_1grow (obstackp, '{'); - } - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - c = skip_white_space (c); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; i--) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - obstack_1grow (obstackp, c); - if (c == '{') - { - look_for_lbrac = 0; - blev++; - } - else if (c == '}') - { - blev--; - if (blev == 0 && !look_for_semicolon) - { - if (pyychar == TRY) - { - if (peekyylex () == CATCH) - { - yylex (); - obstack_grow (obstackp, " catch ", 7); - look_for_lbrac = 1; - } - else - { - yychar = '{'; - goto done; - } - } - else - { - goto done; - } - } - } - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - else if (c == ';') - { - if (look_for_lbrac) - { - error ("function body for constructor missing"); - obstack_1grow (obstackp, '{'); - obstack_1grow (obstackp, '}'); - len += 2; - goto done; - } - else if (look_for_semicolon && blev == 0) - goto done; - } - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -/* Consume a no-commas expression -- actually, a default argument -- and - save it away on the specified obstack. */ - -static void -reinit_parse_for_expr (obstackp) - struct obstack *obstackp; -{ - register int c = 0; - int starting_lineno = lineno; - char *starting_filename = input_filename; - int len; - int plev = 0; - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - while (c != EOF) - { - int this_lineno = lineno; - - c = skip_white_space (c); - - /* Don't lose our cool if there are lots of comments. */ - if (lineno == this_lineno + 1) - obstack_1grow (obstackp, '\n'); - else if (lineno == this_lineno) - ; - else if (lineno - this_lineno < 10) - { - int i; - for (i = lineno - this_lineno; i > 0; --i) - obstack_1grow (obstackp, '\n'); - } - else - { - char buf[16]; - sprintf (buf, "\n# %d \"", lineno); - len = strlen (buf); - obstack_grow (obstackp, buf, len); - - len = strlen (input_filename); - obstack_grow (obstackp, input_filename, len); - obstack_1grow (obstackp, '\"'); - obstack_1grow (obstackp, '\n'); - } - - while (c > ' ') /* ASCII dependent... */ - { - if (plev <= 0 && (c == ')' || c == ',')) - { - put_back (c); - goto done; - } - obstack_1grow (obstackp, c); - if (c == '(' || c == '[') - ++plev; - else if (c == ']' || c == ')') - --plev; - else if (c == '\\') - { - /* Don't act on the next character...e.g, doing an escaped - double-quote. */ - c = getch (); - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - obstack_1grow (obstackp, c); - } - else if (c == '\"') - consume_string (obstackp, c); - else if (c == '\'') - consume_string (obstackp, c); - c = getch (); - } - - if (c == EOF) - { - error_with_file_and_line (starting_filename, - starting_lineno, - "end of file read inside definition"); - goto done; - } - else if (c != '\n') - { - obstack_1grow (obstackp, c); - c = getch (); - } - } - done: - obstack_1grow (obstackp, '\0'); -} - -int do_snarf_defarg; - -/* Decide whether the default argument we are about to see should be - gobbled up as text for later parsing. */ - -void -maybe_snarf_defarg () -{ - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - do_snarf_defarg = 1; -} - -/* When we see a default argument in a method declaration, we snarf it as - text using snarf_defarg. When we get up to namespace scope, we then go - through and parse all of them using do_pending_defargs. Since yacc - parsers are not reentrant, we retain defargs state in these two - variables so that subsequent calls to do_pending_defargs can resume - where the previous call left off. */ - -tree defarg_fns; -tree defarg_parm; - -tree -snarf_defarg () -{ - int len; - char *buf; - tree arg; - - reinit_parse_for_expr (&inline_text_obstack); - len = obstack_object_size (&inline_text_obstack); - buf = obstack_finish (&inline_text_obstack); - - push_obstacks (&inline_text_obstack, &inline_text_obstack); - arg = make_node (DEFAULT_ARG); - DEFARG_LENGTH (arg) = len - 1; - DEFARG_POINTER (arg) = buf; - pop_obstacks (); - - return arg; -} - -/* Called from grokfndecl to note a function decl with unparsed default - arguments for later processing. Also called from grokdeclarator - for function types with unparsed defargs; the call from grokfndecl - will always come second, so we can overwrite the entry from the type. */ - -void -add_defarg_fn (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL) - TREE_VALUE (defarg_fns) = decl; - else - { - push_obstacks (&inline_text_obstack, &inline_text_obstack); - defarg_fns = tree_cons (current_class_type, decl, defarg_fns); - pop_obstacks (); - } -} - -/* Helper for do_pending_defargs. Starts the parsing of a default arg. */ - -static void -feed_defarg (f, p) - tree f, p; -{ - tree d = TREE_PURPOSE (p); - feed_input (DEFARG_POINTER (d), DEFARG_LENGTH (d)); - if (TREE_CODE (f) == FUNCTION_DECL) - { - lineno = DECL_SOURCE_LINE (f); - input_filename = DECL_SOURCE_FILE (f); - } - yychar = DEFARG_MARKER; - yylval.ttype = p; -} - -/* Helper for do_pending_defargs. Ends the parsing of a default arg. */ - -static void -finish_defarg () -{ - if (yychar == YYEMPTY) - yychar = yylex (); - if (yychar != END_OF_SAVED_INPUT) - { - error ("parse error at end of saved function text"); - - /* restore_pending_input will abort unless yychar is either - END_OF_SAVED_INPUT or YYEMPTY; since we already know we're - hosed, feed back YYEMPTY. We also need to discard nextchar, - since that may have gotten set as well. */ - nextchar = -1; - } - yychar = YYEMPTY; - end_input (); -} - -/* Main function for deferred parsing of default arguments. Called from - the parser. */ - -void -do_pending_defargs () -{ - if (defarg_parm) - finish_defarg (); - - for (; defarg_fns; defarg_fns = TREE_CHAIN (defarg_fns)) - { - tree defarg_fn = TREE_VALUE (defarg_fns); - if (defarg_parm == NULL_TREE) - { - push_nested_class (TREE_PURPOSE (defarg_fns), 1); - pushlevel (0); - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - maybe_begin_member_template_processing (defarg_fn); - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { -#if 0 - tree p; - for (p = DECL_ARGUMENTS (defarg_fn); p; p = TREE_CHAIN (p)) - pushdecl (copy_node (p)); -#endif - defarg_parm = TYPE_ARG_TYPES (TREE_TYPE (defarg_fn)); - } - else - defarg_parm = TYPE_ARG_TYPES (defarg_fn); - } - else - defarg_parm = TREE_CHAIN (defarg_parm); - - for (; defarg_parm; defarg_parm = TREE_CHAIN (defarg_parm)) - if (TREE_PURPOSE (defarg_parm) - && TREE_CODE (TREE_PURPOSE (defarg_parm)) == DEFAULT_ARG) - { - feed_defarg (defarg_fn, defarg_parm); - - /* Return to the parser, which will process this defarg - and call us again. */ - return; - } - - if (TREE_CODE (defarg_fn) == FUNCTION_DECL) - { - maybe_end_member_template_processing (); - check_default_args (defarg_fn); - } - - poplevel (0, 0, 0); - pop_nested_class (1); - } -} - -/* Build a default function named NAME for type TYPE. - KIND says what to build. - - When KIND == 0, build default destructor. - When KIND == 1, build virtual destructor. - When KIND == 2, build default constructor. - When KIND == 3, build default X(const X&) constructor. - When KIND == 4, build default X(X&) constructor. - When KIND == 5, build default operator = (const X&). - When KIND == 6, build default operator = (X&). */ - -tree -cons_up_default_function (type, full_name, kind) - tree type, full_name; - int kind; -{ - extern tree void_list_node; - tree declspecs = NULL_TREE; - tree fn, args = NULL_TREE; - tree argtype; - int retref = 0; - tree name = constructor_name (full_name); - - switch (kind) - { - /* Destructors. */ - case 1: - declspecs = build_decl_list (NULL_TREE, ridpointers [(int) RID_VIRTUAL]); - /* Fall through... */ - case 0: - name = build_parse_node (BIT_NOT_EXPR, name); - args = void_list_node; - break; - - case 2: - /* Default constructor. */ - args = void_list_node; - break; - - case 3: - type = build_qualified_type (type, TYPE_QUAL_CONST); - /* Fall through... */ - case 4: - /* According to ARM $12.8, the default copy ctor will be declared, but - not defined, unless it's needed. */ - argtype = build_reference_type (type); - args = tree_cons (NULL_TREE, - build_tree_list (hash_tree_chain (argtype, NULL_TREE), - get_identifier ("_ctor_arg")), - void_list_node); - break; - - case 5: - case 6: - retref = 1; - declspecs = build_decl_list (NULL_TREE, type); - - if (kind == 5) - type = build_qualified_type (type, TYPE_QUAL_CONST); - - name = ansi_opname [(int) MODIFY_EXPR]; - - argtype = build_reference_type (type); - args = tree_cons (NULL_TREE, - build_tree_list (hash_tree_chain (argtype, NULL_TREE), - get_identifier ("_ctor_arg")), - void_list_node); - break; - - default: - my_friendly_abort (59); - } - - declspecs = decl_tree_cons (NULL_TREE, ridpointers [(int) RID_INLINE], - declspecs); - - TREE_PARMLIST (args) = 1; - - { - tree declarator = make_call_declarator (name, args, NULL_TREE, NULL_TREE); - if (retref) - declarator = build_parse_node (ADDR_EXPR, declarator); - - fn = grokfield (declarator, declspecs, NULL_TREE, NULL_TREE, NULL_TREE); - } - - if (fn == void_type_node) - return fn; - - if (kind > 2) - SET_DECL_ARTIFICIAL (TREE_CHAIN (DECL_ARGUMENTS (fn))); - -#if 0 - if (processing_template_defn) - { - SET_DECL_IMPLICIT_INSTANTIATION (fn); - repo_template_used (fn); - } -#endif - -#if 0 - if (CLASSTYPE_INTERFACE_KNOWN (type)) - { - DECL_INTERFACE_KNOWN (fn) = 1; - DECL_NOT_REALLY_EXTERN (fn) = (!CLASSTYPE_INTERFACE_ONLY (type) - && flag_implement_inlines); - } - else -#endif - DECL_NOT_REALLY_EXTERN (fn) = 1; - - mark_inline_for_output (fn); - -#ifdef DEBUG_DEFAULT_FUNCTIONS - { char *fn_type = NULL; - tree t = name; - switch (kind) - { - case 0: fn_type = "default destructor"; break; - case 1: fn_type = "virtual destructor"; break; - case 2: fn_type = "default constructor"; break; - case 3: fn_type = "default X(const X&)"; break; - case 4: fn_type = "default X(X&)"; break; - } - if (fn_type) - { - if (TREE_CODE (name) == BIT_NOT_EXPR) - t = TREE_OPERAND (name, 0); - fprintf (stderr, "[[[[ %s for %s:\n%s]]]]\n", fn_type, - IDENTIFIER_POINTER (t), func_buf); - } - } -#endif /* DEBUG_DEFAULT_FUNCTIONS */ - - /* Show that this function was generated by the compiler. */ - SET_DECL_ARTIFICIAL (fn); - - return fn; -} - -/* Heuristic to tell whether the user is missing a semicolon - after a struct or enum declaration. Emit an error message - if we know the user has blown it. */ - -void -check_for_missing_semicolon (type) - tree type; -{ - if (yychar < 0) - yychar = yylex (); - - if ((yychar > 255 - && yychar != SCSPEC - && yychar != IDENTIFIER - && yychar != TYPENAME - && yychar != CV_QUALIFIER - && yychar != SELFNAME) - || end_of_file) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (type))) - error ("semicolon missing after %s declaration", - TREE_CODE (type) == ENUMERAL_TYPE ? "enum" : "struct"); - else - cp_error ("semicolon missing after declaration of `%T'", type); - shadow_tag (build_tree_list (0, type)); - } - /* Could probably also hack cases where class { ... } f (); appears. */ - clear_anon_tags (); -} - -void -note_got_semicolon (type) - tree type; -{ - if (TREE_CODE_CLASS (TREE_CODE (type)) != 't') - my_friendly_abort (60); - if (CLASS_TYPE_P (type)) - CLASSTYPE_GOT_SEMICOLON (type) = 1; -} - -void -note_list_got_semicolon (declspecs) - tree declspecs; -{ - tree link; - - for (link = declspecs; link; link = TREE_CHAIN (link)) - { - tree type = TREE_VALUE (link); - if (TREE_CODE_CLASS (TREE_CODE (type)) == 't') - note_got_semicolon (type); - } - clear_anon_tags (); -} - -/* If C is not whitespace, return C. - Otherwise skip whitespace and return first nonwhite char read. */ - -static int -skip_white_space (c) - register int c; -{ - for (;;) - { - switch (c) - { - case '\n': - c = check_newline (); - break; - - case ' ': - case '\t': - case '\f': - case '\r': - case '\v': - case '\b': - do - c = getch (); - while (c == ' ' || c == '\t'); - break; - - case '\\': - c = getch (); - if (c == '\n') - lineno++; - else - error ("stray '\\' in program"); - c = getch (); - break; - - default: - return (c); - } - } -} - - - -/* Make the token buffer longer, preserving the data in it. - P should point to just beyond the last valid character in the old buffer. - The value we return is a pointer to the new buffer - at a place corresponding to P. */ - -static char * -extend_token_buffer (p) - char *p; -{ - int offset = p - token_buffer; - - maxtoken = maxtoken * 2 + 10; - token_buffer = (char *) xrealloc (token_buffer, maxtoken + 2); - - return token_buffer + offset; -} - -static int -get_last_nonwhite_on_line () -{ - register int c; - - /* Is this the last nonwhite stuff on the line? */ - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - while (c == ' ' || c == '\t') - c = getch (); - return c; -} - -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - int c; - - if (nextchar != EOF) - { - c = nextchar; - nextchar = EOF; - } - else - c = getch (); - - return c; -} - -static void -pragma_ungetc (arg) - int arg; -{ - yyungetc (arg, 0); -} -#endif /* HANDLE_PRAGMA */ - -/* At the beginning of a line, increment the line number - and process any #-directive on this line. - If the line is a #-directive, read the entire line and return a newline. - Otherwise, return the line's first non-whitespace character. */ - -int linemode; - -static int handle_cp_pragma PROTO((char *)); - -static int -check_newline () -{ - register int c; - register int token; - int saw_line = 0; - - /* Read first nonwhite char on the line. Do this before incrementing the - line number, in case we're at the end of saved text. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - lineno++; - - if (c != '#') - { - /* If not #, return it so caller will use it. */ - return c; - } - - /* Don't read beyond this line. */ - linemode = 1; - - /* Read first nonwhite char after the `#'. */ - - do - c = getch (); - while (c == ' ' || c == '\t'); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma'. */ - - if (ISALPHA (c)) - { - if (c == 'p') - { - if (getch () == 'r' - && getch () == 'a' - && getch () == 'g' - && getch () == 'm' - && getch () == 'a') - { - token = real_yylex (); - if (token == IDENTIFIER - && TREE_CODE (yylval.ttype) == IDENTIFIER_NODE) - { - /* If this is 1, we handled it; if it's -1, it was one we - wanted but had something wrong with it. Only if it's - 0 was it not handled. */ - if (handle_cp_pragma (IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; - } - else if (token == END_OF_LINE) - goto skipline; - -#ifdef HANDLE_PRAGMA - /* We invoke HANDLE_PRAGMA before HANDLE_GENERIC_PRAGMAS - (if both are defined), in order to give the back - end a chance to override the interpretation of - SYSV style pragmas. */ - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, - IDENTIFIER_POINTER (yylval.ttype))) - goto skipline; -#endif /* HANDLE_PRAGMA */ - -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (token)) - goto skipline; -#endif /* HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); - } - - goto skipline; - } - else if (c == 'd') - { - if (getch () == 'e' - && getch () == 'f' - && getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t')) - { - debug_define (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - } - else if (c == 'u') - { - if (getch () == 'n' - && getch () == 'd' - && getch () == 'e' - && getch () == 'f' - && ((c = getch ()) == ' ' || c == '\t')) - { - debug_undef (lineno, GET_DIRECTIVE_LINE ()); - goto skipline; - } - } - else if (c == 'l') - { - if (getch () == 'i' - && getch () == 'n' - && getch () == 'e' - && ((c = getch ()) == ' ' || c == '\t')) - { - saw_line = 1; - goto linenum; - } - } - else if (c == 'i') - { - if (getch () == 'd' - && getch () == 'e' - && getch () == 'n' - && getch () == 't' - && ((c = getch ()) == ' ' || c == '\t')) - { - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - token = real_yylex (); - if (token == END_OF_LINE) - goto skipline; - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #ident"); - goto skipline; - } - - if (! flag_no_ident) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - TREE_STRING_POINTER (yylval.ttype)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - else if (c == 'n') - { - if (getch () == 'e' - && getch () == 'w' - && getch () == 'w' - && getch () == 'o' - && getch () == 'r' - && getch () == 'l' - && getch () == 'd' - && ((c = getch ()) == ' ' || c == '\t')) - { - /* Used to test incremental compilation. */ - sorry ("#pragma newworld"); - goto skipline; - } - } - error ("undefined or invalid # directive"); - goto skipline; - } - -linenum: - /* Here we have either `#line' or `# <nonletter>'. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = getch (); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == EOF) - goto skipline; - - /* Something follows the #; read a token. */ - - put_back (c); - token = real_yylex (); - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - int old_lineno = lineno; - enum { act_none, act_push, act_pop } action = act_none; - int entering_system_header = 0; - int entering_c_header = 0; - - /* subtract one, because it is the following line that - gets the specified number */ - - int l = TREE_INT_CST_LOW (yylval.ttype) - 1; - c = get_last_nonwhite_on_line (); - if (c == EOF) - { - /* No more: store the line number and check following line. */ - lineno = l; - goto skipline; - } - put_back (c); - - /* More follows: it must be a string constant (filename). */ - - if (saw_line) - { - /* Don't treat \ as special if we are processing #line 1 "...". - If you want it to be treated specially, use # 1 "...". */ - ignore_escape_flag = 1; - } - - /* Read the string constant. */ - token = real_yylex (); - - ignore_escape_flag = 0; - - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #line"); - goto skipline; - } - - /* Changing files again. This means currently collected time - is charged against header time, and body time starts back - at 0. */ - if (flag_detailed_statistics) - { - int this_time = my_get_run_time (); - tree time_identifier = get_time_identifier (TREE_STRING_POINTER (yylval.ttype)); - header_time += this_time - body_time; - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - this_filename_time = time_identifier; - body_time = this_time; - } - - input_filename - = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1); - strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype)); - lineno = l; - GNU_xref_file (input_filename); - - if (main_input_filename == 0) - { - struct impl_files *ifiles = impl_file_chain; - - if (ifiles) - { - while (ifiles->next) - ifiles = ifiles->next; - ifiles->filename = file_name_nondirectory (input_filename); - } - - main_input_filename = input_filename; - if (write_virtuals == 3) - walk_vtables (set_typedecl_interface_info, set_vardecl_interface_info); - } - - extract_interface_info (); - - c = get_last_nonwhite_on_line (); - if (c == EOF) - { - /* Update the name in the top element of input_file_stack. */ - if (input_file_stack) - input_file_stack->name = input_filename; - } - else - { - put_back (c); - - token = real_yylex (); - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST) - { - if (TREE_INT_CST_LOW (yylval.ttype) == 1) - action = act_push; - else if (TREE_INT_CST_LOW (yylval.ttype) == 2) - action = act_pop; - - if (action) - { - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - } - - /* `3' after file name means this is a system header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 3) - { - entering_system_header = 1; - - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - - /* `4' after file name means this is a C header file. */ - - if (token == CONSTANT - && TREE_CODE (yylval.ttype) == INTEGER_CST - && TREE_INT_CST_LOW (yylval.ttype) == 4) - { - entering_c_header = 1; - - c = get_last_nonwhite_on_line (); - if (c != EOF) - { - put_back (c); - token = real_yylex (); - } - } - - /* Do the actions implied by the preceding numbers. */ - - if (action == act_push) - { - /* Pushing to a new file. */ - struct file_stack *p; - - p = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; - debug_start_source_file (input_filename); - in_system_header = entering_system_header; - if (c_header_level) - ++c_header_level; - else if (entering_c_header) - { - c_header_level = 1; - ++pending_lang_change; - } - } - else if (action == act_pop) - { - /* Popping out of a file. */ - if (input_file_stack->next) - { - struct file_stack *p; - - if (c_header_level && --c_header_level == 0) - { - if (entering_c_header) - warning ("badly nested C headers from preprocessor"); - --pending_lang_change; - } - in_system_header = entering_system_header; - - p = input_file_stack; - input_file_stack = p->next; - free (p); - input_file_stack_tick++; - debug_end_source_file (input_file_stack->line); - } - else - error ("#-lines for entering and leaving files don't match"); - } - else - in_system_header = entering_system_header; - } - - /* If NEXTCHAR is not end of line, we don't care what it is. */ - if (nextchar == EOF) - c = EOF; - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - linemode = 0; - end_of_file = 0; - nextchar = -1; - while ((c = getch ()) != EOF && c != '\n'); - return c; -} - -void -do_pending_lang_change () -{ - for (; pending_lang_change > 0; --pending_lang_change) - push_lang_context (lang_name_c); - for (; pending_lang_change < 0; ++pending_lang_change) - pop_lang_context (); -} - -#define ENDFILE -1 /* token that represents end-of-file */ - -/* Read an escape sequence, returning its equivalent as a character, - or store 1 in *ignore_ptr if it is backslash-newline. */ - -static int -readescape (ignore_ptr) - int *ignore_ptr; -{ - register int c = getch (); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - switch (c) - { - case 'x': - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getch (); - if (! ISXDIGIT (c)) - { - put_back (c); - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && (((unsigned)1 << - (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getch (); - } - put_back (c); - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - lineno++; - *ignore_ptr = 1; - return 0; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - return TARGET_BELL; - - case 'v': - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("unknown escape sequence `\\%c'", c); - return c; - } - if (ISGRAPH (c)) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -int looking_for_typename; - -#ifdef __GNUC__ -__inline -#endif -int -identifier_type (decl) - tree decl; -{ - tree t; - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL) - return PTYPENAME; - else if (looking_for_template) - return PFUNCNAME; - } - if (looking_for_template && really_overloaded_fn (decl)) - { - /* See through a baselink. */ - if (TREE_CODE (decl) == TREE_LIST) - decl = TREE_VALUE (decl); - - for (t = decl; t != NULL_TREE; t = OVL_CHAIN (t)) - if (DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (t))) - return PFUNCNAME; - } - if (TREE_CODE (decl) == NAMESPACE_DECL) - return NSNAME; - if (TREE_CODE (decl) != TYPE_DECL) - return IDENTIFIER; - if (DECL_ARTIFICIAL (decl) && TREE_TYPE (decl) == current_class_type) - return SELFNAME; - - /* A constructor declarator for a template type will get here as an - implicit typename, a TYPENAME_TYPE with a type. */ - t = got_scope; - if (t && TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - decl = TREE_TYPE (decl); - if (TREE_CODE (decl) == TYPENAME_TYPE) - decl = TREE_TYPE (decl); - if (t && t == decl) - return SELFNAME; - - return TYPENAME; -} - -void -see_typename () -{ - /* Only types expected, not even namespaces. */ - looking_for_typename = 2; - if (yychar < 0) - if ((yychar = yylex ()) < 0) yychar = 0; - looking_for_typename = 0; - if (yychar == IDENTIFIER) - { - lastiddecl = lookup_name (yylval.ttype, -2); - if (lastiddecl == 0) - { - if (flag_labels_ok) - lastiddecl = IDENTIFIER_LABEL_VALUE (yylval.ttype); - } - else - yychar = identifier_type (lastiddecl); - } -} - -/* Return true if d is in a global scope. */ - -static int -is_global (d) - tree d; -{ - while (1) - switch (TREE_CODE (d)) - { - case ERROR_MARK: - return 1; - - case OVERLOAD: d = OVL_FUNCTION (d); continue; - case TREE_LIST: d = TREE_VALUE (d); continue; - default: - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (d)) == 'd', 980629); - d = CP_DECL_CONTEXT (d); - return TREE_CODE (d) == NAMESPACE_DECL; - } -} - -tree -do_identifier (token, parsing, args) - register tree token; - int parsing; - tree args; -{ - register tree id; - int lexing = (parsing == 1); - int in_call = (parsing == 2); - - if (! lexing || IDENTIFIER_OPNAME_P (token)) - id = lookup_name (token, 0); - else - id = lastiddecl; - - /* Scope class declarations before global - declarations. */ - if ((!id || is_global (id)) - && current_class_type != 0 - && TYPE_SIZE (current_class_type) == 0) - { - /* Could be from one of the base classes. */ - tree field = lookup_field (current_class_type, token, 1, 0); - if (field == 0) - ; - else if (field == error_mark_node) - /* We have already generated the error message. - But we still want to return this value. */ - id = lookup_field (current_class_type, token, 0, 0); - else if (TREE_CODE (field) == VAR_DECL - || TREE_CODE (field) == CONST_DECL - || TREE_CODE (field) == TEMPLATE_DECL) - id = field; - else if (TREE_CODE (field) != FIELD_DECL) - my_friendly_abort (61); - else - { - cp_error ("invalid use of member `%D'", field); - id = error_mark_node; - return id; - } - } - - /* Do Koenig lookup if appropriate (inside templates we build lookup - expressions instead). */ - if (args && !current_template_parms && (!id || is_global (id))) - /* If we have arguments and we only found global names, do Koenig - lookup. */ - id = lookup_arg_dependent (token, id, args); - - /* Remember that this name has been used in the class definition, as per - [class.scope0] */ - if (id && current_class_type && parsing - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE (token) - /* Avoid breaking if we get called for a default argument that - refers to an overloaded method. Eventually this will not be - necessary, since default arguments shouldn't be parsed until - after the class is complete. (jason 3/12/97) */ - && TREE_CODE (id) != OVERLOAD) - pushdecl_class_level (id); - - if (!id || id == error_mark_node) - { - if (id == error_mark_node && current_class_type != NULL_TREE) - { - id = lookup_nested_field (token, 1); - /* In lookup_nested_field(), we marked this so we can gracefully - leave this whole mess. */ - if (id && id != error_mark_node && TREE_TYPE (id) == error_mark_node) - return id; - } - - if (current_template_parms) - return build_min_nt (LOOKUP_EXPR, token); - else if (IDENTIFIER_OPNAME_P (token)) - { - if (token != ansi_opname[ERROR_MARK]) - cp_error ("`%D' not defined", token); - id = error_mark_node; - } - else if (in_call && ! flag_strict_prototype) - { - id = implicitly_declare (token); - } - else if (current_function_decl == 0) - { - cp_error ("`%D' was not declared in this scope", token); - id = error_mark_node; - } - else - { - if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node - || IDENTIFIER_ERROR_LOCUS (token) != current_function_decl) - { - static int undeclared_variable_notice; - - cp_error ("`%D' undeclared (first use this function)", token); - - if (! undeclared_variable_notice) - { - error ("(Each undeclared identifier is reported only once"); - error ("for each function it appears in.)"); - undeclared_variable_notice = 1; - } - } - id = error_mark_node; - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); - SET_IDENTIFIER_ERROR_LOCUS (token, current_function_decl); - } - } - - if (TREE_CODE (id) == VAR_DECL && DECL_DEAD_FOR_LOCAL (id)) - { - tree shadowed = DECL_SHADOWED_FOR_VAR (id); - while (shadowed != NULL_TREE && TREE_CODE (shadowed) == VAR_DECL - && DECL_DEAD_FOR_LOCAL (shadowed)) - shadowed = DECL_SHADOWED_FOR_VAR (shadowed); - if (!shadowed) - shadowed = IDENTIFIER_NAMESPACE_VALUE (DECL_NAME (id)); - if (shadowed) - { - if (!DECL_ERROR_REPORTED (id)) - { - warning ("name lookup of `%s' changed", - IDENTIFIER_POINTER (token)); - cp_warning_at (" matches this `%D' under current ANSI rules", - shadowed); - cp_warning_at (" matches this `%D' under old rules", id); - DECL_ERROR_REPORTED (id) = 1; - } - id = shadowed; - } - else if (!DECL_ERROR_REPORTED (id)) - { - static char msg[] - = "name lookup of `%s' changed for new ANSI `for' scoping"; - DECL_ERROR_REPORTED (id) = 1; - if (TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (id))) - { - error (msg, IDENTIFIER_POINTER (token)); - cp_error_at (" cannot use obsolete binding at `%D' because it has a destructor", id); - id = error_mark_node; - } - else - { - pedwarn (msg, IDENTIFIER_POINTER (token)); - cp_pedwarn_at (" using obsolete binding at `%D'", id); - } - } - } - /* TREE_USED is set in `hack_identifier'. */ - if (TREE_CODE (id) == CONST_DECL) - { - if (IDENTIFIER_CLASS_VALUE (token) == id) - { - /* Check access. */ - tree access = compute_access (TYPE_BINFO (current_class_type), id); - if (access == access_private_node) - cp_error ("enum `%D' is private", id); - /* protected is OK, since it's an enum of `this'. */ - } - if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id)) - id = DECL_INITIAL (id); - } - else - id = hack_identifier (id, token); - - /* We must look up dependent names when the template is - instantiated, not while parsing it. For now, we don't - distinguish between dependent and independent names. So, for - example, we look up all overloaded functions at - instantiation-time, even though in some cases we should just use - the DECL we have here. We also use LOOKUP_EXPRs to find things - like local variables, rather than creating TEMPLATE_DECLs for the - local variables and then finding matching instantiations. */ - if (current_template_parms - && (is_overloaded_fn (id) - /* If it's not going to be around at instantiation time, we - look it up then. This is a hack, and should go when we - really get dependent/independent name lookup right. */ - || !TREE_PERMANENT (id) - /* Some local VAR_DECLs (such as those for local variables - in member functions of local classes) are built on the - permanent obstack. */ - || (TREE_CODE (id) == VAR_DECL - && CP_DECL_CONTEXT (id) - && TREE_CODE (CP_DECL_CONTEXT (id)) == FUNCTION_DECL) - || TREE_CODE (id) == PARM_DECL - || TREE_CODE (id) == RESULT_DECL - || TREE_CODE (id) == USING_DECL)) - id = build_min_nt (LOOKUP_EXPR, token); - - return id; -} - -tree -do_scoped_id (token, parsing) - tree token; - int parsing; -{ - tree id; - /* during parsing, this is ::name. Otherwise, it is black magic. */ - if (parsing) - { - struct tree_binding _b; - id = binding_init (&_b); - if (!qualified_lookup_using_namespace (token, global_namespace, id, 0)) - id = NULL_TREE; - else - id = BINDING_VALUE (id); - } - else - id = IDENTIFIER_GLOBAL_VALUE (token); - if (parsing && yychar == YYEMPTY) - yychar = yylex (); - if (! id) - { - if (processing_template_decl) - { - id = build_min_nt (LOOKUP_EXPR, token); - LOOKUP_EXPR_GLOBAL (id) = 1; - return id; - } - if (parsing && (yychar == '(' || yychar == LEFT_RIGHT) - && ! flag_strict_prototype) - id = implicitly_declare (token); - else - { - if (IDENTIFIER_NAMESPACE_VALUE (token) != error_mark_node) - cp_error ("`::%D' undeclared (first use here)", token); - id = error_mark_node; - /* Prevent repeated error messages. */ - SET_IDENTIFIER_NAMESPACE_VALUE (token, error_mark_node); - } - } - else - { - if (TREE_CODE (id) == ADDR_EXPR) - mark_used (TREE_OPERAND (id, 0)); - else if (TREE_CODE (id) != OVERLOAD) - mark_used (id); - } - if (TREE_CODE (id) == CONST_DECL && ! processing_template_decl) - { - /* XXX CHS - should we set TREE_USED of the constant? */ - id = DECL_INITIAL (id); - /* This is to prevent an enum whose value is 0 - from being considered a null pointer constant. */ - id = build1 (NOP_EXPR, TREE_TYPE (id), id); - TREE_CONSTANT (id) = 1; - } - - if (processing_template_decl) - { - if (is_overloaded_fn (id)) - { - id = build_min_nt (LOOKUP_EXPR, token); - LOOKUP_EXPR_GLOBAL (id) = 1; - return id; - } - /* else just use the decl */ - } - return convert_from_reference (id); -} - -tree -identifier_typedecl_value (node) - tree node; -{ - tree t, type; - type = IDENTIFIER_TYPE_VALUE (node); - if (type == NULL_TREE) - return NULL_TREE; - - if (IDENTIFIER_BINDING (node)) - { - t = IDENTIFIER_VALUE (node); - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) - return t; - } - if (IDENTIFIER_NAMESPACE_VALUE (node)) - { - t = IDENTIFIER_NAMESPACE_VALUE (node); - if (t && TREE_CODE (t) == TYPE_DECL && TREE_TYPE (t) == type) - return t; - } - - /* Will this one ever happen? */ - if (TYPE_MAIN_DECL (type)) - return TYPE_MAIN_DECL (type); - - /* We used to do an internal error of 62 here, but instead we will - handle the return of a null appropriately in the callers. */ - return NULL_TREE; -} - -/* CYGNUS LOCAL Embedded C++ */ -#ifdef __GNUC__ -__inline -#endif -void -embedded_pedwarn (s) - char *s; -{ - pedwarn ("Embedded C++ prohibits use of %s", s); -} -/* END CYGNUS LOCAL Embedded C++ */ - -int -real_yylex () -{ - register int c; - register int value; - int wide_flag = 0; - int dollar_seen = 0; - int i; - - if (nextchar >= 0) - c = nextchar, nextchar = -1; - else - c = getch (); - - /* Effectively do c = skip_white_space (c) - but do it faster in the usual cases. */ - while (1) - switch (c) - { - case ' ': - case '\t': - case '\f': - case '\v': - case '\b': - c = getch (); - break; - - case '\r': - /* Call skip_white_space so we can warn if appropriate. */ - - case '\n': - case '/': - case '\\': - c = skip_white_space (c); - default: - goto found_nonwhite; - } - found_nonwhite: - - token_buffer[0] = c; - token_buffer[1] = 0; - -/* yylloc.first_line = lineno; */ - - switch (c) - { - case EOF: - token_buffer[0] = '\0'; - end_of_file = 1; - if (input_redirected ()) - value = END_OF_SAVED_INPUT; - else if (linemode) - value = END_OF_LINE; - else - value = ENDFILE; - break; - - case '$': - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - dollar_seen = 1; - goto letter; - - case 'L': - /* Capital L may start a wide-string or wide-character constant. */ - { - register int c = getch (); - if (c == '\'') - { - wide_flag = 1; - goto char_constant; - } - if (c == '"') - { - wide_flag = 1; - goto string_constant; - } - put_back (c); - } - - case 'A': case 'B': case 'C': case 'D': case 'E': - case 'F': case 'G': case 'H': case 'I': case 'J': - case 'K': 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': - case '_': - letter: - { - register char *p; - - p = token_buffer; - if (input == 0) - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. - We may have to read the value in `putback_char', so call - `getch' once. */ - *p++ = c; - c = getch (); - - /* Make this run fast. We know that we are reading straight - from FINPUT in this case (since identifiers cannot straddle - input sources. */ - while (ISALNUM (c) || (c == '_') || c == '$') - { - if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getch (); - } - - if (linemode && c == '\n') - { - put_back (c); - c = EOF; - } - } - else - { - /* We know that `token_buffer' can hold at least on char, - so we install C immediately. */ - *p++ = c; - c = getch (); - - while (ISALNUM (c) || (c == '_') || c == '$') - { - if (c == '$') - { - if (! dollars_in_ident) - error ("`$' in identifier"); - else if (pedantic) - pedwarn ("`$' in identifier"); - } - - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - - *p++ = c; - c = getch (); - } - } - - *p = 0; - nextchar = c; - - value = IDENTIFIER; - yylval.itype = 0; - - /* Try to recognize a keyword. Uses minimum-perfect hash function */ - - { - register struct resword *ptr; - - if ((ptr = is_reserved_word (token_buffer, p - token_buffer))) - { - if (ptr->rid) - { - tree old_ttype = ridpointers[(int) ptr->rid]; - - /* If this provides a type for us, then revert lexical - state to standard state. */ - if (TREE_CODE (old_ttype) == IDENTIFIER_NODE - && IDENTIFIER_GLOBAL_VALUE (old_ttype) != 0 - && TREE_CODE (IDENTIFIER_GLOBAL_VALUE (old_ttype)) == TYPE_DECL) - looking_for_typename = 0; - else if (ptr->token == AGGR || ptr->token == ENUM) - looking_for_typename = 2; - - /* Check if this is a language-type declaration. - Just glimpse the next non-white character. */ - nextchar = skip_white_space (nextchar); - if (nextchar == '"') - { - /* We are looking at a string. Complain - if the token before the string is no `extern'. - - Could cheat some memory by placing this string - on the temporary_, instead of the saveable_ - obstack. */ - - if (ptr->rid != RID_EXTERN) - error ("invalid modifier `%s' for language string", - ptr->name); - real_yylex (); - value = EXTERN_LANG_STRING; - yylval.ttype = get_identifier (TREE_STRING_POINTER (yylval.ttype)); - break; - } - if (ptr->token == VISSPEC) - { - switch (ptr->rid) - { - case RID_PUBLIC: - yylval.ttype = access_public_node; - break; - case RID_PRIVATE: - yylval.ttype = access_private_node; - break; - case RID_PROTECTED: - yylval.ttype = access_protected_node; - break; - default: - my_friendly_abort (63); - } - } - else - yylval.ttype = old_ttype; - } - else if (ptr->token == EQCOMPARE) - { - yylval.code = NE_EXPR; - token_buffer[0] = '!'; - token_buffer[1] = '='; - token_buffer[2] = 0; - } - else if (ptr->token == ASSIGN) - { - if (strcmp ("and_eq", token_buffer) == 0) - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - } - else if (strcmp ("or_eq", token_buffer) == 0) - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - } - else if (strcmp ("xor_eq", token_buffer) == 0) - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - } - token_buffer[1] = '='; - token_buffer[2] = 0; - } - else if (ptr->token == '&') - { - yylval.code = BIT_AND_EXPR; - token_buffer[0] = '&'; - token_buffer[1] = 0; - } - else if (ptr->token == '|') - { - yylval.code = BIT_IOR_EXPR; - token_buffer[0] = '|'; - token_buffer[1] = 0; - } - else if (ptr->token == '^') - { - yylval.code = BIT_XOR_EXPR; - token_buffer[0] = '^'; - token_buffer[1] = 0; - } - - value = (int) ptr->token; - } - } - - /* If we did not find a keyword, look for an identifier - (or a typename). */ - - if (value == IDENTIFIER || value == TYPESPEC) - GNU_xref_ref (current_function_decl, token_buffer); - - if (value == IDENTIFIER) - { - register tree tmp = get_identifier (token_buffer); - -#if !defined(VMS) && defined(JOINER) - /* Make sure that user does not collide with our internal - naming scheme. */ - if (JOINER == '$' - && dollar_seen - && (THIS_NAME_P (tmp) - || VPTR_NAME_P (tmp) - || DESTRUCTOR_NAME_P (tmp) - || VTABLE_NAME_P (tmp) - || TEMP_NAME_P (tmp) - || ANON_AGGRNAME_P (tmp) - || ANON_PARMNAME_P (tmp))) - warning ("identifier name `%s' conflicts with GNU C++ internal naming strategy", - token_buffer); -#endif - - yylval.ttype = tmp; - } - if (value == NEW && ! global_bindings_p ()) - { - value = NEW; - goto done; - } - } - -/* CYGNUS LOCAL Embedded C++ */ - if (flag_embedded_cxx) - { - if (value == USING || value == NAMESPACE) - { - if (! embedded_namespace_error) - { - embedded_namespace_error = 1; - embedded_pedwarn ("namespaces"); - } - else - pedwarn ("further uses of namespaces with Embedded C++ enabled"); - } - else if (value == TEMPLATE || value == TYPENAME) - { - if (! embedded_namespace_error) - { - embedded_namespace_error = 1; - embedded_pedwarn ("templates"); - } - else - pedwarn ("further uses of templates with Embedded C++ enabled"); - } - else if (value == CATCH || value == THROW || value == TRY) - { - if (! embedded_eh_error) - { - embedded_eh_error = 1; - embedded_pedwarn ("exception handling"); - } - else - pedwarn ("further uses of exception handling with Embedded C++ enabled"); - } - else if (value == DYNAMIC_CAST) - embedded_pedwarn ("dynamic_cast"); - else if (value == STATIC_CAST) - embedded_pedwarn ("static_cast"); - else if (value == REINTERPRET_CAST) - embedded_pedwarn ("reinterpret_cast"); - else if (value == CONST_CAST) - embedded_pedwarn ("const_cast"); - else if (value == TYPEID) - embedded_pedwarn ("typeid"); - } -/* END CYGNUS LOCAL Embedded C++ */ - - break; - - case '.': - { - register int c1 = getch (); - token_buffer[0] = c; - token_buffer[1] = c1; - if (c1 == '*') - { - value = DOT_STAR; - token_buffer[2] = 0; - goto done; - } - if (c1 == '.') - { - c1 = getch (); - if (c1 == '.') - { - token_buffer[2] = c1; - token_buffer[3] = 0; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - if (ISDIGIT (c1)) - { - put_back (c1); - goto resume_numerical_scan; - } - nextchar = c1; - value = '.'; - token_buffer[1] = 0; - goto done; - } - case '0': case '1': - /* Optimize for most frequent case. */ - { - register int c1 = getch (); - if (! ISALNUM (c1) && c1 != '.') - { - /* Terminate string. */ - token_buffer[0] = c; - token_buffer[1] = 0; - if (c == '0') - yylval.ttype = integer_zero_node; - else - yylval.ttype = integer_one_node; - nextchar = c1; - value = CONSTANT; - goto done; - } - put_back (c1); - } - /* fall through... */ - case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - resume_numerical_scan: - { - register char *p; - int base = 10; - int count = 0; - int largest_digit = 0; - int numdigits = 0; - /* for multi-precision arithmetic, - we actually store only HOST_BITS_PER_CHAR bits in each part. - The number of parts is chosen so as to be sufficient to hold - the enough bits to fit into the two HOST_WIDE_INTs that contain - the integer value (this is always at least as many bits as are - in a target `long long' value, but may be wider). */ -#define TOTAL_PARTS ((HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR) * 2 + 2) - int parts[TOTAL_PARTS]; - int overflow = 0; - - enum anon1 { NOT_FLOAT, AFTER_POINT, TOO_MANY_POINTS} floatflag - = NOT_FLOAT; - - for (count = 0; count < TOTAL_PARTS; count++) - parts[count] = 0; - - p = token_buffer; - *p++ = c; - - if (c == '0') - { - *p++ = (c = getch ()); - if ((c == 'x') || (c == 'X')) - { - base = 16; - *p++ = (c = getch ()); - } - /* Leading 0 forces octal unless the 0 is the only digit. */ - else if (c >= '0' && c <= '9') - { - base = 8; - numdigits++; - } - else - numdigits++; - } - - /* Read all the digits-and-decimal-points. */ - - while (c == '.' - || (ISALNUM (c) && (c != 'l') && (c != 'L') - && (c != 'u') && (c != 'U') - && c != 'i' && c != 'I' && c != 'j' && c != 'J' - && (floatflag == NOT_FLOAT || ((c != 'f') && (c != 'F'))))) - { - if (c == '.') - { - if (base == 16) - error ("floating constant may not be in radix 16"); - if (floatflag == TOO_MANY_POINTS) - /* We have already emitted an error. Don't need another. */ - ; - else if (floatflag == AFTER_POINT) - { - error ("malformed floating constant"); - floatflag = TOO_MANY_POINTS; - /* Avoid another error from atof by forcing all characters - from here on to be ignored. */ - p[-1] = '\0'; - } - else - floatflag = AFTER_POINT; - - base = 10; - *p++ = c = getch (); - /* Accept '.' as the start of a floating-point number - only when it is followed by a digit. - Otherwise, unread the following non-digit - and use the '.' as a structural token. */ - if (p == token_buffer + 2 && !ISDIGIT (c)) - { - if (c == '.') - { - c = getch (); - if (c == '.') - { - *p++ = '.'; - *p = '\0'; - value = ELLIPSIS; - goto done; - } - error ("parse error at `..'"); - } - nextchar = c; - token_buffer[1] = '\0'; - value = '.'; - goto done; - } - } - else - { - /* It is not a decimal point. - It should be a digit (perhaps a hex digit). */ - - if (ISDIGIT (c)) - { - c = c - '0'; - } - else if (base <= 10) - { - if (c == 'e' || c == 'E') - { - base = 10; - floatflag = AFTER_POINT; - break; /* start of exponent */ - } - error ("nondigits in number and not hexadecimal"); - c = 0; - } - else if (c >= 'a') - { - c = c - 'a' + 10; - } - else - { - c = c - 'A' + 10; - } - if (c >= largest_digit) - largest_digit = c; - numdigits++; - - for (count = 0; count < TOTAL_PARTS; count++) - { - parts[count] *= base; - if (count) - { - parts[count] - += (parts[count-1] >> HOST_BITS_PER_CHAR); - parts[count-1] - &= (1 << HOST_BITS_PER_CHAR) - 1; - } - else - parts[0] += c; - } - - /* If the extra highest-order part ever gets anything in it, - the number is certainly too big. */ - if (parts[TOTAL_PARTS - 1] != 0) - overflow = 1; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = (c = getch ()); - } - } - - if (numdigits == 0) - error ("numeric constant with no digits"); - - if (largest_digit >= base) - error ("numeric constant contains digits beyond the radix"); - - /* Remove terminating char from the token buffer and delimit the string */ - *--p = 0; - - if (floatflag != NOT_FLOAT) - { - tree type = double_type_node; - int exceeds_double = 0; - int imag = 0; - REAL_VALUE_TYPE value; - jmp_buf handler; - - /* Read explicit exponent if any, and put it in tokenbuf. */ - - if ((c == 'e') || (c == 'E')) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - if ((c == '+') || (c == '-')) - { - *p++ = c; - c = getch (); - } - if (! ISDIGIT (c)) - error ("floating constant exponent has no digits"); - while (ISDIGIT (c)) - { - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - } - - *p = 0; - errno = 0; - - /* Convert string to a double, checking for overflow. */ - if (setjmp (handler)) - { - error ("floating constant out of range"); - value = dconst0; - } - else - { - int fflag = 0, lflag = 0; - /* Copy token_buffer now, while it has just the number - and not the suffixes; once we add `f' or `i', - REAL_VALUE_ATOF may not work any more. */ - char *copy = (char *) alloca (p - token_buffer + 1); - bcopy (token_buffer, copy, p - token_buffer + 1); - - set_float_handler (handler); - - while (1) - { - int lose = 0; - - /* Read the suffixes to choose a data type. */ - switch (c) - { - case 'f': case 'F': - if (fflag) - error ("more than one `f' in numeric constant"); - fflag = 1; - break; - - case 'l': case 'L': - if (lflag) - error ("more than one `l' in numeric constant"); - lflag = 1; - break; - - case 'i': case 'I': - if (imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids imaginary numeric constants"); - imag = 1; - break; - - default: - lose = 1; - } - - if (lose) - break; - - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - *p = 0; - c = getch (); - } - - /* The second argument, machine_mode, of REAL_VALUE_ATOF - tells the desired precision of the binary result - of decimal-to-binary conversion. */ - - if (fflag) - { - if (lflag) - error ("both `f' and `l' in floating constant"); - - type = float_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - /* A diagnostic is required here by some ANSI C testsuites. - This is not pedwarn, become some people don't want - an error for this. */ - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `float'"); - } - else if (lflag) - { - type = long_double_type_node; - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `long double'"); - } - else - { - value = REAL_VALUE_ATOF (copy, TYPE_MODE (type)); - if (REAL_VALUE_ISINF (value) && pedantic) - warning ("floating point number exceeds range of `double'"); - } - - set_float_handler (NULL_PTR); - } -#ifdef ERANGE - if (errno == ERANGE && pedantic) - { - /* ERANGE is also reported for underflow, - so test the value to distinguish overflow from that. */ - if (REAL_VALUES_LESS (dconst1, value) - || REAL_VALUES_LESS (value, dconstm1)) - { - pedwarn ("floating point number exceeds range of `%s'", - IDENTIFIER_POINTER (TYPE_IDENTIFIER (type))); - exceeds_double = 1; - } - } -#endif - - /* If the result is not a number, assume it must have been - due to some error message above, so silently convert - it to a zero. */ - if (REAL_VALUE_ISNAN (value)) - value = dconst0; - - /* Create a node with determined type and value. */ - if (imag) - yylval.ttype = build_complex (NULL_TREE, - cp_convert (type, integer_zero_node), - build_real (type, value)); - else - yylval.ttype = build_real (type, value); - } - else - { - tree type; - HOST_WIDE_INT high, low; - int spec_unsigned = 0; - int spec_long = 0; - int spec_long_long = 0; - int spec_imag = 0; - int bytes, warn; - - while (1) - { - if (c == 'u' || c == 'U') - { - if (spec_unsigned) - error ("two `u's in integer constant"); - spec_unsigned = 1; - } - else if (c == 'l' || c == 'L') - { - if (spec_long) - { - if (spec_long_long) - error ("three `l's in integer constant"); - else if (pedantic && ! in_system_header && warn_long_long) - pedwarn ("ANSI C++ forbids long long integer constants"); - spec_long_long = 1; - } - spec_long = 1; - } - else if (c == 'i' || c == 'j' || c == 'I' || c == 'J') - { - if (spec_imag) - error ("more than one `i' or `j' in numeric constant"); - else if (pedantic) - pedwarn ("ANSI C++ forbids imaginary numeric constants"); - spec_imag = 1; - } - else - break; - if (p >= token_buffer + maxtoken - 3) - p = extend_token_buffer (p); - *p++ = c; - c = getch (); - } - - /* If the constant is not long long and it won't fit in an - unsigned long, or if the constant is long long and won't fit - in an unsigned long long, then warn that the constant is out - of range. */ - - /* ??? This assumes that long long and long integer types are - a multiple of 8 bits. This better than the original code - though which assumed that long was exactly 32 bits and long - long was exactly 64 bits. */ - - if (spec_long_long) - bytes = TYPE_PRECISION (long_long_integer_type_node) / 8; - else - bytes = TYPE_PRECISION (long_integer_type_node) / 8; - - warn = overflow; - for (i = bytes; i < TOTAL_PARTS; i++) - if (parts[i]) - warn = 1; - if (warn) - pedwarn ("integer constant out of range"); - - /* This is simplified by the fact that our constant - is always positive. */ - high = low = 0; - - for (i = 0; i < HOST_BITS_PER_WIDE_INT / HOST_BITS_PER_CHAR; i++) - { - high |= ((HOST_WIDE_INT) parts[i + (HOST_BITS_PER_WIDE_INT - / HOST_BITS_PER_CHAR)] - << (i * HOST_BITS_PER_CHAR)); - low |= (HOST_WIDE_INT) parts[i] << (i * HOST_BITS_PER_CHAR); - } - - - yylval.ttype = build_int_2 (low, high); - TREE_TYPE (yylval.ttype) = long_long_unsigned_type_node; - - /* Calculate the ANSI type. */ - if (!spec_long && !spec_unsigned - && int_fits_type_p (yylval.ttype, integer_type_node)) - type = integer_type_node; - else if (!spec_long && (base != 10 || spec_unsigned) - && int_fits_type_p (yylval.ttype, unsigned_type_node)) - /* Nondecimal constants try unsigned even in traditional C. */ - type = unsigned_type_node; - else if (!spec_unsigned && !spec_long_long - && int_fits_type_p (yylval.ttype, long_integer_type_node)) - type = long_integer_type_node; - else if (! spec_long_long) - type = long_unsigned_type_node; - else if (! spec_unsigned - /* Verify value does not overflow into sign bit. */ - && TREE_INT_CST_HIGH (yylval.ttype) >= 0 - && int_fits_type_p (yylval.ttype, - long_long_integer_type_node)) - type = long_long_integer_type_node; - else - type = long_long_unsigned_type_node; - - if (!int_fits_type_p (yylval.ttype, type) && !warn) - pedwarn ("integer constant out of range"); - - if (base == 10 && ! spec_unsigned && TREE_UNSIGNED (type)) - warning ("decimal integer constant is so large that it is unsigned"); - - if (spec_imag) - { - if (TYPE_PRECISION (type) - <= TYPE_PRECISION (integer_type_node)) - yylval.ttype - = build_complex (NULL_TREE, integer_zero_node, - cp_convert (integer_type_node, - yylval.ttype)); - else - error ("complex integer constant is too wide for `__complex int'"); - } - else - TREE_TYPE (yylval.ttype) = type; - } - - put_back (c); - *p = 0; - - value = CONSTANT; break; - } - - case '\'': - char_constant: - { - register int result = 0; - register int num_chars = 0; - int chars_seen = 0; - unsigned width = TYPE_PRECISION (char_type_node); - int max_chars; -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - max_chars = TYPE_PRECISION (integer_type_node) / width; - if (wide_flag) - width = WCHAR_TYPE_SIZE; - - while (1) - { - tryagain: - c = getch (); - - if (c == '\'' || c == EOF) - break; - - ++chars_seen; - if (c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto tryagain; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - pedwarn ("escape sequence out of range for character"); -#ifdef MAP_CHARACTER - if (ISPRINT (c)) - c = MAP_CHARACTER (c); -#endif - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C forbids newline in character constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 1; i <= longest_char; ++i) - { - if (i > maxtoken - 4) - extend_token_buffer (token_buffer); - - token_buffer[i] = c; - char_len = local_mbtowc (& wc, - token_buffer + 1, - i); - if (char_len != -1) - break; - c = getch (); - } - if (char_len > 1) - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len < i) - put_back (c); - 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 << width) - 1)); - else - result = token_buffer[i]; - } - num_chars += char_len; - goto tryagain; - } - c = wc; - } - else - { - if (char_len == -1) - warning ("Ignoring invalid multibyte character"); - if (wide_flag) - c = wc; -#ifdef MAP_CHARACTER - else - c = MAP_CHARACTER (c); -#endif - } -#else /* ! MULTIBYTE_CHARS */ -#ifdef MAP_CHARACTER - c = MAP_CHARACTER (c); -#endif -#endif /* ! MULTIBYTE_CHARS */ - } - - if (wide_flag) - { - if (chars_seen == 1) /* only keep the first one */ - result = c; - goto tryagain; - } - - /* Merge character into result; ignore excess chars. */ - num_chars++; - if (num_chars < max_chars + 1) - { - 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 && warn_multichar) - 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.ttype = build_int_2 (0, 0); - else if (TREE_UNSIGNED (char_type_node) - || ((result >> (num_bits - 1)) & 1) == 0) - yylval.ttype - = build_int_2 (result & (~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - 0); - else - yylval.ttype - = build_int_2 (result | ~(~(unsigned HOST_WIDE_INT) 0 - >> (HOST_BITS_PER_WIDE_INT - num_bits)), - -1); - if (chars_seen <= 1) - TREE_TYPE (yylval.ttype) = char_type_node; - else - TREE_TYPE (yylval.ttype) = integer_type_node; - } - else - { - yylval.ttype = build_int_2 (result, 0); - TREE_TYPE (yylval.ttype) = wchar_type_node; - } - - value = CONSTANT; - break; - } - - case '"': - string_constant: - { - register char *p; - unsigned width = wide_flag ? WCHAR_TYPE_SIZE - : TYPE_PRECISION (char_type_node); -#ifdef MULTIBYTE_CHARS - int longest_char = local_mb_cur_max (); - (void) local_mbtowc (NULL_PTR, NULL_PTR, 0); -#endif - - c = getch (); - p = token_buffer + 1; - - while (c != '"' && c >= 0) - { - /* ignore_escape_flag is set for reading the filename in #line. */ - if (!ignore_escape_flag && c == '\\') - { - int ignore = 0; - c = readescape (&ignore); - if (ignore) - goto skipnewline; - if (width < HOST_BITS_PER_INT - && (unsigned) c >= ((unsigned)1 << width)) - warning ("escape sequence out of range for character"); - } - else if (c == '\n') - { - if (pedantic) - pedwarn ("ANSI C++ forbids newline in string constant"); - lineno++; - } - else - { -#ifdef MULTIBYTE_CHARS - wchar_t wc; - int i; - int char_len = -1; - for (i = 0; i < longest_char; ++i) - { - if (p + i >= token_buffer + maxtoken) - p = extend_token_buffer (p); - p[i] = c; - - char_len = local_mbtowc (& wc, p, i + 1); - if (char_len != -1) - break; - c = getch (); - } - if (char_len == -1) - warning ("Ignoring invalid multibyte character"); - else - { - /* mbtowc sometimes needs an extra char before accepting */ - if (char_len <= i) - put_back (c); - if (! wide_flag) - { - p += (i + 1); - c = getch (); - continue; - } - c = wc; - } -#endif /* MULTIBYTE_CHARS */ - } - - /* Add this single character into the buffer either as a wchar_t - or as a single byte. */ - if (wide_flag) - { - unsigned width = TYPE_PRECISION (char_type_node); - unsigned bytemask = (1 << width) - 1; - int byte; - - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - - for (byte = 0; byte < WCHAR_BYTES; ++byte) - { - int value; - if (byte >= (int) sizeof(c)) - value = 0; - else - value = (c >> (byte * width)) & bytemask; - if (BYTES_BIG_ENDIAN) - p[WCHAR_BYTES - byte - 1] = value; - else - p[byte] = value; - } - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = c; - } - - skipnewline: - c = getch (); - if (c == EOF) { - error ("Unterminated string"); - break; - } - } - - /* Terminate the string value, either with a single byte zero - or with a wide zero. */ - if (wide_flag) - { - if (p + WCHAR_BYTES > token_buffer + maxtoken) - p = extend_token_buffer (p); - bzero (p, WCHAR_BYTES); - p += WCHAR_BYTES; - } - else - { - if (p >= token_buffer + maxtoken) - p = extend_token_buffer (p); - *p++ = 0; - } - - /* We have read the entire constant. - Construct a STRING_CST for the result. */ - - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - yylval.ttype = build_string (p - (token_buffer + 1), token_buffer + 1); - if (processing_template_decl) - pop_obstacks (); - - if (wide_flag) - TREE_TYPE (yylval.ttype) = wchar_array_type_node; - else - TREE_TYPE (yylval.ttype) = char_array_type_node; - - value = STRING; break; - } - - case '+': - case '-': - case '&': - case '|': - case '<': - case '>': - case '*': - case '/': - case '%': - case '^': - case '!': - case '=': - { - register int c1; - - combine: - - switch (c) - { - case '+': - yylval.code = PLUS_EXPR; break; - case '-': - yylval.code = MINUS_EXPR; break; - case '&': - yylval.code = BIT_AND_EXPR; break; - case '|': - yylval.code = BIT_IOR_EXPR; break; - case '*': - yylval.code = MULT_EXPR; break; - case '/': - yylval.code = TRUNC_DIV_EXPR; break; - case '%': - yylval.code = TRUNC_MOD_EXPR; break; - case '^': - yylval.code = BIT_XOR_EXPR; break; - case LSHIFT: - yylval.code = LSHIFT_EXPR; break; - case RSHIFT: - yylval.code = RSHIFT_EXPR; break; - case '<': - yylval.code = LT_EXPR; break; - case '>': - yylval.code = GT_EXPR; break; - } - - token_buffer[1] = c1 = getch (); - token_buffer[2] = 0; - - if (c1 == '=') - { - switch (c) - { - case '<': - value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done; - case '>': - value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done; - case '!': - value = EQCOMPARE; yylval.code = NE_EXPR; goto done; - case '=': - value = EQCOMPARE; yylval.code = EQ_EXPR; goto done; - } - value = ASSIGN; goto done; - } - else if (c == c1) - switch (c) - { - case '+': - value = PLUSPLUS; goto done; - case '-': - value = MINUSMINUS; goto done; - case '&': - value = ANDAND; goto done; - case '|': - value = OROR; goto done; - case '<': - c = LSHIFT; - goto combine; - case '>': - c = RSHIFT; - goto combine; - } - else if ((c == '-') && (c1 == '>')) - { - nextchar = getch (); - if (nextchar == '*') - { - nextchar = -1; - value = POINTSAT_STAR; - } - else - value = POINTSAT; - goto done; - } - else if (c1 == '?' && (c == '<' || c == '>')) - { - token_buffer[3] = 0; - - c1 = getch (); - yylval.code = (c == '<' ? MIN_EXPR : MAX_EXPR); - if (c1 == '=') - { - /* <?= or >?= expression. */ - token_buffer[2] = c1; - value = ASSIGN; - } - else - { - value = MIN_MAX; - nextchar = c1; - } - if (pedantic) - pedwarn ("use of `operator %s' is not standard C++", - token_buffer); - goto done; - } - /* digraphs */ - else if (c == '<' && c1 == '%') - { value = '{'; goto done; } - else if (c == '<' && c1 == ':') - { value = '['; goto done; } - else if (c == '%' && c1 == '>') - { value = '}'; goto done; } - else if (c == '%' && c1 == ':') - { value = '#'; goto done; } - - nextchar = c1; - token_buffer[1] = 0; - - value = c; - goto done; - } - - case ':': - c = getch (); - if (c == ':') - { - token_buffer[1] = ':'; - token_buffer[2] = '\0'; - value = SCOPE; - yylval.itype = 1; - } - else if (c == '>') - { - value = ']'; - goto done; - } - else - { - nextchar = c; - value = ':'; - } - break; - - case 0: - /* Don't make yyparse think this is eof. */ - value = 1; - break; - - case '(': - /* try, weakly, to handle casts to pointers to functions. */ - nextchar = skip_white_space (getch ()); - if (nextchar == '*') - { - int next_c = skip_white_space (getch ()); - if (next_c == ')') - { - nextchar = -1; - yylval.ttype = build1 (INDIRECT_REF, 0, 0); - value = PAREN_STAR_PAREN; - } - else - { - put_back (next_c); - value = c; - } - } - else if (nextchar == ')') - { - nextchar = -1; - yylval.ttype = NULL_TREE; - value = LEFT_RIGHT; - } - else value = c; - break; - - default: - value = c; - } - -done: -/* yylloc.last_line = lineno; */ -#ifdef GATHER_STATISTICS -#ifdef REDUCE_LENGTH - token_count[value] += 1; -#endif -#endif - - return value; -} - -int -is_rid (t) - tree t; -{ - return !!is_reserved_word (IDENTIFIER_POINTER (t), IDENTIFIER_LENGTH (t)); -} - -#ifdef GATHER_STATISTICS -/* The original for tree_node_kind is in the toplevel tree.c; changes there - need to be brought into here, unless this were actually put into a header - instead. */ -/* Statistics-gathering stuff. */ -typedef enum -{ - d_kind, - t_kind, - b_kind, - s_kind, - r_kind, - e_kind, - c_kind, - id_kind, - op_id_kind, - perm_list_kind, - temp_list_kind, - vec_kind, - x_kind, - lang_decl, - lang_type, - all_kinds -} tree_node_kind; - -extern int tree_node_counts[]; -extern int tree_node_sizes[]; -#endif - -/* Place to save freed lang_decls which were allocated on the - permanent_obstack. @@ Not currently used. */ -tree free_lang_decl_chain; - -tree -build_lang_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - register tree t = build_decl (code, name, type); - retrofit_lang_decl (t); - return t; -} - -/* Add DECL_LANG_SPECIFIC info to T. Called from build_lang_decl - and pushdecl (for functions generated by the backend). */ - -void -retrofit_lang_decl (t) - tree t; -{ - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl) / sizeof (int); - register int *pi; - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - /* Could be that saveable is permanent and current is not. */ - obstack = &permanent_obstack; - - if (free_lang_decl_chain && obstack == &permanent_obstack) - { - pi = (int *)free_lang_decl_chain; - free_lang_decl_chain = TREE_CHAIN (free_lang_decl_chain); - } - else - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl)); - - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - LANG_DECL_PERMANENT ((struct lang_decl *) pi) - = obstack == &permanent_obstack; - my_friendly_assert (LANG_DECL_PERMANENT ((struct lang_decl *) pi) - == TREE_PERMANENT (t), 234); - DECL_MAIN_VARIANT (t) = t; - if (current_lang_name == lang_name_cplusplus) - DECL_LANGUAGE (t) = lang_cplusplus; - else if (current_lang_name == lang_name_c) - DECL_LANGUAGE (t) = lang_c; - else if (current_lang_name == lang_name_java) - DECL_LANGUAGE (t) = lang_java; - else my_friendly_abort (64); - -#if 0 /* not yet, should get fixed properly later */ - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } - -#endif -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_decl] += 1; - tree_node_sizes[(int)lang_decl] += sizeof (struct lang_decl); -#endif -} - -tree -build_lang_field_decl (code, name, type) - enum tree_code code; - tree name; - tree type; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = build_decl (code, name, type); - struct obstack *obstack = current_obstack; - register int i = sizeof (struct lang_decl_flags) / sizeof (int); - register int *pi; -#if 0 /* not yet, should get fixed properly later */ - - if (code == TYPE_DECL) - { - tree id; - id = get_identifier (build_overload_name (type, 1, 1)); - DECL_ASSEMBLER_NAME (t) = id; - } -#endif - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 235); - - pi = (int *) obstack_alloc (obstack, sizeof (struct lang_decl_flags)); - while (i > 0) - pi[--i] = 0; - - DECL_LANG_SPECIFIC (t) = (struct lang_decl *) pi; - return t; -} - -void -copy_lang_decl (node) - tree node; -{ - int size; - int *pi; - - if (! DECL_LANG_SPECIFIC (node)) - return; - - if (TREE_CODE (node) == FIELD_DECL) - size = sizeof (struct lang_decl_flags); - else - size = sizeof (struct lang_decl); - pi = (int *)obstack_alloc (&permanent_obstack, size); - bcopy ((char *)DECL_LANG_SPECIFIC (node), (char *)pi, size); - DECL_LANG_SPECIFIC (node) = (struct lang_decl *)pi; -} - -tree -make_lang_type (code) - enum tree_code code; -{ - extern struct obstack *current_obstack, *saveable_obstack; - register tree t = make_node (code); - - /* Set up some flags that give proper default behavior. */ - if (IS_AGGR_TYPE_CODE (code)) - { - struct obstack *obstack = current_obstack; - struct lang_type *pi; - - SET_IS_AGGR_TYPE (t, 1); - - if (! TREE_PERMANENT (t)) - obstack = saveable_obstack; - else - my_friendly_assert (obstack == &permanent_obstack, 236); - - pi = (struct lang_type *) obstack_alloc (obstack, sizeof (struct lang_type)); - bzero ((char *) pi, (int) sizeof (struct lang_type)); - - TYPE_LANG_SPECIFIC (t) = pi; - CLASSTYPE_AS_LIST (t) = build_expr_list (NULL_TREE, t); - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (t, interface_unknown); - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - TYPE_BINFO (t) = make_binfo (integer_zero_node, t, NULL_TREE, NULL_TREE); - CLASSTYPE_BINFO_AS_LIST (t) - = build_tree_list (NULL_TREE, TYPE_BINFO (t)); - - /* Make sure this is laid out, for ease of use later. In the - presence of parse errors, the normal was of assuring this - might not ever get executed, so we lay it out *immediately*. */ - build_pointer_type (t); - -#ifdef GATHER_STATISTICS - tree_node_counts[(int)lang_type] += 1; - tree_node_sizes[(int)lang_type] += sizeof (struct lang_type); -#endif - } - else - /* We use TYPE_ALIAS_SET for the CLASSTYPE_MARKED bits. But, - TYPE_ALIAS_SET is initialized to -1 by default, so we must - clear it here. */ - TYPE_ALIAS_SET (t) = 0; - - return t; -} - -void -dump_time_statistics () -{ - register tree prev = 0, decl, next; - int this_time = my_get_run_time (); - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (this_filename_time)) - += this_time - body_time; - - fprintf (stderr, "\n******\n"); - print_time ("header files (total)", header_time); - print_time ("main file (total)", this_time - body_time); - fprintf (stderr, "ratio = %g : 1\n", - (double)header_time / (double)(this_time - body_time)); - fprintf (stderr, "\n******\n"); - - for (decl = filename_times; decl; decl = next) - { - next = IDENTIFIER_GLOBAL_VALUE (decl); - SET_IDENTIFIER_GLOBAL_VALUE (decl, prev); - prev = decl; - } - - for (decl = prev; decl; decl = IDENTIFIER_GLOBAL_VALUE (decl)) - print_time (IDENTIFIER_POINTER (decl), - TREE_INT_CST_LOW (TIME_IDENTIFIER_TIME (decl))); -} - -void -compiler_error (s, v, v2) - char *s; - HOST_WIDE_INT v, v2; /* @@also used as pointer */ -{ - char buf[1024]; - sprintf (buf, s, v, v2); - error_with_file_and_line (input_filename, lineno, "%s (compiler error)", buf); -} - -void -yyerror (string) - char *string; -{ - extern int end_of_file; - char buf[200]; - - strcpy (buf, string); - - /* We can't print string and character constants well - because the token_buffer contains the result of processing escapes. */ - if (end_of_file) - strcat (buf, input_redirected () - ? " at end of saved text" - : " at end of input"); - else if (token_buffer[0] == 0) - strcat (buf, " at null character"); - else if (token_buffer[0] == '"') - strcat (buf, " before string constant"); - else if (token_buffer[0] == '\'') - strcat (buf, " before character constant"); - else if (!ISGRAPH ((unsigned char)token_buffer[0])) - sprintf (buf + strlen (buf), " before character 0%o", - (unsigned char) token_buffer[0]); - else - strcat (buf, " before `%s'"); - - error (buf, token_buffer); -} - -static int -handle_cp_pragma (pname) - char *pname; -{ - register int token; - - if (! strcmp (pname, "vtable")) - { - extern tree pending_vtables; - - /* More follows: it must be a string constant (class name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma vtable"); - return -1; - } - - if (write_virtuals != 2) - { - warning ("use `+e2' option to enable #pragma vtable"); - return -1; - } - pending_vtables - = perm_tree_cons (NULL_TREE, - get_identifier (TREE_STRING_POINTER (yylval.ttype)), - pending_vtables); - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "unit")) - { - /* More follows: it must be a string constant (unit name). */ - token = real_yylex (); - if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid #pragma unit"); - return -1; - } - token = real_yylex (); - if (token != END_OF_LINE) - warning ("trailing characters ignored"); - return 1; - } - else if (! strcmp (pname, "interface")) - { - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); - char *main_filename = input_filename; - - main_filename = file_name_nondirectory (main_filename); - - token = real_yylex (); - - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma interface'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma interface' ignored"); - - write_virtuals = 3; - - if (impl_file_chain == 0) - { - /* If this is zero at this point, then we are - auto-implementing. */ - if (main_input_filename == 0) - main_input_filename = input_filename; - -#ifdef AUTO_IMPLEMENT - filename = file_name_nondirectory (main_input_filename); - fi = get_time_identifier (filename); - fi = TIME_IDENTIFIER_FILEINFO (fi); - TREE_INT_CST_LOW (fi) = 0; - TREE_INT_CST_HIGH (fi) = 1; - /* Get default. */ - impl_file_chain = (struct impl_files *)permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = filename; - impl_file_chain->next = 0; -#endif - } - - interface_only = interface_strcmp (main_filename); -#ifdef MULTIPLE_SYMBOL_SPACES - if (! interface_only) - interface_unknown = 0; -#else /* MULTIPLE_SYMBOL_SPACES */ - interface_unknown = 0; -#endif /* MULTIPLE_SYMBOL_SPACES */ - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - - return 1; - } - else if (! strcmp (pname, "implementation")) - { - tree fileinfo - = TIME_IDENTIFIER_FILEINFO (get_time_identifier (input_filename)); - char *main_filename = main_input_filename ? main_input_filename : input_filename; - - main_filename = file_name_nondirectory (main_filename); - token = real_yylex (); - if (token != END_OF_LINE) - { - if (token != STRING - || TREE_CODE (yylval.ttype) != STRING_CST) - { - error ("invalid `#pragma implementation'"); - return -1; - } - main_filename = TREE_STRING_POINTER (yylval.ttype); - token = real_yylex (); - } - - if (token != END_OF_LINE) - warning ("garbage after `#pragma implementation' ignored"); - - if (write_virtuals == 3) - { - struct impl_files *ifiles = impl_file_chain; - while (ifiles) - { - if (! strcmp (ifiles->filename, main_filename)) - break; - ifiles = ifiles->next; - } - if (ifiles == 0) - { - ifiles = (struct impl_files*) permalloc (sizeof (struct impl_files)); - ifiles->filename = main_filename; - ifiles->next = impl_file_chain; - impl_file_chain = ifiles; - } - } - else if ((main_input_filename != 0 - && ! strcmp (main_input_filename, input_filename)) - || ! strcmp (input_filename, main_filename)) - { - write_virtuals = 3; - if (impl_file_chain == 0) - { - impl_file_chain = (struct impl_files*) permalloc (sizeof (struct impl_files)); - impl_file_chain->filename = main_filename; - impl_file_chain->next = 0; - } - } - else - error ("`#pragma implementation' can only appear at top-level"); - interface_only = 0; -#if 1 - /* We make this non-zero so that we infer decl linkage - in the impl file only for variables first declared - in the interface file. */ - interface_unknown = 1; -#else - /* We make this zero so that templates in the impl - file will be emitted properly. */ - interface_unknown = 0; -#endif - TREE_INT_CST_LOW (fileinfo) = interface_only; - TREE_INT_CST_HIGH (fileinfo) = interface_unknown; - - return 1; - } - - return 0; -} - -/* Return the type-qualifier corresponding to the identifier given by - RID. */ - -int -cp_type_qual_from_rid (rid) - tree rid; -{ - if (rid == ridpointers[(int) RID_CONST]) - return TYPE_QUAL_CONST; - else if (rid == ridpointers[(int) RID_VOLATILE]) - return TYPE_QUAL_VOLATILE; - else if (rid == ridpointers[(int) RID_RESTRICT]) - return TYPE_QUAL_RESTRICT; - - my_friendly_abort (0); - return TYPE_UNQUALIFIED; -} - - -#ifdef HANDLE_GENERIC_PRAGMAS - -/* Handle a #pragma directive. TOKEN is the type of the word following - the #pragma directive on the line. Process the entire input line and - return non-zero iff the directive successfully parsed. */ - -/* This function has to be in this file, in order to get at - the token types. */ - -static int -handle_generic_pragma (token) - register int token; -{ - for (;;) - { - switch (token) - { - case IDENTIFIER: - case TYPENAME: - case STRING: - case CONSTANT: - handle_pragma_token (token_buffer, yylval.ttype); - break; - - case LEFT_RIGHT: - handle_pragma_token ("(", NULL_TREE); - handle_pragma_token (")", NULL_TREE); - break; - - case END_OF_LINE: - return handle_pragma_token (NULL_PTR, NULL_TREE); - - default: - handle_pragma_token (token_buffer, NULL); - } - - token = real_yylex (); - } -} -#endif /* HANDLE_GENERIC_PRAGMAS */ diff --git a/gcc/cp/method.c b/gcc/cp/method.c deleted file mode 100755 index 1fa8794..0000000 --- a/gcc/cp/method.c +++ /dev/null @@ -1,2466 +0,0 @@ -/* Handle the hair of processing (but not expanding) inline functions. - Also manage function and variable name overloading. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#ifndef __GNUC__ -#define __inline -#endif - -#ifndef PARM_CAN_BE_ARRAY_TYPE -#define PARM_CAN_BE_ARRAY_TYPE 1 -#endif - -/* Handle method declarations. */ -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "obstack.h" -#include "rtl.h" -#include "expr.h" -#include "output.h" -#include "hard-reg-set.h" -#include "flags.h" -#include "toplev.h" - -/* TREE_LIST of the current inline functions that need to be - processed. */ -struct pending_inline *pending_inlines; - -int static_labelno; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Obstack where we build text strings for overloading, etc. */ -static struct obstack scratch_obstack; -static char *scratch_firstobj; - -static void icat PROTO((HOST_WIDE_INT)); -static void dicat PROTO((HOST_WIDE_INT, HOST_WIDE_INT)); -static void flush_repeats PROTO((int, tree)); -static void build_overload_identifier PROTO((tree)); -static void build_overload_nested_name PROTO((tree)); -static void build_overload_int PROTO((tree, int)); -static void build_overload_identifier PROTO((tree)); -static void build_qualified_name PROTO((tree)); -static void build_overload_value PROTO((tree, tree, int)); -static void issue_nrepeats PROTO((int, tree)); -static char *build_mangled_name PROTO((tree,int,int)); -static void process_modifiers PROTO((tree)); -static void process_overload_item PROTO((tree,int)); -static void do_build_assign_ref PROTO((tree)); -static void do_build_copy_constructor PROTO((tree)); -static tree largest_union_member PROTO((tree)); -static void build_template_template_parm_names PROTO((tree)); -static void build_template_parm_names PROTO((tree, tree)); -static void build_underscore_int PROTO((int)); -static void start_squangling PROTO((void)); -static void end_squangling PROTO((void)); -static int check_ktype PROTO((tree, int)); -static int issue_ktype PROTO((tree)); -static void build_overload_scope_ref PROTO((tree)); -static void build_mangled_template_parm_index PROTO((char *, tree)); -#if HOST_BITS_PER_WIDE_INT >= 64 -static void build_mangled_C9x_name PROTO((int)); -#endif -static int is_back_referenceable_type PROTO((tree)); -static int check_btype PROTO((tree)); -static void build_mangled_name_for_type PROTO((tree)); -static void build_mangled_name_for_type_with_Gcode PROTO((tree, int)); - -# define OB_INIT() (scratch_firstobj ? (obstack_free (&scratch_obstack, scratch_firstobj), 0) : 0) -# define OB_PUTC(C) (obstack_1grow (&scratch_obstack, (C))) -# define OB_PUTC2(C1,C2) \ - (obstack_1grow (&scratch_obstack, (C1)), obstack_1grow (&scratch_obstack, (C2))) -# define OB_PUTS(S) (obstack_grow (&scratch_obstack, (S), sizeof (S) - 1)) -# define OB_PUTID(ID) \ - (obstack_grow (&scratch_obstack, IDENTIFIER_POINTER (ID), \ - IDENTIFIER_LENGTH (ID))) -# define OB_PUTCP(S) (obstack_grow (&scratch_obstack, (S), strlen (S))) -# define OB_FINISH() (obstack_1grow (&scratch_obstack, '\0')) -# define OB_LAST() (obstack_next_free (&scratch_obstack)[-1]) - -void -init_method () -{ - gcc_obstack_init (&scratch_obstack); - scratch_firstobj = (char *)obstack_alloc (&scratch_obstack, 0); -} - -/* This must be large enough to hold any printed integer or floating-point - value. */ -static char digit_buffer[128]; - -/* Move inline function definitions out of structure so that they - can be processed normally. CNAME is the name of the class - we are working from, METHOD_LIST is the list of method lists - of the structure. We delete friend methods here, after - saving away their inline function definitions (if any). */ - -void -do_inline_function_hair (type, friend_list) - tree type, friend_list; -{ - tree method = TYPE_METHODS (type); - - if (method && TREE_CODE (method) == TREE_VEC) - { - if (TREE_VEC_ELT (method, 1)) - method = TREE_VEC_ELT (method, 1); - else if (TREE_VEC_ELT (method, 0)) - method = TREE_VEC_ELT (method, 0); - else - method = TREE_VEC_ELT (method, 2); - } - - while (method) - { - /* Do inline member functions. */ - struct pending_inline *info = DECL_PENDING_INLINE_INFO (method); - if (info) - { - tree args; - - my_friendly_assert (info->fndecl == method, 238); - args = DECL_ARGUMENTS (method); - while (args) - { - DECL_CONTEXT (args) = method; - args = TREE_CHAIN (args); - } - } - method = TREE_CHAIN (method); - } - while (friend_list) - { - tree fndecl = TREE_VALUE (friend_list); - struct pending_inline *info = DECL_PENDING_INLINE_INFO (fndecl); - if (info) - { - tree args; - - my_friendly_assert (info->fndecl == fndecl, 239); - args = DECL_ARGUMENTS (fndecl); - while (args) - { - DECL_CONTEXT (args) = fndecl; - args = TREE_CHAIN (args); - } - } - - friend_list = TREE_CHAIN (friend_list); - } -} - -/* Here is where overload code starts. */ - -/* type tables for K and B type compression */ -static tree *btypelist = NULL; -static tree *ktypelist = NULL; -static int maxbsize = 0; -static int maxksize = 0; - -/* number of each type seen */ -static int maxbtype = 0; -static int maxktype = 0; - -/* Array of types seen so far in top-level call to `build_mangled_name'. - Allocated and deallocated by caller. */ -static tree *typevec = NULL; -static int typevec_size; - -/* Number of types interned by `build_mangled_name' so far. */ -static int maxtype = 0; - -/* Nonzero if we should not try folding parameter types. */ -static int nofold; - -/* This appears to be set to true if an underscore is required to be - comcatenated before another number can be outputed. */ -static int numeric_output_need_bar; - -static __inline void -start_squangling () -{ - if (flag_do_squangling) - { - nofold = 0; - maxbtype = 0; - maxktype = 0; - maxbsize = 50; - maxksize = 50; - btypelist = (tree *)xmalloc (sizeof (tree) * maxbsize); - ktypelist = (tree *)xmalloc (sizeof (tree) * maxksize); - } -} - -static __inline void -end_squangling () -{ - if (flag_do_squangling) - { - if (ktypelist) - free (ktypelist); - if (btypelist) - free (btypelist); - maxbsize = 0; - maxksize = 0; - maxbtype = 0; - maxktype = 0; - ktypelist = NULL; - btypelist = NULL; - } -} - -/* Code to concatenate an asciified integer to a string. */ - -static __inline void -icat (i) - HOST_WIDE_INT i; -{ - unsigned HOST_WIDE_INT ui; - - /* Handle this case first, to go really quickly. For many common values, - the result of ui/10 below is 1. */ - if (i == 1) - { - OB_PUTC ('1'); - return; - } - - if (i >= 0) - ui = i; - else - { - OB_PUTC ('m'); - ui = -i; - } - - if (ui >= 10) - icat (ui / 10); - - OB_PUTC ('0' + (ui % 10)); -} - -static void -dicat (lo, hi) - HOST_WIDE_INT lo, hi; -{ - unsigned HOST_WIDE_INT ulo, uhi, qlo, qhi; - - if (hi >= 0) - { - uhi = hi; - ulo = lo; - } - else - { - uhi = (lo == 0 ? -hi : -hi-1); - ulo = -lo; - } - if (uhi == 0 - && ulo < ((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1))) - { - icat (ulo); - return; - } - /* Divide 2^HOST_WIDE_INT*uhi+ulo by 10. */ - qhi = uhi / 10; - uhi = uhi % 10; - qlo = uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) / 5); - qlo += ulo / 10; - ulo = ulo % 10; - ulo += uhi * (((unsigned HOST_WIDE_INT)1 << (HOST_BITS_PER_WIDE_INT - 1)) % 5) - * 2; - qlo += ulo / 10; - ulo = ulo % 10; - /* Quotient is 2^HOST_WIDE_INT*qhi+qlo, remainder is ulo. */ - dicat (qlo, qhi); - OB_PUTC ('0' + ulo); -} - -static __inline void -flush_repeats (nrepeats, type) - int nrepeats; - tree type; -{ - int tindex = 0; - - while (typevec[tindex] != type) - tindex++; - - if (nrepeats > 1) - { - OB_PUTC ('N'); - icat (nrepeats); - if (nrepeats > 9) - OB_PUTC ('_'); - } - else - OB_PUTC ('T'); - icat (tindex); - if (tindex > 9) - OB_PUTC ('_'); -} - -/* Returns nonzero iff this is a type to which we will want to make - back-references (using the `B' code). */ - -static int -is_back_referenceable_type (type) - tree type; -{ - if (btypelist == NULL) - /* We're not generating any back-references. */ - return 0; - - switch (TREE_CODE (type)) - { - case INTEGER_TYPE: - case REAL_TYPE: - case VOID_TYPE: - case BOOLEAN_TYPE: - /* These types have single-character manglings, so there's no - point in generating back-references. */ - return 0; - - case TEMPLATE_TYPE_PARM: - /* It would be a bit complex to demangle signatures correctly if - we generated back-references to these, and the manglings of - type parameters are short. */ - return 0; - - default: - return 1; - } -} - -/* Issue the squangling code indicating NREPEATS repetitions of TYPE, - which was the last parameter type output. */ - -static void -issue_nrepeats (nrepeats, type) - int nrepeats; - tree type; -{ - if (nrepeats == 1 && !is_back_referenceable_type (type)) - /* For types whose manglings are short, don't bother using the - repetition code if there's only one repetition, since the - repetition code will be about as long as the ordinary mangling. */ - build_mangled_name_for_type (type); - else - { - OB_PUTC ('n'); - icat (nrepeats); - if (nrepeats > 9) - OB_PUTC ('_'); - } -} - -/* Check to see if a tree node has been entered into the Kcode typelist */ -/* if not, add it. Return -1 if it isn't found, otherwise return the index */ -static int -check_ktype (node, add) - tree node; - int add; -{ - int x; - tree localnode = node; - - if (ktypelist == NULL) - return -1; - - if (TREE_CODE (node) == TYPE_DECL) - localnode = TREE_TYPE (node); - - for (x=0; x < maxktype; x++) - { - if (localnode == ktypelist[x]) - return x ; - } - /* Didn't find it, so add it here */ - if (add) - { - if (maxksize <= maxktype) - { - maxksize = maxksize* 3 / 2; - ktypelist = (tree *)xrealloc (ktypelist, sizeof (tree) * maxksize); - } - ktypelist[maxktype++] = localnode; - } - return -1; -} - - -static __inline int -issue_ktype (decl) - tree decl; -{ - int kindex; - kindex = check_ktype (decl, FALSE); - if (kindex != -1) - { - OB_PUTC ('K'); - icat (kindex); - if (kindex > 9) - OB_PUTC ('_'); - return TRUE; - } - return FALSE; -} - -/* Build a representation for DECL, which may be an entity not at - global scope. If so, a marker indicating that the name is - qualified has already been output, but the qualifying context has - not. */ - -static void -build_overload_nested_name (decl) - tree decl; -{ - tree context; - - if (ktypelist && issue_ktype (decl)) - return; - - if (decl == global_namespace) - return; - - context = CP_DECL_CONTEXT (decl); - - /* try to issue a K type, and if we can't continue the normal path */ - if (!(ktypelist && issue_ktype (context))) - { - /* For a template type parameter, we want to output an 'Xn' - rather than 'T' or some such. */ - if (TREE_CODE (context) == TEMPLATE_TYPE_PARM - || TREE_CODE (context) == TEMPLATE_TEMPLATE_PARM) - build_mangled_name_for_type (context); - else - { - if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') - context = TYPE_NAME (context); - build_overload_nested_name (context); - } - } - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - tree name = DECL_ASSEMBLER_NAME (decl); - char *label; - - ASM_FORMAT_PRIVATE_NAME (label, IDENTIFIER_POINTER (name), static_labelno); - static_labelno++; - - if (numeric_output_need_bar) - OB_PUTC ('_'); - icat (strlen (label)); - OB_PUTCP (label); - numeric_output_need_bar = 1; - } - else if (TREE_CODE (decl) == NAMESPACE_DECL) - build_overload_identifier (DECL_NAME (decl)); - else /* TYPE_DECL */ - build_overload_identifier (decl); -} - -/* Output the decimal representation of I. If I > 9, the decimal - representation is preceeded and followed by an underscore. */ - -static void -build_underscore_int (i) - int i; -{ - if (i > 9) - OB_PUTC ('_'); - icat (i); - if (i > 9) - OB_PUTC ('_'); -} - -static void -build_overload_scope_ref (value) - tree value; -{ - OB_PUTC2 ('Q', '2'); - numeric_output_need_bar = 0; - build_mangled_name_for_type (TREE_OPERAND (value, 0)); - build_overload_identifier (TREE_OPERAND (value, 1)); -} - -/* Encoding for an INTEGER_CST value. */ - -static void -build_overload_int (value, in_template) - tree value; - int in_template; -{ - if (in_template && TREE_CODE (value) != INTEGER_CST) - { - if (TREE_CODE (value) == SCOPE_REF) - { - build_overload_scope_ref (value); - return; - } - - OB_PUTC ('E'); - numeric_output_need_bar = 0; - - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (value)))) - { - int i; - int operands = tree_code_length[(int) TREE_CODE (value)]; - tree id; - char* name; - - id = ansi_opname [(int) TREE_CODE (value)]; - my_friendly_assert (id != NULL_TREE, 0); - name = IDENTIFIER_POINTER (id); - if (name[0] != '_' || name[1] != '_') - /* On some erroneous inputs, we can get here with VALUE a - LOOKUP_EXPR. In that case, the NAME will be the - identifier for "<invalid operator>". We must survive - this routine in order to issue a sensible error - message, so we fall through to the case below. */ - goto bad_value; - - for (i = 0; i < operands; ++i) - { - tree operand; - enum tree_code tc; - - /* We just outputted either the `E' or the name of the - operator. */ - numeric_output_need_bar = 0; - - if (i != 0) - /* Skip the leading underscores. */ - OB_PUTCP (name + 2); - - operand = TREE_OPERAND (value, i); - tc = TREE_CODE (operand); - - if (TREE_CODE_CLASS (tc) == 't') - /* We can get here with sizeof, e.g.: - - template <class T> void f(A<sizeof(T)>); */ - build_mangled_name_for_type (operand); - else if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (tc))) - build_overload_int (operand, in_template); - else - build_overload_value (TREE_TYPE (operand), - operand, - in_template); - } - } - else - { - /* We don't ever want this output, but it's - inconvenient not to be able to build the string. - This should cause assembler errors we'll notice. */ - - static int n; - bad_value: - sprintf (digit_buffer, " *%d", n++); - OB_PUTCP (digit_buffer); - } - - OB_PUTC ('W'); - numeric_output_need_bar = 0; - return; - } - - my_friendly_assert (TREE_CODE (value) == INTEGER_CST, 243); - if (TYPE_PRECISION (TREE_TYPE (value)) == 2 * HOST_BITS_PER_WIDE_INT) - { - if (TREE_INT_CST_HIGH (value) - != (TREE_INT_CST_LOW (value) >> (HOST_BITS_PER_WIDE_INT - 1))) - { - /* need to print a DImode value in decimal */ - dicat (TREE_INT_CST_LOW (value), TREE_INT_CST_HIGH (value)); - numeric_output_need_bar = 1; - return; - } - /* else fall through to print in smaller mode */ - } - /* Wordsize or smaller */ - icat (TREE_INT_CST_LOW (value)); - numeric_output_need_bar = 1; -} - - -/* Output S followed by a representation of the TEMPLATE_PARM_INDEX - supplied in INDEX. */ - -static void -build_mangled_template_parm_index (s, index) - char* s; - tree index; -{ - OB_PUTCP (s); - build_underscore_int (TEMPLATE_PARM_IDX (index)); - /* We use the LEVEL, not the ORIG_LEVEL, because the mangling is a - representation of the function from the point of view of its - type. */ - build_underscore_int (TEMPLATE_PARM_LEVEL (index)); -} - - -/* Mangling for C9X integer types (and Cygnus extensions for 128-bit - and other types) is based on the letter "I" followed by the hex - representations of the bitsize for the type in question. For - encodings that result in larger than two digits, a leading and - trailing underscore is added. - - Thus: - int1_t = 001 = I01 - int8_t = 008 = I08 - int16_t = 010 = I10 - int24_t = 018 = I18 - int32_t = 020 = I20 - int64_t = 040 = I40 - int80_t = 050 = I50 - int128_t = 080 = I80 - int256_t = 100 = I_100_ - int512_t = 200 = I_200_ - - Given an integer in decimal format, mangle according to this scheme. */ - -#if HOST_BITS_PER_WIDE_INT >= 64 -static void -build_mangled_C9x_name (bits) - int bits; -{ - char mangled[10] = ""; - - if (bits > 255) - sprintf (mangled, "I_%x_", bits); - else - sprintf (mangled, "I%.2x", bits); - - OB_PUTCP (mangled); -} -#endif - -static void -build_overload_value (type, value, in_template) - tree type, value; - int in_template; -{ - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (type)) == 't', 0); - - while (TREE_CODE (value) == NON_LVALUE_EXPR - || TREE_CODE (value) == NOP_EXPR) - value = TREE_OPERAND (value, 0); - - if (numeric_output_need_bar) - { - OB_PUTC ('_'); - numeric_output_need_bar = 0; - } - - if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) - { - build_mangled_template_parm_index ("Y", value); - return; - } - - if (TYPE_PTRMEM_P (type)) - { - if (TREE_CODE (value) != PTRMEM_CST) - /* We should have already rejected this pointer to member, - since it is not a constant. */ - my_friendly_abort (0); - - /* Get the actual FIELD_DECL. */ - value = PTRMEM_CST_MEMBER (value); - my_friendly_assert (TREE_CODE (value) == FIELD_DECL, 0); - - /* Output the name of the field. */ - build_overload_identifier (DECL_NAME (value)); - return; - } - - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); - - switch (TREE_CODE (type)) - { - case INTEGER_TYPE: - case ENUMERAL_TYPE: - case BOOLEAN_TYPE: - { - build_overload_int (value, in_template); - return; - } - case REAL_TYPE: - { - REAL_VALUE_TYPE val; - char *bufp = digit_buffer; - - pedwarn ("ANSI C++ forbids floating-point template arguments"); - - my_friendly_assert (TREE_CODE (value) == REAL_CST, 244); - val = TREE_REAL_CST (value); - if (REAL_VALUE_ISNAN (val)) - { - sprintf (bufp, "NaN"); - } - else - { - if (REAL_VALUE_NEGATIVE (val)) - { - val = REAL_VALUE_NEGATE (val); - *bufp++ = 'm'; - } - if (REAL_VALUE_ISINF (val)) - { - sprintf (bufp, "Infinity"); - } - else - { - REAL_VALUE_TO_DECIMAL (val, "%.20e", bufp); - bufp = (char *) index (bufp, 'e'); - if (!bufp) - strcat (digit_buffer, "e0"); - else - { - char *p; - bufp++; - if (*bufp == '-') - { - *bufp++ = 'm'; - } - p = bufp; - if (*p == '+') - p++; - while (*p == '0') - p++; - if (*p == 0) - { - *bufp++ = '0'; - *bufp = 0; - } - else if (p != bufp) - { - while (*p) - *bufp++ = *p++; - *bufp = 0; - } - } -#ifdef NO_DOT_IN_LABEL - bufp = (char *) index (bufp, '.'); - if (bufp) - *bufp = '_'; -#endif - } - } - OB_PUTCP (digit_buffer); - numeric_output_need_bar = 1; - return; - } - case POINTER_TYPE: - if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE - && TREE_CODE (value) != ADDR_EXPR) - { - if (TREE_CODE (value) == CONSTRUCTOR) - { - /* This is dangerous code, crack built up pointer to members. */ - tree args = CONSTRUCTOR_ELTS (value); - tree a1 = TREE_VALUE (args); - tree a2 = TREE_VALUE (TREE_CHAIN (args)); - tree a3 = CONSTRUCTOR_ELTS (TREE_VALUE (TREE_CHAIN (TREE_CHAIN (args)))); - a3 = TREE_VALUE (a3); - STRIP_NOPS (a3); - if (TREE_CODE (a1) == INTEGER_CST - && TREE_CODE (a2) == INTEGER_CST) - { - build_overload_int (a1, in_template); - OB_PUTC ('_'); - build_overload_int (a2, in_template); - OB_PUTC ('_'); - if (TREE_CODE (a3) == ADDR_EXPR) - { - a3 = TREE_OPERAND (a3, 0); - if (TREE_CODE (a3) == FUNCTION_DECL) - { - numeric_output_need_bar = 0; - build_overload_identifier (DECL_ASSEMBLER_NAME (a3)); - return; - } - } - else if (TREE_CODE (a3) == INTEGER_CST) - { - OB_PUTC ('i'); - build_overload_int (a3, in_template); - return; - } - } - } - sorry ("template instantiation with pointer to method that is too complex"); - return; - } - if (TREE_CODE (value) == INTEGER_CST) - { - build_overload_int (value, in_template); - return; - } - else if (TREE_CODE (value) == TEMPLATE_PARM_INDEX) - { - build_mangled_template_parm_index ("", value); - numeric_output_need_bar = 1; - return; - } - - value = TREE_OPERAND (value, 0); - - /* Fall through. */ - - case REFERENCE_TYPE: - if (TREE_CODE (value) == VAR_DECL) - { - my_friendly_assert (DECL_NAME (value) != 0, 245); - build_overload_identifier (DECL_ASSEMBLER_NAME (value)); - return; - } - else if (TREE_CODE (value) == FUNCTION_DECL) - { - my_friendly_assert (DECL_NAME (value) != 0, 246); - build_overload_identifier (DECL_ASSEMBLER_NAME (value)); - return; - } - else if (TREE_CODE (value) == SCOPE_REF) - build_overload_scope_ref (value); - else - my_friendly_abort (71); - break; /* not really needed */ - - default: - sorry ("conversion of %s as template parameter", - tree_code_name [(int) TREE_CODE (type)]); - my_friendly_abort (72); - } -} - - -/* Add encodings for the declaration of template template parameters. - PARMLIST must be a TREE_VEC */ - -static void -build_template_template_parm_names (parmlist) - tree parmlist; -{ - int i, nparms; - - my_friendly_assert (TREE_CODE (parmlist) == TREE_VEC, 246.5); - nparms = TREE_VEC_LENGTH (parmlist); - icat (nparms); - for (i = 0; i < nparms; i++) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); - if (TREE_CODE (parm) == TYPE_DECL) - { - /* This parameter is a type. */ - OB_PUTC ('Z'); - } - else if (TREE_CODE (parm) == TEMPLATE_DECL) - { - /* This parameter is a template. */ - OB_PUTC ('z'); - build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); - } - else - /* It's a PARM_DECL. */ - build_mangled_name_for_type (TREE_TYPE (parm)); - } -} - - -/* Add encodings for the vector of template parameters in PARMLIST, - given the vector of arguments to be substituted in ARGLIST. */ - -static void -build_template_parm_names (parmlist, arglist) - tree parmlist; - tree arglist; -{ - int i, nparms; - tree inner_args = innermost_args (arglist); - - nparms = TREE_VEC_LENGTH (parmlist); - icat (nparms); - for (i = 0; i < nparms; i++) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (parmlist, i)); - tree arg = TREE_VEC_ELT (inner_args, i); - if (TREE_CODE (parm) == TYPE_DECL) - { - /* This parameter is a type. */ - OB_PUTC ('Z'); - build_mangled_name_for_type (arg); - } - else if (TREE_CODE (parm) == TEMPLATE_DECL) - { - /* This parameter is a template. */ - if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - /* Output parameter declaration, argument index and level */ - build_mangled_name_for_type (arg); - else - { - /* A TEMPLATE_DECL node, output the parameter declaration - and template name */ - - OB_PUTC ('z'); - build_template_template_parm_names (DECL_INNERMOST_TEMPLATE_PARMS (parm)); - icat (IDENTIFIER_LENGTH (DECL_NAME (arg))); - OB_PUTID (DECL_NAME (arg)); - } - } - else - { - parm = tsubst (parm, arglist, NULL_TREE); - /* It's a PARM_DECL. */ - build_mangled_name_for_type (TREE_TYPE (parm)); - build_overload_value (TREE_TYPE (parm), arg, - uses_template_parms (arglist)); - } - } - } - -/* Output the representation for NAME, which is either a TYPE_DECL or - an IDENTIFIER. */ - -static void -build_overload_identifier (name) - tree name; -{ - if (TREE_CODE (name) == TYPE_DECL - && CLASS_TYPE_P (TREE_TYPE (name)) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (name)) - && (PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name))) - || (TREE_CODE (DECL_CONTEXT (CLASSTYPE_TI_TEMPLATE - (TREE_TYPE (name)))) - == FUNCTION_DECL))) - { - /* NAME is the TYPE_DECL for a template specialization. */ - tree template, parmlist, arglist, tname; - template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (name)); - arglist = CLASSTYPE_TI_ARGS (TREE_TYPE (name)); - tname = DECL_NAME (template); - parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); - OB_PUTC ('t'); - icat (IDENTIFIER_LENGTH (tname)); - OB_PUTID (tname); - build_template_parm_names (parmlist, arglist); - } - else - { - if (TREE_CODE (name) == TYPE_DECL) - name = DECL_NAME (name); - if (numeric_output_need_bar) - { - OB_PUTC ('_'); - numeric_output_need_bar = 0; - } - icat (IDENTIFIER_LENGTH (name)); - OB_PUTID (name); - } -} - -/* Given DECL, either a class TYPE, TYPE_DECL or FUNCTION_DECL, produce - the mangling for it. Used by build_mangled_name and build_static_name. */ - -static void -build_qualified_name (decl) - tree decl; -{ - tree context; - int i = 1; - - if (TREE_CODE_CLASS (TREE_CODE (decl)) == 't') - decl = TYPE_NAME (decl); - - /* If DECL_ASSEMBLER_NAME has been set properly, use it. */ - if (TREE_CODE (decl) == TYPE_DECL - && DECL_ASSEMBLER_NAME (decl) != DECL_NAME (decl) && !flag_do_squangling) - { - tree id = DECL_ASSEMBLER_NAME (decl); - OB_PUTID (id); - if (ISDIGIT (IDENTIFIER_POINTER (id) [IDENTIFIER_LENGTH (id) - 1])) - numeric_output_need_bar = 1; - return; - } - - context = decl; - /* if we can't find a Ktype, do it the hard way */ - if (check_ktype (context, FALSE) == -1) - { - /* count type and namespace scopes */ - while (DECL_CONTEXT (context) && DECL_CONTEXT (context) != global_namespace) - { - i += 1; - context = DECL_CONTEXT (context); - if (check_ktype (context, FALSE) != -1) /* found it! */ - break; - if (TREE_CODE_CLASS (TREE_CODE (context)) == 't') - context = TYPE_NAME (context); - } - } - - if (i > 1) - { - OB_PUTC ('Q'); - build_underscore_int (i); - numeric_output_need_bar = 0; - } - build_overload_nested_name (decl); -} - -/* Output the mangled representation for TYPE. If EXTRA_GCODE is - non-zero, mangled names for structure/union types are intentionally - mangled differently from the method described in the ARM. */ - -static void -build_mangled_name_for_type_with_Gcode (type, extra_Gcode) - tree type; - int extra_Gcode; -{ - if (TYPE_PTRMEMFUNC_P (type)) - type = TYPE_PTRMEMFUNC_FN_TYPE (type); - type = canonical_type_variant (type); - process_modifiers (type); - process_overload_item (type, extra_Gcode); -} - -/* Like build_mangled_name_for_type_with_Gcode, but never outputs the - `G'. */ - -static void -build_mangled_name_for_type (type) - tree type; -{ - build_mangled_name_for_type_with_Gcode (type, 0); -} - -/* Given a list of parameters in PARMTYPES, create an unambiguous - overload string. Should distinguish any type that C (or C++) can - distinguish. I.e., pointers to functions are treated correctly. - - Caller must deal with whether a final `e' goes on the end or not. - - Any default conversions must take place before this function - is called. - - BEGIN and END control initialization and finalization of the - obstack where we build the string. */ - -char * -build_overload_name (parmtypes, begin, end) - tree parmtypes; - int begin, end; -{ - char *ret; - start_squangling (); - ret = build_mangled_name (parmtypes, begin, end); - end_squangling (); - return ret ; -} - -/* Output the mangled representation for PARMTYPES. If PARMTYPES is a - TREE_LIST, then it is a list of parameter types. Otherwise, - PARMTYPES must be a single type. */ - -static char * -build_mangled_name (parmtypes, begin, end) - tree parmtypes; - int begin, end; -{ - if (begin) - OB_INIT (); - - if (TREE_CODE (parmtypes) != TREE_LIST) - /* There is only one type. */ - build_mangled_name_for_type (parmtypes); - else - { - /* There are several types in a parameter list. */ - int nrepeats = 0; - int old_style_repeats = !flag_do_squangling && !nofold && typevec; - tree last_type = NULL_TREE; - - for (; parmtypes && parmtypes != void_list_node; - parmtypes = TREE_CHAIN (parmtypes)) - { - tree parmtype = canonical_type_variant (TREE_VALUE (parmtypes)); - - if (old_style_repeats) - { - /* Every argument gets counted. */ - my_friendly_assert (maxtype < typevec_size, 387); - typevec[maxtype++] = parmtype; - } - - if (parmtype == last_type) - { - if (flag_do_squangling - || (old_style_repeats && TREE_USED (parmtype) - && !TYPE_FOR_JAVA (parmtype))) - { - /* The next type is the same as this one. Keep - track of the repetition, and output the repeat - count later. */ - nrepeats++; - continue; - } - } - else if (nrepeats != 0) - { - /* Indicate how many times the previous parameter was - repeated. */ - if (old_style_repeats) - flush_repeats (nrepeats, last_type); - else - issue_nrepeats (nrepeats, last_type); - nrepeats = 0; - } - - last_type = parmtype; - - if (old_style_repeats) - { - if (nrepeats) - { - flush_repeats (nrepeats, last_type); - nrepeats = 0; - } - - if (TREE_USED (parmtype)) - { -#if 0 - /* We can turn this on at some point when we want - improved symbol mangling. */ - nrepeats++; -#else - /* This is bug compatible with 2.7.x */ - flush_repeats (nrepeats, parmtype); -#endif - nrepeats = 0; - continue; - } - - /* Only cache types which take more than one character. */ - if ((parmtype != TYPE_MAIN_VARIANT (parmtype) - || (TREE_CODE (parmtype) != INTEGER_TYPE - && TREE_CODE (parmtype) != REAL_TYPE)) - && ! TYPE_FOR_JAVA (parmtype)) - TREE_USED (parmtype) = 1; - } - - /* Output the PARMTYPE. */ - build_mangled_name_for_type_with_Gcode (parmtype, 1); - } - - /* Output the repeat count for the last parameter, if - necessary. */ - if (nrepeats != 0) - { - if (old_style_repeats) - flush_repeats (nrepeats, last_type); - else - issue_nrepeats (nrepeats, last_type); - nrepeats = 0; - } - - if (!parmtypes) - /* The parameter list ends in an ellipsis. */ - OB_PUTC ('e'); - } - - if (end) - OB_FINISH (); - return (char *)obstack_base (&scratch_obstack); -} - -/* handles emitting modifiers such as Constant, read-only, and volatile */ -static void -process_modifiers (parmtype) - tree parmtype; -{ - /* Note that here we do not use CP_TYPE_CONST_P and friends because - we describe types recursively; we will get the `const' in - `const int ()[10]' when processing the `const int' part. */ - if (TYPE_READONLY (parmtype)) - OB_PUTC ('C'); - if (TREE_CODE (parmtype) == INTEGER_TYPE - && (TYPE_MAIN_VARIANT (parmtype) - == unsigned_type (TYPE_MAIN_VARIANT (parmtype))) - && ! TYPE_FOR_JAVA (parmtype)) - OB_PUTC ('U'); - if (TYPE_VOLATILE (parmtype)) - OB_PUTC ('V'); - /* It would be better to use `R' for `restrict', but that's already - used for reference types. And `r' is used for `long double'. */ - if (TYPE_RESTRICT (parmtype)) - OB_PUTC ('u'); -} - -/* Check to see if TYPE has been entered into the Bcode typelist. If - so, return 1 and emit a backreference to TYPE. Otherwise, add TYPE - to the list of back-referenceable types and return 0. */ - -static int -check_btype (type) - tree type; -{ - int x; - - if (btypelist == NULL) - return 0; - - if (!is_back_referenceable_type (type)) - return 0; - - /* We assume that our caller has put out any necessary - qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - - for (x = 0; x < maxbtype; x++) - if (type == btypelist[x]) - { - OB_PUTC ('B'); - icat (x); - if (x > 9) - OB_PUTC ('_'); - return 1 ; - } - - if (maxbsize <= maxbtype) - { - /* Enlarge the table. */ - maxbsize = maxbsize * 3 / 2; - btypelist = (tree *)xrealloc (btypelist, sizeof (tree) * maxbsize); - } - - /* Register the TYPE. */ - btypelist[maxbtype++] = type; - - return 0; -} - -/* handle emitting the correct code for various node types */ -static void -process_overload_item (parmtype, extra_Gcode) - tree parmtype; - int extra_Gcode; -{ - numeric_output_need_bar = 0; - - /* These tree types are considered modifiers for B code squangling , */ - /* and therefore should not get entries in the Btypelist */ - /* they are, however, repeatable types */ - - switch (TREE_CODE (parmtype)) - { - case REFERENCE_TYPE: - OB_PUTC ('R'); - goto more; - - case ARRAY_TYPE: -#if PARM_CAN_BE_ARRAY_TYPE - { - OB_PUTC ('A'); - if (TYPE_DOMAIN (parmtype) == NULL_TREE) - OB_PUTC ('_'); - else - { - tree length = array_type_nelts (parmtype); - if (TREE_CODE (length) != INTEGER_CST || flag_do_squangling) - { - length = fold (build (PLUS_EXPR, TREE_TYPE (length), - length, integer_one_node)); - STRIP_NOPS (length); - } - build_overload_value (sizetype, length, 1); - } - if (numeric_output_need_bar && ! flag_do_squangling) - OB_PUTC ('_'); - goto more; - } -#else - OB_PUTC ('P'); - goto more; -#endif - - case POINTER_TYPE: - OB_PUTC ('P'); - more: - build_mangled_name_for_type (TREE_TYPE (parmtype)); - return; - break; - - default: - break; - } - - if (flag_do_squangling && check_btype (parmtype)) - /* If PARMTYPE is already in the list of back-referenceable types, - then check_btype will output the appropriate reference, and - there's nothing more to do. */ - return; - - switch (TREE_CODE (parmtype)) - { - case OFFSET_TYPE: - OB_PUTC ('O'); - build_mangled_name_for_type (TYPE_OFFSET_BASETYPE (parmtype)); - OB_PUTC ('_'); - build_mangled_name_for_type (TREE_TYPE (parmtype)); - break; - - case FUNCTION_TYPE: - case METHOD_TYPE: - { - tree parms = TYPE_ARG_TYPES (parmtype); - - /* Rather than implementing a reentrant TYPEVEC, we turn off - repeat codes here, unless we're squangling. Squangling - doesn't make use of the TYPEVEC, so there's no reentrancy - problem. */ - int old_nofold = nofold; - if (!flag_do_squangling) - nofold = 1; - - if (TREE_CODE (parmtype) == METHOD_TYPE) - { - /* Mark this as a method. */ - OB_PUTC ('M'); - /* Output the class of which this method is a member. */ - build_mangled_name_for_type (TYPE_METHOD_BASETYPE (parmtype)); - /* Output any qualifiers for the `this' parameter. */ - process_modifiers (TREE_TYPE (TREE_VALUE (parms))); - } - - /* Output the parameter types. */ - OB_PUTC ('F'); - if (parms == NULL_TREE) - OB_PUTC ('e'); - else if (parms == void_list_node) - OB_PUTC ('v'); - else - build_mangled_name (parms, 0, 0); - - /* Output the return type. */ - OB_PUTC ('_'); - build_mangled_name_for_type (TREE_TYPE (parmtype)); - - nofold = old_nofold; - break; - } - - case INTEGER_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); - if (parmtype == integer_type_node - || parmtype == unsigned_type_node - || parmtype == java_int_type_node) - OB_PUTC ('i'); - else if (parmtype == long_integer_type_node - || parmtype == long_unsigned_type_node) - OB_PUTC ('l'); - else if (parmtype == short_integer_type_node - || parmtype == short_unsigned_type_node - || parmtype == java_short_type_node) - OB_PUTC ('s'); - else if (parmtype == signed_char_type_node) - { - OB_PUTC ('S'); - OB_PUTC ('c'); - } - else if (parmtype == char_type_node - || parmtype == unsigned_char_type_node - || parmtype == java_byte_type_node) - OB_PUTC ('c'); - else if (parmtype == wchar_type_node - || parmtype == java_char_type_node) - OB_PUTC ('w'); - else if (parmtype == long_long_integer_type_node - || parmtype == long_long_unsigned_type_node - || parmtype == java_long_type_node) - OB_PUTC ('x'); - else if (parmtype == java_boolean_type_node) - OB_PUTC ('b'); -#if HOST_BITS_PER_WIDE_INT >= 64 - else if (parmtype == intTI_type_node - || parmtype == unsigned_intTI_type_node) - { - /* Should just check a flag here instead of specific - *_type_nodes, because all C9x types could use this. */ - int bits = TREE_INT_CST_LOW (TYPE_SIZE (parmtype)); - build_mangled_C9x_name (bits); - } -#endif - else - my_friendly_abort (73); - break; - - case BOOLEAN_TYPE: - OB_PUTC ('b'); - break; - - case REAL_TYPE: - parmtype = TYPE_MAIN_VARIANT (parmtype); - if (parmtype == long_double_type_node) - OB_PUTC ('r'); - else if (parmtype == double_type_node - || parmtype == java_double_type_node) - OB_PUTC ('d'); - else if (parmtype == float_type_node - || parmtype == java_float_type_node) - OB_PUTC ('f'); - else my_friendly_abort (74); - break; - - case COMPLEX_TYPE: - OB_PUTC ('J'); - build_mangled_name_for_type (TREE_TYPE (parmtype)); - break; - - case VOID_TYPE: - OB_PUTC ('v'); - break; - - case ERROR_MARK: /* not right, but nothing is anyway */ - break; - - /* have to do these */ - case UNION_TYPE: - case RECORD_TYPE: - { - if (extra_Gcode) - OB_PUTC ('G'); /* make it look incompatible with AT&T */ - /* drop through into next case */ - } - case ENUMERAL_TYPE: - { - tree name = TYPE_NAME (parmtype); - - my_friendly_assert (TREE_CODE (name) == TYPE_DECL, 248); - - build_qualified_name (name); - break; - } - - case UNKNOWN_TYPE: - /* This will take some work. */ - OB_PUTC ('?'); - break; - - case TEMPLATE_TEMPLATE_PARM: - /* Find and output the original template parameter - declaration. */ - if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parmtype)) - { - build_mangled_template_parm_index ("tzX", - TEMPLATE_TYPE_PARM_INDEX - (parmtype)); - build_template_parm_names - (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_TI_TEMPLATE (parmtype)), - TYPE_TI_ARGS (parmtype)); - } - else - { - build_mangled_template_parm_index ("ZzX", - TEMPLATE_TYPE_PARM_INDEX - (parmtype)); - build_template_template_parm_names - (DECL_INNERMOST_TEMPLATE_PARMS (TYPE_STUB_DECL (parmtype))); - } - break; - - case TEMPLATE_TYPE_PARM: - build_mangled_template_parm_index ("X", - TEMPLATE_TYPE_PARM_INDEX - (parmtype)); - break; - - case TYPENAME_TYPE: - /* When mangling the type of a function template whose - declaration looks like: - - template <class T> void foo(typename T::U) - - we have to mangle these. */ - build_qualified_name (parmtype); - break; - - default: - my_friendly_abort (75); - } - -} - -/* Produce the mangling for a variable named NAME in CONTEXT, which can - be either a class TYPE or a FUNCTION_DECL. */ - -tree -build_static_name (context, name) - tree context, name; -{ - OB_INIT (); - numeric_output_need_bar = 0; - start_squangling (); -#ifdef JOINER - OB_PUTC ('_'); - build_qualified_name (context); - OB_PUTC (JOINER); -#else - OB_PUTS ("__static_"); - build_qualified_name (context); - OB_PUTC ('_'); -#endif - OB_PUTID (name); - OB_FINISH (); - end_squangling (); - - return get_identifier ((char *)obstack_base (&scratch_obstack)); -} - -/* FOR_METHOD should be 1 if the declaration in question is for a member - of a class (including a static member) and 2 if the declaration is - for a constructor. */ -tree -build_decl_overload_real (dname, parms, ret_type, tparms, targs, - for_method) - tree dname; - tree parms; - tree ret_type; - tree tparms; - tree targs; - int for_method; -{ - char *name = IDENTIFIER_POINTER (dname); - - /* member operators new and delete look like methods at this point. */ - if (! for_method && parms != NULL_TREE && TREE_CODE (parms) == TREE_LIST - && TREE_CHAIN (parms) == void_list_node) - { - if (dname == ansi_opname[(int) DELETE_EXPR]) - return get_identifier ("__builtin_delete"); - else if (dname == ansi_opname[(int) VEC_DELETE_EXPR]) - return get_identifier ("__builtin_vec_delete"); - if (dname == ansi_opname[(int) NEW_EXPR]) - return get_identifier ("__builtin_new"); - else if (dname == ansi_opname[(int) VEC_NEW_EXPR]) - return get_identifier ("__builtin_vec_new"); - } - - start_squangling (); - OB_INIT (); - if (for_method != 2) - OB_PUTCP (name); - /* Otherwise, we can divine that this is a constructor, - and figure out its name without any extra encoding. */ - - OB_PUTC2 ('_', '_'); - numeric_output_need_bar = 0; - - if (tparms) - { - OB_PUTC ('H'); - build_template_parm_names (tparms, targs); - OB_PUTC ('_'); - } - else if (!for_method && current_namespace == global_namespace) - /* XXX this works only if we call this in the same namespace - as the declaration. Unfortunately, we don't have the _DECL, - only its name */ - OB_PUTC ('F'); - - if (!for_method && current_namespace != global_namespace) - /* qualify with namespace */ - build_qualified_name (current_namespace); - - if (parms == NULL_TREE) - OB_PUTC ('e'); - else if (parms == void_list_node) - OB_PUTC ('v'); - else - { - if (!flag_do_squangling) /* Allocate typevec array. */ - { - maxtype = 0; - typevec_size = list_length (parms); - if (!for_method && current_namespace != global_namespace) - /* the namespace of a global function needs one slot */ - typevec_size++; - typevec = (tree *)alloca (typevec_size * sizeof (tree)); - } - nofold = 0; - - if (for_method) - { - tree this_type = TREE_VALUE (parms); - - if (TREE_CODE (this_type) == RECORD_TYPE) /* a signature pointer */ - this_type = SIGNATURE_TYPE (this_type); - else - this_type = TREE_TYPE (this_type); - - build_mangled_name_for_type (this_type); - - if (!flag_do_squangling) - { - my_friendly_assert (maxtype < typevec_size, 387); - typevec[maxtype++] = this_type; - TREE_USED (this_type) = 1; - - /* By setting up PARMS in this way, the loop below will - automatically clear TREE_USED on THIS_TYPE. */ - parms = temp_tree_cons (NULL_TREE, this_type, - TREE_CHAIN (parms)); - } - - if (TREE_CHAIN (parms)) - build_mangled_name (TREE_CHAIN (parms), 0, 0); - else - OB_PUTC ('e'); - } - else - { - /* the namespace qualifier for a global function - will count as type */ - if (current_namespace != global_namespace - && !flag_do_squangling) - { - my_friendly_assert (maxtype < typevec_size, 387); - typevec[maxtype++] = current_namespace; - } - build_mangled_name (parms, 0, 0); - } - - if (!flag_do_squangling) /* Deallocate typevec array */ - { - tree t = parms; - typevec = NULL; - while (t) - { - tree temp = TREE_VALUE (t); - TREE_USED (temp) = 0; - /* clear out the type variant in case we used it */ - temp = canonical_type_variant (temp); - TREE_USED (temp) = 0; - t = TREE_CHAIN (t); - } - } - } - - if (ret_type != NULL_TREE && for_method != 2) - { - /* Add the return type. */ - OB_PUTC ('_'); - build_mangled_name_for_type (ret_type); - } - - OB_FINISH (); - end_squangling (); - { - tree n = get_identifier (obstack_base (&scratch_obstack)); - if (IDENTIFIER_OPNAME_P (dname)) - IDENTIFIER_OPNAME_P (n) = 1; - return n; - } -} - -/* Change the name of a function definition so that it may be - overloaded. NAME is the name of the function to overload, - PARMS is the parameter list (which determines what name the - final function obtains). - - FOR_METHOD is 1 if this overload is being performed - for a method, rather than a function type. It is 2 if - this overload is being performed for a constructor. */ - -tree -build_decl_overload (dname, parms, for_method) - tree dname; - tree parms; - int for_method; -{ - return build_decl_overload_real (dname, parms, NULL_TREE, NULL_TREE, - NULL_TREE, for_method); -} - -/* Set the mangled name (DECL_ASSEMBLER_NAME) for DECL. */ - -void -set_mangled_name_for_decl (decl) - tree decl; -{ - tree parm_types; - - if (processing_template_decl) - /* There's no need to mangle the name of a template function. */ - return; - - parm_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - - if (DECL_STATIC_FUNCTION_P (decl)) - parm_types = - hash_tree_chain (build_pointer_type (DECL_CLASS_CONTEXT (decl)), - parm_types); - else - /* The only member functions whose type is a FUNCTION_TYPE, rather - than a METHOD_TYPE, should be static members. */ - my_friendly_assert (!DECL_CONTEXT (decl) - || !IS_AGGR_TYPE_CODE (TREE_CODE (DECL_CONTEXT (decl))) - || TREE_CODE (TREE_TYPE (decl)) != FUNCTION_TYPE, - 0); - - DECL_ASSEMBLER_NAME (decl) - = build_decl_overload (DECL_NAME (decl), parm_types, - DECL_FUNCTION_MEMBER_P (decl) - + DECL_CONSTRUCTOR_P (decl)); -} - -/* Build an overload name for the type expression TYPE. */ - -tree -build_typename_overload (type) - tree type; -{ - tree id; - - OB_INIT (); - OB_PUTID (ansi_opname[(int) TYPE_EXPR]); - nofold = 1; - start_squangling (); - build_mangled_name (type, 0, 1); - id = get_identifier (obstack_base (&scratch_obstack)); - IDENTIFIER_OPNAME_P (id) = 1; -#if 0 - IDENTIFIER_GLOBAL_VALUE (id) = TYPE_MAIN_DECL (type); -#endif - TREE_TYPE (id) = type; - end_squangling (); - return id; -} - -tree -build_overload_with_type (name, type) - tree name, type; -{ - OB_INIT (); - OB_PUTID (name); - nofold = 1; - - start_squangling (); - build_mangled_name (type, 0, 1); - end_squangling (); - return get_identifier (obstack_base (&scratch_obstack)); -} - -tree -get_id_2 (name, name2) - char *name; - tree name2; -{ - OB_INIT (); - OB_PUTCP (name); - OB_PUTID (name2); - OB_FINISH (); - return get_identifier (obstack_base (&scratch_obstack)); -} - -/* Returns a DECL_ASSEMBLER_NAME for the destructor of type TYPE. */ - -tree -build_destructor_name (type) - tree type; -{ - return build_overload_with_type (get_identifier (DESTRUCTOR_DECL_PREFIX), - type); -} - -/* Given a tree_code CODE, and some arguments (at least one), - attempt to use an overloaded operator on the arguments. - - For unary operators, only the first argument need be checked. - For binary operators, both arguments may need to be checked. - - Member functions can convert class references to class pointers, - for one-level deep indirection. More than that is not supported. - Operators [](), ()(), and ->() must be member functions. - - We call function call building calls with LOOKUP_COMPLAIN if they - are our only hope. This is true when we see a vanilla operator - applied to something of aggregate type. If this fails, we are free - to return `error_mark_node', because we will have reported the - error. - - Operators NEW and DELETE overload in funny ways: operator new takes - a single `size' parameter, and operator delete takes a pointer to the - storage being deleted. When overloading these operators, success is - assumed. If there is a failure, report an error message and return - `error_mark_node'. */ - -/* NOSTRICT */ -tree -build_opfncall (code, flags, xarg1, xarg2, arg3) - enum tree_code code; - int flags; - tree xarg1, xarg2, arg3; -{ - return build_new_op (code, flags, xarg1, xarg2, arg3); -} - -/* This function takes an identifier, ID, and attempts to figure out what - it means. There are a number of possible scenarios, presented in increasing - order of hair: - - 1) not in a class's scope - 2) in class's scope, member name of the class's method - 3) in class's scope, but not a member name of the class - 4) in class's scope, member name of a class's variable - - NAME is $1 from the bison rule. It is an IDENTIFIER_NODE. - VALUE is $$ from the bison rule. It is the value returned by lookup_name ($1) - - As a last ditch, try to look up the name as a label and return that - address. - - Values which are declared as being of REFERENCE_TYPE are - automatically dereferenced here (as a hack to make the - compiler faster). */ - -tree -hack_identifier (value, name) - tree value, name; -{ - tree type; - - if (value == error_mark_node) - { - if (current_class_name) - { - tree fields = lookup_fnfields (TYPE_BINFO (current_class_type), name, 1); - if (fields == error_mark_node) - return error_mark_node; - if (fields) - { - tree fndecl; - - fndecl = TREE_VALUE (fields); - my_friendly_assert (TREE_CODE (fndecl) == FUNCTION_DECL, 251); - /* I could not trigger this code. MvL */ - my_friendly_abort (980325); -#ifdef DEAD - if (DECL_CHAIN (fndecl) == NULL_TREE) - { - warning ("methods cannot be converted to function pointers"); - return fndecl; - } - else - { - error ("ambiguous request for method pointer `%s'", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } -#endif - } - } - if (flag_labels_ok && IDENTIFIER_LABEL_VALUE (name)) - { - return IDENTIFIER_LABEL_VALUE (name); - } - return error_mark_node; - } - - type = TREE_TYPE (value); - if (TREE_CODE (value) == FIELD_DECL) - { - if (current_class_ptr == NULL_TREE) - { - if (current_function_decl - && DECL_STATIC_FUNCTION_P (current_function_decl)) - cp_error ("invalid use of member `%D' in static member function", - value); - else - /* We can get here when processing a bad default - argument, like: - struct S { int a; void f(int i = a); } */ - cp_error ("invalid use of member `%D'", value); - - return error_mark_node; - } - TREE_USED (current_class_ptr) = 1; - - /* Mark so that if we are in a constructor, and then find that - this field was initialized by a base initializer, - we can emit an error message. */ - TREE_USED (value) = 1; - value = build_component_ref (current_class_ref, name, NULL_TREE, 1); - } - else if (TREE_CODE (value) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (value)) - { - tree decl; - - if (IS_SIGNATURE (DECL_CLASS_CONTEXT (value))) - return value; - - decl = maybe_dummy_object (DECL_CLASS_CONTEXT (value), 0); - value = build_component_ref (decl, name, NULL_TREE, 1); - } - else if (really_overloaded_fn (value)) - { -#if 0 - tree t = get_first_fn (value); - for (; t; t = DECL_CHAIN (t)) - { - if (TREE_CODE (t) == TEMPLATE_DECL) - continue; - - assemble_external (t); - TREE_USED (t) = 1; - } -#endif - } - else if (TREE_CODE (value) == OVERLOAD) - /* not really overloaded function */ - mark_used (OVL_FUNCTION (value)); - else if (TREE_CODE (value) == TREE_LIST) - { - /* Ambiguous reference to base members, possibly other cases?. */ - tree t = value; - while (t && TREE_CODE (t) == TREE_LIST) - { - mark_used (TREE_VALUE (t)); - t = TREE_CHAIN (t); - } - } - else if (TREE_CODE (value) == NAMESPACE_DECL) - { - cp_error ("use of namespace `%D' as expression", value); - return error_mark_node; - } - else if (DECL_CLASS_TEMPLATE_P (value)) - { - cp_error ("use of class template `%T' as expression", value); - return error_mark_node; - } - else - mark_used (value); - - if (TREE_CODE (value) == VAR_DECL || TREE_CODE (value) == PARM_DECL - || TREE_CODE (value) == RESULT_DECL) - { - tree context = decl_function_context (value); - if (context != NULL_TREE && context != current_function_decl - && ! TREE_STATIC (value)) - { - cp_error ("use of %s from containing function", - (TREE_CODE (value) == VAR_DECL - ? "`auto' variable" : "parameter")); - cp_error_at (" `%#D' declared here", value); - value = error_mark_node; - } - } - - if (TREE_CODE_CLASS (TREE_CODE (value)) == 'd' && DECL_NONLOCAL (value)) - { - if (DECL_LANG_SPECIFIC (value) - && DECL_CLASS_CONTEXT (value) != current_class_type) - { - tree path, access; - register tree context - = (TREE_CODE (value) == FUNCTION_DECL && DECL_VIRTUAL_P (value)) - ? DECL_CLASS_CONTEXT (value) - : DECL_CONTEXT (value); - - get_base_distance (context, current_class_type, 0, &path); - if (path) - { - access = compute_access (path, value); - if (access != access_public_node) - { - if (TREE_CODE (value) == VAR_DECL) - error ("static member `%s' is %s", - IDENTIFIER_POINTER (name), - TREE_PRIVATE (value) ? "private" - : "from a private base class"); - else - error ("enum `%s' is from private base class", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - } - } - } - else if (TREE_CODE (value) == TREE_LIST && TREE_NONLOCAL_FLAG (value)) - { - error ("request for member `%s' is ambiguous in multiple inheritance lattice", - IDENTIFIER_POINTER (name)); - return error_mark_node; - } - - if (! processing_template_decl) - value = convert_from_reference (value); - return value; -} - - -tree -make_thunk (function, delta) - tree function; - int delta; -{ - tree thunk_id; - tree thunk; - tree func_decl; - - if (TREE_CODE (function) != ADDR_EXPR) - abort (); - func_decl = TREE_OPERAND (function, 0); - if (TREE_CODE (func_decl) != FUNCTION_DECL) - abort (); - - OB_INIT (); - OB_PUTS ("__thunk_"); - if (delta > 0) - { - OB_PUTC ('n'); - icat (delta); - } - else - icat (-delta); - OB_PUTC ('_'); - OB_PUTID (DECL_ASSEMBLER_NAME (func_decl)); - OB_FINISH (); - thunk_id = get_identifier (obstack_base (&scratch_obstack)); - - thunk = IDENTIFIER_GLOBAL_VALUE (thunk_id); - if (thunk && TREE_CODE (thunk) != THUNK_DECL) - { - cp_error ("implementation-reserved name `%D' used", thunk_id); - thunk = NULL_TREE; - SET_IDENTIFIER_GLOBAL_VALUE (thunk_id, thunk); - } - if (thunk == NULL_TREE) - { - thunk = build_decl (FUNCTION_DECL, thunk_id, TREE_TYPE (func_decl)); - TREE_READONLY (thunk) = TREE_READONLY (func_decl); - TREE_THIS_VOLATILE (thunk) = TREE_THIS_VOLATILE (func_decl); - comdat_linkage (thunk); - TREE_SET_CODE (thunk, THUNK_DECL); - DECL_INITIAL (thunk) = function; - THUNK_DELTA (thunk) = delta; - DECL_EXTERNAL (thunk) = 1; - DECL_ARTIFICIAL (thunk) = 1; - /* So that finish_file can write out any thunks that need to be: */ - pushdecl_top_level (thunk); - } - return thunk; -} - -/* Emit the definition of a C++ multiple inheritance vtable thunk. */ - -void -emit_thunk (thunk_fndecl) - tree thunk_fndecl; -{ - tree function = TREE_OPERAND (DECL_INITIAL (thunk_fndecl), 0); - int delta = THUNK_DELTA (thunk_fndecl); - - if (TREE_ASM_WRITTEN (thunk_fndecl)) - return; - - TREE_ASM_WRITTEN (thunk_fndecl) = 1; - - TREE_ADDRESSABLE (function) = 1; - mark_used (function); - - if (current_function_decl) - abort (); - - TREE_SET_CODE (thunk_fndecl, FUNCTION_DECL); - - { -#ifdef ASM_OUTPUT_MI_THUNK - char *fnname; - current_function_decl = thunk_fndecl; - /* Make sure we build up its RTL before we go onto the - temporary obstack. */ - make_function_rtl (thunk_fndecl); - temporary_allocation (); - DECL_RESULT (thunk_fndecl) - = build_decl (RESULT_DECL, 0, integer_type_node); - fnname = XSTR (XEXP (DECL_RTL (thunk_fndecl), 0), 0); - init_function_start (thunk_fndecl, input_filename, lineno); - current_function_is_thunk = 1; - assemble_start_function (thunk_fndecl, fnname); - ASM_OUTPUT_MI_THUNK (asm_out_file, thunk_fndecl, delta, function); - assemble_end_function (thunk_fndecl, fnname); - permanent_allocation (1); - current_function_decl = 0; -#else /* 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. - Unfortunately, this doesn't work for varargs. */ - - tree a, t; - - if (varargs_function_p (function)) - cp_error ("generic thunk code fails for method `%#D' which uses `...'", - function); - - /* Set up clone argument trees for the thunk. */ - t = NULL_TREE; - for (a = DECL_ARGUMENTS (function); a; a = TREE_CHAIN (a)) - { - tree x = copy_node (a); - TREE_CHAIN (x) = t; - DECL_CONTEXT (x) = thunk_fndecl; - t = x; - } - a = nreverse (t); - DECL_ARGUMENTS (thunk_fndecl) = a; - DECL_RESULT (thunk_fndecl) = NULL_TREE; - DECL_LANG_SPECIFIC (thunk_fndecl) = DECL_LANG_SPECIFIC (function); - copy_lang_decl (thunk_fndecl); - DECL_INTERFACE_KNOWN (thunk_fndecl) = 1; - DECL_NOT_REALLY_EXTERN (thunk_fndecl) = 1; - - start_function (NULL_TREE, thunk_fndecl, NULL_TREE, 1); - store_parm_decls (); - current_function_is_thunk = 1; - - /* Build up the call to the real function. */ - t = build_int_2 (delta, -1 * (delta < 0)); - TREE_TYPE (t) = signed_type (sizetype); - t = fold (build (PLUS_EXPR, TREE_TYPE (a), a, t)); - t = expr_tree_cons (NULL_TREE, t, NULL_TREE); - for (a = TREE_CHAIN (a); a; a = TREE_CHAIN (a)) - t = expr_tree_cons (NULL_TREE, a, t); - t = nreverse (t); - t = build_call (function, TREE_TYPE (TREE_TYPE (function)), t); - c_expand_return (t); - - finish_function (lineno, 0, 0); - - /* Don't let the backend defer this function. */ - if (DECL_DEFER_OUTPUT (thunk_fndecl)) - { - output_inline_function (thunk_fndecl); - permanent_allocation (1); - } -#endif /* ASM_OUTPUT_MI_THUNK */ - } - - TREE_SET_CODE (thunk_fndecl, THUNK_DECL); -} - -/* Code for synthesizing methods which have default semantics defined. */ - -/* For the anonymous union in TYPE, return the member that is at least as - large as the rest of the members, so we can copy it. */ - -static tree -largest_union_member (type) - tree type; -{ - tree f, type_size = TYPE_SIZE (type); - - for (f = TYPE_FIELDS (type); f; f = TREE_CHAIN (f)) - if (simple_cst_equal (DECL_SIZE (f), type_size) == 1) - return f; - - /* We should always find one. */ - my_friendly_abort (323); - return NULL_TREE; -} - -/* Generate code for default X(X&) constructor. */ - -static void -do_build_copy_constructor (fndecl) - tree fndecl; -{ - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); - tree t; - - clear_last_expr (); - push_momentary (); - - if (TYPE_USES_VIRTUAL_BASECLASSES (current_class_type)) - parm = TREE_CHAIN (parm); - parm = convert_from_reference (parm); - - if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type) - && is_empty_class (current_class_type)) - /* Don't copy the padding byte; it might not have been allocated - if *this is a base subobject. */; - else if (TYPE_HAS_TRIVIAL_INIT_REF (current_class_type)) - { - t = build (INIT_EXPR, void_type_node, current_class_ref, parm); - TREE_SIDE_EFFECTS (t) = 1; - cplus_expand_expr_stmt (t); - } - else - { - tree fields = TYPE_FIELDS (current_class_type); - int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); - tree binfos = TYPE_BINFO_BASETYPES (current_class_type); - int i; - - for (t = CLASSTYPE_VBASECLASSES (current_class_type); t; - t = TREE_CHAIN (t)) - { - tree basetype = BINFO_TYPE (t); - tree p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - p = convert_from_reference (p); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } - - for (i = 0; i < n_bases; ++i) - { - tree p, basetype = TREE_VEC_ELT (binfos, i); - if (TREE_VIA_VIRTUAL (basetype)) - continue; - - basetype = BINFO_TYPE (basetype); - p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - - if (p == error_mark_node) - cp_error ("in default copy constructor"); - else - { - p = convert_from_reference (p); - current_base_init_list = tree_cons (basetype, - p, current_base_init_list); - } - } - for (; fields; fields = TREE_CHAIN (fields)) - { - tree init, t; - tree field = fields; - - if (TREE_CODE (field) != FIELD_DECL) - continue; - - init = parm; - if (DECL_NAME (field)) - { - if (VFIELD_NAME_P (DECL_NAME (field))) - continue; - if (VBASE_NAME_P (DECL_NAME (field))) - continue; - - /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) - continue; - } - else if ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_UNION_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE) - { - do - { - init = build (COMPONENT_REF, t, init, field); - field = largest_union_member (t); - } - while ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_UNION_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE); - } - else - continue; - - init = build (COMPONENT_REF, TREE_TYPE (field), init, field); - init = build_tree_list (NULL_TREE, init); - - current_member_init_list - = tree_cons (DECL_NAME (field), init, current_member_init_list); - } - current_member_init_list = nreverse (current_member_init_list); - current_base_init_list = nreverse (current_base_init_list); - setup_vtbl_ptr (); - } - - pop_momentary (); -} - -static void -do_build_assign_ref (fndecl) - tree fndecl; -{ - tree parm = TREE_CHAIN (DECL_ARGUMENTS (fndecl)); - - clear_last_expr (); - push_momentary (); - - parm = convert_from_reference (parm); - - if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type) - && is_empty_class (current_class_type)) - /* Don't copy the padding byte; it might not have been allocated - if *this is a base subobject. */; - else if (TYPE_HAS_TRIVIAL_ASSIGN_REF (current_class_type)) - { - tree t = build (MODIFY_EXPR, void_type_node, current_class_ref, parm); - TREE_SIDE_EFFECTS (t) = 1; - cplus_expand_expr_stmt (t); - } - else - { - tree fields = TYPE_FIELDS (current_class_type); - int n_bases = CLASSTYPE_N_BASECLASSES (current_class_type); - tree binfos = TYPE_BINFO_BASETYPES (current_class_type); - int i; - - for (i = 0; i < n_bases; ++i) - { - tree basetype = BINFO_TYPE (TREE_VEC_ELT (binfos, i)); - tree p = convert_to_reference - (build_reference_type (basetype), parm, - CONV_IMPLICIT|CONV_CONST, LOOKUP_COMPLAIN, NULL_TREE); - p = convert_from_reference (p); - p = build_member_call (basetype, ansi_opname [MODIFY_EXPR], - build_expr_list (NULL_TREE, p)); - expand_expr_stmt (p); - } - for (; fields; fields = TREE_CHAIN (fields)) - { - tree comp, init, t; - tree field = fields; - - if (TREE_CODE (field) != FIELD_DECL) - continue; - - if (TREE_READONLY (field)) - { - if (DECL_NAME (field)) - cp_error ("non-static const member `%#D', can't use default assignment operator", field); - else - cp_error ("non-static const member in type `%T', can't use default assignment operator", current_class_type); - continue; - } - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) - { - if (DECL_NAME (field)) - cp_error ("non-static reference member `%#D', can't use default assignment operator", field); - else - cp_error ("non-static reference member in type `%T', can't use default assignment operator", current_class_type); - continue; - } - - comp = current_class_ref; - init = parm; - - if (DECL_NAME (field)) - { - if (VFIELD_NAME_P (DECL_NAME (field))) - continue; - if (VBASE_NAME_P (DECL_NAME (field))) - continue; - - /* True for duplicate members. */ - if (IDENTIFIER_CLASS_VALUE (DECL_NAME (field)) != field) - continue; - } - else if ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_UNION_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE) - { - do - { - comp = build (COMPONENT_REF, t, comp, field); - init = build (COMPONENT_REF, t, init, field); - field = largest_union_member (t); - } - while ((t = TREE_TYPE (field)) != NULL_TREE - && ANON_UNION_TYPE_P (t) - && TYPE_FIELDS (t) != NULL_TREE); - } - else - continue; - - comp = build (COMPONENT_REF, TREE_TYPE (field), comp, field); - init = build (COMPONENT_REF, TREE_TYPE (field), init, field); - - expand_expr_stmt (build_modify_expr (comp, NOP_EXPR, init)); - } - } - c_expand_return (current_class_ref); - pop_momentary (); -} - -void -synthesize_method (fndecl) - tree fndecl; -{ - int nested = (current_function_decl != NULL_TREE); - tree context = hack_decl_function_context (fndecl); - - if (at_eof) - import_export_decl (fndecl); - - if (! context) - push_to_top_level (); - else if (nested) - push_cp_function_context (context); - - interface_unknown = 1; - start_function (NULL_TREE, fndecl, NULL_TREE, 1); - store_parm_decls (); - - if (DECL_NAME (fndecl) == ansi_opname[MODIFY_EXPR]) - do_build_assign_ref (fndecl); - else if (DESTRUCTOR_NAME_P (DECL_ASSEMBLER_NAME (fndecl))) - ; - else - { - tree arg_chain = FUNCTION_ARG_CHAIN (fndecl); - if (DECL_CONSTRUCTOR_FOR_VBASE_P (fndecl)) - arg_chain = TREE_CHAIN (arg_chain); - if (arg_chain != void_list_node) - do_build_copy_constructor (fndecl); - else if (TYPE_NEEDS_CONSTRUCTING (current_class_type)) - setup_vtbl_ptr (); - } - - finish_function (lineno, 0, nested); - - extract_interface_info (); - if (! context) - pop_from_top_level (); - else if (nested) - pop_cp_function_context (context); -} diff --git a/gcc/cp/new.cc b/gcc/cp/new.cc deleted file mode 100755 index df921c3..0000000 --- a/gcc/cp/new.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Implementation file for the -*- C++ -*- dynamic memory management header. -// Copyright (C) 1996, 1997, 1998 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -#pragma implementation "new" -#include "new" - -/* CYGNUS LOCAL embedded c++ */ -#ifndef __EMBEDDED_CXX__ -const std::nothrow_t std::nothrow = { }; -#endif -/* END CYGNUS LOCAL */ - -using std::new_handler; -new_handler __new_handler; - -new_handler -set_new_handler (new_handler handler) -{ - new_handler prev_handler = __new_handler; - __new_handler = handler; - return prev_handler; -} diff --git a/gcc/cp/new1.cc b/gcc/cp/new1.cc deleted file mode 100755 index c80e69e..0000000 --- a/gcc/cp/new1.cc +++ /dev/null @@ -1,99 +0,0 @@ -// Support routines for the -*- C++ -*- dynamic memory management. -// Copyright (C) 1997, 1998, 1999 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -#include "new" -using std::new_handler; -using std::bad_alloc; - -extern "C" void *malloc (size_t); -extern new_handler __new_handler; - -#define WEAK(x) \ - x __attribute__ ((weak)); \ - x - -#ifdef L_op_newnt -WEAK (void * operator new (size_t sz, const std::nothrow_t&) __GCC_THROW(__GCC_nothing)) -{ - void *p; - - /* malloc (0) is unpredictable; avoid it. */ - if (sz == 0) - sz = 1; - p = (void *) malloc (sz); - while (p == 0) - { - new_handler handler = __new_handler; - if (! handler) - return 0; -/* CYGNUS LOCAL embedded C++ */ -#ifdef __EMBEDDED_CXX__ - handler (); -#else - try - { - handler (); - } - catch (bad_alloc &) - { - return 0; - } -#endif -/* END CYGNUS LOCAL */ - - p = (void *) malloc (sz); - } - - return p; -} -#endif - -#ifdef L_op_new -WEAK (void * operator new (size_t sz) __GCC_THROW (std::bad_alloc)) -{ - void *p; - - /* malloc (0) is unpredictable; avoid it. */ - if (sz == 0) - sz = 1; - p = (void *) malloc (sz); - while (p == 0) - { - new_handler handler = __new_handler; -/* CYGNUS LOCAL embedded C++ */ -#ifndef __EMBEDDED_CXX__ - if (! handler) - throw bad_alloc (); -#endif -/* END CYGNUS LOCAL */ - handler (); - p = (void *) malloc (sz); - } - - return p; -} -#endif diff --git a/gcc/cp/new2.cc b/gcc/cp/new2.cc deleted file mode 100755 index 82cb169..0000000 --- a/gcc/cp/new2.cc +++ /dev/null @@ -1,80 +0,0 @@ -// Boilerplate support routines for -*- C++ -*- dynamic memory management. -// Copyright (C) 1997, 1998, 1999 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -#include "new" - -extern "C" void free (void *); - -#define WEAK(x) \ - x __attribute__ ((weak)); \ - x - -#ifdef L_op_vnew -WEAK(void * operator new[] (size_t sz) __GCC_THROW (std::bad_alloc)) -{ - return ::operator new(sz); -} -#endif - -#ifdef L_op_vnewnt -WEAK(void *operator new[] (size_t sz, const std::nothrow_t& nothrow) __GCC_THROW(__GCC_nothing)) -{ - return ::operator new(sz, nothrow); -} -#endif - -#ifdef L_op_delete -WEAK (void operator delete (void *ptr) __GCC_THROW (__GCC_nothing)) -{ - if (ptr) - free (ptr); -} -#endif - -#ifdef L_op_vdel -WEAK (void operator delete[] (void *ptr) __GCC_THROW (__GCC_nothing)) -{ - if (ptr) - free (ptr); -} -#endif - -#ifdef L_op_delnt -WEAK (void operator delete (void *ptr, const std::nothrow_t&) __GCC_THROW (__GCC_nothing)) -{ - if (ptr) - free (ptr); -} -#endif - -#ifdef L_op_vdelnt -WEAK (void operator delete[] (void *ptr, const std::nothrow_t&) __GCC_THROW (__GCC_nothing)) -{ - if (ptr) - free (ptr); -} -#endif diff --git a/gcc/cp/parse.c b/gcc/cp/parse.c deleted file mode 100644 index a7424d7..0000000 --- a/gcc/cp/parse.c +++ /dev/null @@ -1,9814 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton implementation for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* C LALR(1) parser skeleton written by Richard Stallman, by - simplifying the original so-called "semantic" parser. */ - -/* All symbols defined below should begin with yy or YY, to avoid - infringing on user name space. This should be done even for local - variables, as they might otherwise be expanded by user macros. - There are some unavoidable exceptions within include files to - define necessary library symbols; they are noted "INFRINGES ON - USER NAME SPACE" below. */ - -/* Identify Bison output. */ -#define YYBISON 1 - -/* Bison version. */ -#define YYBISON_VERSION "2.3" - -/* Skeleton name. */ -#define YYSKELETON_NAME "yacc.c" - -/* Pure parsers. */ -#define YYPURE 0 - -/* Using locations. */ -#define YYLSP_NEEDED 0 - - - -/* Tokens. */ -#ifndef YYTOKENTYPE -# define YYTOKENTYPE - /* Put the tokens into the symbol table, so that GDB and other debuggers - know about them. */ - enum yytokentype { - IDENTIFIER = 258, - TYPENAME = 259, - SELFNAME = 260, - PFUNCNAME = 261, - SCSPEC = 262, - TYPESPEC = 263, - CV_QUALIFIER = 264, - CONSTANT = 265, - STRING = 266, - ELLIPSIS = 267, - SIZEOF = 268, - ENUM = 269, - IF = 270, - ELSE = 271, - WHILE = 272, - DO = 273, - FOR = 274, - SWITCH = 275, - CASE = 276, - DEFAULT = 277, - BREAK = 278, - CONTINUE = 279, - RETURN = 280, - GOTO = 281, - ASM_KEYWORD = 282, - TYPEOF = 283, - ALIGNOF = 284, - SIGOF = 285, - ATTRIBUTE = 286, - EXTENSION = 287, - LABEL = 288, - REALPART = 289, - IMAGPART = 290, - AGGR = 291, - VISSPEC = 292, - DELETE = 293, - NEW = 294, - THIS = 295, - OPERATOR = 296, - CXX_TRUE = 297, - CXX_FALSE = 298, - NAMESPACE = 299, - TYPENAME_KEYWORD = 300, - USING = 301, - LEFT_RIGHT = 302, - TEMPLATE = 303, - TYPEID = 304, - DYNAMIC_CAST = 305, - STATIC_CAST = 306, - REINTERPRET_CAST = 307, - CONST_CAST = 308, - SCOPE = 309, - EMPTY = 310, - NSNAME = 311, - PTYPENAME = 312, - THROW = 313, - ASSIGN = 314, - OROR = 315, - ANDAND = 316, - MIN_MAX = 317, - EQCOMPARE = 318, - ARITHCOMPARE = 319, - RSHIFT = 320, - LSHIFT = 321, - DOT_STAR = 322, - POINTSAT_STAR = 323, - MINUSMINUS = 324, - PLUSPLUS = 325, - UNARY = 326, - HYPERUNARY = 327, - PAREN_STAR_PAREN = 328, - POINTSAT = 329, - CATCH = 330, - TRY = 331, - PRE_PARSED_FUNCTION_DECL = 332, - EXTERN_LANG_STRING = 333, - ALL = 334, - PRE_PARSED_CLASS_DECL = 335, - DEFARG = 336, - DEFARG_MARKER = 337, - TYPENAME_DEFN = 338, - IDENTIFIER_DEFN = 339, - PTYPENAME_DEFN = 340, - END_OF_LINE = 341, - END_OF_SAVED_INPUT = 342 - }; -#endif -/* Tokens. */ -#define IDENTIFIER 258 -#define TYPENAME 259 -#define SELFNAME 260 -#define PFUNCNAME 261 -#define SCSPEC 262 -#define TYPESPEC 263 -#define CV_QUALIFIER 264 -#define CONSTANT 265 -#define STRING 266 -#define ELLIPSIS 267 -#define SIZEOF 268 -#define ENUM 269 -#define IF 270 -#define ELSE 271 -#define WHILE 272 -#define DO 273 -#define FOR 274 -#define SWITCH 275 -#define CASE 276 -#define DEFAULT 277 -#define BREAK 278 -#define CONTINUE 279 -#define RETURN 280 -#define GOTO 281 -#define ASM_KEYWORD 282 -#define TYPEOF 283 -#define ALIGNOF 284 -#define SIGOF 285 -#define ATTRIBUTE 286 -#define EXTENSION 287 -#define LABEL 288 -#define REALPART 289 -#define IMAGPART 290 -#define AGGR 291 -#define VISSPEC 292 -#define DELETE 293 -#define NEW 294 -#define THIS 295 -#define OPERATOR 296 -#define CXX_TRUE 297 -#define CXX_FALSE 298 -#define NAMESPACE 299 -#define TYPENAME_KEYWORD 300 -#define USING 301 -#define LEFT_RIGHT 302 -#define TEMPLATE 303 -#define TYPEID 304 -#define DYNAMIC_CAST 305 -#define STATIC_CAST 306 -#define REINTERPRET_CAST 307 -#define CONST_CAST 308 -#define SCOPE 309 -#define EMPTY 310 -#define NSNAME 311 -#define PTYPENAME 312 -#define THROW 313 -#define ASSIGN 314 -#define OROR 315 -#define ANDAND 316 -#define MIN_MAX 317 -#define EQCOMPARE 318 -#define ARITHCOMPARE 319 -#define RSHIFT 320 -#define LSHIFT 321 -#define DOT_STAR 322 -#define POINTSAT_STAR 323 -#define MINUSMINUS 324 -#define PLUSPLUS 325 -#define UNARY 326 -#define HYPERUNARY 327 -#define PAREN_STAR_PAREN 328 -#define POINTSAT 329 -#define CATCH 330 -#define TRY 331 -#define PRE_PARSED_FUNCTION_DECL 332 -#define EXTERN_LANG_STRING 333 -#define ALL 334 -#define PRE_PARSED_CLASS_DECL 335 -#define DEFARG 336 -#define DEFARG_MARKER 337 -#define TYPENAME_DEFN 338 -#define IDENTIFIER_DEFN 339 -#define PTYPENAME_DEFN 340 -#define END_OF_LINE 341 -#define END_OF_SAVED_INPUT 342 - - - - -/* Copy the first part of user declarations. */ -#line 29 "../../../gbagnu/gcc/cp/parse.y" - -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#include "config.h" - -#include "system.h" - -#include "tree.h" -#include "input.h" -#include "flags.h" -#include "lex.h" -#include "cp-tree.h" -#include "output.h" -#include "except.h" -#include "toplev.h" - -/* Since parsers are distinct for each language, put the language string - definition here. (fnf) */ -char *language_string = "GNU C++"; - -extern tree void_list_node; -extern struct obstack permanent_obstack; - -extern int end_of_file; - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -#define OP0(NODE) (TREE_OPERAND (NODE, 0)) -#define OP1(NODE) (TREE_OPERAND (NODE, 1)) - -/* Contains the statement keyword (if/while/do) to include in an - error message if the user supplies an empty conditional expression. */ -static char *cond_stmt_keyword; - -static tree empty_parms PROTO((void)); - -/* Nonzero if we have an `extern "C"' acting as an extern specifier. */ -int have_extern_spec; -int used_extern_spec; - -/* Cons up an empty parameter list. */ -#ifdef __GNUC__ -__inline -#endif -static tree -empty_parms () -{ - tree parms; - - if (strict_prototype - || current_class_type != NULL) - parms = void_list_node; - else - parms = NULL_TREE; - return parms; -} - - - -/* Enabling traces. */ -#ifndef YYDEBUG -# define YYDEBUG 0 -#endif - -/* Enabling verbose error messages. */ -#ifdef YYERROR_VERBOSE -# undef YYERROR_VERBOSE -# define YYERROR_VERBOSE 1 -#else -# define YYERROR_VERBOSE 0 -#endif - -/* Enabling the token table. */ -#ifndef YYTOKEN_TABLE -# define YYTOKEN_TABLE 0 -#endif - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 92 "../../../gbagnu/gcc/cp/parse.y" -{long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } -/* Line 187 of yacc.c. */ -#line 333 "parse.c" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - - - -/* Copy the second part of user declarations. */ -#line 284 "../../../gbagnu/gcc/cp/parse.y" - -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* List of prefix attributes in effect. - Prefix attributes are parsed by the reserved_declspecs and declmods - rules. They create a list that contains *both* declspecs and attrs. */ -/* ??? It is not clear yet that all cases where an attribute can now appear in - a declspec list have been updated. */ -static tree prefix_attributes; - -/* When defining an aggregate, this is the kind of the most recent one - being defined. (For example, this might be class_type_node.) */ -static tree current_aggr; - -/* When defining an enumeration, this is the type of the enumeration. */ -static tree current_enum_type; - -/* Tell yyparse how to print a token's value, if yydebug is set. */ - -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern tree combine_strings PROTO((tree)); - -static int -parse_decl(declarator, specs_attrs, attributes, initialized, decl) - tree declarator; - tree specs_attrs; - tree attributes; - int initialized; - tree* decl; -{ - int sm; - - split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); - if (current_declspecs - && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = get_decl_list (current_declspecs); - if (have_extern_spec && !used_extern_spec) - { - current_declspecs = decl_tree_cons (NULL_TREE, - get_identifier ("extern"), - current_declspecs); - used_extern_spec = 1; - } - sm = suspend_momentary (); - *decl = start_decl (declarator, current_declspecs, initialized, - attributes, prefix_attributes); - return sm; -} - - -/* Line 216 of yacc.c. */ -#line 397 "parse.c" - -#ifdef short -# undef short -#endif - -#ifdef YYTYPE_UINT8 -typedef YYTYPE_UINT8 yytype_uint8; -#else -typedef unsigned char yytype_uint8; -#endif - -#ifdef YYTYPE_INT8 -typedef YYTYPE_INT8 yytype_int8; -#elif (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -typedef signed char yytype_int8; -#else -typedef short int yytype_int8; -#endif - -#ifdef YYTYPE_UINT16 -typedef YYTYPE_UINT16 yytype_uint16; -#else -typedef unsigned short int yytype_uint16; -#endif - -#ifdef YYTYPE_INT16 -typedef YYTYPE_INT16 yytype_int16; -#else -typedef short int yytype_int16; -#endif - -#ifndef YYSIZE_T -# ifdef __SIZE_TYPE__ -# define YYSIZE_T __SIZE_TYPE__ -# elif defined size_t -# define YYSIZE_T size_t -# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ -# define YYSIZE_T size_t -# else -# define YYSIZE_T unsigned int -# endif -#endif - -#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) - -#ifndef YY_ -# if YYENABLE_NLS -# if ENABLE_NLS -# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ -# define YY_(msgid) dgettext ("bison-runtime", msgid) -# endif -# endif -# ifndef YY_ -# define YY_(msgid) msgid -# endif -#endif - -/* Suppress unused-variable warnings by "using" E. */ -#if ! defined lint || defined __GNUC__ -# define YYUSE(e) ((void) (e)) -#else -# define YYUSE(e) /* empty */ -#endif - -/* Identity function, used to suppress warnings about constant conditions. */ -#ifndef lint -# define YYID(n) (n) -#else -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static int -YYID (int i) -#else -static int -YYID (i) - int i; -#endif -{ - return i; -} -#endif - -#if ! defined yyoverflow || YYERROR_VERBOSE - -/* The parser invokes alloca or malloc; define the necessary symbols. */ - -# ifdef YYSTACK_USE_ALLOCA -# if YYSTACK_USE_ALLOCA -# ifdef __GNUC__ -# define YYSTACK_ALLOC __builtin_alloca -# elif defined __BUILTIN_VA_ARG_INCR -# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ -# elif defined _AIX -# define YYSTACK_ALLOC __alloca -# elif defined _MSC_VER -# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ -# define alloca _alloca -# else -# define YYSTACK_ALLOC alloca -# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# endif -# endif -# endif - -# ifdef YYSTACK_ALLOC - /* Pacify GCC's `empty if-body' warning. */ -# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) -# ifndef YYSTACK_ALLOC_MAXIMUM - /* The OS might guarantee only one guard page at the bottom of the stack, - and a page size can be as small as 4096 bytes. So we cannot safely - invoke alloca (N) if N exceeds 4096. Use a slightly smaller number - to allow for a few compiler-allocated temporary stack slots. */ -# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ -# endif -# else -# define YYSTACK_ALLOC YYMALLOC -# define YYSTACK_FREE YYFREE -# ifndef YYSTACK_ALLOC_MAXIMUM -# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM -# endif -# if (defined __cplusplus && ! defined _STDLIB_H \ - && ! ((defined YYMALLOC || defined malloc) \ - && (defined YYFREE || defined free))) -# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ -# ifndef _STDLIB_H -# define _STDLIB_H 1 -# endif -# endif -# ifndef YYMALLOC -# define YYMALLOC malloc -# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# ifndef YYFREE -# define YYFREE free -# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -void free (void *); /* INFRINGES ON USER NAME SPACE */ -# endif -# endif -# endif -#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ - - -#if (! defined yyoverflow \ - && (! defined __cplusplus \ - || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) - -/* A type that is properly aligned for any stack member. */ -union yyalloc -{ - yytype_int16 yyss; - YYSTYPE yyvs; - }; - -/* The size of the maximum gap between one aligned stack and the next. */ -# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) - -/* The size of an array large to enough to hold all stacks, each with - N elements. */ -# define YYSTACK_BYTES(N) \ - ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ - + YYSTACK_GAP_MAXIMUM) - -/* Copy COUNT objects from FROM to TO. The source and destination do - not overlap. */ -# ifndef YYCOPY -# if defined __GNUC__ && 1 < __GNUC__ -# define YYCOPY(To, From, Count) \ - __builtin_memcpy (To, From, (Count) * sizeof (*(From))) -# else -# define YYCOPY(To, From, Count) \ - do \ - { \ - YYSIZE_T yyi; \ - for (yyi = 0; yyi < (Count); yyi++) \ - (To)[yyi] = (From)[yyi]; \ - } \ - while (YYID (0)) -# endif -# endif - -/* Relocate STACK from its old location to the new one. The - local variables YYSIZE and YYSTACKSIZE give the old and new number of - elements in the stack, and YYPTR gives the new location of the - stack. Advance YYPTR to a properly aligned location for the next - stack. */ -# define YYSTACK_RELOCATE(Stack) \ - do \ - { \ - YYSIZE_T yynewbytes; \ - YYCOPY (&yyptr->Stack, Stack, yysize); \ - Stack = &yyptr->Stack; \ - yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ - yyptr += yynewbytes / sizeof (*yyptr); \ - } \ - while (YYID (0)) - -#endif - -/* YYFINAL -- State number of the termination state. */ -#define YYFINAL 4 -/* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 11289 - -/* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 112 -/* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 289 -/* YYNRULES -- Number of rules. */ -#define YYNRULES 879 -/* YYNRULES -- Number of states. */ -#define YYNSTATES 1630 - -/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ -#define YYUNDEFTOK 2 -#define YYMAXUTOK 342 - -#define YYTRANSLATE(YYX) \ - ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) - -/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ -static const yytype_uint8 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, 110, 2, 2, 2, 82, 70, 2, - 92, 108, 80, 78, 59, 79, 91, 81, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 62, 60, - 73, 63, 74, 65, 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, 93, 2, 111, 69, 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, 58, 68, 109, 85, 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, 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, 61, 64, 66, 67, 71, 72, 75, - 76, 77, 83, 84, 86, 87, 88, 89, 90, 94, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107 -}; - -#if YYDEBUG -/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in - YYRHS. */ -static const yytype_uint16 yyprhs[] = -{ - 0, 0, 3, 4, 6, 7, 10, 13, 15, 16, - 17, 18, 20, 22, 23, 26, 29, 31, 33, 39, - 44, 50, 55, 56, 63, 64, 70, 72, 75, 77, - 80, 81, 88, 91, 95, 99, 103, 107, 112, 113, - 119, 122, 126, 128, 130, 133, 136, 138, 141, 142, - 148, 152, 154, 158, 160, 161, 164, 167, 171, 173, - 177, 179, 183, 185, 189, 192, 195, 198, 200, 202, - 208, 213, 216, 219, 223, 227, 230, 233, 237, 241, - 244, 247, 250, 253, 256, 258, 260, 262, 263, 265, - 268, 269, 271, 276, 280, 284, 285, 294, 300, 301, - 311, 318, 319, 328, 334, 335, 345, 352, 355, 358, - 360, 363, 365, 372, 377, 384, 389, 392, 394, 397, - 400, 402, 405, 407, 410, 413, 418, 421, 425, 426, - 427, 429, 433, 436, 440, 442, 447, 450, 455, 458, - 463, 466, 468, 470, 472, 474, 476, 478, 480, 482, - 484, 486, 488, 489, 496, 497, 504, 505, 511, 512, - 518, 519, 527, 528, 536, 537, 544, 545, 552, 553, - 554, 560, 566, 568, 570, 576, 582, 583, 585, 587, - 588, 590, 592, 596, 598, 600, 602, 604, 606, 608, - 610, 612, 614, 616, 618, 622, 624, 628, 629, 631, - 633, 634, 642, 644, 646, 650, 655, 659, 660, 664, - 666, 670, 674, 678, 682, 684, 686, 688, 691, 694, - 697, 700, 703, 706, 709, 714, 717, 722, 725, 729, - 733, 738, 744, 751, 758, 766, 769, 774, 780, 783, - 786, 788, 789, 794, 799, 803, 805, 809, 812, 816, - 821, 823, 826, 832, 834, 838, 842, 846, 850, 854, - 858, 862, 866, 870, 874, 878, 882, 886, 890, 894, - 898, 902, 906, 910, 916, 920, 924, 926, 929, 933, - 937, 939, 941, 943, 945, 947, 948, 954, 960, 966, - 972, 978, 980, 982, 984, 986, 989, 991, 994, 997, - 1001, 1006, 1011, 1013, 1015, 1017, 1021, 1023, 1025, 1027, - 1029, 1033, 1037, 1041, 1042, 1047, 1052, 1055, 1060, 1063, - 1068, 1071, 1074, 1076, 1081, 1083, 1091, 1099, 1107, 1115, - 1120, 1125, 1128, 1131, 1134, 1136, 1141, 1144, 1147, 1153, - 1157, 1160, 1163, 1169, 1173, 1179, 1183, 1188, 1195, 1198, - 1200, 1203, 1205, 1208, 1210, 1212, 1214, 1217, 1218, 1221, - 1224, 1228, 1232, 1236, 1239, 1242, 1245, 1247, 1249, 1251, - 1254, 1257, 1260, 1263, 1265, 1267, 1269, 1271, 1274, 1277, - 1281, 1285, 1289, 1294, 1296, 1299, 1302, 1305, 1307, 1309, - 1311, 1314, 1317, 1320, 1322, 1324, 1327, 1330, 1334, 1336, - 1339, 1341, 1343, 1345, 1350, 1355, 1360, 1365, 1367, 1369, - 1371, 1373, 1377, 1379, 1383, 1385, 1389, 1390, 1395, 1396, - 1403, 1407, 1408, 1413, 1415, 1419, 1423, 1424, 1429, 1433, - 1434, 1436, 1438, 1441, 1448, 1450, 1454, 1455, 1457, 1462, - 1469, 1474, 1476, 1478, 1480, 1482, 1484, 1488, 1489, 1492, - 1494, 1497, 1501, 1506, 1508, 1510, 1514, 1519, 1523, 1529, - 1531, 1536, 1540, 1544, 1545, 1549, 1553, 1557, 1558, 1561, - 1564, 1565, 1573, 1578, 1579, 1586, 1590, 1593, 1596, 1599, - 1600, 1601, 1611, 1613, 1614, 1616, 1617, 1619, 1621, 1624, - 1627, 1630, 1633, 1636, 1639, 1642, 1645, 1648, 1652, 1657, - 1661, 1664, 1668, 1670, 1671, 1675, 1676, 1680, 1683, 1685, - 1687, 1688, 1691, 1695, 1697, 1702, 1704, 1708, 1710, 1712, - 1717, 1722, 1725, 1728, 1732, 1736, 1738, 1739, 1741, 1744, - 1748, 1751, 1754, 1756, 1759, 1762, 1765, 1768, 1771, 1774, - 1777, 1779, 1782, 1785, 1789, 1792, 1795, 1800, 1805, 1808, - 1810, 1816, 1821, 1823, 1824, 1826, 1830, 1831, 1833, 1837, - 1839, 1841, 1843, 1845, 1850, 1855, 1860, 1865, 1870, 1874, - 1879, 1884, 1889, 1894, 1898, 1900, 1904, 1906, 1910, 1913, - 1915, 1923, 1924, 1927, 1929, 1932, 1933, 1936, 1941, 1946, - 1949, 1954, 1958, 1962, 1965, 1968, 1972, 1974, 1976, 1979, - 1981, 1983, 1986, 1989, 1994, 1999, 2003, 2007, 2010, 2012, - 2014, 2017, 2021, 2025, 2028, 2031, 2035, 2037, 2041, 2045, - 2048, 2051, 2055, 2057, 2062, 2066, 2071, 2075, 2077, 2080, - 2083, 2086, 2089, 2092, 2094, 2097, 2102, 2107, 2110, 2112, - 2114, 2116, 2118, 2121, 2126, 2129, 2132, 2135, 2138, 2140, - 2143, 2146, 2149, 2152, 2156, 2158, 2161, 2165, 2170, 2173, - 2176, 2179, 2182, 2185, 2188, 2193, 2196, 2198, 2201, 2204, - 2208, 2210, 2214, 2217, 2221, 2224, 2227, 2231, 2233, 2237, - 2242, 2246, 2249, 2252, 2254, 2258, 2261, 2264, 2266, 2269, - 2273, 2275, 2279, 2281, 2288, 2293, 2298, 2302, 2308, 2312, - 2316, 2320, 2323, 2325, 2327, 2330, 2333, 2336, 2337, 2339, - 2341, 2344, 2348, 2350, 2353, 2354, 2358, 2359, 2360, 2366, - 2368, 2369, 2372, 2374, 2376, 2378, 2381, 2382, 2387, 2389, - 2390, 2391, 2397, 2398, 2399, 2407, 2408, 2409, 2410, 2411, - 2424, 2425, 2426, 2434, 2435, 2441, 2442, 2450, 2451, 2456, - 2459, 2462, 2465, 2469, 2476, 2485, 2496, 2509, 2514, 2518, - 2521, 2524, 2526, 2528, 2530, 2532, 2534, 2535, 2536, 2543, - 2544, 2545, 2551, 2553, 2556, 2557, 2558, 2564, 2566, 2568, - 2572, 2576, 2579, 2582, 2585, 2588, 2591, 2593, 2596, 2597, - 2599, 2600, 2602, 2604, 2605, 2607, 2609, 2613, 2618, 2620, - 2624, 2625, 2627, 2629, 2631, 2634, 2637, 2640, 2642, 2645, - 2648, 2649, 2653, 2655, 2657, 2659, 2662, 2665, 2668, 2673, - 2676, 2679, 2682, 2685, 2688, 2691, 2693, 2696, 2698, 2701, - 2703, 2705, 2706, 2707, 2709, 2710, 2715, 2718, 2720, 2722, - 2726, 2727, 2731, 2735, 2739, 2741, 2744, 2747, 2750, 2753, - 2756, 2759, 2762, 2765, 2768, 2771, 2774, 2777, 2780, 2783, - 2786, 2789, 2792, 2795, 2798, 2801, 2804, 2807, 2810, 2814, - 2817, 2820, 2823, 2826, 2830, 2833, 2836, 2841, 2846, 2850 -}; - -/* YYRHS -- A `-1'-separated list of the rules' RHS. */ -static const yytype_int16 yyrhs[] = -{ - 113, 0, -1, -1, 114, -1, -1, 115, 121, -1, - 114, 121, -1, 114, -1, -1, -1, -1, 32, -1, - 27, -1, -1, 122, 123, -1, 149, 148, -1, 145, - -1, 142, -1, 120, 92, 220, 108, 60, -1, 134, - 58, 116, 109, -1, 134, 117, 149, 118, 148, -1, - 134, 117, 145, 118, -1, -1, 44, 164, 58, 124, - 116, 109, -1, -1, 44, 58, 125, 116, 109, -1, - 126, -1, 128, 60, -1, 130, -1, 119, 123, -1, - -1, 44, 164, 63, 127, 133, 60, -1, 46, 315, - -1, 46, 329, 315, -1, 46, 329, 210, -1, 46, - 132, 164, -1, 46, 329, 164, -1, 46, 329, 132, - 164, -1, -1, 46, 44, 131, 133, 60, -1, 56, - 54, -1, 132, 56, 54, -1, 210, -1, 315, -1, - 329, 315, -1, 329, 210, -1, 98, -1, 134, 98, - -1, -1, 48, 73, 136, 137, 74, -1, 48, 73, - 74, -1, 141, -1, 137, 59, 141, -1, 164, -1, - -1, 269, 138, -1, 45, 138, -1, 135, 269, 138, - -1, 139, -1, 139, 63, 226, -1, 392, -1, 392, - 63, 205, -1, 140, -1, 140, 63, 185, -1, 135, - 143, -1, 135, 1, -1, 149, 148, -1, 144, -1, - 142, -1, 134, 117, 149, 118, 148, -1, 134, 117, - 144, 118, -1, 119, 143, -1, 237, 60, -1, 230, - 236, 60, -1, 227, 235, 60, -1, 262, 60, -1, - 237, 60, -1, 230, 236, 60, -1, 227, 235, 60, - -1, 230, 60, -1, 167, 60, -1, 227, 60, -1, - 1, 60, -1, 1, 109, -1, 60, -1, 221, -1, - 160, -1, -1, 159, -1, 159, 60, -1, -1, 107, - -1, 155, 147, 146, 339, -1, 155, 147, 363, -1, - 155, 147, 1, -1, -1, 320, 5, 92, 151, 383, - 108, 301, 395, -1, 320, 5, 47, 301, 395, -1, - -1, 329, 320, 5, 92, 152, 383, 108, 301, 395, - -1, 329, 320, 5, 47, 301, 395, -1, -1, 320, - 180, 92, 153, 383, 108, 301, 395, -1, 320, 180, - 47, 301, 395, -1, -1, 329, 320, 180, 92, 154, - 383, 108, 301, 395, -1, 329, 320, 180, 47, 301, - 395, -1, 227, 224, -1, 230, 312, -1, 312, -1, - 230, 150, -1, 150, -1, 5, 92, 383, 108, 301, - 395, -1, 5, 47, 301, 395, -1, 180, 92, 383, - 108, 301, 395, -1, 180, 47, 301, 395, -1, 230, - 156, -1, 156, -1, 227, 224, -1, 230, 312, -1, - 312, -1, 230, 150, -1, 150, -1, 25, 3, -1, - 158, 254, -1, 158, 92, 197, 108, -1, 158, 47, - -1, 62, 161, 162, -1, -1, -1, 163, -1, 162, - 59, 163, -1, 162, 1, -1, 92, 197, 108, -1, - 47, -1, 165, 92, 197, 108, -1, 165, 47, -1, - 307, 92, 197, 108, -1, 307, 47, -1, 322, 92, - 197, 108, -1, 322, 47, -1, 3, -1, 4, -1, - 5, -1, 57, -1, 56, -1, 3, -1, 57, -1, - 56, -1, 104, -1, 103, -1, 105, -1, -1, 48, - 176, 233, 60, 168, 177, -1, -1, 48, 176, 227, - 224, 169, 177, -1, -1, 48, 176, 312, 170, 177, - -1, -1, 48, 176, 150, 171, 177, -1, -1, 7, - 48, 176, 233, 60, 172, 177, -1, -1, 7, 48, - 176, 227, 224, 173, 177, -1, -1, 7, 48, 176, - 312, 174, 177, -1, -1, 7, 48, 176, 150, 175, - 177, -1, -1, -1, 57, 73, 183, 182, 181, -1, - 4, 73, 183, 182, 181, -1, 180, -1, 178, -1, - 164, 73, 183, 74, 181, -1, 5, 73, 183, 182, - 181, -1, -1, 74, -1, 76, -1, -1, 184, -1, - 185, -1, 184, 59, 185, -1, 226, -1, 57, -1, - 205, -1, 79, -1, 78, -1, 87, -1, 86, -1, - 110, -1, 196, -1, 205, -1, 47, -1, 92, 187, - 108, -1, 47, -1, 92, 191, 108, -1, -1, 191, - -1, 1, -1, -1, 373, 224, 238, 247, 63, 192, - 255, -1, 187, -1, 109, -1, 336, 334, 109, -1, - 336, 334, 1, 109, -1, 336, 1, 109, -1, -1, - 58, 195, 193, -1, 348, -1, 205, 59, 205, -1, - 205, 59, 1, -1, 196, 59, 205, -1, 196, 59, - 1, -1, 205, -1, 196, -1, 215, -1, 119, 204, - -1, 80, 204, -1, 70, 204, -1, 85, 204, -1, - 186, 204, -1, 67, 164, -1, 13, 198, -1, 13, - 92, 226, 108, -1, 29, 198, -1, 29, 92, 226, - 108, -1, 217, 300, -1, 217, 300, 202, -1, 217, - 201, 300, -1, 217, 201, 300, 202, -1, 217, 92, - 200, 226, 199, -1, 217, 92, 200, 226, 199, 202, - -1, 217, 201, 92, 200, 226, 199, -1, 217, 201, - 92, 200, 226, 199, 202, -1, 218, 204, -1, 218, - 93, 111, 204, -1, 218, 93, 187, 111, 204, -1, - 34, 204, -1, 35, 204, -1, 108, -1, -1, 92, - 200, 197, 108, -1, 58, 200, 197, 109, -1, 92, - 197, 108, -1, 47, -1, 92, 233, 108, -1, 63, - 255, -1, 92, 226, 108, -1, 203, 92, 226, 108, - -1, 198, -1, 203, 198, -1, 203, 58, 256, 267, - 109, -1, 204, -1, 205, 84, 205, -1, 205, 83, - 205, -1, 205, 78, 205, -1, 205, 79, 205, -1, - 205, 80, 205, -1, 205, 81, 205, -1, 205, 82, - 205, -1, 205, 77, 205, -1, 205, 76, 205, -1, - 205, 75, 205, -1, 205, 73, 205, -1, 205, 74, - 205, -1, 205, 72, 205, -1, 205, 71, 205, -1, - 205, 70, 205, -1, 205, 68, 205, -1, 205, 69, - 205, -1, 205, 67, 205, -1, 205, 66, 205, -1, - 205, 65, 378, 62, 205, -1, 205, 63, 205, -1, - 205, 64, 205, -1, 61, -1, 61, 205, -1, 85, - 393, 164, -1, 85, 393, 178, -1, 208, -1, 400, - -1, 3, -1, 57, -1, 56, -1, -1, 6, 73, - 207, 183, 182, -1, 400, 73, 207, 183, 182, -1, - 48, 164, 73, 183, 182, -1, 48, 6, 73, 183, - 182, -1, 48, 400, 73, 183, 182, -1, 206, -1, - 4, -1, 5, -1, 212, -1, 248, 212, -1, 206, - -1, 80, 211, -1, 70, 211, -1, 92, 211, 108, - -1, 3, 73, 183, 182, -1, 56, 73, 184, 182, - -1, 314, -1, 206, -1, 213, -1, 92, 211, 108, - -1, 206, -1, 10, -1, 219, -1, 220, -1, 92, - 187, 108, -1, 92, 211, 108, -1, 92, 1, 108, - -1, -1, 92, 216, 340, 108, -1, 206, 92, 197, - 108, -1, 206, 47, -1, 215, 92, 197, 108, -1, - 215, 47, -1, 215, 93, 187, 111, -1, 215, 87, - -1, 215, 86, -1, 40, -1, 9, 92, 197, 108, - -1, 318, -1, 50, 73, 226, 74, 92, 187, 108, - -1, 51, 73, 226, 74, 92, 187, 108, -1, 52, - 73, 226, 74, 92, 187, 108, -1, 53, 73, 226, - 74, 92, 187, 108, -1, 49, 92, 187, 108, -1, - 49, 92, 226, 108, -1, 329, 3, -1, 329, 208, - -1, 329, 400, -1, 317, -1, 317, 92, 197, 108, - -1, 317, 47, -1, 222, 209, -1, 222, 209, 92, - 197, 108, -1, 222, 209, 47, -1, 222, 210, -1, - 222, 317, -1, 222, 210, 92, 197, 108, -1, 222, - 210, 47, -1, 222, 317, 92, 197, 108, -1, 222, - 317, 47, -1, 222, 85, 8, 47, -1, 222, 8, - 54, 85, 8, 47, -1, 222, 1, -1, 39, -1, - 329, 39, -1, 38, -1, 329, 218, -1, 42, -1, - 43, -1, 11, -1, 220, 11, -1, -1, 215, 91, - -1, 215, 94, -1, 233, 235, 60, -1, 227, 235, - 60, -1, 230, 236, 60, -1, 227, 60, -1, 230, - 60, -1, 119, 223, -1, 306, -1, 312, -1, 47, - -1, 225, 47, -1, 231, 332, -1, 302, 332, -1, - 233, 332, -1, 231, -1, 302, -1, 231, -1, 228, - -1, 230, 233, -1, 233, 229, -1, 233, 232, 229, - -1, 230, 233, 229, -1, 230, 233, 232, -1, 230, - 233, 232, 229, -1, 7, -1, 229, 234, -1, 229, - 7, -1, 229, 248, -1, 248, -1, 302, -1, 7, - -1, 230, 9, -1, 230, 7, -1, 230, 248, -1, - 248, -1, 233, -1, 302, 233, -1, 233, 232, -1, - 302, 233, 232, -1, 234, -1, 232, 234, -1, 262, - -1, 8, -1, 308, -1, 28, 92, 187, 108, -1, - 28, 92, 226, 108, -1, 30, 92, 187, 108, -1, - 30, 92, 226, 108, -1, 8, -1, 9, -1, 262, - -1, 243, -1, 235, 59, 239, -1, 244, -1, 236, - 59, 239, -1, 245, -1, 237, 59, 239, -1, -1, - 120, 92, 220, 108, -1, -1, 224, 238, 247, 63, - 240, 255, -1, 224, 238, 247, -1, -1, 247, 63, - 242, 255, -1, 247, -1, 224, 238, 241, -1, 312, - 238, 241, -1, -1, 312, 238, 246, 241, -1, 150, - 238, 247, -1, -1, 248, -1, 249, -1, 248, 249, - -1, 31, 92, 92, 250, 108, 108, -1, 251, -1, - 250, 59, 251, -1, -1, 252, -1, 252, 92, 3, - 108, -1, 252, 92, 3, 59, 197, 108, -1, 252, - 92, 197, 108, -1, 164, -1, 7, -1, 8, -1, - 9, -1, 164, -1, 253, 59, 164, -1, -1, 63, - 255, -1, 205, -1, 58, 109, -1, 58, 256, 109, - -1, 58, 256, 59, 109, -1, 1, -1, 255, -1, - 256, 59, 255, -1, 93, 205, 111, 255, -1, 164, - 62, 255, -1, 256, 59, 164, 62, 255, -1, 97, - -1, 257, 147, 146, 339, -1, 257, 147, 363, -1, - 257, 147, 1, -1, -1, 259, 258, 148, -1, 102, - 205, 107, -1, 102, 1, 107, -1, -1, 261, 260, - -1, 261, 1, -1, -1, 14, 164, 58, 263, 298, - 268, 109, -1, 14, 164, 58, 109, -1, -1, 14, - 58, 264, 298, 268, 109, -1, 14, 58, 109, -1, - 14, 164, -1, 14, 327, -1, 45, 322, -1, -1, - -1, 277, 283, 285, 109, 247, 265, 261, 266, 259, - -1, 277, -1, -1, 59, -1, -1, 59, -1, 36, - -1, 269, 7, -1, 269, 8, -1, 269, 9, -1, - 269, 36, -1, 269, 248, -1, 269, 164, -1, 269, - 166, -1, 270, 58, -1, 270, 62, -1, 269, 320, - 164, -1, 269, 329, 320, 164, -1, 269, 329, 164, - -1, 269, 179, -1, 269, 320, 179, -1, 270, -1, - -1, 271, 274, 278, -1, -1, 272, 275, 278, -1, - 269, 58, -1, 276, -1, 273, -1, -1, 62, 393, - -1, 62, 393, 279, -1, 280, -1, 279, 59, 393, - 280, -1, 281, -1, 282, 393, 281, -1, 322, -1, - 307, -1, 30, 92, 187, 108, -1, 30, 92, 226, - 108, -1, 37, 393, -1, 7, 393, -1, 282, 37, - 393, -1, 282, 7, 393, -1, 58, -1, -1, 284, - -1, 284, 287, -1, 285, 286, 287, -1, 285, 286, - -1, 37, 62, -1, 288, -1, 287, 288, -1, 289, - 60, -1, 289, 109, -1, 157, 62, -1, 157, 96, - -1, 157, 25, -1, 157, 58, -1, 60, -1, 119, - 288, -1, 135, 288, -1, 135, 227, 60, -1, 227, - 290, -1, 230, 291, -1, 312, 238, 247, 254, -1, - 150, 238, 247, 254, -1, 62, 205, -1, 1, -1, - 230, 156, 238, 247, 254, -1, 156, 238, 247, 254, - -1, 128, -1, -1, 292, -1, 290, 59, 293, -1, - -1, 295, -1, 291, 59, 297, -1, 294, -1, 295, - -1, 296, -1, 297, -1, 306, 238, 247, 254, -1, - 4, 62, 205, 247, -1, 312, 238, 247, 254, -1, - 150, 238, 247, 254, -1, 3, 62, 205, 247, -1, - 62, 205, 247, -1, 306, 238, 247, 254, -1, 4, - 62, 205, 247, -1, 312, 238, 247, 254, -1, 3, - 62, 205, 247, -1, 62, 205, 247, -1, 299, -1, - 298, 59, 299, -1, 164, -1, 164, 63, 205, -1, - 373, 330, -1, 373, -1, 92, 200, 226, 199, 93, - 187, 111, -1, -1, 301, 9, -1, 9, -1, 302, - 9, -1, -1, 303, 187, -1, 303, 92, 197, 108, - -1, 303, 92, 383, 108, -1, 303, 47, -1, 303, - 92, 1, 108, -1, 80, 302, 306, -1, 70, 302, - 306, -1, 80, 306, -1, 70, 306, -1, 328, 301, - 306, -1, 310, -1, 319, -1, 329, 319, -1, 307, - -1, 309, -1, 329, 309, -1, 320, 319, -1, 310, - 305, 301, 395, -1, 310, 93, 304, 111, -1, 310, - 93, 111, -1, 92, 306, 108, -1, 320, 319, -1, - 319, -1, 312, -1, 248, 312, -1, 80, 302, 311, - -1, 70, 302, 311, -1, 80, 311, -1, 70, 311, - -1, 328, 301, 311, -1, 214, -1, 80, 302, 311, - -1, 70, 302, 311, -1, 80, 313, -1, 70, 313, - -1, 328, 301, 311, -1, 314, -1, 214, 305, 301, - 395, -1, 92, 313, 108, -1, 214, 93, 304, 111, - -1, 214, 93, 111, -1, 316, -1, 320, 213, -1, - 320, 210, -1, 320, 209, -1, 320, 206, -1, 320, - 209, -1, 316, -1, 329, 316, -1, 233, 92, 197, - 108, -1, 233, 92, 211, 108, -1, 233, 225, -1, - 4, -1, 5, -1, 178, -1, 321, -1, 320, 321, - -1, 320, 48, 326, 54, -1, 4, 54, -1, 5, - 54, -1, 56, 54, -1, 178, 54, -1, 323, -1, - 329, 323, -1, 324, 164, -1, 324, 178, -1, 324, - 326, -1, 324, 48, 326, -1, 325, -1, 324, 325, - -1, 324, 326, 54, -1, 324, 48, 326, 54, -1, - 4, 54, -1, 5, 54, -1, 178, 54, -1, 57, - 54, -1, 3, 54, -1, 56, 54, -1, 164, 73, - 183, 182, -1, 329, 319, -1, 309, -1, 329, 309, - -1, 320, 80, -1, 329, 320, 80, -1, 54, -1, - 80, 301, 330, -1, 80, 301, -1, 70, 301, 330, - -1, 70, 301, -1, 328, 301, -1, 328, 301, 330, - -1, 331, -1, 93, 187, 111, -1, 331, 93, 304, - 111, -1, 80, 302, 332, -1, 80, 332, -1, 80, - 302, -1, 80, -1, 70, 302, 332, -1, 70, 332, - -1, 70, 302, -1, 70, -1, 328, 301, -1, 328, - 301, 332, -1, 333, -1, 92, 332, 108, -1, 90, - -1, 333, 92, 383, 108, 301, 395, -1, 333, 47, - 301, 395, -1, 333, 93, 304, 111, -1, 333, 93, - 111, -1, 92, 384, 108, 301, 395, -1, 203, 301, - 395, -1, 225, 301, 395, -1, 93, 304, 111, -1, - 93, 111, -1, 347, -1, 335, -1, 334, 347, -1, - 334, 335, -1, 1, 60, -1, -1, 337, -1, 338, - -1, 337, 338, -1, 33, 253, 60, -1, 340, -1, - 1, 340, -1, -1, 58, 341, 193, -1, -1, -1, - 15, 343, 189, 344, 345, -1, 340, -1, -1, 346, - 348, -1, 340, -1, 348, -1, 223, -1, 187, 60, - -1, -1, 342, 16, 349, 345, -1, 342, -1, -1, - -1, 17, 350, 189, 351, 194, -1, -1, -1, 18, - 352, 345, 17, 353, 188, 60, -1, -1, -1, -1, - -1, 19, 354, 92, 376, 355, 190, 60, 356, 378, - 108, 357, 194, -1, -1, -1, 20, 358, 92, 191, - 108, 359, 345, -1, -1, 21, 205, 62, 360, 347, - -1, -1, 21, 205, 12, 205, 62, 361, 347, -1, - -1, 22, 62, 362, 347, -1, 23, 60, -1, 24, - 60, -1, 25, 60, -1, 25, 187, 60, -1, 120, - 377, 92, 220, 108, 60, -1, 120, 377, 92, 220, - 62, 379, 108, 60, -1, 120, 377, 92, 220, 62, - 379, 62, 379, 108, 60, -1, 120, 377, 92, 220, - 62, 379, 62, 379, 62, 382, 108, 60, -1, 26, - 80, 187, 60, -1, 26, 164, 60, -1, 375, 347, - -1, 375, 109, -1, 60, -1, 366, -1, 130, -1, - 129, -1, 126, -1, -1, -1, 96, 364, 146, 340, - 365, 369, -1, -1, -1, 96, 367, 340, 368, 369, - -1, 370, -1, 369, 370, -1, -1, -1, 95, 371, - 374, 372, 340, -1, 231, -1, 302, -1, 92, 12, - 108, -1, 92, 392, 108, -1, 3, 62, -1, 57, - 62, -1, 4, 62, -1, 5, 62, -1, 378, 60, - -1, 223, -1, 58, 193, -1, -1, 9, -1, -1, - 187, -1, 1, -1, -1, 380, -1, 381, -1, 380, - 59, 381, -1, 11, 92, 187, 108, -1, 11, -1, - 382, 59, 11, -1, -1, 384, -1, 226, -1, 388, - -1, 389, 12, -1, 388, 12, -1, 226, 12, -1, - 12, -1, 388, 62, -1, 226, 62, -1, -1, 63, - 386, 387, -1, 101, -1, 255, -1, 390, -1, 392, - 385, -1, 389, 391, -1, 389, 394, -1, 389, 394, - 63, 255, -1, 388, 59, -1, 226, 59, -1, 228, - 224, -1, 231, 224, -1, 233, 224, -1, 228, 332, - -1, 228, -1, 230, 312, -1, 392, -1, 392, 385, - -1, 390, -1, 226, -1, -1, -1, 312, -1, -1, - 61, 92, 397, 108, -1, 61, 47, -1, 226, -1, - 396, -1, 397, 59, 396, -1, -1, 80, 301, 398, - -1, 70, 301, 398, -1, 328, 301, 398, -1, 41, - -1, 399, 80, -1, 399, 81, -1, 399, 82, -1, - 399, 78, -1, 399, 79, -1, 399, 70, -1, 399, - 68, -1, 399, 69, -1, 399, 85, -1, 399, 59, - -1, 399, 75, -1, 399, 73, -1, 399, 74, -1, - 399, 72, -1, 399, 64, -1, 399, 63, -1, 399, - 77, -1, 399, 76, -1, 399, 87, -1, 399, 86, - -1, 399, 67, -1, 399, 66, -1, 399, 110, -1, - 399, 65, 62, -1, 399, 71, -1, 399, 94, -1, - 399, 84, -1, 399, 47, -1, 399, 93, 111, -1, - 399, 39, -1, 399, 38, -1, 399, 39, 93, 111, - -1, 399, 38, 93, 111, -1, 399, 373, 398, -1, - 399, 1, -1 -}; - -/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ -static const yytype_uint16 yyrline[] = -{ - 0, 337, 337, 339, 348, 348, 351, 356, 357, 361, - 366, 370, 376, 380, 380, 387, 389, 391, 393, 396, - 398, 401, 405, 404, 409, 408, 412, 413, 415, 416, - 422, 421, 433, 435, 437, 442, 444, 446, 452, 451, - 466, 472, 481, 482, 483, 485, 490, 492, 500, 499, - 503, 509, 511, 516, 519, 522, 524, 529, 541, 543, - 545, 547, 549, 551, 565, 567, 572, 574, 576, 578, - 581, 584, 589, 590, 592, 594, 600, 601, 603, 605, - 607, 608, 615, 616, 617, 621, 623, 627, 629, 630, - 633, 635, 639, 641, 647, 653, 652, 656, 661, 660, - 664, 669, 668, 672, 677, 676, 680, 687, 690, 693, - 696, 699, 705, 707, 709, 711, 718, 729, 732, 737, - 742, 745, 750, 756, 765, 767, 769, 774, 788, 808, - 809, 811, 812, 816, 822, 828, 830, 832, 834, 836, - 839, 845, 846, 847, 848, 849, 853, 854, 855, 859, - 860, 861, 866, 865, 870, 869, 874, 873, 877, 876, - 880, 879, 885, 883, 889, 888, 892, 891, 897, 900, - 907, 910, 913, 917, 918, 923, 929, 938, 939, 949, - 950, 954, 956, 961, 963, 965, 969, 971, 973, 975, - 977, 982, 984, 988, 992, 997, 1001, 1007, 1008, 1009, - 1015, 1014, 1039, 1043, 1044, 1045, 1046, 1051, 1050, 1054, - 1059, 1062, 1065, 1067, 1072, 1074, 1078, 1081, 1084, 1086, - 1088, 1090, 1093, 1097, 1099, 1102, 1104, 1110, 1113, 1116, - 1119, 1131, 1136, 1140, 1144, 1149, 1151, 1155, 1159, 1161, - 1171, 1175, 1178, 1180, 1186, 1188, 1190, 1198, 1212, 1216, - 1223, 1224, 1226, 1240, 1242, 1244, 1246, 1248, 1250, 1252, - 1254, 1256, 1258, 1260, 1262, 1264, 1266, 1268, 1270, 1272, - 1274, 1276, 1278, 1280, 1282, 1286, 1288, 1290, 1308, 1310, - 1312, 1313, 1314, 1315, 1316, 1320, 1332, 1334, 1339, 1341, - 1343, 1349, 1350, 1351, 1355, 1356, 1365, 1366, 1368, 1370, - 1375, 1377, 1382, 1385, 1386, 1387, 1392, 1399, 1400, 1401, - 1415, 1417, 1420, 1423, 1422, 1438, 1440, 1442, 1444, 1446, - 1448, 1450, 1453, 1455, 1472, 1473, 1477, 1481, 1485, 1489, - 1491, 1495, 1497, 1499, 1507, 1509, 1511, 1513, 1517, 1519, - 1521, 1523, 1528, 1530, 1532, 1534, 1537, 1539, 1541, 1586, - 1588, 1593, 1595, 1600, 1602, 1608, 1609, 1615, 1627, 1629, - 1637, 1643, 1648, 1650, 1655, 1657, 1665, 1666, 1671, 1674, - 1681, 1684, 1687, 1690, 1693, 1704, 1705, 1709, 1712, 1715, - 1718, 1721, 1724, 1731, 1736, 1738, 1743, 1745, 1755, 1757, - 1759, 1762, 1768, 1770, 1781, 1784, 1787, 1790, 1796, 1798, - 1807, 1808, 1810, 1812, 1815, 1818, 1833, 1853, 1855, 1857, - 1861, 1862, 1867, 1868, 1873, 1874, 1880, 1881, 1887, 1886, - 1892, 1906, 1905, 1914, 1921, 1925, 1931, 1930, 1936, 1946, - 1947, 1952, 1954, 1959, 1964, 1966, 1972, 1973, 1975, 1977, - 1979, 1987, 1988, 1989, 1990, 1995, 1997, 2002, 2004, 2011, - 2012, 2015, 2018, 2021, 2028, 2030, 2033, 2035, 2037, 2042, - 2048, 2055, 2062, 2066, 2068, 2074, 2076, 2080, 2081, 2083, - 2089, 2088, 2099, 2104, 2103, 2114, 2118, 2121, 2124, 2132, - 2142, 2130, 2147, 2167, 2169, 2172, 2174, 2180, 2181, 2183, - 2185, 2187, 2189, 2194, 2202, 2204, 2206, 2211, 2216, 2221, - 2226, 2228, 2233, 2236, 2235, 2246, 2245, 2271, 2277, 2278, - 2282, 2284, 2286, 2291, 2292, 2301, 2305, 2312, 2314, 2315, - 2336, 2360, 2361, 2365, 2376, 2391, 2397, 2403, 2404, 2405, - 2406, 2410, 2425, 2429, 2436, 2437, 2442, 2444, 2446, 2448, - 2450, 2452, 2455, 2465, 2476, 2497, 2503, 2506, 2509, 2511, - 2522, 2527, 2530, 2537, 2538, 2545, 2557, 2558, 2565, 2576, - 2577, 2581, 2582, 2586, 2592, 2601, 2607, 2613, 2619, 2628, - 2631, 2637, 2640, 2643, 2653, 2654, 2659, 2661, 2667, 2670, - 2676, 2688, 2690, 2695, 2698, 2708, 2712, 2718, 2720, 2722, - 2724, 2731, 2733, 2735, 2737, 2739, 2743, 2747, 2764, 2775, - 2776, 2777, 2782, 2787, 2789, 2791, 2793, 2795, 2799, 2806, - 2807, 2816, 2818, 2820, 2822, 2824, 2828, 2832, 2834, 2836, - 2838, 2840, 2844, 2848, 2850, 2852, 2854, 2856, 2858, 2866, - 2869, 2875, 2878, 2884, 2885, 2890, 2892, 2894, 2898, 2899, - 2900, 2904, 2905, 2907, 2914, 2928, 2934, 2940, 2955, 2956, - 2961, 2974, 2976, 2978, 2983, 2988, 3001, 3003, 3008, 3020, - 3026, 3028, 3029, 3030, 3039, 3044, 3052, 3053, 3058, 3060, - 3067, 3073, 3075, 3077, 3079, 3081, 3085, 3089, 3094, 3096, - 3102, 3104, 3106, 3108, 3110, 3112, 3114, 3116, 3118, 3122, - 3126, 3131, 3134, 3135, 3137, 3139, 3141, 3143, 3145, 3147, - 3149, 3151, 3160, 3161, 3162, 3163, 3167, 3172, 3174, 3180, - 3181, 3185, 3199, 3201, 3206, 3205, 3213, 3218, 3212, 3224, - 3225, 3225, 3231, 3233, 3237, 3239, 3242, 3241, 3248, 3251, - 3256, 3250, 3260, 3262, 3259, 3269, 3271, 3273, 3275, 3268, - 3279, 3281, 3278, 3285, 3284, 3288, 3287, 3291, 3290, 3293, - 3295, 3297, 3299, 3301, 3307, 3313, 3316, 3319, 3325, 3327, - 3329, 3333, 3335, 3336, 3337, 3339, 3344, 3350, 3343, 3362, - 3364, 3361, 3370, 3371, 3376, 3378, 3375, 3384, 3385, 3389, - 3405, 3412, 3419, 3421, 3423, 3428, 3430, 3431, 3441, 3443, - 3449, 3450, 3451, 3459, 3460, 3464, 3465, 3470, 3475, 3477, - 3489, 3492, 3493, 3501, 3503, 3506, 3508, 3511, 3513, 3523, - 3539, 3538, 3545, 3546, 3551, 3554, 3557, 3560, 3562, 3567, - 3568, 3578, 3582, 3585, 3588, 3592, 3596, 3603, 3606, 3612, - 3613, 3617, 3622, 3627, 3639, 3641, 3643, 3648, 3653, 3654, - 3662, 3664, 3666, 3668, 3675, 3680, 3682, 3684, 3686, 3688, - 3690, 3692, 3694, 3696, 3698, 3700, 3702, 3704, 3706, 3708, - 3710, 3712, 3714, 3716, 3718, 3720, 3722, 3724, 3726, 3728, - 3730, 3732, 3734, 3736, 3738, 3740, 3742, 3744, 3747, 3749 -}; -#endif - -#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE -/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. - First, the terminals, then, starting at YYNTOKENS, nonterminals. */ -static const char *const yytname[] = -{ - "$end", "error", "$undefined", "IDENTIFIER", "TYPENAME", "SELFNAME", - "PFUNCNAME", "SCSPEC", "TYPESPEC", "CV_QUALIFIER", "CONSTANT", "STRING", - "ELLIPSIS", "SIZEOF", "ENUM", "IF", "ELSE", "WHILE", "DO", "FOR", - "SWITCH", "CASE", "DEFAULT", "BREAK", "CONTINUE", "RETURN", "GOTO", - "ASM_KEYWORD", "TYPEOF", "ALIGNOF", "SIGOF", "ATTRIBUTE", "EXTENSION", - "LABEL", "REALPART", "IMAGPART", "AGGR", "VISSPEC", "DELETE", "NEW", - "THIS", "OPERATOR", "CXX_TRUE", "CXX_FALSE", "NAMESPACE", - "TYPENAME_KEYWORD", "USING", "LEFT_RIGHT", "TEMPLATE", "TYPEID", - "DYNAMIC_CAST", "STATIC_CAST", "REINTERPRET_CAST", "CONST_CAST", "SCOPE", - "EMPTY", "NSNAME", "PTYPENAME", "'{'", "','", "';'", "THROW", "':'", - "'='", "ASSIGN", "'?'", "OROR", "ANDAND", "'|'", "'^'", "'&'", "MIN_MAX", - "EQCOMPARE", "'<'", "'>'", "ARITHCOMPARE", "RSHIFT", "LSHIFT", "'+'", - "'-'", "'*'", "'/'", "'%'", "DOT_STAR", "POINTSAT_STAR", "'~'", - "MINUSMINUS", "PLUSPLUS", "UNARY", "HYPERUNARY", "PAREN_STAR_PAREN", - "'.'", "'('", "'['", "POINTSAT", "CATCH", "TRY", - "PRE_PARSED_FUNCTION_DECL", "EXTERN_LANG_STRING", "ALL", - "PRE_PARSED_CLASS_DECL", "DEFARG", "DEFARG_MARKER", "TYPENAME_DEFN", - "IDENTIFIER_DEFN", "PTYPENAME_DEFN", "END_OF_LINE", "END_OF_SAVED_INPUT", - "')'", "'}'", "'!'", "']'", "$accept", "program", "extdefs", "@1", - "extdefs_opt", ".hush_warning", ".warning_ok", "extension", - "asm_keyword", "lang_extdef", "@2", "extdef", "@3", "@4", - "namespace_alias", "@5", "using_decl", "namespace_using_decl", - "using_directive", "@6", "namespace_qualifier", "any_id", - "extern_lang_string", "template_header", "@7", "template_parm_list", - "maybe_identifier", "template_type_parm", "template_template_parm", - "template_parm", "template_def", "template_extdef", "template_datadef", - "datadef", "ctor_initializer_opt", "maybe_return_init", - "eat_saved_input", "fndef", "constructor_declarator", "@8", "@9", "@10", - "@11", "fn.def1", "component_constructor_declarator", "fn.def2", - "return_id", "return_init", "base_init", ".set_base_init", - "member_init_list", "member_init", "identifier", "notype_identifier", - "identifier_defn", "explicit_instantiation", "@12", "@13", "@14", "@15", - "@16", "@17", "@18", "@19", "begin_explicit_instantiation", - "end_explicit_instantiation", "template_type", "apparent_template_type", - "self_template_type", ".finish_template_type", "template_close_bracket", - "template_arg_list_opt", "template_arg_list", "template_arg", "unop", - "expr", "paren_expr_or_null", "paren_cond_or_null", "xcond", "condition", - "@20", "compstmtend", "already_scoped_stmt", "@21", - "nontrivial_exprlist", "nonnull_exprlist", "unary_expr", - ".finish_new_placement", ".begin_new_placement", "new_placement", - "new_initializer", "regcast_or_absdcl", "cast_expr", "expr_no_commas", - "notype_unqualified_id", "do_id", "template_id", "object_template_id", - "unqualified_id", "expr_or_declarator_intern", "expr_or_declarator", - "notype_template_declarator", "direct_notype_declarator", "primary", - "@22", "new", "delete", "boolean.literal", "string", "nodecls", "object", - "decl", "declarator", "fcast_or_absdcl", "type_id", "typed_declspecs", - "typed_declspecs1", "reserved_declspecs", "declmods", "typed_typespecs", - "reserved_typespecquals", "typespec", "typespecqual_reserved", - "initdecls", "notype_initdecls", "nomods_initdecls", "maybeasm", - "initdcl", "@23", "initdcl0_innards", "@24", "initdcl0", - "notype_initdcl0", "nomods_initdcl0", "@25", "maybe_attribute", - "attributes", "attribute", "attribute_list", "attrib", "any_word", - "identifiers_or_typenames", "maybe_init", "init", "initlist", - "fn.defpen", "pending_inline", "pending_inlines", "defarg_again", - "pending_defargs", "structsp", "@26", "@27", "@28", "@29", "maybecomma", - "maybecomma_warn", "aggr", "named_class_head_sans_basetype", - "named_class_head_sans_basetype_defn", - "named_complex_class_head_sans_basetype", "named_class_head", "@30", - "@31", "unnamed_class_head", "class_head", "maybe_base_class_list", - "base_class_list", "base_class", "base_class.1", - "base_class_access_list", "left_curly", "self_reference", - "opt.component_decl_list", "access_specifier", "component_decl_list", - "component_decl", "component_decl_1", "components", "notype_components", - "component_declarator0", "component_declarator", - "after_type_component_declarator0", "notype_component_declarator0", - "after_type_component_declarator", "notype_component_declarator", - "enumlist", "enumerator", "new_type_id", "cv_qualifiers", - "nonempty_cv_qualifiers", "suspend_mom", "nonmomentary_expr", - "maybe_parmlist", "after_type_declarator", "nonnested_type", - "complete_type_name", "nested_type", "direct_after_type_declarator", - "notype_declarator_intern", "notype_declarator", - "complex_notype_declarator", "complex_direct_notype_declarator", - "qualified_id", "notype_qualified_id", "overqualified_id", - "functional_cast", "type_name", "nested_name_specifier", - "nested_name_specifier_1", "typename_sub", "typename_sub0", - "typename_sub1", "typename_sub2", "explicit_template_type", - "complex_type_name", "ptr_to_mem", "global_scope", "new_declarator", - "direct_new_declarator", "absdcl", "direct_abstract_declarator", "stmts", - "errstmt", "maybe_label_decls", "label_decls", "label_decl", - "compstmt_or_error", "compstmt", "@32", "simple_if", "@33", "@34", - "implicitly_scoped_stmt", "@35", "stmt", "simple_stmt", "@36", "@37", - "@38", "@39", "@40", "@41", "@42", "@43", "@44", "@45", "@46", "@47", - "@48", "@49", "function_try_block", "@50", "@51", "try_block", "@52", - "@53", "handler_seq", "handler", "@54", "@55", "type_specifier_seq", - "handler_args", "label_colon", "for.init.statement", - "maybe_cv_qualifier", "xexpr", "asm_operands", "nonnull_asm_operands", - "asm_operand", "asm_clobbers", "parmlist", "complex_parmlist", "defarg", - "@56", "defarg1", "parms", "parms_comma", "named_parm", "full_parm", - "parm", "see_typename", "bad_parm", "exception_specification_opt", - "ansi_raise_identifier", "ansi_raise_identifiers", - "conversion_declarator", "operator", "operator_name", 0 -}; -#endif - -# ifdef YYPRINT -/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to - token YYLEX-NUM. */ -static const yytype_uint16 yytoknum[] = -{ - 0, 256, 257, 258, 259, 260, 261, 262, 263, 264, - 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, - 275, 276, 277, 278, 279, 280, 281, 282, 283, 284, - 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, - 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, - 305, 306, 307, 308, 309, 310, 311, 312, 123, 44, - 59, 313, 58, 61, 314, 63, 315, 316, 124, 94, - 38, 317, 318, 60, 62, 319, 320, 321, 43, 45, - 42, 47, 37, 322, 323, 126, 324, 325, 326, 327, - 328, 46, 40, 91, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 41, 125, - 33, 93 -}; -# endif - -/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ -static const yytype_uint16 yyr1[] = -{ - 0, 112, 113, 113, 115, 114, 114, 116, 116, 117, - 118, 119, 120, 122, 121, 123, 123, 123, 123, 123, - 123, 123, 124, 123, 125, 123, 123, 123, 123, 123, - 127, 126, 128, 128, 128, 129, 129, 129, 131, 130, - 132, 132, 133, 133, 133, 133, 134, 134, 136, 135, - 135, 137, 137, 138, 138, 139, 139, 140, 141, 141, - 141, 141, 141, 141, 142, 142, 143, 143, 143, 143, - 143, 143, 144, 144, 144, 144, 145, 145, 145, 145, - 145, 145, 145, 145, 145, 146, 146, 147, 147, 147, - 148, 148, 149, 149, 149, 151, 150, 150, 152, 150, - 150, 153, 150, 150, 154, 150, 150, 155, 155, 155, - 155, 155, 156, 156, 156, 156, 157, 157, 157, 157, - 157, 157, 157, 158, 159, 159, 159, 160, 161, 162, - 162, 162, 162, 163, 163, 163, 163, 163, 163, 163, - 163, 164, 164, 164, 164, 164, 165, 165, 165, 166, - 166, 166, 168, 167, 169, 167, 170, 167, 171, 167, - 172, 167, 173, 167, 174, 167, 175, 167, 176, 177, - 178, 178, 178, 179, 179, 180, 181, 182, 182, 183, - 183, 184, 184, 185, 185, 185, 186, 186, 186, 186, - 186, 187, 187, 188, 188, 189, 189, 190, 190, 190, - 192, 191, 191, 193, 193, 193, 193, 195, 194, 194, - 196, 196, 196, 196, 197, 197, 198, 198, 198, 198, - 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, - 198, 198, 198, 198, 198, 198, 198, 198, 198, 198, - 199, 200, 201, 201, 202, 202, 202, 202, 203, 203, - 204, 204, 204, 205, 205, 205, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 206, 206, - 206, 206, 206, 206, 206, 207, 208, 208, 209, 209, - 209, 210, 210, 210, 211, 211, 212, 212, 212, 212, - 213, 213, 214, 214, 214, 214, 215, 215, 215, 215, - 215, 215, 215, 216, 215, 215, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 215, 215, - 215, 215, 215, 215, 215, 215, 215, 215, 215, 217, - 217, 218, 218, 219, 219, 220, 220, 221, 222, 222, - 223, 223, 223, 223, 223, 223, 224, 224, 225, 225, - 226, 226, 226, 226, 226, 227, 227, 228, 228, 228, - 228, 228, 228, 229, 229, 229, 229, 229, 230, 230, - 230, 230, 230, 230, 231, 231, 231, 231, 232, 232, - 233, 233, 233, 233, 233, 233, 233, 234, 234, 234, - 235, 235, 236, 236, 237, 237, 238, 238, 240, 239, - 239, 242, 241, 241, 243, 244, 246, 245, 245, 247, - 247, 248, 248, 249, 250, 250, 251, 251, 251, 251, - 251, 252, 252, 252, 252, 253, 253, 254, 254, 255, - 255, 255, 255, 255, 256, 256, 256, 256, 256, 257, - 258, 258, 258, 259, 259, 260, 260, 261, 261, 261, - 263, 262, 262, 264, 262, 262, 262, 262, 262, 265, - 266, 262, 262, 267, 267, 268, 268, 269, 269, 269, - 269, 269, 269, 270, 271, 271, 271, 272, 272, 272, - 272, 272, 273, 274, 273, 275, 273, 276, 277, 277, - 278, 278, 278, 279, 279, 280, 280, 281, 281, 281, - 281, 282, 282, 282, 282, 283, 284, 285, 285, 285, - 285, 286, 287, 287, 288, 288, 288, 288, 288, 288, - 288, 288, 288, 288, 289, 289, 289, 289, 289, 289, - 289, 289, 289, 290, 290, 290, 291, 291, 291, 292, - 292, 293, 293, 294, 294, 295, 295, 295, 295, 296, - 296, 297, 297, 297, 298, 298, 299, 299, 300, 300, - 300, 301, 301, 302, 302, 303, 304, 305, 305, 305, - 305, 306, 306, 306, 306, 306, 306, 307, 307, 308, - 308, 308, 309, 310, 310, 310, 310, 310, 310, 311, - 311, 312, 312, 312, 312, 312, 312, 313, 313, 313, - 313, 313, 313, 314, 314, 314, 314, 314, 314, 315, - 315, 316, 316, 317, 317, 318, 318, 318, 319, 319, - 319, 320, 320, 320, 321, 321, 321, 321, 322, 322, - 323, 323, 323, 323, 324, 324, 324, 324, 325, 325, - 325, 325, 325, 325, 326, 327, 327, 327, 328, 328, - 329, 330, 330, 330, 330, 330, 330, 330, 331, 331, - 332, 332, 332, 332, 332, 332, 332, 332, 332, 332, - 332, 333, 333, 333, 333, 333, 333, 333, 333, 333, - 333, 333, 334, 334, 334, 334, 335, 336, 336, 337, - 337, 338, 339, 339, 341, 340, 343, 344, 342, 345, - 346, 345, 347, 347, 348, 348, 349, 348, 348, 350, - 351, 348, 352, 353, 348, 354, 355, 356, 357, 348, - 358, 359, 348, 360, 348, 361, 348, 362, 348, 348, - 348, 348, 348, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 348, 348, 348, 364, 365, 363, 367, - 368, 366, 369, 369, 371, 372, 370, 373, 373, 374, - 374, 375, 375, 375, 375, 376, 376, 376, 377, 377, - 378, 378, 378, 379, 379, 380, 380, 381, 382, 382, - 383, 383, 383, 384, 384, 384, 384, 384, 384, 384, - 386, 385, 387, 387, 388, 388, 388, 388, 388, 389, - 389, 390, 390, 390, 390, 390, 390, 391, 391, 392, - 392, 393, 394, 394, 395, 395, 395, 396, 397, 397, - 398, 398, 398, 398, 399, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400, - 400, 400, 400, 400, 400, 400, 400, 400, 400, 400 -}; - -/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ -static const yytype_uint8 yyr2[] = -{ - 0, 2, 0, 1, 0, 2, 2, 1, 0, 0, - 0, 1, 1, 0, 2, 2, 1, 1, 5, 4, - 5, 4, 0, 6, 0, 5, 1, 2, 1, 2, - 0, 6, 2, 3, 3, 3, 3, 4, 0, 5, - 2, 3, 1, 1, 2, 2, 1, 2, 0, 5, - 3, 1, 3, 1, 0, 2, 2, 3, 1, 3, - 1, 3, 1, 3, 2, 2, 2, 1, 1, 5, - 4, 2, 2, 3, 3, 2, 2, 3, 3, 2, - 2, 2, 2, 2, 1, 1, 1, 0, 1, 2, - 0, 1, 4, 3, 3, 0, 8, 5, 0, 9, - 6, 0, 8, 5, 0, 9, 6, 2, 2, 1, - 2, 1, 6, 4, 6, 4, 2, 1, 2, 2, - 1, 2, 1, 2, 2, 4, 2, 3, 0, 0, - 1, 3, 2, 3, 1, 4, 2, 4, 2, 4, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 0, 6, 0, 6, 0, 5, 0, 5, - 0, 7, 0, 7, 0, 6, 0, 6, 0, 0, - 5, 5, 1, 1, 5, 5, 0, 1, 1, 0, - 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 3, 1, 3, 0, 1, 1, - 0, 7, 1, 1, 3, 4, 3, 0, 3, 1, - 3, 3, 3, 3, 1, 1, 1, 2, 2, 2, - 2, 2, 2, 2, 4, 2, 4, 2, 3, 3, - 4, 5, 6, 6, 7, 2, 4, 5, 2, 2, - 1, 0, 4, 4, 3, 1, 3, 2, 3, 4, - 1, 2, 5, 1, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 5, 3, 3, 1, 2, 3, 3, - 1, 1, 1, 1, 1, 0, 5, 5, 5, 5, - 5, 1, 1, 1, 1, 2, 1, 2, 2, 3, - 4, 4, 1, 1, 1, 3, 1, 1, 1, 1, - 3, 3, 3, 0, 4, 4, 2, 4, 2, 4, - 2, 2, 1, 4, 1, 7, 7, 7, 7, 4, - 4, 2, 2, 2, 1, 4, 2, 2, 5, 3, - 2, 2, 5, 3, 5, 3, 4, 6, 2, 1, - 2, 1, 2, 1, 1, 1, 2, 0, 2, 2, - 3, 3, 3, 2, 2, 2, 1, 1, 1, 2, - 2, 2, 2, 1, 1, 1, 1, 2, 2, 3, - 3, 3, 4, 1, 2, 2, 2, 1, 1, 1, - 2, 2, 2, 1, 1, 2, 2, 3, 1, 2, - 1, 1, 1, 4, 4, 4, 4, 1, 1, 1, - 1, 3, 1, 3, 1, 3, 0, 4, 0, 6, - 3, 0, 4, 1, 3, 3, 0, 4, 3, 0, - 1, 1, 2, 6, 1, 3, 0, 1, 4, 6, - 4, 1, 1, 1, 1, 1, 3, 0, 2, 1, - 2, 3, 4, 1, 1, 3, 4, 3, 5, 1, - 4, 3, 3, 0, 3, 3, 3, 0, 2, 2, - 0, 7, 4, 0, 6, 3, 2, 2, 2, 0, - 0, 9, 1, 0, 1, 0, 1, 1, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 3, 4, 3, - 2, 3, 1, 0, 3, 0, 3, 2, 1, 1, - 0, 2, 3, 1, 4, 1, 3, 1, 1, 4, - 4, 2, 2, 3, 3, 1, 0, 1, 2, 3, - 2, 2, 1, 2, 2, 2, 2, 2, 2, 2, - 1, 2, 2, 3, 2, 2, 4, 4, 2, 1, - 5, 4, 1, 0, 1, 3, 0, 1, 3, 1, - 1, 1, 1, 4, 4, 4, 4, 4, 3, 4, - 4, 4, 4, 3, 1, 3, 1, 3, 2, 1, - 7, 0, 2, 1, 2, 0, 2, 4, 4, 2, - 4, 3, 3, 2, 2, 3, 1, 1, 2, 1, - 1, 2, 2, 4, 4, 3, 3, 2, 1, 1, - 2, 3, 3, 2, 2, 3, 1, 3, 3, 2, - 2, 3, 1, 4, 3, 4, 3, 1, 2, 2, - 2, 2, 2, 1, 2, 4, 4, 2, 1, 1, - 1, 1, 2, 4, 2, 2, 2, 2, 1, 2, - 2, 2, 2, 3, 1, 2, 3, 4, 2, 2, - 2, 2, 2, 2, 4, 2, 1, 2, 2, 3, - 1, 3, 2, 3, 2, 2, 3, 1, 3, 4, - 3, 2, 2, 1, 3, 2, 2, 1, 2, 3, - 1, 3, 1, 6, 4, 4, 3, 5, 3, 3, - 3, 2, 1, 1, 2, 2, 2, 0, 1, 1, - 2, 3, 1, 2, 0, 3, 0, 0, 5, 1, - 0, 2, 1, 1, 1, 2, 0, 4, 1, 0, - 0, 5, 0, 0, 7, 0, 0, 0, 0, 12, - 0, 0, 7, 0, 5, 0, 7, 0, 4, 2, - 2, 2, 3, 6, 8, 10, 12, 4, 3, 2, - 2, 1, 1, 1, 1, 1, 0, 0, 6, 0, - 0, 5, 1, 2, 0, 0, 5, 1, 1, 3, - 3, 2, 2, 2, 2, 2, 1, 2, 0, 1, - 0, 1, 1, 0, 1, 1, 3, 4, 1, 3, - 0, 1, 1, 1, 2, 2, 2, 1, 2, 2, - 0, 3, 1, 1, 1, 2, 2, 2, 4, 2, - 2, 2, 2, 2, 2, 1, 2, 1, 2, 1, - 1, 0, 0, 1, 0, 4, 2, 1, 1, 3, - 0, 3, 3, 3, 1, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, - 2, 2, 2, 3, 2, 2, 4, 4, 3, 2 -}; - -/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state - STATE-NUM when YYTABLE doesn't specify something else to do. Zero - means the default is an error. */ -static const yytype_uint16 yydefact[] = -{ - 4, 0, 13, 13, 1, 6, 0, 5, 0, 282, - 638, 639, 0, 389, 401, 583, 0, 12, 0, 0, - 0, 11, 487, 844, 0, 0, 0, 168, 670, 284, - 283, 84, 0, 0, 831, 0, 46, 0, 0, 14, - 26, 0, 28, 9, 0, 17, 16, 90, 111, 87, - 0, 640, 172, 303, 280, 304, 616, 0, 376, 0, - 375, 394, 0, 414, 393, 431, 400, 0, 502, 503, - 505, 509, 508, 482, 388, 599, 402, 600, 109, 302, - 627, 597, 0, 641, 581, 0, 0, 281, 82, 83, - 179, 644, 179, 645, 179, 285, 168, 141, 142, 143, - 145, 144, 473, 476, 0, 666, 0, 477, 0, 0, - 0, 0, 142, 143, 145, 144, 24, 0, 0, 0, - 0, 0, 0, 0, 478, 648, 0, 654, 0, 0, - 0, 38, 0, 0, 32, 0, 0, 48, 0, 646, - 0, 179, 0, 0, 614, 609, 0, 0, 0, 613, - 0, 0, 0, 0, 303, 0, 294, 585, 0, 0, - 302, 581, 29, 0, 27, 4, 47, 0, 65, 389, - 0, 0, 9, 68, 64, 67, 90, 0, 0, 0, - 400, 91, 15, 0, 429, 0, 0, 447, 88, 80, - 647, 585, 0, 581, 81, 0, 0, 0, 107, 0, - 410, 366, 596, 367, 608, 0, 581, 391, 390, 79, - 110, 377, 0, 412, 392, 108, 383, 407, 408, 378, - 396, 398, 387, 409, 0, 76, 432, 488, 489, 490, - 491, 507, 150, 149, 151, 493, 494, 173, 500, 492, - 0, 0, 495, 496, 510, 510, 525, 526, 584, 395, - 0, 426, 639, 0, 668, 172, 631, 632, 628, 602, - 642, 0, 601, 598, 0, 879, 875, 874, 872, 854, - 860, 859, 0, 866, 865, 851, 852, 850, 869, 858, - 856, 857, 855, 862, 861, 848, 849, 845, 846, 847, - 871, 853, 864, 863, 0, 870, 867, 777, 394, 778, - 840, 285, 282, 583, 307, 355, 0, 0, 0, 0, - 351, 349, 322, 353, 354, 0, 0, 0, 0, 0, - 284, 283, 276, 0, 0, 187, 186, 0, 0, 189, - 188, 0, 190, 0, 0, 180, 181, 0, 250, 0, - 253, 185, 306, 216, 0, 0, 308, 309, 0, 183, - 373, 394, 374, 633, 334, 324, 0, 0, 0, 0, - 179, 0, 475, 0, 470, 0, 667, 665, 0, 191, - 192, 0, 0, 0, 436, 4, 22, 30, 662, 658, - 659, 663, 661, 660, 141, 142, 143, 0, 145, 144, - 650, 651, 655, 652, 649, 0, 292, 293, 291, 630, - 629, 34, 33, 50, 0, 158, 0, 0, 394, 156, - 0, 0, 610, 612, 0, 611, 142, 143, 278, 279, - 298, 0, 620, 297, 0, 619, 0, 305, 284, 283, - 0, 0, 0, 296, 295, 624, 0, 0, 13, 0, - 168, 10, 10, 71, 0, 66, 0, 0, 72, 75, - 0, 428, 430, 123, 94, 128, 766, 0, 86, 85, - 93, 126, 0, 0, 124, 89, 626, 0, 0, 589, - 0, 834, 0, 594, 0, 593, 0, 0, 0, 0, - 581, 429, 0, 78, 585, 581, 607, 0, 380, 381, - 0, 77, 429, 385, 384, 386, 379, 399, 416, 415, - 179, 497, 501, 499, 0, 831, 504, 506, 0, 0, - 397, 429, 581, 95, 0, 0, 0, 0, 581, 101, - 582, 615, 639, 669, 172, 0, 0, 868, 873, 396, - 581, 581, 0, 581, 878, 179, 0, 0, 0, 223, - 0, 0, 225, 238, 239, 0, 0, 0, 0, 0, - 277, 222, 219, 218, 220, 0, 0, 0, 0, 0, - 306, 0, 0, 0, 217, 177, 178, 300, 0, 221, - 0, 0, 251, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 316, 0, 318, 321, 320, - 358, 0, 0, 359, 241, 241, 0, 227, 579, 0, - 235, 356, 348, 0, 0, 831, 337, 340, 341, 0, - 0, 368, 687, 683, 692, 0, 585, 581, 581, 581, - 370, 690, 0, 637, 372, 0, 0, 371, 336, 0, - 331, 350, 332, 352, 634, 0, 333, 176, 176, 0, - 166, 0, 394, 164, 576, 485, 574, 472, 0, 0, - 403, 0, 0, 404, 405, 406, 442, 443, 444, 441, - 0, 434, 437, 0, 4, 0, 653, 179, 656, 0, - 42, 43, 0, 54, 0, 0, 58, 62, 51, 830, - 825, 0, 373, 394, 54, 374, 829, 60, 169, 154, - 152, 169, 301, 176, 618, 617, 305, 0, 621, 0, - 19, 21, 90, 10, 10, 74, 73, 0, 129, 357, - 0, 714, 92, 712, 453, 0, 449, 448, 215, 0, - 214, 586, 625, 0, 807, 0, 802, 394, 0, 801, - 803, 832, 814, 0, 0, 623, 592, 591, 0, 0, - 606, 0, 424, 423, 411, 605, 0, 834, 595, 382, - 413, 425, 429, 0, 498, 511, 549, 639, 0, 540, - 0, 0, 552, 0, 122, 117, 0, 172, 553, 556, - 0, 532, 0, 120, 0, 429, 0, 427, 834, 800, - 179, 179, 643, 179, 834, 800, 581, 98, 581, 104, - 877, 876, 840, 840, 840, 0, 0, 0, 0, 637, - 0, 0, 0, 0, 394, 0, 0, 0, 312, 0, - 310, 311, 0, 248, 182, 282, 638, 639, 284, 283, - 0, 0, 454, 483, 0, 274, 275, 792, 791, 0, - 272, 271, 269, 270, 268, 267, 266, 264, 265, 263, - 262, 261, 256, 257, 258, 259, 260, 255, 254, 0, - 0, 0, 0, 0, 241, 229, 245, 0, 0, 228, - 581, 581, 0, 581, 578, 677, 0, 0, 0, 0, - 0, 339, 0, 343, 0, 345, 0, 686, 685, 682, - 681, 830, 0, 0, 701, 0, 0, 834, 369, 834, - 688, 581, 800, 585, 687, 683, 0, 0, 581, 0, - 393, 0, 0, 0, 0, 171, 175, 286, 169, 162, - 160, 169, 0, 486, 0, 485, 213, 212, 211, 210, - 436, 0, 0, 25, 0, 0, 657, 0, 39, 45, - 44, 56, 53, 54, 0, 49, 0, 0, 687, 683, - 0, 821, 581, 824, 826, 0, 822, 823, 55, 493, - 0, 159, 169, 169, 157, 170, 299, 18, 20, 70, - 90, 417, 146, 638, 639, 134, 148, 147, 0, 127, - 130, 0, 640, 0, 0, 0, 0, 713, 707, 450, - 0, 125, 590, 587, 806, 820, 809, 0, 588, 805, - 819, 808, 804, 833, 816, 827, 817, 810, 815, 836, - 0, 421, 604, 603, 420, 176, 831, 0, 831, 512, - 513, 515, 831, 518, 517, 581, 800, 548, 541, 553, - 542, 429, 429, 538, 539, 536, 537, 581, 800, 282, - 638, 0, 416, 118, 544, 554, 559, 560, 416, 416, - 0, 0, 416, 116, 545, 557, 416, 533, 534, 535, - 429, 531, 479, 0, 97, 0, 0, 0, 0, 103, - 0, 834, 800, 834, 800, 842, 841, 843, 287, 323, - 224, 226, 329, 330, 0, 0, 0, 0, 311, 314, - 0, 0, 0, 0, 249, 0, 315, 317, 319, 0, - 0, 0, 0, 230, 247, 0, 0, 674, 672, 0, - 675, 585, 236, 0, 0, 179, 346, 0, 0, 0, - 684, 680, 691, 581, 700, 698, 699, 689, 834, 0, - 696, 0, 635, 636, 0, 335, 167, 169, 169, 165, - 577, 575, 474, 0, 435, 433, 282, 0, 23, 31, - 664, 57, 52, 59, 63, 686, 682, 687, 683, 0, - 597, 0, 581, 688, 61, 155, 153, 69, 0, 132, - 0, 136, 0, 138, 0, 140, 0, 767, 0, 203, - 715, 0, 708, 709, 0, 451, 687, 683, 0, 306, - 0, 633, 828, 0, 0, 837, 838, 0, 0, 418, - 174, 522, 0, 521, 831, 831, 831, 0, 834, 0, - 543, 447, 447, 834, 0, 0, 0, 429, 429, 0, - 429, 429, 0, 429, 0, 447, 467, 581, 289, 288, - 290, 581, 100, 0, 106, 0, 0, 0, 0, 0, - 0, 457, 0, 455, 252, 273, 243, 242, 240, 231, - 0, 244, 246, 673, 671, 678, 676, 0, 237, 0, - 0, 338, 342, 344, 834, 694, 581, 695, 163, 161, - 471, 0, 438, 440, 686, 682, 602, 688, 133, 131, - 0, 0, 0, 0, 445, 0, 0, 282, 638, 639, - 716, 729, 732, 735, 740, 0, 0, 0, 0, 0, - 0, 0, 0, 283, 761, 769, 0, 788, 765, 764, - 763, 0, 724, 0, 0, 394, 0, 703, 722, 728, - 702, 723, 762, 0, 710, 452, 0, 636, 818, 812, - 813, 811, 0, 835, 422, 0, 0, 0, 0, 524, - 523, 516, 113, 581, 547, 551, 115, 581, 429, 429, - 568, 447, 282, 638, 0, 555, 561, 562, 416, 416, - 447, 447, 0, 447, 558, 546, 0, 834, 834, 581, - 581, 0, 0, 0, 0, 456, 0, 0, 232, 233, - 679, 347, 288, 697, 834, 0, 135, 137, 139, 774, - 768, 772, 0, 711, 706, 206, 781, 783, 784, 0, - 0, 720, 0, 0, 0, 747, 749, 750, 751, 0, - 0, 0, 0, 0, 0, 0, 782, 0, 365, 789, - 0, 725, 363, 416, 0, 364, 0, 416, 0, 0, - 0, 204, 705, 704, 726, 760, 759, 311, 839, 419, - 519, 520, 514, 834, 834, 567, 564, 566, 0, 0, - 429, 429, 429, 563, 565, 550, 469, 0, 468, 463, - 96, 102, 834, 834, 325, 326, 327, 328, 458, 0, - 234, 693, 439, 0, 773, 446, 195, 0, 717, 730, - 719, 0, 0, 0, 0, 0, 743, 0, 752, 0, - 758, 40, 145, 35, 145, 0, 36, 770, 0, 361, - 362, 0, 0, 0, 360, 205, 720, 112, 114, 429, - 429, 573, 447, 447, 0, 0, 481, 99, 105, 580, - 0, 775, 202, 0, 394, 0, 720, 0, 733, 721, - 707, 786, 736, 0, 0, 0, 0, 748, 757, 41, - 37, 0, 0, 727, 572, 570, 569, 571, 466, 465, - 459, 87, 90, 0, 0, 0, 196, 416, 718, 207, - 731, 209, 0, 787, 0, 785, 741, 745, 744, 771, - 793, 0, 0, 464, 779, 780, 776, 429, 707, 193, - 0, 0, 199, 0, 198, 720, 0, 0, 0, 794, - 795, 753, 462, 0, 461, 0, 208, 0, 734, 737, - 742, 746, 0, 793, 0, 0, 460, 200, 194, 0, - 0, 0, 754, 796, 0, 0, 797, 0, 0, 201, - 738, 798, 0, 755, 0, 0, 0, 739, 799, 756 -}; - -/* YYDEFGOTO[NTERM-NUM]. */ -static const yytype_int16 yydefgoto[] = -{ - -1, 1, 438, 3, 439, 167, 711, 333, 183, 5, - 6, 39, 674, 375, 1308, 675, 772, 1309, 1310, 395, - 1414, 679, 43, 773, 404, 685, 941, 686, 687, 688, - 45, 174, 175, 46, 457, 186, 182, 47, 48, 789, - 1072, 795, 1074, 49, 775, 776, 187, 188, 458, 718, - 979, 980, 654, 981, 236, 50, 963, 962, 701, 698, - 1138, 1137, 921, 918, 138, 961, 51, 238, 52, 915, - 567, 334, 335, 336, 337, 1311, 1581, 1478, 1583, 1523, - 1614, 1180, 1560, 1578, 369, 907, 338, 1249, 862, 606, - 869, 339, 340, 370, 342, 360, 54, 257, 680, 420, - 156, 55, 56, 343, 562, 344, 345, 346, 347, 459, - 348, 1312, 498, 628, 349, 1313, 58, 219, 691, 350, - 220, 540, 221, 199, 212, 62, 481, 499, 1335, 752, - 1198, 200, 213, 63, 511, 753, 64, 65, 670, 671, - 672, 1285, 464, 832, 833, 1551, 1552, 1516, 1458, 1366, - 66, 658, 363, 1226, 1459, 1093, 924, 67, 68, 69, - 70, 71, 244, 245, 72, 73, 506, 1019, 1020, 1021, - 1022, 247, 508, 509, 786, 780, 781, 782, 1044, 1054, - 1045, 1355, 1046, 1047, 1356, 1357, 655, 656, 607, 897, - 352, 467, 468, 193, 201, 75, 76, 77, 202, 144, - 145, 159, 79, 134, 353, 354, 355, 81, 356, 83, - 1024, 125, 126, 127, 516, 107, 84, 357, 874, 875, - 892, 631, 1316, 1317, 1181, 1182, 1183, 722, 1318, 988, - 1319, 1399, 1526, 1481, 1482, 1320, 1321, 1506, 1400, 1527, - 1401, 1562, 1402, 1564, 1609, 1624, 1403, 1585, 1536, 1586, - 1487, 460, 719, 1283, 1322, 1417, 1541, 1390, 1391, 1473, - 1555, 1525, 1521, 1323, 1532, 1420, 839, 1588, 1589, 1590, - 1622, 738, 739, 1008, 1194, 1331, 740, 741, 742, 1004, - 743, 150, 1006, 745, 1196, 1197, 534, 86, 87 -}; - -/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing - STATE-NUM. */ -#define YYPACT_NINF -1415 -static const yytype_int16 yypact[] = -{ - 149, 229, 265, -1415, -1415, -1415, 10477, -1415, 58, 39, - 219, 332, 138, 239, -1415, -1415, 744, -1415, 253, 285, - 295, -1415, -1415, -1415, 1130, 1379, 889, 352, -1415, 620, - 393, -1415, 1802, 1802, -1415, 4055, -1415, 10477, 406, -1415, - -1415, 470, -1415, 210, 10535, -1415, -1415, 497, 383, 526, - 516, 571, -1415, -1415, -1415, -1415, 384, 2547, -1415, 5045, - -1415, 2065, 311, -1415, 619, -1415, -1415, 1389, 462, -1415, - -1415, -1415, -1415, 595, 3778, -1415, -1415, -1415, 564, -1415, - -1415, -1415, 697, -1415, -1415, 841, 7934, 585, -1415, -1415, - 9553, -1415, 9553, -1415, 9553, -1415, -1415, -1415, 219, 332, - 624, 393, 574, 658, 571, -1415, 589, -1415, 841, 9638, - 9638, 650, -1415, -1415, -1415, -1415, -1415, 82, 657, 636, - 653, 696, 673, 704, -1415, -1415, 1705, -1415, 1050, 219, - 332, -1415, 624, 393, -1415, 1619, 966, 754, 10828, -1415, - 9553, 9553, 4289, 3931, -1415, -1415, 807, 925, 3931, -1415, - 1205, 4309, 4309, 4055, 662, 722, -1415, 745, 737, 734, - 743, -1415, -1415, 849, -1415, 759, -1415, 10593, -1415, -1415, - 352, 5201, 774, -1415, -1415, -1415, 497, 625, 10886, 467, - 814, -1415, -1415, 784, 619, 878, 94, 519, 825, -1415, - -1415, 793, 192, -1415, -1415, 4422, 4422, 4542, 564, 893, - -1415, -1415, 567, -1415, -1415, 1098, -1415, -1415, -1415, -1415, - -1415, 2065, 1000, -1415, 619, 564, -1415, -1415, -1415, 2404, - 2065, -1415, 619, -1415, 625, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, 833, -1415, 571, -1415, 619, - 1770, 1242, -1415, -1415, 846, 846, -1415, -1415, -1415, 1183, - 841, -1415, 828, 1592, -1415, 326, -1415, -1415, -1415, -1415, - -1415, 4611, -1415, -1415, 501, -1415, 824, 832, -1415, -1415, - -1415, -1415, 853, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, 826, -1415, -1415, -1415, 1183, 3778, - 1030, -1415, -1415, 856, -1415, -1415, 10239, 10324, 10409, 10409, - -1415, -1415, -1415, -1415, -1415, 863, 886, 891, 901, 905, - 624, 999, 9723, 1265, 10409, -1415, -1415, 10409, 10409, -1415, - -1415, 3227, -1415, 10409, 419, 903, -1415, 10409, -1415, 9808, - -1415, 11139, 353, 1941, 2775, 9893, -1415, 979, 3627, -1415, - 1035, 2243, 2707, -1415, 422, -1415, 1921, 2346, 419, 419, - 9553, 10828, -1415, 1265, 883, 1265, -1415, -1415, 890, 941, - 11072, 895, 897, 902, 1650, 759, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, 657, 636, 653, 1265, 696, 673, - 939, 704, -1415, 961, -1415, 2113, 219, 332, -1415, -1415, - -1415, -1415, -1415, -1415, 6202, -1415, 625, 6328, 2214, -1415, - 705, 419, -1415, -1415, 616, -1415, 948, 951, -1415, -1415, - -1415, 3931, -1415, -1415, 3931, -1415, 919, -1415, -1415, -1415, - 737, 737, 737, -1415, -1415, -1415, 4611, 54, 922, 927, - -1415, -1415, -1415, -1415, 10828, -1415, 1072, 1101, -1415, -1415, - 849, -1415, 619, -1415, -1415, -1415, -1415, 96, -1415, -1415, - -1415, -1415, 7597, 9723, -1415, -1415, -1415, 9723, 932, -1415, - 6839, 121, 4874, -1415, 4874, -1415, 5823, 5823, 4542, 956, - -1415, 619, 625, -1415, 938, -1415, -1415, 5878, 2404, 2065, - 625, -1415, 619, -1415, -1415, 619, 2404, -1415, 1029, -1415, - 9553, 833, -1415, -1415, 1770, -1415, -1415, -1415, 3869, 68, - 1183, 619, -1415, -1415, 994, 1001, 1024, 1022, -1415, -1415, - -1415, -1415, 885, -1415, 444, 1002, 1005, -1415, -1415, 1183, - -1415, -1415, 822, -1415, -1415, 9553, 9723, 856, 3227, -1415, - 469, 3227, -1415, -1415, -1415, 9638, 3937, 3937, 3937, 3937, - 11117, -1415, -1415, -1415, -1415, 1010, 9984, 9984, 3227, 1016, - 222, 1021, 1079, 1033, -1415, -1415, -1415, -1415, 9553, -1415, - 7140, 3227, -1415, 9723, 9723, 7687, 9723, 9723, 9723, 9723, - 9723, 9723, 9723, 9723, 9723, 9723, 9723, 9723, 9723, 9723, - 9723, 9723, 9723, 9723, 9723, -1415, 9723, -1415, -1415, -1415, - -1415, 9723, 9723, -1415, -1415, -1415, 3641, 592, 542, 8293, - -1415, -1415, -1415, 1089, 1592, 1140, 594, 605, 644, 2005, - 925, -1415, 1370, 1370, -1415, 3036, 1040, 1064, 1122, -1415, - -1415, 641, 8844, 360, -1415, 1013, 841, -1415, -1415, 9723, - -1415, -1415, -1415, -1415, -1415, 109, 585, -1415, -1415, 419, - -1415, 625, 2642, -1415, 1108, 1117, -1415, -1415, 1265, 939, - -1415, 8028, 8118, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - 169, -1415, 1097, 1086, 759, 2113, 1127, 9553, -1415, 1145, - -1415, -1415, 966, 1385, 1154, 329, 1143, 1149, -1415, -1415, - 2183, 10886, 2183, 4191, 1389, 5667, -1415, 1159, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, -1415, 1116, 1121, -1415, 1165, - -1415, -1415, 497, -1415, -1415, -1415, -1415, 70, 752, 1168, - 1079, -1415, -1415, -1415, -1415, 7047, 11117, -1415, 941, 1128, - 11072, -1415, -1415, 1131, -1415, 1144, 299, 5377, 1147, -1415, - 237, 10652, 1191, 1201, 647, -1415, -1415, -1415, 4874, 4874, - -1415, 5878, -1415, 1211, -1415, -1415, 1162, 121, -1415, 2404, - -1415, -1415, 619, 1202, -1415, 2961, -1415, 907, 931, -1415, - 9723, 3137, -1415, 3137, 348, 348, 438, 652, 4748, 10710, - 5499, -1415, 174, 348, 1213, 619, 6087, -1415, 121, 10997, - 9553, 9553, -1415, 9553, 121, 10997, -1415, -1415, -1415, -1415, - -1415, -1415, 767, 767, 767, 419, 1172, 1174, 9208, 1122, - 1175, 1177, 1178, 1215, 3331, 1219, 1232, 1235, -1415, 1179, - -1415, -1415, 1203, -1415, -1415, 1253, 312, 603, 151, 437, - 9723, 1254, -1415, 1259, 1216, 11117, 11117, -1415, -1415, 1263, - 11157, 11174, 11190, 11205, 4770, 3406, 3812, 2123, 2123, 2123, - 1331, 1331, 1221, 1221, 1081, 1081, 1081, -1415, -1415, 1223, - 1224, 1226, 9723, 9638, -1415, 592, -1415, 7597, 9723, -1415, - -1415, -1415, 9723, -1415, -1415, 1241, 10409, 1231, 1260, 1271, - 1299, -1415, 9723, -1415, 9723, -1415, 9723, 1678, -1415, 1678, - -1415, 112, 1252, 1255, -1415, 1239, 3937, 121, -1415, 121, - 2316, -1415, 10997, 1251, 9026, 9026, 6261, 1256, 9808, 1258, - 737, 1894, 2346, 1042, 1261, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, 9723, 1265, 1262, 1117, -1415, 11117, -1415, 11117, - 1650, 1264, 10069, -1415, 1267, 1310, -1415, 419, -1415, -1415, - -1415, -1415, -1415, 2881, 6202, -1415, 3937, 9553, 1900, 1900, - 3463, -1415, -1415, -1415, -1415, 1098, -1415, -1415, -1415, 989, - 9723, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - 497, -1415, 657, 636, 653, -1415, 696, 673, 9723, 1319, - -1415, 667, 704, 728, 757, 1344, 1079, -1415, 66, -1415, - 49, -1415, -1415, -1415, -1415, -1415, -1415, 8935, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, 1201, 1328, -1415, -1415, -1415, - 3937, -1415, -1415, -1415, 1340, -1415, -1415, 1326, -1415, 1360, - -1415, -1415, 578, -1415, -1415, -1415, 10997, 11117, -1415, 2477, - -1415, 619, 619, -1415, -1415, -1415, -1415, -1415, 10997, 524, - 781, 9723, 1029, -1415, 1362, -1415, -1415, -1415, 198, 366, - 697, 925, 377, 348, 1363, -1415, 423, -1415, -1415, -1415, - 619, -1415, -1415, 8361, -1415, 1322, 419, 419, 419, -1415, - 1329, 121, 10997, 121, 10997, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, 1346, 1352, 1356, 1359, 1116, -1415, - 11005, 7597, 7233, 1343, -1415, 9723, -1415, -1415, -1415, 1347, - 1345, 1353, 3937, -1415, -1415, 1364, 255, 205, 205, 1357, - 205, -1415, -1415, 10409, 1447, 9553, -1415, 1365, 1366, 1371, - -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, 121, 1372, - -1415, 1374, -1415, -1415, 1911, -1415, -1415, -1415, -1415, -1415, - 11117, -1415, -1415, 1358, -1415, -1415, 245, 1375, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, 2851, 2851, 2966, 2966, 3463, - -1415, 1098, -1415, 3526, 11139, -1415, -1415, -1415, 1381, -1415, - 752, -1415, 9723, -1415, 9723, -1415, 9723, -1415, 1265, -1415, - -1415, 6637, 1437, -1415, 7323, -1415, 9117, 9117, 6745, 140, - 1387, 425, -1415, 7597, 7413, -1415, -1415, 259, 7597, -1415, - -1415, -1415, 9638, -1415, -1415, -1415, -1415, 1351, 121, 1388, - -1415, 1419, 1419, 121, 1390, 9723, 9723, 10916, 619, 5724, - 619, 619, 1210, 619, 5938, 1419, -1415, -1415, -1415, 1433, - -1415, -1415, -1415, 1397, -1415, 1399, 9723, 9723, 9723, 9723, - 7597, -1415, 1448, -1415, -1415, 11117, -1415, -1415, -1415, 569, - 1353, -1415, -1415, -1415, -1415, -1415, -1415, 1401, -1415, 1466, - 419, -1415, -1415, -1415, 121, -1415, -1415, -1415, -1415, -1415, - -1415, 9723, -1415, -1415, 2851, 2851, -1415, 3526, -1415, -1415, - 1407, 1408, 1410, 1428, -1415, 1107, 318, 1462, 837, 851, - -1415, -1415, -1415, -1415, -1415, 9723, 1474, 1477, 1478, 9293, - 451, 1265, 430, 656, -1415, -1415, 9383, 1530, -1415, -1415, - -1415, 1481, -1415, 5599, 10770, 4975, 6527, -1415, -1415, 1527, - -1415, -1415, -1415, 8454, -1415, -1415, 1443, 420, -1415, -1415, - -1415, -1415, 3937, -1415, -1415, 7597, 1444, 1449, 2961, -1415, - -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, 10916, 10916, - -1415, 1419, 794, 869, 9723, -1415, -1415, -1415, 1029, 1029, - 1419, 1419, 885, 1419, -1415, -1415, 6395, 121, 121, -1415, - -1415, 1455, 1456, 1465, 1467, -1415, 7597, 9723, -1415, 569, - -1415, -1415, -1415, -1415, 121, 1468, -1415, -1415, -1415, -1415, - 1428, -1415, 1265, -1415, -1415, -1415, -1415, -1415, -1415, 792, - 792, 1079, 1453, 1463, 5091, -1415, -1415, -1415, -1415, 1496, - 9723, 1510, 1511, 1524, 1545, 1693, -1415, 1079, -1415, -1415, - 1487, -1415, -1415, 1029, 1120, -1415, 1141, 1029, 9468, 1157, - 324, -1415, -1415, -1415, -1415, -1415, -1415, 525, -1415, -1415, - -1415, -1415, -1415, 121, 121, -1415, -1415, -1415, 9723, 9723, - 10916, 619, 619, -1415, -1415, -1415, -1415, 8208, -1415, -1415, - -1415, -1415, 121, 121, -1415, -1415, -1415, -1415, -1415, 1480, - -1415, -1415, -1415, 1497, -1415, -1415, -1415, 9638, -1415, -1415, - -1415, 1583, 8750, 6949, 9638, 9723, -1415, 8562, -1415, 1544, - -1415, -1415, 1551, -1415, 1524, 1545, -1415, -1415, 849, -1415, - -1415, 10154, 10154, 7507, -1415, -1415, 1079, -1415, -1415, 10916, - 10916, -1415, 1419, 1419, 1500, 11027, 1513, -1415, -1415, -1415, - 11010, -1415, -1415, 1503, 190, 625, 1079, 8656, -1415, -1415, - 66, -1415, -1415, 1548, 1504, 11095, 8562, -1415, -1415, -1415, - -1415, 1428, 81, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - -1415, 526, 497, 1505, 1506, 1079, -1415, 1029, -1415, -1415, - -1415, -1415, 811, -1415, 7777, -1415, -1415, -1415, -1415, 1428, - 1605, 1557, 193, -1415, -1415, -1415, -1415, 619, 66, -1415, - 9723, 1559, -1415, 1561, -1415, 1079, 8562, 1534, 51, 1570, - -1415, -1415, -1415, 96, -1415, 1569, -1415, 1526, -1415, -1415, - -1415, -1415, 9723, 1605, 1575, 1605, -1415, -1415, -1415, 7867, - 1531, 95, -1415, -1415, 7597, 1532, -1415, 1627, 1585, -1415, - -1415, -1415, 382, -1415, 8656, 1632, 1587, -1415, -1415, -1415 -}; - -/* YYPGOTO[NTERM-NUM]. */ -static const yytype_int16 yypgoto[] = -{ - -1415, -1415, 1652, -1415, -333, 1484, -394, 17, 4, 1663, - -1415, 1631, -1415, -1415, 114, -1415, 264, -1415, 275, -1415, - 256, 995, 20, 13, -1415, -1415, -638, -1415, -1415, 735, - 47, 1507, 1236, 1517, -706, 134, -175, -7, 148, -1415, - -1415, -1415, -1415, -1415, 911, -1415, -1415, -1415, -1415, -1415, - -1415, 521, 1146, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, 1593, -582, 5825, 1454, -49, -602, - -101, -70, 1555, -538, -1415, 682, -1415, 300, -1415, -1394, - -1415, -1397, 77, -1415, 1218, 1294, -272, 452, -535, -1415, - -829, 1686, 7, 1552, 3607, 1411, -329, -72, -76, 680, - -141, -67, 91, -1415, -1415, -1415, -328, -1415, -155, -1415, - -1415, -1230, -50, -340, 4852, 136, 910, -113, 79, 100, - -205, -6, -146, -168, -174, 14, -23, 120, -1415, -370, - -1415, -1415, -1415, -1415, -1415, 211, 1306, 8, -1415, 785, - -1415, -1415, -1097, -379, 986, -1415, -1415, -1415, -1415, -1415, - -18, -1415, -1415, -1415, -1415, -1415, 797, -352, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, -1415, 1472, -1415, 380, 512, - -1415, -1415, -1415, -1415, -1415, 937, -671, -1415, -1415, -1415, - -1415, -1415, -1415, 947, -1415, 504, 1071, 808, 1133, 4227, - 45, 19, -457, 1538, 1269, -669, -1415, 2, -1415, 820, - 4043, -149, 171, -104, 4531, 1396, -1415, 4888, 2552, 73, - -20, -116, -1415, 1607, -81, -1415, 4712, 3373, -31, -1415, - 1976, -1415, -1415, 435, -1415, -1415, 570, 162, -441, -1415, - -1415, -1415, -1415, -1358, -1415, -1187, -1388, -1415, -1415, -1415, - -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, -1415, - -1415, 187, -1415, -1415, -1415, -1415, -1415, 224, -1324, -1415, - -1415, -47, -1415, -1415, -1415, -1415, -1414, 160, -1415, 161, - -1415, -678, -585, 762, -1415, -1415, -1415, -1415, -390, -1415, - -384, -443, -1415, 1611, 440, -1415, -214, -1415, -232 -}; - -/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If - positive, shift that token. If negative, reduce the rule which - number is the opposite. If zero, do what YYDEFACT says. - If YYTABLE_NINF, syntax error. */ -#define YYTABLE_NINF -831 -static const yytype_int16 yytable[] = -{ - 61, 445, 422, 425, 447, 124, 489, 198, 437, 446, - 38, 633, 394, 986, 696, 258, 723, 434, 105, 44, - 697, 517, 358, 37, 359, 184, 180, 756, 642, 643, - 824, 61, 402, 255, 539, 542, 1103, 176, 61, 300, - 893, 38, 673, 223, 510, 393, 916, 893, 712, 983, - 44, 74, 694, 211, 37, 251, 958, 44, 179, 400, - 401, 171, 765, 399, 172, 611, 1474, 572, 249, 1533, - 863, 411, 226, 494, 497, 192, 1418, 143, 148, 258, - 298, 611, 74, 727, 351, 59, 351, 262, 351, 74, - 1534, 173, 611, 529, 1529, 454, 1023, 720, 488, 1178, - 1028, 965, 1030, 351, 351, 784, 60, 496, 1184, 1057, - 366, 1065, 90, 1603, 1344, 1345, 59, 1070, 88, 964, - 40, 822, 761, 178, 994, 646, 157, 198, 1365, 1433, - 520, 299, 408, 1563, 351, 351, 1436, 60, 258, 1561, - 376, 787, 57, 1570, 60, 377, 529, 310, 1543, -2, - 226, 40, -357, 180, 721, 260, 455, 1617, 1185, 1604, - 442, 61, 709, 28, 176, 61, 226, 89, 1558, 895, - 1584, 995, 211, 57, 996, 1179, 192, 785, 971, 260, - 177, 1596, 744, 74, 44, 179, 297, -303, 171, 1571, - 456, 172, 492, 223, 1592, 1615, 421, 424, 217, 218, - 809, 223, 223, 1618, 16, 139, 160, 210, 260, 129, - 130, 95, 74, -145, 520, 524, 74, 407, 173, 260, - 823, 192, 226, -366, 1129, 17, 22, 1600, 930, 4, - 226, 223, -303, -303, 1058, 25, 1561, 621, 60, 469, - 472, 474, 157, 157, 157, 1474, 59, 226, -296, 999, - 178, -357, 262, 1531, 1447, 455, -366, 647, 648, 28, - -366, 132, 133, 1453, 1454, -3, 1455, 60, 165, 595, - 41, 60, 617, 91, 406, 870, 616, 931, 260, 987, - 223, 42, 808, 1059, 470, 871, 405, 96, 157, 456, - 649, 681, 92, 249, -366, 717, 1000, 608, 872, 1001, - 1537, 41, 621, 57, 1271, 1151, 676, 177, 166, 702, - 703, 994, 42, 260, 596, 543, 544, 643, 1332, 969, - 970, 893, 160, 160, 160, 351, 210, 422, 425, 1102, - -296, 552, 943, 223, 553, 554, 1136, 260, 298, 1139, - 564, 934, 494, 497, 569, 109, 249, 808, 1209, 1568, - 494, 696, 610, 1272, 351, 652, 699, 1005, 995, 262, - 1214, 996, -830, 1252, 497, 893, 91, 1333, 160, -581, - 224, 225, -581, 518, -142, 17, 759, 110, 1394, -416, - 1165, 1166, 517, 497, 1394, 92, 93, 111, 944, 299, - 223, -367, 1057, 17, 1233, 451, 1235, 633, 693, 1601, - 595, 211, -121, 945, 17, 94, 74, 898, -416, 1154, - 17, -416, 893, 1200, -416, 1546, 1547, 684, 519, -581, - 1378, -581, -581, -581, -367, 137, 180, 1395, -367, 260, - 763, -585, -305, 1505, -581, -121, -581, 714, 61, -121, - 407, 1625, -416, -416, 297, 596, 1131, -305, -119, 695, - 17, -305, -581, -581, 97, 112, 113, -416, 179, 777, - 226, 60, -367, 1033, 737, 805, 141, -305, -581, 638, - 223, 223, -627, -121, 131, 762, -585, 191, 223, -305, - -305, -119, -305, -305, 28, -119, 1413, 260, 1104, 74, - 1626, 798, 223, 565, 351, 566, 1034, 651, 163, -144, - 1035, 983, 61, 226, 692, 10, 522, 114, 115, 650, - 141, 223, -305, -305, 639, 695, 621, -627, -627, -119, - 242, 748, 749, 178, 243, 771, 224, 448, -305, 351, - 164, 1410, 351, -627, 1036, 351, 799, 968, 1023, 351, - 814, 814, 814, 814, 60, 1177, 129, 130, 917, 365, - 1470, 185, 351, 74, 696, 1268, 1269, 132, 133, 608, - 697, 808, 351, 552, 553, 351, 461, 157, 157, 157, - 692, 681, -305, 1201, 893, 1203, 189, 260, 940, 1207, - 177, 523, 462, 642, 643, 1205, 1215, 779, 1075, 1076, - 1077, 17, 694, 10, 11, -416, 28, 90, 132, 133, - 298, 919, 754, 893, 181, 260, 939, 937, 60, 529, - 760, 463, 870, 494, -585, 1206, 866, -305, -305, 693, - 129, 130, 871, -416, -416, 190, 737, -416, 9, 10, - 11, 12, 867, -299, 223, 872, 572, 365, 262, 866, - 951, 881, 956, 957, 778, 132, 133, 160, 160, 160, - 20, 299, 883, 246, 1257, 867, 774, 93, 301, -585, - 484, 868, 1377, 124, 365, -143, 23, 887, 889, 1023, - 695, 351, 132, 133, 139, 223, 94, 695, 139, 28, - 646, 29, 30, 362, 868, 211, 882, 957, 901, 249, - 379, 885, 260, 140, 1009, 195, 523, 884, 984, 1037, - 9, 10, 252, 12, 1078, 196, 297, 380, 260, 92, - 34, 378, 1241, 1243, 1171, 155, 364, 197, 1416, 223, - 1066, 1067, 777, 1068, 777, 692, 94, 382, 1043, 141, - 777, 777, 692, 902, 903, 693, 886, 777, 23, 1010, - 302, 223, 374, 12, 1038, 253, 141, 97, 98, 99, - 381, 1031, 1032, 29, 30, 972, 973, 974, 383, 1172, - 1060, 1338, 1339, 1340, 568, 61, 809, 61, 20, 434, - -296, 129, 130, 211, 61, 1173, 520, 254, 23, 565, - 61, 566, 34, 693, 351, 351, 695, 351, 771, 693, - 771, 368, 372, 428, 429, 1167, 223, 771, 28, 975, - 100, 101, 102, 771, 1175, 1243, 28, 430, 976, 977, - 9, 129, 130, 12, 1328, 1330, 74, 431, 74, 1334, - 1174, 28, 34, 132, 133, 74, 129, 130, 403, 432, - 427, 74, 423, 426, 695, 91, 1150, 530, 191, 1476, - 695, 692, 435, 1216, 978, 10, 11, 531, 23, 1176, - 779, -622, 779, 149, 92, 253, 1448, 351, 1579, 779, - 305, 1375, 1106, 29, 30, 779, 1593, 90, -8, 394, - 365, 60, 166, 60, 449, 512, 450, 155, 132, 133, - 60, 453, 93, 1112, 1477, 465, 60, 254, 258, 692, - 814, 91, 34, 129, 130, 692, 693, 132, 133, 1397, - 737, 94, 254, 1580, 466, 93, 500, 778, 505, 1029, - 92, 552, 553, 1398, 262, 527, 778, 525, 226, 774, - 513, 774, 778, 91, 94, 526, 1042, 1052, 774, 129, - 130, 1449, 796, 131, 774, 129, 130, 528, 693, 93, - 814, 351, 92, 28, 693, 132, 133, 695, 536, 887, - 889, 695, 482, 483, 1025, 545, 1439, 684, 94, 546, - 1480, 93, 568, 413, 547, 1228, 1229, 1230, 415, 302, - 396, 397, 12, 1014, 548, 809, 1497, 797, 549, 1043, - 94, 132, 133, 258, 260, 28, 260, 132, 133, 695, - 611, 737, 657, 1155, 1156, 695, 1062, 1468, 660, 1026, - 661, 255, 692, 663, 814, 664, 692, 23, 422, 425, - 665, 561, 677, 559, 777, 678, 149, 10, 11, 1218, - 693, 92, 320, 30, 94, 1220, 1221, 706, 260, 1218, - 1223, -7, 693, 1221, 129, 130, 710, 422, 425, 129, - 130, 157, 695, 732, 692, 1260, 10, 11, -53, 755, - 692, 34, -53, 118, 119, 120, 17, 61, -184, 490, - 491, 365, 500, -53, 750, 1480, 693, 790, 693, 132, - 133, 695, 141, -184, 791, -184, 1253, 1254, 792, 1256, - 771, 521, 621, 695, 28, 1480, 132, 133, 157, 28, - 365, 132, 133, 254, 258, 793, 814, 692, 132, 133, - 530, 9, 10, 11, 12, 622, 121, 122, 74, 351, - 531, 423, 707, 800, 1576, 623, 801, 695, 818, 695, - 1258, 160, 523, 260, 820, 624, 692, 625, 626, 821, - 696, 482, 715, 97, 112, 113, 1554, 721, 692, 23, - 1426, 823, 779, 878, 1480, 1424, 253, 1429, 880, 731, - 984, 894, 723, 693, 29, 30, 896, 423, 426, 1382, - 490, 716, 103, 60, 593, 594, 1392, 1393, 160, 898, - 117, 922, 692, 524, 692, 1315, 923, 1042, 254, 482, - 1499, 936, 737, 34, 809, 1307, 114, 115, 116, 932, - 22, 217, 218, 552, 553, 933, 351, 16, 1306, 778, - 490, 1500, 1274, 1275, 695, 938, 946, 260, 97, 416, - 417, 774, 947, 235, 129, 1362, 482, 1504, 561, 22, - 559, 561, 960, 559, -299, 967, 74, 811, 25, 966, - 455, 1274, 1275, 695, 260, 1619, 991, 423, 819, 992, - 559, 704, 1211, 1212, 705, 97, 98, 99, 157, 157, - 157, 561, 993, 559, -829, 998, 708, 838, 365, 692, - 1314, 114, 101, 1423, 1007, 1423, 132, 133, 97, 112, - 113, 1225, 390, 1012, 1011, 1061, 1015, 157, 157, 157, - 1079, 60, 1080, 1081, 861, 1082, 1083, 1088, 692, 1084, - 523, 877, 413, 1085, 415, 260, 418, 223, 100, 101, - 1315, 590, 591, 592, 593, 594, 1086, 521, 211, 1087, - 1315, 1089, 909, 564, 690, -141, 1091, 1315, 1092, 529, - 1307, 114, 115, 1306, 1094, 1095, 814, 1307, 160, 160, - 160, 1096, 1097, 1306, 1111, 1451, 1452, 1098, 142, 142, - 1306, 158, 1113, 1542, 1115, 1114, 1116, 118, 973, 974, - 1124, 74, 422, 425, 118, 973, 974, 160, 160, 160, - 1122, 74, 1130, 1123, 1132, 214, 1133, 222, 74, 1135, - 1149, 1142, 1145, 239, 129, 130, 1148, 1573, 1170, 15, - 690, 1017, 118, 119, 120, 1314, 501, 503, 384, 385, - 386, 1193, 97, 98, 99, 1314, 227, 228, 229, 515, - 121, 122, 1314, 1199, 492, 28, 60, 121, 122, 588, - 589, 590, 591, 592, 593, 594, 60, 621, 1202, 1204, - 20, 1219, 1224, 60, 28, 230, 132, 133, 1350, 1351, - 1227, 1360, 1361, 28, 1363, 121, 122, 1231, 1236, 28, - 622, 388, 389, 28, 1237, 100, 101, 231, 1238, 142, - 623, 1239, 1244, 1247, 142, 1259, 1246, 158, 158, 158, - 624, 1248, 625, 626, 473, 475, 479, 1270, 1255, 551, - 1178, 1524, 1251, 1261, 1262, 1557, 1315, 1315, 1524, 1263, - 1266, 1315, 462, 1273, 214, 1267, 1307, -664, 909, 1278, - 452, 1307, 232, 233, 234, 1327, 1343, 351, 1347, 1306, - 1306, 142, 142, 158, 1306, 1369, 223, 1370, 552, 553, - 1376, 659, 1380, 1381, 693, 1386, 1387, 222, 1388, 157, - 669, 1315, 299, 1389, 1396, 495, 222, 74, 74, 299, - 1315, 1307, 74, 659, 1577, 690, 1405, 1406, 1407, 1419, - 1307, 1421, 690, 1434, 1306, 1483, 748, 749, 97, 112, - 113, 1437, 1440, 1306, 1109, 1484, 1488, 1441, 1524, 1445, - 1446, 1314, 1314, 1464, 1465, 695, 1314, 142, 704, 705, - 1490, 708, 74, 1466, 377, 1467, 1472, 297, 1491, 1498, - 1315, 74, 60, 60, 297, 423, 819, 60, 559, 1520, - 1307, 1519, 157, 157, 157, 97, 112, 113, 514, 160, - 1528, 1492, 115, 1306, 1538, 1539, 1314, 1548, 1565, 299, - 1550, 1556, 1566, 1574, 1575, 1314, 1587, 1591, 1315, 1598, - 692, 1599, 302, 396, 397, 12, 1602, 60, 1307, 1605, - 155, 74, 1607, 23, 1608, 1612, 60, 158, 1621, 1616, - 1620, 1306, 341, 1628, 341, 1623, 341, 1629, 114, 115, - 764, 690, 2, 97, 112, 113, 444, 666, 667, 668, - 23, 1511, 1512, 1513, 297, 1314, 7, 253, 162, 74, - 935, 1495, 160, 160, 160, 320, 30, 1190, 443, 1152, - 713, 728, 129, 130, 441, 1572, 60, 248, 728, 361, - 1053, 1279, 341, 341, 502, 410, 97, 112, 113, 690, - 1479, 1627, 1379, 1314, 34, 690, 114, 115, 384, 385, - 386, 990, 535, 214, 222, 1144, 831, 507, 1442, 1341, - 1544, 1545, 1143, 1063, 60, 621, 1055, 142, 1364, 925, - 142, 1141, 28, 392, 132, 133, 158, 158, 158, 865, - 485, 746, 142, 747, 618, 473, 475, 479, 622, 1494, - 115, 1432, 1324, 387, 728, 1606, 758, 729, 623, 1594, - 879, 388, 389, 1611, 735, 1569, 1613, 1192, 624, 149, - 625, 626, 1438, 97, 98, 99, 0, 0, 142, 0, - 142, 0, 158, 158, 158, 0, 0, 452, 1595, 0, - 0, 0, 0, 142, 495, 222, 0, 0, 452, 0, - 0, 0, 495, 0, 0, 9, 129, 130, 12, 0, - 0, 15, 690, 0, 728, 0, 690, 452, 365, 728, - 0, 0, 0, 0, 0, 0, 100, 101, 0, 942, - 806, 0, 0, 20, 0, 0, 0, 0, 423, 426, - 959, 0, 0, 23, 158, 0, 0, 158, 0, 0, - 728, 0, 0, 0, 690, 0, 28, 728, 29, 30, - 690, 0, 158, 158, 158, 0, 0, 423, 1326, 0, - 559, 831, 32, 0, 550, 0, 0, 158, 0, 0, - 0, 0, 33, 0, 1336, 0, 0, 34, 0, 0, - 859, 0, 0, 0, 35, 860, 0, 302, 10, 11, - 12, 0, 0, 9, 10, 11, 12, 690, 0, 15, - 0, 0, 341, 0, 302, 10, 11, 12, 1371, 1372, - 1373, 1374, 0, 0, 302, 10, 11, 12, 0, 0, - 0, 20, 0, 914, 0, 23, 690, 0, 910, 0, - 0, 23, 253, 0, 0, 0, 0, 621, 690, 0, - 320, 30, 23, 0, 28, 0, 29, 30, 222, 253, - 0, 0, 23, 0, 0, 0, 0, 320, 30, 253, - 948, 0, 0, 0, 254, 413, 415, 320, 30, 34, - 949, 1409, 690, 521, 690, 34, 0, 0, 597, 0, - 624, 523, 950, 626, 0, 0, 34, 214, 0, 222, - 239, 0, 0, 0, 0, 0, 34, 0, 302, 129, - 130, 12, 0, 0, 726, 730, 0, 746, 747, 0, - 758, 0, 730, 0, 0, 0, 728, 598, 599, 0, - 0, 0, 600, 601, 602, 603, 627, 627, 627, 0, - 0, 0, 0, 222, 0, 0, 23, 1048, 0, 0, - 0, 0, 341, 253, 142, 142, 0, 142, 0, 1469, - 0, 320, 30, 0, 0, 495, 0, 0, 452, 690, - 0, 0, 216, 217, 218, 0, 669, 0, 0, 16, - 728, 728, 0, 0, 0, 214, 728, 341, 730, 942, - 34, 452, 1489, 0, 704, 705, 20, 708, 690, 0, - 728, 22, 728, 0, 728, 0, 0, 0, 1190, 0, - 25, 0, 0, 0, 158, 0, 302, 396, 397, 12, - 341, 0, 726, 0, 0, 835, 836, 0, 840, 841, - 842, 843, 844, 845, 846, 847, 848, 849, 850, 851, - 852, 853, 854, 855, 856, 857, 858, 0, 730, 0, - 728, 0, 0, 730, 23, 0, 1099, 1100, 0, 1522, - 0, 0, 1105, 0, 0, 838, 1522, 28, 0, 320, - 30, 0, 0, 0, 0, 0, 1117, 0, 1118, 0, - 1119, 0, 423, 1326, 730, 559, 9, 10, 11, 12, - 0, 730, 0, 0, 0, 0, 728, 0, 34, 586, - 587, 588, 589, 590, 591, 592, 593, 594, 0, 0, - 158, 158, 910, 927, 929, 728, 0, 473, 475, 479, - 0, 216, 217, 218, 23, 0, 1147, 0, 16, 341, - 621, 0, 0, 0, 0, 0, 0, 28, 1242, 29, - 30, 0, 0, 0, 0, 20, 1522, 129, 130, 239, - 22, 217, 218, 948, 142, 142, 910, 16, 0, 25, - 0, 0, 1597, 949, 0, 0, 479, 0, 34, 0, - 0, 0, 1168, 624, 700, 950, 626, 726, 0, 22, - 0, 0, 0, 0, 1610, 0, 0, 0, 25, 0, - 621, 838, 0, 0, 0, 0, 0, 28, 1048, 132, - 133, 0, 0, 910, 0, 0, 0, 0, 627, 627, - 0, 627, 0, 622, 0, 0, 0, 0, 908, 0, - 129, 130, 1027, 623, 1284, 520, 630, 634, 637, 0, - 1242, 0, 0, 624, 0, 632, 626, 452, 452, 0, - 0, 0, 341, 341, 0, 341, 0, 0, 0, 640, - 10, 11, 12, 0, 0, 0, 0, 0, 0, 0, - 730, 0, 0, 621, 0, 0, 452, 0, 1013, 0, - 28, 0, 132, 133, 0, 0, 627, 0, 627, 627, - 0, 627, 1090, 0, 310, 641, 622, 23, 0, 0, - 728, 0, 728, 0, 728, 0, 623, 0, 0, 1064, - 28, 0, 132, 133, 0, 1069, 624, 0, 625, 626, - 0, 493, 217, 218, 730, 730, 0, 0, 16, 726, - 730, 0, 0, 627, 746, 747, 473, 475, 479, 0, - 690, 0, 758, 0, 730, 20, 730, 0, 730, 0, - 22, 0, 0, 0, 0, 0, 1411, 1412, 0, 25, - 0, 0, 0, 0, 0, 473, 475, 479, 0, 0, - 0, 142, 142, 158, 158, 910, 1280, 0, 1281, 142, - 1282, 0, 0, 0, 1140, 0, 0, 0, 0, 0, - 1039, 1040, 11, 12, 730, 0, 0, 0, 1358, 728, - 0, 0, 158, 158, 910, 0, 0, 0, 0, 341, - 627, 0, 0, 0, 0, 0, 0, 0, 1125, 0, - 1126, 0, 1164, 0, 0, 0, 0, 0, 23, 0, - 0, 0, 0, 452, 452, 0, 452, 452, 0, 452, - 730, 28, 0, 29, 30, 0, 0, 1210, 1475, 1041, - 0, 0, 0, 746, 747, 0, 758, 195, 0, 730, - 9, 10, 11, 12, 0, 0, 0, 196, 82, 0, - 1493, 1496, 34, 0, 0, 1385, 0, 0, 106, 197, - 0, 0, 0, 627, 0, 627, 0, 0, 135, 0, - 142, 142, 0, 142, 146, 146, 627, 146, 23, 82, - 908, 908, 908, 1217, 0, 0, 82, 0, 888, 890, - 0, 28, 0, 29, 30, 0, 0, 194, 0, 205, - 0, 82, 0, 0, 0, 0, 0, 195, 0, 240, - 214, 222, 0, 0, 0, 0, 106, 196, 0, 0, - 0, 0, 34, 0, 627, 627, 627, 264, 106, 197, - 0, 1540, 0, 726, 726, 0, 728, 1245, 0, 216, - 217, 218, 0, 0, 452, 452, 16, 0, 0, 0, - 106, 0, 0, 0, 0, 0, 953, 341, 630, 634, - 0, 637, 0, 20, 0, 0, 0, 0, 22, 0, - 0, 0, 1232, 908, 1234, 0, 0, 25, 135, 0, - 82, 0, 0, 0, 146, 146, 0, 479, 0, 414, - 146, 0, 920, 146, 146, 146, 0, 0, 0, 0, - 0, 10, 11, 634, 0, 14, 248, 0, 0, 82, - 0, 16, 0, 82, 730, 0, 730, 0, 730, 205, - 82, 0, 0, 0, 158, 18, 726, 19, 0, 1265, - 0, 0, 0, 22, 0, 726, 726, 205, 205, 205, - 726, 0, 25, 0, 621, 0, 452, 452, 452, 0, - 0, 28, 0, 132, 133, 0, 0, 1348, 1349, 0, - 473, 475, 479, 0, 0, 0, 205, 622, 0, 10, - 11, 0, 0, 14, 15, 0, 0, 623, 0, 16, - 634, 0, 726, 504, 0, 0, 0, 624, 0, 625, - 626, 0, 106, 18, 0, 19, 0, 158, 158, 158, - 0, 22, 0, 146, 0, 452, 452, 0, 0, 1342, - 25, 0, 0, 730, 1346, 0, 0, 0, 0, 28, - 0, 132, 133, 604, 0, 0, 0, 0, 0, 0, - 0, 627, 627, 627, 627, 627, 0, 1404, 0, 627, - 0, 106, 532, 0, 9, 10, 11, 12, 0, 0, - 248, 0, 0, 1120, 0, 1121, 0, 605, 0, 0, - 0, 0, 908, 908, 908, 1383, 1127, 0, 0, 0, - 888, 890, 20, 452, 97, 112, 113, 726, 227, 228, - 229, 0, 23, 0, 0, 0, 106, 0, 621, 0, - 619, 0, 532, 532, 635, 28, 1450, 29, 30, 0, - 0, 0, 20, 82, 0, 0, 0, 230, 0, 0, - 0, 948, 0, 0, 888, 890, 0, 0, 726, 0, - 0, 949, 0, 0, 0, 0, 34, 114, 115, 0, - 0, 624, 0, 950, 626, 0, 0, 135, 0, 0, - 0, 0, 0, 0, 0, 0, 106, 0, 205, 106, - 627, 627, 0, 627, 118, 973, 974, 0, 1016, 9, - 10, 11, 12, 146, 0, 15, 146, 0, 1460, 1461, - 730, 0, 0, 0, 0, 0, 0, 0, 146, 0, - 0, 1017, 0, 0, 0, 1471, 82, 20, 1018, 0, - 1509, 1510, 0, 0, 0, 0, 0, 23, 0, 1515, - 0, 0, 0, 621, 0, 28, 0, 121, 122, 0, - 28, 0, 29, 30, 205, 0, 205, 0, 205, 205, - 205, 0, 0, 0, 205, 0, 1157, 1535, 0, 205, - 10, 11, 205, 169, 14, 15, 1158, 0, 734, 0, - 16, 34, 0, 0, 1507, 1508, 624, 0, 1159, 626, - 82, 0, 0, 0, 18, 0, 19, 20, 0, 0, - 0, 0, 22, 1517, 1518, 0, 0, 0, 0, 0, - 0, 25, 0, 621, 0, 0, 0, 0, 0, 0, - 28, 0, 132, 133, 0, 0, 0, 0, 106, 106, - 106, 106, 0, 0, 0, 0, 622, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 623, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 624, 0, 625, 626, - 0, 1120, 1121, 888, 890, 0, 0, 0, 766, 1127, - 9, 10, 767, 12, 169, 14, 15, 0, 0, 0, - 0, 16, 0, 0, 0, 0, 0, 0, 106, 0, - 532, 0, 888, 890, 0, 18, 726, 19, 20, 21, - 0, 0, 619, 22, 532, 532, 0, 635, 23, 0, - 0, 0, 25, 768, 911, 170, 0, 0, 913, 0, - 0, 28, 0, 29, 30, 0, 0, 769, 0, 770, - 0, 0, 0, 205, 0, 0, 0, 32, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 34, 0, 0, 0, 0, 135, 555, 35, - 302, 10, 11, 12, 135, 14, 303, 304, 305, 0, - 306, 16, 205, 955, 205, 205, 240, 635, 0, 0, - 1120, 1121, 0, 1127, 0, 18, 307, 19, 20, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 30, -313, 0, 0, 322, 205, - 0, 0, 0, 955, 323, 0, 0, 556, 0, 0, - 205, 205, 0, 205, 0, 325, 326, 557, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 0, 558, - 135, 0, 0, 82, 0, 82, 0, 0, 0, 0, - 1050, 82, 82, 0, 0, 129, 130, 332, 82, 217, - 218, 106, 0, 0, 0, 16, 0, 106, 0, 0, - 0, 0, 0, 0, 532, 532, 532, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 532, 22, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 0, 621, 85, - 0, 0, 0, 0, 0, 28, 0, 132, 133, 108, - 0, 0, 0, 0, 0, 0, 0, 0, 128, 136, - 0, 622, 0, 0, 0, 147, 147, 0, 147, 0, - 85, 623, 0, 0, 0, 0, 0, 85, 0, 0, - 0, 624, 0, 625, 626, 0, 0, 0, 0, 0, - 147, 0, 85, 0, 0, 0, 0, 0, 0, 532, - 241, 532, 0, 0, 0, 0, 0, 250, 106, 0, - 0, 0, 532, 0, 106, 0, 911, 911, 911, 250, - 0, 0, 0, 0, 1134, 0, 9, 10, 11, 12, - 169, 14, 15, 0, 0, 734, 0, 16, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, - 594, 18, 0, 19, 20, 0, 106, 0, 106, 22, - 205, 205, 1161, 0, 23, 0, 0, 0, 25, 0, - 621, 85, 0, 0, 0, 147, 147, 28, 0, 29, - 30, 147, 0, 0, 147, 147, 147, 0, 0, 9, - 10, 11, 12, 1157, 0, 520, 0, 0, 0, 0, - 85, 0, 0, 1158, 85, 0, 0, 0, 34, 1161, - 147, 85, 0, 624, 0, 1159, 626, 20, 0, 0, - 0, 0, 106, 0, 0, 0, 0, 23, 147, 147, - 147, 0, 0, 621, 0, 0, 0, 0, 106, 0, - 28, 1050, 29, 30, 0, 0, 0, 0, 0, 0, - 106, 0, 0, 0, 0, 0, 948, 147, 0, 0, - 0, 0, 0, 1222, 0, 0, 949, 0, 0, 0, - 0, 34, 0, 53, 0, 82, 624, 0, 950, 626, - 0, 0, 0, 0, 106, 0, 106, 0, 612, 0, - 302, 396, 397, 12, 147, 613, 0, 0, 0, 53, - 53, 0, 154, 0, 53, 10, 11, 0, 0, 14, - 15, 53, 0, 0, 106, 16, 0, 0, 0, 532, - 532, 0, 532, 0, 53, 0, 53, 0, 23, 18, - 0, 19, 250, 147, 0, 614, 0, 22, 0, 0, - 0, 28, 0, 320, 30, 0, 25, 0, 0, 256, - 0, 0, 0, 0, 0, 28, 0, 132, 133, 0, - 0, 0, 0, 0, 0, 0, 0, 205, 205, 205, - 205, 1161, 615, 0, 0, 205, 0, 250, 0, 0, - 0, 620, 0, 147, 147, 636, 0, 0, 0, 0, - 645, 0, 0, 864, 85, 0, 0, 0, 1161, 1161, - 1161, 0, 398, 398, 0, 53, 0, 0, 0, 53, - 53, 0, 0, 256, 0, 53, 0, 0, 154, 154, - 154, 0, 0, 0, 0, 433, 0, 0, 682, 0, - 0, 205, 0, 0, 53, 0, 146, 250, 53, 147, - 250, 0, 10, 11, 53, 53, 14, 248, 0, 0, - 0, 0, 16, 0, 147, 0, 0, 147, 0, 0, - 0, 0, 53, 53, 154, 0, 18, 0, 19, 147, - 0, 0, 256, 0, 22, 0, 0, 85, 0, 0, - 0, 0, 0, 25, 0, 0, 205, 205, 0, 205, - 0, 53, 28, 0, 132, 133, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 147, 0, 147, 0, 147, - 147, 147, 0, 0, 0, 147, 0, 0, 0, 0, - 147, 0, 0, 147, 0, 205, 955, 205, 53, 0, - 766, 0, 9, 10, 767, 12, 169, 14, 15, 0, - 0, 85, 0, 16, 106, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 592, 593, 594, 18, 0, 19, - 20, 21, 0, 0, 0, 22, -527, 0, 0, 0, - 23, 0, 0, 0, 25, 768, 0, 170, 0, 250, - 250, 250, 250, 28, 0, 29, 30, 0, 0, 769, - 0, 770, 0, 0, 9, 129, 130, 12, 560, 32, - 248, 10, 11, 0, 0, 14, 15, 0, 0, 33, - 0, 16, 0, 0, 34, 398, 0, 0, 0, 0, - 0, 35, 20, 256, 0, 18, 0, 19, 53, 0, - 0, 0, 23, 22, 0, 0, 0, 0, -527, 250, - 1161, 147, 25, 0, 0, 28, 0, 29, 30, 0, - 0, 28, 0, 132, 133, 147, 147, 0, 636, 0, - 0, 32, 398, 0, 0, 912, 0, 0, 0, 0, - 0, 33, 0, 53, 0, 0, 34, 0, 645, 0, - 0, 0, 0, 35, 147, 0, 0, 0, 53, 0, - 0, 53, 0, 0, 0, 0, 0, 433, 433, 433, - 0, 0, 0, 53, 0, 0, 0, 0, 682, 78, - 0, 53, 0, 1161, 1161, 1161, 128, 0, 9, 129, - 130, 12, 0, 147, 636, 147, 147, 241, 636, 0, - 0, 0, 106, 0, 0, 0, 0, 205, 0, 53, - 78, 53, 0, 154, 154, 154, 20, 78, 0, 53, - 0, 985, 0, 0, 53, 0, 23, 53, 0, 0, - 203, 0, 215, 0, 0, 0, 0, 0, 0, 28, - 147, 29, 30, 0, 636, 53, 0, 0, 0, 0, - 0, 147, 147, 0, 147, 151, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 152, 0, 0, 985, 0, - 34, 136, 0, 0, 85, 560, 85, 153, 560, 0, - 0, 1051, 85, 85, 0, 0, 0, 0, 0, 85, - 0, 0, 250, 560, 560, 560, 0, 0, 250, 0, - 0, 0, 0, 0, 0, 147, 147, 147, 560, 0, - 0, 409, 0, 0, 0, 412, 0, 147, 0, 0, - 0, 0, 0, 0, 9, 10, 11, 12, 216, 217, - 218, 0, 0, 0, 0, 16, 0, 0, 0, 0, - 78, 0, 0, 0, 78, 0, 0, 0, 0, 0, - 203, 215, 20, 0, 0, 0, 256, 22, 0, 0, - 0, 0, 23, 0, 0, 0, 25, 0, 621, 560, - 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 53, 0, - 147, 948, 147, 0, 0, 0, 0, 203, 0, 250, - 0, 949, 0, 147, 0, 250, 34, 912, 912, 912, - 0, 624, 398, 950, 626, 645, 0, 0, 0, 398, - 0, 0, 9, 129, 130, 12, 0, 53, 53, 53, - 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 261, 9, 129, 130, 12, 0, 250, 15, 250, - 20, 147, 147, 636, 0, 0, 0, 0, 0, 0, - 23, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 20, 0, 0, 28, 53, 29, 30, 0, 53, 0, - 23, 0, 0, 0, 0, 53, 53, 0, 53, 32, - 0, 0, 0, 28, 0, 29, 30, 0, 0, 33, - 912, 0, 0, 0, 34, 0, 0, 0, 53, 151, - 53, 35, 0, 250, 0, 53, 53, 53, 436, 152, - 0, 0, 0, 53, 34, 0, 0, 0, 0, 250, - 0, 153, 1051, 0, 653, 0, 0, 0, 0, 0, - 0, 250, 0, 0, 0, 560, 0, 0, 0, 0, - 471, 0, 0, 0, 0, 9, 10, 11, 12, 0, - 0, 15, 0, 487, 0, 0, 85, 0, 0, 0, - 0, 0, 0, 0, 0, 250, 0, 250, 0, 203, - 0, 0, 0, 20, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 23, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 250, 28, 0, 29, 30, - 147, 147, 0, 147, 0, 0, 0, 78, 0, 0, - 0, 0, 195, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 196, 0, 0, 0, 0, 34, 0, 0, - 0, 560, 560, 560, 197, 0, 0, 433, 256, 0, - 0, 0, 0, 0, 0, 203, 0, 0, 147, 147, - 147, 147, 636, 203, 0, 0, 147, 80, 0, 0, - 0, 0, 0, 985, 0, 9, 10, 11, 12, 0, - 0, 783, 0, 0, 0, 53, 53, 154, 0, 912, - 912, 912, 256, 80, 80, 0, 80, 0, 80, 0, - 0, 0, 0, 20, 0, 80, 0, 0, 0, 0, - 985, 0, 0, 23, 0, 0, 0, 0, 80, 0, - 80, 0, 147, 0, 0, 0, 28, 147, 29, 30, - 0, 0, 0, 0, 1189, 0, 0, 0, 0, 0, - 0, 0, 476, 0, 9, 129, 130, 12, 0, 0, - 520, 0, 477, 0, 0, 0, 0, 34, 0, 0, - 0, 0, 0, 0, 478, 0, 53, 0, 0, 0, - 0, 0, 20, 0, 0, 0, 0, 147, 147, 0, - 147, 0, 23, 0, 0, 0, 0, 256, 0, 0, - 0, 0, 0, 0, 0, 28, 0, 29, 30, 80, - 53, 0, 0, 80, 80, 1415, 0, 0, 0, 80, - 0, 32, 80, 80, 80, 0, 147, 636, 147, 0, - 0, 33, 0, 0, 203, 0, 34, 0, 80, 0, - 0, 0, 80, 35, 0, 250, 0, 751, 80, 80, - 0, 985, 757, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 80, 80, 80, 0, - 0, 0, 0, 203, 954, 203, 203, 0, 0, 788, - 0, 256, 0, 0, 0, 794, 0, 161, 0, 0, - 0, 1039, 1040, 11, 12, 80, 0, 802, 803, 0, - 804, 0, 53, 53, 154, 154, 154, 0, 256, 206, - 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 203, 0, 0, 0, 1003, 0, 0, 0, 0, 23, - 0, 0, 80, 1189, 1189, 1189, 0, 0, 0, 0, - 0, 912, 28, 0, 29, 30, 0, 0, 0, 0, - 1041, 0, 0, 0, 783, 0, 783, 0, 195, 0, - 0, 1049, 1056, 783, 0, 0, 53, 0, 196, 783, - 0, 53, 0, 34, 0, 0, 0, 0, 0, 0, - 197, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 592, 593, 594, 899, 900, 0, 0, 0, - 899, 0, 0, 161, 161, 161, 0, 0, 0, 0, - 0, 0, 0, 0, 912, 912, 912, 9, 10, 11, - 12, 53, 53, 248, 53, 0, 0, 0, 644, 206, - 0, 0, 80, 250, 0, 0, 0, 0, 147, 0, - 0, 0, 0, 0, 0, 20, 0, 206, 206, 480, - 0, 0, 0, 0, 0, 23, 0, 0, 0, 0, - 53, 53, 53, 0, 0, 0, 0, 0, 28, 0, - 29, 30, 0, 0, 0, 0, 206, 80, 0, 0, - 0, 0, 0, 0, 195, 204, 0, 0, 0, 0, - 0, 0, 80, 0, 196, 80, 0, 0, 0, 34, - 0, 371, 373, 0, 0, 0, 197, 80, 0, 0, - 259, 0, 0, 263, 0, 80, 0, 0, 9, 10, - 11, 12, 216, 217, 218, 0, 0, 0, 0, 16, - 0, 0, 0, 0, 259, 0, 367, 0, 0, 0, - 0, 0, 0, 80, 0, 80, 20, 80, 80, 80, - 0, 22, 533, 80, 0, 0, 23, 0, 80, 0, - 25, 80, 621, 1071, 0, 1073, 0, 0, 0, 28, - 0, 29, 30, 0, 0, 1189, 0, 0, 0, 80, - 0, 0, 0, 0, 0, 195, 0, 0, 9, 10, - 11, 12, 207, 14, 208, 196, 0, 0, 0, 16, - 34, 0, 629, 629, 629, 204, 0, 1428, 0, 0, - 0, 0, 1049, 18, 0, 19, 20, 0, 0, 0, - 0, 22, 0, 204, 204, 204, 23, 0, 0, 0, - 25, 0, 0, 486, 0, 0, 0, 1107, 1108, 28, - 1110, 29, 30, 1485, 0, 209, 783, 0, 1189, 1189, - 1189, 0, 204, 0, 0, 32, 0, 0, 206, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 1128, 0, - 34, 0, 53, 0, 0, 0, 0, 35, 263, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 644, 259, 1486, 573, 574, 575, 576, 577, 578, - 579, 580, 581, 582, 583, 584, 585, 586, 587, 588, - 589, 590, 591, 592, 593, 594, 0, 0, 0, 1163, - 0, 0, 80, 563, 206, 0, 206, 0, 480, 480, - 480, 0, 0, 0, 206, 0, 0, 0, 0, 206, - 0, 0, 206, 0, 9, 10, 11, 12, 169, 14, - 15, 0, 0, 0, 0, 16, 0, 0, 0, 0, - 0, 80, 80, 80, 80, 0, 0, 0, 0, 18, - 0, 19, 20, 21, 0, 0, 0, 22, 0, 0, - 0, 0, 23, 0, 259, 263, 25, 0, 0, 170, - 0, 0, 1208, 0, 0, 28, 689, 29, 30, 0, - 0, 0, 1359, 0, 1213, 0, 0, 1359, 80, 0, - 0, 32, 80, 0, 0, 0, 0, 0, 0, 80, - 80, 33, 80, 0, 0, 0, 34, 0, 0, 0, - 0, 0, 0, 35, 204, 0, 0, 0, 0, 36, - 0, 0, 80, 0, 80, 0, 0, 0, 0, 80, - 80, 80, 0, 0, 0, 0, 0, 80, 0, 0, - 873, 0, 736, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 629, 629, 0, 629, 0, 0, - 0, 0, 0, 0, 629, 0, 0, 0, 0, 0, - 1264, 0, 0, 0, 0, 0, 203, 1427, 203, 0, - 204, 0, 204, 206, 204, 204, 204, 0, 0, 0, - 204, 0, 0, 0, 0, 204, 0, 0, 204, 0, - 9, 10, 11, 12, 216, 217, 218, 0, 0, 1277, - 807, 16, 0, 810, 0, 0, 0, 812, 813, 815, - 816, 817, 952, 0, 952, 952, 0, 629, 20, 0, - 563, 0, 0, 22, 0, 0, 0, 0, 23, 0, - 0, 0, 25, 834, 621, 0, 0, 0, 0, 0, - 0, 28, 0, 29, 30, 0, 0, 0, 0, 0, - 0, 0, 0, 644, 0, 0, 0, 948, 0, 952, - 0, 0, 0, 0, 1367, 0, 0, 949, 1368, 0, - 206, 206, 34, 206, 0, 0, 0, 624, 0, 997, - 626, 0, 0, 0, 0, 0, 0, 891, 0, 80, - 80, 80, 0, 0, 891, 0, 0, 0, 0, 0, - 206, 0, 0, 1384, 0, 0, 0, 0, 0, 0, - 766, 0, 9, 10, 767, 12, 169, 14, 15, 0, - 0, 0, 0, 16, 533, 533, 533, 0, 0, 0, - 0, 0, 0, 259, 263, 0, 629, 18, 1191, 19, - 20, 21, 0, 0, 0, 22, -528, 0, 0, 204, - 23, 0, 0, 0, 25, 768, 0, 170, 0, 0, - 0, 0, 0, 28, 0, 29, 30, 0, 0, 769, - 80, 770, 0, 0, 0, 0, 0, 0, 203, 32, - 1443, 0, 0, 0, 1444, 0, 0, 0, 204, 33, - 204, 204, 0, 0, 34, 0, 0, 0, 0, 0, - 0, 35, 0, 689, 80, 0, 1462, 1463, 0, 629, - 0, 629, 9, 10, 11, 12, 0, 0, -528, 0, - 0, 0, 629, 0, 0, 0, 629, 629, 629, 0, - 0, 0, 0, 0, 0, 204, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 204, 204, 0, 204, - 23, 736, 0, 0, 0, 0, 0, 736, 0, 0, - 0, 0, 0, 28, 0, 29, 30, 0, 0, 1422, - 952, 952, 1162, 0, 0, 0, 204, 0, 0, 195, - -388, 10, 11, -388, -388, 14, 248, 0, 0, 196, - 0, 16, 0, 0, 34, 0, 80, 80, 80, 80, - 80, 197, 0, 0, 80, 18, 0, 19, -388, 0, - 0, 0, 0, 22, 0, 0, 0, 0, -388, 1162, - 0, 0, 25, 0, 621, 1101, 0, 1191, 1191, 1191, - 0, 28, 0, 132, 133, 0, 0, 1352, 1353, 11, - 12, 0, 0, 0, 0, 0, 0, 622, 0, 0, - 0, 206, 0, 0, 0, 0, 0, 623, 834, 0, - 80, 0, -388, 0, 736, 80, 0, 624, 891, 625, - 626, 0, 0, 0, 0, 23, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, - 29, 30, 0, 0, 0, 0, 1354, 0, 0, 0, - 0, 0, 0, 0, 195, 0, 689, 0, 1153, 259, - 263, 259, 891, 0, 196, 80, 80, 0, 80, 34, - 0, 0, 0, 0, 0, 0, 197, 0, 0, 873, - 873, 0, 873, 0, 0, 0, 9, 10, 11, 12, - 0, 0, 15, 0, 0, 0, 204, 204, 1160, 0, - 0, 104, 0, 259, 80, 80, 80, 0, 0, 891, - 123, 104, 0, 0, 20, 0, 0, 104, 104, 0, - 104, 0, 1195, 0, 23, 0, 0, 952, 952, 1162, - 1162, 1162, 0, 263, 0, 952, 0, 28, 736, 29, - 30, 9, 10, 11, 12, 1160, 0, 520, 0, 0, - 736, 0, 237, 476, 0, 0, 0, 0, 1162, 1162, - 1162, 0, 0, 477, 0, 0, 0, 0, 34, 20, - 0, 0, 0, 0, 0, 478, 0, 204, 0, 23, - 0, 0, 0, 0, 736, 0, 736, 0, 0, 0, - 0, 206, 28, 0, 29, 30, 0, 0, 486, 0, - 0, 1352, 129, 130, 12, 0, 0, 0, 195, 0, - 0, 391, 0, 123, 1250, 0, 0, 0, 196, 1191, - 104, 104, 0, 34, 0, 0, 0, 104, 104, 0, - 197, 104, 104, 104, 0, 419, 104, 104, 104, 23, - 0, 0, 0, 0, 0, 0, 952, 952, 0, 952, - 0, 0, 28, 0, 29, 30, 0, 0, 0, 0, - 1354, 0, 0, 0, 0, 0, 0, 0, 32, 0, - 0, 891, 0, 0, 0, 0, 0, 0, 33, 0, - 0, 0, 259, 34, 0, 206, 0, 206, 0, 0, - 35, 0, 1191, 1191, 1191, 0, 0, 0, 0, 0, - 891, 0, 0, 204, 204, 204, 204, 1160, 0, 1276, - 0, 204, 0, 0, 1337, 0, 80, 0, 0, 0, - 0, 0, 0, 0, 0, 237, 104, 0, 0, 0, - 0, 0, 0, 0, 1160, 1160, 1160, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 104, 0, 766, 0, - 9, 10, 767, 12, 169, 14, 15, 0, 0, 0, - 0, 16, 0, 0, 0, 0, 0, 204, 0, 0, - 0, 0, 0, 0, 0, 18, 0, 19, 20, 21, - 0, 0, 0, 22, -530, 104, 0, 0, 23, 0, - 0, 0, 25, 768, 0, 170, 0, 0, 0, 0, - 480, 28, 0, 29, 30, 0, 0, 769, 0, 770, - 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, - 0, 0, 204, 204, 0, 204, 0, 33, 0, 0, - 0, 0, 34, 104, 0, 104, 104, 0, 0, 35, - 0, 0, 0, 0, 1195, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -530, 0, 0, 0, - 0, 204, 0, 204, 0, 0, 10, 11, 0, 169, - 14, 15, 0, 480, 480, 480, 16, 0, 0, 0, - 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 18, 0, 19, 20, 0, 0, 0, 206, 22, 104, - 0, 0, 0, 0, 0, 0, 104, 683, 0, 104, - 170, 0, 0, 0, 0, 0, 28, 0, 132, 133, - 0, 104, 555, 0, 302, 10, 11, 12, 169, 14, - 303, 304, 305, 734, 306, 16, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, - 307, 19, 20, 21, 0, 308, 309, 22, 0, 310, - 311, 312, 23, 313, 314, 0, 25, 0, 621, 0, - 315, 316, 317, 318, 319, 28, 1160, 320, 30, -313, - 0, 0, 322, 0, 0, 0, 0, 0, 323, 104, - 0, 904, 10, 11, 0, 207, 14, 208, 0, 325, - 326, 905, 16, 0, 0, 0, 328, 329, 330, 0, - 0, 624, 0, 906, 626, 563, 18, 104, 19, 20, - 0, 0, 0, 0, 22, 0, 0, 0, 0, 0, - 0, 332, 689, 25, 0, 0, 0, 0, 0, 0, - 0, 0, 28, 0, 132, 133, 0, 0, 0, 1160, - 1160, 1160, 0, 0, 0, 0, 1456, 0, -480, -480, - -480, -480, -480, -480, -480, 0, 0, -480, 0, -480, - 0, 0, 0, 204, 0, 0, 0, 0, 0, 0, - -480, 0, -480, 0, 0, 0, -480, 0, 0, 0, - 0, -480, 0, 104, 0, 0, -480, 0, 0, 0, - -480, 0, -480, 0, 104, 104, 0, 104, 104, -480, - 0, -480, -480, -480, -480, -480, 0, -480, -480, -480, - -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, - -480, -480, -480, -480, -480, -480, -480, -480, -480, -480, - -480, -480, -480, 0, 0, -480, -480, -480, -480, -480, - 0, -480, -480, 0, 0, 0, 0, 1457, 0, 0, - 104, 0, -480, -480, -480, 0, -480, 104, 123, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 237, - 0, 0, 0, 0, 0, 0, 0, 0, 1430, 0, - 1287, 1288, 1289, 12, 169, 14, 303, 304, 305, 0, - 306, 16, 1290, 982, 1291, 1292, 1293, 1294, 1295, 1296, - 1297, 1298, 1299, 1300, 17, 18, 307, 19, 20, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 1301, 25, 1302, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 1303, 721, 0, 1304, 322, 0, - 982, 0, 0, 104, 323, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 0, 331, - 0, 0, 0, 1305, 0, 0, 0, 104, 104, 104, - 0, 0, 0, 0, 0, 0, 1431, 332, 1286, 104, - 1287, 1288, 1289, 12, 169, 14, 303, 304, 305, 0, - 306, 16, 1290, 0, 1291, 1292, 1293, 1294, 1295, 1296, - 1297, 1298, 1299, 1300, 17, 18, 307, 19, 20, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 1301, 25, 1302, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 1303, 721, 0, 1304, 322, 0, - 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, - 0, 0, 104, 0, 104, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 104, 0, 0, 0, 331, - 0, 0, 0, 1305, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 555, 332, 9, 10, - 11, 12, 169, 14, 303, 304, 305, 734, 306, 16, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 307, 19, 20, 21, 0, 308, - 309, 22, 0, 310, 311, 312, 23, 313, 314, 0, - 25, 0, 621, 0, 315, 316, 317, 318, 319, 28, - 0, 29, 30, -313, 0, 0, 322, 0, 0, 0, - 982, 0, 323, 0, 0, 1186, 0, 0, 0, 0, - 0, 0, 0, 325, 326, 1187, 0, 0, 0, 0, - 328, 329, 330, 0, 0, 624, 0, 1188, 626, 0, - 733, 0, 302, 10, 11, 12, 169, 14, 303, 304, - 305, 734, 306, 16, 0, 332, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 18, 307, 19, - 20, 21, 0, 308, 309, 22, 104, 310, 311, 312, - 23, 313, 314, 0, 25, 0, 0, 0, 315, 316, - 317, 318, 319, 28, 0, 320, 30, 0, 0, 0, - 322, 0, 0, 0, 0, 0, 323, 0, 0, 324, - 0, 0, 0, 0, 0, 0, 0, 325, 326, 327, - 0, 0, 0, 0, 328, 329, 330, 0, 0, 0, - 0, 331, 104, 104, 0, 104, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, -800, 0, 332, - 837, 0, 302, 10, 11, 12, 169, 14, 303, 304, - 305, 0, 306, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 18, 307, 19, - 20, 21, 0, 308, 309, 22, 0, 310, 311, 312, - 23, 313, 314, 0, 25, 982, 0, 0, 315, 316, - 317, 318, 319, 28, 0, 320, 30, 1530, 0, -790, - 322, 0, 0, 0, 0, 0, 323, 0, 0, 324, - 0, 0, 0, 0, 0, 0, 0, 325, 326, 327, - 0, 0, 982, 0, 328, 329, 330, 0, 0, 0, - 0, 331, 0, 0, 0, 0, 0, 104, 724, 104, - 825, 826, 827, 12, 0, 14, 537, 304, 305, 332, - 306, 16, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 0, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 828, 829, 725, 0, 0, 322, 0, - 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 0, 331, - 830, 724, 0, 825, 826, 827, 12, 0, 14, 537, - 304, 305, 0, 306, 16, 0, 989, 332, 0, 0, - 0, 0, 0, 982, 0, 0, 0, 0, 18, 307, - 19, 0, 21, 0, 308, 309, 22, 0, 310, 311, - 312, 23, 313, 314, 0, 25, 0, 0, 0, 315, - 316, 317, 318, 319, 28, 0, 828, 829, 725, 0, - 0, 322, 0, 0, 0, 0, 0, 323, 0, 0, - 324, 0, 0, 0, 0, 0, 0, 0, 325, 326, - 327, 0, 0, 0, 0, 328, 329, 330, 0, 0, - 0, 0, 331, 830, 724, 0, 825, 826, 827, 12, - 0, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 828, - 829, 725, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 0, 0, 0, 724, 331, 825, 826, 827, 12, - 0, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, -484, 332, 0, 0, 0, 0, 0, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 828, - 829, 725, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 0, 0, 0, 724, 331, 302, 10, 11, 12, - 0, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 1325, 332, 0, 0, 0, 0, 0, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 725, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 0, 0, 0, 0, 331, 0, 0, 555, 0, - 9, 10, 11, 12, 1329, 14, 303, 304, 305, 0, - 306, 16, 0, 332, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 20, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 29, 30, -313, 0, 0, 322, 0, - 0, 0, 0, 0, 323, 0, 0, 1501, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 1502, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 724, 1503, - 302, 10, 11, 12, 0, 14, 537, 304, 305, 0, - 306, 16, 0, 0, 0, 0, 0, 332, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 0, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 30, 725, 0, 0, 322, 0, - 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 837, 331, - 302, 10, 11, 12, 0, 14, 537, 304, 305, 0, - 306, 16, 0, 0, 0, 0, 0, 332, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 0, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 30, 0, 0, 0, 322, -790, - 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 1582, 331, - 302, 10, 11, 12, 0, 14, 303, 304, 305, 0, - 306, 16, 0, 0, 0, 0, 0, 332, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 0, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 30, 0, 0, -197, 322, 0, - 0, 0, 0, 0, 323, 0, 0, 324, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 327, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 837, 331, - 302, 10, 11, 12, 0, 14, 537, 304, 305, 0, - 306, 16, 0, 0, 0, 0, 0, 332, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 0, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 0, 0, 315, 316, 317, 318, - 319, 28, 0, 320, 30, 0, 0, 0, 322, 0, - 0, 0, 0, 0, 323, 265, 0, 324, 10, 11, - 0, 0, 14, 15, 0, 325, 326, 327, 16, 0, - 0, 0, 328, 329, 330, 0, 0, 0, 0, 331, - 0, 0, 18, 0, 19, 0, 0, 0, 0, 0, - 22, 0, 266, 267, 0, -790, 0, 332, 0, 25, - 0, 268, 0, 0, 0, 0, 0, 0, 28, 0, - 132, 133, 0, 269, 0, 0, 0, 270, 271, 272, - 273, 274, 275, 276, 277, 278, 279, 280, 281, 282, - 283, 284, 285, 286, 287, 288, 289, 0, 290, 291, - 292, 293, 0, 0, 0, 0, 0, 294, 295, 926, - 0, 302, 10, 11, 12, 0, 14, 537, 304, 305, - 0, 306, 16, 0, 296, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 307, 19, 0, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 327, 0, - 0, 0, 0, 328, 329, 330, 0, 0, 0, 928, - 331, 302, 10, 11, 12, 0, 14, 537, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 0, 332, 0, - 0, 0, 0, 0, 0, 0, 18, 307, 19, 0, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 327, 0, - 0, 0, 0, 328, 329, 330, 0, 0, 0, 1514, - 331, 302, 10, 11, 12, 0, 14, 537, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 0, 332, 0, - 0, 0, 0, 0, 0, 0, 18, 307, 19, 0, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 327, 0, - 0, 0, 0, 328, 329, 330, 302, 10, 11, 12, - 331, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 0, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 766, 324, 9, 10, 767, 12, 169, 14, - 15, 325, 326, 327, 0, 16, 0, 0, 328, 329, - 330, 0, 0, 0, 0, 331, 0, 0, 0, 18, - 0, 19, 20, 21, 0, 0, 0, 22, -529, 0, - 0, 0, 23, 332, 876, 0, 25, 768, 0, 170, - 0, 0, 0, 0, 0, 28, 0, 29, 30, 0, - 0, 769, 0, 770, 0, 0, 0, 0, 0, 0, - 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 33, 0, 0, 0, 0, 34, 0, 0, 0, - 0, 0, 0, 35, 0, 0, 0, 1287, 1288, 1289, - 12, 169, 14, 303, 304, 305, 0, 306, 16, 1290, - -529, 1291, 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, - 1300, 17, 18, 307, 19, 20, 21, 0, 308, 309, - 22, 0, 310, 311, 312, 23, 313, 314, 1301, 25, - 1302, 0, 0, 315, 316, 317, 318, 319, 28, 0, - 320, 1303, 721, 0, 1304, 322, 0, 0, 0, 0, - 0, 323, 0, 0, 324, 0, 0, 0, 0, 0, - 0, 0, 325, 326, 327, 0, 0, 0, 0, 328, - 329, 330, 0, 0, 0, 0, 331, 0, 0, 0, - 1305, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1435, 332, 1287, 1288, 1289, 12, 169, - 14, 303, 304, 305, 0, 306, 16, 1290, 0, 1291, - 1292, 1293, 1294, 1295, 1296, 1297, 1298, 1299, 1300, 17, - 18, 307, 19, 20, 21, 0, 308, 309, 22, 0, - 310, 311, 312, 23, 313, 314, 1301, 25, 1302, 0, - 0, 315, 316, 317, 318, 319, 28, 0, 320, 1303, - 721, 0, 1304, 322, 0, 0, 0, 0, 0, 323, - 0, 0, 324, 0, 0, 0, 0, 0, 0, 0, - 325, 326, 327, 0, 0, 0, 0, 328, 329, 330, - 0, 0, 0, 0, 331, 0, 0, 0, 1305, 1287, - 1288, 1289, 12, 169, 14, 303, 304, 305, 0, 306, - 16, 1290, 332, 1291, 1292, 1293, 1294, 1295, 1296, 1297, - 1298, 1299, 1300, 17, 18, 307, 19, 20, 21, 0, - 308, 309, 22, 0, 310, 311, 312, 23, 313, 314, - 1301, 25, 1302, 0, 0, 315, 316, 317, 318, 319, - 28, 0, 320, 1303, 1559, 0, 1304, 322, 0, 0, - 0, 0, 0, 323, 0, 0, 324, 0, 0, 0, - 0, 0, 0, 0, 325, 326, 327, 0, 0, 0, - 0, 328, 329, 330, 0, 0, 0, 0, 331, 0, - 0, 0, 1305, 1287, 1288, 1289, 12, 169, 14, 303, - 304, 305, 0, 306, 16, 1290, 332, 1291, 1292, 1293, - 1294, 1295, 1296, 1297, 1298, 1299, 1300, 17, 18, 307, - 19, 20, 21, 0, 308, 309, 22, 0, 310, 311, - 312, 23, 313, 314, 1301, 25, 1302, 0, 0, 315, - 316, 317, 318, 319, 28, 0, 320, 1303, 0, 0, - 1304, 322, 0, 0, 0, 0, 0, 323, 0, 0, - 324, 0, 0, 0, 0, 0, 0, 0, 325, 326, - 327, 0, 0, 0, 0, 328, 329, 330, 0, 0, - 0, 0, 331, 0, 0, 0, 1305, 302, 10, 11, - 12, 169, 14, 303, 304, 305, 734, 306, 16, 0, - 332, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 307, 19, 20, 21, 0, 308, 309, - 22, 0, 310, 311, 312, 23, 313, 314, 0, 25, - 0, 621, 0, 315, 316, 317, 318, 319, 28, 0, - 320, 30, 0, 0, 0, 322, 0, 0, 0, 0, - 0, 323, 0, 0, 904, 0, 0, 0, 0, 0, - 0, 0, 325, 326, 905, 0, 0, 0, 0, 328, - 329, 330, 0, 0, 624, 0, 906, 626, 9, 10, - 11, 12, 169, 14, 303, 304, 305, 734, 306, 16, - 0, 0, 0, 0, 332, 0, 0, 0, 0, 0, - 0, 0, 0, 18, 307, 19, 20, 21, 0, 308, - 309, 22, 0, 310, 311, 312, 23, 313, 314, 0, - 25, 0, 621, 0, 315, 316, 317, 318, 319, 28, - 0, 29, 30, 0, 0, 0, 322, 0, 0, 0, - 0, 0, 323, 0, 0, 1186, 0, 0, 0, 0, - 0, 0, 0, 325, 326, 1187, 0, 0, 0, 0, - 328, 329, 330, 0, 0, 624, 0, 1188, 626, 302, - 10, 11, 12, 0, 14, 303, 304, 305, 0, 306, - 16, 0, 0, 0, 0, 332, 0, 0, 0, 0, - 0, 0, 0, 0, 18, 307, 19, 20, 21, 0, - 308, 309, 22, 0, 310, 311, 312, 23, 313, 314, - 0, 25, 0, 621, 0, 315, 316, 317, 318, 319, - 28, 0, 320, 30, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 323, 0, 0, 904, 0, 0, 0, - 0, 0, 0, 0, 325, 326, 905, 0, 0, 0, - 0, 328, 329, 330, 0, 0, 624, 0, 906, 626, - 9, 10, 11, 12, 0, 14, 303, 304, 305, 0, - 306, 16, 0, 0, 0, 0, 332, 0, 0, 0, - 0, 0, 0, 0, 0, 18, 307, 19, 20, 21, - 0, 308, 309, 22, 0, 310, 311, 312, 23, 313, - 314, 0, 25, 0, 621, 0, 315, 316, 317, 318, - 319, 28, 0, 29, 30, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 323, 0, 0, 1186, 0, 0, - 0, 0, 0, 0, 0, 325, 326, 1187, 0, 0, - 0, 0, 328, 329, 330, 0, 0, 624, 0, 1188, - 626, 302, 10, 11, 12, 0, 14, 537, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 332, 0, 0, - 0, 0, 0, 0, 0, 0, 18, 307, 19, 20, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 556, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 557, 0, - 0, 0, 0, 328, 329, 330, 302, 10, 11, 12, - 558, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 0, 0, 1408, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 0, 0, 0, 0, 331, 302, 10, 11, 12, - 169, 14, 303, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, - 0, 18, 307, 19, 20, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 9, 10, 11, 12, 331, 14, 537, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 332, 0, 0, 18, 307, 19, 20, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 29, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 1501, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 1502, 0, - 0, 0, 0, 328, 329, 330, 302, 10, 11, 12, - 1503, 14, 303, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 321, 0, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 302, 10, 11, 12, 331, 14, 303, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 332, 0, 0, 18, 307, 19, 0, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 0, 0, 0, 322, - 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 327, 0, - 0, 0, 0, 328, 329, 330, 302, 10, 11, 12, - 331, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 0, 0, 0, 322, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 302, 10, 11, 12, 331, 14, 537, 304, 305, - 0, 306, 16, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 332, 0, 0, 18, 307, 19, 0, - 21, 0, 308, 309, 22, 0, 310, 311, 312, 23, - 313, 314, 0, 25, 0, 0, 0, 315, 316, 317, - 318, 319, 28, 0, 320, 30, 570, 0, 0, 0, - 0, 0, 0, 0, 0, 323, 0, 0, 324, 0, - 0, 0, 0, 0, 0, 0, 325, 326, 327, 0, - 0, 0, 0, 328, 329, 330, 302, 10, 11, 12, - 571, 14, 537, 304, 305, 0, 306, 16, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 332, 0, - 0, 18, 307, 19, 0, 21, 0, 308, 309, 22, - 0, 310, 311, 312, 23, 313, 314, 0, 25, 0, - 0, 0, 315, 316, 317, 318, 319, 28, 0, 320, - 30, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 323, 0, 0, 324, 0, 0, 0, 0, 0, 0, - 0, 325, 326, 327, 0, 0, 0, 0, 328, 329, - 330, 0, 0, 0, 0, 331, 609, 302, 10, 11, - 12, 0, 14, 537, 304, 305, 0, 306, 16, 0, - 0, 0, 0, 332, 0, 0, 0, 0, 0, 0, - 0, 0, 18, 307, 19, 20, 21, 0, 308, 309, - 22, 0, 310, 311, 312, 23, 313, 314, 0, 25, - 0, 0, 0, 315, 316, 317, 318, 319, 28, 0, - 320, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 323, 0, 0, 556, 0, 0, 0, 0, 0, - 0, 0, 325, 326, 557, 0, 0, 0, 0, 328, - 329, 330, 1146, 10, 11, 12, 558, 14, 537, 304, - 305, 0, 306, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 0, 0, 18, 307, 19, - 0, 21, 0, 308, 309, 22, 0, 310, 311, 312, - 23, 313, 314, 0, 25, 0, 0, 0, 315, 316, - 317, 318, 319, 28, 0, 320, 30, 0, 0, 0, - 322, 0, 0, 0, 0, 0, 323, 0, 0, 324, - 0, 0, 0, 0, 0, 0, 0, 325, 326, 327, - 0, 0, 0, 0, 328, 329, 330, 9, 10, 11, - 12, 331, 14, 303, 304, 305, 0, 306, 16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, - 0, 0, 18, 307, 19, 20, 21, 0, 308, 309, - 22, 0, 310, 311, 312, 23, 313, 314, 0, 25, - 0, 0, 0, 315, 316, 317, 318, 319, 28, 0, - 29, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 323, 0, 0, 1501, 0, 0, 0, 0, 0, - 0, 0, 325, 326, 1502, 0, 0, 0, 0, 328, - 329, 330, 302, 10, 11, 12, 1503, 14, 537, 304, - 305, 0, 306, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 0, 0, 18, 307, 19, - 0, 21, 0, 308, 309, 22, 0, 310, 311, 312, - 23, 313, 314, 0, 25, 0, 0, 0, 315, 316, - 317, 318, 319, 28, 0, 320, 30, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 323, 0, 0, 324, - 0, 0, 0, 0, 0, 0, 0, 325, 326, 327, - 0, 0, 0, 0, 328, 329, 330, 302, 10, 11, - 12, 538, 14, 537, 304, 305, 0, 306, 16, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 332, - 0, 0, 18, 307, 19, 0, 21, 0, 308, 309, - 22, 0, 310, 311, 312, 23, 313, 314, 0, 25, - 0, 0, 0, 315, 316, 317, 318, 319, 28, 0, - 320, 30, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 323, 0, 0, 324, 0, 0, 0, 0, 0, - 0, 0, 325, 326, 327, 0, 0, 0, 0, 328, - 329, 330, 302, 10, 11, 12, 541, 14, 537, 304, - 305, 0, 306, 16, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 332, 0, 0, 18, 307, 19, - 0, 21, 0, 308, 309, 22, 0, 310, 311, 312, - 23, 313, 314, 0, 25, 0, 0, 0, 315, 316, - 317, 318, 319, 28, 0, 320, 30, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 323, 0, 8, 324, - 9, 10, 11, 12, 13, 14, 15, 325, 326, 327, - 0, 16, 0, 0, 328, 329, 330, 0, 0, 0, - 0, 331, 0, 0, 17, 18, 0, 19, 20, 21, - 0, 0, 0, 22, 0, 0, 0, 0, 23, 332, - 0, 24, 25, 26, 0, 27, 0, 0, 0, 0, - 0, 28, 0, 29, 30, 0, 168, 31, 9, 10, - 11, 12, 169, 14, 15, 0, 0, 32, 0, 16, - 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, - 0, 0, 34, 18, 0, 19, 20, 21, 0, 35, - 0, 22, 0, 0, 0, 36, 23, 0, 0, 0, - 25, 0, 0, 170, 0, 0, 0, 0, 0, 28, - 0, 29, 30, 0, 8, 0, 9, 10, 11, 12, - 13, 14, 15, 0, 0, 32, 0, 16, 0, 0, - 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, - 34, 18, 0, 19, 20, 0, 0, 35, 0, 22, - 0, 0, 0, 36, 23, 0, 0, 0, 25, 0, - 0, 440, 0, 0, 0, 0, 0, 28, 0, 29, - 30, 0, 0, 31, 0, 9, 10, 11, 12, 169, - 14, 15, 0, 32, 1002, 0, 16, 0, 0, 0, - 0, 0, 0, 33, 0, 0, 0, 0, 34, 0, - 18, 0, 19, 20, 0, 35, 0, 0, 22, 0, - 0, 0, 0, 23, 0, 0, 0, 25, 0, 0, - 0, 0, 0, 0, 0, 0, 28, 0, 29, 30, - 0, 0, 0, 1039, 10, 767, 12, 207, 14, 208, - 0, 0, 32, 0, 16, 0, 0, 0, 0, 0, - 0, 0, 33, 0, 0, 0, 0, 34, 18, 0, - 19, 20, 0, 0, 35, 0, 22, 0, 0, 0, - 0, 23, 0, 0, 0, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, - 0, 0, 1041, 9, 10, 11, 12, 207, 14, 208, - 32, 0, 0, 0, 16, 0, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 34, 0, 0, 18, 0, - 19, 20, 35, 0, 0, 0, 22, 0, 0, 0, - 0, 23, 0, 0, 0, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 28, 0, 29, 30, 0, 0, - 1425, 9, 10, 11, 12, 169, 14, 15, 0, 0, - 32, 0, 16, 0, 0, 0, 0, 0, 0, 0, - 33, 0, 0, 0, 0, 34, 18, 0, 19, 20, - 0, 0, 35, 0, 22, 0, 0, 0, 0, 23, - 0, 0, 0, 25, 0, 0, 0, 0, 0, 0, - 0, 0, 28, 0, 29, 30, 0, 0, 0, 9, - 10, 11, 12, 207, 14, 208, 0, 0, 32, 0, - 16, 0, 0, 0, 0, 0, 0, 0, 33, 0, - 0, 0, 0, 34, 18, 0, 19, 20, 0, 0, - 35, 0, 22, 0, 0, 0, 0, 23, 0, 0, - 0, 25, 0, 0, 0, 0, 0, 0, 0, 0, - 28, 0, 29, 30, 0, 0, 0, 20, 0, 0, - 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, - 0, 34, 0, 0, 0, 0, 0, 0, 35, 573, - 574, 575, 576, 577, 578, 579, 580, 581, 582, 583, - 584, 585, 586, 587, 588, 589, 590, 591, 592, 593, - 594, 10, 11, 0, 169, 14, 15, 0, 0, 734, - 0, 16, 0, 0, 10, 11, 0, 169, 14, 15, - 0, 0, 1553, 0, 16, 18, 0, 19, 20, 0, - 0, 0, 0, 22, 0, 0, 0, 0, 18, 0, - 19, 20, 25, 0, 0, 0, 22, 0, 0, 0, - 0, 28, 0, 132, 133, 25, 0, 0, 0, 0, - 0, 0, 0, 0, 28, 0, 132, 133, 573, 574, - 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, - 593, 594, 0, 0, 0, 0, 1240, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 662, 0, 0, 1549, 573, 574, 575, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 592, 593, 594, 1567, 573, 574, - 575, 576, 577, 578, 579, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, - 593, 594, 573, 574, 575, 576, 577, 578, 579, 580, - 581, 582, 583, 0, 585, 586, 587, 588, 589, 590, - 591, 592, 593, 594, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, - 593, 594, 578, 579, 580, 581, 582, 583, 584, 585, - 586, 587, 588, 589, 590, 591, 592, 593, 594, 579, - 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, - 590, 591, 592, 593, 594, 580, 581, 582, 583, 584, - 585, 586, 587, 588, 589, 590, 591, 592, 593, 594 -}; - -static const yytype_int16 yycheck[] = -{ - 6, 176, 151, 152, 178, 25, 211, 57, 163, 177, - 6, 351, 128, 719, 404, 82, 457, 158, 16, 6, - 404, 253, 92, 6, 94, 48, 44, 484, 357, 357, - 568, 37, 136, 82, 306, 307, 865, 44, 44, 86, - 625, 37, 375, 61, 249, 126, 648, 632, 442, 718, - 37, 6, 404, 59, 37, 78, 694, 44, 44, 135, - 136, 44, 505, 135, 44, 11, 1390, 339, 74, 1483, - 605, 141, 64, 219, 220, 56, 1306, 32, 33, 146, - 86, 11, 37, 462, 90, 6, 92, 85, 94, 44, - 1484, 44, 11, 298, 1482, 1, 765, 1, 211, 33, - 771, 703, 773, 109, 110, 37, 6, 220, 59, 780, - 108, 789, 73, 62, 1211, 1212, 37, 795, 60, 701, - 6, 562, 492, 44, 12, 357, 35, 177, 1225, 1316, - 9, 86, 138, 1530, 140, 141, 1323, 37, 205, 1527, - 58, 511, 6, 62, 44, 63, 351, 38, 1506, 0, - 142, 37, 58, 171, 58, 82, 62, 62, 109, 108, - 167, 167, 108, 54, 171, 171, 158, 109, 1526, 626, - 1564, 59, 178, 37, 62, 109, 157, 109, 108, 106, - 44, 1578, 61, 138, 171, 171, 86, 47, 171, 108, - 96, 171, 215, 211, 1, 1609, 151, 152, 8, 9, - 540, 219, 220, 108, 14, 54, 35, 59, 135, 4, - 5, 73, 167, 62, 9, 264, 171, 138, 171, 146, - 108, 202, 214, 25, 902, 27, 36, 1585, 59, 0, - 222, 249, 92, 93, 60, 45, 1624, 47, 138, 47, - 195, 196, 151, 152, 153, 1569, 167, 239, 108, 12, - 171, 58, 250, 1483, 1351, 62, 58, 358, 359, 54, - 62, 56, 57, 1360, 1361, 0, 1363, 167, 58, 47, - 6, 171, 348, 54, 138, 70, 348, 108, 205, 720, - 298, 6, 92, 109, 92, 80, 138, 48, 197, 96, - 360, 395, 73, 299, 96, 450, 59, 344, 93, 62, - 1487, 37, 47, 167, 59, 943, 387, 171, 98, 410, - 411, 12, 37, 240, 92, 308, 309, 645, 59, 713, - 714, 906, 151, 152, 153, 331, 178, 476, 477, 864, - 108, 324, 684, 351, 327, 328, 918, 264, 344, 921, - 333, 674, 488, 489, 337, 92, 352, 92, 1026, 1536, - 496, 741, 345, 108, 360, 361, 406, 741, 59, 357, - 1038, 62, 63, 108, 510, 950, 54, 108, 197, 9, - 59, 60, 12, 47, 62, 27, 489, 92, 60, 31, - 962, 963, 614, 529, 60, 73, 54, 92, 59, 344, - 408, 25, 1063, 27, 1072, 184, 1074, 737, 404, 1586, - 47, 407, 25, 74, 27, 73, 361, 47, 60, 947, - 27, 63, 997, 1015, 31, 1512, 1513, 404, 92, 59, - 1249, 61, 62, 63, 58, 73, 444, 109, 62, 356, - 500, 47, 12, 109, 74, 58, 76, 444, 444, 62, - 361, 59, 59, 60, 344, 92, 903, 27, 25, 404, - 27, 31, 92, 93, 3, 4, 5, 109, 444, 508, - 452, 361, 96, 25, 470, 535, 73, 47, 108, 47, - 488, 489, 47, 96, 44, 498, 92, 93, 496, 59, - 60, 58, 62, 63, 54, 62, 56, 414, 867, 444, - 108, 47, 510, 74, 500, 76, 58, 361, 92, 62, - 62, 1170, 508, 495, 404, 4, 5, 56, 57, 361, - 73, 529, 92, 93, 92, 470, 47, 92, 93, 96, - 58, 476, 477, 444, 62, 508, 59, 60, 108, 535, - 60, 80, 538, 108, 96, 541, 92, 712, 1207, 545, - 546, 547, 548, 549, 444, 986, 4, 5, 649, 48, - 1379, 25, 558, 508, 944, 1137, 1138, 56, 57, 606, - 944, 92, 568, 556, 557, 571, 47, 476, 477, 478, - 470, 675, 47, 1016, 1159, 1018, 60, 504, 682, 1022, - 444, 80, 63, 912, 912, 7, 62, 508, 802, 803, - 804, 27, 944, 4, 5, 31, 54, 73, 56, 57, - 606, 651, 482, 1188, 107, 532, 682, 677, 508, 814, - 490, 92, 70, 759, 47, 37, 47, 92, 93, 625, - 4, 5, 80, 59, 60, 54, 632, 63, 3, 4, - 5, 6, 63, 108, 652, 93, 908, 48, 636, 47, - 690, 47, 692, 693, 508, 56, 57, 476, 477, 478, - 31, 606, 47, 58, 1111, 63, 508, 54, 73, 92, - 93, 92, 93, 683, 48, 62, 41, 622, 623, 1338, - 625, 677, 56, 57, 54, 693, 73, 632, 54, 54, - 912, 56, 57, 109, 92, 691, 92, 737, 47, 695, - 54, 47, 619, 73, 47, 70, 80, 92, 718, 47, - 3, 4, 5, 6, 805, 80, 606, 54, 635, 73, - 85, 54, 1091, 1092, 47, 35, 58, 92, 62, 737, - 790, 791, 771, 793, 773, 625, 73, 54, 778, 73, - 779, 780, 632, 92, 93, 741, 92, 786, 41, 92, - 3, 759, 92, 6, 92, 48, 73, 3, 4, 5, - 54, 774, 775, 56, 57, 3, 4, 5, 54, 92, - 783, 1204, 1205, 1206, 59, 771, 1106, 773, 31, 910, - 108, 4, 5, 779, 780, 47, 9, 80, 41, 74, - 786, 76, 85, 789, 790, 791, 741, 793, 771, 795, - 773, 109, 110, 56, 57, 970, 814, 780, 54, 47, - 56, 57, 58, 786, 47, 1184, 54, 70, 56, 57, - 3, 4, 5, 6, 1193, 1194, 771, 80, 773, 1198, - 92, 54, 85, 56, 57, 780, 4, 5, 74, 92, - 108, 786, 152, 153, 789, 54, 937, 70, 93, 47, - 795, 741, 108, 62, 92, 4, 5, 80, 41, 92, - 771, 108, 773, 33, 73, 48, 62, 863, 47, 780, - 11, 1240, 868, 56, 57, 786, 1572, 73, 109, 985, - 48, 771, 98, 773, 60, 47, 92, 197, 56, 57, - 780, 3, 54, 876, 92, 60, 786, 80, 955, 789, - 896, 54, 85, 4, 5, 795, 902, 56, 57, 62, - 906, 73, 80, 92, 111, 54, 73, 771, 62, 773, - 73, 904, 905, 62, 912, 62, 780, 93, 910, 771, - 92, 773, 786, 54, 73, 93, 778, 779, 780, 4, - 5, 62, 47, 44, 786, 4, 5, 111, 944, 54, - 946, 947, 73, 54, 950, 56, 57, 902, 92, 904, - 905, 906, 59, 60, 47, 92, 1335, 944, 73, 73, - 1401, 54, 59, 143, 73, 1066, 1067, 1068, 148, 3, - 4, 5, 6, 762, 73, 1315, 1417, 92, 73, 1029, - 73, 56, 57, 1050, 911, 54, 913, 56, 57, 944, - 11, 997, 109, 948, 949, 950, 785, 1376, 108, 92, - 59, 1050, 902, 108, 1010, 108, 906, 41, 1157, 1158, - 108, 331, 73, 331, 1063, 54, 196, 4, 5, 1042, - 1026, 73, 56, 57, 73, 1048, 1049, 108, 955, 1052, - 1053, 109, 1038, 1056, 4, 5, 109, 1186, 1187, 4, - 5, 950, 997, 111, 944, 1115, 4, 5, 59, 111, - 950, 85, 63, 3, 4, 5, 27, 1063, 59, 59, - 60, 48, 73, 74, 108, 1506, 1072, 73, 1074, 56, - 57, 1026, 73, 74, 73, 76, 1107, 1108, 54, 1110, - 1063, 261, 47, 1038, 54, 1526, 56, 57, 997, 54, - 48, 56, 57, 80, 1161, 73, 1102, 997, 56, 57, - 70, 3, 4, 5, 6, 70, 56, 57, 1063, 1115, - 80, 431, 432, 111, 1555, 80, 111, 1072, 108, 1074, - 1113, 950, 80, 1050, 108, 90, 1026, 92, 93, 108, - 1520, 59, 60, 3, 4, 5, 1520, 58, 1038, 41, - 1314, 108, 1063, 54, 1585, 1313, 48, 1315, 8, 467, - 1170, 111, 1593, 1159, 56, 57, 92, 477, 478, 1260, - 59, 60, 16, 1063, 83, 84, 59, 60, 997, 47, - 24, 63, 1072, 1222, 1074, 1181, 59, 1029, 80, 59, - 60, 54, 1188, 85, 1524, 1181, 56, 57, 58, 92, - 36, 8, 9, 1186, 1187, 109, 1202, 14, 1181, 1063, - 59, 60, 1157, 1158, 1159, 60, 63, 1134, 3, 4, - 5, 1063, 63, 67, 4, 5, 59, 60, 538, 36, - 538, 541, 63, 541, 108, 60, 1181, 545, 45, 108, - 62, 1186, 1187, 1188, 1161, 1614, 108, 557, 558, 108, - 558, 421, 1031, 1032, 424, 3, 4, 5, 1157, 1158, - 1159, 571, 108, 571, 63, 108, 436, 575, 48, 1159, - 1181, 56, 57, 1313, 63, 1315, 56, 57, 3, 4, - 5, 1060, 126, 111, 63, 62, 74, 1186, 1187, 1188, - 108, 1181, 108, 108, 602, 108, 108, 108, 1188, 74, - 80, 609, 472, 74, 474, 1222, 150, 1315, 56, 57, - 1306, 80, 81, 82, 83, 84, 74, 487, 1314, 74, - 1316, 108, 632, 1306, 404, 62, 62, 1323, 59, 1524, - 1316, 56, 57, 1306, 108, 62, 1332, 1323, 1157, 1158, - 1159, 108, 108, 1316, 93, 1358, 1359, 111, 32, 33, - 1323, 35, 111, 1498, 73, 85, 47, 3, 4, 5, - 111, 1306, 1501, 1502, 3, 4, 5, 1186, 1187, 1188, - 108, 1316, 111, 108, 108, 59, 108, 61, 1323, 108, - 60, 109, 108, 67, 4, 5, 109, 1552, 59, 9, - 470, 30, 3, 4, 5, 1306, 240, 241, 3, 4, - 5, 63, 3, 4, 5, 1316, 7, 8, 9, 253, - 56, 57, 1323, 63, 1427, 54, 1306, 56, 57, 78, - 79, 80, 81, 82, 83, 84, 1316, 47, 92, 59, - 31, 59, 59, 1323, 54, 36, 56, 57, 1217, 1218, - 108, 1220, 1221, 54, 1223, 56, 57, 108, 92, 54, - 70, 56, 57, 54, 92, 56, 57, 58, 92, 143, - 80, 92, 109, 108, 148, 8, 109, 151, 152, 153, - 90, 108, 92, 93, 195, 196, 197, 109, 111, 323, - 33, 1477, 108, 108, 108, 1525, 1482, 1483, 1484, 108, - 108, 1487, 63, 108, 178, 111, 1482, 54, 808, 108, - 184, 1487, 103, 104, 105, 108, 108, 1503, 108, 1482, - 1483, 195, 196, 197, 1487, 108, 1524, 108, 1501, 1502, - 62, 365, 111, 47, 1520, 108, 108, 211, 108, 1428, - 374, 1527, 1477, 95, 62, 219, 220, 1482, 1483, 1484, - 1536, 1527, 1487, 387, 1557, 625, 62, 60, 60, 9, - 1536, 60, 632, 16, 1527, 92, 1501, 1502, 3, 4, - 5, 108, 108, 1536, 872, 92, 60, 108, 1564, 1348, - 1349, 1482, 1483, 108, 108, 1520, 1487, 261, 748, 749, - 60, 751, 1527, 108, 63, 108, 108, 1477, 54, 92, - 1586, 1536, 1482, 1483, 1484, 905, 906, 1487, 906, 92, - 1586, 111, 1501, 1502, 1503, 3, 4, 5, 6, 1428, - 17, 56, 57, 1586, 60, 54, 1527, 107, 60, 1564, - 97, 108, 108, 108, 108, 1536, 11, 60, 1624, 60, - 1520, 60, 3, 4, 5, 6, 92, 1527, 1624, 59, - 950, 1586, 63, 41, 108, 60, 1536, 331, 11, 108, - 108, 1624, 90, 11, 92, 60, 94, 60, 56, 57, - 504, 741, 0, 3, 4, 5, 172, 7, 8, 9, - 41, 1450, 1451, 1452, 1564, 1586, 3, 48, 37, 1624, - 675, 1415, 1501, 1502, 1503, 56, 57, 997, 171, 944, - 444, 463, 4, 5, 167, 1551, 1586, 9, 470, 96, - 779, 1170, 140, 141, 240, 140, 3, 4, 5, 789, - 1400, 1624, 1250, 1624, 85, 795, 56, 57, 3, 4, - 5, 725, 301, 407, 408, 930, 570, 245, 1338, 1207, - 1509, 1510, 925, 786, 1624, 47, 779, 421, 1224, 658, - 424, 923, 54, 126, 56, 57, 430, 431, 432, 606, - 202, 472, 436, 474, 348, 476, 477, 478, 70, 56, - 57, 1316, 1182, 48, 536, 1593, 487, 463, 80, 1572, - 614, 56, 57, 1603, 470, 1541, 1605, 1005, 90, 949, - 92, 93, 1332, 3, 4, 5, -1, -1, 472, -1, - 474, -1, 476, 477, 478, -1, -1, 481, 1577, -1, - -1, -1, -1, 487, 488, 489, -1, -1, 492, -1, - -1, -1, 496, -1, -1, 3, 4, 5, 6, -1, - -1, 9, 902, -1, 596, -1, 906, 511, 48, 601, - -1, -1, -1, -1, -1, -1, 56, 57, -1, 683, - 536, -1, -1, 31, -1, -1, -1, -1, 1158, 1159, - 694, -1, -1, 41, 538, -1, -1, 541, -1, -1, - 632, -1, -1, -1, 944, -1, 54, 639, 56, 57, - 950, -1, 556, 557, 558, -1, -1, 1187, 1188, -1, - 1188, 725, 70, -1, 322, -1, -1, 571, -1, -1, - -1, -1, 80, -1, 1202, -1, -1, 85, -1, -1, - 596, -1, -1, -1, 92, 601, -1, 3, 4, 5, - 6, -1, -1, 3, 4, 5, 6, 997, -1, 9, - -1, -1, 360, -1, 3, 4, 5, 6, 1236, 1237, - 1238, 1239, -1, -1, 3, 4, 5, 6, -1, -1, - -1, 31, -1, 639, -1, 41, 1026, -1, 632, -1, - -1, 41, 48, -1, -1, -1, -1, 47, 1038, -1, - 56, 57, 41, -1, 54, -1, 56, 57, 652, 48, - -1, -1, 41, -1, -1, -1, -1, 56, 57, 48, - 70, -1, -1, -1, 80, 1155, 1156, 56, 57, 85, - 80, 1299, 1072, 1163, 1074, 85, -1, -1, 47, -1, - 90, 80, 92, 93, -1, -1, 85, 691, -1, 693, - 694, -1, -1, -1, -1, -1, 85, -1, 3, 4, - 5, 6, -1, -1, 462, 463, -1, 748, 749, -1, - 751, -1, 470, -1, -1, -1, 808, 86, 87, -1, - -1, -1, 91, 92, 93, 94, 350, 351, 352, -1, - -1, -1, -1, 737, -1, -1, 41, 778, -1, -1, - -1, -1, 500, 48, 748, 749, -1, 751, -1, 1377, - -1, 56, 57, -1, -1, 759, -1, -1, 762, 1159, - -1, -1, 7, 8, 9, -1, 930, -1, -1, 14, - 862, 863, -1, -1, -1, 779, 868, 535, 536, 943, - 85, 785, 1410, -1, 1274, 1275, 31, 1277, 1188, -1, - 882, 36, 884, -1, 886, -1, -1, -1, 1428, -1, - 45, -1, -1, -1, 808, -1, 3, 4, 5, 6, - 568, -1, 570, -1, -1, 573, 574, -1, 576, 577, - 578, 579, 580, 581, 582, 583, 584, 585, 586, 587, - 588, 589, 590, 591, 592, 593, 594, -1, 596, -1, - 932, -1, -1, 601, 41, -1, 862, 863, -1, 1477, - -1, -1, 868, -1, -1, 1483, 1484, 54, -1, 56, - 57, -1, -1, -1, -1, -1, 882, -1, 884, -1, - 886, -1, 1502, 1503, 632, 1503, 3, 4, 5, 6, - -1, 639, -1, -1, -1, -1, 978, -1, 85, 76, - 77, 78, 79, 80, 81, 82, 83, 84, -1, -1, - 904, 905, 906, 661, 662, 997, -1, 948, 949, 950, - -1, 7, 8, 9, 41, -1, 932, -1, 14, 677, - 47, -1, -1, -1, -1, -1, -1, 54, 1092, 56, - 57, -1, -1, -1, -1, 31, 1564, 4, 5, 943, - 36, 8, 9, 70, 948, 949, 950, 14, -1, 45, - -1, -1, 1580, 80, -1, -1, 997, -1, 85, -1, - -1, -1, 978, 90, 60, 92, 93, 725, -1, 36, - -1, -1, -1, -1, 1602, -1, -1, -1, 45, -1, - 47, 1609, -1, -1, -1, -1, -1, 54, 1029, 56, - 57, -1, -1, 997, -1, -1, -1, -1, 622, 623, - -1, 625, -1, 70, -1, -1, -1, -1, 632, -1, - 4, 5, 770, 80, 1178, 9, 350, 351, 352, -1, - 1184, -1, -1, 90, -1, 92, 93, 1031, 1032, -1, - -1, -1, 790, 791, -1, 793, -1, -1, -1, 3, - 4, 5, 6, -1, -1, -1, -1, -1, -1, -1, - 808, -1, -1, 47, -1, -1, 1060, -1, 757, -1, - 54, -1, 56, 57, -1, -1, 690, -1, 692, 693, - -1, 695, 830, -1, 38, 39, 70, 41, -1, -1, - 1172, -1, 1174, -1, 1176, -1, 80, -1, -1, 788, - 54, -1, 56, 57, -1, 794, 90, -1, 92, 93, - -1, 7, 8, 9, 862, 863, -1, -1, 14, 867, - 868, -1, -1, 737, 1155, 1156, 1157, 1158, 1159, -1, - 1520, -1, 1163, -1, 882, 31, 884, -1, 886, -1, - 36, -1, -1, -1, -1, -1, 1300, 1301, -1, 45, - -1, -1, -1, -1, -1, 1186, 1187, 1188, -1, -1, - -1, 1155, 1156, 1157, 1158, 1159, 1172, -1, 1174, 1163, - 1176, -1, -1, -1, 922, -1, -1, -1, -1, -1, - 3, 4, 5, 6, 932, -1, -1, -1, 1219, 1271, - -1, -1, 1186, 1187, 1188, -1, -1, -1, -1, 947, - 814, -1, -1, -1, -1, -1, -1, -1, 897, -1, - 899, -1, 960, -1, -1, -1, -1, -1, 41, -1, - -1, -1, -1, 1217, 1218, -1, 1220, 1221, -1, 1223, - 978, 54, -1, 56, 57, -1, -1, 60, 1392, 62, - -1, -1, -1, 1274, 1275, -1, 1277, 70, -1, 997, - 3, 4, 5, 6, -1, -1, -1, 80, 6, -1, - 1414, 1415, 85, -1, -1, 1271, -1, -1, 16, 92, - -1, -1, -1, 887, -1, 889, -1, -1, 26, -1, - 1274, 1275, -1, 1277, 32, 33, 900, 35, 41, 37, - 904, 905, 906, 1041, -1, -1, 44, -1, 622, 623, - -1, 54, -1, 56, 57, -1, -1, 60, -1, 57, - -1, 59, -1, -1, -1, -1, -1, 70, -1, 67, - 1314, 1315, -1, -1, -1, -1, 74, 80, -1, -1, - -1, -1, 85, -1, 948, 949, 950, 85, 86, 92, - -1, 1495, -1, 1091, 1092, -1, 1428, 1095, -1, 7, - 8, 9, -1, -1, 1348, 1349, 14, -1, -1, -1, - 108, -1, -1, -1, -1, -1, 690, 1115, 692, 693, - -1, 695, -1, 31, -1, -1, -1, -1, 36, -1, - -1, -1, 1071, 997, 1073, -1, -1, 45, 136, -1, - 138, -1, -1, -1, 142, 143, -1, 1428, -1, 147, - 148, -1, 60, 151, 152, 153, -1, -1, -1, -1, - -1, 4, 5, 737, -1, 8, 9, -1, -1, 167, - -1, 14, -1, 171, 1172, -1, 1174, -1, 1176, 177, - 178, -1, -1, -1, 1428, 28, 1184, 30, -1, 1128, - -1, -1, -1, 36, -1, 1193, 1194, 195, 196, 197, - 1198, -1, 45, -1, 47, -1, 1450, 1451, 1452, -1, - -1, 54, -1, 56, 57, -1, -1, 1215, 1216, -1, - 1501, 1502, 1503, -1, -1, -1, 224, 70, -1, 4, - 5, -1, -1, 8, 9, -1, -1, 80, -1, 14, - 814, -1, 1240, 241, -1, -1, -1, 90, -1, 92, - 93, -1, 250, 28, -1, 30, -1, 1501, 1502, 1503, - -1, 36, -1, 261, -1, 1509, 1510, -1, -1, 1208, - 45, -1, -1, 1271, 1213, -1, -1, -1, -1, 54, - -1, 56, 57, 58, -1, -1, -1, -1, -1, -1, - -1, 1155, 1156, 1157, 1158, 1159, -1, 1295, -1, 1163, - -1, 299, 300, -1, 3, 4, 5, 6, -1, -1, - 9, -1, -1, 887, -1, 889, -1, 92, -1, -1, - -1, -1, 1186, 1187, 1188, 1264, 900, -1, -1, -1, - 904, 905, 31, 1577, 3, 4, 5, 1335, 7, 8, - 9, -1, 41, -1, -1, -1, 344, -1, 47, -1, - 348, -1, 350, 351, 352, 54, 1354, 56, 57, -1, - -1, -1, 31, 361, -1, -1, -1, 36, -1, -1, - -1, 70, -1, -1, 948, 949, -1, -1, 1376, -1, - -1, 80, -1, -1, -1, -1, 85, 56, 57, -1, - -1, 90, -1, 92, 93, -1, -1, 395, -1, -1, - -1, -1, -1, -1, -1, -1, 404, -1, 406, 407, - 1274, 1275, -1, 1277, 3, 4, 5, -1, 7, 3, - 4, 5, 6, 421, -1, 9, 424, -1, 1367, 1368, - 1428, -1, -1, -1, -1, -1, -1, -1, 436, -1, - -1, 30, -1, -1, -1, 1384, 444, 31, 37, -1, - 1448, 1449, -1, -1, -1, -1, -1, 41, -1, 1457, - -1, -1, -1, 47, -1, 54, -1, 56, 57, -1, - 54, -1, 56, 57, 472, -1, 474, -1, 476, 477, - 478, -1, -1, -1, 482, -1, 70, 1485, -1, 487, - 4, 5, 490, 7, 8, 9, 80, -1, 12, -1, - 14, 85, -1, -1, 1443, 1444, 90, -1, 92, 93, - 508, -1, -1, -1, 28, -1, 30, 31, -1, -1, - -1, -1, 36, 1462, 1463, -1, -1, -1, -1, -1, - -1, 45, -1, 47, -1, -1, -1, -1, -1, -1, - 54, -1, 56, 57, -1, -1, -1, -1, 546, 547, - 548, 549, -1, -1, -1, -1, 70, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 90, -1, 92, 93, - -1, 1155, 1156, 1157, 1158, -1, -1, -1, 1, 1163, - 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, - -1, 14, -1, -1, -1, -1, -1, -1, 606, -1, - 608, -1, 1186, 1187, -1, 28, 1614, 30, 31, 32, - -1, -1, 620, 36, 622, 623, -1, 625, 41, -1, - -1, -1, 45, 46, 632, 48, -1, -1, 636, -1, - -1, 54, -1, 56, 57, -1, -1, 60, -1, 62, - -1, -1, -1, 651, -1, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 80, -1, -1, - -1, -1, 85, -1, -1, -1, -1, 675, 1, 92, - 3, 4, 5, 6, 682, 8, 9, 10, 11, -1, - 13, 14, 690, 691, 692, 693, 694, 695, -1, -1, - 1274, 1275, -1, 1277, -1, 28, 29, 30, 31, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, -1, 61, 737, - -1, -1, -1, 741, 67, -1, -1, 70, -1, -1, - 748, 749, -1, 751, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, -1, 92, - 768, -1, -1, 771, -1, 773, -1, -1, -1, -1, - 778, 779, 780, -1, -1, 4, 5, 110, 786, 8, - 9, 789, -1, -1, -1, 14, -1, 795, -1, -1, - -1, -1, -1, -1, 802, 803, 804, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 814, 36, -1, -1, - -1, -1, -1, -1, -1, -1, 45, -1, 47, 6, - -1, -1, -1, -1, -1, 54, -1, 56, 57, 16, - -1, -1, -1, -1, -1, -1, -1, -1, 25, 26, - -1, 70, -1, -1, -1, 32, 33, -1, 35, -1, - 37, 80, -1, -1, -1, -1, -1, 44, -1, -1, - -1, 90, -1, 92, 93, -1, -1, -1, -1, -1, - 57, -1, 59, -1, -1, -1, -1, -1, -1, 887, - 67, 889, -1, -1, -1, -1, -1, 74, 896, -1, - -1, -1, 900, -1, 902, -1, 904, 905, 906, 86, - -1, -1, -1, -1, 912, -1, 3, 4, 5, 6, - 7, 8, 9, -1, -1, 12, -1, 14, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 28, -1, 30, 31, -1, 944, -1, 946, 36, - 948, 949, 950, -1, 41, -1, -1, -1, 45, -1, - 47, 138, -1, -1, -1, 142, 143, 54, -1, 56, - 57, 148, -1, -1, 151, 152, 153, -1, -1, 3, - 4, 5, 6, 70, -1, 9, -1, -1, -1, -1, - 167, -1, -1, 80, 171, -1, -1, -1, 85, 997, - 177, 178, -1, 90, -1, 92, 93, 31, -1, -1, - -1, -1, 1010, -1, -1, -1, -1, 41, 195, 196, - 197, -1, -1, 47, -1, -1, -1, -1, 1026, -1, - 54, 1029, 56, 57, -1, -1, -1, -1, -1, -1, - 1038, -1, -1, -1, -1, -1, 70, 224, -1, -1, - -1, -1, -1, 1051, -1, -1, 80, -1, -1, -1, - -1, 85, -1, 6, -1, 1063, 90, -1, 92, 93, - -1, -1, -1, -1, 1072, -1, 1074, -1, 1, -1, - 3, 4, 5, 6, 261, 8, -1, -1, -1, 32, - 33, -1, 35, -1, 37, 4, 5, -1, -1, 8, - 9, 44, -1, -1, 1102, 14, -1, -1, -1, 1107, - 1108, -1, 1110, -1, 57, -1, 59, -1, 41, 28, - -1, 30, 299, 300, -1, 48, -1, 36, -1, -1, - -1, 54, -1, 56, 57, -1, 45, -1, -1, 82, - -1, -1, -1, -1, -1, 54, -1, 56, 57, -1, - -1, -1, -1, -1, -1, -1, -1, 1155, 1156, 1157, - 1158, 1159, 85, -1, -1, 1163, -1, 344, -1, -1, - -1, 348, -1, 350, 351, 352, -1, -1, -1, -1, - 357, -1, -1, 92, 361, -1, -1, -1, 1186, 1187, - 1188, -1, 135, 136, -1, 138, -1, -1, -1, 142, - 143, -1, -1, 146, -1, 148, -1, -1, 151, 152, - 153, -1, -1, -1, -1, 158, -1, -1, 395, -1, - -1, 1219, -1, -1, 167, -1, 1224, 404, 171, 406, - 407, -1, 4, 5, 177, 178, 8, 9, -1, -1, - -1, -1, 14, -1, 421, -1, -1, 424, -1, -1, - -1, -1, 195, 196, 197, -1, 28, -1, 30, 436, - -1, -1, 205, -1, 36, -1, -1, 444, -1, -1, - -1, -1, -1, 45, -1, -1, 1274, 1275, -1, 1277, - -1, 224, 54, -1, 56, 57, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 472, -1, 474, -1, 476, - 477, 478, -1, -1, -1, 482, -1, -1, -1, -1, - 487, -1, -1, 490, -1, 1313, 1314, 1315, 261, -1, - 1, -1, 3, 4, 5, 6, 7, 8, 9, -1, - -1, 508, -1, 14, 1332, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 28, -1, 30, - 31, 32, -1, -1, -1, 36, 37, -1, -1, -1, - 41, -1, -1, -1, 45, 46, -1, 48, -1, 546, - 547, 548, 549, 54, -1, 56, 57, -1, -1, 60, - -1, 62, -1, -1, 3, 4, 5, 6, 331, 70, - 9, 4, 5, -1, -1, 8, 9, -1, -1, 80, - -1, 14, -1, -1, 85, 348, -1, -1, -1, -1, - -1, 92, 31, 356, -1, 28, -1, 30, 361, -1, - -1, -1, 41, 36, -1, -1, -1, -1, 109, 606, - 1428, 608, 45, -1, -1, 54, -1, 56, 57, -1, - -1, 54, -1, 56, 57, 622, 623, -1, 625, -1, - -1, 70, 395, -1, -1, 632, -1, -1, -1, -1, - -1, 80, -1, 406, -1, -1, 85, -1, 645, -1, - -1, -1, -1, 92, 651, -1, -1, -1, 421, -1, - -1, 424, -1, -1, -1, -1, -1, 430, 431, 432, - -1, -1, -1, 436, -1, -1, -1, -1, 675, 6, - -1, 444, -1, 1501, 1502, 1503, 683, -1, 3, 4, - 5, 6, -1, 690, 691, 692, 693, 694, 695, -1, - -1, -1, 1520, -1, -1, -1, -1, 1525, -1, 472, - 37, 474, -1, 476, 477, 478, 31, 44, -1, 482, - -1, 718, -1, -1, 487, -1, 41, 490, -1, -1, - 57, -1, 59, -1, -1, -1, -1, -1, -1, 54, - 737, 56, 57, -1, 741, 508, -1, -1, -1, -1, - -1, 748, 749, -1, 751, 70, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 80, -1, -1, 765, -1, - 85, 768, -1, -1, 771, 538, 773, 92, 541, -1, - -1, 778, 779, 780, -1, -1, -1, -1, -1, 786, - -1, -1, 789, 556, 557, 558, -1, -1, 795, -1, - -1, -1, -1, -1, -1, 802, 803, 804, 571, -1, - -1, 138, -1, -1, -1, 142, -1, 814, -1, -1, - -1, -1, -1, -1, 3, 4, 5, 6, 7, 8, - 9, -1, -1, -1, -1, 14, -1, -1, -1, -1, - 167, -1, -1, -1, 171, -1, -1, -1, -1, -1, - 177, 178, 31, -1, -1, -1, 619, 36, -1, -1, - -1, -1, 41, -1, -1, -1, 45, -1, 47, 632, - -1, -1, -1, -1, -1, 54, -1, 56, 57, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 651, -1, - 887, 70, 889, -1, -1, -1, -1, 224, -1, 896, - -1, 80, -1, 900, -1, 902, 85, 904, 905, 906, - -1, 90, 675, 92, 93, 912, -1, -1, -1, 682, - -1, -1, 3, 4, 5, 6, -1, 690, 691, 692, - 693, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 84, 3, 4, 5, 6, -1, 944, 9, 946, - 31, 948, 949, 950, -1, -1, -1, -1, -1, -1, - 41, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 31, -1, -1, 54, 737, 56, 57, -1, 741, -1, - 41, -1, -1, -1, -1, 748, 749, -1, 751, 70, - -1, -1, -1, 54, -1, 56, 57, -1, -1, 80, - 997, -1, -1, -1, 85, -1, -1, -1, 771, 70, - 773, 92, -1, 1010, -1, 778, 779, 780, 161, 80, - -1, -1, -1, 786, 85, -1, -1, -1, -1, 1026, - -1, 92, 1029, -1, 361, -1, -1, -1, -1, -1, - -1, 1038, -1, -1, -1, 808, -1, -1, -1, -1, - 193, -1, -1, -1, -1, 3, 4, 5, 6, -1, - -1, 9, -1, 206, -1, -1, 1063, -1, -1, -1, - -1, -1, -1, -1, -1, 1072, -1, 1074, -1, 406, - -1, -1, -1, 31, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 41, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 1102, 54, -1, 56, 57, - 1107, 1108, -1, 1110, -1, -1, -1, 444, -1, -1, - -1, -1, 70, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 80, -1, -1, -1, -1, 85, -1, -1, - -1, 904, 905, 906, 92, -1, -1, 910, 911, -1, - -1, -1, -1, -1, -1, 482, -1, -1, 1155, 1156, - 1157, 1158, 1159, 490, -1, -1, 1163, 6, -1, -1, - -1, -1, -1, 1170, -1, 3, 4, 5, 6, -1, - -1, 508, -1, -1, -1, 948, 949, 950, -1, 1186, - 1187, 1188, 955, 32, 33, -1, 35, -1, 37, -1, - -1, -1, -1, 31, -1, 44, -1, -1, -1, -1, - 1207, -1, -1, 41, -1, -1, -1, -1, 57, -1, - 59, -1, 1219, -1, -1, -1, 54, 1224, 56, 57, - -1, -1, -1, -1, 997, -1, -1, -1, -1, -1, - -1, -1, 70, -1, 3, 4, 5, 6, -1, -1, - 9, -1, 80, -1, -1, -1, -1, 85, -1, -1, - -1, -1, -1, -1, 92, -1, 1029, -1, -1, -1, - -1, -1, 31, -1, -1, -1, -1, 1274, 1275, -1, - 1277, -1, 41, -1, -1, -1, -1, 1050, -1, -1, - -1, -1, -1, -1, -1, 54, -1, 56, 57, 138, - 1063, -1, -1, 142, 143, 1302, -1, -1, -1, 148, - -1, 70, 151, 152, 153, -1, 1313, 1314, 1315, -1, - -1, 80, -1, -1, 651, -1, 85, -1, 167, -1, - -1, -1, 171, 92, -1, 1332, -1, 480, 177, 178, - -1, 1338, 485, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 195, 196, 197, -1, - -1, -1, -1, 690, 691, 692, 693, -1, -1, 512, - -1, 1134, -1, -1, -1, 518, -1, 35, -1, -1, - -1, 3, 4, 5, 6, 224, -1, 530, 531, -1, - 533, -1, 1155, 1156, 1157, 1158, 1159, -1, 1161, 57, - 1163, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 737, -1, -1, -1, 741, -1, -1, -1, -1, 41, - -1, -1, 261, 1186, 1187, 1188, -1, -1, -1, -1, - -1, 1428, 54, -1, 56, 57, -1, -1, -1, -1, - 62, -1, -1, -1, 771, -1, 773, -1, 70, -1, - -1, 778, 779, 780, -1, -1, 1219, -1, 80, 786, - -1, 1224, -1, 85, -1, -1, -1, -1, -1, -1, - 92, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 628, 629, -1, -1, -1, - 633, -1, -1, 151, 152, 153, -1, -1, -1, -1, - -1, -1, -1, -1, 1501, 1502, 1503, 3, 4, 5, - 6, 1274, 1275, 9, 1277, -1, -1, -1, 357, 177, - -1, -1, 361, 1520, -1, -1, -1, -1, 1525, -1, - -1, -1, -1, -1, -1, 31, -1, 195, 196, 197, - -1, -1, -1, -1, -1, 41, -1, -1, -1, -1, - 1313, 1314, 1315, -1, -1, -1, -1, -1, 54, -1, - 56, 57, -1, -1, -1, -1, 224, 406, -1, -1, - -1, -1, -1, -1, 70, 57, -1, -1, -1, -1, - -1, -1, 421, -1, 80, 424, -1, -1, -1, 85, - -1, 109, 110, -1, -1, -1, 92, 436, -1, -1, - 82, -1, -1, 85, -1, 444, -1, -1, 3, 4, - 5, 6, 7, 8, 9, -1, -1, -1, -1, 14, - -1, -1, -1, -1, 106, -1, 108, -1, -1, -1, - -1, -1, -1, 472, -1, 474, 31, 476, 477, 478, - -1, 36, 300, 482, -1, -1, 41, -1, 487, -1, - 45, 490, 47, 796, -1, 798, -1, -1, -1, 54, - -1, 56, 57, -1, -1, 1428, -1, -1, -1, 508, - -1, -1, -1, -1, -1, 70, -1, -1, 3, 4, - 5, 6, 7, 8, 9, 80, -1, -1, -1, 14, - 85, -1, 350, 351, 352, 177, -1, 92, -1, -1, - -1, -1, 1029, 28, -1, 30, 31, -1, -1, -1, - -1, 36, -1, 195, 196, 197, 41, -1, -1, -1, - 45, -1, -1, 205, -1, -1, -1, 870, 871, 54, - 873, 56, 57, 12, -1, 60, 1063, -1, 1501, 1502, - 1503, -1, 224, -1, -1, 70, -1, -1, 406, -1, - -1, -1, -1, -1, -1, 80, -1, -1, 901, -1, - 85, -1, 1525, -1, -1, -1, -1, 92, 250, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 620, 264, 62, 63, 64, 65, 66, 67, 68, - 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - 79, 80, 81, 82, 83, 84, -1, -1, -1, 952, - -1, -1, 651, 331, 472, -1, 474, -1, 476, 477, - 478, -1, -1, -1, 482, -1, -1, -1, -1, 487, - -1, -1, 490, -1, 3, 4, 5, 6, 7, 8, - 9, -1, -1, -1, -1, 14, -1, -1, -1, -1, - -1, 690, 691, 692, 693, -1, -1, -1, -1, 28, - -1, 30, 31, 32, -1, -1, -1, 36, -1, -1, - -1, -1, 41, -1, 356, 357, 45, -1, -1, 48, - -1, -1, 1025, -1, -1, 54, 404, 56, 57, -1, - -1, -1, 1219, -1, 1037, -1, -1, 1224, 737, -1, - -1, 70, 741, -1, -1, -1, -1, -1, -1, 748, - 749, 80, 751, -1, -1, -1, 85, -1, -1, -1, - -1, -1, -1, 92, 406, -1, -1, -1, -1, 98, - -1, -1, 771, -1, 773, -1, -1, -1, -1, 778, - 779, 780, -1, -1, -1, -1, -1, 786, -1, -1, - 608, -1, 470, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 622, 623, -1, 625, -1, -1, - -1, -1, -1, -1, 632, -1, -1, -1, -1, -1, - 1123, -1, -1, -1, -1, -1, 1313, 1314, 1315, -1, - 472, -1, 474, 651, 476, 477, 478, -1, -1, -1, - 482, -1, -1, -1, -1, 487, -1, -1, 490, -1, - 3, 4, 5, 6, 7, 8, 9, -1, -1, 1162, - 538, 14, -1, 541, -1, -1, -1, 545, 546, 547, - 548, 549, 690, -1, 692, 693, -1, 695, 31, -1, - 558, -1, -1, 36, -1, -1, -1, -1, 41, -1, - -1, -1, 45, 571, 47, -1, -1, -1, -1, -1, - -1, 54, -1, 56, 57, -1, -1, -1, -1, -1, - -1, -1, -1, 912, -1, -1, -1, 70, -1, 737, - -1, -1, -1, -1, 1227, -1, -1, 80, 1231, -1, - 748, 749, 85, 751, -1, -1, -1, 90, -1, 92, - 93, -1, -1, -1, -1, -1, -1, 625, -1, 948, - 949, 950, -1, -1, 632, -1, -1, -1, -1, -1, - 778, -1, -1, 1266, -1, -1, -1, -1, -1, -1, - 1, -1, 3, 4, 5, 6, 7, 8, 9, -1, - -1, -1, -1, 14, 802, 803, 804, -1, -1, -1, - -1, -1, -1, 635, 636, -1, 814, 28, 997, 30, - 31, 32, -1, -1, -1, 36, 37, -1, -1, 651, - 41, -1, -1, -1, 45, 46, -1, 48, -1, -1, - -1, -1, -1, 54, -1, 56, 57, -1, -1, 60, - 1029, 62, -1, -1, -1, -1, -1, -1, 1525, 70, - 1343, -1, -1, -1, 1347, -1, -1, -1, 690, 80, - 692, 693, -1, -1, 85, -1, -1, -1, -1, -1, - -1, 92, -1, 741, 1063, -1, 1369, 1370, -1, 887, - -1, 889, 3, 4, 5, 6, -1, -1, 109, -1, - -1, -1, 900, -1, -1, -1, 904, 905, 906, -1, - -1, -1, -1, -1, -1, 737, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 748, 749, -1, 751, - 41, 789, -1, -1, -1, -1, -1, 795, -1, -1, - -1, -1, -1, 54, -1, 56, 57, -1, -1, 60, - 948, 949, 950, -1, -1, -1, 778, -1, -1, 70, - 3, 4, 5, 6, 7, 8, 9, -1, -1, 80, - -1, 14, -1, -1, 85, -1, 1155, 1156, 1157, 1158, - 1159, 92, -1, -1, 1163, 28, -1, 30, 31, -1, - -1, -1, -1, 36, -1, -1, -1, -1, 41, 997, - -1, -1, 45, -1, 47, 863, -1, 1186, 1187, 1188, - -1, 54, -1, 56, 57, -1, -1, 3, 4, 5, - 6, -1, -1, -1, -1, -1, -1, 70, -1, -1, - -1, 1029, -1, -1, -1, -1, -1, 80, 896, -1, - 1219, -1, 85, -1, 902, 1224, -1, 90, 906, 92, - 93, -1, -1, -1, -1, 41, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 54, -1, - 56, 57, -1, -1, -1, -1, 62, -1, -1, -1, - -1, -1, -1, -1, 70, -1, 944, -1, 946, 911, - 912, 913, 950, -1, 80, 1274, 1275, -1, 1277, 85, - -1, -1, -1, -1, -1, -1, 92, -1, -1, 1107, - 1108, -1, 1110, -1, -1, -1, 3, 4, 5, 6, - -1, -1, 9, -1, -1, -1, 948, 949, 950, -1, - -1, 16, -1, 955, 1313, 1314, 1315, -1, -1, 997, - 25, 26, -1, -1, 31, -1, -1, 32, 33, -1, - 35, -1, 1010, -1, 41, -1, -1, 1155, 1156, 1157, - 1158, 1159, -1, 985, -1, 1163, -1, 54, 1026, 56, - 57, 3, 4, 5, 6, 997, -1, 9, -1, -1, - 1038, -1, 67, 70, -1, -1, -1, -1, 1186, 1187, - 1188, -1, -1, 80, -1, -1, -1, -1, 85, 31, - -1, -1, -1, -1, -1, 92, -1, 1029, -1, 41, - -1, -1, -1, -1, 1072, -1, 1074, -1, -1, -1, - -1, 1219, 54, -1, 56, 57, -1, -1, 1050, -1, - -1, 3, 4, 5, 6, -1, -1, -1, 70, -1, - -1, 126, -1, 128, 1102, -1, -1, -1, 80, 1428, - 135, 136, -1, 85, -1, -1, -1, 142, 143, -1, - 92, 146, 147, 148, -1, 150, 151, 152, 153, 41, - -1, -1, -1, -1, -1, -1, 1274, 1275, -1, 1277, - -1, -1, 54, -1, 56, 57, -1, -1, -1, -1, - 62, -1, -1, -1, -1, -1, -1, -1, 70, -1, - -1, 1159, -1, -1, -1, -1, -1, -1, 80, -1, - -1, -1, 1134, 85, -1, 1313, -1, 1315, -1, -1, - 92, -1, 1501, 1502, 1503, -1, -1, -1, -1, -1, - 1188, -1, -1, 1155, 1156, 1157, 1158, 1159, -1, 1161, - -1, 1163, -1, -1, 1202, -1, 1525, -1, -1, -1, - -1, -1, -1, -1, -1, 240, 241, -1, -1, -1, - -1, -1, -1, -1, 1186, 1187, 1188, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 261, -1, 1, -1, - 3, 4, 5, 6, 7, 8, 9, -1, -1, -1, - -1, 14, -1, -1, -1, -1, -1, 1219, -1, -1, - -1, -1, -1, -1, -1, 28, -1, 30, 31, 32, - -1, -1, -1, 36, 37, 300, -1, -1, 41, -1, - -1, -1, 45, 46, -1, 48, -1, -1, -1, -1, - 1428, 54, -1, 56, 57, -1, -1, 60, -1, 62, - -1, -1, -1, -1, -1, -1, -1, 70, -1, -1, - -1, -1, 1274, 1275, -1, 1277, -1, 80, -1, -1, - -1, -1, 85, 348, -1, 350, 351, -1, -1, 92, - -1, -1, -1, -1, 1332, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 109, -1, -1, -1, - -1, 1313, -1, 1315, -1, -1, 4, 5, -1, 7, - 8, 9, -1, 1501, 1502, 1503, 14, -1, -1, -1, - 395, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 28, -1, 30, 31, -1, -1, -1, 1525, 36, 414, - -1, -1, -1, -1, -1, -1, 421, 45, -1, 424, - 48, -1, -1, -1, -1, -1, 54, -1, 56, 57, - -1, 436, 1, -1, 3, 4, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, - 29, 30, 31, 32, -1, 34, 35, 36, -1, 38, - 39, 40, 41, 42, 43, -1, 45, -1, 47, -1, - 49, 50, 51, 52, 53, 54, 1428, 56, 57, 58, - -1, -1, 61, -1, -1, -1, -1, -1, 67, 504, - -1, 70, 4, 5, -1, 7, 8, 9, -1, 78, - 79, 80, 14, -1, -1, -1, 85, 86, 87, -1, - -1, 90, -1, 92, 93, 1503, 28, 532, 30, 31, - -1, -1, -1, -1, 36, -1, -1, -1, -1, -1, - -1, 110, 1520, 45, -1, -1, -1, -1, -1, -1, - -1, -1, 54, -1, 56, 57, -1, -1, -1, 1501, - 1502, 1503, -1, -1, -1, -1, 1, -1, 3, 4, - 5, 6, 7, 8, 9, -1, -1, 12, -1, 14, - -1, -1, -1, 1525, -1, -1, -1, -1, -1, -1, - 25, -1, 27, -1, -1, -1, 31, -1, -1, -1, - -1, 36, -1, 608, -1, -1, 41, -1, -1, -1, - 45, -1, 47, -1, 619, 620, -1, 622, 623, 54, - -1, 56, 57, 58, 59, 60, -1, 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, -1, -1, 90, 91, 92, 93, 94, - -1, 96, 97, -1, -1, -1, -1, 102, -1, -1, - 675, -1, 107, 108, 109, -1, 111, 682, 683, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 694, - -1, -1, -1, -1, -1, -1, -1, -1, 1, -1, - 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, - 13, 14, 15, 718, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, 44, 45, 46, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, 60, 61, -1, - 765, -1, -1, 768, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, -1, 92, - -1, -1, -1, 96, -1, -1, -1, 802, 803, 804, - -1, -1, -1, -1, -1, -1, 109, 110, 1, 814, - 3, 4, 5, 6, 7, 8, 9, 10, 11, -1, - 13, 14, 15, -1, 17, 18, 19, 20, 21, 22, - 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, 44, 45, 46, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, 60, 61, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, 887, -1, 889, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, 900, -1, -1, -1, 92, - -1, -1, -1, 96, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 1, 110, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 28, 29, 30, 31, 32, -1, 34, - 35, 36, -1, 38, 39, 40, 41, 42, 43, -1, - 45, -1, 47, -1, 49, 50, 51, 52, 53, 54, - -1, 56, 57, 58, -1, -1, 61, -1, -1, -1, - 985, -1, 67, -1, -1, 70, -1, -1, -1, -1, - -1, -1, -1, 78, 79, 80, -1, -1, -1, -1, - 85, 86, 87, -1, -1, 90, -1, 92, 93, -1, - 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, - 11, 12, 13, 14, -1, 110, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 28, 29, 30, - 31, 32, -1, 34, 35, 36, 1051, 38, 39, 40, - 41, 42, 43, -1, 45, -1, -1, -1, 49, 50, - 51, 52, 53, 54, -1, 56, 57, -1, -1, -1, - 61, -1, -1, -1, -1, -1, 67, -1, -1, 70, - -1, -1, -1, -1, -1, -1, -1, 78, 79, 80, - -1, -1, -1, -1, 85, 86, 87, -1, -1, -1, - -1, 92, 1107, 1108, -1, 1110, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 108, -1, 110, - 1, -1, 3, 4, 5, 6, 7, 8, 9, 10, - 11, -1, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 28, 29, 30, - 31, 32, -1, 34, 35, 36, -1, 38, 39, 40, - 41, 42, 43, -1, 45, 1170, -1, -1, 49, 50, - 51, 52, 53, 54, -1, 56, 57, 58, -1, 60, - 61, -1, -1, -1, -1, -1, 67, -1, -1, 70, - -1, -1, -1, -1, -1, -1, -1, 78, 79, 80, - -1, -1, 1207, -1, 85, 86, 87, -1, -1, -1, - -1, 92, -1, -1, -1, -1, -1, 1222, 1, 1224, - 3, 4, 5, 6, -1, 8, 9, 10, 11, 110, - 13, 14, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, -1, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, -1, 61, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, -1, 92, - 93, 1, -1, 3, 4, 5, 6, -1, 8, 9, - 10, 11, -1, 13, 14, -1, 109, 110, -1, -1, - -1, -1, -1, 1338, -1, -1, -1, -1, 28, 29, - 30, -1, 32, -1, 34, 35, 36, -1, 38, 39, - 40, 41, 42, 43, -1, 45, -1, -1, -1, 49, - 50, 51, 52, 53, 54, -1, 56, 57, 58, -1, - -1, 61, -1, -1, -1, -1, -1, 67, -1, -1, - 70, -1, -1, -1, -1, -1, -1, -1, 78, 79, - 80, -1, -1, -1, -1, 85, 86, 87, -1, -1, - -1, -1, 92, 93, 1, -1, 3, 4, 5, 6, - -1, 8, 9, 10, 11, -1, 13, 14, -1, -1, - 110, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, -1, -1, -1, 1, 92, 3, 4, 5, 6, - -1, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, 109, 110, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, -1, -1, -1, 1, 92, 3, 4, 5, 6, - -1, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, 109, 110, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, 58, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, -1, -1, -1, -1, 92, -1, -1, 1, -1, - 3, 4, 5, 6, 101, 8, 9, 10, 11, -1, - 13, 14, -1, 110, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, -1, 61, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, 1, 92, - 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, - 13, 14, -1, -1, -1, -1, -1, 110, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, -1, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, 58, -1, -1, 61, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, 1, 92, - 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, - 13, 14, -1, -1, -1, -1, -1, 110, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, -1, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, -1, -1, -1, 61, 62, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, 1, 92, - 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, - 13, 14, -1, -1, -1, -1, -1, 110, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, -1, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, -1, -1, 60, 61, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, -1, 1, 92, - 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, - 13, 14, -1, -1, -1, -1, -1, 110, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, -1, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, -1, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, -1, -1, -1, 61, -1, - -1, -1, -1, -1, 67, 1, -1, 70, 4, 5, - -1, -1, 8, 9, -1, 78, 79, 80, 14, -1, - -1, -1, 85, 86, 87, -1, -1, -1, -1, 92, - -1, -1, 28, -1, 30, -1, -1, -1, -1, -1, - 36, -1, 38, 39, -1, 108, -1, 110, -1, 45, - -1, 47, -1, -1, -1, -1, -1, -1, 54, -1, - 56, 57, -1, 59, -1, -1, -1, 63, 64, 65, - 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, -1, 84, 85, - 86, 87, -1, -1, -1, -1, -1, 93, 94, 1, - -1, 3, 4, 5, 6, -1, 8, 9, 10, 11, - -1, 13, 14, -1, 110, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 28, 29, 30, -1, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, -1, -1, -1, 1, - 92, 3, 4, 5, 6, -1, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, -1, 110, -1, - -1, -1, -1, -1, -1, -1, 28, 29, 30, -1, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, -1, -1, -1, 1, - 92, 3, 4, 5, 6, -1, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, -1, 110, -1, - -1, -1, -1, -1, -1, -1, 28, 29, 30, -1, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, 3, 4, 5, 6, - 92, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, 1, 70, 3, 4, 5, 6, 7, 8, - 9, 78, 79, 80, -1, 14, -1, -1, 85, 86, - 87, -1, -1, -1, -1, 92, -1, -1, -1, 28, - -1, 30, 31, 32, -1, -1, -1, 36, 37, -1, - -1, -1, 41, 110, 111, -1, 45, 46, -1, 48, - -1, -1, -1, -1, -1, 54, -1, 56, 57, -1, - -1, 60, -1, 62, -1, -1, -1, -1, -1, -1, - -1, 70, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 80, -1, -1, -1, -1, 85, -1, -1, -1, - -1, -1, -1, 92, -1, -1, -1, 3, 4, 5, - 6, 7, 8, 9, 10, 11, -1, 13, 14, 15, - 109, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 31, 32, -1, 34, 35, - 36, -1, 38, 39, 40, 41, 42, 43, 44, 45, - 46, -1, -1, 49, 50, 51, 52, 53, 54, -1, - 56, 57, 58, -1, 60, 61, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, -1, -1, - -1, -1, 78, 79, 80, -1, -1, -1, -1, 85, - 86, 87, -1, -1, -1, -1, 92, -1, -1, -1, - 96, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 109, 110, 3, 4, 5, 6, 7, - 8, 9, 10, 11, -1, 13, 14, 15, -1, 17, - 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, - 28, 29, 30, 31, 32, -1, 34, 35, 36, -1, - 38, 39, 40, 41, 42, 43, 44, 45, 46, -1, - -1, 49, 50, 51, 52, 53, 54, -1, 56, 57, - 58, -1, 60, 61, -1, -1, -1, -1, -1, 67, - -1, -1, 70, -1, -1, -1, -1, -1, -1, -1, - 78, 79, 80, -1, -1, -1, -1, 85, 86, 87, - -1, -1, -1, -1, 92, -1, -1, -1, 96, 3, - 4, 5, 6, 7, 8, 9, 10, 11, -1, 13, - 14, 15, 110, 17, 18, 19, 20, 21, 22, 23, - 24, 25, 26, 27, 28, 29, 30, 31, 32, -1, - 34, 35, 36, -1, 38, 39, 40, 41, 42, 43, - 44, 45, 46, -1, -1, 49, 50, 51, 52, 53, - 54, -1, 56, 57, 58, -1, 60, 61, -1, -1, - -1, -1, -1, 67, -1, -1, 70, -1, -1, -1, - -1, -1, -1, -1, 78, 79, 80, -1, -1, -1, - -1, 85, 86, 87, -1, -1, -1, -1, 92, -1, - -1, -1, 96, 3, 4, 5, 6, 7, 8, 9, - 10, 11, -1, 13, 14, 15, 110, 17, 18, 19, - 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, - 30, 31, 32, -1, 34, 35, 36, -1, 38, 39, - 40, 41, 42, 43, 44, 45, 46, -1, -1, 49, - 50, 51, 52, 53, 54, -1, 56, 57, -1, -1, - 60, 61, -1, -1, -1, -1, -1, 67, -1, -1, - 70, -1, -1, -1, -1, -1, -1, -1, 78, 79, - 80, -1, -1, -1, -1, 85, 86, 87, -1, -1, - -1, -1, 92, -1, -1, -1, 96, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, -1, - 110, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 28, 29, 30, 31, 32, -1, 34, 35, - 36, -1, 38, 39, 40, 41, 42, 43, -1, 45, - -1, 47, -1, 49, 50, 51, 52, 53, 54, -1, - 56, 57, -1, -1, -1, 61, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, -1, -1, - -1, -1, 78, 79, 80, -1, -1, -1, -1, 85, - 86, 87, -1, -1, 90, -1, 92, 93, 3, 4, - 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, - -1, -1, -1, -1, 110, -1, -1, -1, -1, -1, - -1, -1, -1, 28, 29, 30, 31, 32, -1, 34, - 35, 36, -1, 38, 39, 40, 41, 42, 43, -1, - 45, -1, 47, -1, 49, 50, 51, 52, 53, 54, - -1, 56, 57, -1, -1, -1, 61, -1, -1, -1, - -1, -1, 67, -1, -1, 70, -1, -1, -1, -1, - -1, -1, -1, 78, 79, 80, -1, -1, -1, -1, - 85, 86, 87, -1, -1, 90, -1, 92, 93, 3, - 4, 5, 6, -1, 8, 9, 10, 11, -1, 13, - 14, -1, -1, -1, -1, 110, -1, -1, -1, -1, - -1, -1, -1, -1, 28, 29, 30, 31, 32, -1, - 34, 35, 36, -1, 38, 39, 40, 41, 42, 43, - -1, 45, -1, 47, -1, 49, 50, 51, 52, 53, - 54, -1, 56, 57, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 67, -1, -1, 70, -1, -1, -1, - -1, -1, -1, -1, 78, 79, 80, -1, -1, -1, - -1, 85, 86, 87, -1, -1, 90, -1, 92, 93, - 3, 4, 5, 6, -1, 8, 9, 10, 11, -1, - 13, 14, -1, -1, -1, -1, 110, -1, -1, -1, - -1, -1, -1, -1, -1, 28, 29, 30, 31, 32, - -1, 34, 35, 36, -1, 38, 39, 40, 41, 42, - 43, -1, 45, -1, 47, -1, 49, 50, 51, 52, - 53, 54, -1, 56, 57, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 67, -1, -1, 70, -1, -1, - -1, -1, -1, -1, -1, 78, 79, 80, -1, -1, - -1, -1, 85, 86, 87, -1, -1, 90, -1, 92, - 93, 3, 4, 5, 6, -1, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, 110, -1, -1, - -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, 3, 4, 5, 6, - 92, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, 60, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, -1, -1, -1, -1, 92, 3, 4, 5, 6, - 7, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, 110, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, 3, 4, 5, 6, 92, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 110, -1, -1, 28, 29, 30, 31, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, 3, 4, 5, 6, - 92, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, 3, 4, 5, 6, 92, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 110, -1, -1, 28, 29, 30, -1, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, -1, -1, -1, 61, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, 3, 4, 5, 6, - 92, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, -1, 61, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, 3, 4, 5, 6, 92, 8, 9, 10, 11, - -1, 13, 14, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 110, -1, -1, 28, 29, 30, -1, - 32, -1, 34, 35, 36, -1, 38, 39, 40, 41, - 42, 43, -1, 45, -1, -1, -1, 49, 50, 51, - 52, 53, 54, -1, 56, 57, 58, -1, -1, -1, - -1, -1, -1, -1, -1, 67, -1, -1, 70, -1, - -1, -1, -1, -1, -1, -1, 78, 79, 80, -1, - -1, -1, -1, 85, 86, 87, 3, 4, 5, 6, - 92, 8, 9, 10, 11, -1, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 110, -1, - -1, 28, 29, 30, -1, 32, -1, 34, 35, 36, - -1, 38, 39, 40, 41, 42, 43, -1, 45, -1, - -1, -1, 49, 50, 51, 52, 53, 54, -1, 56, - 57, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 67, -1, -1, 70, -1, -1, -1, -1, -1, -1, - -1, 78, 79, 80, -1, -1, -1, -1, 85, 86, - 87, -1, -1, -1, -1, 92, 93, 3, 4, 5, - 6, -1, 8, 9, 10, 11, -1, 13, 14, -1, - -1, -1, -1, 110, -1, -1, -1, -1, -1, -1, - -1, -1, 28, 29, 30, 31, 32, -1, 34, 35, - 36, -1, 38, 39, 40, 41, 42, 43, -1, 45, - -1, -1, -1, 49, 50, 51, 52, 53, 54, -1, - 56, 57, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, -1, -1, - -1, -1, 78, 79, 80, -1, -1, -1, -1, 85, - 86, 87, 3, 4, 5, 6, 92, 8, 9, 10, - 11, -1, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 110, -1, -1, 28, 29, 30, - -1, 32, -1, 34, 35, 36, -1, 38, 39, 40, - 41, 42, 43, -1, 45, -1, -1, -1, 49, 50, - 51, 52, 53, 54, -1, 56, 57, -1, -1, -1, - 61, -1, -1, -1, -1, -1, 67, -1, -1, 70, - -1, -1, -1, -1, -1, -1, -1, 78, 79, 80, - -1, -1, -1, -1, 85, 86, 87, 3, 4, 5, - 6, 92, 8, 9, 10, 11, -1, 13, 14, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 110, - -1, -1, 28, 29, 30, 31, 32, -1, 34, 35, - 36, -1, 38, 39, 40, 41, 42, 43, -1, 45, - -1, -1, -1, 49, 50, 51, 52, 53, 54, -1, - 56, 57, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, -1, -1, - -1, -1, 78, 79, 80, -1, -1, -1, -1, 85, - 86, 87, 3, 4, 5, 6, 92, 8, 9, 10, - 11, -1, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 110, -1, -1, 28, 29, 30, - -1, 32, -1, 34, 35, 36, -1, 38, 39, 40, - 41, 42, 43, -1, 45, -1, -1, -1, 49, 50, - 51, 52, 53, 54, -1, 56, 57, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 67, -1, -1, 70, - -1, -1, -1, -1, -1, -1, -1, 78, 79, 80, - -1, -1, -1, -1, 85, 86, 87, 3, 4, 5, - 6, 92, 8, 9, 10, 11, -1, 13, 14, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 110, - -1, -1, 28, 29, 30, -1, 32, -1, 34, 35, - 36, -1, 38, 39, 40, 41, 42, 43, -1, 45, - -1, -1, -1, 49, 50, 51, 52, 53, 54, -1, - 56, 57, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 67, -1, -1, 70, -1, -1, -1, -1, -1, - -1, -1, 78, 79, 80, -1, -1, -1, -1, 85, - 86, 87, 3, 4, 5, 6, 92, 8, 9, 10, - 11, -1, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 110, -1, -1, 28, 29, 30, - -1, 32, -1, 34, 35, 36, -1, 38, 39, 40, - 41, 42, 43, -1, 45, -1, -1, -1, 49, 50, - 51, 52, 53, 54, -1, 56, 57, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 67, -1, 1, 70, - 3, 4, 5, 6, 7, 8, 9, 78, 79, 80, - -1, 14, -1, -1, 85, 86, 87, -1, -1, -1, - -1, 92, -1, -1, 27, 28, -1, 30, 31, 32, - -1, -1, -1, 36, -1, -1, -1, -1, 41, 110, - -1, 44, 45, 46, -1, 48, -1, -1, -1, -1, - -1, 54, -1, 56, 57, -1, 1, 60, 3, 4, - 5, 6, 7, 8, 9, -1, -1, 70, -1, 14, - -1, -1, -1, -1, -1, -1, -1, 80, -1, -1, - -1, -1, 85, 28, -1, 30, 31, 32, -1, 92, - -1, 36, -1, -1, -1, 98, 41, -1, -1, -1, - 45, -1, -1, 48, -1, -1, -1, -1, -1, 54, - -1, 56, 57, -1, 1, -1, 3, 4, 5, 6, - 7, 8, 9, -1, -1, 70, -1, 14, -1, -1, - -1, -1, -1, -1, -1, 80, -1, -1, -1, -1, - 85, 28, -1, 30, 31, -1, -1, 92, -1, 36, - -1, -1, -1, 98, 41, -1, -1, -1, 45, -1, - -1, 48, -1, -1, -1, -1, -1, 54, -1, 56, - 57, -1, -1, 60, -1, 3, 4, 5, 6, 7, - 8, 9, -1, 70, 12, -1, 14, -1, -1, -1, - -1, -1, -1, 80, -1, -1, -1, -1, 85, -1, - 28, -1, 30, 31, -1, 92, -1, -1, 36, -1, - -1, -1, -1, 41, -1, -1, -1, 45, -1, -1, - -1, -1, -1, -1, -1, -1, 54, -1, 56, 57, - -1, -1, -1, 3, 4, 5, 6, 7, 8, 9, - -1, -1, 70, -1, 14, -1, -1, -1, -1, -1, - -1, -1, 80, -1, -1, -1, -1, 85, 28, -1, - 30, 31, -1, -1, 92, -1, 36, -1, -1, -1, - -1, 41, -1, -1, -1, 45, -1, -1, -1, -1, - -1, -1, -1, -1, 54, -1, 56, 57, -1, -1, - -1, -1, 62, 3, 4, 5, 6, 7, 8, 9, - 70, -1, -1, -1, 14, -1, -1, -1, -1, -1, - 80, -1, -1, -1, -1, 85, -1, -1, 28, -1, - 30, 31, 92, -1, -1, -1, 36, -1, -1, -1, - -1, 41, -1, -1, -1, 45, -1, -1, -1, -1, - -1, -1, -1, -1, 54, -1, 56, 57, -1, -1, - 60, 3, 4, 5, 6, 7, 8, 9, -1, -1, - 70, -1, 14, -1, -1, -1, -1, -1, -1, -1, - 80, -1, -1, -1, -1, 85, 28, -1, 30, 31, - -1, -1, 92, -1, 36, -1, -1, -1, -1, 41, - -1, -1, -1, 45, -1, -1, -1, -1, -1, -1, - -1, -1, 54, -1, 56, 57, -1, -1, -1, 3, - 4, 5, 6, 7, 8, 9, -1, -1, 70, -1, - 14, -1, -1, -1, -1, -1, -1, -1, 80, -1, - -1, -1, -1, 85, 28, -1, 30, 31, -1, -1, - 92, -1, 36, -1, -1, -1, -1, 41, -1, -1, - -1, 45, -1, -1, -1, -1, -1, -1, -1, -1, - 54, -1, 56, 57, -1, -1, -1, 31, -1, -1, - -1, -1, -1, -1, -1, -1, 70, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 80, -1, -1, -1, - -1, 85, -1, -1, -1, -1, -1, -1, 92, 63, - 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, - 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 84, 4, 5, -1, 7, 8, 9, -1, -1, 12, - -1, 14, -1, -1, 4, 5, -1, 7, 8, 9, - -1, -1, 12, -1, 14, 28, -1, 30, 31, -1, - -1, -1, -1, 36, -1, -1, -1, -1, 28, -1, - 30, 31, 45, -1, -1, -1, 36, -1, -1, -1, - -1, 54, -1, 56, 57, 45, -1, -1, -1, -1, - -1, -1, -1, -1, 54, -1, 56, 57, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, -1, -1, -1, -1, 111, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 59, -1, -1, 107, 63, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 82, 83, 84, 62, 63, 64, - 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 63, 64, 65, 66, 67, 68, 69, 70, - 71, 72, 73, -1, 75, 76, 77, 78, 79, 80, - 81, 82, 83, 84, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 68, 69, 70, 71, 72, 73, 74, 75, - 76, 77, 78, 79, 80, 81, 82, 83, 84, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 70, 71, 72, 73, 74, - 75, 76, 77, 78, 79, 80, 81, 82, 83, 84 -}; - -/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing - symbol of state STATE-NUM. */ -static const yytype_uint16 yystos[] = -{ - 0, 113, 114, 115, 0, 121, 122, 121, 1, 3, - 4, 5, 6, 7, 8, 9, 14, 27, 28, 30, - 31, 32, 36, 41, 44, 45, 46, 48, 54, 56, - 57, 60, 70, 80, 85, 92, 98, 119, 120, 123, - 126, 128, 130, 134, 135, 142, 145, 149, 150, 155, - 167, 178, 180, 206, 208, 213, 214, 227, 228, 230, - 231, 233, 237, 245, 248, 249, 262, 269, 270, 271, - 272, 273, 276, 277, 302, 307, 308, 309, 312, 314, - 316, 319, 320, 321, 328, 329, 399, 400, 60, 109, - 73, 54, 73, 54, 73, 73, 48, 3, 4, 5, - 56, 57, 58, 164, 178, 309, 320, 327, 329, 92, - 92, 92, 4, 5, 56, 57, 58, 164, 3, 4, - 5, 56, 57, 178, 322, 323, 324, 325, 329, 4, - 5, 44, 56, 57, 315, 320, 329, 73, 176, 54, - 73, 73, 248, 302, 311, 312, 320, 329, 302, 311, - 393, 70, 80, 92, 206, 211, 212, 214, 248, 313, - 314, 328, 123, 92, 60, 58, 98, 117, 1, 7, - 48, 119, 134, 142, 143, 144, 149, 227, 230, 237, - 262, 107, 148, 120, 238, 25, 147, 158, 159, 60, - 54, 93, 303, 305, 60, 70, 80, 92, 224, 235, - 243, 306, 310, 312, 319, 320, 328, 7, 9, 60, - 150, 233, 236, 244, 248, 312, 7, 8, 9, 229, - 232, 234, 248, 262, 59, 60, 249, 7, 8, 9, - 36, 58, 103, 104, 105, 164, 166, 178, 179, 248, - 320, 329, 58, 62, 274, 275, 58, 283, 9, 233, - 329, 238, 5, 48, 80, 180, 206, 209, 213, 319, - 321, 301, 309, 319, 320, 1, 38, 39, 47, 59, - 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 84, 85, 86, 87, 93, 94, 110, 231, 233, 302, - 373, 73, 3, 9, 10, 11, 13, 29, 34, 35, - 38, 39, 40, 42, 43, 49, 50, 51, 52, 53, - 56, 57, 61, 67, 70, 78, 79, 80, 85, 86, - 87, 92, 110, 119, 183, 184, 185, 186, 198, 203, - 204, 205, 206, 215, 217, 218, 219, 220, 222, 226, - 231, 233, 302, 316, 317, 318, 320, 329, 183, 183, - 207, 176, 109, 264, 58, 48, 309, 319, 187, 196, - 205, 226, 187, 226, 92, 125, 58, 63, 54, 54, - 54, 54, 54, 54, 3, 4, 5, 48, 56, 57, - 164, 178, 325, 326, 323, 131, 4, 5, 206, 209, - 210, 210, 315, 74, 136, 150, 227, 230, 233, 312, - 184, 183, 312, 311, 320, 311, 4, 5, 164, 178, - 211, 302, 313, 211, 302, 313, 211, 108, 56, 57, - 70, 80, 92, 206, 212, 108, 301, 220, 114, 116, - 48, 145, 149, 143, 117, 148, 235, 236, 60, 60, - 92, 247, 248, 3, 1, 62, 96, 146, 160, 221, - 363, 47, 63, 92, 254, 60, 111, 303, 304, 47, - 92, 301, 302, 306, 302, 306, 70, 80, 92, 306, - 328, 238, 59, 60, 93, 305, 319, 301, 229, 232, - 59, 60, 238, 7, 234, 248, 229, 234, 224, 239, - 73, 164, 179, 164, 320, 62, 278, 278, 284, 285, - 232, 246, 47, 92, 6, 164, 326, 400, 47, 92, - 9, 311, 5, 80, 180, 93, 93, 62, 111, 232, - 70, 80, 320, 328, 398, 207, 92, 9, 92, 198, - 233, 92, 198, 204, 204, 92, 73, 73, 73, 73, - 205, 164, 204, 204, 204, 1, 70, 80, 92, 187, - 206, 211, 216, 226, 204, 74, 76, 182, 59, 204, - 58, 92, 198, 63, 64, 65, 66, 67, 68, 69, - 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 81, 82, 83, 84, 47, 92, 47, 86, 87, - 91, 92, 93, 94, 58, 92, 201, 300, 373, 93, - 204, 11, 1, 8, 48, 85, 209, 210, 317, 320, - 329, 47, 70, 80, 90, 92, 93, 203, 225, 328, - 332, 333, 92, 225, 332, 320, 329, 332, 47, 92, - 3, 39, 208, 218, 316, 329, 400, 182, 182, 183, - 150, 227, 233, 312, 164, 298, 299, 109, 263, 164, - 108, 59, 59, 108, 108, 108, 7, 8, 9, 164, - 250, 251, 252, 116, 124, 127, 326, 73, 54, 133, - 210, 315, 329, 45, 135, 137, 139, 140, 141, 226, - 228, 230, 231, 233, 269, 302, 390, 392, 171, 224, - 60, 170, 182, 182, 311, 311, 108, 211, 311, 108, - 109, 118, 118, 144, 149, 60, 60, 220, 161, 364, - 1, 58, 339, 340, 1, 58, 205, 255, 196, 197, - 205, 187, 111, 1, 12, 197, 226, 233, 383, 384, - 388, 389, 390, 392, 61, 395, 306, 306, 302, 302, - 108, 301, 241, 247, 239, 111, 304, 301, 306, 229, - 239, 241, 238, 183, 164, 393, 1, 5, 46, 60, - 62, 119, 128, 135, 150, 156, 157, 180, 227, 230, - 287, 288, 289, 312, 37, 109, 286, 241, 301, 151, - 73, 73, 54, 73, 301, 153, 47, 92, 47, 92, - 111, 111, 301, 301, 301, 183, 197, 226, 92, 225, - 226, 187, 226, 226, 233, 226, 226, 226, 108, 211, - 108, 108, 340, 108, 185, 3, 4, 5, 56, 57, - 93, 164, 255, 256, 226, 205, 205, 1, 187, 378, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 205, - 205, 205, 205, 205, 205, 205, 205, 205, 205, 197, - 197, 187, 200, 200, 92, 300, 47, 63, 92, 202, - 70, 80, 93, 328, 330, 331, 111, 187, 54, 164, - 8, 47, 92, 47, 92, 47, 92, 302, 332, 302, - 332, 226, 332, 384, 111, 304, 92, 301, 47, 301, - 301, 47, 92, 93, 70, 80, 92, 197, 203, 211, - 248, 320, 329, 320, 197, 181, 181, 182, 175, 224, - 60, 174, 63, 59, 268, 298, 1, 205, 1, 205, - 59, 108, 92, 109, 116, 133, 54, 183, 60, 210, - 315, 138, 164, 269, 59, 74, 63, 63, 70, 80, - 92, 224, 328, 332, 312, 320, 224, 224, 138, 164, - 63, 177, 169, 168, 177, 181, 108, 60, 148, 118, - 118, 108, 3, 4, 5, 47, 56, 57, 92, 162, - 163, 165, 178, 307, 322, 329, 146, 340, 341, 109, - 256, 108, 108, 108, 12, 59, 62, 92, 108, 12, - 59, 62, 12, 312, 391, 392, 394, 63, 385, 47, - 92, 63, 111, 395, 247, 74, 7, 30, 37, 279, - 280, 281, 282, 307, 322, 47, 92, 205, 288, 227, - 288, 238, 238, 25, 58, 62, 96, 47, 92, 3, - 4, 62, 150, 224, 290, 292, 294, 295, 306, 312, - 320, 329, 150, 156, 291, 295, 312, 288, 60, 109, - 238, 62, 247, 287, 395, 383, 183, 183, 183, 395, - 383, 301, 152, 301, 154, 398, 398, 398, 182, 108, - 108, 108, 108, 108, 74, 74, 74, 74, 108, 108, - 205, 62, 59, 267, 108, 62, 108, 108, 111, 197, - 197, 226, 200, 202, 255, 197, 233, 301, 301, 187, - 301, 93, 204, 111, 85, 73, 47, 197, 197, 197, - 332, 332, 108, 108, 111, 395, 395, 332, 301, 383, - 111, 304, 108, 108, 320, 108, 177, 173, 172, 177, - 205, 299, 109, 268, 251, 108, 3, 197, 109, 60, - 182, 138, 141, 226, 185, 302, 302, 70, 80, 92, - 319, 320, 328, 301, 205, 177, 177, 148, 197, 1, - 59, 47, 92, 47, 92, 47, 92, 340, 33, 109, - 193, 336, 337, 338, 59, 109, 70, 80, 92, 206, - 211, 316, 385, 63, 386, 226, 396, 397, 242, 63, - 181, 393, 92, 393, 59, 7, 37, 393, 301, 383, - 60, 247, 247, 301, 383, 62, 62, 205, 238, 59, - 238, 238, 320, 238, 59, 247, 265, 108, 182, 182, - 182, 108, 395, 383, 395, 383, 92, 92, 92, 92, - 111, 255, 164, 255, 109, 205, 109, 108, 108, 199, - 226, 108, 108, 330, 330, 111, 330, 304, 204, 8, - 183, 108, 108, 108, 301, 395, 108, 111, 177, 177, - 109, 59, 108, 108, 302, 302, 319, 301, 108, 163, - 197, 197, 197, 365, 164, 253, 1, 3, 4, 5, - 15, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 44, 46, 57, 60, 96, 119, 120, 126, 129, - 130, 187, 223, 227, 230, 233, 334, 335, 340, 342, - 347, 348, 366, 375, 338, 109, 211, 108, 255, 101, - 255, 387, 59, 108, 255, 240, 187, 226, 393, 393, - 393, 281, 395, 108, 254, 254, 395, 108, 205, 205, - 247, 247, 3, 4, 62, 293, 296, 297, 306, 312, - 247, 247, 5, 247, 297, 254, 261, 301, 301, 108, - 108, 187, 187, 187, 187, 255, 62, 93, 202, 199, - 111, 47, 182, 395, 301, 197, 108, 108, 108, 95, - 369, 370, 59, 60, 60, 109, 62, 62, 62, 343, - 350, 352, 354, 358, 205, 62, 60, 60, 60, 187, - 80, 164, 164, 56, 132, 329, 62, 367, 223, 9, - 377, 60, 60, 224, 235, 60, 236, 312, 92, 235, - 1, 109, 335, 347, 16, 109, 347, 108, 396, 255, - 108, 108, 280, 301, 301, 247, 247, 254, 62, 62, - 205, 238, 238, 254, 254, 254, 1, 102, 260, 266, - 395, 395, 301, 301, 108, 108, 108, 108, 255, 187, - 202, 395, 108, 371, 370, 164, 47, 92, 189, 189, - 340, 345, 346, 92, 92, 12, 62, 362, 60, 187, - 60, 54, 56, 164, 56, 132, 164, 340, 92, 60, - 60, 70, 80, 92, 60, 109, 349, 395, 395, 205, - 205, 247, 247, 247, 1, 205, 259, 395, 395, 111, - 92, 374, 187, 191, 233, 373, 344, 351, 17, 348, - 58, 223, 376, 378, 191, 205, 360, 347, 60, 54, - 164, 368, 220, 345, 247, 247, 254, 254, 107, 107, - 97, 257, 258, 12, 392, 372, 108, 224, 345, 58, - 194, 348, 353, 193, 355, 60, 108, 62, 347, 369, - 62, 108, 147, 148, 108, 108, 340, 238, 195, 47, - 92, 188, 1, 190, 191, 359, 361, 11, 379, 380, - 381, 60, 1, 146, 363, 247, 193, 187, 60, 60, - 345, 347, 92, 62, 108, 59, 339, 63, 108, 356, - 187, 379, 60, 381, 192, 378, 108, 62, 108, 255, - 108, 11, 382, 60, 357, 59, 108, 194, 11, 60 -}; - -#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 yyerrorlab - - -/* 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); \ - yytoken = YYTRANSLATE (yychar); \ - YYPOPSTACK (1); \ - goto yybackup; \ - } \ - else \ - { \ - yyerror (YY_("syntax error: cannot back up")); \ - YYERROR; \ - } \ -while (YYID (0)) - - -#define YYTERROR 1 -#define YYERRCODE 256 - - -/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. - If N is 0, then set CURRENT to the empty location which ends - the previous symbol: RHS[0] (always defined). */ - -#define YYRHSLOC(Rhs, K) ((Rhs)[K]) -#ifndef YYLLOC_DEFAULT -# define YYLLOC_DEFAULT(Current, Rhs, N) \ - do \ - if (YYID (N)) \ - { \ - (Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ - (Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ - (Current).last_line = YYRHSLOC (Rhs, N).last_line; \ - (Current).last_column = YYRHSLOC (Rhs, N).last_column; \ - } \ - else \ - { \ - (Current).first_line = (Current).last_line = \ - YYRHSLOC (Rhs, 0).last_line; \ - (Current).first_column = (Current).last_column = \ - YYRHSLOC (Rhs, 0).last_column; \ - } \ - while (YYID (0)) -#endif - - -/* YY_LOCATION_PRINT -- Print the location on the stream. - This macro was not mandated originally: define only if we know - we won't break user code: when these are the locations we know. */ - -#ifndef YY_LOCATION_PRINT -# if YYLTYPE_IS_TRIVIAL -# define YY_LOCATION_PRINT(File, Loc) \ - fprintf (File, "%d.%d-%d.%d", \ - (Loc).first_line, (Loc).first_column, \ - (Loc).last_line, (Loc).last_column) -# else -# define YY_LOCATION_PRINT(File, Loc) ((void) 0) -# endif -#endif - - -/* YYLEX -- calling `yylex' with the right arguments. */ - -#ifdef YYLEX_PARAM -# define YYLEX yylex (YYLEX_PARAM) -#else -# define YYLEX yylex () -#endif - -/* Enable debugging if requested. */ -#if YYDEBUG - -# ifndef YYFPRINTF -# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ -# define YYFPRINTF fprintf -# endif - -# define YYDPRINTF(Args) \ -do { \ - if (yydebug) \ - YYFPRINTF Args; \ -} while (YYID (0)) - -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ -do { \ - if (yydebug) \ - { \ - YYFPRINTF (stderr, "%s ", Title); \ - yy_symbol_print (stderr, \ - Type, Value); \ - YYFPRINTF (stderr, "\n"); \ - } \ -} while (YYID (0)) - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_value_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (!yyvaluep) - return; -# ifdef YYPRINT - if (yytype < YYNTOKENS) - YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); -# else - YYUSE (yyoutput); -# endif - switch (yytype) - { - default: - break; - } -} - - -/*--------------------------------. -| Print this symbol on YYOUTPUT. | -`--------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) -#else -static void -yy_symbol_print (yyoutput, yytype, yyvaluep) - FILE *yyoutput; - int yytype; - YYSTYPE const * const yyvaluep; -#endif -{ - if (yytype < YYNTOKENS) - YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); - else - YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); - - yy_symbol_value_print (yyoutput, yytype, yyvaluep); - YYFPRINTF (yyoutput, ")"); -} - -/*------------------------------------------------------------------. -| yy_stack_print -- Print the state stack from its BOTTOM up to its | -| TOP (included). | -`------------------------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) -#else -static void -yy_stack_print (bottom, top) - yytype_int16 *bottom; - yytype_int16 *top; -#endif -{ - YYFPRINTF (stderr, "Stack now"); - for (; bottom <= top; ++bottom) - YYFPRINTF (stderr, " %d", *bottom); - YYFPRINTF (stderr, "\n"); -} - -# define YY_STACK_PRINT(Bottom, Top) \ -do { \ - if (yydebug) \ - yy_stack_print ((Bottom), (Top)); \ -} while (YYID (0)) - - -/*------------------------------------------------. -| Report that the YYRULE is going to be reduced. | -`------------------------------------------------*/ - -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yy_reduce_print (YYSTYPE *yyvsp, int yyrule) -#else -static void -yy_reduce_print (yyvsp, yyrule) - YYSTYPE *yyvsp; - int yyrule; -#endif -{ - int yynrhs = yyr2[yyrule]; - int yyi; - unsigned long int yylno = yyrline[yyrule]; - YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", - yyrule - 1, yylno); - /* The symbols being reduced. */ - for (yyi = 0; yyi < yynrhs; yyi++) - { - fprintf (stderr, " $%d = ", yyi + 1); - yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], - &(yyvsp[(yyi + 1) - (yynrhs)]) - ); - fprintf (stderr, "\n"); - } -} - -# define YY_REDUCE_PRINT(Rule) \ -do { \ - if (yydebug) \ - yy_reduce_print (yyvsp, Rule); \ -} while (YYID (0)) - -/* Nonzero means print parse trace. It is left uninitialized so that - multiple parsers can coexist. */ -int yydebug; -#else /* !YYDEBUG */ -# define YYDPRINTF(Args) -# define YY_SYMBOL_PRINT(Title, Type, Value, Location) -# define YY_STACK_PRINT(Bottom, Top) -# define YY_REDUCE_PRINT(Rule) -#endif /* !YYDEBUG */ - - -/* YYINITDEPTH -- initial size of the parser's stacks. */ -#ifndef YYINITDEPTH -# define YYINITDEPTH 200 -#endif - -/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only - if the built-in stack extension method is used). - - Do not make this value too large; the results are undefined if - YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) - evaluated with infinite-precision integer arithmetic. */ - -#ifndef YYMAXDEPTH -# define YYMAXDEPTH 10000 -#endif - - - -#if YYERROR_VERBOSE - -# ifndef yystrlen -# if defined __GLIBC__ && defined _STRING_H -# define yystrlen strlen -# else -/* Return the length of YYSTR. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static YYSIZE_T -yystrlen (const char *yystr) -#else -static YYSIZE_T -yystrlen (yystr) - const char *yystr; -#endif -{ - YYSIZE_T yylen; - for (yylen = 0; yystr[yylen]; yylen++) - continue; - return yylen; -} -# endif -# endif - -# ifndef yystpcpy -# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE -# define yystpcpy stpcpy -# else -/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in - YYDEST. */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static char * -yystpcpy (char *yydest, const char *yysrc) -#else -static char * -yystpcpy (yydest, yysrc) - char *yydest; - const char *yysrc; -#endif -{ - char *yyd = yydest; - const char *yys = yysrc; - - while ((*yyd++ = *yys++) != '\0') - continue; - - return yyd - 1; -} -# endif -# endif - -# ifndef yytnamerr -/* Copy to YYRES the contents of YYSTR after stripping away unnecessary - quotes and backslashes, so that it's suitable for yyerror. The - heuristic is that double-quoting is unnecessary unless the string - contains an apostrophe, a comma, or backslash (other than - backslash-backslash). YYSTR is taken from yytname. If YYRES is - null, do not copy; instead, return the length of what the result - would have been. */ -static YYSIZE_T -yytnamerr (char *yyres, const char *yystr) -{ - if (*yystr == '"') - { - YYSIZE_T yyn = 0; - char const *yyp = yystr; - - for (;;) - switch (*++yyp) - { - case '\'': - case ',': - goto do_not_strip_quotes; - - case '\\': - if (*++yyp != '\\') - goto do_not_strip_quotes; - /* Fall through. */ - default: - if (yyres) - yyres[yyn] = *yyp; - yyn++; - break; - - case '"': - if (yyres) - yyres[yyn] = '\0'; - return yyn; - } - do_not_strip_quotes: ; - } - - if (! yyres) - return yystrlen (yystr); - - return yystpcpy (yyres, yystr) - yyres; -} -# endif - -/* Copy into YYRESULT an error message about the unexpected token - YYCHAR while in state YYSTATE. Return the number of bytes copied, - including the terminating null byte. If YYRESULT is null, do not - copy anything; just return the number of bytes that would be - copied. As a special case, return 0 if an ordinary "syntax error" - message will do. Return YYSIZE_MAXIMUM if overflow occurs during - size calculation. */ -static YYSIZE_T -yysyntax_error (char *yyresult, int yystate, int yychar) -{ - int yyn = yypact[yystate]; - - if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) - return 0; - else - { - int yytype = YYTRANSLATE (yychar); - YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); - YYSIZE_T yysize = yysize0; - YYSIZE_T yysize1; - int yysize_overflow = 0; - enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; - char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; - int yyx; - -# if 0 - /* This is so xgettext sees the translatable formats that are - constructed on the fly. */ - YY_("syntax error, unexpected %s"); - YY_("syntax error, unexpected %s, expecting %s"); - YY_("syntax error, unexpected %s, expecting %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s"); - YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); -# endif - char *yyfmt; - char const *yyf; - static char const yyunexpected[] = "syntax error, unexpected %s"; - static char const yyexpecting[] = ", expecting %s"; - static char const yyor[] = " or %s"; - char yyformat[sizeof yyunexpected - + sizeof yyexpecting - 1 - + ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) - * (sizeof yyor - 1))]; - char const *yyprefix = yyexpecting; - - /* Start YYX at -YYN if negative to avoid negative indexes in - YYCHECK. */ - int yyxbegin = yyn < 0 ? -yyn : 0; - - /* Stay within bounds of both yycheck and yytname. */ - int yychecklim = YYLAST - yyn + 1; - int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; - int yycount = 1; - - yyarg[0] = yytname[yytype]; - yyfmt = yystpcpy (yyformat, yyunexpected); - - for (yyx = yyxbegin; yyx < yyxend; ++yyx) - if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) - { - if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) - { - yycount = 1; - yysize = yysize0; - yyformat[sizeof yyunexpected - 1] = '\0'; - break; - } - yyarg[yycount++] = yytname[yyx]; - yysize1 = yysize + yytnamerr (0, yytname[yyx]); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - yyfmt = yystpcpy (yyfmt, yyprefix); - yyprefix = yyor; - } - - yyf = YY_(yyformat); - yysize1 = yysize + yystrlen (yyf); - yysize_overflow |= (yysize1 < yysize); - yysize = yysize1; - - if (yysize_overflow) - return YYSIZE_MAXIMUM; - - if (yyresult) - { - /* Avoid sprintf, as that infringes on the user's name space. - Don't have undefined behavior even if the translation - produced a string with the wrong number of "%s"s. */ - char *yyp = yyresult; - int yyi = 0; - while ((*yyp = *yyf) != '\0') - { - if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) - { - yyp += yytnamerr (yyp, yyarg[yyi++]); - yyf += 2; - } - else - { - yyp++; - yyf++; - } - } - } - return yysize; - } -} -#endif /* YYERROR_VERBOSE */ - - -/*-----------------------------------------------. -| Release the memory associated to this symbol. | -`-----------------------------------------------*/ - -/*ARGSUSED*/ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -static void -yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) -#else -static void -yydestruct (yymsg, yytype, yyvaluep) - const char *yymsg; - int yytype; - YYSTYPE *yyvaluep; -#endif -{ - YYUSE (yyvaluep); - - if (!yymsg) - yymsg = "Deleting"; - YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); - - switch (yytype) - { - - default: - break; - } -} - - -/* Prevent warnings from -Wmissing-prototypes. */ - -#ifdef YYPARSE_PARAM -#if defined __STDC__ || defined __cplusplus -int yyparse (void *YYPARSE_PARAM); -#else -int yyparse (); -#endif -#else /* ! YYPARSE_PARAM */ -#if defined __STDC__ || defined __cplusplus -int yyparse (void); -#else -int yyparse (); -#endif -#endif /* ! YYPARSE_PARAM */ - - - -/* The look-ahead symbol. */ -int yychar; - -/* The semantic value of the look-ahead symbol. */ -YYSTYPE yylval; - -/* Number of syntax errors so far. */ -int yynerrs; - - - -/*----------. -| yyparse. | -`----------*/ - -#ifdef YYPARSE_PARAM -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void *YYPARSE_PARAM) -#else -int -yyparse (YYPARSE_PARAM) - void *YYPARSE_PARAM; -#endif -#else /* ! YYPARSE_PARAM */ -#if (defined __STDC__ || defined __C99__FUNC__ \ - || defined __cplusplus || defined _MSC_VER) -int -yyparse (void) -#else -int -yyparse () - -#endif -#endif -{ - - int yystate; - int yyn; - int yyresult; - /* Number of tokens to shift before error messages enabled. */ - int yyerrstatus; - /* Look-ahead token as an internal (translated) token number. */ - int yytoken = 0; -#if YYERROR_VERBOSE - /* Buffer for error messages, and its allocated size. */ - char yymsgbuf[128]; - char *yymsg = yymsgbuf; - YYSIZE_T yymsg_alloc = sizeof yymsgbuf; -#endif - - /* Three stacks and their tools: - `yyss': related to states, - `yyvs': related to semantic values, - `yyls': related to locations. - - Refer to the stacks thru separate pointers, to allow yyoverflow - to reallocate them elsewhere. */ - - /* The state stack. */ - yytype_int16 yyssa[YYINITDEPTH]; - yytype_int16 *yyss = yyssa; - yytype_int16 *yyssp; - - /* The semantic value stack. */ - YYSTYPE yyvsa[YYINITDEPTH]; - YYSTYPE *yyvs = yyvsa; - YYSTYPE *yyvsp; - - - -#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) - - YYSIZE_T yystacksize = YYINITDEPTH; - - /* The variables used to return semantic value and location from the - action routines. */ - YYSTYPE yyval; - - - /* The number of symbols on the RHS of the reduced rule. - Keep to zero when no symbol should be popped. */ - int yylen = 0; - - YYDPRINTF ((stderr, "Starting parse\n")); - - 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; - yyvsp = yyvs; - - goto yysetstate; - -/*------------------------------------------------------------. -| yynewstate -- Push a new state, which is found in yystate. | -`------------------------------------------------------------*/ - yynewstate: - /* In all cases, when you get here, the value and location stacks - have just been pushed. So pushing a state here evens the stacks. */ - yyssp++; - - yysetstate: - *yyssp = yystate; - - if (yyss + yystacksize - 1 <= yyssp) - { - /* Get the current used size of the three stacks, in elements. */ - YYSIZE_T yysize = yyssp - yyss + 1; - -#ifdef yyoverflow - { - /* 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; - yytype_int16 *yyss1 = yyss; - - - /* Each stack pointer address is followed by the size of the - data in use in that stack, in bytes. This used to be a - conditional around just the two extra args, but that might - be undefined if yyoverflow is a macro. */ - yyoverflow (YY_("memory exhausted"), - &yyss1, yysize * sizeof (*yyssp), - &yyvs1, yysize * sizeof (*yyvsp), - - &yystacksize); - - yyss = yyss1; - yyvs = yyvs1; - } -#else /* no yyoverflow */ -# ifndef YYSTACK_RELOCATE - goto yyexhaustedlab; -# else - /* Extend the stack our own way. */ - if (YYMAXDEPTH <= yystacksize) - goto yyexhaustedlab; - yystacksize *= 2; - if (YYMAXDEPTH < yystacksize) - yystacksize = YYMAXDEPTH; - - { - yytype_int16 *yyss1 = yyss; - union yyalloc *yyptr = - (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); - if (! yyptr) - goto yyexhaustedlab; - YYSTACK_RELOCATE (yyss); - YYSTACK_RELOCATE (yyvs); - -# undef YYSTACK_RELOCATE - if (yyss1 != yyssa) - YYSTACK_FREE (yyss1); - } -# endif -#endif /* no yyoverflow */ - - yyssp = yyss + yysize - 1; - yyvsp = yyvs + yysize - 1; - - - YYDPRINTF ((stderr, "Stack size increased to %lu\n", - (unsigned long int) yystacksize)); - - if (yyss + yystacksize - 1 <= yyssp) - YYABORT; - } - - YYDPRINTF ((stderr, "Entering state %d\n", yystate)); - - goto yybackup; - -/*-----------. -| yybackup. | -`-----------*/ -yybackup: - - /* Do appropriate processing given the current state. Read a - look-ahead token if we need one and don't already have one. */ - - /* First try to decide what to do without reference to look-ahead token. */ - yyn = yypact[yystate]; - if (yyn == YYPACT_NINF) - goto yydefault; - - /* Not known => get a look-ahead token if don't already have one. */ - - /* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ - if (yychar == YYEMPTY) - { - YYDPRINTF ((stderr, "Reading a token: ")); - yychar = YYLEX; - } - - if (yychar <= YYEOF) - { - yychar = yytoken = YYEOF; - YYDPRINTF ((stderr, "Now at end of input.\n")); - } - else - { - yytoken = YYTRANSLATE (yychar); - YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); - } - - /* If the proper action on seeing token YYTOKEN is to reduce or to - detect an error, take that action. */ - yyn += yytoken; - if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) - goto yydefault; - yyn = yytable[yyn]; - if (yyn <= 0) - { - if (yyn == 0 || yyn == YYTABLE_NINF) - goto yyerrlab; - yyn = -yyn; - goto yyreduce; - } - - if (yyn == YYFINAL) - YYACCEPT; - - /* Count tokens shifted since error; after three, turn off error - status. */ - if (yyerrstatus) - yyerrstatus--; - - /* Shift the look-ahead token. */ - YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); - - /* Discard the shifted token unless it is eof. */ - if (yychar != YYEOF) - yychar = YYEMPTY; - - yystate = yyn; - *++yyvsp = yylval; - - goto yynewstate; - - -/*-----------------------------------------------------------. -| yydefault -- do the default action for the current state. | -`-----------------------------------------------------------*/ -yydefault: - yyn = yydefact[yystate]; - if (yyn == 0) - goto yyerrlab; - goto yyreduce; - - -/*-----------------------------. -| yyreduce -- Do a reduction. | -`-----------------------------*/ -yyreduce: - /* yyn is the number of a rule to reduce with. */ - yylen = yyr2[yyn]; - - /* If YYLEN is nonzero, implement the default value of the action: - `$$ = $1'. - - Otherwise, the following line sets YYVAL to garbage. - This behavior is undocumented and Bison - users should not rely upon it. Assigning to YYVAL - unconditionally makes the parser a bit smaller, and it avoids a - GCC warning that YYVAL may be used uninitialized. */ - yyval = yyvsp[1-yylen]; - - - YY_REDUCE_PRINT (yyn); - switch (yyn) - { - case 3: -#line 340 "../../../gbagnu/gcc/cp/parse.y" - { finish_translation_unit (); ;} - break; - - case 4: -#line 348 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 5: -#line 350 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 6: -#line 352 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 9: -#line 361 "../../../gbagnu/gcc/cp/parse.y" - { have_extern_spec = 1; - used_extern_spec = 0; - (yyval.ttype) = NULL_TREE; ;} - break; - - case 10: -#line 366 "../../../gbagnu/gcc/cp/parse.y" - { have_extern_spec = 0; ;} - break; - - case 11: -#line 371 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = pedantic; - pedantic = 0; ;} - break; - - case 13: -#line 380 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_lang_change) do_pending_lang_change(); ;} - break; - - case 14: -#line 382 "../../../gbagnu/gcc/cp/parse.y" - { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) - pop_everything (); ;} - break; - - case 15: -#line 388 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 16: -#line 390 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 17: -#line 392 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 18: -#line 394 "../../../gbagnu/gcc/cp/parse.y" - { if (TREE_CHAIN ((yyvsp[(3) - (5)].ttype))) (yyvsp[(3) - (5)].ttype) = combine_strings ((yyvsp[(3) - (5)].ttype)); - assemble_asm ((yyvsp[(3) - (5)].ttype)); ;} - break; - - case 19: -#line 397 "../../../gbagnu/gcc/cp/parse.y" - { pop_lang_context (); ;} - break; - - case 20: -#line 399 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); ;} - break; - - case 21: -#line 402 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); ;} - break; - - case 22: -#line 405 "../../../gbagnu/gcc/cp/parse.y" - { push_namespace ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 23: -#line 407 "../../../gbagnu/gcc/cp/parse.y" - { pop_namespace (); ;} - break; - - case 24: -#line 409 "../../../gbagnu/gcc/cp/parse.y" - { push_namespace (NULL_TREE); ;} - break; - - case 25: -#line 411 "../../../gbagnu/gcc/cp/parse.y" - { pop_namespace (); ;} - break; - - case 27: -#line 414 "../../../gbagnu/gcc/cp/parse.y" - { do_toplevel_using_decl ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 29: -#line 417 "../../../gbagnu/gcc/cp/parse.y" - { pedantic = (yyvsp[(1) - (2)].itype); ;} - break; - - case 30: -#line 422 "../../../gbagnu/gcc/cp/parse.y" - { begin_only_namespace_names (); ;} - break; - - case 31: -#line 424 "../../../gbagnu/gcc/cp/parse.y" - { - end_only_namespace_names (); - if (lastiddecl) - (yyvsp[(5) - (6)].ttype) = lastiddecl; - do_namespace_alias ((yyvsp[(2) - (6)].ttype), (yyvsp[(5) - (6)].ttype)); - ;} - break; - - case 32: -#line 434 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 33: -#line 436 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 34: -#line 438 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 35: -#line 443 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 36: -#line 445 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (SCOPE_REF, global_namespace, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 37: -#line 447 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 38: -#line 452 "../../../gbagnu/gcc/cp/parse.y" - { begin_only_namespace_names (); ;} - break; - - case 39: -#line 454 "../../../gbagnu/gcc/cp/parse.y" - { - end_only_namespace_names (); - /* If no declaration was found, the using-directive is - invalid. Since that was not reported, we need the - identifier for the error message. */ - if (TREE_CODE ((yyvsp[(4) - (5)].ttype)) == IDENTIFIER_NODE && lastiddecl) - (yyvsp[(4) - (5)].ttype) = lastiddecl; - do_using_directive ((yyvsp[(4) - (5)].ttype)); - ;} - break; - - case 40: -#line 467 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyval.ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype); - ;} - break; - - case 41: -#line 473 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = (yyvsp[(2) - (3)].ttype); - if (TREE_CODE ((yyval.ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype); - ;} - break; - - case 44: -#line 484 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 45: -#line 486 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 46: -#line 491 "../../../gbagnu/gcc/cp/parse.y" - { push_lang_context ((yyvsp[(1) - (1)].ttype)); ;} - break; - - case 47: -#line 493 "../../../gbagnu/gcc/cp/parse.y" - { if (current_lang_name != (yyvsp[(2) - (2)].ttype)) - cp_error ("use of linkage spec `%D' is different from previous spec `%D'", (yyvsp[(2) - (2)].ttype), current_lang_name); - pop_lang_context (); push_lang_context ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 48: -#line 500 "../../../gbagnu/gcc/cp/parse.y" - { begin_template_parm_list (); ;} - break; - - case 49: -#line 502 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = end_template_parm_list ((yyvsp[(4) - (5)].ttype)); ;} - break; - - case 50: -#line 504 "../../../gbagnu/gcc/cp/parse.y" - { begin_specialization(); - (yyval.ttype) = NULL_TREE; ;} - break; - - case 51: -#line 510 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = process_template_parm (NULL_TREE, (yyvsp[(1) - (1)].ttype)); ;} - break; - - case 52: -#line 512 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = process_template_parm ((yyvsp[(1) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 53: -#line 517 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ttype); ;} - break; - - case 54: -#line 519 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 55: -#line 523 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_template_type_parm ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 56: -#line 525 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_template_type_parm (class_type_node, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 57: -#line 530 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_template_template_parm ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 58: -#line 542 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ttype)); ;} - break; - - case 59: -#line 544 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (groktypename ((yyvsp[(3) - (3)].ftype).t), (yyvsp[(1) - (3)].ttype)); ;} - break; - - case 60: -#line 546 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ftype).t); ;} - break; - - case 61: -#line 548 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].ftype).t); ;} - break; - - case 62: -#line 550 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ttype)); ;} - break; - - case 63: -#line 552 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(3) - (3)].ttype)) != TEMPLATE_DECL - && TREE_CODE ((yyvsp[(3) - (3)].ttype)) != TEMPLATE_TEMPLATE_PARM - && TREE_CODE ((yyvsp[(3) - (3)].ttype)) != TYPE_DECL) - { - error ("invalid default template argument"); - (yyvsp[(3) - (3)].ttype) = error_mark_node; - } - (yyval.ttype) = build_tree_list ((yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].ttype)); - ;} - break; - - case 64: -#line 566 "../../../gbagnu/gcc/cp/parse.y" - { finish_template_decl ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 65: -#line 568 "../../../gbagnu/gcc/cp/parse.y" - { finish_template_decl ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 66: -#line 573 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 67: -#line 575 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 68: -#line 577 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); ;} - break; - - case 69: -#line 579 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); ;} - break; - - case 70: -#line 582 "../../../gbagnu/gcc/cp/parse.y" - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); ;} - break; - - case 71: -#line 585 "../../../gbagnu/gcc/cp/parse.y" - { pedantic = (yyvsp[(1) - (2)].itype); ;} - break; - - case 73: -#line 591 "../../../gbagnu/gcc/cp/parse.y" - {;} - break; - - case 74: -#line 593 "../../../gbagnu/gcc/cp/parse.y" - { note_list_got_semicolon ((yyvsp[(1) - (3)].ftype).t); ;} - break; - - case 75: -#line 595 "../../../gbagnu/gcc/cp/parse.y" - { maybe_process_partial_specialization ((yyvsp[(1) - (2)].ftype).t); - note_got_semicolon ((yyvsp[(1) - (2)].ftype).t); ;} - break; - - case 77: -#line 602 "../../../gbagnu/gcc/cp/parse.y" - {;} - break; - - case 78: -#line 604 "../../../gbagnu/gcc/cp/parse.y" - { note_list_got_semicolon ((yyvsp[(1) - (3)].ftype).t); ;} - break; - - case 79: -#line 606 "../../../gbagnu/gcc/cp/parse.y" - { pedwarn ("empty declaration"); ;} - break; - - case 81: -#line 609 "../../../gbagnu/gcc/cp/parse.y" - { - tree t, attrs; - split_specs_attrs ((yyvsp[(1) - (2)].ftype).t, &t, &attrs); - shadow_tag (t); - note_list_got_semicolon ((yyvsp[(1) - (2)].ftype).t); - ;} - break; - - case 85: -#line 622 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 86: -#line 624 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 1; ;} - break; - - case 92: -#line 640 "../../../gbagnu/gcc/cp/parse.y" - { finish_function (lineno, (int)(yyvsp[(3) - (4)].itype), 0); ;} - break; - - case 93: -#line 642 "../../../gbagnu/gcc/cp/parse.y" - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)(yyvsp[(3) - (3)].itype), nested); - ;} - break; - - case 94: -#line 648 "../../../gbagnu/gcc/cp/parse.y" - { ;} - break; - - case 95: -#line 653 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 96: -#line 655 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(4) - (8)].ttype), (yyvsp[(5) - (8)].ttype), (yyvsp[(7) - (8)].ttype), (yyvsp[(8) - (8)].ttype)); ;} - break; - - case 97: -#line 657 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(1) - (5)].ttype), (yyvsp[(2) - (5)].ttype)); - (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), (yyvsp[(4) - (5)].ttype), (yyvsp[(5) - (5)].ttype)); - ;} - break; - - case 98: -#line 661 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 99: -#line 663 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(5) - (9)].ttype), (yyvsp[(6) - (9)].ttype), (yyvsp[(8) - (9)].ttype), (yyvsp[(9) - (9)].ttype)); ;} - break; - - case 100: -#line 665 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(2) - (6)].ttype), (yyvsp[(3) - (6)].ttype)); - (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), (yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype)); - ;} - break; - - case 101: -#line 669 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 102: -#line 671 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(4) - (8)].ttype), (yyvsp[(5) - (8)].ttype), (yyvsp[(7) - (8)].ttype), (yyvsp[(8) - (8)].ttype)); ;} - break; - - case 103: -#line 673 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(1) - (5)].ttype), (yyvsp[(2) - (5)].ttype)); - (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), (yyvsp[(4) - (5)].ttype), (yyvsp[(5) - (5)].ttype)); - ;} - break; - - case 104: -#line 677 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 105: -#line 679 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(5) - (9)].ttype), (yyvsp[(6) - (9)].ttype), (yyvsp[(8) - (9)].ttype), (yyvsp[(9) - (9)].ttype)); ;} - break; - - case 106: -#line 681 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_constructor_declarator ((yyvsp[(2) - (6)].ttype), (yyvsp[(3) - (6)].ttype)); - (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), (yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype)); - ;} - break; - - case 107: -#line 688 "../../../gbagnu/gcc/cp/parse.y" - { if (!begin_function_definition ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype))) - YYERROR1; ;} - break; - - case 108: -#line 691 "../../../gbagnu/gcc/cp/parse.y" - { if (!begin_function_definition ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype))) - YYERROR1; ;} - break; - - case 109: -#line 694 "../../../gbagnu/gcc/cp/parse.y" - { if (!begin_function_definition (NULL_TREE, (yyvsp[(1) - (1)].ttype))) - YYERROR1; ;} - break; - - case 110: -#line 697 "../../../gbagnu/gcc/cp/parse.y" - { if (!begin_function_definition ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype))) - YYERROR1; ;} - break; - - case 111: -#line 700 "../../../gbagnu/gcc/cp/parse.y" - { if (!begin_function_definition (NULL_TREE, (yyvsp[(1) - (1)].ttype))) - YYERROR1; ;} - break; - - case 112: -#line 706 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(1) - (6)].ttype), (yyvsp[(3) - (6)].ttype), (yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype)); ;} - break; - - case 113: -#line 708 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(1) - (4)].ttype), empty_parms (), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 114: -#line 710 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(1) - (6)].ttype), (yyvsp[(3) - (6)].ttype), (yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype)); ;} - break; - - case 115: -#line 712 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyvsp[(1) - (4)].ttype), empty_parms (), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 116: -#line 719 "../../../gbagnu/gcc/cp/parse.y" - { tree specs, attrs; - split_specs_attrs ((yyvsp[(1) - (2)].ttype), &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - (yyval.ttype) = start_method (specs, (yyvsp[(2) - (2)].ttype), attrs); - rest_of_mdef: - if (! (yyval.ttype)) - YYERROR1; - if (yychar == YYEMPTY) - yychar = YYLEX; - reinit_parse_for_method (yychar, (yyval.ttype)); ;} - break; - - case 117: -#line 730 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = start_method (NULL_TREE, (yyvsp[(1) - (1)].ttype), NULL_TREE); - goto rest_of_mdef; ;} - break; - - case 118: -#line 733 "../../../gbagnu/gcc/cp/parse.y" - { tree specs, attrs; - split_specs_attrs ((yyvsp[(1) - (2)].ftype).t, &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - (yyval.ttype) = start_method (specs, (yyvsp[(2) - (2)].ttype), attrs); goto rest_of_mdef; ;} - break; - - case 119: -#line 738 "../../../gbagnu/gcc/cp/parse.y" - { tree specs, attrs; - split_specs_attrs ((yyvsp[(1) - (2)].ttype), &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - (yyval.ttype) = start_method (specs, (yyvsp[(2) - (2)].ttype), attrs); goto rest_of_mdef; ;} - break; - - case 120: -#line 743 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = start_method (NULL_TREE, (yyval.ttype), NULL_TREE); - goto rest_of_mdef; ;} - break; - - case 121: -#line 746 "../../../gbagnu/gcc/cp/parse.y" - { tree specs, attrs; - split_specs_attrs ((yyvsp[(1) - (2)].ttype), &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - (yyval.ttype) = start_method (specs, (yyvsp[(2) - (2)].ttype), attrs); goto rest_of_mdef; ;} - break; - - case 122: -#line 751 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = start_method (NULL_TREE, (yyval.ttype), NULL_TREE); - goto rest_of_mdef; ;} - break; - - case 123: -#line 757 "../../../gbagnu/gcc/cp/parse.y" - { - if (! current_function_parms_stored) - store_parm_decls (); - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - ;} - break; - - case 124: -#line 766 "../../../gbagnu/gcc/cp/parse.y" - { store_return_init ((yyval.ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 125: -#line 768 "../../../gbagnu/gcc/cp/parse.y" - { store_return_init ((yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 126: -#line 770 "../../../gbagnu/gcc/cp/parse.y" - { store_return_init ((yyval.ttype), NULL_TREE); ;} - break; - - case 127: -#line 775 "../../../gbagnu/gcc/cp/parse.y" - { - if ((yyvsp[(3) - (3)].itype) == 0) - error ("no base initializers given following ':'"); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - ;} - break; - - case 128: -#line 788 "../../../gbagnu/gcc/cp/parse.y" - { - if (! current_function_parms_stored) - store_parm_decls (); - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Make a contour for the initializer list. */ - pushlevel (0); - clear_last_expr (); - expand_start_bindings (0); - } - else if (current_class_type == NULL_TREE) - error ("base initializers not allowed for non-member functions"); - else if (! DECL_CONSTRUCTOR_P (current_function_decl)) - error ("only constructors take base initializers"); - ;} - break; - - case 129: -#line 808 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 130: -#line 810 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 1; ;} - break; - - case 133: -#line 817 "../../../gbagnu/gcc/cp/parse.y" - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, (yyvsp[(2) - (3)].ttype)); - ;} - break; - - case 134: -#line 823 "../../../gbagnu/gcc/cp/parse.y" - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, void_type_node); - ;} - break; - - case 135: -#line 829 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, (yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 136: -#line 831 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, (yyvsp[(1) - (2)].ttype), void_type_node); ;} - break; - - case 137: -#line 833 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, (yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 138: -#line 835 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, (yyvsp[(1) - (2)].ttype), void_type_node); ;} - break; - - case 139: -#line 837 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ((yyvsp[(1) - (4)].ttype)), - (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 140: -#line 840 "../../../gbagnu/gcc/cp/parse.y" - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ((yyvsp[(1) - (2)].ttype)), - void_type_node); ;} - break; - - case 152: -#line 866 "../../../gbagnu/gcc/cp/parse.y" - { do_type_instantiation ((yyvsp[(3) - (4)].ftype).t, NULL_TREE); - yyungetc (';', 1); ;} - break; - - case 154: -#line 870 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(3) - (4)].ftype).t); - do_decl_instantiation (specs, (yyvsp[(4) - (4)].ttype), NULL_TREE); ;} - break; - - case 156: -#line 874 "../../../gbagnu/gcc/cp/parse.y" - { do_decl_instantiation (NULL_TREE, (yyvsp[(3) - (3)].ttype), NULL_TREE); ;} - break; - - case 158: -#line 877 "../../../gbagnu/gcc/cp/parse.y" - { do_decl_instantiation (NULL_TREE, (yyvsp[(3) - (3)].ttype), NULL_TREE); ;} - break; - - case 160: -#line 880 "../../../gbagnu/gcc/cp/parse.y" - { do_type_instantiation ((yyvsp[(4) - (5)].ftype).t, (yyvsp[(1) - (5)].ttype)); - yyungetc (';', 1); ;} - break; - - case 162: -#line 885 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(4) - (5)].ftype).t); - do_decl_instantiation (specs, (yyvsp[(5) - (5)].ttype), (yyvsp[(1) - (5)].ttype)); ;} - break; - - case 164: -#line 889 "../../../gbagnu/gcc/cp/parse.y" - { do_decl_instantiation (NULL_TREE, (yyvsp[(4) - (4)].ttype), (yyvsp[(1) - (4)].ttype)); ;} - break; - - case 166: -#line 892 "../../../gbagnu/gcc/cp/parse.y" - { do_decl_instantiation (NULL_TREE, (yyvsp[(4) - (4)].ttype), (yyvsp[(1) - (4)].ttype)); ;} - break; - - case 168: -#line 897 "../../../gbagnu/gcc/cp/parse.y" - { begin_explicit_instantiation(); ;} - break; - - case 169: -#line 900 "../../../gbagnu/gcc/cp/parse.y" - { end_explicit_instantiation(); ;} - break; - - case 170: -#line 909 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(5) - (5)].ttype); ;} - break; - - case 171: -#line 912 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(5) - (5)].ttype); ;} - break; - - case 174: -#line 920 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(5) - (5)].ttype); ;} - break; - - case 175: -#line 925 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(5) - (5)].ttype); ;} - break; - - case 176: -#line 929 "../../../gbagnu/gcc/cp/parse.y" - { - if (yychar == YYEMPTY) - yychar = YYLEX; - - (yyval.ttype) = finish_template_type ((yyvsp[(-3) - (0)].ttype), (yyvsp[(-1) - (0)].ttype), - yychar == SCOPE); - ;} - break; - - case 178: -#line 940 "../../../gbagnu/gcc/cp/parse.y" - { - /* Handle `Class<Class<Type>>' without space in the `>>' */ - pedwarn ("`>>' should be `> >' in template class name"); - yyungetc ('>', 1); - ;} - break; - - case 179: -#line 949 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 181: -#line 955 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyval.ttype)); ;} - break; - - case 182: -#line 957 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyval.ttype), build_tree_list (NULL_TREE, (yyvsp[(3) - (3)].ttype))); ;} - break; - - case 183: -#line 962 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = groktypename ((yyvsp[(1) - (1)].ftype).t); ;} - break; - - case 184: -#line 964 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lastiddecl; ;} - break; - - case 186: -#line 970 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.code) = NEGATE_EXPR; ;} - break; - - case 187: -#line 972 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.code) = CONVERT_EXPR; ;} - break; - - case 188: -#line 974 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.code) = PREINCREMENT_EXPR; ;} - break; - - case 189: -#line 976 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.code) = PREDECREMENT_EXPR; ;} - break; - - case 190: -#line 978 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.code) = TRUTH_NOT_EXPR; ;} - break; - - case 191: -#line 983 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_compound_expr ((yyval.ttype)); ;} - break; - - case 193: -#line 989 "../../../gbagnu/gcc/cp/parse.y" - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - (yyval.ttype) = integer_zero_node; ;} - break; - - case 194: -#line 993 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 195: -#line 998 "../../../gbagnu/gcc/cp/parse.y" - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - (yyval.ttype) = integer_zero_node; ;} - break; - - case 196: -#line 1002 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 197: -#line 1007 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 199: -#line 1010 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 200: -#line 1015 "../../../gbagnu/gcc/cp/parse.y" - { { - tree d; - for (d = getdecls (); d; d = TREE_CHAIN (d)) - if (TREE_CODE (d) == TYPE_DECL) { - tree s = TREE_TYPE (d); - if (TREE_CODE (s) == RECORD_TYPE) - cp_error ("definition of class `%T' in condition", s); - else if (TREE_CODE (s) == ENUMERAL_TYPE) - cp_error ("definition of enum `%T' in condition", s); - } - } - current_declspecs = (yyvsp[(1) - (5)].ftype).t; - (yyvsp[(5) - (5)].itype) = suspend_momentary (); - (yyval.ttype) = start_decl ((yyvsp[(2) - (5)].ttype), current_declspecs, 1, - (yyvsp[(4) - (5)].ttype), /*prefix_attributes*/ NULL_TREE); - ;} - break; - - case 201: -#line 1032 "../../../gbagnu/gcc/cp/parse.y" - { - cp_finish_decl ((yyvsp[(6) - (7)].ttype), (yyvsp[(7) - (7)].ttype), (yyvsp[(4) - (7)].ttype), 1, LOOKUP_ONLYCONVERTING); - resume_momentary ((yyvsp[(5) - (7)].itype)); - (yyval.ttype) = convert_from_reference ((yyvsp[(6) - (7)].ttype)); - if (TREE_CODE (TREE_TYPE ((yyval.ttype))) == ARRAY_TYPE) - cp_error ("definition of array `%#D' in condition", (yyval.ttype)); - ;} - break; - - case 207: -#line 1051 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_compound_stmt (1); ;} - break; - - case 208: -#line 1053 "../../../gbagnu/gcc/cp/parse.y" - { finish_compound_stmt (1, (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 210: -#line 1060 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = expr_tree_cons (NULL_TREE, (yyval.ttype), - build_expr_list (NULL_TREE, (yyvsp[(3) - (3)].ttype))); ;} - break; - - case 211: -#line 1063 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = expr_tree_cons (NULL_TREE, (yyval.ttype), - build_expr_list (NULL_TREE, error_mark_node)); ;} - break; - - case 212: -#line 1066 "../../../gbagnu/gcc/cp/parse.y" - { chainon ((yyval.ttype), build_expr_list (NULL_TREE, (yyvsp[(3) - (3)].ttype))); ;} - break; - - case 213: -#line 1068 "../../../gbagnu/gcc/cp/parse.y" - { chainon ((yyval.ttype), build_expr_list (NULL_TREE, error_mark_node)); ;} - break; - - case 214: -#line 1073 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_expr_list (NULL_TREE, (yyval.ttype)); ;} - break; - - case 216: -#line 1079 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ttype); ;} - break; - - case 217: -#line 1082 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - pedantic = (yyvsp[(1) - (2)].itype); ;} - break; - - case 218: -#line 1085 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_indirect_ref ((yyvsp[(2) - (2)].ttype), "unary *"); ;} - break; - - case 219: -#line 1087 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_unary_op (ADDR_EXPR, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 220: -#line 1089 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_unary_op (BIT_NOT_EXPR, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 221: -#line 1091 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_unary_op_expr ((yyvsp[(1) - (2)].code), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 222: -#line 1094 "../../../gbagnu/gcc/cp/parse.y" - { if (pedantic) - pedwarn ("ANSI C++ forbids `&&'"); - (yyval.ttype) = finish_label_address_expr ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 223: -#line 1098 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = expr_sizeof ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 224: -#line 1100 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = c_sizeof (groktypename ((yyvsp[(3) - (4)].ftype).t)); - check_for_new_type ("sizeof", (yyvsp[(3) - (4)].ftype)); ;} - break; - - case 225: -#line 1103 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grok_alignof ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 226: -#line 1105 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = c_alignof (groktypename ((yyvsp[(3) - (4)].ftype).t)); - check_for_new_type ("alignof", (yyvsp[(3) - (4)].ftype)); ;} - break; - - case 227: -#line 1111 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new (NULL_TREE, (yyvsp[(2) - (2)].ftype).t, NULL_TREE, (yyvsp[(1) - (2)].itype)); - check_for_new_type ("new", (yyvsp[(2) - (2)].ftype)); ;} - break; - - case 228: -#line 1114 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new (NULL_TREE, (yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].itype)); - check_for_new_type ("new", (yyvsp[(2) - (3)].ftype)); ;} - break; - - case 229: -#line 1117 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ftype).t, NULL_TREE, (yyvsp[(1) - (3)].itype)); - check_for_new_type ("new", (yyvsp[(3) - (3)].ftype)); ;} - break; - - case 230: -#line 1120 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new ((yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ftype).t, (yyvsp[(4) - (4)].ttype), (yyvsp[(1) - (4)].itype)); - check_for_new_type ("new", (yyvsp[(3) - (4)].ftype)); ;} - break; - - case 231: -#line 1133 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new (NULL_TREE, groktypename((yyvsp[(4) - (5)].ftype).t), - NULL_TREE, (yyvsp[(1) - (5)].itype)); - check_for_new_type ("new", (yyvsp[(4) - (5)].ftype)); ;} - break; - - case 232: -#line 1138 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new (NULL_TREE, groktypename((yyvsp[(4) - (6)].ftype).t), (yyvsp[(6) - (6)].ttype), (yyvsp[(1) - (6)].itype)); - check_for_new_type ("new", (yyvsp[(4) - (6)].ftype)); ;} - break; - - case 233: -#line 1142 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new ((yyvsp[(2) - (6)].ttype), groktypename((yyvsp[(5) - (6)].ftype).t), NULL_TREE, (yyvsp[(1) - (6)].itype)); - check_for_new_type ("new", (yyvsp[(5) - (6)].ftype)); ;} - break; - - case 234: -#line 1146 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_new ((yyvsp[(2) - (7)].ttype), groktypename((yyvsp[(5) - (7)].ftype).t), (yyvsp[(7) - (7)].ttype), (yyvsp[(1) - (7)].itype)); - check_for_new_type ("new", (yyvsp[(5) - (7)].ftype)); ;} - break; - - case 235: -#line 1150 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = delete_sanity ((yyvsp[(2) - (2)].ttype), NULL_TREE, 0, (yyvsp[(1) - (2)].itype)); ;} - break; - - case 236: -#line 1152 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = delete_sanity ((yyvsp[(4) - (4)].ttype), NULL_TREE, 1, (yyvsp[(1) - (4)].itype)); - if (yychar == YYEMPTY) - yychar = YYLEX; ;} - break; - - case 237: -#line 1156 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = delete_sanity ((yyvsp[(5) - (5)].ttype), (yyvsp[(3) - (5)].ttype), 2, (yyvsp[(1) - (5)].itype)); - if (yychar == YYEMPTY) - yychar = YYLEX; ;} - break; - - case 238: -#line 1160 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_unary_op (REALPART_EXPR, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 239: -#line 1162 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_unary_op (IMAGPART_EXPR, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 240: -#line 1172 "../../../gbagnu/gcc/cp/parse.y" - { finish_new_placement (NULL_TREE, (yyvsp[(-1) - (1)].itype)); ;} - break; - - case 241: -#line 1175 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = begin_new_placement (); ;} - break; - - case 242: -#line 1179 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_new_placement ((yyvsp[(3) - (4)].ttype), (yyvsp[(2) - (4)].itype)); ;} - break; - - case 243: -#line 1181 "../../../gbagnu/gcc/cp/parse.y" - { cp_pedwarn ("old style placement syntax, use () instead"); - (yyval.ttype) = finish_new_placement ((yyvsp[(3) - (4)].ttype), (yyvsp[(2) - (4)].itype)); ;} - break; - - case 244: -#line 1187 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 245: -#line 1189 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 246: -#line 1191 "../../../gbagnu/gcc/cp/parse.y" - { - cp_error ("`%T' is not a valid expression", (yyvsp[(2) - (3)].ftype).t); - (yyval.ttype) = error_mark_node; - ;} - break; - - case 247: -#line 1199 "../../../gbagnu/gcc/cp/parse.y" - { - if (pedantic) - pedwarn ("ANSI C++ forbids initialization of new expression with `='"); - if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) != TREE_LIST - && TREE_CODE ((yyvsp[(2) - (2)].ttype)) != CONSTRUCTOR) - (yyval.ttype) = build_expr_list (NULL_TREE, (yyvsp[(2) - (2)].ttype)); - else - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - ;} - break; - - case 248: -#line 1213 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(2) - (3)].ftype).t = finish_parmlist (build_tree_list (NULL_TREE, (yyvsp[(2) - (3)].ftype).t), 0); - (yyval.ttype) = make_call_declarator (NULL_TREE, (yyvsp[(2) - (3)].ftype).t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", (yyvsp[(2) - (3)].ftype)); ;} - break; - - case 249: -#line 1217 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(3) - (4)].ftype).t = finish_parmlist (build_tree_list (NULL_TREE, (yyvsp[(3) - (4)].ftype).t), 0); - (yyval.ttype) = make_call_declarator ((yyval.ttype), (yyvsp[(3) - (4)].ftype).t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", (yyvsp[(3) - (4)].ftype)); ;} - break; - - case 251: -#line 1225 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = reparse_absdcl_as_casts ((yyval.ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 252: -#line 1227 "../../../gbagnu/gcc/cp/parse.y" - { - tree init = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse ((yyvsp[(3) - (5)].ttype))); - if (pedantic) - pedwarn ("ANSI C++ forbids constructor-expressions"); - /* Indicate that this was a GNU C constructor expression. */ - TREE_HAS_CONSTRUCTOR (init) = 1; - - (yyval.ttype) = reparse_absdcl_as_casts ((yyval.ttype), init); - ;} - break; - - case 254: -#line 1243 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op (MEMBER_REF, (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 255: -#line 1245 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_m_component_ref ((yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 256: -#line 1247 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 257: -#line 1249 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 258: -#line 1251 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 259: -#line 1253 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 260: -#line 1255 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 261: -#line 1257 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 262: -#line 1259 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 263: -#line 1261 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 264: -#line 1263 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op (LT_EXPR, (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 265: -#line 1265 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op (GT_EXPR, (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 266: -#line 1267 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 267: -#line 1269 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 268: -#line 1271 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 269: -#line 1273 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 270: -#line 1275 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op ((yyvsp[(2) - (3)].code), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 271: -#line 1277 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op (TRUTH_ANDIF_EXPR, (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 272: -#line 1279 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_binary_op (TRUTH_ORIF_EXPR, (yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 273: -#line 1281 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_conditional_expr ((yyval.ttype), (yyvsp[(3) - (5)].ttype), (yyvsp[(5) - (5)].ttype)); ;} - break; - - case 274: -#line 1283 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_modify_expr ((yyval.ttype), NOP_EXPR, (yyvsp[(3) - (3)].ttype)); - if ((yyval.ttype) != error_mark_node) - C_SET_EXP_ORIGINAL_CODE ((yyval.ttype), MODIFY_EXPR); ;} - break; - - case 275: -#line 1287 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_modify_expr ((yyval.ttype), (yyvsp[(2) - (3)].code), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 276: -#line 1289 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_throw (NULL_TREE); ;} - break; - - case 277: -#line 1291 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_throw ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 278: -#line 1309 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (BIT_NOT_EXPR, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 279: -#line 1311 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (BIT_NOT_EXPR, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 285: -#line 1320 "../../../gbagnu/gcc/cp/parse.y" - { - /* If lastiddecl is a TREE_LIST, it's a baselink, which - means that we're in an expression like S::f<int>, so - don't do_identifier; we only do that for unqualified - identifiers. */ - if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) - (yyval.ttype) = do_identifier ((yyvsp[(-1) - (0)].ttype), 1, NULL_TREE); - else - (yyval.ttype) = (yyvsp[(-1) - (0)].ttype); - ;} - break; - - case 286: -#line 1333 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(3) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 287: -#line 1335 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(3) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 288: -#line 1340 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(2) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 289: -#line 1342 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(2) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 290: -#line 1345 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(2) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 295: -#line 1357 "../../../gbagnu/gcc/cp/parse.y" - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - (yyval.ttype) = decl_tree_cons ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype), NULL_TREE); - ;} - break; - - case 297: -#line 1367 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (INDIRECT_REF, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 298: -#line 1369 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ADDR_EXPR, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 299: -#line 1371 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 300: -#line 1376 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 301: -#line 1378 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = lookup_template_function ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 305: -#line 1388 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_decl_parsing ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 306: -#line 1393 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (1)].ttype)) == BIT_NOT_EXPR) - (yyval.ttype) = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ((yyvsp[(1) - (1)].ttype), 0)); - else - (yyval.ttype) = finish_id_expr ((yyvsp[(1) - (1)].ttype)); - ;} - break; - - case 309: -#line 1402 "../../../gbagnu/gcc/cp/parse.y" - { - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - (yyval.ttype) = combine_strings ((yyval.ttype)); - /* combine_strings doesn't set up TYPE_MAIN_VARIANT of - a const array the way we want, so fix it. */ - if (flag_const_strings) - TREE_TYPE ((yyval.ttype)) = build_cplus_array_type - (TREE_TYPE (TREE_TYPE ((yyval.ttype))), - TYPE_DOMAIN (TREE_TYPE ((yyval.ttype)))); - if (processing_template_decl) - pop_obstacks (); - ;} - break; - - case 310: -#line 1416 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parenthesized_expr ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 311: -#line 1418 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(2) - (3)].ttype) = reparse_decl_as_expr (NULL_TREE, (yyvsp[(2) - (3)].ttype)); - (yyval.ttype) = finish_parenthesized_expr ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 312: -#line 1421 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = error_mark_node; ;} - break; - - case 313: -#line 1423 "../../../gbagnu/gcc/cp/parse.y" - { tree scope = current_scope (); - if (!scope || TREE_CODE (scope) != FUNCTION_DECL) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); - (yyval.ttype) = begin_stmt_expr (); - ;} - break; - - case 314: -#line 1434 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_stmt_expr ((yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 315: -#line 1439 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_call_expr ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype), 1); ;} - break; - - case 316: -#line 1441 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_call_expr ((yyvsp[(1) - (2)].ttype), NULL_TREE, 1); ;} - break; - - case 317: -#line 1443 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_call_expr ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype), 0); ;} - break; - - case 318: -#line 1445 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_call_expr ((yyvsp[(1) - (2)].ttype), NULL_TREE, 0); ;} - break; - - case 319: -#line 1447 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grok_array_decl ((yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 320: -#line 1449 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_increment_expr ((yyvsp[(1) - (2)].ttype), POSTINCREMENT_EXPR); ;} - break; - - case 321: -#line 1451 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_increment_expr ((yyvsp[(1) - (2)].ttype), POSTDECREMENT_EXPR); ;} - break; - - case 322: -#line 1454 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_this_expr (); ;} - break; - - case 323: -#line 1456 "../../../gbagnu/gcc/cp/parse.y" - { - /* This is a C cast in C++'s `functional' notation - using the "implicit int" extension so that: - `const (3)' is equivalent to `const int (3)'. */ - tree type; - - if ((yyvsp[(3) - (4)].ttype) == error_mark_node) - { - (yyval.ttype) = error_mark_node; - break; - } - - type = cp_build_qualified_type (integer_type_node, - cp_type_qual_from_rid ((yyvsp[(1) - (4)].ttype))); - (yyval.ttype) = build_c_cast (type, build_compound_expr ((yyvsp[(3) - (4)].ttype))); - ;} - break; - - case 325: -#line 1474 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (7)].ftype).t); - check_for_new_type ("dynamic_cast", (yyvsp[(3) - (7)].ftype)); - (yyval.ttype) = build_dynamic_cast (type, (yyvsp[(6) - (7)].ttype)); ;} - break; - - case 326: -#line 1478 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (7)].ftype).t); - check_for_new_type ("static_cast", (yyvsp[(3) - (7)].ftype)); - (yyval.ttype) = build_static_cast (type, (yyvsp[(6) - (7)].ttype)); ;} - break; - - case 327: -#line 1482 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (7)].ftype).t); - check_for_new_type ("reinterpret_cast", (yyvsp[(3) - (7)].ftype)); - (yyval.ttype) = build_reinterpret_cast (type, (yyvsp[(6) - (7)].ttype)); ;} - break; - - case 328: -#line 1486 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (7)].ftype).t); - check_for_new_type ("const_cast", (yyvsp[(3) - (7)].ftype)); - (yyval.ttype) = build_const_cast (type, (yyvsp[(6) - (7)].ttype)); ;} - break; - - case 329: -#line 1490 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_typeid ((yyvsp[(3) - (4)].ttype)); ;} - break; - - case 330: -#line 1492 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (4)].ftype).t); - check_for_new_type ("typeid", (yyvsp[(3) - (4)].ftype)); - (yyval.ttype) = get_typeid (TYPE_MAIN_VARIANT (type)); ;} - break; - - case 331: -#line 1496 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = do_scoped_id ((yyvsp[(2) - (2)].ttype), 1); ;} - break; - - case 332: -#line 1498 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 333: -#line 1500 "../../../gbagnu/gcc/cp/parse.y" - { - got_scope = NULL_TREE; - if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = do_scoped_id ((yyvsp[(2) - (2)].ttype), 1); - else - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - ;} - break; - - case 334: -#line 1508 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_offset_ref (OP0 ((yyval.ttype)), OP1 ((yyval.ttype))); ;} - break; - - case 335: -#line 1510 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_qualified_call_expr ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 336: -#line 1512 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_qualified_call_expr ((yyvsp[(1) - (2)].ttype), NULL_TREE); ;} - break; - - case 337: -#line 1514 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = build_x_component_ref ((yyval.ttype), (yyvsp[(2) - (2)].ttype), NULL_TREE, 1); - ;} - break; - - case 338: -#line 1518 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_object_call_expr ((yyvsp[(2) - (5)].ttype), (yyvsp[(1) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 339: -#line 1520 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_object_call_expr ((yyvsp[(2) - (3)].ttype), (yyvsp[(1) - (3)].ttype), NULL_TREE); ;} - break; - - case 340: -#line 1522 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_x_component_ref ((yyval.ttype), (yyvsp[(2) - (2)].ttype), NULL_TREE, 1); ;} - break; - - case 341: -#line 1524 "../../../gbagnu/gcc/cp/parse.y" - { if (processing_template_decl) - (yyval.ttype) = build_min_nt (COMPONENT_REF, (yyvsp[(1) - (2)].ttype), copy_to_permanent ((yyvsp[(2) - (2)].ttype))); - else - (yyval.ttype) = build_object_ref ((yyval.ttype), OP0 ((yyvsp[(2) - (2)].ttype)), OP1 ((yyvsp[(2) - (2)].ttype))); ;} - break; - - case 342: -#line 1529 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_object_call_expr ((yyvsp[(2) - (5)].ttype), (yyvsp[(1) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 343: -#line 1531 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_object_call_expr ((yyvsp[(2) - (3)].ttype), (yyvsp[(1) - (3)].ttype), NULL_TREE); ;} - break; - - case 344: -#line 1533 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_qualified_object_call_expr ((yyvsp[(2) - (5)].ttype), (yyvsp[(1) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 345: -#line 1535 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_qualified_object_call_expr ((yyvsp[(2) - (3)].ttype), (yyvsp[(1) - (3)].ttype), NULL_TREE); ;} - break; - - case 346: -#line 1538 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_pseudo_destructor_call_expr ((yyvsp[(1) - (4)].ttype), NULL_TREE, (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 347: -#line 1540 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_pseudo_destructor_call_expr ((yyvsp[(1) - (6)].ttype), (yyvsp[(2) - (6)].ttype), (yyvsp[(5) - (6)].ttype)); ;} - break; - - case 348: -#line 1542 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = error_mark_node; - ;} - break; - - case 349: -#line 1587 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 350: -#line 1589 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; (yyval.itype) = 1; ;} - break; - - case 351: -#line 1594 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 352: -#line 1596 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; (yyval.itype) = 1; ;} - break; - - case 353: -#line 1601 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = boolean_true_node; ;} - break; - - case 354: -#line 1603 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = boolean_false_node; ;} - break; - - case 356: -#line 1610 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyval.ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 357: -#line 1615 "../../../gbagnu/gcc/cp/parse.y" - { - if (! current_function_parms_stored) - store_parm_decls (); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - ;} - break; - - case 358: -#line 1628 "../../../gbagnu/gcc/cp/parse.y" - { got_object = TREE_TYPE ((yyval.ttype)); ;} - break; - - case 359: -#line 1630 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = build_x_arrow ((yyval.ttype)); - got_object = TREE_TYPE ((yyval.ttype)); - ;} - break; - - case 360: -#line 1638 "../../../gbagnu/gcc/cp/parse.y" - { - resume_momentary ((yyvsp[(2) - (3)].itype)); - if ((yyvsp[(1) - (3)].ftype).t && IS_AGGR_TYPE_CODE (TREE_CODE ((yyvsp[(1) - (3)].ftype).t))) - note_got_semicolon ((yyvsp[(1) - (3)].ftype).t); - ;} - break; - - case 361: -#line 1644 "../../../gbagnu/gcc/cp/parse.y" - { - resume_momentary ((yyvsp[(2) - (3)].itype)); - note_list_got_semicolon ((yyvsp[(1) - (3)].ftype).t); - ;} - break; - - case 362: -#line 1649 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((yyvsp[(2) - (3)].itype)); ;} - break; - - case 363: -#line 1651 "../../../gbagnu/gcc/cp/parse.y" - { - shadow_tag ((yyvsp[(1) - (2)].ftype).t); - note_list_got_semicolon ((yyvsp[(1) - (2)].ftype).t); - ;} - break; - - case 364: -#line 1656 "../../../gbagnu/gcc/cp/parse.y" - { warning ("empty declaration"); ;} - break; - - case 365: -#line 1658 "../../../gbagnu/gcc/cp/parse.y" - { pedantic = (yyvsp[(1) - (2)].itype); ;} - break; - - case 368: -#line 1672 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator (NULL_TREE, empty_parms (), - NULL_TREE, NULL_TREE); ;} - break; - - case 369: -#line 1675 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), NULL_TREE, - NULL_TREE); ;} - break; - - case 370: -#line 1682 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 371: -#line 1685 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 372: -#line 1688 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list (get_decl_list ((yyvsp[(1) - (2)].ftype).t), (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 373: -#line 1691 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (1)].ftype).t, NULL_TREE); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 374: -#line 1694 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (1)].ftype).t, NULL_TREE); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 377: -#line 1710 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ftype).t, (yyvsp[(1) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(2) - (2)].ftype).new_type_flag; ;} - break; - - case 378: -#line 1713 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 379: -#line 1716 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(1) - (3)].ftype).t, chainon ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype))); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (3)].ftype).new_type_flag; ;} - break; - - case 380: -#line 1719 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (3)].ftype).t, chainon ((yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].ttype))); - (yyval.ftype).new_type_flag = (yyvsp[(2) - (3)].ftype).new_type_flag; ;} - break; - - case 381: -#line 1722 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (3)].ftype).t, chainon ((yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].ttype))); - (yyval.ftype).new_type_flag = (yyvsp[(2) - (3)].ftype).new_type_flag; ;} - break; - - case 382: -#line 1725 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (4)].ftype).t, - chainon ((yyvsp[(3) - (4)].ttype), chainon ((yyvsp[(4) - (4)].ttype), (yyvsp[(1) - (4)].ttype)))); - (yyval.ftype).new_type_flag = (yyvsp[(2) - (4)].ftype).new_type_flag; ;} - break; - - case 383: -#line 1732 "../../../gbagnu/gcc/cp/parse.y" - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ((yyval.ttype))); - (yyval.ttype) = build_decl_list (NULL_TREE, (yyval.ttype)); ;} - break; - - case 384: -#line 1737 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ftype).t, (yyval.ttype)); ;} - break; - - case 385: -#line 1739 "../../../gbagnu/gcc/cp/parse.y" - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ((yyvsp[(2) - (2)].ttype))); - (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ttype), (yyval.ttype)); ;} - break; - - case 386: -#line 1744 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons ((yyvsp[(2) - (2)].ttype), NULL_TREE, (yyvsp[(1) - (2)].ttype)); ;} - break; - - case 387: -#line 1746 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons ((yyvsp[(1) - (1)].ttype), NULL_TREE, NULL_TREE); ;} - break; - - case 388: -#line 1756 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ftype).t; TREE_STATIC ((yyval.ttype)) = 1; ;} - break; - - case 389: -#line 1758 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = IDENTIFIER_AS_LIST ((yyval.ttype)); ;} - break; - - case 390: -#line 1760 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ttype), (yyval.ttype)); - TREE_STATIC ((yyval.ttype)) = 1; ;} - break; - - case 391: -#line 1763 "../../../gbagnu/gcc/cp/parse.y" - { if (extra_warnings && TREE_STATIC ((yyval.ttype))) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ((yyvsp[(2) - (2)].ttype))); - (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ttype), (yyval.ttype)); - TREE_STATIC ((yyval.ttype)) = TREE_STATIC ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 392: -#line 1769 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons ((yyvsp[(2) - (2)].ttype), NULL_TREE, (yyvsp[(1) - (2)].ttype)); ;} - break; - - case 393: -#line 1771 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons ((yyvsp[(1) - (1)].ttype), NULL_TREE, NULL_TREE); ;} - break; - - case 394: -#line 1782 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = get_decl_list ((yyvsp[(1) - (1)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 395: -#line 1785 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ftype).t, (yyvsp[(1) - (2)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(2) - (2)].ftype).new_type_flag; ;} - break; - - case 396: -#line 1788 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 397: -#line 1791 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (3)].ftype).t, chainon ((yyvsp[(3) - (3)].ttype), (yyvsp[(1) - (3)].ftype).t)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (3)].ftype).new_type_flag; ;} - break; - - case 398: -#line 1797 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_decl_list (NULL_TREE, (yyvsp[(1) - (1)].ftype).t); ;} - break; - - case 399: -#line 1799 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ftype).t, (yyvsp[(1) - (2)].ttype)); ;} - break; - - case 401: -#line 1809 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(1) - (1)].ttype); (yyval.ftype).new_type_flag = 0; ;} - break; - - case 402: -#line 1811 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(1) - (1)].ttype); (yyval.ftype).new_type_flag = 0; ;} - break; - - case 403: -#line 1813 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = finish_typeof ((yyvsp[(3) - (4)].ttype)); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 404: -#line 1816 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = groktypename ((yyvsp[(3) - (4)].ftype).t); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 405: -#line 1819 "../../../gbagnu/gcc/cp/parse.y" - { tree type = TREE_TYPE ((yyvsp[(3) - (4)].ttype)); - - (yyval.ftype).new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - (yyval.ftype).t = type; - } - else - { - error ("`sigof' applied to non-aggregate expression"); - (yyval.ftype).t = error_mark_node; - } - ;} - break; - - case 406: -#line 1834 "../../../gbagnu/gcc/cp/parse.y" - { tree type = groktypename ((yyvsp[(3) - (4)].ftype).t); - - (yyval.ftype).new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - (yyval.ftype).t = type; - } - else - { - error("`sigof' applied to non-aggregate type"); - (yyval.ftype).t = error_mark_node; - } - ;} - break; - - case 407: -#line 1854 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(1) - (1)].ttype); (yyval.ftype).new_type_flag = 0; ;} - break; - - case 408: -#line 1856 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(1) - (1)].ttype); (yyval.ftype).new_type_flag = 0; ;} - break; - - case 411: -#line 1863 "../../../gbagnu/gcc/cp/parse.y" - { check_multiple_declarators (); ;} - break; - - case 413: -#line 1869 "../../../gbagnu/gcc/cp/parse.y" - { check_multiple_declarators (); ;} - break; - - case 415: -#line 1875 "../../../gbagnu/gcc/cp/parse.y" - { check_multiple_declarators (); ;} - break; - - case 416: -#line 1880 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 417: -#line 1882 "../../../gbagnu/gcc/cp/parse.y" - { if (TREE_CHAIN ((yyvsp[(3) - (4)].ttype))) (yyvsp[(3) - (4)].ttype) = combine_strings ((yyvsp[(3) - (4)].ttype)); (yyval.ttype) = (yyvsp[(3) - (4)].ttype); ;} - break; - - case 418: -#line 1887 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = start_decl ((yyvsp[(1) - (4)].ttype), current_declspecs, 1, - (yyvsp[(3) - (4)].ttype), prefix_attributes); ;} - break; - - case 419: -#line 1891 "../../../gbagnu/gcc/cp/parse.y" - { cp_finish_decl ((yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype), (yyvsp[(2) - (6)].ttype), 1, LOOKUP_ONLYCONVERTING); ;} - break; - - case 420: -#line 1893 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = start_decl ((yyvsp[(1) - (3)].ttype), current_declspecs, 0, - (yyvsp[(3) - (3)].ttype), prefix_attributes); - cp_finish_decl ((yyval.ttype), NULL_TREE, (yyvsp[(2) - (3)].ttype), 1, 0); ;} - break; - - case 421: -#line 1906 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(2) - (2)].itype) = parse_decl ((yyvsp[(-1) - (2)].ttype), (yyvsp[(-2) - (2)].ttype), - (yyvsp[(1) - (2)].ttype), 1, &(yyval.ttype)); ;} - break; - - case 422: -#line 1911 "../../../gbagnu/gcc/cp/parse.y" - { cp_finish_decl ((yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype), (yyvsp[(0) - (4)].ttype), 1, - LOOKUP_ONLYCONVERTING); - (yyval.itype) = (yyvsp[(2) - (4)].itype); ;} - break; - - case 423: -#line 1915 "../../../gbagnu/gcc/cp/parse.y" - { tree d; - (yyval.itype) = parse_decl ((yyvsp[(-1) - (1)].ttype), (yyvsp[(-2) - (1)].ttype), (yyvsp[(1) - (1)].ttype), 0, &d); - cp_finish_decl (d, NULL_TREE, (yyvsp[(0) - (1)].ttype), 1, 0); ;} - break; - - case 424: -#line 1922 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = (yyvsp[(3) - (3)].itype); ;} - break; - - case 425: -#line 1926 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = (yyvsp[(3) - (3)].itype); ;} - break; - - case 426: -#line 1931 "../../../gbagnu/gcc/cp/parse.y" - { /* Set things up as initdcl0_innards expects. */ - (yyvsp[(2) - (2)].ttype) = (yyvsp[(1) - (2)].ttype); - (yyvsp[(1) - (2)].ttype) = NULL_TREE; ;} - break; - - case 427: -#line 1935 "../../../gbagnu/gcc/cp/parse.y" - {;} - break; - - case 428: -#line 1937 "../../../gbagnu/gcc/cp/parse.y" - { tree d; - parse_decl((yyvsp[(1) - (3)].ttype), NULL_TREE, (yyvsp[(3) - (3)].ttype), 0, &d); - cp_finish_decl (d, NULL_TREE, (yyvsp[(2) - (3)].ttype), 1, 0); ;} - break; - - case 429: -#line 1946 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 430: -#line 1948 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ttype); ;} - break; - - case 431: -#line 1953 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ttype); ;} - break; - - case 432: -#line 1955 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 433: -#line 1960 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(4) - (6)].ttype); ;} - break; - - case 434: -#line 1965 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(1) - (1)].ttype); ;} - break; - - case 435: -#line 1967 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyvsp[(1) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 436: -#line 1972 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 437: -#line 1974 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyvsp[(1) - (1)].ttype), NULL_TREE); ;} - break; - - case 438: -#line 1976 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyvsp[(1) - (4)].ttype), build_tree_list (NULL_TREE, (yyvsp[(3) - (4)].ttype))); ;} - break; - - case 439: -#line 1978 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyvsp[(1) - (6)].ttype), tree_cons (NULL_TREE, (yyvsp[(3) - (6)].ttype), (yyvsp[(5) - (6)].ttype))); ;} - break; - - case 440: -#line 1980 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 445: -#line 1996 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ttype)); ;} - break; - - case 446: -#line 1998 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyvsp[(1) - (3)].ttype), build_tree_list (NULL_TREE, (yyvsp[(3) - (3)].ttype))); ;} - break; - - case 447: -#line 2003 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 448: -#line 2005 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 450: -#line 2013 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - TREE_HAS_CONSTRUCTOR ((yyval.ttype)) = 1; ;} - break; - - case 451: -#line 2016 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ((yyvsp[(2) - (3)].ttype))); - TREE_HAS_CONSTRUCTOR ((yyval.ttype)) = 1; ;} - break; - - case 452: -#line 2019 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ((yyvsp[(2) - (4)].ttype))); - TREE_HAS_CONSTRUCTOR ((yyval.ttype)) = 1; ;} - break; - - case 453: -#line 2022 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 454: -#line 2029 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list (NULL_TREE, (yyval.ttype)); ;} - break; - - case 455: -#line 2031 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = expr_tree_cons (NULL_TREE, (yyvsp[(3) - (3)].ttype), (yyval.ttype)); ;} - break; - - case 456: -#line 2034 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_expr_list ((yyvsp[(2) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 457: -#line 2036 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_expr_list ((yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 458: -#line 2038 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = expr_tree_cons ((yyvsp[(3) - (5)].ttype), (yyvsp[(5) - (5)].ttype), (yyval.ttype)); ;} - break; - - case 459: -#line 2043 "../../../gbagnu/gcc/cp/parse.y" - { start_function (NULL_TREE, TREE_VALUE ((yyvsp[(1) - (1)].ttype)), - NULL_TREE, 2); - reinit_parse_for_function (); ;} - break; - - case 460: -#line 2049 "../../../gbagnu/gcc/cp/parse.y" - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)(yyvsp[(3) - (4)].itype) | 2, nested); - process_next_inline ((yyvsp[(1) - (4)].ttype)); - ;} - break; - - case 461: -#line 2056 "../../../gbagnu/gcc/cp/parse.y" - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)(yyvsp[(3) - (3)].itype) | 2, nested); - process_next_inline ((yyvsp[(1) - (3)].ttype)); - ;} - break; - - case 462: -#line 2063 "../../../gbagnu/gcc/cp/parse.y" - { process_next_inline ((yyvsp[(1) - (3)].ttype)); ;} - break; - - case 465: -#line 2075 "../../../gbagnu/gcc/cp/parse.y" - { replace_defarg ((yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 466: -#line 2077 "../../../gbagnu/gcc/cp/parse.y" - { replace_defarg ((yyvsp[(1) - (3)].ttype), error_mark_node); ;} - break; - - case 468: -#line 2082 "../../../gbagnu/gcc/cp/parse.y" - { do_pending_defargs (); ;} - break; - - case 469: -#line 2084 "../../../gbagnu/gcc/cp/parse.y" - { do_pending_defargs (); ;} - break; - - case 470: -#line 2089 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(3) - (3)].itype) = suspend_momentary (); - (yyval.ttype) = current_enum_type; - current_enum_type = start_enum ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 471: -#line 2093 "../../../gbagnu/gcc/cp/parse.y" - { TYPE_VALUES (current_enum_type) = (yyvsp[(5) - (7)].ttype); - (yyval.ftype).t = finish_enum (current_enum_type); - (yyval.ftype).new_type_flag = 1; - current_enum_type = (yyvsp[(4) - (7)].ttype); - resume_momentary ((int) (yyvsp[(3) - (7)].itype)); - check_for_missing_semicolon ((yyval.ftype).t); ;} - break; - - case 472: -#line 2100 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = finish_enum (start_enum ((yyvsp[(2) - (4)].ttype))); - (yyval.ftype).new_type_flag = 1; - check_for_missing_semicolon ((yyval.ftype).t); ;} - break; - - case 473: -#line 2104 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(2) - (2)].itype) = suspend_momentary (); - (yyval.ttype) = current_enum_type; - current_enum_type = start_enum (make_anon_name ()); ;} - break; - - case 474: -#line 2108 "../../../gbagnu/gcc/cp/parse.y" - { TYPE_VALUES (current_enum_type) = (yyvsp[(4) - (6)].ttype); - (yyval.ftype).t = finish_enum (current_enum_type); - (yyval.ftype).new_type_flag = 1; - current_enum_type = (yyvsp[(3) - (6)].ttype); - resume_momentary ((int) (yyvsp[(1) - (6)].itype)); - check_for_missing_semicolon ((yyval.ftype).t); ;} - break; - - case 475: -#line 2115 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = finish_enum (start_enum (make_anon_name())); - (yyval.ftype).new_type_flag = 1; - check_for_missing_semicolon ((yyval.ftype).t); ;} - break; - - case 476: -#line 2119 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = xref_tag (enum_type_node, (yyvsp[(2) - (2)].ttype), 1); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 477: -#line 2122 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = xref_tag (enum_type_node, (yyvsp[(2) - (2)].ttype), 1); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 478: -#line 2125 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(2) - (2)].ttype); - (yyval.ftype).new_type_flag = 0; - if (!processing_template_decl) - cp_pedwarn ("using `typename' outside of template"); ;} - break; - - case 479: -#line 2132 "../../../gbagnu/gcc/cp/parse.y" - { - int semi; - - if (yychar == YYEMPTY) - yychar = YYLEX; - semi = yychar == ';'; - - (yyval.ttype) = finish_class_definition ((yyvsp[(1) - (5)].ttype), (yyvsp[(5) - (5)].ttype), semi); - ;} - break; - - case 480: -#line 2142 "../../../gbagnu/gcc/cp/parse.y" - { finish_default_args (); ;} - break; - - case 481: -#line 2144 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = (yyvsp[(6) - (9)].ttype); - (yyval.ftype).new_type_flag = 1; - begin_inline_definitions (); ;} - break; - - case 482: -#line 2148 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ftype).new_type_flag = 0; - if (TYPE_BINFO ((yyvsp[(1) - (1)].ttype)) == NULL_TREE) - { - cp_error ("%T is not a class type", (yyvsp[(1) - (1)].ttype)); - (yyval.ftype).t = error_mark_node; - } - else - { - (yyval.ftype).t = (yyvsp[(1) - (1)].ttype); - /* struct B: public A; is not accepted by the WP grammar. */ - if (TYPE_BINFO_BASETYPES ((yyval.ftype).t) && !TYPE_SIZE ((yyval.ftype).t) - && ! TYPE_BEING_DEFINED ((yyval.ftype).t)) - cp_error ("base clause without member specification for `%#T'", - (yyval.ftype).t); - } - ;} - break; - - case 486: -#line 2175 "../../../gbagnu/gcc/cp/parse.y" - { if (pedantic && !in_system_header) - pedwarn ("comma at end of enumerator list"); ;} - break; - - case 488: -#line 2182 "../../../gbagnu/gcc/cp/parse.y" - { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ((yyvsp[(2) - (2)].ttype))); ;} - break; - - case 489: -#line 2184 "../../../gbagnu/gcc/cp/parse.y" - { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ((yyvsp[(2) - (2)].ttype))); ;} - break; - - case 490: -#line 2186 "../../../gbagnu/gcc/cp/parse.y" - { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ((yyvsp[(2) - (2)].ttype))); ;} - break; - - case 491: -#line 2188 "../../../gbagnu/gcc/cp/parse.y" - { error ("no body nor ';' separates two class, struct or union declarations"); ;} - break; - - case 492: -#line 2190 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_decl_list ((yyvsp[(2) - (2)].ttype), (yyvsp[(1) - (2)].ttype)); ;} - break; - - case 493: -#line 2195 "../../../gbagnu/gcc/cp/parse.y" - { - current_aggr = (yyvsp[(1) - (2)].ttype); - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - ;} - break; - - case 494: -#line 2203 "../../../gbagnu/gcc/cp/parse.y" - { current_aggr = (yyval.ttype); (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 495: -#line 2205 "../../../gbagnu/gcc/cp/parse.y" - { yyungetc ('{', 1); ;} - break; - - case 496: -#line 2207 "../../../gbagnu/gcc/cp/parse.y" - { yyungetc (':', 1); ;} - break; - - case 497: -#line 2212 "../../../gbagnu/gcc/cp/parse.y" - { - current_aggr = (yyvsp[(1) - (3)].ttype); - (yyval.ttype) = handle_class_head ((yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - ;} - break; - - case 498: -#line 2217 "../../../gbagnu/gcc/cp/parse.y" - { - current_aggr = (yyvsp[(1) - (4)].ttype); - (yyval.ttype) = handle_class_head ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); - ;} - break; - - case 499: -#line 2222 "../../../gbagnu/gcc/cp/parse.y" - { - current_aggr = (yyvsp[(1) - (3)].ttype); - (yyval.ttype) = handle_class_head ((yyvsp[(1) - (3)].ttype), NULL_TREE, (yyvsp[(3) - (3)].ttype)); - ;} - break; - - case 500: -#line 2227 "../../../gbagnu/gcc/cp/parse.y" - { current_aggr = (yyval.ttype); (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 501: -#line 2229 "../../../gbagnu/gcc/cp/parse.y" - { current_aggr = (yyval.ttype); (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 502: -#line 2234 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = xref_tag (current_aggr, (yyvsp[(1) - (1)].ttype), 1); ;} - break; - - case 503: -#line 2236 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = xref_tag (current_aggr, (yyvsp[(1) - (1)].ttype), 0); ;} - break; - - case 504: -#line 2240 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = (yyvsp[(2) - (3)].ttype); - if ((yyvsp[(3) - (3)].ttype)) - xref_basetypes (current_aggr, (yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - ;} - break; - - case 505: -#line 2246 "../../../gbagnu/gcc/cp/parse.y" - { push_scope (CP_DECL_CONTEXT ((yyvsp[(1) - (1)].ttype))); ;} - break; - - case 506: -#line 2248 "../../../gbagnu/gcc/cp/parse.y" - { - pop_scope (CP_DECL_CONTEXT ((yyvsp[(1) - (3)].ttype))); - (yyval.ttype) = TREE_TYPE ((yyvsp[(1) - (3)].ttype)); - if (current_aggr == union_type_node - && TREE_CODE ((yyval.ttype)) != UNION_TYPE) - cp_pedwarn ("`union' tag used in declaring `%#T'", (yyval.ttype)); - else if (TREE_CODE ((yyval.ttype)) == UNION_TYPE - && current_aggr != union_type_node) - cp_pedwarn ("non-`union' tag used in declaring `%#T'", (yyval.ttype)); - else if (TREE_CODE ((yyval.ttype)) == RECORD_TYPE) - /* We might be specializing a template with a different - class-key; deal. */ - CLASSTYPE_DECLARED_CLASS ((yyval.ttype)) = (current_aggr - == class_type_node); - if ((yyvsp[(3) - (3)].ttype)) - { - maybe_process_partial_specialization ((yyval.ttype)); - xref_basetypes (current_aggr, (yyvsp[(1) - (3)].ttype), (yyval.ttype), (yyvsp[(3) - (3)].ttype)); - } - ;} - break; - - case 507: -#line 2272 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = xref_tag ((yyval.ttype), make_anon_name (), 0); - yyungetc ('{', 1); ;} - break; - - case 510: -#line 2283 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 511: -#line 2285 "../../../gbagnu/gcc/cp/parse.y" - { yyungetc(':', 1); (yyval.ttype) = NULL_TREE; ;} - break; - - case 512: -#line 2287 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 514: -#line 2293 "../../../gbagnu/gcc/cp/parse.y" - { /* CYGNUS LOCAL Embedded C++ */ - if (flag_embedded_cxx) - pedwarn ("Embedded C++ prohibits multiple inheritance"); - /* END CYGNUS LOCAL Embedded C++ */ - (yyval.ttype) = chainon ((yyval.ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 515: -#line 2302 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_base_specifier (access_default_node, (yyvsp[(1) - (1)].ttype), - current_aggr - == signature_type_node); ;} - break; - - case 516: -#line 2306 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_base_specifier ((yyvsp[(1) - (3)].ttype), (yyvsp[(3) - (3)].ttype), - current_aggr - == signature_type_node); ;} - break; - - case 517: -#line 2313 "../../../gbagnu/gcc/cp/parse.y" - { if ((yyval.ttype) != error_mark_node) (yyval.ttype) = TYPE_MAIN_DECL ((yyvsp[(1) - (1)].ttype)); ;} - break; - - case 519: -#line 2316 "../../../gbagnu/gcc/cp/parse.y" - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (TREE_TYPE ((yyvsp[(3) - (4)].ttype)))) - { - sorry ("`sigof' as base signature specifier"); - (yyval.ttype) = TREE_TYPE ((yyvsp[(3) - (4)].ttype)); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - (yyval.ttype) = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - (yyval.ttype) = error_mark_node; - } - ;} - break; - - case 520: -#line 2337 "../../../gbagnu/gcc/cp/parse.y" - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (groktypename ((yyvsp[(3) - (4)].ftype).t))) - { - sorry ("`sigof' as base signature specifier"); - (yyval.ttype) = groktypename ((yyvsp[(3) - (4)].ftype).t); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - (yyval.ttype) = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - (yyval.ttype) = error_mark_node; - } - ;} - break; - - case 522: -#line 2362 "../../../gbagnu/gcc/cp/parse.y" - { if ((yyvsp[(1) - (2)].ttype) != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", (yyvsp[(1) - (2)].ttype)); - (yyval.ttype) = access_default_virtual_node; ;} - break; - - case 523: -#line 2366 "../../../gbagnu/gcc/cp/parse.y" - { - if ((yyvsp[(1) - (3)].ttype) != access_default_virtual_node) - error ("multiple access specifiers"); - else if ((yyvsp[(2) - (3)].ttype) == access_public_node) - (yyval.ttype) = access_public_virtual_node; - else if ((yyvsp[(2) - (3)].ttype) == access_protected_node) - (yyval.ttype) = access_protected_virtual_node; - else /* $2 == access_private_node */ - (yyval.ttype) = access_private_virtual_node; - ;} - break; - - case 524: -#line 2377 "../../../gbagnu/gcc/cp/parse.y" - { if ((yyvsp[(2) - (3)].ttype) != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", (yyvsp[(2) - (3)].ttype)); - else if ((yyval.ttype) == access_public_node) - (yyval.ttype) = access_public_virtual_node; - else if ((yyval.ttype) == access_protected_node) - (yyval.ttype) = access_protected_virtual_node; - else if ((yyval.ttype) == access_private_node) - (yyval.ttype) = access_private_virtual_node; - else - error ("multiple `virtual' specifiers"); - ;} - break; - - case 525: -#line 2392 "../../../gbagnu/gcc/cp/parse.y" - { (yyvsp[(0) - (1)].ttype) = begin_class_definition ((yyvsp[(0) - (1)].ttype)); ;} - break; - - case 526: -#line 2397 "../../../gbagnu/gcc/cp/parse.y" - { - finish_member_declaration (build_self_reference ()); - ;} - break; - - case 531: -#line 2411 "../../../gbagnu/gcc/cp/parse.y" - { - if (current_aggr == signature_type_node) - { - error ("access specifier not allowed in signature"); - (yyvsp[(1) - (2)].ttype) = access_public_node; - } - - current_access_specifier = (yyvsp[(1) - (2)].ttype); - ;} - break; - - case 532: -#line 2426 "../../../gbagnu/gcc/cp/parse.y" - { - finish_member_declaration ((yyvsp[(1) - (1)].ttype)); - ;} - break; - - case 533: -#line 2430 "../../../gbagnu/gcc/cp/parse.y" - { - finish_member_declaration ((yyvsp[(2) - (2)].ttype)); - ;} - break; - - case 535: -#line 2438 "../../../gbagnu/gcc/cp/parse.y" - { error ("missing ';' before right brace"); - yyungetc ('}', 0); ;} - break; - - case 536: -#line 2443 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_method ((yyval.ttype)); ;} - break; - - case 537: -#line 2445 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_method ((yyval.ttype)); ;} - break; - - case 538: -#line 2447 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_method ((yyval.ttype)); ;} - break; - - case 539: -#line 2449 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_method ((yyval.ttype)); ;} - break; - - case 540: -#line 2451 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 541: -#line 2453 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - pedantic = (yyvsp[(1) - (2)].itype); ;} - break; - - case 542: -#line 2456 "../../../gbagnu/gcc/cp/parse.y" - { - if ((yyvsp[(2) - (2)].ttype)) - (yyval.ttype) = finish_member_template_decl ((yyvsp[(2) - (2)].ttype)); - else - /* The component was already processed. */ - (yyval.ttype) = NULL_TREE; - - finish_template_decl ((yyvsp[(1) - (2)].ttype)); - ;} - break; - - case 543: -#line 2466 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = finish_member_class_template ((yyvsp[(2) - (3)].ftype).t); - finish_template_decl ((yyvsp[(1) - (3)].ttype)); - ;} - break; - - case 544: -#line 2477 "../../../gbagnu/gcc/cp/parse.y" - { - /* Most of the productions for component_decl only - allow the creation of one new member, so we call - finish_member_declaration in component_decl_list. - For this rule and the next, however, there can be - more than one member, e.g.: - - int i, j; - - and we need the first member to be fully - registered before the second is processed. - Therefore, the rules for components take care of - this processing. To avoid registering the - components more than once, we send NULL_TREE up - here; that lets finish_member_declaration now - that there is nothing to do. */ - if (!(yyvsp[(2) - (2)].itype)) - grok_x_components ((yyvsp[(1) - (2)].ftype).t); - (yyval.ttype) = NULL_TREE; - ;} - break; - - case 545: -#line 2498 "../../../gbagnu/gcc/cp/parse.y" - { - if (!(yyvsp[(2) - (2)].itype)) - grok_x_components ((yyvsp[(1) - (2)].ttype)); - (yyval.ttype) = NULL_TREE; - ;} - break; - - case 546: -#line 2504 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokfield ((yyval.ttype), NULL_TREE, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), NULL_TREE)); ;} - break; - - case 547: -#line 2507 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokfield ((yyval.ttype), NULL_TREE, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), NULL_TREE)); ;} - break; - - case 548: -#line 2510 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokbitfield (NULL_TREE, NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 549: -#line 2512 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 550: -#line 2523 "../../../gbagnu/gcc/cp/parse.y" - { tree specs, attrs; - split_specs_attrs ((yyvsp[(1) - (5)].ttype), &specs, &attrs); - (yyval.ttype) = grokfield ((yyvsp[(2) - (5)].ttype), specs, (yyvsp[(5) - (5)].ttype), (yyvsp[(3) - (5)].ttype), - build_tree_list ((yyvsp[(4) - (5)].ttype), attrs)); ;} - break; - - case 551: -#line 2528 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokfield ((yyval.ttype), NULL_TREE, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), NULL_TREE)); ;} - break; - - case 552: -#line 2531 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = do_class_using_decl ((yyvsp[(1) - (1)].ttype)); ;} - break; - - case 553: -#line 2537 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 554: -#line 2539 "../../../gbagnu/gcc/cp/parse.y" - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - (yyvsp[(1) - (1)].ttype) = finish_member_template_decl ((yyvsp[(1) - (1)].ttype)); - finish_member_declaration ((yyvsp[(1) - (1)].ttype)); - (yyval.itype) = 1; - ;} - break; - - case 555: -#line 2546 "../../../gbagnu/gcc/cp/parse.y" - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - (yyvsp[(3) - (3)].ttype) = finish_member_template_decl ((yyvsp[(3) - (3)].ttype)); - finish_member_declaration ((yyvsp[(3) - (3)].ttype)); - (yyval.itype) = 2; - ;} - break; - - case 556: -#line 2557 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = 0; ;} - break; - - case 557: -#line 2559 "../../../gbagnu/gcc/cp/parse.y" - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - (yyvsp[(1) - (1)].ttype) = finish_member_template_decl ((yyvsp[(1) - (1)].ttype)); - finish_member_declaration ((yyvsp[(1) - (1)].ttype)); - (yyval.itype) = 1; - ;} - break; - - case 558: -#line 2566 "../../../gbagnu/gcc/cp/parse.y" - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - (yyvsp[(3) - (3)].ttype) = finish_member_template_decl ((yyvsp[(3) - (3)].ttype)); - finish_member_declaration ((yyvsp[(3) - (3)].ttype)); - (yyval.itype) = 2; - ;} - break; - - case 563: -#line 2587 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (4)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (4)].ttype) = current_declspecs; - (yyval.ttype) = grokfield ((yyval.ttype), current_declspecs, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), prefix_attributes)); ;} - break; - - case 564: -#line 2593 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (4)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (4)].ttype) = current_declspecs; - (yyval.ttype) = grokbitfield ((yyval.ttype), current_declspecs, (yyvsp[(3) - (4)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(4) - (4)].ttype), prefix_attributes); ;} - break; - - case 565: -#line 2602 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (4)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (4)].ttype) = current_declspecs; - (yyval.ttype) = grokfield ((yyval.ttype), current_declspecs, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), prefix_attributes)); ;} - break; - - case 566: -#line 2608 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (4)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (4)].ttype) = current_declspecs; - (yyval.ttype) = grokfield ((yyval.ttype), current_declspecs, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), prefix_attributes)); ;} - break; - - case 567: -#line 2614 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (4)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (4)].ttype) = current_declspecs; - (yyval.ttype) = grokbitfield ((yyval.ttype), current_declspecs, (yyvsp[(3) - (4)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(4) - (4)].ttype), prefix_attributes); ;} - break; - - case 568: -#line 2620 "../../../gbagnu/gcc/cp/parse.y" - { split_specs_attrs ((yyvsp[(0) - (3)].ttype), ¤t_declspecs, - &prefix_attributes); - (yyvsp[(0) - (3)].ttype) = current_declspecs; - (yyval.ttype) = grokbitfield (NULL_TREE, current_declspecs, (yyvsp[(2) - (3)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(3) - (3)].ttype), prefix_attributes); ;} - break; - - case 569: -#line 2629 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokfield ((yyval.ttype), current_declspecs, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), prefix_attributes)); ;} - break; - - case 570: -#line 2632 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokbitfield ((yyval.ttype), current_declspecs, (yyvsp[(3) - (4)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(4) - (4)].ttype), prefix_attributes); ;} - break; - - case 571: -#line 2638 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokfield ((yyval.ttype), current_declspecs, (yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype), - build_tree_list ((yyvsp[(3) - (4)].ttype), prefix_attributes)); ;} - break; - - case 572: -#line 2641 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokbitfield ((yyval.ttype), current_declspecs, (yyvsp[(3) - (4)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(4) - (4)].ttype), prefix_attributes); ;} - break; - - case 573: -#line 2644 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokbitfield (NULL_TREE, current_declspecs, (yyvsp[(2) - (3)].ttype)); - cplus_decl_attributes ((yyval.ttype), (yyvsp[(3) - (3)].ttype), prefix_attributes); ;} - break; - - case 575: -#line 2655 "../../../gbagnu/gcc/cp/parse.y" - { TREE_CHAIN ((yyvsp[(3) - (3)].ttype)) = (yyval.ttype); (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 576: -#line 2660 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_enumerator ((yyval.ttype), NULL_TREE, current_enum_type); ;} - break; - - case 577: -#line 2662 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_enumerator ((yyval.ttype), (yyvsp[(3) - (3)].ttype), current_enum_type); ;} - break; - - case 578: -#line 2668 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 579: -#line 2671 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_decl_list ((yyvsp[(1) - (1)].ftype).t, NULL_TREE); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 580: -#line 2678 "../../../gbagnu/gcc/cp/parse.y" - { - if (pedantic) - pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); - (yyval.ftype).t = build_parse_node (ARRAY_REF, TREE_VALUE ((yyvsp[(3) - (7)].ftype).t), (yyvsp[(6) - (7)].ttype)); - (yyval.ftype).t = build_decl_list (TREE_PURPOSE ((yyvsp[(3) - (7)].ftype).t), (yyval.ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(3) - (7)].ftype).new_type_flag; - ;} - break; - - case 581: -#line 2689 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 582: -#line 2691 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ttype), (yyval.ttype)); ;} - break; - - case 583: -#line 2696 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = IDENTIFIER_AS_LIST ((yyvsp[(1) - (1)].ttype)); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 584: -#line 2699 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = decl_tree_cons (NULL_TREE, (yyvsp[(2) - (2)].ttype), (yyvsp[(1) - (2)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 585: -#line 2708 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.itype) = suspend_momentary (); ;} - break; - - case 586: -#line 2713 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((int) (yyvsp[(1) - (2)].itype)); (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 587: -#line 2719 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((int) (yyvsp[(1) - (4)].itype)); (yyval.ttype) = (yyvsp[(3) - (4)].ttype); ;} - break; - - case 588: -#line 2721 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((int) (yyvsp[(1) - (4)].itype)); (yyval.ttype) = (yyvsp[(3) - (4)].ttype); ;} - break; - - case 589: -#line 2723 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((int) (yyvsp[(1) - (2)].itype)); (yyval.ttype) = empty_parms (); ;} - break; - - case 590: -#line 2725 "../../../gbagnu/gcc/cp/parse.y" - { resume_momentary ((int) (yyvsp[(1) - (4)].itype)); (yyval.ttype) = NULL_TREE; ;} - break; - - case 591: -#line 2732 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 592: -#line 2734 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 593: -#line 2736 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 594: -#line 2738 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 595: -#line 2740 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 597: -#line 2748 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (1)].ttype)) == IDENTIFIER_NODE) - { - (yyval.ttype) = lookup_name ((yyvsp[(1) - (1)].ttype), 1); - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ((yyvsp[(1) - (1)].ttype))) - { - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - pushdecl_class_level ((yyval.ttype)); - } - } - else - (yyval.ttype) = (yyvsp[(1) - (1)].ttype); - ;} - break; - - case 598: -#line 2765 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = IDENTIFIER_GLOBAL_VALUE ((yyvsp[(2) - (2)].ttype)); - else - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - got_scope = NULL_TREE; - ;} - break; - - case 601: -#line 2778 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 602: -#line 2783 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = get_type_decl ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 603: -#line 2788 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyval.ttype), (yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 604: -#line 2790 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 605: -#line 2792 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), NULL_TREE); ;} - break; - - case 606: -#line 2794 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 607: -#line 2796 "../../../gbagnu/gcc/cp/parse.y" - { push_nested_class ((yyvsp[(1) - (2)].ttype), 3); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyval.ttype), (yyvsp[(2) - (2)].ttype)); - TREE_COMPLEXITY ((yyval.ttype)) = current_class_depth; ;} - break; - - case 610: -#line 2808 "../../../gbagnu/gcc/cp/parse.y" - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - (yyval.ttype) = decl_tree_cons ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype), NULL_TREE); - ;} - break; - - case 611: -#line 2817 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 612: -#line 2819 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 613: -#line 2821 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 614: -#line 2823 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 615: -#line 2825 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 617: -#line 2833 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 618: -#line 2835 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 619: -#line 2837 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 620: -#line 2839 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 621: -#line 2841 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 623: -#line 2849 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyval.ttype), (yyvsp[(2) - (4)].ttype), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 624: -#line 2851 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 625: -#line 2853 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 626: -#line 2855 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), NULL_TREE); ;} - break; - - case 627: -#line 2857 "../../../gbagnu/gcc/cp/parse.y" - { enter_scope_of ((yyvsp[(1) - (1)].ttype)); ;} - break; - - case 628: -#line 2859 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); - enter_scope_of ((yyval.ttype)); - ;} - break; - - case 629: -#line 2867 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyval.ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 630: -#line 2870 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 631: -#line 2876 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyval.ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 632: -#line 2879 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 634: -#line 2886 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 635: -#line 2891 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_functional_cast ((yyvsp[(1) - (4)].ftype).t, (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 636: -#line 2893 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = reparse_decl_as_expr ((yyvsp[(1) - (4)].ftype).t, (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 637: -#line 2895 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = reparse_absdcl_as_expr ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 642: -#line 2906 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 643: -#line 2908 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = (yyval.ttype) = make_typename_type ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 644: -#line 2915 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (2)].ttype)) == IDENTIFIER_NODE) - { - (yyval.ttype) = lastiddecl; - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ((yyvsp[(1) - (2)].ttype))) - pushdecl_class_level ((yyval.ttype)); - } - got_scope = (yyval.ttype) = TYPE_MAIN_VARIANT (TREE_TYPE ((yyval.ttype))); - ;} - break; - - case 645: -#line 2929 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (2)].ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype) = TREE_TYPE ((yyval.ttype)); - ;} - break; - - case 646: -#line 2935 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyval.ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype); - ;} - break; - - case 647: -#line 2941 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = (yyval.ttype) = complete_type (TREE_TYPE ((yyvsp[(1) - (2)].ttype))); ;} - break; - - case 649: -#line 2957 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 650: -#line 2962 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE_CLASS (TREE_CODE ((yyvsp[(1) - (2)].ttype))) == 't') - (yyval.ttype) = make_typename_type ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); - else if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", (yyvsp[(2) - (2)].ttype)); - else - { - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - if (TREE_CODE ((yyval.ttype)) == TYPE_DECL) - (yyval.ttype) = TREE_TYPE ((yyval.ttype)); - } - ;} - break; - - case 651: -#line 2975 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = TREE_TYPE ((yyvsp[(2) - (2)].ttype)); ;} - break; - - case 652: -#line 2977 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_typename_type ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 653: -#line 2979 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_typename_type ((yyvsp[(1) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 654: -#line 2984 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (1)].ttype)) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", (yyvsp[(1) - (1)].ttype)); - ;} - break; - - case 655: -#line 2989 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE_CLASS (TREE_CODE ((yyvsp[(1) - (2)].ttype))) == 't') - (yyval.ttype) = make_typename_type ((yyvsp[(1) - (2)].ttype), (yyvsp[(2) - (2)].ttype)); - else if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", (yyvsp[(2) - (2)].ttype)); - else - { - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - if (TREE_CODE ((yyval.ttype)) == TYPE_DECL) - (yyval.ttype) = TREE_TYPE ((yyval.ttype)); - } - ;} - break; - - case 656: -#line 3002 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = (yyval.ttype) = make_typename_type ((yyvsp[(1) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 657: -#line 3004 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = (yyval.ttype) = make_typename_type ((yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 658: -#line 3009 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (2)].ttype)) != IDENTIFIER_NODE) - (yyvsp[(1) - (2)].ttype) = lastiddecl; - - /* Retrieve the type for the identifier, which might involve - some computation. */ - got_scope = (yyval.ttype) = complete_type (IDENTIFIER_TYPE_VALUE ((yyvsp[(1) - (2)].ttype))); - - if ((yyval.ttype) == error_mark_node) - cp_error ("`%T' is not a class or namespace", (yyvsp[(1) - (2)].ttype)); - ;} - break; - - case 659: -#line 3021 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(1) - (2)].ttype)) != IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype) = complete_type (TREE_TYPE ((yyval.ttype))); - ;} - break; - - case 660: -#line 3027 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = (yyval.ttype) = complete_type (TREE_TYPE ((yyval.ttype))); ;} - break; - - case 663: -#line 3031 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyval.ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = lastiddecl; - got_scope = (yyval.ttype); - ;} - break; - - case 664: -#line 3040 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_min_nt (TEMPLATE_ID_EXPR, (yyvsp[(1) - (4)].ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 665: -#line 3045 "../../../gbagnu/gcc/cp/parse.y" - { - if (TREE_CODE ((yyvsp[(2) - (2)].ttype)) == IDENTIFIER_NODE) - (yyval.ttype) = IDENTIFIER_GLOBAL_VALUE ((yyvsp[(2) - (2)].ttype)); - else - (yyval.ttype) = (yyvsp[(2) - (2)].ttype); - got_scope = NULL_TREE; - ;} - break; - - case 667: -#line 3054 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (2)].ttype); ;} - break; - - case 668: -#line 3059 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; ;} - break; - - case 669: -#line 3061 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); got_scope = NULL_TREE; ;} - break; - - case 670: -#line 3068 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = void_type_node; ;} - break; - - case 671: -#line 3074 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 672: -#line 3076 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (2)].ttype), NULL_TREE); ;} - break; - - case 673: -#line 3078 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 674: -#line 3080 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (2)].ttype), NULL_TREE); ;} - break; - - case 675: -#line 3082 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (2)].ttype), NULL_TREE); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (2)].ttype), arg); - ;} - break; - - case 676: -#line 3086 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 678: -#line 3095 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, NULL_TREE, (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 679: -#line 3097 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 680: -#line 3103 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 681: -#line 3105 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 682: -#line 3107 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (2)].ftype).t, NULL_TREE); ;} - break; - - case 683: -#line 3109 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator (NULL_TREE, NULL_TREE); ;} - break; - - case 684: -#line 3111 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 685: -#line 3113 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator (NULL_TREE, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 686: -#line 3115 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (2)].ftype).t, NULL_TREE); ;} - break; - - case 687: -#line 3117 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator (NULL_TREE, NULL_TREE); ;} - break; - - case 688: -#line 3119 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (2)].ttype), NULL_TREE); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (2)].ttype), arg); - ;} - break; - - case 689: -#line 3123 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 691: -#line 3132 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(2) - (3)].ttype); ;} - break; - - case 693: -#line 3136 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyval.ttype), (yyvsp[(3) - (6)].ttype), (yyvsp[(5) - (6)].ttype), (yyvsp[(6) - (6)].ttype)); ;} - break; - - case 694: -#line 3138 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator ((yyval.ttype), empty_parms (), (yyvsp[(3) - (4)].ttype), (yyvsp[(4) - (4)].ttype)); ;} - break; - - case 695: -#line 3140 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 696: -#line 3142 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, (yyval.ttype), NULL_TREE); ;} - break; - - case 697: -#line 3144 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_call_declarator (NULL_TREE, (yyvsp[(2) - (5)].ttype), (yyvsp[(4) - (5)].ttype), (yyvsp[(5) - (5)].ttype)); ;} - break; - - case 698: -#line 3146 "../../../gbagnu/gcc/cp/parse.y" - { set_quals_and_spec ((yyval.ttype), (yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 699: -#line 3148 "../../../gbagnu/gcc/cp/parse.y" - { set_quals_and_spec ((yyval.ttype), (yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 700: -#line 3150 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, NULL_TREE, (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 701: -#line 3152 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); ;} - break; - - case 708: -#line 3175 "../../../gbagnu/gcc/cp/parse.y" - { if (pedantic) - pedwarn ("ANSI C++ forbids label declarations"); ;} - break; - - case 711: -#line 3186 "../../../gbagnu/gcc/cp/parse.y" - { tree link; - for (link = (yyvsp[(2) - (3)].ttype); link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - ;} - break; - - case 712: -#line 3200 "../../../gbagnu/gcc/cp/parse.y" - {;} - break; - - case 714: -#line 3206 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_compound_stmt (0); ;} - break; - - case 715: -#line 3208 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_compound_stmt (0, (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 716: -#line 3213 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = begin_if_stmt (); - cond_stmt_keyword = "if"; - ;} - break; - - case 717: -#line 3218 "../../../gbagnu/gcc/cp/parse.y" - { finish_if_stmt_cond ((yyvsp[(3) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 718: -#line 3220 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_then_clause ((yyvsp[(2) - (5)].ttype)); ;} - break; - - case 720: -#line 3225 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_compound_stmt (0); ;} - break; - - case 721: -#line 3227 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_compound_stmt (0, (yyvsp[(1) - (2)].ttype)); ;} - break; - - case 722: -#line 3232 "../../../gbagnu/gcc/cp/parse.y" - {;} - break; - - case 724: -#line 3238 "../../../gbagnu/gcc/cp/parse.y" - { finish_stmt (); ;} - break; - - case 725: -#line 3240 "../../../gbagnu/gcc/cp/parse.y" - { finish_expr_stmt ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 726: -#line 3242 "../../../gbagnu/gcc/cp/parse.y" - { begin_else_clause (); ;} - break; - - case 727: -#line 3244 "../../../gbagnu/gcc/cp/parse.y" - { - finish_else_clause ((yyvsp[(1) - (4)].ttype)); - finish_if_stmt (); - ;} - break; - - case 728: -#line 3249 "../../../gbagnu/gcc/cp/parse.y" - { finish_if_stmt (); ;} - break; - - case 729: -#line 3251 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = begin_while_stmt (); - cond_stmt_keyword = "while"; - ;} - break; - - case 730: -#line 3256 "../../../gbagnu/gcc/cp/parse.y" - { finish_while_stmt_cond ((yyvsp[(3) - (3)].ttype), (yyvsp[(2) - (3)].ttype)); ;} - break; - - case 731: -#line 3258 "../../../gbagnu/gcc/cp/parse.y" - { finish_while_stmt ((yyvsp[(2) - (5)].ttype)); ;} - break; - - case 732: -#line 3260 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_do_stmt (); ;} - break; - - case 733: -#line 3262 "../../../gbagnu/gcc/cp/parse.y" - { - finish_do_body ((yyvsp[(2) - (4)].ttype)); - cond_stmt_keyword = "do"; - ;} - break; - - case 734: -#line 3267 "../../../gbagnu/gcc/cp/parse.y" - { finish_do_stmt ((yyvsp[(6) - (7)].ttype), (yyvsp[(2) - (7)].ttype)); ;} - break; - - case 735: -#line 3269 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_for_stmt (); ;} - break; - - case 736: -#line 3271 "../../../gbagnu/gcc/cp/parse.y" - { finish_for_init_stmt ((yyvsp[(2) - (4)].ttype)); ;} - break; - - case 737: -#line 3273 "../../../gbagnu/gcc/cp/parse.y" - { finish_for_cond ((yyvsp[(6) - (7)].ttype), (yyvsp[(2) - (7)].ttype)); ;} - break; - - case 738: -#line 3275 "../../../gbagnu/gcc/cp/parse.y" - { finish_for_expr ((yyvsp[(9) - (10)].ttype), (yyvsp[(2) - (10)].ttype)); ;} - break; - - case 739: -#line 3277 "../../../gbagnu/gcc/cp/parse.y" - { finish_for_stmt ((yyvsp[(9) - (12)].ttype), (yyvsp[(2) - (12)].ttype)); ;} - break; - - case 740: -#line 3279 "../../../gbagnu/gcc/cp/parse.y" - { begin_switch_stmt (); ;} - break; - - case 741: -#line 3281 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_switch_cond ((yyvsp[(4) - (5)].ttype)); ;} - break; - - case 742: -#line 3283 "../../../gbagnu/gcc/cp/parse.y" - { finish_switch_stmt ((yyvsp[(4) - (7)].ttype), (yyvsp[(6) - (7)].ttype)); ;} - break; - - case 743: -#line 3285 "../../../gbagnu/gcc/cp/parse.y" - { finish_case_label ((yyvsp[(2) - (3)].ttype), NULL_TREE); ;} - break; - - case 745: -#line 3288 "../../../gbagnu/gcc/cp/parse.y" - { finish_case_label ((yyvsp[(2) - (5)].ttype), (yyvsp[(4) - (5)].ttype)); ;} - break; - - case 747: -#line 3291 "../../../gbagnu/gcc/cp/parse.y" - { finish_case_label (NULL_TREE, NULL_TREE); ;} - break; - - case 749: -#line 3294 "../../../gbagnu/gcc/cp/parse.y" - { finish_break_stmt (); ;} - break; - - case 750: -#line 3296 "../../../gbagnu/gcc/cp/parse.y" - { finish_continue_stmt (); ;} - break; - - case 751: -#line 3298 "../../../gbagnu/gcc/cp/parse.y" - { finish_return_stmt (NULL_TREE); ;} - break; - - case 752: -#line 3300 "../../../gbagnu/gcc/cp/parse.y" - { finish_return_stmt ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 753: -#line 3302 "../../../gbagnu/gcc/cp/parse.y" - { - finish_asm_stmt ((yyvsp[(2) - (6)].ttype), (yyvsp[(4) - (6)].ttype), NULL_TREE, NULL_TREE, - NULL_TREE); - ;} - break; - - case 754: -#line 3308 "../../../gbagnu/gcc/cp/parse.y" - { - finish_asm_stmt ((yyvsp[(2) - (8)].ttype), (yyvsp[(4) - (8)].ttype), (yyvsp[(6) - (8)].ttype), NULL_TREE, - NULL_TREE); - ;} - break; - - case 755: -#line 3314 "../../../gbagnu/gcc/cp/parse.y" - { finish_asm_stmt ((yyvsp[(2) - (10)].ttype), (yyvsp[(4) - (10)].ttype), (yyvsp[(6) - (10)].ttype), (yyvsp[(8) - (10)].ttype), NULL_TREE); ;} - break; - - case 756: -#line 3318 "../../../gbagnu/gcc/cp/parse.y" - { finish_asm_stmt ((yyvsp[(2) - (12)].ttype), (yyvsp[(4) - (12)].ttype), (yyvsp[(6) - (12)].ttype), (yyvsp[(8) - (12)].ttype), (yyvsp[(10) - (12)].ttype)); ;} - break; - - case 757: -#line 3320 "../../../gbagnu/gcc/cp/parse.y" - { - if (pedantic) - pedwarn ("ANSI C++ forbids computed gotos"); - finish_goto_stmt ((yyvsp[(3) - (4)].ttype)); - ;} - break; - - case 758: -#line 3326 "../../../gbagnu/gcc/cp/parse.y" - { finish_goto_stmt ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 759: -#line 3328 "../../../gbagnu/gcc/cp/parse.y" - { finish_stmt (); ;} - break; - - case 760: -#line 3330 "../../../gbagnu/gcc/cp/parse.y" - { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); ;} - break; - - case 761: -#line 3334 "../../../gbagnu/gcc/cp/parse.y" - { finish_stmt (); ;} - break; - - case 764: -#line 3338 "../../../gbagnu/gcc/cp/parse.y" - { do_local_using_decl ((yyvsp[(1) - (1)].ttype)); ;} - break; - - case 766: -#line 3344 "../../../gbagnu/gcc/cp/parse.y" - { - if (! current_function_parms_stored) - store_parm_decls (); - expand_start_early_try_stmts (); - ;} - break; - - case 767: -#line 3350 "../../../gbagnu/gcc/cp/parse.y" - { - expand_start_all_catch (); - ;} - break; - - case 768: -#line 3354 "../../../gbagnu/gcc/cp/parse.y" - { - expand_end_all_catch (); - (yyval.itype) = (yyvsp[(3) - (6)].itype); - ;} - break; - - case 769: -#line 3362 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_try_block (); ;} - break; - - case 770: -#line 3364 "../../../gbagnu/gcc/cp/parse.y" - { finish_try_block ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 771: -#line 3366 "../../../gbagnu/gcc/cp/parse.y" - { finish_handler_sequence ((yyvsp[(2) - (5)].ttype)); ;} - break; - - case 774: -#line 3376 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = begin_handler(); ;} - break; - - case 775: -#line 3378 "../../../gbagnu/gcc/cp/parse.y" - { finish_handler_parms ((yyvsp[(2) - (3)].ttype)); ;} - break; - - case 776: -#line 3380 "../../../gbagnu/gcc/cp/parse.y" - { finish_handler ((yyvsp[(2) - (5)].ttype)); ;} - break; - - case 779: -#line 3390 "../../../gbagnu/gcc/cp/parse.y" - { expand_start_catch_block (NULL_TREE, NULL_TREE); ;} - break; - - case 780: -#line 3406 "../../../gbagnu/gcc/cp/parse.y" - { check_for_new_type ("inside exception declarations", (yyvsp[(2) - (3)].ftype)); - expand_start_catch_block (TREE_PURPOSE ((yyvsp[(2) - (3)].ftype).t), - TREE_VALUE ((yyvsp[(2) - (3)].ftype).t)); ;} - break; - - case 781: -#line 3413 "../../../gbagnu/gcc/cp/parse.y" - { tree label; - do_label: - label = define_label (input_filename, lineno, (yyvsp[(1) - (2)].ttype)); - if (label && ! minimal_parse_mode) - expand_label (label); - ;} - break; - - case 782: -#line 3420 "../../../gbagnu/gcc/cp/parse.y" - { goto do_label; ;} - break; - - case 783: -#line 3422 "../../../gbagnu/gcc/cp/parse.y" - { goto do_label; ;} - break; - - case 784: -#line 3424 "../../../gbagnu/gcc/cp/parse.y" - { goto do_label; ;} - break; - - case 785: -#line 3429 "../../../gbagnu/gcc/cp/parse.y" - { if ((yyvsp[(1) - (2)].ttype)) cplus_expand_expr_stmt ((yyvsp[(1) - (2)].ttype)); ;} - break; - - case 787: -#line 3432 "../../../gbagnu/gcc/cp/parse.y" - { if (pedantic) - pedwarn ("ANSI C++ forbids compound statements inside for initializations"); - ;} - break; - - case 788: -#line 3441 "../../../gbagnu/gcc/cp/parse.y" - { emit_line_note (input_filename, lineno); - (yyval.ttype) = NULL_TREE; ;} - break; - - case 789: -#line 3444 "../../../gbagnu/gcc/cp/parse.y" - { emit_line_note (input_filename, lineno); ;} - break; - - case 790: -#line 3449 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 792: -#line 3452 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 793: -#line 3459 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 796: -#line 3466 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyval.ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 797: -#line 3471 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_tree_list ((yyval.ttype), (yyvsp[(3) - (4)].ttype)); ;} - break; - - case 798: -#line 3476 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = tree_cons (NULL_TREE, (yyval.ttype), NULL_TREE); ;} - break; - - case 799: -#line 3478 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = tree_cons (NULL_TREE, (yyvsp[(3) - (3)].ttype), (yyval.ttype)); ;} - break; - - case 800: -#line 3489 "../../../gbagnu/gcc/cp/parse.y" - { - (yyval.ttype) = empty_parms(); - ;} - break; - - case 802: -#line 3494 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist (build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ftype).t), 0); - check_for_new_type ("inside parameter list", (yyvsp[(1) - (1)].ftype)); ;} - break; - - case 803: -#line 3502 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist ((yyval.ttype), 0); ;} - break; - - case 804: -#line 3504 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist ((yyvsp[(1) - (2)].ttype), 1); ;} - break; - - case 805: -#line 3507 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist ((yyvsp[(1) - (2)].ttype), 1); ;} - break; - - case 806: -#line 3509 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist (build_tree_list (NULL_TREE, - (yyvsp[(1) - (2)].ftype).t), 1); ;} - break; - - case 807: -#line 3512 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = finish_parmlist (NULL_TREE, 1); ;} - break; - - case 808: -#line 3514 "../../../gbagnu/gcc/cp/parse.y" - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - (yyval.ttype) = finish_parmlist ((yyvsp[(1) - (2)].ttype), 0); - yyungetc (':', 0); - yychar = ')'; - ;} - break; - - case 809: -#line 3524 "../../../gbagnu/gcc/cp/parse.y" - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - (yyval.ttype) = finish_parmlist (build_tree_list (NULL_TREE, - (yyvsp[(1) - (2)].ftype).t), 0); - yyungetc (':', 0); - yychar = ')'; - ;} - break; - - case 810: -#line 3539 "../../../gbagnu/gcc/cp/parse.y" - { maybe_snarf_defarg (); ;} - break; - - case 811: -#line 3541 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(3) - (3)].ttype); ;} - break; - - case 814: -#line 3552 "../../../gbagnu/gcc/cp/parse.y" - { check_for_new_type ("in a parameter list", (yyvsp[(1) - (1)].ftype)); - (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ftype).t); ;} - break; - - case 815: -#line 3555 "../../../gbagnu/gcc/cp/parse.y" - { check_for_new_type ("in a parameter list", (yyvsp[(1) - (2)].ftype)); - (yyval.ttype) = build_tree_list ((yyvsp[(2) - (2)].ttype), (yyvsp[(1) - (2)].ftype).t); ;} - break; - - case 816: -#line 3558 "../../../gbagnu/gcc/cp/parse.y" - { check_for_new_type ("in a parameter list", (yyvsp[(2) - (2)].ftype)); - (yyval.ttype) = chainon ((yyval.ttype), (yyvsp[(2) - (2)].ftype).t); ;} - break; - - case 817: -#line 3561 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyval.ttype), build_tree_list (NULL_TREE, (yyvsp[(2) - (2)].ttype))); ;} - break; - - case 818: -#line 3563 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = chainon ((yyval.ttype), build_tree_list ((yyvsp[(4) - (4)].ttype), (yyvsp[(2) - (4)].ttype))); ;} - break; - - case 820: -#line 3569 "../../../gbagnu/gcc/cp/parse.y" - { check_for_new_type ("in a parameter list", (yyvsp[(1) - (2)].ftype)); - (yyval.ttype) = build_tree_list (NULL_TREE, (yyvsp[(1) - (2)].ftype).t); ;} - break; - - case 821: -#line 3579 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(1) - (2)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; - (yyval.ftype).t = build_tree_list (specs, (yyvsp[(2) - (2)].ttype)); ;} - break; - - case 822: -#line 3583 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_tree_list ((yyvsp[(1) - (2)].ftype).t, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 823: -#line 3586 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_tree_list (get_decl_list ((yyvsp[(1) - (2)].ftype).t), (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 824: -#line 3589 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(1) - (2)].ftype).t); - (yyval.ftype).t = build_tree_list (specs, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 825: -#line 3593 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(1) - (1)].ftype).t); - (yyval.ftype).t = build_tree_list (specs, NULL_TREE); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 826: -#line 3597 "../../../gbagnu/gcc/cp/parse.y" - { tree specs = strip_attrs ((yyvsp[(1) - (2)].ttype)); - (yyval.ftype).t = build_tree_list (specs, (yyvsp[(2) - (2)].ttype)); - (yyval.ftype).new_type_flag = 0; ;} - break; - - case 827: -#line 3604 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_tree_list (NULL_TREE, (yyvsp[(1) - (1)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (1)].ftype).new_type_flag; ;} - break; - - case 828: -#line 3607 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ftype).t = build_tree_list ((yyvsp[(2) - (2)].ttype), (yyvsp[(1) - (2)].ftype).t); - (yyval.ftype).new_type_flag = (yyvsp[(1) - (2)].ftype).new_type_flag; ;} - break; - - case 831: -#line 3618 "../../../gbagnu/gcc/cp/parse.y" - { see_typename (); ;} - break; - - case 832: -#line 3623 "../../../gbagnu/gcc/cp/parse.y" - { - error ("type specifier omitted for parameter"); - (yyval.ttype) = build_tree_list (integer_type_node, NULL_TREE); - ;} - break; - - case 833: -#line 3628 "../../../gbagnu/gcc/cp/parse.y" - { - error ("type specifier omitted for parameter"); - if (TREE_CODE ((yyval.ttype)) == SCOPE_REF - && (TREE_CODE (TREE_OPERAND ((yyval.ttype), 0)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_OPERAND ((yyval.ttype), 0)) == TEMPLATE_TEMPLATE_PARM)) - cp_error (" perhaps you want `typename %E' to make it a type", (yyval.ttype)); - (yyval.ttype) = build_tree_list (integer_type_node, (yyval.ttype)); - ;} - break; - - case 834: -#line 3640 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 835: -#line 3642 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = (yyvsp[(3) - (4)].ttype); ;} - break; - - case 836: -#line 3644 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_decl_list (NULL_TREE, NULL_TREE); ;} - break; - - case 837: -#line 3649 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = build_decl_list (NULL_TREE, groktypename((yyvsp[(1) - (1)].ftype).t)); ;} - break; - - case 839: -#line 3655 "../../../gbagnu/gcc/cp/parse.y" - { - TREE_CHAIN ((yyvsp[(3) - (3)].ttype)) = (yyval.ttype); - (yyval.ttype) = (yyvsp[(3) - (3)].ttype); - ;} - break; - - case 840: -#line 3663 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = NULL_TREE; ;} - break; - - case 841: -#line 3665 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 842: -#line 3667 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = make_reference_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 843: -#line 3669 "../../../gbagnu/gcc/cp/parse.y" - { tree arg = make_pointer_declarator ((yyvsp[(2) - (3)].ttype), (yyvsp[(3) - (3)].ttype)); - (yyval.ttype) = build_parse_node (SCOPE_REF, (yyvsp[(1) - (3)].ttype), arg); - ;} - break; - - case 844: -#line 3676 "../../../gbagnu/gcc/cp/parse.y" - { got_scope = NULL_TREE; ;} - break; - - case 845: -#line 3681 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[MULT_EXPR]; ;} - break; - - case 846: -#line 3683 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[TRUNC_DIV_EXPR]; ;} - break; - - case 847: -#line 3685 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[TRUNC_MOD_EXPR]; ;} - break; - - case 848: -#line 3687 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[PLUS_EXPR]; ;} - break; - - case 849: -#line 3689 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[MINUS_EXPR]; ;} - break; - - case 850: -#line 3691 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[BIT_AND_EXPR]; ;} - break; - - case 851: -#line 3693 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[BIT_IOR_EXPR]; ;} - break; - - case 852: -#line 3695 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[BIT_XOR_EXPR]; ;} - break; - - case 853: -#line 3697 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[BIT_NOT_EXPR]; ;} - break; - - case 854: -#line 3699 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[COMPOUND_EXPR]; ;} - break; - - case 855: -#line 3701 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 856: -#line 3703 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[LT_EXPR]; ;} - break; - - case 857: -#line 3705 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[GT_EXPR]; ;} - break; - - case 858: -#line 3707 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 859: -#line 3709 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_assopname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 860: -#line 3711 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname [MODIFY_EXPR]; ;} - break; - - case 861: -#line 3713 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 862: -#line 3715 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 863: -#line 3717 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[POSTINCREMENT_EXPR]; ;} - break; - - case 864: -#line 3719 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[PREDECREMENT_EXPR]; ;} - break; - - case 865: -#line 3721 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[TRUTH_ANDIF_EXPR]; ;} - break; - - case 866: -#line 3723 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[TRUTH_ORIF_EXPR]; ;} - break; - - case 867: -#line 3725 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[TRUTH_NOT_EXPR]; ;} - break; - - case 868: -#line 3727 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[COND_EXPR]; ;} - break; - - case 869: -#line 3729 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[(yyvsp[(2) - (2)].code)]; ;} - break; - - case 870: -#line 3731 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[COMPONENT_REF]; ;} - break; - - case 871: -#line 3733 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[MEMBER_REF]; ;} - break; - - case 872: -#line 3735 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[CALL_EXPR]; ;} - break; - - case 873: -#line 3737 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[ARRAY_REF]; ;} - break; - - case 874: -#line 3739 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[NEW_EXPR]; ;} - break; - - case 875: -#line 3741 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[DELETE_EXPR]; ;} - break; - - case 876: -#line 3743 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[VEC_NEW_EXPR]; ;} - break; - - case 877: -#line 3745 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[VEC_DELETE_EXPR]; ;} - break; - - case 878: -#line 3748 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = grokoptypename ((yyvsp[(2) - (3)].ftype).t, (yyvsp[(3) - (3)].ttype)); ;} - break; - - case 879: -#line 3750 "../../../gbagnu/gcc/cp/parse.y" - { (yyval.ttype) = ansi_opname[ERROR_MARK]; ;} - break; - - -/* Line 1267 of yacc.c. */ -#line 9589 "parse.c" - default: break; - } - YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); - - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - - *++yyvsp = yyval; - - - /* 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 - YYNTOKENS] + *yyssp; - if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) - yystate = yytable[yystate]; - else - yystate = yydefgoto[yyn - YYNTOKENS]; - - goto yynewstate; - - -/*------------------------------------. -| yyerrlab -- here on detecting error | -`------------------------------------*/ -yyerrlab: - /* If not already recovering from an error, report this error. */ - if (!yyerrstatus) - { - ++yynerrs; -#if ! YYERROR_VERBOSE - yyerror (YY_("syntax error")); -#else - { - YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); - if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) - { - YYSIZE_T yyalloc = 2 * yysize; - if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) - yyalloc = YYSTACK_ALLOC_MAXIMUM; - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); - yymsg = (char *) YYSTACK_ALLOC (yyalloc); - if (yymsg) - yymsg_alloc = yyalloc; - else - { - yymsg = yymsgbuf; - yymsg_alloc = sizeof yymsgbuf; - } - } - - if (0 < yysize && yysize <= yymsg_alloc) - { - (void) yysyntax_error (yymsg, yystate, yychar); - yyerror (yymsg); - } - else - { - yyerror (YY_("syntax error")); - if (yysize != 0) - goto yyexhaustedlab; - } - } -#endif - } - - - - if (yyerrstatus == 3) - { - /* If just tried and failed to reuse look-ahead token after an - error, discard it. */ - - if (yychar <= YYEOF) - { - /* Return failure if at end of input. */ - if (yychar == YYEOF) - YYABORT; - } - else - { - yydestruct ("Error: discarding", - yytoken, &yylval); - yychar = YYEMPTY; - } - } - - /* Else will try to reuse look-ahead token after shifting the error - token. */ - goto yyerrlab1; - - -/*---------------------------------------------------. -| yyerrorlab -- error raised explicitly by YYERROR. | -`---------------------------------------------------*/ -yyerrorlab: - - /* Pacify compilers like GCC when the user code never invokes - YYERROR and the label yyerrorlab therefore never appears in user - code. */ - if (/*CONSTCOND*/ 0) - goto yyerrorlab; - - /* Do not reclaim the symbols of the rule which action triggered - this YYERROR. */ - YYPOPSTACK (yylen); - yylen = 0; - YY_STACK_PRINT (yyss, yyssp); - yystate = *yyssp; - goto yyerrlab1; - - -/*-------------------------------------------------------------. -| yyerrlab1 -- common code for both syntax error and YYERROR. | -`-------------------------------------------------------------*/ -yyerrlab1: - yyerrstatus = 3; /* Each real token shifted decrements this. */ - - for (;;) - { - yyn = yypact[yystate]; - if (yyn != YYPACT_NINF) - { - yyn += YYTERROR; - if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) - { - yyn = yytable[yyn]; - if (0 < yyn) - break; - } - } - - /* Pop the current state because it cannot handle the error token. */ - if (yyssp == yyss) - YYABORT; - - - yydestruct ("Error: popping", - yystos[yystate], yyvsp); - YYPOPSTACK (1); - yystate = *yyssp; - YY_STACK_PRINT (yyss, yyssp); - } - - if (yyn == YYFINAL) - YYACCEPT; - - *++yyvsp = yylval; - - - /* Shift the error token. */ - YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); - - yystate = yyn; - goto yynewstate; - - -/*-------------------------------------. -| yyacceptlab -- YYACCEPT comes here. | -`-------------------------------------*/ -yyacceptlab: - yyresult = 0; - goto yyreturn; - -/*-----------------------------------. -| yyabortlab -- YYABORT comes here. | -`-----------------------------------*/ -yyabortlab: - yyresult = 1; - goto yyreturn; - -#ifndef yyoverflow -/*-------------------------------------------------. -| yyexhaustedlab -- memory exhaustion comes here. | -`-------------------------------------------------*/ -yyexhaustedlab: - yyerror (YY_("memory exhausted")); - yyresult = 2; - /* Fall through. */ -#endif - -yyreturn: - if (yychar != YYEOF && yychar != YYEMPTY) - yydestruct ("Cleanup: discarding lookahead", - yytoken, &yylval); - /* Do not reclaim the symbols of the rule which action triggered - this YYABORT or YYACCEPT. */ - YYPOPSTACK (yylen); - YY_STACK_PRINT (yyss, yyssp); - while (yyssp != yyss) - { - yydestruct ("Cleanup: popping", - yystos[*yyssp], yyvsp); - YYPOPSTACK (1); - } -#ifndef yyoverflow - if (yyss != yyssa) - YYSTACK_FREE (yyss); -#endif -#if YYERROR_VERBOSE - if (yymsg != yymsgbuf) - YYSTACK_FREE (yymsg); -#endif - /* Make sure YYID is used. */ - return YYID (yyresult); -} - - -#line 3753 "../../../gbagnu/gcc/cp/parse.y" - - -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} - -#endif - diff --git a/gcc/cp/parse.h b/gcc/cp/parse.h deleted file mode 100644 index c9ade82..0000000 --- a/gcc/cp/parse.h +++ /dev/null @@ -1,140 +0,0 @@ -/* A Bison parser, made by GNU Bison 2.3. */ - -/* Skeleton interface for Bison's Yacc-like parsers in C - - Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 - Free Software Foundation, Inc. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the 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., 51 Franklin Street, Fifth Floor, - Boston, MA 02110-1301, USA. */ - -/* As a special exception, you may create a larger work that contains - part or all of the Bison parser skeleton and distribute that work - under terms of your choice, so long as that work isn't itself a - parser generator using the skeleton or a modified version thereof - as a parser skeleton. Alternatively, if you modify or redistribute - the parser skeleton itself, you may (at your option) remove this - special exception, which will cause the skeleton and the resulting - Bison output files to be licensed under the GNU General Public - License without this special exception. - - This special exception was added by the Free Software Foundation in - version 2.2 of Bison. */ - -/* Tokens. */ -#define IDENTIFIER 258 -#define TYPENAME 259 -#define SELFNAME 260 -#define PFUNCNAME 261 -#define SCSPEC 262 -#define TYPESPEC 263 -#define CV_QUALIFIER 264 -#define CONSTANT 265 -#define STRING 266 -#define ELLIPSIS 267 -#define SIZEOF 268 -#define ENUM 269 -#define IF 270 -#define ELSE 271 -#define WHILE 272 -#define DO 273 -#define FOR 274 -#define SWITCH 275 -#define CASE 276 -#define DEFAULT 277 -#define BREAK 278 -#define CONTINUE 279 -#define RETURN 280 -#define GOTO 281 -#define ASM_KEYWORD 282 -#define TYPEOF 283 -#define ALIGNOF 284 -#define SIGOF 285 -#define ATTRIBUTE 286 -#define EXTENSION 287 -#define LABEL 288 -#define REALPART 289 -#define IMAGPART 290 -#define AGGR 291 -#define VISSPEC 292 -#define DELETE 293 -#define NEW 294 -#define THIS 295 -#define OPERATOR 296 -#define CXX_TRUE 297 -#define CXX_FALSE 298 -#define NAMESPACE 299 -#define TYPENAME_KEYWORD 300 -#define USING 301 -#define LEFT_RIGHT 302 -#define TEMPLATE 303 -#define TYPEID 304 -#define DYNAMIC_CAST 305 -#define STATIC_CAST 306 -#define REINTERPRET_CAST 307 -#define CONST_CAST 308 -#define SCOPE 309 -#define EMPTY 310 -#define NSNAME 311 -#define PTYPENAME 312 -#define THROW 313 -#define ASSIGN 314 -#define OROR 315 -#define ANDAND 316 -#define MIN_MAX 317 -#define EQCOMPARE 318 -#define ARITHCOMPARE 319 -#define RSHIFT 320 -#define LSHIFT 321 -#define DOT_STAR 322 -#define POINTSAT_STAR 323 -#define MINUSMINUS 324 -#define PLUSPLUS 325 -#define UNARY 326 -#define HYPERUNARY 327 -#define PAREN_STAR_PAREN 328 -#define POINTSAT 329 -#define CATCH 330 -#define TRY 331 -#define PRE_PARSED_FUNCTION_DECL 332 -#define EXTERN_LANG_STRING 333 -#define ALL 334 -#define PRE_PARSED_CLASS_DECL 335 -#define DEFARG 336 -#define DEFARG_MARKER 337 -#define TYPENAME_DEFN 338 -#define IDENTIFIER_DEFN 339 -#define PTYPENAME_DEFN 340 -#define END_OF_LINE 341 -#define END_OF_SAVED_INPUT 342 - - - - -#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED -typedef union YYSTYPE -#line 92 "../../../gbagnu/gcc/cp/parse.y" -{long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } -/* Line 1489 of yacc.c. */ -#line 225 "parse.h" - YYSTYPE; -# define yystype YYSTYPE /* obsolescent; will be withdrawn */ -# define YYSTYPE_IS_DECLARED 1 -# define YYSTYPE_IS_TRIVIAL 1 -#endif - -extern YYSTYPE yylval; - -#define YYEMPTY (-2) diff --git a/gcc/cp/parse.y b/gcc/cp/parse.y deleted file mode 100755 index 4970515..0000000 --- a/gcc/cp/parse.y +++ /dev/null @@ -1,3763 +0,0 @@ -/* YACC parser for C++ syntax. - Copyright (C) 1988, 89, 93-97, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This grammar is based on the GNU CC grammar. */ - -/* Note: Bison automatically applies a default action of "$$ = $1" for - all derivations; this is applied before the explicit action, if one - is given. Keep this in mind when reading the actions. */ - -%{ -/* Cause the `yydebug' variable to be defined. */ -#define YYDEBUG 1 - -#include "config.h" - -#include "system.h" - -#include "tree.h" -#include "input.h" -#include "flags.h" -#include "lex.h" -#include "cp-tree.h" -#include "output.h" -#include "except.h" -#include "toplev.h" - -/* Since parsers are distinct for each language, put the language string - definition here. (fnf) */ -char *language_string = "GNU C++"; - -extern tree void_list_node; -extern struct obstack permanent_obstack; - -extern int end_of_file; - -/* Like YYERROR but do call yyerror. */ -#define YYERROR1 { yyerror ("syntax error"); YYERROR; } - -#define OP0(NODE) (TREE_OPERAND (NODE, 0)) -#define OP1(NODE) (TREE_OPERAND (NODE, 1)) - -/* Contains the statement keyword (if/while/do) to include in an - error message if the user supplies an empty conditional expression. */ -static char *cond_stmt_keyword; - -static tree empty_parms PROTO((void)); - -/* Nonzero if we have an `extern "C"' acting as an extern specifier. */ -int have_extern_spec; -int used_extern_spec; - -/* Cons up an empty parameter list. */ -#ifdef __GNUC__ -__inline -#endif -static tree -empty_parms () -{ - tree parms; - - if (strict_prototype - || current_class_type != NULL) - parms = void_list_node; - else - parms = NULL_TREE; - return parms; -} - -%} - -%start program - -%union {long itype; tree ttype; char *strtype; enum tree_code code; flagged_type_tree ftype; } - -/* All identifiers that are not reserved words - and are not declared typedefs in the current block */ -%token IDENTIFIER - -/* All identifiers that are declared typedefs in the current block. - In some contexts, they are treated just like IDENTIFIER, - but they can also serve as typespecs in declarations. */ -%token TYPENAME -%token SELFNAME - -/* A template function. */ -%token PFUNCNAME - -/* Reserved words that specify storage class. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token SCSPEC - -/* Reserved words that specify type. - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token TYPESPEC - -/* Reserved words that qualify type: "const" or "volatile". - yylval contains an IDENTIFIER_NODE which indicates which one. */ -%token CV_QUALIFIER - -/* Character or numeric constants. - yylval is the node for the constant. */ -%token CONSTANT - -/* String constants in raw form. - yylval is a STRING_CST node. */ -%token STRING - -/* "...", used for functions with variable arglists. */ -%token ELLIPSIS - -/* the reserved words */ -/* SCO include files test "ASM", so use something else. */ -%token SIZEOF ENUM /* STRUCT UNION */ IF ELSE WHILE DO FOR SWITCH CASE DEFAULT -%token BREAK CONTINUE RETURN GOTO ASM_KEYWORD TYPEOF ALIGNOF -%token SIGOF -%token ATTRIBUTE EXTENSION LABEL -%token REALPART IMAGPART - -/* the reserved words... C++ extensions */ -%token <ttype> AGGR -%token <ttype> VISSPEC -%token DELETE NEW THIS OPERATOR CXX_TRUE CXX_FALSE -%token NAMESPACE TYPENAME_KEYWORD USING -%token LEFT_RIGHT TEMPLATE -%token TYPEID DYNAMIC_CAST STATIC_CAST REINTERPRET_CAST CONST_CAST -%token <itype> SCOPE - -/* Define the operator tokens and their precedences. - The value is an integer because, if used, it is the tree code - to use in the expression made from the operator. */ - -%left EMPTY /* used to resolve s/r with epsilon */ - -%left error - -/* Add precedence rules to solve dangling else s/r conflict */ -%nonassoc IF -%nonassoc ELSE - -%left IDENTIFIER PFUNCNAME TYPENAME SELFNAME PTYPENAME SCSPEC TYPESPEC CV_QUALIFIER ENUM AGGR ELLIPSIS TYPEOF SIGOF OPERATOR NSNAME TYPENAME_KEYWORD - -%left '{' ',' ';' - -%nonassoc THROW -%right <code> ':' -%right <code> ASSIGN '=' -%right <code> '?' -%left <code> OROR -%left <code> ANDAND -%left <code> '|' -%left <code> '^' -%left <code> '&' -%left <code> MIN_MAX -%left <code> EQCOMPARE -%left <code> ARITHCOMPARE '<' '>' -%left <code> LSHIFT RSHIFT -%left <code> '+' '-' -%left <code> '*' '/' '%' -%left <code> POINTSAT_STAR DOT_STAR -%right <code> UNARY PLUSPLUS MINUSMINUS '~' -%left HYPERUNARY -%left <ttype> PAREN_STAR_PAREN LEFT_RIGHT -%left <code> POINTSAT '.' '(' '[' - -%right SCOPE /* C++ extension */ -%nonassoc NEW DELETE TRY CATCH - -%type <code> unop - -%type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist -%type <ttype> PFUNCNAME maybe_identifier -%type <ttype> paren_expr_or_null nontrivial_exprlist SELFNAME -%type <ttype> expr_no_commas cast_expr unary_expr primary string STRING -%type <ttype> reserved_declspecs boolean.literal -%type <ttype> reserved_typespecquals -%type <ttype> declmods -%type <ttype> SCSPEC TYPESPEC CV_QUALIFIER maybe_cv_qualifier -%type <itype> initdecls notype_initdecls initdcl /* C++ modification */ -%type <ttype> init initlist maybeasm maybe_init defarg defarg1 -%type <ttype> asm_operands nonnull_asm_operands asm_operand asm_clobbers -%type <ttype> maybe_attribute attributes attribute attribute_list attrib -%type <ttype> any_word - -%type <ttype> compstmt implicitly_scoped_stmt - -%type <ttype> declarator notype_declarator after_type_declarator -%type <ttype> notype_declarator_intern -%type <ttype> direct_notype_declarator direct_after_type_declarator -%type <itype> components notype_components -%type <ttype> component_decl component_decl_1 -%type <ttype> component_declarator component_declarator0 -%type <ttype> notype_component_declarator notype_component_declarator0 -%type <ttype> after_type_component_declarator after_type_component_declarator0 -%type <ttype> enumlist enumerator -%type <ttype> absdcl cv_qualifiers -%type <ttype> direct_abstract_declarator conversion_declarator -%type <ttype> new_declarator direct_new_declarator -%type <ttype> xexpr parmlist parms bad_parm -%type <ttype> identifiers_or_typenames -%type <ttype> fcast_or_absdcl regcast_or_absdcl -%type <ttype> expr_or_declarator expr_or_declarator_intern -%type <ttype> complex_notype_declarator -%type <ttype> notype_unqualified_id unqualified_id qualified_id -%type <ttype> template_id do_id object_template_id notype_template_declarator -%type <ttype> overqualified_id notype_qualified_id any_id -%type <ttype> complex_direct_notype_declarator functional_cast -%type <ttype> complex_parmlist parms_comma -%type <ttype> namespace_qualifier namespace_using_decl - -%type <ftype> type_id new_type_id typed_typespecs typespec typed_declspecs -%type <ftype> typed_declspecs1 type_specifier_seq nonempty_cv_qualifiers -%type <ftype> structsp typespecqual_reserved parm named_parm full_parm - -/* C++ extensions */ -%token <ttype> PTYPENAME -%token <ttype> PRE_PARSED_FUNCTION_DECL EXTERN_LANG_STRING ALL -%token <ttype> PRE_PARSED_CLASS_DECL DEFARG DEFARG_MARKER -%type <ttype> component_constructor_declarator -%type <ttype> fn.def2 return_id fn.defpen constructor_declarator -%type <itype> ctor_initializer_opt function_try_block -%type <ttype> named_class_head named_class_head_sans_basetype -%type <ttype> named_complex_class_head_sans_basetype -%type <ttype> unnamed_class_head -%type <ttype> class_head base_class_list -%type <ttype> base_class_access_list -%type <ttype> base_class maybe_base_class_list base_class.1 -%type <ttype> exception_specification_opt ansi_raise_identifier ansi_raise_identifiers -%type <ttype> operator_name -%type <ttype> object aggr -%type <itype> new delete .begin_new_placement -/* %type <ttype> primary_no_id */ -%type <ttype> nonmomentary_expr maybe_parmlist -%type <itype> initdcl0 notype_initdcl0 member_init_list initdcl0_innards -%type <ttype> template_header template_parm_list template_parm -%type <ttype> template_type_parm template_template_parm -%type <code> template_close_bracket -%type <ttype> apparent_template_type -%type <ttype> template_type template_arg_list template_arg_list_opt -%type <ttype> template_arg -%type <ttype> condition xcond paren_cond_or_null -%type <ttype> type_name nested_name_specifier nested_type ptr_to_mem -%type <ttype> complete_type_name notype_identifier nonnested_type -%type <ttype> complex_type_name nested_name_specifier_1 -%type <ttype> new_initializer new_placement -%type <ttype> using_decl -%type <ttype> typename_sub typename_sub0 typename_sub1 typename_sub2 -%type <ttype> explicit_template_type -/* in order to recognize aggr tags as defining and thus shadowing. */ -%token TYPENAME_DEFN IDENTIFIER_DEFN PTYPENAME_DEFN -%type <ttype> named_class_head_sans_basetype_defn -%type <ttype> identifier_defn IDENTIFIER_DEFN TYPENAME_DEFN PTYPENAME_DEFN - -%type <ttype> self_template_type .finish_template_type - -%token NSNAME -%type <ttype> NSNAME - -/* Used in lex.c for parsing pragmas. */ -%token END_OF_LINE - -/* lex.c and pt.c depend on this being the last token. Define - any new tokens before this one! */ -%token END_OF_SAVED_INPUT - -%{ -/* List of types and structure classes of the current declaration. */ -static tree current_declspecs; - -/* List of prefix attributes in effect. - Prefix attributes are parsed by the reserved_declspecs and declmods - rules. They create a list that contains *both* declspecs and attrs. */ -/* ??? It is not clear yet that all cases where an attribute can now appear in - a declspec list have been updated. */ -static tree prefix_attributes; - -/* When defining an aggregate, this is the kind of the most recent one - being defined. (For example, this might be class_type_node.) */ -static tree current_aggr; - -/* When defining an enumeration, this is the type of the enumeration. */ -static tree current_enum_type; - -/* Tell yyparse how to print a token's value, if yydebug is set. */ - -#define YYPRINT(FILE,YYCHAR,YYLVAL) yyprint(FILE,YYCHAR,YYLVAL) -extern void yyprint PROTO((FILE *, int, YYSTYPE)); -extern tree combine_strings PROTO((tree)); - -static int -parse_decl(declarator, specs_attrs, attributes, initialized, decl) - tree declarator; - tree specs_attrs; - tree attributes; - int initialized; - tree* decl; -{ - int sm; - - split_specs_attrs (specs_attrs, ¤t_declspecs, &prefix_attributes); - if (current_declspecs - && TREE_CODE (current_declspecs) != TREE_LIST) - current_declspecs = get_decl_list (current_declspecs); - if (have_extern_spec && !used_extern_spec) - { - current_declspecs = decl_tree_cons (NULL_TREE, - get_identifier ("extern"), - current_declspecs); - used_extern_spec = 1; - } - sm = suspend_momentary (); - *decl = start_decl (declarator, current_declspecs, initialized, - attributes, prefix_attributes); - return sm; -} -%} - -%% -program: - /* empty */ - | extdefs - { finish_translation_unit (); } - ; - -/* the reason for the strange actions in this rule - is so that notype_initdecls when reached via datadef - can find a valid list of type and sc specs in $0. */ - -extdefs: - { $<ttype>$ = NULL_TREE; } - lang_extdef - { $<ttype>$ = NULL_TREE; } - | extdefs lang_extdef - { $<ttype>$ = NULL_TREE; } - ; - -extdefs_opt: - extdefs - | /* empty */ - ; - -.hush_warning: - { have_extern_spec = 1; - used_extern_spec = 0; - $<ttype>$ = NULL_TREE; } - ; -.warning_ok: - { have_extern_spec = 0; } - ; - -extension: - EXTENSION - { $<itype>$ = pedantic; - pedantic = 0; } - ; - -asm_keyword: - ASM_KEYWORD - ; - -lang_extdef: - { if (pending_lang_change) do_pending_lang_change(); } - extdef - { if (! toplevel_bindings_p () && ! pseudo_global_level_p()) - pop_everything (); } - ; - -extdef: - fndef eat_saved_input - { if (pending_inlines) do_pending_inlines (); } - | datadef - { if (pending_inlines) do_pending_inlines (); } - | template_def - { if (pending_inlines) do_pending_inlines (); } - | asm_keyword '(' string ')' ';' - { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); - assemble_asm ($3); } - | extern_lang_string '{' extdefs_opt '}' - { pop_lang_context (); } - | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } - | extern_lang_string .hush_warning datadef .warning_ok - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } - | NAMESPACE identifier '{' - { push_namespace ($2); } - extdefs_opt '}' - { pop_namespace (); } - | NAMESPACE '{' - { push_namespace (NULL_TREE); } - extdefs_opt '}' - { pop_namespace (); } - | namespace_alias - | using_decl ';' - { do_toplevel_using_decl ($1); } - | using_directive - | extension extdef - { pedantic = $<itype>1; } - ; - -namespace_alias: - NAMESPACE identifier '=' - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - if (lastiddecl) - $5 = lastiddecl; - do_namespace_alias ($2, $5); - } - ; - -using_decl: - USING qualified_id - { $$ = $2; } - | USING global_scope qualified_id - { $$ = $3; } - | USING global_scope unqualified_id - { $$ = $3; } - ; - -namespace_using_decl: - USING namespace_qualifier identifier - { $$ = build_parse_node (SCOPE_REF, $2, $3); } - | USING global_scope identifier - { $$ = build_parse_node (SCOPE_REF, global_namespace, $3); } - | USING global_scope namespace_qualifier identifier - { $$ = build_parse_node (SCOPE_REF, $3, $4); } - ; - -using_directive: - USING NAMESPACE - { begin_only_namespace_names (); } - any_id ';' - { - end_only_namespace_names (); - /* If no declaration was found, the using-directive is - invalid. Since that was not reported, we need the - identifier for the error message. */ - if (TREE_CODE ($4) == IDENTIFIER_NODE && lastiddecl) - $4 = lastiddecl; - do_using_directive ($4); - } - ; - -namespace_qualifier: - NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | namespace_qualifier NSNAME SCOPE - { - $$ = $2; - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - -any_id: - unqualified_id - | qualified_id - | global_scope qualified_id - { $$ = $2; } - | global_scope unqualified_id - { $$ = $2; } - ; - -extern_lang_string: - EXTERN_LANG_STRING - { push_lang_context ($1); } - | extern_lang_string EXTERN_LANG_STRING - { if (current_lang_name != $2) - cp_error ("use of linkage spec `%D' is different from previous spec `%D'", $2, current_lang_name); - pop_lang_context (); push_lang_context ($2); } - ; - -template_header: - TEMPLATE '<' - { begin_template_parm_list (); } - template_parm_list '>' - { $$ = end_template_parm_list ($4); } - | TEMPLATE '<' '>' - { begin_specialization(); - $$ = NULL_TREE; } - ; - -template_parm_list: - template_parm - { $$ = process_template_parm (NULL_TREE, $1); } - | template_parm_list ',' template_parm - { $$ = process_template_parm ($1, $3); } - ; - -maybe_identifier: - identifier - { $$ = $1; } - | /* empty */ - { $$ = NULL_TREE; } - -template_type_parm: - aggr maybe_identifier - { $$ = finish_template_type_parm ($1, $2); } - | TYPENAME_KEYWORD maybe_identifier - { $$ = finish_template_type_parm (class_type_node, $2); } - ; - -template_template_parm: - template_header aggr maybe_identifier - { $$ = finish_template_template_parm ($2, $3); } - ; - -template_parm: - /* The following rules introduce a new reduce/reduce - conflict on the ',' and '>' input tokens: they are valid - prefixes for a `structsp', which means they could match a - nameless parameter. See 14.6, paragraph 3. - By putting them before the `parm' rule, we get - their match before considering them nameless parameter - declarations. */ - template_type_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_type_parm '=' type_id - { $$ = build_tree_list (groktypename ($3.t), $1); } - | parm - { $$ = build_tree_list (NULL_TREE, $1.t); } - | parm '=' expr_no_commas %prec ARITHCOMPARE - { $$ = build_tree_list ($3, $1.t); } - | template_template_parm - { $$ = build_tree_list (NULL_TREE, $1); } - | template_template_parm '=' template_arg - { - if (TREE_CODE ($3) != TEMPLATE_DECL - && TREE_CODE ($3) != TEMPLATE_TEMPLATE_PARM - && TREE_CODE ($3) != TYPE_DECL) - { - error ("invalid default template argument"); - $3 = error_mark_node; - } - $$ = build_tree_list ($3, $1); - } - ; - -template_def: - template_header template_extdef - { finish_template_decl ($1); } - | template_header error %prec EMPTY - { finish_template_decl ($1); } - ; - -template_extdef: - fndef eat_saved_input - { if (pending_inlines) do_pending_inlines (); } - | template_datadef - { if (pending_inlines) do_pending_inlines (); } - | template_def - { if (pending_inlines) do_pending_inlines (); } - | extern_lang_string .hush_warning fndef .warning_ok eat_saved_input - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } - | extern_lang_string .hush_warning template_datadef .warning_ok - { if (pending_inlines) do_pending_inlines (); - pop_lang_context (); } - | extension template_extdef - { pedantic = $<itype>1; } - ; - -template_datadef: - nomods_initdecls ';' - | declmods notype_initdecls ';' - {} - | typed_declspecs initdecls ';' - { note_list_got_semicolon ($1.t); } - | structsp ';' - { maybe_process_partial_specialization ($1.t); - note_got_semicolon ($1.t); } - ; - -datadef: - nomods_initdecls ';' - | declmods notype_initdecls ';' - {} - | typed_declspecs initdecls ';' - { note_list_got_semicolon ($1.t); } - | declmods ';' - { pedwarn ("empty declaration"); } - | explicit_instantiation ';' - | typed_declspecs ';' - { - tree t, attrs; - split_specs_attrs ($1.t, &t, &attrs); - shadow_tag (t); - note_list_got_semicolon ($1.t); - } - | error ';' - | error '}' - | ';' - ; - -ctor_initializer_opt: - nodecls - { $$ = 0; } - | base_init - { $$ = 1; } - ; - -maybe_return_init: - /* empty */ - | return_init - | return_init ';' - ; - -eat_saved_input: - /* empty */ - | END_OF_SAVED_INPUT - ; - -fndef: - fn.def1 maybe_return_init ctor_initializer_opt compstmt_or_error - { finish_function (lineno, (int)$3, 0); } - | fn.def1 maybe_return_init function_try_block - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3, nested); - } - | fn.def1 maybe_return_init error - { } - ; - -constructor_declarator: - nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier SELFNAME '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - | nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($1, $2); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>4, $5, $7, $8); } - | nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($1, $2); - $$ = make_call_declarator ($$, empty_parms (), $4, $5); - } - | global_scope nested_name_specifier self_template_type '(' - { $$ = begin_constructor_declarator ($2, $3); } - parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($<ttype>5, $6, $8, $9); } - | global_scope nested_name_specifier self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = begin_constructor_declarator ($2, $3); - $$ = make_call_declarator ($$, empty_parms (), $5, $6); - } - ; - -fn.def1: - typed_declspecs declarator - { if (!begin_function_definition ($1.t, $2)) - YYERROR1; } - | declmods notype_declarator - { if (!begin_function_definition ($1, $2)) - YYERROR1; } - | notype_declarator - { if (!begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - | declmods constructor_declarator - { if (!begin_function_definition ($1, $2)) - YYERROR1; } - | constructor_declarator - { if (!begin_function_definition (NULL_TREE, $1)) - YYERROR1; } - ; - -component_constructor_declarator: - SELFNAME '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | SELFNAME LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - | self_template_type '(' parmlist ')' cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, $3, $5, $6); } - | self_template_type LEFT_RIGHT cv_qualifiers exception_specification_opt - { $$ = make_call_declarator ($1, empty_parms (), $3, $4); } - ; - -/* more C++ complexity. See component_decl for a comment on the - reduce/reduce conflict introduced by these rules. */ -fn.def2: - declmods component_constructor_declarator - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - $$ = start_method (specs, $2, attrs); - rest_of_mdef: - if (! $$) - YYERROR1; - if (yychar == YYEMPTY) - yychar = YYLEX; - reinit_parse_for_method (yychar, $$); } - | component_constructor_declarator - { $$ = start_method (NULL_TREE, $1, NULL_TREE); - goto rest_of_mdef; } - | typed_declspecs declarator - { tree specs, attrs; - split_specs_attrs ($1.t, &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } - | declmods notype_declarator - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } - | notype_declarator - { $$ = start_method (NULL_TREE, $$, NULL_TREE); - goto rest_of_mdef; } - | declmods constructor_declarator - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - attrs = build_tree_list (attrs, NULL_TREE); - $$ = start_method (specs, $2, attrs); goto rest_of_mdef; } - | constructor_declarator - { $$ = start_method (NULL_TREE, $$, NULL_TREE); - goto rest_of_mdef; } - ; - -return_id: - RETURN IDENTIFIER - { - if (! current_function_parms_stored) - store_parm_decls (); - $$ = $2; - } - ; - -return_init: - return_id maybe_init - { store_return_init ($<ttype>$, $2); } - | return_id '(' nonnull_exprlist ')' - { store_return_init ($<ttype>$, $3); } - | return_id LEFT_RIGHT - { store_return_init ($<ttype>$, NULL_TREE); } - ; - -base_init: - ':' .set_base_init member_init_list - { - if ($3 == 0) - error ("no base initializers given following ':'"); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - } - ; - -.set_base_init: - /* empty */ - { - if (! current_function_parms_stored) - store_parm_decls (); - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - /* Make a contour for the initializer list. */ - pushlevel (0); - clear_last_expr (); - expand_start_bindings (0); - } - else if (current_class_type == NULL_TREE) - error ("base initializers not allowed for non-member functions"); - else if (! DECL_CONSTRUCTOR_P (current_function_decl)) - error ("only constructors take base initializers"); - } - ; - -member_init_list: - /* empty */ - { $$ = 0; } - | member_init - { $$ = 1; } - | member_init_list ',' member_init - | member_init_list error - ; - -member_init: - '(' nonnull_exprlist ')' - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, $2); - } - | LEFT_RIGHT - { - if (current_class_name) - pedwarn ("anachronistic old style base class initializer"); - expand_member_init (current_class_ref, NULL_TREE, void_type_node); - } - | notype_identifier '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, $1, $3); } - | notype_identifier LEFT_RIGHT - { expand_member_init (current_class_ref, $1, void_type_node); } - | nonnested_type '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, $1, $3); } - | nonnested_type LEFT_RIGHT - { expand_member_init (current_class_ref, $1, void_type_node); } - | typename_sub '(' nonnull_exprlist ')' - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), - $3); } - | typename_sub LEFT_RIGHT - { expand_member_init (current_class_ref, TYPE_MAIN_DECL ($1), - void_type_node); } - ; - -identifier: - IDENTIFIER - | TYPENAME - | SELFNAME - | PTYPENAME - | NSNAME - ; - -notype_identifier: - IDENTIFIER - | PTYPENAME - | NSNAME %prec EMPTY - ; - -identifier_defn: - IDENTIFIER_DEFN - | TYPENAME_DEFN - | PTYPENAME_DEFN - ; - -explicit_instantiation: - TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($3.t, NULL_TREE); - yyungetc (';', 1); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation typed_declspecs declarator - { tree specs = strip_attrs ($3.t); - do_decl_instantiation (specs, $4, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation notype_declarator - { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | TEMPLATE begin_explicit_instantiation constructor_declarator - { do_decl_instantiation (NULL_TREE, $3, NULL_TREE); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation typespec ';' - { do_type_instantiation ($4.t, $1); - yyungetc (';', 1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation typed_declspecs - declarator - { tree specs = strip_attrs ($4.t); - do_decl_instantiation (specs, $5, $1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation notype_declarator - { do_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - | SCSPEC TEMPLATE begin_explicit_instantiation constructor_declarator - { do_decl_instantiation (NULL_TREE, $4, $1); } - end_explicit_instantiation - ; - -begin_explicit_instantiation: - { begin_explicit_instantiation(); } - -end_explicit_instantiation: - { end_explicit_instantiation(); } - -/* The TYPENAME expansions are to deal with use of a template class name as - a template within the class itself, where the template decl is hidden by - a type decl. Got all that? */ - -template_type: - PTYPENAME '<' template_arg_list_opt template_close_bracket - .finish_template_type - { $$ = $5; } - | TYPENAME '<' template_arg_list_opt template_close_bracket - .finish_template_type - { $$ = $5; } - | self_template_type - ; - -apparent_template_type: - template_type - | identifier '<' template_arg_list_opt '>' - .finish_template_type - { $$ = $5; } - -self_template_type: - SELFNAME '<' template_arg_list_opt template_close_bracket - .finish_template_type - { $$ = $5; } - ; - -.finish_template_type: - { - if (yychar == YYEMPTY) - yychar = YYLEX; - - $$ = finish_template_type ($<ttype>-3, $<ttype>-1, - yychar == SCOPE); - } - -template_close_bracket: - '>' - | RSHIFT - { - /* Handle `Class<Class<Type>>' without space in the `>>' */ - pedwarn ("`>>' should be `> >' in template class name"); - yyungetc ('>', 1); - } - ; - -template_arg_list_opt: - /* empty */ - { $$ = NULL_TREE; } - | template_arg_list - ; - -template_arg_list: - template_arg - { $$ = build_tree_list (NULL_TREE, $$); } - | template_arg_list ',' template_arg - { $$ = chainon ($$, build_tree_list (NULL_TREE, $3)); } - ; - -template_arg: - type_id - { $$ = groktypename ($1.t); } - | PTYPENAME - { $$ = lastiddecl; } - | expr_no_commas %prec ARITHCOMPARE - ; - -unop: - '-' - { $$ = NEGATE_EXPR; } - | '+' - { $$ = CONVERT_EXPR; } - | PLUSPLUS - { $$ = PREINCREMENT_EXPR; } - | MINUSMINUS - { $$ = PREDECREMENT_EXPR; } - | '!' - { $$ = TRUTH_NOT_EXPR; } - ; - -expr: - nontrivial_exprlist - { $$ = build_x_compound_expr ($$); } - | expr_no_commas - ; - -paren_expr_or_null: - LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' expr ')' - { $$ = $2; } - ; - -paren_cond_or_null: - LEFT_RIGHT - { error ("ANSI C++ forbids an empty condition for `%s'", - cond_stmt_keyword); - $$ = integer_zero_node; } - | '(' condition ')' - { $$ = $2; } - ; - -xcond: - /* empty */ - { $$ = NULL_TREE; } - | condition - | error - { $$ = NULL_TREE; } - ; - -condition: - type_specifier_seq declarator maybeasm maybe_attribute '=' - { { - tree d; - for (d = getdecls (); d; d = TREE_CHAIN (d)) - if (TREE_CODE (d) == TYPE_DECL) { - tree s = TREE_TYPE (d); - if (TREE_CODE (s) == RECORD_TYPE) - cp_error ("definition of class `%T' in condition", s); - else if (TREE_CODE (s) == ENUMERAL_TYPE) - cp_error ("definition of enum `%T' in condition", s); - } - } - current_declspecs = $1.t; - $<itype>5 = suspend_momentary (); - $<ttype>$ = start_decl ($<ttype>2, current_declspecs, 1, - $4, /*prefix_attributes*/ NULL_TREE); - } - init - { - cp_finish_decl ($<ttype>6, $7, $4, 1, LOOKUP_ONLYCONVERTING); - resume_momentary ($<itype>5); - $$ = convert_from_reference ($<ttype>6); - if (TREE_CODE (TREE_TYPE ($$)) == ARRAY_TYPE) - cp_error ("definition of array `%#D' in condition", $$); - } - | expr - ; - -compstmtend: - '}' - | maybe_label_decls stmts '}' - | maybe_label_decls stmts error '}' - | maybe_label_decls error '}' - ; - -already_scoped_stmt: - '{' - { $<ttype>$ = begin_compound_stmt (1); } - compstmtend - { finish_compound_stmt (1, $<ttype>2); } - | simple_stmt - ; - - -nontrivial_exprlist: - expr_no_commas ',' expr_no_commas - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, $3)); } - | expr_no_commas ',' error - { $$ = expr_tree_cons (NULL_TREE, $$, - build_expr_list (NULL_TREE, error_mark_node)); } - | nontrivial_exprlist ',' expr_no_commas - { chainon ($$, build_expr_list (NULL_TREE, $3)); } - | nontrivial_exprlist ',' error - { chainon ($$, build_expr_list (NULL_TREE, error_mark_node)); } - ; - -nonnull_exprlist: - expr_no_commas - { $$ = build_expr_list (NULL_TREE, $$); } - | nontrivial_exprlist - ; - -unary_expr: - primary %prec UNARY - { $$ = $1; } - /* __extension__ turns off -pedantic for following primary. */ - | extension cast_expr %prec UNARY - { $$ = $2; - pedantic = $<itype>1; } - | '*' cast_expr %prec UNARY - { $$ = build_x_indirect_ref ($2, "unary *"); } - | '&' cast_expr %prec UNARY - { $$ = build_x_unary_op (ADDR_EXPR, $2); } - | '~' cast_expr - { $$ = build_x_unary_op (BIT_NOT_EXPR, $2); } - | unop cast_expr %prec UNARY - { $$ = finish_unary_op_expr ($1, $2); } - /* Refer to the address of a label as a pointer. */ - | ANDAND identifier - { if (pedantic) - pedwarn ("ANSI C++ forbids `&&'"); - $$ = finish_label_address_expr ($2); } - | SIZEOF unary_expr %prec UNARY - { $$ = expr_sizeof ($2); } - | SIZEOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_sizeof (groktypename ($3.t)); - check_for_new_type ("sizeof", $3); } - | ALIGNOF unary_expr %prec UNARY - { $$ = grok_alignof ($2); } - | ALIGNOF '(' type_id ')' %prec HYPERUNARY - { $$ = c_alignof (groktypename ($3.t)); - check_for_new_type ("alignof", $3); } - - /* The %prec EMPTY's here are required by the = init initializer - syntax extension; see below. */ - | new new_type_id %prec EMPTY - { $$ = build_new (NULL_TREE, $2.t, NULL_TREE, $1); - check_for_new_type ("new", $2); } - | new new_type_id new_initializer - { $$ = build_new (NULL_TREE, $2.t, $3, $1); - check_for_new_type ("new", $2); } - | new new_placement new_type_id %prec EMPTY - { $$ = build_new ($2, $3.t, NULL_TREE, $1); - check_for_new_type ("new", $3); } - | new new_placement new_type_id new_initializer - { $$ = build_new ($2, $3.t, $4, $1); - check_for_new_type ("new", $3); } - /* The .begin_new_placement in the following rules is - necessary to avoid shift/reduce conflicts that lead to - mis-parsing some expressions. Of course, these constructs - are not really new-placement and it is bogus to call - begin_new_placement. But, the parser cannot always tell at this - point whether the next thing is an expression or a type-id, - so there is nothing we can do. Fortunately, - begin_new_placement does nothing harmful. When we rewrite - the parser, this lossage should be removed, of course. */ - | new '(' .begin_new_placement type_id .finish_new_placement - %prec EMPTY - { $$ = build_new (NULL_TREE, groktypename($4.t), - NULL_TREE, $1); - check_for_new_type ("new", $4); } - | new '(' .begin_new_placement type_id .finish_new_placement - new_initializer - { $$ = build_new (NULL_TREE, groktypename($4.t), $6, $1); - check_for_new_type ("new", $4); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement %prec EMPTY - { $$ = build_new ($2, groktypename($5.t), NULL_TREE, $1); - check_for_new_type ("new", $5); } - | new new_placement '(' .begin_new_placement type_id - .finish_new_placement new_initializer - { $$ = build_new ($2, groktypename($5.t), $7, $1); - check_for_new_type ("new", $5); } - - | delete cast_expr %prec UNARY - { $$ = delete_sanity ($2, NULL_TREE, 0, $1); } - | delete '[' ']' cast_expr %prec UNARY - { $$ = delete_sanity ($4, NULL_TREE, 1, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | delete '[' expr ']' cast_expr %prec UNARY - { $$ = delete_sanity ($5, $3, 2, $1); - if (yychar == YYEMPTY) - yychar = YYLEX; } - | REALPART cast_expr %prec UNARY - { $$ = build_x_unary_op (REALPART_EXPR, $2); } - | IMAGPART cast_expr %prec UNARY - { $$ = build_x_unary_op (IMAGPART_EXPR, $2); } - ; - - /* Note this rule is not suitable for use in new_placement - since it uses NULL_TREE as the argument to - finish_new_placement. This rule serves only to avoid - reduce/reduce conflicts in unary_expr. See the comments - there on the use of begin/finish_new_placement. */ -.finish_new_placement: - ')' - { finish_new_placement (NULL_TREE, $<itype>-1); } - -.begin_new_placement: - { $$ = begin_new_placement (); } - -new_placement: - '(' .begin_new_placement nonnull_exprlist ')' - { $$ = finish_new_placement ($3, $2); } - | '{' .begin_new_placement nonnull_exprlist '}' - { cp_pedwarn ("old style placement syntax, use () instead"); - $$ = finish_new_placement ($3, $2); } - ; - -new_initializer: - '(' nonnull_exprlist ')' - { $$ = $2; } - | LEFT_RIGHT - { $$ = NULL_TREE; } - | '(' typespec ')' - { - cp_error ("`%T' is not a valid expression", $2.t); - $$ = error_mark_node; - } - /* GNU extension so people can use initializer lists. Note that - this alters the meaning of `new int = 1', which was previously - syntactically valid but semantically invalid. */ - | '=' init - { - if (pedantic) - pedwarn ("ANSI C++ forbids initialization of new expression with `='"); - if (TREE_CODE ($2) != TREE_LIST - && TREE_CODE ($2) != CONSTRUCTOR) - $$ = build_expr_list (NULL_TREE, $2); - else - $$ = $2; - } - ; - -/* This is necessary to postpone reduction of `int ((int)(int)(int))'. */ -regcast_or_absdcl: - '(' type_id ')' %prec EMPTY - { $2.t = finish_parmlist (build_tree_list (NULL_TREE, $2.t), 0); - $$ = make_call_declarator (NULL_TREE, $2.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $2); } - | regcast_or_absdcl '(' type_id ')' %prec EMPTY - { $3.t = finish_parmlist (build_tree_list (NULL_TREE, $3.t), 0); - $$ = make_call_declarator ($$, $3.t, NULL_TREE, NULL_TREE); - check_for_new_type ("cast", $3); } - ; - -cast_expr: - unary_expr - | regcast_or_absdcl unary_expr %prec UNARY - { $$ = reparse_absdcl_as_casts ($$, $2); } - | regcast_or_absdcl '{' initlist maybecomma '}' %prec UNARY - { - tree init = build_nt (CONSTRUCTOR, NULL_TREE, - nreverse ($3)); - if (pedantic) - pedwarn ("ANSI C++ forbids constructor-expressions"); - /* Indicate that this was a GNU C constructor expression. */ - TREE_HAS_CONSTRUCTOR (init) = 1; - - $$ = reparse_absdcl_as_casts ($$, init); - } - ; - -expr_no_commas: - cast_expr - /* Handle general members. */ - | expr_no_commas POINTSAT_STAR expr_no_commas - { $$ = build_x_binary_op (MEMBER_REF, $$, $3); } - | expr_no_commas DOT_STAR expr_no_commas - { $$ = build_m_component_ref ($$, $3); } - | expr_no_commas '+' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '-' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '*' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '/' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '%' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas LSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas RSHIFT expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ARITHCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '<' expr_no_commas - { $$ = build_x_binary_op (LT_EXPR, $$, $3); } - | expr_no_commas '>' expr_no_commas - { $$ = build_x_binary_op (GT_EXPR, $$, $3); } - | expr_no_commas EQCOMPARE expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas MIN_MAX expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '&' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '|' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas '^' expr_no_commas - { $$ = build_x_binary_op ($2, $$, $3); } - | expr_no_commas ANDAND expr_no_commas - { $$ = build_x_binary_op (TRUTH_ANDIF_EXPR, $$, $3); } - | expr_no_commas OROR expr_no_commas - { $$ = build_x_binary_op (TRUTH_ORIF_EXPR, $$, $3); } - | expr_no_commas '?' xexpr ':' expr_no_commas - { $$ = build_x_conditional_expr ($$, $3, $5); } - | expr_no_commas '=' expr_no_commas - { $$ = build_x_modify_expr ($$, NOP_EXPR, $3); - if ($$ != error_mark_node) - C_SET_EXP_ORIGINAL_CODE ($$, MODIFY_EXPR); } - | expr_no_commas ASSIGN expr_no_commas - { $$ = build_x_modify_expr ($$, $2, $3); } - | THROW - { $$ = build_throw (NULL_TREE); } - | THROW expr_no_commas - { $$ = build_throw ($2); } -/* These extensions are not defined. The second arg to build_m_component_ref - is old, build_m_component_ref now does an implicit - build_indirect_ref (x, NULL_PTR) on the second argument. - | object '&' expr_no_commas %prec UNARY - { $$ = build_m_component_ref ($$, build_x_unary_op (ADDR_EXPR, $3)); } - | object unop expr_no_commas %prec UNARY - { $$ = build_m_component_ref ($$, build_x_unary_op ($2, $3)); } - | object '(' type_id ')' expr_no_commas %prec UNARY - { tree type = groktypename ($3.t); - $$ = build_m_component_ref ($$, build_c_cast (type, $5)); } - | object primary_no_id %prec UNARY - { $$ = build_m_component_ref ($$, $2); } -*/ - ; - -notype_unqualified_id: - '~' see_typename identifier - { $$ = build_parse_node (BIT_NOT_EXPR, $3); } - | '~' see_typename template_type - { $$ = build_parse_node (BIT_NOT_EXPR, $3); } - | template_id - | operator_name - | IDENTIFIER - | PTYPENAME - | NSNAME %prec EMPTY - ; - -do_id: - { - /* If lastiddecl is a TREE_LIST, it's a baselink, which - means that we're in an expression like S::f<int>, so - don't do_identifier; we only do that for unqualified - identifiers. */ - if (lastiddecl && TREE_CODE (lastiddecl) != TREE_LIST) - $$ = do_identifier ($<ttype>-1, 1, NULL_TREE); - else - $$ = $<ttype>-1; - } - -template_id: - PFUNCNAME '<' do_id template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($3, $4); } - | operator_name '<' do_id template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($3, $4); } - ; - -object_template_id: - TEMPLATE identifier '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE PFUNCNAME '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($2, $4); } - | TEMPLATE operator_name '<' template_arg_list_opt - template_close_bracket - { $$ = lookup_template_function ($2, $4); } - ; - -unqualified_id: - notype_unqualified_id - | TYPENAME - | SELFNAME - ; - -expr_or_declarator_intern: - expr_or_declarator - | attributes expr_or_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = decl_tree_cons ($1, $2, NULL_TREE); - } - ; - -expr_or_declarator: - notype_unqualified_id - | '*' expr_or_declarator_intern %prec UNARY - { $$ = build_parse_node (INDIRECT_REF, $2); } - | '&' expr_or_declarator_intern %prec UNARY - { $$ = build_parse_node (ADDR_EXPR, $2); } - | '(' expr_or_declarator_intern ')' - { $$ = $2; } - ; - -notype_template_declarator: - IDENTIFIER '<' template_arg_list_opt template_close_bracket - { $$ = lookup_template_function ($1, $3); } - | NSNAME '<' template_arg_list template_close_bracket - { $$ = lookup_template_function ($1, $3); } - ; - -direct_notype_declarator: - complex_direct_notype_declarator - /* This precedence declaration is to prefer this reduce - to the Koenig lookup shift in primary, below. I hate yacc. */ - | notype_unqualified_id %prec '(' - | notype_template_declarator - | '(' expr_or_declarator_intern ')' - { $$ = finish_decl_parsing ($2); } - ; - -primary: - notype_unqualified_id - { - if (TREE_CODE ($1) == BIT_NOT_EXPR) - $$ = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND ($1, 0)); - else - $$ = finish_id_expr ($1); - } - | CONSTANT - | boolean.literal - | string - { - if (processing_template_decl) - push_obstacks (&permanent_obstack, &permanent_obstack); - $$ = combine_strings ($$); - /* combine_strings doesn't set up TYPE_MAIN_VARIANT of - a const array the way we want, so fix it. */ - if (flag_const_strings) - TREE_TYPE ($$) = build_cplus_array_type - (TREE_TYPE (TREE_TYPE ($$)), - TYPE_DOMAIN (TREE_TYPE ($$))); - if (processing_template_decl) - pop_obstacks (); - } - | '(' expr ')' - { $$ = finish_parenthesized_expr ($2); } - | '(' expr_or_declarator_intern ')' - { $2 = reparse_decl_as_expr (NULL_TREE, $2); - $$ = finish_parenthesized_expr ($2); } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { tree scope = current_scope (); - if (!scope || TREE_CODE (scope) != FUNCTION_DECL) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); - $<ttype>$ = begin_stmt_expr (); - } - compstmt ')' - { $$ = finish_stmt_expr ($<ttype>2, $3); } - /* Koenig lookup support - We could store lastiddecl in $1 to avoid another lookup, - but that would result in many additional reduce/reduce conflicts. */ - | notype_unqualified_id '(' nonnull_exprlist ')' - { $$ = finish_call_expr ($1, $3, 1); } - | notype_unqualified_id LEFT_RIGHT - { $$ = finish_call_expr ($1, NULL_TREE, 1); } - | primary '(' nonnull_exprlist ')' - { $$ = finish_call_expr ($1, $3, 0); } - | primary LEFT_RIGHT - { $$ = finish_call_expr ($1, NULL_TREE, 0); } - | primary '[' expr ']' - { $$ = grok_array_decl ($$, $3); } - | primary PLUSPLUS - { $$ = finish_increment_expr ($1, POSTINCREMENT_EXPR); } - | primary MINUSMINUS - { $$ = finish_increment_expr ($1, POSTDECREMENT_EXPR); } - /* C++ extensions */ - | THIS - { $$ = finish_this_expr (); } - | CV_QUALIFIER '(' nonnull_exprlist ')' - { - /* This is a C cast in C++'s `functional' notation - using the "implicit int" extension so that: - `const (3)' is equivalent to `const int (3)'. */ - tree type; - - if ($3 == error_mark_node) - { - $$ = error_mark_node; - break; - } - - type = cp_build_qualified_type (integer_type_node, - cp_type_qual_from_rid ($1)); - $$ = build_c_cast (type, build_compound_expr ($3)); - } - | functional_cast - | DYNAMIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("dynamic_cast", $3); - $$ = build_dynamic_cast (type, $6); } - | STATIC_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("static_cast", $3); - $$ = build_static_cast (type, $6); } - | REINTERPRET_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("reinterpret_cast", $3); - $$ = build_reinterpret_cast (type, $6); } - | CONST_CAST '<' type_id '>' '(' expr ')' - { tree type = groktypename ($3.t); - check_for_new_type ("const_cast", $3); - $$ = build_const_cast (type, $6); } - | TYPEID '(' expr ')' - { $$ = build_x_typeid ($3); } - | TYPEID '(' type_id ')' - { tree type = groktypename ($3.t); - check_for_new_type ("typeid", $3); - $$ = get_typeid (TYPE_MAIN_VARIANT (type)); } - | global_scope IDENTIFIER - { $$ = do_scoped_id ($2, 1); } - | global_scope template_id - { $$ = $2; } - | global_scope operator_name - { - got_scope = NULL_TREE; - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = do_scoped_id ($2, 1); - else - $$ = $2; - } - | overqualified_id %prec HYPERUNARY - { $$ = build_offset_ref (OP0 ($$), OP1 ($$)); } - | overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_qualified_call_expr ($1, $3); } - | overqualified_id LEFT_RIGHT - { $$ = finish_qualified_call_expr ($1, NULL_TREE); } - | object object_template_id %prec UNARY - { - $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); - } - | object object_template_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object object_template_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object unqualified_id %prec UNARY - { $$ = build_x_component_ref ($$, $2, NULL_TREE, 1); } - | object overqualified_id %prec UNARY - { if (processing_template_decl) - $$ = build_min_nt (COMPONENT_REF, $1, copy_to_permanent ($2)); - else - $$ = build_object_ref ($$, OP0 ($2), OP1 ($2)); } - | object unqualified_id '(' nonnull_exprlist ')' - { $$ = finish_object_call_expr ($2, $1, $4); } - | object unqualified_id LEFT_RIGHT - { $$ = finish_object_call_expr ($2, $1, NULL_TREE); } - | object overqualified_id '(' nonnull_exprlist ')' - { $$ = finish_qualified_object_call_expr ($2, $1, $4); } - | object overqualified_id LEFT_RIGHT - { $$ = finish_qualified_object_call_expr ($2, $1, NULL_TREE); } - /* p->int::~int() is valid -- 12.4 */ - | object '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, NULL_TREE, $3); } - | object TYPESPEC SCOPE '~' TYPESPEC LEFT_RIGHT - { $$ = finish_pseudo_destructor_call_expr ($1, $2, $5); } - | object error - { - $$ = error_mark_node; - } - ; - -/* Not needed for now. - -primary_no_id: - '(' expr ')' - { $$ = $2; } - | '(' error ')' - { $$ = error_mark_node; } - | '(' - { if (current_function_decl == 0) - { - error ("braced-group within expression allowed only inside a function"); - YYERROR; - } - $<ttype>$ = expand_start_stmt_expr (); } - compstmt ')' - { if (pedantic) - pedwarn ("ANSI C++ forbids braced-groups within expressions"); - $$ = expand_end_stmt_expr ($<ttype>2); } - | primary_no_id '(' nonnull_exprlist ')' - { $$ = build_x_function_call ($$, $3, current_class_ref); } - | primary_no_id LEFT_RIGHT - { $$ = build_x_function_call ($$, NULL_TREE, current_class_ref); } - | primary_no_id '[' expr ']' - { goto do_array; } - | primary_no_id PLUSPLUS - { $$ = build_x_unary_op (POSTINCREMENT_EXPR, $$); } - | primary_no_id MINUSMINUS - { $$ = build_x_unary_op (POSTDECREMENT_EXPR, $$); } - | SCOPE IDENTIFIER - { goto do_scoped_id; } - | SCOPE operator_name - { if (TREE_CODE ($2) == IDENTIFIER_NODE) - goto do_scoped_id; - goto do_scoped_operator; - } - ; -*/ - -new: - NEW - { $$ = 0; } - | global_scope NEW - { got_scope = NULL_TREE; $$ = 1; } - ; - -delete: - DELETE - { $$ = 0; } - | global_scope delete - { got_scope = NULL_TREE; $$ = 1; } - ; - -boolean.literal: - CXX_TRUE - { $$ = boolean_true_node; } - | CXX_FALSE - { $$ = boolean_false_node; } - ; - -/* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */ -string: - STRING - | string STRING - { $$ = chainon ($$, $2); } - ; - -nodecls: - /* empty */ - { - if (! current_function_parms_stored) - store_parm_decls (); - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curley braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - } - ; - -object: - primary '.' - { got_object = TREE_TYPE ($$); } - | primary POINTSAT - { - $$ = build_x_arrow ($$); - got_object = TREE_TYPE ($$); - } - ; - -decl: - typespec initdecls ';' - { - resume_momentary ($2); - if ($1.t && IS_AGGR_TYPE_CODE (TREE_CODE ($1.t))) - note_got_semicolon ($1.t); - } - | typed_declspecs initdecls ';' - { - resume_momentary ($2); - note_list_got_semicolon ($1.t); - } - | declmods notype_initdecls ';' - { resume_momentary ($2); } - | typed_declspecs ';' - { - shadow_tag ($1.t); - note_list_got_semicolon ($1.t); - } - | declmods ';' - { warning ("empty declaration"); } - | extension decl - { pedantic = $<itype>1; } - ; - -/* Any kind of declarator (thus, all declarators allowed - after an explicit typespec). */ - -declarator: - after_type_declarator %prec EMPTY - | notype_declarator %prec EMPTY - ; - -/* This is necessary to postpone reduction of `int()()()()'. */ -fcast_or_absdcl: - LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator (NULL_TREE, empty_parms (), - NULL_TREE, NULL_TREE); } - | fcast_or_absdcl LEFT_RIGHT %prec EMPTY - { $$ = make_call_declarator ($$, empty_parms (), NULL_TREE, - NULL_TREE); } - ; - -/* ANSI type-id (8.1) */ -type_id: - typed_typespecs absdcl - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers absdcl - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec absdcl - { $$.t = build_decl_list (get_decl_list ($1.t), $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_typespecs %prec EMPTY - { $$.t = build_decl_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers %prec EMPTY - { $$.t = build_decl_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* Declspecs which contain at least one type specifier or typedef name. - (Just `const' or `volatile' is not enough.) - A typedef'd name following these is taken as a name to be declared. - In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ - -typed_declspecs: - typed_typespecs %prec EMPTY - | typed_declspecs1 - ; - -typed_declspecs1: - declmods typespec - { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_declspecs %prec HYPERUNARY - { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec reserved_typespecquals reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $1.t, chainon ($2, $3)); - $$.new_type_flag = $1.new_type_flag; } - | declmods typespec reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1)); - $$.new_type_flag = $2.new_type_flag; } - | declmods typespec reserved_typespecquals reserved_declspecs - { $$.t = decl_tree_cons (NULL_TREE, $2.t, - chainon ($3, chainon ($4, $1))); - $$.new_type_flag = $2.new_type_flag; } - ; - -reserved_declspecs: - SCSPEC - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($$)); - $$ = build_decl_list (NULL_TREE, $$); } - | reserved_declspecs typespecqual_reserved - { $$ = decl_tree_cons (NULL_TREE, $2.t, $$); } - | reserved_declspecs SCSPEC - { if (extra_warnings) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = decl_tree_cons (NULL_TREE, $2, $$); } - | reserved_declspecs attributes - { $$ = decl_tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } - ; - -/* List of just storage classes and type modifiers. - A declaration can start with just this, but then it cannot be used - to redeclare a typedef-name. - In the result, declspecs have a non-NULL TREE_VALUE, attributes do not. */ - -declmods: - nonempty_cv_qualifiers %prec EMPTY - { $$ = $1.t; TREE_STATIC ($$) = 1; } - | SCSPEC - { $$ = IDENTIFIER_AS_LIST ($$); } - | declmods CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); - TREE_STATIC ($$) = 1; } - | declmods SCSPEC - { if (extra_warnings && TREE_STATIC ($$)) - warning ("`%s' is not at beginning of declaration", - IDENTIFIER_POINTER ($2)); - $$ = decl_tree_cons (NULL_TREE, $2, $$); - TREE_STATIC ($$) = TREE_STATIC ($1); } - | declmods attributes - { $$ = decl_tree_cons ($2, NULL_TREE, $1); } - | attributes - { $$ = decl_tree_cons ($1, NULL_TREE, NULL_TREE); } - ; - -/* Used instead of declspecs where storage classes are not allowed - (that is, for typenames and structure components). - - C++ can takes storage classes for structure components. - Don't accept a typedef-name if anything but a modifier precedes it. */ - -typed_typespecs: - typespec %prec EMPTY - { $$.t = get_decl_list ($1.t); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers typespec - { $$.t = decl_tree_cons (NULL_TREE, $2.t, $1.t); - $$.new_type_flag = $2.new_type_flag; } - | typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | nonempty_cv_qualifiers typespec reserved_typespecquals - { $$.t = decl_tree_cons (NULL_TREE, $2.t, chainon ($3, $1.t)); - $$.new_type_flag = $1.new_type_flag; } - ; - -reserved_typespecquals: - typespecqual_reserved - { $$ = build_decl_list (NULL_TREE, $1.t); } - | reserved_typespecquals typespecqual_reserved - { $$ = decl_tree_cons (NULL_TREE, $2.t, $1); } - ; - -/* A typespec (but not a type qualifier). - Once we have seen one of these in a declaration, - if a typedef name appears then it is being redeclared. */ - -typespec: - structsp - | TYPESPEC %prec EMPTY - { $$.t = $1; $$.new_type_flag = 0; } - | complete_type_name - { $$.t = $1; $$.new_type_flag = 0; } - | TYPEOF '(' expr ')' - { $$.t = finish_typeof ($3); - $$.new_type_flag = 0; } - | TYPEOF '(' type_id ')' - { $$.t = groktypename ($3.t); - $$.new_type_flag = 0; } - | SIGOF '(' expr ')' - { tree type = TREE_TYPE ($3); - - $$.new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$.t = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { tree type = groktypename ($3.t); - - $$.new_type_flag = 0; - if (IS_AGGR_TYPE (type)) - { - sorry ("sigof type specifier"); - $$.t = type; - } - else - { - error("`sigof' applied to non-aggregate type"); - $$.t = error_mark_node; - } - } - ; - -/* A typespec that is a reserved word, or a type qualifier. */ - -typespecqual_reserved: - TYPESPEC - { $$.t = $1; $$.new_type_flag = 0; } - | CV_QUALIFIER - { $$.t = $1; $$.new_type_flag = 0; } - | structsp - ; - -initdecls: - initdcl0 - | initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -notype_initdecls: - notype_initdcl0 - | notype_initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -nomods_initdecls: - nomods_initdcl0 - | nomods_initdecls ',' initdcl - { check_multiple_declarators (); } - ; - -maybeasm: - /* empty */ - { $$ = NULL_TREE; } - | asm_keyword '(' string ')' - { if (TREE_CHAIN ($3)) $3 = combine_strings ($3); $$ = $3; } - ; - -initdcl: - declarator maybeasm maybe_attribute '=' - { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 1, - $3, prefix_attributes); } - init -/* Note how the declaration of the variable is in effect while its init is parsed! */ - { cp_finish_decl ($<ttype>5, $6, $2, 1, LOOKUP_ONLYCONVERTING); } - | declarator maybeasm maybe_attribute - { $<ttype>$ = start_decl ($<ttype>1, current_declspecs, 0, - $3, prefix_attributes); - cp_finish_decl ($<ttype>$, NULL_TREE, $2, 1, 0); } - ; - - /* This rule assumes a certain configuration of the parser stack. - In particular, $0, the element directly before the beginning of - this rule on the stack, must be a maybeasm. $-1 must be a - declarator or notype_declarator. And $-2 must be some declmods - or declspecs. We can't move the maybeasm into this rule because - we need that reduce so we prefer fn.def1 when appropriate. */ -initdcl0_innards: - maybe_attribute '=' - { $<itype>2 = parse_decl ($<ttype>-1, $<ttype>-2, - $1, 1, &$<ttype>$); } - /* Note how the declaration of the variable is in effect - while its init is parsed! */ - init - { cp_finish_decl ($<ttype>3, $4, $<ttype>0, 1, - LOOKUP_ONLYCONVERTING); - $$ = $<itype>2; } - | maybe_attribute - { tree d; - $$ = parse_decl ($<ttype>-1, $<ttype>-2, $1, 0, &d); - cp_finish_decl (d, NULL_TREE, $<ttype>0, 1, 0); } - ; - -initdcl0: - declarator maybeasm initdcl0_innards - { $$ = $3; } - -notype_initdcl0: - notype_declarator maybeasm initdcl0_innards - { $$ = $3; } - ; - -nomods_initdcl0: - notype_declarator maybeasm - { /* Set things up as initdcl0_innards expects. */ - $<ttype>2 = $1; - $1 = NULL_TREE; } - initdcl0_innards - {} - | constructor_declarator maybeasm maybe_attribute - { tree d; - parse_decl($1, NULL_TREE, $3, 0, &d); - cp_finish_decl (d, NULL_TREE, $2, 1, 0); } - ; - -/* the * rules are dummies to accept the Apollo extended syntax - so that the header files compile. */ -maybe_attribute: - /* empty */ - { $$ = NULL_TREE; } - | attributes - { $$ = $1; } - ; - -attributes: - attribute - { $$ = $1; } - | attributes attribute - { $$ = chainon ($1, $2); } - ; - -attribute: - ATTRIBUTE '(' '(' attribute_list ')' ')' - { $$ = $4; } - ; - -attribute_list: - attrib - { $$ = $1; } - | attribute_list ',' attrib - { $$ = chainon ($1, $3); } - ; - -attrib: - /* empty */ - { $$ = NULL_TREE; } - | any_word - { $$ = build_tree_list ($1, NULL_TREE); } - | any_word '(' IDENTIFIER ')' - { $$ = build_tree_list ($1, build_tree_list (NULL_TREE, $3)); } - | any_word '(' IDENTIFIER ',' nonnull_exprlist ')' - { $$ = build_tree_list ($1, tree_cons (NULL_TREE, $3, $5)); } - | any_word '(' nonnull_exprlist ')' - { $$ = build_tree_list ($1, $3); } - ; - -/* This still leaves out most reserved keywords, - shouldn't we include them? */ - -any_word: - identifier - | SCSPEC - | TYPESPEC - | CV_QUALIFIER - ; - -/* A nonempty list of identifiers, including typenames. */ -identifiers_or_typenames: - identifier - { $$ = build_tree_list (NULL_TREE, $1); } - | identifiers_or_typenames ',' identifier - { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); } - ; - -maybe_init: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '=' init - { $$ = $2; } - -/* If we are processing a template, we don't want to expand this - initializer yet. */ - -init: - expr_no_commas %prec '=' - | '{' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, NULL_TREE); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | '{' initlist ',' '}' - { $$ = build_nt (CONSTRUCTOR, NULL_TREE, nreverse ($2)); - TREE_HAS_CONSTRUCTOR ($$) = 1; } - | error - { $$ = NULL_TREE; } - ; - -/* This chain is built in reverse order, - and put in forward order where initlist is used. */ -initlist: - init - { $$ = build_tree_list (NULL_TREE, $$); } - | initlist ',' init - { $$ = expr_tree_cons (NULL_TREE, $3, $$); } - /* These are for labeled elements. */ - | '[' expr_no_commas ']' init - { $$ = build_expr_list ($2, $4); } - | identifier ':' init - { $$ = build_expr_list ($$, $3); } - | initlist ',' identifier ':' init - { $$ = expr_tree_cons ($3, $5, $$); } - ; - -fn.defpen: - PRE_PARSED_FUNCTION_DECL - { start_function (NULL_TREE, TREE_VALUE ($1), - NULL_TREE, 2); - reinit_parse_for_function (); } - -pending_inline: - fn.defpen maybe_return_init ctor_initializer_opt compstmt_or_error - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3 | 2, nested); - process_next_inline ($1); - } - | fn.defpen maybe_return_init function_try_block - { - int nested = (hack_decl_function_context - (current_function_decl) != NULL_TREE); - finish_function (lineno, (int)$3 | 2, nested); - process_next_inline ($1); - } - | fn.defpen maybe_return_init error - { process_next_inline ($1); } - ; - -pending_inlines: - /* empty */ - | pending_inlines pending_inline eat_saved_input - ; - -/* A regurgitated default argument. The value of DEFARG_MARKER will be - the TREE_LIST node for the parameter in question. */ -defarg_again: - DEFARG_MARKER expr_no_commas END_OF_SAVED_INPUT - { replace_defarg ($1, $2); } - | DEFARG_MARKER error END_OF_SAVED_INPUT - { replace_defarg ($1, error_mark_node); } - -pending_defargs: - /* empty */ %prec EMPTY - | pending_defargs defarg_again - { do_pending_defargs (); } - | pending_defargs error - { do_pending_defargs (); } - ; - -structsp: - ENUM identifier '{' - { $<itype>3 = suspend_momentary (); - $<ttype>$ = current_enum_type; - current_enum_type = start_enum ($2); } - enumlist maybecomma_warn '}' - { TYPE_VALUES (current_enum_type) = $5; - $$.t = finish_enum (current_enum_type); - $$.new_type_flag = 1; - current_enum_type = $<ttype>4; - resume_momentary ((int) $<itype>3); - check_for_missing_semicolon ($$.t); } - | ENUM identifier '{' '}' - { $$.t = finish_enum (start_enum ($2)); - $$.new_type_flag = 1; - check_for_missing_semicolon ($$.t); } - | ENUM '{' - { $<itype>2 = suspend_momentary (); - $<ttype>$ = current_enum_type; - current_enum_type = start_enum (make_anon_name ()); } - enumlist maybecomma_warn '}' - { TYPE_VALUES (current_enum_type) = $4; - $$.t = finish_enum (current_enum_type); - $$.new_type_flag = 1; - current_enum_type = $<ttype>3; - resume_momentary ((int) $<itype>1); - check_for_missing_semicolon ($$.t); } - | ENUM '{' '}' - { $$.t = finish_enum (start_enum (make_anon_name())); - $$.new_type_flag = 1; - check_for_missing_semicolon ($$.t); } - | ENUM identifier - { $$.t = xref_tag (enum_type_node, $2, 1); - $$.new_type_flag = 0; } - | ENUM complex_type_name - { $$.t = xref_tag (enum_type_node, $2, 1); - $$.new_type_flag = 0; } - | TYPENAME_KEYWORD typename_sub - { $$.t = $2; - $$.new_type_flag = 0; - if (!processing_template_decl) - cp_pedwarn ("using `typename' outside of template"); } - /* C++ extensions, merged with C to avoid shift/reduce conflicts */ - | class_head left_curly - opt.component_decl_list '}' maybe_attribute - { - int semi; - - if (yychar == YYEMPTY) - yychar = YYLEX; - semi = yychar == ';'; - - $<ttype>$ = finish_class_definition ($1, $5, semi); - } - pending_defargs - { finish_default_args (); } - pending_inlines - { $$.t = $<ttype>6; - $$.new_type_flag = 1; - begin_inline_definitions (); } - | class_head %prec EMPTY - { - $$.new_type_flag = 0; - if (TYPE_BINFO ($1) == NULL_TREE) - { - cp_error ("%T is not a class type", $1); - $$.t = error_mark_node; - } - else - { - $$.t = $1; - /* struct B: public A; is not accepted by the WP grammar. */ - if (TYPE_BINFO_BASETYPES ($$.t) && !TYPE_SIZE ($$.t) - && ! TYPE_BEING_DEFINED ($$.t)) - cp_error ("base clause without member specification for `%#T'", - $$.t); - } - } - ; - -maybecomma: - /* empty */ - | ',' - ; - -maybecomma_warn: - /* empty */ - | ',' - { if (pedantic && !in_system_header) - pedwarn ("comma at end of enumerator list"); } - ; - -aggr: - AGGR - | aggr SCSPEC - { error ("storage class specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr TYPESPEC - { error ("type specifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr CV_QUALIFIER - { error ("type qualifier `%s' not allowed after struct or class", IDENTIFIER_POINTER ($2)); } - | aggr AGGR - { error ("no body nor ';' separates two class, struct or union declarations"); } - | aggr attributes - { $$ = build_decl_list ($2, $1); } - ; - -named_class_head_sans_basetype: - aggr identifier - { - current_aggr = $1; - $$ = $2; - } - ; - -named_class_head_sans_basetype_defn: - aggr identifier_defn %prec EMPTY - { current_aggr = $$; $$ = $2; } - | named_class_head_sans_basetype '{' - { yyungetc ('{', 1); } - | named_class_head_sans_basetype ':' - { yyungetc (':', 1); } - ; - -named_complex_class_head_sans_basetype: - aggr nested_name_specifier identifier - { - current_aggr = $1; - $$ = handle_class_head ($1, $2, $3); - } - | aggr global_scope nested_name_specifier identifier - { - current_aggr = $1; - $$ = handle_class_head ($1, $3, $4); - } - | aggr global_scope identifier - { - current_aggr = $1; - $$ = handle_class_head ($1, NULL_TREE, $3); - } - | aggr apparent_template_type - { current_aggr = $$; $$ = $2; } - | aggr nested_name_specifier apparent_template_type - { current_aggr = $$; $$ = $3; } - ; - -named_class_head: - named_class_head_sans_basetype %prec EMPTY - { $$ = xref_tag (current_aggr, $1, 1); } - | named_class_head_sans_basetype_defn - { $<ttype>$ = xref_tag (current_aggr, $1, 0); } - /* Class name is unqualified, so we look for base classes - in the current scope. */ - maybe_base_class_list %prec EMPTY - { - $$ = $<ttype>2; - if ($3) - xref_basetypes (current_aggr, $1, $<ttype>2, $3); - } - | named_complex_class_head_sans_basetype - { push_scope (CP_DECL_CONTEXT ($1)); } - maybe_base_class_list - { - pop_scope (CP_DECL_CONTEXT ($1)); - $$ = TREE_TYPE ($1); - if (current_aggr == union_type_node - && TREE_CODE ($$) != UNION_TYPE) - cp_pedwarn ("`union' tag used in declaring `%#T'", $$); - else if (TREE_CODE ($$) == UNION_TYPE - && current_aggr != union_type_node) - cp_pedwarn ("non-`union' tag used in declaring `%#T'", $$); - else if (TREE_CODE ($$) == RECORD_TYPE) - /* We might be specializing a template with a different - class-key; deal. */ - CLASSTYPE_DECLARED_CLASS ($$) = (current_aggr - == class_type_node); - if ($3) - { - maybe_process_partial_specialization ($$); - xref_basetypes (current_aggr, $1, $$, $3); - } - } - ; - -unnamed_class_head: - aggr '{' - { $$ = xref_tag ($$, make_anon_name (), 0); - yyungetc ('{', 1); } - ; - -class_head: - unnamed_class_head - | named_class_head - ; - -maybe_base_class_list: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | ':' see_typename %prec EMPTY - { yyungetc(':', 1); $$ = NULL_TREE; } - | ':' see_typename base_class_list %prec EMPTY - { $$ = $3; } - ; - -base_class_list: - base_class - | base_class_list ',' see_typename base_class - { /* CYGNUS LOCAL Embedded C++ */ - if (flag_embedded_cxx) - pedwarn ("Embedded C++ prohibits multiple inheritance"); - /* END CYGNUS LOCAL Embedded C++ */ - $$ = chainon ($$, $4); } - ; - -base_class: - base_class.1 - { $$ = finish_base_specifier (access_default_node, $1, - current_aggr - == signature_type_node); } - | base_class_access_list see_typename base_class.1 - { $$ = finish_base_specifier ($1, $3, - current_aggr - == signature_type_node); } - ; - -base_class.1: - typename_sub - { if ($$ != error_mark_node) $$ = TYPE_MAIN_DECL ($1); } - | nonnested_type - | SIGOF '(' expr ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (TREE_TYPE ($3))) - { - sorry ("`sigof' as base signature specifier"); - $$ = TREE_TYPE ($3); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } - | SIGOF '(' type_id ')' - { - if (current_aggr == signature_type_node) - { - if (IS_AGGR_TYPE (groktypename ($3.t))) - { - sorry ("`sigof' as base signature specifier"); - $$ = groktypename ($3.t); - } - else - { - error ("`sigof' applied to non-aggregate expression"); - $$ = error_mark_node; - } - } - else - { - error ("`sigof' in struct or class declaration"); - $$ = error_mark_node; - } - } - ; - -base_class_access_list: - VISSPEC see_typename - | SCSPEC see_typename - { if ($1 != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", $1); - $$ = access_default_virtual_node; } - | base_class_access_list VISSPEC see_typename - { - if ($1 != access_default_virtual_node) - error ("multiple access specifiers"); - else if ($2 == access_public_node) - $$ = access_public_virtual_node; - else if ($2 == access_protected_node) - $$ = access_protected_virtual_node; - else /* $2 == access_private_node */ - $$ = access_private_virtual_node; - } - | base_class_access_list SCSPEC see_typename - { if ($2 != ridpointers[(int)RID_VIRTUAL]) - cp_error ("`%D' access", $2); - else if ($$ == access_public_node) - $$ = access_public_virtual_node; - else if ($$ == access_protected_node) - $$ = access_protected_virtual_node; - else if ($$ == access_private_node) - $$ = access_private_virtual_node; - else - error ("multiple `virtual' specifiers"); - } - ; - -left_curly: - '{' - { $<ttype>0 = begin_class_definition ($<ttype>0); } - ; - -self_reference: - /* empty */ - { - finish_member_declaration (build_self_reference ()); - } - ; - -opt.component_decl_list: - self_reference - | self_reference component_decl_list - | opt.component_decl_list access_specifier component_decl_list - | opt.component_decl_list access_specifier - ; - -access_specifier: - VISSPEC ':' - { - if (current_aggr == signature_type_node) - { - error ("access specifier not allowed in signature"); - $1 = access_public_node; - } - - current_access_specifier = $1; - } - ; - -/* Note: we no longer warn about the semicolon after a component_decl_list. - ARM $9.2 says that the semicolon is optional, and therefore allowed. */ -component_decl_list: - component_decl - { - finish_member_declaration ($1); - } - | component_decl_list component_decl - { - finish_member_declaration ($2); - } - ; - -component_decl: - component_decl_1 ';' - | component_decl_1 '}' - { error ("missing ';' before right brace"); - yyungetc ('}', 0); } - /* C++: handle constructors, destructors and inline functions */ - /* note that INLINE is like a TYPESPEC */ - | fn.def2 ':' /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn.def2 TRY /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn.def2 RETURN /* base_init compstmt */ - { $$ = finish_method ($$); } - | fn.def2 '{' /* nodecls compstmt */ - { $$ = finish_method ($$); } - | ';' - { $$ = NULL_TREE; } - | extension component_decl - { $$ = $2; - pedantic = $<itype>1; } - | template_header component_decl - { - if ($2) - $$ = finish_member_template_decl ($2); - else - /* The component was already processed. */ - $$ = NULL_TREE; - - finish_template_decl ($1); - } - | template_header typed_declspecs ';' - { - $$ = finish_member_class_template ($2.t); - finish_template_decl ($1); - } - ; - -component_decl_1: - /* Do not add a "typed_declspecs declarator" rule here for - speed; we need to call grok_x_components for enums, so the - speedup would be insignificant. */ - typed_declspecs components - { - /* Most of the productions for component_decl only - allow the creation of one new member, so we call - finish_member_declaration in component_decl_list. - For this rule and the next, however, there can be - more than one member, e.g.: - - int i, j; - - and we need the first member to be fully - registered before the second is processed. - Therefore, the rules for components take care of - this processing. To avoid registering the - components more than once, we send NULL_TREE up - here; that lets finish_member_declaration now - that there is nothing to do. */ - if (!$2) - grok_x_components ($1.t); - $$ = NULL_TREE; - } - | declmods notype_components - { - if (!$2) - grok_x_components ($1); - $$ = NULL_TREE; - } - | notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } - | ':' expr_no_commas - { $$ = grokbitfield (NULL_TREE, NULL_TREE, $2); } - | error - { $$ = NULL_TREE; } - - /* These rules introduce a reduce/reduce conflict; in - typedef int foo, bar; - class A { - foo (bar); - }; - should "A::foo" be declared as a function or "A::bar" as a data - member? In other words, is "bar" an after_type_declarator or a - parmlist? */ - | declmods component_constructor_declarator maybeasm maybe_attribute maybe_init - { tree specs, attrs; - split_specs_attrs ($1, &specs, &attrs); - $$ = grokfield ($2, specs, $5, $3, - build_tree_list ($4, attrs)); } - | component_constructor_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, NULL_TREE, $4, $2, - build_tree_list ($3, NULL_TREE)); } - | using_decl - { $$ = do_class_using_decl ($1); } - -/* The case of exactly one component is handled directly by component_decl. */ -/* ??? Huh? ^^^ */ -components: - /* empty: possibly anonymous */ - { $$ = 0; } - | component_declarator0 - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $1 = finish_member_template_decl ($1); - finish_member_declaration ($1); - $$ = 1; - } - | components ',' component_declarator - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $3 = finish_member_template_decl ($3); - finish_member_declaration ($3); - $$ = 2; - } - ; - -notype_components: - /* empty: possibly anonymous */ - { $$ = 0; } - | notype_component_declarator0 - { - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $1 = finish_member_template_decl ($1); - finish_member_declaration ($1); - $$ = 1; - } - | notype_components ',' notype_component_declarator - { - check_multiple_declarators (); - if (PROCESSING_REAL_TEMPLATE_DECL_P ()) - $3 = finish_member_template_decl ($3); - finish_member_declaration ($3); - $$ = 2; - } - ; - -component_declarator0: - after_type_component_declarator0 - | notype_component_declarator0 - ; - -component_declarator: - after_type_component_declarator - | notype_component_declarator - ; - -after_type_component_declarator0: - after_type_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | TYPENAME ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - ; - -notype_component_declarator0: - notype_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | constructor_declarator maybeasm maybe_attribute maybe_init - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - | ':' expr_no_commas maybe_attribute - { split_specs_attrs ($<ttype>0, ¤t_declspecs, - &prefix_attributes); - $<ttype>0 = current_declspecs; - $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } - ; - -after_type_component_declarator: - after_type_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | TYPENAME ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - ; - -notype_component_declarator: - notype_declarator maybeasm maybe_attribute maybe_init - { $$ = grokfield ($$, current_declspecs, $4, $2, - build_tree_list ($3, prefix_attributes)); } - | IDENTIFIER ':' expr_no_commas maybe_attribute - { $$ = grokbitfield ($$, current_declspecs, $3); - cplus_decl_attributes ($$, $4, prefix_attributes); } - | ':' expr_no_commas maybe_attribute - { $$ = grokbitfield (NULL_TREE, current_declspecs, $2); - cplus_decl_attributes ($$, $3, prefix_attributes); } - ; - -/* We chain the enumerators in reverse order. - Because of the way enums are built, the order is - insignificant. Take advantage of this fact. */ - -enumlist: - enumerator - | enumlist ',' enumerator - { TREE_CHAIN ($3) = $$; $$ = $3; } - ; - -enumerator: - identifier - { $$ = build_enumerator ($$, NULL_TREE, current_enum_type); } - | identifier '=' expr_no_commas - { $$ = build_enumerator ($$, $3, current_enum_type); } - ; - -/* ANSI new-type-id (5.3.4) */ -new_type_id: - type_specifier_seq new_declarator - { $$.t = build_decl_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | type_specifier_seq %prec EMPTY - { $$.t = build_decl_list ($1.t, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - /* GNU extension to allow arrays of arbitrary types with - non-constant dimension. For the use of begin_new_placement - here, see the comments in unary_expr above. */ - | '(' .begin_new_placement type_id .finish_new_placement - '[' expr ']' - { - if (pedantic) - pedwarn ("ANSI C++ forbids array dimensions with parenthesized type in new"); - $$.t = build_parse_node (ARRAY_REF, TREE_VALUE ($3.t), $6); - $$.t = build_decl_list (TREE_PURPOSE ($3.t), $$.t); - $$.new_type_flag = $3.new_type_flag; - } - ; - -cv_qualifiers: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | cv_qualifiers CV_QUALIFIER - { $$ = decl_tree_cons (NULL_TREE, $2, $$); } - ; - -nonempty_cv_qualifiers: - CV_QUALIFIER - { $$.t = IDENTIFIER_AS_LIST ($1); - $$.new_type_flag = 0; } - | nonempty_cv_qualifiers CV_QUALIFIER - { $$.t = decl_tree_cons (NULL_TREE, $2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -/* These rules must follow the rules for function declarations - and component declarations. That way, longer rules are preferred. */ - -suspend_mom: - /* empty */ - { $<itype>$ = suspend_momentary (); } - -/* An expression which will not live on the momentary obstack. */ -nonmomentary_expr: - suspend_mom expr - { resume_momentary ((int) $<itype>1); $$ = $2; } - ; - -/* An expression which will not live on the momentary obstack. */ -maybe_parmlist: - suspend_mom '(' nonnull_exprlist ')' - { resume_momentary ((int) $<itype>1); $$ = $3; } - | suspend_mom '(' parmlist ')' - { resume_momentary ((int) $<itype>1); $$ = $3; } - | suspend_mom LEFT_RIGHT - { resume_momentary ((int) $<itype>1); $$ = empty_parms (); } - | suspend_mom '(' error ')' - { resume_momentary ((int) $<itype>1); $$ = NULL_TREE; } - ; - -/* A declarator that is allowed only after an explicit typespec. */ -/* may all be followed by prec '.' */ -after_type_declarator: - '*' nonempty_cv_qualifiers after_type_declarator %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers after_type_declarator %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' after_type_declarator %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' after_type_declarator %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers after_type_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_after_type_declarator - ; - -nonnested_type: - type_name %prec EMPTY - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - { - $$ = lookup_name ($1, 1); - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - { - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - pushdecl_class_level ($$); - } - } - else - $$ = $1; - } - | global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - ; - -complete_type_name: - nonnested_type - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -nested_type: - nested_name_specifier type_name %prec EMPTY - { $$ = get_type_decl ($2); } - ; - -direct_after_type_declarator: - direct_after_type_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | direct_after_type_declarator '[' nonmomentary_expr ']' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_after_type_declarator '[' ']' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | '(' after_type_declarator ')' - { $$ = $2; } - | nested_name_specifier type_name %prec EMPTY - { push_nested_class ($1, 3); - $$ = build_parse_node (SCOPE_REF, $$, $2); - TREE_COMPLEXITY ($$) = current_class_depth; } - | type_name %prec EMPTY - ; - -/* A declarator allowed whether or not there has been - an explicit typespec. These cannot redeclare a typedef-name. */ - -notype_declarator_intern: - notype_declarator - | attributes notype_declarator - { - /* Provide support for '(' attributes '*' declarator ')' - etc */ - $$ = decl_tree_cons ($1, $2, NULL_TREE); - } - ; - -notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_notype_declarator - ; - -complex_notype_declarator: - '*' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_pointer_declarator ($2.t, $3); } - | '&' nonempty_cv_qualifiers notype_declarator_intern %prec UNARY - { $$ = make_reference_declarator ($2.t, $3); } - | '*' complex_notype_declarator %prec UNARY - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '&' complex_notype_declarator %prec UNARY - { $$ = make_reference_declarator (NULL_TREE, $2); } - | ptr_to_mem cv_qualifiers notype_declarator_intern - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | complex_direct_notype_declarator - ; - -complex_direct_notype_declarator: - direct_notype_declarator maybe_parmlist cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $2, $3, $4); } - | '(' complex_notype_declarator ')' - { $$ = $2; } - | direct_notype_declarator '[' nonmomentary_expr ']' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_notype_declarator '[' ']' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | notype_qualified_id - { enter_scope_of ($1); } - | nested_name_specifier notype_template_declarator - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); - enter_scope_of ($$); - } - ; - -qualified_id: - nested_name_specifier unqualified_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); } - ; - -notype_qualified_id: - nested_name_specifier notype_unqualified_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $$, $2); } - | nested_name_specifier object_template_id - { got_scope = NULL_TREE; - $$ = build_parse_node (SCOPE_REF, $1, $2); } - ; - -overqualified_id: - notype_qualified_id - | global_scope notype_qualified_id - { $$ = $2; } - ; - -functional_cast: - typespec '(' nonnull_exprlist ')' - { $$ = build_functional_cast ($1.t, $3); } - | typespec '(' expr_or_declarator_intern ')' - { $$ = reparse_decl_as_expr ($1.t, $3); } - | typespec fcast_or_absdcl %prec EMPTY - { $$ = reparse_absdcl_as_expr ($1.t, $2); } - ; -type_name: - TYPENAME - | SELFNAME - | template_type %prec EMPTY - ; - -nested_name_specifier: - nested_name_specifier_1 - | nested_name_specifier nested_name_specifier_1 - { $$ = $2; } - | nested_name_specifier TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } - ; - -/* Why the @#$%^& do type_name and notype_identifier need to be expanded - inline here?!? (jason) */ -nested_name_specifier_1: - TYPENAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - { - $$ = lastiddecl; - /* Remember that this name has been used in the class - definition, as per [class.scope0] */ - if (current_class_type - && TYPE_BEING_DEFINED (current_class_type) - && ! IDENTIFIER_CLASS_VALUE ($1)) - pushdecl_class_level ($$); - } - got_scope = $$ = TYPE_MAIN_VARIANT (TREE_TYPE ($$)); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$ = TREE_TYPE ($$); - } - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($1)); } -/* These break 'const i;' - | IDENTIFIER SCOPE - { - failed_scope: - cp_error ("`%D' is not an aggregate typedef", - lastiddecl ? lastiddecl : $$); - $$ = error_mark_node; - } - | PTYPENAME SCOPE - { goto failed_scope; } */ - ; - -typename_sub: - typename_sub0 - | global_scope typename_sub0 - { $$ = $2; } - ; - -typename_sub0: - typename_sub1 identifier %prec EMPTY - { - if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 template_type %prec EMPTY - { $$ = TREE_TYPE ($2); } - | typename_sub1 explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $2); } - | typename_sub1 TEMPLATE explicit_template_type %prec EMPTY - { $$ = make_typename_type ($1, $3); } - ; - -typename_sub1: - typename_sub2 - { - if (TREE_CODE ($1) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $1); - } - | typename_sub1 typename_sub2 - { - if (TREE_CODE_CLASS (TREE_CODE ($1)) == 't') - $$ = make_typename_type ($1, $2); - else if (TREE_CODE ($2) == IDENTIFIER_NODE) - cp_error ("`%T' is not a class or namespace", $2); - else - { - $$ = $2; - if (TREE_CODE ($$) == TYPE_DECL) - $$ = TREE_TYPE ($$); - } - } - | typename_sub1 explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $2); } - | typename_sub1 TEMPLATE explicit_template_type SCOPE - { got_scope = $$ = make_typename_type ($1, $3); } - ; - -typename_sub2: - TYPENAME SCOPE - { - if (TREE_CODE ($1) != IDENTIFIER_NODE) - $1 = lastiddecl; - - /* Retrieve the type for the identifier, which might involve - some computation. */ - got_scope = $$ = complete_type (IDENTIFIER_TYPE_VALUE ($1)); - - if ($$ == error_mark_node) - cp_error ("`%T' is not a class or namespace", $1); - } - | SELFNAME SCOPE - { - if (TREE_CODE ($1) != IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$ = complete_type (TREE_TYPE ($$)); - } - | template_type SCOPE - { got_scope = $$ = complete_type (TREE_TYPE ($$)); } - | PTYPENAME SCOPE - | IDENTIFIER SCOPE - | NSNAME SCOPE - { - if (TREE_CODE ($$) == IDENTIFIER_NODE) - $$ = lastiddecl; - got_scope = $$; - } - ; - -explicit_template_type: - identifier '<' template_arg_list_opt template_close_bracket - { $$ = build_min_nt (TEMPLATE_ID_EXPR, $1, $3); } - ; - -complex_type_name: - global_scope type_name - { - if (TREE_CODE ($2) == IDENTIFIER_NODE) - $$ = IDENTIFIER_GLOBAL_VALUE ($2); - else - $$ = $2; - got_scope = NULL_TREE; - } - | nested_type - | global_scope nested_type - { $$ = $2; } - ; - -ptr_to_mem: - nested_name_specifier '*' - { got_scope = NULL_TREE; } - | global_scope nested_name_specifier '*' - { $$ = $2; got_scope = NULL_TREE; } - ; - -/* All uses of explicit global scope must go through this nonterminal so - that got_scope will be set before yylex is called to get the next token. */ -global_scope: - SCOPE - { got_scope = void_type_node; } - ; - -/* ANSI new-declarator (5.3.4) */ -new_declarator: - '*' cv_qualifiers new_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '*' cv_qualifiers %prec EMPTY - { $$ = make_pointer_declarator ($2, NULL_TREE); } - | '&' cv_qualifiers new_declarator %prec EMPTY - { $$ = make_reference_declarator ($2, $3); } - | '&' cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers new_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_new_declarator %prec EMPTY - ; - -/* ANSI direct-new-declarator (5.3.4) */ -direct_new_declarator: - '[' expr ']' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } - | direct_new_declarator '[' nonmomentary_expr ']' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - ; - -/* ANSI abstract-declarator (8.1) */ -absdcl: - '*' nonempty_cv_qualifiers absdcl - { $$ = make_pointer_declarator ($2.t, $3); } - | '*' absdcl - { $$ = make_pointer_declarator (NULL_TREE, $2); } - | '*' nonempty_cv_qualifiers %prec EMPTY - { $$ = make_pointer_declarator ($2.t, NULL_TREE); } - | '*' %prec EMPTY - { $$ = make_pointer_declarator (NULL_TREE, NULL_TREE); } - | '&' nonempty_cv_qualifiers absdcl - { $$ = make_reference_declarator ($2.t, $3); } - | '&' absdcl - { $$ = make_reference_declarator (NULL_TREE, $2); } - | '&' nonempty_cv_qualifiers %prec EMPTY - { $$ = make_reference_declarator ($2.t, NULL_TREE); } - | '&' %prec EMPTY - { $$ = make_reference_declarator (NULL_TREE, NULL_TREE); } - | ptr_to_mem cv_qualifiers %prec EMPTY - { tree arg = make_pointer_declarator ($2, NULL_TREE); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | ptr_to_mem cv_qualifiers absdcl - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - | direct_abstract_declarator %prec EMPTY - ; - -/* ANSI direct-abstract-declarator (8.1) */ -direct_abstract_declarator: - '(' absdcl ')' - { $$ = $2; } - /* `(typedef)1' is `int'. */ - | PAREN_STAR_PAREN - | direct_abstract_declarator '(' parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, $3, $5, $6); } - | direct_abstract_declarator LEFT_RIGHT cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator ($$, empty_parms (), $3, $4); } - | direct_abstract_declarator '[' nonmomentary_expr ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, $$, $3); } - | direct_abstract_declarator '[' ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, $$, NULL_TREE); } - | '(' complex_parmlist ')' cv_qualifiers exception_specification_opt %prec '.' - { $$ = make_call_declarator (NULL_TREE, $2, $4, $5); } - | regcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | fcast_or_absdcl cv_qualifiers exception_specification_opt %prec '.' - { set_quals_and_spec ($$, $2, $3); } - | '[' nonmomentary_expr ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, $2); } - | '[' ']' %prec '.' - { $$ = build_parse_node (ARRAY_REF, NULL_TREE, NULL_TREE); } - ; - -/* For C++, decls and stmts can be intermixed, so we don't need to - have a special rule that won't start parsing the stmt section - until we have a stmt that parses without errors. */ - -stmts: - stmt - | errstmt - | stmts stmt - | stmts errstmt - ; - -errstmt: - error ';' - ; - -/* Read zero or more forward-declarations for labels - that nested functions can jump to. */ -maybe_label_decls: - /* empty */ - | label_decls - { if (pedantic) - pedwarn ("ANSI C++ forbids label declarations"); } - ; - -label_decls: - label_decl - | label_decls label_decl - ; - -label_decl: - LABEL identifiers_or_typenames ';' - { tree link; - for (link = $2; link; link = TREE_CHAIN (link)) - { - tree label = shadow_label (TREE_VALUE (link)); - C_DECLARED_LABEL_FLAG (label) = 1; - declare_nonlocal_label (label); - } - } - ; - -/* This is the body of a function definition. - It causes syntax errors to ignore to the next openbrace. */ -compstmt_or_error: - compstmt - {} - | error compstmt - ; - -compstmt: - '{' - { $<ttype>$ = begin_compound_stmt (0); } - compstmtend - { $$ = finish_compound_stmt (0, $<ttype>2); } - ; - -simple_if: - IF - { - $<ttype>$ = begin_if_stmt (); - cond_stmt_keyword = "if"; - } - paren_cond_or_null - { finish_if_stmt_cond ($3, $<ttype>2); } - implicitly_scoped_stmt - { $<ttype>$ = finish_then_clause ($<ttype>2); } - ; - -implicitly_scoped_stmt: - compstmt - | { $<ttype>$ = begin_compound_stmt (0); } - simple_stmt - { $$ = finish_compound_stmt (0, $<ttype>1); } - ; - -stmt: - compstmt - {} - | simple_stmt - ; - -simple_stmt: - decl - { finish_stmt (); } - | expr ';' - { finish_expr_stmt ($1); } - | simple_if ELSE - { begin_else_clause (); } - implicitly_scoped_stmt - { - finish_else_clause ($<ttype>1); - finish_if_stmt (); - } - | simple_if %prec IF - { finish_if_stmt (); } - | WHILE - { - $<ttype>$ = begin_while_stmt (); - cond_stmt_keyword = "while"; - } - paren_cond_or_null - { finish_while_stmt_cond ($3, $<ttype>2); } - already_scoped_stmt - { finish_while_stmt ($<ttype>2); } - | DO - { $<ttype>$ = begin_do_stmt (); } - implicitly_scoped_stmt WHILE - { - finish_do_body ($<ttype>2); - cond_stmt_keyword = "do"; - } - paren_expr_or_null ';' - { finish_do_stmt ($6, $<ttype>2); } - | FOR - { $<ttype>$ = begin_for_stmt (); } - '(' for.init.statement - { finish_for_init_stmt ($<ttype>2); } - xcond ';' - { finish_for_cond ($6, $<ttype>2); } - xexpr ')' - { finish_for_expr ($9, $<ttype>2); } - already_scoped_stmt - { finish_for_stmt ($9, $<ttype>2); } - | SWITCH - { begin_switch_stmt (); } - '(' condition ')' - { $<ttype>$ = finish_switch_cond ($4); } - implicitly_scoped_stmt - { finish_switch_stmt ($4, $<ttype>6); } - | CASE expr_no_commas ':' - { finish_case_label ($2, NULL_TREE); } - stmt - | CASE expr_no_commas ELLIPSIS expr_no_commas ':' - { finish_case_label ($2, $4); } - stmt - | DEFAULT ':' - { finish_case_label (NULL_TREE, NULL_TREE); } - stmt - | BREAK ';' - { finish_break_stmt (); } - | CONTINUE ';' - { finish_continue_stmt (); } - | RETURN ';' - { finish_return_stmt (NULL_TREE); } - | RETURN expr ';' - { finish_return_stmt ($2); } - | asm_keyword maybe_cv_qualifier '(' string ')' ';' - { - finish_asm_stmt ($2, $4, NULL_TREE, NULL_TREE, - NULL_TREE); - } - /* This is the case with just output operands. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ')' ';' - { - finish_asm_stmt ($2, $4, $6, NULL_TREE, - NULL_TREE); - } - /* This is the case with input operands as well. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' asm_operands ')' ';' - { finish_asm_stmt ($2, $4, $6, $8, NULL_TREE); } - /* This is the case with clobbered registers as well. */ - | asm_keyword maybe_cv_qualifier '(' string ':' asm_operands ':' - asm_operands ':' asm_clobbers ')' ';' - { finish_asm_stmt ($2, $4, $6, $8, $10); } - | GOTO '*' expr ';' - { - if (pedantic) - pedwarn ("ANSI C++ forbids computed gotos"); - finish_goto_stmt ($3); - } - | GOTO identifier ';' - { finish_goto_stmt ($2); } - | label_colon stmt - { finish_stmt (); } - | label_colon '}' - { error ("label must be followed by statement"); - yyungetc ('}', 0); - finish_stmt (); } - | ';' - { finish_stmt (); } - | try_block - | using_directive - | namespace_using_decl - { do_local_using_decl ($1); } - | namespace_alias - ; - -function_try_block: - TRY - { - if (! current_function_parms_stored) - store_parm_decls (); - expand_start_early_try_stmts (); - } - ctor_initializer_opt compstmt - { - expand_start_all_catch (); - } - handler_seq - { - expand_end_all_catch (); - $$ = $3; - } - ; - -try_block: - TRY - { $<ttype>$ = begin_try_block (); } - compstmt - { finish_try_block ($<ttype>2); } - handler_seq - { finish_handler_sequence ($<ttype>2); } - ; - -handler_seq: - handler - | handler_seq handler - ; - -handler: - CATCH - { $<ttype>$ = begin_handler(); } - handler_args - { finish_handler_parms ($<ttype>2); } - compstmt - { finish_handler ($<ttype>2); } - ; - -type_specifier_seq: - typed_typespecs %prec EMPTY - | nonempty_cv_qualifiers %prec EMPTY - ; - -handler_args: - '(' ELLIPSIS ')' - { expand_start_catch_block (NULL_TREE, NULL_TREE); } - /* This doesn't allow reference parameters, the below does. - | '(' type_specifier_seq absdcl ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' type_specifier_seq ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, NULL_TREE); } - | '(' type_specifier_seq notype_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - | '(' typed_typespecs after_type_declarator ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block ($2.t, $3); } - This allows reference parameters... */ - | '(' parm ')' - { check_for_new_type ("inside exception declarations", $2); - expand_start_catch_block (TREE_PURPOSE ($2.t), - TREE_VALUE ($2.t)); } - ; - -label_colon: - IDENTIFIER ':' - { tree label; - do_label: - label = define_label (input_filename, lineno, $1); - if (label && ! minimal_parse_mode) - expand_label (label); - } - | PTYPENAME ':' - { goto do_label; } - | TYPENAME ':' - { goto do_label; } - | SELFNAME ':' - { goto do_label; } - ; - -for.init.statement: - xexpr ';' - { if ($1) cplus_expand_expr_stmt ($1); } - | decl - | '{' compstmtend - { if (pedantic) - pedwarn ("ANSI C++ forbids compound statements inside for initializations"); - } - ; - -/* Either a type-qualifier or nothing. First thing in an `asm' statement. */ - -maybe_cv_qualifier: - /* empty */ - { emit_line_note (input_filename, lineno); - $$ = NULL_TREE; } - | CV_QUALIFIER - { emit_line_note (input_filename, lineno); } - ; - -xexpr: - /* empty */ - { $$ = NULL_TREE; } - | expr - | error - { $$ = NULL_TREE; } - ; - -/* These are the operands other than the first string and colon - in asm ("addextend %2,%1": "=dm" (x), "0" (y), "g" (*x)) */ -asm_operands: - /* empty */ - { $$ = NULL_TREE; } - | nonnull_asm_operands - ; - -nonnull_asm_operands: - asm_operand - | nonnull_asm_operands ',' asm_operand - { $$ = chainon ($$, $3); } - ; - -asm_operand: - STRING '(' expr ')' - { $$ = build_tree_list ($$, $3); } - ; - -asm_clobbers: - STRING - { $$ = tree_cons (NULL_TREE, $$, NULL_TREE); } - | asm_clobbers ',' STRING - { $$ = tree_cons (NULL_TREE, $3, $$); } - ; - -/* This is what appears inside the parens in a function declarator. - Its value is represented in the format that grokdeclarator expects. - - In C++, declaring a function with no parameters - means that that function takes *no* parameters. */ - -parmlist: - /* empty */ - { - $$ = empty_parms(); - } - | complex_parmlist - | type_id - { $$ = finish_parmlist (build_tree_list (NULL_TREE, $1.t), 0); - check_for_new_type ("inside parameter list", $1); } - ; - -/* This nonterminal does not include the common sequence '(' type_id ')', - as it is ambiguous and must be disambiguated elsewhere. */ -complex_parmlist: - parms - { $$ = finish_parmlist ($$, 0); } - | parms_comma ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - /* C++ allows an ellipsis without a separating ',' */ - | parms ELLIPSIS - { $$ = finish_parmlist ($1, 1); } - | type_id ELLIPSIS - { $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 1); } - | ELLIPSIS - { $$ = finish_parmlist (NULL_TREE, 1); } - | parms ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist ($1, 0); - yyungetc (':', 0); - yychar = ')'; - } - | type_id ':' - { - /* This helps us recover from really nasty - parse errors, for example, a missing right - parenthesis. */ - yyerror ("possibly missing ')'"); - $$ = finish_parmlist (build_tree_list (NULL_TREE, - $1.t), 0); - yyungetc (':', 0); - yychar = ')'; - } - ; - -/* A default argument to a */ -defarg: - '=' - { maybe_snarf_defarg (); } - defarg1 - { $$ = $3; } - ; - -defarg1: - DEFARG - | init - ; - -/* A nonempty list of parameter declarations or type names. */ -parms: - named_parm - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - | parm defarg - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list ($2, $1.t); } - | parms_comma full_parm - { check_for_new_type ("in a parameter list", $2); - $$ = chainon ($$, $2.t); } - | parms_comma bad_parm - { $$ = chainon ($$, build_tree_list (NULL_TREE, $2)); } - | parms_comma bad_parm '=' init - { $$ = chainon ($$, build_tree_list ($4, $2)); } - ; - -parms_comma: - parms ',' - | type_id ',' - { check_for_new_type ("in a parameter list", $1); - $$ = build_tree_list (NULL_TREE, $1.t); } - ; - -/* A single parameter declaration or parameter type name, - as found in a parmlist. */ -named_parm: - /* Here we expand typed_declspecs inline to avoid mis-parsing of - TYPESPEC IDENTIFIER. */ - typed_declspecs1 declarator - { tree specs = strip_attrs ($1.t); - $$.new_type_flag = $1.new_type_flag; - $$.t = build_tree_list (specs, $2); } - | typed_typespecs declarator - { $$.t = build_tree_list ($1.t, $2); - $$.new_type_flag = $1.new_type_flag; } - | typespec declarator - { $$.t = build_tree_list (get_decl_list ($1.t), $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_declspecs1 absdcl - { tree specs = strip_attrs ($1.t); - $$.t = build_tree_list (specs, $2); - $$.new_type_flag = $1.new_type_flag; } - | typed_declspecs1 %prec EMPTY - { tree specs = strip_attrs ($1.t); - $$.t = build_tree_list (specs, NULL_TREE); - $$.new_type_flag = $1.new_type_flag; } - | declmods notype_declarator - { tree specs = strip_attrs ($1); - $$.t = build_tree_list (specs, $2); - $$.new_type_flag = 0; } - ; - -full_parm: - parm - { $$.t = build_tree_list (NULL_TREE, $1.t); - $$.new_type_flag = $1.new_type_flag; } - | parm defarg - { $$.t = build_tree_list ($2, $1.t); - $$.new_type_flag = $1.new_type_flag; } - ; - -parm: - named_parm - | type_id - ; - -see_typename: - /* empty */ %prec EMPTY - { see_typename (); } - ; - -bad_parm: - /* empty */ %prec EMPTY - { - error ("type specifier omitted for parameter"); - $$ = build_tree_list (integer_type_node, NULL_TREE); - } - | notype_declarator - { - error ("type specifier omitted for parameter"); - if (TREE_CODE ($$) == SCOPE_REF - && (TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TYPE_PARM - || TREE_CODE (TREE_OPERAND ($$, 0)) == TEMPLATE_TEMPLATE_PARM)) - cp_error (" perhaps you want `typename %E' to make it a type", $$); - $$ = build_tree_list (integer_type_node, $$); - } - ; - -exception_specification_opt: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | THROW '(' ansi_raise_identifiers ')' %prec EMPTY - { $$ = $3; } - | THROW LEFT_RIGHT %prec EMPTY - { $$ = build_decl_list (NULL_TREE, NULL_TREE); } - ; - -ansi_raise_identifier: - type_id - { $$ = build_decl_list (NULL_TREE, groktypename($1.t)); } - ; - -ansi_raise_identifiers: - ansi_raise_identifier - | ansi_raise_identifiers ',' ansi_raise_identifier - { - TREE_CHAIN ($3) = $$; - $$ = $3; - } - ; - -conversion_declarator: - /* empty */ %prec EMPTY - { $$ = NULL_TREE; } - | '*' cv_qualifiers conversion_declarator - { $$ = make_pointer_declarator ($2, $3); } - | '&' cv_qualifiers conversion_declarator - { $$ = make_reference_declarator ($2, $3); } - | ptr_to_mem cv_qualifiers conversion_declarator - { tree arg = make_pointer_declarator ($2, $3); - $$ = build_parse_node (SCOPE_REF, $1, arg); - } - ; - -operator: - OPERATOR - { got_scope = NULL_TREE; } - ; - -operator_name: - operator '*' - { $$ = ansi_opname[MULT_EXPR]; } - | operator '/' - { $$ = ansi_opname[TRUNC_DIV_EXPR]; } - | operator '%' - { $$ = ansi_opname[TRUNC_MOD_EXPR]; } - | operator '+' - { $$ = ansi_opname[PLUS_EXPR]; } - | operator '-' - { $$ = ansi_opname[MINUS_EXPR]; } - | operator '&' - { $$ = ansi_opname[BIT_AND_EXPR]; } - | operator '|' - { $$ = ansi_opname[BIT_IOR_EXPR]; } - | operator '^' - { $$ = ansi_opname[BIT_XOR_EXPR]; } - | operator '~' - { $$ = ansi_opname[BIT_NOT_EXPR]; } - | operator ',' - { $$ = ansi_opname[COMPOUND_EXPR]; } - | operator ARITHCOMPARE - { $$ = ansi_opname[$2]; } - | operator '<' - { $$ = ansi_opname[LT_EXPR]; } - | operator '>' - { $$ = ansi_opname[GT_EXPR]; } - | operator EQCOMPARE - { $$ = ansi_opname[$2]; } - | operator ASSIGN - { $$ = ansi_assopname[$2]; } - | operator '=' - { $$ = ansi_opname [MODIFY_EXPR]; } - | operator LSHIFT - { $$ = ansi_opname[$2]; } - | operator RSHIFT - { $$ = ansi_opname[$2]; } - | operator PLUSPLUS - { $$ = ansi_opname[POSTINCREMENT_EXPR]; } - | operator MINUSMINUS - { $$ = ansi_opname[PREDECREMENT_EXPR]; } - | operator ANDAND - { $$ = ansi_opname[TRUTH_ANDIF_EXPR]; } - | operator OROR - { $$ = ansi_opname[TRUTH_ORIF_EXPR]; } - | operator '!' - { $$ = ansi_opname[TRUTH_NOT_EXPR]; } - | operator '?' ':' - { $$ = ansi_opname[COND_EXPR]; } - | operator MIN_MAX - { $$ = ansi_opname[$2]; } - | operator POINTSAT %prec EMPTY - { $$ = ansi_opname[COMPONENT_REF]; } - | operator POINTSAT_STAR %prec EMPTY - { $$ = ansi_opname[MEMBER_REF]; } - | operator LEFT_RIGHT - { $$ = ansi_opname[CALL_EXPR]; } - | operator '[' ']' - { $$ = ansi_opname[ARRAY_REF]; } - | operator NEW %prec EMPTY - { $$ = ansi_opname[NEW_EXPR]; } - | operator DELETE %prec EMPTY - { $$ = ansi_opname[DELETE_EXPR]; } - | operator NEW '[' ']' - { $$ = ansi_opname[VEC_NEW_EXPR]; } - | operator DELETE '[' ']' - { $$ = ansi_opname[VEC_DELETE_EXPR]; } - /* Names here should be looked up in class scope ALSO. */ - | operator type_specifier_seq conversion_declarator - { $$ = grokoptypename ($2.t, $3); } - | operator error - { $$ = ansi_opname[ERROR_MARK]; } - ; - -%% - -#ifdef SPEW_DEBUG -const char * -debug_yytranslate (value) - int value; -{ - return yytname[YYTRANSLATE (value)]; -} - -#endif diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c deleted file mode 100755 index 712575c..0000000 --- a/gcc/cp/pt.c +++ /dev/null @@ -1,9074 +0,0 @@ -/* Handle parameterized types (templates) for GNU C++. - Copyright (C) 1992, 93-97, 1998, 1999 Free Software Foundation, Inc. - Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing. - Rewritten by Jason Merrill (jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Known bugs or deficiencies include: - - all methods must be provided in header files; can't use a source - file that contains only the method templates and "just win". */ - -#include "config.h" -#include "system.h" -#include "obstack.h" - -#include "tree.h" -#include "flags.h" -#include "cp-tree.h" -#include "decl.h" -#include "parse.h" -#include "lex.h" -#include "output.h" -#include "defaults.h" -#include "except.h" -#include "toplev.h" - -/* The type of functions taking a tree, and some additional data, and - returning an int. */ -typedef int (*tree_fn_t) PROTO((tree, void*)); - -extern struct obstack permanent_obstack; - -extern int lineno; -extern char *input_filename; -struct pending_inline *pending_template_expansions; - -tree current_template_parms; -HOST_WIDE_INT processing_template_decl; - -tree pending_templates; -static tree *template_tail = &pending_templates; - -tree maybe_templates; -static tree *maybe_template_tail = &maybe_templates; - -int minimal_parse_mode; - -int processing_specialization; -int processing_explicit_instantiation; -int processing_template_parmlist; -static int template_header_count; - -static tree saved_trees; - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -#define UNIFY_ALLOW_NONE 0 -#define UNIFY_ALLOW_MORE_CV_QUAL 1 -#define UNIFY_ALLOW_LESS_CV_QUAL 2 -#define UNIFY_ALLOW_DERIVED 4 -#define UNIFY_ALLOW_INTEGER 8 - -static int unify PROTO((tree, tree, tree, tree, int, int*)); -static int resolve_overloaded_unification PROTO((tree, tree, tree, tree, - unification_kind_t, int, - int*)); -static int try_one_overload PROTO((tree, tree, tree, tree, tree, - unification_kind_t, int, int*)); -static int unify PROTO((tree, tree, tree, tree, int, int*)); -static void add_pending_template PROTO((tree)); -static int push_tinst_level PROTO((tree)); -static tree classtype_mangled_name PROTO((tree)); -static char *mangle_class_name_for_template PROTO((char *, tree, tree)); -static tree tsubst_expr_values PROTO((tree, tree)); -static int list_eq PROTO((tree, tree)); -static tree get_class_bindings PROTO((tree, tree, tree)); -static tree coerce_template_parms PROTO((tree, tree, tree, int, int)); -static void tsubst_enum PROTO((tree, tree, tree)); -static tree add_to_template_args PROTO((tree, tree)); -static tree add_outermost_template_args PROTO((tree, tree)); -static void maybe_adjust_types_for_deduction PROTO((unification_kind_t, tree*, - tree*)); -static int type_unification_real PROTO((tree, tree, tree, tree, - int, unification_kind_t, int, int*)); -static void note_template_header PROTO((int)); -static tree maybe_fold_nontype_arg PROTO((tree)); -static tree convert_nontype_argument PROTO((tree, tree)); -static tree convert_template_argument PROTO ((tree, tree, tree, int, - int , tree)); -static tree get_bindings_overload PROTO((tree, tree, tree)); -static int for_each_template_parm PROTO((tree, tree_fn_t, void*)); -static tree build_template_parm_index PROTO((int, int, int, tree, tree)); -static int inline_needs_template_parms PROTO((tree)); -static void push_inline_template_parms_recursive PROTO((tree, int)); -static tree retrieve_specialization PROTO((tree, tree)); -static tree register_specialization PROTO((tree, tree, tree)); -static int unregister_specialization PROTO((tree, tree)); -static tree reduce_template_parm_level PROTO((tree, tree, int)); -static tree build_template_decl PROTO((tree, tree)); -static int mark_template_parm PROTO((tree, void *)); -static tree tsubst_friend_function PROTO((tree, tree)); -static tree tsubst_friend_class PROTO((tree, tree)); -static tree get_bindings_real PROTO((tree, tree, tree, int)); -static int template_decl_level PROTO((tree)); -static tree maybe_get_template_decl_from_type_decl PROTO((tree)); -static int check_cv_quals_for_unify PROTO((int, tree, tree)); -static tree tsubst_template_arg_vector PROTO((tree, tree)); -static tree tsubst_template_parms PROTO((tree, tree)); -static void regenerate_decl_from_template PROTO((tree, tree)); -static tree most_specialized PROTO((tree, tree, tree)); -static tree most_specialized_class PROTO((tree, tree)); -static tree most_general_template PROTO((tree)); -static void set_mangled_name_for_template_decl PROTO((tree)); -static int template_class_depth_real PROTO((tree, int)); -static tree tsubst_aggr_type PROTO((tree, tree, tree, int)); -static tree tsubst_decl PROTO((tree, tree, tree, tree)); -static tree tsubst_arg_types PROTO((tree, tree, tree)); -static void check_specialization_scope PROTO((void)); -static tree process_partial_specialization PROTO((tree)); -static void set_current_access_from_decl PROTO((tree)); -static void check_default_tmpl_args PROTO((tree, tree, int, int)); -static tree tsubst_call_declarator_parms PROTO((tree, tree, tree)); - -/* We use TREE_VECs to hold template arguments. If there is only one - level of template arguments, then the TREE_VEC contains the - arguments directly. If there is more than one level of template - arguments, then each entry in the TREE_VEC is itself a TREE_VEC, - containing the template arguments for a single level. The first - entry in the outer TREE_VEC is the outermost level of template - parameters; the last is the innermost. - - It is incorrect to ever form a template argument vector containing - only one level of arguments, but which is a TREE_VEC containing as - its only entry the TREE_VEC for that level. */ - -/* Non-zero if the template arguments is actually a vector of vectors, - rather than just a vector. */ -#define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) \ - (NODE != NULL_TREE \ - && TREE_CODE (NODE) == TREE_VEC \ - && TREE_VEC_LENGTH (NODE) > 0 \ - && TREE_VEC_ELT (NODE, 0) != NULL_TREE \ - && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC) - -/* The depth of a template argument vector. When called directly by - the parser, we use a TREE_LIST rather than a TREE_VEC to represent - template arguments. In fact, we may even see NULL_TREE if there - are no template arguments. In both of those cases, there is only - one level of template arguments. */ -#define TMPL_ARGS_DEPTH(NODE) \ - (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (NODE) ? TREE_VEC_LENGTH (NODE) : 1) - -/* The LEVELth level of the template ARGS. Note that template - parameter levels are indexed from 1, not from 0. */ -#define TMPL_ARGS_LEVEL(ARGS, LEVEL) \ - (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (ARGS) \ - ? TREE_VEC_ELT ((ARGS), (LEVEL) - 1) : ARGS) - -/* Set the LEVELth level of the template ARGS to VAL. This macro does - not work with single-level argument vectors. */ -#define SET_TMPL_ARGS_LEVEL(ARGS, LEVEL, VAL) \ - (TREE_VEC_ELT ((ARGS), (LEVEL) - 1) = (VAL)) - -/* Accesses the IDXth parameter in the LEVELth level of the ARGS. */ -#define TMPL_ARG(ARGS, LEVEL, IDX) \ - (TREE_VEC_ELT (TMPL_ARGS_LEVEL (ARGS, LEVEL), IDX)) - -/* Set the IDXth element in the LEVELth level of ARGS to VAL. This - macro does not work with single-level argument vectors. */ -#define SET_TMPL_ARG(ARGS, LEVEL, IDX, VAL) \ - (TREE_VEC_ELT (TREE_VEC_ELT ((ARGS), (LEVEL) - 1), (IDX)) = (VAL)) - -/* Given a single level of template arguments in NODE, return the - number of arguments. */ -#define NUM_TMPL_ARGS(NODE) \ - ((NODE) == NULL_TREE ? 0 \ - : (TREE_CODE (NODE) == TREE_VEC \ - ? TREE_VEC_LENGTH (NODE) : list_length (NODE))) - -/* The number of levels of template parameters given by NODE. */ -#define TMPL_PARMS_DEPTH(NODE) \ - (TREE_INT_CST_HIGH (TREE_PURPOSE (NODE))) - -/* Do any processing required when DECL (a member template declaration - using TEMPLATE_PARAMETERS as its innermost parameter list) is - finished. Returns the TEMPLATE_DECL corresponding to DECL, unless - it is a specialization, in which case the DECL itself is returned. */ - -tree -finish_member_template_decl (decl) - tree decl; -{ - if (decl == NULL_TREE || decl == void_type_node) - return NULL_TREE; - else if (decl == error_mark_node) - /* By returning NULL_TREE, the parser will just ignore this - declaration. We have already issued the error. */ - return NULL_TREE; - else if (TREE_CODE (decl) == TREE_LIST) - { - /* Assume that the class is the only declspec. */ - decl = TREE_VALUE (decl); - if (IS_AGGR_TYPE (decl) && CLASSTYPE_TEMPLATE_INFO (decl) - && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (decl)) - { - tree tmpl = CLASSTYPE_TI_TEMPLATE (decl); - check_member_template (tmpl); - return tmpl; - } - return NULL_TREE; - } - else if (DECL_TEMPLATE_INFO (decl)) - { - if (!DECL_TEMPLATE_SPECIALIZATION (decl)) - { - check_member_template (DECL_TI_TEMPLATE (decl)); - return DECL_TI_TEMPLATE (decl); - } - else - return decl; - } - else - cp_error ("invalid member template declaration `%D'", decl); - - return error_mark_node; -} - -/* Returns the template nesting level of the indicated class TYPE. - - For example, in: - template <class T> - struct A - { - template <class U> - struct B {}; - }; - - A<T>::B<U> has depth two, while A<T> has depth one. - Both A<T>::B<int> and A<int>::B<U> have depth one, if - COUNT_SPECIALIZATIONS is 0 or if they are instantiations, not - specializations. - - This function is guaranteed to return 0 if passed NULL_TREE so - that, for example, `template_class_depth (current_class_type)' is - always safe. */ - -static int -template_class_depth_real (type, count_specializations) - tree type; - int count_specializations; -{ - int depth; - - for (depth = 0; - type && TREE_CODE (type) != NAMESPACE_DECL; - type = (TREE_CODE (type) == FUNCTION_DECL) - ? DECL_REAL_CONTEXT (type) : TYPE_CONTEXT (type)) - { - if (TREE_CODE (type) != FUNCTION_DECL) - { - if (CLASSTYPE_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (CLASSTYPE_TI_TEMPLATE (type)) - && ((count_specializations - && CLASSTYPE_TEMPLATE_SPECIALIZATION (type)) - || uses_template_parms (CLASSTYPE_TI_ARGS (type)))) - ++depth; - } - else - { - if (DECL_TEMPLATE_INFO (type) - && PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (type)) - && ((count_specializations - && DECL_TEMPLATE_SPECIALIZATION (type)) - || uses_template_parms (DECL_TI_ARGS (type)))) - ++depth; - } - } - - return depth; -} - -/* Returns the template nesting level of the indicated class TYPE. - Like template_class_depth_real, but instantiations do not count in - the depth. */ - -int -template_class_depth (type) - tree type; -{ - return template_class_depth_real (type, /*count_specializations=*/0); -} - -/* Returns 1 if processing DECL as part of do_pending_inlines - needs us to push template parms. */ - -static int -inline_needs_template_parms (decl) - tree decl; -{ - if (! DECL_TEMPLATE_INFO (decl)) - return 0; - - return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (most_general_template (decl))) - > (processing_template_decl + DECL_TEMPLATE_SPECIALIZATION (decl))); -} - -/* Subroutine of maybe_begin_member_template_processing. - Push the template parms in PARMS, starting from LEVELS steps into the - chain, and ending at the beginning, since template parms are listed - innermost first. */ - -static void -push_inline_template_parms_recursive (parmlist, levels) - tree parmlist; - int levels; -{ - tree parms = TREE_VALUE (parmlist); - int i; - - if (levels > 1) - push_inline_template_parms_recursive (TREE_CHAIN (parmlist), levels - 1); - - ++processing_template_decl; - current_template_parms - = tree_cons (build_int_2 (0, processing_template_decl), - parms, current_template_parms); - TEMPLATE_PARMS_FOR_INLINE (current_template_parms) = 1; - - pushlevel (0); - for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (parm)) == 'd', 0); - - switch (TREE_CODE (parm)) - { - case TYPE_DECL: - case TEMPLATE_DECL: - pushdecl (parm); - break; - - case PARM_DECL: - { - /* Make a CONST_DECL as is done in process_template_parm. - It is ugly that we recreate this here; the original - version built in process_template_parm is no longer - available. */ - tree decl = build_decl (CONST_DECL, DECL_NAME (parm), - TREE_TYPE (parm)); - SET_DECL_ARTIFICIAL (decl); - DECL_INITIAL (decl) = DECL_INITIAL (parm); - DECL_TEMPLATE_PARM_P (decl) = 1; - pushdecl (decl); - } - break; - - default: - my_friendly_abort (0); - } - } -} - -/* Restore the template parameter context for a member template or - a friend template defined in a class definition. */ - -void -maybe_begin_member_template_processing (decl) - tree decl; -{ - tree parms; - int levels; - - if (! inline_needs_template_parms (decl)) - return; - - parms = DECL_TEMPLATE_PARMS (most_general_template (decl)); - - levels = TMPL_PARMS_DEPTH (parms) - processing_template_decl; - - if (DECL_TEMPLATE_SPECIALIZATION (decl)) - { - --levels; - parms = TREE_CHAIN (parms); - } - - push_inline_template_parms_recursive (parms, levels); -} - -/* Undo the effects of begin_member_template_processing. */ - -void -maybe_end_member_template_processing () -{ - if (! processing_template_decl) - return; - - while (current_template_parms - && TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) - { - --processing_template_decl; - current_template_parms = TREE_CHAIN (current_template_parms); - poplevel (0, 0, 0); - } -} - -/* Returns non-zero iff T is a member template function. We must be - careful as in - - template <class T> class C { void f(); } - - Here, f is a template function, and a member, but not a member - template. This function does not concern itself with the origin of - T, only its present state. So if we have - - template <class T> class C { template <class U> void f(U); } - - then neither C<int>::f<char> nor C<T>::f<double> is considered - to be a member template. But, `template <class U> void - C<int>::f(U)' is considered a member template. */ - -int -is_member_template (t) - tree t; -{ - if (!DECL_FUNCTION_TEMPLATE_P (t)) - /* Anything that isn't a function or a template function is - certainly not a member template. */ - return 0; - - /* A local class can't have member templates. */ - if (hack_decl_function_context (t)) - return 0; - - return (DECL_FUNCTION_MEMBER_P (DECL_TEMPLATE_RESULT (t)) - /* If there are more levels of template parameters than - there are template classes surrounding the declaration, - then we have a member template. */ - && (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > - template_class_depth (DECL_CLASS_CONTEXT (t)))); -} - -#if 0 /* UNUSED */ -/* Returns non-zero iff T is a member template class. See - is_member_template for a description of what precisely constitutes - a member template. */ - -int -is_member_template_class (t) - tree t; -{ - if (!DECL_CLASS_TEMPLATE_P (t)) - /* Anything that isn't a class template, is certainly not a member - template. */ - return 0; - - if (!DECL_CLASS_SCOPE_P (t)) - /* Anything whose context isn't a class type is surely not a - member template. */ - return 0; - - /* If there are more levels of template parameters than there are - template classes surrounding the declaration, then we have a - member template. */ - return (TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (t)) > - template_class_depth (DECL_CONTEXT (t))); -} -#endif - -/* Return a new template argument vector which contains all of ARGS, - but has as its innermost set of arguments the EXTRA_ARGS. The - resulting vector will be built on a temporary obstack, and so must - be explicitly copied to the permanent obstack, if required. */ - -static tree -add_to_template_args (args, extra_args) - tree args; - tree extra_args; -{ - tree new_args; - int extra_depth; - int i; - int j; - - extra_depth = TMPL_ARGS_DEPTH (extra_args); - new_args = make_temp_vec (TMPL_ARGS_DEPTH (args) + extra_depth); - - for (i = 1; i <= TMPL_ARGS_DEPTH (args); ++i) - SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (args, i)); - - for (j = 1; j <= extra_depth; ++j, ++i) - SET_TMPL_ARGS_LEVEL (new_args, i, TMPL_ARGS_LEVEL (extra_args, j)); - - return new_args; -} - -/* Like add_to_template_args, but only the outermost ARGS are added to - the EXTRA_ARGS. In particular, all but TMPL_ARGS_DEPTH - (EXTRA_ARGS) levels are added. This function is used to combine - the template arguments from a partial instantiation with the - template arguments used to attain the full instantiation from the - partial instantiation. */ - -static tree -add_outermost_template_args (args, extra_args) - tree args; - tree extra_args; -{ - tree new_args; - - /* If there are more levels of EXTRA_ARGS than there are ARGS, - something very fishy is going on. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) >= TMPL_ARGS_DEPTH (extra_args), - 0); - - /* If *all* the new arguments will be the EXTRA_ARGS, just return - them. */ - if (TMPL_ARGS_DEPTH (args) == TMPL_ARGS_DEPTH (extra_args)) - return extra_args; - - /* For the moment, we make ARGS look like it contains fewer levels. */ - TREE_VEC_LENGTH (args) -= TMPL_ARGS_DEPTH (extra_args); - - new_args = add_to_template_args (args, extra_args); - - /* Now, we restore ARGS to its full dimensions. */ - TREE_VEC_LENGTH (args) += TMPL_ARGS_DEPTH (extra_args); - - return new_args; -} - -/* We've got a template header coming up; push to a new level for storing - the parms. */ - -void -begin_template_parm_list () -{ - /* We use a non-tag-transparent scope here, which causes pushtag to - put tags in this scope, rather than in the enclosing class or - namespace scope. This is the right thing, since we want - TEMPLATE_DECLS, and not TYPE_DECLS for template classes. For a - global template class, push_template_decl handles putting the - TEMPLATE_DECL into top-level scope. For a nested template class, - e.g.: - - template <class T> struct S1 { - template <class T> struct S2 {}; - }; - - pushtag contains special code to call pushdecl_with_scope on the - TEMPLATE_DECL for S2. */ - pushlevel (0); - declare_pseudo_global_level (); - ++processing_template_decl; - ++processing_template_parmlist; - note_template_header (0); -} - -/* This routine is called when a specialization is declared. If it is - illegal to declare a specialization here, an error is reported. */ - -static void -check_specialization_scope () -{ - tree scope = current_scope (); - - /* [temp.expl.spec] - - An explicit specialization shall be declared in the namespace of - which the template is a member, or, for member templates, in the - namespace of which the enclosing class or enclosing class - template is a member. An explicit specialization of a member - function, member class or static data member of a class template - shall be declared in the namespace of which the class template - is a member. */ - if (scope && TREE_CODE (scope) != NAMESPACE_DECL) - cp_error ("explicit specialization in non-namespace scope `%D'", - scope); - - /* [temp.expl.spec] - - In an explicit specialization declaration for a member of a class - template or a member template that appears in namespace scope, - the member template and some of its enclosing class templates may - remain unspecialized, except that the declaration shall not - explicitly specialize a class member template if its enclosing - class templates are not explicitly specialized as well. */ - if (current_template_parms) - cp_error ("enclosing class templates are not explicitly specialized"); -} - -/* We've just seen template <>. */ - -void -begin_specialization () -{ - note_template_header (1); - check_specialization_scope (); -} - -/* Called at then end of processing a declaration preceeded by - template<>. */ - -void -end_specialization () -{ - reset_specialization (); -} - -/* Any template <>'s that we have seen thus far are not referring to a - function specialization. */ - -void -reset_specialization () -{ - processing_specialization = 0; - template_header_count = 0; -} - -/* We've just seen a template header. If SPECIALIZATION is non-zero, - it was of the form template <>. */ - -static void -note_template_header (specialization) - int specialization; -{ - processing_specialization = specialization; - template_header_count++; -} - -/* We're beginning an explicit instantiation. */ - -void -begin_explicit_instantiation () -{ - ++processing_explicit_instantiation; -} - - -void -end_explicit_instantiation () -{ - my_friendly_assert(processing_explicit_instantiation > 0, 0); - --processing_explicit_instantiation; -} - -/* The TYPE is being declared. If it is a template type, that means it - is a partial specialization. Do appropriate error-checking. */ - -void -maybe_process_partial_specialization (type) - tree type; -{ - if (IS_AGGR_TYPE (type) && CLASSTYPE_USE_TEMPLATE (type)) - { - if (CLASSTYPE_IMPLICIT_INSTANTIATION (type) - && TYPE_SIZE (type) == NULL_TREE) - { - SET_CLASSTYPE_TEMPLATE_SPECIALIZATION (type); - if (processing_template_decl) - push_template_decl (TYPE_MAIN_DECL (type)); - } - else if (CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - cp_error ("specialization of `%T' after instantiation", type); - } -} - -/* Retrieve the specialization (in the sense of [temp.spec] - a - specialization is either an instantiation or an explicit - specialization) of TMPL for the given template ARGS. If there is - no such specialization, return NULL_TREE. The ARGS are a vector of - arguments, or a vector of vectors of arguments, in the case of - templates with more than one level of parameters. */ - -static tree -retrieve_specialization (tmpl, args) - tree tmpl; - tree args; -{ - tree s; - - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); - - /* There should be as many levels of arguments as there are - levels of parameters. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), - 0); - - for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - s != NULL_TREE; - s = TREE_CHAIN (s)) - if (comp_template_args (TREE_PURPOSE (s), args)) - return TREE_VALUE (s); - - return NULL_TREE; -} - -/* Returns non-zero iff DECL is a specialization of TMPL. */ - -int -is_specialization_of (decl, tmpl) - tree decl; - tree tmpl; -{ - tree t; - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - for (t = decl; - t != NULL_TREE; - t = DECL_TEMPLATE_INFO (t) ? DECL_TI_TEMPLATE (t) : NULL_TREE) - if (t == tmpl) - return 1; - } - else - { - my_friendly_assert (TREE_CODE (decl) == TYPE_DECL, 0); - - for (t = TREE_TYPE (decl); - t != NULL_TREE; - t = CLASSTYPE_USE_TEMPLATE (t) - ? TREE_TYPE (CLASSTYPE_TI_TEMPLATE (t)) : NULL_TREE) - if (same_type_p (TYPE_MAIN_VARIANT (t), - TYPE_MAIN_VARIANT (TREE_TYPE (tmpl)))) - return 1; - } - - return 0; -} - -/* Register the specialization SPEC as a specialization of TMPL with - the indicated ARGS. Returns SPEC, or an equivalent prior - declaration, if available. */ - -static tree -register_specialization (spec, tmpl, args) - tree spec; - tree tmpl; - tree args; -{ - tree s; - - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0); - - if (TREE_CODE (spec) == FUNCTION_DECL - && uses_template_parms (DECL_TI_ARGS (spec))) - /* This is the FUNCTION_DECL for a partial instantiation. Don't - register it; we want the corresponding TEMPLATE_DECL instead. - We use `uses_template_parms (DECL_TI_ARGS (spec))' rather than - the more obvious `uses_template_parms (spec)' to avoid problems - with default function arguments. In particular, given - something like this: - - template <class T> void f(T t1, T t = T()) - - the default argument expression is not substituted for in an - instantiation unless and until it is actually needed. */ - return spec; - - /* There should be as many levels of arguments as there are - levels of parameters. */ - my_friendly_assert (TMPL_ARGS_DEPTH (args) - == TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (tmpl)), - 0); - - for (s = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - s != NULL_TREE; - s = TREE_CHAIN (s)) - if (comp_template_args (TREE_PURPOSE (s), args)) - { - tree fn = TREE_VALUE (s); - - if (DECL_TEMPLATE_SPECIALIZATION (spec)) - { - if (DECL_TEMPLATE_INSTANTIATION (fn)) - { - if (TREE_USED (fn) - || DECL_EXPLICIT_INSTANTIATION (fn)) - { - cp_error ("specialization of %D after instantiation", - fn); - return spec; - } - else - { - /* This situation should occur only if the first - specialization is an implicit instantiation, - the second is an explicit specialization, and - the implicit instantiation has not yet been - used. That situation can occur if we have - implicitly instantiated a member function and - then specialized it later. - - We can also wind up here if a friend - declaration that looked like an instantiation - turns out to be a specialization: - - template <class T> void foo(T); - class S { friend void foo<>(int) }; - template <> void foo(int); - - We transform the existing DECL in place so that - any pointers to it become pointers to the - updated declaration. - - If there was a definition for the template, but - not for the specialization, we want this to - look as if there is no definition, and vice - versa. */ - DECL_INITIAL (fn) = NULL_TREE; - duplicate_decls (spec, fn); - - return fn; - } - } - else if (DECL_TEMPLATE_SPECIALIZATION (fn)) - { - duplicate_decls (spec, fn); - return fn; - } - } - } - - DECL_TEMPLATE_SPECIALIZATIONS (tmpl) - = perm_tree_cons (args, spec, DECL_TEMPLATE_SPECIALIZATIONS (tmpl)); - - return spec; -} - -/* Unregister the specialization SPEC as a specialization of TMPL. - Returns nonzero if the SPEC was listed as a specialization of - TMPL. */ - -static int -unregister_specialization (spec, tmpl) - tree spec; - tree tmpl; -{ - tree* s; - - for (s = &DECL_TEMPLATE_SPECIALIZATIONS (tmpl); - *s != NULL_TREE; - s = &TREE_CHAIN (*s)) - if (TREE_VALUE (*s) == spec) - { - *s = TREE_CHAIN (*s); - return 1; - } - - return 0; -} - -/* Print the list of candidate FNS in an error message. */ - -void -print_candidates (fns) - tree fns; -{ - tree fn; - - char* str = "candidates are:"; - - for (fn = fns; fn != NULL_TREE; fn = TREE_CHAIN (fn)) - { - cp_error_at ("%s %+#D", str, TREE_VALUE (fn)); - str = " "; - } -} - -/* Returns the template (one of the functions given by TEMPLATE_ID) - which can be specialized to match the indicated DECL with the - explicit template args given in TEMPLATE_ID. If - NEED_MEMBER_TEMPLATE is true the function is a specialization of a - member template. The template args (those explicitly specified and - those deduced) are output in a newly created vector *TARGS_OUT. If - it is impossible to determine the result, an error message is - issued, unless COMPLAIN is 0. The DECL may be NULL_TREE if none is - available. */ - -tree -determine_specialization (template_id, decl, targs_out, - need_member_template, - complain) - tree template_id; - tree decl; - tree* targs_out; - int need_member_template; - int complain; -{ - tree fns, targs_in; - tree templates = NULL_TREE; - tree fn; - - *targs_out = NULL_TREE; - - if (template_id == error_mark_node) - return error_mark_node; - - fns = TREE_OPERAND (template_id, 0); - targs_in = TREE_OPERAND (template_id, 1); - - if (fns == error_mark_node) - return error_mark_node; - - /* Check for baselinks. */ - if (TREE_CODE (fns) == TREE_LIST) - fns = TREE_VALUE (fns); - - for (; fns; fns = OVL_NEXT (fns)) - { - tree tmpl; - - fn = OVL_CURRENT (fns); - if (!need_member_template - && TREE_CODE (fn) == FUNCTION_DECL - && DECL_FUNCTION_MEMBER_P (fn) - && DECL_USE_TEMPLATE (fn) - && DECL_TI_TEMPLATE (fn)) - /* We can get here when processing something like: - template <class T> class X { void f(); } - template <> void X<int>::f() {} - We're specializing a member function, but not a member - template. */ - tmpl = DECL_TI_TEMPLATE (fn); - else if (TREE_CODE (fn) != TEMPLATE_DECL - || (need_member_template && !is_member_template (fn))) - continue; - else - tmpl = fn; - - if (list_length (targs_in) > DECL_NTPARMS (tmpl)) - continue; - - if (decl == NULL_TREE) - { - /* Unify against ourselves to make sure that the args we have - make sense and there aren't any undeducible parms. It's OK if - not all the parms are specified; they might be deduced - later. */ - tree targs = get_bindings_overload (tmpl, DECL_RESULT (tmpl), - targs_in); - - if (targs) - /* Unification was successful. */ - templates = scratch_tree_cons (targs, tmpl, templates); - } - else - templates = scratch_tree_cons (NULL_TREE, tmpl, templates); - } - - if (decl != NULL_TREE) - { - tree tmpl = most_specialized (templates, decl, targs_in); - tree inner_args; - tree tmpl_args; - - if (tmpl == error_mark_node) - goto ambiguous; - else if (tmpl == NULL_TREE) - goto no_match; - - inner_args = get_bindings (tmpl, decl, targs_in); - tmpl_args = DECL_TI_ARGS (DECL_RESULT (tmpl)); - if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (tmpl_args)) - { - *targs_out = copy_node (tmpl_args); - SET_TMPL_ARGS_LEVEL (*targs_out, - TMPL_ARGS_DEPTH (*targs_out), - inner_args); - } - else - *targs_out = inner_args; - - return tmpl; - } - - if (templates == NULL_TREE) - { - no_match: - if (complain) - { - cp_error_at ("template-id `%D' for `%+D' does not match any template declaration", - template_id, decl); - return error_mark_node; - } - return NULL_TREE; - } - else if (TREE_CHAIN (templates) != NULL_TREE - || uses_template_parms (TREE_PURPOSE (templates))) - { - ambiguous: - if (complain) - { - cp_error_at ("ambiguous template specialization `%D' for `%+D'", - template_id, decl); - print_candidates (templates); - return error_mark_node; - } - return NULL_TREE; - } - - /* We have one, and exactly one, match. */ - *targs_out = TREE_PURPOSE (templates); - return TREE_VALUE (templates); -} - -/* Check to see if the function just declared, as indicated in - DECLARATOR, and in DECL, is a specialization of a function - template. We may also discover that the declaration is an explicit - instantiation at this point. - - Returns DECL, or an equivalent declaration that should be used - instead. - - FLAGS is a bitmask consisting of the following flags: - - 2: The function has a definition. - 4: The function is a friend. - - The TEMPLATE_COUNT is the number of references to qualifying - template classes that appeared in the name of the function. For - example, in - - template <class T> struct S { void f(); }; - void S<int>::f(); - - the TEMPLATE_COUNT would be 1. However, explicitly specialized - classes are not counted in the TEMPLATE_COUNT, so that in - - template <class T> struct S {}; - template <> struct S<int> { void f(); } - template <> void S<int>::f(); - - the TEMPLATE_COUNT would be 0. (Note that this declaration is - illegal; there should be no template <>.) - - If the function is a specialization, it is marked as such via - DECL_TEMPLATE_SPECIALIZATION. Furthermore, its DECL_TEMPLATE_INFO - is set up correctly, and it is added to the list of specializations - for that template. */ - -tree -check_explicit_specialization (declarator, decl, template_count, flags) - tree declarator; - tree decl; - int template_count; - int flags; -{ - int have_def = flags & 2; - int is_friend = flags & 4; - int specialization = 0; - int explicit_instantiation = 0; - int member_specialization = 0; - - tree ctype = DECL_CLASS_CONTEXT (decl); - tree dname = DECL_NAME (decl); - - if (processing_specialization) - { - /* The last template header was of the form template <>. */ - - if (template_header_count > template_count) - { - /* There were more template headers than qualifying template - classes. */ - if (template_header_count - template_count > 1) - /* There shouldn't be that many template parameter - lists. There can be at most one parameter list for - every qualifying class, plus one for the function - itself. */ - cp_error ("too many template parameter lists in declaration of `%D'", decl); - - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - if (ctype) - member_specialization = 1; - else - specialization = 1; - } - else if (template_header_count == template_count) - { - /* The counts are equal. So, this might be a - specialization, but it is not a specialization of a - member template. It might be something like - - template <class T> struct S { - void f(int i); - }; - template <> - void S<int>::f(int i) {} */ - specialization = 1; - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - } - else - { - /* This cannot be an explicit specialization. There are not - enough headers for all of the qualifying classes. For - example, we might have: - - template <> - void S<int>::T<char>::f(); - - But, we're missing another template <>. */ - cp_error("too few template parameter lists in declaration of `%D'", decl); - return decl; - } - } - else if (processing_explicit_instantiation) - { - if (template_header_count) - cp_error ("template parameter list used in explicit instantiation"); - - if (have_def) - cp_error ("definition provided for explicit instantiation"); - - explicit_instantiation = 1; - } - else if (ctype != NULL_TREE - && !TYPE_BEING_DEFINED (ctype) - && CLASSTYPE_TEMPLATE_INSTANTIATION (ctype) - && !is_friend) - { - /* This case catches outdated code that looks like this: - - template <class T> struct S { void f(); }; - void S<int>::f() {} // Missing template <> - - We disable this check when the type is being defined to - avoid complaining about default compiler-generated - constructors, destructors, and assignment operators. - Since the type is an instantiation, not a specialization, - these are the only functions that can be defined before - the class is complete. */ - - /* If they said - template <class T> void S<int>::f() {} - that's bogus. */ - if (template_header_count) - { - cp_error ("template parameters specified in specialization"); - return decl; - } - - if (pedantic) - cp_pedwarn - ("explicit specialization not preceded by `template <>'"); - specialization = 1; - SET_DECL_TEMPLATE_SPECIALIZATION (decl); - } - else if (TREE_CODE (declarator) == TEMPLATE_ID_EXPR) - { - if (is_friend) - /* This could be something like: - - template <class T> void f(T); - class S { friend void f<>(int); } */ - specialization = 1; - else - { - /* This case handles bogus declarations like template <> - template <class T> void f<int>(); */ - - cp_error ("template-id `%D' in declaration of primary template", - declarator); - return decl; - } - } - - if (specialization || member_specialization) - { - tree t = TYPE_ARG_TYPES (TREE_TYPE (decl)); - for (; t; t = TREE_CHAIN (t)) - if (TREE_PURPOSE (t)) - { - cp_pedwarn - ("default argument specified in explicit specialization"); - break; - } - if (current_lang_name == lang_name_c) - cp_error ("template specialization with C linkage"); - } - - if (specialization || member_specialization || explicit_instantiation) - { - tree gen_tmpl; - tree tmpl = NULL_TREE; - tree targs = NULL_TREE; - - /* Make sure that the declarator is a TEMPLATE_ID_EXPR. */ - if (TREE_CODE (declarator) != TEMPLATE_ID_EXPR) - { - tree fns; - - my_friendly_assert (TREE_CODE (declarator) == IDENTIFIER_NODE, - 0); - if (!ctype) - fns = IDENTIFIER_NAMESPACE_VALUE (dname); - else - fns = dname; - - declarator = - lookup_template_function (fns, NULL_TREE); - } - - if (declarator == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_OPERAND (declarator, 0)) == LOOKUP_EXPR) - { - /* A friend declaration. We can't do much, because we don't - know what this resolves to, yet. */ - my_friendly_assert (is_friend != 0, 0); - my_friendly_assert (!explicit_instantiation, 0); - SET_DECL_IMPLICIT_INSTANTIATION (decl); - return decl; - } - - if (ctype != NULL_TREE && TYPE_BEING_DEFINED (ctype)) - { - if (!explicit_instantiation) - /* A specialization in class scope. This is illegal, - but the error will already have been flagged by - check_specialization_scope. */ - return error_mark_node; - else - { - /* It's not legal to write an explicit instantiation in - class scope, e.g.: - - class C { template void f(); } - - This case is caught by the parser. However, on - something like: - - template class C { void f(); }; - - (which is illegal) we can get here. The error will be - issued later. */ - ; - } - - return decl; - } - else if (ctype != NULL_TREE - && (TREE_CODE (TREE_OPERAND (declarator, 0)) == - IDENTIFIER_NODE)) - { - /* Find the list of functions in ctype that have the same - name as the declared function. */ - tree name = TREE_OPERAND (declarator, 0); - tree fns; - - if (name == constructor_name (ctype) - || name == constructor_name_full (ctype)) - { - int is_constructor = DECL_CONSTRUCTOR_P (decl); - - if (is_constructor ? !TYPE_HAS_CONSTRUCTOR (ctype) - : !TYPE_HAS_DESTRUCTOR (ctype)) - { - /* From [temp.expl.spec]: - - If such an explicit specialization for the member - of a class template names an implicitly-declared - special member function (clause _special_), the - program is ill-formed. - - Similar language is found in [temp.explicit]. */ - cp_error ("specialization of implicitly-declared special member function"); - - return decl; - } - - name = is_constructor ? ctor_identifier : dtor_identifier; - } - - fns = lookup_fnfields (TYPE_BINFO (ctype), name, 1); - - if (fns == NULL_TREE) - { - cp_error ("no member function `%s' declared in `%T'", - IDENTIFIER_POINTER (name), - ctype); - return decl; - } - else - TREE_OPERAND (declarator, 0) = fns; - } - - /* Figure out what exactly is being specialized at this point. - Note that for an explicit instantiation, even one for a - member function, we cannot tell apriori whether the - instantiation is for a member template, or just a member - function of a template class. Even if a member template is - being instantiated, the member template arguments may be - elided if they can be deduced from the rest of the - declaration. */ - tmpl = determine_specialization (declarator, decl, - &targs, - member_specialization, - 1); - - if (tmpl && tmpl != error_mark_node) - { - gen_tmpl = most_general_template (tmpl); - - if (explicit_instantiation) - { - /* We don't set DECL_EXPLICIT_INSTANTIATION here; that - is done by do_decl_instantiation later. */ - decl = instantiate_template (tmpl, innermost_args (targs)); - return decl; - } - - /* If we though that the DECL was a member function, but it - turns out to be specializing a static member function, - make DECL a static member function as well. */ - if (DECL_STATIC_FUNCTION_P (tmpl) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) - { - revert_static_member_fn (&decl, 0, 0); - last_function_parms = TREE_CHAIN (last_function_parms); - } - - /* Set up the DECL_TEMPLATE_INFO for DECL. */ - DECL_TEMPLATE_INFO (decl) - = perm_tree_cons (tmpl, targs, NULL_TREE); - - /* Mangle the function name appropriately. Note that we do - not mangle specializations of non-template member - functions of template classes, e.g. with - - template <class T> struct S { void f(); } - - and given the specialization - - template <> void S<int>::f() {} - - we do not mangle S<int>::f() here. That's because it's - just an ordinary member function and doesn't need special - treatment. We do this here so that the ordinary, - non-template, name-mangling algorith will not be used - later. */ - if ((is_member_template (tmpl) || ctype == NULL_TREE) - && name_mangling_version >= 1) - set_mangled_name_for_template_decl (decl); - - if (is_friend && !have_def) - /* This is not really a declaration of a specialization. - It's just the name of an instantiation. But, it's not - a request for an instantiation, either. */ - SET_DECL_IMPLICIT_INSTANTIATION (decl); - - /* Register this specialization so that we can find it - again. */ - decl = register_specialization (decl, gen_tmpl, targs); - - return decl; - } - } - - return decl; -} - -/* TYPE is being declared. Verify that the use of template headers - and such is reasonable. Issue error messages if not. */ - -void -maybe_check_template_type (type) - tree type; -{ - if (template_header_count) - { - /* We are in the scope of some `template <...>' header. */ - - int context_depth - = template_class_depth_real (TYPE_CONTEXT (type), - /*count_specializations=*/1); - - if (template_header_count <= context_depth) - /* This is OK; the template headers are for the context. We - are actually too lenient here; like - check_explicit_specialization we should consider the number - of template types included in the actual declaration. For - example, - - template <class T> struct S { - template <class U> template <class V> - struct I {}; - }; - - is illegal, but: - - template <class T> struct S { - template <class U> struct I; - }; - - template <class T> template <class U. - struct S<T>::I {}; - - is not. */ - ; - else if (template_header_count > context_depth + 1) - /* There are two many template parameter lists. */ - cp_error ("too many template parameter lists in declaration of `%T'", type); - } -} - -/* Returns 1 iff PARMS1 and PARMS2 are identical sets of template - parameters. These are represented in the same format used for - DECL_TEMPLATE_PARMS. */ - -int comp_template_parms (parms1, parms2) - tree parms1; - tree parms2; -{ - tree p1; - tree p2; - - if (parms1 == parms2) - return 1; - - for (p1 = parms1, p2 = parms2; - p1 != NULL_TREE && p2 != NULL_TREE; - p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2)) - { - tree t1 = TREE_VALUE (p1); - tree t2 = TREE_VALUE (p2); - int i; - - my_friendly_assert (TREE_CODE (t1) == TREE_VEC, 0); - my_friendly_assert (TREE_CODE (t2) == TREE_VEC, 0); - - if (TREE_VEC_LENGTH (t1) != TREE_VEC_LENGTH (t2)) - return 0; - - for (i = 0; i < TREE_VEC_LENGTH (t2); ++i) - { - tree parm1 = TREE_VALUE (TREE_VEC_ELT (t1, i)); - tree parm2 = TREE_VALUE (TREE_VEC_ELT (t2, i)); - - if (TREE_CODE (parm1) != TREE_CODE (parm2)) - return 0; - - if (TREE_CODE (parm1) == TEMPLATE_TYPE_PARM) - continue; - else if (!same_type_p (TREE_TYPE (parm1), TREE_TYPE (parm2))) - return 0; - } - } - - if ((p1 != NULL_TREE) != (p2 != NULL_TREE)) - /* One set of parameters has more parameters lists than the - other. */ - return 0; - - return 1; -} - -/* Complain if DECL shadows a template parameter. - - [temp.local]: A template-parameter shall not be redeclared within its - scope (including nested scopes). */ - -void -check_template_shadow (decl) - tree decl; -{ - tree olddecl = IDENTIFIER_VALUE (DECL_NAME (decl)); - - if (current_template_parms && olddecl) - { - /* We check for decl != olddecl to avoid bogus errors for using a - name inside a class. We check TPFI to avoid duplicate errors for - inline member templates. */ - if (decl != olddecl && DECL_TEMPLATE_PARM_P (olddecl) - && ! TEMPLATE_PARMS_FOR_INLINE (current_template_parms)) - { - cp_error_at ("declaration of `%#D'", decl); - cp_error_at (" shadows template parm `%#D'", olddecl); - } - } -} - -/* Return a new TEMPLATE_PARM_INDEX with the indicated INDEX, LEVEL, - ORIG_LEVEL, DECL, and TYPE. */ - -static tree -build_template_parm_index (index, level, orig_level, decl, type) - int index; - int level; - int orig_level; - tree decl; - tree type; -{ - tree t = make_node (TEMPLATE_PARM_INDEX); - TEMPLATE_PARM_IDX (t) = index; - TEMPLATE_PARM_LEVEL (t) = level; - TEMPLATE_PARM_ORIG_LEVEL (t) = orig_level; - TEMPLATE_PARM_DECL (t) = decl; - TREE_TYPE (t) = type; - - return t; -} - -/* Return a TEMPLATE_PARM_INDEX, similar to INDEX, but whose - TEMPLATE_PARM_LEVEL has been decreased by LEVELS. If such a - TEMPLATE_PARM_INDEX already exists, it is returned; otherwise, a - new one is created. */ - -static tree -reduce_template_parm_level (index, type, levels) - tree index; - tree type; - int levels; -{ - if (TEMPLATE_PARM_DESCENDANTS (index) == NULL_TREE - || (TEMPLATE_PARM_LEVEL (TEMPLATE_PARM_DESCENDANTS (index)) - != TEMPLATE_PARM_LEVEL (index) - levels)) - { - tree decl - = build_decl (TREE_CODE (TEMPLATE_PARM_DECL (index)), - DECL_NAME (TEMPLATE_PARM_DECL (index)), - type); - tree t - = build_template_parm_index (TEMPLATE_PARM_IDX (index), - TEMPLATE_PARM_LEVEL (index) - levels, - TEMPLATE_PARM_ORIG_LEVEL (index), - decl, type); - TEMPLATE_PARM_DESCENDANTS (index) = t; - - /* Template template parameters need this. */ - DECL_TEMPLATE_PARMS (decl) - = DECL_TEMPLATE_PARMS (TEMPLATE_PARM_DECL (index)); - } - - return TEMPLATE_PARM_DESCENDANTS (index); -} - -/* Process information from new template parameter NEXT and append it to the - LIST being built. */ - -tree -process_template_parm (list, next) - tree list, next; -{ - tree parm; - tree decl = 0; - tree defval; - int is_type, idx; - - parm = next; - my_friendly_assert (TREE_CODE (parm) == TREE_LIST, 259); - defval = TREE_PURPOSE (parm); - parm = TREE_VALUE (parm); - is_type = TREE_PURPOSE (parm) == class_type_node; - - if (list) - { - tree p = TREE_VALUE (tree_last (list)); - - if (TREE_CODE (p) == TYPE_DECL) - idx = TEMPLATE_TYPE_IDX (TREE_TYPE (p)); - else if (TREE_CODE (p) == TEMPLATE_DECL) - idx = TEMPLATE_TYPE_IDX (TREE_TYPE (DECL_TEMPLATE_RESULT (p))); - else - idx = TEMPLATE_PARM_IDX (DECL_INITIAL (p)); - ++idx; - } - else - idx = 0; - - if (!is_type) - { - my_friendly_assert (TREE_CODE (TREE_PURPOSE (parm)) == TREE_LIST, 260); - /* is a const-param */ - parm = grokdeclarator (TREE_VALUE (parm), TREE_PURPOSE (parm), - PARM, 0, NULL_TREE); - - /* [temp.param] - - The top-level cv-qualifiers on the template-parameter are - ignored when determining its type. */ - TREE_TYPE (parm) = TYPE_MAIN_VARIANT (TREE_TYPE (parm)); - - /* A template parameter is not modifiable. */ - TREE_READONLY (parm) = 1; - if (IS_AGGR_TYPE (TREE_TYPE (parm)) - && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM - && TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE) - { - cp_error ("`%#T' is not a valid type for a template constant parameter", - TREE_TYPE (parm)); - if (DECL_NAME (parm) == NULL_TREE) - error (" a template type parameter must begin with `class' or `typename'"); - TREE_TYPE (parm) = void_type_node; - } - else if (pedantic - && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE - || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE)) - cp_pedwarn ("`%T' is not a valid type for a template constant parameter", - TREE_TYPE (parm)); - if (TREE_PERMANENT (parm) == 0) - { - parm = copy_node (parm); - TREE_PERMANENT (parm) = 1; - } - decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm)); - DECL_INITIAL (parm) = DECL_INITIAL (decl) - = build_template_parm_index (idx, processing_template_decl, - processing_template_decl, - decl, TREE_TYPE (parm)); - } - else - { - tree t; - parm = TREE_VALUE (parm); - - if (parm && TREE_CODE (parm) == TEMPLATE_DECL) - { - t = make_lang_type (TEMPLATE_TEMPLATE_PARM); - /* This is for distinguishing between real templates and template - template parameters */ - TREE_TYPE (parm) = t; - TREE_TYPE (DECL_TEMPLATE_RESULT (parm)) = t; - decl = parm; - } - else - { - t = make_lang_type (TEMPLATE_TYPE_PARM); - /* parm is either IDENTIFIER_NODE or NULL_TREE */ - decl = build_decl (TYPE_DECL, parm, t); - } - - TYPE_NAME (t) = decl; - TYPE_STUB_DECL (t) = decl; - parm = decl; - TEMPLATE_TYPE_PARM_INDEX (t) - = build_template_parm_index (idx, processing_template_decl, - processing_template_decl, - decl, TREE_TYPE (parm)); - } - SET_DECL_ARTIFICIAL (decl); - DECL_TEMPLATE_PARM_P (decl) = 1; - pushdecl (decl); - parm = build_tree_list (defval, parm); - return chainon (list, parm); -} - -/* The end of a template parameter list has been reached. Process the - tree list into a parameter vector, converting each parameter into a more - useful form. Type parameters are saved as IDENTIFIER_NODEs, and others - as PARM_DECLs. */ - -tree -end_template_parm_list (parms) - tree parms; -{ - int nparms; - tree parm; - tree saved_parmlist = make_tree_vec (list_length (parms)); - - current_template_parms - = tree_cons (build_int_2 (0, processing_template_decl), - saved_parmlist, current_template_parms); - - for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++) - TREE_VEC_ELT (saved_parmlist, nparms) = parm; - - --processing_template_parmlist; - - return saved_parmlist; -} - -/* end_template_decl is called after a template declaration is seen. */ - -void -end_template_decl () -{ - reset_specialization (); - - if (! processing_template_decl) - return; - - /* This matches the pushlevel in begin_template_parm_list. */ - poplevel (0, 0, 0); - - --processing_template_decl; - current_template_parms = TREE_CHAIN (current_template_parms); - (void) get_pending_sizes (); /* Why? */ -} - -/* Given a template argument vector containing the template PARMS. - The innermost PARMS are given first. */ - -tree -current_template_args () -{ - tree header; - tree args = NULL_TREE; - int length = TMPL_PARMS_DEPTH (current_template_parms); - int l = length; - - /* If there is only one level of template parameters, we do not - create a TREE_VEC of TREE_VECs. Instead, we return a single - TREE_VEC containing the arguments. */ - if (length > 1) - args = make_tree_vec (length); - - for (header = current_template_parms; header; header = TREE_CHAIN (header)) - { - tree a = copy_node (TREE_VALUE (header)); - int i; - - TREE_TYPE (a) = NULL_TREE; - for (i = TREE_VEC_LENGTH (a) - 1; i >= 0; --i) - { - tree t = TREE_VEC_ELT (a, i); - - /* T will be a list if we are called from within a - begin/end_template_parm_list pair, but a vector directly - if within a begin/end_member_template_processing pair. */ - if (TREE_CODE (t) == TREE_LIST) - { - t = TREE_VALUE (t); - - if (TREE_CODE (t) == TYPE_DECL - || TREE_CODE (t) == TEMPLATE_DECL) - t = TREE_TYPE (t); - else - t = DECL_INITIAL (t); - TREE_VEC_ELT (a, i) = t; - } - } - - if (length > 1) - TREE_VEC_ELT (args, --l) = a; - else - args = a; - } - - return args; -} - -/* Return a TEMPLATE_DECL corresponding to DECL, using the indicated - template PARMS. Used by push_template_decl below. */ - -static tree -build_template_decl (decl, parms) - tree decl; - tree parms; -{ - tree tmpl = build_lang_decl (TEMPLATE_DECL, DECL_NAME (decl), NULL_TREE); - DECL_TEMPLATE_PARMS (tmpl) = parms; - DECL_CONTEXT (tmpl) = DECL_CONTEXT (decl); - if (DECL_LANG_SPECIFIC (decl)) - { - DECL_CLASS_CONTEXT (tmpl) = DECL_CLASS_CONTEXT (decl); - DECL_STATIC_FUNCTION_P (tmpl) = - DECL_STATIC_FUNCTION_P (decl); - } - - return tmpl; -} - -struct template_parm_data -{ - /* The level of the template parameters we are currently - processing. */ - int level; - - /* The index of the specialization argument we are currently - processing. */ - int current_arg; - - /* An array whose size is the number of template parameters. The - elements are non-zero if the parameter has been used in any one - of the arguments processed so far. */ - int* parms; - - /* An array whose size is the number of template arguments. The - elements are non-zero if the argument makes use of template - parameters of this level. */ - int* arg_uses_template_parms; -}; - -/* Subroutine of push_template_decl used to see if each template - parameter in a partial specialization is used in the explicit - argument list. If T is of the LEVEL given in DATA (which is - treated as a template_parm_data*), then DATA->PARMS is marked - appropriately. */ - -static int -mark_template_parm (t, data) - tree t; - void* data; -{ - int level; - int idx; - struct template_parm_data* tpd = (struct template_parm_data*) data; - - if (TREE_CODE (t) == TEMPLATE_PARM_INDEX) - { - level = TEMPLATE_PARM_LEVEL (t); - idx = TEMPLATE_PARM_IDX (t); - } - else - { - level = TEMPLATE_TYPE_LEVEL (t); - idx = TEMPLATE_TYPE_IDX (t); - } - - if (level == tpd->level) - { - tpd->parms[idx] = 1; - tpd->arg_uses_template_parms[tpd->current_arg] = 1; - } - - /* Return zero so that for_each_template_parm will continue the - traversal of the tree; we want to mark *every* template parm. */ - return 0; -} - -/* Process the partial specialization DECL. */ - -static tree -process_partial_specialization (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - tree maintmpl = CLASSTYPE_TI_TEMPLATE (type); - tree specargs = CLASSTYPE_TI_ARGS (type); - tree inner_args = innermost_args (specargs); - tree inner_parms = INNERMOST_TEMPLATE_PARMS (current_template_parms); - tree main_inner_parms = DECL_INNERMOST_TEMPLATE_PARMS (maintmpl); - int nargs = TREE_VEC_LENGTH (inner_args); - int ntparms = TREE_VEC_LENGTH (inner_parms); - int i; - int did_error_intro = 0; - struct template_parm_data tpd; - struct template_parm_data tpd2; - - /* We check that each of the template parameters given in the - partial specialization is used in the argument list to the - specialization. For example: - - template <class T> struct S; - template <class T> struct S<T*>; - - The second declaration is OK because `T*' uses the template - parameter T, whereas - - template <class T> struct S<int>; - - is no good. Even trickier is: - - template <class T> - struct S1 - { - template <class U> - struct S2; - template <class U> - struct S2<T>; - }; - - The S2<T> declaration is actually illegal; it is a - full-specialization. Of course, - - template <class U> - struct S2<T (*)(U)>; - - or some such would have been OK. */ - tpd.level = TMPL_PARMS_DEPTH (current_template_parms); - tpd.parms = alloca (sizeof (int) * ntparms); - bzero ((PTR) tpd.parms, sizeof (int) * ntparms); - - tpd.arg_uses_template_parms = alloca (sizeof (int) * nargs); - bzero ((PTR) tpd.arg_uses_template_parms, sizeof (int) * nargs); - for (i = 0; i < nargs; ++i) - { - tpd.current_arg = i; - for_each_template_parm (TREE_VEC_ELT (inner_args, i), - &mark_template_parm, - &tpd); - } - for (i = 0; i < ntparms; ++i) - if (tpd.parms[i] == 0) - { - /* One of the template parms was not used in the - specialization. */ - if (!did_error_intro) - { - cp_error ("template parameters not used in partial specialization:"); - did_error_intro = 1; - } - - cp_error (" `%D'", - TREE_VALUE (TREE_VEC_ELT (inner_parms, i))); - } - - /* [temp.class.spec] - - The argument list of the specialization shall not be identical to - the implicit argument list of the primary template. */ - if (comp_template_args (inner_args, - innermost_args (CLASSTYPE_TI_ARGS (TREE_TYPE - (maintmpl))))) - cp_error ("partial specialization `%T' does not specialize any template arguments", type); - - /* [temp.class.spec] - - A partially specialized non-type argument expression shall not - involve template parameters of the partial specialization except - when the argument expression is a simple identifier. - - The type of a template parameter corresponding to a specialized - non-type argument shall not be dependent on a parameter of the - specialization. */ - my_friendly_assert (nargs == DECL_NTPARMS (maintmpl), 0); - tpd2.parms = 0; - for (i = 0; i < nargs; ++i) - { - tree arg = TREE_VEC_ELT (inner_args, i); - if (/* These first two lines are the `non-type' bit. */ - TREE_CODE_CLASS (TREE_CODE (arg)) != 't' - && TREE_CODE (arg) != TEMPLATE_DECL - /* This next line is the `argument expression is not just a - simple identifier' condition and also the `specialized - non-type argument' bit. */ - && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) - { - if (tpd.arg_uses_template_parms[i]) - cp_error ("template argument `%E' involves template parameter(s)", arg); - else - { - /* Look at the corresponding template parameter, - marking which template parameters its type depends - upon. */ - tree type = - TREE_TYPE (TREE_VALUE (TREE_VEC_ELT (main_inner_parms, - i))); - - if (!tpd2.parms) - { - /* We haven't yet initialized TPD2. Do so now. */ - tpd2.arg_uses_template_parms - = (int*) alloca (sizeof (int) * nargs); - /* The number of parameters here is the number in the - main template, which, as checked in the assertion - above, is NARGS. */ - tpd2.parms = (int*) alloca (sizeof (int) * nargs); - tpd2.level = - TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (maintmpl)); - } - - /* Mark the template parameters. But this time, we're - looking for the template parameters of the main - template, not in the specialization. */ - tpd2.current_arg = i; - tpd2.arg_uses_template_parms[i] = 0; - bzero ((PTR) tpd2.parms, sizeof (int) * nargs); - for_each_template_parm (type, - &mark_template_parm, - &tpd2); - - if (tpd2.arg_uses_template_parms [i]) - { - /* The type depended on some template parameters. - If they are fully specialized in the - specialization, that's OK. */ - int j; - for (j = 0; j < nargs; ++j) - if (tpd2.parms[j] != 0 - && tpd.arg_uses_template_parms [j]) - { - cp_error ("type `%T' of template argument `%E' depends on template parameter(s)", - type, - arg); - break; - } - } - } - } - } - - if (retrieve_specialization (maintmpl, specargs)) - /* We've already got this specialization. */ - return decl; - - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl) = CLASSTYPE_TI_SPEC_INFO (type) - = perm_tree_cons (inner_args, inner_parms, - DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)); - TREE_TYPE (DECL_TEMPLATE_SPECIALIZATIONS (maintmpl)) = type; - return decl; -} - -/* Check that a template declaration's use of default arguments is not - invalid. Here, PARMS are the template parameters. IS_PRIMARY is - non-zero if DECL is the thing declared by a primary template. - IS_PARTIAL is non-zero if DECL is a partial specialization. */ - -static void -check_default_tmpl_args (decl, parms, is_primary, is_partial) - tree decl; - tree parms; - int is_primary; - int is_partial; -{ - char* msg; - int last_level_to_check; - - /* [temp.param] - - A default template-argument shall not be specified in a - function template declaration or a function template definition, nor - in the template-parameter-list of the definition of a member of a - class template. */ - - if (current_class_type - && !TYPE_BEING_DEFINED (current_class_type) - && DECL_REAL_CONTEXT (decl) == current_class_type - && DECL_DEFINED_IN_CLASS_P (decl)) - /* We already checked these parameters when the template was - declared, so there's no need to do it again now. This is an - inline member function definition. */ - return; - - if (TREE_CODE (decl) != TYPE_DECL || is_partial || !is_primary) - /* For an ordinary class template, default template arguments are - allowed at the innermost level, e.g.: - template <class T = int> - struct S {}; - but, in a partial specialization, they're not allowed even - there, as we have in [temp.class.spec]: - - The template parameter list of a specialization shall not - contain default template argument values. - - So, for a partial specialization, or for a function template, - we look at all of them. */ - ; - else - /* But, for a primary class template that is not a partial - specialization we look at all template parameters except the - innermost ones. */ - parms = TREE_CHAIN (parms); - - /* Figure out what error message to issue. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - msg = "default argument for template parameter in function template `%D'"; - else if (is_partial) - msg = "default argument in partial specialization `%D'"; - else - msg = "default argument for template parameter for class enclosing `%D'"; - - if (current_class_type && TYPE_BEING_DEFINED (current_class_type)) - /* If we're inside a class definition, there's no need to - examine the parameters to the class itself. On the one - hand, they will be checked when the class is defined, and, - on the other, default arguments are legal in things like: - template <class T = double> - struct S { template <class U> void f(U); }; - Here the default argument for `S' has no bearing on the - declaration of `f'. */ - last_level_to_check = template_class_depth (current_class_type) + 1; - else - /* Check everything. */ - last_level_to_check = 0; - - for (; parms && TMPL_PARMS_DEPTH (parms) >= last_level_to_check; - parms = TREE_CHAIN (parms)) - { - tree inner_parms = TREE_VALUE (parms); - int i, ntparms; - - ntparms = TREE_VEC_LENGTH (inner_parms); - for (i = 0; i < ntparms; ++i) - if (TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i))) - { - if (msg) - { - cp_error (msg, decl); - msg = 0; - } - - /* Clear out the default argument so that we are not - confused later. */ - TREE_PURPOSE (TREE_VEC_ELT (inner_parms, i)) = NULL_TREE; - } - - /* At this point, if we're still interested in issuing messages, - they must apply to classes surrounding the object declared. */ - if (msg) - msg = "default argument for template parameter for class enclosing `%D'"; - } -} - -/* Creates a TEMPLATE_DECL for the indicated DECL using the template - parameters given by current_template_args, or reuses a - previously existing one, if appropriate. Returns the DECL, or an - equivalent one, if it is replaced via a call to duplicate_decls. - - If IS_FRIEND is non-zero, DECL is a friend declaration. */ - -tree -push_template_decl_real (decl, is_friend) - tree decl; - int is_friend; -{ - tree tmpl; - tree args; - tree info; - tree ctx; - int primary; - int is_partial; - - /* See if this is a partial specialization. */ - is_partial = (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl) - && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE - && CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_TYPE (decl))); - - is_friend |= (TREE_CODE (decl) == FUNCTION_DECL && DECL_FRIEND_P (decl)); - - if (is_friend) - /* For a friend, we want the context of the friend function, not - the type of which it is a friend. */ - ctx = DECL_CONTEXT (decl); - else if (DECL_REAL_CONTEXT (decl) - && TREE_CODE (DECL_REAL_CONTEXT (decl)) != NAMESPACE_DECL) - /* In the case of a virtual function, we want the class in which - it is defined. */ - ctx = DECL_REAL_CONTEXT (decl); - else - /* Otherwise, if we're currently definining some class, the DECL - is assumed to be a member of the class. */ - ctx = current_class_type; - - if (ctx && TREE_CODE (ctx) == NAMESPACE_DECL) - ctx = NULL_TREE; - - if (!DECL_CONTEXT (decl)) - DECL_CONTEXT (decl) = FROB_CONTEXT (current_namespace); - - /* For determining whether this is a primary template or not, we're really - interested in the lexical context, not the true context. */ - if (is_friend) - info = current_class_type; - else - info = ctx; - - /* See if this is a primary template. */ - if (info && TREE_CODE (info) == FUNCTION_DECL) - primary = 0; - /* Note that template_class_depth returns 0 if given NULL_TREE, so - this next line works even when we are at global scope. */ - else if (processing_template_decl > template_class_depth (info)) - primary = 1; - else - primary = 0; - - if (primary) - { - if (current_lang_name == lang_name_c) - cp_error ("template with C linkage"); - if (TREE_CODE (decl) == TYPE_DECL && ANON_AGGRNAME_P (DECL_NAME (decl))) - cp_error ("template class without a name"); - if (TREE_CODE (decl) == TYPE_DECL - && TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - cp_error ("template declaration of `%#T'", TREE_TYPE (decl)); - } - - /* Check to see that the rules regarding the use of default - arguments are not being violated. */ - check_default_tmpl_args (decl, current_template_parms, - primary, is_partial); - - if (is_partial) - return process_partial_specialization (decl); - - args = current_template_args (); - - if (!ctx - || TREE_CODE (ctx) == FUNCTION_DECL - || TYPE_BEING_DEFINED (ctx) - || (is_friend && !DECL_TEMPLATE_INFO (decl))) - { - if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_INFO (decl) - && DECL_TI_TEMPLATE (decl)) - tmpl = DECL_TI_TEMPLATE (decl); - else - { - tmpl = build_template_decl (decl, current_template_parms); - - if (DECL_LANG_SPECIFIC (decl) - && DECL_TEMPLATE_SPECIALIZATION (decl)) - { - /* A specialization of a member template of a template - class. */ - SET_DECL_TEMPLATE_SPECIALIZATION (tmpl); - DECL_TEMPLATE_INFO (tmpl) = DECL_TEMPLATE_INFO (decl); - DECL_TEMPLATE_INFO (decl) = NULL_TREE; - } - } - } - else - { - tree a, t, current, parms; - int i; - - if (CLASSTYPE_TEMPLATE_INSTANTIATION (ctx)) - cp_error ("must specialize `%#T' before defining member `%#D'", - ctx, decl); - if (TREE_CODE (decl) == TYPE_DECL) - { - if ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (decl))) - || TREE_CODE (TREE_TYPE (decl)) == ENUMERAL_TYPE) - && TYPE_TEMPLATE_INFO (TREE_TYPE (decl)) - && TYPE_TI_TEMPLATE (TREE_TYPE (decl))) - tmpl = TYPE_TI_TEMPLATE (TREE_TYPE (decl)); - else - { - cp_error ("`%D' does not declare a template type", decl); - return decl; - } - } - else if (! DECL_TEMPLATE_INFO (decl)) - { - cp_error ("template definition of non-template `%#D'", decl); - return decl; - } - else - tmpl = DECL_TI_TEMPLATE (decl); - - if (is_member_template (tmpl) - && DECL_FUNCTION_TEMPLATE_P (tmpl) - && DECL_TEMPLATE_INFO (decl) && DECL_TI_ARGS (decl) - && DECL_TEMPLATE_SPECIALIZATION (decl)) - { - tree new_tmpl; - - /* The declaration is a specialization of a member - template, declared outside the class. Therefore, the - innermost template arguments will be NULL, so we - replace them with the arguments determined by the - earlier call to check_explicit_specialization. */ - args = DECL_TI_ARGS (decl); - - new_tmpl - = build_template_decl (decl, current_template_parms); - DECL_TEMPLATE_RESULT (new_tmpl) = decl; - TREE_TYPE (new_tmpl) = TREE_TYPE (decl); - DECL_TI_TEMPLATE (decl) = new_tmpl; - SET_DECL_TEMPLATE_SPECIALIZATION (new_tmpl); - DECL_TEMPLATE_INFO (new_tmpl) = - perm_tree_cons (tmpl, args, NULL_TREE); - - register_specialization (new_tmpl, tmpl, args); - return decl; - } - - /* Make sure the template headers we got make sense. */ - - parms = DECL_TEMPLATE_PARMS (tmpl); - i = TMPL_PARMS_DEPTH (parms); - if (TMPL_ARGS_DEPTH (args) != i) - { - cp_error ("expected %d levels of template parms for `%#D', got %d", - i, decl, TMPL_ARGS_DEPTH (args)); - } - else - for (current = decl; i > 0; --i, parms = TREE_CHAIN (parms)) - { - a = TMPL_ARGS_LEVEL (args, i); - t = INNERMOST_TEMPLATE_PARMS (parms); - - if (TREE_VEC_LENGTH (t) != TREE_VEC_LENGTH (a)) - { - if (current == decl) - cp_error ("got %d template parameters for `%#D'", - TREE_VEC_LENGTH (a), decl); - else - cp_error ("got %d template parameters for `%#T'", - TREE_VEC_LENGTH (a), current); - cp_error (" but %d required", TREE_VEC_LENGTH (t)); - } - - /* Perhaps we should also check that the parms are used in the - appropriate qualifying scopes in the declarator? */ - - if (current == decl) - current = ctx; - else - current = TYPE_CONTEXT (current); - } - } - - DECL_TEMPLATE_RESULT (tmpl) = decl; - TREE_TYPE (tmpl) = TREE_TYPE (decl); - - /* Push template declarations for global functions and types. Note - that we do not try to push a global template friend declared in a - template class; such a thing may well depend on the template - parameters of the class. */ - if (! ctx - && !(is_friend && template_class_depth (current_class_type) > 0)) - tmpl = pushdecl_namespace_level (tmpl); - - if (primary) - DECL_PRIMARY_TEMPLATE (tmpl) = tmpl; - - info = perm_tree_cons (tmpl, args, NULL_TREE); - - if (TREE_CODE (decl) == TYPE_DECL && DECL_ARTIFICIAL (decl)) - { - SET_TYPE_TEMPLATE_INFO (TREE_TYPE (tmpl), info); - if ((!ctx || TREE_CODE (ctx) != FUNCTION_DECL) - && TREE_CODE (TREE_TYPE (decl)) != ENUMERAL_TYPE) - DECL_NAME (decl) = classtype_mangled_name (TREE_TYPE (decl)); - } - else if (! DECL_LANG_SPECIFIC (decl)) - cp_error ("template declaration of `%#D'", decl); - else - DECL_TEMPLATE_INFO (decl) = info; - - return DECL_TEMPLATE_RESULT (tmpl); -} - -tree -push_template_decl (decl) - tree decl; -{ - return push_template_decl_real (decl, 0); -} - -/* Called when a class template TYPE is redeclared with the indicated - template PARMS, e.g.: - - template <class T> struct S; - template <class T> struct S {}; */ - -void -redeclare_class_template (type, parms) - tree type; - tree parms; -{ - tree tmpl = CLASSTYPE_TI_TEMPLATE (type); - tree tmpl_parms; - int i; - - if (!PRIMARY_TEMPLATE_P (tmpl)) - /* The type is nested in some template class. Nothing to worry - about here; there are no new template parameters for the nested - type. */ - return; - - parms = INNERMOST_TEMPLATE_PARMS (parms); - tmpl_parms = DECL_INNERMOST_TEMPLATE_PARMS (tmpl); - - if (TREE_VEC_LENGTH (parms) != TREE_VEC_LENGTH (tmpl_parms)) - { - cp_error_at ("previous declaration `%D'", tmpl); - cp_error ("used %d template parameter%s instead of %d", - TREE_VEC_LENGTH (tmpl_parms), - TREE_VEC_LENGTH (tmpl_parms) == 1 ? "" : "s", - TREE_VEC_LENGTH (parms)); - return; - } - - for (i = 0; i < TREE_VEC_LENGTH (tmpl_parms); ++i) - { - tree tmpl_parm = TREE_VALUE (TREE_VEC_ELT (tmpl_parms, i)); - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - tree tmpl_default = TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)); - tree parm_default = TREE_PURPOSE (TREE_VEC_ELT (parms, i)); - - if (TREE_CODE (tmpl_parm) != TREE_CODE (parm)) - { - cp_error_at ("template parameter `%#D'", tmpl_parm); - cp_error ("redeclared here as `%#D'", parm); - return; - } - - if (tmpl_default != NULL_TREE && parm_default != NULL_TREE) - { - /* We have in [temp.param]: - - A template-parameter may not be given default arguments - by two different declarations in the same scope. */ - cp_error ("redefinition of default argument for `%#D'", parm); - cp_error_at (" original definition appeared here", tmpl_parm); - return; - } - - if (parm_default != NULL_TREE) - /* Update the previous template parameters (which are the ones - that will really count) with the new default value. */ - TREE_PURPOSE (TREE_VEC_ELT (tmpl_parms, i)) = parm_default; - } -} - -/* Attempt to convert the non-type template parameter EXPR to the - indicated TYPE. If the conversion is successful, return the - converted value. If the conversion is unsuccesful, return - NULL_TREE if we issued an error message, or error_mark_node if we - did not. We issue error messages for out-and-out bad template - parameters, but not simply because the conversion failed, since we - might be just trying to do argument deduction. By the time this - function is called, neither TYPE nor EXPR may make use of template - parameters. */ - -static tree -convert_nontype_argument (type, expr) - tree type; - tree expr; -{ - tree expr_type = TREE_TYPE (expr); - - /* A template-argument for a non-type, non-template - template-parameter shall be one of: - - --an integral constant-expression of integral or enumeration - type; or - - --the name of a non-type template-parameter; or - - --the name of an object or function with external linkage, - including function templates and function template-ids but - excluding non-static class members, expressed as id-expression; - or - - --the address of an object or function with external linkage, - including function templates and function template-ids but - excluding non-static class members, expressed as & id-expression - where the & is optional if the name refers to a function or - array; or - - --a pointer to member expressed as described in _expr.unary.op_. */ - - /* An integral constant-expression can include const variables - or enumerators. */ - if (INTEGRAL_TYPE_P (expr_type) && TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - - if (is_overloaded_fn (expr)) - /* OK for now. We'll check that it has external linkage later. - Check this first since if expr_type is the unknown_type_node - we would otherwise complain below. */ - ; - else if (TYPE_PTR_P (expr_type) - || TREE_CODE (expr_type) == ARRAY_TYPE - || TREE_CODE (type) == REFERENCE_TYPE - /* If expr is the address of an overloaded function, we - will get the unknown_type_node at this point. */ - || expr_type == unknown_type_node) - { - tree referent; - tree e = expr; - STRIP_NOPS (e); - - if (TREE_CODE (type) == REFERENCE_TYPE - || TREE_CODE (expr_type) == ARRAY_TYPE) - referent = e; - else - { - if (TREE_CODE (e) != ADDR_EXPR) - { - bad_argument: - cp_error ("`%E' is not a valid template argument", expr); - error ("it must be %s%s with external linkage", - TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE - ? "a pointer to " : "", - TREE_CODE (TREE_TYPE (TREE_TYPE (expr))) == FUNCTION_TYPE - ? "a function" : "an object"); - return NULL_TREE; - } - - referent = TREE_OPERAND (e, 0); - STRIP_NOPS (referent); - } - - if (TREE_CODE (referent) == STRING_CST) - { - cp_error ("string literal %E is not a valid template argument", - referent); - error ("because it is the address of an object with static linkage"); - return NULL_TREE; - } - - if (is_overloaded_fn (referent)) - /* We'll check that it has external linkage later. */ - ; - else if (TREE_CODE (referent) != VAR_DECL) - goto bad_argument; - else if (!TREE_PUBLIC (referent)) - { - cp_error ("address of non-extern `%E' cannot be used as template argument", referent); - return error_mark_node; - } - } - else if (INTEGRAL_TYPE_P (expr_type) - || TYPE_PTRMEM_P (expr_type) - || TYPE_PTRMEMFUNC_P (expr_type) - /* The next two are g++ extensions. */ - || TREE_CODE (expr_type) == REAL_TYPE - || TREE_CODE (expr_type) == COMPLEX_TYPE) - { - if (! TREE_CONSTANT (expr)) - { - non_constant: - cp_error ("non-constant `%E' cannot be used as template argument", - expr); - return NULL_TREE; - } - } - else - { - cp_error ("object `%E' cannot be used as template argument", expr); - return NULL_TREE; - } - - switch (TREE_CODE (type)) - { - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case ENUMERAL_TYPE: - /* For a non-type template-parameter of integral or enumeration - type, integral promotions (_conv.prom_) and integral - conversions (_conv.integral_) are applied. */ - if (!INTEGRAL_TYPE_P (expr_type)) - return error_mark_node; - - /* It's safe to call digest_init in this case; we know we're - just converting one integral constant expression to another. */ - expr = digest_init (type, expr, (tree*) 0); - - if (TREE_CODE (expr) != INTEGER_CST) - /* Curiously, some TREE_CONSTANT integral expressions do not - simplify to integer constants. For example, `3 % 0', - remains a TRUNC_MOD_EXPR. */ - goto non_constant; - - return expr; - - case REAL_TYPE: - case COMPLEX_TYPE: - /* These are g++ extensions. */ - if (TREE_CODE (expr_type) != TREE_CODE (type)) - return error_mark_node; - - expr = digest_init (type, expr, (tree*) 0); - - if (TREE_CODE (expr) != REAL_CST) - goto non_constant; - - return expr; - - case POINTER_TYPE: - { - tree type_pointed_to = TREE_TYPE (type); - - if (TYPE_PTRMEM_P (type)) - /* For a non-type template-parameter of type pointer to data - member, qualification conversions (_conv.qual_) are - applied. */ - return perform_qualification_conversions (type, expr); - else if (TREE_CODE (type_pointed_to) == FUNCTION_TYPE) - { - /* For a non-type template-parameter of type pointer to - function, only the function-to-pointer conversion - (_conv.func_) is applied. If the template-argument - represents a set of overloaded functions (or a pointer to - such), the matching function is selected from the set - (_over.over_). */ - tree fns; - tree fn; - - if (TREE_CODE (expr) == ADDR_EXPR) - fns = TREE_OPERAND (expr, 0); - else - fns = expr; - - fn = instantiate_type (type_pointed_to, fns, 0); - - if (fn == error_mark_node) - return error_mark_node; - - if (!TREE_PUBLIC (fn)) - { - if (really_overloaded_fn (fns)) - return error_mark_node; - else - goto bad_argument; - } - - expr = build_unary_op (ADDR_EXPR, fn, 0); - - my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), - 0); - return expr; - } - else - { - /* For a non-type template-parameter of type pointer to - object, qualification conversions (_conv.qual_) and the - array-to-pointer conversion (_conv.array_) are applied. - [Note: In particular, neither the null pointer conversion - (_conv.ptr_) nor the derived-to-base conversion - (_conv.ptr_) are applied. Although 0 is a valid - template-argument for a non-type template-parameter of - integral type, it is not a valid template-argument for a - non-type template-parameter of pointer type.] - - The call to decay_conversion performs the - array-to-pointer conversion, if appropriate. */ - expr = decay_conversion (expr); - - if (expr == error_mark_node) - return error_mark_node; - else - return perform_qualification_conversions (type, expr); - } - } - break; - - case REFERENCE_TYPE: - { - tree type_referred_to = TREE_TYPE (type); - - if (TREE_CODE (type_referred_to) == FUNCTION_TYPE) - { - /* For a non-type template-parameter of type reference to - function, no conversions apply. If the - template-argument represents a set of overloaded - functions, the matching function is selected from the - set (_over.over_). */ - tree fns = expr; - tree fn; - - fn = instantiate_type (type_referred_to, fns, 0); - - if (fn == error_mark_node) - return error_mark_node; - - if (!TREE_PUBLIC (fn)) - { - if (really_overloaded_fn (fns)) - /* Don't issue an error here; we might get a different - function if the overloading had worked out - differently. */ - return error_mark_node; - else - goto bad_argument; - } - - my_friendly_assert (same_type_p (type_referred_to, - TREE_TYPE (fn)), - 0); - - return fn; - } - else - { - /* For a non-type template-parameter of type reference to - object, no conversions apply. The type referred to by the - reference may be more cv-qualified than the (otherwise - identical) type of the template-argument. The - template-parameter is bound directly to the - template-argument, which must be an lvalue. */ - if ((TYPE_MAIN_VARIANT (expr_type) - != TYPE_MAIN_VARIANT (type_referred_to)) - || !at_least_as_qualified_p (type_referred_to, - expr_type) - || !real_lvalue_p (expr)) - return error_mark_node; - else - return expr; - } - } - break; - - case RECORD_TYPE: - { - if (!TYPE_PTRMEMFUNC_P (type)) - /* This handles templates like - template<class T, T t> void f(); - when T is substituted with any class. The second template - parameter becomes invalid and the template candidate is - rejected. */ - return error_mark_node; - - /* For a non-type template-parameter of type pointer to member - function, no conversions apply. If the template-argument - represents a set of overloaded member functions, the - matching member function is selected from the set - (_over.over_). */ - - if (!TYPE_PTRMEMFUNC_P (expr_type) && - expr_type != unknown_type_node) - return error_mark_node; - - if (TREE_CODE (expr) == CONSTRUCTOR) - { - /* A ptr-to-member constant. */ - if (!same_type_p (type, expr_type)) - return error_mark_node; - else - return expr; - } - - if (TREE_CODE (expr) != ADDR_EXPR) - return error_mark_node; - - expr = instantiate_type (type, expr, 0); - - if (expr == error_mark_node) - return error_mark_node; - - my_friendly_assert (same_type_p (type, TREE_TYPE (expr)), - 0); - return expr; - } - break; - - default: - /* All non-type parameters must have one of these types. */ - my_friendly_abort (0); - break; - } - - return error_mark_node; -} - -/* Return 1 if PARM_PARMS and ARG_PARMS matches using rule for - template template parameters. Both PARM_PARMS and ARG_PARMS are - vectors of TREE_LIST nodes containing TYPE_DECL, TEMPLATE_DECL - or PARM_DECL. - - ARG_PARMS may contain more parameters than PARM_PARMS. If this is - the case, then extra parameters must have default arguments. - - Consider the example: - template <class T, class Allocator = allocator> class vector; - template<template <class U> class TT> class C; - - C<vector> is a valid instantiation. PARM_PARMS for the above code - contains a TYPE_DECL (for U), ARG_PARMS contains two TYPE_DECLs (for - T and Allocator) and OUTER_ARGS contains the argument that is used to - substitute the TT parameter. */ - -static int -coerce_template_template_parms (parm_parms, arg_parms, in_decl, outer_args) - tree parm_parms, arg_parms, in_decl, outer_args; -{ - int nparms, nargs, i; - tree parm, arg; - - my_friendly_assert (TREE_CODE (parm_parms) == TREE_VEC, 0); - my_friendly_assert (TREE_CODE (arg_parms) == TREE_VEC, 0); - - nparms = TREE_VEC_LENGTH (parm_parms); - nargs = TREE_VEC_LENGTH (arg_parms); - - /* The rule here is opposite of coerce_template_parms. */ - if (nargs < nparms - || (nargs > nparms - && TREE_PURPOSE (TREE_VEC_ELT (arg_parms, nparms)) == NULL_TREE)) - return 0; - - for (i = 0; i < nparms; ++i) - { - parm = TREE_VALUE (TREE_VEC_ELT (parm_parms, i)); - arg = TREE_VALUE (TREE_VEC_ELT (arg_parms, i)); - - if (arg == NULL_TREE || arg == error_mark_node - || parm == NULL_TREE || parm == error_mark_node) - return 0; - - if (TREE_CODE (arg) != TREE_CODE (parm)) - return 0; - - switch (TREE_CODE (parm)) - { - case TYPE_DECL: - break; - - case TEMPLATE_DECL: - /* We encounter instantiations of templates like - template <template <template <class> class> class TT> - class C; */ - sorry ("nested template template parameter"); - return 0; - - case PARM_DECL: - /* The tsubst call is used to handle cases such as - template <class T, template <T> class TT> class D; - i.e. the parameter list of TT depends on earlier parameters. */ - if (!same_type_p (tsubst (TREE_TYPE (parm), outer_args, in_decl), - TREE_TYPE (arg))) - return 0; - break; - - default: - my_friendly_abort (0); - } - } - return 1; -} - -/* Convert the indicated template ARG as necessary to match the - indicated template PARM. Returns the converted ARG, or - error_mark_node if the conversion was unsuccessful. Error messages - are issued if COMPLAIN is non-zero. This conversion is for the Ith - parameter in the parameter list. ARGS is the full set of template - arguments deduced so far. */ - -static tree -convert_template_argument (parm, arg, args, complain, i, in_decl) - tree parm; - tree arg; - tree args; - int complain; - int i; - tree in_decl; -{ - tree val; - tree inner_args; - int is_type, requires_type, is_tmpl_type, requires_tmpl_type; - - inner_args = innermost_args (args); - - if (TREE_CODE (arg) == TREE_LIST - && TREE_TYPE (arg) != NULL_TREE - && TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE) - { - /* The template argument was the name of some - member function. That's usually - illegal, but static members are OK. In any - case, grab the underlying fields/functions - and issue an error later if required. */ - arg = TREE_VALUE (arg); - TREE_TYPE (arg) = unknown_type_node; - } - - requires_tmpl_type = TREE_CODE (parm) == TEMPLATE_DECL; - requires_type = (TREE_CODE (parm) == TYPE_DECL - || requires_tmpl_type); - - /* Check if it is a class template. If REQUIRES_TMPL_TYPE is true, - we also accept implicitly created TYPE_DECL as a valid argument. - This is necessary to handle the case where we pass a template name - to a template template parameter in a scope where we've derived from - in instantiation of that template, so the template name refers to that - instantiation. We really ought to handle this better. */ - is_tmpl_type - = ((TREE_CODE (arg) == TEMPLATE_DECL - && TREE_CODE (DECL_TEMPLATE_RESULT (arg)) == TYPE_DECL) - || (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM - && !TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (arg)) - || (TREE_CODE (arg) == RECORD_TYPE - && CLASSTYPE_TEMPLATE_INFO (arg) - && TREE_CODE (TYPE_NAME (arg)) == TYPE_DECL - && DECL_ARTIFICIAL (TYPE_NAME (arg)) - && requires_tmpl_type - && is_base_of_enclosing_class (arg, current_class_type))); - if (is_tmpl_type && TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - arg = TYPE_STUB_DECL (arg); - else if (is_tmpl_type && TREE_CODE (arg) == RECORD_TYPE) - arg = CLASSTYPE_TI_TEMPLATE (arg); - - is_type = TREE_CODE_CLASS (TREE_CODE (arg)) == 't' || is_tmpl_type; - - if (requires_type && ! is_type && TREE_CODE (arg) == SCOPE_REF - && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_TYPE_PARM) - { - cp_pedwarn ("to refer to a type member of a template parameter,"); - cp_pedwarn (" use `typename %E'", arg); - - arg = make_typename_type (TREE_OPERAND (arg, 0), - TREE_OPERAND (arg, 1)); - is_type = 1; - } - if (is_type != requires_type) - { - if (in_decl) - { - if (complain) - { - cp_error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); - if (is_type) - cp_error (" expected a constant of type `%T', got `%T'", - TREE_TYPE (parm), - (is_tmpl_type ? DECL_NAME (arg) : arg)); - else - cp_error (" expected a type, got `%E'", arg); - } - } - return error_mark_node; - } - if (is_tmpl_type ^ requires_tmpl_type) - { - if (in_decl && complain) - { - cp_error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); - if (is_tmpl_type) - cp_error (" expected a type, got `%T'", DECL_NAME (arg)); - else - cp_error (" expected a class template, got `%T'", arg); - } - return error_mark_node; - } - - if (is_type) - { - if (requires_tmpl_type) - { - tree parmparm = DECL_INNERMOST_TEMPLATE_PARMS (parm); - tree argparm = DECL_INNERMOST_TEMPLATE_PARMS (arg); - - if (coerce_template_template_parms (parmparm, argparm, - in_decl, inner_args)) - { - val = arg; - - /* TEMPLATE_TEMPLATE_PARM node is preferred over - TEMPLATE_DECL. */ - if (val != error_mark_node - && DECL_TEMPLATE_TEMPLATE_PARM_P (val)) - val = TREE_TYPE (val); - } - else - { - if (in_decl && complain) - { - cp_error ("type/value mismatch at argument %d in template parameter list for `%D'", - i + 1, in_decl); - cp_error (" expected a template of type `%D', got `%D'", parm, arg); - } - - val = error_mark_node; - } - } - else - { - val = groktypename (arg); - if (! processing_template_decl) - { - /* [basic.link]: A name with no linkage (notably, the - name of a class or enumeration declared in a local - scope) shall not be used to declare an entity with - linkage. This implies that names with no linkage - cannot be used as template arguments. */ - tree t = no_linkage_check (val); - if (t) - { - if (ANON_AGGRNAME_P (TYPE_IDENTIFIER (t))) - cp_pedwarn - ("template-argument `%T' uses anonymous type", val); - else - cp_error - ("template-argument `%T' uses local type `%T'", - val, t); - return error_mark_node; - } - } - } - } - else - { - tree t = tsubst (TREE_TYPE (parm), args, in_decl); - - if (processing_template_decl) - arg = maybe_fold_nontype_arg (arg); - - if (!uses_template_parms (arg) && !uses_template_parms (t)) - /* We used to call digest_init here. However, digest_init - will report errors, which we don't want when complain - is zero. More importantly, digest_init will try too - hard to convert things: for example, `0' should not be - converted to pointer type at this point according to - the standard. Accepting this is not merely an - extension, since deciding whether or not these - conversions can occur is part of determining which - function template to call, or whether a given epxlicit - argument specification is legal. */ - val = convert_nontype_argument (t, arg); - else - val = arg; - - if (val == NULL_TREE) - val = error_mark_node; - else if (val == error_mark_node && complain) - cp_error ("could not convert template argument `%E' to `%T'", - arg, t); - } - - return val; -} - -/* Convert all template arguments to their appropriate types, and - return a vector containing the innermost resulting template - arguments. If any error occurs, return error_mark_node, and, if - COMPLAIN is non-zero, issue an error message. Some error messages - are issued even if COMPLAIN is zero; for instance, if a template - argument is composed from a local class. - - If REQUIRE_ALL_ARGUMENTS is non-zero, all arguments must be - provided in ARGLIST, or else trailing parameters must have default - values. If REQUIRE_ALL_ARGUMENTS is zero, we will attempt argument - deduction for any unspecified trailing arguments. - - The resulting TREE_VEC is allocated on a temporary obstack, and - must be explicitly copied if it will be permanent. */ - -static tree -coerce_template_parms (parms, args, in_decl, - complain, - require_all_arguments) - tree parms, args; - tree in_decl; - int complain; - int require_all_arguments; -{ - int nparms, nargs, i, lost = 0; - tree inner_args; - tree new_args; - tree new_inner_args; - - inner_args = innermost_args (args); - nargs = NUM_TMPL_ARGS (inner_args); - nparms = TREE_VEC_LENGTH (parms); - - if (nargs > nparms - || (nargs < nparms - && require_all_arguments - && TREE_PURPOSE (TREE_VEC_ELT (parms, nargs)) == NULL_TREE)) - { - if (complain) - { - cp_error ("wrong number of template arguments (%d, should be %d)", - nargs, nparms); - - if (in_decl) - cp_error_at ("provided for `%D'", in_decl); - } - - return error_mark_node; - } - - new_inner_args = make_temp_vec (nparms); - new_args = add_outermost_template_args (args, new_inner_args); - for (i = 0; i < nparms; i++) - { - tree arg; - tree parm; - - /* Get the Ith template parameter. */ - parm = TREE_VEC_ELT (parms, i); - - /* Calculate the Ith argument. */ - if (inner_args && TREE_CODE (inner_args) == TREE_LIST) - { - arg = TREE_VALUE (inner_args); - inner_args = TREE_CHAIN (inner_args); - } - else if (i < nargs) - arg = TREE_VEC_ELT (inner_args, i); - /* If no template argument was supplied, look for a default - value. */ - else if (TREE_PURPOSE (parm) == NULL_TREE) - { - /* There was no default value. */ - my_friendly_assert (!require_all_arguments, 0); - break; - } - else if (TREE_CODE (TREE_VALUE (parm)) == TYPE_DECL) - arg = tsubst (TREE_PURPOSE (parm), new_args, in_decl); - else - arg = tsubst_expr (TREE_PURPOSE (parm), new_args, in_decl); - - /* Now, convert the Ith argument, as necessary. */ - if (arg == NULL_TREE) - /* We're out of arguments. */ - { - my_friendly_assert (!require_all_arguments, 0); - break; - } - else if (arg == error_mark_node) - { - cp_error ("template argument %d is invalid", i + 1); - arg = error_mark_node; - } - else - arg = convert_template_argument (TREE_VALUE (parm), - arg, new_args, complain, i, - in_decl); - - if (arg == error_mark_node) - lost++; - TREE_VEC_ELT (new_inner_args, i) = arg; - } - - if (lost) - return error_mark_node; - - return new_inner_args; -} - -/* Returns 1 if template args OT and NT are equivalent. */ - -int -template_args_equal (ot, nt) - tree ot, nt; -{ - if (nt == ot) - return 1; - if (TREE_CODE (nt) != TREE_CODE (ot)) - return 0; - if (TREE_CODE (nt) == TREE_VEC) - /* For member templates */ - return comp_template_args (ot, nt); - else if (TREE_CODE_CLASS (TREE_CODE (ot)) == 't') - return same_type_p (ot, nt); - else - return (cp_tree_equal (ot, nt) > 0); -} - -/* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets - of template arguments. Returns 0 otherwise. */ - -int -comp_template_args (oldargs, newargs) - tree oldargs, newargs; -{ - int i; - - if (TREE_VEC_LENGTH (oldargs) != TREE_VEC_LENGTH (newargs)) - return 0; - - for (i = 0; i < TREE_VEC_LENGTH (oldargs); ++i) - { - tree nt = TREE_VEC_ELT (newargs, i); - tree ot = TREE_VEC_ELT (oldargs, i); - - if (! template_args_equal (ot, nt)) - return 0; - } - return 1; -} - -/* Given class template name and parameter list, produce a user-friendly name - for the instantiation. */ - -static char * -mangle_class_name_for_template (name, parms, arglist) - char *name; - tree parms, arglist; -{ - static struct obstack scratch_obstack; - static char *scratch_firstobj; - int i, nparms; - - if (!scratch_firstobj) - gcc_obstack_init (&scratch_obstack); - else - obstack_free (&scratch_obstack, scratch_firstobj); - scratch_firstobj = obstack_alloc (&scratch_obstack, 1); - -#define ccat(c) obstack_1grow (&scratch_obstack, (c)); -#define cat(s) obstack_grow (&scratch_obstack, (s), strlen (s)) - - cat (name); - ccat ('<'); - nparms = TREE_VEC_LENGTH (parms); - arglist = innermost_args (arglist); - my_friendly_assert (nparms == TREE_VEC_LENGTH (arglist), 268); - for (i = 0; i < nparms; i++) - { - tree parm = TREE_VALUE (TREE_VEC_ELT (parms, i)); - tree arg = TREE_VEC_ELT (arglist, i); - - if (i) - ccat (','); - - if (TREE_CODE (parm) == TYPE_DECL) - { - cat (type_as_string_real (arg, 0, 1)); - continue; - } - else if (TREE_CODE (parm) == TEMPLATE_DECL) - { - if (TREE_CODE (arg) == TEMPLATE_DECL) - { - /* Already substituted with real template. Just output - the template name here */ - tree context = DECL_CONTEXT (arg); - if (context) - { - my_friendly_assert (TREE_CODE (context) == NAMESPACE_DECL, 980422); - cat(decl_as_string (DECL_CONTEXT (arg), 0)); - cat("::"); - } - cat (IDENTIFIER_POINTER (DECL_NAME (arg))); - } - else - /* Output the parameter declaration */ - cat (type_as_string_real (arg, 0, 1)); - continue; - } - else - my_friendly_assert (TREE_CODE (parm) == PARM_DECL, 269); - - if (TREE_CODE (arg) == TREE_LIST) - { - /* New list cell was built because old chain link was in - use. */ - my_friendly_assert (TREE_PURPOSE (arg) == NULL_TREE, 270); - arg = TREE_VALUE (arg); - } - /* No need to check arglist against parmlist here; we did that - in coerce_template_parms, called from lookup_template_class. */ - cat (expr_as_string (arg, 0)); - } - { - char *bufp = obstack_next_free (&scratch_obstack); - int offset = 0; - while (bufp[offset - 1] == ' ') - offset--; - obstack_blank_fast (&scratch_obstack, offset); - - /* B<C<char> >, not B<C<char>> */ - if (bufp[offset - 1] == '>') - ccat (' '); - } - ccat ('>'); - ccat ('\0'); - return (char *) obstack_base (&scratch_obstack); -} - -static tree -classtype_mangled_name (t) - tree t; -{ - if (CLASSTYPE_TEMPLATE_INFO (t) - /* Specializations have already had their names set up in - lookup_template_class. */ - && !CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) - { - tree tmpl = most_general_template (CLASSTYPE_TI_TEMPLATE (t)); - - /* For non-primary templates, the template parameters are - implicit from their surrounding context. */ - if (PRIMARY_TEMPLATE_P (tmpl)) - { - tree name = DECL_NAME (tmpl); - char *mangled_name = mangle_class_name_for_template - (IDENTIFIER_POINTER (name), - DECL_INNERMOST_TEMPLATE_PARMS (tmpl), - CLASSTYPE_TI_ARGS (t)); - tree id = get_identifier (mangled_name); - IDENTIFIER_TEMPLATE (id) = name; - return id; - } - } - - return TYPE_IDENTIFIER (t); -} - -static void -add_pending_template (d) - tree d; -{ - tree ti; - - if (TREE_CODE_CLASS (TREE_CODE (d)) == 't') - ti = CLASSTYPE_TEMPLATE_INFO (d); - else - ti = DECL_TEMPLATE_INFO (d); - - if (TI_PENDING_TEMPLATE_FLAG (ti)) - return; - - *template_tail = perm_tree_cons - (build_srcloc_here (), d, NULL_TREE); - template_tail = &TREE_CHAIN (*template_tail); - TI_PENDING_TEMPLATE_FLAG (ti) = 1; -} - - -/* Return a TEMPLATE_ID_EXPR corresponding to the indicated FNS (which - may be either a _DECL or an overloaded function or an - IDENTIFIER_NODE), and ARGLIST. */ - -tree -lookup_template_function (fns, arglist) - tree fns, arglist; -{ - tree type; - - if (fns == NULL_TREE) - { - cp_error ("non-template used as template"); - return error_mark_node; - } - - type = TREE_TYPE (fns); - if (TREE_CODE (fns) == OVERLOAD || !type) - type = unknown_type_node; - - if (processing_template_decl) - return build_min (TEMPLATE_ID_EXPR, type, fns, arglist); - else - return build (TEMPLATE_ID_EXPR, type, fns, arglist); -} - -/* Within the scope of a template class S<T>, the name S gets bound - (in build_self_reference) to a TYPE_DECL for the class, not a - TEMPLATE_DECL. If DECL is a TYPE_DECL for current_class_type, - or one of its enclosing classes, and that type is a template, - return the associated TEMPLATE_DECL. Otherwise, the original - DECL is returned. */ - -static tree -maybe_get_template_decl_from_type_decl (decl) - tree decl; -{ - return (decl != NULL_TREE - && TREE_CODE (decl) == TYPE_DECL - && DECL_ARTIFICIAL (decl) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (decl))) - ? CLASSTYPE_TI_TEMPLATE (TREE_TYPE (decl)) : decl; -} - -/* Given an IDENTIFIER_NODE (type TEMPLATE_DECL) and a chain of - parameters, find the desired type. - - D1 is the PTYPENAME terminal, and ARGLIST is the list of arguments. - (Actually ARGLIST may be either a TREE_LIST or a TREE_VEC. It will - be a TREE_LIST if called directly from the parser, and a TREE_VEC - otherwise.) Since ARGLIST is build on the decl_obstack, we must - copy it here to keep it from being reclaimed when the decl storage - is reclaimed. - - IN_DECL, if non-NULL, is the template declaration we are trying to - instantiate. - - If ENTERING_SCOPE is non-zero, we are about to enter the scope of - the class we are looking up. - - If the template class is really a local class in a template - function, then the FUNCTION_CONTEXT is the function in which it is - being instantiated. */ - -tree -lookup_template_class (d1, arglist, in_decl, context, entering_scope) - tree d1, arglist; - tree in_decl; - tree context; - int entering_scope; -{ - tree template = NULL_TREE, parmlist; - tree t; - - if (TREE_CODE (d1) == IDENTIFIER_NODE) - { - if (IDENTIFIER_VALUE (d1) - && DECL_TEMPLATE_TEMPLATE_PARM_P (IDENTIFIER_VALUE (d1))) - template = IDENTIFIER_VALUE (d1); - else - { - if (context) - push_decl_namespace (context); - if (current_class_type != NULL_TREE) - template = - maybe_get_template_decl_from_type_decl - (IDENTIFIER_CLASS_VALUE (d1)); - if (template == NULL_TREE) - template = lookup_name_nonclass (d1); - if (context) - pop_decl_namespace (); - } - if (template) - context = DECL_CONTEXT (template); - } - else if (TREE_CODE (d1) == TYPE_DECL && IS_AGGR_TYPE (TREE_TYPE (d1))) - { - if (CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (d1))) - { - template = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d1)); - d1 = DECL_NAME (template); - } - } - else if (TREE_CODE (d1) == ENUMERAL_TYPE - || (TREE_CODE_CLASS (TREE_CODE (d1)) == 't' - && IS_AGGR_TYPE (d1))) - { - template = TYPE_TI_TEMPLATE (d1); - d1 = DECL_NAME (template); - } - else if (TREE_CODE (d1) == TEMPLATE_DECL - && TREE_CODE (DECL_RESULT (d1)) == TYPE_DECL) - { - template = d1; - d1 = DECL_NAME (template); - context = DECL_CONTEXT (template); - } - else - my_friendly_abort (272); - - /* With something like `template <class T> class X class X { ... };' - we could end up with D1 having nothing but an IDENTIFIER_VALUE. - We don't want to do that, but we have to deal with the situation, - so let's give them some syntax errors to chew on instead of a - crash. */ - if (! template) - { - cp_error ("`%T' is not a template", d1); - return error_mark_node; - } - - if (context == NULL_TREE) - context = global_namespace; - - if (TREE_CODE (template) != TEMPLATE_DECL) - { - cp_error ("non-template type `%T' used as a template", d1); - if (in_decl) - cp_error_at ("for template declaration `%D'", in_decl); - return error_mark_node; - } - - if (DECL_TEMPLATE_TEMPLATE_PARM_P (template)) - { - /* Create a new TEMPLATE_DECL and TEMPLATE_TEMPLATE_PARM node to store - template arguments */ - - tree parm = copy_template_template_parm (TREE_TYPE (template)); - tree template2 = TYPE_STUB_DECL (parm); - tree arglist2; - - parmlist = DECL_INNERMOST_TEMPLATE_PARMS (template); - - arglist2 = coerce_template_parms (parmlist, arglist, template, 1, 1); - if (arglist2 == error_mark_node) - return error_mark_node; - - arglist2 = copy_to_permanent (arglist2); - TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm) - = perm_tree_cons (template2, arglist2, NULL_TREE); - TYPE_SIZE (parm) = 0; - return parm; - } - else - { - tree template_type = TREE_TYPE (template); - tree type_decl; - tree found = NULL_TREE; - int arg_depth; - int parm_depth; - int is_partial_instantiation; - - template = most_general_template (template); - parmlist = DECL_TEMPLATE_PARMS (template); - parm_depth = TMPL_PARMS_DEPTH (parmlist); - arg_depth = TMPL_ARGS_DEPTH (arglist); - - /* We build up the coerced arguments and such on the - momentary_obstack. */ - push_momentary (); - - if (arg_depth == 1 && parm_depth > 1) - { - /* We've been given an incomplete set of template arguments. - For example, given: - - template <class T> struct S1 { - template <class U> struct S2 {}; - template <class U> struct S2<U*> {}; - }; - - we will be called with an ARGLIST of `U*', but the - TEMPLATE will be `template <class T> template - <class U> struct S1<T>::S2'. We must fill in the missing - arguments. */ - my_friendly_assert (context != NULL_TREE, 0); - while (!IS_AGGR_TYPE_CODE (TREE_CODE (context)) - && context != global_namespace) - context = DECL_REAL_CONTEXT (context); - - if (context == global_namespace) - /* This is bad. We cannot get enough arguments, even from - the surrounding context, to resolve this class. One - case where this might happen is (illegal) code like: - - template <class U> - template <class T> - struct S { - A(const A<T>& a) {} - }; - - We should catch this error sooner (at the opening curly - for `S', but it is better to be safe than sorry here. */ - { - cp_error ("invalid use of `%D'", template); - return error_mark_node; - } - - arglist = add_to_template_args (TYPE_TI_ARGS (context), - arglist); - arg_depth = TMPL_ARGS_DEPTH (arglist); - } - - my_friendly_assert (parm_depth == arg_depth, 0); - - /* Calculate the BOUND_ARGS. These will be the args that are - actually tsubst'd into the definition to create the - instantiation. */ - if (parm_depth > 1) - { - /* We have multiple levels of arguments to coerce, at once. */ - int i; - int saved_depth = TMPL_ARGS_DEPTH (arglist); - - tree bound_args = make_temp_vec (parm_depth); - - for (i = saved_depth, - t = DECL_TEMPLATE_PARMS (template); - i > 0 && t != NULL_TREE; - --i, t = TREE_CHAIN (t)) - { - tree a = coerce_template_parms (TREE_VALUE (t), - arglist, template, 1, 1); - SET_TMPL_ARGS_LEVEL (bound_args, i, a); - - /* We temporarily reduce the length of the ARGLIST so - that coerce_template_parms will see only the arguments - corresponding to the template parameters it is - examining. */ - TREE_VEC_LENGTH (arglist)--; - } - - /* Restore the ARGLIST to its full size. */ - TREE_VEC_LENGTH (arglist) = saved_depth; - - arglist = bound_args; - } - else - arglist - = coerce_template_parms (INNERMOST_TEMPLATE_PARMS (parmlist), - innermost_args (arglist), - template, 1, 1); - - if (arglist == error_mark_node) - /* We were unable to bind the arguments. */ - return error_mark_node; - - /* In the scope of a template class, explicit references to the - template class refer to the type of the template, not any - instantiation of it. For example, in: - - template <class T> class C { void f(C<T>); } - - the `C<T>' is just the same as `C'. Outside of the - class, however, such a reference is an instantiation. */ - if (comp_template_args (TYPE_TI_ARGS (template_type), - arglist)) - { - found = template_type; - - if (!entering_scope && PRIMARY_TEMPLATE_P (template)) - { - tree ctx; - - /* Note that we use DECL_CONTEXT, rather than - CP_DECL_CONTEXT, so that the termination test is - always just `ctx'. We're not interested in namepace - scopes. */ - for (ctx = current_class_type; - ctx; - ctx = (TREE_CODE_CLASS (TREE_CODE (ctx)) == 't') - ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx)) - if (same_type_p (ctx, template_type)) - break; - - if (!ctx) - /* We're not in the scope of the class, so the - TEMPLATE_TYPE is not the type we want after - all. */ - found = NULL_TREE; - } - } - - if (!found) - { - for (found = DECL_TEMPLATE_INSTANTIATIONS (template); - found; found = TREE_CHAIN (found)) - if (comp_template_args (TREE_PURPOSE (found), arglist)) - break; - - if (found) - found = TREE_VALUE (found); - } - - if (found) - { - pop_momentary (); - return found; - } - - /* Since we didn't find the type, we'll have to create it. - Since we'll be saving this type on the - DECL_TEMPLATE_INSTANTIATIONS list, it must be permanent. */ - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* This type is a "partial instantiation" if any of the template - arguments still inolve template parameters. Note that we set - IS_PARTIAL_INSTANTIATION for partial specializations as - well. */ - is_partial_instantiation = uses_template_parms (arglist); - - /* Create the type. */ - if (TREE_CODE (template_type) == ENUMERAL_TYPE) - { - if (!is_partial_instantiation) - t = start_enum (TYPE_IDENTIFIER (template_type)); - else - /* We don't want to call start_enum for this type, since - the values for the enumeration constants may involve - template parameters. And, no one should be interested - in the enumeration constants for such a type. */ - t = make_node (ENUMERAL_TYPE); - } - else - { - t = make_lang_type (TREE_CODE (template_type)); - CLASSTYPE_DECLARED_CLASS (t) - = CLASSTYPE_DECLARED_CLASS (template_type); - CLASSTYPE_GOT_SEMICOLON (t) = 1; - SET_CLASSTYPE_IMPLICIT_INSTANTIATION (t); - TYPE_FOR_JAVA (t) = TYPE_FOR_JAVA (template_type); - } - - /* If we called start_enum above, this information will already - be set up. */ - if (!TYPE_NAME (t)) - { - TYPE_CONTEXT (t) = FROB_CONTEXT (context); - - /* Create a stub TYPE_DECL for it. */ - type_decl = build_decl (TYPE_DECL, DECL_NAME (template), t); - SET_DECL_ARTIFICIAL (type_decl); - DECL_CONTEXT (type_decl) = TYPE_CONTEXT (t); - DECL_SOURCE_FILE (type_decl) - = DECL_SOURCE_FILE (TYPE_STUB_DECL (template_type)); - DECL_SOURCE_LINE (type_decl) - = DECL_SOURCE_LINE (TYPE_STUB_DECL (template_type)); - TYPE_STUB_DECL (t) = TYPE_NAME (t) = type_decl; - } - else - type_decl = TYPE_NAME (t); - - /* Set up the template information. We have to figure out which - template is the immediate parent if this is a full - instantiation. */ - if (parm_depth == 1 || is_partial_instantiation - || !PRIMARY_TEMPLATE_P (template)) - /* This case is easy; there are no member templates involved. */ - found = template; - else - { - /* This is a full instantiation of a member template. There - should be some partial instantiation of which this is an - instance. */ - - for (found = DECL_TEMPLATE_INSTANTIATIONS (template); - found; found = TREE_CHAIN (found)) - { - int success; - tree tmpl = CLASSTYPE_TI_TEMPLATE (TREE_VALUE (found)); - - /* We only want partial instantiations, here, not - specializations or full instantiations. */ - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (TREE_VALUE (found)) - || !uses_template_parms (TREE_VALUE (found))) - continue; - - /* Temporarily reduce by one the number of levels in the - ARGLIST and in FOUND so as to avoid comparing the - last set of arguments. */ - TREE_VEC_LENGTH (arglist)--; - TREE_VEC_LENGTH (TREE_PURPOSE (found)) --; - - /* See if the arguments match. If they do, then TMPL is - the partial instantiation we want. */ - success = comp_template_args (TREE_PURPOSE (found), arglist); - - /* Restore the argument vectors to their full size. */ - TREE_VEC_LENGTH (arglist)++; - TREE_VEC_LENGTH (TREE_PURPOSE (found))++; - - if (success) - { - found = tmpl; - break; - } - } - - if (!found) - my_friendly_abort (0); - } - - arglist = copy_to_permanent (arglist); - SET_TYPE_TEMPLATE_INFO (t, - tree_cons (found, arglist, NULL_TREE)); - DECL_TEMPLATE_INSTANTIATIONS (template) - = tree_cons (arglist, t, - DECL_TEMPLATE_INSTANTIATIONS (template)); - - if (TREE_CODE (t) == ENUMERAL_TYPE - && !is_partial_instantiation) - /* Now that the type has been registered on the instantiations - list, we set up the enumerators. Because the enumeration - constants may involve the enumeration type itself, we make - sure to register the type first, and then create the - constants. That way, doing tsubst_expr for the enumeration - constants won't result in recursive calls here; we'll find - the instantiation and exit above. */ - tsubst_enum (template_type, t, arglist); - - /* We're done with the permanent obstack, now. */ - pop_obstacks (); - /* We're also done with the momentary allocation we started - above. */ - pop_momentary (); - - /* Reset the name of the type, now that CLASSTYPE_TEMPLATE_INFO - is set up. */ - if (TREE_CODE (t) != ENUMERAL_TYPE) - DECL_NAME (type_decl) = classtype_mangled_name (t); - DECL_ASSEMBLER_NAME (type_decl) = DECL_NAME (type_decl); - if (!is_partial_instantiation) - { - DECL_ASSEMBLER_NAME (type_decl) - = get_identifier (build_overload_name (t, 1, 1)); - - /* For backwards compatibility; code that uses - -fexternal-templates expects looking up a template to - instantiate it. I think DDD still relies on this. - (jason 8/20/1998) */ - if (TREE_CODE (t) != ENUMERAL_TYPE - && flag_external_templates - && CLASSTYPE_INTERFACE_KNOWN (TREE_TYPE (template)) - && ! CLASSTYPE_INTERFACE_ONLY (TREE_TYPE (template))) - add_pending_template (t); - } - else - /* If the type makes use of template parameters, the - code that generates debugging information will crash. */ - DECL_IGNORED_P (TYPE_STUB_DECL (t)) = 1; - - return t; - } -} - -/* For each TEMPLATE_TYPE_PARM, TEMPLATE_TEMPLATE_PARM, or - TEMPLATE_PARM_INDEX in T, call FN with the parameter and the DATA. - If FN returns non-zero, the iteration is terminated, and - for_each_template_parm returns 1. Otherwise, the iteration - continues. If FN never returns a non-zero value, the value - returned by for_each_template_parm is 0. If FN is NULL, it is - considered to be the function which always returns 1. */ - -static int -for_each_template_parm (t, fn, data) - tree t; - tree_fn_t fn; - void* data; -{ - if (!t) - return 0; - - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't' - && for_each_template_parm (TYPE_CONTEXT (t), fn, data)) - return 1; - - switch (TREE_CODE (t)) - { - case INDIRECT_REF: - case COMPONENT_REF: - /* We assume that the object must be instantiated in order to build - the COMPONENT_REF, so we test only whether the type of the - COMPONENT_REF uses template parms. */ - return for_each_template_parm (TREE_TYPE (t), fn, data); - - case ARRAY_REF: - return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data) - || for_each_template_parm (TREE_OPERAND (t, 1), fn, data)); - - case IDENTIFIER_NODE: - if (!IDENTIFIER_TEMPLATE (t)) - return 0; - my_friendly_abort (42); - - /* aggregates of tree nodes */ - case TREE_VEC: - { - int i = TREE_VEC_LENGTH (t); - while (i--) - if (for_each_template_parm (TREE_VEC_ELT (t, i), fn, data)) - return 1; - return 0; - } - case TREE_LIST: - if (for_each_template_parm (TREE_PURPOSE (t), fn, data) - || for_each_template_parm (TREE_VALUE (t), fn, data)) - return 1; - return for_each_template_parm (TREE_CHAIN (t), fn, data); - - case OVERLOAD: - if (for_each_template_parm (OVL_FUNCTION (t), fn, data)) - return 1; - return for_each_template_parm (OVL_CHAIN (t), fn, data); - - /* constructed type nodes */ - case POINTER_TYPE: - case REFERENCE_TYPE: - return for_each_template_parm (TREE_TYPE (t), fn, data); - - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_FLAG (t)) - return for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE (t), - fn, data); - /* Fall through. */ - - case UNION_TYPE: - case ENUMERAL_TYPE: - if (! TYPE_TEMPLATE_INFO (t)) - return 0; - return for_each_template_parm (TREE_VALUE - (TYPE_TEMPLATE_INFO (t)), - fn, data); - case METHOD_TYPE: - if (for_each_template_parm (TYPE_METHOD_BASETYPE (t), fn, data)) - return 1; - /* Fall through. */ - - case FUNCTION_TYPE: - /* Check the parameter types. Since default arguments are not - instantiated until they are needed, the TYPE_ARG_TYPES may - contain expressions that involve template parameters. But, - no-one should be looking at them yet. And, once they're - instantiated, they don't contain template parameters, so - there's no point in looking at them then, either. */ - { - tree parm; - - for (parm = TYPE_ARG_TYPES (t); parm; parm = TREE_CHAIN (parm)) - if (for_each_template_parm (TREE_VALUE (parm), fn, data)) - return 1; - } - - /* Check the return type, too. */ - return for_each_template_parm (TREE_TYPE (t), fn, data); - - case ARRAY_TYPE: - if (for_each_template_parm (TYPE_DOMAIN (t), fn, data)) - return 1; - return for_each_template_parm (TREE_TYPE (t), fn, data); - case OFFSET_TYPE: - if (for_each_template_parm (TYPE_OFFSET_BASETYPE (t), fn, data)) - return 1; - return for_each_template_parm (TREE_TYPE (t), fn, data); - - /* decl nodes */ - case TYPE_DECL: - return for_each_template_parm (TREE_TYPE (t), fn, data); - - case TEMPLATE_DECL: - /* A template template parameter is encountered */ - if (DECL_TEMPLATE_TEMPLATE_PARM_P (t)) - return for_each_template_parm (TREE_TYPE (t), fn, data); - /* Already substituted template template parameter */ - return 0; - - case CONST_DECL: - if (for_each_template_parm (DECL_INITIAL (t), fn, data)) - return 1; - goto check_type_and_context; - - case FUNCTION_DECL: - case VAR_DECL: - /* ??? What about FIELD_DECLs? */ - if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t) - && for_each_template_parm (DECL_TI_ARGS (t), fn, data)) - return 1; - /* fall through */ - case PARM_DECL: - check_type_and_context: - if (for_each_template_parm (TREE_TYPE (t), fn, data)) - return 1; - if (DECL_CONTEXT (t) - && for_each_template_parm (DECL_CONTEXT (t), fn, data)) - return 1; - return 0; - - case CALL_EXPR: - return (for_each_template_parm (TREE_OPERAND (t, 0), fn, data) - || for_each_template_parm (TREE_OPERAND (t, 1), fn, data)); - - case ADDR_EXPR: - return for_each_template_parm (TREE_OPERAND (t, 0), fn, data); - - /* template parm nodes */ - case TEMPLATE_TEMPLATE_PARM: - /* Record template parameters such as `T' inside `TT<T>'. */ - if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t) - && for_each_template_parm (TYPE_TI_ARGS (t), fn, data)) - return 1; - case TEMPLATE_TYPE_PARM: - case TEMPLATE_PARM_INDEX: - if (fn) - return (*fn)(t, data); - else - return 1; - - /* simple type nodes */ - case INTEGER_TYPE: - if (for_each_template_parm (TYPE_MIN_VALUE (t), fn, data)) - return 1; - return for_each_template_parm (TYPE_MAX_VALUE (t), fn, data); - - case REAL_TYPE: - case COMPLEX_TYPE: - case VOID_TYPE: - case BOOLEAN_TYPE: - case NAMESPACE_DECL: - return 0; - - /* constants */ - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - return 0; - - case ERROR_MARK: - /* Non-error_mark_node ERROR_MARKs are bad things. */ - my_friendly_assert (t == error_mark_node, 274); - /* NOTREACHED */ - return 0; - - case LOOKUP_EXPR: - case TYPENAME_TYPE: - return 1; - - case PTRMEM_CST: - return for_each_template_parm (TREE_TYPE (t), fn, data); - - case SCOPE_REF: - return for_each_template_parm (TREE_OPERAND (t, 0), fn, data); - - case CONSTRUCTOR: - if (TREE_TYPE (t) && TYPE_PTRMEMFUNC_P (TREE_TYPE (t))) - return for_each_template_parm (TYPE_PTRMEMFUNC_FN_TYPE - (TREE_TYPE (t)), fn, data); - return for_each_template_parm (TREE_OPERAND (t, 1), fn, data); - - case MODOP_EXPR: - case CAST_EXPR: - case REINTERPRET_CAST_EXPR: - case CONST_CAST_EXPR: - case STATIC_CAST_EXPR: - case DYNAMIC_CAST_EXPR: - case ARROW_EXPR: - case DOTSTAR_EXPR: - case TYPEID_EXPR: - return 1; - - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - return for_each_template_parm (TREE_OPERAND (t, 0), fn, data); - - default: - switch (TREE_CODE_CLASS (TREE_CODE (t))) - { - case '1': - case '2': - case 'e': - case '<': - { - int i; - for (i = first_rtl_op (TREE_CODE (t)); --i >= 0;) - if (for_each_template_parm (TREE_OPERAND (t, i), fn, data)) - return 1; - return 0; - } - default: - break; - } - sorry ("testing %s for template parms", - tree_code_name [(int) TREE_CODE (t)]); - my_friendly_abort (82); - /* NOTREACHED */ - return 0; - } -} - -int -uses_template_parms (t) - tree t; -{ - return for_each_template_parm (t, 0, 0); -} - -static struct tinst_level *current_tinst_level; -static struct tinst_level *free_tinst_level; -static int tinst_depth; -extern int max_tinst_depth; -#ifdef GATHER_STATISTICS -int depth_reached; -#endif -int tinst_level_tick; -int last_template_error_tick; - -/* Print out all the template instantiations that we are currently - working on. If ERR, we are being called from cp_thing, so do - the right thing for an error message. */ - -static void -print_template_context (err) - int err; -{ - struct tinst_level *p = current_tinst_level; - int line = lineno; - char *file = input_filename; - - if (err && p) - { - if (current_function_decl != p->decl - && current_function_decl != NULL_TREE) - /* We can get here during the processing of some synthesized - method. Then, p->decl will be the function that's causing - the synthesis. */ - ; - else - { - if (current_function_decl == p->decl) - /* Avoid redundancy with the the "In function" line. */; - else - fprintf (stderr, "%s: In instantiation of `%s':\n", - file, decl_as_string (p->decl, 0)); - - line = p->line; - file = p->file; - p = p->next; - } - } - - for (; p; p = p->next) - { - fprintf (stderr, "%s:%d: instantiated from `%s'\n", file, line, - decl_as_string (p->decl, 0)); - line = p->line; - file = p->file; - } - fprintf (stderr, "%s:%d: instantiated from here\n", file, line); -} - -/* Called from cp_thing to print the template context for an error. */ - -void -maybe_print_template_context () -{ - if (last_template_error_tick == tinst_level_tick - || current_tinst_level == 0) - return; - - last_template_error_tick = tinst_level_tick; - print_template_context (1); -} - -static int -push_tinst_level (d) - tree d; -{ - struct tinst_level *new; - - if (tinst_depth >= max_tinst_depth) - { - /* If the instantiation in question still has unbound template parms, - we don't really care if we can't instantiate it, so just return. - This happens with base instantiation for implicit `typename'. */ - if (uses_template_parms (d)) - return 0; - - last_template_error_tick = tinst_level_tick; - error ("template instantiation depth exceeds maximum of %d", - max_tinst_depth); - error (" (use -ftemplate-depth-NN to increase the maximum)"); - cp_error (" instantiating `%D'", d); - - print_template_context (0); - - return 0; - } - - if (free_tinst_level) - { - new = free_tinst_level; - free_tinst_level = new->next; - } - else - new = (struct tinst_level *) xmalloc (sizeof (struct tinst_level)); - - new->decl = d; - new->line = lineno; - new->file = input_filename; - new->next = current_tinst_level; - current_tinst_level = new; - - ++tinst_depth; -#ifdef GATHER_STATISTICS - if (tinst_depth > depth_reached) - depth_reached = tinst_depth; -#endif - - ++tinst_level_tick; - return 1; -} - -void -pop_tinst_level () -{ - struct tinst_level *old = current_tinst_level; - - /* Restore the filename and line number stashed away when we started - this instantiation. */ - lineno = old->line; - input_filename = old->file; - extract_interface_info (); - - current_tinst_level = old->next; - old->next = free_tinst_level; - free_tinst_level = old; - --tinst_depth; - ++tinst_level_tick; -} - -struct tinst_level * -tinst_for_decl () -{ - struct tinst_level *p = current_tinst_level; - - if (p) - for (; p->next ; p = p->next ) - ; - return p; -} - -/* DECL is a friend FUNCTION_DECL or TEMPLATE_DECL. ARGS is the - vector of template arguments, as for tsubst. - - Returns an appropriate tsbust'd friend declaration. */ - -static tree -tsubst_friend_function (decl, args) - tree decl; - tree args; -{ - tree new_friend; - int line = lineno; - char *file = input_filename; - - lineno = DECL_SOURCE_LINE (decl); - input_filename = DECL_SOURCE_FILE (decl); - - if (TREE_CODE (decl) == FUNCTION_DECL - && DECL_TEMPLATE_INSTANTIATION (decl) - && TREE_CODE (DECL_TI_TEMPLATE (decl)) != TEMPLATE_DECL) - /* This was a friend declared with an explicit template - argument list, e.g.: - - friend void f<>(T); - - to indicate that f was a template instantiation, not a new - function declaration. Now, we have to figure out what - instantiation of what template. */ - { - tree template_id; - tree new_args; - tree tmpl; - - template_id - = lookup_template_function (tsubst_expr (DECL_TI_TEMPLATE (decl), - args, NULL_TREE), - tsubst (DECL_TI_ARGS (decl), - args, NULL_TREE)); - /* FIXME: The decl we create via the next tsubst could be - created on a temporary obstack. */ - new_friend = tsubst (decl, args, NULL_TREE); - tmpl = determine_specialization (template_id, new_friend, - &new_args, - /*need_member_template=*/0, - /*complain=*/1); - new_friend = instantiate_template (tmpl, new_args); - goto done; - } - - new_friend = tsubst (decl, args, NULL_TREE); - - /* The NEW_FRIEND will look like an instantiation, to the - compiler, but is not an instantiation from the point of view of - the language. For example, we might have had: - - template <class T> struct S { - template <class U> friend void f(T, U); - }; - - Then, in S<int>, template <class U> void f(int, U) is not an - instantiation of anything. */ - DECL_USE_TEMPLATE (new_friend) = 0; - if (TREE_CODE (decl) == TEMPLATE_DECL) - DECL_USE_TEMPLATE (DECL_TEMPLATE_RESULT (new_friend)) = 0; - - /* The mangled name for the NEW_FRIEND is incorrect. The call to - tsubst will have resulted in a call to - set_mangled_name_for_template_decl. But, the function is not a - template instantiation and should not be mangled like one. - Therefore, we remangle the function name. We don't have to do - this if the NEW_FRIEND is a template since - set_mangled_name_for_template_decl doesn't do anything if the - function declaration still uses template arguments. */ - if (TREE_CODE (new_friend) != TEMPLATE_DECL) - { - set_mangled_name_for_decl (new_friend); - DECL_RTL (new_friend) = 0; - make_decl_rtl (new_friend, NULL_PTR, 1); - } - - if (DECL_NAMESPACE_SCOPE_P (new_friend)) - { - tree old_decl; - tree new_friend_template_info; - tree new_friend_result_template_info; - int new_friend_is_defn; - - /* We must save some information from NEW_FRIEND before calling - duplicate decls since that function will free NEW_FRIEND if - possible. */ - new_friend_template_info = DECL_TEMPLATE_INFO (new_friend); - if (TREE_CODE (new_friend) == TEMPLATE_DECL) - { - /* This declaration is a `primary' template. */ - DECL_PRIMARY_TEMPLATE (new_friend) = new_friend; - - new_friend_is_defn - = DECL_INITIAL (DECL_RESULT (new_friend)) != NULL_TREE; - new_friend_result_template_info - = DECL_TEMPLATE_INFO (DECL_RESULT (new_friend)); - } - else - { - new_friend_is_defn = DECL_INITIAL (new_friend) != NULL_TREE; - new_friend_result_template_info = NULL_TREE; - } - - old_decl = pushdecl_namespace_level (new_friend); - - if (old_decl != new_friend) - { - /* This new friend declaration matched an existing - declaration. For example, given: - - template <class T> void f(T); - template <class U> class C { - template <class T> friend void f(T) {} - }; - - the friend declaration actually provides the definition - of `f', once C has been instantiated for some type. So, - old_decl will be the out-of-class template declaration, - while new_friend is the in-class definition. - - But, if `f' was called before this point, the - instantiation of `f' will have DECL_TI_ARGS corresponding - to `T' but not to `U', references to which might appear - in the definition of `f'. Previously, the most general - template for an instantiation of `f' was the out-of-class - version; now it is the in-class version. Therefore, we - run through all specialization of `f', adding to their - DECL_TI_ARGS appropriately. In particular, they need a - new set of outer arguments, corresponding to the - arguments for this class instantiation. - - The same situation can arise with something like this: - - friend void f(int); - template <class T> class C { - friend void f(T) {} - }; - - when `C<int>' is instantiated. Now, `f(int)' is defined - in the class. */ - - if (!new_friend_is_defn) - /* On the other hand, if the in-class declaration does - *not* provide a definition, then we don't want to alter - existing definitions. We can just leave everything - alone. */ - ; - else - { - /* Overwrite whatever template info was there before, if - any, with the new template information pertaining to - the declaration. */ - DECL_TEMPLATE_INFO (old_decl) = new_friend_template_info; - - if (TREE_CODE (old_decl) != TEMPLATE_DECL) - /* duplicate_decls will take care of this case. */ - ; - else - { - tree t; - tree new_friend_args; - - DECL_TEMPLATE_INFO (DECL_RESULT (old_decl)) - = new_friend_result_template_info; - - new_friend_args = TI_ARGS (new_friend_template_info); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (old_decl); - t != NULL_TREE; - t = TREE_CHAIN (t)) - { - tree spec = TREE_VALUE (t); - - DECL_TI_ARGS (spec) - = add_outermost_template_args (new_friend_args, - DECL_TI_ARGS (spec)); - DECL_TI_ARGS (spec) - = copy_to_permanent (DECL_TI_ARGS (spec)); - } - - /* Now, since specializations are always supposed to - hang off of the most general template, we must move - them. */ - t = most_general_template (old_decl); - if (t != old_decl) - { - DECL_TEMPLATE_SPECIALIZATIONS (t) - = chainon (DECL_TEMPLATE_SPECIALIZATIONS (t), - DECL_TEMPLATE_SPECIALIZATIONS (old_decl)); - DECL_TEMPLATE_SPECIALIZATIONS (old_decl) = NULL_TREE; - } - } - } - - /* The information from NEW_FRIEND has been merged into OLD_DECL - by duplicate_decls. */ - new_friend = old_decl; - } - } - else if (TYPE_SIZE (DECL_CONTEXT (new_friend))) - { - /* Check to see that the declaration is really present, and, - possibly obtain an improved declaration. */ - tree fn = check_classfn (DECL_CONTEXT (new_friend), - new_friend); - - if (fn) - new_friend = fn; - } - - done: - lineno = line; - input_filename = file; - return new_friend; -} - -/* FRIEND_TMPL is a friend TEMPLATE_DECL. ARGS is the vector of - template arguments, as for tsubst. - - Returns an appropriate tsbust'd friend type. */ - -static tree -tsubst_friend_class (friend_tmpl, args) - tree friend_tmpl; - tree args; -{ - tree friend_type; - tree tmpl = lookup_name (DECL_NAME (friend_tmpl), 1); - - tmpl = maybe_get_template_decl_from_type_decl (tmpl); - - if (tmpl != NULL_TREE && DECL_CLASS_TEMPLATE_P (tmpl)) - { - /* The friend template has already been declared. Just - check to see that the declarations match, and install any new - default parameters. We must tsubst the default parameters, - of course. We only need the innermost template parameters - because that is all that redeclare_class_template will look - at. */ - tree parms - = tsubst_template_parms (DECL_TEMPLATE_PARMS (friend_tmpl), - args); - redeclare_class_template (TREE_TYPE (tmpl), parms); - friend_type = TREE_TYPE (tmpl); - } - else - { - /* The friend template has not already been declared. In this - case, the instantiation of the template class will cause the - injection of this template into the global scope. */ - tmpl = tsubst (friend_tmpl, args, NULL_TREE); - - /* The new TMPL is not an instantiation of anything, so we - forget its origins. We don't reset CLASSTYPE_TI_TEMPLATE for - the new type because that is supposed to be the corresponding - template decl, i.e., TMPL. */ - DECL_USE_TEMPLATE (tmpl) = 0; - DECL_TEMPLATE_INFO (tmpl) = NULL_TREE; - CLASSTYPE_USE_TEMPLATE (TREE_TYPE (tmpl)) = 0; - - /* Inject this template into the global scope. */ - friend_type = TREE_TYPE (pushdecl_top_level (tmpl)); - } - - return friend_type; -} - -tree -instantiate_class_template (type) - tree type; -{ - tree template, args, pattern, t; - tree typedecl; - - if (type == error_mark_node) - return error_mark_node; - - if (TYPE_BEING_DEFINED (type) || TYPE_SIZE (type)) - return type; - - /* We want to allocate temporary vectors of template arguments and - template argument expressions on the momentary obstack, not on - the expression obstack. Otherwise, all the space allocated in - argument coercion and such is simply lost. */ - push_momentary (); - - /* Figure out which template is being instantiated. */ - template = most_general_template (CLASSTYPE_TI_TEMPLATE (type)); - my_friendly_assert (TREE_CODE (template) == TEMPLATE_DECL, 279); - - /* Figure out which arguments are being used to do the - instantiation. */ - args = CLASSTYPE_TI_ARGS (type); - PARTIAL_INSTANTIATION_P (type) = uses_template_parms (args); - - if (pedantic && PARTIAL_INSTANTIATION_P (type)) - /* If this is a partial instantiation, then we can't instantiate - the type; there's no telling whether or not one of the - template parameters might eventually be instantiated to some - value that results in a specialization being used. For - example, consider: - - template <class T> - struct S {}; - - template <class U> - void f(S<U>); - - template <> - struct S<int> {}; - - Now, the `S<U>' in `f<int>' is the specialization, not an - instantiation of the original template. */ - goto end; - - /* Determine what specialization of the original template to - instantiate. */ - if (PARTIAL_INSTANTIATION_P (type)) - /* There's no telling which specialization is appropriate at this - point. Since all peeking at the innards of this partial - instantiation are extensions (like the "implicit typename" - extension, which allows users to omit the keyword `typename' on - names that are declared as types in template base classes), we - are free to do what we please. - - Trying to figure out which partial instantiation to use can - cause a crash. (Some of the template arguments don't even have - types.) So, we just use the most general version. */ - t = NULL_TREE; - else - { - t = most_specialized_class (template, args); - - if (t == error_mark_node) - { - char *str = "candidates are:"; - cp_error ("ambiguous class template instantiation for `%#T'", type); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (template); t; - t = TREE_CHAIN (t)) - { - if (get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), - args)) - { - cp_error_at ("%s %+#T", str, TREE_TYPE (t)); - str = " "; - } - } - TYPE_BEING_DEFINED (type) = 1; - type = error_mark_node; - goto end; - } - } - - if (t) - pattern = TREE_TYPE (t); - else - pattern = TREE_TYPE (template); - - /* If the template we're instantiating is incomplete, then clearly - there's nothing we can do. */ - if (TYPE_SIZE (pattern) == NULL_TREE) - goto end; - - /* If this is a partial instantiation, don't tsubst anything. We will - only use this type for implicit typename, so the actual contents don't - matter. All that matters is whether a particular name is a type. */ - if (PARTIAL_INSTANTIATION_P (type)) - { - /* The fields set here must be kept in sync with those cleared - in begin_class_definition. */ - TYPE_BINFO_BASETYPES (type) = TYPE_BINFO_BASETYPES (pattern); - TYPE_FIELDS (type) = TYPE_FIELDS (pattern); - TYPE_METHODS (type) = TYPE_METHODS (pattern); - CLASSTYPE_TAGS (type) = CLASSTYPE_TAGS (pattern); - /* Pretend that the type is complete, so that we will look - inside it during name lookup and such. */ - TYPE_SIZE (type) = integer_zero_node; - goto end; - } - - /* If we've recursively instantiated too many templates, stop. */ - if (! push_tinst_level (type)) - goto end; - - /* Now we're really doing the instantiation. Mark the type as in - the process of being defined. */ - TYPE_BEING_DEFINED (type) = 1; - - maybe_push_to_top_level (uses_template_parms (type)); - pushclass (type, 0); - - if (t) - { - /* This TYPE is actually a instantiation of of a partial - specialization. We replace the innermost set of ARGS with - the arguments appropriate for substitution. For example, - given: - - template <class T> struct S {}; - template <class T> struct S<T*> {}; - - and supposing that we are instantiating S<int*>, ARGS will - present be {int*} but we need {int}. */ - tree inner_args - = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), - args); - - /* If there were multiple levels in ARGS, replacing the - innermost level would alter CLASSTYPE_TI_ARGS, which we don't - want, so we make a copy first. */ - if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args)) - { - args = copy_node (args); - SET_TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args), inner_args); - } - else - args = inner_args; - } - - if (flag_external_templates) - { - if (flag_alt_external_templates) - { - CLASSTYPE_INTERFACE_ONLY (type) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X (type, interface_unknown); - CLASSTYPE_VTABLE_NEEDS_WRITING (type) - = (! CLASSTYPE_INTERFACE_ONLY (type) - && CLASSTYPE_INTERFACE_KNOWN (type)); - } - else - { - CLASSTYPE_INTERFACE_ONLY (type) = CLASSTYPE_INTERFACE_ONLY (pattern); - SET_CLASSTYPE_INTERFACE_UNKNOWN_X - (type, CLASSTYPE_INTERFACE_UNKNOWN (pattern)); - CLASSTYPE_VTABLE_NEEDS_WRITING (type) - = (! CLASSTYPE_INTERFACE_ONLY (type) - && CLASSTYPE_INTERFACE_KNOWN (type)); - } - } - else - { - SET_CLASSTYPE_INTERFACE_UNKNOWN (type); - CLASSTYPE_VTABLE_NEEDS_WRITING (type) = 1; - } - - TYPE_HAS_CONSTRUCTOR (type) = TYPE_HAS_CONSTRUCTOR (pattern); - TYPE_HAS_DESTRUCTOR (type) = TYPE_HAS_DESTRUCTOR (pattern); - TYPE_HAS_ASSIGNMENT (type) = TYPE_HAS_ASSIGNMENT (pattern); - TYPE_OVERLOADS_CALL_EXPR (type) = TYPE_OVERLOADS_CALL_EXPR (pattern); - TYPE_OVERLOADS_ARRAY_REF (type) = TYPE_OVERLOADS_ARRAY_REF (pattern); - TYPE_OVERLOADS_ARROW (type) = TYPE_OVERLOADS_ARROW (pattern); - TYPE_GETS_NEW (type) = TYPE_GETS_NEW (pattern); - TYPE_GETS_DELETE (type) = TYPE_GETS_DELETE (pattern); - TYPE_VEC_DELETE_TAKES_SIZE (type) = TYPE_VEC_DELETE_TAKES_SIZE (pattern); - TYPE_HAS_ASSIGN_REF (type) = TYPE_HAS_ASSIGN_REF (pattern); - TYPE_HAS_CONST_ASSIGN_REF (type) = TYPE_HAS_CONST_ASSIGN_REF (pattern); - TYPE_HAS_ABSTRACT_ASSIGN_REF (type) = TYPE_HAS_ABSTRACT_ASSIGN_REF (pattern); - TYPE_HAS_INIT_REF (type) = TYPE_HAS_INIT_REF (pattern); - TYPE_HAS_CONST_INIT_REF (type) = TYPE_HAS_CONST_INIT_REF (pattern); - TYPE_HAS_DEFAULT_CONSTRUCTOR (type) = TYPE_HAS_DEFAULT_CONSTRUCTOR (pattern); - TYPE_HAS_CONVERSION (type) = TYPE_HAS_CONVERSION (pattern); - TYPE_USES_COMPLEX_INHERITANCE (type) - = TYPE_USES_COMPLEX_INHERITANCE (pattern); - TYPE_USES_MULTIPLE_INHERITANCE (type) - = TYPE_USES_MULTIPLE_INHERITANCE (pattern); - TYPE_USES_VIRTUAL_BASECLASSES (type) - = TYPE_USES_VIRTUAL_BASECLASSES (pattern); - TYPE_PACKED (type) = TYPE_PACKED (pattern); - TYPE_ALIGN (type) = TYPE_ALIGN (pattern); - TYPE_FOR_JAVA (type) = TYPE_FOR_JAVA (pattern); /* For libjava's JArray<T> */ - - /* We must copy the arguments to the permanent obstack since - during the tsubst'ing below they may wind up in the - DECL_TI_ARGS of some instantiated member template. */ - args = copy_to_permanent (args); - - { - tree binfo = TYPE_BINFO (type); - tree pbases = TYPE_BINFO_BASETYPES (pattern); - - if (pbases) - { - tree bases; - int i; - int len = TREE_VEC_LENGTH (pbases); - bases = make_tree_vec (len); - for (i = 0; i < len; ++i) - { - tree elt, basetype; - - TREE_VEC_ELT (bases, i) = elt - = tsubst (TREE_VEC_ELT (pbases, i), args, NULL_TREE); - BINFO_INHERITANCE_CHAIN (elt) = binfo; - - basetype = TREE_TYPE (elt); - - if (! IS_AGGR_TYPE (basetype)) - cp_error - ("base type `%T' of `%T' fails to be a struct or class type", - basetype, type); - else if (TYPE_SIZE (complete_type (basetype)) == NULL_TREE) - cp_error ("base class `%T' of `%T' has incomplete type", - basetype, type); - - /* These are set up in xref_basetypes for normal classes, so - we have to handle them here for template bases. */ - - unshare_base_binfos (elt); - - if (TYPE_USES_VIRTUAL_BASECLASSES (basetype)) - { - TYPE_USES_VIRTUAL_BASECLASSES (type) = 1; - TYPE_USES_COMPLEX_INHERITANCE (type) = 1; - } - TYPE_GETS_NEW (type) |= TYPE_GETS_NEW (basetype); - TYPE_GETS_DELETE (type) |= TYPE_GETS_DELETE (basetype); - } - /* Don't initialize this until the vector is filled out, or - lookups will crash. */ - BINFO_BASETYPES (binfo) = bases; - } - } - - for (t = CLASSTYPE_TAGS (pattern); t; t = TREE_CHAIN (t)) - { - tree tag = TREE_VALUE (t); - tree name = TYPE_IDENTIFIER (tag); - tree newtag; - - newtag = tsubst (tag, args, NULL_TREE); - if (TREE_CODE (newtag) != ENUMERAL_TYPE) - { - if (TYPE_LANG_SPECIFIC (tag) && CLASSTYPE_IS_TEMPLATE (tag)) - /* Unfortunately, lookup_template_class sets - CLASSTYPE_IMPLICIT_INSTANTIATION for a partial - instantiation (i.e., for the type of a member template - class nested within a template class.) This behavior is - required for maybe_process_partial_specialization to work - correctly, but is not accurate in this case; the TAG is not - an instantiation of anything. (The corresponding - TEMPLATE_DECL is an instantiation, but the TYPE is not.) */ - CLASSTYPE_USE_TEMPLATE (newtag) = 0; - - /* Now, we call pushtag to put this NEWTAG into the scope of - TYPE. We first set up the IDENTIFIER_TYPE_VALUE to avoid - pushtag calling push_template_decl. We don't have to do - this for enums because it will already have been done in - tsubst_enum. */ - if (name) - SET_IDENTIFIER_TYPE_VALUE (name, newtag); - pushtag (name, newtag, /*globalize=*/0); - } - } - - /* Don't replace enum constants here. */ - for (t = TYPE_FIELDS (pattern); t; t = TREE_CHAIN (t)) - if (TREE_CODE (t) != CONST_DECL) - { - tree r; - - /* The the file and line for this declaration, to assist in - error message reporting. Since we called push_tinst_level - above, we don't need to restore these. */ - lineno = DECL_SOURCE_LINE (t); - input_filename = DECL_SOURCE_FILE (t); - - r = tsubst (t, args, NULL_TREE); - if (TREE_CODE (r) == VAR_DECL) - { - pending_statics = perm_tree_cons (NULL_TREE, r, pending_statics); - /* Perhaps we should do more of grokfield here. */ - if (DECL_DEFINED_IN_CLASS_P (r)) - /* Set up DECL_INITIAL, since tsubst doesn't. */ - DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args, - NULL_TREE); - start_decl_1 (r); - DECL_IN_AGGR_P (r) = 1; - DECL_EXTERNAL (r) = 1; - cp_finish_decl (r, DECL_INITIAL (r), NULL_TREE, 0, 0); - if (DECL_DEFINED_IN_CLASS_P (r)) - check_static_variable_definition (r, TREE_TYPE (r)); - } - - /* R will have a TREE_CHAIN if and only if it has already been - processed by finish_member_declaration. This can happen - if, for example, it is a TYPE_DECL for a class-scoped - ENUMERAL_TYPE; such a thing will already have been added to - the field list by tsubst_enum above. */ - if (!TREE_CHAIN (r)) - { - set_current_access_from_decl (r); - finish_member_declaration (r); - } - } - - /* Set up the list (TYPE_METHODS) and vector (CLASSTYPE_METHOD_VEC) - for this instantiation. */ - for (t = TYPE_METHODS (pattern); t; t = TREE_CHAIN (t)) - { - tree r = tsubst (t, args, NULL_TREE); - set_current_access_from_decl (r); - finish_member_declaration (r); - } - - /* Construct the DECL_FRIENDLIST for the new class type. */ - typedecl = TYPE_MAIN_DECL (type); - for (t = DECL_FRIENDLIST (TYPE_MAIN_DECL (pattern)); - t != NULL_TREE; - t = TREE_CHAIN (t)) - { - tree friends; - - DECL_FRIENDLIST (typedecl) - = tree_cons (TREE_PURPOSE (t), NULL_TREE, - DECL_FRIENDLIST (typedecl)); - - for (friends = TREE_VALUE (t); - friends != NULL_TREE; - friends = TREE_CHAIN (friends)) - { - if (TREE_PURPOSE (friends) == error_mark_node) - { - TREE_VALUE (DECL_FRIENDLIST (typedecl)) - = tree_cons (error_mark_node, - tsubst_friend_function (TREE_VALUE (friends), - args), - TREE_VALUE (DECL_FRIENDLIST (typedecl))); - } - else - { - TREE_VALUE (DECL_FRIENDLIST (typedecl)) - = tree_cons (tsubst (TREE_PURPOSE (friends), args, NULL_TREE), - NULL_TREE, - TREE_VALUE (DECL_FRIENDLIST (typedecl))); - - } - } - } - - for (t = CLASSTYPE_FRIEND_CLASSES (pattern); - t != NULL_TREE; - t = TREE_CHAIN (t)) - { - tree friend_type = TREE_VALUE (t); - tree new_friend_type; - - if (TREE_CODE (friend_type) == TEMPLATE_DECL) - new_friend_type = tsubst_friend_class (friend_type, args); - else if (uses_template_parms (friend_type)) - new_friend_type = tsubst (friend_type, args, NULL_TREE); - else - /* The call to xref_tag_from_type does injection for friend - classes. */ - new_friend_type = - xref_tag_from_type (friend_type, NULL_TREE, 1); - - - if (TREE_CODE (friend_type) == TEMPLATE_DECL) - /* Trick make_friend_class into realizing that the friend - we're adding is a template, not an ordinary class. It's - important that we use make_friend_class since it will - perform some error-checking and output cross-reference - information. */ - ++processing_template_decl; - - make_friend_class (type, new_friend_type); - - if (TREE_CODE (friend_type) == TEMPLATE_DECL) - --processing_template_decl; - } - - /* This does injection for friend functions. */ - if (!processing_template_decl) - { - t = tsubst (DECL_TEMPLATE_INJECT (template), args, NULL_TREE); - - for (; t; t = TREE_CHAIN (t)) - { - tree d = TREE_VALUE (t); - - if (TREE_CODE (d) == TYPE_DECL) - /* Already injected. */; - else - pushdecl (d); - } - } - - for (t = TYPE_FIELDS (type); t; t = TREE_CHAIN (t)) - if (TREE_CODE (t) == FIELD_DECL) - { - TREE_TYPE (t) = complete_type (TREE_TYPE (t)); - require_complete_type (t); - } - - /* Set the file and line number information to whatever is given for - the class itself. This puts error messages involving generated - implicit functions at a predictable point, and the same point - that would be used for non-template classes. */ - lineno = DECL_SOURCE_LINE (typedecl); - input_filename = DECL_SOURCE_FILE (typedecl); - - unreverse_member_declarations (type); - type = finish_struct_1 (type, 0); - CLASSTYPE_GOT_SEMICOLON (type) = 1; - - /* Clear this now so repo_template_used is happy. */ - TYPE_BEING_DEFINED (type) = 0; - repo_template_used (type); - - popclass (0); - pop_from_top_level (); - pop_tinst_level (); - - end: - pop_momentary (); - - return type; -} - -static int -list_eq (t1, t2) - tree t1, t2; -{ - if (t1 == NULL_TREE) - return t2 == NULL_TREE; - if (t2 == NULL_TREE) - return 0; - /* Don't care if one declares its arg const and the other doesn't -- the - main variant of the arg type is all that matters. */ - if (TYPE_MAIN_VARIANT (TREE_VALUE (t1)) - != TYPE_MAIN_VARIANT (TREE_VALUE (t2))) - return 0; - return list_eq (TREE_CHAIN (t1), TREE_CHAIN (t2)); -} - -/* If arg is a non-type template parameter that does not depend on template - arguments, fold it like we weren't in the body of a template. */ - -static tree -maybe_fold_nontype_arg (arg) - tree arg; -{ - if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't' - && !uses_template_parms (arg)) - { - /* Sometimes, one of the args was an expression involving a - template constant parameter, like N - 1. Now that we've - tsubst'd, we might have something like 2 - 1. This will - confuse lookup_template_class, so we do constant folding - here. We have to unset processing_template_decl, to - fool build_expr_from_tree() into building an actual - tree. */ - - int saved_processing_template_decl = processing_template_decl; - processing_template_decl = 0; - arg = fold (build_expr_from_tree (arg)); - processing_template_decl = saved_processing_template_decl; - } - return arg; -} - -/* Return the TREE_VEC with the arguments for the innermost template header, - where ARGS is either that or the VEC of VECs for all the - arguments. */ - -tree -innermost_args (args) - tree args; -{ - return TMPL_ARGS_LEVEL (args, TMPL_ARGS_DEPTH (args)); -} - -/* Substitute ARGS into the vector of template arguments T. */ - -static tree -tsubst_template_arg_vector (t, args) - tree t; - tree args; -{ - int len = TREE_VEC_LENGTH (t), need_new = 0, i; - tree *elts = (tree *) alloca (len * sizeof (tree)); - - bzero ((char *) elts, len * sizeof (tree)); - - for (i = 0; i < len; i++) - { - if (TREE_VEC_ELT (t, i) != NULL_TREE - && TREE_CODE (TREE_VEC_ELT (t, i)) == TREE_VEC) - elts[i] = tsubst_template_arg_vector (TREE_VEC_ELT (t, i), args); - else - elts[i] = maybe_fold_nontype_arg - (tsubst_expr (TREE_VEC_ELT (t, i), args, NULL_TREE)); - - if (elts[i] != TREE_VEC_ELT (t, i)) - need_new = 1; - } - - if (!need_new) - return t; - - t = make_temp_vec (len); - for (i = 0; i < len; i++) - TREE_VEC_ELT (t, i) = elts[i]; - - return t; -} - -/* Return the result of substituting ARGS into the template parameters - given by PARMS. If there are m levels of ARGS and m + n levels of - PARMS, then the result will contain n levels of PARMS. For - example, if PARMS is `template <class T> template <class U> - template <T*, U, class V>' and ARGS is {{int}, {double}} then the - result will be `template <int*, double, class V>'. */ - -static tree -tsubst_template_parms (parms, args) - tree parms; - tree args; -{ - tree r; - tree* new_parms = &r; - - for (new_parms = &r; - TMPL_PARMS_DEPTH (parms) > TMPL_ARGS_DEPTH (args); - new_parms = &(TREE_CHAIN (*new_parms)), - parms = TREE_CHAIN (parms)) - { - tree new_vec = - make_tree_vec (TREE_VEC_LENGTH (TREE_VALUE (parms))); - int i; - - for (i = 0; i < TREE_VEC_LENGTH (new_vec); ++i) - { - tree default_value = - TREE_PURPOSE (TREE_VEC_ELT (TREE_VALUE (parms), i)); - tree parm_decl = - TREE_VALUE (TREE_VEC_ELT (TREE_VALUE (parms), i)); - - TREE_VEC_ELT (new_vec, i) - = build_tree_list (tsubst (default_value, args, NULL_TREE), - tsubst (parm_decl, args, NULL_TREE)); - - } - - *new_parms = - tree_cons (build_int_2 (0, (TMPL_PARMS_DEPTH (parms) - - TMPL_ARGS_DEPTH (args))), - new_vec, NULL_TREE); - } - - return r; -} - -/* Substitute the ARGS into the indicated aggregate (or enumeration) - type T. If T is not an aggregate or enumeration type, it is - handled as if by tsubst. IN_DECL is as for tsubst. If - ENTERING_SCOPE is non-zero, T is the context for a template which - we are presently tsubst'ing. Return the subsituted value. */ - -static tree -tsubst_aggr_type (t, args, in_decl, entering_scope) - tree t; - tree args; - tree in_decl; - int entering_scope; -{ - if (t == NULL_TREE) - return NULL_TREE; - - switch (TREE_CODE (t)) - { - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (t)) - { - tree r = build_ptrmemfunc_type - (tsubst (TYPE_PTRMEMFUNC_FN_TYPE (t), args, in_decl)); - return cp_build_qualified_type (r, TYPE_QUALS (t)); - } - - /* else fall through */ - case ENUMERAL_TYPE: - case UNION_TYPE: - if (TYPE_TEMPLATE_INFO (t)) - { - tree argvec; - tree context; - tree r; - - /* First, determine the context for the type we are looking - up. */ - if (TYPE_CONTEXT (t) != NULL_TREE) - context = tsubst_aggr_type (TYPE_CONTEXT (t), args, - in_decl, /*entering_scope=*/1); - else - context = NULL_TREE; - - /* Then, figure out what arguments are appropriate for the - type we are trying to find. For example, given: - - template <class T> struct S; - template <class T, class U> void f(T, U) { S<U> su; } - - and supposing that we are instantiating f<int, double>, - then our ARGS will be {int, double}, but, when looking up - S we only want {double}. */ - push_momentary (); - argvec = tsubst_template_arg_vector (TYPE_TI_ARGS (t), args); - - r = lookup_template_class (t, argvec, in_decl, context, - entering_scope); - pop_momentary (); - - return cp_build_qualified_type (r, TYPE_QUALS (t)); - } - else - /* This is not a template type, so there's nothing to do. */ - return t; - - default: - return tsubst (t, args, in_decl); - } -} - -/* Substitute the ARGS into the T, which is a _DECL. TYPE is the - (already computed) substitution of ARGS into TREE_TYPE (T), if - appropriate. Return the result of the substitution. IN_DECL is as - for tsubst. */ - -static tree -tsubst_decl (t, args, type, in_decl) - tree t; - tree args; - tree type; - tree in_decl; -{ - int saved_lineno; - char* saved_filename; - tree r = NULL_TREE; - - /* Set the filename and linenumber to improve error-reporting. */ - saved_lineno = lineno; - saved_filename = input_filename; - lineno = DECL_SOURCE_LINE (t); - input_filename = DECL_SOURCE_FILE (t); - - switch (TREE_CODE (t)) - { - case TEMPLATE_DECL: - { - /* We can get here when processing a member template function - of a template class. */ - tree decl = DECL_TEMPLATE_RESULT (t); - tree spec; - int is_template_template_parm = DECL_TEMPLATE_TEMPLATE_PARM_P (t); - - if (!is_template_template_parm) - { - /* We might already have an instance of this template. - The ARGS are for the surrounding class type, so the - full args contain the tsubst'd args for the context, - plus the innermost args from the template decl. */ - tree tmpl_args = DECL_CLASS_TEMPLATE_P (t) - ? CLASSTYPE_TI_ARGS (TREE_TYPE (t)) - : DECL_TI_ARGS (DECL_RESULT (t)); - tree full_args; - - push_momentary (); - full_args = tsubst_template_arg_vector (tmpl_args, args); - - /* tsubst_template_arg_vector doesn't copy the vector if - nothing changed. But, *something* should have - changed. */ - my_friendly_assert (full_args != tmpl_args, 0); - - spec = retrieve_specialization (t, full_args); - pop_momentary (); - if (spec != NULL_TREE) - { - r = spec; - break; - } - } - - /* Make a new template decl. It will be similar to the - original, but will record the current template arguments. - We also create a new function declaration, which is just - like the old one, but points to this new template, rather - than the old one. */ - r = copy_node (t); - copy_lang_decl (r); - my_friendly_assert (DECL_LANG_SPECIFIC (r) != 0, 0); - TREE_CHAIN (r) = NULL_TREE; - - if (is_template_template_parm) - { - tree new_decl = tsubst (decl, args, in_decl); - DECL_RESULT (r) = new_decl; - TREE_TYPE (r) = TREE_TYPE (new_decl); - break; - } - - DECL_CONTEXT (r) - = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl, - /*entering_scope=*/1); - DECL_CLASS_CONTEXT (r) - = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args, in_decl, - /*entering_scope=*/1); - DECL_TEMPLATE_INFO (r) = build_tree_list (t, args); - - if (TREE_CODE (decl) == TYPE_DECL) - { - tree new_type = tsubst (TREE_TYPE (t), args, in_decl); - TREE_TYPE (r) = new_type; - CLASSTYPE_TI_TEMPLATE (new_type) = r; - DECL_RESULT (r) = TYPE_MAIN_DECL (new_type); - DECL_TI_ARGS (r) = CLASSTYPE_TI_ARGS (new_type); - } - else - { - tree new_decl = tsubst (decl, args, in_decl); - DECL_RESULT (r) = new_decl; - DECL_TI_TEMPLATE (new_decl) = r; - TREE_TYPE (r) = TREE_TYPE (new_decl); - DECL_TI_ARGS (r) = DECL_TI_ARGS (new_decl); - } - - SET_DECL_IMPLICIT_INSTANTIATION (r); - DECL_TEMPLATE_INSTANTIATIONS (r) = NULL_TREE; - DECL_TEMPLATE_SPECIALIZATIONS (r) = NULL_TREE; - - /* The template parameters for this new template are all the - template parameters for the old template, except the - outermost level of parameters. */ - DECL_TEMPLATE_PARMS (r) - = tsubst_template_parms (DECL_TEMPLATE_PARMS (t), args); - - if (PRIMARY_TEMPLATE_P (t)) - DECL_PRIMARY_TEMPLATE (r) = r; - - /* We don't partially instantiate partial specializations. */ - if (TREE_CODE (decl) == TYPE_DECL) - break; - - for (spec = DECL_TEMPLATE_SPECIALIZATIONS (t); - spec != NULL_TREE; - spec = TREE_CHAIN (spec)) - { - /* It helps to consider example here. Consider: - - template <class T> - struct S { - template <class U> - void f(U u); - - template <> - void f(T* t) {} - }; - - Now, for example, we are instantiating S<int>::f(U u). - We want to make a template: - - template <class U> - void S<int>::f(U); - - It will have a specialization, for the case U = int*, of - the form: - - template <> - void S<int>::f<int*>(int*); - - This specialization will be an instantiation of - the specialization given in the declaration of S, with - argument list int*. */ - - tree fn = TREE_VALUE (spec); - tree spec_args; - tree new_fn; - - if (!DECL_TEMPLATE_SPECIALIZATION (fn)) - /* Instantiations are on the same list, but they're of - no concern to us. */ - continue; - - if (TREE_CODE (fn) != TEMPLATE_DECL) - /* A full specialization. There's no need to record - that here. */ - continue; - - spec_args = tsubst (DECL_TI_ARGS (fn), args, in_decl); - new_fn = tsubst (DECL_RESULT (most_general_template (fn)), - spec_args, in_decl); - DECL_TI_TEMPLATE (new_fn) = fn; - register_specialization (new_fn, r, - innermost_args (spec_args)); - } - - /* Record this partial instantiation. */ - register_specialization (r, t, - DECL_TI_ARGS (DECL_RESULT (r))); - - } - break; - - case FUNCTION_DECL: - { - tree ctx; - tree argvec = NULL_TREE; - tree gen_tmpl; - int member; - int args_depth; - int parms_depth; - - /* Nobody should be tsubst'ing into non-template functions. */ - my_friendly_assert (DECL_TEMPLATE_INFO (t) != NULL_TREE, 0); - - if (TREE_CODE (DECL_TI_TEMPLATE (t)) == TEMPLATE_DECL) - { - tree spec; - - /* Allocate template arguments on the momentary obstack, - in case we don't need to keep them. */ - push_momentary (); - - /* Calculate the most general template of which R is a - specialization, and the complete set of arguments used to - specialize R. */ - gen_tmpl = most_general_template (DECL_TI_TEMPLATE (t)); - argvec - = tsubst_template_arg_vector (DECL_TI_ARGS - (DECL_TEMPLATE_RESULT (gen_tmpl)), - args); - - /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, argvec); - - if (spec) - { - r = spec; - pop_momentary (); - break; - } - - /* We're going to need to keep the ARGVEC, so we copy it - here. */ - argvec = copy_to_permanent (argvec); - pop_momentary (); - - /* Here, we deal with the peculiar case: - - template <class T> struct S { - template <class U> friend void f(); - }; - template <class U> friend void f() {} - template S<int>; - template void f<double>(); - - Here, the ARGS for the instantiation of will be {int, - double}. But, we only need as many ARGS as there are - levels of template parameters in CODE_PATTERN. We are - careful not to get fooled into reducing the ARGS in - situations like: - - template <class T> struct S { template <class U> void f(U); } - template <class T> template <> void S<T>::f(int) {} - - which we can spot because the pattern will be a - specialization in this case. */ - args_depth = TMPL_ARGS_DEPTH (args); - parms_depth = - TMPL_PARMS_DEPTH (DECL_TEMPLATE_PARMS (DECL_TI_TEMPLATE (t))); - if (args_depth > parms_depth - && !DECL_TEMPLATE_SPECIALIZATION (t)) - { - my_friendly_assert (DECL_FRIEND_P (t), 0); - - if (parms_depth > 1) - { - int i; - - args = make_temp_vec (parms_depth); - for (i = 0; i < parms_depth; ++i) - TREE_VEC_ELT (args, i) = - TREE_VEC_ELT (args, i + (args_depth - parms_depth)); - } - else - args = TREE_VEC_ELT (args, args_depth - parms_depth); - } - } - else - { - /* This special case arises when we have something like this: - - template <class T> struct S { - friend void f<int>(int, double); - }; - - Here, the DECL_TI_TEMPLATE for the friend declaration - will be a LOOKUP_EXPR or an IDENTIFIER_NODE. We are - being called from tsubst_friend_function, and we want - only to create a new decl (R) with appropriate types so - that we can call determine_specialization. */ - my_friendly_assert ((TREE_CODE (DECL_TI_TEMPLATE (t)) - == LOOKUP_EXPR) - || (TREE_CODE (DECL_TI_TEMPLATE (t)) - == IDENTIFIER_NODE), 0); - gen_tmpl = NULL_TREE; - } - - if (DECL_CLASS_SCOPE_P (t)) - { - if (DECL_NAME (t) == constructor_name (DECL_CONTEXT (t))) - member = 2; - else - member = 1; - ctx = tsubst_aggr_type (DECL_CLASS_CONTEXT (t), args, t, - /*entering_scope=*/1); - } - else - { - member = 0; - ctx = NULL_TREE; - } - type = tsubst (type, args, in_decl); - - /* We do NOT check for matching decls pushed separately at this - point, as they may not represent instantiations of this - template, and in any case are considered separate under the - discrete model. Instead, see add_maybe_template. */ - - r = copy_node (t); - copy_lang_decl (r); - DECL_USE_TEMPLATE (r) = 0; - TREE_TYPE (r) = type; - - DECL_CONTEXT (r) - = tsubst_aggr_type (DECL_CONTEXT (t), args, t, /*entering_scope=*/1); - DECL_CLASS_CONTEXT (r) = ctx; - - if (member && IDENTIFIER_TYPENAME_P (DECL_NAME (r))) - /* Type-conversion operator. Reconstruct the name, in - case it's the name of one of the template's parameters. */ - DECL_NAME (r) = build_typename_overload (TREE_TYPE (type)); - - DECL_ARGUMENTS (r) = tsubst (DECL_ARGUMENTS (t), args, t); - DECL_MAIN_VARIANT (r) = r; - DECL_RESULT (r) = NULL_TREE; - - TREE_STATIC (r) = 0; - TREE_PUBLIC (r) = TREE_PUBLIC (t); - DECL_EXTERNAL (r) = 1; - DECL_INTERFACE_KNOWN (r) = 0; - DECL_DEFER_OUTPUT (r) = 0; - TREE_CHAIN (r) = NULL_TREE; - DECL_PENDING_INLINE_INFO (r) = 0; - TREE_USED (r) = 0; - - /* Set up the DECL_TEMPLATE_INFO for R and compute its mangled - name. There's no need to do this in the special friend - case mentioned above where GEN_TMPL is NULL. */ - if (gen_tmpl) - { - /* The ARGVEC was built on the momentary obstack. Make it - permanent now. */ - argvec = copy_to_permanent (argvec); - DECL_TEMPLATE_INFO (r) - = perm_tree_cons (gen_tmpl, argvec, NULL_TREE); - SET_DECL_IMPLICIT_INSTANTIATION (r); - register_specialization (r, gen_tmpl, argvec); - - /* Set the mangled name for R. */ - if (DECL_DESTRUCTOR_P (t)) - DECL_ASSEMBLER_NAME (r) = build_destructor_name (ctx); - else - { - /* Instantiations of template functions must be mangled - specially, in order to conform to 14.5.5.1 - [temp.over.link]. */ - tree tmpl = DECL_TI_TEMPLATE (t); - - /* TMPL will be NULL if this is a specialization of a - member function of a template class. */ - if (name_mangling_version < 1 - || tmpl == NULL_TREE - || (member && !is_member_template (tmpl) - && !DECL_TEMPLATE_INFO (tmpl))) - set_mangled_name_for_decl (r); - else - set_mangled_name_for_template_decl (r); - } - - DECL_RTL (r) = 0; - make_decl_rtl (r, NULL_PTR, 1); - - /* Like grokfndecl. If we don't do this, pushdecl will - mess up our TREE_CHAIN because it doesn't find a - previous decl. Sigh. */ - if (member - && ! uses_template_parms (r) - && (IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r)) - == NULL_TREE)) - SET_IDENTIFIER_GLOBAL_VALUE (DECL_ASSEMBLER_NAME (r), r); - } - - if (DECL_CONSTRUCTOR_P (r)) - { - maybe_retrofit_in_chrg (r); - grok_ctor_properties (ctx, r); - } - if (IDENTIFIER_OPNAME_P (DECL_NAME (r))) - grok_op_properties (r, DECL_VIRTUAL_P (r), DECL_FRIEND_P (r)); - } - break; - - case PARM_DECL: - { - r = copy_node (t); - TREE_TYPE (r) = type; - if (TREE_CODE (DECL_INITIAL (r)) != TEMPLATE_PARM_INDEX) - DECL_INITIAL (r) = TREE_TYPE (r); - else - DECL_INITIAL (r) = tsubst (DECL_INITIAL (r), args, in_decl); - - DECL_CONTEXT (r) = NULL_TREE; -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && TYPE_PRECISION (type) < TYPE_PRECISION (integer_type_node)) - DECL_ARG_TYPE (r) = integer_type_node; -#endif - if (TREE_CHAIN (t)) - TREE_CHAIN (r) = tsubst (TREE_CHAIN (t), args, TREE_CHAIN (t)); - } - break; - - case FIELD_DECL: - { - r = copy_node (t); - TREE_TYPE (r) = type; - copy_lang_decl (r); -#if 0 - DECL_FIELD_CONTEXT (r) = tsubst (DECL_FIELD_CONTEXT (t), args, in_decl); -#endif - DECL_INITIAL (r) = tsubst_expr (DECL_INITIAL (t), args, in_decl); - TREE_CHAIN (r) = NULL_TREE; - if (TREE_CODE (type) == VOID_TYPE) - cp_error_at ("instantiation of `%D' as type void", r); - } - break; - - case USING_DECL: - { - r = copy_node (t); - DECL_INITIAL (r) - = tsubst_copy (DECL_INITIAL (t), args, in_decl); - TREE_CHAIN (r) = NULL_TREE; - } - break; - - case VAR_DECL: - { - tree argvec; - tree gen_tmpl; - tree spec; - tree tmpl; - tree ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl, - /*entering_scope=*/1); - - /* Nobody should be tsubst'ing into non-template variables. */ - my_friendly_assert (DECL_LANG_SPECIFIC (t) - && DECL_TEMPLATE_INFO (t) != NULL_TREE, 0); - - /* Check to see if we already have this specialization. */ - tmpl = DECL_TI_TEMPLATE (t); - gen_tmpl = most_general_template (tmpl); - argvec = tsubst (DECL_TI_ARGS (t), args, in_decl); - spec = retrieve_specialization (gen_tmpl, argvec); - - if (spec) - { - r = spec; - break; - } - - r = copy_node (t); - TREE_TYPE (r) = type; - DECL_CONTEXT (r) = ctx; - if (TREE_STATIC (r)) - DECL_ASSEMBLER_NAME (r) - = build_static_name (DECL_CONTEXT (r), DECL_NAME (r)); - - /* Don't try to expand the initializer until someone tries to use - this variable; otherwise we run into circular dependencies. */ - DECL_INITIAL (r) = NULL_TREE; - DECL_RTL (r) = 0; - DECL_SIZE (r) = 0; - copy_lang_decl (r); - DECL_CLASS_CONTEXT (r) = DECL_CONTEXT (r); - - DECL_TEMPLATE_INFO (r) = perm_tree_cons (tmpl, argvec, NULL_TREE); - SET_DECL_IMPLICIT_INSTANTIATION (r); - register_specialization (r, gen_tmpl, argvec); - - TREE_CHAIN (r) = NULL_TREE; - if (TREE_CODE (type) == VOID_TYPE) - cp_error_at ("instantiation of `%D' as type void", r); - } - break; - - case TYPE_DECL: - if (t == TYPE_NAME (TREE_TYPE (t))) - r = TYPE_NAME (type); - else - { - r = copy_node (t); - TREE_TYPE (r) = type; - DECL_CONTEXT (r) = current_class_type; - TREE_CHAIN (r) = NULL_TREE; - } - break; - - default: - my_friendly_abort (0); - } - - /* Restore the file and line information. */ - lineno = saved_lineno; - input_filename = saved_filename; - - return r; -} - -/* Substitue into the ARG_TYPES of a function type. */ - -static tree -tsubst_arg_types (arg_types, args, in_decl) - tree arg_types; - tree args; - tree in_decl; -{ - tree remaining_arg_types; - tree type; - - if (!arg_types || arg_types == void_list_node) - return arg_types; - - remaining_arg_types = tsubst_arg_types (TREE_CHAIN (arg_types), - args, in_decl); - - /* We use TYPE_MAIN_VARIANT is because top-level qualifiers don't - matter on function types. */ - type = TYPE_MAIN_VARIANT (type_decays_to - (tsubst (TREE_VALUE (arg_types), - args, in_decl))); - - /* Note that we do not substitute into default arguments here. The - standard mandates that they be instantiated only when needed, - which is done in build_over_call. */ - return hash_tree_cons_simple (TREE_PURPOSE (arg_types), type, - remaining_arg_types); - -} - -/* Substitute into the PARMS of a call-declarator. */ - -static tree -tsubst_call_declarator_parms (parms, args, in_decl) - tree parms; - tree args; - tree in_decl; -{ - tree new_parms; - tree type; - tree defarg; - - if (!parms || parms == void_list_node) - return parms; - - new_parms = tsubst_call_declarator_parms (TREE_CHAIN (parms), - args, in_decl); - - /* Figure out the type of this parameter. */ - type = tsubst (TREE_VALUE (parms), args, in_decl); - - /* Figure out the default argument as well. Note that we use - tsubst_copy since the default argument is really an - expression. */ - defarg = tsubst_expr (TREE_PURPOSE (parms), args, in_decl); - - /* Chain this parameter on to the front of those we have already - processed. We don't use hash_tree_cons because that function - doesn't check TREE_PARMLIST. */ - new_parms = tree_cons (defarg, type, new_parms); - - /* And note that these are parameters. */ - TREE_PARMLIST (new_parms) = 1; - - return new_parms; -} - -/* Take the tree structure T and replace template parameters used therein - with the argument vector ARGS. IN_DECL is an associated decl for - diagnostics. - - tsubst is used for dealing with types, decls and the like; for - expressions, use tsubst_expr or tsubst_copy. */ - -tree -tsubst (t, args, in_decl) - tree t, args; - tree in_decl; -{ - tree type, r; - - if (t == NULL_TREE || t == error_mark_node - || t == integer_type_node - || t == void_type_node - || t == char_type_node - || TREE_CODE (t) == NAMESPACE_DECL) - return t; - - if (TREE_CODE (t) == IDENTIFIER_NODE) - type = IDENTIFIER_TYPE_VALUE (t); - else - type = TREE_TYPE (t); - if (type == unknown_type_node) - my_friendly_abort (42); - - if (type && TREE_CODE (t) != FUNCTION_DECL - && TREE_CODE (t) != TYPENAME_TYPE - && TREE_CODE (t) != TEMPLATE_DECL - && TREE_CODE (t) != IDENTIFIER_NODE) - type = tsubst (type, args, in_decl); - - if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd') - return tsubst_decl (t, args, type, in_decl); - - switch (TREE_CODE (t)) - { - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - return tsubst_aggr_type (t, args, in_decl, /*entering_scope=*/0); - - case ERROR_MARK: - case IDENTIFIER_NODE: - case OP_IDENTIFIER: - case VOID_TYPE: - case REAL_TYPE: - case COMPLEX_TYPE: - case BOOLEAN_TYPE: - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - return t; - - case INTEGER_TYPE: - if (t == integer_type_node) - return t; - - if (TREE_CODE (TYPE_MIN_VALUE (t)) == INTEGER_CST - && TREE_CODE (TYPE_MAX_VALUE (t)) == INTEGER_CST) - return t; - - { - tree max = TREE_OPERAND (TYPE_MAX_VALUE (t), 0); - - max = tsubst_expr (max, args, in_decl); - if (processing_template_decl) - { - tree itype = make_node (INTEGER_TYPE); - TYPE_MIN_VALUE (itype) = size_zero_node; - TYPE_MAX_VALUE (itype) = build_min (MINUS_EXPR, sizetype, max, - integer_one_node); - return itype; - } - - if (pedantic && integer_zerop (max)) - pedwarn ("creating array with size zero"); - else if (INT_CST_LT (max, integer_zero_node)) - { - cp_error ("creating array with size `%E'", max); - max = integer_one_node; - } - - max = fold (build_binary_op (MINUS_EXPR, max, integer_one_node, 1)); - if (!TREE_PERMANENT (max) && !allocation_temporary_p ()) - max = copy_to_permanent (max); - return build_index_type (max); - } - - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - case TEMPLATE_PARM_INDEX: - { - int idx; - int level; - int levels; - - r = NULL_TREE; - - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM - || TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM) - { - idx = TEMPLATE_TYPE_IDX (t); - level = TEMPLATE_TYPE_LEVEL (t); - } - else - { - idx = TEMPLATE_PARM_IDX (t); - level = TEMPLATE_PARM_LEVEL (t); - } - - if (TREE_VEC_LENGTH (args) > 0) - { - tree arg = NULL_TREE; - - levels = TMPL_ARGS_DEPTH (args); - if (level <= levels) - arg = TMPL_ARG (args, level, idx); - - if (arg == error_mark_node) - return error_mark_node; - else if (arg != NULL_TREE) - { - if (TREE_CODE (t) == TEMPLATE_TYPE_PARM) - { - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (arg)) - == 't', 0); - return cp_build_qualified_type - (arg, CP_TYPE_QUALS (arg) | CP_TYPE_QUALS (t)); - } - else if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM) - { - if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)) - { - /* We are processing a type constructed from - a template template parameter */ - tree argvec = tsubst (TYPE_TI_ARGS (t), - args, in_decl); - - /* We can get a TEMPLATE_TEMPLATE_PARM here when - we are resolving nested-types in the signature of - a member function templates. - Otherwise ARG is a TEMPLATE_DECL and is the real - template to be instantiated. */ - if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) - arg = TYPE_NAME (arg); - - r = lookup_template_class (DECL_NAME (arg), - argvec, in_decl, - DECL_CONTEXT (arg), - /*entering_scope=*/0); - return cp_build_qualified_type (r, TYPE_QUALS (t)); - } - else - /* We are processing a template argument list. */ - return arg; - } - else - return arg; - } - } - else - my_friendly_abort (981018); - - if (level == 1) - /* This can happen during the attempted tsubst'ing in - unify. This means that we don't yet have any information - about the template parameter in question. */ - return t; - - /* If we get here, we must have been looking at a parm for a - more deeply nested template. Make a new version of this - template parameter, but with a lower level. */ - switch (TREE_CODE (t)) - { - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - r = copy_node (t); - TEMPLATE_TYPE_PARM_INDEX (r) - = reduce_template_parm_level (TEMPLATE_TYPE_PARM_INDEX (t), - r, levels); - TYPE_STUB_DECL (r) = TYPE_NAME (r) = TEMPLATE_TYPE_DECL (r); - TYPE_MAIN_VARIANT (r) = r; - TYPE_POINTER_TO (r) = NULL_TREE; - TYPE_REFERENCE_TO (r) = NULL_TREE; - - if (TREE_CODE (t) == TEMPLATE_TEMPLATE_PARM - && TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t)) - { - tree argvec = tsubst (TYPE_TI_ARGS (t), args, in_decl); - TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (r) - = perm_tree_cons (TYPE_NAME (t), argvec, NULL_TREE); - } - break; - - case TEMPLATE_PARM_INDEX: - r = reduce_template_parm_level (t, type, levels); - break; - - default: - my_friendly_abort (0); - } - - return r; - } - - case TREE_LIST: - { - tree purpose, value, chain, result; - int via_public, via_virtual, via_protected; - - if (t == void_list_node) - return t; - - via_public = TREE_VIA_PUBLIC (t); - via_protected = TREE_VIA_PROTECTED (t); - via_virtual = TREE_VIA_VIRTUAL (t); - - purpose = TREE_PURPOSE (t); - if (purpose) - purpose = tsubst (purpose, args, in_decl); - value = TREE_VALUE (t); - if (value) - value = tsubst (value, args, in_decl); - chain = TREE_CHAIN (t); - if (chain && chain != void_type_node) - chain = tsubst (chain, args, in_decl); - if (purpose == TREE_PURPOSE (t) - && value == TREE_VALUE (t) - && chain == TREE_CHAIN (t)) - return t; - result = hash_tree_cons (via_public, via_virtual, via_protected, - purpose, value, chain); - TREE_PARMLIST (result) = TREE_PARMLIST (t); - return result; - } - case TREE_VEC: - if (type != NULL_TREE) - { - /* A binfo node. We always need to make a copy, of the node - itself and of its BINFO_BASETYPES. */ - - t = copy_node (t); - - /* Make sure type isn't a typedef copy. */ - type = BINFO_TYPE (TYPE_BINFO (type)); - - TREE_TYPE (t) = complete_type (type); - if (IS_AGGR_TYPE (type)) - { - BINFO_VTABLE (t) = TYPE_BINFO_VTABLE (type); - BINFO_VIRTUALS (t) = TYPE_BINFO_VIRTUALS (type); - if (TYPE_BINFO_BASETYPES (type) != NULL_TREE) - BINFO_BASETYPES (t) = copy_node (TYPE_BINFO_BASETYPES (type)); - } - return t; - } - - /* Otherwise, a vector of template arguments. */ - return tsubst_template_arg_vector (t, args); - - case POINTER_TYPE: - case REFERENCE_TYPE: - { - enum tree_code code; - - if (type == TREE_TYPE (t)) - return t; - - code = TREE_CODE (t); - if (TREE_CODE (type) == REFERENCE_TYPE - || (code == REFERENCE_TYPE && TREE_CODE (type) == VOID_TYPE)) - { - static int last_line = 0; - static char* last_file = 0; - - /* We keep track of the last time we issued this error - message to avoid spewing a ton of messages during a - single bad template instantiation. */ - if (last_line != lineno || - last_file != input_filename) - { - if (TREE_CODE (type) == VOID_TYPE) - cp_error ("forming reference to void"); - else - cp_error ("forming %s to reference type `%T'", - (code == POINTER_TYPE) ? "pointer" : "reference", - type); - last_line = lineno; - last_file = input_filename; - } - - /* Use the underlying type in an attempt at error - recovery; maybe the user meant vector<int> and wrote - vector<int&>, or some such. */ - if (code == REFERENCE_TYPE) - r = type; - else - r = build_pointer_type (TREE_TYPE (type)); - } - else if (code == POINTER_TYPE) - r = build_pointer_type (type); - else - r = build_reference_type (type); - r = cp_build_qualified_type (r, TYPE_QUALS (t)); - - /* Will this ever be needed for TYPE_..._TO values? */ - layout_type (r); - return r; - } - case OFFSET_TYPE: - { - r = tsubst (TYPE_OFFSET_BASETYPE (t), args, in_decl); - if (! IS_AGGR_TYPE (r)) - cp_error ("creating pointer to member of non-class type `%T'", r); - return build_offset_type (r, type); - } - case FUNCTION_TYPE: - case METHOD_TYPE: - { - tree arg_types; - tree raises; - tree fntype; - - /* The TYPE_CONTEXT is not used for function/method types. */ - my_friendly_assert (TYPE_CONTEXT (t) == NULL_TREE, 0); - - /* Substitue the argument types. */ - arg_types = tsubst_arg_types (TYPE_ARG_TYPES (t), args, in_decl); - - /* Construct a new type node and return it. */ - if (TREE_CODE (t) == FUNCTION_TYPE) - fntype = build_function_type (type, arg_types); - else - { - r = TREE_TYPE (TREE_VALUE (arg_types)); - if (! IS_AGGR_TYPE (r)) - cp_error ("creating pointer to member function of non-class type `%T'", - r); - - fntype = build_cplus_method_type (r, type, TREE_CHAIN (arg_types)); - } - fntype = build_qualified_type (fntype, TYPE_QUALS (t)); - - /* Substitue the exception specification. */ - raises = TYPE_RAISES_EXCEPTIONS (t); - if (raises) - { - raises = tsubst (raises, args, in_decl); - fntype = build_exception_variant (fntype, raises); - } - return fntype; - } - case ARRAY_TYPE: - { - tree domain = tsubst (TYPE_DOMAIN (t), args, in_decl); - if (type == TREE_TYPE (t) && domain == TYPE_DOMAIN (t)) - return t; - - /* These checks should match the ones in grokdeclarator. */ - if (TREE_CODE (type) == VOID_TYPE) - { - cp_error ("creating array of void"); - type = build_pointer_type (type); - } - else if (TREE_CODE (type) == FUNCTION_TYPE) - { - cp_error ("creating array of functions `%T'", type); - type = build_pointer_type (type); - } - else if (TREE_CODE (type) == REFERENCE_TYPE) - { - cp_error ("creating array of references `%T'", type); - type = TREE_TYPE (type); - } - - r = build_cplus_array_type (type, domain); - return r; - } - - case PLUS_EXPR: - case MINUS_EXPR: - return fold (build (TREE_CODE (t), TREE_TYPE (t), - tsubst (TREE_OPERAND (t, 0), args, in_decl), - tsubst (TREE_OPERAND (t, 1), args, in_decl))); - - case NEGATE_EXPR: - case NOP_EXPR: - return fold (build1 (TREE_CODE (t), TREE_TYPE (t), - tsubst (TREE_OPERAND (t, 0), args, in_decl))); - - case TYPENAME_TYPE: - { - tree ctx = tsubst_aggr_type (TYPE_CONTEXT (t), args, in_decl, - /*entering_scope=*/1); - tree f = tsubst_copy (TYPENAME_TYPE_FULLNAME (t), args, in_decl); - - /* Normally, make_typename_type does not require that the CTX - have complete type in order to allow things like: - - template <class T> struct S { typename S<T>::X Y; }; - - But, such constructs have already been resolved by this - point, so here CTX really should have complete type, unless - it's a partial instantiation. */ - if (!uses_template_parms (ctx) - && !TYPE_BEING_DEFINED (ctx) - && !complete_type_or_else (ctx)) - return error_mark_node; - - f = make_typename_type (ctx, f); - return cp_build_qualified_type (f, - CP_TYPE_QUALS (f) - | CP_TYPE_QUALS (t)); - } - - case INDIRECT_REF: - return make_pointer_declarator - (type, tsubst (TREE_OPERAND (t, 0), args, in_decl)); - - case ADDR_EXPR: - return make_reference_declarator - (type, tsubst (TREE_OPERAND (t, 0), args, in_decl)); - - case ARRAY_REF: - return build_parse_node - (ARRAY_REF, tsubst (TREE_OPERAND (t, 0), args, in_decl), - tsubst_expr (TREE_OPERAND (t, 1), args, in_decl)); - - case CALL_EXPR: - return make_call_declarator - (tsubst (TREE_OPERAND (t, 0), args, in_decl), - tsubst_call_declarator_parms (TREE_OPERAND (t, 1), args, in_decl), - TREE_OPERAND (t, 2), - tsubst (TREE_TYPE (t), args, in_decl)); - - case SCOPE_REF: - return build_parse_node - (TREE_CODE (t), tsubst (TREE_OPERAND (t, 0), args, in_decl), - tsubst (TREE_OPERAND (t, 1), args, in_decl)); - - case TYPEOF_TYPE: - return TREE_TYPE (tsubst_expr (TYPE_FIELDS (t), args, in_decl)); - - default: - sorry ("use of `%s' in template", - tree_code_name [(int) TREE_CODE (t)]); - return error_mark_node; - } -} - -void -do_pushlevel () -{ - emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); -} - -tree -do_poplevel () -{ - tree t; - int saved_warn_unused = 0; - - if (processing_template_decl) - { - saved_warn_unused = warn_unused; - warn_unused = 0; - } - expand_end_bindings (getdecls (), kept_level_p (), 0); - if (processing_template_decl) - warn_unused = saved_warn_unused; - t = poplevel (kept_level_p (), 1, 0); - pop_momentary (); - return t; -} - -/* Like tsubst, but deals with expressions. This function just replaces - template parms; to finish processing the resultant expression, use - tsubst_expr. */ - -tree -tsubst_copy (t, args, in_decl) - tree t, args; - tree in_decl; -{ - enum tree_code code; - tree r; - - if (t == NULL_TREE || t == error_mark_node) - return t; - - code = TREE_CODE (t); - - switch (code) - { - case PARM_DECL: - return do_identifier (DECL_NAME (t), 0, NULL_TREE); - - case CONST_DECL: - { - tree enum_type; - tree v; - - if (!DECL_CONTEXT (t)) - /* This is a global enumeration constant. */ - return t; - - /* Unfortunately, we cannot just call lookup_name here. - Consider: - - template <int I> int f() { - enum E { a = I }; - struct S { void g() { E e = a; } }; - }; - - When we instantiate f<7>::S::g(), say, lookup_name is not - clever enough to find f<7>::a. */ - enum_type - = tsubst_aggr_type (TREE_TYPE (t), args, in_decl, - /*entering_scope=*/0); - - for (v = TYPE_VALUES (enum_type); - v != NULL_TREE; - v = TREE_CHAIN (v)) - if (TREE_PURPOSE (v) == DECL_NAME (t)) - return TREE_VALUE (v); - - /* We didn't find the name. That should never happen; if - name-lookup found it during preliminary parsing, we - should find it again here during instantiation. */ - my_friendly_abort (0); - } - return t; - - case FIELD_DECL: - if (DECL_CONTEXT (t)) - { - tree ctx; - - ctx = tsubst_aggr_type (DECL_CONTEXT (t), args, in_decl, - /*entering_scope=*/1); - if (ctx != DECL_CONTEXT (t)) - return lookup_field (ctx, DECL_NAME (t), 0, 0); - } - return t; - - case VAR_DECL: - case FUNCTION_DECL: - if (DECL_LANG_SPECIFIC (t) && DECL_TEMPLATE_INFO (t)) - t = tsubst (t, args, in_decl); - mark_used (t); - return t; - - case TEMPLATE_DECL: - if (is_member_template (t)) - return tsubst (t, args, in_decl); - else - return t; - - case LOOKUP_EXPR: - { - /* We must tsbust into a LOOKUP_EXPR in case the names to - which it refers is a conversion operator; in that case the - name will change. We avoid making unnecessary copies, - however. */ - - tree id = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl); - - if (id != TREE_OPERAND (t, 0)) - { - r = build_nt (LOOKUP_EXPR, id); - LOOKUP_EXPR_GLOBAL (r) = LOOKUP_EXPR_GLOBAL (t); - t = r; - } - - return t; - } - - case CAST_EXPR: - case REINTERPRET_CAST_EXPR: - case CONST_CAST_EXPR: - case STATIC_CAST_EXPR: - case DYNAMIC_CAST_EXPR: - case NOP_EXPR: - return build1 - (code, tsubst (TREE_TYPE (t), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 0), args, in_decl)); - - case INDIRECT_REF: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case NEGATE_EXPR: - case TRUTH_NOT_EXPR: - case BIT_NOT_EXPR: - case ADDR_EXPR: - case CONVERT_EXPR: /* Unary + */ - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - case ARROW_EXPR: - case THROW_EXPR: - case TYPEID_EXPR: - return build1 - (code, NULL_TREE, - tsubst_copy (TREE_OPERAND (t, 0), args, in_decl)); - - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case EXACT_DIV_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case RSHIFT_EXPR: - case LSHIFT_EXPR: - case RROTATE_EXPR: - case LROTATE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case MAX_EXPR: - case MIN_EXPR: - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - case COMPONENT_REF: - case ARRAY_REF: - case COMPOUND_EXPR: - case SCOPE_REF: - case DOTSTAR_EXPR: - case MEMBER_REF: - return build_nt - (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 1), args, in_decl)); - - case CALL_EXPR: - { - tree fn = TREE_OPERAND (t, 0); - if (is_overloaded_fn (fn)) - fn = tsubst_copy (get_first_fn (fn), args, in_decl); - else - /* Sometimes FN is a LOOKUP_EXPR. */ - fn = tsubst_copy (fn, args, in_decl); - return build_nt - (code, fn, tsubst_copy (TREE_OPERAND (t, 1), args, in_decl), - NULL_TREE); - } - - case METHOD_CALL_EXPR: - { - tree name = TREE_OPERAND (t, 0); - if (TREE_CODE (name) == BIT_NOT_EXPR) - { - name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl); - name = build1 (BIT_NOT_EXPR, NULL_TREE, name); - } - else if (TREE_CODE (name) == SCOPE_REF - && TREE_CODE (TREE_OPERAND (name, 1)) == BIT_NOT_EXPR) - { - tree base = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl); - name = TREE_OPERAND (name, 1); - name = tsubst_copy (TREE_OPERAND (name, 0), args, in_decl); - name = build1 (BIT_NOT_EXPR, NULL_TREE, name); - name = build_nt (SCOPE_REF, base, name); - } - else - name = tsubst_copy (TREE_OPERAND (t, 0), args, in_decl); - return build_nt - (code, name, tsubst_copy (TREE_OPERAND (t, 1), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 2), args, in_decl), - NULL_TREE); - } - - case BIND_EXPR: - case COND_EXPR: - case MODOP_EXPR: - { - r = build_nt - (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 1), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 2), args, in_decl)); - - if (code == BIND_EXPR && !processing_template_decl) - { - /* This processing should really occur in tsubst_expr, - However, tsubst_expr does not recurse into expressions, - since it assumes that there aren't any statements - inside them. Instead, it simply calls - build_expr_from_tree. So, we need to expand the - BIND_EXPR here. */ - tree rtl_expr = begin_stmt_expr (); - tree block = tsubst_expr (TREE_OPERAND (r, 1), args, in_decl); - r = finish_stmt_expr (rtl_expr, block); - } - - return r; - } - - case NEW_EXPR: - { - r = build_nt - (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 1), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 2), args, in_decl)); - NEW_EXPR_USE_GLOBAL (r) = NEW_EXPR_USE_GLOBAL (t); - return r; - } - - case DELETE_EXPR: - { - r = build_nt - (code, tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), - tsubst_copy (TREE_OPERAND (t, 1), args, in_decl)); - DELETE_EXPR_USE_GLOBAL (r) = DELETE_EXPR_USE_GLOBAL (t); - DELETE_EXPR_USE_VEC (r) = DELETE_EXPR_USE_VEC (t); - return r; - } - - case TEMPLATE_ID_EXPR: - { - /* Substituted template arguments */ - tree targs = tsubst_copy (TREE_OPERAND (t, 1), args, in_decl); - tree chain; - for (chain = targs; chain; chain = TREE_CHAIN (chain)) - TREE_VALUE (chain) = maybe_fold_nontype_arg (TREE_VALUE (chain)); - - return lookup_template_function - (tsubst_copy (TREE_OPERAND (t, 0), args, in_decl), targs); - } - - case TREE_LIST: - { - tree purpose, value, chain; - - if (t == void_list_node) - return t; - - purpose = TREE_PURPOSE (t); - if (purpose) - purpose = tsubst_copy (purpose, args, in_decl); - value = TREE_VALUE (t); - if (value) - value = tsubst_copy (value, args, in_decl); - chain = TREE_CHAIN (t); - if (chain && chain != void_type_node) - chain = tsubst_copy (chain, args, in_decl); - if (purpose == TREE_PURPOSE (t) - && value == TREE_VALUE (t) - && chain == TREE_CHAIN (t)) - return t; - return tree_cons (purpose, value, chain); - } - - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - case INTEGER_TYPE: - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - case TEMPLATE_PARM_INDEX: - case POINTER_TYPE: - case REFERENCE_TYPE: - case OFFSET_TYPE: - case FUNCTION_TYPE: - case METHOD_TYPE: - case ARRAY_TYPE: - case TYPENAME_TYPE: - case TYPE_DECL: - return tsubst (t, args, in_decl); - - case IDENTIFIER_NODE: - if (IDENTIFIER_TYPENAME_P (t) - /* Make sure it's not just a variable named `__opr', for instance, - which can occur in some existing code. */ - && TREE_TYPE (t)) - return build_typename_overload - (tsubst (TREE_TYPE (t), args, in_decl)); - else - return t; - - case CONSTRUCTOR: - { - r = build - (CONSTRUCTOR, tsubst (TREE_TYPE (t), args, in_decl), NULL_TREE, - tsubst_copy (CONSTRUCTOR_ELTS (t), args, in_decl)); - TREE_HAS_CONSTRUCTOR (r) = TREE_HAS_CONSTRUCTOR (t); - return r; - } - - default: - return t; - } -} - -/* Like tsubst_copy, but also does semantic processing and RTL expansion. */ - -tree -tsubst_expr (t, args, in_decl) - tree t, args; - tree in_decl; -{ - if (t == NULL_TREE || t == error_mark_node) - return t; - - if (processing_template_decl) - return tsubst_copy (t, args, in_decl); - - switch (TREE_CODE (t)) - { - case RETURN_STMT: - lineno = TREE_COMPLEXITY (t); - finish_return_stmt (tsubst_expr (RETURN_EXPR (t), - args, in_decl)); - break; - - case EXPR_STMT: - lineno = TREE_COMPLEXITY (t); - finish_expr_stmt (tsubst_expr (EXPR_STMT_EXPR (t), - args, in_decl)); - break; - - case DECL_STMT: - { - int i = suspend_momentary (); - tree dcl, init; - - lineno = TREE_COMPLEXITY (t); - emit_line_note (input_filename, lineno); - dcl = start_decl - (tsubst (TREE_OPERAND (t, 0), args, in_decl), - tsubst (TREE_OPERAND (t, 1), args, in_decl), - TREE_OPERAND (t, 2) != 0, NULL_TREE, NULL_TREE); - init = tsubst_expr (TREE_OPERAND (t, 2), args, in_decl); - cp_finish_decl - (dcl, init, NULL_TREE, 1, /*init ? LOOKUP_ONLYCONVERTING :*/ 0); - resume_momentary (i); - return dcl; - } - - case FOR_STMT: - { - tree tmp; - lineno = TREE_COMPLEXITY (t); - - begin_for_stmt (); - for (tmp = FOR_INIT_STMT (t); tmp; tmp = TREE_CHAIN (tmp)) - tsubst_expr (tmp, args, in_decl); - finish_for_init_stmt (NULL_TREE); - finish_for_cond (tsubst_expr (FOR_COND (t), args, - in_decl), - NULL_TREE); - tmp = tsubst_expr (FOR_EXPR (t), args, in_decl); - finish_for_expr (tmp, NULL_TREE); - tsubst_expr (FOR_BODY (t), args, in_decl); - finish_for_stmt (tmp, NULL_TREE); - } - break; - - case WHILE_STMT: - { - lineno = TREE_COMPLEXITY (t); - begin_while_stmt (); - finish_while_stmt_cond (tsubst_expr (WHILE_COND (t), - args, in_decl), - NULL_TREE); - tsubst_expr (WHILE_BODY (t), args, in_decl); - finish_while_stmt (NULL_TREE); - } - break; - - case DO_STMT: - { - lineno = TREE_COMPLEXITY (t); - begin_do_stmt (); - tsubst_expr (DO_BODY (t), args, in_decl); - finish_do_body (NULL_TREE); - finish_do_stmt (tsubst_expr (DO_COND (t), args, - in_decl), - NULL_TREE); - } - break; - - case IF_STMT: - { - tree tmp; - - lineno = TREE_COMPLEXITY (t); - begin_if_stmt (); - finish_if_stmt_cond (tsubst_expr (IF_COND (t), - args, in_decl), - NULL_TREE); - - if (tmp = THEN_CLAUSE (t), tmp) - { - tsubst_expr (tmp, args, in_decl); - finish_then_clause (NULL_TREE); - } - - if (tmp = ELSE_CLAUSE (t), tmp) - { - begin_else_clause (); - tsubst_expr (tmp, args, in_decl); - finish_else_clause (NULL_TREE); - } - - finish_if_stmt (); - } - break; - - case COMPOUND_STMT: - { - tree substmt; - - lineno = TREE_COMPLEXITY (t); - begin_compound_stmt (COMPOUND_STMT_NO_SCOPE (t)); - for (substmt = COMPOUND_BODY (t); - substmt != NULL_TREE; - substmt = TREE_CHAIN (substmt)) - tsubst_expr (substmt, args, in_decl); - return finish_compound_stmt (COMPOUND_STMT_NO_SCOPE (t), - NULL_TREE); - } - break; - - case BREAK_STMT: - lineno = TREE_COMPLEXITY (t); - finish_break_stmt (); - break; - - case CONTINUE_STMT: - lineno = TREE_COMPLEXITY (t); - finish_continue_stmt (); - break; - - case SWITCH_STMT: - { - tree val, tmp; - - lineno = TREE_COMPLEXITY (t); - begin_switch_stmt (); - val = tsubst_expr (SWITCH_COND (t), args, in_decl); - finish_switch_cond (val); - - if (tmp = TREE_OPERAND (t, 1), tmp) - tsubst_expr (tmp, args, in_decl); - - finish_switch_stmt (val, NULL_TREE); - } - break; - - case CASE_LABEL: - finish_case_label (tsubst_expr (CASE_LOW (t), args, in_decl), - tsubst_expr (CASE_HIGH (t), args, in_decl)); - break; - - case LABEL_DECL: - t = define_label (DECL_SOURCE_FILE (t), DECL_SOURCE_LINE (t), - DECL_NAME (t)); - if (t) - expand_label (t); - break; - - case GOTO_STMT: - lineno = TREE_COMPLEXITY (t); - t = GOTO_DESTINATION (t); - if (TREE_CODE (t) != IDENTIFIER_NODE) - /* Computed goto's must be tsubst'd into. On the other hand, - non-computed gotos must not be; the identifier in question - will have no binding. */ - t = tsubst_expr (t, args, in_decl); - finish_goto_stmt (t); - break; - - case ASM_STMT: - lineno = TREE_COMPLEXITY (t); - finish_asm_stmt (tsubst_expr (ASM_CV_QUAL (t), args, in_decl), - tsubst_expr (ASM_STRING (t), args, in_decl), - tsubst_expr (ASM_OUTPUTS (t), args, in_decl), - tsubst_expr (ASM_INPUTS (t), args, in_decl), - tsubst_expr (ASM_CLOBBERS (t), args, in_decl)); - break; - - case TRY_BLOCK: - lineno = TREE_COMPLEXITY (t); - begin_try_block (); - tsubst_expr (TRY_STMTS (t), args, in_decl); - finish_try_block (NULL_TREE); - { - tree handler = TRY_HANDLERS (t); - for (; handler; handler = TREE_CHAIN (handler)) - tsubst_expr (handler, args, in_decl); - } - finish_handler_sequence (NULL_TREE); - break; - - case HANDLER: - lineno = TREE_COMPLEXITY (t); - begin_handler (); - if (HANDLER_PARMS (t)) - { - tree d = HANDLER_PARMS (t); - expand_start_catch_block - (tsubst (TREE_OPERAND (d, 1), args, in_decl), - tsubst (TREE_OPERAND (d, 0), args, in_decl)); - } - else - expand_start_catch_block (NULL_TREE, NULL_TREE); - finish_handler_parms (NULL_TREE); - tsubst_expr (HANDLER_BODY (t), args, in_decl); - finish_handler (NULL_TREE); - break; - - case TAG_DEFN: - lineno = TREE_COMPLEXITY (t); - t = TREE_TYPE (t); - if (TREE_CODE (t) == ENUMERAL_TYPE) - tsubst (t, args, NULL_TREE); - break; - - default: - return build_expr_from_tree (tsubst_copy (t, args, in_decl)); - } - return NULL_TREE; -} - -/* Instantiate the indicated variable or function template TMPL with - the template arguments in TARG_PTR. */ - -tree -instantiate_template (tmpl, targ_ptr) - tree tmpl, targ_ptr; -{ - tree fndecl; - tree gen_tmpl; - tree spec; - int i, len; - struct obstack *old_fmp_obstack; - extern struct obstack *function_maybepermanent_obstack; - tree inner_args; - - if (tmpl == error_mark_node) - return error_mark_node; - - my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 283); - - /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (tmpl, targ_ptr); - if (spec != NULL_TREE) - return spec; - - if (DECL_TEMPLATE_INFO (tmpl)) - { - /* The TMPL is a partial instantiation. To get a full set of - arguments we must add the arguments used to perform the - partial instantiation. */ - targ_ptr = add_outermost_template_args (DECL_TI_ARGS (tmpl), - targ_ptr); - gen_tmpl = most_general_template (tmpl); - - /* Check to see if we already have this specialization. */ - spec = retrieve_specialization (gen_tmpl, targ_ptr); - if (spec != NULL_TREE) - return spec; - } - else - gen_tmpl = tmpl; - - push_obstacks (&permanent_obstack, &permanent_obstack); - old_fmp_obstack = function_maybepermanent_obstack; - function_maybepermanent_obstack = &permanent_obstack; - - len = DECL_NTPARMS (gen_tmpl); - inner_args = innermost_args (targ_ptr); - i = len; - while (i--) - { - tree t = TREE_VEC_ELT (inner_args, i); - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - { - tree nt = target_type (t); - if (IS_AGGR_TYPE (nt) && decl_function_context (TYPE_MAIN_DECL (nt))) - { - cp_error ("type `%T' composed from a local class is not a valid template-argument", t); - cp_error (" trying to instantiate `%D'", gen_tmpl); - fndecl = error_mark_node; - goto out; - } - } - } - targ_ptr = copy_to_permanent (targ_ptr); - - /* substitute template parameters */ - fndecl = tsubst (DECL_RESULT (gen_tmpl), targ_ptr, gen_tmpl); - /* The DECL_TI_TEMPLATE should always be the immediate parent - template, not the most general template. */ - DECL_TI_TEMPLATE (fndecl) = tmpl; - - if (flag_external_templates) - add_pending_template (fndecl); - - out: - function_maybepermanent_obstack = old_fmp_obstack; - pop_obstacks (); - - return fndecl; -} - -/* Push the name of the class template into the scope of the instantiation. */ - -void -overload_template_name (type) - tree type; -{ - tree id = DECL_NAME (CLASSTYPE_TI_TEMPLATE (type)); - tree decl; - - if (IDENTIFIER_CLASS_VALUE (id) - && TREE_TYPE (IDENTIFIER_CLASS_VALUE (id)) == type) - return; - - decl = build_decl (TYPE_DECL, id, type); - SET_DECL_ARTIFICIAL (decl); - pushdecl_class_level (decl); -} - -/* Like type_unification but designed specially to handle conversion - operators. - - The FN is a TEMPLATE_DECL for a function. The ARGS are the - arguments that are being used when calling it. - - If FN is a conversion operator, RETURN_TYPE is the type desired as - the result of the conversion operator. - - The EXTRA_FN_ARG, if any, is the type of an additional - parameter to be added to the beginning of FN's parameter list. - - The other arguments are as for type_unification. */ - -int -fn_type_unification (fn, explicit_targs, targs, args, return_type, - strict, extra_fn_arg) - tree fn, explicit_targs, targs, args, return_type; - unification_kind_t strict; - tree extra_fn_arg; -{ - tree parms; - - my_friendly_assert (TREE_CODE (fn) == TEMPLATE_DECL, 0); - - parms = TYPE_ARG_TYPES (TREE_TYPE (fn)); - - if (DECL_CONV_FN_P (fn)) - { - /* This is a template conversion operator. Use the return types - as well as the argument types. */ - parms = scratch_tree_cons (NULL_TREE, - TREE_TYPE (TREE_TYPE (fn)), - parms); - args = scratch_tree_cons (NULL_TREE, return_type, args); - } - - if (extra_fn_arg != NULL_TREE) - parms = scratch_tree_cons (NULL_TREE, extra_fn_arg, parms); - - /* We allow incomplete unification without an error message here - because the standard doesn't seem to explicitly prohibit it. Our - callers must be ready to deal with unification failures in any - event. */ - return type_unification (DECL_INNERMOST_TEMPLATE_PARMS (fn), - targs, - parms, - args, - explicit_targs, - strict, 1); -} - - -/* Type unification. - - We have a function template signature with one or more references to - template parameters, and a parameter list we wish to fit to this - template. If possible, produce a list of parameters for the template - which will cause it to fit the supplied parameter list. - - Return zero for success, 2 for an incomplete match that doesn't resolve - all the types, and 1 for complete failure. An error message will be - printed only for an incomplete match. - - TPARMS[NTPARMS] is an array of template parameter types. - - TARGS[NTPARMS] is the array into which the deduced template - parameter values are placed. PARMS is the function template's - signature (using TEMPLATE_PARM_IDX nodes), and ARGS is the argument - list we're trying to match against it. - - The EXPLICIT_TARGS are explicit template arguments provided via a - template-id. - - The parameter STRICT is one of: - - DEDUCE_CALL: - We are deducing arguments for a function call, as in - [temp.deduct.call]. - - DEDUCE_CONV: - We are deducing arguments for a conversion function, as in - [temp.deduct.conv]. - - DEDUCE_EXACT: - We are deducing arguments when calculating the partial - ordering between specializations of function or class - templates, as in [temp.func.order] and [temp.class.order], - when doing an explicit instantiation as in [temp.explicit], - when determining an explicit specialization as in - [temp.expl.spec], or when taking the address of a function - template, as in [temp.deduct.funcaddr]. */ - -int -type_unification (tparms, targs, parms, args, explicit_targs, - strict, allow_incomplete) - tree tparms, targs, parms, args, explicit_targs; - unification_kind_t strict; - int allow_incomplete; -{ - int* explicit_mask; - int i; - - for (i = 0; i < TREE_VEC_LENGTH (tparms); i++) - TREE_VEC_ELT (targs, i) = NULL_TREE; - - if (explicit_targs != NULL_TREE) - { - tree arg_vec; - arg_vec = coerce_template_parms (tparms, explicit_targs, NULL_TREE, 0, - 0); - - if (arg_vec == error_mark_node) - return 1; - - explicit_mask = alloca (sizeof (int) * TREE_VEC_LENGTH (targs)); - bzero ((char *) explicit_mask, sizeof(int) * TREE_VEC_LENGTH (targs)); - - for (i = 0; - i < TREE_VEC_LENGTH (arg_vec) - && TREE_VEC_ELT (arg_vec, i) != NULL_TREE; - ++i) - { - TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (arg_vec, i); - /* Let unify know that this argument was explicit. */ - explicit_mask [i] = 1; - } - } - else - explicit_mask = 0; - - return - type_unification_real (tparms, targs, parms, args, 0, - strict, allow_incomplete, explicit_mask); -} - -/* Adjust types before performing type deduction, as described in - [temp.deduct.call] and [temp.deduct.conv]. The rules in these two - sections are symmetric. PARM is the type of a function parameter - or the return type of the conversion function. ARG is the type of - the argument passed to the call, or the type of the value - intialized with the result of the conversion function. */ - -static void -maybe_adjust_types_for_deduction (strict, parm, arg) - unification_kind_t strict; - tree* parm; - tree* arg; -{ - switch (strict) - { - case DEDUCE_CALL: - break; - - case DEDUCE_CONV: - { - /* Swap PARM and ARG throughout the remainder of this - function; the handling is precisely symmetric since PARM - will initialize ARG rather than vice versa. */ - tree* temp = parm; - parm = arg; - arg = temp; - break; - } - - case DEDUCE_EXACT: - /* There is nothing to do in this case. */ - return; - - default: - my_friendly_abort (0); - } - - if (TREE_CODE (*parm) != REFERENCE_TYPE) - { - /* [temp.deduct.call] - - If P is not a reference type: - - --If A is an array type, the pointer type produced by the - array-to-pointer standard conversion (_conv.array_) is - used in place of A for type deduction; otherwise, - - --If A is a function type, the pointer type produced by - the function-to-pointer standard conversion - (_conv.func_) is used in place of A for type deduction; - otherwise, - - --If A is a cv-qualified type, the top level - cv-qualifiers of A's type are ignored for type - deduction. */ - if (TREE_CODE (*arg) == ARRAY_TYPE) - *arg = build_pointer_type (TREE_TYPE (*arg)); - else if (TREE_CODE (*arg) == FUNCTION_TYPE) - *arg = build_pointer_type (*arg); - else - *arg = TYPE_MAIN_VARIANT (*arg); - } - - /* [temp.deduct.call] - - If P is a cv-qualified type, the top level cv-qualifiers - of P's type are ignored for type deduction. If P is a - reference type, the type referred to by P is used for - type deduction. */ - *parm = TYPE_MAIN_VARIANT (*parm); - if (TREE_CODE (*parm) == REFERENCE_TYPE) - *parm = TREE_TYPE (*parm); -} - -/* Like type_unfication. EXPLICIT_MASK, if non-NULL, is an array of - integers, with ones in positions corresponding to arguments in - targs that were provided explicitly, and zeros elsewhere. - - If SUBR is 1, we're being called recursively (to unify the - arguments of a function or method parameter of a function - template). */ - -static int -type_unification_real (tparms, targs, parms, args, subr, - strict, allow_incomplete, explicit_mask) - tree tparms, targs, parms, args; - int subr; - unification_kind_t strict; - int allow_incomplete; - int* explicit_mask; -{ - tree parm, arg; - int i; - int ntparms = TREE_VEC_LENGTH (tparms); - int sub_strict; - - my_friendly_assert (TREE_CODE (tparms) == TREE_VEC, 289); - my_friendly_assert (parms == NULL_TREE - || TREE_CODE (parms) == TREE_LIST, 290); - /* ARGS could be NULL (via a call from parse.y to - build_x_function_call). */ - if (args) - my_friendly_assert (TREE_CODE (args) == TREE_LIST, 291); - my_friendly_assert (ntparms > 0, 292); - - switch (strict) - { - case DEDUCE_CALL: - sub_strict = UNIFY_ALLOW_MORE_CV_QUAL | UNIFY_ALLOW_DERIVED; - break; - - case DEDUCE_CONV: - sub_strict = UNIFY_ALLOW_LESS_CV_QUAL; - break; - - case DEDUCE_EXACT: - sub_strict = UNIFY_ALLOW_NONE; - break; - - default: - my_friendly_abort (0); - } - - while (parms - && parms != void_list_node - && args - && args != void_list_node) - { - parm = TREE_VALUE (parms); - parms = TREE_CHAIN (parms); - arg = TREE_VALUE (args); - args = TREE_CHAIN (args); - - if (arg == error_mark_node) - return 1; - if (arg == unknown_type_node) - /* We can't deduce anything from this, but we might get all the - template args from other function args. */ - continue; - - /* Conversions will be performed on a function argument that - corresponds with a function parameter that contains only - non-deducible template parameters and explicitly specified - template parameters. */ - if (! uses_template_parms (parm)) - { - tree type; - - if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't') - type = TREE_TYPE (arg); - else - { - type = arg; - arg = NULL_TREE; - } - - if (strict == DEDUCE_EXACT) - { - if (same_type_p (parm, type)) - continue; - } - else - /* It might work; we shouldn't check now, because we might - get into infinite recursion. Overload resolution will - handle it. */ - continue; - - return 1; - } - -#if 0 - if (TREE_CODE (arg) == VAR_DECL) - arg = TREE_TYPE (arg); - else if (TREE_CODE_CLASS (TREE_CODE (arg)) == 'e') - arg = TREE_TYPE (arg); -#else - if (TREE_CODE_CLASS (TREE_CODE (arg)) != 't') - { - my_friendly_assert (TREE_TYPE (arg) != NULL_TREE, 293); - if (type_unknown_p (arg)) - { - /* [temp.deduct.type] A template-argument can be deduced from - a pointer to function or pointer to member function - argument if the set of overloaded functions does not - contain function templates and at most one of a set of - overloaded functions provides a unique match. */ - - if (resolve_overloaded_unification - (tparms, targs, parm, arg, strict, sub_strict, explicit_mask) - != 0) - return 1; - continue; - } - arg = TREE_TYPE (arg); - } -#endif - if (!subr) - maybe_adjust_types_for_deduction (strict, &parm, &arg); - - switch (unify (tparms, targs, parm, arg, sub_strict, - explicit_mask)) - { - case 0: - break; - case 1: - return 1; - } - } - /* Fail if we've reached the end of the parm list, and more args - are present, and the parm list isn't variadic. */ - if (args && args != void_list_node && parms == void_list_node) - return 1; - /* Fail if parms are left and they don't have default values. */ - if (parms - && parms != void_list_node - && TREE_PURPOSE (parms) == NULL_TREE) - return 1; - if (!subr) - for (i = 0; i < ntparms; i++) - if (TREE_VEC_ELT (targs, i) == NULL_TREE) - { - if (!allow_incomplete) - error ("incomplete type unification"); - return 2; - } - return 0; -} - -/* Subroutine of type_unification_real. Args are like the variables at the - call site. ARG is an overloaded function (or template-id); we try - deducing template args from each of the overloads, and if only one - succeeds, we go with that. Modifies TARGS and returns 0 on success. */ - -static int -resolve_overloaded_unification (tparms, targs, parm, arg, strict, - sub_strict, explicit_mask) - tree tparms, targs, parm, arg; - unification_kind_t strict; - int sub_strict; - int* explicit_mask; -{ - tree tempargs = copy_node (targs); - int good = 0; - - if (TREE_CODE (arg) == ADDR_EXPR) - arg = TREE_OPERAND (arg, 0); - - if (TREE_CODE (arg) == COMPONENT_REF) - /* Handle `&x' where `x' is some static or non-static member - function name. */ - arg = TREE_OPERAND (arg, 1); - - /* Strip baselink information. */ - while (TREE_CODE (arg) == TREE_LIST) - arg = TREE_VALUE (arg); - - if (TREE_CODE (arg) == TEMPLATE_ID_EXPR) - { - /* If we got some explicit template args, we need to plug them into - the affected templates before we try to unify, in case the - explicit args will completely resolve the templates in question. */ - - tree expl_subargs = TREE_OPERAND (arg, 1); - arg = TREE_OPERAND (arg, 0); - - for (; arg; arg = OVL_NEXT (arg)) - { - tree fn = OVL_CURRENT (arg); - tree subargs, elem; - - if (TREE_CODE (fn) != TEMPLATE_DECL) - continue; - - subargs = get_bindings_overload (fn, DECL_RESULT (fn), expl_subargs); - if (subargs) - { - elem = tsubst (TREE_TYPE (fn), subargs, NULL_TREE); - if (TREE_CODE (elem) == METHOD_TYPE) - elem = build_ptrmemfunc_type (build_pointer_type (elem)); - good += try_one_overload (tparms, targs, tempargs, parm, elem, - strict, sub_strict, explicit_mask); - } - } - } - else if (TREE_CODE (arg) == OVERLOAD) - { - for (; arg; arg = OVL_NEXT (arg)) - { - tree type = TREE_TYPE (OVL_CURRENT (arg)); - if (TREE_CODE (type) == METHOD_TYPE) - type = build_ptrmemfunc_type (build_pointer_type (type)); - good += try_one_overload (tparms, targs, tempargs, parm, - type, - strict, sub_strict, explicit_mask); - } - } - else - my_friendly_abort (981006); - - /* [temp.deduct.type] A template-argument can be deduced from a pointer - to function or pointer to member function argument if the set of - overloaded functions does not contain function templates and at most - one of a set of overloaded functions provides a unique match. - - So if we found multiple possibilities, we return success but don't - deduce anything. */ - - if (good == 1) - { - int i = TREE_VEC_LENGTH (targs); - for (; i--; ) - if (TREE_VEC_ELT (tempargs, i)) - TREE_VEC_ELT (targs, i) = TREE_VEC_ELT (tempargs, i); - } - if (good) - return 0; - - return 1; -} - -/* Subroutine of resolve_overloaded_unification; does deduction for a single - overload. Fills TARGS with any deduced arguments, or error_mark_node if - different overloads deduce different arguments for a given parm. - Returns 1 on success. */ - -static int -try_one_overload (tparms, orig_targs, targs, parm, arg, strict, - sub_strict, explicit_mask) - tree tparms, orig_targs, targs, parm, arg; - unification_kind_t strict; - int sub_strict; - int* explicit_mask; -{ - int nargs; - tree tempargs; - int i; - - /* [temp.deduct.type] A template-argument can be deduced from a pointer - to function or pointer to member function argument if the set of - overloaded functions does not contain function templates and at most - one of a set of overloaded functions provides a unique match. - - So if this is a template, just return success. */ - - if (uses_template_parms (arg)) - return 1; - - maybe_adjust_types_for_deduction (strict, &parm, &arg); - - /* We don't copy orig_targs for this because if we have already deduced - some template args from previous args, unify would complain when we - try to deduce a template parameter for the same argument, even though - there isn't really a conflict. */ - nargs = TREE_VEC_LENGTH (targs); - tempargs = make_scratch_vec (nargs); - - if (unify (tparms, tempargs, parm, arg, sub_strict, explicit_mask) != 0) - return 0; - - /* First make sure we didn't deduce anything that conflicts with - explicitly specified args. */ - for (i = nargs; i--; ) - { - tree elt = TREE_VEC_ELT (tempargs, i); - tree oldelt = TREE_VEC_ELT (orig_targs, i); - - if (elt == NULL_TREE) - continue; - else if (uses_template_parms (elt)) - { - /* Since we're unifying against ourselves, we will fill in template - args used in the function parm list with our own template parms. - Discard them. */ - TREE_VEC_ELT (tempargs, i) = NULL_TREE; - continue; - } - else if (oldelt && ! template_args_equal (oldelt, elt)) - return 0; - } - - for (i = nargs; i--; ) - { - tree elt = TREE_VEC_ELT (tempargs, i); - - if (elt) - TREE_VEC_ELT (targs, i) = elt; - } - - return 1; -} - -/* Returns the level of DECL, which declares a template parameter. */ - -static int -template_decl_level (decl) - tree decl; -{ - switch (TREE_CODE (decl)) - { - case TYPE_DECL: - case TEMPLATE_DECL: - return TEMPLATE_TYPE_LEVEL (TREE_TYPE (decl)); - - case PARM_DECL: - return TEMPLATE_PARM_LEVEL (DECL_INITIAL (decl)); - - default: - my_friendly_abort (0); - return 0; - } -} - -/* Decide whether ARG can be unified with PARM, considering only the - cv-qualifiers of each type, given STRICT as documented for unify. - Returns non-zero iff the unification is OK on that basis.*/ - -static int -check_cv_quals_for_unify (strict, arg, parm) - int strict; - tree arg; - tree parm; -{ - return !((!(strict & UNIFY_ALLOW_MORE_CV_QUAL) - && !at_least_as_qualified_p (arg, parm)) - || (!(strict & UNIFY_ALLOW_LESS_CV_QUAL) - && (!at_least_as_qualified_p (parm, arg)))); -} - -/* Takes parameters as for type_unification. Returns 0 if the - type deduction suceeds, 1 otherwise. The parameter STRICT is a - bitwise or of the following flags: - - UNIFY_ALLOW_NONE: - Require an exact match between PARM and ARG. - UNIFY_ALLOW_MORE_CV_QUAL: - Allow the deduced ARG to be more cv-qualified than ARG. - UNIFY_ALLOW_LESS_CV_QUAL: - Allow the deduced ARG to be less cv-qualified than ARG. - UNIFY_ALLOW_DERIVED: - Allow the deduced ARG to be a template base class of ARG, - or a pointer to a template base class of the type pointed to by - ARG. - UNIFY_ALLOW_INTEGER: - Allow any integral type to be deduced. See the TEMPLATE_PARM_INDEX - case for more information. */ - -static int -unify (tparms, targs, parm, arg, strict, explicit_mask) - tree tparms, targs, parm, arg; - int strict; - int* explicit_mask; -{ - int idx; - tree targ; - tree tparm; - - /* I don't think this will do the right thing with respect to types. - But the only case I've seen it in so far has been array bounds, where - signedness is the only information lost, and I think that will be - okay. */ - while (TREE_CODE (parm) == NOP_EXPR) - parm = TREE_OPERAND (parm, 0); - - if (arg == error_mark_node) - return 1; - if (arg == unknown_type_node) - /* We can't deduce anything from this, but we might get all the - template args from other function args. */ - return 0; - - /* If PARM uses template parameters, then we can't bail out here, - even if ARG == PARM, since we won't record unifications for the - template parameters. We might need them if we're trying to - figure out which of two things is more specialized. */ - if (arg == parm && !uses_template_parms (parm)) - return 0; - - /* Immediately reject some pairs that won't unify because of - cv-qualification mismatches. */ - if (TREE_CODE (arg) == TREE_CODE (parm) - && TREE_CODE_CLASS (TREE_CODE (arg)) == 't' - /* We check the cv-qualifiers when unifying with template type - parameters below. We want to allow ARG `const T' to unify with - PARM `T' for example, when computing which of two templates - is more specialized, for example. */ - && TREE_CODE (arg) != TEMPLATE_TYPE_PARM - && !check_cv_quals_for_unify (strict, arg, parm)) - return 1; - - switch (TREE_CODE (parm)) - { - case TYPENAME_TYPE: - /* In a type which contains a nested-name-specifier, template - argument values cannot be deduced for template parameters used - within the nested-name-specifier. */ - return 0; - - case TEMPLATE_TYPE_PARM: - case TEMPLATE_TEMPLATE_PARM: - tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - - if (TEMPLATE_TYPE_LEVEL (parm) - != template_decl_level (tparm)) - /* The PARM is not one we're trying to unify. Just check - to see if it matches ARG. */ - return (TREE_CODE (arg) == TREE_CODE (parm) - && same_type_p (parm, arg)) ? 0 : 1; - idx = TEMPLATE_TYPE_IDX (parm); - targ = TREE_VEC_ELT (targs, idx); - tparm = TREE_VALUE (TREE_VEC_ELT (tparms, idx)); - - /* Check for mixed types and values. */ - if ((TREE_CODE (parm) == TEMPLATE_TYPE_PARM - && TREE_CODE (tparm) != TYPE_DECL) - || (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM - && TREE_CODE (tparm) != TEMPLATE_DECL)) - return 1; - - if (!strict && targ != NULL_TREE - && explicit_mask && explicit_mask[idx]) - /* An explicit template argument. Don't even try to match - here; the overload resolution code will manage check to - see whether the call is legal. */ - return 0; - - if (TREE_CODE (parm) == TEMPLATE_TEMPLATE_PARM) - { - if (TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (parm)) - { - /* We arrive here when PARM does not involve template - specialization. */ - - /* ARG must be constructed from a template class. */ - if (TREE_CODE (arg) != RECORD_TYPE || !CLASSTYPE_TEMPLATE_INFO (arg)) - return 1; - - { - tree parmtmpl = TYPE_TI_TEMPLATE (parm); - tree parmvec = TYPE_TI_ARGS (parm); - tree argvec = CLASSTYPE_TI_ARGS (arg); - tree argtmplvec - = DECL_INNERMOST_TEMPLATE_PARMS (CLASSTYPE_TI_TEMPLATE (arg)); - int i; - - /* The parameter and argument roles have to be switched here - in order to handle default arguments properly. For example, - template<template <class> class TT> void f(TT<int>) - should be able to accept vector<int> which comes from - template <class T, class Allocator = allocator> - class vector. */ - - if (coerce_template_parms (argtmplvec, parmvec, parmtmpl, 0, 1) - == error_mark_node) - return 1; - - /* Deduce arguments T, i from TT<T> or TT<i>. - We check each element of PARMVEC and ARGVEC individually - rather than the whole TREE_VEC since they can have - different number of elements. */ - - for (i = 0; i < TREE_VEC_LENGTH (parmvec); ++i) - { - tree t = TREE_VEC_ELT (parmvec, i); - - if (unify (tparms, targs, t, - TREE_VEC_ELT (argvec, i), - UNIFY_ALLOW_NONE, explicit_mask)) - return 1; - } - } - arg = CLASSTYPE_TI_TEMPLATE (arg); - } - } - else - { - /* If PARM is `const T' and ARG is only `int', we don't have - a match unless we are allowing additional qualification. - If ARG is `const int' and PARM is just `T' that's OK; - that binds `const int' to `T'. */ - if (!check_cv_quals_for_unify (strict | UNIFY_ALLOW_LESS_CV_QUAL, - arg, parm)) - return 1; - - /* Consider the case where ARG is `const volatile int' and - PARM is `const T'. Then, T should be `volatile int'. */ - arg = - cp_build_qualified_type (arg, - CP_TYPE_QUALS (arg) - & ~CP_TYPE_QUALS (parm)); - } - - /* Simple cases: Value already set, does match or doesn't. */ - if (targ != NULL_TREE - && (same_type_p (targ, arg) - || (explicit_mask && explicit_mask[idx]))) - return 0; - else if (targ) - return 1; - - /* Make sure that ARG is not a variable-sized array. (Note that - were talking about variable-sized arrays (like `int[n]'), - rather than arrays of unknown size (like `int[]').) We'll - get very confused by such a type since the bound of the array - will not be computable in an instantiation. Besides, such - types are not allowed in ISO C++, so we can do as we please - here. */ - if (TREE_CODE (arg) == ARRAY_TYPE - && !uses_template_parms (arg) - && (TREE_CODE (TYPE_MAX_VALUE (TYPE_DOMAIN (arg))) - != INTEGER_CST)) - return 1; - - TREE_VEC_ELT (targs, idx) = arg; - return 0; - - case TEMPLATE_PARM_INDEX: - tparm = TREE_VALUE (TREE_VEC_ELT (tparms, 0)); - - if (TEMPLATE_PARM_LEVEL (parm) - != template_decl_level (tparm)) - /* The PARM is not one we're trying to unify. Just check - to see if it matches ARG. */ - return (TREE_CODE (arg) == TREE_CODE (parm) - && cp_tree_equal (parm, arg) > 0) ? 0 : 1; - - idx = TEMPLATE_PARM_IDX (parm); - targ = TREE_VEC_ELT (targs, idx); - - if (targ) - { - int i = (cp_tree_equal (targ, arg) > 0); - if (i == 1) - return 0; - else if (i == 0) - return 1; - else - my_friendly_abort (42); - } - - /* [temp.deduct.type] If, in the declaration of a function template - with a non-type template-parameter, the non-type - template-parameter is used in an expression in the function - parameter-list and, if the corresponding template-argument is - deduced, the template-argument type shall match the type of the - template-parameter exactly, except that a template-argument - deduced from an array bound may be of any integral type. */ - if (same_type_p (TREE_TYPE (arg), TREE_TYPE (parm))) - /* OK */; - else if ((strict & UNIFY_ALLOW_INTEGER) - && (TREE_CODE (TREE_TYPE (parm)) == INTEGER_TYPE - || TREE_CODE (TREE_TYPE (parm)) == BOOLEAN_TYPE)) - /* OK */; - else - return 1; - - TREE_VEC_ELT (targs, idx) = copy_to_permanent (arg); - return 0; - - case POINTER_TYPE: - { - int sub_strict; - - if (TREE_CODE (arg) == RECORD_TYPE && TYPE_PTRMEMFUNC_FLAG (arg)) - return (unify (tparms, targs, parm, - TYPE_PTRMEMFUNC_FN_TYPE (arg), strict, - explicit_mask)); - - if (TREE_CODE (arg) != POINTER_TYPE) - return 1; - - /* [temp.deduct.call] - - A can be another pointer or pointer to member type that can - be converted to the deduced A via a qualification - conversion (_conv.qual_). - - We pass down STRICT here rather than UNIFY_ALLOW_NONE. - This will allow for additional cv-qualification of the - pointed-to types if appropriate. In general, this is a bit - too generous; we are only supposed to allow qualification - conversions and this method will allow an ARG of char** and - a deduced ARG of const char**. However, overload - resolution will subsequently invalidate the candidate, so - this is probably OK. */ - sub_strict = strict; - - if (TREE_CODE (TREE_TYPE (arg)) != RECORD_TYPE - || TYPE_PTRMEMFUNC_FLAG (TREE_TYPE (arg))) - /* The derived-to-base conversion only persists through one - level of pointers. */ - sub_strict &= ~UNIFY_ALLOW_DERIVED; - - return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE - (arg), sub_strict, explicit_mask); - } - - case REFERENCE_TYPE: - if (TREE_CODE (arg) != REFERENCE_TYPE) - return 1; - return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), - UNIFY_ALLOW_NONE, explicit_mask); - - case ARRAY_TYPE: - if (TREE_CODE (arg) != ARRAY_TYPE) - return 1; - if ((TYPE_DOMAIN (parm) == NULL_TREE) - != (TYPE_DOMAIN (arg) == NULL_TREE)) - return 1; - if (TYPE_DOMAIN (parm) != NULL_TREE - && unify (tparms, targs, TYPE_DOMAIN (parm), - TYPE_DOMAIN (arg), UNIFY_ALLOW_NONE, explicit_mask) != 0) - return 1; - return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), - UNIFY_ALLOW_NONE, explicit_mask); - - case REAL_TYPE: - case COMPLEX_TYPE: - case INTEGER_TYPE: - case BOOLEAN_TYPE: - case VOID_TYPE: - if (TREE_CODE (arg) != TREE_CODE (parm)) - return 1; - - if (TREE_CODE (parm) == INTEGER_TYPE - && TREE_CODE (TYPE_MAX_VALUE (parm)) != INTEGER_CST) - { - if (TYPE_MIN_VALUE (parm) && TYPE_MIN_VALUE (arg) - && unify (tparms, targs, TYPE_MIN_VALUE (parm), - TYPE_MIN_VALUE (arg), UNIFY_ALLOW_INTEGER, - explicit_mask)) - return 1; - if (TYPE_MAX_VALUE (parm) && TYPE_MAX_VALUE (arg) - && unify (tparms, targs, TYPE_MAX_VALUE (parm), - TYPE_MAX_VALUE (arg), UNIFY_ALLOW_INTEGER, - explicit_mask)) - return 1; - } - /* We use the TYPE_MAIN_VARIANT since we have already - checked cv-qualification at the top of the - function. */ - else if (!same_type_p (TYPE_MAIN_VARIANT (arg), - TYPE_MAIN_VARIANT (parm))) - return 1; - - /* As far as unification is concerned, this wins. Later checks - will invalidate it if necessary. */ - return 0; - - /* Types INTEGER_CST and MINUS_EXPR can come from array bounds. */ - /* Type INTEGER_CST can come from ordinary constant template args. */ - case INTEGER_CST: - while (TREE_CODE (arg) == NOP_EXPR) - arg = TREE_OPERAND (arg, 0); - - if (TREE_CODE (arg) != INTEGER_CST) - return 1; - return !tree_int_cst_equal (parm, arg); - - case TREE_VEC: - { - int i; - if (TREE_CODE (arg) != TREE_VEC) - return 1; - if (TREE_VEC_LENGTH (parm) != TREE_VEC_LENGTH (arg)) - return 1; - for (i = TREE_VEC_LENGTH (parm) - 1; i >= 0; i--) - if (unify (tparms, targs, - TREE_VEC_ELT (parm, i), TREE_VEC_ELT (arg, i), - UNIFY_ALLOW_NONE, explicit_mask)) - return 1; - return 0; - } - - case RECORD_TYPE: - case UNION_TYPE: - if (TYPE_PTRMEMFUNC_FLAG (parm)) - return unify (tparms, targs, TYPE_PTRMEMFUNC_FN_TYPE (parm), - arg, strict, explicit_mask); - - if (TREE_CODE (arg) != TREE_CODE (parm)) - return 1; - - if (CLASSTYPE_TEMPLATE_INFO (parm)) - { - tree t = NULL_TREE; - if (strict & UNIFY_ALLOW_DERIVED) - /* [temp.deduct.call] - - If P is a class, and P has the form template-id, then A - can be a derived class of the deduced A. Likewise, if - P is a pointer to a class of the form template-id, A - can be a pointer to a derived class pointed to by the - deduced A. - - The call to get_template_base also handles the case - where PARM and ARG are the same type, i.e., where no - derivation is involved. */ - t = get_template_base (CLASSTYPE_TI_TEMPLATE (parm), arg); - else if (CLASSTYPE_TEMPLATE_INFO (arg) - && (CLASSTYPE_TI_TEMPLATE (parm) - == CLASSTYPE_TI_TEMPLATE (arg))) - /* Perhaps PARM is something like S<U> and ARG is S<int>. - Then, we should unify `int' and `U'. */ - t = arg; - - if (! t || t == error_mark_node) - return 1; - - return unify (tparms, targs, CLASSTYPE_TI_ARGS (parm), - CLASSTYPE_TI_ARGS (t), UNIFY_ALLOW_NONE, - explicit_mask); - } - else if (!same_type_p (TYPE_MAIN_VARIANT (parm), - TYPE_MAIN_VARIANT (arg))) - return 1; - return 0; - - case METHOD_TYPE: - case FUNCTION_TYPE: - if (TREE_CODE (arg) != TREE_CODE (parm)) - return 1; - - if (unify (tparms, targs, TREE_TYPE (parm), - TREE_TYPE (arg), UNIFY_ALLOW_NONE, explicit_mask)) - return 1; - return type_unification_real (tparms, targs, TYPE_ARG_TYPES (parm), - TYPE_ARG_TYPES (arg), 1, - DEDUCE_EXACT, 0, explicit_mask); - - case OFFSET_TYPE: - if (TREE_CODE (arg) != OFFSET_TYPE) - return 1; - if (unify (tparms, targs, TYPE_OFFSET_BASETYPE (parm), - TYPE_OFFSET_BASETYPE (arg), UNIFY_ALLOW_NONE, explicit_mask)) - return 1; - return unify (tparms, targs, TREE_TYPE (parm), TREE_TYPE (arg), - strict, explicit_mask); - - case CONST_DECL: - if (arg != decl_constant_value (parm)) - return 1; - return 0; - - case TEMPLATE_DECL: - /* Matched cases are handled by the ARG == PARM test above. */ - return 1; - - case MINUS_EXPR: - if (TREE_CODE (TREE_OPERAND (parm, 1)) == INTEGER_CST) - { - /* We handle this case specially, since it comes up with - arrays. In particular, something like: - - template <int N> void f(int (&x)[N]); - - Here, we are trying to unify the range type, which - looks like [0 ... (N - 1)]. */ - tree t, t1, t2; - t1 = TREE_OPERAND (parm, 0); - t2 = TREE_OPERAND (parm, 1); - - /* Should this be a regular fold? */ - t = maybe_fold_nontype_arg (build (PLUS_EXPR, - integer_type_node, - arg, t2)); - - return unify (tparms, targs, t1, t, strict, explicit_mask); - } - /* else fall through */ - - default: - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (parm)))) - { - /* We're looking at an expression. This can happen with - something like: - - template <int I> - void foo(S<I>, S<I + 2>); - - If the call looked like: - - foo(S<2>(), S<4>()); - - we would have already matched `I' with `2'. Now, we'd - like to know if `4' matches `I + 2'. So, we substitute - into that expression, and fold constants, in the hope of - figuring it out. */ - tree t = - maybe_fold_nontype_arg (tsubst_expr (parm, targs, NULL_TREE)); - tree a = maybe_fold_nontype_arg (arg); - - if (!IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (t)))) - /* Good, we mangaged to simplify the exression. */ - return unify (tparms, targs, t, a, UNIFY_ALLOW_NONE, - explicit_mask); - else - /* Bad, we couldn't simplify this. Assume it doesn't - unify. */ - return 1; - } - else - sorry ("use of `%s' in template type unification", - tree_code_name [(int) TREE_CODE (parm)]); - - return 1; - } -} - -/* Called if RESULT is explicitly instantiated, or is a member of an - explicitly instantiated class, or if using -frepo and the - instantiation of RESULT has been assigned to this file. */ - -void -mark_decl_instantiated (result, extern_p) - tree result; - int extern_p; -{ - if (TREE_CODE (result) != FUNCTION_DECL) - /* The TREE_PUBLIC flag for function declarations will have been - set correctly by tsubst. */ - TREE_PUBLIC (result) = 1; - - if (! extern_p) - { - DECL_INTERFACE_KNOWN (result) = 1; - DECL_NOT_REALLY_EXTERN (result) = 1; - - /* Always make artificials weak. */ - if (DECL_ARTIFICIAL (result) && flag_weak) - comdat_linkage (result); - /* For WIN32 we also want to put explicit instantiations in - linkonce sections. */ - else if (TREE_PUBLIC (result)) - maybe_make_one_only (result); - } - else if (TREE_CODE (result) == FUNCTION_DECL) - mark_inline_for_output (result); -} - -/* Given two function templates PAT1 and PAT2, and explicit template - arguments EXPLICIT_ARGS return: - - 1 if PAT1 is more specialized than PAT2 as described in [temp.func.order]. - -1 if PAT2 is more specialized than PAT1. - 0 if neither is more specialized. */ - -int -more_specialized (pat1, pat2, explicit_args) - tree pat1, pat2, explicit_args; -{ - tree targs; - int winner = 0; - - targs = get_bindings_overload (pat1, pat2, explicit_args); - if (targs) - --winner; - - targs = get_bindings_overload (pat2, pat1, explicit_args); - if (targs) - ++winner; - - return winner; -} - -/* Given two class template specialization list nodes PAT1 and PAT2, return: - - 1 if PAT1 is more specialized than PAT2 as described in [temp.class.order]. - -1 if PAT2 is more specialized than PAT1. - 0 if neither is more specialized. */ - -int -more_specialized_class (pat1, pat2) - tree pat1, pat2; -{ - tree targs; - int winner = 0; - - targs = get_class_bindings (TREE_VALUE (pat1), TREE_PURPOSE (pat1), - TREE_PURPOSE (pat2)); - if (targs) - --winner; - - targs = get_class_bindings (TREE_VALUE (pat2), TREE_PURPOSE (pat2), - TREE_PURPOSE (pat1)); - if (targs) - ++winner; - - return winner; -} - -/* Return the template arguments that will produce the function signature - DECL from the function template FN, with the explicit template - arguments EXPLICIT_ARGS. If CHECK_RETTYPE is 1, the return type must - also match. */ - -static tree -get_bindings_real (fn, decl, explicit_args, check_rettype) - tree fn, decl, explicit_args; - int check_rettype; -{ - int ntparms = DECL_NTPARMS (fn); - tree targs = make_scratch_vec (ntparms); - tree decl_arg_types = TYPE_ARG_TYPES (TREE_TYPE (decl)); - tree extra_fn_arg = NULL_TREE; - int i; - - if (DECL_STATIC_FUNCTION_P (fn) - && DECL_NONSTATIC_MEMBER_FUNCTION_P (decl)) - { - /* Sometimes we are trying to figure out what's being - specialized by a declaration that looks like a method, and it - turns out to be a static member function. */ - if (CLASSTYPE_TEMPLATE_INFO (DECL_REAL_CONTEXT (fn)) - && !is_member_template (fn)) - /* The natural thing to do here seems to be to remove the - spurious `this' parameter from the DECL, but that prevents - unification from making use of the class type. So, - instead, we have fn_type_unification add to the parameters - for FN. */ - extra_fn_arg = build_pointer_type (DECL_REAL_CONTEXT (fn)); - else - /* In this case, though, adding the extra_fn_arg can confuse - things, so we remove from decl_arg_types instead. */ - decl_arg_types = TREE_CHAIN (decl_arg_types); - } - - i = fn_type_unification (fn, explicit_args, targs, - decl_arg_types, - TREE_TYPE (TREE_TYPE (decl)), - DEDUCE_EXACT, - extra_fn_arg); - - if (i != 0) - return NULL_TREE; - - if (check_rettype) - { - /* Check to see that the resulting return type is also OK. */ - tree t = tsubst (TREE_TYPE (TREE_TYPE (fn)), targs, - NULL_TREE); - - if (!same_type_p (t, TREE_TYPE (TREE_TYPE (decl)))) - return NULL_TREE; - } - - return targs; -} - -/* For most uses, we want to check the return type. */ - -tree -get_bindings (fn, decl, explicit_args) - tree fn, decl, explicit_args; -{ - return get_bindings_real (fn, decl, explicit_args, 1); -} - -/* But for more_specialized, we only care about the parameter types. */ - -static tree -get_bindings_overload (fn, decl, explicit_args) - tree fn, decl, explicit_args; -{ - return get_bindings_real (fn, decl, explicit_args, 0); -} - -/* Return the innermost template arguments that, when applied to a - template specialization whose innermost template parameters are - TPARMS, and whose specialization arguments are ARGS, yield the - ARGS. - - For example, suppose we have: - - template <class T, class U> struct S {}; - template <class T> struct S<T*, int> {}; - - Then, suppose we want to get `S<double*, int>'. The TPARMS will be - {T}, the PARMS will be {T*, int} and the ARGS will be {double*, - int}. The resulting vector will be {double}, indicating that `T' - is bound to `double'. */ - -static tree -get_class_bindings (tparms, parms, args) - tree tparms, parms, args; -{ - int i, ntparms = TREE_VEC_LENGTH (tparms); - tree vec = make_temp_vec (ntparms); - - args = innermost_args (args); - - for (i = 0; i < TREE_VEC_LENGTH (parms); ++i) - { - switch (unify (tparms, vec, - TREE_VEC_ELT (parms, i), TREE_VEC_ELT (args, i), - UNIFY_ALLOW_NONE, 0)) - { - case 0: - break; - case 1: - return NULL_TREE; - } - } - - for (i = 0; i < ntparms; ++i) - if (! TREE_VEC_ELT (vec, i)) - return NULL_TREE; - - return vec; -} - -/* In INSTANTIATIONS is a list of <INSTANTIATION, TEMPLATE> pairs. - Pick the most specialized template, and return the corresponding - 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 - at all, NULL_TREE is returned. */ - -tree -most_specialized_instantiation (instantiations, explicit_args) - tree instantiations; - tree explicit_args; -{ - tree fn, champ; - int fate; - - if (!instantiations) - return NULL_TREE; - - champ = instantiations; - for (fn = TREE_CHAIN (instantiations); fn; fn = TREE_CHAIN (fn)) - { - fate = more_specialized (TREE_VALUE (champ), - TREE_VALUE (fn), explicit_args); - if (fate == 1) - ; - else - { - if (fate == 0) - { - fn = TREE_CHAIN (fn); - if (! fn) - return error_mark_node; - } - champ = fn; - } - } - - for (fn = instantiations; fn && fn != champ; fn = TREE_CHAIN (fn)) - { - fate = more_specialized (TREE_VALUE (champ), - TREE_VALUE (fn), explicit_args); - if (fate != 1) - return error_mark_node; - } - - return TREE_PURPOSE (champ) ? TREE_PURPOSE (champ) : TREE_VALUE (champ); -} - -/* Return the most specialized of the list of templates in FNS that can - produce an instantiation matching DECL, given the explicit template - arguments EXPLICIT_ARGS. */ - -static tree -most_specialized (fns, decl, explicit_args) - tree fns, decl, explicit_args; -{ - tree candidates = NULL_TREE; - tree fn, args; - - for (fn = fns; fn; fn = TREE_CHAIN (fn)) - { - tree candidate = TREE_VALUE (fn); - - args = get_bindings (candidate, decl, explicit_args); - if (args) - candidates = scratch_tree_cons (NULL_TREE, candidate, - candidates); - } - - return most_specialized_instantiation (candidates, explicit_args); -} - -/* If DECL is a specialization of some template, return the most - general such template. For example, given: - - template <class T> struct S { template <class U> void f(U); }; - - if TMPL is `template <class U> void S<int>::f(U)' this will return - the full template. This function will not trace past partial - specializations, however. For example, given in addition: - - template <class T> struct S<T*> { template <class U> void f(U); }; - - if TMPL is `template <class U> void S<int*>::f(U)' this will return - `template <class T> template <class U> S<T*>::f(U)'. */ - -static tree -most_general_template (decl) - tree decl; -{ - while (DECL_TEMPLATE_INFO (decl)) - decl = DECL_TI_TEMPLATE (decl); - - return decl; -} - -/* Return the most specialized of the class template specializations - of TMPL which can produce an instantiation matching ARGS, or - error_mark_node if the choice is ambiguous. */ - -static tree -most_specialized_class (tmpl, args) - tree tmpl; - tree args; -{ - tree list = NULL_TREE; - tree t; - tree champ; - int fate; - - tmpl = most_general_template (tmpl); - for (t = DECL_TEMPLATE_SPECIALIZATIONS (tmpl); t; t = TREE_CHAIN (t)) - { - tree spec_args - = get_class_bindings (TREE_VALUE (t), TREE_PURPOSE (t), args); - if (spec_args) - { - list = decl_tree_cons (TREE_PURPOSE (t), TREE_VALUE (t), list); - TREE_TYPE (list) = TREE_TYPE (t); - } - } - - if (! list) - return NULL_TREE; - - t = list; - champ = t; - t = TREE_CHAIN (t); - for (; t; t = TREE_CHAIN (t)) - { - fate = more_specialized_class (champ, t); - if (fate == 1) - ; - else - { - if (fate == 0) - { - t = TREE_CHAIN (t); - if (! t) - return error_mark_node; - } - champ = t; - } - } - - for (t = list; t && t != champ; t = TREE_CHAIN (t)) - { - fate = more_specialized_class (champ, t); - if (fate != 1) - return error_mark_node; - } - - return champ; -} - -/* called from the parser. */ - -void -do_decl_instantiation (declspecs, declarator, storage) - tree declspecs, declarator, storage; -{ - tree decl = grokdeclarator (declarator, declspecs, NORMAL, 0, NULL_TREE); - tree result = NULL_TREE; - int extern_p = 0; - - if (! DECL_LANG_SPECIFIC (decl)) - { - cp_error ("explicit instantiation of non-template `%#D'", decl); - return; - } - else if (TREE_CODE (decl) == VAR_DECL) - { - /* There is an asymmetry here in the way VAR_DECLs and - FUNCTION_DECLs are handled by grokdeclarator. In the case of - the latter, the DECL we get back will be marked as a - template instantiation, and the appropriate - DECL_TEMPLATE_INFO will be set up. This does not happen for - VAR_DECLs so we do the lookup here. Probably, grokdeclarator - should handle VAR_DECLs as it currently handles - FUNCTION_DECLs. */ - result = lookup_field (DECL_CONTEXT (decl), DECL_NAME (decl), 0, 0); - if (result && TREE_CODE (result) != VAR_DECL) - { - cp_error ("no matching template for `%D' found", result); - return; - } - } - else if (TREE_CODE (decl) != FUNCTION_DECL) - { - cp_error ("explicit instantiation of `%#D'", decl); - return; - } - else - result = decl; - - /* Check for various error cases. Note that if the explicit - instantiation is legal the RESULT will currently be marked as an - *implicit* instantiation; DECL_EXPLICIT_INSTANTIATION is not set - until we get here. */ - - if (DECL_TEMPLATE_SPECIALIZATION (result)) - { - /* [temp.spec] - - No program shall both explicitly instantiate and explicitly - specialize a template. */ - cp_error ("explicit instantiation of `%#D' after", result); - cp_error_at ("explicit specialization here", result); - return; - } - else if (DECL_EXPLICIT_INSTANTIATION (result)) - { - /* [temp.spec] - - No program shall explicitly instantiate any template more - than once. - - We check DECL_INTERFACE_KNOWN so as not to complain when the - first instantiation was `extern' and the second is not, and - EXTERN_P for the opposite case. */ - if (DECL_INTERFACE_KNOWN (result) && !extern_p) - cp_error ("duplicate explicit instantiation of `%#D'", result); - - /* If we've already instantiated the template, just return now. */ - if (DECL_INTERFACE_KNOWN (result)) - return; - } - else if (!DECL_IMPLICIT_INSTANTIATION (result)) - { - cp_error ("no matching template for `%D' found", result); - return; - } - else if (!DECL_TEMPLATE_INFO (result)) - { - cp_pedwarn ("explicit instantiation of non-template `%#D'", result); - return; - } - - if (flag_external_templates) - return; - - if (storage == NULL_TREE) - ; - else if (storage == ridpointers[(int) RID_EXTERN]) - { - if (pedantic) - cp_pedwarn ("ANSI C++ forbids the use of `extern' on explicit instantiations"); - extern_p = 1; - } - else - cp_error ("storage class `%D' applied to template instantiation", - storage); - - SET_DECL_EXPLICIT_INSTANTIATION (result); - mark_decl_instantiated (result, extern_p); - repo_template_instantiated (result, extern_p); - if (! extern_p) - instantiate_decl (result); -} - -void -mark_class_instantiated (t, extern_p) - tree t; - int extern_p; -{ - SET_CLASSTYPE_EXPLICIT_INSTANTIATION (t); - SET_CLASSTYPE_INTERFACE_KNOWN (t); - CLASSTYPE_INTERFACE_ONLY (t) = extern_p; - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = ! extern_p; - TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = extern_p; - if (! extern_p) - { - CLASSTYPE_DEBUG_REQUESTED (t) = 1; - rest_of_type_compilation (t, 1); - } -} - -void -do_type_instantiation (t, storage) - tree t, storage; -{ - int extern_p = 0; - int nomem_p = 0; - int static_p = 0; - - if (TREE_CODE (t) == TYPE_DECL) - t = TREE_TYPE (t); - - if (! CLASS_TYPE_P (t) || ! CLASSTYPE_TEMPLATE_INFO (t)) - { - cp_error ("explicit instantiation of non-template type `%T'", t); - return; - } - - complete_type (t); - - /* With -fexternal-templates, explicit instantiations are treated the same - as implicit ones. */ - if (flag_external_templates) - return; - - if (TYPE_SIZE (t) == NULL_TREE) - { - cp_error ("explicit instantiation of `%#T' before definition of template", - t); - return; - } - - if (storage != NULL_TREE) - { - if (pedantic) - cp_pedwarn("ANSI C++ forbids the use of `%s' on explicit instantiations", - IDENTIFIER_POINTER (storage)); - - if (storage == ridpointers[(int) RID_INLINE]) - nomem_p = 1; - else if (storage == ridpointers[(int) RID_EXTERN]) - extern_p = 1; - else if (storage == ridpointers[(int) RID_STATIC]) - static_p = 1; - else - { - cp_error ("storage class `%D' applied to template instantiation", - storage); - extern_p = 0; - } - } - - if (CLASSTYPE_TEMPLATE_SPECIALIZATION (t)) - { - /* [temp.spec] - - No program shall both explicitly instantiate and explicitly - specialize a template. */ - cp_error ("explicit instantiation of `%#T' after", t); - cp_error_at ("explicit specialization here", t); - return; - } - else if (CLASSTYPE_EXPLICIT_INSTANTIATION (t)) - { - /* [temp.spec] - - No program shall explicitly instantiate any template more - than once. - - If CLASSTYPE_INTERFACE_ONLY, then the first explicit - instantiation was `extern', and if EXTERN_P then the second - is. Both cases are OK. */ - if (!CLASSTYPE_INTERFACE_ONLY (t) && !extern_p) - cp_error ("duplicate explicit instantiation of `%#T'", t); - - /* If we've already instantiated the template, just return now. */ - if (!CLASSTYPE_INTERFACE_ONLY (t)) - return; - } - - mark_class_instantiated (t, extern_p); - repo_template_instantiated (t, extern_p); - - if (nomem_p) - return; - - { - tree tmp; - - /* In contrast to implicit instantiation, where only the - declarations, and not the definitions, of members are - instantiated, we have here: - - [temp.explicit] - - The explicit instantiation of a class template specialization - implies the instantiation of all of its members not - previously explicitly specialized in the translation unit - containing the explicit instantiation. - - Of course, we can't instantiate member template classes, since - we don't have any arguments for them. Note that the standard - is unclear on whether the instatiation of the members are - *explicit* instantiations or not. We choose to be generous, - and not set DECL_EXPLICIT_INSTANTIATION. Therefore, we allow - the explicit instantiation of a class where some of the members - have no definition in the current translation unit. */ - - if (! static_p) - for (tmp = TYPE_METHODS (t); tmp; tmp = TREE_CHAIN (tmp)) - if (TREE_CODE (tmp) == FUNCTION_DECL - && DECL_TEMPLATE_INSTANTIATION (tmp)) - { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp); - } - - for (tmp = TYPE_FIELDS (t); tmp; tmp = TREE_CHAIN (tmp)) - if (TREE_CODE (tmp) == VAR_DECL && DECL_TEMPLATE_INSTANTIATION (tmp)) - { - mark_decl_instantiated (tmp, extern_p); - repo_template_instantiated (tmp, extern_p); - if (! extern_p) - instantiate_decl (tmp); - } - - for (tmp = CLASSTYPE_TAGS (t); tmp; tmp = TREE_CHAIN (tmp)) - if (IS_AGGR_TYPE (TREE_VALUE (tmp)) - && !uses_template_parms (CLASSTYPE_TI_ARGS (TREE_VALUE (tmp)))) - do_type_instantiation (TYPE_MAIN_DECL (TREE_VALUE (tmp)), storage); - } -} - -/* Given a function DECL, which is a specialization of TMPL, modify - DECL to be a re-instantiation of TMPL with the same template - arguments. TMPL should be the template into which tsubst'ing - should occur for DECL, not the most general template. - - One reason for doing this is a scenario like this: - - template <class T> - void f(const T&, int i); - - void g() { f(3, 7); } - - template <class T> - void f(const T& t, const int i) { } - - Note that when the template is first instantiated, with - instantiate_template, the resulting DECL will have no name for the - first parameter, and the wrong type for the second. So, when we go - to instantiate the DECL, we regenerate it. */ - -static void -regenerate_decl_from_template (decl, tmpl) - tree decl; - tree tmpl; -{ - tree args; - tree code_pattern; - tree new_decl; - tree gen_tmpl; - int unregistered; - - args = DECL_TI_ARGS (decl); - code_pattern = DECL_TEMPLATE_RESULT (tmpl); - - /* Unregister the specialization so that when we tsubst we will not - just return DECL. We don't have to unregister DECL from TMPL - because if would only be registered there if it were a partial - instantiation of a specialization, which it isn't: it's a full - instantiation. */ - gen_tmpl = most_general_template (tmpl); - unregistered = unregister_specialization (decl, gen_tmpl); - - /* If the DECL was not unregistered then something peculiar is - happening: we created a specialization but did not call - register_specialization for it. */ - my_friendly_assert (unregistered, 0); - - if (TREE_CODE (decl) == VAR_DECL) - /* Make sure that we can see identifiers, and compute access - correctly, for the class members used in the declaration of - this static variable. */ - pushclass (DECL_CONTEXT (decl), 2); - - /* Do the substitution to get the new declaration. */ - new_decl = tsubst (code_pattern, args, NULL_TREE); - - if (TREE_CODE (decl) == VAR_DECL) - { - /* Set up DECL_INITIAL, since tsubst doesn't. */ - DECL_INITIAL (new_decl) = - tsubst_expr (DECL_INITIAL (code_pattern), args, - DECL_TI_TEMPLATE (decl)); - /* Pop the class context we pushed above. */ - popclass (1); - } - - if (TREE_CODE (decl) == FUNCTION_DECL) - { - /* Convince duplicate_decls to use the DECL_ARGUMENTS from the - new decl. */ - DECL_INITIAL (new_decl) = error_mark_node; - /* And don't complain about a duplicate definition. */ - DECL_INITIAL (decl) = NULL_TREE; - } - - /* The immediate parent of the new template is still whatever it was - before, even though tsubst sets DECL_TI_TEMPLATE up as the most - general template. We also reset the DECL_ASSEMBLER_NAME since - tsubst always calculates the name as if the function in question - were really a template instance, and sometimes, with friend - functions, this is not so. See tsubst_friend_function for - details. */ - DECL_TI_TEMPLATE (new_decl) = DECL_TI_TEMPLATE (decl); - DECL_ASSEMBLER_NAME (new_decl) = DECL_ASSEMBLER_NAME (decl); - DECL_RTL (new_decl) = DECL_RTL (decl); - - /* Call duplicate decls to merge the old and new declarations. */ - duplicate_decls (new_decl, decl); - - /* Now, re-register the specialization. */ - register_specialization (decl, gen_tmpl, args); -} - -/* Produce the definition of D, a _DECL generated from a template. */ - -tree -instantiate_decl (d) - tree d; -{ - tree tmpl = DECL_TI_TEMPLATE (d); - tree args = DECL_TI_ARGS (d); - tree td; - tree code_pattern; - tree spec; - tree gen_tmpl; - int nested = in_function_p (); - int pattern_defined; - int line = lineno; - char *file = input_filename; - - /* This function should only be used to instantiate templates for - functions and static member variables. */ - my_friendly_assert (TREE_CODE (d) == FUNCTION_DECL - || TREE_CODE (d) == VAR_DECL, 0); - - if (DECL_TEMPLATE_INSTANTIATED (d)) - /* D has already been instantiated. It might seem reasonable to - check whether or not D is an explict instantiation, and, if so, - stop here. But when an explicit instantiation is deferred - until the end of the compilation, DECL_EXPLICIT_INSTANTIATION - is set, even though we still need to do the instantiation. */ - return d; - - /* If we already have a specialization of this declaration, then - there's no reason to instantiate it. Note that - retrieve_specialization gives us both instantiations and - specializations, so we must explicitly check - DECL_TEMPLATE_SPECIALIZATION. */ - gen_tmpl = most_general_template (tmpl); - spec = retrieve_specialization (gen_tmpl, args); - if (spec != NULL_TREE && DECL_TEMPLATE_SPECIALIZATION (spec)) - return spec; - - /* This needs to happen before any tsubsting. */ - if (! push_tinst_level (d)) - return d; - - /* Set TD to the template whose DECL_TEMPLATE_RESULT is the pattern - for the instantiation. This is not always the most general - template. Consider, for example: - - template <class T> - struct S { template <class U> void f(); - template <> void f<int>(); }; - - and an instantiation of S<double>::f<int>. We want TD to be the - specialization S<T>::f<int>, not the more general S<T>::f<U>. */ - td = tmpl; - for (td = tmpl; - /* An instantiation cannot have a definition, so we need a - more general template. */ - DECL_TEMPLATE_INSTANTIATION (td) - /* We must also deal with friend templates. Given: - - template <class T> struct S { - template <class U> friend void f() {}; - }; - - S<int>::f<U> say, is not an instantiation of S<T>::f<U>, - so far as the language is concerned, but that's still - where we get the pattern for the instantiation from. On - ther hand, if the definition comes outside the class, say: - - template <class T> struct S { - template <class U> friend void f(); - }; - template <class U> friend void f() {} - - we don't need to look any further. That's what the check for - DECL_INITIAL is for. */ - || (TREE_CODE (d) == FUNCTION_DECL - && DECL_FRIEND_PSEUDO_TEMPLATE_INSTANTIATION (td) - && !DECL_INITIAL (DECL_TEMPLATE_RESULT (td))); - ) - { - /* The present template, TD, should not be a definition. If it - were a definition, we should be using it! Note that we - cannot restructure the loop to just keep going until we find - a template with a definition, since that might go too far if - a specialization was declared, but not defined. */ - my_friendly_assert (!(TREE_CODE (d) == VAR_DECL - && !DECL_IN_AGGR_P (DECL_TEMPLATE_RESULT (td))), - 0); - - /* Fetch the more general template. */ - td = DECL_TI_TEMPLATE (td); - } - - code_pattern = DECL_TEMPLATE_RESULT (td); - - if (TREE_CODE (d) == FUNCTION_DECL) - pattern_defined = (DECL_INITIAL (code_pattern) != NULL_TREE); - else - pattern_defined = ! DECL_IN_AGGR_P (code_pattern); - - push_to_top_level (); - lineno = DECL_SOURCE_LINE (d); - input_filename = DECL_SOURCE_FILE (d); - - if (pattern_defined) - { - repo_template_used (d); - - if (flag_external_templates && ! DECL_INTERFACE_KNOWN (d)) - { - if (flag_alt_external_templates) - { - if (interface_unknown) - warn_if_unknown_interface (d); - } - else if (DECL_INTERFACE_KNOWN (code_pattern)) - { - DECL_INTERFACE_KNOWN (d) = 1; - DECL_NOT_REALLY_EXTERN (d) = ! DECL_EXTERNAL (code_pattern); - } - else - warn_if_unknown_interface (code_pattern); - } - - if (at_eof) - import_export_decl (d); - } - - /* Reject all external templates except inline functions. */ - if (DECL_INTERFACE_KNOWN (d) - && ! DECL_NOT_REALLY_EXTERN (d) - && ! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d))) - goto out; - - if (TREE_CODE (d) == VAR_DECL - && TREE_READONLY (d) - && DECL_INITIAL (d) == NULL_TREE - && DECL_INITIAL (code_pattern) != NULL_TREE) - /* We need to set up DECL_INITIAL regardless of pattern_defined if - the variable is a static const initialized in the class body. */; - else if (! pattern_defined - || (! (TREE_CODE (d) == FUNCTION_DECL && DECL_INLINE (d) && nested) - && ! at_eof)) - { - /* Defer all templates except inline functions used in another - function. We restore the source position here because it's used - by add_pending_template. */ - lineno = line; - input_filename = file; - - if (at_eof && !pattern_defined - && DECL_EXPLICIT_INSTANTIATION (d)) - /* [temp.explicit] - - The definition of a non-exported function template, a - non-exported member function template, or a non-exported - member function or static data member of a class template - shall be present in every translation unit in which it is - explicitly instantiated. */ - cp_error ("explicit instantiation of `%D' but no definition available", - d); - - add_pending_template (d); - goto out; - } - - regenerate_decl_from_template (d, td); - DECL_TEMPLATE_INSTANTIATED (d) = 1; - - /* We already set the file and line above. Reset them now in case - they changed as a result of calling regenerate_decl_from_template. */ - lineno = DECL_SOURCE_LINE (d); - input_filename = DECL_SOURCE_FILE (d); - - if (TREE_CODE (d) == VAR_DECL) - { - DECL_IN_AGGR_P (d) = 0; - if (DECL_INTERFACE_KNOWN (d)) - DECL_EXTERNAL (d) = ! DECL_NOT_REALLY_EXTERN (d); - else - { - DECL_EXTERNAL (d) = 1; - DECL_NOT_REALLY_EXTERN (d) = 1; - } - cp_finish_decl (d, DECL_INITIAL (d), NULL_TREE, 0, 0); - } - else if (TREE_CODE (d) == FUNCTION_DECL) - { - tree t = DECL_SAVED_TREE (code_pattern); - - start_function (NULL_TREE, d, NULL_TREE, 1); - store_parm_decls (); - - if (t && TREE_CODE (t) == RETURN_INIT) - { - store_return_init - (TREE_OPERAND (t, 0), - tsubst_expr (TREE_OPERAND (t, 1), args, tmpl)); - t = TREE_CHAIN (t); - } - - if (t && TREE_CODE (t) == CTOR_INITIALIZER) - { - current_member_init_list - = tsubst_expr_values (TREE_OPERAND (t, 0), args); - current_base_init_list - = tsubst_expr_values (TREE_OPERAND (t, 1), args); - t = TREE_CHAIN (t); - } - - setup_vtbl_ptr (); - /* Always keep the BLOCK node associated with the outermost - pair of curly braces of a function. These are needed - for correct operation of dwarfout.c. */ - keep_next_level (); - - my_friendly_assert (TREE_CODE (t) == COMPOUND_STMT, 42); - tsubst_expr (t, args, tmpl); - - finish_function (lineno, 0, nested); - } - -out: - lineno = line; - input_filename = file; - - pop_from_top_level (); - pop_tinst_level (); - - return d; -} - -static tree -tsubst_expr_values (t, argvec) - tree t, argvec; -{ - tree first = NULL_TREE; - tree *p = &first; - - for (; t; t = TREE_CHAIN (t)) - { - tree pur = tsubst_copy (TREE_PURPOSE (t), argvec, NULL_TREE); - tree val = tsubst_expr (TREE_VALUE (t), argvec, NULL_TREE); - *p = build_tree_list (pur, val); - p = &TREE_CHAIN (*p); - } - return first; -} - -tree last_tree; - -void -add_tree (t) - tree t; -{ - last_tree = TREE_CHAIN (last_tree) = t; -} - - -void -begin_tree () -{ - saved_trees = tree_cons (NULL_TREE, last_tree, saved_trees); - last_tree = NULL_TREE; -} - - -void -end_tree () -{ - my_friendly_assert (saved_trees != NULL_TREE, 0); - - last_tree = TREE_VALUE (saved_trees); - saved_trees = TREE_CHAIN (saved_trees); -} - -/* D is an undefined function declaration in the presence of templates with - the same name, listed in FNS. If one of them can produce D as an - instantiation, remember this so we can instantiate it at EOF if D has - not been defined by that time. */ - -void -add_maybe_template (d, fns) - tree d, fns; -{ - tree t; - - if (DECL_MAYBE_TEMPLATE (d)) - return; - - t = most_specialized (fns, d, NULL_TREE); - if (! t) - return; - if (t == error_mark_node) - { - cp_error ("ambiguous template instantiation for `%D'", d); - return; - } - - *maybe_template_tail = perm_tree_cons (t, d, NULL_TREE); - maybe_template_tail = &TREE_CHAIN (*maybe_template_tail); - DECL_MAYBE_TEMPLATE (d) = 1; -} - -/* Set CURRENT_ACCESS_SPECIFIER based on the protection of DECL. */ - -static void -set_current_access_from_decl (decl) - tree decl; -{ - if (TREE_PRIVATE (decl)) - current_access_specifier = access_private_node; - else if (TREE_PROTECTED (decl)) - current_access_specifier = access_protected_node; - else - current_access_specifier = access_public_node; -} - -/* Instantiate an enumerated type. TAG is the template type, NEWTAG - is the instantiation (which should have been created with - start_enum) and ARGS are the template arguments to use. */ - -static void -tsubst_enum (tag, newtag, args) - tree tag; - tree newtag; - tree args; -{ - tree e; - - for (e = TYPE_VALUES (tag); e; e = TREE_CHAIN (e)) - { - tree value; - tree elt; - - /* Note that in a template enum, the TREE_VALUE is the - CONST_DECL, not the corresponding INTEGER_CST. */ - value = tsubst_expr (DECL_INITIAL (TREE_VALUE (e)), - args, - NULL_TREE); - - /* Give this enumeration constant the correct access. */ - set_current_access_from_decl (TREE_VALUE (e)); - - /* Actually build the enumerator itself. */ - elt = build_enumerator (TREE_PURPOSE (e), value, newtag); - - /* We save the enumerators we have built so far in the - TYPE_VALUES so that if the enumeration constants for - subsequent enumerators involve those for previous ones, - tsubst_copy will be able to find them. */ - TREE_CHAIN (elt) = TYPE_VALUES (newtag); - TYPE_VALUES (newtag) = elt; - } - - finish_enum (newtag); -} - -/* Set the DECL_ASSEMBLER_NAME for DECL, which is a FUNCTION_DECL that - is either an instantiation or specialization of a template - function. */ - -static void -set_mangled_name_for_template_decl (decl) - tree decl; -{ - tree saved_namespace; - tree context = NULL_TREE; - tree fn_type; - tree ret_type; - tree parm_types; - tree tparms; - tree targs; - tree tmpl; - int parm_depth; - - my_friendly_assert (TREE_CODE (decl) == FUNCTION_DECL, 0); - my_friendly_assert (DECL_TEMPLATE_INFO (decl) != NULL_TREE, 0); - - /* The names of template functions must be mangled so as to indicate - what template is being specialized with what template arguments. - For example, each of the following three functions must get - different mangled names: - - void f(int); - template <> void f<7>(int); - template <> void f<8>(int); */ - - targs = DECL_TI_ARGS (decl); - if (uses_template_parms (targs)) - /* This DECL is for a partial instantiation. There's no need to - mangle the name of such an entity. */ - return; - - tmpl = most_general_template (DECL_TI_TEMPLATE (decl)); - tparms = DECL_TEMPLATE_PARMS (tmpl); - parm_depth = TMPL_PARMS_DEPTH (tparms); - - /* There should be as many levels of arguments as there are levels - of parameters. */ - my_friendly_assert (parm_depth == TMPL_ARGS_DEPTH (targs), 0); - - /* We now compute the PARMS and RET_TYPE to give to - build_decl_overload_real. The PARMS and RET_TYPE are the - parameter and return types of the template, after all but the - innermost template arguments have been substituted, not the - parameter and return types of the function DECL. For example, - given: - - template <class T> T f(T); - - both PARMS and RET_TYPE should be `T' even if DECL is `int f(int)'. - A more subtle example is: - - template <class T> struct S { template <class U> void f(T, U); } - - Here, if DECL is `void S<int>::f(int, double)', PARMS should be - {int, U}. Thus, the args that we want to subsitute into the - return and parameter type for the function are those in TARGS, - with the innermost level omitted. */ - fn_type = TREE_TYPE (tmpl); - if (DECL_STATIC_FUNCTION_P (decl)) - context = DECL_CLASS_CONTEXT (decl); - - if (parm_depth == 1) - /* No substitution is necessary. */ - ; - else - { - int i; - tree partial_args; - - /* Replace the innermost level of the TARGS with NULL_TREEs to - let tsubst know not to subsitute for those parameters. */ - partial_args = make_temp_vec (TREE_VEC_LENGTH (targs)); - for (i = 1; i < TMPL_ARGS_DEPTH (targs); ++i) - SET_TMPL_ARGS_LEVEL (partial_args, i, - TMPL_ARGS_LEVEL (targs, i)); - SET_TMPL_ARGS_LEVEL (partial_args, - TMPL_ARGS_DEPTH (targs), - make_temp_vec (DECL_NTPARMS (tmpl))); - - /* Now, do the (partial) substitution to figure out the - appropriate function type. */ - fn_type = tsubst (fn_type, partial_args, NULL_TREE); - if (DECL_STATIC_FUNCTION_P (decl)) - context = tsubst (context, partial_args, NULL_TREE); - - /* Substitute into the template parameters to obtain the real - innermost set of parameters. This step is important if the - innermost set of template parameters contains value - parameters whose types depend on outer template parameters. */ - TREE_VEC_LENGTH (partial_args)--; - tparms = tsubst_template_parms (tparms, partial_args); - } - - /* Now, get the innermost parameters and arguments, and figure out - the parameter and return types. */ - tparms = INNERMOST_TEMPLATE_PARMS (tparms); - targs = innermost_args (targs); - ret_type = TREE_TYPE (fn_type); - parm_types = TYPE_ARG_TYPES (fn_type); - - /* For a static member function, we generate a fake `this' pointer, - for the purposes of mangling. This indicates of which class the - function is a member. Because of: - - [class.static] - - There shall not be a static and a nonstatic member function - with the same name and the same parameter types - - we don't have to worry that this will result in a clash with a - non-static member function. */ - if (DECL_STATIC_FUNCTION_P (decl)) - parm_types = hash_tree_chain (build_pointer_type (context), parm_types); - - /* There should be the same number of template parameters as - template arguments. */ - my_friendly_assert (TREE_VEC_LENGTH (tparms) == TREE_VEC_LENGTH (targs), - 0); - - /* If the template is in a namespace, we need to put that into the - mangled name. Unfortunately, build_decl_overload_real does not - get the decl to mangle, so it relies on the current - namespace. Therefore, we set that here temporarily. */ - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (decl)) == 'd', 980702); - saved_namespace = current_namespace; - current_namespace = CP_DECL_CONTEXT (decl); - - /* Actually set the DCL_ASSEMBLER_NAME. */ - DECL_ASSEMBLER_NAME (decl) - = build_decl_overload_real (DECL_NAME (decl), parm_types, ret_type, - tparms, targs, - DECL_FUNCTION_MEMBER_P (decl) - + DECL_CONSTRUCTOR_P (decl)); - - /* Restore the previously active namespace. */ - current_namespace = saved_namespace; -} diff --git a/gcc/cp/ptree.c b/gcc/cp/ptree.c deleted file mode 100755 index 4fb0413..0000000 --- a/gcc/cp/ptree.c +++ /dev/null @@ -1,192 +0,0 @@ -/* Prints out trees in human readable form. - Copyright (C) 1992, 93-96, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" - -void -print_lang_decl (file, node, indent) - FILE *file; - tree node; - int indent; -{ - if (!DECL_LANG_SPECIFIC (node)) - return; - /* A FIELD_DECL only has the flags structure, which we aren't displaying - anyways. */ - if (DECL_MUTABLE_P (node)) - { - indent_to (file, indent + 3); - fprintf (file, " mutable "); - } - if (TREE_CODE (node) == FIELD_DECL) - return; - indent_to (file, indent + 3); - if (DECL_MAIN_VARIANT (node)) - { - fprintf (file, " decl-main-variant "); - fprintf (file, HOST_PTR_PRINTF, DECL_MAIN_VARIANT (node)); - } - if (DECL_PENDING_INLINE_INFO (node)) - { - fprintf (file, " pending-inline-info "); - fprintf (file, HOST_PTR_PRINTF, DECL_PENDING_INLINE_INFO (node)); - } - if (DECL_TEMPLATE_INFO (node)) - { - fprintf (file, " template-info "); - fprintf (file, HOST_PTR_PRINTF, DECL_TEMPLATE_INFO (node)); - } -} - -void -print_lang_type (file, node, indent) - FILE *file; - register tree node; - int indent; -{ - if (TREE_CODE (node) == TEMPLATE_TYPE_PARM - || TREE_CODE (node) == TEMPLATE_TEMPLATE_PARM) - { - indent_to (file, indent + 3); - fputs ("index ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_IDX (node)); - fputs (" level ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_LEVEL (node)); - fputs (" orig_level ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_TYPE_ORIG_LEVEL (node)); - return; - } - - if (! (TREE_CODE (node) == RECORD_TYPE - || TREE_CODE (node) == UNION_TYPE)) - return; - - if (!TYPE_LANG_SPECIFIC (node)) - return; - - indent_to (file, indent + 3); - - if (TYPE_NEEDS_CONSTRUCTING (node)) - fputs ( "needs-constructor", file); - if (TYPE_NEEDS_DESTRUCTOR (node)) - fputs (" needs-destructor", file); - if (TYPE_HAS_DESTRUCTOR (node)) - fputs (" ~X()", file); - if (TYPE_HAS_DEFAULT_CONSTRUCTOR (node)) - fputs (" X()", file); - if (TYPE_HAS_CONVERSION (node)) - fputs (" has-type-conversion", file); - if (TYPE_HAS_INIT_REF (node)) - { - if (TYPE_HAS_CONST_INIT_REF (node)) - fputs (" X(constX&)", file); - else - fputs (" X(X&)", file); - } - if (TYPE_GETS_NEW (node) & 1) - fputs (" new", file); - if (TYPE_GETS_NEW (node) & 2) - fputs (" new[]", file); - if (TYPE_GETS_DELETE (node) & 1) - fputs (" delete", file); - if (TYPE_GETS_DELETE (node) & 2) - fputs (" delete[]", file); - if (TYPE_HAS_ASSIGNMENT (node)) - fputs (" has=", file); - if (TYPE_HAS_ASSIGN_REF (node)) - fputs (" this=(X&)", file); - if (TYPE_OVERLOADS_CALL_EXPR (node)) - fputs (" op()", file); - if (TYPE_OVERLOADS_ARRAY_REF (node)) - fputs (" op[]", file); - if (TYPE_OVERLOADS_ARROW (node)) - fputs (" op->", file); - if (TYPE_USES_MULTIPLE_INHERITANCE (node)) - fputs (" uses-multiple-inheritance", file); - - if (TREE_CODE (node) == RECORD_TYPE) - { - fprintf (file, " n_parents %d n_ancestors %d", - CLASSTYPE_N_BASECLASSES (node), - CLASSTYPE_N_SUPERCLASSES (node)); - fprintf (file, " use_template=%d", CLASSTYPE_USE_TEMPLATE (node)); - if (CLASSTYPE_INTERFACE_ONLY (node)) - fprintf (file, " interface-only"); - if (CLASSTYPE_INTERFACE_UNKNOWN (node)) - fprintf (file, " interface-unknown"); - print_node (file, "member-functions", CLASSTYPE_METHOD_VEC (node), - indent + 4); - print_node (file, "baselinks", - TYPE_BINFO_BASETYPES (node) ? CLASSTYPE_BASELINK_VEC (node) : NULL_TREE, - indent + 4); - } -} - -void -print_lang_identifier (file, node, indent) - FILE *file; - tree node; - int indent; -{ - print_node (file, "bindings", IDENTIFIER_NAMESPACE_BINDINGS (node), indent + 4); - print_node (file, "class", IDENTIFIER_CLASS_VALUE (node), indent + 4); - print_node (file, "local bindings", IDENTIFIER_BINDING (node), indent + 4); - print_node (file, "label", IDENTIFIER_LABEL_VALUE (node), indent + 4); - print_node (file, "template", IDENTIFIER_TEMPLATE (node), indent + 4); - print_node (file, "implicit", IDENTIFIER_IMPLICIT_DECL (node), indent + 4); - print_node (file, "error locus", IDENTIFIER_ERROR_LOCUS (node), indent + 4); -} - -void -lang_print_xnode (file, node, indent) - FILE *file; - tree node; - int indent; -{ - switch (TREE_CODE (node)) - { - case CPLUS_BINDING: - fprintf (file, " scope "); - fprintf (file, HOST_PTR_PRINTF, BINDING_SCOPE (node)); - print_node (file, "value", BINDING_VALUE (node), indent+4); - print_node (file, "chain", TREE_CHAIN (node), indent+4); - break; - case OVERLOAD: - print_node (file, "function", OVL_FUNCTION (node), indent+4); - print_node (file, "chain", TREE_CHAIN (node), indent+4); - break; - case TEMPLATE_PARM_INDEX: - indent_to (file, indent + 3); - fputs ("index ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_IDX (node)); - fputs (" level ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_LEVEL (node)); - fputs (" orig_level ", file); - fprintf (file, HOST_WIDE_INT_PRINT_DEC, TEMPLATE_PARM_ORIG_LEVEL (node)); - break; - default: - break; - } -} diff --git a/gcc/cp/repo.c b/gcc/cp/repo.c deleted file mode 100755 index 90ce845..0000000 --- a/gcc/cp/repo.c +++ /dev/null @@ -1,447 +0,0 @@ -/* Code to maintain a C++ template repository. - Copyright (C) 1995, 96-97, 1998 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* My strategy here is as follows: - - Everything should be emitted in a translation unit where it is used. - The results of the automatic process should be easily reproducible with - explicit code. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "input.h" -#include "obstack.h" -#include "toplev.h" - -extern char *getpwd PROTO((void)); - -static tree repo_get_id PROTO((tree)); -static char *extract_string PROTO((char **)); -static char *get_base_filename PROTO((char *)); -static void open_repo_file PROTO((char *)); -static char *afgets PROTO((FILE *)); -static void reopen_repo_file_for_write PROTO((void)); - -static tree pending_repo; -static tree original_repo; -static char *repo_name; -static FILE *repo_file; - -static char *old_args, *old_dir, *old_main; - -extern int flag_use_repository; -extern int errorcount, sorrycount; -extern struct obstack temporary_obstack; -extern struct obstack permanent_obstack; - -#define IDENTIFIER_REPO_USED(NODE) (TREE_LANG_FLAG_3 (NODE)) -#define IDENTIFIER_REPO_CHOSEN(NODE) (TREE_LANG_FLAG_4 (NODE)) - -#if 0 -/* Record the flags used to compile this translation unit. */ - -void -repo_compile_flags (argc, argv) - int argc; - char **argv; -{ -} - -/* If this template has not been seen before, add a note to the repository - saying where the declaration was. This may be used to find the - definition at link time. */ - -void -repo_template_declared (t) - tree t; -{} - -/* Note where the definition of a template lives so that instantiations can - be generated later. */ - -void -repo_template_defined (t) - tree t; -{} - -/* Note where the definition of a class lives to that template - instantiations can use it. */ - -void -repo_class_defined (t) - tree t; -{} -#endif - -static tree -repo_get_id (t) - tree t; -{ - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - { - /* If we're not done setting up the class, we may not have set up - the vtable, so going ahead would give the wrong answer. - See g++.pt/instantiate4.C. */ - if (TYPE_SIZE (t) == NULL_TREE || TYPE_BEING_DEFINED (t)) - my_friendly_abort (981113); - - t = TYPE_BINFO_VTABLE (t); - if (t == NULL_TREE) - return t; - } - return DECL_ASSEMBLER_NAME (t); -} - -/* Note that a template has been used. If we can see the definition, offer - to emit it. */ - -void -repo_template_used (t) - tree t; -{ - tree id; - - if (! flag_use_repository) - return; - - id = repo_get_id (t); - if (id == NULL_TREE) - return; - - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - { - if (IDENTIFIER_REPO_CHOSEN (id)) - mark_class_instantiated (t, 0); - } - else if (TREE_CODE_CLASS (TREE_CODE (t)) == 'd') - { - if (IDENTIFIER_REPO_CHOSEN (id)) - mark_decl_instantiated (t, 0); - } - else - my_friendly_abort (1); - - if (! IDENTIFIER_REPO_USED (id)) - { - IDENTIFIER_REPO_USED (id) = 1; - pending_repo = perm_tree_cons (NULL_TREE, id, pending_repo); - } -} - -#if 0 -/* Note that the vtable for a class has been used, and offer to emit it. */ - -static void -repo_vtable_used (t) - tree t; -{ - if (! flag_use_repository) - return; - - pending_repo = perm_tree_cons (NULL_TREE, t, pending_repo); -} - -/* Note that an inline with external linkage has been used, and offer to - emit it. */ - -void -repo_inline_used (fn) - tree fn; -{ - if (! flag_use_repository) - return; - - /* Member functions of polymorphic classes go with their vtables. */ - if (DECL_FUNCTION_MEMBER_P (fn) && TYPE_VIRTUAL_P (DECL_CLASS_CONTEXT (fn))) - { - repo_vtable_used (DECL_CLASS_CONTEXT (fn)); - return; - } - - pending_repo = perm_tree_cons (NULL_TREE, fn, pending_repo); -} - -/* Note that a particular typeinfo node has been used, and offer to - emit it. */ - -void -repo_tinfo_used (ti) - tree ti; -{ -} -#endif - -void -repo_template_instantiated (t, extern_p) - tree t; - int extern_p; -{ - if (! extern_p) - { - tree id = repo_get_id (t); - if (id) - IDENTIFIER_REPO_CHOSEN (id) = 1; - } -} - -/* Parse a reasonable subset of shell quoting syntax. */ - -static char * -extract_string (pp) - char **pp; -{ - char *p = *pp; - int backquote = 0; - int inside = 0; - - for (;;) - { - char c = *p; - if (c == '\0') - break; - ++p; - if (backquote) - obstack_1grow (&temporary_obstack, c); - else if (! inside && c == ' ') - break; - else if (! inside && c == '\\') - backquote = 1; - else if (c == '\'') - inside = !inside; - else - obstack_1grow (&temporary_obstack, c); - } - - obstack_1grow (&temporary_obstack, '\0'); - *pp = p; - return obstack_finish (&temporary_obstack); -} - -static char * -get_base_filename (filename) - char *filename; -{ - char *p = getenv ("COLLECT_GCC_OPTIONS"); - char *output = NULL; - int compiling = 0; - - while (p && *p) - { - char *q = extract_string (&p); - - if (strcmp (q, "-o") == 0) - output = extract_string (&p); - else if (strcmp (q, "-c") == 0) - compiling = 1; - } - - if (compiling && output) - return output; - - if (p && ! compiling) - { - warning ("-frepo must be used with -c"); - flag_use_repository = 0; - return NULL; - } - - return file_name_nondirectory (filename); -} - -static void -open_repo_file (filename) - char *filename; -{ - register char *p; - char *s = get_base_filename (filename); - - if (s == NULL) - return; - - p = file_name_nondirectory (s); - p = rindex (p, '.'); - if (! p) - p = s + strlen (s); - - obstack_grow (&permanent_obstack, s, p - s); - repo_name = obstack_copy0 (&permanent_obstack, ".rpo", 4); - - repo_file = fopen (repo_name, "r"); -} - -static char * -afgets (stream) - FILE *stream; -{ - int c; - while ((c = getc (stream)) != EOF && c != '\n') - obstack_1grow (&temporary_obstack, c); - if (obstack_object_size (&temporary_obstack) == 0) - return NULL; - obstack_1grow (&temporary_obstack, '\0'); - return obstack_finish (&temporary_obstack); -} - -void -init_repo (filename) - char *filename; -{ - char *buf; - - if (! flag_use_repository) - return; - - open_repo_file (filename); - - if (repo_file == 0) - return; - - while ((buf = afgets (repo_file))) - { - switch (buf[0]) - { - case 'A': - old_args = obstack_copy0 (&permanent_obstack, buf + 2, - strlen (buf + 2)); - break; - case 'D': - old_dir = obstack_copy0 (&permanent_obstack, buf + 2, - strlen (buf + 2)); - break; - case 'M': - old_main = obstack_copy0 (&permanent_obstack, buf + 2, - strlen (buf + 2)); - break; - case 'C': - case 'O': - { - tree id = get_identifier (buf + 2); - tree orig; - - if (buf[0] == 'C') - { - IDENTIFIER_REPO_CHOSEN (id) = 1; - orig = integer_one_node; - } - else - orig = NULL_TREE; - - original_repo = perm_tree_cons (orig, id, original_repo); - } - break; - default: - error ("mysterious repository information in %s", repo_name); - } - obstack_free (&temporary_obstack, buf); - } -} - -static void -reopen_repo_file_for_write () -{ - if (repo_file) - fclose (repo_file); - repo_file = fopen (repo_name, "w"); - - if (repo_file == 0) - { - error ("can't create repository information file `%s'", repo_name); - flag_use_repository = 0; - } -} - -/* Emit any pending repos. */ - -void -finish_repo () -{ - tree t; - int repo_changed = 0; - char *dir, *args; - - if (! flag_use_repository) - return; - - /* Do we have to write out a new info file? */ - - /* Are there any old templates that aren't used any longer or that are - newly chosen? */ - - for (t = original_repo; t; t = TREE_CHAIN (t)) - { - if (! IDENTIFIER_REPO_USED (TREE_VALUE (t)) - || (! TREE_PURPOSE (t) && IDENTIFIER_REPO_CHOSEN (TREE_VALUE (t)))) - { - repo_changed = 1; - break; - } - IDENTIFIER_REPO_USED (TREE_VALUE (t)) = 0; - } - - /* Are there any templates that are newly used? */ - - if (! repo_changed) - for (t = pending_repo; t; t = TREE_CHAIN (t)) - { - if (IDENTIFIER_REPO_USED (TREE_VALUE (t))) - { - repo_changed = 1; - break; - } - } - - dir = getpwd (); - args = getenv ("COLLECT_GCC_OPTIONS"); - - if (! repo_changed && pending_repo) - if (strcmp (old_main, main_input_filename) != 0 - || strcmp (old_dir, dir) != 0 - || (args == NULL) != (old_args == NULL) - || (args && strcmp (old_args, args) != 0)) - repo_changed = 1; - - if (! repo_changed || errorcount || sorrycount) - goto out; - - reopen_repo_file_for_write (); - - if (repo_file == 0) - goto out; - - fprintf (repo_file, "M %s\n", main_input_filename); - fprintf (repo_file, "D %s\n", dir); - if (args) - fprintf (repo_file, "A %s\n", args); - - for (t = pending_repo; t; t = TREE_CHAIN (t)) - { - tree val = TREE_VALUE (t); - char type = IDENTIFIER_REPO_CHOSEN (val) ? 'C' : 'O'; - - fprintf (repo_file, "%c %s\n", type, IDENTIFIER_POINTER (val)); - } - - out: - if (repo_file) - fclose (repo_file); -} diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c deleted file mode 100755 index 59b2c93..0000000 --- a/gcc/cp/rtti.c +++ /dev/null @@ -1,1165 +0,0 @@ -/* RunTime Type Identification - Copyright (C) 1995, 96-97, 1998, 1999 Free Software Foundation, Inc. - Mostly written by Jason Merrill (jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" -#include "output.h" -#include "assert.h" -#include "toplev.h" - -#ifndef INT_TYPE_SIZE -#define INT_TYPE_SIZE BITS_PER_WORD -#endif - -extern struct obstack permanent_obstack; - -static tree call_void_fn PROTO((char *)); -static tree build_headof_sub PROTO((tree)); -static tree build_headof PROTO((tree)); -static tree get_tinfo_var PROTO((tree)); -static tree ifnonnull PROTO((tree, tree)); -static tree build_dynamic_cast_1 PROTO((tree, tree)); -static void expand_si_desc PROTO((tree, tree)); -static void expand_class_desc PROTO((tree, tree)); -static void expand_attr_desc PROTO((tree, tree)); -static void expand_ptr_desc PROTO((tree, tree)); -static void expand_generic_desc PROTO((tree, tree, char *)); -static tree throw_bad_cast PROTO((void)); -static tree throw_bad_typeid PROTO((void)); - -tree type_info_type_node; -tree tinfo_fn_id; -tree tinfo_fn_type; - -void -init_rtti_processing () -{ - if (flag_honor_std) - push_namespace (get_identifier ("std")); - type_info_type_node = xref_tag - (class_type_node, get_identifier ("type_info"), 1); - if (flag_honor_std) - pop_namespace (); - tinfo_fn_id = get_identifier ("__tf"); - tinfo_fn_type = build_function_type - (build_reference_type (build_qualified_type (type_info_type_node, - TYPE_QUAL_CONST)), - void_list_node); -} - -/* Given a pointer to an object with at least one virtual table - pointer somewhere, return a pointer to a possible sub-object that - has a virtual table pointer in it that is the vtable parent for - that sub-object. */ - -static tree -build_headof_sub (exp) - tree exp; -{ - tree type = TREE_TYPE (TREE_TYPE (exp)); - tree basetype = CLASSTYPE_RTTI (type); - tree binfo = get_binfo (basetype, type, 0); - - exp = convert_pointer_to_real (binfo, exp); - return exp; -} - -/* Given the expression EXP of type `class *', return the head of the - object pointed to by EXP with type cv void*, if the class has any - virtual functions (TYPE_VIRTUAL_P), else just return the - expression. */ - -static tree -build_headof (exp) - tree exp; -{ - tree type = TREE_TYPE (exp); - tree aref; - tree offset; - - if (TREE_CODE (type) != POINTER_TYPE) - { - error ("`headof' applied to non-pointer type"); - return error_mark_node; - } - type = TREE_TYPE (type); - - if (!TYPE_VIRTUAL_P (type)) - return exp; - - /* If we don't have rtti stuff, get to a sub-object that does. */ - if (!CLASSTYPE_VFIELDS (TREE_TYPE (TREE_TYPE (exp)))) - exp = build_headof_sub (exp); - - /* We use this a couple of times below, protect it. */ - exp = save_expr (exp); - - aref = build_vtbl_ref (build_indirect_ref (exp, NULL_PTR), integer_zero_node); - - if (flag_vtable_thunks) - offset = aref; - else - offset = build_component_ref (aref, delta_identifier, NULL_TREE, 0); - - type = build_qualified_type (ptr_type_node, - CP_TYPE_QUALS (TREE_TYPE (exp))); - return build (PLUS_EXPR, type, exp, - cp_convert (ptrdiff_type_node, offset)); -} - -/* Build a call to a generic entry point taking and returning void. */ - -static tree -call_void_fn (name) - char *name; -{ - tree d = get_identifier (name); - tree type; - - if (IDENTIFIER_GLOBAL_VALUE (d)) - d = IDENTIFIER_GLOBAL_VALUE (d); - else - { - push_obstacks (&permanent_obstack, &permanent_obstack); - - type = build_function_type (void_type_node, void_list_node); - d = build_lang_decl (FUNCTION_DECL, d, type); - DECL_EXTERNAL (d) = 1; - TREE_PUBLIC (d) = 1; - DECL_ARTIFICIAL (d) = 1; - pushdecl_top_level (d); - make_function_rtl (d); - pop_obstacks (); - } - - mark_used (d); - return build_call (d, void_type_node, NULL_TREE); -} - -/* Get a bad_cast node for the program to throw... - - See libstdc++/exception.cc for __throw_bad_cast */ - -static tree -throw_bad_cast () -{ - return call_void_fn ("__throw_bad_cast"); -} - -static tree -throw_bad_typeid () -{ - return call_void_fn ("__throw_bad_typeid"); -} - -/* Return the type_info function associated with the expression EXP. If - EXP is a reference to a polymorphic class, return the dynamic type; - otherwise return the static type of the expression. */ - -tree -get_tinfo_fn_dynamic (exp) - tree exp; -{ - tree type; - - if (exp == error_mark_node) - return error_mark_node; - - if (type_unknown_p (exp)) - { - error ("typeid of overloaded function"); - return error_mark_node; - } - - type = TREE_TYPE (exp); - - /* peel back references, so they match. */ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* Peel off cv qualifiers. */ - type = TYPE_MAIN_VARIANT (type); - - if (TYPE_SIZE (complete_type (type)) == NULL_TREE) - { - cp_error ("taking typeid of incomplete type `%T'", type); - return error_mark_node; - } - - /* If exp is a reference to polymorphic type, get the real type_info. */ - if (TYPE_VIRTUAL_P (type) && ! resolves_to_fixed_type_p (exp, 0)) - { - /* build reference to type_info from vtable. */ - tree t; - - if (! flag_rtti) - error ("taking dynamic typeid of object with -fno-rtti"); - - /* If we don't have rtti stuff, get to a sub-object that does. */ - if (! CLASSTYPE_VFIELDS (type)) - { - exp = build_unary_op (ADDR_EXPR, exp, 0); - exp = build_headof_sub (exp); - exp = build_indirect_ref (exp, NULL_PTR); - } - - if (flag_vtable_thunks) - t = build_vfn_ref ((tree *) 0, exp, integer_one_node); - else - t = build_vfn_ref ((tree *) 0, exp, integer_zero_node); - TREE_TYPE (t) = build_pointer_type (tinfo_fn_type); - return t; - } - - /* otherwise return the type_info for the static type of the expr. */ - return get_tinfo_fn (TYPE_MAIN_VARIANT (type)); -} - -tree -build_typeid (exp) - tree exp; -{ - exp = get_tinfo_fn_dynamic (exp); - exp = build_call (exp, TREE_TYPE (tinfo_fn_type), NULL_TREE); - return convert_from_reference (exp); -} - -tree -build_x_typeid (exp) - tree exp; -{ - tree cond = NULL_TREE; - tree type = TREE_TYPE (tinfo_fn_type); - int nonnull; - - if (TYPE_SIZE (type_info_type_node) == NULL_TREE) - { - error ("must #include <typeinfo> before using typeid"); - return error_mark_node; - } - - if (processing_template_decl) - return build_min_nt (TYPEID_EXPR, exp); - - if (TREE_CODE (exp) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (exp, 0))) == POINTER_TYPE - && TYPE_VIRTUAL_P (TREE_TYPE (exp)) - && ! resolves_to_fixed_type_p (exp, &nonnull) - && ! nonnull) - { - exp = stabilize_reference (exp); - cond = cp_convert (boolean_type_node, TREE_OPERAND (exp, 0)); - } - - exp = get_tinfo_fn_dynamic (exp); - - if (exp == error_mark_node) - return error_mark_node; - - exp = build_call (exp, type, NULL_TREE); - - if (cond) - { - tree bad = throw_bad_typeid (); - - bad = build_compound_expr - (expr_tree_cons (NULL_TREE, bad, build_expr_list - (NULL_TREE, cp_convert (type, integer_zero_node)))); - exp = build (COND_EXPR, type, cond, exp, bad); - } - - return convert_from_reference (exp); -} - -static tree -get_tinfo_var (type) - tree type; -{ - tree tname = build_overload_with_type (get_identifier ("__ti"), type); - tree tdecl, arrtype; - int size; - - if (IDENTIFIER_GLOBAL_VALUE (tname)) - return IDENTIFIER_GLOBAL_VALUE (tname); - - /* Figure out how much space we need to allocate for the type_info object. - If our struct layout or the type_info classes are changed, this will - need to be modified. */ - if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) - size = 3 * POINTER_SIZE + INT_TYPE_SIZE; - else if (TREE_CODE (type) == POINTER_TYPE - && ! (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE - || TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE)) - size = 3 * POINTER_SIZE; - else if (IS_AGGR_TYPE (type)) - { - if (CLASSTYPE_N_BASECLASSES (type) == 0) - size = 2 * POINTER_SIZE; - else if (! TYPE_USES_COMPLEX_INHERITANCE (type) - && (TREE_VIA_PUBLIC - (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0)))) - size = 3 * POINTER_SIZE; - else - size = 3 * POINTER_SIZE + TYPE_PRECISION (sizetype); - } - else - size = 2 * POINTER_SIZE; - - push_obstacks (&permanent_obstack, &permanent_obstack); - - /* The type for a character array of the appropriate size. */ - arrtype = build_cplus_array_type - (unsigned_char_type_node, - build_index_type (size_int (size / BITS_PER_UNIT - 1))); - - tdecl = build_decl (VAR_DECL, tname, arrtype); - TREE_PUBLIC (tdecl) = 1; - DECL_EXTERNAL (tdecl) = 1; - DECL_ARTIFICIAL (tdecl) = 1; - pushdecl_top_level (tdecl); - cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0); - - pop_obstacks (); - - return tdecl; -} - -tree -get_tinfo_fn (type) - tree type; -{ - tree name; - tree d; - - if (TREE_CODE (type) == OFFSET_TYPE) - type = TREE_TYPE (type); - if (TREE_CODE (type) == METHOD_TYPE) - type = build_function_type (TREE_TYPE (type), - TREE_CHAIN (TYPE_ARG_TYPES (type))); - - name = build_overload_with_type (tinfo_fn_id, type); - - if (IDENTIFIER_GLOBAL_VALUE (name)) - return IDENTIFIER_GLOBAL_VALUE (name); - - push_obstacks (&permanent_obstack, &permanent_obstack); - - d = build_lang_decl (FUNCTION_DECL, name, tinfo_fn_type); - DECL_EXTERNAL (d) = 1; - TREE_PUBLIC (d) = 1; - DECL_ARTIFICIAL (d) = 1; - DECL_NOT_REALLY_EXTERN (d) = 1; - DECL_MUTABLE_P (d) = 1; - TREE_TYPE (name) = copy_to_permanent (type); - - pushdecl_top_level (d); - make_function_rtl (d); - mark_used (d); - mark_inline_for_output (d); - pop_obstacks (); - - return d; -} - -tree -get_typeid_1 (type) - tree type; -{ - tree t; - - t = build_call - (get_tinfo_fn (type), TREE_TYPE (tinfo_fn_type), NULL_TREE); - return convert_from_reference (t); -} - -/* Return the type_info object for TYPE, creating it if necessary. */ - -tree -get_typeid (type) - tree type; -{ - if (type == error_mark_node) - return error_mark_node; - - if (TYPE_SIZE (type_info_type_node) == NULL_TREE) - { - error ("must #include <typeinfo> before using typeid"); - return error_mark_node; - } - - if (! flag_rtti) - error ("requesting typeid with -fno-rtti"); - - if (processing_template_decl) - return build_min_nt (TYPEID_EXPR, type); - - /* If the type of the type-id is a reference type, the result of the - typeid expression refers to a type_info object representing the - referenced type. */ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* The top-level cv-qualifiers of the lvalue expression or the type-id - that is the operand of typeid are always ignored. */ - type = TYPE_MAIN_VARIANT (type); - - if (TYPE_SIZE (complete_type (type)) == NULL_TREE) - { - cp_error ("taking typeid of incomplete type `%T'", type); - return error_mark_node; - } - - return get_typeid_1 (type); -} - -/* Check whether TEST is null before returning RESULT. If TEST is used in - RESULT, it must have previously had a save_expr applied to it. */ - -static tree -ifnonnull (test, result) - tree test, result; -{ - return build (COND_EXPR, TREE_TYPE (result), - build (EQ_EXPR, boolean_type_node, test, integer_zero_node), - cp_convert (TREE_TYPE (result), integer_zero_node), - result); -} - -/* Execute a dynamic cast, as described in section 5.2.6 of the 9/93 working - paper. */ - -static tree -build_dynamic_cast_1 (type, expr) - tree type, expr; -{ - enum tree_code tc = TREE_CODE (type); - tree exprtype; - enum tree_code ec; - tree dcast_fn; - tree old_expr = expr; - - if (TREE_CODE (expr) == OFFSET_REF) - expr = resolve_offset_ref (expr); - - exprtype = TREE_TYPE (expr); - assert (exprtype != NULL_TREE); - ec = TREE_CODE (exprtype); - - switch (tc) - { - case POINTER_TYPE: - if (ec == REFERENCE_TYPE) - { - expr = convert_from_reference (expr); - exprtype = TREE_TYPE (expr); - ec = TREE_CODE (exprtype); - } - if (ec != POINTER_TYPE) - goto fail; - if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE) - goto fail; - if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE) - goto fail; - if (!at_least_as_qualified_p (TREE_TYPE (type), - TREE_TYPE (exprtype))) - goto fail; - if (TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) - break; - /* else fall through */ - case REFERENCE_TYPE: - if (TREE_CODE (TREE_TYPE (type)) != RECORD_TYPE) - goto fail; - if (TYPE_SIZE (complete_type (TREE_TYPE (type))) == NULL_TREE) - goto fail; - break; - /* else fall through */ - default: - goto fail; - } - - /* Apply trivial conversion T -> T& for dereferenced ptrs. */ - if (ec == RECORD_TYPE) - { - exprtype = build_reference_type (exprtype); - expr = convert_to_reference (exprtype, expr, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); - ec = REFERENCE_TYPE; - } - - if (tc == REFERENCE_TYPE) - { - if (ec != REFERENCE_TYPE) - goto fail; - if (TREE_CODE (TREE_TYPE (exprtype)) != RECORD_TYPE) - goto fail; - if (TYPE_SIZE (complete_type (TREE_TYPE (exprtype))) == NULL_TREE) - goto fail; - if (!at_least_as_qualified_p (TREE_TYPE (type), - TREE_TYPE (exprtype))) - goto fail; - } - - /* If *type is an unambiguous accessible base class of *exprtype, - convert statically. */ - { - int distance; - tree path; - - distance = get_base_distance (TREE_TYPE (type), TREE_TYPE (exprtype), 1, - &path); - - if (distance == -2) - { - cp_error ("dynamic_cast from `%T' to ambiguous base class `%T'", - TREE_TYPE (exprtype), TREE_TYPE (type)); - return error_mark_node; - } - if (distance == -3) - { - cp_error ("dynamic_cast from `%T' to private base class `%T'", - TREE_TYPE (exprtype), TREE_TYPE (type)); - return error_mark_node; - } - - if (distance >= 0) - return build_vbase_path (PLUS_EXPR, type, expr, path, 0); - } - - /* Otherwise *exprtype must be a polymorphic class (have a vtbl). */ - if (TYPE_VIRTUAL_P (TREE_TYPE (exprtype))) - { - tree expr1; - /* if TYPE is `void *', return pointer to complete object. */ - if (tc == POINTER_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) - { - /* if b is an object, dynamic_cast<void *>(&b) == (void *)&b. */ - if (TREE_CODE (expr) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (expr, 0)) == VAR_DECL - && TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == RECORD_TYPE) - return build1 (NOP_EXPR, type, expr); - - /* Since expr is used twice below, save it. */ - expr = save_expr (expr); - - expr1 = build_headof (expr); - if (TREE_TYPE (expr1) != type) - expr1 = build1 (NOP_EXPR, type, expr1); - return ifnonnull (expr, expr1); - } - else - { - tree retval; - tree result, td1, td2, td3, elems, expr2; - - /* If we got here, we can't convert statically. Therefore, - dynamic_cast<D&>(b) (b an object) cannot succeed. */ - if (ec == REFERENCE_TYPE) - { - if (TREE_CODE (old_expr) == VAR_DECL - && TREE_CODE (TREE_TYPE (old_expr)) == RECORD_TYPE) - { - cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed", - old_expr, type); - return throw_bad_cast (); - } - } - /* Ditto for dynamic_cast<D*>(&b). */ - else if (TREE_CODE (expr) == ADDR_EXPR) - { - tree op = TREE_OPERAND (expr, 0); - if (TREE_CODE (op) == VAR_DECL - && TREE_CODE (TREE_TYPE (op)) == RECORD_TYPE) - { - cp_warning ("dynamic_cast of `%#D' to `%#T' can never succeed", - op, type); - retval = build_int_2 (0, 0); - TREE_TYPE (retval) = type; - return retval; - } - } - - /* Since expr is used twice below, save it. */ - expr = save_expr (expr); - - expr1 = expr; - if (tc == REFERENCE_TYPE) - expr1 = build_unary_op (ADDR_EXPR, expr1, 0); - - /* Build run-time conversion. */ - expr2 = build_headof (expr1); - - if (ec == POINTER_TYPE) - td1 = get_tinfo_fn_dynamic (build_indirect_ref (expr, NULL_PTR)); - else - td1 = get_tinfo_fn_dynamic (expr); - td1 = decay_conversion (td1); - - td2 = decay_conversion - (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (type)))); - td3 = decay_conversion - (get_tinfo_fn (TYPE_MAIN_VARIANT (TREE_TYPE (exprtype)))); - - elems = tree_cons - (NULL_TREE, td1, tree_cons - (NULL_TREE, td2, tree_cons - (NULL_TREE, build_int_2 (1, 0), tree_cons - (NULL_TREE, expr2, tree_cons - (NULL_TREE, td3, tree_cons - (NULL_TREE, expr1, NULL_TREE)))))); - - dcast_fn = get_identifier ("__dynamic_cast"); - if (IDENTIFIER_GLOBAL_VALUE (dcast_fn)) - dcast_fn = IDENTIFIER_GLOBAL_VALUE (dcast_fn); - else - { - tree tmp; - - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, TREE_TYPE (td1), tree_cons - (NULL_TREE, TREE_TYPE (td1), tree_cons - (NULL_TREE, integer_type_node, tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, TREE_TYPE (td1), tree_cons - (NULL_TREE, ptr_type_node, void_list_node)))))); - tmp = build_function_type (ptr_type_node, tmp); - dcast_fn = build_lang_decl (FUNCTION_DECL, dcast_fn, tmp); - DECL_EXTERNAL (dcast_fn) = 1; - TREE_PUBLIC (dcast_fn) = 1; - DECL_ARTIFICIAL (dcast_fn) = 1; - pushdecl_top_level (dcast_fn); - make_function_rtl (dcast_fn); - pop_obstacks (); - } - - mark_used (dcast_fn); - result = build_call - (dcast_fn, TREE_TYPE (TREE_TYPE (dcast_fn)), elems); - - if (tc == REFERENCE_TYPE) - { - expr1 = throw_bad_cast (); - expr1 = build_compound_expr - (expr_tree_cons (NULL_TREE, expr1, - build_expr_list (NULL_TREE, cp_convert (type, integer_zero_node)))); - TREE_TYPE (expr1) = type; - result = save_expr (result); - return build (COND_EXPR, type, result, result, expr1); - } - - /* Now back to the type we want from a void*. */ - result = cp_convert (type, result); - return ifnonnull (expr, result); - } - } - - fail: - cp_error ("cannot dynamic_cast `%E' (of type `%#T') to type `%#T'", - expr, exprtype, type); - return error_mark_node; -} - -tree -build_dynamic_cast (type, expr) - tree type, expr; -{ - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - if (processing_template_decl) - return build_min (DYNAMIC_CAST_EXPR, copy_to_permanent (type), expr); - - return convert_from_reference (build_dynamic_cast_1 (type, expr)); -} - -/* Build and initialize various sorts of descriptors. Every descriptor - node has a name associated with it (the name created by mangling). - For this reason, we use the identifier as our access to the __*_desc - nodes, instead of sticking them directly in the types. Otherwise we - would burden all built-in types (and pointer types) with slots that - we don't necessarily want to use. - - For each descriptor we build, we build a variable that contains - the descriptor's information. When we need this info at runtime, - all we need is access to these variables. - - Note: these constructors always return the address of the descriptor - info, since that is simplest for their mutual interaction. */ - -extern tree const_string_type_node; - -/* Build an initializer for a __si_type_info node. */ - -static void -expand_si_desc (tdecl, type) - tree tdecl; - tree type; -{ - tree t, elems, fn; - char *name = build_overload_name (type, 1, 1); - tree name_string = combine_strings (build_string (strlen (name)+1, name)); - - type = BINFO_TYPE (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0)); - expand_expr_stmt (get_typeid_1 (type)); - t = decay_conversion (get_tinfo_var (type)); - elems = tree_cons - (NULL_TREE, decay_conversion (tdecl), tree_cons - (NULL_TREE, decay_conversion (name_string), tree_cons - (NULL_TREE, t, NULL_TREE))); - - fn = get_identifier ("__rtti_si"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree tmp; - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, const_string_type_node, tree_cons - (NULL_TREE, build_pointer_type (type_info_type_node), - void_list_node))); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems); - expand_expr_stmt (fn); -} - -/* Build an initializer for a __class_type_info node. */ - -static void -expand_class_desc (tdecl, type) - tree tdecl; - tree type; -{ - tree name_string; - tree fn, tmp; - char *name; - - int i = CLASSTYPE_N_BASECLASSES (type); - int base_cnt = 0; - tree binfos = TYPE_BINFO_BASETYPES (type); -#if 0 - /* See code below that used these. */ - tree vb = CLASSTYPE_VBASECLASSES (type); - int n_base = i; -#endif - tree base, elems, access, offset, isvir; - tree elt, elts = NULL_TREE; - static tree base_info_type_node; - - if (base_info_type_node == NULL_TREE) - { - tree fields [4]; - - /* A reasonably close approximation of __class_type_info::base_info */ - - push_obstacks (&permanent_obstack, &permanent_obstack); - base_info_type_node = make_lang_type (RECORD_TYPE); - - /* Actually const __user_type_info * */ - fields [0] = build_lang_field_decl - (FIELD_DECL, NULL_TREE, - build_pointer_type (build_qualified_type - (type_info_type_node, - TYPE_QUAL_CONST))); - fields [1] = build_lang_field_decl - (FIELD_DECL, NULL_TREE, unsigned_intSI_type_node); - DECL_BIT_FIELD (fields[1]) = 1; - DECL_FIELD_SIZE (fields[1]) = 29; - - fields [2] = build_lang_field_decl - (FIELD_DECL, NULL_TREE, boolean_type_node); - DECL_BIT_FIELD (fields[2]) = 1; - DECL_FIELD_SIZE (fields[2]) = 1; - - /* Actually enum access */ - fields [3] = build_lang_field_decl - (FIELD_DECL, NULL_TREE, integer_type_node); - DECL_BIT_FIELD (fields[3]) = 1; - DECL_FIELD_SIZE (fields[3]) = 2; - - finish_builtin_type (base_info_type_node, "__base_info", fields, - 3, ptr_type_node); - pop_obstacks (); - } - - while (--i >= 0) - { - tree binfo = TREE_VEC_ELT (binfos, i); - - expand_expr_stmt (get_typeid_1 (BINFO_TYPE (binfo))); - base = decay_conversion (get_tinfo_var (BINFO_TYPE (binfo))); - - if (TREE_VIA_VIRTUAL (binfo)) - { - tree t = BINFO_TYPE (binfo); - char *name; - tree field; - - FORMAT_VBASE_NAME (name, t); - field = lookup_field (type, get_identifier (name), 0, 0); - offset = size_binop (FLOOR_DIV_EXPR, - DECL_FIELD_BITPOS (field), size_int (BITS_PER_UNIT)); - offset = convert (sizetype, offset); - } - else - offset = BINFO_OFFSET (binfo); - - if (TREE_VIA_PUBLIC (binfo)) - access = access_public_node; - else if (TREE_VIA_PROTECTED (binfo)) - access = access_protected_node; - else - access = access_private_node; - if (TREE_VIA_VIRTUAL (binfo)) - isvir = boolean_true_node; - else - isvir = boolean_false_node; - - elt = build - (CONSTRUCTOR, base_info_type_node, NULL_TREE, tree_cons - (NULL_TREE, base, tree_cons - (NULL_TREE, offset, tree_cons - (NULL_TREE, isvir, tree_cons - (NULL_TREE, access, NULL_TREE))))); - TREE_HAS_CONSTRUCTOR (elt) = TREE_CONSTANT (elt) = TREE_STATIC (elt) = 1; - elts = expr_tree_cons (NULL_TREE, elt, elts); - base_cnt++; - } -#if 0 - i = n_base; - while (vb) - { - tree b; - access = access_public_node; - while (--i >= 0) - { - b = TREE_VEC_ELT (binfos, i); - if (BINFO_TYPE (vb) == BINFO_TYPE (b) && TREE_VIA_VIRTUAL (b)) - { - if (TREE_VIA_PUBLIC (b)) - access = access_public_node; - else if (TREE_VIA_PROTECTED (b)) - access = access_protected_node; - else - access = access_private_node; - break; - } - } - base = build_t_desc (BINFO_TYPE (vb), 1); - offset = BINFO_OFFSET (vb); - isvir = build_int_2 (1, 0); - - base_list = expr_tree_cons (NULL_TREE, base, base_list); - isvir_list = expr_tree_cons (NULL_TREE, isvir, isvir_list); - acc_list = expr_tree_cons (NULL_TREE, access, acc_list); - off_list = expr_tree_cons (NULL_TREE, offset, off_list); - - base_cnt++; - vb = TREE_CHAIN (vb); - } -#endif - - name = build_overload_name (type, 1, 1); - name_string = combine_strings (build_string (strlen (name)+1, name)); - - { - tree arrtype = build_array_type (base_info_type_node, NULL_TREE); - elts = build (CONSTRUCTOR, arrtype, NULL_TREE, elts); - TREE_HAS_CONSTRUCTOR (elts) = TREE_CONSTANT (elts) - = TREE_STATIC (elts) = 1; - complete_array_type (arrtype, elts, 1); - } - - elems = tree_cons - (NULL_TREE, decay_conversion (tdecl), tree_cons - (NULL_TREE, decay_conversion (name_string), tree_cons - (NULL_TREE, decay_conversion (elts), tree_cons - (NULL_TREE, cp_convert (sizetype, build_int_2 (base_cnt, 0)), - NULL_TREE)))); - - fn = get_identifier ("__rtti_class"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, const_string_type_node, tree_cons - (NULL_TREE, build_pointer_type (base_info_type_node), tree_cons - (NULL_TREE, sizetype, void_list_node)))); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems); - expand_expr_stmt (fn); -} - -/* Build an initializer for a __pointer_type_info node. */ - -static void -expand_ptr_desc (tdecl, type) - tree tdecl; - tree type; -{ - tree t, elems, fn; - char *name = build_overload_name (type, 1, 1); - tree name_string = combine_strings (build_string (strlen (name)+1, name)); - - type = TREE_TYPE (type); - expand_expr_stmt (get_typeid_1 (type)); - t = decay_conversion (get_tinfo_var (type)); - elems = tree_cons - (NULL_TREE, decay_conversion (tdecl), tree_cons - (NULL_TREE, decay_conversion (name_string), tree_cons - (NULL_TREE, t, NULL_TREE))); - - fn = get_identifier ("__rtti_ptr"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree tmp; - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, const_string_type_node, tree_cons - (NULL_TREE, build_pointer_type (type_info_type_node), - void_list_node))); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems); - expand_expr_stmt (fn); -} - -/* Build an initializer for a __attr_type_info node. */ - -static void -expand_attr_desc (tdecl, type) - tree tdecl; - tree type; -{ - tree elems, t, fn; - char *name = build_overload_name (type, 1, 1); - tree name_string = combine_strings (build_string (strlen (name)+1, name)); - tree attrval = build_int_2 (TYPE_QUALS (type), 0); - - expand_expr_stmt (get_typeid_1 (TYPE_MAIN_VARIANT (type))); - t = decay_conversion (get_tinfo_var (TYPE_MAIN_VARIANT (type))); - elems = tree_cons - (NULL_TREE, decay_conversion (tdecl), tree_cons - (NULL_TREE, decay_conversion (name_string), tree_cons - (NULL_TREE, attrval, expr_tree_cons (NULL_TREE, t, NULL_TREE)))); - - fn = get_identifier ("__rtti_attr"); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree tmp; - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, const_string_type_node, tree_cons - (NULL_TREE, integer_type_node, tree_cons - (NULL_TREE, build_pointer_type (type_info_type_node), - void_list_node)))); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems); - expand_expr_stmt (fn); -} - -/* Build an initializer for a type_info node that just has a name. */ - -static void -expand_generic_desc (tdecl, type, fnname) - tree tdecl; - tree type; - char *fnname; -{ - char *name = build_overload_name (type, 1, 1); - tree name_string = combine_strings (build_string (strlen (name)+1, name)); - tree elems = tree_cons - (NULL_TREE, decay_conversion (tdecl), tree_cons - (NULL_TREE, decay_conversion (name_string), NULL_TREE)); - - tree fn = get_identifier (fnname); - if (IDENTIFIER_GLOBAL_VALUE (fn)) - fn = IDENTIFIER_GLOBAL_VALUE (fn); - else - { - tree tmp; - push_obstacks (&permanent_obstack, &permanent_obstack); - tmp = tree_cons - (NULL_TREE, ptr_type_node, tree_cons - (NULL_TREE, const_string_type_node, void_list_node)); - tmp = build_function_type (void_type_node, tmp); - - fn = build_lang_decl (FUNCTION_DECL, fn, tmp); - DECL_EXTERNAL (fn) = 1; - TREE_PUBLIC (fn) = 1; - DECL_ARTIFICIAL (fn) = 1; - pushdecl_top_level (fn); - make_function_rtl (fn); - pop_obstacks (); - } - - mark_used (fn); - fn = build_call (fn, TREE_TYPE (TREE_TYPE (fn)), elems); - expand_expr_stmt (fn); -} - -/* Generate the code for a type_info initialization function. - Note that we take advantage of the passage - - 5.2.7 Type identification [expr.typeid] - - Whether or not the destructor is called for the type_info object at the - end of the program is unspecified. - - and don't bother to arrange for these objects to be destroyed. It - doesn't matter, anyway, since the destructors don't do anything. - - This must only be called from toplevel (i.e. from finish_file)! */ - -void -synthesize_tinfo_fn (fndecl) - tree fndecl; -{ - tree type = TREE_TYPE (DECL_NAME (fndecl)); - tree tmp, addr, tdecl; - - if (at_eof) - { - import_export_decl (fndecl); - if (DECL_REALLY_EXTERN (fndecl)) - return; - } - - tdecl = get_tinfo_var (type); - DECL_EXTERNAL (tdecl) = 0; - TREE_STATIC (tdecl) = 1; - DECL_COMMON (tdecl) = 1; - TREE_USED (tdecl) = 1; - DECL_ALIGN (tdecl) = TYPE_ALIGN (ptr_type_node); - cp_finish_decl (tdecl, NULL_TREE, NULL_TREE, 0, 0); - - start_function (NULL_TREE, fndecl, NULL_TREE, 1); - store_parm_decls (); - clear_last_expr (); - push_momentary (); - - /* If the first word of the array (the vtable) is non-zero, we've already - initialized the object, so don't do it again. */ - addr = decay_conversion (tdecl); - tmp = cp_convert (build_pointer_type (ptr_type_node), addr); - tmp = build_indirect_ref (tmp, 0); - tmp = build_binary_op (EQ_EXPR, tmp, integer_zero_node, 1); - expand_start_cond (tmp, 0); - - if (TREE_CODE (type) == FUNCTION_TYPE) - expand_generic_desc (tdecl, type, "__rtti_func"); - else if (TREE_CODE (type) == ARRAY_TYPE) - expand_generic_desc (tdecl, type, "__rtti_array"); - else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) - expand_attr_desc (tdecl, type); - else if (TREE_CODE (type) == POINTER_TYPE) - { - if (TREE_CODE (TREE_TYPE (type)) == OFFSET_TYPE) - expand_generic_desc (tdecl, type, "__rtti_ptmd"); - else if (TREE_CODE (TREE_TYPE (type)) == METHOD_TYPE) - expand_generic_desc (tdecl, type, "__rtti_ptmf"); - else - expand_ptr_desc (tdecl, type); - } - else if (TYPE_PTRMEMFUNC_P (type)) - expand_generic_desc (tdecl, type, "__rtti_ptmf"); - else if (IS_AGGR_TYPE (type)) - { - if (CLASSTYPE_N_BASECLASSES (type) == 0) - expand_generic_desc (tdecl, type, "__rtti_user"); - else if (! TYPE_USES_COMPLEX_INHERITANCE (type) - && (TREE_VIA_PUBLIC - (TREE_VEC_ELT (TYPE_BINFO_BASETYPES (type), 0)))) - expand_si_desc (tdecl, type); - else - expand_class_desc (tdecl, type); - } - else if (TREE_CODE (type) == ENUMERAL_TYPE) - expand_generic_desc (tdecl, type, "__rtti_user"); - else - my_friendly_abort (252); - - expand_end_cond (); - - /* OK, now return the type_info object. */ - tmp = cp_convert (build_pointer_type (type_info_type_node), addr); - tmp = build_indirect_ref (tmp, 0); - c_expand_return (tmp); - finish_function (lineno, 0, 0); -} diff --git a/gcc/cp/search.c b/gcc/cp/search.c deleted file mode 100755 index 9a8657e..0000000 --- a/gcc/cp/search.c +++ /dev/null @@ -1,3499 +0,0 @@ -/* Breadth-first and depth-first routines for - searching multiple-inheritance lattice for GNU C++. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* High-level class interface. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "obstack.h" -#include "flags.h" -#include "rtl.h" -#include "output.h" -#include "toplev.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -extern struct obstack *current_obstack; -extern tree abort_fndecl; - -#include "stack.h" - -/* Obstack used for remembering decision points of breadth-first. */ - -static struct obstack search_obstack; - -/* Methods for pushing and popping objects to and from obstacks. */ - -struct stack_level * -push_stack_level (obstack, tp, size) - struct obstack *obstack; - char *tp; /* Sony NewsOS 5.0 compiler doesn't like void * here. */ - int size; -{ - struct stack_level *stack; - obstack_grow (obstack, tp, size); - stack = (struct stack_level *) ((char*)obstack_next_free (obstack) - size); - obstack_finish (obstack); - stack->obstack = obstack; - stack->first = (tree *) obstack_base (obstack); - stack->limit = obstack_room (obstack) / sizeof (tree *); - return stack; -} - -struct stack_level * -pop_stack_level (stack) - struct stack_level *stack; -{ - struct stack_level *tem = stack; - struct obstack *obstack = tem->obstack; - stack = tem->prev; - obstack_free (obstack, tem); - return stack; -} - -#define search_level stack_level -static struct search_level *search_stack; - -static tree get_abstract_virtuals_1 PROTO((tree, int, tree)); -static tree get_vbase_1 PROTO((tree, tree, unsigned int *)); -static tree convert_pointer_to_vbase PROTO((tree, tree)); -static tree lookup_field_1 PROTO((tree, tree)); -static tree convert_pointer_to_single_level PROTO((tree, tree)); -static int lookup_fnfields_1 PROTO((tree, tree)); -static int lookup_fnfields_here PROTO((tree, tree)); -static int is_subobject_of_p PROTO((tree, tree)); -static int hides PROTO((tree, tree)); -static tree virtual_context PROTO((tree, tree, tree)); -static tree get_template_base_recursive - PROTO((tree, tree, tree, int)); -static void dfs_walk PROTO((tree, void (*) (tree), int (*) (tree))); -static void dfs_check_overlap PROTO((tree)); -static int dfs_no_overlap_yet PROTO((tree)); -static void envelope_add_decl PROTO((tree, tree, tree *)); -static int get_base_distance_recursive - PROTO((tree, int, int, int, int *, tree *, tree, - int, int *, int, int)); -static void expand_upcast_fixups - PROTO((tree, tree, tree, tree, tree, tree, tree *)); -static void fixup_virtual_upcast_offsets - PROTO((tree, tree, int, int, tree, tree, tree, tree, - tree *)); -static int markedp PROTO((tree)); -static int unmarkedp PROTO((tree)); -static int marked_vtable_pathp PROTO((tree)); -static int unmarked_vtable_pathp PROTO((tree)); -static int marked_new_vtablep PROTO((tree)); -static int unmarked_new_vtablep PROTO((tree)); -static int dfs_debug_unmarkedp PROTO((tree)); -static void dfs_debug_mark PROTO((tree)); -static void dfs_find_vbases PROTO((tree)); -static void dfs_clear_vbase_slots PROTO((tree)); -static void dfs_unmark PROTO((tree)); -static void dfs_init_vbase_pointers PROTO((tree)); -static void dfs_get_vbase_types PROTO((tree)); -static void dfs_pushdecls PROTO((tree)); -static void dfs_compress_decls PROTO((tree)); -static void dfs_unuse_fields PROTO((tree)); -static tree add_conversions PROTO((tree)); -static tree get_virtuals_named_this PROTO((tree)); -static tree get_virtual_destructor PROTO((tree)); -static int tree_has_any_destructor_p PROTO((tree)); -static int covariant_return_p PROTO((tree, tree)); -static struct search_level *push_search_level - PROTO((struct stack_level *, struct obstack *)); -static struct search_level *pop_search_level - PROTO((struct stack_level *)); -static tree breadth_first_search - PROTO((tree, tree (*) (tree), int (*) (tree))); - -static tree vbase_types; -static tree vbase_decl_ptr_intermediate, vbase_decl_ptr; -static tree vbase_init_result; - -/* Allocate a level of searching. */ - -static struct search_level * -push_search_level (stack, obstack) - struct stack_level *stack; - struct obstack *obstack; -{ - struct search_level tem; - - tem.prev = stack; - return push_stack_level (obstack, (char *)&tem, sizeof (tem)); -} - -/* Discard a level of search allocation. */ - -static struct search_level * -pop_search_level (obstack) - struct stack_level *obstack; -{ - register struct search_level *stack = pop_stack_level (obstack); - - return stack; -} - -static tree _vptr_name; - -/* Variables for gathering statistics. */ -#ifdef GATHER_STATISTICS -static int n_fields_searched; -static int n_calls_lookup_field, n_calls_lookup_field_1; -static int n_calls_lookup_fnfields, n_calls_lookup_fnfields_1; -static int n_calls_get_base_type; -static int n_outer_fields_searched; -static int n_contexts_saved; -#endif /* GATHER_STATISTICS */ - -/* This list is used by push_class_decls to know what decls need to - be pushed into class scope. */ -static tree closed_envelopes = NULL_TREE; - -/* Get a virtual binfo that is found inside BINFO's hierarchy that is - the same type as the type given in PARENT. To be optimal, we want - the first one that is found by going through the least number of - virtual bases. - - This uses a clever algorithm that updates *depth when we find the vbase, - and cuts off other paths of search when they reach that depth. */ - -static tree -get_vbase_1 (parent, binfo, depth) - tree parent, binfo; - unsigned int *depth; -{ - tree binfos; - int i, n_baselinks; - tree rval = NULL_TREE; - - if (BINFO_TYPE (binfo) == parent && TREE_VIA_VIRTUAL (binfo)) - { - *depth = 0; - return binfo; - } - - *depth = *depth - 1; - - binfos = BINFO_BASETYPES (binfo); - n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Process base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree nrval; - - if (*depth == 0) - break; - - nrval = get_vbase_1 (parent, base_binfo, depth); - if (nrval) - rval = nrval; - } - *depth = *depth+1; - return rval; -} - -/* Return the shortest path to vbase PARENT within BINFO, ignoring - access and ambiguity. */ - -tree -get_vbase (parent, binfo) - tree parent; - tree binfo; -{ - unsigned int d = (unsigned int)-1; - return get_vbase_1 (parent, binfo, &d); -} - -/* Convert EXPR to a virtual base class of type TYPE. We know that - EXPR is a non-null POINTER_TYPE to RECORD_TYPE. We also know that - the type of what expr points to has a virtual base of type TYPE. */ - -static tree -convert_pointer_to_vbase (type, expr) - tree type; - tree expr; -{ - tree vb = get_vbase (type, TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr)))); - return convert_pointer_to_real (vb, expr); -} - -/* Check whether the type given in BINFO is derived from PARENT. If - it isn't, return 0. If it is, but the derivation is MI-ambiguous - AND protect != 0, emit an error message and return error_mark_node. - - Otherwise, if TYPE is derived from PARENT, return the actual base - information, unless a one of the protection violations below - occurs, in which case emit an error message and return error_mark_node. - - If PROTECT is 1, then check if access to a public field of PARENT - would be private. Also check for ambiguity. */ - -tree -get_binfo (parent, binfo, protect) - register tree parent, binfo; - int protect; -{ - tree type = NULL_TREE; - int dist; - tree rval = NULL_TREE; - - if (TREE_CODE (parent) == TREE_VEC) - parent = BINFO_TYPE (parent); - else if (! IS_AGGR_TYPE_CODE (TREE_CODE (parent))) - my_friendly_abort (89); - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo))) - type = binfo; - else - my_friendly_abort (90); - - dist = get_base_distance (parent, binfo, protect, &rval); - - if (dist == -3) - { - cp_error ("fields of `%T' are inaccessible in `%T' due to private inheritance", - parent, type); - return error_mark_node; - } - else if (dist == -2 && protect) - { - cp_error ("type `%T' is ambiguous base class for type `%T'", parent, - type); - return error_mark_node; - } - - return rval; -} - -/* This is the newer depth first get_base_distance routine. */ - -static int -get_base_distance_recursive (binfo, depth, is_private, rval, - rval_private_ptr, new_binfo_ptr, parent, - protect, via_virtual_ptr, via_virtual, - current_scope_in_chain) - tree binfo; - int depth, is_private, rval; - int *rval_private_ptr; - tree *new_binfo_ptr, parent; - int protect, *via_virtual_ptr, via_virtual; - int current_scope_in_chain; -{ - tree binfos; - int i, n_baselinks; - - if (protect - && !current_scope_in_chain - && is_friend (BINFO_TYPE (binfo), current_scope ())) - current_scope_in_chain = 1; - - if (BINFO_TYPE (binfo) == parent || binfo == parent) - { - int better = 0; - - if (rval == -1) - /* This is the first time we've found parent. */ - better = 1; - else if (tree_int_cst_equal (BINFO_OFFSET (*new_binfo_ptr), - BINFO_OFFSET (binfo)) - && *via_virtual_ptr && via_virtual) - { - /* A new path to the same vbase. If this one has better - access or is shorter, take it. */ - - if (protect) - better = *rval_private_ptr - is_private; - if (better == 0) - better = rval - depth; - } - else - { - /* Ambiguous base class. */ - rval = depth = -2; - - /* If we get an ambiguity between virtual and non-virtual base - class, return the non-virtual in case we are ignoring - ambiguity. */ - better = *via_virtual_ptr - via_virtual; - } - - if (better > 0) - { - rval = depth; - *rval_private_ptr = is_private; - *new_binfo_ptr = binfo; - *via_virtual_ptr = via_virtual; - } - - return rval; - } - - binfos = BINFO_BASETYPES (binfo); - n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - depth += 1; - - /* Process base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - int via_private - = (protect - && (is_private - || (!TREE_VIA_PUBLIC (base_binfo) - && !(TREE_VIA_PROTECTED (base_binfo) - && current_scope_in_chain) - && !is_friend (BINFO_TYPE (binfo), current_scope ())))); - int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo); - - rval = get_base_distance_recursive (base_binfo, depth, via_private, - rval, rval_private_ptr, - new_binfo_ptr, parent, - protect, via_virtual_ptr, - this_virtual, - current_scope_in_chain); - - /* If we've found a non-virtual, ambiguous base class, we don't need - to keep searching. */ - if (rval == -2 && *via_virtual_ptr == 0) - return rval; - } - - return rval; -} - -/* Return the number of levels between type PARENT and the type given - in BINFO, following the leftmost path to PARENT not found along a - virtual path, if there are no real PARENTs (all come from virtual - base classes), then follow the shortest public path to PARENT. - - Return -1 if TYPE is not derived from PARENT. - Return -2 if PARENT is an ambiguous base class of TYPE, and PROTECT is - non-negative. - Return -3 if PARENT is private to TYPE, and PROTECT is non-zero. - - If PATH_PTR is non-NULL, then also build the list of types - from PARENT to TYPE, with TREE_VIA_VIRTUAL and TREE_VIA_PUBLIC - set. - - PARENT can also be a binfo, in which case that exact parent is found - and no other. convert_pointer_to_real uses this functionality. - - If BINFO is a binfo, its BINFO_INHERITANCE_CHAIN will be left alone. */ - -int -get_base_distance (parent, binfo, protect, path_ptr) - register tree parent, binfo; - int protect; - tree *path_ptr; -{ - int rval; - int rval_private = 0; - tree type = NULL_TREE; - tree new_binfo = NULL_TREE; - int via_virtual; - int watch_access = protect; - - /* Should we be completing types here? */ - if (TREE_CODE (parent) != TREE_VEC) - parent = complete_type (TYPE_MAIN_VARIANT (parent)); - else - complete_type (TREE_TYPE (parent)); - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo))) - { - type = complete_type (binfo); - binfo = TYPE_BINFO (type); - - if (path_ptr) - my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE, - 980827); - } - else - my_friendly_abort (92); - - if (parent == type || parent == binfo) - { - /* If the distance is 0, then we don't really need - a path pointer, but we shouldn't let garbage go back. */ - if (path_ptr) - *path_ptr = binfo; - return 0; - } - - if (path_ptr) - watch_access = 1; - - rval = get_base_distance_recursive (binfo, 0, 0, -1, - &rval_private, &new_binfo, parent, - watch_access, &via_virtual, 0, - 0); - - /* Access restrictions don't count if we found an ambiguous basetype. */ - if (rval == -2 && protect >= 0) - rval_private = 0; - - if (rval && protect && rval_private) - return -3; - - /* If they gave us the real vbase binfo, which isn't in the main binfo - tree, deal with it. This happens when we are called from - expand_upcast_fixups. */ - if (rval == -1 && TREE_CODE (parent) == TREE_VEC - && parent == binfo_member (BINFO_TYPE (parent), - CLASSTYPE_VBASECLASSES (type))) - { - my_friendly_assert (BINFO_INHERITANCE_CHAIN (parent) == binfo, 980827); - new_binfo = parent; - rval = 1; - } - - if (path_ptr) - *path_ptr = new_binfo; - return rval; -} - -/* Search for a member with name NAME in a multiple inheritance lattice - specified by TYPE. If it does not exist, return NULL_TREE. - If the member is ambiguously referenced, return `error_mark_node'. - Otherwise, return the FIELD_DECL. */ - -/* Do a 1-level search for NAME as a member of TYPE. The caller must - figure out whether it can access this field. (Since it is only one - level, this is reasonable.) */ - -static tree -lookup_field_1 (type, name) - tree type, name; -{ - register tree field; - - if (TREE_CODE (type) == TEMPLATE_TYPE_PARM - || TREE_CODE (type) == TEMPLATE_TEMPLATE_PARM) - /* The TYPE_FIELDS of a TEMPLATE_TYPE_PARM are not fields at all; - instead TYPE_FIELDS is the TEMPLATE_PARM_INDEX. (Miraculously, - the code often worked even when we treated the index as a list - of fields!) */ - return NULL_TREE; - - field = TYPE_FIELDS (type); - -#ifdef GATHER_STATISTICS - n_calls_lookup_field_1++; -#endif /* GATHER_STATISTICS */ - while (field) - { -#ifdef GATHER_STATISTICS - n_fields_searched++; -#endif /* GATHER_STATISTICS */ - my_friendly_assert (TREE_CODE_CLASS (TREE_CODE (field)) == 'd', 0); - if (DECL_NAME (field) == NULL_TREE - && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) - { - tree temp = lookup_field_1 (TREE_TYPE (field), name); - if (temp) - return temp; - } - if (TREE_CODE (field) == USING_DECL) - /* For now, we're just treating member using declarations as - old ARM-style access declarations. Thus, there's no reason - to return a USING_DECL, and the rest of the compiler can't - handle it. Once the class is defined, these are purged - from TYPE_FIELDS anyhow; see handle_using_decl. */ - ; - else if (DECL_NAME (field) == name) - { - if ((TREE_CODE(field) == VAR_DECL || TREE_CODE(field) == CONST_DECL) - && DECL_ASSEMBLER_NAME (field) != NULL) - GNU_xref_ref(current_function_decl, - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (field))); - return field; - } - field = TREE_CHAIN (field); - } - /* Not found. */ - if (name == _vptr_name) - { - /* Give the user what s/he thinks s/he wants. */ - if (TYPE_VIRTUAL_P (type)) - return CLASSTYPE_VFIELD (type); - } - return NULL_TREE; -} - -/* There are a number of cases we need to be aware of here: - current_class_type current_function_decl - global NULL NULL - fn-local NULL SET - class-local SET NULL - class->fn SET SET - fn->class SET SET - - Those last two make life interesting. If we're in a function which is - itself inside a class, we need decls to go into the fn's decls (our - second case below). But if we're in a class and the class itself is - inside a function, we need decls to go into the decls for the class. To - achieve this last goal, we must see if, when both current_class_ptr and - current_function_decl are set, the class was declared inside that - function. If so, we know to put the decls into the class's scope. */ - -tree -current_scope () -{ - if (current_function_decl == NULL_TREE) - return current_class_type; - if (current_class_type == NULL_TREE) - return current_function_decl; - if (DECL_CLASS_CONTEXT (current_function_decl) == current_class_type) - return current_function_decl; - - return current_class_type; -} - -/* Compute the access of FIELD. This is done by computing - the access available to each type in BASETYPES (which comes - as a list of [via_public/basetype] in reverse order, namely base - class before derived class). The first one which defines a - access defines the access for the field. Otherwise, the - access of the field is that which occurs normally. - - Uses global variables CURRENT_CLASS_TYPE and - CURRENT_FUNCTION_DECL to use friend relationships - if necessary. - - This will be static when lookup_fnfield comes into this file. - - access_public_node means that the field can be accessed by the current lexical - scope. - - access_protected_node means that the field cannot be accessed by the current - lexical scope because it is protected. - - access_private_node means that the field cannot be accessed by the current - lexical scope because it is private. */ - -#if 0 -#define PUBLIC_RETURN return (DECL_PUBLIC (field) = 1), access_public_node -#define PROTECTED_RETURN return (DECL_PROTECTED (field) = 1), access_protected_node -#define PRIVATE_RETURN return (DECL_PRIVATE (field) = 1), access_private_node -#else -#define PUBLIC_RETURN return access_public_node -#define PROTECTED_RETURN return access_protected_node -#define PRIVATE_RETURN return access_private_node -#endif - -#if 0 -/* Disabled with DECL_PUBLIC &c. */ -static tree previous_scope = NULL_TREE; -#endif - -tree -compute_access (basetype_path, field) - tree basetype_path, field; -{ - tree access; - tree types; - tree context; - int protected_ok, via_protected; - extern int flag_access_control; -#if 1 - /* Replaces static decl above. */ - tree previous_scope; -#endif - int static_mem - = ((TREE_CODE (field) == FUNCTION_DECL && DECL_STATIC_FUNCTION_P (field)) - || (TREE_CODE (field) != FUNCTION_DECL && TREE_STATIC (field))); - - if (! flag_access_control) - return access_public_node; - - /* The field lives in the current class. */ - if (BINFO_TYPE (basetype_path) == current_class_type) - return access_public_node; - -#if 0 - /* Disabled until pushing function scope clears these out. If ever. */ - /* Make these special cases fast. */ - if (current_scope () == previous_scope) - { - if (DECL_PUBLIC (field)) - return access_public_node; - if (DECL_PROTECTED (field)) - return access_protected_node; - if (DECL_PRIVATE (field)) - return access_private_node; - } -#endif - - /* We don't currently support access control on nested types. */ - if (TREE_CODE (field) == TYPE_DECL) - return access_public_node; - - previous_scope = current_scope (); - - context = DECL_REAL_CONTEXT (field); - - /* Fields coming from nested anonymous unions have their DECL_CLASS_CONTEXT - slot set to the union type rather than the record type containing - the anonymous union. */ - if (context && ANON_UNION_TYPE_P (context) - && TREE_CODE (field) == FIELD_DECL) - context = TYPE_CONTEXT (context); - - /* Virtual function tables are never private. But we should know that - we are looking for this, and not even try to hide it. */ - if (DECL_NAME (field) && VFIELD_NAME_P (DECL_NAME (field)) == 1) - PUBLIC_RETURN; - - /* Member found immediately within object. */ - if (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE) - { - /* Are we (or an enclosing scope) friends with the class that has - FIELD? */ - if (is_friend (context, previous_scope)) - PUBLIC_RETURN; - - /* If it's private, it's private, you letch. */ - if (TREE_PRIVATE (field)) - PRIVATE_RETURN; - - /* ARM $11.5. Member functions of a derived class can access the - non-static protected members of a base class only through a - pointer to the derived class, a reference to it, or an object - of it. Also any subsequently derived classes also have - access. */ - else if (TREE_PROTECTED (field)) - { - if (current_class_type - && (static_mem || DECL_CONSTRUCTOR_P (field)) - && ACCESSIBLY_DERIVED_FROM_P (context, current_class_type)) - PUBLIC_RETURN; - else - PROTECTED_RETURN; - } - else - PUBLIC_RETURN; - } - - /* must reverse more than one element */ - basetype_path = reverse_path (basetype_path); - types = basetype_path; - via_protected = 0; - access = access_default_node; - protected_ok = static_mem && current_class_type - && ACCESSIBLY_DERIVED_FROM_P (BINFO_TYPE (types), current_class_type); - - while (1) - { - tree member; - tree binfo = types; - tree type = BINFO_TYPE (binfo); - int private_ok = 0; - - /* Friends of a class can see protected members of its bases. - Note that classes are their own friends. */ - if (is_friend (type, previous_scope)) - { - protected_ok = 1; - private_ok = 1; - } - - member = purpose_member (type, DECL_ACCESS (field)); - if (member) - { - access = TREE_VALUE (member); - break; - } - - types = BINFO_INHERITANCE_CHAIN (types); - - /* If the next type was VIA_PROTECTED, then fields of all remaining - classes past that one are *at least* protected. */ - if (types) - { - if (TREE_VIA_PROTECTED (types)) - via_protected = 1; - else if (! TREE_VIA_PUBLIC (types) && ! private_ok) - { - access = access_private_node; - break; - } - } - else - break; - } - - /* No special visibilities apply. Use normal rules. */ - - if (access == access_default_node) - { - if (is_friend (context, previous_scope)) - access = access_public_node; - else if (TREE_PRIVATE (field)) - access = access_private_node; - else if (TREE_PROTECTED (field)) - access = access_protected_node; - else - access = access_public_node; - } - - if (access == access_public_node && via_protected) - access = access_protected_node; - - if (access == access_protected_node && protected_ok) - access = access_public_node; - -#if 0 - if (access == access_public_node) - DECL_PUBLIC (field) = 1; - else if (access == access_protected_node) - DECL_PROTECTED (field) = 1; - else if (access == access_private_node) - DECL_PRIVATE (field) = 1; - else my_friendly_abort (96); -#endif - return access; -} - -/* Routine to see if the sub-object denoted by the binfo PARENT can be - found as a base class and sub-object of the object denoted by - BINFO. This routine relies upon binfos not being shared, except - for binfos for virtual bases. */ - -static int -is_subobject_of_p (parent, binfo) - tree parent, binfo; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - if (parent == binfo) - return 1; - - /* Process and/or queue base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (TREE_VIA_VIRTUAL (base_binfo)) - base_binfo = TYPE_BINFO (BINFO_TYPE (base_binfo)); - if (is_subobject_of_p (parent, base_binfo)) - return 1; - } - return 0; -} - -/* See if a one FIELD_DECL hides another. This routine is meant to - correspond to ANSI working paper Sept 17, 1992 10p4. The two - binfos given are the binfos corresponding to the particular places - the FIELD_DECLs are found. This routine relies upon binfos not - being shared, except for virtual bases. */ - -static int -hides (hider_binfo, hidee_binfo) - tree hider_binfo, hidee_binfo; -{ - /* hider hides hidee, if hider has hidee as a base class and - the instance of hidee is a sub-object of hider. The first - part is always true is the second part is true. - - When hider and hidee are the same (two ways to get to the exact - same member) we consider either one as hiding the other. */ - return is_subobject_of_p (hidee_binfo, hider_binfo); -} - -/* Very similar to lookup_fnfields_1 but it ensures that at least one - function was declared inside the class given by TYPE. It really should - only return functions that match the given TYPE. */ - -static int -lookup_fnfields_here (type, name) - tree type, name; -{ - int idx = lookup_fnfields_1 (type, name); - tree fndecls; - - /* ctors and dtors are always only in the right class. */ - if (idx <= 1) - return idx; - fndecls = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); - while (fndecls) - { - if (TYPE_MAIN_VARIANT (DECL_CLASS_CONTEXT (OVL_CURRENT (fndecls))) - == TYPE_MAIN_VARIANT (type)) - return idx; - fndecls = OVL_CHAIN (fndecls); - } - return -1; -} - -/* Look for a field named NAME in an inheritance lattice dominated by - XBASETYPE. PROTECT is zero if we can avoid computing access - information, otherwise it is 1. WANT_TYPE is 1 when we should only - return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE. - - It was not clear what should happen if WANT_TYPE is set, and an - ambiguity is found. At least one use (lookup_name) to not see - the error. */ - -tree -lookup_field (xbasetype, name, protect, want_type) - register tree xbasetype, name; - int protect, want_type; -{ - int head = 0, tail = 0; - tree rval, rval_binfo = NULL_TREE, rval_binfo_h = NULL_TREE; - tree type = NULL_TREE, basetype_chain, basetype_path = NULL_TREE; - tree this_v = access_default_node; - tree entry, binfo, binfo_h; - tree own_access = access_default_node; - int vbase_name_p = VBASE_NAME_P (name); - - /* rval_binfo is the binfo associated with the found member, note, - this can be set with useful information, even when rval is not - set, because it must deal with ALL members, not just non-function - members. It is used for ambiguity checking and the hidden - checks. Whereas rval is only set if a proper (not hidden) - non-function member is found. */ - - /* rval_binfo_h and binfo_h are binfo values used when we perform the - hiding checks, as virtual base classes may not be shared. The strategy - is we always go into the binfo hierarchy owned by TYPE_BINFO of - virtual base classes, as we cross virtual base class lines. This way - we know that binfo of a virtual base class will always == itself when - found along any line. (mrs) */ - - char *errstr = 0; - -#if 0 - /* We cannot search for constructor/destructor names like this. */ - /* This can't go here, but where should it go? */ - /* If we are looking for a constructor in a templated type, use the - unspecialized name, as that is how we store it. */ - if (IDENTIFIER_TEMPLATE (name)) - name = constructor_name (name); -#endif - - if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype) - && IDENTIFIER_CLASS_VALUE (name)) - { - tree field = IDENTIFIER_CLASS_VALUE (name); - if (TREE_CODE (field) != FUNCTION_DECL - && ! (want_type && TREE_CODE (field) != TYPE_DECL)) - return field; - } - - if (TREE_CODE (xbasetype) == TREE_VEC) - { - type = BINFO_TYPE (xbasetype); - basetype_path = xbasetype; - } - else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))) - { - type = xbasetype; - basetype_path = TYPE_BINFO (type); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE, - 980827); - } - else - my_friendly_abort (97); - - complete_type (type); - -#ifdef GATHER_STATISTICS - n_calls_lookup_field++; -#endif /* GATHER_STATISTICS */ - - rval = lookup_field_1 (type, name); - - if (rval || lookup_fnfields_here (type, name) >= 0) - { - if (rval) - { - if (want_type) - { - if (TREE_CODE (rval) != TYPE_DECL) - { - rval = purpose_member (name, CLASSTYPE_TAGS (type)); - if (rval) - rval = TYPE_MAIN_DECL (TREE_VALUE (rval)); - } - } - else - { - if (TREE_CODE (rval) == TYPE_DECL - && lookup_fnfields_here (type, name) >= 0) - rval = NULL_TREE; - } - } - - if (protect && rval) - { - if (TREE_PRIVATE (rval) | TREE_PROTECTED (rval)) - this_v = compute_access (basetype_path, rval); - if (TREE_CODE (rval) == CONST_DECL) - { - if (this_v == access_private_node) - errstr = "enum `%D' is a private value of class `%T'"; - else if (this_v == access_protected_node) - errstr = "enum `%D' is a protected value of class `%T'"; - } - else - { - if (this_v == access_private_node) - errstr = "member `%D' is a private member of class `%T'"; - else if (this_v == access_protected_node) - errstr = "member `%D' is a protected member of class `%T'"; - } - } - - rval_binfo = basetype_path; - goto out; - } - - basetype_chain = build_expr_list (NULL_TREE, basetype_path); - - /* The ambiguity check relies upon breadth first searching. */ - - search_stack = push_search_level (search_stack, &search_obstack); - binfo = basetype_path; - binfo_h = binfo; - - while (1) - { - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree nval; - - /* Process and/or queue base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (BINFO_FIELDS_MARKED (base_binfo) == 0) - { - tree btypes; - - SET_BINFO_FIELDS_MARKED (base_binfo); - btypes = scratch_tree_cons (NULL_TREE, base_binfo, basetype_chain); - if (TREE_VIA_VIRTUAL (base_binfo)) - btypes = scratch_tree_cons (NULL_TREE, - TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))), - btypes); - else - btypes = scratch_tree_cons (NULL_TREE, - TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i), - btypes); - obstack_ptr_grow (&search_obstack, btypes); - tail += 1; - if (tail >= search_stack->limit) - my_friendly_abort (98); - } - } - - /* Process head of queue, if one exists. */ - if (head >= tail) - break; - - basetype_chain = search_stack->first[head++]; - binfo_h = TREE_VALUE (basetype_chain); - basetype_chain = TREE_CHAIN (basetype_chain); - basetype_path = TREE_VALUE (basetype_chain); - if (TREE_CHAIN (basetype_chain)) - my_friendly_assert - ((BINFO_INHERITANCE_CHAIN (basetype_path) - == TREE_VALUE (TREE_CHAIN (basetype_chain))) - /* We only approximate base info for partial instantiations. */ - || current_template_parms, - 980827); - else - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) - == NULL_TREE, 980827); - - binfo = basetype_path; - type = BINFO_TYPE (binfo); - - /* See if we can find NAME in TYPE. If RVAL is nonzero, - and we do find NAME in TYPE, verify that such a second - sighting is in fact valid. */ - - nval = lookup_field_1 (type, name); - - if (nval || lookup_fnfields_here (type, name)>=0) - { - if (nval && nval == rval && SHARED_MEMBER_P (nval)) - { - /* This is ok, the member found is the same [class.ambig] */ - } - else if (rval_binfo && hides (rval_binfo_h, binfo_h)) - { - /* This is ok, the member found is in rval_binfo, not - here (binfo). */ - } - else if (rval_binfo==NULL_TREE || hides (binfo_h, rval_binfo_h)) - { - /* This is ok, the member found is here (binfo), not in - rval_binfo. */ - if (nval) - { - rval = nval; - if (protect) - this_v = compute_access (basetype_path, rval); - /* These may look ambiguous, but they really are not. */ - if (vbase_name_p) - break; - } - else - { - /* Undo finding it before, as something else hides it. */ - rval = NULL_TREE; - } - rval_binfo = binfo; - rval_binfo_h = binfo_h; - } - else - { - /* This is ambiguous. */ - errstr = "request for member `%D' is ambiguous"; - protect += 2; - break; - } - } - } - { - tree *tp = search_stack->first; - tree *search_tail = tp + tail; - - if (rval_binfo) - { - type = BINFO_TYPE (rval_binfo); - - if (rval) - { - if (want_type) - { - if (TREE_CODE (rval) != TYPE_DECL) - { - rval = purpose_member (name, CLASSTYPE_TAGS (type)); - if (rval) - rval = TYPE_MAIN_DECL (TREE_VALUE (rval)); - } - } - else - { - if (TREE_CODE (rval) == TYPE_DECL - && lookup_fnfields_here (type, name) >= 0) - rval = NULL_TREE; - } - } - } - - if (rval == NULL_TREE) - errstr = 0; - - /* If this FIELD_DECL defines its own access level, deal with that. */ - if (rval && errstr == 0 - && (protect & 1) - && DECL_LANG_SPECIFIC (rval) - && DECL_ACCESS (rval)) - { - while (tp < search_tail) - { - /* If is possible for one of the derived types on the path to - have defined special access for this field. Look for such - declarations and report an error if a conflict is found. */ - tree new_v = NULL_TREE; - - if (this_v != access_default_node) - new_v = compute_access (TREE_VALUE (TREE_CHAIN (*tp)), rval); - if (this_v != access_default_node && new_v != this_v) - { - errstr = "conflicting access to member `%D'"; - this_v = access_default_node; - } - own_access = new_v; - CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp))); - tp += 1; - } - } - else - { - while (tp < search_tail) - { - CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp))); - tp += 1; - } - } - } - search_stack = pop_search_level (search_stack); - - if (errstr == 0) - { - if (own_access == access_private_node) - errstr = "member `%D' declared private"; - else if (own_access == access_protected_node) - errstr = "member `%D' declared protected"; - else if (this_v == access_private_node) - errstr = TREE_PRIVATE (rval) - ? "member `%D' is private" - : "member `%D' is from private base class"; - else if (this_v == access_protected_node) - errstr = TREE_PROTECTED (rval) - ? "member `%D' is protected" - : "member `%D' is from protected base class"; - } - - out: - if (protect == 2) - { - /* If we are not interested in ambiguities, don't report them, - just return NULL_TREE. */ - rval = NULL_TREE; - protect = 0; - } - - if (errstr && protect) - { - cp_error (errstr, name, type); - rval = error_mark_node; - } - - /* Do implicit typename stuff. This code also handles out-of-class - definitions of nested classes whose enclosing class is a - template. For example: - - template <class T> struct S { struct I { void f(); }; }; - template <class T> void S<T>::I::f() {} - - will come through here to handle `S<T>::I'. */ - if (rval && processing_template_decl - && ! currently_open_class (BINFO_TYPE (rval_binfo)) - && uses_template_parms (type)) - { - /* We need to return a member template class so we can define partial - specializations. Is there a better way? */ - if (DECL_CLASS_TEMPLATE_P (rval)) - return rval; - - /* Don't return a non-type. Actually, we ought to return something - so lookup_name_real can give a warning. */ - if (TREE_CODE (rval) != TYPE_DECL) - return NULL_TREE; - - binfo = rval_binfo; - for (; ; binfo = BINFO_INHERITANCE_CHAIN (binfo)) - if (BINFO_INHERITANCE_CHAIN (binfo) == NULL_TREE - || (BINFO_TYPE (BINFO_INHERITANCE_CHAIN (binfo)) - == current_class_type)) - break; - - entry = build_typename_type (BINFO_TYPE (binfo), name, name, - TREE_TYPE (rval)); - return TYPE_STUB_DECL (entry); - } - - return rval; -} - -/* Try to find NAME inside a nested class. */ - -tree -lookup_nested_field (name, complain) - tree name; - int complain; -{ - register tree t; - - tree id = NULL_TREE; - if (TYPE_MAIN_DECL (current_class_type)) - { - /* Climb our way up the nested ladder, seeing if we're trying to - modify a field in an enclosing class. If so, we should only - be able to modify if it's static. */ - for (t = TYPE_MAIN_DECL (current_class_type); - t && DECL_CONTEXT (t); - t = TYPE_MAIN_DECL (DECL_CONTEXT (t))) - { - if (TREE_CODE (DECL_CONTEXT (t)) != RECORD_TYPE) - break; - - /* N.B.: lookup_field will do the access checking for us */ - id = lookup_field (DECL_CONTEXT (t), name, complain, 0); - if (id == error_mark_node) - { - id = NULL_TREE; - continue; - } - - if (id != NULL_TREE) - { - if (TREE_CODE (id) == FIELD_DECL - && ! TREE_STATIC (id) - && TREE_TYPE (id) != error_mark_node) - { - if (complain) - { - /* At parse time, we don't want to give this error, since - we won't have enough state to make this kind of - decision properly. But there are times (e.g., with - enums in nested classes) when we do need to call - this fn at parse time. So, in those cases, we pass - complain as a 0 and just return a NULL_TREE. */ - cp_error ("assignment to non-static member `%D' of enclosing class `%T'", - id, DECL_CONTEXT (t)); - /* Mark this for do_identifier(). It would otherwise - claim that the variable was undeclared. */ - TREE_TYPE (id) = error_mark_node; - } - else - { - id = NULL_TREE; - continue; - } - } - break; - } - } - } - - return id; -} - -/* TYPE is a class type. Return the index of the fields within - the method vector with name NAME, or -1 is no such field exists. */ - -static int -lookup_fnfields_1 (type, name) - tree type, name; -{ - register tree method_vec - = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE; - - if (method_vec != 0) - { - register tree *methods = &TREE_VEC_ELT (method_vec, 0); - register tree *end = TREE_VEC_END (method_vec); - -#ifdef GATHER_STATISTICS - n_calls_lookup_fnfields_1++; -#endif /* GATHER_STATISTICS */ - - /* Constructors are first... */ - if (*methods && name == ctor_identifier) - return 0; - - /* and destructors are second. */ - if (*++methods && name == dtor_identifier) - return 1; - - while (++methods != end && *methods) - { -#ifdef GATHER_STATISTICS - n_outer_fields_searched++; -#endif /* GATHER_STATISTICS */ - if (DECL_NAME (OVL_CURRENT (*methods)) == name) - break; - } - - /* If we didn't find it, it might have been a template - conversion operator. (Note that we don't look for this case - above so that we will always find specializations first.) */ - if ((methods == end || !*methods) - && IDENTIFIER_TYPENAME_P (name)) - { - methods = &TREE_VEC_ELT (method_vec, 0) + 1; - - while (++methods != end && *methods) - { - tree method_name = DECL_NAME (OVL_CURRENT (*methods)); - - if (!IDENTIFIER_TYPENAME_P (method_name)) - { - /* Since all conversion operators come first, we know - there is no such operator. */ - methods = end; - break; - } - else if (TREE_CODE (OVL_CURRENT (*methods)) == TEMPLATE_DECL) - break; - } - } - - if (methods != end && *methods) - return methods - &TREE_VEC_ELT (method_vec, 0); - } - - return -1; -} - -/* Starting from BASETYPE, return a TREE_BASELINK-like object - which gives the following information (in a list): - - TREE_TYPE: list of basetypes needed to get to... - TREE_VALUE: list of all functions in a given type - which have name NAME. - - No access information is computed by this function, - other then to adorn the list of basetypes with - TREE_VIA_PUBLIC. - - If there are two ways to find a name (two members), if COMPLAIN is - non-zero, then error_mark_node is returned, and an error message is - printed, otherwise, just an error_mark_node is returned. - - As a special case, is COMPLAIN is -1, we don't complain, and we - don't return error_mark_node, but rather the complete list of - virtuals. This is used by get_virtuals_named_this. */ - -tree -lookup_fnfields (basetype_path, name, complain) - tree basetype_path, name; - int complain; -{ - int head = 0, tail = 0; - tree type, rval, rval_binfo = NULL_TREE, rvals = NULL_TREE; - tree rval_binfo_h = NULL_TREE, binfo, basetype_chain, binfo_h; - int idx, find_all = 0; - - /* rval_binfo is the binfo associated with the found member, note, - this can be set with useful information, even when rval is not - set, because it must deal with ALL members, not just function - members. It is used for ambiguity checking and the hidden - checks. Whereas rval is only set if a proper (not hidden) - function member is found. */ - - /* rval_binfo_h and binfo_h are binfo values used when we perform the - hiding checks, as virtual base classes may not be shared. The strategy - is we always go into the binfo hierarchy owned by TYPE_BINFO of - virtual base classes, as we cross virtual base class lines. This way - we know that binfo of a virtual base class will always == itself when - found along any line. (mrs) */ - - /* For now, don't try this. */ - int protect = complain; - - char *errstr = 0; - - if (complain == -1) - { - find_all = 1; - protect = complain = 0; - } - -#if 0 - /* We cannot search for constructor/destructor names like this. */ - /* This can't go here, but where should it go? */ - /* If we are looking for a constructor in a templated type, use the - unspecialized name, as that is how we store it. */ - if (IDENTIFIER_TEMPLATE (name)) - name = constructor_name (name); -#endif - - binfo = basetype_path; - binfo_h = binfo; - type = complete_type (BINFO_TYPE (basetype_path)); - -#ifdef GATHER_STATISTICS - n_calls_lookup_fnfields++; -#endif /* GATHER_STATISTICS */ - - idx = lookup_fnfields_here (type, name); - if (idx >= 0 || lookup_field_1 (type, name)) - { - rval_binfo = basetype_path; - rval_binfo_h = rval_binfo; - } - - if (idx >= 0) - { - rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); - rvals = scratch_tree_cons (basetype_path, rval, rvals); - if (BINFO_BASETYPES (binfo) && CLASSTYPE_BASELINK_VEC (type)) - TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), idx); - - return rvals; - } - rval = NULL_TREE; - - if (name == ctor_identifier || name == dtor_identifier) - { - /* Don't allow lookups of constructors and destructors to go - deeper than the first place we look. */ - return NULL_TREE; - } - - if (basetype_path == TYPE_BINFO (type)) - { - basetype_chain = CLASSTYPE_BINFO_AS_LIST (type); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE, - 980827); - } - else - basetype_chain = build_expr_list (NULL_TREE, basetype_path); - - /* The ambiguity check relies upon breadth first searching. */ - - search_stack = push_search_level (search_stack, &search_obstack); - binfo = basetype_path; - binfo_h = binfo; - - while (1) - { - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int idx; - - /* Process and/or queue base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - if (BINFO_FIELDS_MARKED (base_binfo) == 0) - { - tree btypes; - - SET_BINFO_FIELDS_MARKED (base_binfo); - btypes = scratch_tree_cons (NULL_TREE, base_binfo, basetype_chain); - if (TREE_VIA_VIRTUAL (base_binfo)) - btypes = scratch_tree_cons (NULL_TREE, - TYPE_BINFO (BINFO_TYPE (TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i))), - btypes); - else - btypes = scratch_tree_cons (NULL_TREE, - TREE_VEC_ELT (BINFO_BASETYPES (binfo_h), i), - btypes); - obstack_ptr_grow (&search_obstack, btypes); - tail += 1; - if (tail >= search_stack->limit) - my_friendly_abort (99); - } - } - - /* Process head of queue, if one exists. */ - if (head >= tail) - break; - - basetype_chain = search_stack->first[head++]; - binfo_h = TREE_VALUE (basetype_chain); - basetype_chain = TREE_CHAIN (basetype_chain); - basetype_path = TREE_VALUE (basetype_chain); - if (TREE_CHAIN (basetype_chain)) - my_friendly_assert - ((BINFO_INHERITANCE_CHAIN (basetype_path) - == TREE_VALUE (TREE_CHAIN (basetype_chain))) - /* We only approximate base info for partial instantiations. */ - || current_template_parms, - 980827); - else - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) - == NULL_TREE, 980827); - - binfo = basetype_path; - type = BINFO_TYPE (binfo); - - /* See if we can find NAME in TYPE. If RVAL is nonzero, - and we do find NAME in TYPE, verify that such a second - sighting is in fact valid. */ - - idx = lookup_fnfields_here (type, name); - - if (idx >= 0 || (lookup_field_1 (type, name)!=NULL_TREE && !find_all)) - { - if (rval_binfo && !find_all && hides (rval_binfo_h, binfo_h)) - { - /* This is ok, the member found is in rval_binfo, not - here (binfo). */ - } - else if (rval_binfo==NULL_TREE || find_all || hides (binfo_h, rval_binfo_h)) - { - /* This is ok, the member found is here (binfo), not in - rval_binfo. */ - if (idx >= 0) - { - rval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); - /* Note, rvals can only be previously set if find_all is - true. */ - rvals = scratch_tree_cons (basetype_path, rval, rvals); - if (TYPE_BINFO_BASETYPES (type) - && CLASSTYPE_BASELINK_VEC (type)) - TREE_TYPE (rvals) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), idx); - } - else - { - /* Undo finding it before, as something else hides it. */ - rval = NULL_TREE; - rvals = NULL_TREE; - } - rval_binfo = binfo; - rval_binfo_h = binfo_h; - } - else - { - /* This is ambiguous. */ - errstr = "request for method `%D' is ambiguous"; - rvals = error_mark_node; - break; - } - } - } - { - tree *tp = search_stack->first; - tree *search_tail = tp + tail; - - while (tp < search_tail) - { - CLEAR_BINFO_FIELDS_MARKED (TREE_VALUE (TREE_CHAIN (*tp))); - tp += 1; - } - } - search_stack = pop_search_level (search_stack); - - if (errstr && protect) - { - cp_error (errstr, name); - rvals = error_mark_node; - } - - return rvals; -} - -/* Look for a field or function named NAME in an inheritance lattice - dominated by XBASETYPE. PROTECT is zero if we can avoid computing - access information, otherwise it is 1. WANT_TYPE is 1 when we should - only return TYPE_DECLs, if no TYPE_DECL can be found return NULL_TREE. */ - -tree -lookup_member (xbasetype, name, protect, want_type) - tree xbasetype, name; - int protect, want_type; -{ - tree ret, basetype_path; - - if (TREE_CODE (xbasetype) == TREE_VEC) - basetype_path = xbasetype; - else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype))) - { - basetype_path = TYPE_BINFO (xbasetype); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) - == NULL_TREE, 980827); - } - else - my_friendly_abort (97); - - ret = lookup_field (basetype_path, name, protect, want_type); - if (! ret && ! want_type) - ret = lookup_fnfields (basetype_path, name, protect); - return ret; -} - -/* BREADTH-FIRST SEARCH ROUTINES. */ - -/* Search a multiple inheritance hierarchy by breadth-first search. - - BINFO is an aggregate type, possibly in a multiple-inheritance hierarchy. - TESTFN is a function, which, if true, means that our condition has been met, - and its return value should be returned. - QFN, if non-NULL, is a predicate dictating whether the type should - even be queued. */ - -static tree -breadth_first_search (binfo, testfn, qfn) - tree binfo; - tree (*testfn) PROTO((tree)); - int (*qfn) PROTO((tree)); -{ - int head = 0, tail = 0; - tree rval = NULL_TREE; - - search_stack = push_search_level (search_stack, &search_obstack); - - SET_BINFO_MARKED (binfo); - obstack_ptr_grow (&search_obstack, binfo); - ++tail; - - while (1) - { - tree binfos = BINFO_BASETYPES (binfo); - int n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - int i; - - /* Process and/or queue base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (BINFO_MARKED (base_binfo) == 0 - && (qfn == 0 || (*qfn) (base_binfo))) - { - SET_BINFO_MARKED (base_binfo); - obstack_ptr_grow (&search_obstack, base_binfo); - ++tail; - if (tail >= search_stack->limit) - my_friendly_abort (100); - } - } - /* Process head of queue, if one exists. */ - if (head >= tail) - { - rval = 0; - break; - } - - binfo = search_stack->first[head++]; - if ((rval = (*testfn) (binfo))) - break; - } - { - tree *tp = search_stack->first; - tree *search_tail = tp + tail; - while (tp < search_tail) - { - tree binfo = *tp++; - CLEAR_BINFO_MARKED (binfo); - } - } - - search_stack = pop_search_level (search_stack); - return rval; -} - -/* Functions to use in breadth first searches. */ -typedef tree (*pfi) PROTO((tree)); - -static tree declarator; - -static tree -get_virtuals_named_this (binfo) - tree binfo; -{ - tree fields; - - fields = lookup_fnfields (binfo, declarator, -1); - /* fields cannot be error_mark_node */ - - if (fields == 0) - return 0; - - /* Get to the function decls, and return the first virtual function - with this name, if there is one. */ - while (fields) - { - tree fndecl; - - for (fndecl = TREE_VALUE (fields); fndecl; fndecl = OVL_NEXT (fndecl)) - if (DECL_VINDEX (OVL_CURRENT (fndecl))) - return fields; - fields = next_baselink (fields); - } - return NULL_TREE; -} - -static tree -get_virtual_destructor (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - if (TYPE_HAS_DESTRUCTOR (type) - && DECL_VINDEX (TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1))) - return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), 1); - return 0; -} - -static int -tree_has_any_destructor_p (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - return TYPE_NEEDS_DESTRUCTOR (type); -} - -/* Returns > 0 if a function with type DRETTYPE overriding a function - with type BRETTYPE is covariant, as defined in [class.virtual]. - - Returns 1 if trivial covariance, 2 if non-trivial (requiring runtime - adjustment), or -1 if pedantically invalid covariance. */ - -static int -covariant_return_p (brettype, drettype) - tree brettype, drettype; -{ - tree binfo; - - if (TREE_CODE (brettype) == FUNCTION_DECL - || TREE_CODE (brettype) == THUNK_DECL) - { - brettype = TREE_TYPE (TREE_TYPE (brettype)); - drettype = TREE_TYPE (TREE_TYPE (drettype)); - } - else if (TREE_CODE (brettype) == METHOD_TYPE) - { - brettype = TREE_TYPE (brettype); - drettype = TREE_TYPE (drettype); - } - - if (same_type_p (brettype, drettype)) - return 0; - - if (! (TREE_CODE (brettype) == TREE_CODE (drettype) - && (TREE_CODE (brettype) == POINTER_TYPE - || TREE_CODE (brettype) == REFERENCE_TYPE) - && TYPE_QUALS (brettype) == TYPE_QUALS (drettype))) - return 0; - - if (! can_convert (brettype, drettype)) - return 0; - - brettype = TREE_TYPE (brettype); - drettype = TREE_TYPE (drettype); - - /* If not pedantic, allow any standard pointer conversion. */ - if (! IS_AGGR_TYPE (drettype) || ! IS_AGGR_TYPE (brettype)) - return -1; - - binfo = get_binfo (brettype, drettype, 1); - - /* If we get an error_mark_node from get_binfo, it already complained, - so let's just succeed. */ - if (binfo == error_mark_node) - return 1; - - if (! BINFO_OFFSET_ZEROP (binfo) || TREE_VIA_VIRTUAL (binfo)) - return 2; - return 1; -} - -/* Given a class type TYPE, and a function decl FNDECL, look for a - virtual function in TYPE's hierarchy which FNDECL could match as a - virtual function. It doesn't matter which one we find. - - DTORP is nonzero if we are looking for a destructor. Destructors - need special treatment because they do not match by name. */ - -tree -get_matching_virtual (binfo, fndecl, dtorp) - tree binfo, fndecl; - int dtorp; -{ - tree tmp = NULL_TREE; - int i; - - if (TREE_CODE (fndecl) == TEMPLATE_DECL) - /* In [temp.mem] we have: - - A specialization of a member function template does not - override a virtual function from a base class. */ - return NULL_TREE; - - /* Breadth first search routines start searching basetypes - of TYPE, so we must perform first ply of search here. */ - if (dtorp) - { - return breadth_first_search (binfo, - get_virtual_destructor, - tree_has_any_destructor_p); - } - else - { - tree drettype, dtypes, btypes, instptr_type; - tree basetype = DECL_CLASS_CONTEXT (fndecl); - tree baselink, best = NULL_TREE; - tree name = DECL_ASSEMBLER_NAME (fndecl); - - declarator = DECL_NAME (fndecl); - if (IDENTIFIER_VIRTUAL_P (declarator) == 0) - return NULL_TREE; - - baselink = get_virtuals_named_this (binfo); - if (baselink == NULL_TREE) - return NULL_TREE; - - drettype = TREE_TYPE (TREE_TYPE (fndecl)); - dtypes = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); - if (DECL_STATIC_FUNCTION_P (fndecl)) - instptr_type = NULL_TREE; - else - instptr_type = TREE_TYPE (TREE_VALUE (dtypes)); - - for (; baselink; baselink = next_baselink (baselink)) - { - tree tmps; - for (tmps = TREE_VALUE (baselink); tmps; tmps = OVL_NEXT (tmps)) - { - tmp = OVL_CURRENT (tmps); - if (! DECL_VINDEX (tmp)) - continue; - - btypes = TYPE_ARG_TYPES (TREE_TYPE (tmp)); - if (instptr_type == NULL_TREE) - { - if (compparms (TREE_CHAIN (btypes), dtypes)) - /* Caller knows to give error in this case. */ - return tmp; - return NULL_TREE; - } - - if (/* The first parameter is the `this' parameter, - which has POINTER_TYPE, and we can therefore - safely use TYPE_QUALS, rather than - CP_TYPE_QUALS. */ - (TYPE_QUALS (TREE_TYPE (TREE_VALUE (btypes))) - == TYPE_QUALS (instptr_type)) - && compparms (TREE_CHAIN (btypes), TREE_CHAIN (dtypes))) - { - tree brettype = TREE_TYPE (TREE_TYPE (tmp)); - if (same_type_p (brettype, drettype)) - /* OK */; - else if ((i = covariant_return_p (brettype, drettype))) - { - if (i == 2) - sorry ("adjusting pointers for covariant returns"); - - if (pedantic && i == -1) - { - cp_pedwarn_at ("invalid covariant return type for `%#D' (must be pointer or reference to class)", fndecl); - cp_pedwarn_at (" overriding `%#D'", tmp); - } - } - else if (IS_AGGR_TYPE_2 (brettype, drettype) - && same_or_base_type_p (brettype, drettype)) - { - error ("invalid covariant return type (must use pointer or reference)"); - cp_error_at (" overriding `%#D'", tmp); - cp_error_at (" with `%#D'", fndecl); - } - else if (IDENTIFIER_ERROR_LOCUS (name) == NULL_TREE) - { - cp_error_at ("conflicting return type specified for virtual function `%#D'", fndecl); - cp_error_at (" overriding definition as `%#D'", tmp); - SET_IDENTIFIER_ERROR_LOCUS (name, basetype); - } - break; - } - } - /* If not at the end */ - if (tmps) - { - best = tmp; - break; - } - } - - return best; - } -} - -/* Return the list of virtual functions which are abstract in type - TYPE that come from non virtual base classes. See - expand_direct_vtbls_init for the style of search we do. */ - -static tree -get_abstract_virtuals_1 (binfo, do_self, abstract_virtuals) - tree binfo; - int do_self; - tree abstract_virtuals; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (! TREE_VIA_VIRTUAL (base_binfo)) - abstract_virtuals - = get_abstract_virtuals_1 (base_binfo, is_not_base_vtable, - abstract_virtuals); - } - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (do_self && CLASSTYPE_VFIELDS (BINFO_TYPE (binfo))) - { - tree virtuals = BINFO_VIRTUALS (binfo); - - skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)); - tree base_fndecl = TREE_OPERAND (base_pfn, 0); - if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl)) - abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals); - virtuals = TREE_CHAIN (virtuals); - } - } - return abstract_virtuals; -} - -/* Return the list of virtual functions which are abstract in type TYPE. - This information is cached, and so must be built on a - non-temporary obstack. */ - -tree -get_abstract_virtuals (type) - tree type; -{ - tree vbases; - tree abstract_virtuals = NULL; - - /* First get all from non-virtual bases. */ - abstract_virtuals - = get_abstract_virtuals_1 (TYPE_BINFO (type), 1, abstract_virtuals); - - for (vbases = CLASSTYPE_VBASECLASSES (type); vbases; vbases = TREE_CHAIN (vbases)) - { - tree virtuals = BINFO_VIRTUALS (vbases); - - skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree base_pfn = FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)); - tree base_fndecl = TREE_OPERAND (base_pfn, 0); - if (DECL_NEEDS_FINAL_OVERRIDER_P (base_fndecl)) - cp_error ("`%#D' needs a final overrider", base_fndecl); - else if (DECL_ABSTRACT_VIRTUAL_P (base_fndecl)) - abstract_virtuals = tree_cons (NULL_TREE, base_fndecl, abstract_virtuals); - virtuals = TREE_CHAIN (virtuals); - } - } - return nreverse (abstract_virtuals); -} - -/* For the type TYPE, return a list of member functions available from - base classes with name NAME. The TREE_VALUE of the list is a chain of - member functions with name NAME. The TREE_PURPOSE of the list is a - basetype, or a list of base types (in reverse order) which were - traversed to reach the chain of member functions. If we reach a base - type which provides a member function of name NAME, and which has at - most one base type itself, then we can terminate the search. */ - -tree -get_baselinks (type_as_binfo_list, type, name) - tree type_as_binfo_list; - tree type, name; -{ - int head = 0, tail = 0, idx; - tree rval = 0, nval = 0; - tree basetypes = type_as_binfo_list; - tree binfo = TYPE_BINFO (type); - - search_stack = push_search_level (search_stack, &search_obstack); - - while (1) - { - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Process and/or queue base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - tree btypes; - - btypes = hash_tree_cons (TREE_VIA_PUBLIC (base_binfo), - TREE_VIA_VIRTUAL (base_binfo), - TREE_VIA_PROTECTED (base_binfo), - NULL_TREE, base_binfo, - basetypes); - obstack_ptr_grow (&search_obstack, btypes); - search_stack->first = (tree *)obstack_base (&search_obstack); - tail += 1; - } - - dont_queue: - /* Process head of queue, if one exists. */ - if (head >= tail) - break; - - basetypes = search_stack->first[head++]; - binfo = TREE_VALUE (basetypes); - type = BINFO_TYPE (binfo); - idx = lookup_fnfields_1 (type, name); - if (idx >= 0) - { - nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx); - rval = hash_tree_cons (0, 0, 0, basetypes, nval, rval); - if (TYPE_BINFO_BASETYPES (type) == 0) - goto dont_queue; - else if (TREE_VEC_LENGTH (TYPE_BINFO_BASETYPES (type)) == 1) - { - if (CLASSTYPE_BASELINK_VEC (type)) - TREE_TYPE (rval) = TREE_VEC_ELT (CLASSTYPE_BASELINK_VEC (type), idx); - goto dont_queue; - } - } - nval = NULL_TREE; - } - - search_stack = pop_search_level (search_stack); - return rval; -} - -tree -next_baselink (baselink) - tree baselink; -{ - tree tmp = TREE_TYPE (baselink); - baselink = TREE_CHAIN (baselink); - while (tmp) - { - /* @@ does not yet add previous base types. */ - baselink = tree_cons (TREE_PURPOSE (tmp), TREE_VALUE (tmp), - baselink); - TREE_TYPE (baselink) = TREE_TYPE (tmp); - tmp = TREE_CHAIN (tmp); - } - return baselink; -} - -/* DEPTH-FIRST SEARCH ROUTINES. */ - -/* This routine converts a pointer to be a pointer of an immediate - base class. The normal convert_pointer_to routine would diagnose - the conversion as ambiguous, under MI code that has the base class - as an ambiguous base class. */ - -static tree -convert_pointer_to_single_level (to_type, expr) - tree to_type, expr; -{ - tree binfo_of_derived; - tree last; - - binfo_of_derived = TYPE_BINFO (TREE_TYPE (TREE_TYPE (expr))); - last = get_binfo (to_type, TREE_TYPE (TREE_TYPE (expr)), 0); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (last) == binfo_of_derived, - 980827); - my_friendly_assert (BINFO_INHERITANCE_CHAIN (binfo_of_derived) == NULL_TREE, - 980827); - return build_vbase_path (PLUS_EXPR, build_pointer_type (to_type), expr, - last, 1); -} - -/* The main function which implements depth first search. - - This routine has to remember the path it walked up, when - dfs_init_vbase_pointers is the work function, as otherwise there - would be no record. */ - -static void -dfs_walk (binfo, fn, qfn) - tree binfo; - void (*fn) PROTO((tree)); - int (*qfn) PROTO((tree)); -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (qfn == 0 || (*qfn)(base_binfo)) - { - if (TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TYPE_PARM - || TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TEMPLATE_PARM) - /* Pass */; - else if (fn == dfs_init_vbase_pointers) - { - /* When traversing an arbitrary MI hierarchy, we need to keep - a record of the path we took to get down to the final base - type, as otherwise there would be no record of it, and just - trying to blindly convert at the bottom would be ambiguous. - - The easiest way is to do the conversions one step at a time, - as we know we want the immediate base class at each step. - - The only special trick to converting one step at a time, - is that when we hit the last virtual base class, we must - use the SLOT value for it, and not use the normal convert - routine. We use the last virtual base class, as in our - implementation, we have pointers to all virtual base - classes in the base object. */ - - tree saved_vbase_decl_ptr_intermediate - = vbase_decl_ptr_intermediate; - - if (TREE_VIA_VIRTUAL (base_binfo)) - { - /* No need for the conversion here, as we know it is the - right type. */ - vbase_decl_ptr_intermediate - = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)); - } - else - { - vbase_decl_ptr_intermediate - = convert_pointer_to_single_level (BINFO_TYPE (base_binfo), - vbase_decl_ptr_intermediate); - } - - dfs_walk (base_binfo, fn, qfn); - - vbase_decl_ptr_intermediate = saved_vbase_decl_ptr_intermediate; - } - else - dfs_walk (base_binfo, fn, qfn); - } - } - - fn (binfo); -} - -/* Like dfs_walk, but only walk until fn returns something, and return - that. We also use the real vbase binfos instead of the placeholders - in the normal binfo hierarchy. START is the most-derived type for this - hierarchy, so that we can find the vbase binfos. */ - -static tree -dfs_search (binfo, fn, start) - tree binfo, start; - tree (*fn) PROTO((tree)); -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree retval; - - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TYPE_PARM - || TREE_CODE (BINFO_TYPE (base_binfo)) == TEMPLATE_TEMPLATE_PARM) - /* Pass */; - else - { - if (TREE_VIA_VIRTUAL (base_binfo) && start) - base_binfo = binfo_member (BINFO_TYPE (base_binfo), - CLASSTYPE_VBASECLASSES (start)); - retval = dfs_search (base_binfo, fn, start); - if (retval) - return retval; - } - } - - return fn (binfo); -} - -static int markedp (binfo) tree binfo; -{ return BINFO_MARKED (binfo); } -static int unmarkedp (binfo) tree binfo; -{ return BINFO_MARKED (binfo) == 0; } - -#if 0 -static int bfs_markedp (binfo, i) tree binfo; int i; -{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)); } -static int bfs_unmarkedp (binfo, i) tree binfo; int i; -{ return BINFO_MARKED (BINFO_BASETYPE (binfo, i)) == 0; } -static int bfs_marked_vtable_pathp (binfo, i) tree binfo; int i; -{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)); } -static int bfs_unmarked_vtable_pathp (binfo, i) tree binfo; int i; -{ return BINFO_VTABLE_PATH_MARKED (BINFO_BASETYPE (binfo, i)) == 0; } -static int bfs_marked_new_vtablep (binfo, i) tree binfo; int i; -{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)); } -static int bfs_unmarked_new_vtablep (binfo, i) tree binfo; int i; -{ return BINFO_NEW_VTABLE_MARKED (BINFO_BASETYPE (binfo, i)) == 0; } -#endif - -static int marked_vtable_pathp (binfo) tree binfo; -{ return BINFO_VTABLE_PATH_MARKED (binfo); } -static int unmarked_vtable_pathp (binfo) tree binfo; -{ return BINFO_VTABLE_PATH_MARKED (binfo) == 0; } -static int marked_new_vtablep (binfo) tree binfo; -{ return BINFO_NEW_VTABLE_MARKED (binfo); } -static int unmarked_new_vtablep (binfo) tree binfo; -{ return BINFO_NEW_VTABLE_MARKED (binfo) == 0; } -static int marked_pushdecls_p (binfo) tree binfo; -{ return BINFO_PUSHDECLS_MARKED (binfo); } -static int unmarked_pushdecls_p (binfo) tree binfo; -{ return BINFO_PUSHDECLS_MARKED (binfo) == 0; } - -#if 0 -static int dfs_search_slot_nonempty_p (binfo) tree binfo; -{ return CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) != 0; } -#endif - -static int dfs_debug_unmarkedp (binfo) tree binfo; -{ return CLASSTYPE_DEBUG_REQUESTED (BINFO_TYPE (binfo)) == 0; } - -/* The worker functions for `dfs_walk'. These do not need to - test anything (vis a vis marking) if they are paired with - a predicate function (above). */ - -#if 0 -static void -dfs_mark (binfo) tree binfo; -{ SET_BINFO_MARKED (binfo); } -#endif - -static void -dfs_unmark (binfo) tree binfo; -{ CLEAR_BINFO_MARKED (binfo); } - -#if 0 -static void -dfs_mark_vtable_path (binfo) tree binfo; -{ SET_BINFO_VTABLE_PATH_MARKED (binfo); } - -static void -dfs_unmark_vtable_path (binfo) tree binfo; -{ CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); } - -static void -dfs_mark_new_vtable (binfo) tree binfo; -{ SET_BINFO_NEW_VTABLE_MARKED (binfo); } - -static void -dfs_unmark_new_vtable (binfo) tree binfo; -{ CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); } - -static void -dfs_clear_search_slot (binfo) tree binfo; -{ CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (binfo)) = 0; } -#endif - -static void -dfs_debug_mark (binfo) - tree binfo; -{ - tree t = BINFO_TYPE (binfo); - - /* Use heuristic that if there are virtual functions, - ignore until we see a non-inline virtual function. */ - tree methods = CLASSTYPE_METHOD_VEC (t); - - CLASSTYPE_DEBUG_REQUESTED (t) = 1; - - if (methods == 0) - return; - - /* If interface info is known, either we've already emitted the debug - info or we don't need to. */ - if (CLASSTYPE_INTERFACE_KNOWN (t)) - return; - - /* If debug info is requested from this context for this type, supply it. - If debug info is requested from another context for this type, - see if some third context can supply it. */ - if (current_function_decl == NULL_TREE - || DECL_CLASS_CONTEXT (current_function_decl) != t) - { - if (TREE_VEC_ELT (methods, 1)) - methods = TREE_VEC_ELT (methods, 1); - else if (TREE_VEC_ELT (methods, 0)) - methods = TREE_VEC_ELT (methods, 0); - else - methods = TREE_VEC_ELT (methods, 2); - methods = OVL_CURRENT (methods); - while (methods) - { - if (DECL_VINDEX (methods) - && DECL_THIS_INLINE (methods) == 0 - && DECL_ABSTRACT_VIRTUAL_P (methods) == 0) - { - /* Somebody, somewhere is going to have to define this - virtual function. When they do, they will provide - the debugging info. */ - return; - } - methods = TREE_CHAIN (methods); - } - } - /* We cannot rely on some alien method to solve our problems, - so we must write out the debug info ourselves. */ - TYPE_DECL_SUPPRESS_DEBUG (TYPE_NAME (t)) = 0; - rest_of_type_compilation (t, toplevel_bindings_p ()); -} - -/* Attach to the type of the virtual base class, the pointer to the - virtual base class, given the global pointer vbase_decl_ptr. - - We use the global vbase_types. ICK! */ - -static void -dfs_find_vbases (binfo) - tree binfo; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = n_baselinks-1; i >= 0; i--) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (TREE_VIA_VIRTUAL (base_binfo) - && CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (base_binfo)) == 0) - { - tree vbase = BINFO_TYPE (base_binfo); - tree binfo = binfo_member (vbase, vbase_types); - - CLASSTYPE_SEARCH_SLOT (vbase) - = build (PLUS_EXPR, build_pointer_type (vbase), - vbase_decl_ptr, BINFO_OFFSET (binfo)); - } - } - SET_BINFO_VTABLE_PATH_MARKED (binfo); - SET_BINFO_NEW_VTABLE_MARKED (binfo); -} - -static void -dfs_init_vbase_pointers (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - tree fields = TYPE_FIELDS (type); - tree this_vbase_ptr; - - CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); - -#if 0 - /* See finish_struct_1 for when we can enable this. */ - /* If we have a vtable pointer first, skip it. */ - if (VFIELD_NAME_P (DECL_NAME (fields))) - fields = TREE_CHAIN (fields); -#endif - - if (fields == NULL_TREE - || DECL_NAME (fields) == NULL_TREE - || ! VBASE_NAME_P (DECL_NAME (fields))) - return; - - this_vbase_ptr = vbase_decl_ptr_intermediate; - - if (build_pointer_type (type) != TYPE_MAIN_VARIANT (TREE_TYPE (this_vbase_ptr))) - my_friendly_abort (125); - - while (fields && DECL_NAME (fields) - && VBASE_NAME_P (DECL_NAME (fields))) - { - tree ref = build (COMPONENT_REF, TREE_TYPE (fields), - build_indirect_ref (this_vbase_ptr, NULL_PTR), fields); - tree init = CLASSTYPE_SEARCH_SLOT (TREE_TYPE (TREE_TYPE (fields))); - vbase_init_result = tree_cons (binfo_member (TREE_TYPE (TREE_TYPE (fields)), - vbase_types), - build_modify_expr (ref, NOP_EXPR, init), - vbase_init_result); - fields = TREE_CHAIN (fields); - } -} - -/* Sometimes this needs to clear both VTABLE_PATH and NEW_VTABLE. Other - times, just NEW_VTABLE, but optimizer should make both with equal - efficiency (though it does not currently). */ - -static void -dfs_clear_vbase_slots (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - CLASSTYPE_SEARCH_SLOT (type) = 0; - CLEAR_BINFO_VTABLE_PATH_MARKED (binfo); - CLEAR_BINFO_NEW_VTABLE_MARKED (binfo); -} - -tree -init_vbase_pointers (type, decl_ptr) - tree type; - tree decl_ptr; -{ - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - int old_flag = flag_this_is_variable; - tree binfo = TYPE_BINFO (type); - flag_this_is_variable = -2; - vbase_types = CLASSTYPE_VBASECLASSES (type); - vbase_decl_ptr = vbase_decl_ptr_intermediate = decl_ptr; - vbase_init_result = NULL_TREE; - dfs_walk (binfo, dfs_find_vbases, unmarked_vtable_pathp); - dfs_walk (binfo, dfs_init_vbase_pointers, marked_vtable_pathp); - dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep); - flag_this_is_variable = old_flag; - return vbase_init_result; - } - return 0; -} - -/* get the virtual context (the vbase that directly contains the - DECL_CLASS_CONTEXT of the FNDECL) that the given FNDECL is declared in, - or NULL_TREE if there is none. - - FNDECL must come from a virtual table from a virtual base to ensure that - there is only one possible DECL_CLASS_CONTEXT. - - We know that if there is more than one place (binfo) the fndecl that the - declared, they all refer to the same binfo. See get_class_offset_1 for - the check that ensures this. */ - -static tree -virtual_context (fndecl, t, vbase) - tree fndecl, t, vbase; -{ - tree path; - if (get_base_distance (DECL_CLASS_CONTEXT (fndecl), t, 0, &path) < 0) - { - /* DECL_CLASS_CONTEXT can be ambiguous in t. */ - if (get_base_distance (DECL_CLASS_CONTEXT (fndecl), vbase, 0, &path) >= 0) - { - while (path) - { - /* Not sure if checking path == vbase is necessary here, but just in - case it is. */ - if (TREE_VIA_VIRTUAL (path) || path == vbase) - return binfo_member (BINFO_TYPE (path), CLASSTYPE_VBASECLASSES (t)); - path = BINFO_INHERITANCE_CHAIN (path); - } - } - /* This shouldn't happen, I don't want errors! */ - warning ("recoverable compiler error, fixups for virtual function"); - return vbase; - } - while (path) - { - if (TREE_VIA_VIRTUAL (path)) - return binfo_member (BINFO_TYPE (path), CLASSTYPE_VBASECLASSES (t)); - path = BINFO_INHERITANCE_CHAIN (path); - } - return 0; -} - -/* Fixups upcast offsets for one vtable. - Entries may stay within the VBASE given, or - they may upcast into a direct base, or - they may upcast into a different vbase. - - We only need to do fixups in case 2 and 3. In case 2, we add in - the virtual base offset to effect an upcast, in case 3, we add in - the virtual base offset to effect an upcast, then subtract out the - offset for the other virtual base, to effect a downcast into it. - - This routine mirrors fixup_vtable_deltas in functionality, though - this one is runtime based, and the other is compile time based. - Conceivably that routine could be removed entirely, and all fixups - done at runtime. - - VBASE_OFFSETS is an association list of virtual bases that contains - offset information for the virtual bases, so the offsets are only - calculated once. The offsets are computed by where we think the - vbase should be (as noted by the CLASSTYPE_SEARCH_SLOT) minus where - the vbase really is. */ - -static void -expand_upcast_fixups (binfo, addr, orig_addr, vbase, vbase_addr, t, - vbase_offsets) - tree binfo, addr, orig_addr, vbase, vbase_addr, t, *vbase_offsets; -{ - tree virtuals = BINFO_VIRTUALS (binfo); - tree vc; - tree delta; - unsigned HOST_WIDE_INT n; - - delta = purpose_member (vbase, *vbase_offsets); - if (! delta) - { - delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vbase)); - delta = build (MINUS_EXPR, ptrdiff_type_node, delta, vbase_addr); - delta = save_expr (delta); - delta = tree_cons (vbase, delta, *vbase_offsets); - *vbase_offsets = delta; - } - - n = skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree current_fndecl = TREE_VALUE (virtuals); - current_fndecl = FNADDR_FROM_VTABLE_ENTRY (current_fndecl); - current_fndecl = TREE_OPERAND (current_fndecl, 0); - if (current_fndecl - && current_fndecl != abort_fndecl - && (vc=virtual_context (current_fndecl, t, vbase)) != vbase) - { - /* This may in fact need a runtime fixup. */ - tree idx = build_int_2 (n, 0); - tree vtbl = BINFO_VTABLE (binfo); - tree nvtbl = lookup_name (DECL_NAME (vtbl), 0); - tree aref, ref, naref; - tree old_delta, new_delta; - tree init; - - if (nvtbl == NULL_TREE - || nvtbl == IDENTIFIER_GLOBAL_VALUE (DECL_NAME (vtbl))) - { - /* Dup it if it isn't in local scope yet. */ - nvtbl = build_decl - (VAR_DECL, DECL_NAME (vtbl), - TYPE_MAIN_VARIANT (TREE_TYPE (vtbl))); - DECL_ALIGN (nvtbl) = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (nvtbl)); - TREE_READONLY (nvtbl) = 0; - DECL_ARTIFICIAL (nvtbl) = 1; - nvtbl = pushdecl (nvtbl); - init = NULL_TREE; - cp_finish_decl (nvtbl, init, NULL_TREE, 0, - LOOKUP_ONLYCONVERTING); - - /* We don't set DECL_VIRTUAL_P and DECL_CONTEXT on nvtbl - because they wouldn't be useful; everything that wants to - look at the vtable will look at the decl for the normal - vtable. Setting DECL_CONTEXT also screws up - decl_function_context. */ - - init = build (MODIFY_EXPR, TREE_TYPE (nvtbl), - nvtbl, vtbl); - TREE_SIDE_EFFECTS (init) = 1; - expand_expr_stmt (init); - /* Update the vtable pointers as necessary. */ - ref = build_vfield_ref - (build_indirect_ref (addr, NULL_PTR), - DECL_CONTEXT (CLASSTYPE_VFIELD (BINFO_TYPE (binfo)))); - expand_expr_stmt - (build_modify_expr (ref, NOP_EXPR, nvtbl)); - } - assemble_external (vtbl); - aref = build_array_ref (vtbl, idx); - naref = build_array_ref (nvtbl, idx); - old_delta = build_component_ref (aref, delta_identifier, - NULL_TREE, 0); - new_delta = build_component_ref (naref, delta_identifier, - NULL_TREE, 0); - - /* This is a upcast, so we have to add the offset for the - virtual base. */ - old_delta = build_binary_op (PLUS_EXPR, old_delta, - TREE_VALUE (delta), 0); - if (vc) - { - /* If this is set, we need to subtract out the delta - adjustments for the other virtual base that we - downcast into. */ - tree vc_delta = purpose_member (vc, *vbase_offsets); - if (! vc_delta) - { - tree vc_addr = convert_pointer_to_real (vc, orig_addr); - vc_delta = CLASSTYPE_SEARCH_SLOT (BINFO_TYPE (vc)); - vc_delta = build (MINUS_EXPR, ptrdiff_type_node, - vc_delta, vc_addr); - vc_delta = save_expr (vc_delta); - *vbase_offsets = tree_cons (vc, vc_delta, *vbase_offsets); - } - else - vc_delta = TREE_VALUE (vc_delta); - - /* This is a downcast, so we have to subtract the offset - for the virtual base. */ - old_delta = build_binary_op (MINUS_EXPR, old_delta, vc_delta, 0); - } - - TREE_READONLY (new_delta) = 0; - TREE_TYPE (new_delta) = - cp_build_qualified_type (TREE_TYPE (new_delta), - CP_TYPE_QUALS (TREE_TYPE (new_delta)) - & ~TYPE_QUAL_CONST); - expand_expr_stmt (build_modify_expr (new_delta, NOP_EXPR, - old_delta)); - } - ++n; - virtuals = TREE_CHAIN (virtuals); - } -} - -/* Fixup upcast offsets for all direct vtables. Patterned after - expand_direct_vtbls_init. */ - -static void -fixup_virtual_upcast_offsets (real_binfo, binfo, init_self, can_elide, addr, orig_addr, type, vbase, vbase_offsets) - tree real_binfo, binfo; - int init_self, can_elide; - tree addr, orig_addr, type, vbase, *vbase_offsets; -{ - tree real_binfos = BINFO_BASETYPES (real_binfo); - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = real_binfos ? TREE_VEC_LENGTH (real_binfos) : 0; - - for (i = 0; i < n_baselinks; i++) - { - tree real_base_binfo = TREE_VEC_ELT (real_binfos, i); - tree base_binfo = TREE_VEC_ELT (binfos, i); - int is_not_base_vtable - = i != CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (real_binfo)); - if (! TREE_VIA_VIRTUAL (real_base_binfo)) - fixup_virtual_upcast_offsets (real_base_binfo, base_binfo, - is_not_base_vtable, can_elide, addr, - orig_addr, type, vbase, vbase_offsets); - } -#if 0 - /* Before turning this on, make sure it is correct. */ - if (can_elide && ! BINFO_MODIFIED (binfo)) - return; -#endif - /* Should we use something besides CLASSTYPE_VFIELDS? */ - if (init_self && CLASSTYPE_VFIELDS (BINFO_TYPE (real_binfo))) - { - tree new_addr = convert_pointer_to_real (binfo, addr); - expand_upcast_fixups (real_binfo, new_addr, orig_addr, vbase, addr, - type, vbase_offsets); - } -} - -/* Build a COMPOUND_EXPR which when expanded will generate the code - needed to initialize all the virtual function table slots of all - the virtual baseclasses. MAIN_BINFO is the binfo which determines - the virtual baseclasses to use; TYPE is the type of the object to - which the initialization applies. TRUE_EXP is the true object we - are initializing, and DECL_PTR is the pointer to the sub-object we - are initializing. - - When USE_COMPUTED_OFFSETS is non-zero, we can assume that the - object was laid out by a top-level constructor and the computed - offsets are valid to store vtables. When zero, we must store new - vtables through virtual baseclass pointers. - - We setup and use the globals: vbase_decl_ptr, vbase_types - ICK! */ - -void -expand_indirect_vtbls_init (binfo, true_exp, decl_ptr) - tree binfo; - tree true_exp, decl_ptr; -{ - tree type = BINFO_TYPE (binfo); - - /* This function executes during the finish_function() segment, - AFTER the auto variables and temporary stack space has been marked - unused...If space is needed for the virtual function tables, - some of them might fit within what the compiler now thinks - are available stack slots... These values are actually initialized at - the beginnning of the function, so when the automatics use their space, - they will overwrite the values that are placed here. Marking all - temporary space as unavailable prevents this from happening. */ - - mark_all_temps_used(); - - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - rtx fixup_insns = NULL_RTX; - tree vbases = CLASSTYPE_VBASECLASSES (type); - vbase_types = vbases; - vbase_decl_ptr = true_exp ? build_unary_op (ADDR_EXPR, true_exp, 0) : decl_ptr; - - dfs_walk (binfo, dfs_find_vbases, unmarked_new_vtablep); - - /* Initialized with vtables of type TYPE. */ - for (; vbases; vbases = TREE_CHAIN (vbases)) - { - tree addr; - - addr = convert_pointer_to_vbase (TREE_TYPE (vbases), vbase_decl_ptr); - - /* Do all vtables from this virtual base. */ - /* This assumes that virtual bases can never serve as parent - binfos. (in the CLASSTYPE_VFIELD_PARENT sense) */ - expand_direct_vtbls_init (vbases, TYPE_BINFO (BINFO_TYPE (vbases)), - 1, 0, addr); - - /* Now we adjust the offsets for virtual functions that - cross virtual boundaries on an implicit upcast on vf call - so that the layout of the most complete type is used, - instead of assuming the layout of the virtual bases from - our current type. */ - - if (flag_vtable_thunks) - { - /* We don't have dynamic thunks yet! - So for now, just fail silently. */ - } - else - { - tree vbase_offsets = NULL_TREE; - push_to_sequence (fixup_insns); - fixup_virtual_upcast_offsets (vbases, - TYPE_BINFO (BINFO_TYPE (vbases)), - 1, 0, addr, vbase_decl_ptr, - type, vbases, &vbase_offsets); - fixup_insns = get_insns (); - end_sequence (); - } - } - - if (fixup_insns) - { - extern tree in_charge_identifier; - tree in_charge_node = lookup_name (in_charge_identifier, 0); - if (! in_charge_node) - { - warning ("recoverable internal compiler error, nobody's in charge!"); - in_charge_node = integer_zero_node; - } - in_charge_node = build_binary_op (EQ_EXPR, in_charge_node, integer_zero_node, 1); - expand_start_cond (in_charge_node, 0); - emit_insns (fixup_insns); - expand_end_cond (); - } - - dfs_walk (binfo, dfs_clear_vbase_slots, marked_new_vtablep); - } -} - -/* get virtual base class types. - This adds type to the vbase_types list in reverse dfs order. - Ordering is very important, so don't change it. */ - -static void -dfs_get_vbase_types (binfo) - tree binfo; -{ - if (TREE_VIA_VIRTUAL (binfo) && ! BINFO_VBASE_MARKED (binfo)) - { - tree new_vbase = make_binfo (integer_zero_node, binfo, - BINFO_VTABLE (binfo), - BINFO_VIRTUALS (binfo)); - TREE_CHAIN (new_vbase) = vbase_types; - TREE_VIA_VIRTUAL (new_vbase) = 1; - vbase_types = new_vbase; - SET_BINFO_VBASE_MARKED (binfo); - } - SET_BINFO_MARKED (binfo); -} - -/* get a list of virtual base classes in dfs order. */ - -tree -get_vbase_types (type) - tree type; -{ - tree vbases; - tree binfo; - - binfo = TYPE_BINFO (type); - vbase_types = NULL_TREE; - dfs_walk (binfo, dfs_get_vbase_types, unmarkedp); - dfs_walk (binfo, dfs_unmark, markedp); - /* Rely upon the reverse dfs ordering from dfs_get_vbase_types, and now - reverse it so that we get normal dfs ordering. */ - vbase_types = nreverse (vbase_types); - - /* unmark marked vbases */ - for (vbases = vbase_types; vbases; vbases = TREE_CHAIN (vbases)) - CLEAR_BINFO_VBASE_MARKED (vbases); - - return vbase_types; -} - -/* If we want debug info for a type TYPE, make sure all its base types - are also marked as being potentially interesting. This avoids - the problem of not writing any debug info for intermediate basetypes - that have abstract virtual functions. Also mark member types. */ - -void -note_debug_info_needed (type) - tree type; -{ - tree field; - - if (current_template_parms) - return; - - if (TYPE_BEING_DEFINED (type)) - /* We can't go looking for the base types and fields just yet. */ - return; - - /* We can't do the TYPE_DECL_SUPPRESS_DEBUG thing with DWARF, which - does not support name references between translation units. Well, we - could, but that would mean putting global labels in the debug output - before each exported type and each of its functions and static data - members. */ - if (write_symbols == DWARF_DEBUG || write_symbols == DWARF2_DEBUG) - return; - - dfs_walk (TYPE_BINFO (type), dfs_debug_mark, dfs_debug_unmarkedp); - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - { - tree ttype; - if (TREE_CODE (field) == FIELD_DECL - && IS_AGGR_TYPE (ttype = target_type (TREE_TYPE (field))) - && dfs_debug_unmarkedp (TYPE_BINFO (ttype))) - note_debug_info_needed (ttype); - } -} - -/* Subroutines of push_class_decls (). */ - -/* Add in a decl to the envelope. */ -static void -envelope_add_decl (type, decl, values) - tree type, decl, *values; -{ - tree context, *tmp; - tree name = DECL_NAME (decl); - int dont_add = 0; - - /* Yet Another Implicit Typename Kludge: Since we don't tsubst - the members for partial instantiations, DECL_CONTEXT (decl) is wrong. - But pretend it's right for this function. */ - if (processing_template_decl) - type = DECL_REAL_CONTEXT (decl); - - /* virtual base names are always unique. */ - if (VBASE_NAME_P (name)) - *values = NULL_TREE; - - /* Possible ambiguity. If its defining type(s) - is (are all) derived from us, no problem. */ - else if (*values && TREE_CODE (*values) != TREE_LIST) - { - tree value = *values; - /* Only complain if we shadow something we can access. */ - if (warn_shadow && TREE_CODE (decl) == FUNCTION_DECL - && ((DECL_LANG_SPECIFIC (*values) - && DECL_CLASS_CONTEXT (value) == current_class_type) - || ! TREE_PRIVATE (value))) - /* Should figure out access control more accurately. */ - { - cp_warning_at ("member `%#D' is shadowed", value); - cp_warning_at ("by member function `%#D'", decl); - warning ("in this context"); - } - - context = DECL_REAL_CONTEXT (value); - - if (context == type) - { - if (TREE_CODE (value) == TYPE_DECL - && DECL_ARTIFICIAL (value)) - *values = NULL_TREE; - else - dont_add = 1; - } - else if (type == current_class_type - || DERIVED_FROM_P (context, type)) - { - /* Don't add in *values to list */ - *values = NULL_TREE; - } - else - *values = build_tree_list (NULL_TREE, value); - } - else - for (tmp = values; *tmp;) - { - tree value = TREE_VALUE (*tmp); - my_friendly_assert (TREE_CODE (value) != TREE_LIST, 999); - context = (TREE_CODE (value) == FUNCTION_DECL - && DECL_VIRTUAL_P (value)) - ? DECL_CLASS_CONTEXT (value) - : DECL_CONTEXT (value); - - if (type == current_class_type - || DERIVED_FROM_P (context, type)) - { - /* remove *tmp from list */ - *tmp = TREE_CHAIN (*tmp); - } - else - tmp = &TREE_CHAIN (*tmp); - } - - if (! dont_add) - { - /* Put the new contents in our envelope. */ - if (TREE_CODE (decl) == FUNCTION_DECL) - { - *values = tree_cons (name, decl, *values); - TREE_NONLOCAL_FLAG (*values) = 1; - TREE_TYPE (*values) = unknown_type_node; - } - else - { - if (*values) - { - *values = tree_cons (NULL_TREE, decl, *values); - /* Mark this as a potentially ambiguous member. */ - /* Leaving TREE_TYPE blank is intentional. - We cannot use `error_mark_node' (lookup_name) - or `unknown_type_node' (all member functions use this). */ - TREE_NONLOCAL_FLAG (*values) = 1; - } - else - *values = decl; - } - } -} - -/* Returns 1 iff BINFO is a base we shouldn't really be able to see into, - because it (or one of the intermediate bases) depends on template parms. */ - -static int -dependent_base_p (binfo) - tree binfo; -{ - for (; binfo; binfo = BINFO_INHERITANCE_CHAIN (binfo)) - { - if (TREE_TYPE (binfo) == current_class_type) - break; - if (uses_template_parms (TREE_TYPE (binfo))) - return 1; - } - return 0; -} - -/* Add the instance variables which this class contributed to the - current class binding contour. When a redefinition occurs, if the - redefinition is strictly within a single inheritance path, we just - overwrite the old declaration with the new. If the fields are not - within a single inheritance path, we must cons them. - - In order to know what decls are new (stemming from the current - invocation of push_class_decls) we enclose them in an "envelope", - which is a TREE_LIST node where the TREE_PURPOSE slot contains the - new decl (or possibly a list of competing ones), the TREE_VALUE slot - points to the old value and the TREE_CHAIN slot chains together all - envelopes which needs to be "opened" in push_class_decls. Opening an - envelope means: push the old value onto the class_shadowed list, - install the new one and if it's a TYPE_DECL do the same to the - IDENTIFIER_TYPE_VALUE. Such an envelope is recognized by seeing that - the TREE_PURPOSE slot is non-null, and that it is not an identifier. - Because if it is, it could be a set of overloaded methods from an - outer scope. */ - -static void -dfs_pushdecls (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - tree fields; - tree method_vec; - int dummy = 0; - - /* Only record types if we're a template base. */ - if (processing_template_decl && type != current_class_type - && dependent_base_p (binfo)) - dummy = 1; - - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - { - if (dummy && TREE_CODE (fields) != TYPE_DECL) - continue; - - /* Unmark so that if we are in a constructor, and then find that - this field was initialized by a base initializer, - we can emit an error message. */ - if (TREE_CODE (fields) == FIELD_DECL) - TREE_USED (fields) = 0; - - /* Recurse into anonymous unions. */ - if (DECL_NAME (fields) == NULL_TREE - && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) - { - dfs_pushdecls (TYPE_BINFO (TREE_TYPE (fields))); - continue; - } - - if (DECL_NAME (fields)) - { - tree name = DECL_NAME (fields); - tree class_value = IDENTIFIER_CLASS_VALUE (name); - - /* If the class value is not an envelope of the kind described in - the comment above, we create a new envelope. */ - maybe_push_cache_obstack (); - if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST - || TREE_PURPOSE (class_value) == NULL_TREE - || TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE) - { - /* See comment above for a description of envelopes. */ - closed_envelopes = tree_cons (NULL_TREE, class_value, - closed_envelopes); - IDENTIFIER_CLASS_VALUE (name) = closed_envelopes; - class_value = IDENTIFIER_CLASS_VALUE (name); - } - - envelope_add_decl (type, fields, &TREE_PURPOSE (class_value)); - pop_obstacks (); - } - } - - method_vec = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE; - if (method_vec && ! dummy) - { - tree *methods; - tree *end; - - /* Farm out constructors and destructors. */ - end = TREE_VEC_END (method_vec); - - for (methods = &TREE_VEC_ELT (method_vec, 2); - *methods && methods != end; - methods++) - { - /* This will cause lookup_name to return a pointer - to the tree_list of possible methods of this name. */ - tree name; - tree class_value; - - - name = DECL_NAME (OVL_CURRENT (*methods)); - class_value = IDENTIFIER_CLASS_VALUE (name); - - maybe_push_cache_obstack (); - - /* If the class value is not an envelope of the kind described in - the comment above, we create a new envelope. */ - if (class_value == NULL_TREE || TREE_CODE (class_value) != TREE_LIST - || TREE_PURPOSE (class_value) == NULL_TREE - || TREE_CODE (TREE_PURPOSE (class_value)) == IDENTIFIER_NODE) - { - /* See comment above for a description of envelopes. */ - closed_envelopes = tree_cons (NULL_TREE, class_value, - closed_envelopes); - IDENTIFIER_CLASS_VALUE (name) = closed_envelopes; - class_value = IDENTIFIER_CLASS_VALUE (name); - } - - /* Here we try to rule out possible ambiguities. - If we can't do that, keep a TREE_LIST with possibly ambiguous - decls in there. */ - /* Arbitrarily choose the first function in the list. This is OK - because this is only used for initial lookup; anything that - actually uses the function will look it up again. */ - envelope_add_decl (type, OVL_CURRENT (*methods), - &TREE_PURPOSE (class_value)); - pop_obstacks (); - } - } - - /* We can't just use BINFO_MARKED because envelope_add_decl uses - DERIVED_FROM_P, which calls get_base_distance. */ - SET_BINFO_PUSHDECLS_MARKED (binfo); -} - -/* Consolidate unique (by name) member functions. */ - -static void -dfs_compress_decls (binfo) - tree binfo; -{ - tree type = BINFO_TYPE (binfo); - tree method_vec - = CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE; - - if (processing_template_decl && type != current_class_type - && dependent_base_p (binfo)) - /* We only record types if we're a template base. */; - else if (method_vec != 0) - { - /* Farm out constructors and destructors. */ - tree *methods; - tree *end = TREE_VEC_END (method_vec); - - for (methods = &TREE_VEC_ELT (method_vec, 2); - methods != end && *methods; methods++) - { - /* This is known to be an envelope of the kind described before - dfs_pushdecls. */ - tree class_value = - IDENTIFIER_CLASS_VALUE (DECL_NAME (OVL_CURRENT (*methods))); - tree tmp = TREE_PURPOSE (class_value); - - /* This was replaced in scope by somebody else. Just leave it - alone. */ - if (TREE_CODE (tmp) != TREE_LIST) - continue; - - if (TREE_CHAIN (tmp) == NULL_TREE - && TREE_VALUE (tmp) - && OVL_NEXT (TREE_VALUE (tmp)) == NULL_TREE) - { - TREE_PURPOSE (class_value) = TREE_VALUE (tmp); - } - } - } - CLEAR_BINFO_PUSHDECLS_MARKED (binfo); -} - -/* When entering the scope of a class, we cache all of the - fields that that class provides within its inheritance - lattice. Where ambiguities result, we mark them - with `error_mark_node' so that if they are encountered - without explicit qualification, we can emit an error - message. */ - -void -push_class_decls (type) - tree type; -{ - struct obstack *ambient_obstack = current_obstack; - search_stack = push_search_level (search_stack, &search_obstack); - - /* Build up all the relevant bindings and such on the cache - obstack. That way no memory is wasted when we throw away the - cache later. */ - maybe_push_cache_obstack (); - - /* Push class fields into CLASS_VALUE scope, and mark. */ - dfs_walk (TYPE_BINFO (type), dfs_pushdecls, unmarked_pushdecls_p); - - /* Compress fields which have only a single entry - by a given name, and unmark. */ - dfs_walk (TYPE_BINFO (type), dfs_compress_decls, marked_pushdecls_p); - - /* Open up all the closed envelopes and push the contained decls into - class scope. */ - while (closed_envelopes) - { - tree new = TREE_PURPOSE (closed_envelopes); - tree id; - - /* This is messy because the class value may be a *_DECL, or a - TREE_LIST of overloaded *_DECLs or even a TREE_LIST of ambiguous - *_DECLs. The name is stored at different places in these three - cases. */ - if (TREE_CODE (new) == TREE_LIST) - { - if (TREE_PURPOSE (new) != NULL_TREE) - id = TREE_PURPOSE (new); - else - { - tree node = TREE_VALUE (new); - - if (TREE_CODE (node) == TYPE_DECL - && DECL_ARTIFICIAL (node) - && IS_AGGR_TYPE (TREE_TYPE (node)) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (node))) - { - tree t = CLASSTYPE_TI_TEMPLATE (TREE_TYPE (node)); - tree n = new; - - for (; n; n = TREE_CHAIN (n)) - { - tree d = TREE_VALUE (n); - if (TREE_CODE (d) == TYPE_DECL - && DECL_ARTIFICIAL (node) - && IS_AGGR_TYPE (TREE_TYPE (d)) - && CLASSTYPE_TEMPLATE_INFO (TREE_TYPE (d)) - && CLASSTYPE_TI_TEMPLATE (TREE_TYPE (d)) == t) - /* OK */; - else - break; - } - - if (n == NULL_TREE) - new = t; - } - else while (TREE_CODE (node) == TREE_LIST) - node = TREE_VALUE (node); - id = DECL_NAME (node); - } - } - else - id = DECL_NAME (new); - - /* Install the original class value in order to make - pushdecl_class_level work correctly. */ - IDENTIFIER_CLASS_VALUE (id) = TREE_VALUE (closed_envelopes); - if (TREE_CODE (new) == TREE_LIST) - push_class_level_binding (id, new); - else - pushdecl_class_level (new); - closed_envelopes = TREE_CHAIN (closed_envelopes); - } - - /* Undo the call to maybe_push_cache_obstack above. */ - pop_obstacks (); - - current_obstack = ambient_obstack; -} - -/* Here's a subroutine we need because C lacks lambdas. */ - -static void -dfs_unuse_fields (binfo) - tree binfo; -{ - tree type = TREE_TYPE (binfo); - tree fields; - - for (fields = TYPE_FIELDS (type); fields; fields = TREE_CHAIN (fields)) - { - if (TREE_CODE (fields) != FIELD_DECL) - continue; - - TREE_USED (fields) = 0; - if (DECL_NAME (fields) == NULL_TREE - && TREE_CODE (TREE_TYPE (fields)) == UNION_TYPE) - unuse_fields (TREE_TYPE (fields)); - } -} - -void -unuse_fields (type) - tree type; -{ - dfs_walk (TYPE_BINFO (type), dfs_unuse_fields, unmarkedp); -} - -void -pop_class_decls () -{ - /* We haven't pushed a search level when dealing with cached classes, - so we'd better not try to pop it. */ - if (search_stack) - search_stack = pop_search_level (search_stack); -} - -void -print_search_statistics () -{ -#ifdef GATHER_STATISTICS - fprintf (stderr, "%d fields searched in %d[%d] calls to lookup_field[_1]\n", - n_fields_searched, n_calls_lookup_field, n_calls_lookup_field_1); - fprintf (stderr, "%d fnfields searched in %d calls to lookup_fnfields\n", - n_outer_fields_searched, n_calls_lookup_fnfields); - fprintf (stderr, "%d calls to get_base_type\n", n_calls_get_base_type); -#else /* GATHER_STATISTICS */ - fprintf (stderr, "no search statistics\n"); -#endif /* GATHER_STATISTICS */ -} - -void -init_search_processing () -{ - gcc_obstack_init (&search_obstack); - _vptr_name = get_identifier ("_vptr"); -} - -void -reinit_search_statistics () -{ -#ifdef GATHER_STATISTICS - n_fields_searched = 0; - n_calls_lookup_field = 0, n_calls_lookup_field_1 = 0; - n_calls_lookup_fnfields = 0, n_calls_lookup_fnfields_1 = 0; - n_calls_get_base_type = 0; - n_outer_fields_searched = 0; - n_contexts_saved = 0; -#endif /* GATHER_STATISTICS */ -} - -#define scratch_tree_cons expr_tree_cons - -static tree conversions; -static tree -add_conversions (binfo) - tree binfo; -{ - int i; - tree method_vec = CLASSTYPE_METHOD_VEC (BINFO_TYPE (binfo)); - - for (i = 2; i < TREE_VEC_LENGTH (method_vec); ++i) - { - tree tmp = TREE_VEC_ELT (method_vec, i); - tree name; - - if (!tmp || ! DECL_CONV_FN_P (OVL_CURRENT (tmp))) - break; - - name = DECL_NAME (OVL_CURRENT (tmp)); - - /* Make sure we don't already have this conversion. */ - if (! IDENTIFIER_MARKED (name)) - { - conversions = scratch_tree_cons (binfo, tmp, conversions); - IDENTIFIER_MARKED (name) = 1; - } - } - return NULL_TREE; -} - -tree -lookup_conversions (type) - tree type; -{ - tree t; - - conversions = NULL_TREE; - - if (TYPE_SIZE (type)) - breadth_first_search (TYPE_BINFO (type), add_conversions, 0); - - for (t = conversions; t; t = TREE_CHAIN (t)) - IDENTIFIER_MARKED (DECL_NAME (OVL_CURRENT (TREE_VALUE (t)))) = 0; - - return conversions; -} - -/* Subroutine of get_template_base. */ - -static tree -get_template_base_recursive (binfo, rval, template, via_virtual) - tree binfo, template, rval; - int via_virtual; -{ - tree binfos; - int i, n_baselinks; - tree type = BINFO_TYPE (binfo); - - if (CLASSTYPE_TEMPLATE_INFO (type) - && CLASSTYPE_TI_TEMPLATE (type) == template) - { - if (rval == NULL_TREE || rval == type) - return type; - else - return error_mark_node; - } - - binfos = BINFO_BASETYPES (binfo); - n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - /* Process base types. */ - for (i = 0; i < n_baselinks; i++) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - /* Find any specific instance of a virtual base, when searching with - a binfo... */ - if (BINFO_MARKED (base_binfo) == 0) - { - int this_virtual = via_virtual || TREE_VIA_VIRTUAL (base_binfo); - - /* When searching for a non-virtual, we cannot mark - virtually found binfos. */ - if (! this_virtual) - SET_BINFO_MARKED (base_binfo); - - rval = get_template_base_recursive - (base_binfo, rval, template, this_virtual); - if (rval == error_mark_node) - return rval; - } - } - - return rval; -} - -/* Given a class template TEMPLATE and a class type or binfo node BINFO, - find the unique base type in BINFO that is an instance of TEMPLATE. - If there are more than one, return error_mark_node. Used by unify. */ - -tree -get_template_base (template, binfo) - register tree template, binfo; -{ - tree type = NULL_TREE, rval; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else if (IS_AGGR_TYPE_CODE (TREE_CODE (binfo))) - { - type = complete_type (binfo); - binfo = TYPE_BINFO (type); - } - else - my_friendly_abort (92); - - if (CLASSTYPE_TEMPLATE_INFO (type) - && CLASSTYPE_TI_TEMPLATE (type) == template) - return type; - - rval = get_template_base_recursive (binfo, NULL_TREE, template, 0); - dfs_walk (binfo, dfs_unmark, markedp); - - return rval; -} - -/* Check whether the empty class indicated by EMPTY_BINFO is also present - at offset 0 in COMPARE_TYPE, and set found_overlap if so. */ - -static tree compare_type; -static int found_overlap; -static void -dfs_check_overlap (empty_binfo) - tree empty_binfo; -{ - tree binfo; - for (binfo = TYPE_BINFO (compare_type); ; binfo = BINFO_BASETYPE (binfo, 0)) - { - if (BINFO_TYPE (binfo) == BINFO_TYPE (empty_binfo)) - { - found_overlap = 1; - break; - } - else if (BINFO_BASETYPES (binfo) == NULL_TREE) - break; - } -} - -/* Trivial function to stop base traversal when we find something. */ - -static int -dfs_no_overlap_yet (t) - tree t ATTRIBUTE_UNUSED; -{ - return found_overlap == 0; -} - -/* Returns nonzero if EMPTY_TYPE or any of its bases can also be found at - offset 0 in NEXT_TYPE. Used in laying out empty base class subobjects. */ - -int -types_overlap_p (empty_type, next_type) - tree empty_type, next_type; -{ - if (! IS_AGGR_TYPE (next_type)) - return 0; - compare_type = next_type; - found_overlap = 0; - dfs_walk (TYPE_BINFO (empty_type), dfs_check_overlap, dfs_no_overlap_yet); - return found_overlap; -} - -/* Given a vtable VAR, determine which binfo it comes from. */ - -tree -binfo_for_vtable (var) - tree var; -{ - tree binfo = TYPE_BINFO (DECL_CONTEXT (var)); - tree binfos; - int i; - - while (1) - { - binfos = BINFO_BASETYPES (binfo); - if (binfos == NULL_TREE) - break; - - i = CLASSTYPE_VFIELD_PARENT (BINFO_TYPE (binfo)); - if (i == -1) - break; - - binfo = TREE_VEC_ELT (binfos, i); - } - - return binfo; -} diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c deleted file mode 100755 index fd6f3d0..0000000 --- a/gcc/cp/semantics.c +++ /dev/null @@ -1,1678 +0,0 @@ -/* Perform the semantic phase of parsing, i.e., the process of - building tree structure, checking semantic consistency, and - building RTL. These routines are used both during actual parsing - and during the instantiation of template functions. - - Copyright (C) 1998, 1999 Free Software Foundation, Inc. - Written by Mark Mitchell (mmitchell@usa.net) based on code found - formerly in parse.y and pt.c. - - 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 - Software Foundation, 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "except.h" -#include "lex.h" -#include "toplev.h" - -/* There routines provide a modular interface to perform many parsing - operations. They may therefore be used during actual parsing, or - during template instantiation, which may be regarded as a - degenerate form of parsing. Since the current g++ parser is - lacking in several respects, and will be reimplemented, we are - attempting to move most code that is not directly related to - parsing into this file; that will make implementing the new parser - much easier since it will be able to make use of these routines. */ - -/* When parsing a template, LAST_TREE contains the last statement - parsed. These are chained together through the TREE_CHAIN field, - but often need to be re-organized since the parse is performed - bottom-up. This macro makes LAST_TREE the indicated SUBSTMT of - STMT. */ - -#define RECHAIN_STMTS(stmt, substmt, last) \ - do { \ - substmt = last; \ - TREE_CHAIN (stmt) = NULL_TREE; \ - last_tree = stmt; \ - } while (0) - -#define RECHAIN_STMTS_FROM_LAST(stmt, substmt) \ - RECHAIN_STMTS (stmt, substmt, last_tree) - -#define RECHAIN_STMTS_FROM_CHAIN(stmt, substmt) \ - RECHAIN_STMTS (stmt, substmt, TREE_CHAIN (stmt)) - -/* Finish an expression-statement, whose EXPRESSION is as indicated. */ - -void -finish_expr_stmt (expr) - tree expr; -{ - if (expr != NULL_TREE) - { - if (!processing_template_decl) - { - emit_line_note (input_filename, lineno); - /* Do default conversion if safe and possibly important, - in case within ({...}). */ - if ((TREE_CODE (TREE_TYPE (expr)) == ARRAY_TYPE - && lvalue_p (expr)) - || TREE_CODE (TREE_TYPE (expr)) == FUNCTION_TYPE) - expr = default_conversion (expr); - } - - cplus_expand_expr_stmt (expr); - clear_momentary (); - } - - finish_stmt (); -} - -/* Begin an if-statement. Returns a newly created IF_STMT if - appropriate. */ - -tree -begin_if_stmt () -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (IF_STMT, NULL_TREE, NULL_TREE, NULL_TREE); - add_tree (r); - } - else - r = NULL_TREE; - - do_pushlevel (); - - return r; -} - -/* Process the COND of an if-statement, which may be given by - IF_STMT. */ - -void -finish_if_stmt_cond (cond, if_stmt) - tree cond; - tree if_stmt; -{ - if (processing_template_decl) - { - if (last_tree != if_stmt) - RECHAIN_STMTS_FROM_LAST (if_stmt, IF_COND (if_stmt)); - else - IF_COND (if_stmt) = cond; - } - else - { - emit_line_note (input_filename, lineno); - expand_start_cond (condition_conversion (cond), 0); - } -} - -/* Finish the then-clause of an if-statement, which may be given by - IF_STMT. */ - -tree -finish_then_clause (if_stmt) - tree if_stmt; -{ - if (processing_template_decl) - { - RECHAIN_STMTS_FROM_CHAIN (if_stmt, - THEN_CLAUSE (if_stmt)); - last_tree = if_stmt; - return if_stmt; - } - else - return NULL_TREE; -} - -/* Begin the else-clause of an if-statement. */ - -void -begin_else_clause () -{ - if (!processing_template_decl) - expand_start_else (); -} - -/* Finish the else-clause of an if-statement, which may be given by - IF_STMT. */ - -void -finish_else_clause (if_stmt) - tree if_stmt; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (if_stmt, ELSE_CLAUSE (if_stmt)); -} - -/* Finsh an if-statement. */ - -void -finish_if_stmt () -{ - if (!processing_template_decl) - expand_end_cond (); - - do_poplevel (); - finish_stmt (); -} - -/* Begin a while-statement. Returns a newly created WHILE_STMT if - appropriate. */ - -tree -begin_while_stmt () -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (WHILE_STMT, NULL_TREE, NULL_TREE); - add_tree (r); - } - else - { - emit_nop (); - emit_line_note (input_filename, lineno); - expand_start_loop (1); - r = NULL_TREE; - } - - do_pushlevel (); - - return r; -} - -/* Process the COND of an if-statement, which may be given by - WHILE_STMT. */ - -void -finish_while_stmt_cond (cond, while_stmt) - tree cond; - tree while_stmt; -{ - if (processing_template_decl) - { - if (last_tree != while_stmt) - RECHAIN_STMTS_FROM_LAST (while_stmt, - WHILE_COND (while_stmt)); - else - TREE_OPERAND (while_stmt, 0) = cond; - } - else - { - emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (0, condition_conversion (cond)); - } - - /* If COND wasn't a declaration, clear out the - block we made for it and start a new one here so the - optimization in expand_end_loop will work. */ - if (getdecls () == NULL_TREE) - { - do_poplevel (); - do_pushlevel (); - } -} - -/* Finish a while-statement, which may be given by WHILE_STMT. */ - -void -finish_while_stmt (while_stmt) - tree while_stmt; -{ - do_poplevel (); - - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (while_stmt, WHILE_BODY (while_stmt)); - else - expand_end_loop (); - finish_stmt (); -} - -/* Begin a do-statement. Returns a newly created DO_STMT if - appropriate. */ - -tree -begin_do_stmt () -{ - if (processing_template_decl) - { - tree r = build_min_nt (DO_STMT, NULL_TREE, NULL_TREE); - add_tree (r); - return r; - } - else - { - emit_nop (); - emit_line_note (input_filename, lineno); - expand_start_loop_continue_elsewhere (1); - return NULL_TREE; - } -} - -/* Finish the body of a do-statement, which may be given by DO_STMT. */ - -void -finish_do_body (do_stmt) - tree do_stmt; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (do_stmt, DO_BODY (do_stmt)); - else - expand_loop_continue_here (); -} - -/* Finish a do-statement, which may be given by DO_STMT, and whose - COND is as indicated. */ - -void -finish_do_stmt (cond, do_stmt) - tree cond; - tree do_stmt; -{ - if (processing_template_decl) - DO_COND (do_stmt) = cond; - else - { - emit_line_note (input_filename, lineno); - expand_exit_loop_if_false (0, condition_conversion (cond)); - expand_end_loop (); - } - - clear_momentary (); - finish_stmt (); -} - -/* Finish a return-statement. The EXPRESSION returned, if any, is as - indicated. */ - -void -finish_return_stmt (expr) - tree expr; -{ - emit_line_note (input_filename, lineno); - c_expand_return (expr); - finish_stmt (); -} - -/* Begin a for-statement. Returns a new FOR_STMT if appropriate. */ - -tree -begin_for_stmt () -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (FOR_STMT, NULL_TREE, NULL_TREE, - NULL_TREE, NULL_TREE); - add_tree (r); - } - else - r = NULL_TREE; - - if (flag_new_for_scope > 0) - { - do_pushlevel (); - note_level_for_for (); - } - - return r; -} - -/* Finish the for-init-statement of a for-statement, which may be - given by FOR_STMT. */ - -void -finish_for_init_stmt (for_stmt) - tree for_stmt; -{ - if (processing_template_decl) - { - if (last_tree != for_stmt) - RECHAIN_STMTS_FROM_CHAIN (for_stmt, FOR_INIT_STMT (for_stmt)); - } - else - { - emit_nop (); - emit_line_note (input_filename, lineno); - expand_start_loop_continue_elsewhere (1); - } - - do_pushlevel (); -} - -/* Finish the COND of a for-statement, which may be given by - FOR_STMT. */ - -void -finish_for_cond (cond, for_stmt) - tree cond; - tree for_stmt; -{ - if (processing_template_decl) - { - if (last_tree != for_stmt) - RECHAIN_STMTS_FROM_LAST (for_stmt, FOR_COND (for_stmt)); - else - FOR_COND (for_stmt) = cond; - } - else - { - emit_line_note (input_filename, lineno); - if (cond) - expand_exit_loop_if_false (0, condition_conversion (cond)); - } - - /* If the cond wasn't a declaration, clear out the - block we made for it and start a new one here so the - optimization in expand_end_loop will work. */ - if (getdecls () == NULL_TREE) - { - do_poplevel (); - do_pushlevel (); - } -} - -/* Finish the increment-EXPRESSION in a for-statement, which may be - given by FOR_STMT. */ - -void -finish_for_expr (expr, for_stmt) - tree expr; - tree for_stmt; -{ - if (processing_template_decl) - FOR_EXPR (for_stmt) = expr; - - /* Don't let the tree nodes for EXPR be discarded - by clear_momentary during the parsing of the next stmt. */ - push_momentary (); -} - -/* Finish the body of a for-statement, which may be given by - FOR_STMT. The increment-EXPR for the loop must be - provided. */ - -void -finish_for_stmt (expr, for_stmt) - tree expr; - tree for_stmt; -{ - /* Pop the scope for the body of the loop. */ - do_poplevel (); - - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (for_stmt, FOR_BODY (for_stmt)); - else - { - emit_line_note (input_filename, lineno); - expand_loop_continue_here (); - if (expr) - cplus_expand_expr_stmt (expr); - expand_end_loop (); - } - - pop_momentary (); - - if (flag_new_for_scope > 0) - do_poplevel (); - - finish_stmt (); -} - -/* Finish a break-statement. */ - -void -finish_break_stmt () -{ - emit_line_note (input_filename, lineno); - if (processing_template_decl) - add_tree (build_min_nt (BREAK_STMT)); - else if ( ! expand_exit_something ()) - cp_error ("break statement not within loop or switch"); -} - -/* Finish a continue-statement. */ - -void -finish_continue_stmt () -{ - emit_line_note (input_filename, lineno); - if (processing_template_decl) - add_tree (build_min_nt (CONTINUE_STMT)); - else if (! expand_continue_loop (0)) - cp_error ("continue statement not within a loop"); -} - -/* Begin a switch-statement. */ - -void -begin_switch_stmt () -{ - do_pushlevel (); -} - -/* Finish the cond of a switch-statement. Returns a new - SWITCH_STMT if appropriate. */ - -tree -finish_switch_cond (cond) - tree cond; -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (SWITCH_STMT, cond, NULL_TREE); - add_tree (r); - } - else - { - emit_line_note (input_filename, lineno); - c_expand_start_case (cond); - r = NULL_TREE; - } - push_switch (); - - /* Don't let the tree nodes for COND be discarded by - clear_momentary during the parsing of the next stmt. */ - push_momentary (); - - return r; -} - -/* Finish the body of a switch-statement, which may be given by - SWITCH_STMT. The COND to switch on is indicated. */ - -void -finish_switch_stmt (cond, switch_stmt) - tree cond; - tree switch_stmt; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (switch_stmt, SWITCH_BODY (switch_stmt)); - else - expand_end_case (cond); - pop_momentary (); - pop_switch (); - do_poplevel (); - finish_stmt (); -} - -/* Finish a case-label. */ - -void -finish_case_label (low_value, high_value) - tree low_value; - tree high_value; -{ - do_case (low_value, high_value); -} - - -/* Finish a goto-statement. */ - -void -finish_goto_stmt (destination) - tree destination; -{ - if (processing_template_decl) - add_tree (build_min_nt (GOTO_STMT, destination)); - else - { - emit_line_note (input_filename, lineno); - - if (TREE_CODE (destination) == IDENTIFIER_NODE) - { - tree decl = lookup_label (destination); - TREE_USED (decl) = 1; - expand_goto (decl); - } - else - expand_computed_goto (destination); - } -} - -/* Begin a try-block. Returns a newly-created TRY_BLOCK if - appropriate. */ - -tree -begin_try_block () -{ - if (processing_template_decl) - { - tree r = build_min_nt (TRY_BLOCK, NULL_TREE, - NULL_TREE); - add_tree (r); - return r; - } - else - { - emit_line_note (input_filename, lineno); - expand_start_try_stmts (); - return NULL_TREE; - } -} - -/* Finish a try-block, which may be given by TRY_BLOCK. */ - -void -finish_try_block (try_block) - tree try_block; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_LAST (try_block, TRY_STMTS (try_block)); - else - { - expand_start_all_catch (); - } -} - -/* Finish a handler-sequence for a try-block, which may be given by - TRY_BLOCK. */ - -void -finish_handler_sequence (try_block) - tree try_block; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (try_block, TRY_HANDLERS (try_block)); - else - { - expand_end_all_catch (); - } -} - -/* Begin a handler. Returns a HANDLER if appropriate. */ - -tree -begin_handler () -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (HANDLER, NULL_TREE, NULL_TREE); - add_tree (r); - } - else - r = NULL_TREE; - - do_pushlevel (); - - return r; -} - -/* Finish the handler-parameters for a handler, which may be given by - HANDLER. */ - -void -finish_handler_parms (handler) - tree handler; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (handler, HANDLER_PARMS (handler)); -} - -/* Finish a handler, which may be given by HANDLER. */ - -void -finish_handler (handler) - tree handler; -{ - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (handler, HANDLER_BODY (handler)); - else - expand_end_catch_block (); - - do_poplevel (); -} - -/* Begin a compound-statement. If HAS_NO_SCOPE is non-zero, the - compound-statement does not define a scope. Returns a new - COMPOUND_STMT if appropriate. */ - -tree -begin_compound_stmt (has_no_scope) - int has_no_scope; -{ - tree r; - - if (processing_template_decl) - { - r = build_min_nt (COMPOUND_STMT, NULL_TREE); - add_tree (r); - if (has_no_scope) - COMPOUND_STMT_NO_SCOPE (r) = 1; - } - else - r = NULL_TREE; - - if (!has_no_scope) - do_pushlevel (); - - return r; -} - - -/* Finish a compound-statement, which may be given by COMPOUND_STMT. - If HAS_NO_SCOPE is non-zero, the compound statement does not define - a scope. */ - -tree -finish_compound_stmt (has_no_scope, compound_stmt) - int has_no_scope; - tree compound_stmt; -{ - tree r; - - if (!has_no_scope) - r = do_poplevel (); - else - r = NULL_TREE; - - if (processing_template_decl) - RECHAIN_STMTS_FROM_CHAIN (compound_stmt, - COMPOUND_BODY (compound_stmt)); - - finish_stmt (); - - return r; -} - -/* Finish an asm-statement, whose components are a CV_QUALIFIER, a - STRING, some OUTPUT_OPERANDS, some INPUT_OPERANDS, and some - CLOBBERS. */ - -void -finish_asm_stmt (cv_qualifier, string, output_operands, - input_operands, clobbers) - tree cv_qualifier; - tree string; - tree output_operands; - tree input_operands; - tree clobbers; -{ - if (TREE_CHAIN (string)) - string = combine_strings (string); - - if (processing_template_decl) - { - tree r = build_min_nt (ASM_STMT, cv_qualifier, string, - output_operands, input_operands, - clobbers); - add_tree (r); - } - else - { - emit_line_note (input_filename, lineno); - if (output_operands != NULL_TREE || input_operands != NULL_TREE - || clobbers != NULL_TREE) - { - if (cv_qualifier != NULL_TREE - && cv_qualifier != ridpointers[(int) RID_VOLATILE]) - cp_warning ("%s qualifier ignored on asm", - IDENTIFIER_POINTER (cv_qualifier)); - - c_expand_asm_operands (string, output_operands, - input_operands, - clobbers, - cv_qualifier - == ridpointers[(int) RID_VOLATILE], - input_filename, lineno); - } - else - { - /* Don't warn about redundant specification of 'volatile' here. */ - if (cv_qualifier != NULL_TREE - && cv_qualifier != ridpointers[(int) RID_VOLATILE]) - cp_warning ("%s qualifier ignored on asm", - IDENTIFIER_POINTER (cv_qualifier)); - expand_asm (string); - } - - finish_stmt (); - } -} - -/* Finish a parenthesized expression EXPR. */ - -tree -finish_parenthesized_expr (expr) - tree expr; -{ - if (IS_EXPR_CODE_CLASS (TREE_CODE_CLASS (TREE_CODE (expr)))) - /* This inhibits warnings in truthvalue_conversion. */ - C_SET_EXP_ORIGINAL_CODE (expr, ERROR_MARK); - - return expr; -} - -/* Begin a statement-expression. The value returned must be passed to - finish_stmt_expr. */ - -tree -begin_stmt_expr () -{ - keep_next_level (); - /* If we're processing_template_decl, then the upcoming compound - statement will be chained onto the tree structure, starting at - last_tree. We return last_tree so that we can later unhook the - compound statement. */ - return processing_template_decl ? last_tree : expand_start_stmt_expr(); -} - -/* Finish a statement-expression. RTL_EXPR should be the value - returned by the previous begin_stmt_expr; EXPR is the - statement-expression. Returns an expression representing the - statement-expression. */ - -tree -finish_stmt_expr (rtl_expr, expr) - tree rtl_expr; - tree expr; -{ - tree result; - - if (!processing_template_decl) - { - rtl_expr = expand_end_stmt_expr (rtl_expr); - /* The statements have side effects, so the group does. */ - TREE_SIDE_EFFECTS (rtl_expr) = 1; - } - - if (TREE_CODE (expr) == BLOCK) - { - /* Make a BIND_EXPR for the BLOCK already made. */ - if (processing_template_decl) - result = build_min_nt (BIND_EXPR, NULL_TREE, last_tree, - NULL_TREE); - else - result = build (BIND_EXPR, TREE_TYPE (rtl_expr), - NULL_TREE, rtl_expr, expr); - - /* Remove the block from the tree at this point. - It gets put back at the proper place - when the BIND_EXPR is expanded. */ - delete_block (expr); - } - else - result = expr; - - if (processing_template_decl) - { - /* Remove the compound statement from the tree structure; it is - now saved in the BIND_EXPR. */ - last_tree = rtl_expr; - TREE_CHAIN (last_tree) = NULL_TREE; - } - - return result; -} - -/* Finish a call to FN with ARGS. Returns a representation of the - call. */ - -tree -finish_call_expr (fn, args, koenig) - tree fn; - tree args; - int koenig; -{ - tree result; - - if (koenig) - { - if (TREE_CODE (fn) == BIT_NOT_EXPR) - fn = build_x_unary_op (BIT_NOT_EXPR, TREE_OPERAND (fn, 0)); - else if (TREE_CODE (fn) != TEMPLATE_ID_EXPR) - fn = do_identifier (fn, 2, args); - } - result = build_x_function_call (fn, args, current_class_ref); - - if (TREE_CODE (result) == CALL_EXPR - && TREE_TYPE (result) != void_type_node) - result = require_complete_type (result); - - return result; -} - -/* Finish a call to a postfix increment or decrement or EXPR. (Which - is indicated by CODE, which should be POSTINCREMENT_EXPR or - POSTDECREMENT_EXPR.) */ - -tree -finish_increment_expr (expr, code) - tree expr; - enum tree_code code; -{ - /* If we get an OFFSET_REF, turn it into what it really means (e.g., - a COMPONENT_REF). This way if we've got, say, a reference to a - static member that's being operated on, we don't end up trying to - find a member operator for the class it's in. */ - - if (TREE_CODE (expr) == OFFSET_REF) - expr = resolve_offset_ref (expr); - return build_x_unary_op (code, expr); -} - -/* Finish a use of `this'. Returns an expression for `this'. */ - -tree -finish_this_expr () -{ - tree result; - - if (current_class_ptr) - { -#ifdef WARNING_ABOUT_CCD - TREE_USED (current_class_ptr) = 1; -#endif - result = current_class_ptr; - } - else if (current_function_decl - && DECL_STATIC_FUNCTION_P (current_function_decl)) - { - error ("`this' is unavailable for static member functions"); - result = error_mark_node; - } - else - { - if (current_function_decl) - error ("invalid use of `this' in non-member function"); - else - error ("invalid use of `this' at top level"); - result = error_mark_node; - } - - return result; -} - -/* Finish a member function call using OBJECT and ARGS as arguments to - FN. Returns an expression for the call. */ - -tree -finish_object_call_expr (fn, object, args) - tree fn; - tree object; - tree args; -{ -#if 0 - /* This is a future direction of this code, but because - build_x_function_call cannot always undo what is done in - build_component_ref entirely yet, we cannot do this. */ - - tree real_fn = build_component_ref (object, fn, NULL_TREE, 1); - return finish_call_expr (real_fn, args); -#else - if (TREE_CODE (fn) == TYPE_DECL) - { - if (processing_template_decl) - /* This can happen on code like: - - class X; - template <class T> void f(T t) { - t.X(); - } - - We just grab the underlying IDENTIFIER. */ - fn = DECL_NAME (fn); - else - { - cp_error ("calling type `%T' like a method", fn); - return error_mark_node; - } - } - - return build_method_call (object, fn, args, NULL_TREE, LOOKUP_NORMAL); -#endif -} - -/* Finish a qualified member function call using OBJECT and ARGS as - arguments to FN. Returns an expressino for the call. */ - -tree -finish_qualified_object_call_expr (fn, object, args) - tree fn; - tree object; - tree args; -{ - if (IS_SIGNATURE (TREE_OPERAND (fn, 0))) - { - warning ("signature name in scope resolution ignored"); - return finish_object_call_expr (TREE_OPERAND (fn, 1), object, args); - } - else - return build_scoped_method_call (object, TREE_OPERAND (fn, 0), - TREE_OPERAND (fn, 1), args); -} - -/* Finish a pseudo-destructor call expression of OBJECT, with SCOPE - being the scope, if any, of DESTRUCTOR. Returns an expression for - the call. */ - -tree -finish_pseudo_destructor_call_expr (object, scope, destructor) - tree object; - tree scope; - tree destructor; -{ - if (scope && scope != destructor) - cp_error ("destructor specifier `%T::~%T()' must have matching names", - scope, destructor); - - if ((scope == NULL_TREE || IDENTIFIER_GLOBAL_VALUE (destructor)) - && (TREE_CODE (TREE_TYPE (object)) != - TREE_CODE (TREE_TYPE (IDENTIFIER_GLOBAL_VALUE (destructor))))) - cp_error ("`%E' is not of type `%T'", object, destructor); - - return cp_convert (void_type_node, object); -} - -/* Finish a call to a globally qualified member function FN using - ARGS. Returns an expression for the call. */ - -tree -finish_qualified_call_expr (fn, args) - tree fn; - tree args; -{ - if (processing_template_decl) - return build_min_nt (CALL_EXPR, copy_to_permanent (fn), args, - NULL_TREE); - else - return build_member_call (TREE_OPERAND (fn, 0), - TREE_OPERAND (fn, 1), - args); -} - -/* Finish an expression taking the address of LABEL. Returns an - expression for the address. */ - -tree -finish_label_address_expr (label) - tree label; -{ - tree result; - - label = lookup_label (label); - if (label == NULL_TREE) - result = null_pointer_node; - else - { - TREE_USED (label) = 1; - result = build1 (ADDR_EXPR, ptr_type_node, label); - TREE_CONSTANT (result) = 1; - } - - return result; -} - -/* Finish an expression of the form CODE EXPR. */ - -tree -finish_unary_op_expr (code, expr) - enum tree_code code; - tree expr; -{ - tree result = build_x_unary_op (code, expr); - if (code == NEGATE_EXPR && TREE_CODE (expr) == INTEGER_CST) - TREE_NEGATED_INT (result) = 1; - overflow_warning (result); - return result; -} - -/* Finish an id-expression. */ - -tree -finish_id_expr (expr) - tree expr; -{ - if (TREE_CODE (expr) == IDENTIFIER_NODE) - expr = do_identifier (expr, 1, NULL_TREE); - - return expr; -} - -/* Begin a new-placement. */ - -int -begin_new_placement () -{ - /* The arguments to a placement new might be passed to a - deallocation function, in the event that the allocation throws an - exception. Since we don't expand exception handlers until the - end of a function, we must make sure the arguments stay around - that long. */ - return suspend_momentary (); -} - -/* Finish a new-placement. The ARGS are the placement arguments. The - COOKIE is the value returned by the previous call to - begin_new_placement. */ - -tree -finish_new_placement (args, cookie) - tree args; - int cookie; -{ - resume_momentary (cookie); - return args; -} - -/* Begin a function defniition declared with DECL_SPECS and - DECLARATOR. Returns non-zero if the function-declaration is - legal. */ - -int -begin_function_definition (decl_specs, declarator) - tree decl_specs; - tree declarator; -{ - tree specs; - tree attrs; - split_specs_attrs (decl_specs, &specs, &attrs); - if (!start_function (specs, declarator, attrs, 0)) - return 0; - - reinit_parse_for_function (); - /* The things we're about to see are not directly qualified by any - template headers we've seen thus far. */ - reset_specialization (); - - return 1; -} - -/* Begin a constructor declarator of the form `SCOPE::NAME'. Returns - a SCOPE_REF. */ - -tree -begin_constructor_declarator (scope, name) - tree scope; - tree name; -{ - tree result = build_parse_node (SCOPE_REF, scope, name); - enter_scope_of (result); - return result; -} - -/* Finish an init-declarator. Returns a DECL. */ - -tree -finish_declarator (declarator, declspecs, attributes, - prefix_attributes, initialized) - tree declarator; - tree declspecs; - tree attributes; - tree prefix_attributes; - int initialized; -{ - return start_decl (declarator, declspecs, initialized, attributes, - prefix_attributes); -} - -/* Finish a translation unit. */ - -void -finish_translation_unit () -{ - /* In case there were missing closebraces, - get us back to the global binding level. */ - while (! toplevel_bindings_p ()) - poplevel (0, 0, 0); - while (current_namespace != global_namespace) - pop_namespace (); - finish_file (); -} - -/* Finish a template type parameter, specified as AGGR IDENTIFIER. - Returns the parameter. */ - -tree -finish_template_type_parm (aggr, identifier) - tree aggr; - tree identifier; -{ - if (aggr == signature_type_node) - sorry ("signature as template type parameter"); - else if (aggr != class_type_node) - { - pedwarn ("template type parameters must use the keyword `class' or `typename'"); - aggr = class_type_node; - } - - return build_tree_list (aggr, identifier); -} - -/* Finish a template template parameter, specified as AGGR IDENTIFIER. - Returns the parameter. */ - -tree -finish_template_template_parm (aggr, identifier) - tree aggr; - tree identifier; -{ - tree decl = build_decl (TYPE_DECL, identifier, NULL_TREE); - tree tmpl = build_lang_decl (TEMPLATE_DECL, identifier, NULL_TREE); - DECL_TEMPLATE_PARMS (tmpl) = current_template_parms; - DECL_TEMPLATE_RESULT (tmpl) = decl; - SET_DECL_ARTIFICIAL (decl); - end_template_decl (); - - return finish_template_type_parm (aggr, tmpl); -} - -/* Finish a parameter list, indicated by PARMS. If ELLIPSIS is - non-zero, the parameter list was terminated by a `...'. */ - -tree -finish_parmlist (parms, ellipsis) - tree parms; - int ellipsis; -{ - if (!ellipsis) - chainon (parms, void_list_node); - /* We mark the PARMS as a parmlist so that declarator processing can - disambiguate certain constructs. */ - if (parms != NULL_TREE) - TREE_PARMLIST (parms) = 1; - - return parms; -} - -/* Begin a class definition, as indicated by T. */ - -tree -begin_class_definition (t) - tree t; -{ - push_obstacks_nochange (); - end_temporary_allocation (); - - if (t == error_mark_node - || ! IS_AGGR_TYPE (t)) - { - t = make_lang_type (RECORD_TYPE); - pushtag (make_anon_name (), t, 0); - } - - /* In a definition of a member class template, we will get here with an - implicit typename, a TYPENAME_TYPE with a type. */ - if (TREE_CODE (t) == TYPENAME_TYPE) - t = TREE_TYPE (t); - - /* If we generated a partial instantiation of this type, but now - we're seeing a real definition, we're actually looking at a - partial specialization. Consider: - - template <class T, class U> - struct Y {}; - - template <class T> - struct X {}; - - template <class T, class U> - void f() - { - typename X<Y<T, U> >::A a; - } - - template <class T, class U> - struct X<Y<T, U> > - { - }; - - We have to undo the effects of the previous partial - instantiation. */ - if (PARTIAL_INSTANTIATION_P (t)) - { - if (!pedantic) - { - /* Unfortunately, when we're not in pedantic mode, we - attempt to actually fill in some of the fields of the - partial instantiation, in order to support the implicit - typename extension. Clear those fields now, in - preparation for the definition here. The fields cleared - here must match those set in instantiate_class_template. - Look for a comment mentioning begin_class_definition - there. */ - TYPE_BINFO_BASETYPES (t) = NULL_TREE; - TYPE_FIELDS (t) = NULL_TREE; - TYPE_METHODS (t) = NULL_TREE; - CLASSTYPE_TAGS (t) = NULL_TREE; - TYPE_SIZE (t) = NULL_TREE; - } - - /* This isn't a partial instantiation any more. */ - PARTIAL_INSTANTIATION_P (t) = 0; - } - /* If this type was already complete, and we see another definition, - that's an error. */ - else if (TYPE_SIZE (t)) - duplicate_tag_error (t); - - if (TYPE_BEING_DEFINED (t)) - { - t = make_lang_type (TREE_CODE (t)); - pushtag (TYPE_IDENTIFIER (t), t, 0); - } - maybe_process_partial_specialization (t); - if (processing_template_decl - && ! CLASSTYPE_TEMPLATE_SPECIALIZATION (t) - && TYPE_CONTEXT (t) && TYPE_P (TYPE_CONTEXT (t)) - && ! current_class_type) - push_template_decl (TYPE_STUB_DECL (t)); - pushclass (t, 0); - TYPE_BEING_DEFINED (t) = 1; - /* Reset the interface data, at the earliest possible - moment, as it might have been set via a class foo; - before. */ - /* Don't change signatures. */ - if (! IS_SIGNATURE (t)) - { - int needs_writing; - tree name = TYPE_IDENTIFIER (t); - - if (! ANON_AGGRNAME_P (name)) - { - CLASSTYPE_INTERFACE_ONLY (t) = interface_only; - SET_CLASSTYPE_INTERFACE_UNKNOWN_X - (t, interface_unknown); - } - - /* Record how to set the access of this class's - virtual functions. If write_virtuals == 3, then - inline virtuals are ``extern inline''. */ - if (write_virtuals == 3) - needs_writing = ! CLASSTYPE_INTERFACE_ONLY (t) - && CLASSTYPE_INTERFACE_KNOWN (t); - else - needs_writing = 1; - CLASSTYPE_VTABLE_NEEDS_WRITING (t) = needs_writing; - } -#if 0 - tmp = TYPE_IDENTIFIER ($<ttype>0); - if (tmp && IDENTIFIER_TEMPLATE (tmp)) - overload_template_name (tmp, 1); -#endif - reset_specialization(); - - /* In case this is a local class within a template - function, we save the current tree structure so - that we can get it back later. */ - begin_tree (); - - return t; -} - -/* Finish the member declaration given by DECL. */ - -void -finish_member_declaration (decl) - tree decl; -{ - if (decl == error_mark_node || decl == NULL_TREE) - return; - - if (decl == void_type_node) - /* The COMPONENT was a friend, not a member, and so there's - nothing for us to do. */ - return; - - /* We should see only one DECL at a time. */ - my_friendly_assert (TREE_CHAIN (decl) == NULL_TREE, 0); - - /* Set up access control for DECL. */ - TREE_PRIVATE (decl) - = (current_access_specifier == access_private_node); - TREE_PROTECTED (decl) - = (current_access_specifier == access_protected_node); - if (TREE_CODE (decl) == TEMPLATE_DECL) - { - TREE_PRIVATE (DECL_RESULT (decl)) = TREE_PRIVATE (decl); - TREE_PROTECTED (DECL_RESULT (decl)) = TREE_PROTECTED (decl); - } - - /* Mark the DECL as a member of the current class. */ - if (TREE_CODE (decl) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (decl)) - /* Historically, DECL_CONTEXT was not set for a FUNCTION_DECL in - finish_struct. Presumably it is already set as the function is - parsed. Perhaps DECL_CLASS_CONTEXT is already set, too? */ - DECL_CLASS_CONTEXT (decl) = current_class_type; - else if (TREE_CODE (decl) == TYPE_DECL) - /* Historically, DECL_CONTEXT was not set for a TYPE_DECL in - finish_struct, so we do not do it here either. Perhaps we - should, though. */ - ; - else - DECL_CONTEXT (decl) = current_class_type; - - /* Put functions on the TYPE_METHODS list and everything else on the - TYPE_FIELDS list. Note that these are built up in reverse order. - We reverse them (to obtain declaration order) in finish_struct. */ - if (TREE_CODE (decl) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (decl)) - { - /* We also need to add this function to the - CLASSTYPE_METHOD_VEC. */ - add_method (current_class_type, 0, decl); - - TREE_CHAIN (decl) = TYPE_METHODS (current_class_type); - TYPE_METHODS (current_class_type) = decl; - } - else - { - /* All TYPE_DECLs go at the end of TYPE_FIELDS. Ordinary fields - go at the beginning. The reason is that lookup_field_1 - searches the list in order, and we want a field name to - override a type name so that the "struct stat hack" will - work. In particular: - - struct S { enum E { }; int E } s; - s.E = 3; - - is legal. In addition, the FIELD_DECLs must be maintained in - declaration order so that class layout works as expected. - However, we don't need that order until class layout, so we - save a little time by putting FIELD_DECLs on in reverse order - here, and then reversing them in finish_struct_1. (We could - also keep a pointer to the correct insertion points in the - list.) */ - - if (TREE_CODE (decl) == TYPE_DECL) - TYPE_FIELDS (current_class_type) - = chainon (TYPE_FIELDS (current_class_type), decl); - else - { - TREE_CHAIN (decl) = TYPE_FIELDS (current_class_type); - TYPE_FIELDS (current_class_type) = decl; - } - } -} - -/* Finish a class definition T with the indicate ATTRIBUTES. If SEMI, - the definition is immediately followed by a semicolon. Returns the - type. */ - -tree -finish_class_definition (t, attributes, semi) - tree t; - tree attributes; - int semi; -{ -#if 0 - /* Need to rework class nesting in the presence of nested classes, - etc. */ - shadow_tag (CLASSTYPE_AS_LIST (t)); */ -#endif - - /* finish_struct nukes this anyway; if finish_exception does too, - then it can go. */ - if (semi) - note_got_semicolon (t); - - /* If we got any attributes in class_head, xref_tag will stick them in - TREE_TYPE of the type. Grab them now. */ - attributes = chainon (TREE_TYPE (t), attributes); - TREE_TYPE (t) = NULL_TREE; - - if (TREE_CODE (t) == ENUMERAL_TYPE) - ; - else - { - t = finish_struct (t, attributes, semi); - if (semi) - note_got_semicolon (t); - } - - pop_obstacks (); - - if (! semi) - check_for_missing_semicolon (t); - if (current_scope () == current_function_decl) - do_pending_defargs (); - - return t; -} - -/* Finish processing the default argument expressions cached during - the processing of a class definition. */ - -void -finish_default_args () -{ - if (pending_inlines - && current_scope () == current_function_decl) - do_pending_inlines (); -} - -/* Finish processing the inline function definitions cached during the - processing of a class definition. */ - -void -begin_inline_definitions () -{ - if (current_class_type == NULL_TREE) - clear_inline_text_obstack (); - - /* Undo the begin_tree in begin_class_definition. */ - end_tree (); -} - -/* Finish processing the declaration of a member class template - TYPES whose template parameters are given by PARMS. */ - -tree -finish_member_class_template (types) - tree types; -{ - tree t; - - /* If there are declared, but undefined, partial specializations - mixed in with the typespecs they will not yet have passed through - maybe_process_partial_specialization, so we do that here. */ - for (t = types; t != NULL_TREE; t = TREE_CHAIN (t)) - if (IS_AGGR_TYPE_CODE (TREE_CODE (TREE_VALUE (t)))) - maybe_process_partial_specialization (TREE_VALUE (t)); - - note_list_got_semicolon (types); - grok_x_components (types); - if (TYPE_CONTEXT (TREE_VALUE (types)) != current_class_type) - /* The component was in fact a friend declaration. We avoid - finish_member_template_decl performing certain checks by - unsetting TYPES. */ - types = NULL_TREE; - - finish_member_template_decl (types); - - /* As with other component type declarations, we do - not store the new DECL on the list of - component_decls. */ - return NULL_TREE; -} - -/* Finish processsing a complete template declaration. The PARMS are - the template parameters. */ - -void -finish_template_decl (parms) - tree parms; -{ - if (parms) - end_template_decl (); - else - end_specialization (); -} - -/* Finish processing a a template-id (which names a type) of the form - NAME < ARGS >. Return the TYPE_DECL for the type named by the - template-id. If ENTERING_SCOPE is non-zero we are about to enter - the scope of template-id indicated. */ - -tree -finish_template_type (name, args, entering_scope) - tree name; - tree args; - int entering_scope; -{ - tree decl; - - decl = lookup_template_class (name, args, - NULL_TREE, NULL_TREE, entering_scope); - if (decl != error_mark_node) - decl = TYPE_STUB_DECL (decl); - - return decl; -} - -/* SR is a SCOPE_REF node. Enter the scope of SR, whether it is a - namespace scope or a class scope. */ - -void -enter_scope_of (sr) - tree sr; -{ - tree scope = TREE_OPERAND (sr, 0); - - if (TREE_CODE (scope) == NAMESPACE_DECL) - { - push_decl_namespace (scope); - TREE_COMPLEXITY (sr) = -1; - } - else if (scope != current_class_type) - { - if (TREE_CODE (scope) == TYPENAME_TYPE) - { - /* In a declarator for a template class member, the scope will - get here as an implicit typename, a TYPENAME_TYPE with a type. */ - scope = TREE_TYPE (scope); - TREE_OPERAND (sr, 0) = scope; - } - push_nested_class (scope, 3); - TREE_COMPLEXITY (sr) = current_class_depth; - } -} - -/* Finish processing a BASE_CLASS with the indicated ACCESS_SPECIFIER. - Return a TREE_LIST containing the ACCESS_SPECIFIER and the - BASE_CLASS, or NULL_TREE if an error occurred. The - ACCESSS_SPECIFIER is one of - access_{default,public,protected_private}[_virtual]_node.*/ - -tree -finish_base_specifier (access_specifier, base_class, - current_aggr_is_signature) - tree access_specifier; - tree base_class; - int current_aggr_is_signature; -{ - tree type; - tree result; - - if (base_class == NULL_TREE) - { - error ("invalid base class"); - type = error_mark_node; - } - else - type = TREE_TYPE (base_class); - if (current_aggr_is_signature && access_specifier) - error ("access and source specifiers not allowed in signature"); - if (! is_aggr_type (type, 1)) - result = NULL_TREE; - else if (current_aggr_is_signature - && (! type) && (! IS_SIGNATURE (type))) - { - error ("class name not allowed as base signature"); - result = NULL_TREE; - } - else if (current_aggr_is_signature) - { - sorry ("signature inheritance, base type `%s' ignored", - IDENTIFIER_POINTER (access_specifier)); - result = build_tree_list (access_public_node, type); - } - else if (type && IS_SIGNATURE (type)) - { - error ("signature name not allowed as base class"); - result = NULL_TREE; - } - else - result = build_tree_list (access_specifier, type); - - return result; -} - -/* Called when multiple declarators are processed. If that is not - premitted in this context, an error is issued. */ - -void -check_multiple_declarators () -{ - /* [temp] - - In a template-declaration, explicit specialization, or explicit - instantiation the init-declarator-list in the declaration shall - contain at most one declarator. - - We don't just use PROCESSING_TEMPLATE_DECL for the first - condition since that would disallow the perfectly legal code, - like `template <class T> struct S { int i, j; };'. */ - tree scope = current_scope (); - - if (scope && TREE_CODE (scope) == FUNCTION_DECL) - /* It's OK to write `template <class T> void f() { int i, j;}'. */ - return; - - if (PROCESSING_REAL_TEMPLATE_DECL_P () - || processing_explicit_instantiation - || processing_specialization) - cp_error ("multiple declarators in template declaration"); -} - -tree -finish_typeof (expr) - tree expr; -{ - if (processing_template_decl) - { - tree t; - - push_obstacks_nochange (); - end_temporary_allocation (); - - t = make_lang_type (TYPEOF_TYPE); - TYPE_FIELDS (t) = expr; - - pop_obstacks (); - - return t; - } - - return TREE_TYPE (expr); -} diff --git a/gcc/cp/sig.c b/gcc/cp/sig.c deleted file mode 100755 index f264d31..0000000 --- a/gcc/cp/sig.c +++ /dev/null @@ -1,1071 +0,0 @@ -/* Functions dealing with signatures and signature pointers/references. - Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. - Contributed by Gerald Baumgartner (gb@cs.purdue.edu) - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "obstack.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" -#include "assert.h" -#include "toplev.h" - -extern struct obstack *current_obstack; -extern struct obstack permanent_obstack; -extern struct obstack *saveable_obstack; - -extern void compiler_error (); - -static tree save_this PROTO((tree)); -static tree build_sptr_ref PROTO((tree)); -static tree build_member_function_pointer PROTO((tree)); -static void undo_casts PROTO((tree)); -static tree build_signature_pointer_or_reference_name - PROTO((tree, int, int)); -static void build_signature_pointer_or_reference_decl - PROTO((tree, tree)); -static tree build_signature_pointer_or_reference_type - PROTO((tree, int, int)); -static tree get_sigtable_name PROTO((tree, tree)); -static tree build_signature_table_constructor PROTO((tree, tree)); -static int match_method_types PROTO((tree, tree)); -static tree build_sigtable PROTO((tree, tree, tree)); - -/* Used to help generate globally unique names for signature tables. */ - -static int global_sigtable_name_counter; - -/* Build an identifier for a signature pointer or reference, so we - can use it's name in function name mangling. */ - -static tree -build_signature_pointer_or_reference_name (to_type, type_quals, refp) - tree to_type; - int type_quals; - int refp; -{ - char * sig_name = TYPE_NAME_STRING (to_type); - int name_len = TYPE_NAME_LENGTH (to_type) + 3 /* Enough room for - C,V,R. */; - char * name; - - char *const_rep = (type_quals & TYPE_QUAL_CONST) ? "C" : ""; - char *restrict_rep = (type_quals & TYPE_QUAL_RESTRICT) ? "R" : ""; - char *volatile_rep = (type_quals & TYPE_QUAL_VOLATILE) ? "C" : ""; - - if (refp) - { - name = (char *) alloca (name_len + sizeof (SIGNATURE_REFERENCE_NAME) +2); - sprintf (name, SIGNATURE_REFERENCE_NAME_FORMAT, - const_rep, volatile_rep, restrict_rep, sig_name); - } - else - { - name = (char *) alloca (name_len + sizeof (SIGNATURE_POINTER_NAME) + 2); - sprintf (name, SIGNATURE_POINTER_NAME_FORMAT, - const_rep, volatile_rep, restrict_rep, sig_name); - } - return get_identifier (name); -} - -/* Build a DECL node for a signature pointer or reference, so we can - tell the debugger the structure of signature pointers/references. - This function is called at most eight times for a given signature, - once for each [const] [volatile] signature pointer/reference. */ - -static void -build_signature_pointer_or_reference_decl (type, name) - tree type, name; -{ - tree decl; - - /* We don't enter this declaration in any sort of symbol table. */ - decl = build_decl (TYPE_DECL, name, type); - TYPE_NAME (type) = decl; - TREE_CHAIN (type) = decl; -} - -/* Construct, lay out and return the type of pointers or references to - signature TO_TYPE. If such a type has already been constructed, - reuse it. If TYPE_QUALS are specified, qualify the `optr'. If we - are constructing a const/volatile type variant and the main type - variant doesn't exist yet, it is built as well. If REFP is 1, we - construct a signature reference, otherwise a signature pointer is - constructed. - - This function is a subroutine of `build_signature_pointer_type' and - `build_signature_reference_type'. */ - -static tree -build_signature_pointer_or_reference_type (to_type, type_quals, refp) - tree to_type; - int type_quals; - int refp; -{ - register tree t, m; - register struct obstack *ambient_obstack = current_obstack; - register struct obstack *ambient_saveable_obstack = saveable_obstack; - - m = refp ? SIGNATURE_REFERENCE_TO (to_type) : SIGNATURE_POINTER_TO (to_type); - - /* If we don't have the main variant yet, construct it. */ - if (m == NULL_TREE && type_quals != TYPE_UNQUALIFIED) - m = build_signature_pointer_or_reference_type (to_type, - TYPE_UNQUALIFIED, refp); - - /* Treat any nonzero argument as 1. */ - refp = !!refp; - - /* If not generating auxiliary info, search the chain of variants to see - if there is already one there just like the one we need to have. If so, - use that existing one. - - We don't do this in the case where we are generating aux info because - in that case we want each typedef names to get it's own distinct type - node, even if the type of this new typedef is the same as some other - (existing) type. */ - - if (m && !flag_gen_aux_info) - for (t = m; t; t = TYPE_NEXT_VARIANT (t)) - if (type_quals == CP_TYPE_QUALS (TREE_TYPE (TREE_TYPE - (TYPE_FIELDS (t))))) - return t; - - /* We need a new one. If TO_TYPE is permanent, make this permanent too. */ - if (TREE_PERMANENT (to_type)) - { - current_obstack = &permanent_obstack; - saveable_obstack = &permanent_obstack; - } - - /* A signature pointer or reference to a signature `s' looks like this: - - struct { - void * optr; - const s * sptr; - }; - - A `const' signature pointer/reference is a - - struct { - const void * optr; - const s * sptr; - }; - - Similarly, for `volatile' and `const volatile'. */ - - t = make_lang_type (RECORD_TYPE); - { - tree obj_type = build_qualified_type (void_type_node, type_quals); - tree optr_type = build_pointer_type (obj_type); - tree optr, sptr; - - optr = build_lang_field_decl (FIELD_DECL, - get_identifier (SIGNATURE_OPTR_NAME), - optr_type); - DECL_FIELD_CONTEXT (optr) = t; - DECL_CLASS_CONTEXT (optr) = t; - - if (m) - /* We can share the `sptr' field among type variants. */ - sptr = TREE_CHAIN (TYPE_FIELDS (m)); - else - { - tree sig_tbl_type = - cp_build_qualified_type (to_type, TYPE_QUAL_CONST); - - sptr = build_lang_field_decl (FIELD_DECL, - get_identifier (SIGNATURE_SPTR_NAME), - build_pointer_type (sig_tbl_type)); - DECL_FIELD_CONTEXT (sptr) = t; - DECL_CLASS_CONTEXT (sptr) = t; - TREE_CHAIN (sptr) = NULL_TREE; - } - - TREE_CHAIN (optr) = sptr; - TYPE_FIELDS (t) = optr; - /* Allow signature pointers/references to be grabbed 2 words at a time. - For this to work on a Sparc, we need 8-byte alignment. */ - TYPE_ALIGN (t) = MAX (TYPE_ALIGN (double_type_node), - TYPE_ALIGN (optr_type)); - - /* A signature pointer/reference type isn't a `real' class type. */ - SET_IS_AGGR_TYPE (t, 0); - } - - { - tree name = build_signature_pointer_or_reference_name (to_type, - type_quals, - refp); - - /* Build a DECL node for this type, so the debugger has access to it. */ - build_signature_pointer_or_reference_decl (t, name); - } - - CLASSTYPE_GOT_SEMICOLON (t) = 1; - IS_SIGNATURE_POINTER (t) = ! refp; - IS_SIGNATURE_REFERENCE (t) = refp; - SIGNATURE_TYPE (t) = to_type; - - if (m) - { - /* Add this type to the chain of variants of TYPE. - Every type has to be its own TYPE_MAIN_VARIANT. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - } - else if (refp) - /* Record this type as the reference to TO_TYPE. */ - SIGNATURE_REFERENCE_TO (to_type) = t; - else - /* Record this type as the pointer to TO_TYPE. */ - SIGNATURE_POINTER_TO (to_type) = t; - - /* Lay out the type. This function has many callers that are concerned - with expression-construction, and this simplifies them all. - Also, it guarantees the TYPE_SIZE is permanent if the type is. */ - layout_type (t); - - current_obstack = ambient_obstack; - saveable_obstack = ambient_saveable_obstack; - - /* Output debug information for this type. */ - rest_of_type_compilation (t, 1); - - return t; -} - -/* Construct, lay out and return the type of pointers to signature TO_TYPE. */ - -tree -build_signature_pointer_type (to_type) - tree to_type; -{ - return - build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type), - CP_TYPE_QUALS (to_type), 0); -} - -/* Construct, lay out and return the type of pointers to signature TO_TYPE. */ - -tree -build_signature_reference_type (to_type) - tree to_type; -{ - return - build_signature_pointer_or_reference_type (TYPE_MAIN_VARIANT (to_type), - CP_TYPE_QUALS (to_type), 1); -} - -/* Return the name of the signature table (as an IDENTIFIER_NODE) - for the given signature type SIG_TYPE and rhs type RHS_TYPE. */ - -static tree -get_sigtable_name (sig_type, rhs_type) - tree sig_type, rhs_type; -{ - tree sig_type_id = build_typename_overload (sig_type); - tree rhs_type_id = build_typename_overload (rhs_type); - char *buf = (char *) alloca (sizeof (SIGTABLE_NAME_FORMAT_LONG) - + IDENTIFIER_LENGTH (sig_type_id) - + IDENTIFIER_LENGTH (rhs_type_id) + 20); - char *sig_ptr = IDENTIFIER_POINTER (sig_type_id); - char *rhs_ptr = IDENTIFIER_POINTER (rhs_type_id); - int i, j; - - for (i = 0; sig_ptr[i] == OPERATOR_TYPENAME_FORMAT[i]; i++) - /* do nothing */; - while (sig_ptr[i] >= '0' && sig_ptr[i] <= '9') - i += 1; - - for (j = 0; rhs_ptr[j] == OPERATOR_TYPENAME_FORMAT[j]; j++) - /* do nothing */; - while (rhs_ptr[j] >= '0' && rhs_ptr[j] <= '9') - j += 1; - - if (IS_SIGNATURE (rhs_type)) - sprintf (buf, SIGTABLE_NAME_FORMAT_LONG, sig_ptr+i, rhs_ptr+j, - global_sigtable_name_counter++); - else - sprintf (buf, SIGTABLE_NAME_FORMAT, sig_ptr+i, rhs_ptr+j); - return get_identifier (buf); -} - -/* Build a field decl that points to a signature member function. */ - -static tree -build_member_function_pointer (member) - tree member; -{ - char *namstr = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (member)); - int namlen = IDENTIFIER_LENGTH (DECL_ASSEMBLER_NAME (member)); - char *name; - tree entry; - - name = (char *) alloca (namlen + sizeof (SIGNATURE_FIELD_NAME) + 2); - sprintf (name, SIGNATURE_FIELD_NAME_FORMAT, namstr); - - /* @@ Do we really want to xref signature table fields? */ - GNU_xref_ref (current_function_decl, name); - - entry = build_lang_field_decl (FIELD_DECL, get_identifier (name), - sigtable_entry_type); - TREE_CONSTANT (entry) = 1; - TREE_READONLY (entry) = 1; - - /* @@ Do we really want to xref signature table fields? */ - GNU_xref_decl (current_function_decl, entry); - - return entry; -} - -/* For each FUNCTION_DECL in a signature we construct a member function - pointer of the appropriate type. We also need two flags to test - whether the member function pointer points to a virtual function or - to a default implementation. Those flags will be the two lower order - bits of the member function pointer (or the two higher order bits, - based on the configuration). - - The new FIELD_DECLs are appended at the end of the last (and only) - sublist of `list_of_fieldlists.' - - T is the signature type. - - As a side effect, each member function in the signature gets the - `decl.ignored' bit turned on, so we don't output debug info for it. */ - -void -append_signature_fields (t) - tree t; -{ - tree x; - tree mfptr; - tree last_mfptr = NULL_TREE; - tree mfptr_list = NULL_TREE; - - for (x = TYPE_METHODS (t); x; x = TREE_CHAIN (x)) - { - if (TREE_CODE (x) == FUNCTION_DECL) - { - mfptr = build_member_function_pointer (x); - DECL_MEMFUNC_POINTER_TO (x) = mfptr; - DECL_MEMFUNC_POINTING_TO (mfptr) = x; - DECL_IGNORED_P (x) = 1; - DECL_IN_AGGR_P (mfptr) = 1; - if (! mfptr_list) - mfptr_list = last_mfptr = mfptr; - else - { - TREE_CHAIN (last_mfptr) = mfptr; - last_mfptr = mfptr; - } - } - } - - /* The member function pointers must come after the TYPE_DECLs, in - this case, because build_signature_table_constructor depends on - finding opaque TYPE_DECLS before the functions that make use of - them. */ - if (last_mfptr) - TYPE_FIELDS (t) = chainon (TYPE_FIELDS (t), mfptr_list); -} - -/* Compare the types of a signature member function and a class member - function. Returns 1 if the types are in the C++ `<=' relationship. - - If we have a signature pointer/reference as argument or return type - we don't want to do a recursive conformance check. The conformance - check only succeeds if both LHS and RHS refer to the same signature - pointer. Otherwise we need to keep information about parameter types - around at run time to initialize the signature table correctly. */ - -static int -match_method_types (sig_mtype, class_mtype) - tree sig_mtype, class_mtype; -{ - tree sig_return_type = TREE_TYPE (sig_mtype); - tree sig_arg_types = TYPE_ARG_TYPES (sig_mtype); - tree class_return_type = TREE_TYPE (class_mtype); - tree class_arg_types = TYPE_ARG_TYPES (class_mtype); - - /* The return types have to be the same. */ - if (!same_type_p (sig_return_type, class_return_type)) - return 0; - - /* Compare the first argument `this.' */ - { - /* Get the type of what the `optr' is pointing to. */ - tree sig_this - = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (TREE_VALUE (sig_arg_types)))); - tree class_this = TREE_VALUE (class_arg_types); - - if (TREE_CODE (class_this) == RECORD_TYPE) /* Is `this' a sig ptr? */ - class_this = TREE_TYPE (TREE_TYPE (TYPE_FIELDS (class_this))); - else - class_this = TREE_TYPE (class_this); - - /* If a signature method's `this' is const or volatile, so has to be - the corresponding class method's `this.' */ - if (!at_least_as_qualified_p (class_this, sig_this)) - return 0; - } - - sig_arg_types = TREE_CHAIN (sig_arg_types); - class_arg_types = TREE_CHAIN (class_arg_types); - - /* The number of arguments and the argument types have to be the same. */ - return compparms (sig_arg_types, class_arg_types); -} - -/* Undo casts of opaque type variables to the RHS types. */ - -static void -undo_casts (sig_ty) - tree sig_ty; -{ - tree field = TYPE_FIELDS (sig_ty); - - /* Since all the FIELD_DECLs for the signature table entries are at the end - of the chain (see `append_signature_fields'), we can do it this way. */ - for (; field && TREE_CODE (field) != FIELD_DECL; field = TREE_CHAIN (field)) - if (TYPE_MAIN_VARIANT (TREE_TYPE (field)) == opaque_type_node) - TREE_TYPE (TREE_TYPE (field)) = TREE_TYPE (ptr_type_node); -} - -/* Do the type checking necessary to see whether the `rhs' conforms to - the lhs's `sig_ty'. Depending on the type of `rhs' return a NULL_TREE, - an integer_zero_node, a constructor, or an expression offsetting the - `rhs' signature table. */ - -static tree -build_signature_table_constructor (sig_ty, rhs) - tree sig_ty, rhs; -{ - tree rhstype = TREE_TYPE (rhs); - tree sig_field = TYPE_FIELDS (sig_ty); - tree result = NULL_TREE; - tree first_rhs_field = NULL_TREE; - tree last_rhs_field = NULL_TREE; - int sig_ptr_p = IS_SIGNATURE (rhstype); - int offset_p = sig_ptr_p; - - rhstype = sig_ptr_p ? rhstype : TREE_TYPE (rhstype); - - if (CLASSTYPE_TAGS (sig_ty)) - { - sorry ("conformance check with signature containing class declarations"); - return error_mark_node; - } - - for (; sig_field; sig_field = TREE_CHAIN (sig_field)) - { - tree basetype_path, baselink, basetypes; - tree sig_method, sig_mname, sig_mtype; - tree rhs_method, tbl_entry; - - if (TREE_CODE (sig_field) == TYPE_DECL) - { - tree sig_field_type = TREE_TYPE (sig_field); - - if (TYPE_MAIN_VARIANT (sig_field_type) == opaque_type_node) - { - /* We've got an opaque type here. */ - tree oty_name = DECL_NAME (sig_field); - tree oty_type = lookup_field (rhstype, oty_name, 1, 1); - - if (oty_type == NULL_TREE || oty_type == error_mark_node) - { - cp_error ("class `%T' does not contain type `%T'", - rhstype, oty_type); - undo_casts (sig_ty); - return error_mark_node; - } - oty_type = TREE_TYPE (oty_type); - - /* Cast `sig_field' to be of type `oty_type'. This will be - undone in `undo_casts' by walking over all the TYPE_DECLs. */ - TREE_TYPE (sig_field_type) = TREE_TYPE (oty_type); - } - /* If we don't have an opaque type, we can ignore the `typedef'. */ - continue; - } - - /* Find the signature method corresponding to `sig_field'. */ - sig_method = DECL_MEMFUNC_POINTING_TO (sig_field); - sig_mname = DECL_NAME (sig_method); - sig_mtype = TREE_TYPE (sig_method); - - basetype_path = TYPE_BINFO (rhstype); - baselink = lookup_fnfields (basetype_path, sig_mname, 0); - if (baselink == NULL_TREE || baselink == error_mark_node) - { - if (! IS_DEFAULT_IMPLEMENTATION (sig_method)) - { - cp_error ("class `%T' does not contain method `%D'", - rhstype, sig_mname); - undo_casts (sig_ty); - return error_mark_node; - } - else - { - /* We use the signature's default implementation. */ - rhs_method = sig_method; - } - } - else - { - /* Find the class method of the correct type. */ - tree rhs_methods; - basetypes = TREE_PURPOSE (baselink); - if (TREE_CODE (basetypes) == TREE_LIST) - basetypes = TREE_VALUE (basetypes); - - rhs_methods = TREE_VALUE (baselink); - for (; rhs_methods; rhs_methods = OVL_NEXT (rhs_methods)) - if ((rhs_method = OVL_CURRENT (rhs_methods)) - && sig_mname == DECL_NAME (rhs_method) - && ! DECL_STATIC_FUNCTION_P (rhs_method) - && match_method_types (sig_mtype, TREE_TYPE (rhs_method))) - break; - - if (rhs_methods == NULL_TREE - || (compute_access (basetypes, rhs_method) - != access_public_node)) - { - error ("class `%s' does not contain a method conforming to `%s'", - TYPE_NAME_STRING (rhstype), - fndecl_as_string (sig_method, 1)); - undo_casts (sig_ty); - return error_mark_node; - } - } - - if (sig_ptr_p && rhs_method != sig_method) - { - tree rhs_field = DECL_MEMFUNC_POINTER_TO (rhs_method); - - if (first_rhs_field == NULL_TREE) - { - first_rhs_field = rhs_field; - last_rhs_field = rhs_field; - } - else if (TREE_CHAIN (last_rhs_field) == rhs_field) - last_rhs_field = rhs_field; - else - offset_p = 0; - - tbl_entry = build_component_ref (rhs, DECL_NAME (rhs_field), - NULL_TREE, 1); - } - else - { - tree tag, vb_off, delta, idx, pfn = NULL_TREE, vt_off = NULL_TREE; - tree tag_decl, vb_off_decl, delta_decl, index_decl; - tree pfn_decl, vt_off_decl; - - if (rhs_method == sig_method) - { - /* default implementation */ - tag = build_unary_op (NEGATE_EXPR, integer_one_node, 0); - vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); - delta = integer_zero_node; - idx = integer_zero_node; - pfn = build_addr_func (rhs_method); - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1; - TREE_TYPE (pfn) = ptr_type_node; - TREE_ADDRESSABLE (rhs_method) = 1; - offset_p = 0; /* we can't offset the rhs sig table */ - } - else if (DECL_VINDEX (rhs_method)) - { - /* virtual member function */ - tag = integer_one_node; - vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); - if (flag_vtable_thunks) - delta = BINFO_OFFSET - (get_binfo (DECL_CONTEXT (rhs_method), rhstype, 1)); - else - delta = BINFO_OFFSET - (get_binfo (DECL_CLASS_CONTEXT (rhs_method), rhstype, 1)); - idx = DECL_VINDEX (rhs_method); - vt_off = get_vfield_offset (get_binfo (DECL_CONTEXT (rhs_method), - rhstype, 0)); - } - else - { - /* non-virtual member function */ - tag = integer_zero_node; - vb_off = build_unary_op (NEGATE_EXPR, integer_one_node, 0); - delta = BINFO_OFFSET (get_binfo (DECL_CLASS_CONTEXT (rhs_method), - rhstype, 1)); - idx = integer_zero_node; - pfn = build_addr_func (rhs_method); - TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (rhs_method)) = 1; - TREE_TYPE (pfn) = ptr_type_node; - TREE_ADDRESSABLE (rhs_method) = 1; - } - - /* Since digest_init doesn't handle initializing selected fields - of a struct (i.e., anonymous union), we build the constructor - by hand, without calling digest_init. */ - tag_decl = TYPE_FIELDS (sigtable_entry_type); - vb_off_decl = TREE_CHAIN (tag_decl); - delta_decl = TREE_CHAIN (vb_off_decl); - index_decl = TREE_CHAIN (delta_decl); - pfn_decl = TREE_CHAIN (index_decl); - vt_off_decl = TREE_CHAIN (pfn_decl); - - tag = cp_convert (TREE_TYPE (tag_decl), tag); - vb_off = cp_convert (TREE_TYPE (vb_off_decl), vb_off); - delta = cp_convert (TREE_TYPE (delta_decl), delta); - idx = cp_convert (TREE_TYPE (index_decl), idx); - - if (DECL_VINDEX (rhs_method)) - { - vt_off = cp_convert (TREE_TYPE (vt_off_decl), vt_off); - - tbl_entry = build_tree_list (vt_off_decl, vt_off); - } - else - { - pfn = cp_convert (TREE_TYPE (pfn_decl), pfn); - - tbl_entry = build_tree_list (pfn_decl, pfn); - } - tbl_entry = tree_cons (delta_decl, delta, - tree_cons (index_decl, idx, tbl_entry)); - tbl_entry = tree_cons (tag_decl, tag, - tree_cons (vb_off_decl, vb_off, tbl_entry)); - tbl_entry = build (CONSTRUCTOR, sigtable_entry_type, - NULL_TREE, tbl_entry); - - TREE_CONSTANT (tbl_entry) = 1; - } - - /* Chain those function address expressions together. */ - if (result) - result = tree_cons (NULL_TREE, tbl_entry, result); - else - result = build_tree_list (NULL_TREE, tbl_entry); - } - - if (result == NULL_TREE) - { - /* The signature was empty, we don't need a signature table. */ - undo_casts (sig_ty); - return NULL_TREE; - } - - if (offset_p) - { - if (first_rhs_field == TYPE_FIELDS (rhstype)) - { - /* The sptr field on the lhs can be copied from the rhs. */ - undo_casts (sig_ty); - return integer_zero_node; - } - else - { - /* The sptr field on the lhs will point into the rhs sigtable. */ - undo_casts (sig_ty); - return build_component_ref (rhs, DECL_NAME (first_rhs_field), - NULL_TREE, 0); - } - } - - /* We need to construct a new signature table. */ - result = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (result)); - TREE_HAS_CONSTRUCTOR (result) = 1; - TREE_CONSTANT (result) = !sig_ptr_p; - - undo_casts (sig_ty); - return result; -} - -/* Build a signature table declaration and initialize it or return an - existing one if we built one already. If we don't get a constructor - as initialization expression, we don't need a new signature table - variable and just hand back the init expression. - - The declaration processing is done by hand instead of using `cp_finish_decl' - so that we can make signature pointers global variables instead of - static ones. */ - -static tree -build_sigtable (sig_type, rhs_type, init_from) - tree sig_type, rhs_type, init_from; -{ - tree name = NULL_TREE; - tree decl = NULL_TREE; - tree init_expr; - - push_obstacks_nochange (); - end_temporary_allocation (); - - if (! IS_SIGNATURE (rhs_type)) - { - name = get_sigtable_name (sig_type, rhs_type); - decl = IDENTIFIER_GLOBAL_VALUE (name); - } - if (decl == NULL_TREE) - { - tree init = NULL_TREE; - - /* We allow only one signature table to be generated for signatures - with opaque types. Otherwise we create a loophole in the type - system since we could cast data from one classes implementation - of the opaque type to that of another class. */ - if (SIGNATURE_HAS_OPAQUE_TYPEDECLS (sig_type) - && SIGTABLE_HAS_BEEN_GENERATED (sig_type)) - { - error ("signature with opaque type implemented by multiple classes"); - return error_mark_node; - } - SIGTABLE_HAS_BEEN_GENERATED (sig_type) = 1; - - init_expr = build_signature_table_constructor (sig_type, init_from); - if (init_expr == NULL_TREE || TREE_CODE (init_expr) != CONSTRUCTOR) - return init_expr; - - if (name == NULL_TREE) - name = get_sigtable_name (sig_type, rhs_type); - { - tree context = current_function_decl; - - /* Make the signature table global, not just static in whichever - function a signature pointer/ref is used for the first time. */ - current_function_decl = NULL_TREE; - decl = pushdecl_top_level (build_decl (VAR_DECL, name, sig_type)); - current_function_decl = context; - } - SET_IDENTIFIER_GLOBAL_VALUE (name, decl); - store_init_value (decl, init_expr); - if (IS_SIGNATURE (rhs_type)) - { - init = DECL_INITIAL (decl); - DECL_INITIAL (decl) = error_mark_node; - } - - DECL_ALIGN (decl) = MAX (TYPE_ALIGN (double_type_node), - DECL_ALIGN (decl)); -#if 0 - /* GDB-4.7 doesn't find the initialization value of a signature table - when it is constant. */ - TREE_READONLY (decl) = 1; -#endif - TREE_STATIC (decl) = 1; - TREE_USED (decl) = 1; - - make_decl_rtl (decl, NULL, 1); - if (IS_SIGNATURE (rhs_type)) - expand_static_init (decl, init); - } - - pop_obstacks (); - - return decl; -} - -/* Create a constructor or modify expression if the LHS of an assignment - is a signature pointer or a signature reference. If LHS is a record - type node, we build a constructor, otherwise a compound expression. */ - -tree -build_signature_pointer_constructor (lhs, rhs) - tree lhs, rhs; -{ - register struct obstack *ambient_obstack = current_obstack; - register struct obstack *ambient_saveable_obstack = saveable_obstack; - int initp = (TREE_CODE (lhs) == RECORD_TYPE); - tree lhstype = initp ? lhs : TREE_TYPE (lhs); - tree rhstype = TREE_TYPE (rhs); - tree sig_ty = SIGNATURE_TYPE (lhstype); - tree sig_tbl, sptr_expr, optr_expr; - tree result; - - if (! ((TREE_CODE (rhstype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (rhstype)) == RECORD_TYPE) - || (TYPE_LANG_SPECIFIC (rhstype) - && (IS_SIGNATURE_POINTER (rhstype) - || IS_SIGNATURE_REFERENCE (rhstype))))) - { - error ("invalid assignment to signature pointer or reference"); - return error_mark_node; - } - - if (TYPE_SIZE (sig_ty) == NULL_TREE) - { - cp_error ("undefined signature `%T' used in signature %s declaration", - sig_ty, - IS_SIGNATURE_POINTER (lhstype) ? "pointer" : "reference"); - return error_mark_node; - } - - /* If SIG_TY is permanent, make the signature table constructor and - the signature pointer/reference constructor permanent too. */ - if (TREE_PERMANENT (sig_ty)) - { - current_obstack = &permanent_obstack; - saveable_obstack = &permanent_obstack; - } - - if (TYPE_LANG_SPECIFIC (rhstype) - && (IS_SIGNATURE_POINTER (rhstype) || IS_SIGNATURE_REFERENCE (rhstype))) - { - if (SIGNATURE_TYPE (rhstype) == sig_ty) - { - /* LHS and RHS are signature pointers/refs of the same signature. */ - optr_expr = build_optr_ref (rhs); - sptr_expr = build_sptr_ref (rhs); - } - else - { - /* We need to create a new signature table and copy - elements from the rhs signature table. */ - tree rhs_sptr_ref = build_sptr_ref (rhs); - tree rhs_tbl = build1 (INDIRECT_REF, SIGNATURE_TYPE (rhstype), - rhs_sptr_ref); - - sig_tbl = build_sigtable (sig_ty, SIGNATURE_TYPE (rhstype), rhs_tbl); - if (sig_tbl == error_mark_node) - return error_mark_node; - - optr_expr = build_optr_ref (rhs); - if (sig_tbl == NULL_TREE) - /* The signature was empty. The signature pointer is - pretty useless, but the user has been warned. */ - sptr_expr = copy_node (null_pointer_node); - else if (sig_tbl == integer_zero_node) - sptr_expr = rhs_sptr_ref; - else - sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0); - TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty); - } - } - else - { - sig_tbl = build_sigtable (sig_ty, TREE_TYPE (rhstype), rhs); - if (sig_tbl == error_mark_node) - return error_mark_node; - - optr_expr = rhs; - if (sig_tbl == NULL_TREE) - /* The signature was empty. The signature pointer is - pretty useless, but the user has been warned. */ - { - sptr_expr = copy_node (null_pointer_node); - TREE_TYPE (sptr_expr) = build_pointer_type (sig_ty); - } - else - sptr_expr = build_unary_op (ADDR_EXPR, sig_tbl, 0); - } - - if (initp) - { - result = tree_cons (NULL_TREE, optr_expr, - build_tree_list (NULL_TREE, sptr_expr)); - result = build_nt (CONSTRUCTOR, NULL_TREE, result); - result = digest_init (lhstype, result, 0); - } - else - { - if (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype)) - readonly_error (lhs, "assignment", 0); - - optr_expr = build_modify_expr (build_optr_ref (lhs), NOP_EXPR, - optr_expr); - sptr_expr = build_modify_expr (build_sptr_ref (lhs), NOP_EXPR, - sptr_expr); - - result = tree_cons (NULL_TREE, optr_expr, - tree_cons (NULL_TREE, sptr_expr, - build_tree_list (NULL_TREE, lhs))); - result = build_compound_expr (result); - } - - current_obstack = ambient_obstack; - saveable_obstack = ambient_saveable_obstack; - return result; -} - -/* Build a temporary variable declaration for the instance of a signature - member function call if it isn't a declaration node already. Simply - using a SAVE_EXPR doesn't work since we need `this' in both branches - of a conditional expression. */ - -static tree -save_this (instance) - tree instance; -{ - tree decl; - - if (TREE_CODE_CLASS (TREE_CODE (instance)) == 'd') - decl = instance; - else - { - decl = build_decl (VAR_DECL, NULL_TREE, TREE_TYPE (instance)); - DECL_REGISTER (decl) = 1; - layout_decl (decl, 0); - expand_decl (decl); - } - - return decl; -} - -/* Build a signature member function call. Looks up the signature table - entry corresponding to FUNCTION. Depending on the value of the CODE - field, either call the function in PFN directly, or use OFFSET to - index the object's virtual function table. */ - -tree -build_signature_method_call (function, parms) - tree function, parms; -{ - tree instance = TREE_VALUE (parms); - tree saved_instance = save_this (instance); /* Create temp for `this'. */ - tree object_ptr = build_optr_ref (saved_instance); - tree new_object_ptr, new_parms; - tree signature_tbl_ptr = build_sptr_ref (saved_instance); - tree sig_field_name = DECL_NAME (DECL_MEMFUNC_POINTER_TO (function)); - tree basetype = DECL_CONTEXT (function); - tree basetype_path = TYPE_BINFO (basetype); - tree tbl_entry = build_component_ref (build1 (INDIRECT_REF, basetype, - signature_tbl_ptr), - sig_field_name, basetype_path, 1); - tree tag, delta, pfn, vt_off, idx, vfn; - tree deflt_call = NULL_TREE, direct_call, virtual_call, result; - - tbl_entry = save_expr (tbl_entry); - tag = build_component_ref (tbl_entry, tag_identifier, NULL_TREE, 1); - delta = build_component_ref (tbl_entry, delta_identifier, NULL_TREE, 1); - pfn = build_component_ref (tbl_entry, pfn_identifier, NULL_TREE, 1); - vt_off = build_component_ref (tbl_entry, vt_off_identifier, NULL_TREE, 1); - idx = build_component_ref (tbl_entry, index_identifier, NULL_TREE, 1); - TREE_TYPE (pfn) = build_pointer_type (TREE_TYPE (function)); - - if (IS_DEFAULT_IMPLEMENTATION (function)) - { - pfn = save_expr (pfn); - deflt_call = build_function_call (pfn, parms); - } - - new_object_ptr = build (PLUS_EXPR, build_pointer_type (basetype), - cp_convert (ptrdiff_type_node, object_ptr), - cp_convert (ptrdiff_type_node, delta)); - - parms = tree_cons (NULL_TREE, - cp_convert (build_pointer_type (basetype), object_ptr), - TREE_CHAIN (parms)); - new_parms = tree_cons (NULL_TREE, new_object_ptr, TREE_CHAIN (parms)); - - { - /* Cast the signature method to have `this' of a normal pointer type. */ - tree old_this = TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))); - - TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) - = build_qualified_type (build_pointer_type (basetype), - TYPE_QUALS (old_this)); - - direct_call = build_function_call (pfn, new_parms); - - { - tree vfld, vtbl, aref; - - vfld = build (PLUS_EXPR, - build_pointer_type (build_pointer_type (vtbl_type_node)), - cp_convert (ptrdiff_type_node, object_ptr), - cp_convert (ptrdiff_type_node, vt_off)); - vtbl = build_indirect_ref (build_indirect_ref (vfld, NULL_PTR), - NULL_PTR); - aref = build_array_ref (vtbl, idx); - - if (flag_vtable_thunks) - vfn = aref; - else - vfn = build_component_ref (aref, pfn_identifier, NULL_TREE, 0); - - TREE_TYPE (vfn) = build_pointer_type (TREE_TYPE (function)); - - virtual_call = build_function_call (vfn, new_parms); - } - - /* Undo the cast, make `this' a signature pointer again. */ - TREE_VALUE (TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (pfn)))) = old_this; - } - - /* Once the function was found, there should be no reason why we - couldn't build the member function pointer call. */ - if (!direct_call || direct_call == error_mark_node - || !virtual_call || virtual_call == error_mark_node - || (IS_DEFAULT_IMPLEMENTATION (function) - && (!deflt_call || deflt_call == error_mark_node))) - { - compiler_error ("cannot build call of signature member function `%s'", - fndecl_as_string (function, 1)); - return error_mark_node; - } - - if (IS_DEFAULT_IMPLEMENTATION (function)) - { - tree test = build_binary_op_nodefault (LT_EXPR, tag, integer_zero_node, - LT_EXPR); - result = build_conditional_expr (tag, - build_conditional_expr (test, - deflt_call, - virtual_call), - direct_call); - } - else - result = build_conditional_expr (tag, virtual_call, direct_call); - - /* If we created a temporary variable for `this', initialize it first. */ - if (instance != saved_instance) - result = build (COMPOUND_EXPR, TREE_TYPE (result), - build_modify_expr (saved_instance, NOP_EXPR, instance), - result); - - return result; -} - -/* Create a COMPONENT_REF expression for referencing the OPTR field - of a signature pointer or reference. */ - -tree -build_optr_ref (instance) - tree instance; -{ - tree field = get_identifier (SIGNATURE_OPTR_NAME); - - return build_component_ref (instance, field, NULL_TREE, 1); -} - -/* Create a COMPONENT_REF expression for referencing the SPTR field - of a signature pointer or reference. */ - -static tree -build_sptr_ref (instance) - tree instance; -{ - tree field = get_identifier (SIGNATURE_SPTR_NAME); - - return build_component_ref (instance, field, NULL_TREE, 1); -} diff --git a/gcc/cp/spew.c b/gcc/cp/spew.c deleted file mode 100755 index a573cba..0000000 --- a/gcc/cp/spew.c +++ /dev/null @@ -1,489 +0,0 @@ -/* Type Analyzer for GNU C++. - Copyright (C) 1987, 89, 92-97, 1998 Free Software Foundation, Inc. - Hacked... nay, bludgeoned... by Mark Eichin (eichin@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file is the type analyzer for GNU C++. To debug it, define SPEW_DEBUG - when compiling parse.c and spew.c. */ - -#include "config.h" -#include "system.h" -#include "input.h" -#include "tree.h" -#include "lex.h" -#include "cp-tree.h" -#include "parse.h" -#include "flags.h" -#include "obstack.h" -#include "toplev.h" - -/* This takes a token stream that hasn't decided much about types and - tries to figure out as much as it can, with excessive lookahead and - backtracking. */ - -/* fifo of tokens recognized and available to parser. */ -struct token { - /* The values for YYCHAR will fit in a short. */ - short yychar; - short end_of_file; - YYSTYPE yylval; -}; - -static int do_aggr PROTO((void)); -static int probe_obstack PROTO((struct obstack *, tree, unsigned int)); -static void scan_tokens PROTO((unsigned int)); - -#ifdef SPEW_DEBUG -static int num_tokens PROTO((void)); -static struct token *nth_token PROTO((int)); -static void add_token PROTO((struct token *)); -static void consume_token PROTO((void)); -static int debug_yychar PROTO((int)); -#endif - -/* From lex.c: */ -/* the declaration found for the last IDENTIFIER token read in. - yylex must look this up to detect typedefs, which get token type TYPENAME, - so it is left around in case the identifier is not a typedef but is - used in a context which makes it a reference to a variable. */ -extern tree lastiddecl; /* let our brains leak out here too */ -extern int yychar; /* the lookahead symbol */ -extern YYSTYPE yylval; /* the semantic value of the */ - /* lookahead symbol */ -extern int end_of_file; - -struct obstack token_obstack; -int first_token; - -#ifdef SPEW_DEBUG -int spew_debug = 0; -static unsigned int yylex_ctr = 0; -static int debug_yychar (); -#endif - -/* Initialize token_obstack. Called once, from init_parse. */ - -void -init_spew () -{ - gcc_obstack_init (&token_obstack); -} - -#ifdef SPEW_DEBUG -/* Use functions for debugging... */ - -/* Return the number of tokens available on the fifo. */ - -static int -num_tokens () -{ - return (obstack_object_size (&token_obstack) / sizeof (struct token)) - - first_token; -} - -/* Fetch the token N down the line from the head of the fifo. */ - -static struct token* -nth_token (n) - int n; -{ - /* could just have this do slurp_ implicitly, but this way is easier - to debug... */ - my_friendly_assert (n < num_tokens (), 298); - return ((struct token*)obstack_base (&token_obstack)) + n + first_token; -} - -/* Add a token to the token fifo. */ - -static void -add_token (t) - struct token* t; -{ - obstack_grow (&token_obstack, t, sizeof (struct token)); -} - -/* Consume the next token out of the fifo. */ - -static void -consume_token () -{ - if (num_tokens () == 1) - { - obstack_free (&token_obstack, obstack_base (&token_obstack)); - first_token = 0; - } - else - first_token++; -} - -#else -/* ...otherwise use macros. */ - -#define num_tokens() \ - ((obstack_object_size (&token_obstack) / sizeof (struct token)) - first_token) - -#define nth_token(N) \ - (((struct token*)obstack_base (&token_obstack))+(N)+first_token) - -#define add_token(T) obstack_grow (&token_obstack, (T), sizeof (struct token)) - -#define consume_token() \ - (num_tokens () == 1 \ - ? (obstack_free (&token_obstack, obstack_base (&token_obstack)), \ - (first_token = 0)) \ - : first_token++) -#endif - -/* Pull in enough tokens from real_yylex that the queue is N long beyond - the current token. */ - -static void -scan_tokens (n) - unsigned int n; -{ - unsigned int i; - struct token *tmp; - - /* We cannot read past certain tokens, so make sure we don't. */ - i = num_tokens (); - if (i > n) - return; - while (i-- > 0) - { - tmp = nth_token (i); - /* Never read past these characters: they might separate - the current input stream from one we save away later. */ - if (tmp->yychar == '{' || tmp->yychar == ':' || tmp->yychar == ';') - goto pad_tokens; - } - - while (num_tokens () <= n) - { - obstack_blank (&token_obstack, sizeof (struct token)); - tmp = ((struct token *)obstack_next_free (&token_obstack))-1; - tmp->yychar = real_yylex (); - tmp->end_of_file = end_of_file; - tmp->yylval = yylval; - end_of_file = 0; - if (tmp->yychar == '{' - || tmp->yychar == ':' - || tmp->yychar == ';') - { - pad_tokens: - while (num_tokens () <= n) - { - obstack_blank (&token_obstack, sizeof (struct token)); - tmp = ((struct token *)obstack_next_free (&token_obstack))-1; - tmp->yychar = EMPTY; - tmp->end_of_file = 0; - } - } - } -} - -/* Like _obstack_allocated_p, but stop after checking NLEVELS chunks. */ - -static int -probe_obstack (h, obj, nlevels) - struct obstack *h; - tree obj; - unsigned int nlevels; -{ - register struct _obstack_chunk* lp; /* below addr of any objects in this chunk */ - register struct _obstack_chunk* plp; /* point to previous chunk if any */ - - lp = (h)->chunk; - /* We use >= rather than > since the object cannot be exactly at - the beginning of the chunk but might be an empty object exactly - at the end of an adjacent chunk. */ - for (; nlevels != 0 && lp != 0 && ((tree)lp >= obj || (tree)lp->limit < obj); - nlevels -= 1) - { - plp = lp->prev; - lp = plp; - } - return nlevels != 0 && lp != 0; -} - -/* from lex.c: */ -/* Value is 1 (or 2) if we should try to make the next identifier look like - a typename (when it may be a local variable or a class variable). - Value is 0 if we treat this name in a default fashion. */ -extern int looking_for_typename; -int looking_for_template; -extern int do_snarf_defarg; - -extern struct obstack *current_obstack, *saveable_obstack; -tree got_scope; -tree got_object; - -int -peekyylex () -{ - scan_tokens (0); - return nth_token (0)->yychar; -} - -int -yylex () -{ - struct token tmp_token; - tree trrr = NULL_TREE; - int old_looking_for_typename = 0; - - retry: -#ifdef SPEW_DEBUG - if (spew_debug) - { - yylex_ctr ++; - fprintf (stderr, "\t\t## %d ##", yylex_ctr); - } -#endif - - if (do_snarf_defarg) - { - my_friendly_assert (num_tokens () == 0, 2837); - tmp_token.yychar = DEFARG; - tmp_token.yylval.ttype = snarf_defarg (); - tmp_token.end_of_file = 0; - do_snarf_defarg = 0; - add_token (&tmp_token); - } - - /* if we've got tokens, send them */ - else if (num_tokens ()) - { - tmp_token= *nth_token (0); - - /* TMP_TOKEN.YYLVAL.TTYPE may have been allocated on the wrong obstack. - If we don't find it in CURRENT_OBSTACK's current or immediately - previous chunk, assume it was and copy it to the current obstack. */ - if ((tmp_token.yychar == CONSTANT - || tmp_token.yychar == STRING) - && ! TREE_PERMANENT (tmp_token.yylval.ttype) - && ! probe_obstack (current_obstack, tmp_token.yylval.ttype, 2) - && ! probe_obstack (saveable_obstack, tmp_token.yylval.ttype, 2)) - tmp_token.yylval.ttype = copy_node (tmp_token.yylval.ttype); - } - else - { - /* if not, grab the next one and think about it */ - tmp_token.yychar = real_yylex (); - tmp_token.yylval = yylval; - tmp_token.end_of_file = end_of_file; - add_token (&tmp_token); - } - - /* many tokens just need to be returned. At first glance, all we - have to do is send them back up, but some of them are needed to - figure out local context. */ - switch (tmp_token.yychar) - { - case EMPTY: - /* This is a lexical no-op. */ - consume_token (); -#ifdef SPEW_DEBUG - if (spew_debug) - debug_yychar (tmp_token.yychar); -#endif - goto retry; - - case IDENTIFIER: - scan_tokens (1); - if (nth_token (1)->yychar == SCOPE) - { - /* Don't interfere with the setting from an 'aggr' prefix. */ - old_looking_for_typename = looking_for_typename; - looking_for_typename = 1; - } - else if (nth_token (1)->yychar == '<') - looking_for_template = 1; - - trrr = lookup_name (tmp_token.yylval.ttype, -2); - - if (trrr) - { - tmp_token.yychar = identifier_type (trrr); - switch (tmp_token.yychar) - { - case TYPENAME: - case SELFNAME: - case NSNAME: - case PTYPENAME: - lastiddecl = trrr; - - /* If this got special lookup, remember it. In these cases, - we don't have to worry about being a declarator-id. */ - if (got_scope || got_object) - tmp_token.yylval.ttype = trrr; - break; - - case PFUNCNAME: - case IDENTIFIER: - lastiddecl = trrr; - break; - - default: - my_friendly_abort (101); - } - } - else - lastiddecl = NULL_TREE; - got_scope = NULL_TREE; - /* and fall through to... */ - case IDENTIFIER_DEFN: - case TYPENAME: - case TYPENAME_DEFN: - case PTYPENAME: - case PTYPENAME_DEFN: - consume_token (); - /* If we see a SCOPE next, restore the old value. - Otherwise, we got what we want. */ - looking_for_typename = old_looking_for_typename; - looking_for_template = 0; - break; - - case SCSPEC: - /* If export, warn that it's unimplemented and go on. */ - if (tmp_token.yylval.ttype == get_identifier("export")) - { - warning ("keyword 'export' not implemented and will be ignored"); - consume_token (); - goto retry; - } - else - { - ++first_token; - break; - } - - case NEW: - /* do_aggr needs to check if the previous token was RID_NEW, - so just increment first_token instead of calling consume_token. */ - ++first_token; - break; - - case TYPESPEC: - consume_token (); - break; - - case AGGR: - *nth_token (0) = tmp_token; - do_aggr (); - /* fall through to output... */ - case ENUM: - /* Set this again, in case we are rescanning. */ - looking_for_typename = 2; - /* fall through... */ - default: - consume_token (); - } - - /* class member lookup only applies to the first token after the object - expression, except for explicit destructor calls. */ - if (tmp_token.yychar != '~') - got_object = NULL_TREE; - - /* Clear looking_for_typename if we got 'enum { ... };'. */ - if (tmp_token.yychar == '{' || tmp_token.yychar == ':' - || tmp_token.yychar == ';') - looking_for_typename = 0; - - yylval = tmp_token.yylval; - yychar = tmp_token.yychar; - end_of_file = tmp_token.end_of_file; -#ifdef SPEW_DEBUG - if (spew_debug) - debug_yychar (yychar); -#endif - - return yychar; -} - -/* token[0] == AGGR (struct/union/enum) - Thus, token[1] is either a TYPENAME or a TYPENAME_DEFN. - If token[2] == '{' or ':' then it's TYPENAME_DEFN. - It's also a definition if it's a forward declaration (as in 'struct Foo;') - which we can tell if token[2] == ';' *and* token[-1] != FRIEND or NEW. */ - -static int -do_aggr () -{ - int yc1, yc2; - - scan_tokens (2); - yc1 = nth_token (1)->yychar; - if (yc1 != TYPENAME && yc1 != IDENTIFIER && yc1 != PTYPENAME) - return 0; - yc2 = nth_token (2)->yychar; - if (yc2 == ';') - { - /* It's a forward declaration iff we were not preceded by - 'friend' or `new'. */ - if (first_token > 0) - { - if (nth_token (-1)->yychar == SCSPEC - && nth_token (-1)->yylval.ttype == ridpointers[(int) RID_FRIEND]) - return 0; - if (nth_token (-1)->yychar == NEW) - return 0; - } - } - else if (yc2 != '{' && yc2 != ':') - return 0; - - switch (yc1) - { - case TYPENAME: - nth_token (1)->yychar = TYPENAME_DEFN; - break; - case PTYPENAME: - nth_token (1)->yychar = PTYPENAME_DEFN; - break; - case IDENTIFIER: - nth_token (1)->yychar = IDENTIFIER_DEFN; - break; - default: - my_friendly_abort (102); - } - return 0; -} - -#ifdef SPEW_DEBUG -/* debug_yychar takes a yychar (token number) value and prints its name. */ - -static int -debug_yychar (yy) - int yy; -{ - /* In parse.y: */ - extern char *debug_yytranslate (); - - int i; - - if (yy<256) { - fprintf (stderr, "<%d: %c >\n", yy, yy); - return 0; - } - fprintf (stderr, "<%d:%s>\n", yy, debug_yytranslate (yy)); - return 1; -} - -#endif diff --git a/gcc/cp/tinfo.cc b/gcc/cp/tinfo.cc deleted file mode 100755 index 0d782ea..0000000 --- a/gcc/cp/tinfo.cc +++ /dev/null @@ -1,134 +0,0 @@ -// Methods for type_info for -*- C++ -*- Run Time Type Identification. -// Copyright (C) 1994, 1996, 1998 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -#pragma implementation "typeinfo" - -#include <stddef.h> -#include "tinfo.h" -#include "new" // for placement new - -// This file contains the minimal working set necessary to link with code -// that uses virtual functions and -frtti but does not actually use RTTI -// functionality. - -std::type_info:: -~type_info () -{ } - -// We can't rely on common symbols being shared between shared objects. -bool type_info:: -operator== (const type_info& arg) const -{ - return (&arg == this) || (strcmp (name (), arg.name ()) == 0); -} - -extern "C" void -__rtti_class (void *addr, const char *name, - const __class_type_info::base_info *bl, size_t bn) -{ new (addr) __class_type_info (name, bl, bn); } - -extern "C" void -__rtti_si (void *addr, const char *n, const std::type_info *ti) -{ - new (addr) __si_type_info - (n, static_cast <const __user_type_info &> (*ti)); -} - -extern "C" void -__rtti_user (void *addr, const char *name) -{ new (addr) __user_type_info (name); } - -// dynamic_cast helper methods. -// Returns a pointer to the desired sub-object or 0. - -void * __user_type_info:: -dcast (const type_info& to, int, void *addr, const type_info *, void *) const -{ return (*this == to) ? addr : 0; } - -void * __si_type_info:: -dcast (const type_info& to, int require_public, void *addr, - const type_info *sub, void *subptr) const -{ - if (*this == to) - return addr; - return base.dcast (to, require_public, addr, sub, subptr); -} - -void* __class_type_info:: -dcast (const type_info& desired, int is_public, void *objptr, - const type_info *sub, void *subptr) const -{ - if (*this == desired) - return objptr; - - void *match_found = 0; - for (size_t i = 0; i < n_bases; i++) - { - if (is_public && base_list[i].access != PUBLIC) - continue; - - void *p = (char *)objptr + base_list[i].offset; - if (base_list[i].is_virtual) - p = *(void **)p; - p = base_list[i].base->dcast (desired, is_public, p, sub, subptr); - if (p) - { - if (match_found == 0) - match_found = p; - else if (match_found != p) - { - if (sub) - { - // Perhaps we're downcasting from *sub to desired; see if - // subptr is a subobject of exactly one of {match_found,p}. - - const __user_type_info &d = - static_cast <const __user_type_info &> (desired); - - void *os = d.dcast (*sub, 1, match_found); - void *ns = d.dcast (*sub, 1, p); - - if (os == ns) - /* ambiguous -- subptr is a virtual base */; - else if (os == subptr) - continue; - else if (ns == subptr) - { - match_found = p; - continue; - } - } - - // base found at two different pointers, - // conversion is not unique - return 0; - } - } - } - - return match_found; -} diff --git a/gcc/cp/tinfo.h b/gcc/cp/tinfo.h deleted file mode 100755 index 2601ce2..0000000 --- a/gcc/cp/tinfo.h +++ /dev/null @@ -1,55 +0,0 @@ -// RTTI support internals for -*- C++ -*- -// Copyright (C) 1994, 1995, 1996, 1998 Free Software Foundation - -#include "typeinfo" - -// Class declarations shared between the typeinfo implementation files. - -// type_info for a class with no base classes (or an enum). - -struct __user_type_info : public std::type_info { - __user_type_info (const char *n) : type_info (n) {} - - // If our type can be converted to the desired type, - // return the pointer, adjusted accordingly; else return 0. - virtual void* dcast (const type_info &, int, void *, - const type_info * = 0, void * = 0) const; -}; - -// type_info for a class with one public, nonvirtual base class. - -class __si_type_info : public __user_type_info { - const __user_type_info &base; - -public: - __si_type_info (const char *n, const __user_type_info &b) - : __user_type_info (n), base (b) { } - - virtual void *dcast (const type_info &, int, void *, - const type_info * = 0, void * = 0) const; -}; - -// type_info for a general class. - -typedef unsigned int USItype __attribute__ ((mode (SI))); - -struct __class_type_info : public __user_type_info { - enum access { PUBLIC = 1, PROTECTED = 2, PRIVATE = 3 }; - - struct base_info { - const __user_type_info *base; - USItype offset: 29; - bool is_virtual: 1; - access access: 2; - }; - - const base_info *base_list; - size_t n_bases; - - __class_type_info (const char *name, const base_info *bl, size_t bn) - : __user_type_info (name), base_list (bl), n_bases (bn) {} - - // This is a little complex. - virtual void* dcast (const type_info &, int, void *, - const type_info * = 0, void * = 0) const; -}; diff --git a/gcc/cp/tinfo2.cc b/gcc/cp/tinfo2.cc deleted file mode 100755 index 3de6a14..0000000 --- a/gcc/cp/tinfo2.cc +++ /dev/null @@ -1,306 +0,0 @@ -// Methods for type_info for -*- C++ -*- Run Time Type Identification. -// Copyright (C) 1994, 96-97, 1998 Free Software Foundation - -// 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 Software Foundation, 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. - -// As a special exception, if you link this library with other files, -// some of which are compiled with GCC, to produce an executable, -// this library does not by itself cause the resulting executable -// to be covered by the GNU General Public License. -// This exception does not however invalidate any other reasons why -// the executable file might be covered by the GNU General Public License. - -/* CYGNUS LOCAL embedded c++ */ -#ifndef __EMBEDDED_CXX__ -/* END CYGNUS LOCAL */ -#include <stddef.h> -#include "tinfo.h" -#include "new" // for placement new - -using std::type_info; - -bool -type_info::before (const type_info &arg) const -{ - return strcmp (name (), arg.name ()) < 0; -} - -// type info for pointer type. - -struct __pointer_type_info : public type_info { - const type_info& type; - - __pointer_type_info (const char *n, const type_info& ti) - : type_info (n), type (ti) {} -}; - -// type info for attributes - -struct __attr_type_info : public type_info { - enum cv { NONE = 0, CONST = 1, VOLATILE = 2, CONSTVOL = 1 | 2 }; - - const type_info& type; - cv attr; - - __attr_type_info (const char *n, cv a, const type_info& t) - : type_info (n), type (t), attr (a) {} -}; - -// type_info for builtin type - -struct __builtin_type_info : public type_info { - __builtin_type_info (const char *n): type_info (n) {} -}; - -// type info for function. - -struct __func_type_info : public type_info { - __func_type_info (const char *n) : type_info (n) {} -}; - -// type info for pointer to member function. - -struct __ptmf_type_info : public type_info { - __ptmf_type_info (const char *n) : type_info (n) {} -}; - -// type info for pointer to data member. - -struct __ptmd_type_info : public type_info { - __ptmd_type_info (const char *n): type_info (n) {} -}; - -// type info for array. - -struct __array_type_info : public type_info { - __array_type_info (const char *n): type_info (n) {} -}; - -// Entry points for the compiler. - -/* Low level match routine used by compiler to match types of catch - variables and thrown objects. */ - -extern "C" void* -__throw_type_match_rtti (const void *catch_type_r, const void *throw_type_r, - void *objptr) -{ - const type_info &catch_type = *(const type_info *)catch_type_r; - const type_info &throw_type = *(const type_info *)throw_type_r; - - if (catch_type == throw_type) - return objptr; - -#if 0 - printf ("We want to match a %s against a %s!\n", - throw_type.name (), catch_type.name ()); -#endif - - void *new_objptr = 0; - - if (const __user_type_info *p - = dynamic_cast <const __user_type_info *> (&throw_type)) - { - /* The 1 skips conversions to private bases. */ - new_objptr = p->dcast (catch_type, 1, objptr); - } - else if (const __pointer_type_info *fr = - dynamic_cast <const __pointer_type_info *> (&throw_type)) - { - const __pointer_type_info *to = - dynamic_cast <const __pointer_type_info *> (&catch_type); - - if (! to) - goto fail; - - const type_info *subfr = &fr->type, *subto = &to->type; - __attr_type_info::cv cvfrom, cvto; - - if (const __attr_type_info *at - = dynamic_cast <const __attr_type_info *> (subfr)) - { - cvfrom = at->attr; - subfr = &at->type; - } - else - cvfrom = __attr_type_info::NONE; - - if (const __attr_type_info *at - = dynamic_cast <const __attr_type_info *> (subto)) - { - cvto = at->attr; - subto = &at->type; - } - else - cvto = __attr_type_info::NONE; - - if (((cvfrom & __attr_type_info::CONST) - > (cvto & __attr_type_info::CONST)) - || ((cvfrom & __attr_type_info::VOLATILE) - > (cvto & __attr_type_info::VOLATILE))) - goto fail; - - if (*subto == *subfr) - new_objptr = objptr; - else if (*subto == typeid (void) - && dynamic_cast <const __func_type_info *> (subfr) == 0) - new_objptr = objptr; - else if (const __user_type_info *p - = dynamic_cast <const __user_type_info *> (subfr)) - { - /* The 1 skips conversions to private bases. */ - new_objptr = p->dcast (*subto, 1, objptr); - } - else if (const __pointer_type_info *pfr - = dynamic_cast <const __pointer_type_info *> (subfr)) - { - // Multi-level pointer conversion. - - const __pointer_type_info *pto - = dynamic_cast <const __pointer_type_info *> (subto); - - if (! pto) - goto fail; - - bool constp = (cvto & __attr_type_info::CONST); - for (subto = &pto->type, subfr = &pfr->type; ; - subto = &pto->type, subfr = &pfr->type) - { - if (const __attr_type_info *at - = dynamic_cast <const __attr_type_info *> (subfr)) - { - cvfrom = at->attr; - subfr = &at->type; - } - else - cvfrom = __attr_type_info::NONE; - - if (const __attr_type_info *at - = dynamic_cast <const __attr_type_info *> (subto)) - { - cvto = at->attr; - subto = &at->type; - } - else - cvto = __attr_type_info::NONE; - - if (((cvfrom & __attr_type_info::CONST) - > (cvto & __attr_type_info::CONST)) - || ((cvfrom & __attr_type_info::VOLATILE) - > (cvto & __attr_type_info::VOLATILE))) - goto fail; - - if (! constp - && (((cvfrom & __attr_type_info::CONST) - < (cvto & __attr_type_info::CONST)) - || ((cvfrom & __attr_type_info::VOLATILE) - < (cvto & __attr_type_info::VOLATILE)))) - goto fail; - - if (*subto == *subfr) - { - new_objptr = objptr; - break; - } - - pto = dynamic_cast <const __pointer_type_info *> (subto); - pfr = dynamic_cast <const __pointer_type_info *> (subfr); - if (! pto || ! pfr) - goto fail; - - if (! (cvto & __attr_type_info::CONST)) - constp = false; - } - } - } - fail: - -#if 0 - if (new_objptr) - printf ("It converts, delta is %d\n", new_objptr-objptr); -#endif - return new_objptr; -} - -/* Called from __cp_pop_exception. Is P the type_info node for a pointer - of some kind? */ - -bool -__is_pointer (void *p) -{ - const type_info *t = reinterpret_cast <const type_info *>(p); - const __pointer_type_info *pt = - dynamic_cast <const __pointer_type_info *> (t); - return pt != 0; -} - -extern "C" void -__rtti_ptr (void *addr, const char *n, const type_info *ti) -{ new (addr) __pointer_type_info (n, *ti); } - -extern "C" void -__rtti_attr (void *addr, const char *n, int attrval, const type_info *ti) -{ - new (addr) __attr_type_info - (n, static_cast <__attr_type_info::cv> (attrval), *ti); -} - -extern "C" void -__rtti_func (void *addr, const char *name) -{ new (addr) __func_type_info (name); } - -extern "C" void -__rtti_ptmf (void *addr, const char *name) -{ new (addr) __ptmf_type_info (name); } - -extern "C" void -__rtti_ptmd (void *addr, const char *name) -{ new (addr) __ptmd_type_info (name); } - -extern "C" void -__rtti_array (void *addr, const char *name) -{ new (addr) __array_type_info (name); } - -extern "C" void * -__dynamic_cast (const type_info& (*from)(void), const type_info& (*to)(void), - int require_public, void *address, - const type_info & (*sub)(void), void *subptr) -{ - return static_cast <const __user_type_info &> (from ()).dcast - (to (), require_public, address, &(sub ()), subptr); -} - -// type_info nodes and functions for the builtin types. The mangling here -// must match the mangling in gcc/cp/rtti.c. - -#define BUILTIN(mangled) \ -unsigned char __ti##mangled [sizeof (__builtin_type_info)] \ - __attribute__ ((aligned (__alignof__ (void *)))); \ -extern "C" const type_info &__tf##mangled (void) { \ - if ((*(void **) __ti##mangled) == 0) \ - new (__ti##mangled) __builtin_type_info (#mangled); \ - return *(type_info *)__ti##mangled; \ -} - -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); -/* CYGNUS LOCAL embedded C++ */ -#endif -/* END CYGNUS LOCAL */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c deleted file mode 100755 index 2579c6c..0000000 --- a/gcc/cp/tree.c +++ /dev/null @@ -1,2765 +0,0 @@ -/* Language-dependent node constructors for parse phase of GNU compiler. - Copyright (C) 1987, 88, 92-98, 1999 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "obstack.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" -#include "rtl.h" -#include "toplev.h" - -extern void compiler_error (); - -static tree get_identifier_list PROTO((tree)); -static tree bot_manip PROTO((tree)); -static tree perm_manip PROTO((tree)); -static tree build_cplus_array_type_1 PROTO((tree, tree)); -static void list_hash_add PROTO((int, tree)); -static int list_hash PROTO((tree, tree, tree)); -static tree list_hash_lookup PROTO((int, int, int, int, tree, tree, - tree)); -static void propagate_binfo_offsets PROTO((tree, tree)); -static int avoid_overlap PROTO((tree, tree)); -static int lvalue_p_1 PROTO((tree, int)); -static int equal_functions PROTO((tree, tree)); - -#define CEIL(x,y) (((x) + (y) - 1) / (y)) - -/* Returns non-zero if REF is an lvalue. If - TREAT_CLASS_RVALUES_AS_LVALUES is non-zero, rvalues of class type - are considered lvalues. */ - -static int -lvalue_p_1 (ref, treat_class_rvalues_as_lvalues) - tree ref; - int treat_class_rvalues_as_lvalues; -{ - if (TREE_CODE (TREE_TYPE (ref)) == REFERENCE_TYPE) - return 1; - - if (ref == current_class_ptr && flag_this_is_variable <= 0) - return 0; - - switch (TREE_CODE (ref)) - { - /* preincrements and predecrements are valid lvals, provided - what they refer to are valid lvals. */ - case PREINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case COMPONENT_REF: - case SAVE_EXPR: - case UNSAVE_EXPR: - case TRY_CATCH_EXPR: - case WITH_CLEANUP_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - return lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues); - - case STRING_CST: - return 1; - - case VAR_DECL: - if (TREE_READONLY (ref) && ! TREE_STATIC (ref) - && DECL_LANG_SPECIFIC (ref) - && DECL_IN_AGGR_P (ref)) - return 0; - case INDIRECT_REF: - case ARRAY_REF: - case PARM_DECL: - case RESULT_DECL: - if (TREE_CODE (TREE_TYPE (ref)) != METHOD_TYPE) - return 1; - break; - - /* A currently unresolved scope ref. */ - case SCOPE_REF: - my_friendly_abort (103); - case OFFSET_REF: - if (TREE_CODE (TREE_OPERAND (ref, 1)) == FUNCTION_DECL) - return 1; - return (lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues) - && lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues)); - break; - - case COND_EXPR: - return (lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues) - && lvalue_p_1 (TREE_OPERAND (ref, 2), - treat_class_rvalues_as_lvalues)); - - case MODIFY_EXPR: - return 1; - - case COMPOUND_EXPR: - return lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues); - - case MAX_EXPR: - case MIN_EXPR: - return (lvalue_p_1 (TREE_OPERAND (ref, 0), - treat_class_rvalues_as_lvalues) - && lvalue_p_1 (TREE_OPERAND (ref, 1), - treat_class_rvalues_as_lvalues)); - - case TARGET_EXPR: - return treat_class_rvalues_as_lvalues; - - case CALL_EXPR: - return (treat_class_rvalues_as_lvalues - && IS_AGGR_TYPE (TREE_TYPE (ref))); - - case FUNCTION_DECL: - /* All functions (except non-static-member functions) are - lvalues. */ - return !DECL_NONSTATIC_MEMBER_FUNCTION_P (ref); - - default: - break; - } - - return 0; -} - -/* Return nonzero if REF is an lvalue valid for this language. - Lvalues can be assigned, unless they have TREE_READONLY, or unless - they are FUNCTION_DECLs. Lvalues can have their address taken, - unless they have DECL_REGISTER. */ - -int -real_lvalue_p (ref) - tree ref; -{ - return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/0); -} - -/* This differs from real_lvalue_p in that class rvalues are considered - lvalues. */ - -int -lvalue_p (ref) - tree ref; -{ - return lvalue_p_1 (ref, /*treat_class_rvalues_as_lvalues=*/1); -} - -/* Return nonzero if REF is an lvalue valid for this language; - otherwise, print an error message and return zero. */ - -int -lvalue_or_else (ref, string) - tree ref; - char *string; -{ - int win = lvalue_p (ref); - if (! win) - error ("non-lvalue in %s", string); - return win; -} - -/* INIT is a CALL_EXPR which needs info about its target. - TYPE is the type that this initialization should appear to have. - - Build an encapsulation of the initialization to perform - and return it so that it can be processed by language-independent - and language-specific expression expanders. */ - -tree -build_cplus_new (type, init) - tree type; - tree init; -{ - tree slot; - tree rval; - - if (TREE_CODE (init) != CALL_EXPR && TREE_CODE (init) != AGGR_INIT_EXPR) - return init; - - slot = build (VAR_DECL, type); - DECL_ARTIFICIAL (slot) = 1; - layout_decl (slot, 0); - rval = build (AGGR_INIT_EXPR, type, - TREE_OPERAND (init, 0), TREE_OPERAND (init, 1), slot); - TREE_SIDE_EFFECTS (rval) = 1; - rval = build (TARGET_EXPR, type, slot, rval, NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (rval) = 1; - - return rval; -} - -/* Encapsulate the expression INIT in a TARGET_EXPR. */ - -tree -get_target_expr (init) - tree init; -{ - tree slot; - tree rval; - - slot = build (VAR_DECL, TREE_TYPE (init)); - DECL_ARTIFICIAL (slot) = 1; - layout_decl (slot, 0); - rval = build (TARGET_EXPR, TREE_TYPE (init), slot, init, - NULL_TREE, NULL_TREE); - TREE_SIDE_EFFECTS (rval) = 1; - - return rval; -} - -/* Recursively search EXP for CALL_EXPRs that need cleanups and replace - these CALL_EXPRs with tree nodes that will perform the cleanups. */ - -tree -break_out_cleanups (exp) - tree exp; -{ - tree tmp = exp; - - if (TREE_CODE (tmp) == CALL_EXPR - && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (tmp))) - return build_cplus_new (TREE_TYPE (tmp), tmp); - - while (TREE_CODE (tmp) == NOP_EXPR - || TREE_CODE (tmp) == CONVERT_EXPR - || TREE_CODE (tmp) == NON_LVALUE_EXPR) - { - if (TREE_CODE (TREE_OPERAND (tmp, 0)) == CALL_EXPR - && TYPE_NEEDS_DESTRUCTOR (TREE_TYPE (TREE_OPERAND (tmp, 0)))) - { - TREE_OPERAND (tmp, 0) - = build_cplus_new (TREE_TYPE (TREE_OPERAND (tmp, 0)), - TREE_OPERAND (tmp, 0)); - break; - } - else - tmp = TREE_OPERAND (tmp, 0); - } - return exp; -} - -/* Recursively perform a preorder search EXP for CALL_EXPRs, making - copies where they are found. Returns a deep copy all nodes transitively - containing CALL_EXPRs. */ - -tree -break_out_calls (exp) - tree exp; -{ - register tree t1, t2 = NULL_TREE; - register enum tree_code code; - register int changed = 0; - register int i; - - if (exp == NULL_TREE) - return exp; - - code = TREE_CODE (exp); - - if (code == CALL_EXPR) - return copy_node (exp); - - /* Don't try and defeat a save_expr, as it should only be done once. */ - if (code == SAVE_EXPR) - return exp; - - switch (TREE_CODE_CLASS (code)) - { - default: - abort (); - - case 'c': /* a constant */ - case 't': /* a type node */ - case 'x': /* something random, like an identifier or an ERROR_MARK. */ - return exp; - - case 'd': /* A decl node */ -#if 0 /* This is bogus. jason 9/21/94 */ - - t1 = break_out_calls (DECL_INITIAL (exp)); - if (t1 != DECL_INITIAL (exp)) - { - exp = copy_node (exp); - DECL_INITIAL (exp) = t1; - } -#endif - return exp; - - case 'b': /* A block node */ - { - /* Don't know how to handle these correctly yet. Must do a - break_out_calls on all DECL_INITIAL values for local variables, - and also break_out_calls on all sub-blocks and sub-statements. */ - abort (); - } - return exp; - - case 'e': /* an expression */ - case 'r': /* a reference */ - case 's': /* an expression with side effects */ - for (i = tree_code_length[(int) code] - 1; i >= 0; i--) - { - t1 = break_out_calls (TREE_OPERAND (exp, i)); - if (t1 != TREE_OPERAND (exp, i)) - { - exp = copy_node (exp); - TREE_OPERAND (exp, i) = t1; - } - } - return exp; - - case '<': /* a comparison expression */ - case '2': /* a binary arithmetic expression */ - t2 = break_out_calls (TREE_OPERAND (exp, 1)); - if (t2 != TREE_OPERAND (exp, 1)) - changed = 1; - case '1': /* a unary arithmetic expression */ - t1 = break_out_calls (TREE_OPERAND (exp, 0)); - if (t1 != TREE_OPERAND (exp, 0)) - changed = 1; - if (changed) - { - if (tree_code_length[(int) code] == 1) - return build1 (code, TREE_TYPE (exp), t1); - else - return build (code, TREE_TYPE (exp), t1, t2); - } - return exp; - } - -} - -extern struct obstack *current_obstack; -extern struct obstack permanent_obstack, class_obstack; -extern struct obstack *saveable_obstack; -extern struct obstack *expression_obstack; - -/* Here is how primitive or already-canonicalized types' hash - codes are made. MUST BE CONSISTENT WITH tree.c !!! */ -#define TYPE_HASH(TYPE) ((HOST_WIDE_INT) (TYPE) & 0777777) - -/* Construct, lay out and return the type of methods belonging to class - BASETYPE and whose arguments are described by ARGTYPES and whose values - are described by RETTYPE. If each type exists already, reuse it. */ - -tree -build_cplus_method_type (basetype, rettype, argtypes) - tree basetype, rettype, argtypes; -{ - register tree t; - tree ptype; - int hashcode; - - /* Make a node of the sort we want. */ - t = make_node (METHOD_TYPE); - - TYPE_METHOD_BASETYPE (t) = TYPE_MAIN_VARIANT (basetype); - TREE_TYPE (t) = rettype; - if (IS_SIGNATURE (basetype)) - ptype = build_signature_pointer_type (basetype); - else - ptype = build_pointer_type (basetype); - - /* The actual arglist for this function includes a "hidden" argument - which is "this". Put it into the list of argument types. */ - - argtypes = tree_cons (NULL_TREE, ptype, argtypes); - TYPE_ARG_TYPES (t) = argtypes; - TREE_SIDE_EFFECTS (argtypes) = 1; /* Mark first argtype as "artificial". */ - - /* If we already have such a type, use the old one and free this one. - Note that it also frees up the above cons cell if found. */ - hashcode = TYPE_HASH (basetype) + TYPE_HASH (rettype) + type_hash_list (argtypes); - t = type_hash_canon (hashcode, t); - - if (TYPE_SIZE (t) == 0) - layout_type (t); - - return t; -} - -static tree -build_cplus_array_type_1 (elt_type, index_type) - tree elt_type; - tree index_type; -{ - register struct obstack *ambient_obstack = current_obstack; - register struct obstack *ambient_saveable_obstack = saveable_obstack; - tree t; - - /* We need a new one. If both ELT_TYPE and INDEX_TYPE are permanent, - make this permanent too. */ - if (TREE_PERMANENT (elt_type) - && (index_type == 0 || TREE_PERMANENT (index_type))) - { - current_obstack = &permanent_obstack; - saveable_obstack = &permanent_obstack; - } - - if (processing_template_decl - || uses_template_parms (elt_type) - || uses_template_parms (index_type)) - { - t = make_node (ARRAY_TYPE); - TREE_TYPE (t) = elt_type; - TYPE_DOMAIN (t) = index_type; - } - else - t = build_array_type (elt_type, index_type); - - /* Push these needs up so that initialization takes place - more easily. */ - TYPE_NEEDS_CONSTRUCTING (t) = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (elt_type)); - TYPE_NEEDS_DESTRUCTOR (t) = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (elt_type)); - current_obstack = ambient_obstack; - saveable_obstack = ambient_saveable_obstack; - return t; -} - -tree -build_cplus_array_type (elt_type, index_type) - tree elt_type; - tree index_type; -{ - tree t; - int type_quals = CP_TYPE_QUALS (elt_type); - - elt_type = TYPE_MAIN_VARIANT (elt_type); - - t = build_cplus_array_type_1 (elt_type, index_type); - - if (type_quals != TYPE_UNQUALIFIED) - t = cp_build_qualified_type (t, type_quals); - - return t; -} - -/* Make a variant type in the proper way for C/C++, propagating qualifiers - down to the element type of an array. */ - -tree -cp_build_qualified_type (type, type_quals) - tree type; - int type_quals; -{ - if (type == error_mark_node) - return type; - - /* A restrict-qualified pointer type must be a pointer (or reference) - to object or incomplete type. */ - if ((type_quals & TYPE_QUAL_RESTRICT) - && (!POINTER_TYPE_P (type) - || TYPE_PTRMEM_P (type) - || TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE)) - { - cp_error ("`%T' cannot be `restrict'-qualified", type); - type_quals &= ~TYPE_QUAL_RESTRICT; - } - - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree real_main_variant = TYPE_MAIN_VARIANT (type); - - push_obstacks (TYPE_OBSTACK (real_main_variant), - TYPE_OBSTACK (real_main_variant)); - type = build_cplus_array_type_1 (cp_build_qualified_type - (TREE_TYPE (type), type_quals), - TYPE_DOMAIN (type)); - - /* TYPE must be on same obstack as REAL_MAIN_VARIANT. If not, - make a copy. (TYPE might have come from the hash table and - REAL_MAIN_VARIANT might be in some function's obstack.) */ - - if (TYPE_OBSTACK (type) != TYPE_OBSTACK (real_main_variant)) - { - type = copy_node (type); - TYPE_POINTER_TO (type) = TYPE_REFERENCE_TO (type) = 0; - } - - TYPE_MAIN_VARIANT (type) = real_main_variant; - pop_obstacks (); - return type; - } - return build_qualified_type (type, type_quals); -} - -/* Returns the canonical version of TYPE. In other words, if TYPE is - a typedef, returns the underlying type. The cv-qualification of - the type returned matches the type input; they will always be - compatible types. */ - -tree -canonical_type_variant (t) - tree t; -{ - return cp_build_qualified_type (TYPE_MAIN_VARIANT (t), CP_TYPE_QUALS (t)); -} - -/* Add OFFSET to all base types of T. - - OFFSET, which is a type offset, is number of bytes. - - Note that we don't have to worry about having two paths to the - same base type, since this type owns its association list. */ - -static void -propagate_binfo_offsets (binfo, offset) - tree binfo; - tree offset; -{ - tree binfos = BINFO_BASETYPES (binfo); - int i, n_baselinks = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - for (i = 0; i < n_baselinks; /* note increment is done in the loop. */) - { - tree base_binfo = TREE_VEC_ELT (binfos, i); - - if (TREE_VIA_VIRTUAL (base_binfo)) - i += 1; - else - { - int j; - tree delta = NULL_TREE; - - for (j = i+1; j < n_baselinks; j++) - if (! TREE_VIA_VIRTUAL (TREE_VEC_ELT (binfos, j))) - { - /* The next basetype offset must take into account the space - between the classes, not just the size of each class. */ - delta = size_binop (MINUS_EXPR, - BINFO_OFFSET (TREE_VEC_ELT (binfos, j)), - BINFO_OFFSET (base_binfo)); - break; - } - -#if 0 - if (BINFO_OFFSET_ZEROP (base_binfo)) - BINFO_OFFSET (base_binfo) = offset; - else - BINFO_OFFSET (base_binfo) - = size_binop (PLUS_EXPR, BINFO_OFFSET (base_binfo), offset); -#else - BINFO_OFFSET (base_binfo) = offset; -#endif - - propagate_binfo_offsets (base_binfo, offset); - - /* Go to our next class that counts for offset propagation. */ - i = j; - if (i < n_baselinks) - offset = size_binop (PLUS_EXPR, offset, delta); - } - } -} - -/* Makes new binfos for the indirect bases under BINFO, and updates - BINFO_OFFSET for them and their bases. */ - -void -unshare_base_binfos (binfo) - tree binfo; -{ - tree binfos = BINFO_BASETYPES (binfo); - tree new_binfo; - int j; - - if (binfos == NULL_TREE) - return; - - /* Now unshare the structure beneath BINFO. */ - for (j = TREE_VEC_LENGTH (binfos)-1; - j >= 0; j--) - { - tree base_binfo = TREE_VEC_ELT (binfos, j); - new_binfo = TREE_VEC_ELT (binfos, j) - = make_binfo (BINFO_OFFSET (base_binfo), - base_binfo, - BINFO_VTABLE (base_binfo), - BINFO_VIRTUALS (base_binfo)); - TREE_VIA_PUBLIC (new_binfo) = TREE_VIA_PUBLIC (base_binfo); - TREE_VIA_PROTECTED (new_binfo) = TREE_VIA_PROTECTED (base_binfo); - TREE_VIA_VIRTUAL (new_binfo) = TREE_VIA_VIRTUAL (base_binfo); - BINFO_INHERITANCE_CHAIN (new_binfo) = binfo; - unshare_base_binfos (new_binfo); - } -} - -/* Finish the work of layout_record, now taking virtual bases into account. - Also compute the actual offsets that our base classes will have. - This must be performed after the fields are laid out, since virtual - baseclasses must lay down at the end of the record. - - Returns the maximum number of virtual functions any of the - baseclasses provide. */ - -int -layout_basetypes (rec, max) - tree rec; - int max; -{ - tree binfos = TYPE_BINFO_BASETYPES (rec); - int i, n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - - tree vbase_types; - - unsigned int record_align = MAX (BITS_PER_UNIT, TYPE_ALIGN (rec)); - unsigned int desired_align; - - /* Record size so far is CONST_SIZE bits, where CONST_SIZE is an integer. */ - register unsigned int const_size = 0; - unsigned int nonvirtual_const_size; - -#ifdef STRUCTURE_SIZE_BOUNDARY - /* Packed structures don't need to have minimum size. */ - if (! TYPE_PACKED (rec)) - record_align = MAX (record_align, STRUCTURE_SIZE_BOUNDARY); -#endif - - /* Get all the virtual base types that this type uses. The - TREE_VALUE slot holds the virtual baseclass type. Note that - get_vbase_types makes copies of the virtual base BINFOs, so that - the vbase_types are unshared. */ - CLASSTYPE_VBASECLASSES (rec) = vbase_types = get_vbase_types (rec); - - my_friendly_assert (TREE_CODE (TYPE_SIZE (rec)) == INTEGER_CST, 19970302); - const_size = TREE_INT_CST_LOW (TYPE_SIZE (rec)); - - nonvirtual_const_size = const_size; - - while (vbase_types) - { - tree basetype = BINFO_TYPE (vbase_types); - tree offset; - - desired_align = TYPE_ALIGN (basetype); - record_align = MAX (record_align, desired_align); - - if (const_size == 0) - offset = integer_zero_node; - else - { - /* Give each virtual base type the alignment it wants. */ - const_size = CEIL (const_size, desired_align) * desired_align; - offset = size_int (CEIL (const_size, BITS_PER_UNIT)); - } - - if (CLASSTYPE_VSIZE (basetype) > max) - max = CLASSTYPE_VSIZE (basetype); - BINFO_OFFSET (vbase_types) = offset; - - /* Every virtual baseclass takes a least a UNIT, so that we can - take it's address and get something different for each base. */ - const_size += MAX (BITS_PER_UNIT, - TREE_INT_CST_LOW (CLASSTYPE_SIZE (basetype))); - - vbase_types = TREE_CHAIN (vbase_types); - } - - if (const_size) - { - /* Because a virtual base might take a single byte above, - we have to re-adjust the total size to make sure it is - a multiple of the alignment. */ - /* Give the whole object the alignment it wants. */ - const_size = CEIL (const_size, record_align) * record_align; - } - - /* Set the alignment in the complete type. We don't set CLASSTYPE_ALIGN - here, as that is for this class, without any virtual base classes. */ - TYPE_ALIGN (rec) = record_align; - if (const_size != nonvirtual_const_size) - { - TYPE_SIZE (rec) = size_int (const_size); - TYPE_SIZE_UNIT (rec) = size_binop (FLOOR_DIV_EXPR, TYPE_SIZE (rec), - size_int (BITS_PER_UNIT)); - } - - /* Now propagate offset information throughout the lattice. */ - for (i = 0; i < n_baseclasses; i++) - { - register tree base_binfo = TREE_VEC_ELT (binfos, i); - register tree basetype = BINFO_TYPE (base_binfo); - tree field = TYPE_FIELDS (rec); - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - my_friendly_assert (TREE_TYPE (field) == basetype, 23897); - - if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) - cp_warning ("direct base `%T' inaccessible in `%T' due to ambiguity", - basetype, rec); - - BINFO_OFFSET (base_binfo) - = size_int (CEIL (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field)), - BITS_PER_UNIT)); - propagate_binfo_offsets (base_binfo, BINFO_OFFSET (base_binfo)); - TYPE_FIELDS (rec) = TREE_CHAIN (field); - } - - for (vbase_types = CLASSTYPE_VBASECLASSES (rec); vbase_types; - vbase_types = TREE_CHAIN (vbase_types)) - { - BINFO_INHERITANCE_CHAIN (vbase_types) = TYPE_BINFO (rec); - unshare_base_binfos (vbase_types); - propagate_binfo_offsets (vbase_types, BINFO_OFFSET (vbase_types)); - - if (extra_warnings) - { - tree basetype = BINFO_TYPE (vbase_types); - if (get_base_distance (basetype, rec, 0, (tree*)0) == -2) - cp_warning ("virtual base `%T' inaccessible in `%T' due to ambiguity", - basetype, rec); - } - } - - return max; -} - -/* If the empty base field in DECL overlaps with a base of the same type in - NEWDECL, which is either another base field or the first data field of - the class, pad the base just before NEWDECL and return 1. Otherwise, - return 0. */ - -static int -avoid_overlap (decl, newdecl) - tree decl, newdecl; -{ - tree field; - - if (newdecl == NULL_TREE - || ! types_overlap_p (TREE_TYPE (decl), TREE_TYPE (newdecl))) - return 0; - - for (field = decl; TREE_CHAIN (field) && TREE_CHAIN (field) != newdecl; - field = TREE_CHAIN (field)) - ; - - DECL_SIZE (field) = integer_one_node; - - return 1; -} - -/* Returns a list of fields to stand in for the base class subobjects - of REC. These fields are later removed by layout_basetypes. */ - -tree -build_base_fields (rec) - tree rec; -{ - /* Chain to hold all the new FIELD_DECLs which stand in for base class - subobjects. */ - tree base_decls = NULL_TREE; - tree binfos = TYPE_BINFO_BASETYPES (rec); - int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree decl, nextdecl; - int i, saw_empty = 0; - unsigned int base_align = 0; - - for (i = 0; i < n_baseclasses; ++i) - { - register tree base_binfo = TREE_VEC_ELT (binfos, i); - register tree basetype = BINFO_TYPE (base_binfo); - - if (TYPE_SIZE (basetype) == 0) - /* This error is now reported in xref_tag, thus giving better - location information. */ - continue; - - if (TREE_VIA_VIRTUAL (base_binfo)) - continue; - - decl = build_lang_field_decl (FIELD_DECL, NULL_TREE, basetype); - DECL_ARTIFICIAL (decl) = 1; - DECL_FIELD_CONTEXT (decl) = DECL_CLASS_CONTEXT (decl) = rec; - DECL_SIZE (decl) = CLASSTYPE_SIZE (basetype); - DECL_ALIGN (decl) = CLASSTYPE_ALIGN (basetype); - TREE_CHAIN (decl) = base_decls; - base_decls = decl; - - if (! flag_new_abi) - { - /* Brain damage for backwards compatibility. For no good reason, - the old layout_basetypes made every base at least as large as - the alignment for the bases up to that point, gratuitously - wasting space. So we do the same thing here. */ - base_align = MAX (base_align, DECL_ALIGN (decl)); - DECL_SIZE (decl) - = size_int (MAX (TREE_INT_CST_LOW (DECL_SIZE (decl)), - (int) base_align)); - } - else if (DECL_SIZE (decl) == integer_zero_node) - saw_empty = 1; - } - - /* Reverse the list of fields so we allocate the bases in the proper - order. */ - base_decls = nreverse (base_decls); - - /* In the presence of empty base classes, we run the risk of allocating - two objects of the same class on top of one another. Avoid that. */ - if (flag_new_abi && saw_empty) - for (decl = base_decls; decl; decl = TREE_CHAIN (decl)) - { - if (DECL_SIZE (decl) == integer_zero_node) - { - /* First step through the following bases until we find - an overlap or a non-empty base. */ - for (nextdecl = TREE_CHAIN (decl); nextdecl; - nextdecl = TREE_CHAIN (nextdecl)) - { - if (avoid_overlap (decl, nextdecl) - || DECL_SIZE (nextdecl) != integer_zero_node) - goto nextbase; - } - - /* If we're still looking, also check against the first - field. */ - for (nextdecl = TYPE_FIELDS (rec); - nextdecl && TREE_CODE (nextdecl) != FIELD_DECL; - nextdecl = TREE_CHAIN (nextdecl)) - /* keep looking */; - avoid_overlap (decl, nextdecl); - } - nextbase:; - } - - return base_decls; -} - -/* Returns list of virtual base class pointers in a FIELD_DECL chain. */ - -tree -build_vbase_pointer_fields (rec) - tree rec; -{ - /* Chain to hold all the new FIELD_DECLs which point at virtual - base classes. */ - tree vbase_decls = NULL_TREE; - tree binfos = TYPE_BINFO_BASETYPES (rec); - int n_baseclasses = binfos ? TREE_VEC_LENGTH (binfos) : 0; - tree decl; - int i; - - /* Handle basetypes almost like fields, but record their - offsets differently. */ - - for (i = 0; i < n_baseclasses; i++) - { - register tree base_binfo = TREE_VEC_ELT (binfos, i); - register tree basetype = BINFO_TYPE (base_binfo); - - if (TYPE_SIZE (basetype) == 0) - /* This error is now reported in xref_tag, thus giving better - location information. */ - continue; - - /* All basetypes are recorded in the association list of the - derived type. */ - - if (TREE_VIA_VIRTUAL (base_binfo)) - { - int j; - char *name; - - /* The offset for a virtual base class is only used in computing - virtual function tables and for initializing virtual base - pointers. It is built once `get_vbase_types' is called. */ - - /* If this basetype can come from another vbase pointer - without an additional indirection, we will share - that pointer. If an indirection is involved, we - make our own pointer. */ - for (j = 0; j < n_baseclasses; j++) - { - tree other_base_binfo = TREE_VEC_ELT (binfos, j); - if (! TREE_VIA_VIRTUAL (other_base_binfo) - && binfo_member (basetype, - CLASSTYPE_VBASECLASSES (BINFO_TYPE - (other_base_binfo)) - )) - goto got_it; - } - FORMAT_VBASE_NAME (name, basetype); - decl = build_lang_field_decl (FIELD_DECL, get_identifier (name), - build_pointer_type (basetype)); - /* If you change any of the below, take a look at all the - other VFIELD_BASEs and VTABLE_BASEs in the code, and change - them too. */ - DECL_ASSEMBLER_NAME (decl) = get_identifier (VTABLE_BASE); - DECL_VIRTUAL_P (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - DECL_FIELD_CONTEXT (decl) = rec; - DECL_CLASS_CONTEXT (decl) = rec; - DECL_FCONTEXT (decl) = basetype; - DECL_SAVED_INSNS (decl) = NULL_RTX; - DECL_FIELD_SIZE (decl) = 0; - DECL_ALIGN (decl) = TYPE_ALIGN (ptr_type_node); - TREE_CHAIN (decl) = vbase_decls; - BINFO_VPTR_FIELD (base_binfo) = decl; - vbase_decls = decl; - - got_it: - /* The space this decl occupies has already been accounted for. */ - ; - } - } - - return vbase_decls; -} - -/* Hashing of lists so that we don't make duplicates. - The entry point is `list_hash_canon'. */ - -/* Each hash table slot is a bucket containing a chain - of these structures. */ - -struct list_hash -{ - struct list_hash *next; /* Next structure in the bucket. */ - int hashcode; /* Hash code of this list. */ - tree list; /* The list recorded here. */ -}; - -/* Now here is the hash table. When recording a list, it is added - to the slot whose index is the hash code mod the table size. - Note that the hash table is used for several kinds of lists. - While all these live in the same table, they are completely independent, - and the hash code is computed differently for each of these. */ - -#define TYPE_HASH_SIZE 59 -static struct list_hash *list_hash_table[TYPE_HASH_SIZE]; - -/* Compute a hash code for a list (chain of TREE_LIST nodes - with goodies in the TREE_PURPOSE, TREE_VALUE, and bits of the - TREE_COMMON slots), by adding the hash codes of the individual entries. */ - -static int -list_hash (purpose, value, chain) - tree purpose, value, chain; -{ - register int hashcode = 0; - - if (chain) - hashcode += TYPE_HASH (chain); - - if (value) - hashcode += TYPE_HASH (value); - else - hashcode += 1007; - if (purpose) - hashcode += TYPE_HASH (purpose); - else - hashcode += 1009; - return hashcode; -} - -/* Look in the type hash table for a type isomorphic to TYPE. - If one is found, return it. Otherwise return 0. */ - -static tree -list_hash_lookup (hashcode, via_public, via_protected, via_virtual, - purpose, value, chain) - int hashcode, via_public, via_virtual, via_protected; - tree purpose, value, chain; -{ - register struct list_hash *h; - - for (h = list_hash_table[hashcode % TYPE_HASH_SIZE]; h; h = h->next) - if (h->hashcode == hashcode - && TREE_VIA_VIRTUAL (h->list) == via_virtual - && TREE_VIA_PUBLIC (h->list) == via_public - && TREE_VIA_PROTECTED (h->list) == via_protected - && TREE_PURPOSE (h->list) == purpose - && TREE_VALUE (h->list) == value - && TREE_CHAIN (h->list) == chain) - return h->list; - return 0; -} - -/* Add an entry to the list-hash-table - for a list TYPE whose hash code is HASHCODE. */ - -static void -list_hash_add (hashcode, list) - int hashcode; - tree list; -{ - register struct list_hash *h; - - h = (struct list_hash *) obstack_alloc (&class_obstack, sizeof (struct list_hash)); - h->hashcode = hashcode; - h->list = list; - h->next = list_hash_table[hashcode % TYPE_HASH_SIZE]; - list_hash_table[hashcode % TYPE_HASH_SIZE] = h; -} - -/* Given TYPE, and HASHCODE its hash code, return the canonical - object for an identical list if one already exists. - Otherwise, return TYPE, and record it as the canonical object - if it is a permanent object. - - To use this function, first create a list of the sort you want. - Then compute its hash code from the fields of the list that - make it different from other similar lists. - Then call this function and use the value. - This function frees the list you pass in if it is a duplicate. */ - -/* Set to 1 to debug without canonicalization. Never set by program. */ - -static int debug_no_list_hash = 0; - -tree -hash_tree_cons (via_public, via_virtual, via_protected, purpose, value, chain) - int via_public, via_virtual, via_protected; - tree purpose, value, chain; -{ - struct obstack *ambient_obstack = current_obstack; - tree t; - int hashcode = 0; - - if (! debug_no_list_hash) - { - hashcode = list_hash (purpose, value, chain); - t = list_hash_lookup (hashcode, via_public, via_protected, via_virtual, - purpose, value, chain); - if (t) - return t; - } - - current_obstack = &class_obstack; - - t = tree_cons (purpose, value, chain); - TREE_VIA_PUBLIC (t) = via_public; - TREE_VIA_PROTECTED (t) = via_protected; - TREE_VIA_VIRTUAL (t) = via_virtual; - - /* If this is a new list, record it for later reuse. */ - if (! debug_no_list_hash) - list_hash_add (hashcode, t); - - current_obstack = ambient_obstack; - return t; -} - -/* Constructor for hashed lists. */ - -tree -hash_tree_chain (value, chain) - tree value, chain; -{ - return hash_tree_cons (0, 0, 0, NULL_TREE, value, chain); -} - -/* Similar, but used for concatenating two lists. */ - -tree -hash_chainon (list1, list2) - tree list1, list2; -{ - if (list2 == 0) - return list1; - if (list1 == 0) - return list2; - if (TREE_CHAIN (list1) == NULL_TREE) - return hash_tree_chain (TREE_VALUE (list1), list2); - return hash_tree_chain (TREE_VALUE (list1), - hash_chainon (TREE_CHAIN (list1), list2)); -} - -static tree -get_identifier_list (value) - tree value; -{ - tree list = IDENTIFIER_AS_LIST (value); - if (list != NULL_TREE - && (TREE_CODE (list) != TREE_LIST - || TREE_VALUE (list) != value)) - list = NULL_TREE; - else if (IDENTIFIER_HAS_TYPE_VALUE (value) - && TREE_CODE (IDENTIFIER_TYPE_VALUE (value)) == RECORD_TYPE - && IDENTIFIER_TYPE_VALUE (value) - == TYPE_MAIN_VARIANT (IDENTIFIER_TYPE_VALUE (value))) - { - tree type = IDENTIFIER_TYPE_VALUE (value); - - if (TYPE_PTRMEMFUNC_P (type)) - list = NULL_TREE; - else if (type == current_class_type) - /* Don't mess up the constructor name. */ - list = tree_cons (NULL_TREE, value, NULL_TREE); - else - { - if (! CLASSTYPE_ID_AS_LIST (type)) - CLASSTYPE_ID_AS_LIST (type) - = perm_tree_cons (NULL_TREE, TYPE_IDENTIFIER (type), NULL_TREE); - list = CLASSTYPE_ID_AS_LIST (type); - } - } - return list; -} - -tree -get_decl_list (value) - tree value; -{ - tree list = NULL_TREE; - - if (TREE_CODE (value) == IDENTIFIER_NODE) - list = get_identifier_list (value); - else if (TREE_CODE (value) == RECORD_TYPE - && TYPE_LANG_SPECIFIC (value) - && value == TYPE_MAIN_VARIANT (value)) - list = CLASSTYPE_AS_LIST (value); - - if (list != NULL_TREE) - { - my_friendly_assert (TREE_CHAIN (list) == NULL_TREE, 301); - return list; - } - - return build_decl_list (NULL_TREE, value); -} - -/* Build an association between TYPE and some parameters: - - OFFSET is the offset added to `this' to convert it to a pointer - of type `TYPE *' - - BINFO is the base binfo to use, if we are deriving from one. This - is necessary, as we want specialized parent binfos from base - classes, so that the VTABLE_NAMEs of bases are for the most derived - type, instead of the simple type. - - VTABLE is the virtual function table with which to initialize - sub-objects of type TYPE. - - VIRTUALS are the virtual functions sitting in VTABLE. */ - -tree -make_binfo (offset, binfo, vtable, virtuals) - tree offset, binfo; - tree vtable, virtuals; -{ - tree new_binfo = make_tree_vec (7); - tree type; - - if (TREE_CODE (binfo) == TREE_VEC) - type = BINFO_TYPE (binfo); - else - { - type = binfo; - binfo = CLASS_TYPE_P (type) ? TYPE_BINFO (binfo) : NULL_TREE; - } - - TREE_TYPE (new_binfo) = TYPE_MAIN_VARIANT (type); - BINFO_OFFSET (new_binfo) = offset; - BINFO_VTABLE (new_binfo) = vtable; - BINFO_VIRTUALS (new_binfo) = virtuals; - BINFO_VPTR_FIELD (new_binfo) = NULL_TREE; - - if (binfo && BINFO_BASETYPES (binfo) != NULL_TREE) - BINFO_BASETYPES (new_binfo) = copy_node (BINFO_BASETYPES (binfo)); - return new_binfo; -} - -/* Return the binfo value for ELEM in TYPE. */ - -tree -binfo_value (elem, type) - tree elem; - tree type; -{ - if (get_base_distance (elem, type, 0, (tree *)0) == -2) - compiler_error ("base class `%s' ambiguous in binfo_value", - TYPE_NAME_STRING (elem)); - if (elem == type) - return TYPE_BINFO (type); - if (TREE_CODE (elem) == RECORD_TYPE && TYPE_BINFO (elem) == type) - return type; - return get_binfo (elem, type, 0); -} - -/* Return a reversed copy of the BINFO-chain given by PATH. (If the - BINFO_INHERITANCE_CHAIN points from base classes to derived - classes, it will instead point from derived classes to base - classes.) Returns the first node in the reversed chain. */ - -tree -reverse_path (path) - tree path; -{ - register tree prev = NULL_TREE, cur; - push_expression_obstack (); - for (cur = path; cur; cur = BINFO_INHERITANCE_CHAIN (cur)) - { - tree r = copy_node (cur); - BINFO_INHERITANCE_CHAIN (r) = prev; - prev = r; - } - pop_obstacks (); - return prev; -} - -void -debug_binfo (elem) - tree elem; -{ - unsigned HOST_WIDE_INT n; - tree virtuals; - - fprintf (stderr, "type \"%s\"; offset = %ld\n", - TYPE_NAME_STRING (BINFO_TYPE (elem)), - (long) TREE_INT_CST_LOW (BINFO_OFFSET (elem))); - fprintf (stderr, "vtable type:\n"); - debug_tree (BINFO_TYPE (elem)); - if (BINFO_VTABLE (elem)) - fprintf (stderr, "vtable decl \"%s\"\n", IDENTIFIER_POINTER (DECL_NAME (BINFO_VTABLE (elem)))); - else - fprintf (stderr, "no vtable decl yet\n"); - fprintf (stderr, "virtuals:\n"); - virtuals = BINFO_VIRTUALS (elem); - - n = skip_rtti_stuff (&virtuals); - - while (virtuals) - { - tree fndecl = TREE_OPERAND (FNADDR_FROM_VTABLE_ENTRY (TREE_VALUE (virtuals)), 0); - fprintf (stderr, "%s [%ld =? %ld]\n", - IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (fndecl)), - (long) n, (long) TREE_INT_CST_LOW (DECL_VINDEX (fndecl))); - ++n; - virtuals = TREE_CHAIN (virtuals); - } -} - -/* Initialize an CPLUS_BINDING node that does not live on an obstack. */ - -tree -binding_init (node) - struct tree_binding* node; -{ - static struct tree_binding* source; - if (!source) - { - extern struct obstack permanent_obstack; - push_obstacks (&permanent_obstack, &permanent_obstack); - source = (struct tree_binding*)make_node (CPLUS_BINDING); - pop_obstacks (); - } - *node = *source; - TREE_PERMANENT ((tree)node) = 0; - return (tree)node; -} - -int -count_functions (t) - tree t; -{ - int i; - if (TREE_CODE (t) == FUNCTION_DECL) - return 1; - else if (TREE_CODE (t) == OVERLOAD) - { - for (i=0; t; t = OVL_CHAIN (t)) - i++; - return i; - } - - my_friendly_abort (359); - return 0; -} - -int -is_overloaded_fn (x) - tree x; -{ - /* XXX A baselink is also considered an overloaded function. - As is a placeholder from push_class_decls. - As is an expression like X::f. */ - if (TREE_CODE (x) == TREE_LIST) - { - if (TREE_PURPOSE (x) == error_mark_node) - { - x = TREE_VALUE (x); - my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121); - } - my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC - || TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE, - 388); - x = TREE_VALUE (x); - } - return (TREE_CODE (x) == FUNCTION_DECL - || TREE_CODE (x) == TEMPLATE_ID_EXPR - || DECL_FUNCTION_TEMPLATE_P (x) - || TREE_CODE (x) == OVERLOAD); -} - -int -really_overloaded_fn (x) - tree x; -{ - /* A baselink is also considered an overloaded function. - This might also be an ambiguous class member. */ - if (TREE_CODE (x) == TREE_LIST) - x = TREE_VALUE (x); - return (TREE_CODE (x) == OVERLOAD - && (TREE_CHAIN (x) != NULL_TREE - || DECL_FUNCTION_TEMPLATE_P (OVL_FUNCTION (x)))); -} - -tree -get_first_fn (from) - tree from; -{ - my_friendly_assert (is_overloaded_fn (from), 9); - /* A baselink is also considered an overloaded function. */ - if (TREE_CODE (from) == TREE_LIST) - from = TREE_VALUE (from); - return OVL_CURRENT (from); -} - -/* Returns nonzero if T is a ->* or .* expression that refers to a - member function. */ - -int -bound_pmf_p (t) - tree t; -{ - return (TREE_CODE (t) == OFFSET_REF - && TYPE_PTRMEMFUNC_P (TREE_TYPE (TREE_OPERAND (t, 1)))); -} - -/* Return a new OVL node, concatenating it with the old one. */ - -tree -ovl_cons (decl, chain) - tree decl; - tree chain; -{ - tree result = make_node (OVERLOAD); - TREE_TYPE (result) = unknown_type_node; - OVL_FUNCTION (result) = decl; - TREE_CHAIN (result) = chain; - - return result; -} - -/* Same as ovl_cons, but on the scratch_obstack. */ - -tree -scratch_ovl_cons (value, chain) - tree value, chain; -{ - register tree node; - register struct obstack *ambient_obstack = current_obstack; - extern struct obstack *expression_obstack; - current_obstack = expression_obstack; - node = ovl_cons (value, chain); - current_obstack = ambient_obstack; - return node; -} - -/* Build a new overloaded function. If this is the first one, - just return it; otherwise, ovl_cons the _DECLs */ - -tree -build_overload (decl, chain) - tree decl; - tree chain; -{ - if (! chain && TREE_CODE (decl) != TEMPLATE_DECL) - return decl; - if (chain && TREE_CODE (chain) != OVERLOAD) - chain = ovl_cons (chain, NULL_TREE); - return ovl_cons (decl, chain); -} - -/* Returns true iff functions are equivalent. Equivalent functions are - not identical only if one is a function-local extern function. - This assumes that function-locals don't have TREE_PERMANENT. */ - -static int -equal_functions (fn1, fn2) - tree fn1; - tree fn2; -{ - if (!TREE_PERMANENT (fn1) || !TREE_PERMANENT (fn2)) - return decls_match (fn1, fn2); - return fn1 == fn2; -} - -/* True if fn is in ovl. */ - -int -ovl_member (fn, ovl) - tree fn; - tree ovl; -{ - if (ovl == NULL_TREE) - return 0; - if (TREE_CODE (ovl) != OVERLOAD) - return equal_functions (ovl, fn); - for (; ovl; ovl = OVL_CHAIN (ovl)) - if (equal_functions (OVL_FUNCTION (ovl), fn)) - return 1; - return 0; -} - -int -is_aggr_type_2 (t1, t2) - tree t1, t2; -{ - if (TREE_CODE (t1) != TREE_CODE (t2)) - return 0; - return IS_AGGR_TYPE (t1) && IS_AGGR_TYPE (t2); -} - -#define PRINT_RING_SIZE 4 - -char * -lang_printable_name (decl, v) - tree decl; - int v; -{ - static tree decl_ring[PRINT_RING_SIZE]; - static char *print_ring[PRINT_RING_SIZE]; - static int ring_counter; - int i; - - /* Only cache functions. */ - if (v < 2 - || TREE_CODE (decl) != FUNCTION_DECL - || DECL_LANG_SPECIFIC (decl) == 0) - return lang_decl_name (decl, v); - - /* See if this print name is lying around. */ - for (i = 0; i < PRINT_RING_SIZE; i++) - if (decl_ring[i] == decl) - /* yes, so return it. */ - return print_ring[i]; - - if (++ring_counter == PRINT_RING_SIZE) - ring_counter = 0; - - if (current_function_decl != NULL_TREE) - { - if (decl_ring[ring_counter] == current_function_decl) - ring_counter += 1; - if (ring_counter == PRINT_RING_SIZE) - ring_counter = 0; - if (decl_ring[ring_counter] == current_function_decl) - my_friendly_abort (106); - } - - if (print_ring[ring_counter]) - free (print_ring[ring_counter]); - - print_ring[ring_counter] = xstrdup (lang_decl_name (decl, v)); - decl_ring[ring_counter] = decl; - return print_ring[ring_counter]; -} - -/* Build the FUNCTION_TYPE or METHOD_TYPE which may throw exceptions - listed in RAISES. */ - -tree -build_exception_variant (type, raises) - tree type; - tree raises; -{ - tree v = TYPE_MAIN_VARIANT (type); - int type_quals = TYPE_QUALS (type); - - for (; v; v = TYPE_NEXT_VARIANT (v)) - { - tree t; - tree u; - - if (TYPE_QUALS (v) != type_quals) - continue; - - for (t = TYPE_RAISES_EXCEPTIONS (v), u = raises; - t != NULL_TREE && u != NULL_TREE; - t = TREE_CHAIN (t), u = TREE_CHAIN (v)) - if (((TREE_VALUE (t) != NULL_TREE) - != (TREE_VALUE (u) != NULL_TREE)) - || !same_type_p (TREE_VALUE (t), TREE_VALUE (u))) - break; - - if (!t && !u) - /* There's a memory leak here; RAISES is not freed. */ - return v; - } - - /* Need to build a new variant. */ - v = build_type_copy (type); - - if (raises && ! TREE_PERMANENT (raises)) - { - push_obstacks_nochange (); - end_temporary_allocation (); - raises = copy_list (raises); - pop_obstacks (); - } - - TYPE_RAISES_EXCEPTIONS (v) = raises; - return v; -} - -/* Given a TEMPLATE_TEMPLATE_PARM node T, create a new one together with its - lang_specific field and its corresponding TEMPLATE_DECL node */ - -tree -copy_template_template_parm (t) - tree t; -{ - tree template = TYPE_NAME (t); - tree t2; - - /* Make sure these end up on the permanent_obstack. */ - push_obstacks_nochange (); - end_temporary_allocation (); - - t2 = make_lang_type (TEMPLATE_TEMPLATE_PARM); - template = copy_node (template); - copy_lang_decl (template); - - pop_obstacks (); - - TREE_TYPE (template) = t2; - TYPE_NAME (t2) = template; - TYPE_STUB_DECL (t2) = template; - - /* No need to copy these */ - TYPE_FIELDS (t2) = TYPE_FIELDS (t); - TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2) - = TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t); - return t2; -} - -/* Walk through the tree structure T, applying func. If func ever returns - non-null, return that value. */ - -tree -search_tree (t, func) - tree t; - tree (*func) PROTO((tree)); -{ -#define TRY(ARG) if (tmp=search_tree (ARG, func), tmp != NULL_TREE) return tmp - - tree tmp; - - if (t == NULL_TREE) - return t; - - if (tmp = func (t), tmp != NULL_TREE) - return tmp; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - break; - - case IDENTIFIER_NODE: - break; - - case VAR_DECL: - case FUNCTION_DECL: - case CONST_DECL: - case TEMPLATE_DECL: - case NAMESPACE_DECL: - break; - - case TYPE_DECL: - TRY (TREE_TYPE (t)); - break; - - case PARM_DECL: - TRY (TREE_TYPE (t)); - TRY (TREE_CHAIN (t)); - break; - - case TREE_LIST: - TRY (TREE_PURPOSE (t)); - TRY (TREE_VALUE (t)); - TRY (TREE_CHAIN (t)); - break; - - case OVERLOAD: - TRY (OVL_FUNCTION (t)); - TRY (OVL_CHAIN (t)); - break; - - case TREE_VEC: - { - int len = TREE_VEC_LENGTH (t); - - t = copy_node (t); - while (len--) - TRY (TREE_VEC_ELT (t, len)); - } - break; - - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - case DEFAULT_ARG: - break; - - case PTRMEM_CST: - TRY (TREE_TYPE (t)); - break; - - case COND_EXPR: - case TARGET_EXPR: - case AGGR_INIT_EXPR: - case NEW_EXPR: - TRY (TREE_OPERAND (t, 0)); - TRY (TREE_OPERAND (t, 1)); - TRY (TREE_OPERAND (t, 2)); - break; - - case MODIFY_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case COMPOUND_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case ARRAY_REF: - case SCOPE_REF: - case TRY_CATCH_EXPR: - case WITH_CLEANUP_EXPR: - case CALL_EXPR: - TRY (TREE_OPERAND (t, 0)); - TRY (TREE_OPERAND (t, 1)); - break; - - case SAVE_EXPR: - case CONVERT_EXPR: - case ADDR_EXPR: - case INDIRECT_REF: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case NOP_EXPR: - case NON_LVALUE_EXPR: - case COMPONENT_REF: - case CLEANUP_POINT_EXPR: - case LOOKUP_EXPR: - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - TRY (TREE_OPERAND (t, 0)); - break; - - case MODOP_EXPR: - case CAST_EXPR: - case REINTERPRET_CAST_EXPR: - case CONST_CAST_EXPR: - case STATIC_CAST_EXPR: - case DYNAMIC_CAST_EXPR: - case ARROW_EXPR: - case DOTSTAR_EXPR: - case TYPEID_EXPR: - break; - - case COMPLEX_CST: - TRY (TREE_REALPART (t)); - TRY (TREE_IMAGPART (t)); - break; - - case CONSTRUCTOR: - TRY (CONSTRUCTOR_ELTS (t)); - break; - - case TEMPLATE_TEMPLATE_PARM: - case TEMPLATE_PARM_INDEX: - case TEMPLATE_TYPE_PARM: - break; - - case BIND_EXPR: - break; - - case REAL_TYPE: - case COMPLEX_TYPE: - case VOID_TYPE: - case BOOLEAN_TYPE: - case TYPENAME_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - case TYPEOF_TYPE: - break; - - case POINTER_TYPE: - case REFERENCE_TYPE: - TRY (TREE_TYPE (t)); - break; - - case FUNCTION_TYPE: - case METHOD_TYPE: - TRY (TREE_TYPE (t)); - TRY (TYPE_ARG_TYPES (t)); - break; - - case ARRAY_TYPE: - TRY (TREE_TYPE (t)); - TRY (TYPE_DOMAIN (t)); - break; - - case INTEGER_TYPE: - TRY (TYPE_MAX_VALUE (t)); - break; - - case OFFSET_TYPE: - TRY (TREE_TYPE (t)); - TRY (TYPE_OFFSET_BASETYPE (t)); - break; - - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (t)) - TRY (TYPE_PTRMEMFUNC_FN_TYPE (t)); - break; - - /* This list is incomplete, but should suffice for now. - It is very important that `sorry' not call - `report_error_function'. That could cause an infinite loop. */ - default: - sorry ("initializer contains unrecognized tree code"); - return error_mark_node; - - } - - return NULL_TREE; - -#undef TRY -} - -/* Passed to search_tree. Checks for the use of types with no linkage. */ - -static tree -no_linkage_helper (t) - tree t; -{ - if (TYPE_P (t) - && (IS_AGGR_TYPE (t) || TREE_CODE (t) == ENUMERAL_TYPE) - && (decl_function_context (TYPE_MAIN_DECL (t)) - || ANON_AGGRNAME_P (TYPE_IDENTIFIER (t)))) - return t; - return NULL_TREE; -} - -/* Check if the type T depends on a type with no linkage and if so, return - it. */ - -tree -no_linkage_check (t) - tree t; -{ - t = search_tree (t, no_linkage_helper); - if (t != error_mark_node) - return t; - return NULL_TREE; -} - - -/* Subroutine of copy_to_permanent - - Assuming T is a node build bottom-up, make it all exist on - permanent obstack, if it is not permanent already. */ - -tree -mapcar (t, func) - tree t; - tree (*func) PROTO((tree)); -{ - tree tmp; - - if (t == NULL_TREE) - return t; - - if (tmp = func (t), tmp != NULL_TREE) - return tmp; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - return error_mark_node; - - case VAR_DECL: - case FUNCTION_DECL: - case CONST_DECL: - /* Rather than aborting, return error_mark_node. This allows us - to report a sensible error message on code like this: - - void g() { int i; f<i>(7); } - - In a case like: - - void g() { const int i = 7; f<i>(7); } - - however, we must actually return the constant initializer. */ - tmp = decl_constant_value (t); - if (tmp != t) - return mapcar (tmp, func); - else - return error_mark_node; - - case PARM_DECL: - { - tree chain = TREE_CHAIN (t); - t = copy_node (t); - TREE_CHAIN (t) = mapcar (chain, func); - TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); - DECL_INITIAL (t) = mapcar (DECL_INITIAL (t), func); - DECL_SIZE (t) = mapcar (DECL_SIZE (t), func); - return t; - } - - case TREE_LIST: - { - tree chain = TREE_CHAIN (t); - t = copy_node (t); - TREE_PURPOSE (t) = mapcar (TREE_PURPOSE (t), func); - TREE_VALUE (t) = mapcar (TREE_VALUE (t), func); - TREE_CHAIN (t) = mapcar (chain, func); - return t; - } - - case OVERLOAD: - { - tree chain = OVL_CHAIN (t); - t = copy_node (t); - OVL_FUNCTION (t) = mapcar (OVL_FUNCTION (t), func); - OVL_CHAIN (t) = mapcar (chain, func); - return t; - } - - case TREE_VEC: - { - int len = TREE_VEC_LENGTH (t); - - t = copy_node (t); - while (len--) - TREE_VEC_ELT (t, len) = mapcar (TREE_VEC_ELT (t, len), func); - return t; - } - - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - return copy_node (t); - - case PTRMEM_CST: - t = copy_node (t); - TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); - PTRMEM_CST_MEMBER (t) = mapcar (PTRMEM_CST_MEMBER (t), func); - return t; - - case COND_EXPR: - case TARGET_EXPR: - case AGGR_INIT_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); - TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); - return t; - - case SAVE_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - return t; - - case MODIFY_EXPR: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case TRUNC_MOD_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case COMPOUND_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case ARRAY_REF: - case SCOPE_REF: - case TRY_CATCH_EXPR: - case WITH_CLEANUP_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); - return t; - - case CALL_EXPR: - t = copy_node (t); - TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); - - /* tree.def says that operand two is RTL, but - make_call_declarator puts trees in there. */ - if (TREE_OPERAND (t, 2) - && TREE_CODE (TREE_OPERAND (t, 2)) == TREE_LIST) - TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); - else - TREE_OPERAND (t, 2) = NULL_TREE; - return t; - - case CONVERT_EXPR: - case ADDR_EXPR: - case INDIRECT_REF: - case NEGATE_EXPR: - case BIT_NOT_EXPR: - case TRUTH_NOT_EXPR: - case NOP_EXPR: - case COMPONENT_REF: - case CLEANUP_POINT_EXPR: - t = copy_node (t); - TREE_TYPE (t) = mapcar (TREE_TYPE (t), func); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - return t; - - case POINTER_TYPE: - tmp = build_pointer_type (mapcar (TREE_TYPE (t), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - case REFERENCE_TYPE: - tmp = build_reference_type (mapcar (TREE_TYPE (t), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - case FUNCTION_TYPE: - tmp = build_function_type (mapcar (TREE_TYPE (t), func), - mapcar (TYPE_ARG_TYPES (t), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - case ARRAY_TYPE: - tmp = build_cplus_array_type (mapcar (TREE_TYPE (t), func), - mapcar (TYPE_DOMAIN (t), func)); - return cp_build_qualified_type (tmp, CP_TYPE_QUALS (t)); - case INTEGER_TYPE: - tmp = build_index_type (mapcar (TYPE_MAX_VALUE (t), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - case OFFSET_TYPE: - tmp = build_offset_type (mapcar (TYPE_OFFSET_BASETYPE (t), func), - mapcar (TREE_TYPE (t), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - case METHOD_TYPE: - tmp = build_cplus_method_type - (mapcar (TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t))), func), - mapcar (TREE_TYPE (t), func), - mapcar (TREE_CHAIN (TYPE_ARG_TYPES (t)), func)); - return cp_build_qualified_type (tmp, TYPE_QUALS (t)); - - case COMPLEX_CST: - t = copy_node (t); - TREE_REALPART (t) = mapcar (TREE_REALPART (t), func); - TREE_IMAGPART (t) = mapcar (TREE_REALPART (t), func); - return t; - - case CONSTRUCTOR: - t = copy_node (t); - CONSTRUCTOR_ELTS (t) = mapcar (CONSTRUCTOR_ELTS (t), func); - return t; - - case TEMPLATE_TEMPLATE_PARM: - return copy_template_template_parm (t); - - case BIND_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); - TREE_OPERAND (t, 2) = NULL_TREE; - return t; - - case NEW_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - TREE_OPERAND (t, 1) = mapcar (TREE_OPERAND (t, 1), func); - TREE_OPERAND (t, 2) = mapcar (TREE_OPERAND (t, 2), func); - return t; - - case LOOKUP_EXPR: - t = copy_node (t); - TREE_OPERAND (t, 0) = mapcar (TREE_OPERAND (t, 0), func); - return t; - - case RECORD_TYPE: - if (TYPE_PTRMEMFUNC_P (t)) - return build_ptrmemfunc_type - (mapcar (TYPE_PTRMEMFUNC_FN_TYPE (t), func)); - /* else fall through */ - - /* This list is incomplete, but should suffice for now. - It is very important that `sorry' not call - `report_error_function'. That could cause an infinite loop. */ - default: - sorry ("initializer contains unrecognized tree code"); - return error_mark_node; - - } - my_friendly_abort (107); - /* NOTREACHED */ - return NULL_TREE; -} - -static tree -perm_manip (t) - tree t; -{ - if (TREE_PERMANENT (t)) - return t; - - /* Support `void f () { extern int i; A<&i> a; }' */ - if ((TREE_CODE (t) == VAR_DECL || TREE_CODE (t) == FUNCTION_DECL) - && TREE_PUBLIC (t)) - { - t = copy_node (t); - - /* copy_rtx won't make a new SYMBOL_REF, so call make_decl_rtl again. */ - DECL_RTL (t) = 0; - make_decl_rtl (t, NULL_PTR, 1); - - return t; - } - return NULL_TREE; -} - -/* Assuming T is a node built bottom-up, make it all exist on - permanent obstack, if it is not permanent already. */ - -tree -copy_to_permanent (t) - tree t; -{ - if (t == NULL_TREE || TREE_PERMANENT (t)) - return t; - - push_obstacks_nochange (); - end_temporary_allocation (); - - t = mapcar (t, perm_manip); - - pop_obstacks (); - - return t; -} - -#ifdef GATHER_STATISTICS -extern int depth_reached; -#endif - -void -print_lang_statistics () -{ - extern struct obstack decl_obstack; - print_obstack_statistics ("class_obstack", &class_obstack); - print_obstack_statistics ("decl_obstack", &decl_obstack); - print_search_statistics (); - print_class_statistics (); -#ifdef GATHER_STATISTICS - fprintf (stderr, "maximum template instantiation depth reached: %d\n", - depth_reached); -#endif -} - -/* This is used by the `assert' macro. It is provided in libgcc.a, - which `cc' doesn't know how to link. Note that the C++ front-end - no longer actually uses the `assert' macro (instead, it calls - my_friendly_assert). But all of the back-end files still need this. */ - -void -__eprintf (string, expression, line, filename) -#ifdef __STDC__ - const char *string; - const char *expression; - unsigned line; - const char *filename; -#else - char *string; - char *expression; - unsigned line; - char *filename; -#endif -{ - fprintf (stderr, string, expression, line, filename); - fflush (stderr); - abort (); -} - -/* Return, as an INTEGER_CST node, the number of elements for TYPE - (which is an ARRAY_TYPE). This counts only elements of the top - array. */ - -tree -array_type_nelts_top (type) - tree type; -{ - return fold (build (PLUS_EXPR, sizetype, - array_type_nelts (type), - integer_one_node)); -} - -/* Return, as an INTEGER_CST node, the number of elements for TYPE - (which is an ARRAY_TYPE). This one is a recursive count of all - ARRAY_TYPEs that are clumped together. */ - -tree -array_type_nelts_total (type) - tree type; -{ - tree sz = array_type_nelts_top (type); - type = TREE_TYPE (type); - while (TREE_CODE (type) == ARRAY_TYPE) - { - tree n = array_type_nelts_top (type); - sz = fold (build (MULT_EXPR, sizetype, sz, n)); - type = TREE_TYPE (type); - } - return sz; -} - -static -tree -bot_manip (t) - tree t; -{ - if (TREE_CODE (t) != TREE_LIST && ! TREE_SIDE_EFFECTS (t)) - return t; - else if (TREE_CODE (t) == TARGET_EXPR) - { - if (TREE_CODE (TREE_OPERAND (t, 1)) == AGGR_INIT_EXPR) - { - mark_used (TREE_OPERAND (TREE_OPERAND (TREE_OPERAND (t, 1), 0), 0)); - return build_cplus_new - (TREE_TYPE (t), break_out_target_exprs (TREE_OPERAND (t, 1))); - } - t = copy_node (t); - TREE_OPERAND (t, 0) = build (VAR_DECL, TREE_TYPE (t)); - layout_decl (TREE_OPERAND (t, 0), 0); - return t; - } - else if (TREE_CODE (t) == CALL_EXPR) - mark_used (TREE_OPERAND (TREE_OPERAND (t, 0), 0)); - - return NULL_TREE; -} - -/* Actually, we'll just clean out the target exprs for the moment. */ - -tree -break_out_target_exprs (t) - tree t; -{ - return mapcar (t, bot_manip); -} - -/* Obstack used for allocating nodes in template function and variable - definitions. */ - -/* Similar to `build_nt', except we build - on the permanent_obstack, regardless. */ - -tree -build_min_nt VPROTO((enum tree_code code, ...)) -{ -#ifndef ANSI_PROTOTYPES - enum tree_code code; -#endif - register struct obstack *ambient_obstack = expression_obstack; - va_list p; - register tree t; - register int length; - register int i; - - VA_START (p, code); - -#ifndef ANSI_PROTOTYPES - code = va_arg (p, enum tree_code); -#endif - - expression_obstack = &permanent_obstack; - - t = make_node (code); - length = tree_code_length[(int) code]; - TREE_COMPLEXITY (t) = lineno; - - for (i = 0; i < length; i++) - { - tree x = va_arg (p, tree); - TREE_OPERAND (t, i) = copy_to_permanent (x); - } - - va_end (p); - expression_obstack = ambient_obstack; - return t; -} - -/* Similar to `build', except we build - on the permanent_obstack, regardless. */ - -tree -build_min VPROTO((enum tree_code code, tree tt, ...)) -{ -#ifndef ANSI_PROTOTYPES - enum tree_code code; - tree tt; -#endif - register struct obstack *ambient_obstack = expression_obstack; - va_list p; - register tree t; - register int length; - register int i; - - VA_START (p, tt); - -#ifndef ANSI_PROTOTYPES - code = va_arg (p, enum tree_code); - tt = va_arg (p, tree); -#endif - - expression_obstack = &permanent_obstack; - - t = make_node (code); - length = tree_code_length[(int) code]; - TREE_TYPE (t) = copy_to_permanent (tt); - TREE_COMPLEXITY (t) = lineno; - - for (i = 0; i < length; i++) - { - tree x = va_arg (p, tree); - TREE_OPERAND (t, i) = copy_to_permanent (x); - } - - va_end (p); - expression_obstack = ambient_obstack; - return t; -} - -/* Same as `tree_cons' but make a permanent object. */ - -tree -min_tree_cons (purpose, value, chain) - tree purpose, value, chain; -{ - register tree node; - register struct obstack *ambient_obstack = current_obstack; - current_obstack = &permanent_obstack; - - node = tree_cons (copy_to_permanent (purpose), - copy_to_permanent (value), chain); - current_obstack = ambient_obstack; - return node; -} - -tree -get_type_decl (t) - tree t; -{ - if (TREE_CODE (t) == TYPE_DECL) - return t; - if (TREE_CODE_CLASS (TREE_CODE (t)) == 't') - return TYPE_STUB_DECL (t); - - my_friendly_abort (42); - - /* Stop compiler from complaining control reaches end of non-void function. */ - return 0; -} - -int -can_free (obstack, t) - struct obstack *obstack; - tree t; -{ - int size = 0; - - if (TREE_CODE (t) == TREE_VEC) - size = (TREE_VEC_LENGTH (t)-1) * sizeof (tree) + sizeof (struct tree_vec); - else - my_friendly_abort (42); - -#define ROUND(x) ((x + obstack_alignment_mask (obstack)) \ - & ~ obstack_alignment_mask (obstack)) - if ((char *)t + ROUND (size) == obstack_next_free (obstack)) - return 1; -#undef ROUND - - return 0; -} - -/* Return first vector element whose BINFO_TYPE is ELEM. - Return 0 if ELEM is not in VEC. VEC may be NULL_TREE. */ - -tree -vec_binfo_member (elem, vec) - tree elem, vec; -{ - int i; - - if (vec) - for (i = 0; i < TREE_VEC_LENGTH (vec); ++i) - if (same_type_p (elem, BINFO_TYPE (TREE_VEC_ELT (vec, i)))) - return TREE_VEC_ELT (vec, i); - - return NULL_TREE; -} - -/* Kludge around the fact that DECL_CONTEXT for virtual functions returns - the wrong thing for decl_function_context. Hopefully the uses in the - backend won't matter, since we don't need a static chain for local class - methods. FIXME! */ - -tree -hack_decl_function_context (decl) - tree decl; -{ - if (TREE_CODE (decl) == FUNCTION_DECL && DECL_FUNCTION_MEMBER_P (decl)) - return decl_function_context (TYPE_MAIN_DECL (DECL_CLASS_CONTEXT (decl))); - return decl_function_context (decl); -} - -/* Return truthvalue of whether T1 is the same tree structure as T2. - Return 1 if they are the same. - Return 0 if they are understandably different. - Return -1 if either contains tree structure not understood by - this function. */ - -int -cp_tree_equal (t1, t2) - tree t1, t2; -{ - register enum tree_code code1, code2; - int cmp; - - if (t1 == t2) - return 1; - if (t1 == 0 || t2 == 0) - return 0; - - code1 = TREE_CODE (t1); - code2 = TREE_CODE (t2); - - if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR) - { - if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR) - return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - else - return cp_tree_equal (TREE_OPERAND (t1, 0), t2); - } - else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR - || code2 == NON_LVALUE_EXPR) - return cp_tree_equal (t1, TREE_OPERAND (t2, 0)); - - if (code1 != code2) - return 0; - - switch (code1) - { - case INTEGER_CST: - return TREE_INT_CST_LOW (t1) == TREE_INT_CST_LOW (t2) - && TREE_INT_CST_HIGH (t1) == TREE_INT_CST_HIGH (t2); - - case REAL_CST: - return REAL_VALUES_EQUAL (TREE_REAL_CST (t1), TREE_REAL_CST (t2)); - - case STRING_CST: - return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2) - && !bcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2), - TREE_STRING_LENGTH (t1)); - - case CONSTRUCTOR: - /* We need to do this when determining whether or not two - non-type pointer to member function template arguments - are the same. */ - if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2)) - /* The first operand is RTL. */ - && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0))) - return 0; - return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); - - case TREE_LIST: - cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)); - if (cmp <= 0) - return cmp; - cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)); - if (cmp <= 0) - return cmp; - return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2)); - - case SAVE_EXPR: - return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - - case CALL_EXPR: - cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - if (cmp <= 0) - return cmp; - return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); - - case TARGET_EXPR: - /* Special case: if either target is an unallocated VAR_DECL, - it means that it's going to be unified with whatever the - TARGET_EXPR is really supposed to initialize, so treat it - as being equivalent to anything. */ - if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL - && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE - && DECL_RTL (TREE_OPERAND (t1, 0)) == 0) - || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL - && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE - && DECL_RTL (TREE_OPERAND (t2, 0)) == 0)) - cmp = 1; - else - cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - if (cmp <= 0) - return cmp; - return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1)); - - case WITH_CLEANUP_EXPR: - cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - if (cmp <= 0) - return cmp; - return cp_tree_equal (TREE_OPERAND (t1, 2), TREE_OPERAND (t1, 2)); - - case COMPONENT_REF: - if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1)) - return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - return 0; - - case VAR_DECL: - case PARM_DECL: - case CONST_DECL: - case FUNCTION_DECL: - return 0; - - case TEMPLATE_PARM_INDEX: - return TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2) - && TEMPLATE_PARM_LEVEL (t1) == TEMPLATE_PARM_LEVEL (t2); - - case SIZEOF_EXPR: - case ALIGNOF_EXPR: - if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0))) - return 0; - if (TREE_CODE_CLASS (TREE_CODE (TREE_OPERAND (t1, 0))) == 't') - return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)); - break; - - case PTRMEM_CST: - /* Two pointer-to-members are the same if they point to the same - field or function in the same class. */ - return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2) - && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2))); - - default: - break; - } - - switch (TREE_CODE_CLASS (code1)) - { - int i; - case '1': - case '2': - case '<': - case 'e': - case 'r': - case 's': - cmp = 1; - for (i=0; i<tree_code_length[(int) code1]; ++i) - { - cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)); - if (cmp <= 0) - return cmp; - } - return cmp; - } - - return -1; -} - -/* Similar to make_tree_vec, but build on the momentary_obstack. - Thus, these vectors are really and truly temporary. */ - -tree -make_temp_vec (len) - int len; -{ - register tree node; - push_expression_obstack (); - node = make_tree_vec (len); - pop_obstacks (); - return node; -} - -/* Build a wrapper around some pointer PTR so we can use it as a tree. */ - -tree -build_ptr_wrapper (ptr) - void *ptr; -{ - tree t = make_node (WRAPPER); - WRAPPER_PTR (t) = ptr; - return t; -} - -/* Same, but on the expression_obstack. */ - -tree -build_expr_ptr_wrapper (ptr) - void *ptr; -{ - tree t; - push_expression_obstack (); - t = build_ptr_wrapper (ptr); - pop_obstacks (); - return t; -} - -/* Build a wrapper around some integer I so we can use it as a tree. */ - -tree -build_int_wrapper (i) - int i; -{ - tree t = make_node (WRAPPER); - WRAPPER_INT (t) = i; - return t; -} - -tree -build_srcloc (file, line) - char *file; - int line; -{ - tree t; - - /* Make sure that we put these on the permanent obstack; up in - add_pending_template, we pass this return value into perm_tree_cons, - which also puts it on the permanent_obstack. However, this wasn't - explicitly doing the same. */ - register struct obstack *ambient_obstack = current_obstack; - current_obstack = &permanent_obstack; - - t = make_node (SRCLOC); - SRCLOC_FILE (t) = file; - SRCLOC_LINE (t) = line; - - current_obstack = ambient_obstack; - - return t; -} - -tree -build_srcloc_here () -{ - return build_srcloc (input_filename, lineno); -} - -void -push_expression_obstack () -{ - push_obstacks_nochange (); - current_obstack = expression_obstack; -} - -/* The type of ARG when used as an lvalue. */ - -tree -lvalue_type (arg) - tree arg; -{ - tree type = TREE_TYPE (arg); - if (TREE_CODE (arg) == OVERLOAD) - type = unknown_type_node; - return type; -} - -/* The type of ARG for printing error messages; denote lvalues with - reference types. */ - -tree -error_type (arg) - tree arg; -{ - tree type = TREE_TYPE (arg); - if (TREE_CODE (type) == ARRAY_TYPE) - ; - else if (real_lvalue_p (arg)) - type = build_reference_type (lvalue_type (arg)); - else if (IS_AGGR_TYPE (type)) - type = lvalue_type (arg); - - return type; -} - -/* Does FUNCTION use a variable-length argument list? */ - -int -varargs_function_p (function) - tree function; -{ - tree parm = TYPE_ARG_TYPES (TREE_TYPE (function)); - for (; parm; parm = TREE_CHAIN (parm)) - if (TREE_VALUE (parm) == void_type_node) - return 0; - return 1; -} - -/* Returns 1 if decl is a member of a class. */ - -int -member_p (decl) - tree decl; -{ - tree ctx = DECL_CONTEXT (decl); - return (ctx && TREE_CODE_CLASS (TREE_CODE (ctx)) == 't'); -} - -/* Create a placeholder for member access where we don't actually have an - object that the access is against. */ - -tree -build_dummy_object (type) - tree type; -{ - tree decl = build1 (NOP_EXPR, build_pointer_type (type), error_mark_node); - return build_indirect_ref (decl, NULL_PTR); -} - -/* We've gotten a reference to a member of TYPE. Return *this if appropriate, - or a dummy object otherwise. If BINFOP is non-0, it is filled with the - binfo path from current_class_type to TYPE, or 0. */ - -tree -maybe_dummy_object (type, binfop) - tree type; - tree *binfop; -{ - tree decl, context; - - if (current_class_type - && get_base_distance (type, current_class_type, 0, binfop) != -1) - context = current_class_type; - else - { - /* Reference from a nested class member function. */ - context = type; - if (binfop) - *binfop = TYPE_BINFO (type); - } - - if (current_class_ref && context == current_class_type) - decl = current_class_ref; - else - decl = build_dummy_object (context); - - return decl; -} - -/* Returns 1 if OB is a placeholder object, or a pointer to one. */ - -int -is_dummy_object (ob) - tree ob; -{ - if (TREE_CODE (ob) == INDIRECT_REF) - ob = TREE_OPERAND (ob, 0); - return (TREE_CODE (ob) == NOP_EXPR - && TREE_OPERAND (ob, 0) == error_mark_node); -} - -/* Returns 1 iff type T is a POD type, as defined in [basic.types]. */ - -int -pod_type_p (t) - tree t; -{ - tree f; - - while (TREE_CODE (t) == ARRAY_TYPE) - t = TREE_TYPE (t); - - if (! IS_AGGR_TYPE (t)) - return 1; - - if (CLASSTYPE_NON_AGGREGATE (t) - || TYPE_HAS_COMPLEX_ASSIGN_REF (t) - || TYPE_HAS_DESTRUCTOR (t)) - return 0; - - for (f = TYPE_FIELDS (t); f; f = TREE_CHAIN (f)) - { - if (TREE_CODE (f) != FIELD_DECL) - continue; - - if (TREE_CODE (TREE_TYPE (f)) == REFERENCE_TYPE - || TYPE_PTRMEMFUNC_P (TREE_TYPE (f)) - || TYPE_PTRMEM_P (TREE_TYPE (f))) - return 0; - } - - return 1; -} diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c deleted file mode 100755 index 58c19a4..0000000 --- a/gcc/cp/typeck.c +++ /dev/null @@ -1,7495 +0,0 @@ -/* Build expressions with type checking for C++ compiler. - Copyright (C) 1987, 88, 89, 92-98, 1999 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file is part of the C++ front end. - It contains routines to build C++ expressions given their operands, - including computing the types of the result, C and C++ specific error - checks, and some optimization. - - There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, - and to process initializations in declarations (since they work - like a strange sort of assignment). */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "rtl.h" -#include "cp-tree.h" -#include "flags.h" -#include "output.h" -#include "expr.h" -#include "toplev.h" - -extern void compiler_error (); - -static tree convert_for_assignment PROTO((tree, tree, char*, tree, - int)); -static tree pointer_int_sum PROTO((enum tree_code, tree, tree)); -static tree rationalize_conditional_expr PROTO((enum tree_code, tree)); -static int comp_target_parms PROTO((tree, tree, int)); -static int comp_ptr_ttypes_real PROTO((tree, tree, int)); -static int comp_ptr_ttypes_const PROTO((tree, tree)); -static int comp_ptr_ttypes_reinterpret PROTO((tree, tree)); -static int comp_array_types PROTO((int (*) (tree, tree, int), tree, - tree, int)); -static tree build_ptrmemfunc1 PROTO((tree, tree, tree, tree, tree)); -static tree common_base_type PROTO((tree, tree)); -#if 0 -static tree convert_sequence PROTO((tree, tree)); -#endif -static tree lookup_anon_field PROTO((tree, tree)); -static tree pointer_diff PROTO((tree, tree, tree)); -static tree qualify_type PROTO((tree, tree)); -static tree get_delta_difference PROTO((tree, tree, int)); - -/* Return the target type of TYPE, which meas return T for: - T*, T&, T[], T (...), and otherwise, just T. */ - -tree -target_type (type) - tree type; -{ - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - while (TREE_CODE (type) == POINTER_TYPE - || TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE - || TREE_CODE (type) == OFFSET_TYPE) - type = TREE_TYPE (type); - return type; -} - -/* Do `exp = require_complete_type (exp);' to make sure exp - does not have an incomplete type. (That includes void types.) - Returns the error_mark_node if the VALUE does not have - complete type when this function returns. */ - -tree -require_complete_type (value) - tree value; -{ - tree type; - - if (processing_template_decl) - return value; - - if (TREE_CODE (value) == OVERLOAD) - type = unknown_type_node; - else - type = TREE_TYPE (value); - - /* First, detect a valid value with a complete type. */ - if (TYPE_SIZE (type) != 0 - && type != void_type_node - && ! (TYPE_LANG_SPECIFIC (type) - && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)) - && TYPE_SIZE (SIGNATURE_TYPE (type)) == 0)) - return value; - - /* If we see X::Y, we build an OFFSET_TYPE which has - not been laid out. Try to avoid an error by interpreting - it as this->X::Y, if reasonable. */ - if (TREE_CODE (value) == OFFSET_REF - && current_class_ref != 0 - && TREE_OPERAND (value, 0) == current_class_ref) - { - tree base, member = TREE_OPERAND (value, 1); - tree basetype = TYPE_OFFSET_BASETYPE (type); - my_friendly_assert (TREE_CODE (member) == FIELD_DECL, 305); - base = convert_pointer_to (basetype, current_class_ptr); - value = build (COMPONENT_REF, TREE_TYPE (member), - build_indirect_ref (base, NULL_PTR), member); - return require_complete_type (value); - } - - if (complete_type_or_else (type)) - return value; - else - return error_mark_node; -} - -/* Try to complete TYPE, if it is incomplete. For example, if TYPE is - a template instantiation, do the instantiation. Returns TYPE, - whether or not it could be completed, unless something goes - horribly wrong, in which case the error_mark_node is returned. */ - -tree -complete_type (type) - tree type; -{ - if (type == NULL_TREE) - /* Rather than crash, we return something sure to cause an error - at some point. */ - return error_mark_node; - - if (type == error_mark_node || TYPE_SIZE (type) != NULL_TREE) - ; - else if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type)) - { - tree t = complete_type (TREE_TYPE (type)); - if (TYPE_SIZE (t) != NULL_TREE && ! processing_template_decl) - layout_type (type); - TYPE_NEEDS_CONSTRUCTING (type) - = TYPE_NEEDS_CONSTRUCTING (TYPE_MAIN_VARIANT (t)); - TYPE_NEEDS_DESTRUCTOR (type) - = TYPE_NEEDS_DESTRUCTOR (TYPE_MAIN_VARIANT (t)); - } - else if (CLASS_TYPE_P (type) && CLASSTYPE_TEMPLATE_INSTANTIATION (type)) - instantiate_class_template (TYPE_MAIN_VARIANT (type)); - - return type; -} - -/* Like complete_type, but issue an error if the TYPE cannot be - completed. Returns NULL_TREE if the type cannot be made - complete. */ - -tree -complete_type_or_else (type) - tree type; -{ - type = complete_type (type); - if (type == error_mark_node) - /* We already issued an error. */ - return NULL_TREE; - else if (!TYPE_SIZE (type)) - { - incomplete_type_error (NULL_TREE, type); - return NULL_TREE; - } - else - return type; -} - -/* Return truthvalue of whether type of EXP is instantiated. */ - -int -type_unknown_p (exp) - tree exp; -{ - return (TREE_CODE (exp) == OVERLOAD - || TREE_CODE (exp) == TREE_LIST - || TREE_TYPE (exp) == unknown_type_node - || (TREE_CODE (TREE_TYPE (exp)) == OFFSET_TYPE - && TREE_TYPE (TREE_TYPE (exp)) == unknown_type_node)); -} - -/* Return truthvalue of whether T is function (or pfn) type. */ - -int -fntype_p (t) - tree t; -{ - return (TREE_CODE (t) == FUNCTION_TYPE || TREE_CODE (t) == METHOD_TYPE - || (TREE_CODE (t) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (t)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (t)) == METHOD_TYPE))); -} - -/* Return a variant of TYPE which has all the type qualifiers of LIKE - as well as those of TYPE. */ - -static tree -qualify_type (type, like) - tree type, like; -{ - /* @@ Must do member pointers here. */ - return cp_build_qualified_type (type, (CP_TYPE_QUALS (type) - | CP_TYPE_QUALS (like))); -} - -/* Return the common type of two parameter lists. - We assume that comptypes has already been done and returned 1; - if that isn't so, this may crash. - - As an optimization, free the space we allocate if the parameter - lists are already common. */ - -tree -commonparms (p1, p2) - tree p1, p2; -{ - tree oldargs = p1, newargs, n; - int i, len; - int any_change = 0; - char *first_obj = (char *) oballoc (0); - - len = list_length (p1); - newargs = tree_last (p1); - - if (newargs == void_list_node) - i = 1; - else - { - i = 0; - newargs = 0; - } - - for (; i < len; i++) - newargs = tree_cons (NULL_TREE, NULL_TREE, newargs); - - n = newargs; - - for (i = 0; p1; - p1 = TREE_CHAIN (p1), p2 = TREE_CHAIN (p2), n = TREE_CHAIN (n), i++) - { - if (TREE_PURPOSE (p1) && !TREE_PURPOSE (p2)) - { - TREE_PURPOSE (n) = TREE_PURPOSE (p1); - any_change = 1; - } - else if (! TREE_PURPOSE (p1)) - { - if (TREE_PURPOSE (p2)) - { - TREE_PURPOSE (n) = TREE_PURPOSE (p2); - any_change = 1; - } - } - else - { - if (1 != simple_cst_equal (TREE_PURPOSE (p1), TREE_PURPOSE (p2))) - any_change = 1; - TREE_PURPOSE (n) = TREE_PURPOSE (p2); - } - if (TREE_VALUE (p1) != TREE_VALUE (p2)) - { - any_change = 1; - TREE_VALUE (n) = common_type (TREE_VALUE (p1), TREE_VALUE (p2)); - } - else - TREE_VALUE (n) = TREE_VALUE (p1); - } - if (! any_change) - { - obfree (first_obj); - return oldargs; - } - - return newargs; -} - -/* Given a type, perhaps copied for a typedef, - find the "original" version of it. */ -tree -original_type (t) - tree t; -{ - while (TYPE_NAME (t) != NULL_TREE) - { - tree x = TYPE_NAME (t); - if (TREE_CODE (x) != TYPE_DECL) - break; - x = DECL_ORIGINAL_TYPE (x); - if (x == NULL_TREE) - break; - t = x; - } - return t; -} - -/* Return the common type of two types. - We assume that comptypes has already been done and returned 1; - if that isn't so, this may crash. - - This is the type for the result of most arithmetic operations - if the operands have the given two types. - - We do not deal with enumeral types here because they have already been - converted to integer types. */ - -tree -common_type (t1, t2) - tree t1, t2; -{ - register enum tree_code code1; - register enum tree_code code2; - tree attributes; - - /* Save time if the two types are the same. */ - if (t1 == t2) - return t1; - t1 = original_type (t1); - t2 = original_type (t2); - if (t1 == t2) - return t1; - - /* If one type is nonsense, use the other. */ - if (t1 == error_mark_node) - return t2; - if (t2 == error_mark_node) - return t1; - - /* Merge the attributes. */ - attributes = merge_machine_type_attributes (t1, t2); - - { register tree a1, a2; - a1 = TYPE_ATTRIBUTES (t1); - a2 = TYPE_ATTRIBUTES (t2); - - /* Either one unset? Take the set one. */ - - if (!(attributes = a1)) - attributes = a2; - - /* One that completely contains the other? Take it. */ - - else if (a2 && !attribute_list_contained (a1, a2)) - { - if (attribute_list_contained (a2, a1)) - attributes = a2; - else - { - /* Pick the longest list, and hang on the other list. */ - /* ??? For the moment we punt on the issue of attrs with args. */ - - if (list_length (a1) < list_length (a2)) - attributes = a2, a2 = a1; - - for (; a2; a2 = TREE_CHAIN (a2)) - if (lookup_attribute (IDENTIFIER_POINTER (TREE_PURPOSE (a2)), - attributes) == NULL_TREE) - { - a1 = copy_node (a2); - TREE_CHAIN (a1) = attributes; - attributes = a1; - } - } - } - } - - /* Treat an enum type as the unsigned integer type of the same width. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - - if (TYPE_PTRMEMFUNC_P (t1)) - t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1); - if (TYPE_PTRMEMFUNC_P (t2)) - t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2); - - code1 = TREE_CODE (t1); - code2 = TREE_CODE (t2); - - /* If one type is complex, form the common type of the non-complex - components, then make that complex. Use T1 or T2 if it is the - required type. */ - if (code1 == COMPLEX_TYPE || code2 == COMPLEX_TYPE) - { - tree subtype1 = code1 == COMPLEX_TYPE ? TREE_TYPE (t1) : t1; - tree subtype2 = code2 == COMPLEX_TYPE ? TREE_TYPE (t2) : t2; - tree subtype = common_type (subtype1, subtype2); - - if (code1 == COMPLEX_TYPE && TREE_TYPE (t1) == subtype) - return build_type_attribute_variant (t1, attributes); - else if (code2 == COMPLEX_TYPE && TREE_TYPE (t2) == subtype) - return build_type_attribute_variant (t2, attributes); - else - return build_type_attribute_variant (build_complex_type (subtype), - attributes); - } - - switch (code1) - { - case INTEGER_TYPE: - case REAL_TYPE: - /* If only one is real, use it as the result. */ - - if (code1 == REAL_TYPE && code2 != REAL_TYPE) - return build_type_attribute_variant (t1, attributes); - - if (code2 == REAL_TYPE && code1 != REAL_TYPE) - return build_type_attribute_variant (t2, attributes); - - /* Both real or both integers; use the one with greater precision. */ - - if (TYPE_PRECISION (t1) > TYPE_PRECISION (t2)) - return build_type_attribute_variant (t1, attributes); - else if (TYPE_PRECISION (t2) > TYPE_PRECISION (t1)) - return build_type_attribute_variant (t2, attributes); - - /* Same precision. Prefer longs to ints even when same size. */ - - if (TYPE_MAIN_VARIANT (t1) == long_unsigned_type_node - || TYPE_MAIN_VARIANT (t2) == long_unsigned_type_node) - return build_type_attribute_variant (long_unsigned_type_node, - attributes); - - if (TYPE_MAIN_VARIANT (t1) == long_integer_type_node - || TYPE_MAIN_VARIANT (t2) == long_integer_type_node) - { - /* But preserve unsignedness from the other type, - since long cannot hold all the values of an unsigned int. */ - if (TREE_UNSIGNED (t1) || TREE_UNSIGNED (t2)) - t1 = long_unsigned_type_node; - else - t1 = long_integer_type_node; - return build_type_attribute_variant (t1, attributes); - } - - if (TYPE_MAIN_VARIANT (t1) == long_double_type_node - || TYPE_MAIN_VARIANT (t2) == long_double_type_node) - return build_type_attribute_variant (long_double_type_node, - attributes); - - /* Otherwise prefer the unsigned one. */ - - if (TREE_UNSIGNED (t1)) - return build_type_attribute_variant (t1, attributes); - else - return build_type_attribute_variant (t2, attributes); - - case POINTER_TYPE: - case REFERENCE_TYPE: - /* For two pointers, do this recursively on the target type, - and combine the qualifiers of the two types' targets. */ - /* This code was turned off; I don't know why. - But ANSI C++ specifies doing this with the qualifiers. - So I turned it on again. */ - { - tree tt1 = TYPE_MAIN_VARIANT (TREE_TYPE (t1)); - tree tt2 = TYPE_MAIN_VARIANT (TREE_TYPE (t2)); - int type_quals = (CP_TYPE_QUALS (TREE_TYPE (t1)) - | CP_TYPE_QUALS (TREE_TYPE (t2))); - tree target; - - if (tt1 == tt2) - target = tt1; - else if (tt1 == void_type_node || tt2 == void_type_node) - target = void_type_node; - else if (tt1 == unknown_type_node) - target = tt2; - else if (tt2 == unknown_type_node) - target = tt1; - else - target = common_type (tt1, tt2); - - target = cp_build_qualified_type (target, type_quals); - if (code1 == POINTER_TYPE) - t1 = build_pointer_type (target); - else - t1 = build_reference_type (target); - t1 = build_type_attribute_variant (t1, attributes); - - if (TREE_CODE (target) == METHOD_TYPE) - t1 = build_ptrmemfunc_type (t1); - - return t1; - } - - case ARRAY_TYPE: - { - tree elt = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - /* Save space: see if the result is identical to one of the args. */ - if (elt == TREE_TYPE (t1) && TYPE_DOMAIN (t1)) - return build_type_attribute_variant (t1, attributes); - if (elt == TREE_TYPE (t2) && TYPE_DOMAIN (t2)) - return build_type_attribute_variant (t2, attributes); - /* Merge the element types, and have a size if either arg has one. */ - t1 = build_cplus_array_type - (elt, TYPE_DOMAIN (TYPE_DOMAIN (t1) ? t1 : t2)); - return build_type_attribute_variant (t1, attributes); - } - - case FUNCTION_TYPE: - /* Function types: prefer the one that specified arg types. - If both do, merge the arg types. Also merge the return types. */ - { - tree valtype = common_type (TREE_TYPE (t1), TREE_TYPE (t2)); - tree p1 = TYPE_ARG_TYPES (t1); - tree p2 = TYPE_ARG_TYPES (t2); - tree rval, raises; - - /* Save space: see if the result is identical to one of the args. */ - if (valtype == TREE_TYPE (t1) && ! p2) - return build_type_attribute_variant (t1, attributes); - if (valtype == TREE_TYPE (t2) && ! p1) - return build_type_attribute_variant (t2, attributes); - - /* Simple way if one arg fails to specify argument types. */ - if (p1 == NULL_TREE || TREE_VALUE (p1) == void_type_node) - { - rval = build_function_type (valtype, p2); - if ((raises = TYPE_RAISES_EXCEPTIONS (t2))) - rval = build_exception_variant (rval, raises); - return build_type_attribute_variant (rval, attributes); - } - raises = TYPE_RAISES_EXCEPTIONS (t1); - if (p2 == NULL_TREE || TREE_VALUE (p2) == void_type_node) - { - rval = build_function_type (valtype, p1); - if (raises) - rval = build_exception_variant (rval, raises); - return build_type_attribute_variant (rval, attributes); - } - - rval = build_function_type (valtype, commonparms (p1, p2)); - rval = build_exception_variant (rval, raises); - return build_type_attribute_variant (rval, attributes); - } - - case RECORD_TYPE: - case UNION_TYPE: - t1 = TYPE_MAIN_VARIANT (t1); - t2 = TYPE_MAIN_VARIANT (t2); - - if (DERIVED_FROM_P (t1, t2) && binfo_or_else (t1, t2)) - return build_type_attribute_variant (t1, attributes); - else if (binfo_or_else (t2, t1)) - return build_type_attribute_variant (t2, attributes); - else - { - compiler_error ("common_type called with uncommon aggregate types"); - return error_mark_node; - } - - case METHOD_TYPE: - if (TREE_CODE (TREE_TYPE (t1)) == TREE_CODE (TREE_TYPE (t2))) - { - /* Get this value the long way, since TYPE_METHOD_BASETYPE - is just the main variant of this. */ - tree basetype; - tree raises, t3; - - tree b1 = TYPE_OFFSET_BASETYPE (t1); - tree b2 = TYPE_OFFSET_BASETYPE (t2); - - if (same_type_p (b1, b2) - || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) - basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t2))); - else - { - if (binfo_or_else (b2, b1) == NULL_TREE) - compiler_error ("common_type called with uncommon method types"); - basetype = TREE_TYPE (TREE_VALUE (TYPE_ARG_TYPES (t1))); - } - - raises = TYPE_RAISES_EXCEPTIONS (t1); - - /* If this was a member function type, get back to the - original type of type member function (i.e., without - the class instance variable up front. */ - t1 = build_function_type (TREE_TYPE (t1), - TREE_CHAIN (TYPE_ARG_TYPES (t1))); - t2 = build_function_type (TREE_TYPE (t2), - TREE_CHAIN (TYPE_ARG_TYPES (t2))); - t3 = common_type (t1, t2); - t3 = build_cplus_method_type (basetype, TREE_TYPE (t3), - TYPE_ARG_TYPES (t3)); - t1 = build_exception_variant (t3, raises); - } - else - compiler_error ("common_type called with uncommon method types"); - - return build_type_attribute_variant (t1, attributes); - - case OFFSET_TYPE: - if (TREE_TYPE (t1) == TREE_TYPE (t2)) - { - tree b1 = TYPE_OFFSET_BASETYPE (t1); - tree b2 = TYPE_OFFSET_BASETYPE (t2); - - if (same_type_p (b1, b2) - || (DERIVED_FROM_P (b1, b2) && binfo_or_else (b1, b2))) - return build_type_attribute_variant (t2, attributes); - else if (binfo_or_else (b2, b1)) - return build_type_attribute_variant (t1, attributes); - } - compiler_error ("common_type called with uncommon member types"); - - default: - return build_type_attribute_variant (t1, attributes); - } -} - -/* Return 1 if TYPE1 and TYPE2 raise the same exceptions. */ - -int -compexcepttypes (t1, t2) - tree t1, t2; -{ - return TYPE_RAISES_EXCEPTIONS (t1) == TYPE_RAISES_EXCEPTIONS (t2); -} - -/* Compare the array types T1 and T2, using CMP as the type comparison - function for the element types. STRICT is as for comptypes. */ - -static int -comp_array_types (cmp, t1, t2, strict) - register int (*cmp) PROTO((tree, tree, int)); - tree t1, t2; - int strict; -{ - tree d1; - tree d2; - - if (t1 == t2) - return 1; - - /* The type of the array elements must be the same. */ - if (!(TREE_TYPE (t1) == TREE_TYPE (t2) - || (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), - strict & ~COMPARE_REDECLARATION))) - return 0; - - d1 = TYPE_DOMAIN (t1); - d2 = TYPE_DOMAIN (t2); - - if (d1 == d2) - return 1; - - /* If one of the arrays is dimensionless, and the other has a - dimension, they are of different types. However, it is legal to - write: - - extern int a[]; - int a[3]; - - by [basic.link]: - - declarations for an array object can specify - array types that differ by the presence or absence of a major - array bound (_dcl.array_). */ - if (!d1 || !d2) - return strict & COMPARE_REDECLARATION; - - /* Check that the dimensions are the same. */ - return (cp_tree_equal (TYPE_MIN_VALUE (d1), - TYPE_MIN_VALUE (d2)) - && cp_tree_equal (TYPE_MAX_VALUE (d1), - TYPE_MAX_VALUE (d2))); -} - -/* Return 1 if TYPE1 and TYPE2 are compatible types for assignment - or various other operations. STRICT is a bitwise-or of the - COMPARE_* flags. */ - -int -comptypes (type1, type2, strict) - tree type1, type2; - int strict; -{ - register tree t1 = type1; - register tree t2 = type2; - int attrval, val; - int orig_strict = strict; - - /* The special exemption for redeclaring array types without an - array bound only applies at the top level: - - extern int (*i)[]; - int (*i)[8]; - - is not legal, for example. */ - strict &= ~COMPARE_REDECLARATION; - - /* Suppress errors caused by previously reported errors */ - if (t1 == t2) - return 1; - - /* This should never happen. */ - my_friendly_assert (t1 != error_mark_node, 307); - - if (t2 == error_mark_node) - return 0; - - if (strict & COMPARE_RELAXED) - { - /* Treat an enum type as the unsigned integer type of the same width. */ - - if (TREE_CODE (t1) == ENUMERAL_TYPE) - t1 = type_for_size (TYPE_PRECISION (t1), 1); - if (TREE_CODE (t2) == ENUMERAL_TYPE) - t2 = type_for_size (TYPE_PRECISION (t2), 1); - - if (t1 == t2) - return 1; - } - - if (TYPE_PTRMEMFUNC_P (t1)) - t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1); - if (TYPE_PTRMEMFUNC_P (t2)) - t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2); - - /* Different classes of types can't be compatible. */ - if (TREE_CODE (t1) != TREE_CODE (t2)) - return 0; - - /* Qualifiers must match. */ - if (CP_TYPE_QUALS (t1) != CP_TYPE_QUALS (t2)) - return 0; - if (strict == COMPARE_STRICT - && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2)) - return 0; - - /* Allow for two different type nodes which have essentially the same - definition. Note that we already checked for equality of the type - qualifiers (just above). */ - - if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2)) - return 1; - - /* ??? COMP_TYPE_ATTRIBUTES is currently useless for variables as each - attribute is its own main variant (`val' will remain 0). */ -#ifndef COMP_TYPE_ATTRIBUTES -#define COMP_TYPE_ATTRIBUTES(t1,t2) 1 -#endif - - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - if (! (attrval = COMP_TYPE_ATTRIBUTES (t1, t2))) - return 0; - - /* 1 if no need for warning yet, 2 if warning cause has been seen. */ - val = 0; - - switch (TREE_CODE (t1)) - { - case TEMPLATE_TEMPLATE_PARM: - if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2) - || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2)) - return 0; - if (! comp_template_parms (DECL_TEMPLATE_PARMS (TYPE_NAME (t1)), - DECL_TEMPLATE_PARMS (TYPE_NAME (t2)))) - return 0; - if (!TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t1) - && ! TEMPLATE_TEMPLATE_PARM_TEMPLATE_INFO (t2)) - return 1; - /* Don't check inheritance. */ - strict = COMPARE_STRICT; - /* fall through */ - - case RECORD_TYPE: - case UNION_TYPE: - if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2) - && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2) - || TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)) - val = comp_template_args (TYPE_TI_ARGS (t1), - TYPE_TI_ARGS (t2)); - look_hard: - if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2)) - { - val = 1; - break; - } - if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1)) - { - val = 1; - break; - } - break; - - case OFFSET_TYPE: - val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)), - build_pointer_type (TYPE_OFFSET_BASETYPE (t2)), strict) - && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)); - break; - - case METHOD_TYPE: - if (! compexcepttypes (t1, t2)) - return 0; - - /* This case is anti-symmetrical! - One can pass a base member (or member function) - to something expecting a derived member (or member function), - but not vice-versa! */ - - val = (comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict) - && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))); - break; - - case POINTER_TYPE: - case REFERENCE_TYPE: - t1 = TREE_TYPE (t1); - t2 = TREE_TYPE (t2); - /* first, check whether the referred types match with the - required level of strictness */ - val = comptypes (t1, t2, strict); - if (val) - break; - if (TREE_CODE (t1) == RECORD_TYPE - && TREE_CODE (t2) == RECORD_TYPE) - goto look_hard; - break; - - case FUNCTION_TYPE: - if (! compexcepttypes (t1, t2)) - return 0; - - val = ((TREE_TYPE (t1) == TREE_TYPE (t2) - || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict)) - && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2))); - break; - - case ARRAY_TYPE: - /* Target types must match incl. qualifiers. We use ORIG_STRICT - here since this is the one place where - COMPARE_REDECLARATION should be used. */ - val = comp_array_types (comptypes, t1, t2, orig_strict); - break; - - case TEMPLATE_TYPE_PARM: - return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2) - && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2); - - case TYPENAME_TYPE: - if (TYPE_IDENTIFIER (t1) != TYPE_IDENTIFIER (t2)) - return 0; - return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2)); - - default: - break; - } - return attrval == 2 && val == 1 ? 2 : val; -} - -/* Subroutine of comp_target-types. Make sure that the cv-quals change - only in the same direction as the target type. */ - -static int -comp_cv_target_types (ttl, ttr, nptrs) - tree ttl, ttr; - int nptrs; -{ - int t; - - if (!at_least_as_qualified_p (ttl, ttr) - && !at_least_as_qualified_p (ttr, ttl)) - /* The qualifications are incomparable. */ - return 0; - - if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr)) - return more_qualified_p (ttr, ttl) ? -1 : 1; - - t = comp_target_types (ttl, ttr, nptrs); - if ((t == 1 && at_least_as_qualified_p (ttl, ttr)) - || (t == -1 && at_least_as_qualified_p (ttr, ttl))) - return t; - - return 0; -} - -/* Return 1 or -1 if TTL and TTR are pointers to types that are equivalent, - ignoring their qualifiers, 0 if not. Return 1 means that TTR can be - converted to TTL. Return -1 means that TTL can be converted to TTR but - not vice versa. - - NPTRS is the number of pointers we can strip off and keep cool. - This is used to permit (for aggr A, aggr B) A, B* to convert to A*, - but to not permit B** to convert to A**. - - This should go away. Callers should use can_convert or something - similar instead. (jason 17 Apr 1997) */ - -int -comp_target_types (ttl, ttr, nptrs) - tree ttl, ttr; - int nptrs; -{ - ttl = TYPE_MAIN_VARIANT (ttl); - ttr = TYPE_MAIN_VARIANT (ttr); - if (ttl == ttr) - return 1; - - if (TREE_CODE (ttr) != TREE_CODE (ttl)) - return 0; - - if ((TREE_CODE (ttr) == POINTER_TYPE - || TREE_CODE (ttr) == REFERENCE_TYPE) - /* If we get a pointer with nptrs == 0, we don't allow any tweaking - of the type pointed to. This is necessary for reference init - semantics. We won't get here from a previous call with nptrs == 1; - for multi-level pointers we end up in comp_ptr_ttypes. */ - && nptrs > 0) - { - int is_ptr = TREE_CODE (ttr) == POINTER_TYPE; - - ttl = TREE_TYPE (ttl); - ttr = TREE_TYPE (ttr); - - if (is_ptr) - { - if (TREE_CODE (ttl) == UNKNOWN_TYPE - || TREE_CODE (ttr) == UNKNOWN_TYPE) - return 1; - else if (TREE_CODE (ttl) == VOID_TYPE - && TREE_CODE (ttr) != FUNCTION_TYPE - && TREE_CODE (ttr) != METHOD_TYPE - && TREE_CODE (ttr) != OFFSET_TYPE) - return 1; - else if (TREE_CODE (ttr) == VOID_TYPE - && TREE_CODE (ttl) != FUNCTION_TYPE - && TREE_CODE (ttl) != METHOD_TYPE - && TREE_CODE (ttl) != OFFSET_TYPE) - return -1; - else if (TREE_CODE (ttl) == POINTER_TYPE - || TREE_CODE (ttl) == ARRAY_TYPE) - { - if (comp_ptr_ttypes (ttl, ttr)) - return 1; - else if (comp_ptr_ttypes (ttr, ttl)) - return -1; - return 0; - } - } - - /* Const and volatile mean something different for function types, - so the usual checks are not appropriate. */ - if (TREE_CODE (ttl) == FUNCTION_TYPE || TREE_CODE (ttl) == METHOD_TYPE) - return comp_target_types (ttl, ttr, nptrs - 1); - - return comp_cv_target_types (ttl, ttr, nptrs - 1); - } - - if (TREE_CODE (ttr) == ARRAY_TYPE) - return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT); - else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE) - { - tree argsl, argsr; - int saw_contra = 0; - - if (pedantic) - { - if (!same_type_p (TREE_TYPE (ttl), TREE_TYPE (ttr))) - return 0; - } - else - { - switch (comp_target_types (TREE_TYPE (ttl), TREE_TYPE (ttr), -1)) - { - case 0: - return 0; - case -1: - saw_contra = 1; - } - } - - argsl = TYPE_ARG_TYPES (ttl); - argsr = TYPE_ARG_TYPES (ttr); - - /* Compare 'this' here, not in comp_target_parms. */ - if (TREE_CODE (ttr) == METHOD_TYPE) - { - tree tl = TYPE_METHOD_BASETYPE (ttl); - tree tr = TYPE_METHOD_BASETYPE (ttr); - - if (!same_or_base_type_p (tr, tl)) - { - if (same_or_base_type_p (tl, tr)) - saw_contra = 1; - else - return 0; - } - - argsl = TREE_CHAIN (argsl); - argsr = TREE_CHAIN (argsr); - } - - switch (comp_target_parms (argsl, argsr, 1)) - { - case 0: - return 0; - case -1: - saw_contra = 1; - } - - return saw_contra ? -1 : 1; - } - /* for C++ */ - else if (TREE_CODE (ttr) == OFFSET_TYPE) - { - int base; - - /* Contravariance: we can assign a pointer to base member to a pointer - to derived member. Note difference from simple pointer case, where - we can pass a pointer to derived to a pointer to base. */ - if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttr), - TYPE_OFFSET_BASETYPE (ttl))) - base = 1; - else if (same_or_base_type_p (TYPE_OFFSET_BASETYPE (ttl), - TYPE_OFFSET_BASETYPE (ttr))) - { - tree tmp = ttl; - ttl = ttr; - ttr = tmp; - base = -1; - } - else - return 0; - - ttl = TREE_TYPE (ttl); - ttr = TREE_TYPE (ttr); - - if (TREE_CODE (ttl) == POINTER_TYPE - || TREE_CODE (ttl) == ARRAY_TYPE) - { - if (comp_ptr_ttypes (ttl, ttr)) - return base; - return 0; - } - else - { - if (comp_cv_target_types (ttl, ttr, nptrs) == 1) - return base; - return 0; - } - } - else if (IS_AGGR_TYPE (ttl)) - { - if (nptrs < 0) - return 0; - if (same_or_base_type_p (build_pointer_type (ttl), - build_pointer_type (ttr))) - return 1; - if (same_or_base_type_p (build_pointer_type (ttr), - build_pointer_type (ttl))) - return -1; - return 0; - } - - return 0; -} - -/* Returns 1 if TYPE1 is at least as qualified as TYPE2. */ - -int -at_least_as_qualified_p (type1, type2) - tree type1; - tree type2; -{ - /* All qualifiers for TYPE2 must also appear in TYPE1. */ - return ((CP_TYPE_QUALS (type1) & CP_TYPE_QUALS (type2)) - == CP_TYPE_QUALS (type2)); -} - -/* Returns 1 if TYPE1 is more qualified than TYPE2. */ - -int -more_qualified_p (type1, type2) - tree type1; - tree type2; -{ - return (CP_TYPE_QUALS (type1) != CP_TYPE_QUALS (type2) - && at_least_as_qualified_p (type1, type2)); -} - -/* Returns 1 if TYPE1 is more cv-qualified than TYPE2, -1 if TYPE2 is - more cv-qualified that TYPE1, and 0 otherwise. */ - -int -comp_cv_qualification (type1, type2) - tree type1; - tree type2; -{ - if (CP_TYPE_QUALS (type1) == CP_TYPE_QUALS (type2)) - return 0; - - if (at_least_as_qualified_p (type1, type2)) - return 1; - - else if (at_least_as_qualified_p (type2, type1)) - return -1; - - return 0; -} - -/* Returns 1 if the cv-qualification signature of TYPE1 is a proper - subset of the cv-qualification signature of TYPE2, and the types - are similar. Returns -1 if the other way 'round, and 0 otherwise. */ - -int -comp_cv_qual_signature (type1, type2) - tree type1; - tree type2; -{ - if (comp_ptr_ttypes_real (type2, type1, -1)) - return 1; - else if (comp_ptr_ttypes_real (type1, type2, -1)) - return -1; - else - return 0; -} - -/* If two types share a common base type, return that basetype. - If there is not a unique most-derived base type, this function - returns ERROR_MARK_NODE. */ - -static tree -common_base_type (tt1, tt2) - tree tt1, tt2; -{ - tree best = NULL_TREE; - int i; - - /* If one is a baseclass of another, that's good enough. */ - if (UNIQUELY_DERIVED_FROM_P (tt1, tt2)) - return tt1; - if (UNIQUELY_DERIVED_FROM_P (tt2, tt1)) - return tt2; - - /* Otherwise, try to find a unique baseclass of TT1 - that is shared by TT2, and follow that down. */ - for (i = CLASSTYPE_N_BASECLASSES (tt1)-1; i >= 0; i--) - { - tree basetype = TYPE_BINFO_BASETYPE (tt1, i); - tree trial = common_base_type (basetype, tt2); - if (trial) - { - if (trial == error_mark_node) - return trial; - if (best == NULL_TREE) - best = trial; - else if (best != trial) - return error_mark_node; - } - } - - /* Same for TT2. */ - for (i = CLASSTYPE_N_BASECLASSES (tt2)-1; i >= 0; i--) - { - tree basetype = TYPE_BINFO_BASETYPE (tt2, i); - tree trial = common_base_type (tt1, basetype); - if (trial) - { - if (trial == error_mark_node) - return trial; - if (best == NULL_TREE) - best = trial; - else if (best != trial) - return error_mark_node; - } - } - return best; -} - -/* Subroutines of `comptypes'. */ - -/* Return 1 if two parameter type lists PARMS1 and PARMS2 - are equivalent in the sense that functions with those parameter types - can have equivalent types. - If either list is empty, we win. - Otherwise, the two lists must be equivalent, element by element. - - C++: See comment above about TYPE1, TYPE2. - - STRICT is no longer used. */ - -int -compparms (parms1, parms2) - tree parms1, parms2; -{ - register tree t1 = parms1, t2 = parms2; - - /* An unspecified parmlist matches any specified parmlist - whose argument types don't need default promotions. */ - - while (1) - { - if (t1 == 0 && t2 == 0) - return 1; - /* If one parmlist is shorter than the other, - they fail to match. */ - if (t1 == 0 || t2 == 0) - return 0; - if (!same_type_p (TREE_VALUE (t2), TREE_VALUE (t1))) - return 0; - - t1 = TREE_CHAIN (t1); - t2 = TREE_CHAIN (t2); - } -} - -/* This really wants return whether or not parameter type lists - would make their owning functions assignment compatible or not. - - The return value is like for comp_target_types. - - This should go away, possibly with the exception of the empty parmlist - conversion; there are no conversions between function types in C++. - (jason 17 Apr 1997) */ - -static int -comp_target_parms (parms1, parms2, strict) - tree parms1, parms2; - int strict; -{ - register tree t1 = parms1, t2 = parms2; - int warn_contravariance = 0; - - /* In C, an unspecified parmlist matches any specified parmlist - whose argument types don't need default promotions. This is not - true for C++, but let's do it anyway for unfixed headers. */ - - if (t1 == 0 && t2 != 0) - { - cp_pedwarn ("ANSI C++ prohibits conversion from `(%#T)' to `(...)'", - parms2); - return self_promoting_args_p (t2); - } - if (t2 == 0) - return self_promoting_args_p (t1); - - for (; t1 || t2; t1 = TREE_CHAIN (t1), t2 = TREE_CHAIN (t2)) - { - tree p1, p2; - - /* If one parmlist is shorter than the other, - they fail to match, unless STRICT is <= 0. */ - if (t1 == 0 || t2 == 0) - { - if (strict > 0) - return 0; - if (strict < 0) - return 1 + warn_contravariance; - return ((t1 && TREE_PURPOSE (t1)) + warn_contravariance); - } - p1 = TREE_VALUE (t1); - p2 = TREE_VALUE (t2); - if (same_type_p (p1, p2)) - continue; - - if (pedantic) - return 0; - - if ((TREE_CODE (p1) == POINTER_TYPE && TREE_CODE (p2) == POINTER_TYPE) - || (TREE_CODE (p1) == REFERENCE_TYPE - && TREE_CODE (p2) == REFERENCE_TYPE)) - { - if (strict <= 0 - && (TYPE_MAIN_VARIANT (TREE_TYPE (p1)) - == TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) - continue; - - /* The following is wrong for contravariance, - but many programs depend on it. */ - if (TREE_TYPE (p1) == void_type_node) - continue; - if (TREE_TYPE (p2) == void_type_node) - { - warn_contravariance = 1; - continue; - } - if (IS_AGGR_TYPE (TREE_TYPE (p1)) - && !same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (p1)), - TYPE_MAIN_VARIANT (TREE_TYPE (p2)))) - return 0; - } - /* Note backwards order due to contravariance. */ - if (comp_target_types (p2, p1, 1) <= 0) - { - if (comp_target_types (p1, p2, 1) > 0) - { - warn_contravariance = 1; - continue; - } - if (strict != 0) - return 0; - } - } - return warn_contravariance ? -1 : 1; -} - -/* Return 1 if PARMS specifies a fixed number of parameters - and none of their types is affected by default promotions. */ - -int -self_promoting_args_p (parms) - tree parms; -{ - register tree t; - for (t = parms; t; t = TREE_CHAIN (t)) - { - register tree type = TREE_VALUE (t); - - if (TREE_CHAIN (t) == 0 && type != void_type_node) - return 0; - - if (type == 0) - return 0; - - if (TYPE_MAIN_VARIANT (type) == float_type_node) - return 0; - - if (C_PROMOTING_INTEGER_TYPE_P (type)) - return 0; - } - return 1; -} - -/* Return an unsigned type the same as TYPE in other respects. - - C++: must make these work for type variants as well. */ - -tree -unsigned_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == signed_char_type_node || type1 == char_type_node) - return unsigned_char_type_node; - if (type1 == integer_type_node) - return unsigned_type_node; - if (type1 == short_integer_type_node) - return short_unsigned_type_node; - if (type1 == long_integer_type_node) - return long_unsigned_type_node; - if (type1 == long_long_integer_type_node) - return long_long_unsigned_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 - if (type1 == intTI_type_node) - return unsigned_intTI_type_node; -#endif - if (type1 == intDI_type_node) - return unsigned_intDI_type_node; - if (type1 == intSI_type_node) - return unsigned_intSI_type_node; - if (type1 == intHI_type_node) - return unsigned_intHI_type_node; - if (type1 == intQI_type_node) - return unsigned_intQI_type_node; - - return signed_or_unsigned_type (1, type); -} - -/* Return a signed type the same as TYPE in other respects. */ - -tree -signed_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - if (type1 == unsigned_char_type_node || type1 == char_type_node) - return signed_char_type_node; - if (type1 == unsigned_type_node) - return integer_type_node; - if (type1 == short_unsigned_type_node) - return short_integer_type_node; - if (type1 == long_unsigned_type_node) - return long_integer_type_node; - if (type1 == long_long_unsigned_type_node) - return long_long_integer_type_node; -#if HOST_BITS_PER_WIDE_INT >= 64 - if (type1 == unsigned_intTI_type_node) - return intTI_type_node; -#endif - if (type1 == unsigned_intDI_type_node) - return intDI_type_node; - if (type1 == unsigned_intSI_type_node) - return intSI_type_node; - if (type1 == unsigned_intHI_type_node) - return intHI_type_node; - if (type1 == unsigned_intQI_type_node) - return intQI_type_node; - - return signed_or_unsigned_type (0, type); -} - -/* Return a type the same as TYPE except unsigned or - signed according to UNSIGNEDP. */ - -tree -signed_or_unsigned_type (unsignedp, type) - int unsignedp; - tree type; -{ - if (! INTEGRAL_TYPE_P (type) - || TREE_UNSIGNED (type) == unsignedp) - return type; - - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - return type; -} - -/* Compute the value of the `sizeof' operator. */ - -tree -c_sizeof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (processing_template_decl) - return build_min (SIZEOF_EXPR, sizetype, type); - - if (code == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids taking the sizeof a function type"); - return size_int (1); - } - if (code == METHOD_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids taking the sizeof a method type"); - return size_int (1); - } - if (code == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids taking the sizeof a void type"); - return size_int (1); - } - if (code == ERROR_MARK) - return size_int (1); - - /* ARM $5.3.2: ``When applied to a reference, the result is the size of the - referenced object.'' */ - if (code == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* We couldn't find anything in the ARM or the draft standard that says, - one way or the other, if doing sizeof on something that doesn't have - an object associated with it is correct or incorrect. For example, if - you declare `struct S { char str[16]; };', and in your program do - a `sizeof (S::str)', should we flag that as an error or should we give - the size of it? Since it seems like a reasonable thing to do, we'll go - with giving the value. */ - if (code == OFFSET_TYPE) - type = TREE_TYPE (type); - - /* @@ This also produces an error for a signature ref. - In that case we should be able to do better. */ - if (IS_SIGNATURE (type)) - { - error ("`sizeof' applied to a signature type"); - return size_int (0); - } - - if (TYPE_SIZE (complete_type (type)) == 0) - { - cp_error ("`sizeof' applied to incomplete type `%T'", type); - return size_int (0); - } - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - /* size_binop does not put the constant in range, so do it now. */ - if (TREE_CODE (t) == INTEGER_CST && force_fit_type (t, 0)) - TREE_CONSTANT_OVERFLOW (t) = TREE_OVERFLOW (t) = 1; - return t; -} - -tree -expr_sizeof (e) - tree e; -{ - if (processing_template_decl) - return build_min (SIZEOF_EXPR, sizetype, e); - - if (TREE_CODE (e) == COMPONENT_REF - && DECL_C_BIT_FIELD (TREE_OPERAND (e, 1))) - error ("sizeof applied to a bit-field"); - /* ANSI says arrays and functions are converted inside comma. - But we can't really convert them in build_compound_expr - because that would break commas in lvalues. - So do the conversion here if operand was a comma. */ - if (TREE_CODE (e) == COMPOUND_EXPR - && (TREE_CODE (TREE_TYPE (e)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (e)) == FUNCTION_TYPE)) - e = default_conversion (e); - else if (is_overloaded_fn (e)) - { - pedwarn ("ANSI C++ forbids taking the sizeof a function type"); - return size_int (1); - } - - return c_sizeof (TREE_TYPE (e)); -} - -tree -c_sizeof_nowarn (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (code == FUNCTION_TYPE - || code == METHOD_TYPE - || code == VOID_TYPE - || code == ERROR_MARK) - return size_int (1); - if (code == REFERENCE_TYPE) - type = TREE_TYPE (type); - - if (TYPE_SIZE (type) == 0) - return size_int (0); - - /* Convert in case a char is more than one unit. */ - t = size_binop (CEIL_DIV_EXPR, TYPE_SIZE (type), - size_int (TYPE_PRECISION (char_type_node))); - t = convert (sizetype, t); - force_fit_type (t, 0); - return t; -} - -/* Implement the __alignof keyword: Return the minimum required - alignment of TYPE, measured in bytes. */ - -tree -c_alignof (type) - tree type; -{ - enum tree_code code = TREE_CODE (type); - tree t; - - if (processing_template_decl) - return build_min (ALIGNOF_EXPR, sizetype, type); - - if (code == FUNCTION_TYPE || code == METHOD_TYPE) - return size_int (FUNCTION_BOUNDARY / BITS_PER_UNIT); - - if (code == VOID_TYPE || code == ERROR_MARK) - return size_int (1); - - /* C++: this is really correct! */ - if (code == REFERENCE_TYPE) - type = TREE_TYPE (type); - - /* @@ This also produces an error for a signature ref. - In that case we should be able to do better. */ - if (IS_SIGNATURE (type)) - { - error ("`__alignof' applied to a signature type"); - return size_int (1); - } - - t = size_int (TYPE_ALIGN (type) / BITS_PER_UNIT); - force_fit_type (t, 0); - return t; -} - -/* Perform default promotions for C data used in expressions. - Arrays and functions are converted to pointers; - enumeral types or short or char, to int. - In addition, manifest constants symbols are replaced by their values. - - C++: this will automatically bash references to their target type. */ - -tree -decay_conversion (exp) - tree exp; -{ - register tree type = TREE_TYPE (exp); - register enum tree_code code = TREE_CODE (type); - - if (code == OFFSET_TYPE) - { - if (TREE_CODE (exp) == OFFSET_REF) - return decay_conversion (resolve_offset_ref (exp)); - - type = TREE_TYPE (type); - code = TREE_CODE (type); - - if (type == unknown_type_node) - { - cp_pedwarn ("assuming & on overloaded member function"); - return build_unary_op (ADDR_EXPR, exp, 0); - } - } - - if (code == REFERENCE_TYPE) - { - exp = convert_from_reference (exp); - type = TREE_TYPE (exp); - code = TREE_CODE (type); - } - - /* Constants can be used directly unless they're not loadable. */ - if (TREE_CODE (exp) == CONST_DECL) - exp = DECL_INITIAL (exp); - /* Replace a nonvolatile const static variable with its value. */ - else if (TREE_READONLY_DECL_P (exp)) - { - exp = decl_constant_value (exp); - type = TREE_TYPE (exp); - } - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */ - - if (code == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - if (code == METHOD_TYPE) - { - cp_pedwarn ("assuming & on `%E'", exp); - return build_unary_op (ADDR_EXPR, exp, 0); - } - if (code == FUNCTION_TYPE || is_overloaded_fn (exp)) - { - return build_unary_op (ADDR_EXPR, exp, 0); - } - if (code == ARRAY_TYPE) - { - register tree adr; - tree ptrtype; - - if (TREE_CODE (exp) == INDIRECT_REF) - { - /* Stripping away the INDIRECT_REF is not the right - thing to do for references... */ - tree inner = TREE_OPERAND (exp, 0); - if (TREE_CODE (TREE_TYPE (inner)) == REFERENCE_TYPE) - { - inner = build1 (CONVERT_EXPR, - build_pointer_type (TREE_TYPE - (TREE_TYPE (inner))), - inner); - TREE_CONSTANT (inner) = TREE_CONSTANT (TREE_OPERAND (inner, 0)); - } - return cp_convert (build_pointer_type (TREE_TYPE (type)), inner); - } - - if (TREE_CODE (exp) == COMPOUND_EXPR) - { - tree op1 = decay_conversion (TREE_OPERAND (exp, 1)); - return build (COMPOUND_EXPR, TREE_TYPE (op1), - TREE_OPERAND (exp, 0), op1); - } - - if (!lvalue_p (exp) - && ! (TREE_CODE (exp) == CONSTRUCTOR && TREE_STATIC (exp))) - { - error ("invalid use of non-lvalue array"); - return error_mark_node; - } - - ptrtype = build_pointer_type (TREE_TYPE (type)); - - if (TREE_CODE (exp) == VAR_DECL) - { - /* ??? This is not really quite correct - in that the type of the operand of ADDR_EXPR - is not the target type of the type of the ADDR_EXPR itself. - Question is, can this lossage be avoided? */ - adr = build1 (ADDR_EXPR, ptrtype, exp); - if (mark_addressable (exp) == 0) - return error_mark_node; - TREE_CONSTANT (adr) = staticp (exp); - TREE_SIDE_EFFECTS (adr) = 0; /* Default would be, same as EXP. */ - return adr; - } - /* This way is better for a COMPONENT_REF since it can - simplify the offset for a component. */ - adr = build_unary_op (ADDR_EXPR, exp, 1); - return cp_convert (ptrtype, adr); - } - - return exp; -} - -tree -default_conversion (exp) - tree exp; -{ - tree type; - enum tree_code code; - - exp = decay_conversion (exp); - - type = TREE_TYPE (exp); - code = TREE_CODE (type); - - if (INTEGRAL_CODE_P (code)) - { - tree t = type_promotes_to (type); - if (t != type) - return cp_convert (t, exp); - } - - return exp; -} - -/* Take the address of an inline function without setting TREE_ADDRESSABLE - or TREE_USED. */ - -tree -inline_conversion (exp) - tree exp; -{ - if (TREE_CODE (exp) == FUNCTION_DECL) - exp = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (exp)), exp); - - return exp; -} - -/* Returns nonzero iff exp is a STRING_CST or the result of applying - decay_conversion to one. */ - -int -string_conv_p (totype, exp, warn) - tree totype, exp; - int warn; -{ - tree t; - - if (! flag_const_strings || TREE_CODE (totype) != POINTER_TYPE) - return 0; - - t = TREE_TYPE (totype); - if (!same_type_p (t, char_type_node) - && !same_type_p (t, wchar_type_node)) - return 0; - - if (TREE_CODE (exp) == STRING_CST) - { - /* Make sure that we don't try to convert between char and wchar_t. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (exp))) != t) - return 0; - } - else - { - /* Is this a string constant which has decayed to 'const char *'? */ - t = build_pointer_type (build_qualified_type (t, TYPE_QUAL_CONST)); - if (!same_type_p (TREE_TYPE (exp), t)) - return 0; - STRIP_NOPS (exp); - if (TREE_CODE (exp) != ADDR_EXPR - || TREE_CODE (TREE_OPERAND (exp, 0)) != STRING_CST) - return 0; - } - - /* This warning is not very useful, as it complains about printf. */ - if (warn && warn_write_strings) - cp_warning ("deprecated conversion from string constant to `%T'", totype); - - return 1; -} - -tree -build_object_ref (datum, basetype, field) - tree datum, basetype, field; -{ - tree dtype; - if (datum == error_mark_node) - return error_mark_node; - - dtype = TREE_TYPE (datum); - if (TREE_CODE (dtype) == REFERENCE_TYPE) - dtype = TREE_TYPE (dtype); - if (! IS_AGGR_TYPE_CODE (TREE_CODE (dtype))) - { - cp_error ("request for member `%T::%D' in expression of non-aggregate type `%T'", - basetype, field, dtype); - return error_mark_node; - } - else if (IS_SIGNATURE (basetype)) - { - warning ("signature name in scope resolution ignored"); - return build_component_ref (datum, field, NULL_TREE, 1); - } - else if (is_aggr_type (basetype, 1)) - { - tree binfo = binfo_or_else (basetype, dtype); - if (binfo) - return build_x_component_ref (build_scoped_ref (datum, basetype), - field, binfo, 1); - } - return error_mark_node; -} - -/* Like `build_component_ref, but uses an already found field, and converts - from a reference. Must compute access for current_class_ref. - Otherwise, ok. */ - -tree -build_component_ref_1 (datum, field, protect) - tree datum, field; - int protect; -{ - return convert_from_reference - (build_component_ref (datum, field, NULL_TREE, protect)); -} - -/* Given a COND_EXPR, MIN_EXPR, or MAX_EXPR in T, return it in a form that we - can, for example, use as an lvalue. This code used to be in - unary_complex_lvalue, but we needed it to deal with `a = (d == c) ? b : c' - expressions, where we're dealing with aggregates. But now it's again only - called from unary_complex_lvalue. The case (in particular) that led to - this was with CODE == ADDR_EXPR, since it's not an lvalue when we'd - get it there. */ - -static tree -rationalize_conditional_expr (code, t) - enum tree_code code; - tree t; -{ - /* For MIN_EXPR or MAX_EXPR, fold-const.c has arranged things so that - the first operand is always the one to be used if both operands - are equal, so we know what conditional expression this used to be. */ - if (TREE_CODE (t) == MIN_EXPR || TREE_CODE (t) == MAX_EXPR) - { - return - build_conditional_expr (build_x_binary_op ((TREE_CODE (t) == MIN_EXPR - ? LE_EXPR : GE_EXPR), - TREE_OPERAND (t, 0), - TREE_OPERAND (t, 1)), - build_unary_op (code, TREE_OPERAND (t, 0), 0), - build_unary_op (code, TREE_OPERAND (t, 1), 0)); - } - - return - build_conditional_expr (TREE_OPERAND (t, 0), - build_unary_op (code, TREE_OPERAND (t, 1), 0), - build_unary_op (code, TREE_OPERAND (t, 2), 0)); -} - -/* Given the TYPE of an anonymous union field inside T, return the - FIELD_DECL for the field. If not found return NULL_TREE. Because - anonymous unions can nest, we must also search all anonymous unions - that are directly reachable. */ - -static tree -lookup_anon_field (t, type) - tree t, type; -{ - tree field; - - for (field = TYPE_FIELDS (t); field; field = TREE_CHAIN (field)) - { - if (TREE_STATIC (field)) - continue; - if (TREE_CODE (field) != FIELD_DECL) - continue; - - /* If we find it directly, return the field. */ - if (DECL_NAME (field) == NULL_TREE - && type == TREE_TYPE (field)) - { - return field; - } - - /* Otherwise, it could be nested, search harder. */ - if (DECL_NAME (field) == NULL_TREE - && TREE_CODE (TREE_TYPE (field)) == UNION_TYPE) - { - tree subfield = lookup_anon_field (TREE_TYPE (field), type); - if (subfield) - return subfield; - } - } - return NULL_TREE; -} - -/* Build a COMPONENT_REF for a given DATUM, and it's member COMPONENT. - COMPONENT can be an IDENTIFIER_NODE that is the name of the member - that we are interested in, or it can be a FIELD_DECL. */ - -tree -build_component_ref (datum, component, basetype_path, protect) - tree datum, component, basetype_path; - int protect; -{ - register tree basetype; - register enum tree_code code; - register tree field = NULL; - register tree ref; - tree field_type; - int type_quals; - - if (processing_template_decl) - return build_min_nt (COMPONENT_REF, datum, component); - - if (datum == error_mark_node - || TREE_TYPE (datum) == error_mark_node) - return error_mark_node; - - /* BASETYPE holds the type of the class containing the COMPONENT. */ - basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum)); - - /* If DATUM is a COMPOUND_EXPR or COND_EXPR, move our reference - inside it. */ - switch (TREE_CODE (datum)) - { - case COMPOUND_EXPR: - { - tree value = build_component_ref (TREE_OPERAND (datum, 1), component, - basetype_path, protect); - return build (COMPOUND_EXPR, TREE_TYPE (value), - TREE_OPERAND (datum, 0), value); - } - case COND_EXPR: - return build_conditional_expr - (TREE_OPERAND (datum, 0), - build_component_ref (TREE_OPERAND (datum, 1), component, - basetype_path, protect), - build_component_ref (TREE_OPERAND (datum, 2), component, - basetype_path, protect)); - - case TEMPLATE_DECL: - cp_error ("invalid use of %D", datum); - datum = error_mark_node; - break; - - default: - break; - } - - code = TREE_CODE (basetype); - - if (code == REFERENCE_TYPE) - { - datum = convert_from_reference (datum); - basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum)); - code = TREE_CODE (basetype); - } - if (TREE_CODE (datum) == OFFSET_REF) - { - datum = resolve_offset_ref (datum); - basetype = TYPE_MAIN_VARIANT (TREE_TYPE (datum)); - code = TREE_CODE (basetype); - } - - /* First, see if there is a field or component with name COMPONENT. */ - if (TREE_CODE (component) == TREE_LIST) - { - /* I could not trigger this code. MvL */ - my_friendly_abort (980326); -#ifdef DEAD - my_friendly_assert (!(TREE_CHAIN (component) == NULL_TREE - && DECL_CHAIN (TREE_VALUE (component)) == NULL_TREE), 309); -#endif - return build (COMPONENT_REF, TREE_TYPE (component), datum, component); - } - - if (! IS_AGGR_TYPE_CODE (code)) - { - if (code != ERROR_MARK) - cp_error ("request for member `%D' in `%E', which is of non-aggregate type `%T'", - component, datum, basetype); - return error_mark_node; - } - - if (!complete_type_or_else (basetype)) - return error_mark_node; - - if (TREE_CODE (component) == BIT_NOT_EXPR) - { - if (TYPE_IDENTIFIER (basetype) != TREE_OPERAND (component, 0)) - { - cp_error ("destructor specifier `%T::~%T' must have matching names", - basetype, TREE_OPERAND (component, 0)); - return error_mark_node; - } - if (! TYPE_HAS_DESTRUCTOR (basetype)) - { - cp_error ("type `%T' has no destructor", basetype); - return error_mark_node; - } - return TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (basetype), 1); - } - - /* Look up component name in the structure type definition. */ - if (CLASSTYPE_VFIELD (basetype) - && DECL_NAME (CLASSTYPE_VFIELD (basetype)) == component) - /* Special-case this because if we use normal lookups in an ambiguous - hierarchy, the compiler will abort (because vptr lookups are - not supposed to be ambiguous. */ - field = CLASSTYPE_VFIELD (basetype); - else if (TREE_CODE (component) == FIELD_DECL) - field = component; - else if (TREE_CODE (component) == TYPE_DECL) - { - cp_error ("invalid use of type decl `%#D' as expression", component); - return error_mark_node; - } - else - { - tree name = component; - if (TREE_CODE (component) == VAR_DECL) - name = DECL_NAME (component); - if (basetype_path == NULL_TREE) - basetype_path = TYPE_BINFO (basetype); - field = lookup_field (basetype_path, name, - protect && !VFIELD_NAME_P (name), 0); - if (field == error_mark_node) - return error_mark_node; - - if (field == NULL_TREE) - { - /* Not found as a data field, look for it as a method. If found, - then if this is the only possible one, return it, else - report ambiguity error. */ - tree fndecls = lookup_fnfields (basetype_path, name, 1); - if (fndecls == error_mark_node) - return error_mark_node; - if (fndecls) - { - /* If the function is unique and static, we can resolve it - now. Otherwise, we have to wait and see what context it is - used in; a component_ref involving a non-static member - function can only be used in a call (expr.ref). */ - - if (TREE_CHAIN (fndecls) == NULL_TREE - && TREE_CODE (TREE_VALUE (fndecls)) == FUNCTION_DECL) - { - if (DECL_STATIC_FUNCTION_P (TREE_VALUE (fndecls))) - { - tree fndecl = TREE_VALUE (fndecls); - enforce_access (TREE_PURPOSE (fndecls), fndecl); - mark_used (fndecl); - return fndecl; - } - else - { - /* A unique non-static member function. Other parts - of the compiler expect something with - unknown_type_node to be really overloaded, so - let's oblige. */ - TREE_VALUE (fndecls) - = scratch_ovl_cons (TREE_VALUE (fndecls), NULL_TREE); - } - } - - ref = build (COMPONENT_REF, unknown_type_node, - datum, fndecls); - return ref; - } - - cp_error ("`%#T' has no member named `%D'", basetype, name); - return error_mark_node; - } - else if (TREE_TYPE (field) == error_mark_node) - return error_mark_node; - - if (TREE_CODE (field) != FIELD_DECL) - { - if (TREE_CODE (field) == TYPE_DECL) - cp_pedwarn ("invalid use of type decl `%#D' as expression", field); - else if (DECL_RTL (field) != 0) - mark_used (field); - else - TREE_USED (field) = 1; - return field; - } - } - - /* See if we have to do any conversions so that we pick up the field from the - right context. */ - if (DECL_FIELD_CONTEXT (field) != basetype) - { - tree context = DECL_FIELD_CONTEXT (field); - tree base = context; - while (!same_type_p (base, basetype) && TYPE_NAME (base) - && ANON_UNION_TYPE_P (base)) - { - base = TYPE_CONTEXT (base); - } - - /* Handle base classes here... */ - if (base != basetype && TYPE_USES_COMPLEX_INHERITANCE (basetype)) - { - tree addr = build_unary_op (ADDR_EXPR, datum, 0); - if (integer_zerop (addr)) - { - error ("invalid reference to NULL ptr, use ptr-to-member instead"); - return error_mark_node; - } - if (VBASE_NAME_P (DECL_NAME (field))) - { - /* It doesn't matter which vbase pointer we grab, just - find one of them. */ - tree binfo = get_binfo (base, - TREE_TYPE (TREE_TYPE (addr)), 0); - addr = convert_pointer_to_real (binfo, addr); - } - else - addr = convert_pointer_to (base, addr); - datum = build_indirect_ref (addr, NULL_PTR); - my_friendly_assert (datum != error_mark_node, 311); - } - basetype = base; - - /* Handle things from anon unions here... */ - if (TYPE_NAME (context) && ANON_UNION_TYPE_P (context)) - { - tree subfield = lookup_anon_field (basetype, context); - tree subdatum = build_component_ref (datum, subfield, - basetype_path, protect); - return build_component_ref (subdatum, field, basetype_path, protect); - } - } - - /* Compute the type of the field, as described in [expr.ref]. */ - type_quals = TYPE_UNQUALIFIED; - field_type = TREE_TYPE (field); - if (TREE_CODE (field_type) == REFERENCE_TYPE) - /* The standard says that the type of the result should be the - type referred to by the reference. But for now, at least, we - do the conversion from reference type later. */ - ; - else - { - type_quals = (CP_TYPE_QUALS (field_type) - | CP_TYPE_QUALS (TREE_TYPE (datum))); - - /* A field is const (volatile) if the enclosing object, or the - field itself, is const (volatile). But, a mutable field is - not const, even within a const object. */ - if (DECL_LANG_SPECIFIC (field) && DECL_MUTABLE_P (field)) - type_quals &= ~TYPE_QUAL_CONST; - if (!IS_SIGNATURE (field_type)) - field_type = cp_build_qualified_type (field_type, type_quals); - } - - ref = fold (build (COMPONENT_REF, field_type, - break_out_cleanups (datum), field)); - - /* Mark the expression const or volatile, as appropriate. Even - though we've dealt with the type above, we still have to mark the - expression itself. */ - if (type_quals & TYPE_QUAL_CONST) - TREE_READONLY (ref) = 1; - else if (type_quals & TYPE_QUAL_VOLATILE) - TREE_THIS_VOLATILE (ref) = 1; - - return ref; -} - -/* Variant of build_component_ref for use in expressions, which should - never have REFERENCE_TYPE. */ - -tree -build_x_component_ref (datum, component, basetype_path, protect) - tree datum, component, basetype_path; - int protect; -{ - tree t = build_component_ref (datum, component, basetype_path, protect); - - if (! processing_template_decl) - t = convert_from_reference (t); - - return t; -} - -/* Given an expression PTR for a pointer, return an expression - for the value pointed to. - ERRORSTRING is the name of the operator to appear in error messages. - - This function may need to overload OPERATOR_FNNAME. - Must also handle REFERENCE_TYPEs for C++. */ - -tree -build_x_indirect_ref (ptr, errorstring) - tree ptr; - char *errorstring; -{ - tree rval; - - if (processing_template_decl) - return build_min_nt (INDIRECT_REF, ptr); - - rval = build_opfncall (INDIRECT_REF, LOOKUP_NORMAL, ptr, NULL_TREE, - NULL_TREE); - if (rval) - return rval; - return build_indirect_ref (ptr, errorstring); -} - -tree -build_indirect_ref (ptr, errorstring) - tree ptr; - char *errorstring; -{ - register tree pointer, type; - - if (ptr == error_mark_node) - return error_mark_node; - - pointer = (TREE_CODE (TREE_TYPE (ptr)) == REFERENCE_TYPE - ? ptr : default_conversion (ptr)); - type = TREE_TYPE (pointer); - - if (ptr == current_class_ptr) - return current_class_ref; - - if (TYPE_PTR_P (type) || TREE_CODE (type) == REFERENCE_TYPE) - { - /* [expr.unary.op] - - If the type of the expression is "pointer to T," the type - of the result is "T." - - We must use the canonical variant because certain parts of - the back end, like fold, do pointer comparisons between - types. */ - tree t = canonical_type_variant (TREE_TYPE (type)); - - if (TREE_CODE (pointer) == ADDR_EXPR - && !flag_volatile - && same_type_p (t, TREE_TYPE (TREE_OPERAND (pointer, 0)))) - /* The POINTER was something like `&x'. We simplify `*&x' to - `x'. */ - return TREE_OPERAND (pointer, 0); - else - { - tree ref = build1 (INDIRECT_REF, t, pointer); - - /* We *must* set TREE_READONLY when dereferencing a pointer to const, - so that we get the proper error message if the result is used - to assign to. Also, &* is supposed to be a no-op. */ - TREE_READONLY (ref) = CP_TYPE_CONST_P (t); - TREE_THIS_VOLATILE (ref) = CP_TYPE_VOLATILE_P (t); - TREE_SIDE_EFFECTS (ref) - = (TREE_THIS_VOLATILE (ref) || TREE_SIDE_EFFECTS (pointer) - || flag_volatile); - return ref; - } - } - /* `pointer' won't be an error_mark_node if we were given a - pointer to member, so it's cool to check for this here. */ - else if (TYPE_PTRMEM_P (type) || TYPE_PTRMEMFUNC_P (type)) - error ("invalid use of `%s' on pointer to member", errorstring); - else if (TREE_CODE (type) == RECORD_TYPE - && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))) - error ("cannot dereference signature pointer/reference"); - else if (pointer != error_mark_node) - { - if (errorstring) - error ("invalid type argument of `%s'", errorstring); - else - error ("invalid type argument"); - } - return error_mark_node; -} - -/* This handles expressions of the form "a[i]", which denotes - an array reference. - - This is logically equivalent in C to *(a+i), but we may do it differently. - If A is a variable or a member, we generate a primitive ARRAY_REF. - This avoids forcing the array out of registers, and can work on - arrays that are not lvalues (for example, members of structures returned - by functions). - - If INDEX is of some user-defined type, it must be converted to - integer type. Otherwise, to make a compatible PLUS_EXPR, it - will inherit the type of the array, which will be some pointer type. */ - -tree -build_array_ref (array, idx) - tree array, idx; -{ - if (idx == 0) - { - error ("subscript missing in array reference"); - return error_mark_node; - } - - if (TREE_TYPE (array) == error_mark_node - || TREE_TYPE (idx) == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (array)) == ARRAY_TYPE - && TREE_CODE (array) != INDIRECT_REF) - { - tree rval, type; - - /* Subscripting with type char is likely to lose - on a machine where chars are signed. - So warn on any machine, but optionally. - Don't warn for unsigned char since that type is safe. - Don't warn for signed char because anyone who uses that - must have done so deliberately. */ - if (warn_char_subscripts - && TYPE_MAIN_VARIANT (TREE_TYPE (idx)) == char_type_node) - warning ("array subscript has type `char'"); - - /* Apply default promotions *after* noticing character types. */ - idx = default_conversion (idx); - - if (TREE_CODE (TREE_TYPE (idx)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - /* An array that is indexed by a non-constant - cannot be stored in a register; we must be able to do - address arithmetic on its address. - Likewise an array of elements of variable size. */ - if (TREE_CODE (idx) != INTEGER_CST - || (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))) != 0 - && (TREE_CODE (TYPE_SIZE (TREE_TYPE (TREE_TYPE (array)))) - != INTEGER_CST))) - { - if (mark_addressable (array) == 0) - return error_mark_node; - } - /* An array that is indexed by a constant value which is not within - the array bounds cannot be stored in a register either; because we - would get a crash in store_bit_field/extract_bit_field when trying - to access a non-existent part of the register. */ - if (TREE_CODE (idx) == INTEGER_CST - && TYPE_VALUES (TREE_TYPE (array)) - && ! int_fits_type_p (idx, TYPE_VALUES (TREE_TYPE (array)))) - { - if (mark_addressable (array) == 0) - return error_mark_node; - } - - if (pedantic && !lvalue_p (array)) - pedwarn ("ANSI C++ forbids subscripting non-lvalue array"); - - /* Note in C++ it is valid to subscript a `register' array, since - it is valid to take the address of something with that - storage specification. */ - if (extra_warnings) - { - tree foo = array; - while (TREE_CODE (foo) == COMPONENT_REF) - foo = TREE_OPERAND (foo, 0); - if (TREE_CODE (foo) == VAR_DECL && DECL_REGISTER (foo)) - warning ("subscripting array declared `register'"); - } - - type = TREE_TYPE (TREE_TYPE (array)); - rval = build (ARRAY_REF, type, array, idx); - /* Array ref is const/volatile if the array elements are - or if the array is.. */ - TREE_READONLY (rval) - |= (CP_TYPE_CONST_P (type) | TREE_READONLY (array)); - TREE_SIDE_EFFECTS (rval) - |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array)); - TREE_THIS_VOLATILE (rval) - |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array)); - return require_complete_type (fold (rval)); - } - - { - tree ar = default_conversion (array); - tree ind = default_conversion (idx); - - /* Put the integer in IND to simplify error checking. */ - if (TREE_CODE (TREE_TYPE (ar)) == INTEGER_TYPE) - { - tree temp = ar; - ar = ind; - ind = temp; - } - - if (ar == error_mark_node) - return ar; - - if (TREE_CODE (TREE_TYPE (ar)) != POINTER_TYPE) - { - error ("subscripted value is neither array nor pointer"); - return error_mark_node; - } - if (TREE_CODE (TREE_TYPE (ind)) != INTEGER_TYPE) - { - error ("array subscript is not an integer"); - return error_mark_node; - } - - return build_indirect_ref (build_binary_op_nodefault (PLUS_EXPR, ar, - ind, PLUS_EXPR), - "array indexing"); - } -} - -/* Build a function call to function FUNCTION with parameters PARAMS. - PARAMS is a list--a chain of TREE_LIST nodes--in which the - TREE_VALUE of each node is a parameter-expression. The PARAMS do - not include any object pointer that may be required. FUNCTION's - data type may be a function type or a pointer-to-function. - - For C++: If FUNCTION's data type is a TREE_LIST, then the tree list - is the list of possible methods that FUNCTION could conceivably - be. If the list of methods comes from a class, then it will be - a list of lists (where each element is associated with the class - that produced it), otherwise it will be a simple list (for - functions overloaded in global scope). - - In the first case, TREE_VALUE (function) is the head of one of those - lists, and TREE_PURPOSE is the name of the function. - - In the second case, TREE_PURPOSE (function) is the function's - name directly. - - DECL is the class instance variable, usually CURRENT_CLASS_REF. - - When calling a TEMPLATE_DECL, we don't require a complete return - type. */ - -tree -build_x_function_call (function, params, decl) - tree function, params, decl; -{ - tree type; - tree template_id = NULL_TREE; - int is_method; - - if (function == error_mark_node) - return error_mark_node; - - if (processing_template_decl) - return build_min_nt (CALL_EXPR, function, params, NULL_TREE); - - /* Save explicit template arguments if found */ - if (TREE_CODE (function) == TEMPLATE_ID_EXPR) - { - template_id = function; - function = TREE_OPERAND (function, 0); - } - - type = TREE_TYPE (function); - - if (TREE_CODE (type) == OFFSET_TYPE - && TREE_TYPE (type) == unknown_type_node - && TREE_CODE (function) == TREE_LIST - && TREE_CHAIN (function) == NULL_TREE) - { - /* Undo (Foo:bar)()... */ - type = TYPE_OFFSET_BASETYPE (type); - function = TREE_VALUE (function); - my_friendly_assert (TREE_CODE (function) == TREE_LIST, 999); - my_friendly_assert (TREE_CHAIN (function) == NULL_TREE, 999); - function = TREE_VALUE (function); - if (TREE_CODE (function) == OVERLOAD) - function = OVL_FUNCTION (function); - my_friendly_assert (TREE_CODE (function) == FUNCTION_DECL, 999); - function = DECL_NAME (function); - return build_method_call (decl, function, params, - TYPE_BINFO (type), LOOKUP_NORMAL); - } - - is_method = ((TREE_CODE (function) == TREE_LIST - && current_class_type != NULL_TREE - && (IDENTIFIER_CLASS_VALUE (TREE_PURPOSE (function)) - == function)) - || TREE_CODE (function) == IDENTIFIER_NODE - || TREE_CODE (type) == METHOD_TYPE - || TYPE_PTRMEMFUNC_P (type)); - - if ((TREE_CODE (function) == FUNCTION_DECL - && DECL_STATIC_FUNCTION_P (function)) - || (TREE_CODE (function) == TEMPLATE_DECL - && DECL_STATIC_FUNCTION_P (DECL_RESULT (function)))) - return build_member_call - (DECL_CONTEXT (function), DECL_NAME (function), params); - - /* A friend template. Make it look like a toplevel declaration. */ - if (! is_method && TREE_CODE (function) == TEMPLATE_DECL) - function = scratch_ovl_cons (function, NULL_TREE); - - /* Handle methods, friends, and overloaded functions, respectively. */ - if (is_method) - { - tree basetype = NULL_TREE; - - if (TREE_CODE (function) == FUNCTION_DECL - || DECL_FUNCTION_TEMPLATE_P (function)) - { - basetype = DECL_CLASS_CONTEXT (function); - - if (DECL_NAME (function)) - function = DECL_NAME (function); - else - function = TYPE_IDENTIFIER (DECL_CLASS_CONTEXT (function)); - } - else if (TREE_CODE (function) == TREE_LIST) - { - my_friendly_assert (TREE_CODE (TREE_VALUE (function)) - == FUNCTION_DECL, 312); - basetype = DECL_CLASS_CONTEXT (TREE_VALUE (function)); - function = TREE_PURPOSE (function); - } - else if (TREE_CODE (function) != IDENTIFIER_NODE) - { - if (TREE_CODE (function) == OFFSET_REF) - { - if (TREE_OPERAND (function, 0)) - decl = TREE_OPERAND (function, 0); - } - /* Call via a pointer to member function. */ - if (decl == NULL_TREE) - { - error ("pointer to member function called, but not in class scope"); - return error_mark_node; - } - /* What other type of POINTER_TYPE could this be? */ - if (TREE_CODE (TREE_TYPE (function)) != POINTER_TYPE - && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (function)) - && TREE_CODE (function) != OFFSET_REF) - function = build (OFFSET_REF, TREE_TYPE (type), NULL_TREE, - function); - goto do_x_function; - } - - /* this is an abbreviated method call. - must go through here in case it is a virtual function. - @@ Perhaps this could be optimized. */ - - if (basetype && (! current_class_type - || ! DERIVED_FROM_P (basetype, current_class_type))) - return build_member_call (basetype, function, params); - - if (decl == NULL_TREE) - { - if (current_class_type == NULL_TREE) - { - error ("object missing in call to method `%s'", - IDENTIFIER_POINTER (function)); - return error_mark_node; - } - /* Yow: call from a static member function. */ - decl = build_dummy_object (current_class_type); - } - - /* Put back explicit template arguments, if any. */ - if (template_id) - function = template_id; - return build_method_call (decl, function, params, - NULL_TREE, LOOKUP_NORMAL); - } - else if (TREE_CODE (function) == COMPONENT_REF - && type == unknown_type_node) - { - /* Undo what we did in build_component_ref. */ - decl = TREE_OPERAND (function, 0); - function = TREE_OPERAND (function, 1); - function = DECL_NAME (OVL_CURRENT (TREE_VALUE (function))); - return build_method_call (decl, function, params, - NULL_TREE, LOOKUP_NORMAL); - } - else if (really_overloaded_fn (function)) - { - if (OVL_FUNCTION (function) == NULL_TREE) - { - cp_error ("function `%D' declared overloaded, but no definitions appear with which to resolve it?!?", - TREE_PURPOSE (function)); - return error_mark_node; - } - else - { - /* Put back explicit template arguments, if any. */ - if (template_id) - function = template_id; - return build_new_function_call (function, params); - } - } - else - /* Remove a potential OVERLOAD around it */ - function = OVL_CURRENT (function); - - do_x_function: - if (TREE_CODE (function) == OFFSET_REF) - { - /* If the component is a data element (or a virtual function), we play - games here to make things work. */ - tree decl_addr; - - if (TREE_OPERAND (function, 0)) - decl = TREE_OPERAND (function, 0); - else - decl = current_class_ref; - - decl_addr = build_unary_op (ADDR_EXPR, decl, 0); - - /* Sigh. OFFSET_REFs are being used for too many things. - They're being used both for -> and ->*, and we want to resolve - the -> cases here, but leave the ->*. We could use - resolve_offset_ref for those, too, but it would call - get_member_function_from_ptrfunc and decl_addr wouldn't get - updated properly. Nasty. */ - if (TREE_CODE (TREE_OPERAND (function, 1)) == FIELD_DECL) - function = resolve_offset_ref (function); - else - function = TREE_OPERAND (function, 1); - - function = get_member_function_from_ptrfunc (&decl_addr, function); - params = expr_tree_cons (NULL_TREE, decl_addr, params); - return build_function_call (function, params); - } - - type = TREE_TYPE (function); - if (type != error_mark_node) - { - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - if (IS_AGGR_TYPE (type)) - return build_opfncall (CALL_EXPR, LOOKUP_NORMAL, function, params, NULL_TREE); - } - - if (is_method) - { - tree fntype = TREE_TYPE (function); - tree ctypeptr = NULL_TREE; - - /* Explicitly named method? */ - if (TREE_CODE (function) == FUNCTION_DECL) - ctypeptr = build_pointer_type (DECL_CLASS_CONTEXT (function)); - /* Expression with ptr-to-method type? It could either be a plain - usage, or it might be a case where the ptr-to-method is being - passed in as an argument. */ - else if (TYPE_PTRMEMFUNC_P (fntype)) - { - tree rec = TYPE_METHOD_BASETYPE (TREE_TYPE - (TYPE_PTRMEMFUNC_FN_TYPE (fntype))); - ctypeptr = build_pointer_type (rec); - } - /* Unexpected node type? */ - else - my_friendly_abort (116); - if (decl == NULL_TREE) - { - if (current_function_decl - && DECL_STATIC_FUNCTION_P (current_function_decl)) - error ("invalid call to member function needing `this' in static member function scope"); - else - error ("pointer to member function called, but not in class scope"); - return error_mark_node; - } - if (TREE_CODE (TREE_TYPE (decl)) != POINTER_TYPE - && ! TYPE_PTRMEMFUNC_P (TREE_TYPE (decl))) - { - decl = build_unary_op (ADDR_EXPR, decl, 0); - decl = convert_pointer_to (TREE_TYPE (ctypeptr), decl); - } - else - decl = build_c_cast (ctypeptr, decl); - params = expr_tree_cons (NULL_TREE, decl, params); - } - - return build_function_call (function, params); -} - -/* Resolve a pointer to member function. INSTANCE is the object - instance to use, if the member points to a virtual member. */ - -tree -get_member_function_from_ptrfunc (instance_ptrptr, function) - tree *instance_ptrptr; - tree function; -{ - if (TREE_CODE (function) == OFFSET_REF) - { - function = TREE_OPERAND (function, 1); - } - - if (TYPE_PTRMEMFUNC_P (TREE_TYPE (function))) - { - tree fntype, idx, e1, delta, delta2, e2, e3, aref, vtbl; - tree instance, basetype; - - tree instance_ptr = *instance_ptrptr; - - if (TREE_SIDE_EFFECTS (instance_ptr)) - instance_ptr = save_expr (instance_ptr); - - if (TREE_SIDE_EFFECTS (function)) - function = save_expr (function); - - fntype = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (function)); - basetype = TYPE_METHOD_BASETYPE (TREE_TYPE (fntype)); - - delta = cp_convert (ptrdiff_type_node, - build_component_ref (function, delta_identifier, - NULL_TREE, 0)); - e3 = PFN_FROM_PTRMEMFUNC (function); - - if (TYPE_SIZE (basetype) != NULL_TREE - && ! TYPE_VIRTUAL_P (basetype)) - /* If basetype doesn't have virtual functions, don't emit code to - handle that case. */ - e1 = e3; - else - { - /* Promoting idx before saving it improves performance on RISC - targets. Without promoting, the first compare used - load-with-sign-extend, while the second used normal load then - shift to sign-extend. An optimizer flaw, perhaps, but it's - easier to make this change. */ - idx = save_expr (default_conversion - (build_component_ref (function, - index_identifier, - NULL_TREE, 0))); - e1 = build_binary_op (GT_EXPR, idx, integer_zero_node, 1); - - /* Convert down to the right base, before using the instance. */ - instance = convert_pointer_to_real (basetype, instance_ptr); - if (instance == error_mark_node && instance_ptr != error_mark_node) - return instance; - - vtbl = convert_pointer_to (ptr_type_node, instance); - delta2 = DELTA2_FROM_PTRMEMFUNC (function); - vtbl = build - (PLUS_EXPR, - build_pointer_type (build_pointer_type (vtable_entry_type)), - vtbl, cp_convert (ptrdiff_type_node, delta2)); - vtbl = build_indirect_ref (vtbl, NULL_PTR); - aref = build_array_ref (vtbl, build_binary_op (MINUS_EXPR, - idx, - integer_one_node, 1)); - if (! flag_vtable_thunks) - { - aref = save_expr (aref); - - delta = build_binary_op - (PLUS_EXPR, - build_conditional_expr (e1, - build_component_ref (aref, - delta_identifier, - NULL_TREE, 0), - integer_zero_node), - delta, 1); - } - - if (flag_vtable_thunks) - e2 = aref; - else - e2 = build_component_ref (aref, pfn_identifier, NULL_TREE, 0); - TREE_TYPE (e2) = TREE_TYPE (e3); - e1 = build_conditional_expr (e1, e2, e3); - - /* Make sure this doesn't get evaluated first inside one of the - branches of the COND_EXPR. */ - if (TREE_CODE (instance_ptr) == SAVE_EXPR) - e1 = build (COMPOUND_EXPR, TREE_TYPE (e1), - instance_ptr, e1); - } - - *instance_ptrptr = build (PLUS_EXPR, TREE_TYPE (instance_ptr), - instance_ptr, delta); - - if (instance_ptr == error_mark_node - && TREE_CODE (e1) != ADDR_EXPR - && TREE_CODE (TREE_OPERAND (e1, 0)) != FUNCTION_DECL) - cp_error ("object missing in `%E'", function); - - function = e1; - } - return function; -} - -tree -build_function_call_real (function, params, require_complete, flags) - tree function, params; - int require_complete, flags; -{ - register tree fntype, fndecl; - register tree value_type; - register tree coerced_params; - tree name = NULL_TREE, assembler_name = NULL_TREE; - int is_method; - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs, since FUNCTION is used in non-lvalue context. */ - if (TREE_CODE (function) == NOP_EXPR - && TREE_TYPE (function) == TREE_TYPE (TREE_OPERAND (function, 0))) - function = TREE_OPERAND (function, 0); - - if (TREE_CODE (function) == FUNCTION_DECL) - { - name = DECL_NAME (function); - assembler_name = DECL_ASSEMBLER_NAME (function); - - GNU_xref_call (current_function_decl, - IDENTIFIER_POINTER (name ? name - : TYPE_IDENTIFIER (DECL_CLASS_CONTEXT - (function)))); - mark_used (function); - fndecl = function; - - /* Convert anything with function type to a pointer-to-function. */ - if (pedantic && DECL_MAIN_P (function)) - pedwarn ("ANSI C++ forbids calling `main' from within program"); - - /* Differs from default_conversion by not setting TREE_ADDRESSABLE - (because calling an inline function does not mean the function - needs to be separately compiled). */ - - if (DECL_INLINE (function)) - function = inline_conversion (function); - else - function = build_addr_func (function); - } - else - { - fndecl = NULL_TREE; - - function = build_addr_func (function); - } - - if (function == error_mark_node) - return error_mark_node; - - fntype = TREE_TYPE (function); - - if (TYPE_PTRMEMFUNC_P (fntype)) - { - cp_error ("must use .* or ->* to call pointer-to-member function in `%E (...)'", - function); - return error_mark_node; - } - - is_method = (TREE_CODE (fntype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (fntype)) == METHOD_TYPE); - - if (!((TREE_CODE (fntype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (fntype)) == FUNCTION_TYPE) - || is_method - || TREE_CODE (function) == TEMPLATE_ID_EXPR)) - { - cp_error ("`%E' cannot be used as a function", function); - return error_mark_node; - } - - /* fntype now gets the type of function pointed to. */ - fntype = TREE_TYPE (fntype); - - /* Convert the parameters to the types declared in the - function prototype, or apply default promotions. */ - - if (flags & LOOKUP_COMPLAIN) - coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype), - params, fndecl, LOOKUP_NORMAL); - else - coerced_params = convert_arguments (TYPE_ARG_TYPES (fntype), - params, fndecl, 0); - - if (coerced_params == error_mark_node) - { - if (flags & LOOKUP_SPECULATIVELY) - return NULL_TREE; - else - return error_mark_node; - } - - /* Check for errors in format strings. */ - - if (warn_format && (name || assembler_name)) - check_function_format (name, assembler_name, coerced_params); - - /* Recognize certain built-in functions so we can make tree-codes - other than CALL_EXPR. We do this when it enables fold-const.c - to do something useful. */ - - if (TREE_CODE (function) == ADDR_EXPR - && TREE_CODE (TREE_OPERAND (function, 0)) == FUNCTION_DECL - && DECL_BUILT_IN (TREE_OPERAND (function, 0))) - switch (DECL_FUNCTION_CODE (TREE_OPERAND (function, 0))) - { - case BUILT_IN_ABS: - case BUILT_IN_LABS: - case BUILT_IN_FABS: - if (coerced_params == 0) - return integer_zero_node; - return build_unary_op (ABS_EXPR, TREE_VALUE (coerced_params), 0); - - default: - break; - } - - /* C++ */ - value_type = TREE_TYPE (fntype) ? TREE_TYPE (fntype) : void_type_node; - { - register tree result - = build_call (function, value_type, coerced_params); - - if (require_complete) - { - if (value_type == void_type_node) - return result; - result = require_complete_type (result); - } - if (IS_AGGR_TYPE (value_type)) - result = build_cplus_new (value_type, result); - return convert_from_reference (result); - } -} - -tree -build_function_call (function, params) - tree function, params; -{ - return build_function_call_real (function, params, 1, LOOKUP_NORMAL); -} - -/* Convert the actual parameter expressions in the list VALUES - to the types in the list TYPELIST. - If parmdecls is exhausted, or when an element has NULL as its type, - perform the default conversions. - - NAME is an IDENTIFIER_NODE or 0. It is used only for error messages. - - This is also where warnings about wrong number of args are generated. - - Return a list of expressions for the parameters as converted. - - Both VALUES and the returned value are chains of TREE_LIST nodes - with the elements of the list in the TREE_VALUE slots of those nodes. - - In C++, unspecified trailing parameters can be filled in with their - default arguments, if such were specified. Do so here. */ - -tree -convert_arguments (typelist, values, fndecl, flags) - tree typelist, values, fndecl; - int flags; -{ - register tree typetail, valtail; - register tree result = NULL_TREE; - char *called_thing = 0; - int i = 0; - - /* Argument passing is always copy-initialization. */ - flags |= LOOKUP_ONLYCONVERTING; - - if (fndecl) - { - if (TREE_CODE (TREE_TYPE (fndecl)) == METHOD_TYPE) - { - if (DECL_NAME (fndecl) == NULL_TREE - || IDENTIFIER_HAS_TYPE_VALUE (DECL_NAME (fndecl))) - called_thing = "constructor"; - else - called_thing = "member function"; - } - else - called_thing = "function"; - } - - for (valtail = values, typetail = typelist; - valtail; - valtail = TREE_CHAIN (valtail), i++) - { - register tree type = typetail ? TREE_VALUE (typetail) : 0; - register tree val = TREE_VALUE (valtail); - - if (val == error_mark_node) - return error_mark_node; - - if (type == void_type_node) - { - if (fndecl) - { - cp_error_at ("too many arguments to %s `%+D'", called_thing, - fndecl); - error ("at this point in file"); - } - else - error ("too many arguments to function"); - /* In case anybody wants to know if this argument - list is valid. */ - if (result) - TREE_TYPE (tree_last (result)) = error_mark_node; - break; - } - - if (TREE_CODE (val) == OFFSET_REF) - val = resolve_offset_ref (val); - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs, since VAL is used in non-lvalue context. */ - if (TREE_CODE (val) == NOP_EXPR - && TREE_TYPE (val) == TREE_TYPE (TREE_OPERAND (val, 0)) - && (type == 0 || TREE_CODE (type) != REFERENCE_TYPE)) - val = TREE_OPERAND (val, 0); - - if (type == 0 || TREE_CODE (type) != REFERENCE_TYPE) - { - if (TREE_CODE (TREE_TYPE (val)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (val)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (val)) == METHOD_TYPE) - val = default_conversion (val); - - val = require_complete_type (val); - } - - if (val == error_mark_node) - return error_mark_node; - - if (type != 0) - { - /* Formal parm type is specified by a function prototype. */ - tree parmval; - - if (TYPE_SIZE (complete_type (type)) == 0) - { - error ("parameter type of called function is incomplete"); - parmval = val; - } - else - { - parmval = convert_for_initialization - (NULL_TREE, type, val, flags, - "argument passing", fndecl, i); -#ifdef PROMOTE_PROTOTYPES - if ((TREE_CODE (type) == INTEGER_TYPE - || TREE_CODE (type) == ENUMERAL_TYPE) - && (TYPE_PRECISION (type) - < TYPE_PRECISION (integer_type_node))) - parmval = default_conversion (parmval); -#endif - } - - if (parmval == error_mark_node) - return error_mark_node; - - result = expr_tree_cons (NULL_TREE, parmval, result); - } - else - { - if (TREE_CODE (TREE_TYPE (val)) == REFERENCE_TYPE) - val = convert_from_reference (val); - - result = expr_tree_cons (NULL_TREE, - convert_arg_to_ellipsis (val), - result); - } - - if (typetail) - typetail = TREE_CHAIN (typetail); - } - - if (typetail != 0 && typetail != void_list_node) - { - /* See if there are default arguments that can be used */ - if (TREE_PURPOSE (typetail)) - { - for (; typetail != void_list_node; ++i) - { - tree parmval - = convert_default_arg (TREE_VALUE (typetail), - TREE_PURPOSE (typetail), - fndecl); - - if (parmval == error_mark_node) - return error_mark_node; - - result = expr_tree_cons (0, parmval, result); - typetail = TREE_CHAIN (typetail); - /* ends with `...'. */ - if (typetail == NULL_TREE) - break; - } - } - else - { - if (fndecl) - { - char *buf = (char *)alloca (32 + strlen (called_thing)); - sprintf (buf, "too few arguments to %s `%%#D'", called_thing); - cp_error_at (buf, fndecl); - error ("at this point in file"); - } - else - error ("too few arguments to function"); - return error_mark_list; - } - } - - return nreverse (result); -} - -/* Build a binary-operation expression, after performing default - conversions on the operands. CODE is the kind of expression to build. */ - -tree -build_x_binary_op (code, arg1, arg2) - enum tree_code code; - tree arg1, arg2; -{ - if (processing_template_decl) - return build_min_nt (code, arg1, arg2); - - return build_new_op (code, LOOKUP_NORMAL, arg1, arg2, NULL_TREE); -} - -tree -build_binary_op (code, arg1, arg2, convert_p) - enum tree_code code; - tree arg1, arg2; - int convert_p ATTRIBUTE_UNUSED; -{ - return build_binary_op_nodefault (code, arg1, arg2, code); -} - -/* Build a binary-operation expression without default conversions. - CODE is the kind of expression to build. - This function differs from `build' in several ways: - the data type of the result is computed and recorded in it, - warnings are generated if arg data types are invalid, - special handling for addition and subtraction of pointers is known, - and some optimization is done (operations on narrow ints - are done in the narrower type when that gives the same result). - Constant folding is also done before the result is returned. - - ERROR_CODE is the code that determines what to say in error messages. - It is usually, but not always, the same as CODE. - - Note that the operands will never have enumeral types - because either they have just had the default conversions performed - or they have both just been converted to some other type in which - the arithmetic is to be done. - - C++: must do special pointer arithmetic when implementing - multiple inheritance, and deal with pointer to member functions. */ - -tree -build_binary_op_nodefault (code, orig_op0, orig_op1, error_code) - enum tree_code code; - tree orig_op0, orig_op1; - enum tree_code error_code; -{ - tree op0, op1; - register enum tree_code code0, code1; - tree type0, type1; - - /* Expression code to give to the expression when it is built. - Normally this is CODE, which is what the caller asked for, - but in some special cases we change it. */ - register enum tree_code resultcode = code; - - /* Data type in which the computation is to be performed. - In the simplest cases this is the common type of the arguments. */ - register tree result_type = NULL; - - /* Nonzero means operands have already been type-converted - in whatever way is necessary. - Zero means they need to be converted to RESULT_TYPE. */ - int converted = 0; - - /* Nonzero means create the expression with this type, rather than - RESULT_TYPE. */ - tree build_type = 0; - - /* Nonzero means after finally constructing the expression - convert it to this type. */ - tree final_type = 0; - - /* Nonzero if this is an operation like MIN or MAX which can - safely be computed in short if both args are promoted shorts. - Also implies COMMON. - -1 indicates a bitwise operation; this makes a difference - in the exact conditions for when it is safe to do the operation - in a narrower mode. */ - int shorten = 0; - - /* Nonzero if this is a comparison operation; - if both args are promoted shorts, compare the original shorts. - Also implies COMMON. */ - int short_compare = 0; - - /* Nonzero if this is a right-shift operation, which can be computed on the - original short and then promoted if the operand is a promoted short. */ - int short_shift = 0; - - /* Nonzero means set RESULT_TYPE to the common type of the args. */ - int common = 0; - - /* Apply default conversions. */ - if (code == TRUTH_AND_EXPR || code == TRUTH_ANDIF_EXPR - || code == TRUTH_OR_EXPR || code == TRUTH_ORIF_EXPR - || code == TRUTH_XOR_EXPR) - { - op0 = decay_conversion (orig_op0); - op1 = decay_conversion (orig_op1); - } - else - { - op0 = default_conversion (orig_op0); - op1 = default_conversion (orig_op1); - } - - type0 = TREE_TYPE (op0); - type1 = TREE_TYPE (op1); - - /* The expression codes of the data types of the arguments tell us - whether the arguments are integers, floating, pointers, etc. */ - code0 = TREE_CODE (type0); - code1 = TREE_CODE (type1); - - /* Strip NON_LVALUE_EXPRs, etc., since we aren't using as an lvalue. */ - STRIP_TYPE_NOPS (op0); - STRIP_TYPE_NOPS (op1); - - /* If an error was already reported for one of the arguments, - avoid reporting another error. */ - - if (code0 == ERROR_MARK || code1 == ERROR_MARK) - return error_mark_node; - - switch (code) - { - case PLUS_EXPR: - /* Handle the pointer + int case. */ - if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op0, op1); - else if (code1 == POINTER_TYPE && code0 == INTEGER_TYPE) - return pointer_int_sum (PLUS_EXPR, op1, op0); - else - common = 1; - break; - - case MINUS_EXPR: - /* Subtraction of two similar pointers. - We must subtract them as integers, then divide by object size. */ - if (code0 == POINTER_TYPE && code1 == POINTER_TYPE - && comp_target_types (type0, type1, 1)) - return pointer_diff (op0, op1, common_type (type0, type1)); - /* Handle pointer minus int. Just like pointer plus int. */ - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - return pointer_int_sum (MINUS_EXPR, op0, op1); - else - common = 1; - break; - - case MULT_EXPR: - common = 1; - break; - - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case EXACT_DIV_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - { - if (TREE_CODE (op1) == INTEGER_CST && integer_zerop (op1)) - cp_warning ("division by zero in `%E / 0'", op0); - else if (TREE_CODE (op1) == REAL_CST && real_zerop (op1)) - cp_warning ("division by zero in `%E / 0.'", op0); - - if (!(code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)) - resultcode = RDIV_EXPR; - else - /* When dividing two signed integers, we have to promote to int. - unless we divide by a constant != -1. Note that default - conversion will have been performed on the operands at this - point, so we have to dig out the original type to find out if - it was unsigned. */ - shorten = ((TREE_CODE (op0) == NOP_EXPR - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - || (TREE_CODE (op1) == INTEGER_CST - && (TREE_INT_CST_LOW (op1) != -1 - || TREE_INT_CST_HIGH (op1) != -1))); - common = 1; - } - break; - - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - shorten = -1; - /* If one operand is a constant, and the other is a short type - that has been converted to an int, - really do the work in the short type and then convert the - result to int. If we are lucky, the constant will be 0 or 1 - in the short type, making the entire operation go away. */ - if (TREE_CODE (op0) == INTEGER_CST - && TREE_CODE (op1) == NOP_EXPR - && (TYPE_PRECISION (type1) - > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op1, 0)))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op1, 0)))) - { - final_type = result_type; - op1 = TREE_OPERAND (op1, 0); - result_type = TREE_TYPE (op1); - } - if (TREE_CODE (op1) == INTEGER_CST - && TREE_CODE (op0) == NOP_EXPR - && (TYPE_PRECISION (type0) - > TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (op0, 0)))) - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - { - final_type = result_type; - op0 = TREE_OPERAND (op0, 0); - result_type = TREE_TYPE (op0); - } - break; - - case TRUNC_MOD_EXPR: - case FLOOR_MOD_EXPR: - if (code1 == INTEGER_TYPE && integer_zerop (op1)) - cp_warning ("division by zero in `%E %% 0'", op0); - else if (code1 == REAL_TYPE && real_zerop (op1)) - cp_warning ("division by zero in `%E %% 0.'", op0); - - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - /* Although it would be tempting to shorten always here, that loses - on some targets, since the modulo instruction is undefined if the - quotient can't be represented in the computation mode. We shorten - only if unsigned or if dividing by something we know != -1. */ - shorten = ((TREE_CODE (op0) == NOP_EXPR - && TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (op0, 0)))) - || (TREE_CODE (op1) == INTEGER_CST - && (TREE_INT_CST_LOW (op1) != -1 - || TREE_INT_CST_HIGH (op1) != -1))); - common = 1; - } - break; - - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - result_type = boolean_type_node; - break; - - /* Shift operations: result has same type as first operand; - always convert second operand to int. - Also set SHORT_SHIFT if shifting rightward. */ - - case RSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("right shift count is negative"); - else - { - if (TREE_INT_CST_LOW (op1) | TREE_INT_CST_HIGH (op1)) - short_shift = 1; - if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("right shift count >= width of type"); - } - } - /* Convert the shift-count to an integer, regardless of - size of value being shifted. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - break; - - case LSHIFT_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("left shift count is negative"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("left shift count >= width of type"); - } - /* Convert the shift-count to an integer, regardless of - size of value being shifted. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); - /* Avoid converting op1 to result_type later. */ - converted = 1; - } - break; - - case RROTATE_EXPR: - case LROTATE_EXPR: - if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - if (TREE_CODE (op1) == INTEGER_CST) - { - if (tree_int_cst_lt (op1, integer_zero_node)) - warning ("%s rotate count is negative", - (code == LROTATE_EXPR) ? "left" : "right"); - else if (TREE_INT_CST_HIGH (op1) != 0 - || ((unsigned HOST_WIDE_INT) TREE_INT_CST_LOW (op1) - >= TYPE_PRECISION (type0))) - warning ("%s rotate count >= width of type", - (code == LROTATE_EXPR) ? "left" : "right"); - } - /* Convert the shift-count to an integer, regardless of - size of value being shifted. */ - if (TYPE_MAIN_VARIANT (TREE_TYPE (op1)) != integer_type_node) - op1 = cp_convert (integer_type_node, op1); - } - break; - - case EQ_EXPR: - case NE_EXPR: - build_type = boolean_type_node; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE - || code0 == COMPLEX_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE - || code1 == COMPLEX_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - register tree tt0 = TYPE_MAIN_VARIANT (TREE_TYPE (type0)); - register tree tt1 = TYPE_MAIN_VARIANT (TREE_TYPE (type1)); - - if (comp_target_types (type0, type1, 1)) - result_type = common_type (type0, type1); - else if (tt0 == void_type_node) - { - if (pedantic && TREE_CODE (tt1) == FUNCTION_TYPE - && tree_int_cst_lt (TYPE_SIZE (type0), TYPE_SIZE (type1))) - pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer"); - else if (TREE_CODE (tt1) == OFFSET_TYPE) - pedwarn ("ANSI C++ forbids conversion of a pointer to member to `void *'"); - } - else if (tt1 == void_type_node) - { - if (pedantic && TREE_CODE (tt0) == FUNCTION_TYPE - && tree_int_cst_lt (TYPE_SIZE (type1), TYPE_SIZE (type0))) - pedwarn ("ANSI C++ forbids comparison of `void *' with function pointer"); - } - else - cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast", - type0, type1); - - if (result_type == NULL_TREE) - result_type = ptr_type_node; - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - result_type = type0; - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - result_type = type1; - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - error ("ANSI C++ forbids comparison between pointer and integer"); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = type1; - error ("ANSI C++ forbids comparison between pointer and integer"); - } - else if (TYPE_PTRMEMFUNC_P (type0) && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - { - op0 = build_component_ref (op0, index_identifier, NULL_TREE, 0); - op1 = integer_zero_node; - result_type = TREE_TYPE (op0); - } - else if (TYPE_PTRMEMFUNC_P (type1) && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - { - op0 = build_component_ref (op1, index_identifier, NULL_TREE, 0); - op1 = integer_zero_node; - result_type = TREE_TYPE (op0); - } - else if (TYPE_PTRMEMFUNC_P (type0) && TYPE_PTRMEMFUNC_P (type1) - && (TYPE_PTRMEMFUNC_FN_TYPE (type0) - == TYPE_PTRMEMFUNC_FN_TYPE (type1))) - { - /* The code we generate for the test is: - - (op0.index == op1.index - && ((op1.index != -1 && op0.delta2 == op1.delta2) - || op0.pfn == op1.pfn)) */ - - tree index0 = build_component_ref (op0, index_identifier, - NULL_TREE, 0); - tree index1 = save_expr (build_component_ref (op1, index_identifier, - NULL_TREE, 0)); - tree pfn0 = PFN_FROM_PTRMEMFUNC (op0); - tree pfn1 = PFN_FROM_PTRMEMFUNC (op1); - tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0); - tree delta21 = DELTA2_FROM_PTRMEMFUNC (op1); - tree e1, e2, e3; - tree integer_neg_one_node - = build_binary_op (MINUS_EXPR, integer_zero_node, - integer_one_node, 1); - e1 = build_binary_op (EQ_EXPR, index0, index1, 1); - e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1); - e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2, - build_binary_op (EQ_EXPR, delta20, delta21, 1), - 1); - e3 = build_binary_op (EQ_EXPR, pfn0, pfn1, 1); - e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1); - e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1); - if (code == EQ_EXPR) - return e2; - return build_binary_op (EQ_EXPR, e2, integer_zero_node, 1); - } - else if (TYPE_PTRMEMFUNC_P (type0) - && TYPE_PTRMEMFUNC_FN_TYPE (type0) == type1) - { - tree index0 = build_component_ref (op0, index_identifier, - NULL_TREE, 0); - tree index1; - tree pfn0 = PFN_FROM_PTRMEMFUNC (op0); - tree delta20 = DELTA2_FROM_PTRMEMFUNC (op0); - tree delta21 = integer_zero_node; - tree e1, e2, e3; - tree integer_neg_one_node - = build_binary_op (MINUS_EXPR, integer_zero_node, integer_one_node, 1); - if (TREE_CODE (TREE_OPERAND (op1, 0)) == FUNCTION_DECL - && DECL_VINDEX (TREE_OPERAND (op1, 0))) - { - /* Map everything down one to make room for - the null pointer to member. */ - index1 = size_binop (PLUS_EXPR, - DECL_VINDEX (TREE_OPERAND (op1, 0)), - integer_one_node); - op1 = integer_zero_node; - delta21 = CLASSTYPE_VFIELD (TYPE_METHOD_BASETYPE - (TREE_TYPE (type1))); - delta21 = DECL_FIELD_BITPOS (delta21); - delta21 = size_binop (FLOOR_DIV_EXPR, delta21, - size_int (BITS_PER_UNIT)); - delta21 = convert (sizetype, delta21); - } - else - index1 = integer_neg_one_node; - { - tree nop1 = build1 (NOP_EXPR, TYPE_PTRMEMFUNC_FN_TYPE (type0), - op1); - TREE_CONSTANT (nop1) = TREE_CONSTANT (op1); - op1 = nop1; - } - e1 = build_binary_op (EQ_EXPR, index0, index1, 1); - e2 = build_binary_op (NE_EXPR, index1, integer_neg_one_node, 1); - e2 = build_binary_op (TRUTH_ANDIF_EXPR, e2, - build_binary_op (EQ_EXPR, delta20, delta21, 1), - 1); - e3 = build_binary_op (EQ_EXPR, pfn0, op1, 1); - e2 = build_binary_op (TRUTH_ORIF_EXPR, e2, e3, 1); - e2 = build_binary_op (TRUTH_ANDIF_EXPR, e1, e2, 1); - if (code == EQ_EXPR) - return e2; - return build_binary_op (EQ_EXPR, e2, integer_zero_node, 1); - } - else if (TYPE_PTRMEMFUNC_P (type1) - && TYPE_PTRMEMFUNC_FN_TYPE (type1) == type0) - { - return build_binary_op (code, op1, op0, 1); - } - break; - - case MAX_EXPR: - case MIN_EXPR: - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) - shorten = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (comp_target_types (type0, type1, 1)) - result_type = common_type (type0, type1); - else - { - cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast", - type0, type1); - result_type = ptr_type_node; - } - } - break; - - case LE_EXPR: - case GE_EXPR: - case LT_EXPR: - case GT_EXPR: - build_type = boolean_type_node; - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE) - && (code1 == INTEGER_TYPE || code1 == REAL_TYPE)) - short_compare = 1; - else if (code0 == POINTER_TYPE && code1 == POINTER_TYPE) - { - if (comp_target_types (type0, type1, 1)) - result_type = common_type (type0, type1); - else - { - cp_pedwarn ("comparison of distinct pointer types `%T' and `%T' lacks a cast", - type0, type1); - result_type = ptr_type_node; - } - } - else if (code0 == POINTER_TYPE && TREE_CODE (op1) == INTEGER_CST - && integer_zerop (op1)) - result_type = type0; - else if (code1 == POINTER_TYPE && TREE_CODE (op0) == INTEGER_CST - && integer_zerop (op0)) - result_type = type1; - else if (code0 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - result_type = type0; - pedwarn ("ANSI C++ forbids comparison between pointer and integer"); - } - else if (code0 == INTEGER_TYPE && code1 == POINTER_TYPE) - { - result_type = type1; - pedwarn ("ANSI C++ forbids comparison between pointer and integer"); - } - break; - - default: - break; - } - - if ((code0 == INTEGER_TYPE || code0 == REAL_TYPE || code0 == COMPLEX_TYPE) - && - (code1 == INTEGER_TYPE || code1 == REAL_TYPE || code1 == COMPLEX_TYPE)) - { - int none_complex = (code0 != COMPLEX_TYPE && code1 != COMPLEX_TYPE); - - if (shorten || common || short_compare) - result_type = common_type (type0, type1); - - /* For certain operations (which identify themselves by shorten != 0) - if both args were extended from the same smaller type, - do the arithmetic in that type and then extend. - - shorten !=0 and !=1 indicates a bitwise operation. - For them, this optimization is safe only if - both args are zero-extended or both are sign-extended. - Otherwise, we might change the result. - Eg, (short)-1 | (unsigned short)-1 is (int)-1 - but calculated in (unsigned short) it would be (unsigned short)-1. */ - - if (shorten && none_complex) - { - int unsigned0, unsigned1; - tree arg0 = get_narrower (op0, &unsigned0); - tree arg1 = get_narrower (op1, &unsigned1); - /* UNS is 1 if the operation to be done is an unsigned one. */ - int uns = TREE_UNSIGNED (result_type); - tree type; - - final_type = result_type; - - /* Handle the case that OP0 does not *contain* a conversion - but it *requires* conversion to FINAL_TYPE. */ - - if (op0 == arg0 && TREE_TYPE (op0) != final_type) - unsigned0 = TREE_UNSIGNED (TREE_TYPE (op0)); - if (op1 == arg1 && TREE_TYPE (op1) != final_type) - unsigned1 = TREE_UNSIGNED (TREE_TYPE (op1)); - - /* Now UNSIGNED0 is 1 if ARG0 zero-extends to FINAL_TYPE. */ - - /* For bitwise operations, signedness of nominal type - does not matter. Consider only how operands were extended. */ - if (shorten == -1) - uns = unsigned0; - - /* Note that in all three cases below we refrain from optimizing - an unsigned operation on sign-extended args. - That would not be valid. */ - - /* Both args variable: if both extended in same way - from same width, do it in that width. - Do it unsigned if args were zero-extended. */ - if ((TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - == TYPE_PRECISION (TREE_TYPE (arg0))) - && unsigned0 == unsigned1 - && (unsigned0 || !uns)) - result_type - = signed_or_unsigned_type (unsigned0, - common_type (TREE_TYPE (arg0), - TREE_TYPE (arg1))); - else if (TREE_CODE (arg0) == INTEGER_CST - && (unsigned1 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg1)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned1, - TREE_TYPE (arg1)), - int_fits_type_p (arg0, type))) - result_type = type; - else if (TREE_CODE (arg1) == INTEGER_CST - && (unsigned0 || !uns) - && (TYPE_PRECISION (TREE_TYPE (arg0)) - < TYPE_PRECISION (result_type)) - && (type = signed_or_unsigned_type (unsigned0, - TREE_TYPE (arg0)), - int_fits_type_p (arg1, type))) - result_type = type; - } - - /* Shifts can be shortened if shifting right. */ - - if (short_shift) - { - int unsigned_arg; - tree arg0 = get_narrower (op0, &unsigned_arg); - - final_type = result_type; - - if (arg0 == op0 && final_type == TREE_TYPE (op0)) - unsigned_arg = TREE_UNSIGNED (TREE_TYPE (op0)); - - if (TYPE_PRECISION (TREE_TYPE (arg0)) < TYPE_PRECISION (result_type) - /* We can shorten only if the shift count is less than the - number of bits in the smaller type size. */ - && TREE_INT_CST_HIGH (op1) == 0 - && TYPE_PRECISION (TREE_TYPE (arg0)) > TREE_INT_CST_LOW (op1) - /* If arg is sign-extended and then unsigned-shifted, - we can simulate this with a signed shift in arg's type - only if the extended result is at least twice as wide - as the arg. Otherwise, the shift could use up all the - ones made by sign-extension and bring in zeros. - We can't optimize that case at all, but in most machines - it never happens because available widths are 2**N. */ - && (!TREE_UNSIGNED (final_type) - || unsigned_arg - || (((unsigned) 2 * TYPE_PRECISION (TREE_TYPE (arg0))) - <= TYPE_PRECISION (result_type)))) - { - /* Do an unsigned shift if the operand was zero-extended. */ - result_type - = signed_or_unsigned_type (unsigned_arg, - TREE_TYPE (arg0)); - /* Convert value-to-be-shifted to that type. */ - if (TREE_TYPE (op0) != result_type) - op0 = cp_convert (result_type, op0); - converted = 1; - } - } - - /* Comparison operations are shortened too but differently. - They identify themselves by setting short_compare = 1. */ - - if (short_compare) - { - /* Don't write &op0, etc., because that would prevent op0 - from being kept in a register. - Instead, make copies of the our local variables and - pass the copies by reference, then copy them back afterward. */ - tree xop0 = op0, xop1 = op1, xresult_type = result_type; - enum tree_code xresultcode = resultcode; - tree val - = shorten_compare (&xop0, &xop1, &xresult_type, &xresultcode); - if (val != 0) - return cp_convert (boolean_type_node, val); - op0 = xop0, op1 = xop1; - converted = 1; - resultcode = xresultcode; - } - - if (short_compare && warn_sign_compare) - { - int op0_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op0)); - int op1_signed = ! TREE_UNSIGNED (TREE_TYPE (orig_op1)); - - int unsignedp0, unsignedp1; - tree primop0 = get_narrower (op0, &unsignedp0); - tree primop1 = get_narrower (op1, &unsignedp1); - - /* Check for comparison of different enum types. */ - if (TREE_CODE (TREE_TYPE (orig_op0)) == ENUMERAL_TYPE - && TREE_CODE (TREE_TYPE (orig_op1)) == ENUMERAL_TYPE - && TYPE_MAIN_VARIANT (TREE_TYPE (orig_op0)) - != TYPE_MAIN_VARIANT (TREE_TYPE (orig_op1))) - { - cp_warning ("comparison between `%#T' and `%#T'", - TREE_TYPE (orig_op0), TREE_TYPE (orig_op1)); - } - - /* Give warnings for comparisons between signed and unsigned - quantities that may fail. */ - /* Do the checking based on the original operand trees, so that - casts will be considered, but default promotions won't be. */ - - /* Do not warn if the comparison is being done in a signed type, - since the signed type will only be chosen if it can represent - all the values of the unsigned type. */ - if (! TREE_UNSIGNED (result_type)) - /* OK */; - /* Do not warn if both operands are unsigned. */ - else if (op0_signed == op1_signed) - /* OK */; - /* Do not warn if the signed quantity is an unsuffixed - integer literal (or some static constant expression - involving such literals) and it is non-negative. */ - else if ((op0_signed && TREE_CODE (orig_op0) == INTEGER_CST - && tree_int_cst_sgn (orig_op0) >= 0) - || (op1_signed && TREE_CODE (orig_op1) == INTEGER_CST - && tree_int_cst_sgn (orig_op1) >= 0)) - /* OK */; - /* Do not warn if the comparison is an equality operation, - the unsigned quantity is an integral constant and it does - not use the most significant bit of result_type. */ - else if ((resultcode == EQ_EXPR || resultcode == NE_EXPR) - && ((op0_signed && TREE_CODE (orig_op1) == INTEGER_CST - && int_fits_type_p (orig_op1, - signed_type (result_type))) - || (op1_signed && TREE_CODE (orig_op0) == INTEGER_CST - && int_fits_type_p (orig_op0, - signed_type (result_type))))) - /* OK */; - else - warning ("comparison between signed and unsigned"); - - /* Warn if two unsigned values are being compared in a size - larger than their original size, and one (and only one) is the - result of a `~' operator. This comparison will always fail. - - Also warn if one operand is a constant, and the constant does not - have all bits set that are set in the ~ operand when it is - extended. */ - - if ((TREE_CODE (primop0) == BIT_NOT_EXPR) - ^ (TREE_CODE (primop1) == BIT_NOT_EXPR)) - { - if (TREE_CODE (primop0) == BIT_NOT_EXPR) - primop0 = get_narrower (TREE_OPERAND (op0, 0), &unsignedp0); - if (TREE_CODE (primop1) == BIT_NOT_EXPR) - primop1 = get_narrower (TREE_OPERAND (op1, 0), &unsignedp1); - - if (TREE_CODE (primop0) == INTEGER_CST - || TREE_CODE (primop1) == INTEGER_CST) - { - tree primop; - HOST_WIDE_INT constant, mask; - int unsignedp; - unsigned bits; - - if (TREE_CODE (primop0) == INTEGER_CST) - { - primop = primop1; - unsignedp = unsignedp1; - constant = TREE_INT_CST_LOW (primop0); - } - else - { - primop = primop0; - unsignedp = unsignedp0; - constant = TREE_INT_CST_LOW (primop1); - } - - bits = TYPE_PRECISION (TREE_TYPE (primop)); - if (bits < TYPE_PRECISION (result_type) - && bits < HOST_BITS_PER_LONG && unsignedp) - { - mask = (~ (HOST_WIDE_INT) 0) << bits; - if ((mask & constant) != mask) - warning ("comparison of promoted ~unsigned with constant"); - } - } - else if (unsignedp0 && unsignedp1 - && (TYPE_PRECISION (TREE_TYPE (primop0)) - < TYPE_PRECISION (result_type)) - && (TYPE_PRECISION (TREE_TYPE (primop1)) - < TYPE_PRECISION (result_type))) - warning ("comparison of promoted ~unsigned with unsigned"); - } - } - } - - /* At this point, RESULT_TYPE must be nonzero to avoid an error message. - If CONVERTED is zero, both args will be converted to type RESULT_TYPE. - Then the expression will be built. - It will be given type FINAL_TYPE if that is nonzero; - otherwise, it will be given type RESULT_TYPE. */ - - if (!result_type) - { - cp_error ("invalid operands `%T' and `%T' to binary `%O'", - TREE_TYPE (orig_op0), TREE_TYPE (orig_op1), error_code); - return error_mark_node; - } - - /* Issue warnings about peculiar, but legal, uses of NULL. */ - if (/* It's reasonable to use pointer values as operands of && - and ||, so NULL is no exception. */ - !(code == TRUTH_ANDIF_EXPR || code == TRUTH_ORIF_EXPR) - && (/* If OP0 is NULL and OP1 is not a pointer, or vice versa. */ - (orig_op0 == null_node - && TREE_CODE (TREE_TYPE (op1)) != POINTER_TYPE) - /* Or vice versa. */ - || (orig_op1 == null_node - && TREE_CODE (TREE_TYPE (op0)) != POINTER_TYPE) - /* Or, both are NULL and the operation was not a comparison. */ - || (orig_op0 == null_node && orig_op1 == null_node - && code != EQ_EXPR && code != NE_EXPR))) - /* Some sort of arithmetic operation involving NULL was - performed. Note that pointer-difference and pointer-addition - have already been handled above, and so we don't end up here in - that case. */ - cp_warning ("NULL used in arithmetic"); - - if (! converted) - { - if (TREE_TYPE (op0) != result_type) - op0 = cp_convert (result_type, op0); - if (TREE_TYPE (op1) != result_type) - op1 = cp_convert (result_type, op1); - - if (op0 == error_mark_node || op1 == error_mark_node) - return error_mark_node; - } - - if (build_type == NULL_TREE) - build_type = result_type; - - { - register tree result = build (resultcode, build_type, op0, op1); - register tree folded; - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - if (final_type != 0) - return cp_convert (final_type, folded); - return folded; - } -} - -/* Return a tree for the sum or difference (RESULTCODE says which) - of pointer PTROP and integer INTOP. */ - -static tree -pointer_int_sum (resultcode, ptrop, intop) - enum tree_code resultcode; - register tree ptrop, intop; -{ - tree size_exp; - - register tree result; - register tree folded = fold (intop); - - /* The result is a pointer of the same type that is being added. */ - - register tree result_type = TREE_TYPE (ptrop); - - if (!complete_type_or_else (result_type)) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (result_type)) == VOID_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids using pointer of type `void *' in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == FUNCTION_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids using pointer to a function in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids using pointer to a method in arithmetic"); - size_exp = integer_one_node; - } - else if (TREE_CODE (TREE_TYPE (result_type)) == OFFSET_TYPE) - { - if (pedantic || warn_pointer_arith) - pedwarn ("ANSI C++ forbids using pointer to a member in arithmetic"); - size_exp = integer_one_node; - } - else - size_exp = size_in_bytes (complete_type (TREE_TYPE (result_type))); - - /* Needed to make OOPS V2R3 work. */ - intop = folded; - if (TREE_CODE (intop) == INTEGER_CST - && TREE_INT_CST_LOW (intop) == 0 - && TREE_INT_CST_HIGH (intop) == 0) - return ptrop; - - /* If what we are about to multiply by the size of the elements - contains a constant term, apply distributive law - and multiply that constant term separately. - This helps produce common subexpressions. */ - - if ((TREE_CODE (intop) == PLUS_EXPR || TREE_CODE (intop) == MINUS_EXPR) - && ! TREE_CONSTANT (intop) - && TREE_CONSTANT (TREE_OPERAND (intop, 1)) - && TREE_CONSTANT (size_exp)) - { - enum tree_code subcode = resultcode; - if (TREE_CODE (intop) == MINUS_EXPR) - subcode = (subcode == PLUS_EXPR ? MINUS_EXPR : PLUS_EXPR); - ptrop = build_binary_op (subcode, ptrop, TREE_OPERAND (intop, 1), 1); - intop = TREE_OPERAND (intop, 0); - } - - /* Convert the integer argument to a type the same size as sizetype - so the multiply won't overflow spuriously. */ - - if (TYPE_PRECISION (TREE_TYPE (intop)) != TYPE_PRECISION (sizetype)) - intop = cp_convert (type_for_size (TYPE_PRECISION (sizetype), 0), intop); - - /* Replace the integer argument with a suitable product by the object size. - Do this multiplication as signed, then convert to the appropriate - pointer type (actually unsigned integral). */ - - intop = cp_convert (result_type, - build_binary_op (MULT_EXPR, intop, - cp_convert (TREE_TYPE (intop), - size_exp), - 1)); - - /* Create the sum or difference. */ - - result = build (resultcode, result_type, ptrop, intop); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (ptrop) & TREE_CONSTANT (intop); - return folded; -} - -/* Return a tree for the difference of pointers OP0 and OP1. - The resulting tree has type int. */ - -static tree -pointer_diff (op0, op1, ptrtype) - register tree op0, op1; - register tree ptrtype; -{ - register tree result, folded; - tree restype = ptrdiff_type_node; - tree target_type = TREE_TYPE (ptrtype); - - if (!complete_type_or_else (target_type)) - return error_mark_node; - - if (pedantic || warn_pointer_arith) - { - if (TREE_CODE (target_type) == VOID_TYPE) - pedwarn ("ANSI C++ forbids using pointer of type `void *' in subtraction"); - if (TREE_CODE (target_type) == FUNCTION_TYPE) - pedwarn ("ANSI C++ forbids using pointer to a function in subtraction"); - if (TREE_CODE (target_type) == METHOD_TYPE) - pedwarn ("ANSI C++ forbids using pointer to a method in subtraction"); - if (TREE_CODE (target_type) == OFFSET_TYPE) - pedwarn ("ANSI C++ forbids using pointer to a member in subtraction"); - } - - /* First do the subtraction as integers; - then drop through to build the divide operator. */ - - op0 = build_binary_op (MINUS_EXPR, cp_convert (restype, op0), - cp_convert (restype, op1), 1); - - /* This generates an error if op1 is a pointer to an incomplete type. */ - if (TYPE_SIZE (TREE_TYPE (TREE_TYPE (op1))) == 0) - error ("arithmetic on pointer to an incomplete type"); - - op1 = ((TREE_CODE (target_type) == VOID_TYPE - || TREE_CODE (target_type) == FUNCTION_TYPE - || TREE_CODE (target_type) == METHOD_TYPE - || TREE_CODE (target_type) == OFFSET_TYPE) - ? integer_one_node - : size_in_bytes (target_type)); - - /* Do the division. */ - - result = build (EXACT_DIV_EXPR, restype, op0, cp_convert (restype, op1)); - - folded = fold (result); - if (folded == result) - TREE_CONSTANT (folded) = TREE_CONSTANT (op0) & TREE_CONSTANT (op1); - return folded; -} - -/* Handle the case of taking the address of a COMPONENT_REF. - Called by `build_unary_op' and `build_up_reference'. - - ARG is the COMPONENT_REF whose address we want. - ARGTYPE is the pointer type that this address should have. - MSG is an error message to print if this COMPONENT_REF is not - addressable (such as a bitfield). */ - -tree -build_component_addr (arg, argtype, msg) - tree arg, argtype; - char *msg; -{ - tree field = TREE_OPERAND (arg, 1); - tree basetype = decl_type_context (field); - tree rval = build_unary_op (ADDR_EXPR, TREE_OPERAND (arg, 0), 0); - - my_friendly_assert (TREE_CODE (field) == FIELD_DECL, 981018); - - if (DECL_C_BIT_FIELD (field)) - { - error (msg, IDENTIFIER_POINTER (DECL_NAME (field))); - return error_mark_node; - } - - if (TREE_CODE (field) == FIELD_DECL - && TYPE_USES_COMPLEX_INHERITANCE (basetype)) - { - /* Can't convert directly to ARGTYPE, since that - may have the same pointer type as one of our - baseclasses. */ - rval = build1 (NOP_EXPR, argtype, - convert_pointer_to (basetype, rval)); - TREE_CONSTANT (rval) = TREE_CONSTANT (TREE_OPERAND (rval, 0)); - } - else - /* This conversion is harmless. */ - rval = convert_force (argtype, rval, 0); - - if (! integer_zerop (DECL_FIELD_BITPOS (field))) - { - tree offset = size_binop (EASY_DIV_EXPR, DECL_FIELD_BITPOS (field), - size_int (BITS_PER_UNIT)); - int flag = TREE_CONSTANT (rval); - offset = convert (sizetype, offset); - rval = fold (build (PLUS_EXPR, argtype, - rval, cp_convert (argtype, offset))); - TREE_CONSTANT (rval) = flag; - } - return rval; -} - -/* Construct and perhaps optimize a tree representation - for a unary operation. CODE, a tree_code, specifies the operation - and XARG is the operand. */ - -tree -build_x_unary_op (code, xarg) - enum tree_code code; - tree xarg; -{ - if (processing_template_decl) - return build_min_nt (code, xarg, NULL_TREE); - - /* & rec, on incomplete RECORD_TYPEs is the simple opr &, not an - error message. */ - if (code == ADDR_EXPR - && TREE_CODE (xarg) != TEMPLATE_ID_EXPR - && ((IS_AGGR_TYPE_CODE (TREE_CODE (TREE_TYPE (xarg))) - && TYPE_SIZE (TREE_TYPE (xarg)) == NULL_TREE) - || (TREE_CODE (xarg) == OFFSET_REF))) - /* don't look for a function */; - else - { - tree rval; - - rval = build_new_op (code, LOOKUP_NORMAL, xarg, - NULL_TREE, NULL_TREE); - if (rval || code != ADDR_EXPR) - return rval; - } - - if (code == ADDR_EXPR) - { - if (TREE_CODE (xarg) == TARGET_EXPR) - warning ("taking address of temporary"); - } - - return build_unary_op (code, xarg, 0); -} - -/* Just like truthvalue_conversion, but we want a CLEANUP_POINT_EXPR. */ - -tree -condition_conversion (expr) - tree expr; -{ - tree t; - if (processing_template_decl) - return expr; - t = cp_convert (boolean_type_node, expr); - t = fold (build1 (CLEANUP_POINT_EXPR, boolean_type_node, t)); - return t; -} - -/* C++: Must handle pointers to members. - - Perhaps type instantiation should be extended to handle conversion - from aggregates to types we don't yet know we want? (Or are those - cases typically errors which should be reported?) - - NOCONVERT nonzero suppresses the default promotions - (such as from short to int). */ - -tree -build_unary_op (code, xarg, noconvert) - enum tree_code code; - tree xarg; - int noconvert; -{ - /* No default_conversion here. It causes trouble for ADDR_EXPR. */ - register tree arg = xarg; - register tree argtype = 0; - char *errstring = NULL; - tree val; - - if (arg == error_mark_node) - return error_mark_node; - - switch (code) - { - case CONVERT_EXPR: - /* This is used for unary plus, because a CONVERT_EXPR - is enough to prevent anybody from looking inside for - associativity, but won't generate any code. */ - if (!(arg = build_expr_type_conversion - (WANT_ARITH | WANT_ENUM | WANT_POINTER, arg, 1))) - errstring = "wrong type argument to unary plus"; - else - { - if (!noconvert) - arg = default_conversion (arg); - arg = build1 (NON_LVALUE_EXPR, TREE_TYPE (arg), arg); - TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0)); - } - break; - - case NEGATE_EXPR: - if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1))) - errstring = "wrong type argument to unary minus"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case BIT_NOT_EXPR: - if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - code = CONJ_EXPR; - if (!noconvert) - arg = default_conversion (arg); - } - else if (!(arg = build_expr_type_conversion (WANT_INT | WANT_ENUM, - arg, 1))) - errstring = "wrong type argument to bit-complement"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case ABS_EXPR: - if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1))) - errstring = "wrong type argument to abs"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case CONJ_EXPR: - /* Conjugating a real value is a no-op, but allow it anyway. */ - if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_ENUM, arg, 1))) - errstring = "wrong type argument to conjugation"; - else if (!noconvert) - arg = default_conversion (arg); - break; - - case TRUTH_NOT_EXPR: - arg = cp_convert (boolean_type_node, arg); - val = invert_truthvalue (arg); - if (arg != error_mark_node) - return val; - errstring = "in argument to unary !"; - break; - - case NOP_EXPR: - break; - - case REALPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_REALPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (REALPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return arg; - - case IMAGPART_EXPR: - if (TREE_CODE (arg) == COMPLEX_CST) - return TREE_IMAGPART (arg); - else if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - return fold (build1 (IMAGPART_EXPR, TREE_TYPE (TREE_TYPE (arg)), arg)); - else - return cp_convert (TREE_TYPE (arg), integer_zero_node); - - case PREINCREMENT_EXPR: - case POSTINCREMENT_EXPR: - case PREDECREMENT_EXPR: - case POSTDECREMENT_EXPR: - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - - /* Increment or decrement the real part of the value, - and don't change the imaginary part. */ - if (TREE_CODE (TREE_TYPE (arg)) == COMPLEX_TYPE) - { - tree real, imag; - - arg = stabilize_reference (arg); - real = build_unary_op (REALPART_EXPR, arg, 1); - imag = build_unary_op (IMAGPART_EXPR, arg, 1); - return build (COMPLEX_EXPR, TREE_TYPE (arg), - build_unary_op (code, real, 1), imag); - } - - /* Report invalid types. */ - - if (!(arg = build_expr_type_conversion (WANT_ARITH | WANT_POINTER, - arg, 1))) - { - if (code == PREINCREMENT_EXPR) - errstring ="no pre-increment operator for type"; - else if (code == POSTINCREMENT_EXPR) - errstring ="no post-increment operator for type"; - else if (code == PREDECREMENT_EXPR) - errstring ="no pre-decrement operator for type"; - else - errstring ="no post-decrement operator for type"; - break; - } - - /* Report something read-only. */ - - if (CP_TYPE_CONST_P (TREE_TYPE (arg)) - || TREE_READONLY (arg)) - readonly_error (arg, ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"), - 0); - - { - register tree inc; - tree result_type = TREE_TYPE (arg); - - arg = get_unwidened (arg, 0); - argtype = TREE_TYPE (arg); - - /* ARM $5.2.5 last annotation says this should be forbidden. */ - if (TREE_CODE (argtype) == ENUMERAL_TYPE) - pedwarn ("ANSI C++ forbids %sing an enum", - (code == PREINCREMENT_EXPR || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"); - - /* Compute the increment. */ - - if (TREE_CODE (argtype) == POINTER_TYPE) - { - enum tree_code tmp = TREE_CODE (TREE_TYPE (argtype)); - if (TYPE_SIZE (complete_type (TREE_TYPE (argtype))) == 0) - cp_error ("cannot %s a pointer to incomplete type `%T'", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"), TREE_TYPE (argtype)); - else if ((pedantic || warn_pointer_arith) - && (tmp == FUNCTION_TYPE || tmp == METHOD_TYPE - || tmp == VOID_TYPE || tmp == OFFSET_TYPE)) - cp_pedwarn ("ANSI C++ forbids %sing a pointer of type `%T'", - ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"), argtype); - inc = c_sizeof_nowarn (TREE_TYPE (argtype)); - } - else - inc = integer_one_node; - - inc = cp_convert (argtype, inc); - - /* Handle incrementing a cast-expression. */ - - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - { - tree incremented, modify, value, compound; - if (! lvalue_p (arg) && pedantic) - pedwarn ("cast to non-reference type used as lvalue"); - arg = stabilize_reference (arg); - if (code == PREINCREMENT_EXPR || code == PREDECREMENT_EXPR) - value = arg; - else - value = save_expr (arg); - incremented = build (((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? PLUS_EXPR : MINUS_EXPR), - argtype, value, inc); - TREE_SIDE_EFFECTS (incremented) = 1; - - modify = build_modify_expr (arg, NOP_EXPR, incremented); - compound = build (COMPOUND_EXPR, TREE_TYPE (arg), modify, value); - - /* Eliminate warning about unused result of + or -. */ - TREE_NO_UNUSED_WARNING (compound) = 1; - return compound; - } - - default: - break; - } - - /* Complain about anything else that is not a true lvalue. */ - if (!lvalue_or_else (arg, ((code == PREINCREMENT_EXPR - || code == POSTINCREMENT_EXPR) - ? "increment" : "decrement"))) - return error_mark_node; - - /* Forbid using -- on `bool'. */ - if (TREE_TYPE (arg) == boolean_type_node) - { - if (code == POSTDECREMENT_EXPR || code == PREDECREMENT_EXPR) - { - cp_error ("invalid use of `--' on bool variable `%D'", arg); - return error_mark_node; - } -#if 0 - /* This will only work if someone can convince Kenner to accept - my patch to expand_increment. (jason) */ - val = build (code, TREE_TYPE (arg), arg, inc); -#else - if (code == POSTINCREMENT_EXPR) - { - arg = stabilize_reference (arg); - val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, - boolean_true_node); - TREE_SIDE_EFFECTS (val) = 1; - arg = save_expr (arg); - val = build (COMPOUND_EXPR, TREE_TYPE (arg), val, arg); - val = build (COMPOUND_EXPR, TREE_TYPE (arg), arg, val); - } - else - val = build (MODIFY_EXPR, TREE_TYPE (arg), arg, - boolean_true_node); -#endif - } - else - val = build (code, TREE_TYPE (arg), arg, inc); - - TREE_SIDE_EFFECTS (val) = 1; - return cp_convert (result_type, val); - } - - case ADDR_EXPR: - /* Note that this operation never does default_conversion - regardless of NOCONVERT. */ - - argtype = lvalue_type (arg); - if (TREE_CODE (argtype) == REFERENCE_TYPE) - { - arg = build1 - (CONVERT_EXPR, - build_pointer_type (TREE_TYPE (argtype)), arg); - TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0)); - return arg; - } - else if (pedantic && DECL_MAIN_P (arg)) - /* ARM $3.4 */ - pedwarn ("taking address of function `main'"); - - /* Let &* cancel out to simplify resulting code. */ - if (TREE_CODE (arg) == INDIRECT_REF) - { - /* We don't need to have `current_class_ptr' wrapped in a - NON_LVALUE_EXPR node. */ - if (arg == current_class_ref) - return current_class_ptr; - - arg = TREE_OPERAND (arg, 0); - if (TREE_CODE (TREE_TYPE (arg)) == REFERENCE_TYPE) - { - arg = build1 - (CONVERT_EXPR, - build_pointer_type (TREE_TYPE (TREE_TYPE (arg))), arg); - TREE_CONSTANT (arg) = TREE_CONSTANT (TREE_OPERAND (arg, 0)); - } - else if (lvalue_p (arg)) - /* Don't let this be an lvalue. */ - return non_lvalue (arg); - return arg; - } - - /* For &x[y], return x+y */ - if (TREE_CODE (arg) == ARRAY_REF) - { - if (mark_addressable (TREE_OPERAND (arg, 0)) == 0) - return error_mark_node; - return build_binary_op (PLUS_EXPR, TREE_OPERAND (arg, 0), - TREE_OPERAND (arg, 1), 1); - } - - /* Uninstantiated types are all functions. Taking the - address of a function is a no-op, so just return the - argument. */ - - if (TREE_CODE (arg) == IDENTIFIER_NODE - && IDENTIFIER_OPNAME_P (arg)) - { - my_friendly_abort (117); - /* We don't know the type yet, so just work around the problem. - We know that this will resolve to an lvalue. */ - return build1 (ADDR_EXPR, unknown_type_node, arg); - } - - if (TREE_CODE (arg) == TEMPLATE_ID_EXPR) - { - tree targs; - tree fn; - - /* We don't require a match here; it's possible that the - context (like a cast to a particular type) will resolve - the particular choice of template. */ - fn = determine_specialization (arg, - NULL_TREE, - &targs, - 0, - 0); - - if (fn) - { - fn = instantiate_template (fn, targs); - mark_addressable (fn); - return build_unary_op (ADDR_EXPR, fn, 0); - } - - return build1 (ADDR_EXPR, unknown_type_node, arg); - } - else if (type_unknown_p (arg)) - return build1 (ADDR_EXPR, unknown_type_node, arg); - - /* Handle complex lvalues (when permitted) - by reduction to simpler cases. */ - val = unary_complex_lvalue (code, arg); - if (val != 0) - return val; - - switch (TREE_CODE (arg)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (! lvalue_p (arg) && pedantic) - pedwarn ("taking the address of a cast to non-reference type"); - break; - - default: - break; - } - - /* Allow the address of a constructor if all the elements - are constant. */ - if (TREE_CODE (arg) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (arg) - && TREE_CONSTANT (arg)) - ; - /* Anything not already handled and not a true memory reference - is an error. */ - else if (TREE_CODE (argtype) != FUNCTION_TYPE - && TREE_CODE (argtype) != METHOD_TYPE - && !lvalue_or_else (arg, "unary `&'")) - return error_mark_node; - - if (argtype != error_mark_node) - argtype = build_pointer_type (argtype); - - if (mark_addressable (arg) == 0) - return error_mark_node; - - { - tree addr; - - if (TREE_CODE (arg) == COMPONENT_REF) - addr = build_component_addr - (arg, argtype, - "attempt to take address of bit-field structure member `%s'"); - else - addr = build1 (code, argtype, arg); - - /* Address of a static or external variable or - function counts as a constant */ - if (staticp (arg)) - TREE_CONSTANT (addr) = 1; - - if (TREE_CODE (argtype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (argtype)) == METHOD_TYPE) - { - build_ptrmemfunc_type (argtype); - addr = build_ptrmemfunc (argtype, addr, 0); - } - - return addr; - } - - default: - break; - } - - if (!errstring) - { - if (argtype == 0) - argtype = TREE_TYPE (arg); - return fold (build1 (code, argtype, arg)); - } - - error (errstring); - return error_mark_node; -} - -#if 0 -/* If CONVERSIONS is a conversion expression or a nested sequence of such, - convert ARG with the same conversions in the same order - and return the result. */ - -static tree -convert_sequence (conversions, arg) - tree conversions; - tree arg; -{ - switch (TREE_CODE (conversions)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - return cp_convert (TREE_TYPE (conversions), - convert_sequence (TREE_OPERAND (conversions, 0), - arg)); - - default: - return arg; - } -} -#endif - -/* Apply unary lvalue-demanding operator CODE to the expression ARG - for certain kinds of expressions which are not really lvalues - but which we can accept as lvalues. - - If ARG is not a kind of expression we can handle, return zero. */ - -tree -unary_complex_lvalue (code, arg) - enum tree_code code; - tree arg; -{ - /* Handle (a, b) used as an "lvalue". */ - if (TREE_CODE (arg) == COMPOUND_EXPR) - { - tree real_result = build_unary_op (code, TREE_OPERAND (arg, 1), 0); - return build (COMPOUND_EXPR, TREE_TYPE (real_result), - TREE_OPERAND (arg, 0), real_result); - } - - /* Handle (a ? b : c) used as an "lvalue". */ - if (TREE_CODE (arg) == COND_EXPR - || TREE_CODE (arg) == MIN_EXPR || TREE_CODE (arg) == MAX_EXPR) - return rationalize_conditional_expr (code, arg); - - if (TREE_CODE (arg) == MODIFY_EXPR - || TREE_CODE (arg) == PREINCREMENT_EXPR - || TREE_CODE (arg) == PREDECREMENT_EXPR) - return unary_complex_lvalue - (code, build (COMPOUND_EXPR, TREE_TYPE (TREE_OPERAND (arg, 0)), - arg, TREE_OPERAND (arg, 0))); - - if (code != ADDR_EXPR) - return 0; - - /* Handle (a = b) used as an "lvalue" for `&'. */ - if (TREE_CODE (arg) == MODIFY_EXPR - || TREE_CODE (arg) == INIT_EXPR) - { - tree real_result = build_unary_op (code, TREE_OPERAND (arg, 0), 0); - arg = build (COMPOUND_EXPR, TREE_TYPE (real_result), arg, real_result); - TREE_NO_UNUSED_WARNING (arg) = 1; - return arg; - } - - if (TREE_CODE (TREE_TYPE (arg)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (arg)) == METHOD_TYPE - || TREE_CODE (TREE_TYPE (arg)) == OFFSET_TYPE) - { - /* The representation of something of type OFFSET_TYPE - is really the representation of a pointer to it. - Here give the representation its true type. */ - tree t; - - my_friendly_assert (TREE_CODE (arg) != SCOPE_REF, 313); - - if (TREE_CODE (arg) != OFFSET_REF) - return 0; - - t = TREE_OPERAND (arg, 1); - - /* Check all this code for right semantics. */ - if (TREE_CODE (t) == FUNCTION_DECL) - { - if (DECL_DESTRUCTOR_P (t)) - cp_error ("taking address of destructor"); - return build_unary_op (ADDR_EXPR, t, 0); - } - if (TREE_CODE (t) == VAR_DECL) - return build_unary_op (ADDR_EXPR, t, 0); - else - { - tree type; - - if (TREE_OPERAND (arg, 0) - && ! is_dummy_object (TREE_OPERAND (arg, 0)) - && TREE_CODE (t) != FIELD_DECL) - { - cp_error ("taking address of bound pointer-to-member expression"); - return error_mark_node; - } - - type = build_offset_type (DECL_FIELD_CONTEXT (t), TREE_TYPE (t)); - type = build_pointer_type (type); - - t = make_node (PTRMEM_CST); - TREE_TYPE (t) = type; - PTRMEM_CST_MEMBER (t) = TREE_OPERAND (arg, 1); - return t; - } - } - - - /* We permit compiler to make function calls returning - objects of aggregate type look like lvalues. */ - { - tree targ = arg; - - if (TREE_CODE (targ) == SAVE_EXPR) - targ = TREE_OPERAND (targ, 0); - - if (TREE_CODE (targ) == CALL_EXPR && IS_AGGR_TYPE (TREE_TYPE (targ))) - { - if (TREE_CODE (arg) == SAVE_EXPR) - targ = arg; - else - targ = build_cplus_new (TREE_TYPE (arg), arg); - return build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (arg)), targ); - } - - if (TREE_CODE (arg) == SAVE_EXPR && TREE_CODE (targ) == INDIRECT_REF) - return build (SAVE_EXPR, build_pointer_type (TREE_TYPE (arg)), - TREE_OPERAND (targ, 0), current_function_decl, NULL); - } - - /* Don't let anything else be handled specially. */ - return 0; -} - -/* Mark EXP saying that we need to be able to take the - address of it; it should not be allocated in a register. - Value is 1 if successful. - - C++: we do not allow `current_class_ptr' to be addressable. */ - -int -mark_addressable (exp) - tree exp; -{ - register tree x = exp; - - if (TREE_ADDRESSABLE (x) == 1) - return 1; - - while (1) - switch (TREE_CODE (x)) - { - case ADDR_EXPR: - case COMPONENT_REF: - case ARRAY_REF: - case REALPART_EXPR: - case IMAGPART_EXPR: - x = TREE_OPERAND (x, 0); - break; - - case PARM_DECL: - if (x == current_class_ptr) - { - if (! flag_this_is_variable) - error ("address of `this' not available"); - TREE_ADDRESSABLE (x) = 1; /* so compiler doesn't die later */ - put_var_into_stack (x); - return 1; - } - case VAR_DECL: - if (TREE_STATIC (x) && TREE_READONLY (x) - && DECL_RTL (x) != 0 - && ! DECL_IN_MEMORY_P (x)) - { - /* We thought this would make a good constant variable, - but we were wrong. */ - push_obstacks_nochange (); - end_temporary_allocation (); - - TREE_ASM_WRITTEN (x) = 0; - DECL_RTL (x) = 0; - rest_of_decl_compilation (x, 0, - !DECL_FUNCTION_SCOPE_P (x), - 0); - TREE_ADDRESSABLE (x) = 1; - - pop_obstacks (); - - return 1; - } - /* Caller should not be trying to mark initialized - constant fields addressable. */ - my_friendly_assert (DECL_LANG_SPECIFIC (x) == 0 - || DECL_IN_AGGR_P (x) == 0 - || TREE_STATIC (x) - || DECL_EXTERNAL (x), 314); - - case CONST_DECL: - case RESULT_DECL: - if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) - && !DECL_ARTIFICIAL (x) && extra_warnings) - cp_warning ("address requested for `%D', which is declared `register'", - x); - put_var_into_stack (x); - TREE_ADDRESSABLE (x) = 1; - return 1; - - case FUNCTION_DECL: - if (DECL_LANG_SPECIFIC (x) != 0) - { - x = DECL_MAIN_VARIANT (x); - /* We have to test both conditions here. The first may be - non-zero in the case of processing a default function. The - second may be non-zero in the case of a template function. */ - if (DECL_TEMPLATE_INFO (x) && !DECL_TEMPLATE_SPECIALIZATION (x)) - mark_used (x); - } - TREE_ADDRESSABLE (x) = 1; - TREE_USED (x) = 1; - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; - return 1; - - case CONSTRUCTOR: - TREE_ADDRESSABLE (x) = 1; - return 1; - - case TARGET_EXPR: - TREE_ADDRESSABLE (x) = 1; - mark_addressable (TREE_OPERAND (x, 0)); - return 1; - - default: - return 1; - } -} - -/* Build and return a conditional expression IFEXP ? OP1 : OP2. */ - -tree -build_x_conditional_expr (ifexp, op1, op2) - tree ifexp, op1, op2; -{ - if (processing_template_decl) - return build_min_nt (COND_EXPR, ifexp, op1, op2); - - return build_new_op (COND_EXPR, LOOKUP_NORMAL, ifexp, op1, op2); -} - -tree -build_conditional_expr (ifexp, op1, op2) - tree ifexp, op1, op2; -{ - register tree type1; - register tree type2; - register enum tree_code code1; - register enum tree_code code2; - register tree result_type = NULL_TREE; - - /* If second operand is omitted, it is the same as the first one; - make sure it is calculated only once. */ - if (op1 == 0) - { - if (pedantic) - pedwarn ("ANSI C++ forbids omitting the middle term of a ?: expression"); - ifexp = op1 = save_expr (ifexp); - } - - ifexp = cp_convert (boolean_type_node, ifexp); - - if (TREE_CODE (ifexp) == ERROR_MARK) - return error_mark_node; - - /* C++: REFERENCE_TYPES must be dereferenced. */ - type1 = TREE_TYPE (op1); - code1 = TREE_CODE (type1); - type2 = TREE_TYPE (op2); - code2 = TREE_CODE (type2); - - if (code1 == REFERENCE_TYPE) - { - op1 = convert_from_reference (op1); - type1 = TREE_TYPE (op1); - code1 = TREE_CODE (type1); - } - if (code2 == REFERENCE_TYPE) - { - op2 = convert_from_reference (op2); - type2 = TREE_TYPE (op2); - code2 = TREE_CODE (type2); - } - - /* Don't promote the operands separately if they promote - the same way. Return the unpromoted type and let the combined - value get promoted if necessary. */ - - if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2) - && code2 != ARRAY_TYPE - && code2 != FUNCTION_TYPE - && code2 != METHOD_TYPE) - { - tree result; - - if (TREE_CONSTANT (ifexp) - && (TREE_CODE (ifexp) == INTEGER_CST - || TREE_CODE (ifexp) == ADDR_EXPR)) - return (integer_zerop (ifexp) ? op2 : op1); - - if (TREE_CODE (op1) == CONST_DECL) - op1 = DECL_INITIAL (op1); - else if (TREE_READONLY_DECL_P (op1)) - op1 = decl_constant_value (op1); - if (TREE_CODE (op2) == CONST_DECL) - op2 = DECL_INITIAL (op2); - else if (TREE_READONLY_DECL_P (op2)) - op2 = decl_constant_value (op2); - if (type1 != type2) - type1 = cp_build_qualified_type - (type1, (CP_TYPE_QUALS (TREE_TYPE (op1)) - | CP_TYPE_QUALS (TREE_TYPE (op2)))); - /* ??? This is a kludge to deal with the fact that - we don't sort out integers and enums properly, yet. */ - result = fold (build (COND_EXPR, type1, ifexp, op1, op2)); - if (TREE_TYPE (result) != type1) - result = build1 (NOP_EXPR, type1, result); - /* Expand both sides into the same slot, - hopefully the target of the ?: expression. */ - if (TREE_CODE (op1) == TARGET_EXPR && TREE_CODE (op2) == TARGET_EXPR) - { - tree slot = build (VAR_DECL, TREE_TYPE (result)); - layout_decl (slot, 0); - result = build (TARGET_EXPR, TREE_TYPE (result), - slot, result, NULL_TREE, NULL_TREE); - } - return result; - } - - /* They don't match; promote them both and then try to reconcile them. - But don't permit mismatching enum types. */ - if (code1 == ENUMERAL_TYPE) - { - if (code2 == ENUMERAL_TYPE) - { - cp_error ("enumeral mismatch in conditional expression: `%T' vs `%T'", - type1, type2); - return error_mark_node; - } - else if (extra_warnings && ! IS_AGGR_TYPE_CODE (code2) - && type2 != type_promotes_to (type1)) - warning ("enumeral and non-enumeral type in conditional expression"); - } - else if (extra_warnings - && code2 == ENUMERAL_TYPE && ! IS_AGGR_TYPE_CODE (code1) - && type1 != type_promotes_to (type2)) - warning ("enumeral and non-enumeral type in conditional expression"); - - if (code1 != VOID_TYPE) - { - op1 = default_conversion (op1); - type1 = TREE_TYPE (op1); - if (TYPE_PTRMEMFUNC_P (type1)) - type1 = TYPE_PTRMEMFUNC_FN_TYPE (type1); - code1 = TREE_CODE (type1); - } - if (code2 != VOID_TYPE) - { - op2 = default_conversion (op2); - type2 = TREE_TYPE (op2); - if (TYPE_PTRMEMFUNC_P (type2)) - type2 = TYPE_PTRMEMFUNC_FN_TYPE (type2); - code2 = TREE_CODE (type2); - } - - if (code1 == RECORD_TYPE && code2 == RECORD_TYPE - && real_lvalue_p (op1) && real_lvalue_p (op2) - && comptypes (type1, type2, COMPARE_BASE | COMPARE_RELAXED)) - { - type1 = build_reference_type (type1); - type2 = build_reference_type (type2); - result_type = common_type (type1, type2); - op1 = convert_to_reference (result_type, op1, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); - op2 = convert_to_reference (result_type, op2, CONV_IMPLICIT, - LOOKUP_NORMAL, NULL_TREE); - } - /* Quickly detect the usual case where op1 and op2 have the same type - after promotion. */ - else if (TYPE_MAIN_VARIANT (type1) == TYPE_MAIN_VARIANT (type2)) - { - if (type1 == type2) - result_type = type1; - else - result_type = - cp_build_qualified_type (type1, - CP_TYPE_QUALS (TREE_TYPE (op1)) - | CP_TYPE_QUALS (TREE_TYPE (op2))); - } - else if ((code1 == INTEGER_TYPE || code1 == REAL_TYPE) - && (code2 == INTEGER_TYPE || code2 == REAL_TYPE)) - { - result_type = common_type (type1, type2); - } - else if (code1 == VOID_TYPE || code2 == VOID_TYPE) - { - if (pedantic && (code1 != VOID_TYPE || code2 != VOID_TYPE)) - pedwarn ("ANSI C++ forbids conditional expr with only one void side"); - result_type = void_type_node; - } - else if (code1 == POINTER_TYPE && null_ptr_cst_p (op2)) - result_type = qualify_type (type1, type2); - else if (code2 == POINTER_TYPE && null_ptr_cst_p (op1)) - result_type = qualify_type (type2, type1); - else if (code1 == POINTER_TYPE && code2 == POINTER_TYPE) - { - if (comp_target_types (type1, type2, 1)) - result_type = common_type (type1, type2); - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type1)) == void_type_node) - { - if (pedantic && TREE_CODE (type2) == FUNCTION_TYPE) - pedwarn ("ANSI C++ forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type1, type2); - } - else if (TYPE_MAIN_VARIANT (TREE_TYPE (type2)) == void_type_node) - { - if (pedantic && TREE_CODE (type1) == FUNCTION_TYPE) - pedwarn ("ANSI C++ forbids conditional expr between `void *' and function pointer"); - result_type = qualify_type (type2, type1); - } - /* C++ */ - else if (same_or_base_type_p (type2, type1)) - result_type = type2; - else if (IS_AGGR_TYPE (TREE_TYPE (type1)) - && IS_AGGR_TYPE (TREE_TYPE (type2)) - && (result_type = common_base_type (TREE_TYPE (type1), - TREE_TYPE (type2)))) - { - if (result_type == error_mark_node) - { - cp_error ("common base type of types `%T' and `%T' is ambiguous", - TREE_TYPE (type1), TREE_TYPE (type2)); - result_type = ptr_type_node; - } - else - { - if (pedantic - && result_type != TREE_TYPE (type1) - && result_type != TREE_TYPE (type2)) - cp_pedwarn ("`%T' and `%T' converted to `%T *' in conditional expression", - type1, type2, result_type); - - result_type = build_pointer_type (result_type); - } - } - else - { - pedwarn ("pointer type mismatch in conditional expression"); - result_type = ptr_type_node; - } - } - else if (code1 == POINTER_TYPE && code2 == INTEGER_TYPE) - { - pedwarn ("pointer/integer type mismatch in conditional expression"); - result_type = type1; - } - else if (code2 == POINTER_TYPE && code1 == INTEGER_TYPE) - { - pedwarn ("pointer/integer type mismatch in conditional expression"); - result_type = type2; - } - if (type2 == unknown_type_node) - result_type = type1; - else if (type1 == unknown_type_node) - result_type = type2; - - if (!result_type) - { - /* The match does not look good. If either is - an aggregate value, try converting to a scalar type. */ - if (code1 == RECORD_TYPE && code2 == RECORD_TYPE) - { - cp_error ("aggregate mismatch in conditional expression: `%T' vs `%T'", - type1, type2); - return error_mark_node; - } - /* Warning: this code assumes that conversion between cv-variants of - a type is done using NOP_EXPRs. */ - if (code1 == RECORD_TYPE && TYPE_HAS_CONVERSION (type1)) - { - /* There are other types besides pointers and records. */ - tree tmp; - if (code2 == POINTER_TYPE) - tmp = build_pointer_type - (cp_build_qualified_type (TREE_TYPE (type2), - TYPE_QUAL_CONST - | TYPE_QUAL_VOLATILE - | TYPE_QUAL_RESTRICT)); - else - tmp = type2; - tmp = build_type_conversion (CONVERT_EXPR, tmp, op1, 0); - if (tmp == NULL_TREE) - { - cp_error ("incompatible types `%T' and `%T' in `?:'", - type1, type2); - return error_mark_node; - } - if (tmp == error_mark_node) - error ("ambiguous pointer conversion"); - else - STRIP_NOPS (tmp); - result_type = common_type (type2, TREE_TYPE (tmp)); - op1 = tmp; - } - else if (code2 == RECORD_TYPE && TYPE_HAS_CONVERSION (type2)) - { - tree tmp; - if (code1 == POINTER_TYPE) - tmp = build_pointer_type - (cp_build_qualified_type (TREE_TYPE (type1), - TYPE_QUAL_CONST - | TYPE_QUAL_VOLATILE - | TYPE_QUAL_RESTRICT)); - else - tmp = type1; - - tmp = build_type_conversion (CONVERT_EXPR, tmp, op2, 0); - if (tmp == NULL_TREE) - { - cp_error ("incompatible types `%T' and `%T' in `?:'", - type1, type2); - return error_mark_node; - } - if (tmp == error_mark_node) - error ("ambiguous pointer conversion"); - else - STRIP_NOPS (tmp); - result_type = common_type (type1, TREE_TYPE (tmp)); - op2 = tmp; - } - else if (flag_cond_mismatch) - result_type = void_type_node; - else - { - error ("type mismatch in conditional expression"); - return error_mark_node; - } - } - - if (TREE_CODE (result_type) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (result_type)) == METHOD_TYPE) - result_type = build_ptrmemfunc_type (result_type); - - if (result_type != TREE_TYPE (op1)) - op1 = convert_for_initialization - (NULL_TREE, result_type, op1, LOOKUP_NORMAL, "converting", NULL_TREE, 0); - if (result_type != TREE_TYPE (op2)) - op2 = convert_for_initialization - (NULL_TREE, result_type, op2, LOOKUP_NORMAL, "converting", NULL_TREE, 0); - - if (TREE_CODE (ifexp) == INTEGER_CST) - return integer_zerop (ifexp) ? op2 : op1; - - return convert_from_reference - (fold (build (COND_EXPR, result_type, ifexp, op1, op2))); -} - -/* Handle overloading of the ',' operator when needed. Otherwise, - this function just builds an expression list. */ - -tree -build_x_compound_expr (list) - tree list; -{ - tree rest = TREE_CHAIN (list); - tree result; - - if (processing_template_decl) - return build_min_nt (COMPOUND_EXPR, list, NULL_TREE); - - if (rest == NULL_TREE) - return build_compound_expr (list); - - result = build_opfncall (COMPOUND_EXPR, LOOKUP_NORMAL, - TREE_VALUE (list), TREE_VALUE (rest), NULL_TREE); - if (result) - return build_x_compound_expr (expr_tree_cons (NULL_TREE, result, - TREE_CHAIN (rest))); - - if (! TREE_SIDE_EFFECTS (TREE_VALUE (list))) - { - /* the left-hand operand of a comma expression is like an expression - statement: we should warn if it doesn't have any side-effects, - unless it was explicitly cast to (void). */ - if ((extra_warnings || warn_unused) - && !(TREE_CODE (TREE_VALUE(list)) == CONVERT_EXPR - && TREE_TYPE (TREE_VALUE(list)) == void_type_node)) - warning("left-hand operand of comma expression has no effect"); - } -#if 0 /* this requires a gcc backend patch to export warn_if_unused_value */ - else if (warn_unused) - warn_if_unused_value (TREE_VALUE(list)); -#endif - - return build_compound_expr - (expr_tree_cons (NULL_TREE, TREE_VALUE (list), - build_expr_list (NULL_TREE, - build_x_compound_expr (rest)))); -} - -/* Given a list of expressions, return a compound expression - that performs them all and returns the value of the last of them. */ - -tree -build_compound_expr (list) - tree list; -{ - register tree rest; - - if (TREE_READONLY_DECL_P (TREE_VALUE (list))) - TREE_VALUE (list) = decl_constant_value (TREE_VALUE (list)); - - if (TREE_CHAIN (list) == 0) - { - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs, since LIST is used in non-lvalue context. */ - if (TREE_CODE (list) == NOP_EXPR - && TREE_TYPE (list) == TREE_TYPE (TREE_OPERAND (list, 0))) - list = TREE_OPERAND (list, 0); - - /* Convert arrays to pointers. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (list))) == ARRAY_TYPE) - return default_conversion (TREE_VALUE (list)); - else - return TREE_VALUE (list); - } - - rest = build_compound_expr (TREE_CHAIN (list)); - - /* When pedantic, a compound expression cannot be a constant expression. */ - if (! TREE_SIDE_EFFECTS (TREE_VALUE (list)) && ! pedantic) - return rest; - - return build (COMPOUND_EXPR, TREE_TYPE (rest), - break_out_cleanups (TREE_VALUE (list)), rest); -} - -tree -build_static_cast (type, expr) - tree type, expr; -{ - tree intype, binfo; - int ok; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - if (TREE_CODE (expr) == OFFSET_REF) - expr = resolve_offset_ref (expr); - - if (processing_template_decl) - { - tree t = build_min (STATIC_CAST_EXPR, copy_to_permanent (type), - expr); - return t; - } - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ - if (TREE_CODE (type) != REFERENCE_TYPE - && TREE_CODE (expr) == NOP_EXPR - && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 0); - - if (TREE_CODE (type) == VOID_TYPE) - return build1 (CONVERT_EXPR, type, expr); - - if (TREE_CODE (type) == REFERENCE_TYPE) - return (convert_from_reference - (convert_to_reference (type, expr, CONV_STATIC|CONV_IMPLICIT, - LOOKUP_COMPLAIN, NULL_TREE))); - - if (IS_AGGR_TYPE (type)) - return build_cplus_new - (type, (build_method_call - (NULL_TREE, ctor_identifier, build_expr_list (NULL_TREE, expr), - TYPE_BINFO (type), LOOKUP_NORMAL))); - - expr = decay_conversion (expr); - intype = TREE_TYPE (expr); - - /* FIXME handle casting to array type. */ - - ok = 0; - if (can_convert_arg (type, intype, expr)) - ok = 1; - else if (TYPE_PTROB_P (type) && TYPE_PTROB_P (intype)) - { - tree binfo; - if (IS_AGGR_TYPE (TREE_TYPE (type)) && IS_AGGR_TYPE (TREE_TYPE (intype)) - && at_least_as_qualified_p (TREE_TYPE (type), - TREE_TYPE (intype)) - && (binfo = get_binfo (TREE_TYPE (intype), TREE_TYPE (type), 0)) - && ! TREE_VIA_VIRTUAL (binfo)) - ok = 1; - } - else if (TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) - { - if (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (type))), - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (intype)))) - && at_least_as_qualified_p (TREE_TYPE (TREE_TYPE (type)), - TREE_TYPE (TREE_TYPE (intype))) - && (binfo = get_binfo (TYPE_OFFSET_BASETYPE (TREE_TYPE (type)), - TYPE_OFFSET_BASETYPE (TREE_TYPE (intype)), 0)) - && ! TREE_VIA_VIRTUAL (binfo)) - ok = 1; - } - else if (TREE_CODE (intype) != BOOLEAN_TYPE - && TREE_CODE (type) != ARRAY_TYPE - && TREE_CODE (type) != FUNCTION_TYPE - && can_convert (intype, type)) - ok = 1; - - if (ok) - return build_c_cast (type, expr); - - cp_error ("static_cast from `%T' to `%T'", intype, type); - return error_mark_node; -} - -tree -build_reinterpret_cast (type, expr) - tree type, expr; -{ - tree intype; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - if (TREE_CODE (expr) == OFFSET_REF) - expr = resolve_offset_ref (expr); - - if (processing_template_decl) - { - tree t = build_min (REINTERPRET_CAST_EXPR, - copy_to_permanent (type), expr); - return t; - } - - if (TREE_CODE (type) != REFERENCE_TYPE) - { - expr = decay_conversion (expr); - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ - if (TREE_CODE (expr) == NOP_EXPR - && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 0); - } - - intype = TREE_TYPE (expr); - - if (TREE_CODE (type) == REFERENCE_TYPE) - { - if (! real_lvalue_p (expr)) - { - cp_error ("reinterpret_cast from `%T' rvalue to `%T'", intype, type); - return error_mark_node; - } - expr = build_unary_op (ADDR_EXPR, expr, 0); - if (expr != error_mark_node) - expr = build_reinterpret_cast - (build_pointer_type (TREE_TYPE (type)), expr); - if (expr != error_mark_node) - expr = build_indirect_ref (expr, 0); - return expr; - } - else if (same_type_p (TYPE_MAIN_VARIANT (intype), - TYPE_MAIN_VARIANT (type))) - return build_static_cast (type, expr); - - if (TYPE_PTR_P (type) && (TREE_CODE (intype) == INTEGER_TYPE - || TREE_CODE (intype) == ENUMERAL_TYPE)) - /* OK */; - else if (TREE_CODE (type) == INTEGER_TYPE && TYPE_PTR_P (intype)) - { - if (TYPE_PRECISION (type) < TYPE_PRECISION (intype)) - cp_pedwarn ("reinterpret_cast from `%T' to `%T' loses precision", - intype, type); - } - else if ((TYPE_PTRFN_P (type) && TYPE_PTRFN_P (intype)) - || (TYPE_PTRMEMFUNC_P (type) && TYPE_PTRMEMFUNC_P (intype))) - { - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return fold (build1 (NOP_EXPR, type, expr)); - } - else if ((TYPE_PTRMEM_P (type) && TYPE_PTRMEM_P (intype)) - || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype))) - { - if (! comp_ptr_ttypes_reinterpret (TREE_TYPE (type), TREE_TYPE (intype))) - cp_pedwarn ("reinterpret_cast from `%T' to `%T' casts away const (or volatile)", - intype, type); - - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return fold (build1 (NOP_EXPR, type, expr)); - } - else if ((TYPE_PTRFN_P (type) && TYPE_PTROBV_P (intype)) - || (TYPE_PTRFN_P (intype) && TYPE_PTROBV_P (type))) - { - pedwarn ("ANSI C++ forbids casting between pointers to functions and objects"); - if (TREE_READONLY_DECL_P (expr)) - expr = decl_constant_value (expr); - return fold (build1 (NOP_EXPR, type, expr)); - } - else - { - cp_error ("reinterpret_cast from `%T' to `%T'", intype, type); - return error_mark_node; - } - - return cp_convert (type, expr); -} - -tree -build_const_cast (type, expr) - tree type, expr; -{ - tree intype; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - if (TREE_CODE (expr) == OFFSET_REF) - expr = resolve_offset_ref (expr); - - if (processing_template_decl) - { - tree t = build_min (CONST_CAST_EXPR, copy_to_permanent (type), - expr); - return t; - } - - if (TREE_CODE (type) != REFERENCE_TYPE) - { - expr = decay_conversion (expr); - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ - if (TREE_CODE (expr) == NOP_EXPR - && TREE_TYPE (expr) == TREE_TYPE (TREE_OPERAND (expr, 0))) - expr = TREE_OPERAND (expr, 0); - } - - intype = TREE_TYPE (expr); - - if (same_type_p (TYPE_MAIN_VARIANT (intype), TYPE_MAIN_VARIANT (type))) - return build_static_cast (type, expr); - else if (TREE_CODE (type) == REFERENCE_TYPE) - { - if (! real_lvalue_p (expr)) - { - cp_error ("const_cast from `%T' rvalue to `%T'", intype, type); - return error_mark_node; - } - - if (comp_ptr_ttypes_const (TREE_TYPE (type), intype)) - { - expr = build_unary_op (ADDR_EXPR, expr, 0); - expr = build1 (NOP_EXPR, type, expr); - return convert_from_reference (expr); - } - } - else if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (intype) == POINTER_TYPE - && comp_ptr_ttypes_const (TREE_TYPE (type), TREE_TYPE (intype))) - return cp_convert (type, expr); - - cp_error ("const_cast from `%T' to `%T'", intype, type); - return error_mark_node; -} - -/* Build an expression representing a cast to type TYPE of expression EXPR. - - ALLOW_NONCONVERTING is true if we should allow non-converting constructors - when doing the cast. */ - -tree -build_c_cast (type, expr) - tree type, expr; -{ - register tree value = expr; - tree otype; - - if (type == error_mark_node || expr == error_mark_node) - return error_mark_node; - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs if VALUE is being used in non-lvalue context. */ - if (TREE_CODE (type) != REFERENCE_TYPE - && TREE_CODE (value) == NOP_EXPR - && TREE_TYPE (value) == TREE_TYPE (TREE_OPERAND (value, 0))) - value = TREE_OPERAND (value, 0); - - if (TREE_TYPE (expr) - && TREE_CODE (TREE_TYPE (expr)) == OFFSET_TYPE - && TREE_CODE (type) != OFFSET_TYPE) - value = resolve_offset_ref (value); - - if (TREE_CODE (type) == ARRAY_TYPE) - { - /* Allow casting from T1* to T2[] because Cfront allows it. - NIHCL uses it. It is not valid ANSI C however, and hence, not - valid ANSI C++. */ - if (TREE_CODE (TREE_TYPE (expr)) == POINTER_TYPE) - { - if (pedantic) - pedwarn ("ANSI C++ forbids casting to an array type"); - type = build_pointer_type (TREE_TYPE (type)); - } - else - { - error ("ANSI C++ forbids casting to an array type"); - return error_mark_node; - } - } - - if (TREE_CODE (type) == FUNCTION_TYPE - || TREE_CODE (type) == METHOD_TYPE) - { - cp_error ("casting to function type `%T'", type); - return error_mark_node; - } - - if (IS_SIGNATURE (type)) - { - error ("cast specifies signature type"); - return error_mark_node; - } - - if (processing_template_decl) - { - tree t = build_min (CAST_EXPR, type, - min_tree_cons (NULL_TREE, value, NULL_TREE)); - return t; - } - - /* Convert functions and arrays to pointers and - convert references to their expanded types, - but don't convert any other types. If, however, we are - casting to a class type, there's no reason to do this: the - cast will only succeed if there is a converting constructor, - and the default conversions will be done at that point. In - fact, doing the default conversion here is actually harmful - in cases like this: - - typedef int A[2]; - struct S { S(const A&); }; - - since we don't want the array-to-pointer conversion done. */ - if (!IS_AGGR_TYPE (type)) - { - if (TREE_CODE (TREE_TYPE (value)) == FUNCTION_TYPE - || (TREE_CODE (TREE_TYPE (value)) == METHOD_TYPE - /* Don't do the default conversion on a ->* expression. */ - && ! (TREE_CODE (type) == POINTER_TYPE - && bound_pmf_p (value))) - || TREE_CODE (TREE_TYPE (value)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE) - value = default_conversion (value); - } - else if (TREE_CODE (TREE_TYPE (value)) == REFERENCE_TYPE) - /* However, even for class types, we still need to strip away - the reference type, since the call to convert_force below - does not expect the input expression to be of reference - type. */ - value = convert_from_reference (value); - - otype = TREE_TYPE (value); - - /* Optionally warn about potentially worrisome casts. */ - - if (warn_cast_qual - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && !at_least_as_qualified_p (TREE_TYPE (type), - TREE_TYPE (otype))) - cp_warning ("cast discards qualifiers from pointer target type"); - - /* Warn about possible alignment problems. */ - if (STRICT_ALIGNMENT && warn_cast_align - && TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (otype)) != VOID_TYPE - && TREE_CODE (TREE_TYPE (otype)) != FUNCTION_TYPE - && TYPE_ALIGN (TREE_TYPE (type)) > TYPE_ALIGN (TREE_TYPE (otype))) - warning ("cast increases required alignment of target type"); - -#if 0 - /* We should see about re-enabling these, they seem useful to - me. */ - if (TREE_CODE (type) == INTEGER_TYPE - && TREE_CODE (otype) == POINTER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype)) - warning ("cast from pointer to integer of different size"); - - if (TREE_CODE (type) == POINTER_TYPE - && TREE_CODE (otype) == INTEGER_TYPE - && TYPE_PRECISION (type) != TYPE_PRECISION (otype) - /* Don't warn about converting 0 to pointer, - provided the 0 was explicit--not cast or made by folding. */ - && !(TREE_CODE (value) == INTEGER_CST && integer_zerop (value))) - warning ("cast to pointer from integer of different size"); -#endif - - if (TREE_CODE (type) == REFERENCE_TYPE) - value = (convert_from_reference - (convert_to_reference (type, value, CONV_C_CAST, - LOOKUP_COMPLAIN, NULL_TREE))); - else - { - tree ovalue; - - if (TREE_READONLY_DECL_P (value)) - value = decl_constant_value (value); - - ovalue = value; - value = convert_force (type, value, CONV_C_CAST); - - /* Ignore any integer overflow caused by the cast. */ - if (TREE_CODE (value) == INTEGER_CST) - { - TREE_OVERFLOW (value) = TREE_OVERFLOW (ovalue); - TREE_CONSTANT_OVERFLOW (value) = TREE_CONSTANT_OVERFLOW (ovalue); - } - } - - /* Always produce some operator for an explicit cast, - so we can tell (for -pedantic) that the cast is no lvalue. */ - if (TREE_CODE (type) != REFERENCE_TYPE && value == expr - && real_lvalue_p (value)) - value = non_lvalue (value); - - return value; -} - -/* Build an assignment expression of lvalue LHS from value RHS. - MODIFYCODE is the code for a binary operator that we use - to combine the old value of LHS with RHS to get the new value. - Or else MODIFYCODE is NOP_EXPR meaning do a simple assignment. - - C++: If MODIFYCODE is INIT_EXPR, then leave references unbashed. */ - -tree -build_modify_expr (lhs, modifycode, rhs) - tree lhs; - enum tree_code modifycode; - tree rhs; -{ - register tree result; - tree newrhs = rhs; - tree lhstype = TREE_TYPE (lhs); - tree olhstype = lhstype; - tree olhs = lhs; - - /* Avoid duplicate error messages from operands that had errors. */ - if (lhs == error_mark_node || rhs == error_mark_node) - return error_mark_node; - - /* Types that aren't fully specified cannot be used in assignments. */ - lhs = require_complete_type (lhs); - - newrhs = rhs; - - /* Handle assignment to signature pointers/refs. */ - - if (TYPE_LANG_SPECIFIC (lhstype) - && (IS_SIGNATURE_POINTER (lhstype) || IS_SIGNATURE_REFERENCE (lhstype))) - { - return build_signature_pointer_constructor (lhs, rhs); - } - - /* Handle control structure constructs used as "lvalues". */ - - switch (TREE_CODE (lhs)) - { - /* Handle --foo = 5; as these are valid constructs in C++ */ - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - if (TREE_SIDE_EFFECTS (TREE_OPERAND (lhs, 0))) - lhs = build (TREE_CODE (lhs), TREE_TYPE (lhs), - stabilize_reference (TREE_OPERAND (lhs, 0)), - TREE_OPERAND (lhs, 1)); - return build (COMPOUND_EXPR, lhstype, - lhs, - build_modify_expr (TREE_OPERAND (lhs, 0), - modifycode, rhs)); - - /* Handle (a, b) used as an "lvalue". */ - case COMPOUND_EXPR: - newrhs = build_modify_expr (TREE_OPERAND (lhs, 1), - modifycode, rhs); - if (newrhs == error_mark_node) - return error_mark_node; - return build (COMPOUND_EXPR, lhstype, - TREE_OPERAND (lhs, 0), newrhs); - - case MODIFY_EXPR: - newrhs = build_modify_expr (TREE_OPERAND (lhs, 0), modifycode, rhs); - if (newrhs == error_mark_node) - return error_mark_node; - return build (COMPOUND_EXPR, lhstype, lhs, newrhs); - - /* Handle (a ? b : c) used as an "lvalue". */ - case COND_EXPR: - rhs = save_expr (rhs); - { - /* Produce (a ? (b = rhs) : (c = rhs)) - except that the RHS goes through a save-expr - so the code to compute it is only emitted once. */ - tree cond - = build_conditional_expr (TREE_OPERAND (lhs, 0), - build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 1)), - modifycode, rhs), - build_modify_expr (cp_convert (TREE_TYPE (lhs), TREE_OPERAND (lhs, 2)), - modifycode, rhs)); - if (cond == error_mark_node) - return cond; - /* Make sure the code to compute the rhs comes out - before the split. */ - return build (COMPOUND_EXPR, TREE_TYPE (lhs), - /* Case to void to suppress warning - from warn_if_unused_value. */ - cp_convert (void_type_node, rhs), cond); - } - - default: - break; - } - - if (TREE_CODE (lhs) == OFFSET_REF) - { - if (TREE_OPERAND (lhs, 0) == NULL_TREE) - { - /* Static class member? */ - tree member = TREE_OPERAND (lhs, 1); - if (TREE_CODE (member) == VAR_DECL) - lhs = member; - else - { - compiler_error ("invalid static class member"); - return error_mark_node; - } - } - else - lhs = resolve_offset_ref (lhs); - - olhstype = lhstype = TREE_TYPE (lhs); - } - - if (TREE_CODE (lhstype) == REFERENCE_TYPE - && modifycode != INIT_EXPR) - { - lhs = convert_from_reference (lhs); - olhstype = lhstype = TREE_TYPE (lhs); - } - - /* If a binary op has been requested, combine the old LHS value with the RHS - producing the value we should actually store into the LHS. */ - - if (modifycode == INIT_EXPR) - { - if (! IS_AGGR_TYPE (lhstype)) - /* Do the default thing */; - else - { - result = build_method_call (lhs, ctor_identifier, - build_expr_list (NULL_TREE, rhs), - TYPE_BINFO (lhstype), LOOKUP_NORMAL); - if (result == NULL_TREE) - return error_mark_node; - return result; - } - } - else if (modifycode == NOP_EXPR) - { - /* `operator=' is not an inheritable operator. */ - if (! IS_AGGR_TYPE (lhstype)) - /* Do the default thing */; - else - { - result = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, - lhs, rhs, make_node (NOP_EXPR)); - if (result == NULL_TREE) - return error_mark_node; - return result; - } - lhstype = olhstype; - } - else if (PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE)) - { - my_friendly_abort (978652); - } - else - { - lhs = stabilize_reference (lhs); - newrhs = build_binary_op (modifycode, lhs, rhs, 1); - if (newrhs == error_mark_node) - { - cp_error (" in evaluation of `%Q(%#T, %#T)'", modifycode, - TREE_TYPE (lhs), TREE_TYPE (rhs)); - return error_mark_node; - } - } - - /* Handle a cast used as an "lvalue". - We have already performed any binary operator using the value as cast. - Now convert the result to the cast type of the lhs, - and then true type of the lhs and store it there; - then convert result back to the cast type to be the value - of the assignment. */ - - switch (TREE_CODE (lhs)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - if (TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE - || TREE_CODE (TREE_TYPE (newrhs)) == FUNCTION_TYPE - || TREE_CODE (TREE_TYPE (newrhs)) == METHOD_TYPE - || TREE_CODE (TREE_TYPE (newrhs)) == OFFSET_TYPE) - newrhs = default_conversion (newrhs); - { - tree inner_lhs = TREE_OPERAND (lhs, 0); - tree result; - - /* WP 5.4.1: The result is an lvalue if T is a reference type, - otherwise the result is an rvalue. */ - if (! lvalue_p (lhs)) - pedwarn ("ANSI C++ forbids cast to non-reference type used as lvalue"); - - result = build_modify_expr (inner_lhs, NOP_EXPR, - cp_convert (TREE_TYPE (inner_lhs), - cp_convert (lhstype, newrhs))); - if (result == error_mark_node) - return result; - return cp_convert (TREE_TYPE (lhs), result); - } - - default: - break; - } - - /* Now we have handled acceptable kinds of LHS that are not truly lvalues. - Reject anything strange now. */ - - if (!lvalue_or_else (lhs, "assignment")) - return error_mark_node; - - GNU_xref_assign (lhs); - - /* Warn about storing in something that is `const'. */ - /* For C++, don't warn if this is initialization. */ - if (modifycode != INIT_EXPR - /* For assignment to `const' signature pointer/reference fields, - don't warn either, we already printed a better message before. */ - && ! (TREE_CODE (lhs) == COMPONENT_REF - && (IS_SIGNATURE_POINTER (TREE_TYPE (TREE_OPERAND (lhs, 0))) - || IS_SIGNATURE_REFERENCE (TREE_TYPE (TREE_OPERAND (lhs, 0))))) - && (TREE_READONLY (lhs) || CP_TYPE_CONST_P (lhstype) - /* Functions are not modifiable, even though they are - lvalues. */ - || TREE_CODE (TREE_TYPE (lhs)) == FUNCTION_TYPE - || ((TREE_CODE (lhstype) == RECORD_TYPE - || TREE_CODE (lhstype) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (lhstype)) - || (TREE_CODE (lhstype) == REFERENCE_TYPE - && CP_TYPE_CONST_P (TREE_TYPE (lhstype))))) - readonly_error (lhs, "assignment", 0); - - /* If storing into a structure or union member, - it has probably been given type `int'. - Compute the type that would go with - the actual amount of storage the member occupies. */ - - if (TREE_CODE (lhs) == COMPONENT_REF - && (TREE_CODE (lhstype) == INTEGER_TYPE - || TREE_CODE (lhstype) == REAL_TYPE - || TREE_CODE (lhstype) == ENUMERAL_TYPE)) - { - lhstype = TREE_TYPE (get_unwidened (lhs, 0)); - - /* If storing in a field that is in actuality a short or narrower - than one, we must store in the field in its actual type. */ - - if (lhstype != TREE_TYPE (lhs)) - { - lhs = copy_node (lhs); - TREE_TYPE (lhs) = lhstype; - } - } - - /* check to see if there is an assignment to `this' */ - if (lhs == current_class_ptr) - { - if (flag_this_is_variable > 0 - && DECL_NAME (current_function_decl) != NULL_TREE - && (DECL_NAME (current_function_decl) - != constructor_name (current_class_type))) - warning ("assignment to `this' not in constructor or destructor"); - current_function_just_assigned_this = 1; - } - - if (modifycode != INIT_EXPR) - { - /* Make modifycode now either a NOP_EXPR or an INIT_EXPR. */ - modifycode = NOP_EXPR; - /* Reference-bashing */ - if (TREE_CODE (lhstype) == REFERENCE_TYPE) - { - tree tmp = convert_from_reference (lhs); - lhstype = TREE_TYPE (tmp); - if (TYPE_SIZE (lhstype) == 0) - { - incomplete_type_error (lhs, lhstype); - return error_mark_node; - } - lhs = tmp; - olhstype = lhstype; - } - if (TREE_CODE (TREE_TYPE (newrhs)) == REFERENCE_TYPE) - { - tree tmp = convert_from_reference (newrhs); - if (TYPE_SIZE (TREE_TYPE (tmp)) == 0) - { - incomplete_type_error (newrhs, TREE_TYPE (tmp)); - return error_mark_node; - } - newrhs = tmp; - } - } - - if (TREE_SIDE_EFFECTS (lhs)) - lhs = stabilize_reference (lhs); - if (TREE_SIDE_EFFECTS (newrhs)) - newrhs = stabilize_reference (newrhs); - - /* Convert new value to destination type. */ - - if (TREE_CODE (lhstype) == ARRAY_TYPE) - { - int from_array; - - if (!same_or_base_type_p (lhstype, TREE_TYPE (rhs))) - { - cp_error ("incompatible types in assignment of `%T' to `%T'", - TREE_TYPE (rhs), lhstype); - return error_mark_node; - } - - /* Allow array assignment in compiler-generated code. */ - if (pedantic && ! DECL_ARTIFICIAL (current_function_decl)) - pedwarn ("ANSI C++ forbids assignment of arrays"); - - /* Have to wrap this in RTL_EXPR for two cases: - in base or member initialization and if we - are a branch of a ?: operator. Since we - can't easily know the latter, just do it always. */ - - result = make_node (RTL_EXPR); - - TREE_TYPE (result) = void_type_node; - do_pending_stack_adjust (); - start_sequence_for_rtl_expr (result); - - /* As a matter of principle, `start_sequence' should do this. */ - emit_note (0, -1); - - from_array = TREE_CODE (TREE_TYPE (newrhs)) == ARRAY_TYPE - ? 1 + (modifycode != INIT_EXPR): 0; - expand_vec_init (lhs, lhs, array_type_nelts (lhstype), newrhs, - from_array); - - do_pending_stack_adjust (); - - TREE_SIDE_EFFECTS (result) = 1; - RTL_EXPR_SEQUENCE (result) = get_insns (); - RTL_EXPR_RTL (result) = const0_rtx; - end_sequence (); - return result; - } - - if (modifycode == INIT_EXPR) - { - newrhs = convert_for_initialization (lhs, lhstype, newrhs, LOOKUP_NORMAL, - "assignment", NULL_TREE, 0); - if (lhs == DECL_RESULT (current_function_decl)) - { - if (DECL_INITIAL (lhs)) - warning ("return value from function receives multiple initializations"); - DECL_INITIAL (lhs) = newrhs; - } - } - else - { - /* Avoid warnings on enum bit fields. */ - if (TREE_CODE (olhstype) == ENUMERAL_TYPE - && TREE_CODE (lhstype) == INTEGER_TYPE) - { - newrhs = convert_for_assignment (olhstype, newrhs, "assignment", - NULL_TREE, 0); - newrhs = convert_force (lhstype, newrhs, 0); - } - else - newrhs = convert_for_assignment (lhstype, newrhs, "assignment", - NULL_TREE, 0); - if (TREE_CODE (newrhs) == CALL_EXPR - && TYPE_NEEDS_CONSTRUCTING (lhstype)) - newrhs = build_cplus_new (lhstype, newrhs); - - /* Can't initialize directly from a TARGET_EXPR, since that would - cause the lhs to be constructed twice, and possibly result in - accidental self-initialization. So we force the TARGET_EXPR to be - expanded without a target. */ - if (TREE_CODE (newrhs) == TARGET_EXPR) - newrhs = build (COMPOUND_EXPR, TREE_TYPE (newrhs), newrhs, - TREE_OPERAND (newrhs, 0)); - } - - if (newrhs == error_mark_node) - return error_mark_node; - - if (TREE_CODE (newrhs) == COND_EXPR) - { - tree lhs1; - tree cond = TREE_OPERAND (newrhs, 0); - - if (TREE_SIDE_EFFECTS (lhs)) - cond = build_compound_expr (tree_cons - (NULL_TREE, lhs, - build_expr_list (NULL_TREE, cond))); - - /* Cannot have two identical lhs on this one tree (result) as preexpand - calls will rip them out and fill in RTL for them, but when the - rtl is generated, the calls will only be in the first side of the - condition, not on both, or before the conditional jump! (mrs) */ - lhs1 = break_out_calls (lhs); - - if (lhs == lhs1) - /* If there's no change, the COND_EXPR behaves like any other rhs. */ - result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, - lhstype, lhs, newrhs); - else - { - tree result_type = TREE_TYPE (newrhs); - /* We have to convert each arm to the proper type because the - types may have been munged by constant folding. */ - result - = build (COND_EXPR, result_type, cond, - build_modify_expr (lhs, modifycode, - cp_convert (result_type, - TREE_OPERAND (newrhs, 1))), - build_modify_expr (lhs1, modifycode, - cp_convert (result_type, - TREE_OPERAND (newrhs, 2)))); - } - } - else - result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR, - lhstype, lhs, newrhs); - - TREE_SIDE_EFFECTS (result) = 1; - - /* If we got the LHS in a different type for storing in, - convert the result back to the nominal type of LHS - so that the value we return always has the same type - as the LHS argument. */ - - if (olhstype == TREE_TYPE (result)) - return result; - /* Avoid warnings converting integral types back into enums - for enum bit fields. */ - if (TREE_CODE (TREE_TYPE (result)) == INTEGER_TYPE - && TREE_CODE (olhstype) == ENUMERAL_TYPE) - { - result = build (COMPOUND_EXPR, olhstype, result, olhs); - TREE_NO_UNUSED_WARNING (result) = 1; - return result; - } - return convert_for_assignment (olhstype, result, "assignment", - NULL_TREE, 0); -} - -tree -build_x_modify_expr (lhs, modifycode, rhs) - tree lhs; - enum tree_code modifycode; - tree rhs; -{ - if (processing_template_decl) - return build_min_nt (MODOP_EXPR, lhs, - build_min_nt (modifycode, NULL_TREE, NULL_TREE), rhs); - - if (modifycode != NOP_EXPR) - { - tree rval = build_opfncall (MODIFY_EXPR, LOOKUP_NORMAL, lhs, rhs, - make_node (modifycode)); - if (rval) - return rval; - } - return build_modify_expr (lhs, modifycode, rhs); -} - - -/* Get difference in deltas for different pointer to member function - types. Return integer_zero_node, if FROM cannot be converted to a - TO type. If FORCE is true, then allow reverse conversions as well. */ - -static tree -get_delta_difference (from, to, force) - tree from, to; - int force; -{ - tree delta = integer_zero_node; - tree binfo; - - if (to == from) - return delta; - - /* Should get_base_distance here, so we can check if any thing along the - path is virtual, and we need to make sure we stay - inside the real binfos when going through virtual bases. - Maybe we should replace virtual bases with - binfo_member (...CLASSTYPE_VBASECLASSES...)... (mrs) */ - binfo = get_binfo (from, to, 1); - if (binfo == error_mark_node) - { - error (" in pointer to member function conversion"); - return delta; - } - if (binfo == 0) - { - if (!force) - { - error_not_base_type (from, to); - error (" in pointer to member conversion"); - return delta; - } - binfo = get_binfo (to, from, 1); - if (binfo == 0 || binfo == error_mark_node) - return delta; - if (TREE_VIA_VIRTUAL (binfo)) - { - binfo = binfo_member (BINFO_TYPE (binfo), - CLASSTYPE_VBASECLASSES (from)); - cp_warning ("pointer to member cast to virtual base `%T'", - BINFO_TYPE (binfo)); - warning (" will only work if you are very careful"); - } - delta = BINFO_OFFSET (binfo); - delta = cp_convert (ptrdiff_type_node, delta); - - return build_binary_op (MINUS_EXPR, - integer_zero_node, - delta, 1); - } - - if (TREE_VIA_VIRTUAL (binfo)) - { - if (force) - { - cp_warning ("pointer to member cast from virtual base `%T'", - BINFO_TYPE (binfo)); - warning (" will only work if you are very careful"); - } - else - cp_error ("pointer to member conversion from virtual base `%T'", - BINFO_TYPE (binfo)); - } - - return BINFO_OFFSET (binfo); -} - -static tree -build_ptrmemfunc1 (type, delta, idx, pfn, delta2) - tree type, delta, idx, pfn, delta2; -{ - tree u; - -#if 0 - /* This is the old way we did it. We want to avoid calling - digest_init, so that it can give an error if we use { } when - initializing a pointer to member function. */ - - if (pfn) - { - u = build_nt (CONSTRUCTOR, NULL_TREE, - expr_tree_cons (pfn_identifier, pfn, NULL_TREE)); - } - else - { - u = build_nt (CONSTRUCTOR, NULL_TREE, - expr_tree_cons (delta2_identifier, delta2, NULL_TREE)); - } - - u = build_nt (CONSTRUCTOR, NULL_TREE, - expr_tree_cons (NULL_TREE, delta, - expr_tree_cons (NULL_TREE, idx, - expr_tree_cons (NULL_TREE, u, NULL_TREE)))); - - return digest_init (type, u, (tree*)0); -#else - tree delta_field, idx_field, pfn_or_delta2_field, pfn_field, delta2_field; - tree subtype; - int allconstant, allsimple; - - delta_field = TYPE_FIELDS (type); - idx_field = TREE_CHAIN (delta_field); - pfn_or_delta2_field = TREE_CHAIN (idx_field); - subtype = TREE_TYPE (pfn_or_delta2_field); - pfn_field = TYPE_FIELDS (subtype); - delta2_field = TREE_CHAIN (pfn_field); - - if (pfn) - { - allconstant = TREE_CONSTANT (pfn); - allsimple = !! initializer_constant_valid_p (pfn, TREE_TYPE (pfn)); - u = expr_tree_cons (pfn_field, pfn, NULL_TREE); - } - else - { - delta2 = convert_and_check (delta_type_node, delta2); - allconstant = TREE_CONSTANT (delta2); - allsimple = !! initializer_constant_valid_p (delta2, TREE_TYPE (delta2)); - u = expr_tree_cons (delta2_field, delta2, NULL_TREE); - } - - delta = convert_and_check (delta_type_node, delta); - idx = convert_and_check (delta_type_node, idx); - - allconstant = allconstant && TREE_CONSTANT (delta) && TREE_CONSTANT (idx); - allsimple = allsimple - && initializer_constant_valid_p (delta, TREE_TYPE (delta)) - && initializer_constant_valid_p (idx, TREE_TYPE (idx)); - - u = build (CONSTRUCTOR, subtype, NULL_TREE, u); - u = expr_tree_cons (delta_field, delta, - expr_tree_cons (idx_field, idx, - expr_tree_cons (pfn_or_delta2_field, u, NULL_TREE))); - u = build (CONSTRUCTOR, type, NULL_TREE, u); - TREE_CONSTANT (u) = allconstant; - TREE_STATIC (u) = allconstant && allsimple; - return u; -#endif -} - -/* Build a constructor for a pointer to member function. It can be - used to initialize global variables, local variable, or used - as a value in expressions. TYPE is the POINTER to METHOD_TYPE we - want to be. - - If FORCE is non-zero, then force this conversion, even if - we would rather not do it. Usually set when using an explicit - cast. - - Return error_mark_node, if something goes wrong. */ - -tree -build_ptrmemfunc (type, pfn, force) - tree type, pfn; - int force; -{ - tree idx = integer_zero_node; - tree delta = integer_zero_node; - tree delta2 = integer_zero_node; - tree vfield_offset; - tree npfn = NULL_TREE; - - /* Handle multiple conversions of pointer to member functions. */ - if (TYPE_PTRMEMFUNC_P (TREE_TYPE (pfn))) - { - tree ndelta, ndelta2; - tree e1, e2, e3, n; - tree pfn_type; - - /* Is is already the right type? */ - if (type == TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn))) - return pfn; - - pfn_type = TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (pfn)); - if (!force - && comp_target_types (type, pfn_type, 1) != 1) - cp_error ("conversion to `%T' from `%T'", type, pfn_type); - - ndelta = cp_convert (ptrdiff_type_node, build_component_ref (pfn, delta_identifier, NULL_TREE, 0)); - ndelta2 = cp_convert (ptrdiff_type_node, DELTA2_FROM_PTRMEMFUNC (pfn)); - idx = build_component_ref (pfn, index_identifier, NULL_TREE, 0); - - n = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (pfn_type)), - TYPE_METHOD_BASETYPE (TREE_TYPE (type)), - force); - - delta = build_binary_op (PLUS_EXPR, ndelta, n, 1); - delta2 = build_binary_op (PLUS_EXPR, ndelta2, n, 1); - e1 = fold (build (GT_EXPR, boolean_type_node, idx, integer_zero_node)); - - e2 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, - NULL_TREE, delta2); - - pfn = PFN_FROM_PTRMEMFUNC (pfn); - npfn = build1 (NOP_EXPR, type, pfn); - TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn); - - e3 = build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, npfn, - NULL_TREE); - return build_conditional_expr (e1, e2, e3); - } - - /* Handle null pointer to member function conversions. */ - if (integer_zerop (pfn)) - { - pfn = build_c_cast (type, integer_zero_node); - return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), - integer_zero_node, integer_zero_node, - pfn, NULL_TREE); - } - - if (type_unknown_p (pfn)) - return instantiate_type (type, pfn, 1); - - if (!force - && comp_target_types (type, TREE_TYPE (pfn), 0) != 1) - cp_error ("conversion to `%T' from `%T'", type, TREE_TYPE (pfn)); - - /* Allow pointer to member conversions here. */ - delta = get_delta_difference (TYPE_METHOD_BASETYPE (TREE_TYPE (TREE_TYPE (pfn))), - TYPE_METHOD_BASETYPE (TREE_TYPE (type)), - force); - delta2 = build_binary_op (PLUS_EXPR, delta2, delta, 1); - - if (TREE_CODE (TREE_OPERAND (pfn, 0)) != FUNCTION_DECL) - warning ("assuming pointer to member function is non-virtual"); - - if (TREE_CODE (TREE_OPERAND (pfn, 0)) == FUNCTION_DECL - && DECL_VINDEX (TREE_OPERAND (pfn, 0))) - { - /* Find the offset to the vfield pointer in the object. */ - vfield_offset = get_binfo (DECL_CONTEXT (TREE_OPERAND (pfn, 0)), - DECL_CLASS_CONTEXT (TREE_OPERAND (pfn, 0)), - 0); - vfield_offset = get_vfield_offset (vfield_offset); - delta2 = size_binop (PLUS_EXPR, vfield_offset, delta2); - - /* Map everything down one to make room for the null pointer to member. */ - idx = size_binop (PLUS_EXPR, - DECL_VINDEX (TREE_OPERAND (pfn, 0)), - integer_one_node); - } - else - { - idx = size_binop (MINUS_EXPR, integer_zero_node, integer_one_node); - - if (type == TREE_TYPE (pfn)) - { - npfn = pfn; - } - else - { - npfn = build1 (NOP_EXPR, type, pfn); - TREE_CONSTANT (npfn) = TREE_CONSTANT (pfn); - } - } - - return build_ptrmemfunc1 (TYPE_GET_PTRMEMFUNC_TYPE (type), delta, idx, npfn, delta2); -} - -/* Convert value RHS to type TYPE as preparation for an assignment - to an lvalue of type TYPE. - The real work of conversion is done by `convert'. - The purpose of this function is to generate error messages - for assignments that are not allowed in C. - ERRTYPE is a string to use in error messages: - "assignment", "return", etc. - - C++: attempts to allow `convert' to find conversions involving - implicit type conversion between aggregate and scalar types - as per 8.5.6 of C++ manual. Does not randomly dereference - pointers to aggregates! */ - -static tree -convert_for_assignment (type, rhs, errtype, fndecl, parmnum) - tree type, rhs; - char *errtype; - tree fndecl; - int parmnum; -{ - register enum tree_code codel = TREE_CODE (type); - register tree rhstype; - register enum tree_code coder = TREE_CODE (TREE_TYPE (rhs)); - - /* Issue warnings about peculiar, but legal, uses of NULL. */ - if (ARITHMETIC_TYPE_P (type) && rhs == null_node) - cp_warning ("converting NULL to non-pointer type"); - - if (coder == ERROR_MARK) - return error_mark_node; - - if (codel == OFFSET_TYPE) - { - type = TREE_TYPE (type); - codel = TREE_CODE (type); - } - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (rhs) == NON_LVALUE_EXPR) - rhs = TREE_OPERAND (rhs, 0); - - if (rhs == error_mark_node) - return error_mark_node; - - if (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (rhs)) == OFFSET_TYPE) - { - rhs = resolve_offset_ref (rhs); - if (rhs == error_mark_node) - return error_mark_node; - rhstype = TREE_TYPE (rhs); - coder = TREE_CODE (rhstype); - } - - if (TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE - || is_overloaded_fn (rhs)) - rhs = default_conversion (rhs); - else if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE) - rhs = convert_from_reference (rhs); - - /* If rhs is some sort of overloaded function, ocp_convert will either - do the right thing or complain; we don't need to check anything else. - So just hand off. */ - if (type_unknown_p (rhs)) - return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL); - - rhstype = TREE_TYPE (rhs); - coder = TREE_CODE (rhstype); - - /* This should no longer change types on us. */ - if (TREE_CODE (rhs) == CONST_DECL) - rhs = DECL_INITIAL (rhs); - else if (TREE_READONLY_DECL_P (rhs)) - rhs = decl_constant_value (rhs); - - if (same_type_p (type, rhstype)) - { - overflow_warning (rhs); - return rhs; - } - - if (coder == VOID_TYPE) - { - error ("void value not ignored as it ought to be"); - return error_mark_node; - } - /* Arithmetic types all interconvert. */ - if ((codel == INTEGER_TYPE || codel == REAL_TYPE || codel == BOOLEAN_TYPE - || codel == COMPLEX_TYPE) - && (coder == INTEGER_TYPE || coder == REAL_TYPE || coder == BOOLEAN_TYPE - || coder == COMPLEX_TYPE)) - { - /* But we should warn if assigning REAL_TYPE to INTEGER_TYPE. */ - if (coder == REAL_TYPE && codel == INTEGER_TYPE) - { - if (fndecl) - cp_warning ("`%T' used for argument %P of `%D'", - rhstype, parmnum, fndecl); - else - cp_warning ("%s to `%T' from `%T'", errtype, type, rhstype); - } - /* And we should warn if assigning a negative value to - an unsigned variable. */ - else if (TREE_UNSIGNED (type) && codel != BOOLEAN_TYPE) - { - if (TREE_CODE (rhs) == INTEGER_CST - && TREE_NEGATED_INT (rhs)) - { - if (fndecl) - cp_warning ("negative value `%E' passed as argument %P of `%D'", - rhs, parmnum, fndecl); - else - cp_warning ("%s of negative value `%E' to `%T'", - errtype, rhs, type); - } - overflow_warning (rhs); - if (TREE_CONSTANT (rhs)) - rhs = fold (rhs); - } - - return convert_and_check (type, rhs); - } - /* Conversions involving enums. */ - else if ((codel == ENUMERAL_TYPE - && (INTEGRAL_CODE_P (coder) || coder == REAL_TYPE)) - || (coder == ENUMERAL_TYPE - && (INTEGRAL_CODE_P (codel) || codel == REAL_TYPE))) - { - return ocp_convert (type, rhs, CONV_IMPLICIT, LOOKUP_NORMAL); - } - /* Conversions among pointers */ - else if (codel == POINTER_TYPE - && (coder == POINTER_TYPE - || (coder == RECORD_TYPE - && (IS_SIGNATURE_POINTER (rhstype) - || IS_SIGNATURE_REFERENCE (rhstype))))) - { - register tree ttl = TREE_TYPE (type); - register tree ttr; - int ctt = 0; - - if (coder == RECORD_TYPE) - { - rhs = build_optr_ref (rhs); - rhstype = TREE_TYPE (rhs); - } - ttr = TREE_TYPE (rhstype); - - /* If both pointers are of aggregate type, then we - can give better error messages, and save some work - as well. */ - if (TREE_CODE (ttl) == RECORD_TYPE && TREE_CODE (ttr) == RECORD_TYPE) - { - tree binfo; - - if (TYPE_MAIN_VARIANT (ttl) == TYPE_MAIN_VARIANT (ttr) - || type == class_star_type_node - || rhstype == class_star_type_node) - binfo = TYPE_BINFO (ttl); - else - binfo = get_binfo (ttl, ttr, 1); - - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == 0) - return error_not_base_type (ttl, ttr); - - if (!at_least_as_qualified_p (ttl, ttr)) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' discards qualifiers", - errtype, type, rhstype); - } - } - - /* Any non-function converts to a [const][volatile] void * - and vice versa; otherwise, targets must be the same. - Meanwhile, the lhs target must have all the qualifiers of the rhs. */ - else if (TYPE_MAIN_VARIANT (ttl) == void_type_node - || TYPE_MAIN_VARIANT (ttr) == void_type_node - || (ctt = comp_target_types (type, rhstype, 1)) - || (unsigned_type (TYPE_MAIN_VARIANT (ttl)) - == unsigned_type (TYPE_MAIN_VARIANT (ttr)))) - { - /* ARM $4.8, commentary on p39. */ - if (TYPE_MAIN_VARIANT (ttl) == void_type_node - && TREE_CODE (ttr) == OFFSET_TYPE) - { - cp_error ("no standard conversion from `%T' to `void *'", ttr); - return error_mark_node; - } - - if (ctt < 0 && TYPE_MAIN_VARIANT (ttl) != TYPE_MAIN_VARIANT (ttr)) - cp_pedwarn ("converting `%T' to `%T' is a contravariance violation", - rhstype, type); - - if (TYPE_MAIN_VARIANT (ttl) != void_type_node - && TYPE_MAIN_VARIANT (ttr) == void_type_node - && ! null_ptr_cst_p (rhs)) - { - if (coder == RECORD_TYPE) - cp_pedwarn ("implicit conversion of signature pointer to type `%T'", - type); - else - pedwarn ("ANSI C++ forbids implicit conversion from `void *' in %s", - errtype); - } - /* Const and volatile mean something different for function types, - so the usual warnings are not appropriate. */ - else if ((TREE_CODE (ttr) != FUNCTION_TYPE && TREE_CODE (ttr) != METHOD_TYPE) - || (TREE_CODE (ttl) != FUNCTION_TYPE && TREE_CODE (ttl) != METHOD_TYPE)) - { - if (TREE_CODE (ttl) == OFFSET_TYPE - && binfo_member (TYPE_OFFSET_BASETYPE (ttr), - CLASSTYPE_VBASECLASSES (TYPE_OFFSET_BASETYPE (ttl)))) - { - error ("%s between pointer to members converting across virtual baseclasses", errtype); - return error_mark_node; - } - else if (!at_least_as_qualified_p (ttl, ttr)) - { - if (string_conv_p (type, rhs, 1)) - /* converting from string constant to char *, OK. */; - else if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' discards qualifiers", - errtype, type, rhstype); - } - else if (TREE_CODE (ttl) == TREE_CODE (ttr) - && ! comp_target_types (type, rhstype, 1)) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' changes signedness", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' changes signedness", - errtype, type, rhstype); - } - } - } - else - { - int add_quals = 0; - int drops_quals = 0; - int left_const = 1; - int unsigned_parity; - int nptrs = 0; - - /* This code is basically a duplicate of comp_ptr_ttypes_real. */ - for (; ; ttl = TREE_TYPE (ttl), ttr = TREE_TYPE (ttr)) - { - nptrs -= 1; - drops_quals |= !at_least_as_qualified_p (ttl, ttr); - - if (! left_const - && !at_least_as_qualified_p (ttr, ttl)) - add_quals = 1; - left_const &= TYPE_READONLY (ttl); - - if (TREE_CODE (ttl) != POINTER_TYPE - || TREE_CODE (ttr) != POINTER_TYPE) - break; - } - unsigned_parity = TREE_UNSIGNED (ttl) - TREE_UNSIGNED (ttr); - if (unsigned_parity) - { - if (TREE_UNSIGNED (ttl)) - ttr = unsigned_type (ttr); - else - ttl = unsigned_type (ttl); - } - - if (comp_target_types (ttl, ttr, nptrs) > 0) - { - if (add_quals) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' adds cv-quals without intervening `const'", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' adds cv-quals without intervening `const'", - errtype, type, rhstype); - } - if (drops_quals) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' discards qualifiers", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' discards qualifiers", - errtype, type, rhstype); - } - if (unsigned_parity > 0) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' changes signed to unsigned", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' changes signed to unsigned", - errtype, type, rhstype); - } - else if (unsigned_parity < 0) - { - if (fndecl) - cp_pedwarn ("passing `%T' as argument %P of `%D' changes unsigned to signed", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' changes unsigned to signed", - errtype, type, rhstype); - } - - /* C++ is not so friendly about converting function and - member function pointers as C. Emit warnings here. */ - if (TREE_CODE (ttl) == FUNCTION_TYPE - || TREE_CODE (ttl) == METHOD_TYPE) - if (!same_or_base_type_p (ttl, ttr)) - { - warning ("conflicting function types in %s:", errtype); - cp_warning ("\t`%T' != `%T'", type, rhstype); - } - } - else - { - if (fndecl) - cp_error ("passing `%T' as argument %P of `%D'", - rhstype, parmnum, fndecl); - else - cp_error ("%s to `%T' from `%T'", errtype, type, rhstype); - return error_mark_node; - } - } - return cp_convert (type, rhs); - } - else if (codel == POINTER_TYPE && coder == INTEGER_TYPE) - { - /* An explicit constant 0 can convert to a pointer, - but not a 0 that results from casting or folding. */ - if (! (TREE_CODE (rhs) == INTEGER_CST && integer_zerop (rhs))) - { - if (fndecl) - cp_pedwarn ("passing `%T' to argument %P of `%D' lacks a cast", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' lacks a cast", - errtype, type, rhstype); - } - return cp_convert (type, rhs); - } - else if (codel == INTEGER_TYPE - && (coder == POINTER_TYPE - || (coder == RECORD_TYPE - && (IS_SIGNATURE_POINTER (rhstype) - || TYPE_PTRMEMFUNC_FLAG (rhstype) - || IS_SIGNATURE_REFERENCE (rhstype))))) - { - if (fndecl) - cp_pedwarn ("passing `%T' to argument %P of `%D' lacks a cast", - rhstype, parmnum, fndecl); - else - cp_pedwarn ("%s to `%T' from `%T' lacks a cast", - errtype, type, rhstype); - return cp_convert (type, rhs); - } - else if (codel == BOOLEAN_TYPE - && (coder == POINTER_TYPE - || (coder == RECORD_TYPE - && (IS_SIGNATURE_POINTER (rhstype) - || TYPE_PTRMEMFUNC_FLAG (rhstype) - || IS_SIGNATURE_REFERENCE (rhstype))))) - return cp_convert (type, rhs); - - /* C++ */ - else if (((coder == POINTER_TYPE - && TREE_CODE (TREE_TYPE (rhstype)) == METHOD_TYPE) - || integer_zerop (rhs) - || TYPE_PTRMEMFUNC_P (rhstype)) - && TYPE_PTRMEMFUNC_P (type)) - { - tree ttl = TYPE_PTRMEMFUNC_FN_TYPE (type); - tree ttr = (TYPE_PTRMEMFUNC_P (rhstype) - ? TYPE_PTRMEMFUNC_FN_TYPE (rhstype) - : rhstype); - int ctt = (TREE_CODE (rhstype) == INTEGER_TYPE ? 1 - : comp_target_types (ttl, ttr, 1)); - - if (ctt < 0) - cp_pedwarn ("converting `%T' to `%T' is a contravariance violation", - ttr, ttl); - else if (ctt == 0) - cp_error ("%s to `%T' from `%T'", errtype, ttl, ttr); - - /* compatible pointer to member functions. */ - return build_ptrmemfunc (ttl, rhs, 0); - } - else if (codel == ERROR_MARK || coder == ERROR_MARK) - return error_mark_node; - - /* This should no longer happen. References are initialized via - `convert_for_initialization'. They should otherwise be - bashed before coming here. */ - else if (codel == REFERENCE_TYPE) - my_friendly_abort (317); - else if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (rhs))) - { - tree nrhs = build1 (NOP_EXPR, type, rhs); - TREE_CONSTANT (nrhs) = TREE_CONSTANT (rhs); - return nrhs; - } - else if (TYPE_HAS_CONSTRUCTOR (type) || IS_AGGR_TYPE (TREE_TYPE (rhs))) - return cp_convert (type, rhs); - /* Handle anachronistic conversions from (::*)() to cv void* or (*)(). */ - else if (TREE_CODE (type) == POINTER_TYPE - && (TREE_CODE (TREE_TYPE (type)) == FUNCTION_TYPE - || TYPE_MAIN_VARIANT (TREE_TYPE (type)) == void_type_node) - && TREE_TYPE (rhs) - && TYPE_PTRMEMFUNC_P (TREE_TYPE (rhs))) - return cp_convert (type, rhs); - - cp_error ("%s to `%T' from `%T'", errtype, type, rhstype); - return error_mark_node; -} - -/* Convert RHS to be of type TYPE. - If EXP is non-zero, it is the target of the initialization. - ERRTYPE is a string to use in error messages. - - Two major differences between the behavior of - `convert_for_assignment' and `convert_for_initialization' - are that references are bashed in the former, while - copied in the latter, and aggregates are assigned in - the former (operator=) while initialized in the - latter (X(X&)). - - If using constructor make sure no conversion operator exists, if one does - exist, an ambiguity exists. - - If flags doesn't include LOOKUP_COMPLAIN, don't complain about anything. */ - -tree -convert_for_initialization (exp, type, rhs, flags, errtype, fndecl, parmnum) - tree exp, type, rhs; - int flags; - char *errtype; - tree fndecl; - int parmnum; -{ - register enum tree_code codel = TREE_CODE (type); - register tree rhstype; - register enum tree_code coder; - - /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. - Strip such NOP_EXPRs, since RHS is used in non-lvalue context. */ - if (TREE_CODE (rhs) == NOP_EXPR - && TREE_TYPE (rhs) == TREE_TYPE (TREE_OPERAND (rhs, 0)) - && codel != REFERENCE_TYPE) - rhs = TREE_OPERAND (rhs, 0); - - if (rhs == error_mark_node - || (TREE_CODE (rhs) == TREE_LIST && TREE_VALUE (rhs) == error_mark_node)) - return error_mark_node; - - if (TREE_CODE (TREE_TYPE (rhs)) == OFFSET_TYPE) - { - rhs = resolve_offset_ref (rhs); - if (rhs == error_mark_node) - return error_mark_node; - } - - if (TREE_CODE (TREE_TYPE (rhs)) == REFERENCE_TYPE) - rhs = convert_from_reference (rhs); - - if ((TREE_CODE (TREE_TYPE (rhs)) == ARRAY_TYPE - && TREE_CODE (type) != ARRAY_TYPE - && (TREE_CODE (type) != REFERENCE_TYPE - || TREE_CODE (TREE_TYPE (type)) != ARRAY_TYPE)) - || (TREE_CODE (TREE_TYPE (rhs)) == FUNCTION_TYPE - && (TREE_CODE (type) != REFERENCE_TYPE - || TREE_CODE (TREE_TYPE (type)) != FUNCTION_TYPE)) - || TREE_CODE (TREE_TYPE (rhs)) == METHOD_TYPE) - rhs = default_conversion (rhs); - - rhstype = TREE_TYPE (rhs); - coder = TREE_CODE (rhstype); - - if (coder == ERROR_MARK) - return error_mark_node; - - /* We accept references to incomplete types, so we can - return here before checking if RHS is of complete type. */ - - if (codel == REFERENCE_TYPE) - { - /* This should eventually happen in convert_arguments. */ - extern int warningcount, errorcount; - int savew = 0, savee = 0; - - if (fndecl) - savew = warningcount, savee = errorcount; - rhs = convert_to_reference (type, rhs, CONV_IMPLICIT, flags, - exp ? exp : error_mark_node); - if (fndecl) - { - if (warningcount > savew) - cp_warning_at ("in passing argument %P of `%+D'", parmnum, fndecl); - else if (errorcount > savee) - cp_error_at ("in passing argument %P of `%+D'", parmnum, fndecl); - } - return rhs; - } - - rhs = require_complete_type (rhs); - if (rhs == error_mark_node) - return error_mark_node; - - if (exp != 0) exp = require_complete_type (exp); - if (exp == error_mark_node) - return error_mark_node; - - if (TREE_CODE (rhstype) == REFERENCE_TYPE) - rhstype = TREE_TYPE (rhstype); - - type = complete_type (type); - - if (TYPE_LANG_SPECIFIC (type) - && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type))) - return build_signature_pointer_constructor (type, rhs); - - if (IS_AGGR_TYPE (type)) - return ocp_convert (type, rhs, CONV_IMPLICIT|CONV_FORCE_TEMP, flags); - - if (type == TREE_TYPE (rhs)) - { - /* Issue warnings about peculiar, but legal, uses of NULL. We - do this *before* the call to decl_constant_value so as to - avoid duplicate warnings on code like `const int I = NULL; - f(I);'. */ - if (ARITHMETIC_TYPE_P (type) && rhs == null_node) - cp_warning ("converting NULL to non-pointer type"); - - if (TREE_READONLY_DECL_P (rhs)) - rhs = decl_constant_value (rhs); - - return rhs; - } - - return convert_for_assignment (type, rhs, errtype, fndecl, parmnum); -} - -/* Expand an ASM statement with operands, handling output operands - that are not variables or INDIRECT_REFS by transforming such - cases into cases that expand_asm_operands can handle. - - Arguments are same as for expand_asm_operands. - - We don't do default conversions on all inputs, because it can screw - up operands that are expected to be in memory. */ - -void -c_expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line) - tree string, outputs, inputs, clobbers; - int vol; - char *filename; - int line; -{ - int noutputs = list_length (outputs); - register int i; - /* o[I] is the place that output number I should be written. */ - register tree *o = (tree *) alloca (noutputs * sizeof (tree)); - register tree tail; - - /* Record the contents of OUTPUTS before it is modified. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - o[i] = TREE_VALUE (tail); - - /* Generate the ASM_OPERANDS insn; - store into the TREE_VALUEs of OUTPUTS some trees for - where the values were actually stored. */ - expand_asm_operands (string, outputs, inputs, clobbers, vol, filename, line); - - /* Copy all the intermediate outputs into the specified outputs. */ - for (i = 0, tail = outputs; tail; tail = TREE_CHAIN (tail), i++) - { - if (o[i] != TREE_VALUE (tail)) - { - expand_expr (build_modify_expr (o[i], NOP_EXPR, TREE_VALUE (tail)), - const0_rtx, VOIDmode, EXPAND_NORMAL); - free_temp_slots (); - } - /* Detect modification of read-only values. - (Otherwise done by build_modify_expr.) */ - else - { - tree type = TREE_TYPE (o[i]); - if (CP_TYPE_CONST_P (type) - || ((TREE_CODE (type) == RECORD_TYPE - || TREE_CODE (type) == UNION_TYPE) - && C_TYPE_FIELDS_READONLY (type))) - readonly_error (o[i], "modification by `asm'", 1); - } - } - - /* Those MODIFY_EXPRs could do autoincrements. */ - emit_queue (); -} - -/* Expand a C `return' statement. - RETVAL is the expression for what to return, - or a null pointer for `return;' with no value. - - C++: upon seeing a `return', we must call destructors on all - variables in scope which had constructors called on them. - This means that if in a destructor, the base class destructors - must be called before returning. - - The RETURN statement in C++ has initialization semantics. */ - -void -c_expand_return (retval) - tree retval; -{ - extern struct nesting *cond_stack, *loop_stack, *case_stack; - extern tree dtor_label, ctor_label; - tree result = DECL_RESULT (current_function_decl); - tree valtype = TREE_TYPE (result); - - if (TREE_THIS_VOLATILE (current_function_decl)) - warning ("function declared `noreturn' has a `return' statement"); - - if (retval == error_mark_node) - { - current_function_returns_null = 1; - return; - } - - if (processing_template_decl) - { - add_tree (build_min_nt (RETURN_STMT, retval)); - return; - } - - if (dtor_label) - { - if (retval) - error ("returning a value from a destructor"); - - /* Can't just return from a destructor. */ - expand_goto (dtor_label); - return; - } - - if (retval == NULL_TREE) - { - /* A non-named return value does not count. */ - - if (DECL_CONSTRUCTOR_P (current_function_decl)) - retval = current_class_ptr; - else if (DECL_NAME (result) != NULL_TREE - && TREE_CODE (valtype) != VOID_TYPE) - retval = result; - else - { - current_function_returns_null = 1; - - if (valtype != NULL_TREE && TREE_CODE (valtype) != VOID_TYPE) - { - if (DECL_NAME (DECL_RESULT (current_function_decl)) == NULL_TREE) - { - pedwarn ("`return' with no value, in function returning non-void"); - /* Clear this, so finish_function won't say that we - reach the end of a non-void function (which we don't, - we gave a return!). */ - current_function_returns_null = 0; - } - } - - expand_null_return (); - return; - } - } - else if (DECL_CONSTRUCTOR_P (current_function_decl)) - { - if (flag_this_is_variable) - error ("return from a constructor: use `this = ...' instead"); - else - error ("returning a value from a constructor"); - retval = current_class_ptr; - } - - /* Effective C++ rule 15. See also start_function. */ - if (warn_ecpp - && DECL_NAME (current_function_decl) == ansi_opname[(int) MODIFY_EXPR] - && retval != current_class_ref) - cp_warning ("`operator=' should return a reference to `*this'"); - - if (valtype == NULL_TREE || TREE_CODE (valtype) == VOID_TYPE) - { - current_function_returns_null = 1; - if (TREE_CODE (TREE_TYPE (retval)) != VOID_TYPE) - pedwarn ("`return' with a value, in function returning void"); - expand_return (retval); - return; - } - - /* Now deal with possible C++ hair: - (1) Compute the return value. - (2) If there are aggregate values with destructors which - must be cleaned up, clean them (taking care - not to clobber the return value). - (3) If an X(X&) constructor is defined, the return - value must be returned via that. */ - - if (retval == result - || DECL_CONSTRUCTOR_P (current_function_decl)) - /* It's already done for us. */; - else if (TREE_TYPE (retval) == void_type_node) - { - pedwarn ("return of void value in function returning non-void"); - expand_expr_stmt (retval); - retval = 0; - } - else - { - tree functype = TREE_TYPE (TREE_TYPE (current_function_decl)); - - /* First convert the value to the function's return type, then - to the type of return value's location to handle the - case that functype is thiner than the valtype. */ - - retval = convert_for_initialization - (NULL_TREE, functype, retval, LOOKUP_NORMAL|LOOKUP_ONLYCONVERTING, - "return", NULL_TREE, 0); - - retval = convert (valtype, retval); - - if (retval == error_mark_node) - { - /* Avoid warning about control reaching end of function. */ - expand_null_return (); - return; - } - - /* We can't initialize a register from a AGGR_INIT_EXPR. */ - else if (! current_function_returns_struct - && TREE_CODE (retval) == TARGET_EXPR - && TREE_CODE (TREE_OPERAND (retval, 1)) == AGGR_INIT_EXPR) - retval = build (COMPOUND_EXPR, TREE_TYPE (retval), retval, - TREE_OPERAND (retval, 0)); - - /* Add some useful error checking for C++. */ - else if (TREE_CODE (valtype) == REFERENCE_TYPE) - { - tree whats_returned; - - /* Sort through common things to see what it is - we are returning. */ - whats_returned = retval; - if (TREE_CODE (whats_returned) == COMPOUND_EXPR) - { - whats_returned = TREE_OPERAND (whats_returned, 1); - if (TREE_CODE (whats_returned) == ADDR_EXPR) - whats_returned = TREE_OPERAND (whats_returned, 0); - } - while (TREE_CODE (whats_returned) == CONVERT_EXPR - || TREE_CODE (whats_returned) == NOP_EXPR) - whats_returned = TREE_OPERAND (whats_returned, 0); - if (TREE_CODE (whats_returned) == ADDR_EXPR) - { - whats_returned = TREE_OPERAND (whats_returned, 0); - while (TREE_CODE (whats_returned) == AGGR_INIT_EXPR - || TREE_CODE (whats_returned) == TARGET_EXPR) - { - /* Get the target. */ - whats_returned = TREE_OPERAND (whats_returned, 0); - warning ("returning reference to temporary"); - } - } - - if (TREE_CODE (whats_returned) == VAR_DECL && DECL_NAME (whats_returned)) - { - if (TEMP_NAME_P (DECL_NAME (whats_returned))) - warning ("reference to non-lvalue returned"); - else if (TREE_CODE (TREE_TYPE (whats_returned)) != REFERENCE_TYPE - && DECL_FUNCTION_SCOPE_P (whats_returned) - && !(TREE_STATIC (whats_returned) - || TREE_PUBLIC (whats_returned))) - cp_warning_at ("reference to local variable `%D' returned", whats_returned); - } - } - else if (TREE_CODE (retval) == ADDR_EXPR) - { - tree whats_returned = TREE_OPERAND (retval, 0); - - if (TREE_CODE (whats_returned) == VAR_DECL - && DECL_NAME (whats_returned) - && DECL_FUNCTION_SCOPE_P (whats_returned) - && !(TREE_STATIC (whats_returned) - || TREE_PUBLIC (whats_returned))) - cp_warning_at ("address of local variable `%D' returned", whats_returned); - } - } - - if (retval != NULL_TREE - && TREE_CODE_CLASS (TREE_CODE (retval)) == 'd' - && cond_stack == 0 && loop_stack == 0 && case_stack == 0) - current_function_return_value = retval; - - if (ctor_label && TREE_CODE (ctor_label) != ERROR_MARK) - { - /* Here RETVAL is CURRENT_CLASS_PTR, so there's nothing to do. */ - expand_goto (ctor_label); - } - - if (retval && retval != result) - { - result = build (INIT_EXPR, TREE_TYPE (result), result, retval); - TREE_SIDE_EFFECTS (result) = 1; - } - - expand_start_target_temps (); - - expand_return (result); - - expand_end_target_temps (); - - current_function_returns_value = 1; -} - -/* Start a C switch statement, testing expression EXP. - Return EXP if it is valid, an error node otherwise. */ - -tree -c_expand_start_case (exp) - tree exp; -{ - tree type, idx; - - exp = build_expr_type_conversion (WANT_INT | WANT_ENUM, exp, 1); - if (exp == NULL_TREE) - { - error ("switch quantity not an integer"); - exp = error_mark_node; - } - if (exp == error_mark_node) - return error_mark_node; - - exp = default_conversion (exp); - type = TREE_TYPE (exp); - idx = get_unwidened (exp, 0); - /* We can't strip a conversion from a signed type to an unsigned, - because if we did, int_fits_type_p would do the wrong thing - when checking case values for being in range, - and it's too hard to do the right thing. */ - if (TREE_UNSIGNED (TREE_TYPE (exp)) == TREE_UNSIGNED (TREE_TYPE (idx))) - exp = idx; - - expand_start_case - (1, fold (build1 (CLEANUP_POINT_EXPR, TREE_TYPE (exp), exp)), - type, "switch statement"); - - return exp; -} - -/* Returns non-zero if the pointer-type FROM can be converted to the - pointer-type TO via a qualification conversion. If CONSTP is -1, - then we return non-zero if the pointers are similar, and the - cv-qualification signature of FROM is a proper subset of that of TO. - - If CONSTP is positive, then all outer pointers have been - const-qualified. */ - -static int -comp_ptr_ttypes_real (to, from, constp) - tree to, from; - int constp; -{ - int to_more_cv_qualified = 0; - - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { - if (TREE_CODE (to) != TREE_CODE (from)) - return 0; - - if (TREE_CODE (from) == OFFSET_TYPE - && same_type_p (TYPE_OFFSET_BASETYPE (from), - TYPE_OFFSET_BASETYPE (to))) - continue; - - /* Const and volatile mean something different for function types, - so the usual checks are not appropriate. */ - if (TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE) - { - if (!at_least_as_qualified_p (to, from)) - return 0; - - if (!at_least_as_qualified_p (from, to)) - { - if (constp == 0) - return 0; - else - ++to_more_cv_qualified; - } - - if (constp > 0) - constp &= TYPE_READONLY (to); - } - - if (TREE_CODE (to) != POINTER_TYPE) - return - same_type_p (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from)) - && (constp >= 0 || to_more_cv_qualified); - } -} - -/* When comparing, say, char ** to char const **, this function takes the - 'char *' and 'char const *'. Do not pass non-pointer types to this - function. */ - -int -comp_ptr_ttypes (to, from) - tree to, from; -{ - return comp_ptr_ttypes_real (to, from, 1); -} - -/* Returns 1 if to and from are (possibly multi-level) pointers to the same - type or inheritance-related types, regardless of cv-quals. */ - -int -ptr_reasonably_similar (to, from) - tree to, from; -{ - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { - if (TREE_CODE (to) != TREE_CODE (from)) - return 0; - - if (TREE_CODE (from) == OFFSET_TYPE - && comptypes (TYPE_OFFSET_BASETYPE (to), - TYPE_OFFSET_BASETYPE (from), - COMPARE_BASE | COMPARE_RELAXED)) - continue; - - if (TREE_CODE (to) != POINTER_TYPE) - return comptypes - (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), - COMPARE_BASE | COMPARE_RELAXED); - } -} - -/* Like comp_ptr_ttypes, for const_cast. */ - -static int -comp_ptr_ttypes_const (to, from) - tree to, from; -{ - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { - if (TREE_CODE (to) != TREE_CODE (from)) - return 0; - - if (TREE_CODE (from) == OFFSET_TYPE - && same_type_p (TYPE_OFFSET_BASETYPE (from), - TYPE_OFFSET_BASETYPE (to))) - continue; - - if (TREE_CODE (to) != POINTER_TYPE) - return same_type_p (TYPE_MAIN_VARIANT (to), - TYPE_MAIN_VARIANT (from)); - } -} - -/* Like comp_ptr_ttypes, for reinterpret_cast. */ - -static int -comp_ptr_ttypes_reinterpret (to, from) - tree to, from; -{ - int constp = 1; - - for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) - { - if (TREE_CODE (from) == OFFSET_TYPE) - from = TREE_TYPE (from); - if (TREE_CODE (to) == OFFSET_TYPE) - to = TREE_TYPE (to); - - /* Const and volatile mean something different for function types, - so the usual checks are not appropriate. */ - if (TREE_CODE (from) != FUNCTION_TYPE && TREE_CODE (from) != METHOD_TYPE - && TREE_CODE (to) != FUNCTION_TYPE && TREE_CODE (to) != METHOD_TYPE) - { - if (!at_least_as_qualified_p (to, from)) - return 0; - - if (! constp - && !at_least_as_qualified_p (from, to)) - return 0; - constp &= TYPE_READONLY (to); - } - - if (TREE_CODE (from) != POINTER_TYPE - || TREE_CODE (to) != POINTER_TYPE) - return 1; - } -} - -/* Returns the type-qualifier set corresponding to TYPE. */ - -int -cp_type_quals (type) - tree type; -{ - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - return TYPE_QUALS (type); -} - -/* Returns non-zero if the TYPE contains a mutable member */ - -int -cp_has_mutable_p (type) - tree type; -{ - while (TREE_CODE (type) == ARRAY_TYPE) - type = TREE_TYPE (type); - - return CLASS_TYPE_P (type) && CLASSTYPE_HAS_MUTABLE (type); -} diff --git a/gcc/cp/typeck2.c b/gcc/cp/typeck2.c deleted file mode 100755 index eca5598..0000000 --- a/gcc/cp/typeck2.c +++ /dev/null @@ -1,1647 +0,0 @@ -/* Report error messages, build initializers, and perform - some front-end optimizations for C++ compiler. - Copyright (C) 1987, 88, 89, 92-97, 1998 Free Software Foundation, Inc. - Hacked by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* This file is part of the C++ front end. - It contains routines to build C++ expressions given their operands, - including computing the types of the result, C and C++ specific error - checks, and some optimization. - - There are also routines to build RETURN_STMT nodes and CASE_STMT nodes, - and to process initializations in declarations (since they work - like a strange sort of assignment). */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "flags.h" -#include "toplev.h" - -static tree process_init_constructor PROTO((tree, tree, tree *)); - -extern int errorcount; -extern int sorrycount; - -/* Print an error message stemming from an attempt to use - BASETYPE as a base class for TYPE. */ - -tree -error_not_base_type (basetype, type) - tree basetype, type; -{ - if (TREE_CODE (basetype) == FUNCTION_DECL) - basetype = DECL_CLASS_CONTEXT (basetype); - cp_error ("type `%T' is not a base type for type `%T'", basetype, type); - return error_mark_node; -} - -tree -binfo_or_else (parent_or_type, type) - tree parent_or_type, type; -{ - tree binfo; - if (TYPE_MAIN_VARIANT (parent_or_type) == TYPE_MAIN_VARIANT (type)) - return TYPE_BINFO (parent_or_type); - if ((binfo = get_binfo (parent_or_type, TYPE_MAIN_VARIANT (type), 0))) - { - if (binfo == error_mark_node) - return NULL_TREE; - return binfo; - } - error_not_base_type (parent_or_type, type); - return NULL_TREE; -} - -/* According to ARM $7.1.6, "A `const' object may be initialized, but its - value may not be changed thereafter. Thus, we emit hard errors for these, - rather than just pedwarns. If `SOFT' is 1, then we just pedwarn. (For - example, conversions to references.) */ - -void -readonly_error (arg, string, soft) - tree arg; - char *string; - int soft; -{ - char *fmt; - void (*fn)(); - - if (soft) - fn = cp_pedwarn; - else - fn = cp_error; - - if (TREE_CODE (arg) == COMPONENT_REF) - { - if (TYPE_READONLY (TREE_TYPE (TREE_OPERAND (arg, 0)))) - fmt = "%s of member `%D' in read-only structure"; - else - fmt = "%s of read-only member `%D'"; - (*fn) (fmt, string, TREE_OPERAND (arg, 1)); - } - else if (TREE_CODE (arg) == VAR_DECL) - { - if (DECL_LANG_SPECIFIC (arg) - && DECL_IN_AGGR_P (arg) - && !TREE_STATIC (arg)) - fmt = "%s of constant field `%D'"; - else - fmt = "%s of read-only variable `%D'"; - (*fn) (fmt, string, arg); - } - else if (TREE_CODE (arg) == PARM_DECL) - (*fn) ("%s of read-only parameter `%D'", string, arg); - else if (TREE_CODE (arg) == INDIRECT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 0))) == REFERENCE_TYPE - && (TREE_CODE (TREE_OPERAND (arg, 0)) == VAR_DECL - || TREE_CODE (TREE_OPERAND (arg, 0)) == PARM_DECL)) - (*fn) ("%s of read-only reference `%D'", string, TREE_OPERAND (arg, 0)); - else if (TREE_CODE (arg) == RESULT_DECL) - (*fn) ("%s of read-only named return value `%D'", string, arg); - else if (TREE_CODE (arg) == FUNCTION_DECL) - (*fn) ("%s of function `%D'", string, arg); - else - (*fn) ("%s of read-only location", string); -} - -/* Print an error message for invalid use of a type which declares - virtual functions which are not inheritable. */ - -void -abstract_virtuals_error (decl, type) - tree decl; - tree type; -{ - tree u = CLASSTYPE_ABSTRACT_VIRTUALS (type); - tree tu; - - if (decl) - { - if (TREE_CODE (decl) == RESULT_DECL) - return; - - if (TREE_CODE (decl) == VAR_DECL) - cp_error ("cannot declare variable `%D' to be of type `%T'", - decl, type); - else if (TREE_CODE (decl) == PARM_DECL) - cp_error ("cannot declare parameter `%D' to be of type `%T'", - decl, type); - else if (TREE_CODE (decl) == FIELD_DECL) - cp_error ("cannot declare field `%D' to be of type `%T'", - decl, type); - else if (TREE_CODE (decl) == FUNCTION_DECL - && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - cp_error ("invalid return type for method `%#D'", decl); - else if (TREE_CODE (decl) == FUNCTION_DECL) - cp_error ("invalid return type for function `%#D'", decl); - } - else - cp_error ("cannot allocate an object of type `%T'", type); - - /* Only go through this once. */ - if (TREE_PURPOSE (u) == NULL_TREE) - { - TREE_PURPOSE (u) = error_mark_node; - - error (" since the following virtual functions are abstract:"); - for (tu = u; tu; tu = TREE_CHAIN (tu)) - cp_error_at ("\t%#D", TREE_VALUE (tu)); - } - else - cp_error (" since type `%T' has abstract virtual functions", type); -} - -/* Print an error message for invalid use of a signature type. - Signatures are treated similar to abstract classes here, they - cannot be instantiated. */ - -void -signature_error (decl, type) - tree decl; - tree type; -{ - if (decl) - { - if (TREE_CODE (decl) == RESULT_DECL) - return; - - if (TREE_CODE (decl) == VAR_DECL) - cp_error ("cannot declare variable `%D' to be of signature type `%T'", - decl, type); - else if (TREE_CODE (decl) == PARM_DECL) - cp_error ("cannot declare parameter `%D' to be of signature type `%T'", - decl, type); - else if (TREE_CODE (decl) == FIELD_DECL) - cp_error ("cannot declare field `%D' to be of signature type `%T'", - decl, type); - else if (TREE_CODE (decl) == FUNCTION_DECL - && TREE_CODE (TREE_TYPE (decl)) == METHOD_TYPE) - cp_error ("invalid return type for method `%#D'", decl); - else if (TREE_CODE (decl) == FUNCTION_DECL) - cp_error ("invalid return type for function `%#D'", decl); - } - else - cp_error ("cannot allocate an object of signature type `%T'", type); -} - -/* Print an error message for invalid use of an incomplete type. - VALUE is the expression that was used (or 0 if that isn't known) - and TYPE is the type that was invalid. */ - -void -incomplete_type_error (value, type) - tree value; - tree type; -{ - char *errmsg = 0; - - /* Avoid duplicate error message. */ - if (TREE_CODE (type) == ERROR_MARK) - return; - - if (value != 0 && (TREE_CODE (value) == VAR_DECL - || TREE_CODE (value) == PARM_DECL)) - cp_error ("`%D' has incomplete type", value); - else - { - retry: - /* We must print an error message. Be clever about what it says. */ - - switch (TREE_CODE (type)) - { - case RECORD_TYPE: - case UNION_TYPE: - case ENUMERAL_TYPE: - errmsg = "invalid use of undefined type `%#T'"; - break; - - case VOID_TYPE: - error ("invalid use of void expression"); - return; - - case ARRAY_TYPE: - if (TYPE_DOMAIN (type)) - { - type = TREE_TYPE (type); - goto retry; - } - error ("invalid use of array with unspecified bounds"); - return; - - case OFFSET_TYPE: - error ("invalid use of member type (did you forget the `&' ?)"); - return; - - case TEMPLATE_TYPE_PARM: - error ("invalid use of template type parameter"); - return; - - default: - my_friendly_abort (108); - } - - cp_error (errmsg, type); - } -} - -/* Like error(), but don't call report_error_function(). */ - -static void -ack (s, v, v2) - char *s; - HOST_WIDE_INT v; - HOST_WIDE_INT v2; -{ - extern char * progname; - - if (input_filename) - fprintf (stderr, "%s:%d: ", input_filename, lineno); - else - fprintf (stderr, "%s: ", progname); - - fprintf (stderr, s, v, v2); - fprintf (stderr, "\n"); -} - -/* There are times when the compiler can get very confused, confused - to the point of giving up by aborting, simply because of previous - input errors. It is much better to have the user go back and - correct those errors first, and see if it makes us happier, than it - is to abort on him. This is because when one has a 10,000 line - program, and the compiler comes back with ``core dump'', the user - is left not knowing even where to begin to fix things and no place - to even try and work around things. - - The parameter is to uniquely identify the problem to the user, so - that they can say, I am having problem 59, and know that fix 7 will - probably solve their problem. Or, we can document what problem - 59 is, so they can understand how to work around it, should they - ever run into it. - - We used to tell people to "fix the above error[s] and try recompiling - the program" via a call to fatal, but that message tended to look - silly. So instead, we just do the equivalent of a call to fatal in the - same situation (call exit). - - We used to assign sequential numbers for the aborts; now we use an - encoding of the date the abort was added, since that has more meaning - when we only see the error message. */ - -static int abortcount = 0; - -void -my_friendly_abort (i) - int i; -{ - /* if the previous error came through here, i.e. report_error_function - ended up calling us again, don't just exit; we want a diagnostic of - some kind. */ - if (abortcount == 1) - current_function_decl = NULL_TREE; - else if (errorcount > 0 || sorrycount > 0) - { - if (abortcount > 1) - { - if (i == 0) - ack ("Internal compiler error."); - else - ack ("Internal compiler error %d.", i); -/* CYGNUS LOCAL where to report bugs -- g++ */ -#if 1 - ack ("Please submit a Problem Report to Cygnus Solutions with send-pr."); -#else - ack ("Please submit a full bug report to `egcs-bugs@cygnus.com'."); - ack ("See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details."); -#endif -/* END CYGNUS LOCAL */ - - } - else - error ("confused by earlier errors, bailing out"); - - exit (34); - } - ++abortcount; - - if (i == 0) - error ("Internal compiler error."); - else - error ("Internal compiler error %d.", i); - - error ("Please submit a full bug report to `egcs-bugs@cygnus.com'."); - fatal ("See <URL:http://egcs.cygnus.com/faq.html#bugreport> for details."); -} - -void -my_friendly_assert (cond, where) - int cond, where; -{ - if (cond == 0) - my_friendly_abort (where); -} - -/* Return nonzero if VALUE is a valid constant-valued expression - for use in initializing a static variable; one that can be an - element of a "constant" initializer. - - Return null_pointer_node if the value is absolute; - if it is relocatable, return the variable that determines the relocation. - We assume that VALUE has been folded as much as possible; - therefore, we do not need to check for such things as - arithmetic-combinations of integers. */ - -tree -initializer_constant_valid_p (value, endtype) - tree value; - tree endtype; -{ - switch (TREE_CODE (value)) - { - case CONSTRUCTOR: - if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE - && TREE_CONSTANT (value)) - return - initializer_constant_valid_p (TREE_VALUE (CONSTRUCTOR_ELTS (value)), - endtype); - - return TREE_STATIC (value) ? null_pointer_node : 0; - - case INTEGER_CST: - case REAL_CST: - case STRING_CST: - case COMPLEX_CST: - return null_pointer_node; - - case ADDR_EXPR: - return TREE_OPERAND (value, 0); - - case NON_LVALUE_EXPR: - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - case CONVERT_EXPR: - case NOP_EXPR: - /* Allow conversions between pointer types. */ - if (POINTER_TYPE_P (TREE_TYPE (value)) - && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between real types. */ - if (TREE_CODE (TREE_TYPE (value)) == REAL_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == REAL_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow length-preserving conversions between integer types. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - == TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), endtype); - - /* Allow conversions between other integer types only if - explicit value. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) - { - tree inner = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - if (inner == null_pointer_node) - return null_pointer_node; - return 0; - } - - /* Allow (int) &foo provided int is as wide as a pointer. */ - if (TREE_CODE (TREE_TYPE (value)) == INTEGER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == POINTER_TYPE - && (TYPE_PRECISION (TREE_TYPE (value)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0))))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - - /* Likewise conversions from int to pointers, but also allow - conversions from 0. */ - if (TREE_CODE (TREE_TYPE (value)) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (TREE_OPERAND (value, 0))) == INTEGER_TYPE) - { - if (integer_zerop (TREE_OPERAND (value, 0))) - return null_pointer_node; - else if (TYPE_PRECISION (TREE_TYPE (value)) - <= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (value, 0)))) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - } - - /* Allow conversions to union types if the value inside is okay. */ - if (TREE_CODE (TREE_TYPE (value)) == UNION_TYPE) - return initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - return 0; - - case PLUS_EXPR: - if ((TREE_CODE (endtype) == INTEGER_TYPE) - && (TYPE_PRECISION (endtype) < POINTER_SIZE)) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* If either term is absolute, use the other terms relocation. */ - if (valid0 == null_pointer_node) - return valid1; - if (valid1 == null_pointer_node) - return valid0; - return 0; - } - - case MINUS_EXPR: - if ((TREE_CODE (endtype) == INTEGER_TYPE) - && (TYPE_PRECISION (endtype) < POINTER_SIZE)) - return 0; - { - tree valid0 = initializer_constant_valid_p (TREE_OPERAND (value, 0), - endtype); - tree valid1 = initializer_constant_valid_p (TREE_OPERAND (value, 1), - endtype); - /* Win if second argument is absolute. */ - if (valid1 == null_pointer_node) - return valid0; - /* Win if both arguments have the same relocation. - Then the value is absolute. */ - if (valid0 == valid1) - return null_pointer_node; - return 0; - } - - default: - break; - } - - return 0; -} - -/* Perform appropriate conversions on the initial value of a variable, - store it in the declaration DECL, - and print any error messages that are appropriate. - If the init is invalid, store an ERROR_MARK. - - C++: Note that INIT might be a TREE_LIST, which would mean that it is - a base class initializer for some aggregate type, hopefully compatible - with DECL. If INIT is a single element, and DECL is an aggregate - type, we silently convert INIT into a TREE_LIST, allowing a constructor - to be called. - - If INIT is a TREE_LIST and there is no constructor, turn INIT - into a CONSTRUCTOR and use standard initialization techniques. - Perhaps a warning should be generated? - - Returns value of initializer if initialization could not be - performed for static variable. In that case, caller must do - the storing. */ - -tree -store_init_value (decl, init) - tree decl, init; -{ - register tree value, type; - - /* If variable's type was invalidly declared, just ignore it. */ - - type = TREE_TYPE (decl); - if (TREE_CODE (type) == ERROR_MARK) - return NULL_TREE; - -#if 0 - /* This breaks arrays, and should not have any effect for other decls. */ - /* Take care of C++ business up here. */ - type = TYPE_MAIN_VARIANT (type); -#endif - - if (IS_AGGR_TYPE (type)) - { - if (! TYPE_HAS_TRIVIAL_INIT_REF (type) - && TREE_CODE (init) != CONSTRUCTOR) - my_friendly_abort (109); - - /* Although we are not allowed to declare variables of signature - type, we complain about a possible constructor call in such a - declaration as well. */ - if (TREE_CODE (init) == TREE_LIST - && IS_SIGNATURE (type)) - { - cp_error ("constructor syntax cannot be used with signature type `%T'", - type); - init = error_mark_node; - } - else if (TREE_CODE (init) == TREE_LIST) - { - cp_error ("constructor syntax used, but no constructor declared for type `%T'", type); - init = build_nt (CONSTRUCTOR, NULL_TREE, nreverse (init)); - } -#if 0 - if (TREE_CODE (init) == CONSTRUCTOR) - { - tree field; - - /* Check that we're really an aggregate as ARM 8.4.1 defines it. */ - if (CLASSTYPE_N_BASECLASSES (type)) - cp_error_at ("initializer list construction invalid for derived class object `%D'", decl); - if (CLASSTYPE_VTBL_PTR (type)) - cp_error_at ("initializer list construction invalid for polymorphic class object `%D'", decl); - if (TYPE_NEEDS_CONSTRUCTING (type)) - { - cp_error_at ("initializer list construction invalid for `%D'", decl); - error ("due to the presence of a constructor"); - } - for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field)) - if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) - { - cp_error_at ("initializer list construction invalid for `%D'", decl); - cp_error_at ("due to non-public access of member `%D'", field); - } - for (field = TYPE_METHODS (type); field; field = TREE_CHAIN (field)) - if (TREE_PRIVATE (field) || TREE_PROTECTED (field)) - { - cp_error_at ("initializer list construction invalid for `%D'", decl); - cp_error_at ("due to non-public access of member `%D'", field); - } - } -#endif - } - else if (TREE_CODE (init) == TREE_LIST - && TREE_TYPE (init) != unknown_type_node) - { - if (TREE_CODE (decl) == RESULT_DECL) - { - if (TREE_CHAIN (init)) - { - warning ("comma expression used to initialize return value"); - init = build_compound_expr (init); - } - else - init = TREE_VALUE (init); - } - else if (TREE_CODE (init) == TREE_LIST - && TREE_CODE (TREE_TYPE (decl)) == ARRAY_TYPE) - { - error ("cannot initialize arrays using this syntax"); - return NULL_TREE; - } - else - { - /* We get here with code like `int a (2);' */ - - if (TREE_CHAIN (init) != NULL_TREE) - { - pedwarn ("initializer list being treated as compound expression"); - init = build_compound_expr (init); - } - else - init = TREE_VALUE (init); - } - } - - /* End of special C++ code. */ - - /* Digest the specified initializer into an expression. */ - - value = digest_init (type, init, (tree *) 0); - - /* Store the expression if valid; else report error. */ - - if (TREE_CODE (value) == ERROR_MARK) - ; - /* Other code expects that initializers for objects of types that need - constructing never make it into DECL_INITIAL, and passes 'init' to - expand_aggr_init without checking DECL_INITIAL. So just return. */ - else if (TYPE_NEEDS_CONSTRUCTING (type)) - return value; - else if (TREE_STATIC (decl) - && (! TREE_CONSTANT (value) - || ! initializer_constant_valid_p (value, TREE_TYPE (value)) -#if 0 - /* A STATIC PUBLIC int variable doesn't have to be - run time inited when doing pic. (mrs) */ - /* Since ctors and dtors are the only things that can - reference vtables, and they are always written down - the vtable definition, we can leave the - vtables in initialized data space. - However, other initialized data cannot be initialized - this way. Instead a global file-level initializer - must do the job. */ - || (flag_pic && !DECL_VIRTUAL_P (decl) && TREE_PUBLIC (decl)) -#endif - )) - - return value; -#if 0 /* No, that's C. jason 9/19/94 */ - else - { - if (pedantic && TREE_CODE (value) == CONSTRUCTOR - /* Don't complain about non-constant initializers of - signature tables and signature pointers/references. */ - && ! (TYPE_LANG_SPECIFIC (type) - && (IS_SIGNATURE (type) - || IS_SIGNATURE_POINTER (type) - || IS_SIGNATURE_REFERENCE (type)))) - { - if (! TREE_CONSTANT (value) || ! TREE_STATIC (value)) - pedwarn ("ANSI C++ forbids non-constant aggregate initializer expressions"); - } - } -#endif - DECL_INITIAL (decl) = value; - return NULL_TREE; -} - -/* Digest the parser output INIT as an initializer for type TYPE. - Return a C expression of type TYPE to represent the initial value. - - If TAIL is nonzero, it points to a variable holding a list of elements - of which INIT is the first. We update the list stored there by - removing from the head all the elements that we use. - Normally this is only one; we use more than one element only if - TYPE is an aggregate and INIT is not a constructor. */ - -tree -digest_init (type, init, tail) - tree type, init, *tail; -{ - enum tree_code code = TREE_CODE (type); - tree element = NULL_TREE; - tree old_tail_contents = NULL_TREE; - /* Nonzero if INIT is a braced grouping, which comes in as a CONSTRUCTOR - tree node which has no TREE_TYPE. */ - int raw_constructor; - - /* By default, assume we use one element from a list. - We correct this later in the sole case where it is not true. */ - - if (tail) - { - old_tail_contents = *tail; - *tail = TREE_CHAIN (*tail); - } - - if (init == error_mark_node || (TREE_CODE (init) == TREE_LIST - && TREE_VALUE (init) == error_mark_node)) - return error_mark_node; - - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (TREE_CODE (init) == NON_LVALUE_EXPR) - init = TREE_OPERAND (init, 0); - - if (TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == type) - return init; - - raw_constructor = TREE_CODE (init) == CONSTRUCTOR && TREE_TYPE (init) == 0; - - if (raw_constructor - && CONSTRUCTOR_ELTS (init) != 0 - && TREE_CHAIN (CONSTRUCTOR_ELTS (init)) == 0) - { - element = TREE_VALUE (CONSTRUCTOR_ELTS (init)); - /* Strip NON_LVALUE_EXPRs since we aren't using as an lvalue. */ - if (element && TREE_CODE (element) == NON_LVALUE_EXPR) - element = TREE_OPERAND (element, 0); - if (element == error_mark_node) - return element; - } - - /* Initialization of an array of chars from a string constant - optionally enclosed in braces. */ - - if (code == ARRAY_TYPE) - { - tree typ1; - - if (TREE_CODE (init) == TREE_LIST) - { - error ("initializing array with parameter list"); - return error_mark_node; - } - - typ1 = TYPE_MAIN_VARIANT (TREE_TYPE (type)); - if ((typ1 == char_type_node - || typ1 == signed_char_type_node - || typ1 == unsigned_char_type_node - || typ1 == unsigned_wchar_type_node - || typ1 == signed_wchar_type_node) - && ((init && TREE_CODE (init) == STRING_CST) - || (element && TREE_CODE (element) == STRING_CST))) - { - tree string = element ? element : init; - - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - != char_type_node) - && TYPE_PRECISION (typ1) == BITS_PER_UNIT) - { - error ("char-array initialized from wide string"); - return error_mark_node; - } - if ((TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (string))) - == char_type_node) - && TYPE_PRECISION (typ1) != BITS_PER_UNIT) - { - error ("int-array initialized from non-wide string"); - return error_mark_node; - } - - TREE_TYPE (string) = type; - if (TYPE_DOMAIN (type) != 0 - && TREE_CONSTANT (TYPE_SIZE (type))) - { - register int size - = TREE_INT_CST_LOW (TYPE_SIZE (type)); - size = (size + BITS_PER_UNIT - 1) / BITS_PER_UNIT; - /* In C it is ok to subtract 1 from the length of the string - because it's ok to ignore the terminating null char that is - counted in the length of the constant, but in C++ this would - be invalid. */ - if (size < TREE_STRING_LENGTH (string)) - pedwarn ("initializer-string for array of chars is too long"); - } - return string; - } - } - - /* Handle scalar types, including conversions, - and signature pointers and references. */ - - if (code == INTEGER_TYPE || code == REAL_TYPE || code == POINTER_TYPE - || code == ENUMERAL_TYPE || code == REFERENCE_TYPE - || code == BOOLEAN_TYPE || code == COMPLEX_TYPE - || TYPE_PTRMEMFUNC_P (type) - || (code == RECORD_TYPE && ! raw_constructor - && (IS_SIGNATURE_POINTER (type) || IS_SIGNATURE_REFERENCE (type)))) - { - if (raw_constructor) - { - if (element == 0) - { - error ("initializer for scalar variable requires one element"); - return error_mark_node; - } - init = element; - } - while (TREE_CODE (init) == CONSTRUCTOR && TREE_HAS_CONSTRUCTOR (init)) - { - cp_pedwarn ("braces around scalar initializer for `%T'", type); - init = CONSTRUCTOR_ELTS (init); - if (TREE_CHAIN (init)) - cp_pedwarn ("ignoring extra initializers for `%T'", type); - init = TREE_VALUE (init); - } - - return convert_for_initialization (0, type, init, LOOKUP_NORMAL, - "initialization", NULL_TREE, 0); - } - - /* Come here only for records and arrays (and unions with constructors). */ - - if (TYPE_SIZE (type) && ! TREE_CONSTANT (TYPE_SIZE (type))) - { - cp_error ("variable-sized object of type `%T' may not be initialized", - type); - return error_mark_node; - } - - if (code == ARRAY_TYPE || code == RECORD_TYPE || code == UNION_TYPE) - { - if (raw_constructor && TYPE_NON_AGGREGATE_CLASS (type)) - { - cp_error ("subobject of type `%T' must be initialized by constructor, not by `%E'", - type, init); - return error_mark_node; - } - else if (raw_constructor) - return process_init_constructor (type, init, (tree *)0); - else if (can_convert_arg (type, TREE_TYPE (init), init) - || TYPE_NON_AGGREGATE_CLASS (type)) - /* These are never initialized from multiple constructor elements. */; - else if (tail != 0) - { - *tail = old_tail_contents; - return process_init_constructor (type, 0, tail); - } - - if (code != ARRAY_TYPE) - { - int flags = LOOKUP_NORMAL; - /* Initialization from { } is copy-initialization. */ - if (tail) - flags |= LOOKUP_ONLYCONVERTING; - - return convert_for_initialization (NULL_TREE, type, init, flags, - "initialization", NULL_TREE, 0); - } - } - - error ("invalid initializer"); - return error_mark_node; -} - -/* Process a constructor for a variable of type TYPE. - The constructor elements may be specified either with INIT or with ELTS, - only one of which should be non-null. - - If INIT is specified, it is a CONSTRUCTOR node which is specifically - and solely for initializing this datum. - - If ELTS is specified, it is the address of a variable containing - a list of expressions. We take as many elements as we need - from the head of the list and update the list. - - In the resulting constructor, TREE_CONSTANT is set if all elts are - constant, and TREE_STATIC is set if, in addition, all elts are simple enough - constants that the assembler and linker can compute them. */ - -static tree -process_init_constructor (type, init, elts) - tree type, init, *elts; -{ - register tree tail; - /* List of the elements of the result constructor, - in reverse order. */ - register tree members = NULL; - register tree next1; - tree result; - int allconstant = 1; - int allsimple = 1; - int erroneous = 0; - - /* Make TAIL be the list of elements to use for the initialization, - no matter how the data was given to us. */ - - if (elts) - { - if (warn_missing_braces) - warning ("aggregate has a partly bracketed initializer"); - tail = *elts; - } - else - tail = CONSTRUCTOR_ELTS (init); - - /* Gobble as many elements as needed, and make a constructor or initial value - for each element of this aggregate. Chain them together in result. - If there are too few, use 0 for each scalar ultimate component. */ - - if (TREE_CODE (type) == ARRAY_TYPE) - { - tree domain = TYPE_DOMAIN (type); - register long len; - register int i; - - if (domain) - len = (TREE_INT_CST_LOW (TYPE_MAX_VALUE (domain)) - - TREE_INT_CST_LOW (TYPE_MIN_VALUE (domain)) - + 1); - else - len = -1; /* Take as many as there are */ - - for (i = 0; len < 0 || i < len; i++) - { - if (tail) - { - if (TREE_PURPOSE (tail) - && (TREE_CODE (TREE_PURPOSE (tail)) != INTEGER_CST - || TREE_INT_CST_LOW (TREE_PURPOSE (tail)) != i)) - sorry ("non-trivial labeled initializers"); - - if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - next1 = digest_init (TREE_TYPE (type), - TREE_VALUE (tail), &tail1); - my_friendly_assert - (same_type_p (TYPE_MAIN_VARIANT (TREE_TYPE (type)), - TYPE_MAIN_VARIANT (TREE_TYPE (next1))), - 981123); - my_friendly_assert (tail1 == 0 - || TREE_CODE (tail1) == TREE_LIST, 319); - if (tail == tail1 && len < 0) - { - error ("non-empty initializer for array of empty elements"); - /* Just ignore what we were supposed to use. */ - tail1 = NULL_TREE; - } - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - } - else if (len < 0) - /* We're done. */ - break; - else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (type))) - { - /* If this type needs constructors run for - default-initialization, we can't rely on the backend to do it - for us, so build up TARGET_EXPRs. If the type in question is - a class, just build one up; if it's an array, recurse. */ - - if (IS_AGGR_TYPE (TREE_TYPE (type))) - next1 = build_functional_cast (TREE_TYPE (type), NULL_TREE); - else - next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, NULL_TREE); - next1 = digest_init (TREE_TYPE (type), next1, 0); - } - else - /* The default zero-initialization is fine for us; don't - add anything to the CONSTRUCTOR. */ - break; - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1))) - allsimple = 0; - members = expr_tree_cons (NULL_TREE, next1, members); - } - } - else if (TREE_CODE (type) == RECORD_TYPE) - { - register tree field; - - if (tail) - { - if (TYPE_USES_VIRTUAL_BASECLASSES (type)) - { - sorry ("initializer list for object of class with virtual baseclasses"); - return error_mark_node; - } - - if (TYPE_BINFO_BASETYPES (type)) - { - sorry ("initializer list for object of class with baseclasses"); - return error_mark_node; - } - - if (TYPE_VIRTUAL_P (type)) - { - sorry ("initializer list for object using virtual functions"); - return error_mark_node; - } - } - - for (field = TYPE_FIELDS (type); field; - field = TREE_CHAIN (field)) - { - if (! DECL_NAME (field) && DECL_C_BIT_FIELD (field)) - { - members = expr_tree_cons (field, integer_zero_node, members); - continue; - } - - if (TREE_CODE (field) != FIELD_DECL) - continue; - - if (tail) - { - if (TREE_PURPOSE (tail) - && TREE_PURPOSE (tail) != field - && TREE_PURPOSE (tail) != DECL_NAME (field)) - sorry ("non-trivial labeled initializers"); - - if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1); - my_friendly_assert (tail1 == 0 - || TREE_CODE (tail1) == TREE_LIST, 320); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - } - else if (TYPE_NEEDS_CONSTRUCTING (TREE_TYPE (field))) - { - /* If this type needs constructors run for - default-initialization, we can't rely on the backend to do it - for us, so build up TARGET_EXPRs. If the type in question is - a class, just build one up; if it's an array, recurse. */ - - if (IS_AGGR_TYPE (TREE_TYPE (field))) - next1 = build_functional_cast (TREE_TYPE (field), - NULL_TREE); - else - next1 = build (CONSTRUCTOR, NULL_TREE, NULL_TREE, - NULL_TREE); - next1 = digest_init (TREE_TYPE (field), next1, 0); - - /* Warn when some struct elements are implicitly initialized. */ - if (extra_warnings) - cp_warning ("missing initializer for member `%D'", field); - } - else - { - if (TREE_READONLY (field)) - cp_error ("uninitialized const member `%D'", field); - else if (TYPE_LANG_SPECIFIC (TREE_TYPE (field)) - && CLASSTYPE_READONLY_FIELDS_NEED_INIT (TREE_TYPE (field))) - cp_error ("member `%D' with uninitialized const fields", - field); - else if (TREE_CODE (TREE_TYPE (field)) == REFERENCE_TYPE) - cp_error ("member `%D' is uninitialized reference", field); - - /* Warn when some struct elements are implicitly initialized - to zero. */ - if (extra_warnings) - cp_warning ("missing initializer for member `%D'", field); - - /* The default zero-initialization is fine for us; don't - add anything to the CONSTRUCTOR. */ - continue; - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (! initializer_constant_valid_p (next1, TREE_TYPE (next1))) - allsimple = 0; - members = expr_tree_cons (field, next1, members); - } - } - else if (TREE_CODE (type) == UNION_TYPE) - { - register tree field = TYPE_FIELDS (type); - - /* Find the first named field. ANSI decided in September 1990 - that only named fields count here. */ - while (field && (DECL_NAME (field) == 0 - || TREE_CODE (field) != FIELD_DECL)) - field = TREE_CHAIN (field); - - /* If this element specifies a field, initialize via that field. */ - if (TREE_PURPOSE (tail) != NULL_TREE) - { - int win = 0; - - if (TREE_CODE (TREE_PURPOSE (tail)) == FIELD_DECL) - /* Handle the case of a call by build_c_cast. */ - field = TREE_PURPOSE (tail), win = 1; - else if (TREE_CODE (TREE_PURPOSE (tail)) != IDENTIFIER_NODE) - error ("index value instead of field name in union initializer"); - else - { - tree temp; - for (temp = TYPE_FIELDS (type); - temp; - temp = TREE_CHAIN (temp)) - if (DECL_NAME (temp) == TREE_PURPOSE (tail)) - break; - if (temp) - field = temp, win = 1; - else - cp_error ("no field `%D' in union being initialized", - TREE_PURPOSE (tail)); - } - if (!win) - TREE_VALUE (tail) = error_mark_node; - } - else if (field == 0) - { - cp_error ("union `%T' with no named members cannot be initialized", - type); - TREE_VALUE (tail) = error_mark_node; - } - - if (TREE_VALUE (tail) != 0) - { - tree tail1 = tail; - - next1 = digest_init (TREE_TYPE (field), - TREE_VALUE (tail), &tail1); - if (tail1 != 0 && TREE_CODE (tail1) != TREE_LIST) - my_friendly_abort (357); - tail = tail1; - } - else - { - next1 = error_mark_node; - tail = TREE_CHAIN (tail); - } - - if (next1 == error_mark_node) - erroneous = 1; - else if (!TREE_CONSTANT (next1)) - allconstant = 0; - else if (initializer_constant_valid_p (next1, TREE_TYPE (next1)) == 0) - allsimple = 0; - members = expr_tree_cons (field, next1, members); - } - - /* If arguments were specified as a list, just remove the ones we used. */ - if (elts) - *elts = tail; - /* If arguments were specified as a constructor, - complain unless we used all the elements of the constructor. */ - else if (tail) - pedwarn ("excess elements in aggregate initializer"); - - if (erroneous) - return error_mark_node; - - result = build (CONSTRUCTOR, type, NULL_TREE, nreverse (members)); - if (init) - TREE_HAS_CONSTRUCTOR (result) = TREE_HAS_CONSTRUCTOR (init); - if (allconstant) TREE_CONSTANT (result) = 1; - if (allconstant && allsimple) TREE_STATIC (result) = 1; - return result; -} - -/* Given a structure or union value DATUM, construct and return - the structure or union component which results from narrowing - that value by the type specified in BASETYPE. For example, given the - hierarchy - - class L { int ii; }; - class A : L { ... }; - class B : L { ... }; - class C : A, B { ... }; - - and the declaration - - C x; - - then the expression - - x.A::ii refers to the ii member of the L part of - the A part of the C object named by X. In this case, - DATUM would be x, and BASETYPE would be A. */ - -tree -build_scoped_ref (datum, basetype) - tree datum; - tree basetype; -{ - tree ref; - tree type = TREE_TYPE (datum); - - if (datum == error_mark_node) - return error_mark_node; - - if (TREE_CODE (type) == REFERENCE_TYPE) - type = TREE_TYPE (type); - - type = TYPE_MAIN_VARIANT (type); - - /* This is an easy conversion. */ - if (is_aggr_type (basetype, 1)) - { - tree binfo = TYPE_BINFO (basetype); - if (binfo != TYPE_BINFO (type)) - { - binfo = get_binfo (binfo, type, 1); - if (binfo == error_mark_node) - return error_mark_node; - if (binfo == 0) - return error_not_base_type (basetype, type); - } - - switch (TREE_CODE (datum)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - ref = convert_pointer_to (binfo, - build_unary_op (ADDR_EXPR, TREE_OPERAND (datum, 0), 0)); - break; - default: - ref = convert_pointer_to (binfo, - build_unary_op (ADDR_EXPR, datum, 0)); - } - return build_indirect_ref (ref, "(compiler error in build_scoped_ref)"); - } - return error_mark_node; -} - -/* Build a reference to an object specified by the C++ `->' operator. - Usually this just involves dereferencing the object, but if the - `->' operator is overloaded, then such overloads must be - performed until an object which does not have the `->' operator - overloaded is found. An error is reported when circular pointer - delegation is detected. */ - -tree -build_x_arrow (datum) - tree datum; -{ - tree types_memoized = NULL_TREE; - register tree rval = datum; - tree type = TREE_TYPE (rval); - tree last_rval = NULL_TREE; - - if (type == error_mark_node) - return error_mark_node; - - if (processing_template_decl) - return build_min_nt (ARROW_EXPR, rval); - - if (TREE_CODE (rval) == OFFSET_REF) - { - rval = resolve_offset_ref (datum); - type = TREE_TYPE (rval); - } - - if (TREE_CODE (type) == REFERENCE_TYPE) - { - rval = convert_from_reference (rval); - type = TREE_TYPE (rval); - } - - if (IS_AGGR_TYPE (type)) - { - while ((rval = build_opfncall (COMPONENT_REF, LOOKUP_NORMAL, rval, - NULL_TREE, NULL_TREE))) - { - if (rval == error_mark_node) - return error_mark_node; - - if (value_member (TREE_TYPE (rval), types_memoized)) - { - error ("circular pointer delegation detected"); - return error_mark_node; - } - else - { - types_memoized = tree_cons (NULL_TREE, TREE_TYPE (rval), - types_memoized); - } - last_rval = rval; - } - - if (last_rval == NULL_TREE) - { - cp_error ("base operand of `->' has non-pointer type `%T'", type); - return error_mark_node; - } - - if (TREE_CODE (TREE_TYPE (last_rval)) == REFERENCE_TYPE) - last_rval = convert_from_reference (last_rval); - } - else - last_rval = default_conversion (rval); - - /* Signature pointers are not dereferenced. */ - if (TYPE_LANG_SPECIFIC (TREE_TYPE (last_rval)) - && IS_SIGNATURE_POINTER (TREE_TYPE (last_rval))) - return last_rval; - - if (TREE_CODE (TREE_TYPE (last_rval)) == POINTER_TYPE) - return build_indirect_ref (last_rval, NULL_PTR); - - if (types_memoized) - error ("result of `operator->()' yields non-pointer result"); - else - error ("base operand of `->' is not a pointer"); - return error_mark_node; -} - -/* Make an expression to refer to the COMPONENT field of - structure or union value DATUM. COMPONENT is an arbitrary - expression. DATUM has not already been checked out to be of - aggregate type. - - For C++, COMPONENT may be a TREE_LIST. This happens when we must - return an object of member type to a method of the current class, - but there is not yet enough typing information to know which one. - As a special case, if there is only one method by that name, - it is returned. Otherwise we return an expression which other - routines will have to know how to deal with later. */ - -tree -build_m_component_ref (datum, component) - tree datum, component; -{ - tree type; - tree objtype = TREE_TYPE (datum); - tree rettype; - tree binfo; - - if (processing_template_decl) - return build_min_nt (DOTSTAR_EXPR, datum, component); - - if (TYPE_PTRMEMFUNC_P (TREE_TYPE (component))) - { - type = TREE_TYPE (TYPE_PTRMEMFUNC_FN_TYPE (TREE_TYPE (component))); - rettype = type; - } - else - { - type = TREE_TYPE (TREE_TYPE (component)); - rettype = TREE_TYPE (type); - } - - if (datum == error_mark_node || component == error_mark_node) - return error_mark_node; - - if (TREE_CODE (type) != OFFSET_TYPE && TREE_CODE (type) != METHOD_TYPE) - { - cp_error ("`%E' cannot be used as a member pointer, since it is of type `%T'", component, type); - return error_mark_node; - } - - if (TREE_CODE (objtype) == REFERENCE_TYPE) - objtype = TREE_TYPE (objtype); - objtype = TYPE_MAIN_VARIANT (objtype); - - if (! IS_AGGR_TYPE (objtype)) - { - cp_error ("cannot apply member pointer `%E' to `%E'", component, datum); - cp_error ("which is of non-aggregate type `%T'", objtype); - return error_mark_node; - } - - binfo = get_binfo (TYPE_METHOD_BASETYPE (type), objtype, 1); - if (binfo == NULL_TREE) - { - cp_error ("member type `%T::' incompatible with object type `%T'", - TYPE_METHOD_BASETYPE (type), objtype); - return error_mark_node; - } - else if (binfo == error_mark_node) - return error_mark_node; - - component = build (OFFSET_REF, rettype, datum, component); - if (TREE_CODE (type) == OFFSET_TYPE) - component = resolve_offset_ref (component); - return component; -} - -/* Return a tree node for the expression TYPENAME '(' PARMS ')'. */ - -tree -build_functional_cast (exp, parms) - tree exp; - tree parms; -{ - /* This is either a call to a constructor, - or a C cast in C++'s `functional' notation. */ - tree type; - - if (exp == error_mark_node || parms == error_mark_node) - return error_mark_node; - - if (TREE_CODE (exp) == IDENTIFIER_NODE) - { - if (IDENTIFIER_HAS_TYPE_VALUE (exp)) - /* Either an enum or an aggregate type. */ - type = IDENTIFIER_TYPE_VALUE (exp); - else - { - type = lookup_name (exp, 1); - if (!type || TREE_CODE (type) != TYPE_DECL) - { - cp_error ("`%T' fails to be a typedef or built-in type", exp); - return error_mark_node; - } - type = TREE_TYPE (type); - } - } - else if (TREE_CODE (exp) == TYPE_DECL) - type = TREE_TYPE (exp); - else - type = exp; - - if (processing_template_decl) - return build_min (CAST_EXPR, type, parms); - - if (IS_SIGNATURE (type)) - { - error ("signature type not allowed in cast or constructor expression"); - return error_mark_node; - } - - if (! IS_AGGR_TYPE (type)) - { - /* this must build a C cast */ - if (parms == NULL_TREE) - parms = integer_zero_node; - else - { - if (TREE_CHAIN (parms) != NULL_TREE) - pedwarn ("initializer list being treated as compound expression"); - parms = build_compound_expr (parms); - } - - return build_c_cast (type, parms); - } - - /* Prepare to evaluate as a call to a constructor. If this expression - is actually used, for example, - - return X (arg1, arg2, ...); - - then the slot being initialized will be filled in. */ - - if (TYPE_SIZE (complete_type (type)) == NULL_TREE) - { - cp_error ("type `%T' is not yet defined", type); - return error_mark_node; - } - if (IS_AGGR_TYPE (type) && CLASSTYPE_ABSTRACT_VIRTUALS (type)) - { - abstract_virtuals_error (NULL_TREE, type); - return error_mark_node; - } - - if (parms && TREE_CHAIN (parms) == NULL_TREE) - return build_c_cast (type, TREE_VALUE (parms)); - - /* We need to zero-initialize POD types. Let's do that for everything - that doesn't need a constructor. */ - if (parms == NULL_TREE && !TYPE_NEEDS_CONSTRUCTING (type) - && TYPE_HAS_DEFAULT_CONSTRUCTOR (type)) - { - exp = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); - return get_target_expr (exp); - } - - exp = build_method_call (NULL_TREE, ctor_identifier, parms, - TYPE_BINFO (type), LOOKUP_NORMAL); - - if (exp == error_mark_node) - return error_mark_node; - - return build_cplus_new (type, exp); -} - -/* Return the character string for the name that encodes the - enumeral value VALUE in the domain TYPE. */ - -char * -enum_name_string (value, type) - tree value; - tree type; -{ - register tree values = TYPE_VALUES (type); - register HOST_WIDE_INT intval = TREE_INT_CST_LOW (value); - - my_friendly_assert (TREE_CODE (type) == ENUMERAL_TYPE, 324); - while (values - && TREE_INT_CST_LOW (TREE_VALUE (values)) != intval) - values = TREE_CHAIN (values); - if (values == NULL_TREE) - { - char *buf = (char *)oballoc (16 + TYPE_NAME_LENGTH (type)); - - /* Value must have been cast. */ - sprintf (buf, "(enum %s)%ld", - TYPE_NAME_STRING (type), (long) intval); - return buf; - } - return IDENTIFIER_POINTER (TREE_PURPOSE (values)); -} - -#if 0 -/* Print out a language-specific error message for - (Pascal) case or (C) switch statements. - CODE tells what sort of message to print. - TYPE is the type of the switch index expression. - NEW is the new value that we were trying to add. - OLD is the old value that stopped us from adding it. */ - -void -report_case_error (code, type, new_value, old_value) - int code; - tree type; - tree new_value, old_value; -{ - if (code == 1) - { - if (new_value) - error ("case label not within a switch statement"); - else - error ("default label not within a switch statement"); - } - else if (code == 2) - { - if (new_value == 0) - { - error ("multiple default labels in one switch"); - return; - } - if (TREE_CODE (new_value) == RANGE_EXPR) - if (TREE_CODE (old_value) == RANGE_EXPR) - { - char *buf = (char *)alloca (4 * (8 + TYPE_NAME_LENGTH (type))); - if (TREE_CODE (type) == ENUMERAL_TYPE) - sprintf (buf, "overlapping ranges [%s..%s], [%s..%s] in case expression", - enum_name_string (TREE_OPERAND (new_value, 0), type), - enum_name_string (TREE_OPERAND (new_value, 1), type), - enum_name_string (TREE_OPERAND (old_value, 0), type), - enum_name_string (TREE_OPERAND (old_value, 1), type)); - else - sprintf (buf, "overlapping ranges [%d..%d], [%d..%d] in case expression", - TREE_INT_CST_LOW (TREE_OPERAND (new_value, 0)), - TREE_INT_CST_LOW (TREE_OPERAND (new_value, 1)), - TREE_INT_CST_LOW (TREE_OPERAND (old_value, 0)), - TREE_INT_CST_LOW (TREE_OPERAND (old_value, 1))); - error (buf); - } - else - { - char *buf = (char *)alloca (4 * (8 + TYPE_NAME_LENGTH (type))); - if (TREE_CODE (type) == ENUMERAL_TYPE) - sprintf (buf, "range [%s..%s] includes element `%s' in case expression", - enum_name_string (TREE_OPERAND (new_value, 0), type), - enum_name_string (TREE_OPERAND (new_value, 1), type), - enum_name_string (old_value, type)); - else - sprintf (buf, "range [%d..%d] includes (%d) in case expression", - TREE_INT_CST_LOW (TREE_OPERAND (new_value, 0)), - TREE_INT_CST_LOW (TREE_OPERAND (new_value, 1)), - TREE_INT_CST_LOW (old_value)); - error (buf); - } - else if (TREE_CODE (old_value) == RANGE_EXPR) - { - char *buf = (char *)alloca (4 * (8 + TYPE_NAME_LENGTH (type))); - if (TREE_CODE (type) == ENUMERAL_TYPE) - sprintf (buf, "range [%s..%s] includes element `%s' in case expression", - enum_name_string (TREE_OPERAND (old_value, 0), type), - enum_name_string (TREE_OPERAND (old_value, 1), type), - enum_name_string (new_value, type)); - else - sprintf (buf, "range [%d..%d] includes (%d) in case expression", - TREE_INT_CST_LOW (TREE_OPERAND (old_value, 0)), - TREE_INT_CST_LOW (TREE_OPERAND (old_value, 1)), - TREE_INT_CST_LOW (new_value)); - error (buf); - } - else - { - if (TREE_CODE (type) == ENUMERAL_TYPE) - error ("duplicate label `%s' in switch statement", - enum_name_string (new_value, type)); - else - error ("duplicate label (%d) in switch statement", - TREE_INT_CST_LOW (new_value)); - } - } - else if (code == 3) - { - if (TREE_CODE (type) == ENUMERAL_TYPE) - warning ("case value out of range for enum %s", - TYPE_NAME_STRING (type)); - else - warning ("case value out of range"); - } - else if (code == 4) - { - if (TREE_CODE (type) == ENUMERAL_TYPE) - error ("range values `%s' and `%s' reversed", - enum_name_string (new_value, type), - enum_name_string (old_value, type)); - else - error ("range values reversed"); - } -} -#endif - -/* Complain about defining new types in inappropriate places. We give an - exception for C-style casts, to accommodate GNU C stylings. */ - -void -check_for_new_type (string, inptree) - char *string; - flagged_type_tree inptree; -{ - if (inptree.new_type_flag - && (pedantic || strcmp (string, "cast") != 0)) - pedwarn ("ANSI C++ forbids defining types within %s",string); -} diff --git a/gcc/cp/xref.c b/gcc/cp/xref.c deleted file mode 100755 index e38546e..0000000 --- a/gcc/cp/xref.c +++ /dev/null @@ -1,838 +0,0 @@ -/* Code for handling XREF output from GNU C++. - Copyright (C) 1992, 93-97, 1998 Free Software Foundation, Inc. - Contributed by Michael Tiemann (tiemann@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "cp-tree.h" -#include "input.h" -#include "toplev.h" - -extern char *getpwd PROTO((void)); - -/* The character(s) used to join a directory specification (obtained with - getwd or equivalent) with a non-absolute file name. */ - -#ifndef FILE_NAME_JOINER -#define FILE_NAME_JOINER "/" -#endif - -/* Nonzero if NAME as a file name is absolute. */ -#ifndef FILE_NAME_ABSOLUTE_P -#define FILE_NAME_ABSOLUTE_P(NAME) (NAME[0] == '/') -#endif - -/* For cross referencing. */ - -int flag_gnu_xref; - -/************************************************************************/ -/* */ -/* Common definitions */ -/* */ -/************************************************************************/ - -#ifndef TRUE -#define TRUE 1 -#endif -#ifndef FALSE -#define FALSE 0 -#endif - -#define PALLOC(typ) ((typ *) calloc(1,sizeof(typ))) - - -/* Return a malloc'd copy of STR. */ -#define SALLOC(str) \ - ((char *) ((str) == NULL ? NULL \ - : (char *) strcpy ((char *) malloc (strlen ((str)) + 1), (str)))) -#define SFREE(str) (str != NULL && (free(str),0)) - -#define STREQL(s1,s2) (strcmp((s1),(s2)) == 0) -#define STRNEQ(s1,s2) (strcmp((s1),(s2)) != 0) -#define STRLSS(s1,s2) (strcmp((s1),(s2)) < 0) -#define STRLEQ(s1,s2) (strcmp((s1),(s2)) <= 0) -#define STRGTR(s1,s2) (strcmp((s1),(s2)) > 0) -#define STRGEQ(s1,s2) (strcmp((s1),(s2)) >= 0) - -/************************************************************************/ -/* */ -/* Type definitions */ -/* */ -/************************************************************************/ - - -typedef struct _XREF_FILE * XREF_FILE; -typedef struct _XREF_SCOPE * XREF_SCOPE; - -typedef struct _XREF_FILE -{ - char *name; - char *outname; - XREF_FILE next; -} XREF_FILE_INFO; - -typedef struct _XREF_SCOPE -{ - int gid; - int lid; - XREF_FILE file; - int start; - XREF_SCOPE outer; -} XREF_SCOPE_INFO; - -/************************************************************************/ -/* */ -/* Local storage */ -/* */ -/************************************************************************/ - -static char doing_xref = 0; -static FILE * xref_file = NULL; -static char xref_name[1024]; -static XREF_FILE all_files = NULL; -static char * wd_name = NULL; -static XREF_SCOPE cur_scope = NULL; -static int scope_ctr = 0; -static XREF_FILE last_file = NULL; -static tree last_fndecl = NULL; - -/************************************************************************/ -/* */ -/* Forward definitions */ -/* */ -/************************************************************************/ -static void gen_assign PROTO((XREF_FILE, tree)); -static XREF_FILE find_file PROTO((char *)); -static char * filename PROTO((XREF_FILE)); -static char * fctname PROTO((tree)); -static char * declname PROTO((tree)); -static void simplify_type PROTO((char *)); -static char * fixname PROTO((char *, char *)); -static void open_xref_file PROTO((char *)); - -/* Start cross referencing. FILE is the name of the file we xref. */ - -void -GNU_xref_begin (file) - char *file; -{ - doing_xref = 1; - - if (file != NULL && STRNEQ (file,"-")) - { - open_xref_file(file); - GNU_xref_file(file); - } -} - -/* Finish cross-referencing. ERRCNT is the number of errors - we encountered. */ - -void -GNU_xref_end (ect) - int ect; -{ - XREF_FILE xf; - - if (!doing_xref) return; - - xf = find_file (input_filename); - if (xf == NULL) return; - - while (cur_scope != NULL) - GNU_xref_end_scope(cur_scope->gid,0,0,0); - - doing_xref = 0; - - if (xref_file == NULL) return; - - fclose (xref_file); - - xref_file = NULL; - all_files = NULL; - - if (ect > 0) unlink (xref_name); -} - -/* Write out xref for file named NAME. */ - -void -GNU_xref_file (name) - char *name; -{ - XREF_FILE xf; - - if (!doing_xref || name == NULL) return; - - if (xref_file == NULL) - { - open_xref_file (name); - if (!doing_xref) return; - } - - if (all_files == NULL) - fprintf(xref_file,"SCP * 0 0 0 0 RESET\n"); - - xf = find_file (name); - if (xf != NULL) return; - - xf = PALLOC (XREF_FILE_INFO); - xf->name = SALLOC (name); - xf->next = all_files; - all_files = xf; - - if (wd_name == NULL) - wd_name = getpwd (); - - if (FILE_NAME_ABSOLUTE_P (name) || ! wd_name) - xf->outname = xf->name; - else - { - char *nmbuf - = (char *) malloc (strlen (wd_name) + strlen (FILE_NAME_JOINER) - + strlen (name) + 1); - sprintf (nmbuf, "%s%s%s", wd_name, FILE_NAME_JOINER, name); - name = nmbuf; - xf->outname = nmbuf; - } - - fprintf (xref_file, "FIL %s %s 0\n", name, wd_name); - - filename (xf); - fctname (NULL); -} - -/* Start a scope identified at level ID. */ - -void -GNU_xref_start_scope (id) - HOST_WIDE_INT id; -{ - XREF_SCOPE xs; - XREF_FILE xf; - - if (!doing_xref) return; - xf = find_file (input_filename); - - xs = PALLOC (XREF_SCOPE_INFO); - xs->file = xf; - xs->start = lineno; - if (xs->start <= 0) xs->start = 1; - xs->gid = id; - xs->lid = ++scope_ctr; - xs->outer = cur_scope; - cur_scope = xs; -} - -/* Finish a scope at level ID. - INID is ??? - PRM is ??? - KEEP is nonzero iff this scope is retained (nonzero if it's - a compiler-generated invisible scope). - TRNS is ??? */ - -void -GNU_xref_end_scope (id,inid,prm,keep) - HOST_WIDE_INT id; - HOST_WIDE_INT inid; - int prm,keep; -{ - XREF_FILE xf; - XREF_SCOPE xs,lxs,oxs; - char *stype; - - if (!doing_xref) return; - xf = find_file (input_filename); - if (xf == NULL) return; - - lxs = NULL; - for (xs = cur_scope; xs != NULL; xs = xs->outer) - { - if (xs->gid == id) break; - lxs = xs; - } - if (xs == NULL) return; - - if (inid != 0) { - for (oxs = cur_scope; oxs != NULL; oxs = oxs->outer) { - if (oxs->gid == inid) break; - } - if (oxs == NULL) return; - inid = oxs->lid; - } - - if (prm == 2) stype = "SUE"; - else if (prm != 0) stype = "ARGS"; - else if (keep == 2 || inid != 0) stype = "INTERN"; - else stype = "EXTERN"; - - fprintf (xref_file, "SCP %s %d %d %d ", - filename (xf), xs->start, lineno,xs->lid); - fprintf (xref_file, HOST_WIDE_INT_PRINT_DEC, inid); - fprintf (xref_file, " %s\n", stype); - - if (lxs == NULL) cur_scope = xs->outer; - else lxs->outer = xs->outer; - - free (xs); -} - -/* Output a reference to NAME in FNDECL. */ - -void -GNU_xref_ref (fndecl,name) - tree fndecl; - char *name; -{ - XREF_FILE xf; - - if (!doing_xref) return; - xf = find_file (input_filename); - if (xf == NULL) return; - - fprintf (xref_file, "REF %s %d %s %s\n", - filename (xf), lineno, fctname (fndecl), name); -} - -/* Output a reference to DECL in FNDECL. */ - -void -GNU_xref_decl (fndecl,decl) - tree fndecl; - tree decl; -{ - XREF_FILE xf,xf1; - char *cls = 0; - char *name; - char buf[10240]; - int uselin; - - if (!doing_xref) return; - xf = find_file (input_filename); - if (xf == NULL) return; - - uselin = FALSE; - - if (TREE_CODE (decl) == TYPE_DECL) cls = "TYPEDEF"; - else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; - else if (TREE_CODE (decl) == VAR_DECL) - { - if (fndecl == NULL && TREE_STATIC(decl) - && TREE_READONLY(decl) && DECL_INITIAL(decl) != 0 - && !TREE_PUBLIC(decl) && !DECL_EXTERNAL(decl) - && DECL_MODE(decl) != BLKmode) cls = "CONST"; - else if (DECL_EXTERNAL(decl)) cls = "EXTERN"; - else if (TREE_PUBLIC(decl)) cls = "EXTDEF"; - else if (TREE_STATIC(decl)) cls = "STATIC"; - else if (DECL_REGISTER(decl)) cls = "REGISTER"; - else cls = "AUTO"; - } - else if (TREE_CODE (decl) == PARM_DECL) cls = "PARAM"; - else if (TREE_CODE (decl) == FIELD_DECL) cls = "FIELD"; - else if (TREE_CODE (decl) == CONST_DECL) cls = "CONST"; - else if (TREE_CODE (decl) == FUNCTION_DECL) - { - if (DECL_EXTERNAL (decl)) cls = "EXTERN"; - else if (TREE_PUBLIC (decl)) cls = "EFUNCTION"; - else cls = "SFUNCTION"; - } - else if (TREE_CODE (decl) == LABEL_DECL) cls = "LABEL"; - else if (TREE_CODE (decl) == UNION_TYPE) - { - cls = "UNIONID"; - decl = TYPE_NAME (decl); - uselin = TRUE; - } - else if (TREE_CODE (decl) == RECORD_TYPE) - { - if (CLASSTYPE_DECLARED_CLASS (decl)) cls = "CLASSID"; - else if (IS_SIGNATURE (decl)) cls = "SIGNATUREID"; - else cls = "STRUCTID"; - decl = TYPE_NAME (decl); - uselin = TRUE; - } - else if (TREE_CODE (decl) == ENUMERAL_TYPE) - { - cls = "ENUMID"; - decl = TYPE_NAME (decl); - uselin = TRUE; - } - else if (TREE_CODE (decl) == TEMPLATE_DECL) - { - if (TREE_CODE (DECL_RESULT (decl)) == TYPE_DECL) - cls = "CLASSTEMP"; - else if (TREE_CODE (DECL_RESULT (decl)) == FUNCTION_DECL) - cls = "FUNCTEMP"; - else if (TREE_CODE (DECL_RESULT (decl)) == VAR_DECL) - cls = "VARTEMP"; - else - my_friendly_abort (358); - uselin = TRUE; - } - else cls = "UNKNOWN"; - - if (decl == NULL || DECL_NAME (decl) == NULL) return; - - if (uselin && decl->decl.linenum > 0 && decl->decl.filename != NULL) - { - xf1 = find_file (decl->decl.filename); - if (xf1 != NULL) - { - lineno = decl->decl.linenum; - xf = xf1; - } - } - - if (DECL_ASSEMBLER_NAME (decl)) - name = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)); - else - name = IDENTIFIER_POINTER (DECL_NAME (decl)); - - strcpy (buf, type_as_string (TREE_TYPE (decl), 0)); - simplify_type (buf); - - fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", - filename(xf), lineno, name, - (cur_scope != NULL ? cur_scope->lid : 0), - cls, fctname(fndecl), buf); - - if (STREQL (cls, "STRUCTID") || STREQL (cls, "UNIONID") - || STREQL (cls, "SIGNATUREID")) - { - cls = "CLASSID"; - fprintf (xref_file, "DCL %s %d %s %d %s %s %s\n", - filename(xf), lineno,name, - (cur_scope != NULL ? cur_scope->lid : 0), - cls, fctname(fndecl), buf); - } -} - -/* Output a reference to a call to NAME in FNDECL. */ - -void -GNU_xref_call (fndecl, name) - tree fndecl; - char *name; -{ - XREF_FILE xf; - char buf[1024]; - char *s; - - if (!doing_xref) return; - xf = find_file (input_filename); - if (xf == NULL) return; - name = fixname (name, buf); - - for (s = name; *s != 0; ++s) - if (*s == '_' && s[1] == '_') break; - if (*s != 0) GNU_xref_ref (fndecl, name); - - fprintf (xref_file, "CAL %s %d %s %s\n", - filename (xf), lineno, name, fctname (fndecl)); -} - -/* Output cross-reference info about FNDECL. If non-NULL, - ARGS are the arguments for the function (i.e., before the FUNCTION_DECL - has been fully built). */ - -void -GNU_xref_function (fndecl, args) - tree fndecl; - tree args; -{ - XREF_FILE xf; - int ct; - char buf[1024]; - - if (!doing_xref) return; - xf = find_file (input_filename); - if (xf == NULL) return; - - ct = 0; - buf[0] = 0; - if (args == NULL) args = DECL_ARGUMENTS (fndecl); - - GNU_xref_decl (NULL, fndecl); - - for ( ; args != NULL; args = TREE_CHAIN (args)) - { - GNU_xref_decl (fndecl,args); - if (ct != 0) strcat (buf,","); - strcat (buf, declname (args)); - ++ct; - } - - fprintf (xref_file, "PRC %s %d %s %d %d %s\n", - filename(xf), lineno, declname(fndecl), - (cur_scope != NULL ? cur_scope->lid : 0), - ct, buf); -} - -/* Output cross-reference info about an assignment to NAME. */ - -void -GNU_xref_assign(name) - tree name; -{ - XREF_FILE xf; - - if (!doing_xref) return; - xf = find_file(input_filename); - if (xf == NULL) return; - - gen_assign(xf, name); -} - -static void -gen_assign(xf, name) - XREF_FILE xf; - tree name; -{ - char *s; - - s = NULL; - - switch (TREE_CODE (name)) - { - case IDENTIFIER_NODE : - s = IDENTIFIER_POINTER(name); - break; - case VAR_DECL : - s = declname(name); - break; - case COMPONENT_REF : - gen_assign(xf, TREE_OPERAND(name, 0)); - gen_assign(xf, TREE_OPERAND(name, 1)); - break; - case INDIRECT_REF : - case OFFSET_REF : - case ARRAY_REF : - case BUFFER_REF : - gen_assign(xf, TREE_OPERAND(name, 0)); - break; - case COMPOUND_EXPR : - gen_assign(xf, TREE_OPERAND(name, 1)); - break; - default : - break; - } - - if (s != NULL) - fprintf(xref_file, "ASG %s %d %s\n", filename(xf), lineno, s); -} - -static char* -classname (cls) - tree cls; -{ - if (cls && TREE_CODE_CLASS (TREE_CODE (cls)) == 't') - cls = TYPE_NAME (cls); - if (cls && TREE_CODE_CLASS (TREE_CODE (cls)) == 'd') - cls = DECL_NAME (cls); - if (cls && TREE_CODE (cls) == IDENTIFIER_NODE) - return IDENTIFIER_POINTER (cls); - return "?"; -} - -/* Output cross-reference info about a class hierarchy. - CLS is the class type of interest. BASE is a baseclass - for CLS. PUB and VIRT give the access info about - the class derivation. FRND is nonzero iff BASE is a friend - of CLS. - - ??? Needs to handle nested classes. */ - -void -GNU_xref_hier(cls, base, pub, virt, frnd) - tree cls; - tree base; - int pub; - int virt; - int frnd; -{ - XREF_FILE xf; - - if (!doing_xref) return; - xf = find_file(input_filename); - if (xf == NULL) return; - - fprintf(xref_file, "HIE %s %d %s %s %d %d %d\n", - filename(xf), lineno, classname (cls), classname (base), - pub, virt, frnd); -} - -/* Output cross-reference info about class members. CLS - is the containing type; FLD is the class member. */ - -void -GNU_xref_member(cls, fld) - tree cls; - tree fld; -{ - XREF_FILE xf; - char *prot; - int confg, pure; - char *d; -#ifdef XREF_SHORT_MEMBER_NAMES - int i; -#endif - char buf[1024], bufa[1024]; - - if (!doing_xref) return; - xf = find_file(fld->decl.filename); - if (xf == NULL) return; - - if (TREE_PRIVATE (fld)) prot = "PRIVATE"; - else if (TREE_PROTECTED(fld)) prot = "PROTECTED"; - else prot = "PUBLIC"; - - confg = 0; - if (TREE_CODE (fld) == FUNCTION_DECL && DECL_CONST_MEMFUNC_P(fld)) - confg = 1; - else if (TREE_CODE (fld) == CONST_DECL) - confg = 1; - - pure = 0; - if (TREE_CODE (fld) == FUNCTION_DECL && DECL_ABSTRACT_VIRTUAL_P(fld)) - pure = 1; - - d = IDENTIFIER_POINTER(cls); - sprintf(buf, "%d%s", (int) strlen(d), d); -#ifdef XREF_SHORT_MEMBER_NAMES - i = strlen(buf); -#endif - strcpy(bufa, declname(fld)); - -#ifdef XREF_SHORT_MEMBER_NAMES - for (p = &bufa[1]; *p != 0; ++p) - { - if (p[0] == '_' && p[1] == '_' && p[2] >= '0' && p[2] <= '9') { - if (strncmp(&p[2], buf, i) == 0) *p = 0; - break; - } - else if (p[0] == '_' && p[1] == '_' && p[2] == 'C' && p[3] >= '0' && p[3] <= '9') { - if (strncmp(&p[3], buf, i) == 0) *p = 0; - break; - } - } -#endif - - fprintf(xref_file, "MEM %s %d %s %s %s %d %d %d %d %d %d %d\n", - filename(xf), fld->decl.linenum, d, bufa, prot, - (TREE_CODE (fld) == FUNCTION_DECL ? 0 : 1), - (DECL_INLINE (fld) ? 1 : 0), - (DECL_LANG_SPECIFIC(fld) && DECL_FRIEND_P(fld) ? 1 : 0), - (DECL_VINDEX(fld) ? 1 : 0), - (TREE_STATIC(fld) ? 1 : 0), - pure, confg); -} - -/* Find file entry given name. */ - -static XREF_FILE -find_file(name) - char *name; -{ - XREF_FILE xf; - - for (xf = all_files; xf != NULL; xf = xf->next) { - if (STREQL(name, xf->name)) break; - } - - return xf; -} - -/* Return filename for output purposes. */ - -static char * -filename(xf) - XREF_FILE xf; -{ - if (xf == NULL) { - last_file = NULL; - return "*"; - } - - if (last_file == xf) return "*"; - - last_file = xf; - - return xf->outname; -} - -/* Return function name for output purposes. */ - -static char * -fctname(fndecl) - tree fndecl; -{ - static char fctbuf[1024]; - char *s; - - if (fndecl == NULL && last_fndecl == NULL) return "*"; - - if (fndecl == NULL) - { - last_fndecl = NULL; - return "*TOP*"; - } - - if (fndecl == last_fndecl) return "*"; - - last_fndecl = fndecl; - - s = declname(fndecl); - s = fixname(s, fctbuf); - - return s; -} - -/* Return decl name for output purposes. */ - -static char * -declname(dcl) - tree dcl; -{ - if (DECL_NAME (dcl) == NULL) return "?"; - - if (DECL_ASSEMBLER_NAME (dcl)) - return IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (dcl)); - else - return IDENTIFIER_POINTER (DECL_NAME (dcl)); -} - -/* Simplify a type string by removing unneeded parenthesis. */ - -static void -simplify_type(typ) - char *typ; -{ - char *s; - int lvl, i; - - i = strlen(typ); - while (i > 0 && ISSPACE((unsigned char) typ[i-1])) typ[--i] = 0; - - if (i > 7 && STREQL(&typ[i-5], "const")) - { - typ[i-5] = 0; - i -= 5; - } - - if (typ[i-1] != ')') return; - - s = &typ[i-2]; - lvl = 1; - while (*s != 0) { - if (*s == ')') ++lvl; - else if (*s == '(') - { - --lvl; - if (lvl == 0) - { - s[1] = ')'; - s[2] = 0; - break; - } - } - --s; - } - - if (*s != 0 && s[-1] == ')') - { - --s; - --s; - if (*s == '(') s[2] = 0; - else if (*s == ':') { - while (*s != '(') --s; - s[1] = ')'; - s[2] = 0; - } - } -} - -/* Fixup a function name (take care of embedded spaces). */ - -static char * -fixname(nam, buf) - char *nam; - char *buf; -{ - char *s, *t; - int fg; - - s = nam; - t = buf; - fg = 0; - - while (*s != 0) - { - if (*s == ' ') - { - *t++ = '\36'; - ++fg; - } - else *t++ = *s; - ++s; - } - *t = 0; - - if (fg == 0) return nam; - - return buf; -} - -/* Open file for xreffing. */ - -static void -open_xref_file(file) - char *file; -{ - char *s, *t; - -#ifdef XREF_FILE_NAME - XREF_FILE_NAME (xref_name, file); -#else - s = rindex (file, '/'); - if (s == NULL) - sprintf (xref_name, ".%s.gxref", file); - else - { - ++s; - strcpy (xref_name, file); - t = rindex (xref_name, '/'); - ++t; - *t++ = '.'; - strcpy (t, s); - strcat (t, ".gxref"); - } -#endif /* no XREF_FILE_NAME */ - - xref_file = fopen(xref_name, "w"); - - if (xref_file == NULL) - { - error("Can't create cross-reference file `%s'", xref_name); - doing_xref = 0; - } -} diff --git a/gcc/crtstuff.c b/gcc/crtstuff.c deleted file mode 100755 index ce2c956..0000000 --- a/gcc/crtstuff.c +++ /dev/null @@ -1,530 +0,0 @@ -/* Specialized bits of code needed to support construction and - destruction of file-scope objects in C++ code. - Copyright (C) 1991, 94, 95, 96, 97, 1998 Free Software Foundation, Inc. - Contributed by Ron Guilmette (rfg@monkeys.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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with files - compiled with GCC to produce an executable, this does not cause - the resulting executable to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -/* This file is a bit like libgcc1.c/libgcc2.c in that it is compiled - multiple times and yields multiple .o files. - - This file is useful on target machines where the object file format - supports multiple "user-defined" sections (e.g. COFF, ELF, ROSE). On - such systems, this file allows us to avoid running collect (or any - other such slow and painful kludge). Additionally, if the target - system supports a .init section, this file allows us to support the - linking of C++ code with a non-C++ main program. - - Note that if INIT_SECTION_ASM_OP is defined in the tm.h file, then - this file *will* make use of the .init section. If that symbol is - not defined however, then the .init section will not be used. - - Currently, only ELF and COFF are supported. It is likely however that - ROSE could also be supported, if someone was willing to do the work to - make whatever (small?) adaptations are needed. (Some work may be - needed on the ROSE assembler and linker also.) - - This file must be compiled with gcc. */ - -/* It is incorrect to include config.h here, because this file is being - compiled for the target, and hence definitions concerning only the host - do not apply. */ - -#include "tm.h" -#include "defaults.h" -#include <stddef.h> -#include "frame.h" - -#ifndef OBJECT_FORMAT_MACHO - -/* Provide default definitions for the pseudo-ops used to switch to the - .ctors and .dtors sections. - - Note that we want to give these sections the SHF_WRITE attribute - because these sections will actually contain data (i.e. tables of - addresses of functions in the current root executable or shared library - file) and, in the case of a shared library, the relocatable addresses - will have to be properly resolved/relocated (and then written into) by - the dynamic linker when it actually attaches the given shared library - to the executing process. (Note that on SVR4, you may wish to use the - `-z text' option to the ELF linker, when building a shared library, as - an additional check that you are doing everything right. But if you do - use the `-z text' option when building a shared library, you will get - errors unless the .ctors and .dtors sections are marked as writable - via the SHF_WRITE attribute.) */ - -#ifndef CTORS_SECTION_ASM_OP -#define CTORS_SECTION_ASM_OP ".section\t.ctors,\"aw\"" -#endif -#ifndef DTORS_SECTION_ASM_OP -#define DTORS_SECTION_ASM_OP ".section\t.dtors,\"aw\"" -#endif -#if !defined (EH_FRAME_SECTION_ASM_OP) && defined (DWARF2_UNWIND_INFO) && defined(ASM_OUTPUT_SECTION_NAME) -#define EH_FRAME_SECTION_ASM_OP ".section\t.eh_frame,\"aw\"" -#endif - -#ifdef OBJECT_FORMAT_ELF - -/* Declare a pointer to void function type. */ -typedef void (*func_ptr) (void); -#define STATIC static - -#else /* OBJECT_FORMAT_ELF */ - -#include "gbl-ctors.h" - -#ifndef ON_EXIT -#define ON_EXIT(a, b) -#endif -#define STATIC - -#endif /* OBJECT_FORMAT_ELF */ - -#ifdef CRT_BEGIN - -#ifdef INIT_SECTION_ASM_OP - -#ifdef OBJECT_FORMAT_ELF - -/* Run all the global destructors on exit from the program. */ - -/* Some systems place the number of pointers in the first word of the - table. On SVR4 however, that word is -1. In all cases, the table is - null-terminated. On SVR4, we start from the beginning of the list and - invoke each per-compilation-unit destructor routine in order - until we find that null. - - Note that this function MUST be static. There will be one of these - functions in each root executable and one in each shared library, but - although they all have the same code, each one is unique in that it - refers to one particular associated `__DTOR_LIST__' which belongs to the - same particular root executable or shared library file. - - On some systems, this routine is run more than once from the .fini, - when exit is called recursively, so we arrange to remember where in - the list we left off processing, and we resume at that point, - should we be re-invoked. */ - -static char __EH_FRAME_BEGIN__[]; -static func_ptr __DTOR_LIST__[]; -static void -__do_global_dtors_aux () -{ - static func_ptr *p = __DTOR_LIST__ + 1; - static int completed = 0; - - if (completed) - return; - - while (*p) - { - p++; - (*(p-1)) (); - } - -#ifdef EH_FRAME_SECTION_ASM_OP - __deregister_frame_info (__EH_FRAME_BEGIN__); -#endif - completed = 1; -} - - -/* Stick a call to __do_global_dtors_aux into the .fini section. */ - -static void __attribute__ ((__unused__)) -fini_dummy () -{ - asm (FINI_SECTION_ASM_OP); - __do_global_dtors_aux (); -#ifdef FORCE_FINI_SECTION_ALIGN - FORCE_FINI_SECTION_ALIGN; -#endif - asm (TEXT_SECTION_ASM_OP); -} - -#ifdef EH_FRAME_SECTION_ASM_OP -/* Stick a call to __register_frame_info into the .init section. For some - reason calls with no arguments work more reliably in .init, so stick the - call in another function. */ - -static void -frame_dummy () -{ - static struct object object; - __register_frame_info (__EH_FRAME_BEGIN__, &object); -} - -static void __attribute__ ((__unused__)) -init_dummy () -{ - asm (INIT_SECTION_ASM_OP); - frame_dummy (); -#ifdef FORCE_INIT_SECTION_ALIGN - FORCE_INIT_SECTION_ALIGN; -#endif - asm (TEXT_SECTION_ASM_OP); -} -#endif /* EH_FRAME_SECTION_ASM_OP */ - -#else /* OBJECT_FORMAT_ELF */ - -/* The function __do_global_ctors_aux is compiled twice (once in crtbegin.o - and once in crtend.o). It must be declared static to avoid a link - error. Here, we define __do_global_ctors as an externally callable - function. It is externally callable so that __main can invoke it when - INVOKE__main is defined. This has the additional effect of forcing cc1 - to switch to the .text section. */ - -static void __do_global_ctors_aux (); -void __do_global_ctors () -{ -#ifdef INVOKE__main /* If __main won't actually call __do_global_ctors - then it doesn't matter what's inside the function. - The inside of __do_global_ctors_aux is called - automatically in that case. - And the Alliant fx2800 linker crashes - on this reference. So prevent the crash. */ - __do_global_ctors_aux (); -#endif -} - -asm (INIT_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ - -/* On some svr4 systems, the initial .init section preamble code provided in - crti.o may do something, such as bump the stack, which we have to - undo before we reach the function prologue code for __do_global_ctors - (directly below). For such systems, define the macro INIT_SECTION_PREAMBLE - to expand into the code needed to undo the actions of the crti.o file. */ - -#ifdef INIT_SECTION_PREAMBLE - INIT_SECTION_PREAMBLE; -#endif - -/* A routine to invoke all of the global constructors upon entry to the - program. We put this into the .init section (for systems that have - such a thing) so that we can properly perform the construction of - file-scope static-storage C++ objects within shared libraries. */ - -static void -__do_global_ctors_aux () /* prologue goes in .init section */ -{ -#ifdef FORCE_INIT_SECTION_ALIGN - FORCE_INIT_SECTION_ALIGN; /* Explicit align before switch to .text */ -#endif - asm (TEXT_SECTION_ASM_OP); /* don't put epilogue and body in .init */ - DO_GLOBAL_CTORS_BODY; - ON_EXIT (__do_global_dtors, 0); -} - -#endif /* OBJECT_FORMAT_ELF */ - -#else /* defined(INIT_SECTION_ASM_OP) */ - -#ifdef HAS_INIT_SECTION -/* This case is used by the Irix 6 port, which supports named sections but - not an SVR4-style .fini section. __do_global_dtors can be non-static - in this case because we protect it with -hidden_symbol. */ - -static char __EH_FRAME_BEGIN__[]; -static func_ptr __DTOR_LIST__[]; -void -__do_global_dtors () -{ - func_ptr *p; - for (p = __DTOR_LIST__ + 1; *p; p++) - (*p) (); - -#ifdef EH_FRAME_SECTION_ASM_OP - __deregister_frame_info (__EH_FRAME_BEGIN__); -#endif -} - -#ifdef EH_FRAME_SECTION_ASM_OP -/* Define a function here to call __register_frame. crtend.o is linked in - after libgcc.a, and hence can't call libgcc.a functions directly. That - can lead to unresolved function references. */ -void -__frame_dummy () -{ - static struct object object; - __register_frame_info (__EH_FRAME_BEGIN__, &object); -} -#endif -#endif - -#endif /* defined(INIT_SECTION_ASM_OP) */ - -/* Force cc1 to switch to .data section. */ -static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; - -/* NOTE: In order to be able to support SVR4 shared libraries, we arrange - to have one set of symbols { __CTOR_LIST__, __DTOR_LIST__, __CTOR_END__, - __DTOR_END__ } per root executable and also one set of these symbols - per shared library. So in any given whole process image, we may have - multiple definitions of each of these symbols. In order to prevent - these definitions from conflicting with one another, and in order to - ensure that the proper lists are used for the initialization/finalization - of each individual shared library (respectively), we give these symbols - only internal (i.e. `static') linkage, and we also make it a point to - refer to only the __CTOR_END__ symbol in crtend.o and the __DTOR_LIST__ - symbol in crtbegin.o, where they are defined. */ - -/* The -1 is a flag to __do_global_[cd]tors - indicating that this table does not start with a count of elements. */ -#ifdef CTOR_LIST_BEGIN -CTOR_LIST_BEGIN; -#else -asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ -STATIC func_ptr __CTOR_LIST__[1] __attribute__ ((__unused__)) - = { (func_ptr) (-1) }; -#endif - -#ifdef DTOR_LIST_BEGIN -DTOR_LIST_BEGIN; -#else -asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ -STATIC func_ptr __DTOR_LIST__[1] = { (func_ptr) (-1) }; -#endif - -#ifdef EH_FRAME_SECTION_ASM_OP -/* Stick a label at the beginning of the frame unwind info so we can register - and deregister it with the exception handling library code. */ - -asm (EH_FRAME_SECTION_ASM_OP); -#ifdef INIT_SECTION_ASM_OP -STATIC -#endif -char __EH_FRAME_BEGIN__[] = { }; -#endif /* EH_FRAME_SECTION_ASM_OP */ - -#endif /* defined(CRT_BEGIN) */ - -#ifdef CRT_END - -#ifdef INIT_SECTION_ASM_OP - -#ifdef OBJECT_FORMAT_ELF - -static func_ptr __CTOR_END__[]; -static void -__do_global_ctors_aux () -{ - func_ptr *p; - for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) - (*p) (); -} - -/* Stick a call to __do_global_ctors_aux into the .init section. */ - -static void __attribute__ ((__unused__)) -init_dummy () -{ - asm (INIT_SECTION_ASM_OP); - __do_global_ctors_aux (); -#ifdef FORCE_INIT_SECTION_ALIGN - FORCE_INIT_SECTION_ALIGN; -#endif - asm (TEXT_SECTION_ASM_OP); - -/* This is a kludge. The i386 GNU/Linux dynamic linker needs ___brk_addr, - __environ and atexit (). We have to make sure they are in the .dynsym - section. We accomplish it by making a dummy call here. This - code is never reached. */ - -#if defined(__linux__) && defined(__PIC__) && defined(__i386__) - { - extern void *___brk_addr; - extern char **__environ; - - ___brk_addr = __environ; - atexit (); - } -#endif -} - -#else /* OBJECT_FORMAT_ELF */ - -/* Stick the real initialization code, followed by a normal sort of - function epilogue at the very end of the .init section for this - entire root executable file or for this entire shared library file. - - Note that we use some tricks here to get *just* the body and just - a function epilogue (but no function prologue) into the .init - section of the crtend.o file. Specifically, we switch to the .text - section, start to define a function, and then we switch to the .init - section just before the body code. - - Earlier on, we put the corresponding function prologue into the .init - section of the crtbegin.o file (which will be linked in first). - - Note that we want to invoke all constructors for C++ file-scope static- - storage objects AFTER any other possible initialization actions which - may be performed by the code in the .init section contributions made by - other libraries, etc. That's because those other initializations may - include setup operations for very primitive things (e.g. initializing - the state of the floating-point coprocessor, etc.) which should be done - before we start to execute any of the user's code. */ - -static void -__do_global_ctors_aux () /* prologue goes in .text section */ -{ - asm (INIT_SECTION_ASM_OP); - DO_GLOBAL_CTORS_BODY; - ON_EXIT (__do_global_dtors, 0); -} /* epilogue and body go in .init section */ - -#ifdef FORCE_INIT_SECTION_ALIGN -FORCE_INIT_SECTION_ALIGN; -#endif - -asm (TEXT_SECTION_ASM_OP); - -#endif /* OBJECT_FORMAT_ELF */ - -#else /* defined(INIT_SECTION_ASM_OP) */ - -#ifdef HAS_INIT_SECTION -/* This case is used by the Irix 6 port, which supports named sections but - not an SVR4-style .init section. __do_global_ctors can be non-static - in this case because we protect it with -hidden_symbol. */ -static func_ptr __CTOR_END__[]; -#ifdef EH_FRAME_SECTION_ASM_OP -extern void __frame_dummy (void); -#endif -void -__do_global_ctors () -{ - func_ptr *p; -#ifdef EH_FRAME_SECTION_ASM_OP - __frame_dummy (); -#endif - for (p = __CTOR_END__ - 1; *p != (func_ptr) -1; p--) - (*p) (); -} -#endif - -#endif /* defined(INIT_SECTION_ASM_OP) */ - -/* Force cc1 to switch to .data section. */ -static func_ptr force_to_data[0] __attribute__ ((__unused__)) = { }; - -/* Put a word containing zero at the end of each of our two lists of function - addresses. Note that the words defined here go into the .ctors and .dtors - sections of the crtend.o file, and since that file is always linked in - last, these words naturally end up at the very ends of the two lists - contained in these two sections. */ - -#ifdef CTOR_LIST_END -CTOR_LIST_END; -#else -asm (CTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ -STATIC func_ptr __CTOR_END__[1] = { (func_ptr) 0 }; -#endif - -#ifdef DTOR_LIST_END -DTOR_LIST_END; -#else -asm (DTORS_SECTION_ASM_OP); /* cc1 doesn't know that we are switching! */ -STATIC func_ptr __DTOR_END__[1] __attribute__ ((__unused__)) - = { (func_ptr) 0 }; -#endif - -#ifdef EH_FRAME_SECTION_ASM_OP -/* Terminate the frame unwind info section with a 4byte 0 as a sentinel; - this would be the 'length' field in a real FDE. */ - -typedef unsigned int ui32 __attribute__ ((mode (SI))); -asm (EH_FRAME_SECTION_ASM_OP); -STATIC ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; -#endif /* EH_FRAME_SECTION */ - -#endif /* defined(CRT_END) */ - -#else /* OBJECT_FORMAT_MACHO */ - -/* For Mach-O format executables, we assume that the system's runtime is - smart enough to handle constructors and destructors, but doesn't have - an init section (if it can't even handle constructors/destructors - you should be using INVOKE__main, not crtstuff). All we need to do - is install/deinstall the frame information for exceptions. We do this - by putting a constructor in crtbegin.o and a destructor in crtend.o. - - crtend.o also puts in the terminating zero in the frame information - segment. */ - -/* The crtstuff for other object formats use the symbol __EH_FRAME_BEGIN__ - to figure out the start of the exception frame, but here we use - getsectbynamefromheader to find this value. Either method would work, - but this method avoids creating any global symbols, which seems - cleaner. */ - -#include <mach-o/ldsyms.h> -extern const struct section * - getsectbynamefromheader (const struct mach_header *, - const char *, const char *); - -#ifdef CRT_BEGIN - -static void __reg_frame_ctor () __attribute__ ((constructor)); - -static void -__reg_frame_ctor () -{ - static struct object object; - const struct section *eh_frame; - - eh_frame = getsectbynamefromheader (&_mh_execute_header, - "__TEXT", "__eh_frame"); - __register_frame_info ((void *) eh_frame->addr, &object); -} - -#endif /* CRT_BEGIN */ - -#ifdef CRT_END - -static void __dereg_frame_dtor () __attribute__ ((destructor)); - -static -void __dereg_frame_dtor () -{ - const struct section *eh_frame; - - eh_frame = getsectbynamefromheader (&_mh_execute_header, - "__TEXT", "__eh_frame"); - __deregister_frame_info ((void *) eh_frame->addr); -} - -/* Terminate the frame section with a final zero. */ - -/* Force cc1 to switch to .data section. */ -static void * force_to_data[0] __attribute__ ((__unused__)) = { }; - -typedef unsigned int ui32 __attribute__ ((mode (SI))); -asm (EH_FRAME_SECTION_ASM_OP); -static ui32 __FRAME_END__[] __attribute__ ((__unused__)) = { 0 }; - -#endif /* CRT_END */ - -#endif /* OBJECT_FORMAT_MACHO */ - diff --git a/gcc/f/BUGS b/gcc/f/BUGS deleted file mode 100755 index 703393f..0000000 --- a/gcc/f/BUGS +++ /dev/null @@ -1,221 +0,0 @@ -This file lists known bugs in the GNU Fortran compiler. Copyright (C) -1995, 1996 Free Software Foundation, Inc. You may copy, distribute, -and modify it freely as long as you preserve this copyright notice and -permission notice. - -Bugs in GNU Fortran -******************* - - This section identifies bugs that `g77' *users* might run into. -This includes bugs that are actually in the `gcc' back end (GBE) or in -`libf2c', because those sets of code are at least somewhat under the -control of (and necessarily intertwined with) `g77', so it isn't worth -separating them out. - - For information on bugs that might afflict people who configure, -port, build, and install `g77', *Note Problems Installing::. - - * `g77' sometimes crashes when compiling code containing the - construct `CMPLX(0.)' or similar. This is a `gcc' back-end bug. - It can be worked around using `-fno-emulate-complex', though that - might trigger other, older bugs. Compiling without optimization - is another work-around. - - Fixed in `egcs' 1.1. - - * Automatic arrays aren't working on HP-UX systems, at least in - HP-UX version 10.20. Writing into them apparently causes - over-writing of statically declared data in the main program. - This probably means the arrays themselves are being - under-allocated, or pointers to them being improperly handled, - e.g. not passed to other procedures as they should be. - - * Some Fortran code has been found to be miscompiled by `g77' built - on `gcc' version 2.8.1 on m68k-next-nextstep3 configurations when - using the `-O2' option. Even a C function is known to miscompile - on that configuration when using the `-O2 -funroll-loops' options. - - Fixed in `egcs'. - - * A code-generation bug afflicts Intel x86 targets when `-O2' is - specified compiling, for example, an old version of the `DNRM2' - routine. The x87 coprocessor stack is being mismanaged in cases - where assigned `GOTO' and `ASSIGN' are involved. - - Fixed in `egcs' version 1.1. - - * `g77' fails to warn about use of a "live" iterative-DO variable as - an implied-DO variable in a `WRITE' or `PRINT' statement (although - it does warn about this in a `READ' statement). - - * A compiler crash, or apparently infinite run time, can result when - compiling complicated expressions involving `COMPLEX' arithmetic - (especially multiplication). - - Fixed in `egcs' version 1.1. - - * Something about `g77''s straightforward handling of label - references and definitions sometimes prevents the GBE from - unrolling loops. Until this is solved, try inserting or removing - `CONTINUE' statements as the terminal statement, using the `END DO' - form instead, and so on. - - * Some confusion in diagnostics concerning failing `INCLUDE' - statements from within `INCLUDE''d or `#include''d files. - - * `g77' assumes that `INTEGER(KIND=1)' constants range from `-2**31' - to `2**31-1' (the range for two's-complement 32-bit values), - instead of determining their range from the actual range of the - type for the configuration (and, someday, for the constant). - - Further, it generally doesn't implement the handling of constants - very well in that it makes assumptions about the configuration - that it no longer makes regarding variables (types). - - Included with this item is the fact that `g77' doesn't recognize - that, on IEEE-754/854-compliant systems, `0./0.' should produce a - NaN and no warning instead of the value `0.' and a warning. This - is to be fixed in version 0.6, when `g77' will use the `gcc' back - end's constant-handling mechanisms to replace its own. - - * `g77' uses way too much memory and CPU time to process large - aggregate areas having any initialized elements. - - For example, `REAL A(1000000)' followed by `DATA A(1)/1/' takes up - way too much time and space, including the size of the generated - assembler file. This is to be mitigated somewhat in version 0.6. - - Version 0.5.18 improves cases like this--specifically, cases of - *sparse* initialization that leave large, contiguous areas - uninitialized--significantly. However, even with the - improvements, these cases still require too much memory and CPU - time. - - (Version 0.5.18 also improves cases where the initial values are - zero to a much greater degree, so if the above example ends with - `DATA A(1)/0/', the compile-time performance will be about as good - as it will ever get, aside from unrelated improvements to the - compiler.) - - Note that `g77' does display a warning message to notify the user - before the compiler appears to hang. *Note Initialization of - Large Aggregate Areas: Large Initialization, for information on - how to change the point at which `g77' decides to issue this - warning. - - * `g77' doesn't emit variable and array members of common blocks for - use with a debugger (the `-g' command-line option). The code is - present to do this, but doesn't work with at least one debug - format--perhaps it works with others. And it turns out there's a - similar bug for local equivalence areas, so that has been disabled - as well. - - As of Version 0.5.19, a temporary kludge solution is provided - whereby some rudimentary information on a member is written as a - string that is the member's value as a character string. - - *Note Options for Code Generation Conventions: Code Gen Options, - for information on the `-fdebug-kludge' option. - - * When debugging, after starting up the debugger but before being - able to see the source code for the main program unit, the user - must currently set a breakpoint at `MAIN__' (or `MAIN___' or - `MAIN_' if `MAIN__' doesn't exist) and run the program until it - hits the breakpoint. At that point, the main program unit is - activated and about to execute its first executable statement, but - that's the state in which the debugger should start up, as is the - case for languages like C. - - * Debugging `g77'-compiled code using debuggers other than `gdb' is - likely not to work. - - Getting `g77' and `gdb' to work together is a known - problem--getting `g77' to work properly with other debuggers, for - which source code often is unavailable to `g77' developers, seems - like a much larger, unknown problem, and is a lower priority than - making `g77' and `gdb' work together properly. - - On the other hand, information about problems other debuggers have - with `g77' output might make it easier to properly fix `g77', and - perhaps even improve `gdb', so it is definitely welcome. Such - information might even lead to all relevant products working - together properly sooner. - - * `g77' doesn't work perfectly on 64-bit configurations such as the - Digital Semiconductor ("DEC") Alpha. - - This problem is largely resolved as of version 0.5.23. Version - 0.6 should solve most or all remaining problems (such as - cross-compiling involving 64-bit machines). - - * Maintainers of `gcc' report that the back end definitely has - "broken" support for `COMPLEX' types. Based on their input, it - seems many of the problems affect only the more-general facilities - for gcc's `__complex__' type, such as `__complex__ int' (where the - real and imaginary parts are integers) that GNU Fortran does not - use. - - Version 0.5.20 of `g77' works around this problem by not using the - back end's support for `COMPLEX'. The new option - `-fno-emulate-complex' avoids the work-around, reverting to using - the same "broken" mechanism as that used by versions of `g77' - prior to 0.5.20. - - * `g77' sometimes produces invalid assembler code when using the - `-fPIC' option (such as compiling for ELF targets) on the Intel - x86 architecture target. The symptom is that the assembler - complains about invalid opcodes. This bug is in the `gcc' back - end. - - Fixed in `egcs' version 1.0.2. - - * `g77' currently inserts needless padding for things like `COMMON - A,IPAD' where `A' is `CHARACTER*1' and `IPAD' is `INTEGER(KIND=1)' - on machines like x86, because the back end insists that `IPAD' be - aligned to a 4-byte boundary, but the processor has no such - requirement (though it is usually good for performance). - - The `gcc' back end needs to provide a wider array of - specifications of alignment requirements and preferences for - targets, and front ends like `g77' should take advantage of this - when it becomes available. - - * The x86 target's `-malign-double' option no longer reliably aligns - double-precision variables and arrays when they are placed in the - stack frame. - - This can significantly reduce the performance of some applications, - even on a run-to-run basis (that is, performance measurements can - vary fairly widely depending on whether frequently used variables - are properly aligned, and that can change from one program run to - the next, even from one procedure call to the next). - - Versions 0.5.22 and earlier of `g77' included a patch to `gcc' - that enabled this, but that patch has been deemed an improper - (probably buggy) one for version 2.8 of `gcc' and for `egcs'. - - Note that version 1.1 of `egcs' aligns double-precision variables - and arrays when they are in static storage even if - `-malign-double' is not specified. - - There is ongoing investigation into how to make `-malign-double' - work properly, also into how to make it unnecessary to get all - double-precision variables and arrays aligned when such alignment - would not violate the relevant specifications for processor and - inter-procedural interfaces. - - For a suite of programs to test double-precision alignment, see - `ftp://alpha.gnu.org/gnu/g77/align/'. - - * The `libf2c' routines that perform some run-time arithmetic on - `COMPLEX' operands were modified circa version 0.5.20 of `g77' to - work properly even in the presence of aliased operands. - - While the `g77' and `netlib' versions of `libf2c' differ on how - this is accomplished, the main differences are that we believe the - `g77' version works properly even in the presence of *partially* - aliased operands. - - However, these modifications have reduced performance on targets - such as x86, due to the extra copies of operands involved. - diff --git a/gcc/f/ChangeLog b/gcc/f/ChangeLog deleted file mode 100755 index 00790eb..0000000 --- a/gcc/f/ChangeLog +++ /dev/null @@ -1,5143 +0,0 @@ -Tue Jan 5 22:12:41 1999 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Make-lang.in (g77.o): Depend on prefix.h. - -Fri Nov 27 13:10:32 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * fini.c: Rename variable `spaces' to `xspaces' to avoid - conflicting with function `spaces' from libiberty. - - * g77spec.c: Don't prototype libiberty functions. - * malloc.c: Likewise. - -1998-11-20 Dave Love <d.love@dl.ac.uk> - - * g77.texi: Assorted minor changes. - -1998-11-19 Dave Love <d.love@dl.ac.uk> - - * bugs.texi: Formatting changes from Craig. - - * intdoc.in: Terminate some @xrefs with `,'. - -1998-11-19 Manfred Hollstein <manfred@s-direktnet.de> - - * Make-lang.in (mandir): Replace all uses of $(mandir) by $(man1dir). - -Mon Nov 9 23:15:39 1998 Jeffrey A Law (law@cygnus.com) - - * g77.texi, news.texi: Updates from Craig. - -Sun Nov 8 17:47:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Makefile.in (INCLUDES): Add "-I$(srcdir)/../../include". - -Sat Nov 7 15:58:54 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * g77spec.c: Don't include gansidecl.h. - * output.j: Likewise. - -1998-11-04 Dave Love <d.love@dl.ac.uk> - - * g77.texi: Small formatting/indexing fixes. - -Mon Oct 12 20:41:59 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * bad.c (ffebad_finish): Change type of variable `c' to unsigned - char, change type of variable `s' to unsigned char *. - - * com.c (ffecom_symbol_null_): Add missing initializers. - - * fini.c (MAXNAMELEN): Undef it before defining. - - * implic.c (ffeimplic_lookup_): Change type of parameter `c' to - unsigned char. - - * intrin.c (ffeintrin_init_0): Cast the argument of ctype macros - to (unsigned char). - - * lex.c (ffelex_splice_tokens): Change type of variable `p' to - unsigned char *. - (ffelex_token_name_from_names): Cast the argument of - `ffelex_is_firstnamechar' to (unsigned char). - (ffelex_token_names_from_names): Likewise. - (ffelex_token_new_name): Likewise. - (ffelex_token_new_names): Likewise. - - * malloc.c (malloc_root_): Add missing initializer. - - * stb.c (ffestb_do): Change type of variable `p' to unsigned char *. - (ffestb_else) Likewise. - (ffestb_else3_) Likewise. - (ffestb_endxyz) Likewise. - (ffestb_goto) Likewise. - (ffestb_let) Likewise. - (ffestb_varlist) Likewise. - (ffestb_R522) Likewise. - (ffestb_R528) Likewise. - (ffestb_R834) Likewise. - (ffestb_R835) Likewise. - (ffestb_R838) Likewise. - (ffestb_R1102) Likewise. - (ffestb_blockdata) Likewise. - (ffestb_R1212) Likewise. - (ffestb_R810) Likewise. - (ffestb_R10014_): Cast the argument of `ffelex_is_firstnamechar' - to (unsigned char). - (ffestb_V014): Change type of variable `p' to unsigned char *. - (ffestb_dummy) Likewise. - (ffestb_R524) Likewise. - (ffestb_R547) Likewise. - (ffestb_decl_chartype) Likewise. - (ffestb_decl_dbltype) Likewise. - (ffestb_decl_gentype) Likewise. - (ffestb_decl_entsp_2_) Likewise. - (ffestb_V027) Likewise. - (ffestb_decl_R539) Likewise. - - * top.c (ffe_decode_option): Mark parameter `argc' with - ATTRIBUTE_UNUSED. - - * where.c (ffewhere_unknown_line_): Add missing initializers. - -1998-10-02 Dave Love <d.love@dl.ac.uk> - - * com.c (ffecom_expr_intrinsic_): Fix return type for RAND. - -Thu Oct 1 10:43:45 1998 Nick Clifton <nickc@cygnus.com> - - * lex.c: Replace occurances of HANDLE_SYSV_PRAGMA with - HANDLE_GENERIC_PRAGMAS. - -Mon Sep 28 04:22:00 1998 Jeffrey A Law (law@cygnus.com) - - * news.texi: Update from Craig. - -1998-09-23 Dave Love <d.love@dl.ac.uk> - - * g77.texi: Additions about `/*', trailing comments and cpp. - -1998-09-18 Dave Love <d.love@dl.ac.uk> - - * g77.texi: Various additions and some small fixes. - -Thu Sep 10 14:55:44 1998 Kamil Iskra <iskra@student.uci.agh.edu.pl> - - * Make-lang.in (f77.install-common): Add missing "else true;". - -1998-09-07 Dave Love <d.love@dl.ac.uk> - - * ChangeLog.egcs: Deleted. Entries merged here. - -1998-09-05 Dave Love <d.love@dl.ac.uk> - - * Makefile.in (LDFLAGS): Set from BOOT_LDFLAGS. - (F771_LDFLAGS): Variable dispensed with. - -Fri Sep 4 19:53:34 1998 Craig Burley <burley@gnu.org> - - * intdoc.in: Minor editorial tweaks. - -Fri Sep 4 18:35:52 1998 Craig Burley <burley@gnu.org> - - * lang-options.h: Convert to wrap option and doc string - in a new macro invocation, FTNOPT, so the nearly identical - list can be used in FSF-g77. - -Fri Sep 4 18:35:52 1998 Craig Burley <burley@gnu.org> - - * Makefile.in (fini.o): Don't define USE_HCONFIG here. - * fini.c: Define USE_HCONFIG here instead, so deps-kinda - picks up correct dependency. - - * Makefile.in (proj-h.o): Fix dependencies list. - -Wed Sep 02 09:25:29 1998 Nick Clifton <nickc@cygnus.com> - - * lex.c (ffe_lex_hash): Change how HANDLE_PRAGMA and - HANDLE_SYSV_PRAGMA would be called if they pragma parsing was - enabled in this code. - Generate warning messages if unknown pragmas are encountered. - (pragma_getc): New function: retrieves characters from the - input stream. Defined when HANDLE_PRAGMA is defined. - (pragma_ungetc): New function: replaces characters back into the - input stream. Defined when HANDLE_PRAGMA is defined. - -Tue Sep 1 10:00:21 1998 Craig Burley <burley@gnu.org> - - * bugs.texi, g77.1, g77.texi, intdoc.in, news.texi: Doc updates - from Craig. - -1998-08-23 Dave Love <d.love@dl.ac.uk> - - * g77.texi: Increment `version-g77' and fix a few typos. - -Tue Aug 18 21:41:31 1998 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in: Add several "else true" clauses to deal with lame - systems. - -Tue Aug 11 08:12:14 1998 H.J. Lu (hjl@gnu.org) - - * Make-lang.in (g77.o): Touch lang-f77 before checking it. - -1998-08-09 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (f/g77.dvi): Replace non-working use of texi2dvi - with explicit use of tex. - (f77.mostlyclean): Remove TeX index files. - - * g77install.texi (Prerequisites): Kluge round TeX lossage with - hyphen in @value in @code. - -Tue Aug 4 16:59:39 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_convert_narrow_, ffecom_convert_widen_): - Allow conversion from pointer to same-sized integer, - to fix invoking SIGNAL as a function. - -1998-07-26 Dave Love <d.love@dl.ac.uk> - - * BUGS, INSTALL, NEWS: Rebuilt. - -Sat Jul 25 17:23:55 1998 Craig Burley <burley@gnu.org> - - Fix 980615-0.f: - * stc.c (ffestc_R1229_start): Set info to ANY as well. - -Tue Jul 21 04:33:37 1998 Craig Burley <burley@gnu.org> - - * g77spec.c (lang_specific_driver): Return unmolested - command line when --help seen. - Comment out code that printed g77-specific --help info. - -Sat Jul 18 19:16:48 1998 Craig Burley <burley@gnu.org> - - * lang-options.h: Fix up doc strings. - Remove the unimplemented -fdcp-intrinsics-* options. - - * str-1t.fin: Change mixed-case spelling of `GoTo' from - `Goto'. - -Thu Jul 16 13:26:36 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_finish_symbol_transform_): Revert change - of 1998-05-23, as it was too aggressive, in that it - prevented transformation of (used) functions before - primary code generation. - -1998-07-15 Dave Love <d.love@dl.ac.uk> - - * intdoc.texi: Regenerated. - -Mon Jul 13 18:45:06 1998 Craig Burley <burley@gnu.org> - - * Make-lang.in (f77.rebuilt): Fix to depend on - build-dir-based, not source-based, g77.info. - - * g77.texi: Merge docs with 0.5.24. - * g77install.texi: Ditto. - -Mon Jul 13 18:02:29 1998 Craig Burley <burley@gnu.org> - - Cleanups vis-a-vis g77-0.5.24: - * g77spec.c (lang_specific_driver): Tabify source. - * top.c (ffe_decode_option): Use fixed macro to set - internal-checking flag. - * top.h (ffe_set_is_do_internal_checks): Fix macro. - -Mon Jul 13 17:33:44 1998 Craig Burley <burley@gnu.org> - - Cleanups vis-a-vis system.h cutover and g77-0.5.24: - * Makefile.in (fini.o): Define USE_HCONFIG macro - so source code doesn't have to. - * fini.c: Don't define USE_HCONFIG here, since - source code usually shouldn't care about this. - * ansify.c: Include stddef.h only if we have it. - * intdoc.c: Ditto. - * proj.h: Ditto. - -Mon Jul 13 17:30:29 1998 Nick Clifton <nickc@cygnus.com> - - * lang-options.h: Format changed to work with --help support added - to gcc/toplev.c - -Mon Jul 13 11:54:03 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_push_tempvar): Replace kludge that - munged back-end globals directly with proper calls - to push_topmost_sequence and pop_topmost_sequence. - -1998-07-12 Dave Love <d.love@dl.ac.uk> - - * version.c: Bump version. - -Sat Jul 11 19:24:32 1998 Craig Burley <burley@gnu.org> - - Fix 980616-0.f: - * equiv.c (ffeequiv_offset_): Don't crash on various - possible ANY operands. - -Sat Jul 11 18:24:37 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_expr_) [FFEBLD_opCONTER]: Die if padding - for constant is non-zero. - - * com.c (__eprintf): Delete this function, it is obsolete. - -1998-07-09 Dave Love <d.love@dl.ac.uk> - - * intdoc.in (HOSTNM_func, HOSTNM_subr): Update last change. - -Thu Jul 9 00:45:59 1998 Craig Burley <burley@gnu.org> - - Fix debugging of CHARACTER*(*), etc., which requires - emitting debug info on types like `ftnlen': - * com.c (ffecom_start_progunit_): Don't bother - resetting "invented" flag for identifier. - (ffecom_transform_equiv_): Don't bother zeroing - "ignored" flag for decl. - (pushdecl): No longer set "ignored", "used", or - "suppressed debug" flags for decls having "invented" - identifiers. - -1998-07-06 Mike Stump <mrs@wrs.com> - - * Make-lang.in (f77.stage?): Use mv -f instead of just mv so that - we can move g77.c. - -1998-07-06 Dave Love <d.love@dl.ac.uk> - - * intdoc.in (HOSTNM_func, HOSTNM_subr): Note possible need for - -lsocket. - -1998-07-05 Dave Love <d.love@dl.ac.uk> - - * intdoc.in: Add entry for DATE_AND_TIME. - - * intrin.def: Add implementation for DATE_AND_TIME. Make second - and third args of SYSTEM_CLOCK optional. - - * com.c (ffecom_expr_intrinsic_): New case for DATE_AND_TIME. - - * com-rt.def (FFECOM_gfrtSYSTEM_CLOCK): Call G77_system_clock_0, - not system_clock_. - (FFECOM_gfrtDATE_AND_TIME): New DEFGFRT. - -Wed Jul 1 11:19:13 1998 Craig Burley <burley@gnu.org> - - Fix 980701-1.f (which was producing "unaligned trap" - on an Alpha running GNU/Linux, as predicted): - * equiv.c (ffeequiv_layout_local_): Don't bother - coping with pre-padding of entire area while building - it; do that instead after the building is done, and - do it by modifying only the modulo field. This covers - the case of alignment stringency being increased without - lowering the starting offset, unlike the previous changes, - and even more elegantly than those. - - * target.c (ffetarget_align): Make sure alignments - are non-zero, just in case. - -Mon Jun 29 09:47:33 1998 Craig Burley <burley@gnu.org> - - Fix 980628-*.f: - * bld.h: New `pad' field and accessor macros for - ACCTER, ARRTER, and CONTER ops. - * bld.c (ffebld_new_accter, ffebld_new_arrter, - ffebld_new_conter_with_orig): Initialize `pad' field - to zero. - * com.c (ffecom_transform_common_): Include initial - padding (aka modulo aka offset) in size calculation. - Copy initial padding value into FFE initialization expression - so the GBE transformation of that expression includes it. - Make array low bound 0 instead of 1, for consistency. - (ffecom_transform_equiv_): Include initial - padding (aka modulo aka offset) in size calculation. - Copy initial padding value into FFE initialization expression - so the GBE transformation of that expression includes it. - Make array low bound 0 instead of 1, for consistency. - (ffecom_expr_, case FFEBLD_opACCTER): Delete unused `size' - variable. - Track destination offset separately, allowing for - initial padding. - Don't bother setting initial PURPOSE offset if zero. - Include initial padding in size calculation. - (ffecom_expr_, case FFEBLD_opARRTER): Allow for - initial padding. - Include initial padding in size calculation. - Make array low bound 0 instead of 1, for consistency. - (ffecom_finish_global_): Make array low bound 0 instead - of 1, for consistency. - (ffecom_notify_init_storage): Copy `pad' field from old - ACCTER to new ARRTER. - (ffecom_notify_init_symbol): Ditto. - * data.c (ffedata_gather_): Initialize `pad' field in new - ARRTER to 0. - (ffedata_value_): Ditto. - * equiv.c (ffeequiv_layout_local_): When lowering start - of equiv area, extend lowering to maintain needed alignment. - * target.c (ffetarget_align): Handle negative offset correctly. - - * global.c (ffeglobal_pad_common): Warn about non-zero - padding only the first time its seen. - If new padding larger than old, update old. - (ffeglobal_save_common): Use correct type for size throughout. - * global.h: Use correct type for size throughout. - (ffeglobal_common_pad): New macro. - (ffeglobal_pad): Delete this unused and broken macro. - -Sat Jun 27 12:18:33 1998 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (g77): Depend on mkstemp.o. Link in mkstemp.o. - -Fri Jun 26 11:54:19 1998 Craig Burley <burley@gnu.org> - - * g77spec.c (lang_specific_driver): Put `-lg2c' in - front of any `-lm' that is seen. - -Wed Jun 24 01:01:23 1998 Jeffrey A Law (law@cygnus.com) - - * g77spec.c (lang_specific_driver): Revert last change. - -Mon Jun 22 23:12:05 1998 H.J. Lu (hjl@gnu.org) - - * Make-lang.in (G77STAGESTUFF): Add g77.c. - -Fri Jun 19 07:54:40 1998 H.J. Lu (hjl@gnu.org) - - * g77spec.c (lang_specific_driver): Check n_infiles before - appending args. - -Mon Jun 15 23:39:24 1998 Craig Burley <burley@gnu.org> - - * Make-lang.in (f/g77.info): Use -f when removing - pre-existing Info files, if any. (This rm command - can go away once makeinfo has been changed to delete - .info-N files beyond the last one it creates.) - - * Make-lang.in ($(srcdir)/f/intdoc.texi): Compile - using $(INCLUDES) macro to get the new hconfig.h - and system.h headers. - -Mon Jun 15 22:21:57 1998 Craig Burley <burley@gnu.org> - - Cutover to system.h: - * Make-lang.in: - * Makefile.in: - * ansify.c: - * bad.c: - * bld.c: - * com.c: - * com.h: - * expr.c: - * fini.c: - * g77spec.c: - * implic.c: - * intdoc.c: - * intrin.c: - * lex.c: - * lex.h: - * parse.c: - * proj.c: - * proj.h: - * src.c: - * src.h: - * stb.c: - * ste.c: - * target.c: - * top.c: - * system.j: New file. - - Use toplev.h where appropriate: - * Make-lang.in: - * Makefile.in: - * bad.c: - * bld.c: - * com.c: - * lex.c: - * ste.c: - * top.c: - * toplev.j: New file. - - Conditionalize all dumping/reporting routines so they don't - get built for gcc/egcs: - * bld.c: - * bld.h: - * com.c: - * equiv.c: - * equiv.h: - * sta.c: - * stt.c: - * stt.h: - * symbol.c: - * symbol.h: - - Use hconfig.h instead of config.h where appropriate: - * Makefile.in (proj-h.o): Compile with -DUSE_HCONFIG. - * fini.c: Define USE_HCONFIG before including proj.h. - - * Makefile.in (deps-kinda): Redirect stderr to stdout, - to eliminate diagnostics vis-a-vis g77spec.c. - - * Makefile.in: Regenerate dependencies via deps-kinda. - - * lex.c (ffelex_file_fixed, ffelex_file_free): Eliminate - apparently spurious warnings about uninitialized variables - `c', `column', and so on. - -Sat Jun 13 03:13:18 1998 Craig Burley <burley@gnu.org> - - * g77spec.c (lang_specific_driver): Print out egcs - version info first, to be compatible with what some - test facilities expect. - -Wed Jun 10 13:17:32 1998 Dave Brolley <brolley@cygnus.com> - - * top.h (ffe_decode_option): New argc/argv interface. - * top.c (ffe_decode_option): New argc/argv interface. - * parse.c (yyparse): New argc/argv interface for ffe_decode_option. - * com.c (lang_decode_option): New argc/argv interface. - -Sun Jun 7 14:04:34 1998 Richard Henderson <rth@cygnus.com> - - * com.c (lang_init_options): New function. - * top.c (ffe_decode_option): Remove all trace of -fset-g77-defaults. - Set ffe_is_do_internal_checks_ with -version. - * lang-options.h: Likewise. - * lang-specs.h: Likewise. - -Fri Jun 5 15:53:17 1998 Per Bothner <bothner@cygnus.com> - - * g77spec.c (lang_specific_pre_link, lang_specific_extra_ofiles): - Define - update needed by gcc.c change. - -Mon Jun 1 19:37:42 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_init_0): Fix setup of INTEGER(KIND=7) - pointer type. - * info.c (ffeinfo_type): Don't crash on null type. - * expr.c (ffeexpr_fulfill_call_): Don't special-case - %LOC(expr) or LOC(expr). - Delete FFEGLOBAL_argsummaryPTR. - * global.c, global.h: Delete FFEGLOBAL_argsummaryPTR. - -Thu May 28 21:32:18 1998 Craig Burley <burley@gnu.org> - - Restore circa-0.5.22 capabilities of `g77' driver: - * Make-lang.in (g77spec.o): Depend on f/version.h. - (g77version.o): New rule to compile g77 version info. - (g77$(exeext)): Depend on and link in g77version.o. - * g77spec.c: Rewrite to be more like 0.5.22 version - of g77.c, making filtering of command line smarter - so mixed Fortran and C (etc.) can be compiled, verbose - version info can be obtained, etc. - * lang-specs.h (f77-version): New "language" to support - "g77 -v" command under new gcc 2.8 regime. - * lex.c (ffelex_file_fixed): If -fnull-version, just - substitute a "source file" that prints out version info. - * top.c, top.h: Support -fnull-version. - - * lang-specs.h: Use "%O" instead of OO macro to specify - object extension. Remove old stringizing cruft. - - * Make-lang.in (g77.c, g77spec.o, g77.o, g77$(exeext), - g77-cross$(exeext), f771, - $(srcdir)/f/g77.info, $(srcdir)/f/g77.dvi, - $(srcdir)/f/intdoc.texi, - f77.install-common, f77.install-info, f77.install-man, - f77.uninstall, $(G77STAGESTUFF), f77.stage1, f77.stage2, - f77.stage3, f77.stage4, f77.distdir): Don't do anything - unless user specified "f77" or "F77" in $LANGUAGES either - during configuration or explicitly. For convenience of - various tests and to work around lack of the assignment - "LANGUAGES=$(BOOT_LANGUAGES)" in the "make stage1" command - of "make bootstrap" in gcc, use a touch file named "lang-f77" - to communicate whether this is the case. - - * Make-lang.in (F77_FLAGS_TO_PASS): Delete this macro, - replace with minimal expansion of its former self in - each of the two instances where it was used. - - * Makefile.in (HOST_CC): Delete this definition. - - * com.c (index, rindex): Delete these declarations. - - * proj.h: (isascii): Delete this. - - * Make-lang.in (f77.install-common): Warn if `f77-install-ok' - flag-file exists, since it no longer triggers any activity. - - Rename libf2c.a and f2c.h to libg2c.a and g2c.h, - normalize and simplify g77/libg2c build process: - * Make-lang.in: Remove all support for overwriting - /usr/bin/f77 etc., or whatever the actual names are - via $(prefix) and $(local_prefix). (g++ overwrites - /usr/bin/c++, but then it's often the only C++ compiler - on the system; f77 often exists on systems that are - installing g77.) - (f77.realclean): Remove obsolete target. - (g77.c, g77$(exeext)): Minor changes to look more like g++'s - stuff. - (f771): Now built with srcdir=gcc/f, not srcdir=gcc, to be - more like g++ and such. - (f/Makefile): Removed, as g++ doesn't need this rule. - (f77.install-common): No longer install f77, etc. - (f77.install-man): No longer install f77.1. - (f77.uninstall): No longer uninstall f77, f77.1, etc. - (f77.stage1, f77.stage2, f77.stage3, f77.stage4): Do work - only if "f77" appears in $(LANGUAGES). - (Note: gcc's Makefile.in's bootstrap target should set - LANGUAGES=$(BOOT_LANGUAGES) when making the stage1 target.) - * Makefile.in: Update vis-a-vis gcc/cp/Makefile.in. - (none): Remove. - (g77-only): Relocate. - (all.indirect, f771, *.o): Now assumes current directory - is this dir (gcc/f), not the parent directory. - (TAGS): Remove "echo 'parse.y,0' >> TAGS ;" line. - * config-lang.in: Delete commented-out code. - Fix stagestuff definition. Add more stuff to - diff_excludes definition. Don't create any directories. - Set outputs to f/Makefile, to get variable substition - to happen (what does that really do, anyway?!). - * g77spec.c: Rename libf2c to libg2c. - - * com.h: Remove all of the gcc back-end decls, - since egcs should have all of them correct. - - * com.c: Include "proj.h" before anything else, - as that's how things are supposed to work. - * ste.c: Ditto. - - * bad.c: Include "flags.j" here, since some diagnostics - check flag_pedantic_errors. - - * Makefile.in (f/*.o): Rebuild dependencies via - deps-kinda. - - * output.j: New source file. - * Make-lang.in (F77_SRCS): Update accordingly. - * Makefile.in (OUTPUT_H): Ditto. - (deps-kinda): Ditto. - * com.c: Include "output.j" here. - * lex.c: Ditto. - -Mon May 25 03:34:42 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_expr_): Fix D**I and Z**I cases to - not convert (DOUBLE PRECISION) D and (DOUBLE COMPLEX) Z - to INTEGER. (This is dead code here anyway.) - -Sat May 23 06:32:52 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_finish_symbol_transform_): Don't transform - statement (nested) functions, to avoid gcc compiling them - and thus producing linker errors if they refer to undefined - external functions. But warn if they're unused and -Wunused. - * bad.def (FFEBAD_SFUNC_UNUSED): New diagnostic. - -Wed May 20 12:12:55 1998 Craig Burley <burley@gnu.org> - - * Version 0.5.23 released. - -Tue May 19 14:52:41 1998 Craig Burley <burley@gnu.org> - - * bad.def (FFEBAD_OPEN_UNSUPPORTED, FFEBAD_INQUIRE_UNSUPPORTED, - FFEBAD_READ_UNSUPPORTED, FFEBAD_WRITE_UNSUPPORTED, - FFEBAD_QUAD_UNSUPPORTED, FFEBAD_BLOCKDATA_STMT, - FFEBAD_TRUNCATING_CHARACTER, FFEBAD_TRUNCATING_HOLLERITH, - FFEBAD_TRUNCATING_NUMERIC, FFEBAD_TRUNCATING_TYPELESS, - FFEBAD_TYPELESS_OVERFLOW): Change these from warnings - to errors. - -Tue May 19 14:51:59 1998 Craig Burley <burley@gnu.org> - - * Make-lang.in (f77.install-info, f77.uninstall): - Use install-info as appropriate. - -Tue May 19 12:56:54 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_init_0): Rename xargc to f__xargc, - in accord with same-dated change to f/runtime. - -Fri May 15 10:52:49 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_convert_narrow_, ffecom_convert_widen_): - Be even more persnickety in checking for internal bugs. - Also, if precision isn't changing, just return the expr. - - * expr.c (ffeexpr_token_number_): Call - ffeexpr_make_float_const_ to make an integer. - (ffeexpr_make_float_const_): Handle making an integer. - - * intrin.c (ffeintrin_init_0): Distinguish between - crashes on bad arg base and kind types. - -Fri May 15 01:44:22 1998 Mumit Khan <khan@xraylith.wisc.edu> - - * Make-lang.in (f77.mostlyclean): Add missing exeext. - -Thu May 14 13:30:59 1998 Craig Burley <burley@gnu.org> - - * Make-lang.in (f/expr.c): Now depends on f/stamp-str. - * expr.c: Use ffestrOther in place of ffeexprDotdot_. - * str-ot.fin: Add more keywords for expr.c. - - * intdoc.c (dumpimp): Trivial fix. - - * com.c (ffecom_expr_): Add ltkt variable for clarity. - -Wed May 13 13:05:34 1998 Craig Burley <burley@gnu.org> - - * Make-lang.in (G77STAGESTUFF): Add g77.o, g77spec.o, - and g77version.o. - (f77.clean): Add removal of g77.c, g77.o, g77spec.o, - and g77version.o. - (f77.distclean): Delete removal of g77.c. - -Thu Apr 30 18:59:43 1998 Jim Wilson <wilson@cygnus.com> - - * Make-lang.in (g77.info, g77.dvi, BUGS, INSTALL, NEWS): Put -o - option before input file. - -Tue Apr 28 09:23:10 1998 Craig Burley <burley@gnu.org> - - Fix 980427-0.f: - * global.c (ffeglobal_ref_progunit_): When transitioning - from EXT to FUNC, discard hook, since the decl, if any, is - probably wrong. - -Sun Apr 26 09:05:50 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_char_enhance_arg_): Wrap the upper bound - (the PARM_DECL specifying the length of the CHARACTER*(*) - dummy arg) in a variable_size invocation, to prevent - dwarf2out.c crashing when compiling code with -g. - -Sat Apr 18 15:26:57 1998 Jim Wilson <wilson@cygnus.com> - - * g77spec.c (lang_specific_driver): New argument in_added_libraries. - New local added_libraries. Increment count when add library to - arglist. - -Sat Apr 18 05:03:21 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_check_size_overflow_): Ignore overflow - as well if dummy argument. - -Fri Apr 17 17:18:04 1998 Craig Burley <burley@gnu.org> - - * version.h: Get rid of the overly large headers - here too, as done in version.c. - -Tue Apr 14 15:51:37 1998 Dave Brolley <brolley@cygnus.com> - - * com.c (init_parse): Now returns char* containing filename; - -Tue Apr 14 14:40:40 1998 Craig Burley <burley@gnu.org> - - * com.c (ffecom_start_progunit_): Mark function decl - as used, to avoid spurious warning (-Wunused) for ENTRY. - -Tue Apr 14 14:19:34 1998 Craig Burley <burley@gnu.org> - - * sta.c (ffesta_second_): Check for CASE DEFAULT - as well as CASE, or it won't be recognized. - -Thu Apr 9 00:18:44 1998 Dave Brolley (brolley@cygnus.com) - - * com.c (finput): New variable. - (init_parse): Handle !USE_CPPLIB. - (finish_parse): New function. - (lang_init): No longer declare finput. - -Sat Apr 4 17:45:01 1998 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_expr_): Revert Oct 22 change. Instead take a WIDENP - argument so that we can respect the signedness of the original type. - (ffecom_init_0): Do sizetype initialization first. - -1998-03-28 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (f771$(exeext)): Fix typo. - -1998-03-24 Martin von Loewis <loewis@informatik.hu-berlin.de> - - * com.c (lang_print_xnode): New function. - -Mon Mar 23 21:20:35 1998 Craig Burley <burley@gnu.org> - - * version.c: Reduce to a one-line file, like - gcc's version.c, since there's really no content - there. - -Mon Mar 23 11:58:43 1998 Craig Burley <burley@gnu.org> - - * bugs.texi: Various updates. - - * com.c (ffecom_tree_canonize_ptr_): Fix up spacing a bit. - -Sun Mar 22 00:50:42 1998 Nick Clifton <nickc@cygnus.com> - Geoff Noer <noer@cygnus.com> - - * Makefile.in: Various fixes for building cygwin32 native toolchains. - * Make-lang.in: Likewise. - -Mon Mar 16 21:20:35 1998 Craig Burley <burley@gnu.org> - - * expr.c (ffeexpr_sym_impdoitem_): Don't blindly - reset symbol info after calling ffesymbol_error, - to avoid crash. - -Mon Mar 16 15:38:50 1998 Craig Burley <burley@gnu.org> - - * Version 0.5.22 released. - -Mon Mar 16 14:36:02 1998 Craig Burley <burley@gnu.org> - - Make -g work better for ENTRY: - * com.c (ffecom_start_progunit_): Master function - for ENTRY-laden procedure is not really invented, - so it can be debugged. - (ffecom_do_entry_): Push/set/pop lineno for each - entry point. - -Sun Mar 15 05:48:49 1998 Craig Burley <burley@gnu.org> - - * intrin.def: Fix spelling of mixed-case form - of `CPU_Time' (was `Cpu_Time'). - -Thu Mar 12 13:50:21 1998 Craig Burley <burley@gnu.org> - - * lang-options.h: Sort all -f*-intrinsics-* options, - for consistency with other g77 versions. - -Thu Mar 12 09:39:40 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * lang-specs.h: Properly put brackets around array elements in initializer. - -1998-03-09 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in: Set CONFIG_SITE to a non-existent file since - /dev/null loses with bash 2.0/autoconf 2.12. Put - F77_FLAGS_TO_PASS before CC. - -Sun Mar 8 16:35:34 1998 Craig Burley <burley@gnu.org> - - * intrin.def: Use tabs instead of blanks more - consistently (excepting DEFGEN section for now). - -Wed Mar 4 17:38:21 1998 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in: Remove more references to libf77. - -Tue Mar 3 10:52:35 1998 Manfred Hollstein <manfred@s-direktnet.de> - - * g77.texi: Use @url for citing URLs. - -Sat Feb 28 15:24:38 1998 Craig Burley <burley@gnu.org> - - * intrin.def: Make CPU_TIME's arg generic real to be just - like SECOND_subr. - -Fri Feb 20 12:45:53 1998 Craig Burley <burley@gnu.org> - - * expr.c (ffeexpr_token_arguments_): Make sure - outer exprstack isn't null. - -1998-02-16 Dave Love <d.love@dl.ac.uk> - - * Makefile.in (f/fini): Don't use -W -Wall with HOST_CC. - -Fri Feb 13 00:14:56 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * com.c (type_for_mode): Add explicit braces to avoid ambiguous `else'. - - * expr.c (ffeexpr_type_combine): Likewise. - (ffeexpr_reduce_): Likewise. - (ffeexpr_declare_parenthesized_): Likewise. - - * src.c (ffesrc_strcmp_1ns2i): Likewise. - (ffesrc_strcmp_2c): Likewise. - (ffesrc_strncmp_2c): Likewise. - - * stb.c (ffestb_halt1_): Likewise. - (ffestb_R90910_): Likewise. - (ffestb_R9109_): Likewise. - - * stc.c (ffestc_R544_equiv_): Likewise. - - * std.c (ffestd_subr_copy_easy_): Likewise. - (ffestd_R1001dump_): Likewise. - (ffestd_R1001dump_1005_1_): Likewise. - (ffestd_R1001dump_1005_2_): Likewise. - (ffestd_R1001dump_1005_3_): Likewise. - (ffestd_R1001dump_1005_4_): Likewise. - (ffestd_R1001dump_1005_5_): Likewise. - (ffestd_R1001dump_1010_2_): Likewise. - - * ste.c (ffeste_R840): Likewise. - - * sts.c (ffests_puttext): Likewise. - - * symbol.c (ffesymbol_check_token_): Likewise. - - * target.c (ffetarget_real1): Likewise. - (ffetarget_real2): Likewise. - -Wed Feb 11 01:44:48 1998 Richard Henderson (rth@cygnus.com) - - * com.c (ffecom_ptr_to_expr) [FFEBLD_opARRAYREF]: Do upper - lower - in the native type, so as to properly handle negative indices. - -Tue Feb 3 20:13:05 1998 Richard Henderson <rth@cygnus.com> - - * config-lang.in: Remove references to runtime/. - -Sun Feb 1 12:43:49 1998 J"orn Rennecke <amylaar@cygnus.co.uk> - - * com.c (ffecom_tree_canonize_ptr_): Place bitsizetype typed expr - as first agument in MULT_EXPR. - Use bitsize_int (0L, 0L) as zero for bitsizes. - (ffecom_tree_canonize_ref_): - Use bitsize_int (0L, 0L) as zero for bitsizes. - (ffecom_init_0): Use set_sizetype. - -Sun Feb 1 02:26:58 1998 Richard Henderson <rth@cygnus.com> - - * runtime directory -- moved into "libf2c" in the toplevel - directory. - * Make-lang.in: Remove all runtime related stuff. - -Sun Jan 25 12:32:15 1998 Kaveh R. Ghazi <ghazi@caip.rutgers.edu> - - * Make-lang.in (f77.stage1): Depend on stage1-start so parallel - make works better. - * (f77.stage2): Likewise for stage2-start. - * (f77.stage3): Likewise for stage3-start. - * (f77.stage4): Likewise for stage4-start. - -Sat Jan 17 21:28:08 1998 Pieter Nagel <pnagel@epiuse.co.za> - - * Makefile.in (FLAGS_TO_PASS): Pass down gcc_include_dir and - local_prefix to sub-make invocations. - -Tue Jan 13 22:07:54 1998 Jeffrey A Law (law@cygnus.com) - - * lang-options.h: Add missing options. - -Sun Jan 11 02:14:47 1998 Craig Burley <burley@gnu.org> - - Support FORMAT(I<1+2>) (constant variable-FORMAT - expressions): - * bad.def (FFEBAD_FORMAT_VARIABLE): New diagnostic. - * std.c (ffestd_R1001rtexpr_): New function. - (ffestd_R1001dump_, ffestd_R1001dump_1005_1_, - ffestd_R1001dump_1005_2_, ffestd_R1001dump_1005_3_, - ffestd_R1001dump_1005_4_, ffestd_R1001dump_1005_5_, - ffestd_R1001dump_1010_2_, ffestd_R1001dump_1010_3_, - ffestd_R1001dump_1010_4_, ffestd_R1001dump_1010_5_): - Use new function instead of ffestd_R1001error_. - - * stb.c (ffestb_R10014_, ffestb_R10016_, ffestb_R10018_, - ffestb_R100110_): Restructure `for' loop for style. - - Fix 970626-2.f by not doing most back-end processing - when current_function_decl is an ERROR_MARK, and by - making that the case when its type would be an ERROR_MARK: - * com.c (ffecom_start_progunit_, finish_function, - lang_printable_name, start_function, - ffecom_finish_symbol_transform_): Test for ERROR_MARK. - * std.c (ffestd_stmt_pass_): Don't do any downstream - processing if ERROR_MARK. - - * Make-lang.in (f77.install-common): Don't install, and - don't uninstall existing, Info files if f/g77.info - doesn't exit. (This is a somewhat modified version - of an egcs patch on 1998-01-07 12:05:51 by Bruno Haible - <bruno@linuix.mathematik.uni-karlsruhe.de>.) - -Fri Jan 9 19:09:07 1998 Craig Burley <burley@gnu.org> - - Fix -fpedantic combined with `F()' invocation, - also -fugly-comma combined with `IARGC()' invocation: - * bad.def (FFEBAD_NULL_ARGUMENT_W): New diagnostic. - * expr.c (ffeexpr_finished_): Don't reject null expressions - in the argument-expression context -- let outer context - handle that. - (ffeexpr_token_arguments_): Warn about null expressions - here if -fpedantic (as appropriate). - Obey -fugly-comma for only external-procedure invocations. - * intrin.c (ffeintrin_check_): No longer ignore explicit - omitted trailing args. - -Tue Dec 23 14:58:04 1997 Craig Burley <burley@gnu.org> - - * intrin.c (ffeintrin_fulfill_generic): Don't generate - FFEBAD_INTRINSIC_TYPE for CHARACTER*(*) intrinsic. - - * com.c (ffecom_gfrt_basictype): - (ffecom_gfrt_kindtype): - (ffecom_make_gfrt_): - (FFECOM_rttypeVOIDSTAR_): New return type `void *', for - the SIGNAL intrinsic. - * com-rt.def (FFECOM_rttypeSIGNAL): Now returns `void *'. - * intdoc.c: Replace `p' kind specifier with `7'. - * intrin.c (ffeintrin_check_, ffeintrin_init_0): Replace - `p' kind specifier with `7'. - * intrin.def (FFEINTRIN_impLOC, FFEINTRIN_impSIGNAL_func, - FFEINTRIN_impSIGNAL_subr): Replace `p' specifier with `7'. - Also, SIGNAL now returns a `void *' status, not `int'. - - Improve run-time diagnostic for "PRINT '(I1', 42": - * com.c (ffecom_char_args_x_): Renamed from ffecom_char_args_, - which is now a macro (to avoid lots of changes to other code) - with new arg, ffecom_char_args_with_null_ being another new - macro to call same function with different value for new arg. - This function now appends a null byte to opCONTER expression - if the new arg is TRUE. - (ffecom_arg_ptr_to_expr): Support NULL length pointer. - * ste.c (ffeste_io_cilist_): - (ffeste_io_icilist_): Pass NULL length ptr for - FORMAT expression, so null byte gets appended where - feasible. - * target.c (ffetarget_character1): - (ffetarget_concatenate_character1): - (ffetarget_substr_character1): - (ffetarget_convert_character1_character1): - (ffetarget_convert_character1_hollerith): - (ffetarget_convert_character1_integer4): - (ffetarget_convert_character1_logical4): - (ffetarget_convert_character1_typeless): - (ffetarget_hollerith): Append extra phantom null byte as - part of FFETARGET-NULL-BYTE kludge. - - * intrin.def (FFEINTRIN_impCPU_TIME): Point to - FFECOM_gfrtSECOND as primary run-time routine. - -Mon Dec 22 12:41:07 1997 Craig Burley <burley@gnu.org> - - * intrin.c (ffeintrin_init_0): Remove duplicate - check for `!'. - -Fri Dec 19 00:12:01 1997 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_sym_transform_): Assumed arrays have no upper bound. - -Mon Dec 15 17:35:35 1997 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_type_vardesc_): Vardesc.dims is a `ftnlen*'. - -Sun Dec 14 02:49:58 1997 Craig Burley <burley@gnu.org> - - * intrin.c (ffeintrin_init_0): Fix up indentation a bit. - Fix bug that prevented checking of arguments other - than the first. - - * intdoc.c: Fix up indentation a bit. - -Tue Dec 9 16:20:57 1997 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_type_vardesc_): Vardesc.dims is a `ftnlen*'. - -Tue Dec 2 09:57:16 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (f77.clean): Remove g77.c. - -Mon Dec 1 19:12:36 1997 Craig Burley <burley@gnu.org> - - * intrin.c (ffeintrin_check_): Fix up indentation a bit more. - -Mon Dec 1 16:21:08 1997 Craig Burley <burley@gnu.org> - - * com.c (ffecom_arglist_expr_): Crash if non-supplied - optional arg isn't passed as an address. - Pass null pointer explicitly, instead of via ffecom routine. - If incoming argstring is NULL, substitute pointer to "0". - Recognize '0' as ending the usual arg stuff, just like '\0'. - -Sun Nov 30 22:22:22 1997 Craig Burley <burley@gnu.org> - - * intdoc.c: Minor fix-ups. - - * intrin.c (ffeintrin_check_): Fix up indentation a bit. - - * intrin.def: Fix up spacing a bit. - -Tue Nov 25 15:33:28 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (f77.all.build): Add $(exeext) to binary files. - (f77.all.cross, f77.start.encap): Simliarly. - -Fri Nov 21 09:35:20 1997 Fred Fish <fnf@cygnus.com> - - * Make-lang.in (stmp-f2c.h): Move inclusion of F77_FLAGS_TO_PASS - to before override of CC so that the override works. - -Thu Nov 20 00:58:14 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * Make-lang.in (f77.install-info): Depend on f77.info. - -1997-11-17 Dave Love <d.love@dl.ac.uk> - - * com.c (ffecom_arglist_expr_): Pass null pointers for optional - args which aren't supplied. - -Sun Nov 16 21:45:43 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * Make-lang.in (f77.install-info): Depend on f77.info. - -1997-11-14 Dave Love <d.love@dl.ac.uk> - - * intrin.def: Supply gfrt for CPU_TIME. Generalize arg types of - INT2, INT8, per doc. - -1997-11-06 Dave Love <d.love@dl.ac.uk> - - * intrin.def: Allow non-integer args for INT2 and INT8 (per - documentation). - -Sun Nov 2 19:49:51 1997 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_expr_): Only use TREE_TYPE argument for simple - arithmetic; convert types as necessary; recurse with target tree type. - -Tue Oct 28 02:21:25 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * lang-options.h: Add -fgnu-intrinsics-* and - -fbadu77-intrinsics-* options. - -Sun Oct 26 02:36:21 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (lang_print_error_function): Fix to more - reliably notice when the diagnosed region changes. - -Sat Oct 25 23:43:36 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix 950327-0.f: - * sta.c, sta.h (ffesta_outpooldisp): New function. - * std.c (ffestd_stmt_pass_): Don't kill NULL pool. - (ffestd_R842): If pool already preserved, save NULL - for pool, because it should be killed only once. - - * malloc.c [MALLOC_DEBUG]: Put initializer for `name' - component in braces, to avoid compiler warning. - -Wed Oct 22 11:37:41 1997 Richard Henderson <rth@cygnus.com> - - * com.c (ffecom_expr_): Take an new arg TREE_TYPE that if non-null - specifies the type in which to do the calculation. Change all callers. - [FFEBLD_opARRAYREF]: Force the index expr to use sizetype. - -Thu Oct 16 02:04:08 1997 Paul Koning <pkoning@xedia.com> - - * Make-lang.in (stmp-f2c.h): Don't configure the runtime - directory if LANGUAGES does not include f77. - -Mon Oct 13 12:12:41 1997 Richard Henderson <rth@cygnus.com> - - * Make-lang.in (g77*): Copied from cp/Make-lang.in g++*. - * g77spec.c: New file, mostly copied from g++spec.c - * g77.c: Removed. - -Fri Oct 10 13:00:48 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * ste.c (ffeste_begin_iterdo_): Fix loop setup so iteration - variable is modified only after the #iterations is calculated; - otherwise if the iteration variable is aliased to any of the - operands in the start, end, or increment expressions, the - wrong #iterations might be calculated. - - * com.c (ffecom_save_tree): Fix indentation. - -Mon Oct 6 14:15:03 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (f77.mostlyclean): Clean up stuff in the - object tree too. - (f77.clean, f77.distclean, f77.maintainer-clean): Likewise. - -1997-10-05 Dave Love <d.love@dl.ac.uk> - - * intrin.def: Make SECOND_subr's arg generic real for people - porting from Cray and making everything double precision. - -Wed Oct 1 01:45:36 1997 Philippe De Muyter <phdm@info.ucl.ac.be> - - * g77.c (pexecute, main): Use unlink, not remove. - -Mon Sep 29 16:18:21 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * stu.c (ffestu_list_exec_transition_, - ffestu_dummies_transition_): Specify `bool' type for - `in_progress' variables. - - * com.h (assemble_string): Declare this routine (instead - of #include'ing "output.h" from gcc) to eliminate warnings - from lex.c. - -Mon Sep 29 10:37:07 1997 Jeffrey A Law (law@cygnus.com) - - * intdoc.c (main): Remove unused attribute for main's arguments. - -Sun Sep 28 01:47:17 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in (G77_FLAGS_TO_PASS): Pass down RANLIB, RANLIB_TEST - and AR instead of the _FOR_TARGET versions. - -Tue Sep 23 00:39:57 1997 Alexandre Oliva <oliva@dcc.unicamp.br> - - * Make-lang.in: install.texi was renamed to g77install.texi - * install0.texi: Likewise. - -Fri Sep 19 01:12:27 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_reduced_eqop2_): - (ffeexpr_reduced_relop2_): Minor fixes to diagnostic code. - - * fini.c (main): Change return type to `int'. - -Thu Sep 18 17:31:38 1997 Jeffrey A Law (law@cygnus.com) - - * proj.h (FFEPROJ_BSEARCH): Delete all references. - (FFEPROJ_STRTOUL): Likewise. - * proj.c (bsearch): Compile this if no bsearch is provided by the - host system. - (strtoul): Similarly. - - * g77install.texi: Renamed from install.texi - * g77.texi: Corresponding changes. - - * fini.c (main): Return type is int. - - * com.c (lang_printable_name): Use verbosity argument. - -Thu Sep 18 16:08:40 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in: Fix merge problems. - -Wed Sep 17 10:47:08 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com-rt.def (FFECOM_gfrtDSIGN, FFECOM_gfrtISIGN, - FFECOM_gfrtSIGN): Add second argument. - - * expr.c (ffeexpr_cb_comma_c_): Trivial fixes. - -Sun Sep 14 21:01:23 1997 Jeffrey A Law (law@cygnus.com) - - * Make-lang.in: Various changes to build info files - in the object tree rather than the source tree. - - * proj.h: Include ctype.h. - -Sun Sep 14 12:35:20 1997 Fred Fish (fnf@ninemoons.com) - - * proj.h (isascii): Provide a default definition if none is available. - -Thu Sep 11 19:26:10 1997 Dave Love <d.love@dl.ac.uk> - - * config-lang.in: Remove the messages about possible build problems. - -Wed Sep 10 16:39:47 1997 Jim Wilson <wilson@cygnus.com> - - * Make-lang.in (LN, LN_S): New macros, use where appropriate. - -Tue Sep 9 13:20:40 1997 Jim Wilson <wilson@cygnus.com> - - * g77.c (pexecute, doit): Add checks for __CYGWIN32__. - -Tue Sep 9 01:59:35 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Version 0.5.21 released. - -Tue Sep 9 00:31:01 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intdoc.c (dumpem): Put appropriate commentary in - output file, so readers know it isn't source. - -Wed Aug 27 20:32:03 1997 Jeffrey A Law (law@cygnus.com) - - * top.c (ffe_decode_option): Turn on flag_move_all_moveables - and flag_reduce_all_givs. - -Wed Aug 27 08:08:25 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * proj.h: Always #include "config.j" first, to pick up - gcc's configuration. - * com.c: Change bcopy() and bzero() calls to memcpy() - and memset() calls, to make more of g77 ANSI C. - -1997-08-26 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in ($(srcdir)/f/runtime/configure, - $(srcdir)/f/runtime/libU77/configure): Fix for when srcdir isn't - relative. - -Tue Aug 26 05:59:21 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * ansify.c (main): Make sure readers of stdout know - it's derived from stdin; omit comment text; get source - line numbers in future stderr output to be correct. - -Tue Aug 26 01:36:01 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix 970825-0.f: - * stb.c (ffestb_R5284_): Allow OPEN_PAREN after closing - SLASH as well as NAME. - -Mon Aug 25 23:48:17 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Changes to allow g77 docs to be built entirely from scratch - using any ANSI C compiler, not requiring GNU C: - * Make-lang.in ($(srcdir)/f/intdoc.texi): "Pipe" new - location of intrinsic documentation data base, f/intdoc.in, - through new `ansify' program to append `\n\' to quoted - newlines, into f/intdoc.h0. Do appropriate cleanups. Explain. - (f77.mostlyclean): Add f/ansify and f/intdoc.h0 to cleanups. - * f/ansify.c: New program. - * f/intdoc.c: Fix so it conforms to ANSI C. - #include f/intdoc.h0 instead of f/intdoc.h. - Avoid some warnings. - * f/intdoc.h, f/intdoc.in: Rename the former to the latter; no - changes made to the content in this patch! - * f/intrin.h (ffeintrinFamily): Fix to conform to ANSI C. - -Mon Aug 25 23:24:32 1997 H.J. Lu (hjl@gnu.ai.mit.edu) - - * Make-lang.in ($(srcdir)/f/runtime/configure, - $(srcdir)/f/runtime/libU77/configure, f77.mostlyclean, - f77.clean, f77.distclean, f77.maintainer-clean, f77.realclean): - Handle absolute pathname of $(srcdir). - (stmp-f2c.h): New. - (include/f2c.h, f/runtime/Makefile, f/runtime/libF77/Makefile, - f/runtime/libI77/Makefile, f/runtime/libU77/Makefile): Only - depend on stmp-f2c.h. - (f77.maintainer-clean): Don't make itself. - -Sun Aug 24 17:00:27 1997 Jim Wilson <wilson@cygnus.com> - - * Make-lang.in (f77.install-info): Don't cd into srcdir. Add srcdir - to filenames. Use sed to extract base filename for install. - -Sun Aug 24 06:52:48 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix up g77 compiler data base for libf2c routines: - * com-rt.def (FFECOM_gfrtSIGNAL): Change return type to - FTNINT to match actual code. - - * com.c (ffecomRttype_): Replace FFECOM_rttypeINT_ with - FFECOM_rttypeFTNINT_. - Add and fix up comments. - (ffecom_make_gfrt_, ffecom_gfrt_basictype, - ffecom_gfrt_kindtype): Replace FFECOM_rttypeINT_ with - FFECOM_rttypeFTNINT_; add FFECOM_rttypeDOUBLEREAL_. - -Thu Aug 21 13:15:29 1997 Jim Wilson <wilson@cygnus.com> - - * Make-lang.in (f77): Delete f77-runtime. - (f77.all.build, f77.all.cross, f77.rest.encap): Add f77-runtime. - -Wed Aug 20 17:18:40 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * global.c (ffeglobal_ref_progunit_): It's okay to have - a different CHARACTER*n length for a reference if the - existing length is for another reference, not a definition. - -Wed Aug 20 16:36:59 1997 Jim Wilson <wilson@cygnus.com> - - * intdoc.texi: Readd generated file. - -Mon Aug 18 14:27:18 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix 970814-0.f: - * global.c (ffeglobal_new_progunit_): Distinguish - between previously defined, versus inferred, filewide - when it comes to diagnostics. - - Fix 970816-1.f: - * global.c (ffeglobal_ref_progunit_): Change BDATA into EXT - right at the beginning, so EXTERNAL FOO followed later - by SUBROUTINE FOO is not diagnosed. - - Fix 970813-0.f: - * com-rt.def (FFECOM_gfrtALARM): Returns `integer', not - `void'. - -Mon Aug 18 09:01:54 1997 Jeffrey A Law (law@cygnus.com) - - * Makefile.in (F77_OBJS): Re-alphabetize. - * Make-lang.in (F77_SRCS): Likewise. - -Sun Aug 17 08:35:11 1997 Jeffrey A Law (law@cygnus.com) - - * INSTALL: Rebuilt. - * install.texi: Remove "Object File Differences" section. Remove - all references to zzz.o failing comparison tests. - * version.c, version.h: Renamed from zzz.c and zzz.h. Remove - date and time stamps so a 3 stage build reports no differences. - * Make-lang.in: Corresponding changes. - * Makefile.in: Likewise. - * g77.c, parse.c: Likewise. - - * intdoc.texi: Remove generated file from distribution. - -Sun Aug 17 03:32:44 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix up problems when virtual memory exhausted: - * malloc.c (malloc_new_): Use gcc's xmalloc(), so we - print a nicer message when malloc returns no memory. - (malloc_resize_): Ditto for xrealloc(). - - * Make-lang.in, Makefile.in: Comment out lines containing - just formfeeds. - -Sat Aug 16 19:41:33 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_make_gfrt_): For rttypeREAL_F2C_, return - double_type_node; for rttypeREAL_GNU_, return - _real_type_node. - -1997-08-13 Dave Love <d.love@dl.ac.uk> - - * config-lang.in (diff_excludes): Add some hints about known - problematic platforms. - -1997-08-13 Dave Love <d.love@dl.ac.uk> - - * intdoc.h: Document `alarm'. - -Tue Aug 12 10:23:02 1997 Jeffrey A Law (law@cygnus.com) - - * config-lang.in: Don't demand the backend patch. - * com.c (lang_printable_name): Second argument is now an int. Don't - store into the value of the second argument. - * top.c (ffe_decode_option): Temporarily disable setting - of "Toon" loop options until we figure out how to address - them. - -Mon Aug 11 23:18:35 1997 Jeffrey A Law (law@cygnus.com) - - * g77-0.5.21-19970811 Imported. - This file describes changes to the front end necessary to make - it work with egcs. - -Mon Aug 11 21:19:22 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in ($(RUNTIMESTAGESTUFF)): Add - f/runtime/stamp-lib. - -Mon Aug 11 01:52:03 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_build_complex_constant_): Go with the - new build_complex() approach used in gcc-2.8. - - * com.c (ffecom_sym_transform_): Don't set - DECL_IN_SYSTEM_HEADER for a tree node that isn't - a VAR_DECL, which happens when var is in common! - - * com.c (ffecom_expr_intrinsic_) (case FFEINTRIN_impALARM): - No need to test codegen_imp -- there's only one valid here. - - * intrin.def (FFEINTRIN_impALARM): Specify `Status' argument - as write-only. - -Fri Aug 8 05:40:23 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Substantial changes to accommodate distinctions among - run-time routines that support intrinsics, and between - routines that compute and return the same type vs. those - that compute one type and return another (or `void'): - * com-rt.def: Specify new return type REAL_F2C_ instead - of many DOUBLE_, COMPLEX_F2C_ instead of COMPLEX_, and - so on. - Clear up the *BES* routines "once and for all". - * com.c: New return types. - (ffecom_convert_narrow_, ffecom_convert_widen_): - New functions that are "safe" variants of convert(), - to catch errors that ffecom_expr_intrinsic_() now - no longer catches. - (ffecom_arglist_expr_): Ensure arguments are not - converted to narrower types. - (ffecom_call_): Ensure return value is not converted - to a wider type. - (ffecom_char_args_): Use new ffeintrin_gfrt_direct() - routine. - (ffecom_expr_intrinsic_): Simplify how run-time - routine is selected (via `gfrt' only now; lose the - redundant `ix' variable). - Eliminate the `library' label; any code that doesn't - return directly just `break's out now with `gfrt' - set appropriately. - Set `gfrt' to default choice initially, either a - fast direct form or, if not available, a slower - indirect-callable form. - (ffecom_make_gfrt_): No longer need to do special - check for complex; it's built into the new return-type - regime. - (ffecom_ptr_to_expr): Use new ffeintrin_gfrt_indirect() - routine. - * intrin.c, intrin.h: `gfrt' field replaced with three fields, - so it is easier to provide faster direct-callable and - GNU-convention indirect-callable routines in the future. - DEFIMP macro adjusted accordingly, along with all its uses. - (ffeintrin_gfrt_direct): New function. - (ffeintrin_gfrt_indirect): Ditto. - (ffeintrin_is_actualarg): If `-fno-f2c' is in effect, - require a GNU-callable version of intrinsic instead of - an f2c-callable version, so indirect calling is still checked. - * intrin.def: Replace one GFRT field with the three new fields, - as appropriate for each DEFIMP intrinsic. - - * com.c (ffecom_stabilize_aggregate_, - ffecom_convert_to_complex_): Make these `static'. - -Thu Aug 7 11:24:34 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Provide means for front end to determine actual - "standard" return type for an intrinsic if it is - passed as an actual argument: - * com.h, com.c (ffecom_gfrt_basictype, - ffecom_gfrt_kindtype): New functions. - (ffecom_gfrt_kind_type_): Replaced with new function. - All callers updated. - (ffecom_make_gfrt_): No longer need do anything - with kind type. - - * intrin.c (ffeintrin_basictype, ffeintrin_kindtype): - Now returns correct type info for specific intrinsic - (based on type of run-time-library implementation). - -Wed Aug 6 23:08:46 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * global.c (ffeglobal_ref_progunit_): Don't reset - number of arguments just due to new type info, - so useful warnings can be issued. - -1997-08-06 Dave Love <d.love@dl.ac.uk> - - * intrin.def: Fix IDATE_vxt argument order. - * intdoc.h: Likewise. - -Thu Jul 31 22:22:03 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * global.c (ffeglobal_proc_ref_arg): If REF/DESCR - disagreement, DESCR is CHARACTER, and types disagree, - pretend the argsummary agrees so the message ends up - being about type disagreement. - (ffeglobal_proc_def_arg): Ditto. - - * expr.c (ffeexpr_token_first_rhs_3_): Set info for LABTOK - to NONE of everything, to avoid misdiagnosing filewide - usage of alternate returns. - -Sun Jul 20 23:07:47 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_sym_transform_): If type gets set - to error_mark_node, just return that for transformed symbol. - (ffecom_member_phase2_): If type gets set to error_mark_node, - just return. - (ffecom_check_size_overflow_): Add `dummy' argument to - flag that type is for a dummy, update all callers. - -Sun Jul 13 17:40:53 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix 970712-1.f: - * where.c (ffewhere_set_from_track): If start point - is too large, just use initial start point. 0.6 should - fix all this properly. - - Fix 970712-2.f: - * com.c (ffecom_sym_transform_): Preserve error_mark_node for type. - (ffecom_type_localvar_): Ditto. - (ffecom_sym_transform_): If type is error_mark_node, - don't error-check decl size, because back end responds by - setting that to an integer 0 instead of error_mark_node. - (ffecom_transform_common_): Same as earlier fix to _transform_ - in that size is checked by dividing BITS_PER_UNIT instead of - multiplying. - (ffecom_transform_equiv_): Ditto. - - Fix 970712-3.f: - * stb.c (ffestb_R10014_): Fix flaky fall-through in error - test for FFELEX_typeCONCAT by just replicating the code, - and do FFELEX_typeCOLONCOLON while at it. - -1997-07-07 Dave Love <d.love@dl.ac.uk> - - * intdoc.h: Add various missing pieces; correct GMTIME, LTIME - result ordering. - - * intrin.def, com-rt.def: Add alarm. - - * com.c (ffecom_expr_intrinsic_): Add case for alarm. - -Thu Jun 26 04:19:40 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix 970302-3.f: - * com.c (ffecom_sym_transform_): For sanity-check compare - of gbe size of local variable to g77 expectation, - use varasm.c/assemble_variable technique of dividing - BITS_PER_UNIT out of gbe info instead of multiplying - g77 info up, to avoid crash when size in bytes is very - large, and overflows an `int' or similar when multiplied. - - Fix 970626-2.f: - * com.c (ffecom_finish_symbol_transform_): Don't bother - transforming a dummy argument, to avoid a crash. - * ste.c (ffeste_R1227): Don't return a value if the - result decl, or its type, is error_mark_node. - - Fix 970626-4.f: - * lex.c (ffelex_splice_tokens): `-fdollar-ok' is - irrelevant to whether a DOLLAR token should be made - from an initial character of `$'. - - Fix 970626-6.f: - * stb.c (ffestb_do3_): DO iteration variable is an - lhs, not rhs, expression. - - Fix 970626-7.f and 970626-8.f: - * expr.c (ffeexpr_cb_comma_i_1_): Set IMPDO expression - to have clean info, because undefined rank, for example, - caused crash on mangled source on UltraSPARC but not - on Alpha for a series of weird reasons. - (ffeexpr_cb_close_paren_): If not CLOSE_PAREN, push - opANY expression onto stack instead of attempting - to mimic what program might have wanted. - (ffeexpr_cb_close_paren_): Don't wrap opPAREN around - opIMPDO, just warn that it's gratuitous. - * bad.def (FFEBAD_IMPDO_PAREN): New warning. - - Fix 970626-9.f: - * expr.c (ffeexpr_declare_parenthesized_): Must shut down - parsing in kindANY case, otherwise the parsing engine might - decide there's an ambiguity. - (ffeexpr_token_name_rhs_): Eliminate parentypeSUBROUTINE_ - case, so we crash right away if it comes through. - * st.c, st.h, sta.c, sta.h (ffest_shutdown, ffesta_shutdown): - New functions. - -Tue Jun 24 19:47:29 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_check_size_overflow_): New function - catches some cases of the size of a type getting - too large. varasm.c must catch the rest. - (ffecom_sym_transform_): Use new function. - (ffecom_type_localvar_): Ditto. - -Mon Jun 23 01:09:28 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * global.c (ffeglobal_proc_def_arg): Fix comparison - of argno to #args. - (ffeglobal_proc_ref_arg): Ditto. - - * lang-options.h, top.c: Rename `-fdebug' to `-fxyzzy', - since it's an unsupported internals option and some - poor user might guess that it does something. - - * bad.def: Make a warning for each filewide diagnostic. - Put all filewides together. - * com.c (ffecom_sym_transform_): Don't substitute - known global tree for global entities when `-fno-globals'. - * global.c (ffeglobal_new_progunit_): Don't produce - fatal diagnostics about globals when `-fno-globals'. - Instead, produce equivalent warning when `-Wglobals'. - (ffeglobal_proc_ref_arg): Ditto. - (ffeglobal_proc_ref_nargs): Ditto. - (ffeglobal_ref_progunit_): Ditto. - * lang-options.h, top.c, top.h: New `-fno-globals' option. - -Sat Jun 21 12:32:54 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_fulfill_call_): Set array variable - to avoid warning about uninitialized variable. - - * Make-lang.in: Get rid of any setting of HOST_* macros, - since these will break gcc's build! - * makefile: New file to make building derived files - easier. - -Thu Jun 19 18:19:28 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * g77.c (main): Install Emilio Lopes' patch to support - Ratfor, and to fix the printing of the version string - to go to stderr, not stdout. - * lang-specs.h: Install Emilio Lopes' patch to support - Ratfor, and patch the result to support picking up - `*f771' from the `specs' file. - -Thu Jun 12 14:36:25 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * storag.c (ffestorag_update_init, ffestorag_update_save): - Also update parent, in case equivalence processing - has already eliminated pointers to it via the - local equivalence info. - -Tue Jun 10 14:08:26 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intdoc.c: Add cross-reference to end of description - of any generic intrinsic pointing to other intrinsics - with the same name. - - Warn about explicit type declaration for intrinsic - that disagrees with invocation: - * expr.c (ffeexpr_paren_rhs_let_): Preserve type info - for intrinsic functions. - (ffeexpr_token_funsubstr_): Ditto. - * intrin.c (ffeintrin_fulfill_generic): Warn if type - info of fulfilled intrinsic invocation disagrees with - explicit type info given symbol. - (ffeintrin_fulfill_specific): Ditto. - * stc.c (ffestc_R1208_item): Preserve type info - for intrinsics. - (ffestc_R501_item): Ditto. - -Mon Jun 9 17:45:44 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_expr_intrinsic_): Fix several of the - libU77/libF77-unix handlers to properly convert their - arguments. - - * com-rt.def (FFECOM_gfrtFSTAT): Append missing "i" to - arg string. - -Fri Jun 6 14:37:30 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_expr_intrinsic_): Have a case statement - for every intrinsic implementation, so missing ones - are caught via gcc warnings. - Don't call ffeintrin_codegen_imp anymore. - * intrin.c (ffeintrin_fulfill_generic): Remove cg_imp - stuff from here. - (ffeintrin_codegen_imp): Delete this function. - * intrin.def, intrin.h: Remove DEFIMQ stuff from here - as well. - -Thu Jun 5 13:03:07 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c (ffe_decode_option): New -fbadu77-intrinsics-* - options. - * top.h: Ditto. - * intrin.h: New BADU77 family. - * intrin.c (ffeintrin_state_family): Ditto. - - Implement new scheme to track intrinsic names vs. forms: - * intrin.c (ffeintrin_fulfill_generic), - (ffeintrin_fulfill_specific), (ffeintrin_is_intrinsic), - intrin.def: The documented name is now either in the - generic info or, if no generic, in the specific info. - For a generic, the specific info contains merely the - distinguishing form (usually "function" or "subroutine"), - used for diagnostics about ambiguous references and - in the documentation. - - * intrin.def: Clean up formatting of DEFNAME block. - Convert many libU77 intrinsics into generics that - support both subroutine and function forms. - Put the function forms of side-effect routines into - the new BADU77 family. - Make MCLOCK and TIME return INTEGER*4 again, and add - INTEGER*8 equivalents called MCLOCK8 and TIME8. - Fix up more status return values to be written and - insist on them being I1 as well. - * com.c (ffecom_expr_intrinsic_): Lots of changes to - support new libU77 intrinsic interfaces. - -Mon Jun 2 00:37:53 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_init_0): Pointer type is now INTEGER(KIND=7), - not INTEGER(KIND=0), since we want to reserve KIND=0 for - future use. - -Thu May 29 14:30:33 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix bugs preventing CTIME(I*4) from working correctly: - * com.c (ffecom_char_args_): For FUNCREF case, process - args to intrinsic just as they would be in - ffecom_expr_intrinsic_. - * com-rt.def (FFECOM_gfrtCTIME, FFECOM_gfrtTTYNAM): Fix - argument decls to specify `&'. - -Wed May 28 22:19:49 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix gratuitous warnings exposed by dophot aka 970528-1: - * global.c (ffeglobal_proc_def_arg, ffeglobal_proc_ref_arg): - Support distinct function/subroutine arguments instead of - just procedures. - * global.h: Ditto. - * expr.c (ffeexpr_fulfill_call_): A SYMTER with kindNONE - also is a procedure (either function or subroutine). - -Mon May 26 20:25:31 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * bad.def: Have several lexer diagnostics refer to - documentation for people who need more info on what Fortran - source code is supposed to look like. - - * expr.c (ffeexpr_reduced_bool1_), bad.def: New diagnostics - specific to .NOT. now mention only one operand instead - of two. - - * g77.c: Recognize -fsyntax-only, similar to -c etc. - (lookup_option): Fix bug that prevented non-`--' options - from being recognized. - -Sun May 25 04:29:04 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intrin.def (FFEINTRIN_impCTIME): Accept `I*' expression - for STime instead of requiring `I2'. - -Tue May 20 16:14:40 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * symbol.c (ffesymbol_reference): All references to - standard intrinsics are considered explicit, so as - to avoid generating basically useless warnings. - * intrin.c, intrin.h (ffeintrin_is_standard): Returns TRUE - if intrinsic is standard. - -Sun May 18 21:14:59 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com-rt.def: Changed all external names of the - form `"\([a-z0-9]*\)_' to `"G77_\1_0"' so as to - allow any name valid as an intrinsic to be used - as such and as a user-defined external procedure - name or common block as well. - -Thu May 8 13:07:10 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_cb_end_notloc_): For %VAL, %REF, and - %DESCR, copy arg info into new node. - -Mon May 5 14:42:17 1997 Craig Burley <burley@gnu.ai.mit.edu> - - From Uwe F. Mayer <mayer@math.Vanderbilt.Edu>: - * Make-lang.in (g77-cross): Fix typo in g77.c path. - - From Brian McIlwrath <bkm@star.rl.ac.uk>: - * lang-specs.h: Have g77 pick up options from a section - labeled `*f771' of the `specs' file. - -Sat May 3 02:46:08 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intrin.def (FFEINTRIN_defSIGNAL): Add optional `Status' - argument that com.c already expects (per Dave Love). - - More changes to support better tracking of (filewide) - globals, in particular, the arguments to procedures: - * bad.def (FFEBAD_FILEWIDE_NARGS, FFEBAD_FILEWIDE_NARGS_W, - FFEBAD_FILEWIDE_ARG, FFEBAD_FILEWIDE_ARG_W): New diagnostics. - * expr.c (ffebad_fulfill_call_): Provide info on each - argument to ffeglobal. - * global.c, global.h (ffeglobal_proc_def_arg, - ffeglobal_proc_def_nargs, ffeglobal_proc_ref_arg, - ffeglobal_proc_ref_args): New functions. - (ffeglobalArgSummary, ffeglobalArgInfo_): New types. - -Tue Apr 29 18:35:41 1997 Craig Burley <burley@gnu.ai.mit.edu> - - More changes to support better tracking of (filewide) - globals: - * expr.c (ffeexpr_fulfill_call_): New function. - (ffeexpr_token_name_lhs_): Call after building procedure - reference expression. Also leave info field for ANY-ized - expression alone. - (ffeexpr_token_arguments_): Ditto. - -Mon Apr 28 20:04:18 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Changes to support better tracking of (filewide) - globals, mainly to avoid crashes due to inlining: - * bad.def: Go back to quoting intrinsic names, - (FFEBAD_FILEWIDE_DISAGREEMENT, FFEBAD_FILEWIDE_TIFF, - FFEBAD_FILEWIDE_TYPE_MISMATCH): New diagnostics. - (FFEBAD_INTRINSIC_EXPIMP, FFEBAD_INTRINSIC_GLOBAL): Reword - for clarity. - * com.c (ffecom_do_entry_, ffecom_start_progunit_, - ffecom_sym_transform_): Accommodate new FFEGLOBAL_typeEXT - possibility. - * expr.c (ffeexpr_sym_lhs_call_, ffeexpr_sym_lhs_extfunc_, - ffeexpr_sym_rhs_actualarg_, ffeexpr_declare_parenthesized_, - ffeexpr_paren_rhs_let_, ffeexpr_token_funsubstr_): - Fill in real kind info instead of leaving NONE where - appropriate. - Register references to intrinsics and globals with ffesymbol - using new ffesymbol_reference function instead of - ffesymbol_globalize. - * global.c (ffeglobal_type_string_): New array for - new diagnostics. - * global.h, global.c: - Replace ->init mechanism with ->tick mechanism. - Move other common-related members into a substructure of - a union, so the proc substructure can be introduced - to include members related to externals other than commons. - Don't complain about ANY-ized globals; ANY-ize globals - once they're complained about, in any case where code - generation could become a problem. - Handle global entries that have NONE type (seen as - intrinsics), EXT type (seen as EXTERNAL), and so on. - Keep track of kind and type of externals, both via - definition and via reference. - Diagnose disagreements about kind or type of externals - (such as functions). - (ffeglobal_ref_intrinsic, ffeglobal_ref_progunit_): New - functions. - * stc.c (ffestc_R1207_item, ffestc_R1208_item, - ffestc_R1219, ffestc_R1226): - Call ffesymbol_reference, not ffesymbol_globalize. - * stu.c (ffestu_sym_end_transition, - ffestu_sym_exec_transition): - Call ffesymbol_reference, not ffesymbol_globalize. - * symbol.c (ffesymbol_globalize): Removed... - (ffesymbol_reference): ...to this new function, - which more generally registers references to symbols, - globalizes globals, and calls on the ffeglobal module - to check globals filewide. - - * global.h, global.c: Rename some macros and functions - to more clearly distinguish common from other globals. - All callers changed. - - * com.c (ffecom_sym_transform_): Trees describing - filewide globals must be allocated on permanent obstack. - - * expr.c (ffeexpr_token_name_lhs_): Don't generate - gratuitous diagnostics for FFEINFO_whereANY case. - -Thu Apr 17 03:27:18 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * global.c: Add support for flagging intrinsic/global - confusion via warnings. - * bad.def (FFEBAD_INTRINSIC_EXPIMP, - FFEBAD_INTRINSIC_GLOBAL): New diagnostics. - * expr.c (ffeexpr_token_funsubstr_): Ditto. - (ffeexpr_sym_lhs_call_): Ditto. - (ffeexpr_paren_rhs_let_): Ditto. - * stc.c (ffestc_R1208_item): Ditto. - -Wed Apr 16 22:40:56 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_declare_parenthesized_): INCLUDE - context can't be an intrinsic invocation either. - -Fri Mar 28 10:43:28 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_token_arguments_): Make sure top of - exprstack is operand before dereferencing operand field. - - * lex.c (ffelex_prepare_eos_): Fill up truncated - hollerith token, so crash on null ->text field doesn't - happen later. - - * stb.c (ffestb_R10014_): If NAMES isn't recognized (or - the recognized part is followed in the token by a - non-digit), don't try and collect digits, as there - might be more than FFEWHERE_indexMAX letters to skip - past to do so -- and the code is diagnosed anyway. - -Thu Mar 27 00:02:48 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_sym_transform_): Force local - adjustable array onto stack. - - * stc.c (ffestc_R547_item_object): Don't actually put - the symbol in COMMON if the symbol has already been - EQUIVALENCE'd to a different COMMON area. - - * equiv.c (ffeequiv_add): Don't actually do anything - if there's a disagreement over which COMMON area is - involved. - -Tue Mar 25 03:35:19 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_transform_common_): If no explicit init - of COMMON area, don't actually init it even though - storage area suggests it. - -Mon Mar 24 12:10:08 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * lex.c (ffelex_image_char_): Avoid overflowing the - column counter itself, as well as the card image. - - * where.c (ffewhere_line_new): Cast ffelex_line_length() - to (size_t) so 255 doesn't overflow to 0! - - * stc.c (ffestc_labeldef_notloop_begin_): Don't gratuitously - terminate loop before processing statement, so block - doesn't disappear out from under EXIT/CYCLE processing. - (ffestc_labeldef_notloop_): Has old code from above - function, instead of just calling it. - - * expr.c (ffeexpr_cb_comma_i_4_): Don't skip over - arbitrary token (such as EOS). - - * com.c (ffecom_init_zero_): Handle RECORD_TYPE and - UNION_TYPE so -fno-zeros works with -femulated-complex. - -1997-03-12 Dave Love <d.love@dl.ac.uk> - - * intrin.def: New intrinsics INT2, INT8, CPU_TIME. Fix AND, OR, - XOR. [Integrated by burley, AND/OR/XOR already fixed, INT8 - implementation changed/fixed.] - -Wed Mar 12 10:40:08 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in ($(srcdir)/f/intdoc.texi): Simplify rules - so building f/intdoc is not always necessary; remove - f/intdoc after running it if it is built. - -Tue Mar 11 23:42:00 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intrin.def (FFEINTRIN_impAND, FFEINTRIN_impOR, - FFEINTRIN_impXOR): Use the IAND, IOR, and IEOR implementations - of these, instead of crashing in ffecom_expr_intrinsic_ - or adding case labels there. - -Mon Mar 10 22:51:23 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * intdoc.c: Fix so any C compiler can compile this. - -Fri Feb 28 13:16:50 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Version 0.5.20 released. - -Fri Feb 28 01:45:25 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (RUNTIMESTAGESTUFF, LIBU77STAGESTUFF): - Move some files incorrectly in the former to the latter, - and add another file or two to the latter. - - New meanings for (KIND=n), and new denotations in the - little language describing intrinsics: - * com.c (ffecom_init_0): Assign new meanings. - * intdoc.c: Document new meanings. - Support the new denotations. - * intrin.c: Employ new meanings, mapping them to internal - values (which are the same as they ever were for now). - Support the new denotations. - * intrin.def: Switch DEFIMP table to the new denotations. - - * intrin.c (ffeintrin_check_): Fix bug that was leaving - LOC() and %LOC() returning INTEGER*4 on systems where - it should return INTEGER*8. - - * type.c: Canonicalize function definitions, for etags - and such. - -Wed Feb 26 20:43:03 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_init_0): Choose INTEGER(KIND=n) types, - where n is 2, 3, and 4, according to the new docs - instead of according to the old C correspondences - (which seem less useful at this point). - - * equiv.c (ffeequiv_destroy_): New function. - (ffeequiv_layout_local_): Use this new function - whenever the laying out of a local equivalence chain - is aborted for any reason. - Otherwise ensure that symbols no longer reference - the stale ffeequiv entries that result when they - are killed off in this procedure. - Also, the rooted symbol is one that has storage, - it really is irrelevant whether it has an equiv entry - at this point (though the code to remove the equiv - entry was put in at the end, just in case). - (ffeequiv_kill): When doing internal checks, make - sure the victim isn't named by any symbols it points - to. Not as complete a check as looking through the - entire symbol table (which does matter, since some - code in equiv.c used to remove symbols from the lists - for an ffeequiv victim but not remove that victim as the - symbol's equiv info), but this check did find some - real bugs in the code (that were fixed). - -Mon Feb 24 16:42:13 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_expr_intrinsic_): Fix a couple of - warnings about uninitialized variables. - * intrin.c (ffeintrin_check_): Ditto, but there were - a couple of _real_ uninitialized-variable _bugs_ here! - (ffeintrin_fulfill_specific): Ditto, no real bug here. - -Sun Feb 23 15:01:20 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Clean up diagnostics (especially about intrinsics): - * bad.def (FFEBAD_UNIMPL_STMT): Remove. - (FFEBAD_INTRINSIC_*, FFEBAD_NEED_INTRINSIC): Clean these - up so they're friendlier. - (FFEBAD_INTRINSIC_CMPAMBIG): New. - * intrin.c (ffeintrin_fulfill_generic, - ffeintrin_fulfill_specific, ffeintrin_is_intrinsic): - Always choose - generic or specific name text (which is for doc purposes - anyway) over implementation name text (which is for - internal use). - * intrin.def: Use more descriptive name texts for generics - and specifics in cases where the names themselves are not - enough (e.g. IDATE, which has two forms). - - Fix some intrinsic mappings: - * intrin.def (FFEINTRIN_specIDINT, FFEINTRIN_specAND, - FFEINTRIN_specDFLOAT, FFEINTRIN_specDREAL, FFEINTRIN_specOR, - FFEINTRIN_specXOR): Now have their own implementations, - instead of borrowing from others. - (FFEINTRIN_specAJMAX0, FFEINTRIN_specAJMIN0, FFEINTRIN_specBJTEST, - FFEINTRIN_specDFLOTJ, FFEINTRIN_specFLOATJ, FFEINTRIN_specJIABS, - FFEINTRIN_specJIAND, FFEINTRIN_specJIBCLR, FFEINTRIN_specJIBITS, - FFEINTRIN_specJIBSET, FFEINTRIN_specJIDIM, FFEINTRIN_specJIDINT, - FFEINTRIN_specJIDNNT, FFEINTRIN_specJIEOR, FFEINTRIN_specJIFIX, - FFEINTRIN_specJINT, FFEINTRIN_specJIOR, FFEINTRIN_specJISHFT, - FFEINTRIN_specJISHFTC, FFEINTRIN_specJISIN, FFEINTRIN_specJMAX0, - FFEINTRIN_specJMAX1, FFEINTRIN_specJMIN0, FFEINTRIN_specJMIN1, - FFEINTRIN_specJMOD, FFEINTRIN_specJNINT, FFEINTRIN_specJNOT,): - Turn these implementations off, since it's not clear - just what types they expect in the context of portable Fortran. - (DFLOAT): Now in FVZ family, since f2c supports them - - Support intrinsic inquiry functions (BIT_SIZE, LEN): - * intrin.c: Allow `i' in <arg_extra>. - * intrin.def (FFEINTRIN_impBIT_SIZE, FFEINTRIN_impLEN): - Mark args with `i'. - -Sat Feb 22 13:34:09 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Only warn, don't error, for reference to unimplemented - intrinsic: - * bad.def (FFEBAD_INTRINSIC_UNIMPLW): Warning version - of _UNIMPL. - * intrin.c (ffeintrin_is_intrinsic): Use new warning - version of _UNIMPL (FFEBAD_INTRINSIC_UNIMPLW). - - Complain about REAL(Z) and AIMAG(Z) (Z is DOUBLE COMPLEX): - * bad.def (FFEBAD_INTRINSIC_CMPAMBIG): New diagnostic. - * expr.c: Needed #include "intrin.h" anyway. - (ffeexpr_token_intrincheck_): New function handles delayed - diagnostic for "REAL(REAL(expr)" if next token isn't ")". - (ffeexpr_token_arguments_): Do most of the actual checking here. - * intrin.h, intrin.c (ffeintrin_fulfill_specific): New - argument, check_intrin, to tell caller that intrin is REAL(Z) - or AIMAG(Z). All callers updated, mostly to pass NULL in - for this. - (ffeintrin_check_): Also has new arg check_intrin for same - purpose. All callers updated the same way. - * intrin.def (FFEINTRIN_impAIMAG): Change return type - from "R0" to "RC", to accommodate f2c (and perhaps other - non-F90 F77 compilers). - * top.h, top.c: New option -fugly-complex. - - New GNU intrinsics REALPART, IMAGPART, and COMPLEX: - * com.c (ffecom_expr_intrinsic_): Implement impCOMPLEX - and impREALPART here. (specIMAGPART => specAIMAG.) - * intrin.def: Add the intrinsics here. - - Rename implementations of VXTIDATE and VXTTIME to IDATEVXT - and TIMEVXT, so they sort more consistently: - * com.c (ffecom_expr_intrinsic_): - * intrin.def: - - Delete intrinsic group `dcp', add `gnu', etc.: - * intrin.c (ffeintrin_state_family): FFEINTRIN_familyGNU - replaces FFEINTRIN_familyDCP, and gets state from `gnu' - group. - Get rid of FFEINTRIN_familyF2Z, nobody needs it. - Move FFEINTRIN_specDCMPLX from DCP family to FVZ family, - as f2c has it. - Move FFEINTRIN_specDFLOAT from F2C family to FVZ family. - (FFEINTRIN_specZABS, FFEINTRIN_specZCOS, FFEINTRIN_specZEXP, - FFEINTRIN_specZLOG, FFEINTRIN_specZSIN, FFEINTRIN_specZSQRT): - Move these from F2Z family to F2C family. - * intrin.h (FFEINTRIN_familyF2Z, FFEINTRIN_familyDCP): Remove. - (FFEINTRIN_familyGNU): Add. - * top.h, top.c: Replace `dcp' with `gnu'. - - * com.c (ffecom_expr_intrinsic_): Clean up by collecting - simple conversions into one nice, conceptual place. - Fix up some intrinsic subroutines (MVBITS, KILL, UMASK) to - properly push and pop call temps, to avoid wasting temp - registers. - - * g77.c (doit): Toon says variables should be defined - before being referenced. Spoilsport. - - * intrin.c (ffeintrin_check_): Now Dave's worried about - warnings about uninitialized variables. Okay, so for - basic return values 'g' and 's', they _were_ - uninitialized -- is determinism really _that_ useful? - - * intrin.def (FFEINTRIN_impFGETC): Fix STATUS argument - so that it is INTENT(OUT) instead of INTENT(IN). - -1997-02-21 Dave Love <d.love@dl.ac.uk> - - * intrin.def, com.c: Support Sun-type `short' and `long' - intrinsics. Perhaps should also do Microcruft-style `int2'. - -Thu Feb 20 15:16:53 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_expr_intrinsic_): Clean up indentation. - Support SECONDSUBR intrinsic implementation. - Rename SECOND to SECONDFUNC for direct support via library. - - * g77.c: Fix to return proper status value to shell, - by obtaining it from processes it spawns. - - * intdoc.c: Fix minor typo. - - * intrin.def: Turn SECOND into generic that maps into - function and subroutine forms. - - * intrin.def: Make FLOAT and SNGL into specific intrinsics. - - * intrin.def, intrin.h: Change the way DEFGEN and DEFSPEC - macros work, to save on verbage. - -Mon Feb 17 02:08:04 1997 Craig Burley <burley@gnu.ai.mit.edu> - - New subsystem to automatically generate documentation - on intrinsics: - * Make-lang.in ($(srcdir)/f/g77.info, - $(srcdir)/f/g77.dvi): Move g77 doc rules around. - Add to g77 doc rules the new subsystem. - (f77.mostlyclean, f77.maintainer-clean): Also clean up - after new doc subsystem. - * intdoc.c, intdoc.h: New doc subsystem code. - * intrin.h [FFEINTRIN_DOC]: When 1, don't pull in - stuff not needed by doc subsystem. - - Improve on intrinsics mechanism to both be more - self-documenting and to catch more user errors: - * intrin.c (ffeintrin_check_): Recognize new arg-len - and arg-rank information, and check it. - Move goto and signal indicators to the basic type. - Permit reference to arbitrary argument number, not - just first argument (for BESJN and BESYN). - (ffeintrin_init_0): Check and accept new notations. - * intrin.c, intrin.def: Value in COL now identifies - arguments starting with number 0 being the first. - - Some minor intrinsics cleanups (resulting from doc work): - * com.c (ffecom_expr_intrinsic_): Implement FLUSH - directly once again, handle its optional argument, - so it need not be a generic (awkward to handle in docs). - * intrin.def (BESJ0, BESJ1, BESJN, BESY0, BESY1, BESYN, - CHDIR, CHMOD, CTIME, DBESJ0, DBESJ1, DBESJN, DBESY0, - DBESY1, DBESYN, DDIM, ETIME, FGETC, FNUM, FPUTC, FSTAT, - GERROR, GETCWD, GETGID, GETLOG, GETPID, GETUID, GMTIME, - HOSTNM, IDATE, IERRNO, IIDINT, IRAND, ISATTY, ITIME, JIDINT, - LNBLNK, LSTAT, LTIME, MCLOCK, PERROR, SRAND, SYMLNK, TTYNAM, - UMASK): Change capitalization of initcaps (official) name - to be consistent with Burley's somewhat arbitrary rules. - (BESJN, BESYN): These have return arguments of same type - as their _second_ argument. - (FLUSH): Now a specific, not generic, intrinsic, with one - optional argument. - (FLUSH1): Eliminated. - Add arg-len and arg-rank info to several intrinsics. - (ITIME): Change argument type from REAL to INTEGER. - -Tue Feb 11 14:04:42 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (f771): Invocation of Makefile now done - with $(srcdir)=gcc to go along with $(VPATH)=gcc. - ($(srcdir)/f/runtime/configure, - $(srcdir)/f/runtime/libU77/configure): Break these out - so spurious triggers of this rule don't happen (as when - configure.in is more recent than libU77/configure). - (f77.rebuilt): Distinguish source versus build files, - so this target can be invoked from build directory and - still work. - * Makefile.in: This now expects $(srcdir) to be the gcc - source directory, not gcc/f, to agree with $(VPATH). - Accordingly, $(INCLUDES) has been fixed, various cruft - removed, the removal of f771 has been fixed to remove - the _real_ f771 (not the one in gcc's parent directory), - and so on. - - * lex.c: Part of ffelex_finish_statement_() now done - by new function ffelex_prepare_eos_(), so that, in one - popular case, the EOS can be prepared while the pointer - is at the end of the non-continued line instead of the - end of the line that marks no continuation. This improves - the appearance of diagnostics substantially. - -Mon Feb 10 12:44:06 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in: runtime Makefile's, and include/f2c.h, - also depend on f/runtime/configure and f/runtime/libU77/configure. - - Fix various libU77 routines: - * com-rt.def (FFECOM_gfrtCTIME, FFECOM_gfrtMCLOCK, - FFECOM_gfrtTIME): These now use INTEGER*8 for time values, - for compatibility with systems like Alpha. - (FFECOM_gfrtSYSTEM_CLOCK, FFECOM_gfrtTTYNAM): Delete incorrect - trailing underscore in routine names. - * intrin.c, intrin.def: Support INTEGER*8 return values and - arguments ('4'). Change FFEINTRIN_impCTIME, FFEINTRIN_impMCLOCK, - and FFEINTRIN_impTIME accordingly. - (ffeintrin_is_intrinsic): Don't give caller a clue about - form of intrinsic -- shouldn't be needed at this point. - - Cope with generic intrinsics that are subroutines and functions: - * com.c (ffecom_finish_symbol_transform_, ffecom_expr_transform_): - Don't transform an intrinsic that is not known to be a subroutine - or a function. (Maybe someday have to avoid transforming - any intrinsic with an undecided or unknown implementation.) - * expr.c (ffeexpr_declare_unadorned_, - ffeexpr_declare_parenthesized_): Ok to invoke generic - intrinsic that has at least one subroutine form as a - subroutine. - Ok to pass intrinsic as actual arg if it has a known specific - intrinsic form that is valid as actual arg. - (ffeexpr_declare_parenthesized_): An unknown kind of - intrinsic has a paren_type chosen based on context. - (ffeexpr_token_arguments_): Build funcref/subrref based - on context, not on kind of procedure being called. - * intrin.h, intrin.c (ffeintrin_is_intrinsic): Undo changes of - Tue Feb 4 23:12:04 1997 by me, change all callers to leave - intrinsics as FFEINFO_kindNONE at this point. (Some callers - also had unused variables deleted as a result.) - - Enable all intrinsic groups (especially f90 and vxt): - * target.h (FFETARGET_defaultSTATE_DCP, FFETARGET_defaultSTATE_F2C, - FFETARGET_defaultSTATE_F90, FFETARGET_defaultSTATE_MIL, - FFETARGET_defaultSTATE_UNIX, FFETARGET_defaultSTATE_VXT): - Delete these macros, let top.c set them directly. - * top.c (ffeintrinsic_state_dcp_, ffe_intrinsic_state_f2c_, - ffe_intrinsic_state_f90_, ffe_intrinsic_state_mil_, - ffe_intrinsic_state_unix_, ffe_intrinsic_state_vxt_): - Enable all these directly. - -Sat Feb 8 03:21:50 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * g77.c: Incorporate recent changes to ../gcc.c. - For version magic (e.g. `g77 -v'), instead of compiling - /dev/null, write, compile, run, and then delete a small - program that prints the version numbers of the three - components of libf2c (libF77, libI77, and libU77), - so we get this info with bug reports. - Also, this change reduces the chances of accidentally - linking to an old (complex-alias-problem) libf2c. - Fix `-L' so the argument is expected in `-Larg'. - - * com.h (FFECOM_f2cLONGINT): For INTEGER*8 support in f2c.h, - dynamically determine proper type here, instead of - assuming `long long int' is correct. - -Tue Feb 4 23:12:04 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Add libU77 library from Dave Love <d.love@dl.ac.uk>: - * Make-lang.in (f77-runtime): Depend on new Makefile. - (f/runtime/libU77/Makefile): New rule. - Also configure libU77. - ($(srcdir)/f/runtime/configure: Use Makefile.in, - so configuration doesn't have to have happened. - (f77.mostlyclean, f77.clean, f77.distclean, - f77.maintainer-clean): Some fixups here, but more work - needed. - (RUNTIMESTAGESTUFF): Add libU77's config.status. - (LIBU77STAGESTUFF, f77.stage1, f77.stage2, f77.stage3, - f77.stage4): New macro, appropriate uses added. - * com-rt.def: Add libU77 procedures. - * com.c (ffecom_f2c_ptr_to_integer_type_node, - ffecom_f2c_ptr_to_real_type_node): New type nodes. - (FFECOM_rttypeCHARACTER_): New type of run-time function. - (ffecom_char_args_): Handle CHARACTER*n intrinsics - where n != 1 here, instead of in ffecom_expr_intrinsic_. - (ffecom_expr_intrinsic_): New code to handle new - intrinsics. - In particular, change how FFEINTRIN_impFLUSH is handled. - (ffecom_make_gfrt_): Handle new type of run-time function. - (ffecom_init_0): Initialize new type nodes. - * config-lang.in: New libU77 directory. - * intrin.h, intrin.c (ffeintrin_is_intrinsic): Handle - potential generic for subroutine _and_ function - specifics via two new arguments. All callers changed. - Properly ignore deleted/disabled intrinsics in resolving - generics. - (ffeintrin_check_, ffeintrin_init_0): Handle CHARACTER intrinsics of (*) - length. - * intrin.def: Permission granted by FSF to place this in - public domain, which will allow it to serve as source - for both g77 program and its documentation. - Add libU77 intrinsics. - (FLUSH): Now a generic, not specific, intrinsic. - (DEFIMP): Now support return modifier for CHARACTER intrinsics. - - * com-rt.def (FFECOM_gfrtDIM, FFECOM_gfrtERF, - FFECOM_gfrtERFC, FFECOM_gfrtEXP, FFECOM_gfrtSIGN, - FFECOM_gfrtSIN, FFECOM_gfrtSINH, FFECOM_gfrtTAN, - FFECOM_gfrtTANH, FFECOM_gfrtPOW_RI): Change "&r" to "&f". - -Sat Feb 1 12:15:09 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Version 0.5.19.1 released. - - * com.c (ffecom_expr_, ffecom_expr_intrinsic_, - ffecom_tree_divide_): FFECOM_gfrtPOW_ZI, - FFECOM_gfrtCONJG, FFECOM_gfrtDCONJG, - FFECOM_gfrtCCOS, FFECOM_gfrtCDCOS, - FFECOM_gfrtCLOG, FFECOM_gfrtCDLOG, - FFECOM_gfrtCSIN, FFECOM_gfrtCDSIN, - FFECOM_gfrtCSQRT, FFECOM_gfrtCDSQRT, - FFECOM_gfrtDIV_CC, FFECOM_gfrtDIV_ZZ: These all require - result to _not_ overlap one or more inputs. - -Sat Feb 1 00:25:55 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_init_0): Do internal checks only if - -fset-g77-defaults not specified. - - Fix %LOC(), LOC() to return sufficiently wide type: - * com.h, com.c (ffecom_pointer_kind_, ffecom_label_kind_, - ffecom_pointer_kind(), ffecom_label_kind()): New globals - and accessor macros hold kind for integer pointers on target - machine. - (ffecom_init_0): Determine narrowest INTEGER type that - can hold a pointer (usually INTEGER*4 or INTEGER*8), - store it in ffecom_pointer_kind_, etc. - * expr.c (ffeexpr_cb_end_loc_): Use right type for %LOC(). - * intrin.c (ffeintrin_check_, ffeintrin_init_0): Support - new 'p' kind for type of intrinsic. - * intrin.def (FFEINTRIN_impLOC): Returns "Ip" instead of "I1", - so LOC() type is correct for target machine. - - Support -fugly-assign: - * lang-options.h, top.h, top.c (ffe_decode_option): - Accept -fugly-assign and -fno-ugly-assign. - * com.c (ffecom_expr_): Handle -fugly-assign. - * expr.c (ffeexpr_finished_): Check right type for ASSIGN - contexts. - -Fri Jan 31 14:30:00 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Remove last vestiges of -fvxt-not-f90: - * stb.c (ffestb_R10012_, ffestb_R10014_, ffestb_V0201_): - top.c, top.h: - -Fri Jan 31 02:13:54 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c (ffe_decode_option): Warn if -fugly is specified, - it'll go away soon. - - * symbol.h: No need to #include "bad.h". - - Reorganize features from -fvxt-not-f90 to -fvxt: - * lang-options.h, top.h, top.c: - Accept -fvxt and -fno-vxt, but not -fvxt-not-f90 or -ff90-not-vxt. - Warn if the latter two are used. - * expr.c (ffeexpr_nil_rhs_): Double-quote means octal constant. - (ffeexpr_token_rhs_): Double-quote means octal constant. - * target.h (FFETARGET_defaultIS_VXT_NOT_90): Delete macro - definition, no longer needed. - - Make some -ff90 features the default: - * data.c (ffedata_value): DATA implies SAVE. - * src.h (ffesrc_is_name_noninit): Underscores always okay. - - Fix up some more #error directives by quoting their text: - * bld.c (ffebld_constant_is_zero): - * target.h: - -Sat Jan 18 18:22:09 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * g77.c (lookup_option, main): Recognize `-Xlinker', - `-Wl,', `-l', `-L', `--library-directory', `-o', - `--output'. - (lookup_option): Don't depend on SWITCH_TAKES_ARG - being correct, it might or might not have `-x' in - it depending on host. - Return NULL argument if it would be an empty string. - (main): If no input files (by gcc.c's definition) - but `-o' or `--output' specified, produce diagnostic - to avoid overwriting output via gcc. - Recognize C++ `+e' options. - Treat -L as another non-magical option (like -B). - Don't append_arg `-x' twice. - -Fri Jan 10 23:36:00 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c [BUILT_FOR_270] (ffe_decode_option): Make - -fargument-noalias-global the default. - -Fri Jan 10 07:42:27 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Enable inlining of previously-compiled program units: - * com.c (ffecom_do_entry_, ffecom_start_progunit_): - Register new public function in ffeglobal database. - (ffecom_sym_transform_): Any GLOBAL or potentially GLOBAL - symbol should be looked up in ffeglobal database and - that tree node used, if found. That way, gcc knows - the references are to those earlier definitions, so it - can emit shorter branches/calls, inline, etc. - (ffecom_transform_common_): Minor change for clarity. - * expr.c (ffeexpr_sym-lhs_call_, ffeexpr_sym_lhs_extfunc_, - ffeexpr_sym_rhs_actualarg_, ffeexpr_paren_rhs_let_, - ffeexpr_token_funsubstr_): Globalize symbol as needed. - * global.c (ffeglobal_promoted): New function to look up - existing local symbol in ffeglobal database. - * global.h: Declare new function. - * name.h (ffename_token): New macro, plus alphabetize. - * stc.c (ffestc_R1207_item): Globalize EXTERNAL symbol. - * stu.c (ffestu_sym_end_transition, ffestu_sym_exec_transition): - Globalize symbol as needed. - * symbol.h, symbol.c (ffesymbol_globalize): New function. - -Thu Jan 9 14:20:00 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * ste.c (ffeste_R809): Produce a diagnostic for SELECT CASE - on CHARACTER type, instead of crashing. - -Thu Jan 9 00:52:45 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * stc.c (ffestc_order_entry_, ffestc_order_format_, - ffestc_R1226): Allow ENTRY and FORMAT before IMPLICIT - NONE, by having them transition only to state 1 instead - of state 2 (which is disallowed by IMPLICIT NONE). - -Mon Jan 6 22:44:53 1997 Craig Burley <burley@gnu.ai.mit.edu> - - Fix AXP bug found by Rick Niles (961201-1.f): - * com.c (ffecom_init_0): Undo my 1996-05-14 change, as - it is incorrect and prevented easily finding this bug. - * target.h [__alpha__] (ffetargetReal1, ffetargetReal2): - Use int instead of long. - (ffetarget_cvt_r1_to_rv_, ffetarget_cvt_rv_to_r1_, - ffetarget_cvt_r2_to_rv_, ffetarget_cvt_rv_to_r2_): - New functions that intercede for callers of - REAL_VALUE_(TO|UNTO)_TARGET_(SINGLE|DOUBLE). - All callers changed, and damaging casts to (long *) removed. - -Sun Jan 5 03:26:11 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (g77, g77-cross): Depend on both g77.c and - zzz.c, in $(srcdir)/f/. - - Better design for -fugly-assumed: - * stc.c (ffestc_R501_item, ffestc_R524_item, - ffestc_R547_item_object): Pass new is_ugly_assumed flag. - * stt.c, stt.h (ffestt_dimlist_as_expr, - ffestt_dimlist_type): New is_ugly_assumed flag now - controls whether "1" is treated as "*". - Don't treat "2-1" or other collapsed constants as "*". - -Sat Jan 4 15:26:22 1997 Craig Burley <burley@gnu.ai.mit.edu> - - * stb.c (ffestb_R10012_): Don't confirm on FORMAT(A,) - or even FORMAT(A,,B), as R1229 only warns about the - former currently, and this seems reasonable. - - Improvements to diagnostics: - * sta.c (ffesta_second_): Don't add any ffestb parsers - unless they're specifically called for. - Set up ffesta_tokens[0] before calling ffestc_exec_transition, - else stale info might get used. - (ffesta_save_): Do a better job picking which parser to run - after running all parsers with no confirmed possibles. - (FFESTA_maxPOSSIBLES_): Decrease from 100 now that so few - possibles are ever on the list at a given time. - (struct _ffesta_possible): Add named attribute. - (ffesta_add_possible_exec_, ffesta_add_possible_nonexec_): - Make these into macros that call a single function that now - sets the named attribute. - (ffesta_add_possible_unnamed_exec_, - ffeseta_add_possible_unnamed_nonexec_): New macros. - (ffesta_second_): Designate unnamed possibles as - appropriate. - * stb.c (ffestb_R1229, ffestb_R12291_): Use more general - diagnostic, so things like "POINTER (FOO, BAR)" are - diagnosed as unrecognized statements, not invalid statement - functions. - * stb.h, stb.c (ffestb_unimplemented): Remove function. - -1996-12-30 Dave Love <d.love@dl.ac.uk> - - * com.c: #include libU77/config.h - (ffecom_f2c_ptr_to_integer_type_node, - ffecom_f2c_ptr_to_integer_type_node): New variables. - (ffecom_init_0): Use them. - (ffecom_expr_intrinsic_): Many news cases for libU77 intrinsics. - - * com-rt.def: New definitions for libU77. - * intrin.def: Likewise. Also correct ftell arg spec. - - * Makefile.in (f/runtime/libU77/config.h): New target for com.c - dependency. - * Make-lang.in (f771): Depend on f/runtime/Makefile for the above. - -Sat Dec 28 12:28:29 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * stt.c (ffestt_dimlist_type): Treat ([...,]1) in dimlist - as ([...,]*) if -fugly-assumed, so assumed-size array - detected early enough. - -Thu Dec 19 14:01:57 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * target.h (FFETARGET_REAL_VALUE_FROM_INT_): Conditionalize - definition on BUILT_FOR_280, not BUILT_WITH_280, since - the name of the macro was (properly) changed since 0.5.19. - - Fix warnings/errors resulting from ffetargetOffset becoming - `long long int' instead of `unsigned long' as of 0.5.19, - while ffebitCount remains `unsigned long': - * bld.c (ffebld_constantarray_dump): Avoid warnings by - using loop var of appropriate type, and using casts. - * com.c (ffecom_expr_): Use right type for loop var. - (ffecom_sym_transform_, ffecom_transform_equiv_): - Cast to right type in assertions. - * data.c (ffedata_gather_, ffedata_value_): Cast to right - type in assertions and comparisons. - -Wed Dec 18 12:07:11 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Patch from Alexandre Oliva <oliva@dcc.unicamp.br>: - * Makefile.in (all.indirect): Don't pass -bbigtoc option - to GNU ld. - - Cope with new versions of gcc: - * com.h (BUILT_FOR_280): New macro. - * com.c (ffecom_ptr_to_expr): Conditionalize test of - OFFSET_REF. - (ffecom_build_complex_constant_): Conditionalize calling - sequence for build_complex. - -Sat Dec 7 07:15:17 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * Version 0.5.19 released. - -Fri Dec 6 12:23:55 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * g77.c: Default to assuming "f77" is in $LANGUAGES, since - the LANGUAGE_F77 macro isn't defined by anyone anymore (but - might as well leave the no-f77 code in just in case). - * Make-lang.in (g77, g77-cross): Don't define LANGUAGE_F77 - anymore. - -1996-12-06 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (g77, g77-cross): Revert to building `g77' or not - conditional on `f77' in LANGUAGES. - -Wed Dec 4 13:08:44 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (g77, g77-cross): No libs or lib dependencies - in case where "f77" is not in $LANGUAGES. - - * lex.c (ffelex_image_char_, ffelex_file_fixed, - ffelex_file_free): Fixes to properly handle lines with - null character, and too-long lines as well. - - * lex.c: Call ffebad_start_msg_lex instead of - ffebad_start_msg throughout. - -Sun Dec 1 21:19:55 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Fix-up for 1996-11-25 changes: - * com.c (ffecom_member_phase2_): Subtract out 0 offset for - elegance and consistency with EQUIVALENCE aggregates. - (ffecom_sym_transform_): Ditto for LOCAL/COMMON, and - ensure we get the same parent storage area. - * data.c (ffedata_gather_, ffedata_value_): Subtract out - aggregate offset. - -Wed Nov 27 13:55:57 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * proj.h: Quote the text of the #error message, to avoid - strange-looking diagnostics from non-gcc ANSI compilers. - - * top.c: Make -fno-debug-kludge the default. - -Mon Nov 25 20:13:45 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Provide more info on EQUIVALENCE mismatches: - * bad.def (FFEBAD_EQUIV_MISMATCH): More detailed message. - * equiv.c (ffeequiv_layout_local_, ffeequiv_layout_cblock): - More details for FFEBAD_EQUIV_MISMATCH. - - Fix problem with EQUIVALENCE handling: - * equiv.c (ffeequiv_layout_local_): Redesign algorithm -- - old one was broken, resulting in rejection of good code. - (ffeequiv_offset_): Add argument, change callers. - Clean up the code, fix up the (probably unused) negative-value - case for SYMTER. - * com.c (ffecom_sym_transform_): For local EQUIVALENCE - member, subtract out aggregate offset (which is <= 0). - -Thu Nov 21 12:44:56 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Change type of ffetargetOffset from `unsigned long' to `long long': - * bld.c (ffebld_constantarray_dump): Change printf formats. - * storag.c (ffestorag_dump): Ditto. - * symbol.c (ffesymbol_report): Ditto. - * target.h (ffetargetOffset_f): Ditto and change type itself. - - Handle situation where list of languages does not include f77: - * Make-lang.in: Define LANGUAGE_F77 to 1 only if `f77' is in - the $LANGUAGES macro for the build. - * g77.c: Compile to a (nearly) no-op program if LANGUAGE_F77 - is not defined to 1. - - Fixes to delay confirmation of READ, WRITE, and GOTO statements - so the corresponding assignments to same-named CHAR*(*) arrays - work: - * stb.c (ffestb_R90915_, ffestb_91014_): New functions. - (ffestb_goto3_, ffestb_goto5_): Move confirmation from 3 to 5 - for the OPEN_PAREN case. - (ffestb_R9091_, ffestb_R9094_, ffestb_R90913_, ffestb_R90914_, - ffestb_R91012_, ffestb_R91013_): Use new functions, and confirm - except for the OPEN_PAREN case. - - Fixes to not confirm declarations with an open paren where - an equal sign or other assignment-like token might be, so the - corresponding assignments to same-named CHAR*(*) arrays work: - (ffestb_decl_entsp_5_): Move assertion so we crash on that first, - if it turns out to be wrong, before the less-debuggable crash - on mistaken confirmation. - (ffestb_decl_entsp_6_, ffestb_decl_entsp_7_, ffestb_decl_entsp_8_): - Include OPEN_PAREN in list of assignment-only tokens. - - Fix more diagnosed-crash bugs: - * stu.c (ffestu_sym_end_transition): ANY-ize an adjustable array - with bad dimension expressions even if still stateUNCERTAIN. - (ffestu_symter_end_transition_, ffestu_symter_exec_transition_): - Return TRUE for opANY as well. - For code elegance, move opSYMTER case into first switch. - -1996-11-17 Dave Love <d.love@dl.ac.uk> - - * lex.c: Fix last change. - -1996-11-14 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in, config-lang.in: Remove the (broken) libU77 stuff, - pending 0.5.20. - -Thu Nov 14 15:40:59 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * bad.def (FFEBAD_UNIMPL_STMT): Explain that invalid - intrinsic references can trigger this message, too. - -1996-11-12 Dave Love <d.love@dl.ac.uk> - - * lex.c: Declare dwarfout routines. - - * config-lang.in: Sink grep o/p. - -Mon Nov 11 14:21:13 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * g77.c (main): Might as well print version number - for --verbose as well. - -Thu Nov 7 18:41:41 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c, lang-options.h, target.h, top.c, top.h: Split out - remaining -fugly stuff into -fugly-logint and -fugly-comma, - leaving -fugly as simply a `macro' that expands into other - options, and eliminate defaults for some of the ugly stuff - in target.h. - - * Make-lang.in (gcc-cross): Compile zzz.c, not version.o (!), - in to get version info for this target. - - * config-lang.in: Test for GBE patch application based - on whether 2.6.x or 2.7.x GBE is detected. - -Wed Nov 6 14:19:45 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (g77): Compile zzz.c in to get version info. - * g77.c: Add support for --help and --version. - - * g77.c (lookup_option): Short-circuit long-winded tests - when second char is not hyphen, just to save a spot of time. - -Sat Nov 2 13:50:31 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * intrin.def: Add FTELL and FSEEK intrinsics, plus new - `g' codes for alternate-return (GOTO) arguments. - * intrin.c (ffeintrin_check_): Support `g' codes. - * com-rt.def: Add ftell_() and fseek_() to database. - * com.c (ffecom_expr_intrinsic_): Ditto. Also, let each - subroutine intrinsic decide for itself what to do with - tree_type, the default being NULL_TREE once again (so - ffecom_call_ doesn't think it's supposed to cast the - function call to the type in the fall-through case). - - * ste.c (ffeste_R909_finish): Don't special-case list-directed - I/O, now that libf2c can return non-zero status codes. - (ffeste_R910_finish): Ditto. - (ffeste_io_call_): Simplify logic. - (ffeste_io_impdo_): - (ffeste_subr_beru_): - (ffeste_R904): - (ffeste_R907): - (ffeste_R909_start): - (ffeste_R909_item): - (ffeste_R909_finish): - (ffeste_R910_start): - (ffeste_R910_item): - (ffeste_R910_finish): - (ffeste_R911_start): - (ffeste_R923A): Ditto all the above. - -Thu Oct 31 20:56:28 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * config-lang.in, Make-lang.in: Rename flag file - build-u77 to build-libu77, for consistency with - install-libf2c and such. - - * config-lang.in: Don't complain about failure to patch - if pre-2.7.0 gcc is involved (since our patch for that - doesn't add support for tooning). - -Sat Oct 26 05:56:51 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * bad.def (FFEBAD_TYPELESS_TOO_LARGE): Remove this - unused and redundant diagnostic. - -Sat Oct 26 00:45:42 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * target.c (ffetarget_integerhex): Fix dumb bug. - -1996-10-20 Dave Love <d.love@dl.ac.uk> - - * gbe/2.7.2.1.diff: New file. - - * Makefile.in (F771_LDFLAGS): Add -bbigtoc for AIX4.1 up, suggested by - endo@material.tohoku.ac.jp [among others!]. - -Sat Oct 19 03:11:14 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * bad.def, bld.c, bld.h, expr.c, lang-options.h, target.c, - target.h, top.c, top.h (ffebld_constant_new_integerbinary, - ffebld_constant_new_integerhex, ffebld_constant_new_integeroctal, - ffeexpr_token_name_apos_name_, ffetarget_integerbinary, - ffetarget_integerhex, ffetarget_integeroctal): Support - new -fno-typeless-boz option with new functions, mods to - existing octal-handling functions, new macros, new error - messages, and so on. - - * com.c, lang-options.h, top.c, top.h (ffecom_notify_primary_entry): - Print program unit name on stderr if -fno-silent (new option). - - * lang-options.h, top.c, top.h, stt.c (ffestt_dimlist_as_expr): - Treat ([...,]1) in dimlist as ([...,]*) if -fugly-assumed - (new option). - - * lang-options.h: Comment out options duplicated in gcc/toplev.c, - because, somehow, having them commented in and building on my - DEC Alpha results in a cc1 that always segfaults, and gdb that - also segfaults whenever it debugs it up to init_lex() calling - xmalloc() or so. - -Thu Oct 17 00:39:27 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * stb.c (ffestb_R10013_): Don't change meaning of .sign until - after previous meaning/value used to set sign of value - (960507-1.f). - -Sun Oct 13 22:15:23 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c (ffe_decode_option): Don't set back-end flags - that are nonexistent prior to gcc 2.7.0. - -Sun Oct 13 12:48:45 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (convert): Don't convert emulated complex expr to - real (via REALPART_EXPR) if the target type is (emulated) - complex. - -Wed Oct 2 21:57:12 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_debug_kludge_): Set DECL_IN_SYSTEM_HEADER so - -Wunused doesn't complain about these manufactured decls. - (ffecom_expr_): Ditto, for original (non-ASSIGN'ed) variable. - (ffecom_transform_equiv_): Clear DECL_IGNORED_P for aggregate - area so it shows up as a debug-accessible symbol. - (pushdecl): Default for "invented" identifiers (a g77-specific - concept for now) is that they are artificial, in system header, - ignored for debugging purposes, used, and (for types) suppressed. - This ought to be overkill. - -Fri Sep 27 23:13:07 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * ste.c (ffeste_begin_iterdo_, ffeste_end_iterdo_): Support - one-trip DO loops (F66-style). - * lang-options.h, top.c, top.h (-fonetrip): New option. - -Thu Sep 26 00:18:40 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_debug_kludge_): New function. - (ffecom_sym_transform_): Use new function for COMMON and EQUIVALENCE - members. - - * lang-options.h, top.c, top.h (-fno-debug-kludge): - New option. - -1996-09-24 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (include/f2c.h): - Remove dependencies on xmake_file and tmake_file. - They expand inconsistently in 2.8 c.f. 2.7; $(GCC_PARTS) depends on - them anyhow. - -1996-09-22 Dave Love <d.love@dl.ac.uk> - - * config-lang.in: Add --enable-libu77 option handling. - - * Make-lang.in: - Conditionally add --enable-libu77 when running runtime configure. - Define LIBU77STAGESTUFF and use it in relevant rules. - -1996-08-21 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (f77-runtime): - `stmp-hdrs' should have been `stmp-headers'. - -1996-08-20 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (f77-runtime): - Depend on stmp-hdrs, not stmp-int-hdrs, since libF77 - needs float.h. - -Sat Jun 22 18:17:11 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_tree_divide_): Fix RECORD_TYPE case to - look at type of first field, properly, to determine - whether to call c_div or z_div. - -Tue Jun 4 04:27:18 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_build_complex_constant_): Explicitly specify - TREE_PURPOSE. - (ffecom_expr_): Fix thinko. - (ffecom_2): For COMPLEX_EXPR, explicitly specify TREE_PURPOSE. - -Mon May 27 16:23:43 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Changes to optionally avoid gcc's back-end complex support: - * com.c (ffecom_stabilize_aggregate_): New function. - (ffecom_convert_to_complex_): New function. - (ffecom_make_complex_type_): New function. - (ffecom_build_complex_constant_): New function. - (ffecom_expr_): For opCONVERT of non-COMPLEX to COMPLEX, - don't bother explicitly converting to the subtype first, - because gcc does that anyway, and more code would have - to be added to find the subtype for the emulated-complex - case. - (ffecom_f2c_make_type_): Use ffecom_make_complex_type_ - instead of make_node etc. to make a complex type. - (ffecom_1, ffecom_2): Translate operations on COMPLEX operands - to appropriate operations when emulating complex. - (ffecom_constantunion): Use ffecom_build_complex_constant_ - instead of build_complex to build a complex constant. - (ffecom_init_0): Change point at which types are laid out - for improved consistency. - Use ffecom_make_complex_type_ instead of make_node etc. - to make a complex type. - Always calculate storage sizes from TYPE_SIZE, never TYPE_PRECISION. - (convert): Use e, not expr, since we've copied into that anyway. - For RECORD_TYPE cases, do emulated-complex conversions. - (ffecom_f2c_set_lio_code_): Always calculate storage sizes - from TYPE_SIZE, never TYPE_PRECISION. - (ffecom_tree_divide_): Allow RECORD_TYPE to also be handled - by run-time library. - (ffecom_expr_intrinsic_): Handle possible RECORD_TYPE as argument - to AIMAG intrinsic. - - * top.h, top.c, lang-options.h: Support new -f(no-)emulate-complex option. - - * com.c (ffecom_sym_transform_): Clarify and fix typos in comments. - -Mon May 20 02:06:27 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * target.h: Use new REAL_VALUE_UNTO_TARGET_* macros instead - of REAL_VALUE_FROM_TARGET_DOUBLE and _SINGLE. - Explicitly use long instead of HOST_WIDE_INT for emulation - of ffetargetReal1 and ffetargetReal2. - -1996-05-20 Dave Love <d.love@dl.ac.uk> - - * config-lang.in: - Test for patch being applied with flag_move_all_movables in toplev.c. - - * install.texi (Patching GNU Fortran): - Mention overriding X_CFLAGS rather than - editing proj.h on SunOS4. - - * Make-lang.in (F77_FLAGS_TO_PASS): - Add X_CFLAGS (convenient for SunOS4 kluge, in - particular). - (f77.{,mostly,dist}clean): Reorder things, in particular not to delete - Makefiles too early. - - * g77.c (DEFAULT_SWITCH_TAKES_ARG): Define a la gcc.c in the - current GCC snapshot. - -Tue May 14 00:24:07 1996 Craig Burley <burley@gnu.ai.mit.edu> - - Changes for DEC Alpha AXP support: - * com.c (ffecom_init_0): REAL_ARITHMETIC means internal - REAL/DOUBLE PRECISION might well have a different size - than the compiled type, so don't crash if this is the - case. - * target.h: Use `int' for ffetargetInteger1, - ffetargetLogical1, and magical tests. Set _f format - strings accordingly. - -Tue Apr 16 14:08:28 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c (ffe_decode_option): -Wall no longer implies - -Wsurprising. - -Sat Apr 13 14:50:06 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_char_args_): If item is error_mark_node, - set *length that way, too. - - * com.c (ffecom_expr_power_integer_): If either operand - is error_mark_node, return that. - - * com.c (ffecom_intrinsic_len_): If item is error_mark_node, - return that for length. - - * expr.c (ffeexpr_declare_unadorned_, - ffeexpr_declare_parenthesized_): Instead of crashing - on unexpected contexts, produce a diagnostic. - - * intrin.c (ffeintrin_check_), intrin.def (impSIGNAL): - Allow procedure as second arg to SIGNAL intrinsic. - - * stu.c (ffestu_symter_end_transition_): New function. - (ffestu_symter_exec_transition_): Return bool arg. - Always transition symbol (don't inhibit when !whereNONE). - (ffestu_sym_end_transition): If DUMMY/LOCAL arg has any - opANY exprs in its dimlist, diagnose it so it doesn't - make it through to later stages that try to deal with - dimlist stuff. - (ffestu_sym_exec_transition): If sym has any opANY exprs - in its dimlist, diagnose it so it becomes opANY itself. - - * symbol.c (ffesymbol_error): If token arg is NULL, - just ANY-ize the symbol -- don't produce diagnostic. - -Mon Apr 1 10:14:02 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * Version 0.5.18 released. - -Mon Mar 25 20:52:24 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_expr_power_integer_): Don't generate code - that compares COMPLEX (or, as it happens, REAL) via "LT_EXPR", - since the back end crashes on that. (This code would never - be executed anyway, but the test that avoids it has now been - translated to control whether the code gets generated at all.) - Fixes 960323-3.f. - - * com.c (ffecom_type_localvar_): Handle variable-sized - dimension bounds expressions here, so they get calculated - and saved on procedure entry. Fixes 960323-4.f. - - * com.c (ffecom_notify_init_symbol): Symbol has no init - info at all if only zeros have been used to initialize it. - Fixes 960324-0.f. - - * expr.c, expr.h (ffeexpr_type_combine): Renamed from - ffeexpr_type_combine_ and now a public procedure; last arg now - a token, instead of an internal structure used to extract a token. - Now allows the outputs to be aliased with the inputs. - Now allows a NULL token to mean "don't report error". - (ffeexpr_reduced_bool2_, ffeexpr_reduced_eqop2_, - ffeexpr_reduced_math2_, ffeexpr_reduced_power_, - ffeexpr_reduced_relop2_): Handle new calling sequence for - ffeexpr_type_combine. - * (ffeexpr_convert): Don't put an opCONVERT node - in just because the size is unknown; all downstream code - should be able to deal without it being there anyway, and - getting rid of it allows new intrinsic code to more easily - combine types and such without generating bad code. - * info.c, info.h (ffeinfo_kindtype_max): Rewrite to do - proper comparison of size of types, not just comparison - of their internal kind numbers (so I2.eq.I1 doesn't promote - I1 to I2, rather the other way around). - * intrin.c (ffeintrin_check_): Combine types of arguments - in COL a la expression handling, for greater flexibility - and permissiveness (though, someday, -fpedantic should - report use of this kind of thing). - Make sure Hollerith/typeless where CHARACTER expected is - rejected. This all fixes 960323-2.f. - - * ste.c (ffeste_begin_iterdo_): Fix some more type conversions - so INTEGER*2-laden DO loops don't crash at compile time on - certain machines. Believed to fix 960323-1.f. - - * stu.c (ffestu_sym_end_transition): Certainly reject - whereDUMMY not in any dummy list, whether stateUNCERTAIN - or stateUNDERSTOOD. Fixes 960323-0.f. - -Tue Mar 19 13:12:40 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * data.c (ffedata_value): Fix crash on opANY, and simplify - the code at the same time. - - * Make-lang.in (f77-runtime): Also depends on lib[FI]77/Makefile... - (include/f2c.h...): ...which in turn depend on */Makefile.in. - (f77.rebuilt): Rebuild runtime stuff too. - - * intrin.c (ffeintrin_check_): Accommodate TYPELESS/HOLLERITH - types, convert args as necessary, etc. - - * expr.c (ffeexpr_convert): Fix test for TYPELESS/HOLLERITH - to obey the docs; crash if no source token when error. - (ffeexpr_collapse_convert): Crash if no token when error. - -Mon Mar 18 15:51:30 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_init_zero_): Renamed from - ffecom_init_local_zero_; now handles top-level - (COMMON) initializations too. - - * bld.c (ffebld_constant_is_zero): - * com.c (ffecom_symbol_transform_, ffecom_sym_transform_assign_, - ffecom_transform_common_, ffecom_transform_equiv_): - * data.c: - * equiv.c: - * equiv.h: - * lang-options.h: - * stc.c: - * storag.c: - * storag.h: - * symbol.c: - * symbol.h: - * target.c: - * target.h: - * top.c: - * top.h: All of this is mostly housekeeping-type changes - to support -f(no-)zeros, i.e. not always stuff zero - values into the initializer fields of symbol/storage objects, - but still track that they have been given initial values. - - * bad.def: Fix wording for DATA-related diagnostics. - - * com.c (ffecom_sym_transform_assign_): Don't check - any EQUIVALENCE stuff for local ASSIGN, the check was - bad (crashing), and it's not necessary, anyway. - - * com.c (ffecom_expr_intrinsic_): For MAX and MIN, - ignore null arguments as far arg[123], and fix handling - of ANY arguments. (New intrinsic support now allows - spurious trailing null arguments.) - - * com.c (ffecom_init_0): Add HOLLERITH (unsigned) - equivalents for INTEGER*2, *4, and *8, so shift intrinsics - and other things that need unsigned versions of signed - types work. - -Sat Mar 16 12:11:40 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * storag.c (ffestorag_exec_layout): Treat adjustable - local array like dummy -- don't create storage object. - * com.c (ffecom_sym_transform_): Allow for NULL storage - object in LOCAL case (adjustable array). - -Fri Mar 15 13:09:41 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_sym_transform_): Allow local symbols - with nonconstant sizes (adjustable local arrays). - (ffecom_type_localvar_): Allow dimensions with nonconstant - component (adjustable local arrays). - * expr.c: Various minor changes to handle adjustable - local arrays (a new case of stateUNCERTAIN). - * stu.c (ffestu_sym_end_transition, - ffestu_sym_exec_transition): Ditto. - * symbol.def: Update docs to reflect these changes. - - * com.c (ffecom_expr_): Reduce space/time needed for - opACCTER case by handling it here instead of converting - it to opARRTER earlier on. - (ffecom_notify_init_storage): Don't convert ACCTER to ARRTER. - (ffecom_notify_init_symbol): Ditto. - - * com.c (ffecom_init_0): Crash and burn if any of the types' - sizes, according to the GBE, disagrees with the sizes of - the FFE's internal implementation. This might catch - Alpha/SGI bugs earlier. - -Fri Mar 15 01:09:41 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com-rt.def, com.c, com.h: Changes for rewrite of intrinsic - handling. - * com.c (ffecom_arglist_expr_): New function. - (ffecom_widest_expr_type_): New function. - (ffecom_expr_intrinsic_): Reorganize, some rewriting. - (ffecom_f2c_make_type_): Layout complex types. - (ffecom_gfrt_args_): New function. - (ffecom_list_expr): Trivial change for consistency. - - * expr.c (ffeexpr_token_name_rhs_): Go back to getting - type from specific, not implementation, info. - (ffeexpr_token_funsubstr_): Set intrinsic implementation too! - * intrin.c: Major rewrite of most portions. - * intrin.def: Major rearchitecting of tables. - * intrin.h (ffeintrin_basictype, ffeintrin_kindtype): - Now (once again) take ffeintrinSpec as arg, not ffeintrinImp; - for now, these return NONE, since they're not really needed - and adding the necessary info to the tables is not trivial. - (ffeintrin_codegen_imp): New function. - * stc.c (ffestc_R1208_item): Change way ffeintrin funcs called, - back to original per above; but comment out the code anyway. - - * intrin.c (ffe_init_0): Do internal checks only if - -fset-g77-defaults not specified. - - * lang-options.h: Add -fset-g77-defaults option. - * lang-specs.h: Always pass -fset-g77-defaults. - * top.c, top.h: New option. - -Sat Mar 9 17:49:50 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in (stmp-int-hdrs): Use --no-validate when - generating the f77.rebuilt files (BUGS, INSTALL, NEWS) - so cross-references can work properly in g77.info - without a lot of hassle. Users can probably deal with - the way they end up looking in the f77.rebuilt files. - - * bld.c (ffebld_constant_new_integer4_val): INTEGER*8 - support -- new function. - (ffebld_constant_new_logical4_val): New function. - * com.c (ffecom_f2c_longint_type_node): New type. - (FFECOM_rttypeLONGINT_): New return type code. - (ffecom_expr_): Add code to invoke pow_qq instead - of pow_ii for INTEGER4 (INTEGER*8) case. - If ffecom_expr_power_integer_ returns NULL_TREE, just do - the usual work. - (ffecom_make_gfrt_): Handle new type. - (ffecom_expr_power_integer_): Let caller do the work if in - dummy-transforming case, since - caller now knows about INTEGER*8 and such, by returning - NULL_TREE. - * expr.c (ffeexpr_reduced_power_): Complain about non-INTEGER - raised to INTEGER4 (INTEGER*8) power. - - * target.c (ffetarget_power_integerdefault_integerdefault): - Fix any**negative. - * com.c (ffecom_expr_power_integer_): Fix (-1)**(-8) and similar - to ABS() the integral result if the exponent is negative - and even. - - * ste.c (ffeste_begin_iterdo_): Clean up a type ref. - Always convert iteration count to _default_ INTEGER. - - * sta.c (ffesta_second_): Add BYTE and WORD type/stmts; - changes by Scott Snyder <snyder@d0sgif.fnal.gov>. - * stb.c (ffestb_decl_recursive): Ditto. - (ffestb_decl_recursive): Ditto. - (ffestb_decl_entsp_2_): Ditto. - (ffestb_decl_entsp_3_): Ditto. - (ffestb_decl_funcname_2_): Ditto. - (ffestb_decl_R539): Ditto. - (ffestb_decl_R5395_): Ditto. - * stc.c (ffestc_establish_declstmt_): Ditto. - * std.c (ffestd_R539item): Ditto. - (ffestd_R1219): Ditto. - * stp.h: Ditto. - * str-1t.fin: Ditto. - * str-2t.fin: Ditto. - - * expr.c (ffeexpr_finished_): For DO loops, allow - any INTEGER type; convert LOGICAL (assuming -fugly) - to corresponding INTEGER type instead of always default - INTEGER; let later phases do conversion of DO start, - end, incr vars for implied-DO; change checks for non-integral - DO vars to be -Wsurprising warnings. - * ste.c (ffeste_io_impdo_): Convert start, end, and incr - to type of DO variable. - - * com.c (ffecom_init_0): Add new types for [IL][234], - much of which was done by Scott Snyder <snyder@d0sgif.fnal.gov>. - * target.c: Ditto. - * target.h: Ditto. - -Wed Mar 6 14:08:45 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * top.c (ffe_init_gbe_): Make -frerun-loop-opt the default. - -Mon Mar 4 12:27:00 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_exprstack_push_unary_): Really warn only - about two successive _arithmetic_ operators. - - * stc.c (ffestc_R522item_object): Allow SAVE of (understood) - local entity. - - * top.c (ffe_decode_option): New -f(no-)second-underscore options. - * top.h: New options. - * com.c (ffecom_get_external_identifier_, ffecom_get_identifier_): - New options. - - * Make-lang.in (f77.maintainer-clean): Clean f/BUGS, f/INSTALL, - f/NEWS. - ($(srcdir)/f/BUGS, $(srcdir)/f/INSTALL, $(srcdir)/f/NEWS): - New rules. - ($(srcdir)/f/g77.info, $(srcdir)/f/g77.dvi): Depend on - f/bugs.texi and f/news.texi. - (f77.install-man): Install f77 man pages (if enabled). - (f77.uninstall): Uninstall info docs, f77 man pages (if enabled). - - * top.c (ffe_init_gbe_): New function. - (ffe_decode_option, ffe_file): Call ffe_init_gbe_ to - set defaults for gcc options. - -Sat Jan 20 13:57:19 1996 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_get_identifier_): Eliminate needless - comparison of results of strchr. - -Tue Dec 26 11:41:56 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * Make-lang.in: Add rules for new files g77.texi, g77.info, - and g77.dvi. - Reorganize the *clean rules to more closely parallel gcc's. - - * config-lang.in: Exclude g77.info from diffs. - -Sun Dec 10 02:29:13 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * expr.c (ffeexpr_declare_unadorned_, - ffeexpr_declare_parenthesized_): Break out handling of - contextDATAIMPDO[INDEX,CTRL] so it's independent of symbol state. - Don't exec-transition these here (let ffeexpr_sym_impdoitem_ - handle that when appropriate). Don't "declare" them twice. - -Tue Dec 5 06:48:26 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * stc.c (ffestc_promote_sfdummy_): Allow whereNONE parent - symbol, since it is not necessarily known whether it will - become LOCAL or DUMMY. - -Mon Dec 4 03:46:55 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * lex.c (ffelex_display_token, ffelex_type_string_): Resurrect - these from their old versions and update them for possible invocation - from debugger. - * lex.h (ffelex_display_token): Declare this in case anyone - else wants to call it. - - * lex.c (ffelex_total_tokens_): Have this reflect actual allocated - tokens, no longer include outstanding "uses" of tokens. - - * malloc.c, malloc.h (MALLOC_DEBUG): New macro to control - checking of whether callers follow rules, now defaults to 0 - for "no checking" to improve compile times. - - * malloc.c (malloc_pool_kill): Fix bug that could prevent - subpool from actually being killed (wasn't setting its use - count to 1). - - * proj.h, *.c (dmpout): Replace all occurrences of `stdout' - and some of `stderr' with `dmpout', so where to dump debugging - output can be easily controlled during build; add default - for `dmpout' of `stderr' to proj.h. - -Sun Dec 3 00:56:29 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * com.c (ffecom_return_expr): Eliminate attempt at warning - about unset return values, since the back end does this better, - with better wording, and is not triggered by clearly working - (but spaghetti) code as easily as this test. - -Sat Dec 2 08:28:56 1995 Craig Burley <burley@gnu.ai.mit.edu> - - * target.c (ffetarget_power_*_integerdefault): Raising 0 to - integer constant power should not be an error condition; - if so, other code should catch 0 to any power, etc. - - * bad.def (FFEBAD_BAD_POWER): 0**integer now a warning instead - of an error. - -Fri Dec 1 00:12:03 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.def: Clarify diagnostic regarding complex constant elements. - * expr.c (ffeexpr_cb_comma_c_): Capitalize real/imaginary - for clarified diagnostic. - - * com.c (ffecom_close_include_): Close the file! - - * lex.c (ffelex_file_fixed): Update line info if the line - has any content, not just if it finishes a previous line - or has a label. - (ffelex_file_free): Clarify switch statement code. - -Sat Nov 18 19:37:22 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.17 released. - -Fri Nov 17 14:27:24 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in: Fix typo in comment. - - * Makefile.in (f/fini.o, f/proj-h.o): Don't use `$<' since - not all makes support it (e.g. NeXT make), use explicit - source name instead (with $(srcdir) and munging). - (ASSERT_H): assert.h lives in source dir, not build dir. - -Thu Nov 16 12:47:50 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_init_0): Fix dumb bug in code to produce - warning message about non-32-bit-systems. - - * stc.c (ffestc_R501_item): Parenthesize test to make - warning go away (and perhaps fix bug). - -Thu Nov 16 03:43:33 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * g77.c: Upgrade to 2.7.0's gcc.c. - Fix -v to pass a temp name instead of "/dev/null" for "-o". - -Fri Nov 10 19:16:05 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * ste.c (ffeste_begin_iterdo_): Add Toon's change to - make loops faster on some machines (implement termination - condition as "--i >= 0" instead of "i-- > 0"). - -Thu Nov 2 03:58:17 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in: Remove unnecessary $(exeext) a la cp/Make-lang.in. - - * com.c (ffecom_expr_): Restore old strategy for assignp variant - of opSYMTER case...always return the ASSIGN version of var. - That way, `-O -Wuninitialized' will catch "I=3;GOTO I;END" - (though the diagnostic will refer to `__g77_ASSIGN_i'). - - * com.c (ffecom_expr_power_integer_): For constant rhs case, - wrap every new eval of lhs in save_expr() so it is clear to - back end that MULT_EXPR(lhs,lhs) has identical operands, - otherwise for an rhs like 32767 it generates around 65K pseudo - registers, with which stupid_life_analysis cannot cope - (due to reg_renumber in regs.h being `short *' instead of - `int *'). - - * com.c (ffecom_expr_): Speed up implementation of LOGICAL - versions of opNOT, opAND, opOR, opXOR/opNEQV, and opEQV by - assuming the values actually are kosher LOGICAL bit patterns. - Also simplify code that implements some of the INTEGER versions - of these. - - * com.c (skip_redundant_dir_prefix, read_name_map, - ffecom_open_include_, signed_type, unsigned_type): Fold in - changes to cccp.c made from 2.7.0 through ss-950826. - - * equiv.c (ffeequiv_layout_local_): Kill the equiv list - if no syms in list. - - * expr.c (ffeexpr_reduced_eqop2_): Issue specific diagnostic - regarding usage of .EQV./.NEQV. in preference to .EQ./.NE.. - - * intrin.c: Add ERF and ERFC as generic intrinsics. - intrin.def: Same. - - * sta.c (ffesta_save_, ffesta_second_): Whoever calls - ffestd_exec_begin must also set ffesta_seen_first_exec = TRUE, - and anytime stc sees an exec transition, it must do both. - stc.c (ffestc_eof): Same. - - * stc.c (ffestc_promote_sfdummy_): If failed implicit typing - or CHARACTER*(*) arg, after calling ffesymbol_error, don't - reset info to ENTITY/DUMMY, because ffecom_sym_transform_ - doesn't expect such a thing with ANY/ANY type. - - * target.h (*logical*): Change some of these so they parallel - changes in com.c, e.g. for _eqv_, use (l)==(r) instead of - !!(l)==!!(r), to get a more faithful result. - -Fri Oct 27 07:06:59 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_sym_transform_): Simplify code for local - EQUIVALENCE case. - - * expr.c (ffeexpr_exprstack_push_unary_): Warn about two - successive operators. - (ffeexpr_exprstack_push_binary_): Warn about "surprising" - operator precedence, as in "-2**2". - - * lang-options.h: Add -W(no-)surprising options. - - * parse.c (yyparse): Don't reset -fpedantic if not -pedantic. - - * top.c (ffe_decode_option): Support new -Wsurprising option. - * top.h: Ditto. - -Mon Oct 23 09:14:15 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_finish_symbol_transform_): Don't transform - NONE/NONE (CHARACTER*(*)) vars, as these don't mean anything - in debugging terms, and can't be turned into anything - in the back end (so ffecom_sym_transform_ crashes on them). - - * com.c (ffecom_expr_): Change strategy for assignp variant - of opSYMTER case...always return the original var unless - it is not wide enough. - - * ste.c (ffeste_io_cilist_): Clarify diagnostic for ASSIGN - involving too-narrow variable. This shouldn't happen, though. - (ffeste_io_icilist_): Ditto. - (ffeste_R838): Ditto. - (ffeste_R839): Ditto. - -Thu Oct 19 03:21:20 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_sym_transform_assign_): Set TREE_STATIC - using the same decision-making process as used for their twin - variables, so ASSIGN can last across RETURN/CALL as appropriate. - -Fri Sep 22 20:21:18 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Makefile.in: fini is a host program, so it needs a host-compiled - version of proj.o, named proj-h.o. f/fini, f/fini.o, and - f/proj-h.o targets updated accordingly. - - * com.c (__eprintf): New function. - -Wed Sep 20 02:26:36 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * lang-options.h: Add omitted -funix-intrinsics-* options. - - * malloc.c (malloc_find_inpool_): Check for infinite - loop, crash if detected (user reports encountering - them in some large programs, this might help track - down the bugs). - -Thu Sep 7 13:00:32 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (lang_print_error_function): Don't dereference null - pointer when outside any program unit. - (ffecom_let_char_, ffecom_arg_ptr_to_expr): If catlist - item or length ever error_mark_node, don't continue processing, - since back-end functions like build_pointer_type crash on - error_mark_node's (due to pushing bad obstacks, etc.). - -Wed Aug 30 15:58:35 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.16 released. - -Mon Aug 28 12:24:20 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.c (ffebad_finish): Fix botched message when no places - are printed (due to unknown line info, etc.). - - * std.c (ffestd_subr_labels_): Do a better job finding - line info in the case of typeANY and diagnostics. - -Fri Aug 25 15:19:29 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (DECL_ARTIFICIAL): Surround all references to this - macro with #if !BUILT_FOR_270 and #endif. - (init_lex): Surround print_error_function decl with - #if !BUILT_FOR_270 and #endif. - (lang_init): Call new ffelex_hash_kludge function to solve - problem with preprocessed files that have INCLUDE statements. - - * lex.c (ffelex_getc_): New function. - (ffelex_cfelex_): Use ffelex_getc_ instead of getc in any - paths of code that can be affected by ffelex_hash_kludge. - Don't make an EOF token for unrecognized token; set token - to NULL instead, to avoid problems when not initialized. - (ffelex_hash_): Use ffelex_getc_ instead of getc in any - paths of code that can be affected by ffelex_hash_kludge. - Test token returned by ffelex_cfelex_ for NULL, meaning - unrecognized token. - Get rid of useless used_up variable. - Don't do ffewhere stuff or kill any tokens if in - ffelex_hash_kludge. - (ffelex_file_fixed, ffelex_file_free): Use ffelex_getc_ - instead of getc in any paths of code that can be affected - by ffelex_hash_kludge. - (ffelex_hash_kludge): New function. - - * lex.h (ffelex_hash_kludge): New function. - -Wed Aug 23 15:17:40 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c: Implement -f(no-)underscoring options by always - compiling in code to do it, and having that code inhibit - itself when -fno-underscoring is in effect. This option - overrides -f(no-)f2c for this purpose; -f(no-)f2c returns - to it's <=0.5.15 behavior of affecting only how code - is generated, not how/whether names are mangled. - - * target.h: Redo specification of appending underscores so - the macros are named "_default" instead of "_is" and the - two-underscore macro defaults to 1. - - * top.c, top.h (underscoring): Add appropriate stuff - for the -f(no-)underscoring options. - -Tue Aug 22 10:25:01 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.c (ffebad_finish): Call report_error_function (in toplev.c) - to better identify location of problem. - Say "(continued):" instead of "(continued:)" for consistency. - - * com.c (ffecom_gen_sfuncdef_): Set and reset new - ffecom_nested_entry_ variable to hold ffesymbol being compiled. - (lang_print_error_function): New function from toplev.c. - Use ffecom_nested_entry_ to help determine which name - and kind-string to print. - (ffecom_expr_intrinsic_): Handle EXIT and FLUSH invocations - with different calling sequences than library functions. - Have SIGNAL and SYSTEM push and pop calltemps, and convert - their return values to the destination type (just in case). - (FFECOM_rttypeINT_): New return type for `int', in case - gcc/f/runtime/libF77/system_.c(system_) is really supposed - to return `int' instead of `ftnint'. - - * com.h (report_error_function): Declare this. - - * equiv.c (ffeequiv_layout_local_): Don't forget to consider - root variable itself as possible "first rooted variable", - else might never set symbol and then crash later. - - * intrin.c (ffeintrin_check_exit_): Change to allow no args - and rename to ffeintrin_check_int_1_o_ for `optional'. - #define ffeintrin_check_exit_ and _flush_ to this new - function, so intrin.def can refer to the appropriate names. - - * intrin.def (FFEINTRIN_impFLUSH): Validate using - ffeintrin_check_flush_ so passing an INTEGER arg is allowed. - - * lex.c (ffelex_file_push_, ffelex_file_pop_): New functions - to manage input_file_stack in gbe. - (ffelex_hash_): Call new functions (instead of doing code). - (ffelex_include_): Call new functions to update stack for - INCLUDE (_hash_ handles cpp output of #include). - -Mon Aug 21 08:09:04 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Makefile.in: Put `-W' in front of every `-Wall', since - 2.7.0 requires that to engage `-Wunused' for parameters. - - * com.c: Mark all parameters as artificial, so - `-W -Wunused' doesn't complain about unused ones (since - there's no way right not to individually specify attributes - like `unused'). - - * proj.h: Don't #define UNUSED if already defined, regardless - of host compiler. - -Sun Aug 20 16:03:56 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * gbe/2.7.0.diff: Regenerate. - - * lang-options.h, lang-specs.h: If not __STDC__ (ANSI C), - avoid doing anything, especially the stringizing in -specs.h. - -Thu Aug 17 03:36:12 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * lang-specs.h: Remove useless optional settings of -traditional, - since -traditional is always set anyway. - -Wed Aug 16 16:56:46 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in (F2C_INSTALL_FLAG, F2CLIBOK): More - control over whether to install f2c-related stuff. - (install-f2c-*): New targets to install f2c-related - stuff in system, not just gcc, directories. - - * com.c: Change calls to ffecom_get_invented_identifier - to use generally more predictable names. - Change calls to build_range_type to ensure consistency - of types of operands. - (ffecom_get_external_identifier_): Change to accept - symbol info, not just text, so it can use f2c flag for - symbol to decide whether to append underscore(s). - (ffecom_get_identifier_): Don't change names if f2c flag - off for compilation. - (ffecom_type_permanent_copy_): Use same type for new max as - used for min. - (ffecom_notify_init_storage): Offline fixups for stand-alone. - - * data.c (ffedata_gather): Explicitly test for common block, - since it's no longer always the case that a local EQUIVALENCE - group has no symbol ptr (it now can, if a user-predictable - "rooted" symbol has been identified). - - * equiv.c: Add some debugging stuff. - (ffeequiv_layout_local_): Set symbol ptr with user-predictable - "rooted" symbol, for giving the invented aggregate a - predictable name. - - * g77.c (append_arg): Allow for 20 extra args instead of 10. - (main): For version-only case, add `-fnull-version' and, unless - explicitly omitted, `-lf2c -lm'. - - * lang-options.h: New "-fnull-version" option. - - * lang-specs.h: Support ".fpp" suffix for preprocessed source - (useful for OS/2, MS-DOS, other case-insensitive systems). - - * stc.c (ffestc_R544_equiv_): Swap way lists are merged so this - is consistent with the order in which lists are built, making - user predictability of invented aggregate name much higher. - - * storag.c, storag.h (FFESTORAG_typeDUMMY): Delete this enum. - - * top.c: Accept, but otherwise ignore, `-fnull-version'. - -Tue Aug 15 07:01:07 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * DOC, INSTALL, PROJECTS: Extensive improvements to documentation. - -Sun Aug 13 01:55:18 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * INSTALL (f77-install-ok): Document the use of this file. - - * Make-lang.in (F77_INSTALL_FLAG): New flag to control - whether to install an `f77' command (based on whether - a file named `f77-install-ok' exists in the source or - build directory) to replace the broken attempt to use - comment lines to avoid installing `f77' (broken in the - sense that it prevented installation of `g77'). - -Mon Aug 7 06:14:26 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * DOC: Add new sections for g77 & gcc compiler options, - source code form, and types, sizes and precisions. - Remove lots of old "delta-version" info, or at least - summarize it. - - * INSTALL: Add info here that used to be in DOC. - Other changes. - - * g77.c (lookup_option, main): Check for --print-* options, - so we avoid adding version-determining stuff. - -Wed Jul 26 15:51:03 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in, Makefile.in (input.j, INPUT_H): New file. - Update dependencies accordingly. - - * bad.c (ffebad_here): Okay to use unknown line/col. - - * compilers.h (@f77-cpp-input): Remove -P option now that - # directives are handled by f771. Update other options - to be more consistent with @c in gcc/gcc.c. Don't run f771 - if -E specified, etc., a la @c. - (@f77): Don't run f771 if -E specified, etc., a la @c. - - * config-lang.in: Avoid use of word "guaranteed". - - * input.j: New file to wrap around gcc/input.h. - - * lex.j: Add support for parsing # directives output by cpp. - (ffelex_cfebackslash_): New function. - (ffelex_cfelex_): New function. - (ffelex_get_directive_line_): New function. - (ffelex_hash_): New function. - (ffelex_include_): Change to not use ffewhere_file_(begin|end). - Also fix bug in pointing to next line (for diagnostics, &c) - following successful INCLUDE. - (ffelex_next_line_): New function that does chunk of code - seen in several places elsewhere in the lexers. - (ffelex_file_fixed): Delay finishing statement until source - line is registered with ffewhere, so INCLUDE processing - picks up the info correctly. - Okay to kill or use unknown line/col objects now. - Handle HASH (#) lines. - Reorder tests for insubstantial lines to put most frequent - occurrences at top, for possible minor speedup. - Some general consolidation of code. - (ffelex_file_free): Handle HASH (#) lines. - Okay to kill or use unknown line/col objects now. - Some general consolidation of code. - (ffelex_init_1): Detect HASH (#) lines. - (ffelex_set_expecting_hollerith): Okay to kill or use unknown - line/col objects now. - - * lex.h (FFELEX_typeHASH): New enum. - - * options-lang.h (-fident, -fno-ident): New options. - - * stw.c (ffestw_update): Okay to kill unknown line/col objects - now. - - * target.h (FFETARGET_okREALQUAD, FFETARGET_okCOMPLEXDOUBLE, - FFETARGET_okCOMPLEXQUAD): #define these appropriately. - - * top.c: Include flag.j wrapper, not flags.h directly. - (ffe_is_ident_): New flag. - (ffe_decode_option): Handle -fident and -fno-ident. - (ffe_file): Replace obsolete ffewhere_file_(begin|end) with - ffewhere_file_set. - - * top.h (ffe_is_ident_, ffe_is_ident, ffe_set_is_ident): - New flag and access functions. - - * where.c, where.h: Remove all tracking of parent file. - (ffewhere_file_begin, ffewhere_file_end): Delete these. - (ffewhere_line_use): Make it work with unknown line object. - -Mon Jul 17 03:04:09 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_sym_transform_): Set DECL_IN_SYSTEM_HEADER - flag for any local vars used as stmtfunc dummies or DATA - implied-DO iter vars, so no -Wunused warnings are produced - for them (a la f2c). - (ffecom_init_0): Do "extern int xargc;" for IARGC() intrinsic. - Warn if target machine not 32 bits, since g77 isn't yet - working on them at all well. - - * expr.c (ffeexpr_sym_lhs_call_, ffeexpr_sym_lhs_data_, - ffeexpr_sym_lhs_extfunc_, ffeexpr_sym_rhs_actualarg_, - ffeexpr_sym_rhs_let_, ffeexpr_paren_rhs_let_): Don't - gratuitously set attr bits that don't apply just - to avoid null set meaning error; instead, use explicit - error flag, and allow null attr set, to - fix certain bugs discovered by looking at this code. - - * g77.c: Major changes to improve support for gcc long options, - to make `g77 -v' report more useful info, and so on. - -Mon Jul 3 14:49:16 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * DOC, com.c, intrin.h, intrin.c, intrin.def, target.h, top.c, - top.h: Add new `unix' group of intrinsics, which includes the - newly added ERF, ERFC, EXIT, plus even newer ABORT, DERF, DERFC, - FLUSH, GETARG, GETENV, SIGNAL, and SYSTEM. - -Tue Jun 27 23:01:05 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bld.c, bld.h (ffebld_constant_pool, - ffebld_constant_character_pool): Use a single macro (the - former) to access the pool for allocating constants, instead - of latter in public and FFEBLD_CONSTANT_POOL_ internally - in bld.c (which was the only one that was correct before - these changes). Add verification of integrity of certain - heap-allocated areas. - - * com.c (ffecom_overlap_, ffecom_args_overlap_, - ffecom_tree_canonize_ptr_, ffecom_tree_canonize_ref_): New - functions to optimize calling COMPLEX and, someday, CHARACTER - functions requiring additional argument to be passed. - (ffecom_call_, ffecom_call_binop_, ffecom_expr_, - ffecom_expr_intrinsic_): Change calling - sequences to include more info on possible destination. - (ffecom_expr_intrinsic_): Add ERF(), ERFC(), and EXIT() - intrinsic code. - (ffecom_sym_transform_): For assumed-size arrays, set high - bound to highest possible value instead of low bound, to - improve validity of overlap checking. - (duplicate_decls): If olddecl and newdecl are the same, - don't do any munging, just return affirmative. - - * expr.c: Change ffecom_constant_character_pool() to - ffecom_constant_pool(). - - * info.c (ffeinfo_new): Compile this version if not being - compiled by GNU C. - - * info.h (ffeinfo_new): Don't define macro if not being - compiled by GNU C. - - * intrin.c, intrin.def: Add ERF(), ERFC(), and EXIT() intrinsics. - (ffeintrin_check_exit_): New for EXIT() subroutine intrinsic. - - * malloc.c, malloc.h (malloc_verify_*): New functions to verify - integrity of heap-storage areas. - - * stc.c (ffestc_R834, ffestc_R835): Handle possibility that - an enclosing DO won't have a construct name even when the - CYCLE/EXIT does (i.e. without dereferencing NULL). - - * target.c, target.h (ffetarget_verify_character1): New function - to verify integrity of heap storage used to hold character constant. - -Thu Jun 22 15:36:39 1995 Howard Gordon (flash@super.org) - - * stp.h (ffestpVxtcodeIx): Fix typo in typedef for this. - -Mon May 29 15:22:31 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * *: Make all sorts of changes to accommodate upcoming gcc-2.7.0. - I didn't keep track of them, nor just when I made them, nor - when I (much later, probably in early August 1995) modified - them so they could properly handle both 2.7.0 and 2.6.x. - - * com.c (ffecom_expr_power_integer_): Don't expand_start_stmt_expr - if transforming dummy args, because the back end cannot handle - that (it's rejected by the gcc front end), just generate - call to run-time library. - Back out changes in 0.5.15 because more temporaries might be - needed anyway (for COMPLEX**INTEGER). - (ffecom_push_tempvar): Remove inhibitor. - Around start_decl and finish_decl (in particular, arround - expand_decl, which is called by them), push NULL_TREE into - sequence_rtl_expr, an external published by gcc/function.c. - This makes sure the temporary is truly in the function's - context, not the inner context of a statement-valued expression. - (I think the back end is inconsistent here, but am not - interested in convincing the gbe maintainers about this now.) - (pushdecl): Make sure that when pushing PARM_DECLs, nothing - other than them are pushed, as happened for 0.5.15 and which, - if done for other reasons not fixed here, might well indicate - some other problem -- so crash if it happens. - - * equiv.c (ffeequiv_layout_local_): If the local equiv group - has a non-nil COMMON field, it should mean that an error has - occurred and been reported, so just trash the local equiv - group and do nothing. - - * stc.c (ffestc_promote_sfdummy_): Set sfdummy arg state to - UNDERSTOOD so above checking for duplicate args actually - works, and so we don't crash later in pushdecl. - - * ste.c (ffeste_R1001): Set initial value only for VAR_DECLs, - not for, e.g., LABEL_DECLs, which the FORMAT label can be - if it was previously treated as an executable label. - -Sat May 20 01:53:53 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_sym_transform_): For adjustable arrays, - pass high bound through variable_size in case its primaries - are changed (dumb0.f, and this might also improve - performance so it approaches f2c|gcc). - -Fri May 19 11:00:36 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.15 released. - - * com.c (ffecom_expr_power_integer_): Push temp vars - before expanding a statement expression, since that seems - to cause temp vars to be "forgotten" after the end of the - expansion in the back end. Disallow more temp-var - pushing during such an expansion, just in case. - (ffecom_push_tempvar): Crash if a new variable needs to be - pushed but cannot be at this point (should never happen). - -Wed May 17 12:26:16 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * expr.c (ffeexpr_collapse_convert): Add code to convert - LOGICAL to CHARACTER. Reject conversion of REAL or COMPLEX - to CHARACTER entirely, as it cannot be supported with all - configurations. - - * target.h, target.c (ffetarget_convert_character1_logical1): - New function. - -Sun May 14 00:00:09 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_do_entry_, ffecom_gen_sfuncdef_, - ffecom_start_progunit_, ffecom_sym_transform_, - ffecom_init_0, start_function): Changes to have REAL - external functions return same type as DOUBLE PRECISION - external functions when -ff2c is in force; while at it, - some code cleanups done. - - * stc.c (ffestc_R547_item_object): Disallow array declarator - if one already exists for symbol. - - * ste.c (ffeste_R1227): Convert result variable to type - of function result as seen by back end (e.g. for when REAL - external function actually returns result as double). - - * target.h (FFETARGET_defaultFIXED_LINE_LENGTH): New - macro for default for -ffixed-line-length-N option. - - * top.c (ffe_fixed_line_length_): Initialize this to new - target.h macro instead of constant 72. - -Tue May 9 01:20:03 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * lex.c (ffelex_send_token_): If sending CHARACTER token with - null text field, put a single '\0' in it and set length/size - fields to 0 (to fix 950508-0.f). - (ffelex_image_char_): When setting ffelex_bad_line_ to TRUE, - always "close" card image by appending a null char and setting - ffelex_card_length_. As part of this, append useful text - to identify the two kinds of problems that involve this. - (ffelex_file_fixed): Reset ffelex_bad_line_ to FALSE after - seeing a line with invalid first character (fixes 950508-1.f). - If final nontab column is zero, assume tab seen in line. - (ffelex_card_image_): Always make this array 8 characters - longer than reflected by ffelex_card_size_. - (ffelex_init_1): Get final nontab column info from top instead - of assuming 72. - - * options-lang.h: Add -ffixed-line-length- prefix. - - * top.h: Add ffe_fixed_line_length() and _set_ version, plus - corresponding extern. - - * top.c: Handle -ffixed-line-length- option prefix. - -Fri Apr 28 05:40:25 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.14 released. - - * Make-lang.in: Add assert.j. - - * Makefile.in: Add assert.j. - - * assert.j: New file. - -Thu Apr 27 16:24:22 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.h (ffebad_severity): New function. - - * bad.c (ffebad_severity): New function. - - * bad.def (FFEBAD_OPEN_INCLUDE): Change severity from SEVERE - to FATAL, since processing continues, and that seems fine. - - * com.c: Add facility to handle -I. - (ffecom_file, ffecom_close_include, ffecom_open_include, - ffecom_decode_include_option): New global functions for -I. - (ffecom_file_, ffecom_initialize_char_syntax_, - ffecom_close_include_, ffecom_decode_include_option_, - ffecom_open_include_, append_include_chain, open_include_file, - print_containing_files, read_filename_string, file_name_map, - savestring): New internal functions for -I. - - * compilers.h: Pass -I flag(s) to f771 (via "%{I*}"). - - * lex.c (ffelex_include_): Call ffecom_close_include - to close include file, for its tracking needs for -I, - instead of using fclose. - - * options-lang.h: Add -I prefix. - - * parse.c (yyparse): Call ffecom_file for main input file, - so -I handling works (diagnostics). - - * std.c (ffestd_S3P4): Have ffecom_open_include handle - opening and diagnosing errors with INCLUDE files. - - * ste.c (ffeste_begin_iterdo_): Use correct algorithm for - calculating # of iterations -- mathematically similar but - computationally different algorithm was not handling cases - like "DO I=6,5,2" correctly, because (5-6)/2+1 => 1, not 0. - - * top.c (ffe_decode_option): Allow -I, restructure a bit - for clarity and, maybe, speed. - -Mon Apr 17 13:31:11 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * g77.c: Remove -lc, turns out not all systems has it, but - leave other changes in for clarity of code. - -Sun Apr 16 21:50:33 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_expr_): Implement ARRAY_EXPR as INDIRECT_REF - of appropriate PLUS_EXPRs of ptr_to_expr of array, to see - if this generates better code. (Conditional on - FFECOM_FASTER_ARRAY_REFS.) - -Sun Apr 16 00:22:48 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in (F77_SRCS): Remove g77.c, since it doesn't - contribute to building f771. - - * Makefile.in (dircheck): Remove/replace with f/Makefile, because - phony targets that are referenced in other real targets get run - when those targets are specified, which is a waste of time (e.g. - when rebuilding and only g77.c has changed, f771 was being linked - anyway). - - * g77.c: Include -lc between -lf2c and -lm throughout. - - * implic.c (ffeimplic_establish_symbol): If -Wimplicit, warn if - implicit type given to symbol. - - * lex.c (ffelex_include_): Don't gratuitously increment line - number here. - - * top.h, top.c (ffe_is_warn_implicit_): New global variable and - related access macros. - (ffe_decode_option): Handle -W options, including -Wall and - -Wimplicit. - - * where.c (ffewhere_line_new): Don't muck with root line (was - crashing on null input since lexer changes over the past week - or so). - -Thu Apr 13 16:48:30 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_init_0): Register built-in functions for cos, - sin, and sqrt. - (ffecom_tree_fun_type_double): New variable. - (ffecom_expr_intrinsic_): Update f2c input and output files - to latest version of f2c (no important g77-related changes - noted, just bug fixes to f2c and such). - (builtin_function): New function from c-decl.c. - - * com-rt.def: Refer to built-in functions for cos, sin, and sqrt. - -Thu Apr 13 10:25:09 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_expr_intrinsic_): Convert 0. to appropriate - type to keep DCMPLX(I) from crashing the compiler. - (ffecom_expr_): Don't convert result from ffecom_tree_divide_. - (ffecom_tree_divide_): Add tree_type argument, have all callers - pass one, and don't convert right-hand operand to it (this is - to make this new function work as much like the old in-line - code used in ffecom_expr_ as possible). - - * lex.c: Maintain lineno and input_filename the way the gcc - lexer does. - - * std.c (ffestd_exec_end): Save and restore lineno and - input_filename around the second pass, which sets them - appropriately for each saved statement. - -Wed Apr 12 09:44:45 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_expr_power_integer_): New function. - (ffecom_expr_): Call new function for power op with integer second - argument, for generating better code. Also replace divide - code with call to new ffecom_tree_divide_ function. - Canonicalize calls to ffecom_truth_value(_invert). - (ffecom_tree_divide_): New function. - -Wed Apr 5 14:15:44 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * lex.c: Change to allocate text for tokens only when actually - needed, which should speed compilation up somewhat. - Change to allow INCLUDE at any point where a statement - can end, i.e. in ffelex_finish_statement_ or when a SEMICOLON - token is sent. - Remove some old, obsolete code. - Clean up layout of entire file to improve formatting, - readability, etc. - (ffelex_set_expecting_hollerith): Remove include argument. - -Fri Mar 31 23:19:08 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.h, bad.c (ffebad_start_msg, ffebad_start_msg_lex): - New functions to generate arbitrary messages. - (FFEBAD_severityPEDANTIC): New severity, to correspond - to toplev's pedwarn() function. - - * lex.c (ffelex_backslash_): New function to implement - backslash processing. - (ffelex_file_fixed, ffelex_file_free): Implement new - backslash processing. - - * std.c (ffestd_R1001dump_): Don't assume CHARACTER and - HOLLERITH tokens stop at '\0' characters, now that backslash - processing is supported -- use their advertised lengths instead, - and double up the '\002' character for libf2c. - -Mon Mar 27 17:10:33 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_init_local_zero_): Implement -finit-local-zero. - (ffecom_sym_transform_): Same. - (ffecom_transform_equiv_): Same. - - * options-lang.h: Add -f(no-)(init-local-zero,backslash,ugly-init). - - * stb.c (ffestb_V020): Reject "TYPEblah(...", which might be - an array assignment. - - * target.h, top.h, top.c: Implement -finit-local-zero. - -Fri Mar 24 19:56:22 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Make-lang.in, Makefile.in: Remove conf-proj(.in) and - proj.h(.in) rules, plus related config.log, config.cache, - and config.status stuff. - - * com.c (ffecom_init_0): Change messages when atof(), bsearch(), - or strtoul() do not work as expected in the start-up test. - - * conf-proj, conf-proj.in: Delete. - - * lex.c (ffelex_file_fixed): Allow f2c's '&' in column 1 - to mean continuation line. - - * options-lang.h: New file, #include'd by ../toplev.c. - - * proj.h.in: Rename back to proj.h. - - * proj.h (LAME_ASSERT): Remove. - (LAME_STDIO): Remove. - (NO_STDDEF): Remove. - (NO_STDLIB): Remove. - (NO_BSEARCH): Remove auto detection, rename to !FFEPROJ_BSEARCH. - (NO_STRTOUL): Remove auto detection, rename to !FFEPROJ_STRTOUL. - (USE_HOST_LIMITS): Remove (maybe still needed by stand-alone?). - (STR, STRX): Do only ANSI C definitions. - -Mon Mar 13 10:46:13 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * BUGS: Add item about g77 requiring gcc to compile it. - - * NEWS: New file listing user-visible changes in the release. - - * PROJECTS: Update to include a new item or two, and modify - or delete items that are addressed in this or previous releases. - - * bad.c (ffebad_finish): Don't crash if missing string &c, - just substitute obviously distressed string "[REPORT BUG!!]" - for cases where the message/caller are fudgy. - - * bad.def: Clean up error messages in a major way, add new ones - for use by changes in target.c. - - * com.c (ffecom_expr_): Handle opANY in opCONVERT. - (ffecom_let_char_): Disregard destinations with ERROR_MARK. - (ffecom_1, ffecom_1_fn, ffecom_2, ffecom_2s, ffecom_3, - ffecom_3s, &c): Check all inputs for error_mark_node. - (ffecom_start_progunit_): Don't transform all symbols - in BLOCK DATA, since it never executes, and it is silly - to, e.g., generate all the structures for NAMELIST. - (ffecom_char_length_expr_): Rename to ffecom_intrinsic_len_. - (ffecom_intrinsic_ichar_): New function to handle ICHAR of - arbitrary expression with possible 0-length operands. - (ffecom_expr_intrinsic_): Use ffecom_intrinsic_char_. - For MVBITS, set tree_type to void_type_node. - (ffecom_start_progunit_): Name master function for entry points - after primary entry point so users can easily guess it while - debugging. - (ffecom_arg_ptr_to_expr): Change treatment of Hollerith, - Typeless, and %DESCR. - (ffecom_expr_): Change treatment of Hollerith. - - * data.c (ffedata_gather_): Handle opANY in opCONVERT. - - * expr.c (ffeexpr_token_apostrophe_): Issue FFEBAD_NULL_CHAR_CONST - warning as necessary. - (ffeexpr_token_name_rhs_): Set context for args to intrinsic - so that assignment-like concatenation is allowed for ICHAR(), - IACHAR(), and LEN() intrinsics. - (ffeexpr_reduced_*_): Say "an array" instead of "an entity" in - diagnostics, since it's more informative. - (ffeexpr_finished_): For many contexts, check for null expression - and array before trying to do a conversion, to avoid redundant - diagnostics. - - * g77.1: Fix typo for preprocessed suffix (.F, not .f). - - * global.c (ffeglobal_init_common): Warn if initializing - blank common. - (ffeglobal_pad_common): Enable code to warn if initial - padding needed. - (ffeglobal_size_common): Complain if enlarging already- - initialized common, since it won't work right anyway. - - * intrin.c: Add IMAG() intrinsic. - (ffeintrin_check_loc_): Allow opSUBSTR in LOC(). - - * intrin.def: Add IMAG() intrinsic. - - * lex.c: Don't report FFEBAD_NULL_CHAR_CONST errors. - - * sta.c, sta.h, stb.c: Changes to clean up error messages (see - bad.def). - - * stb.c (ffestb_R100113_): Issue FFEBAD_NULL_CHAR_CONST - warning as necessary. - - * stc.c (ffestc_shriek_do_): Don't try to reference doref_line - stuff in ANY case, since it won't be valid. - (ffestc_R1227): Allow RETURN in main program unit, with - appropriate warnings/errors. - (ffestc_subr_format_): Array of any type is a CHAREXPR (F77 C5). - - * ste.c (ffeste_begin_doiter_): Couple of fixes to accurately - determine if loop never executes. - - * target.c (ffetarget_convert_*_hollerith_): Append spaces, - not zeros, to follow F77 Appendix C, and to warn when - truncation of non-blanks done. - (ffetarget_convert_*_typeless): Rewrite to do typeless - conversions properly, and warn when truncation done. - (ffetarget_print_binary, ffetarget_print_octal, - ffetarget_print_hex): Rewrite to use new implementation of - typeless. - (ffetarget_typeless_*): Rewrite to use new implementation - of typeless, and to warn about overflow. - - * target.h (ffetargetTypeless): New implementation of - this type. - - * type.h, type.c (ffetype_size_typeless): Remove (incorrect) - implementation of this function and its extern. - -Sun Mar 5 18:46:42 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * BUGS: Clarify that constant handling would also fix lack of - adequate IEEE-754/854 support to some degree, and typeless - and non-decimal constants. - - * com.c (ffecom_type_permanent_copy_): Comment out to avoid - warnings. - (duplicate_decls): New function a la gcc/c-decl.c. - (pushdecl): Use duplicate_decls to decide whether to return - existing decl or new one, instead of always returning existing - decl. - (ffecom_expr_): opPERCENT_LOC now supports CHARACTER arguments. - (ffecom_init_0): Give f2c I/O code 0 for basictypeANY/kindtypeANY. - (ffecom_sym_transform_): For adjustable arrays, pass low bound - through variable_size in case its primaries are changed (950302-1.f). - - * com.h: More decls that belong in tree.h &c. - - * data.c (ffedata_eval_integer1_): Fix opPAREN case to not - treat value of expression as an error code. - - * expr.c (ffeexpr_finished_): Allow opSUBSTR in contextLOC case. - - * proj.c: Add "const" as appropriate. - -Mon Feb 27 10:04:03 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * bad.def (FFEBAD_BAD_SUBSTR): Fix bad grammar in message. - -Fri Feb 24 16:21:31 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.13 released. - - * INSTALL: Warn that f/zzz.o will compare differently between - stages, since it puts the __TIME__ macro into a string. - - * com.c (ffecom_sym_transform_): Transform kindFUNCTION/whereDUMMY - to pointer-to-function, not function. - (ffecom_expr_): Use ffecom_arg_ptr_to_expr instead of - ffecom_char_args_ to handle comparison between CHARACTER - types, so either operand can be a CONCATENATE. - (ffecom_transform_common_): Set size of initialized common area - to global (largest-known) size, even though size of init might - be smaller. - - * equiv.c (ffeequiv_offset_): Check symbol info for ANY. - - * expr.c (ffeexpr_find_close_paren_, ffeexpr_nil_*): New functions - to handle following the contour of a rejected expression, so - statements like "PRINT(I,I,I)=0" don't cause the PRINT statement - code to get the second passed back to it as if there was a - missing close-paren before it, the comma causing the PRINT code - to confirm the statement, resulting in an ambiguity vis-a-vis - the let statement code. - Use the new ffecom_find_close_paren_ handler when an expected - close-paren is missing. - (ffeexpr_isdigits_): New function, use in all places that - currently use isdigit in repetitive code. - (ffeexpr_collapse_symter): Collapse to ANY if init-expr is ANY, - so as to avoid having symbol get "transformed" if used to - dimension an array. - (ffeexpr_token_real_, ffeexpr_token_number_real_): Don't issue - diagnostic about exponent, since it'll be passed along the - handler path, resulting in a diagnostic anyway. - (ffeexpr_token_apos_char_): Use consistent handler path - regardless of whether diagnostics inhibited. - (ffeexpr_token_name_apos_name_): Skip past closing quote/apos - even if not a match or other diagnostic issued. - (ffeexpr_sym_impdoitem_): Exec-transition local SEEN symbol. - - * lex.c (ffelex_image_char_): Set ffelex_saw_tab_ if TAB - seen, not if anything other than TAB seen! - - * stc.c (ffestc_R537_item): If source is ANY but dest isn't, - set dest symbol's init expr to ANY. - (ffestc_R501_attrib, ffestc_R522, ffestc_R522start): Complain - about conflict between "SAVE" by itself and other uses of - SAVE only in pedantic mode. - - * ste.c (ffeste_R1212): Fix loop over labels to always - increment caseno, to avoid pushcase returning 2 for duplicate - values when one of the labels is invalid. - -Thu Feb 23 12:42:04 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.12 released. - - * Make-lang.in (f77.install-common): Add "else true;" before outer - "fi" per Makefile.in patch. - - * Makefile.in (dircheck): Add "else true;" before "fi" per - patch from chs1pm@surrey.ac.uk. - - * com.c (ffecom_push_tempvar): If type desired is ERROR_MARK, - return error_mark_node, to avoid crash that results from - making a VAR_DECL with error_mark_node as its type. - - * ste.c (ffeste_begin_iterdo_): Convert itercount to INTEGER - anytime calculation of number of iterations ends up with type - other than INTEGER (e.g. DOUBLE PRECISION, REAL). - -Thu Feb 23 02:48:38 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.11 released. - - * DOC: Explain -fugly-args. - - * bad.def (FFEBAD_ACTUALARG): Explain -fugly-args and how to - rewrite code to not require it. - - * com.c (ffecom_vardesc_): Handle negative type code, just in - case. - (ffecom_arg_ptr_to_expr): Let ffecom_expr handle hollerith - and typeless constants (move code to ffecom_constantunion). - (ffecom_constantunion): Handle hollerith and typeless constants. - - * expr.c (ffecom_finished_): Check -fugly-args in actual-arg - context where hollerith/typeless provided. - - * intrin.def (FFEINTRIN_genDFLOAT): Add FFEINTRIN_specDFLOAT. - (FFEINTRIN_specDFLOAT): Add as f2c intrinsic. - - * target.h (ffetarget_convert_real[12]_integer, - ffetarget_convert_complex[12]_integer): Pass -1 for high integer - value if low part is negative. - (FFETARGET_defaultIS_UGLY_ARGS): New macro. - - * top.c (ffe_is_ugly_args_): New variable. - (ffe_decode_option): Handle -fugly-args and -fno-ugly-args. - - * top.h (ffe_is_ugly_args_, ffe_is_ugly_args(), - ffe_set_is_ugly_args()): New variable and macros. - -Thu Feb 23 02:48:38 1995 Pedro A M Vazquez (vazquez@iqm.unicamp.br) - - * g77.c (sys_errlist): Use const for __FreeBSD__ systems - as well. - -Wed Feb 22 13:33:43 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.10 released. - - * CREDITS: Add Rick Niles. - - * INSTALL: Note how to get around lack of makeinfo. - - * Make-lang.in (f/proj.h): Remove # comment. - - * Makefile.in (f/proj.h): Remove # comment. - - * com.c (ffecom_expr_): Simplify opFUNCREF/opSUBRREF conversion. - (ffecom_sym_transform_): For whereGLOBAL and whereDUMMY - kindFUNCTION, use ffecom_tree_fun_type[][] only for non-constant - (non-statement-function) f2c functions. - (ffecom_init_0): ffecom_tree_fun_type[][] and _ptr_to_*_* are - really f2c-interface arrays, so use base type void for COMPLEX - (like CHARACTER). - -Tue Feb 21 19:01:18 1995 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (f77.install-common): Expurgate the test for and - possible installation of f2c in line with elsewhere. Seems to have - been missing a semicolon anyhow! - -Tue Feb 21 11:45:25 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.9 released. - - * Make-lang.in (f/proj.h): touch file to register update, - because the previous commands won't necessarily modify it. - - * Makefile.in (f/proj.h): touch file to register update, - because the previous commands won't necessarily modify it. - - * Makefile.in (f/str-*.h, f/str-*.j): Explicitly specify - output file names, so these targets go in build, not source, - directory. - - * bits.c, bits.h: Switch to valid ANSI C replacement for - ARRAY_ZERO. - - * com.c (ffecom_expr_): Add assignp arg to support ASSIGN better. - If assignp is TRUE, use different tree for FFEBLD_opSYMTER case. - (ffecom_sym_transform_assign_): New function. - (ffecom_expr_assign): New function. - (ffecom_expr_assign_w): New function. - - * com.c (ffecom_f2c_make_type_): Do make_signed_type instead - of make_unsigned_type throughout. - - * com.c (ffecom_finish_symbol_transform_): Expand scope of - commented-out code to probably produce faster compiler code. - - * com.c (ffecom_gen_sfuncdef_): Push/pop calltemps so - COMPLEX works right. - Remove obsolete comment. - - * com.c (ffecom_start_progunit_): If non-multi alt-entry - COMPLEX function, primary (static) entry point returns result - directory, not via extra arg -- to agree with ffecom_return_expr - and others. - Pretransform all symbols so statement functions are defined - before any code emitted. - - * com.c (ffecom_finish_progunit): Don't posttransform all - symbols here -- pretransform them instead. - - * com.c (ffecom_init_0): Don't warn about possible ASSIGN - crash, as this shouldn't happen now. - - * com.c (ffecom_push_tempvar): Fix to handle temp vars - pushed while context is a statement (nested) function, and - add appropriate commentary. - - * com.c (ffecom_return_expr): Check TREE_USED to determine - where return value is unset. - - * com.h (struct _ffecom_symbol_): Add note about length_tree - now being used to keep tree for ASSIGN version of symbol. - - * com.h (ffecom_expr_assign, ffecom_expr_assign_rw): New decls. - (error): Add this prototype for back-end function. - - * fini.c (main): Grab input, output, and include names - directly off the command line instead of making the latter - two out of the first. - - * lex.c: Improve tab handling for both fixed and free source - forms, and ignore carriage-returns on input, while generally - improving the code. ffelex_handle_tab_ has been renamed and - reinvented as ffelex_image_char_, among other things. - - * malloc.c, malloc.h: Switch to valid ANSI C replacement for - ARRAY_ZERO, and kill the full number of bytes in pools and - areas. - - * proj.h.in (ARRAY_ZERO, ARRAY_ZERO_SIZE): Remove. - - * ste.c (ffeste_io_cilist_, ffeste_io_icilist_, ffeste_R838, - ffeste_R839): Issue diagnostic if a too-narrow variable used in an - ASSIGN context despite changes to this code and code in com.c. - - * where.c, where.h: Switch to valid ANSI C replacement for - ARRAY_ZERO. - -Fri Feb 17 03:35:19 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.8 released. - - * INSTALL: In quick-build case, list g77 target first so g77 - gets installed. Also, explain that gcc gets built and installed - as well, even though this isn't really what we want (and maybe - we'll find a way around this someday). - -Fri Feb 17 02:35:41 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.7 released. - - * Makefile.in (CONFIG_H, HCONFIG_H, TCONFIG_H, TM_H): Remove - ../ prefix in front of .h files, since they're in the cd. - -Fri Feb 17 01:50:48 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.6 released. - -Thu Feb 16 20:26:54 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * ../README.g77: Remove description of g77 as "not-yet-published". - - * CREDITS: More changes. - - * Make-lang.in (G77STAGESTUFF): Remove cktyps stuff. - - * Makefile.in (CONFIG_H, HCONFIG_H, TCONFIG_H, TM_H): Don't - prefix gcc dir with $(srcdir) since these don't live there, - they are created in the build dir by gcc's configure. Add - a note explaining what these macros are about. - Update dependencies via deps-kinda. - - * README.NEXTSTEP: Credit Toon, and per his request, add his - email address. - - * com.h (FFECOM_DETERMINE_TYPES): #include "config.j". - - * config.j, convert.j, flags.j, hconfig.j, rtl.j, tconfig.j, - tm.j, tree.j: Don't #include if already done. - - * convert.j: #include "tree.j" first, as convert.h clearly depends - on trees being defined. - - * rtl.j: #include "config.j" first, since there's some stuff - in rtl.h that assumes it has been #included. - - * tree.j: #include "config.j" first, or real.h makes inconsistent - decision about return type of ereal_atof, leading to bugs, and - because tree.h/real.h assume config.h already included. - -Wed Feb 15 14:40:20 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.5 released. - - * Copyright notices updated to be FSF-style. - - * INSTALL: Some more clarification regarding building just f77. - - * Make-lang.in (F77_SRCS): Update wrt changing some .h to .j. - (install-libf77): Fix typo in new parenthetical note. - - * Makefile.in (f/*.o): Update. - (CONFIG_H, CONVERT_H, FLAGS_H, GLIMITS_H, HCONFIG_H, RTL_H, - TCONFIG_H, TM_H, TREE_H): Update/new symbols. - (deps-kinda): More fixes wrt changing some .h to .j. - Document and explain this rule a bit better. - Accommodate changes in output of gcc -MM. - - * *.h, *.c: Change #include's so proj.h not assumed to #include - malloc.h or config.h (now config.j), and so new .j files are - used instead of old .h ones. - - * com.c (ffecom_init_0): Use FLOAT_TYPE_SIZE for f2c's - TYLONG/TYLOGICAL type codes, to get g77 working on Alpha. - - * com.h: Make all f2c-related integral types "int", not "long - int". - - * config.j, convert.j, flags.j, glimits.j, hconfig.j, rtl.j, - tconfig.j, tm.j, tree.j: New files wrapping around gbe - .h files. - - * config.h, convert.h, flags.h, glimits.h, hconfig.h, rtl.h, - tconfig.h, tm.h, tree.h: Deleted so new .j files - can #include the gbe files directly, instead of using "../", - and thus do better with various kinds of builds. - - * proj.h: Delete unused NO_STDDEF and related stuff. - -Tue Feb 14 08:28:08 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * BUGS: Remove item #12, cross-compiling & autoconf scripts - reportedly expected to work properly (according to d.love). - - * INSTALL: Add explanation of d.love's patch to config-lang.in. - Add explanation of how to install just g77 when gcc already installed. - Add note about usability of "-Wall". Add note about bug- - reporting. - - * Make-lang.in ($(srcdir)/f/conf-proj): Add comment about why - conf-proj.out. - (install-libf77): Echo parenthetical note to user about how to do - just the (aborted) libf2c installation. - (deps-kinda): Update to work with new configuration/build stuff. - - * bad.c (ffebad_finish): Put capitalized "warning:" &c message - as prefix on any diagnostic without pointers into source. - - * bad.def (FFEBAD_TOO_BIG_INIT): Add this warning message. - - * config-lang.in: Add Dave Love's patch to catch case where - back-end patches not applied and abort configuration. - - * data.c (ffedata_gather_, ffedata_value_): Warn when about - to initialize a large aggregate area, due to design flaw resulting - in too much time/space used to handle such cases. - Use COMMON area name, and first notice of symbol, for multiple- - initialization diagnostic, instead of member symbol and unknown - location. - (FFEDATA_sizeTOO_BIG_INIT_): New macro per above. - -Mon Feb 13 13:54:26 1995 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (F77_SRCS): Use $(srcdir)/f/proj.h.in, not - $(srcdir)/f/proj.h for build outside srcdir. - -Sun Feb 12 13:37:11 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * ../README.g77: Clarify procedures for unpacking, add asterisks - to mark important things the user must do. - - * Fix dates in/add dates to ../README.g77, BUGS, CREDITS, DOC, - INSTALL, PROJECTS, README. - -Sun Feb 12 00:26:10 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.4 released. - - * Make-lang.in (f/proj.h): Reproduce this rule here from - Makefile.in. - ($(srcdir)/f/conf-proj): Put autoconf's stdout in temp file - conf-proj.out, then mv to conf-proj only if successful, so - conf-proj not touched if autoconf not installed. - - * Makefile.in ($(srcdir)/conf-proj): See Make-lang.in's similar - rule. - -Sat Feb 11 20:56:02 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * BUGS: Clarify some bugs. - - * DOC: Many improvements and fixes. - - * README: Move bulk of text, edited, to ../README.g77, and - replace with pointer to that file. - - * com.c (ffecom_init_0): Comment out warning about sizeof(ftnlen) - as per ste.c change. Add text about ASSIGN to help user understand - what is being warned about. - - * conf-proj.in: Fix typos in comments. - - * proj.h.in: Add ARRAY_ZERO_SIZE to parallel malloc.h's version, - in case it proves to be needed. - - * ste.c: Comment out assertions requiring sizeof(ftnlen) >= - sizeof(char *), in the hopes that overflow will never happen. - (ffeste_R838): Change assertion to fatal() with at least - partially helpful message. - -Sat Feb 11 12:38:00 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * com.c (ffecom_vardesc_): Crash if typecode is -1. - - * ste.c (ffeste_io_dolio_): Crash if typecode is -1. - -Sat Feb 11 09:51:57 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * ste.c: In I/O code tests for item arrayness, sort of revert - to much earlier code that tests original exp, but also check - in newer way just in case. Newer way alone treated FOO(1:40) - as an array, not sure why older way alone didn't work, but I - think maybe it was when diagnosed code was involved, and - since there are now checks for error_mark_node, maybe the old - way alone would work. But better to be safe; both original - ffebld exp _and_ the transformed tree must indicate an array - for the size-determination code to be used, else just 1/2 elements - assumed. And this text is for EMACS: (foo at bar). - -Fri Feb 10 11:05:50 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * ste.c: In many cases, surround statement-expansion code - with ffecom_push_calltemps () and ffecom_pop_calltemps () - so COMPLEX-returning functions can have temporaries pushed - in "auto-pop" mode and have them auto-popped at the end of - the statement. - -Wed Feb 8 14:35:10 1995 Dave Love <d.love@dl.ac.uk> - - * runtime/f2c.h.in (ftnlen, ftnint): Make same size as integer. - - * runtime/libI77/err.c (f_init): Thinko in MISSING_FILE_ELEMS - conditional. - * runtime/libI77/wrtfmt.c (mv_cur): Likewise. - * runtime/libI77/wsfe.c (x_putc): Likewise. - - * runtime/libF77/signal_.c (signal_): Return 0 (this is a - subroutine). - - * Makefile.in (f/proj.h): Depend on com.h. - * Make-lang.in (include/f2c.h): Likewise (and proj.h). - (install-libf77): Also install f2c.h. - - * runtime/libI77/Makefile.in (*.o): Add f2c.h dependency. - * runtime/libF77/Makefile.in: Likewise. - -Wed Feb 8 13:56:47 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * stc.c (ffestc_R501_item): Don't reset kind/where to NONE when - setting basictype/kindtype info for symbol, or especially - its function/result twin, because kind/where might not be NONE. - -Tue Feb 7 14:47:26 1995 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in (include/f2c.h:): Set shell variable src more - robustly (independent of whether srcdir is relative or absolute). - * Makefile.in (f/proj.h:): Likewise. - - * conf-proj.in: Check need for LAME_ASSERT. Fix indentation in - check for LAME_STDIO (cosmetic only with ANSI C). - - * com.h: Extra ...SIZE stuff taken from com.c. - - * com.c (FFECOM_DETERMINE_TYPES): Define before including com.h. - (BITS_PER_WORD etc.) Remove and use conditional definitions to com.h. - - * runtime/configure.in: #define FFECOM_DETERMINE_TYPES for com.h in - f2c type determination. - - * tm.h: Remove (at least pro tem) because of relative path and use - top-level one. - - * Make-lang.in (include/f2c.h:): Set shell variable src more - robustly (independent of whether srcdir is relative or absolute). - * Makefile.in (f/proj.h:): Likewise. - -Mon Feb 6 19:58:32 1995 Dave Love <d.love@dl.ac.uk> - - * g77.c (append_arg): Use K&R declaration for, e.g. SunOS4 build. - -Fri Feb 3 20:33:14 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * g77.c (main): Treat -l like filename in terms of -x handling. - Rewrite arglist mechanism for ease of maintenance. - Make sure every -lf2c is followed by -lm and vice versa. - - * Make-lang.in: Put complete list of sources in F77_SRCS def - so changing a .h file, for example, causes rebuild. - - * Makefile.in: Change test for nextstep to m68k-next-nextstep* so - all versions of nextstep on m68k get the necessary flag. - -Fri Feb 3 19:10:32 1995 Dave Love <d.love@dl.ac.uk> - - * INSTALL: Note about possible conflict with existing libf2c.a and - f2c.h. - - * Make-lang.in (f77.distclean): Tidy and move deletion of - f/config.cache to mostlyclean. - (install-libf77): Test for $(libdir)/libf2c.* and barf if found - unless F2CLIBOK defined. - - * runtime/Makefile.in (all): Change path to include directory (and - elsewhere). - (INCLUDES): Remove (unused/misleading). - (distclean): Include f2c.h. - (clean): Include config.cache. - - * runtime/libF77/Makefile.in (.SUFFIXES): Correct typo. - (ALL_CFLAGS) Fix up include search path to find f2c.h in top level - includes always. - (all): Depend on f2c.h. - * runtime/libI77/Makefile.in (.SUFFIXES): Likewise. - -Thu Feb 2 17:17:06 1995 Dave Love <d.love@dl.ac.uk> - - * INSTALL: Note about --srcdir and GNU make. - - * runtime/f2c.h.in (Pad_UDread, ALWAYS_FLUSH): Reomve the #defines - per below. - - * runtime/configure.in (Pad_UDread, ALWAYS_FLUSH): Define these - here, not in f2c.h as they'r eonly relevant for building. - * runtime/configure: Regenerated. - - * config-lang.in: Warn about using GNU make outside source tree - since I can't get Irix5 or SunOS4 makes to work in this case. - - * Makefile.in (VPATH): Don't set it here. - (srcdir): Make it the normal `.' (overridden) at top level. - (all.indirect): New dependency `dircheck'. - (f771): Likewise - (dircheck): New target for foolproofing. - (f/proj.h:): Change finding source. - (CONFIG_H): Don't use this as the relative path in the include loses - f builddir != srcdir. - - * config.h: Remove per CONFIG_H change above. - - * Make-lang.in (F77_FLAGS_TO_PASS): Remove GCC_FOR_TARGET. - (f771:): Pass VPATH, srcdir to sub-make. - (f/Makefile:): New target. - (stmp-int-hdrs): new variable for cheating build. - (f77-runtime:): Alter GCC_FOR_TARGET treatment. - (include/f2c.h f/runtime/Makefile:) Likewise. - (f77-runtime-unsafe:): New (cheating) target. - -Thu Feb 2 12:09:51 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * BUGS: Update regarding losing EQUIVALENCE members in -g, and - regarding RS/6000 problems in the back end. - - * CREDITS: Make some changes as requested. - - * com.c (ffecom_member_trunk_): Remove unused static variable. - (ffecom_finish_symbol_transform_): Improve comments. - (ffecom_let_char_): Fix size of temp address-type var. - (ffecom_member_phase2_): Try fixing problem fixed by change - to ffecom_transform_equiv_ (f_m_p2_ function currently not used). - (ffecom_transform_equiv_): Remove def of unused static variable. - Comment-out use of ffecom_member_phase2_, until problems with - back end fixed. - (ffecom_push_tempvar): Fix assertion to not crash okay code. - - * com.h: Remove old, commented-out code. - Add prototype for warning() in back end. - - * ste.c (ffeste_io_dofio_, ffeste_io_dolio_, ffeste_io_douio_, - ffeste_io_icilist_): Check correct type of variable for arrayness. - -Sun Jan 29 14:41:42 1995 Dave Love <d.love@dl.ac.uk> - - * BUGS: Remove references to my configure bugs; add another. - - * runtime/Makefile.in (AR_FLAGS): Provide default value. - - * runtime/f2c.h.in (integer, logical): Take typedefs from - F2C_INTEGER configuration parameter again. - (NON_UNIX_STDIO): don't define it. - - * runtime/configure.in: Bring type checks for f2c.h in line with - com.h. - (MISSING_FILE_ELEMS): New variable to determine whether the relevant - elements of the FILE struct exist, independent of NON_UNIX_STDIO. - * runtime/libI77/{err,wrtfmt,wsfe}.c (MISSING_FILE_ELEMS): Use new - parameter. - - * config-lang.in: Comment out more of f2c rules (c.f. Make-lang.in). - (This stuff is relevant iff you gave configure --enable-f2c.) - Create f/runtime directory tree iff not building in source - directory. - - * Makefile.in (srcdir): Append slash so we get the right value when - not building in the source directory. This is a consequence of not - building the `f' sources in `f'. - (VPATH): Override configure's value for reasons above. - (f/proj.h f/conf-proj): New rules to build proj.h by - autoconfiguration. - - * proj.h: Rename to proj.h.in for autoconfiguration. - * proj.h.in: New as above. - * conf-proj conf-proj.in: New files for autoconfiguration. - - * Make-lang.in (include/f2c.h f/runtime/Makefile:): Change the order - of setting the sh variables so that the right GCC_FOR_TARGET is - used. - (f77.*clean:) Add products of new configuration files and make sure - all the *clean targets do something (unlike the ones in - cp/Make-lange.in). - - * com.h (FFECOM_f2cINTEGER, FFECOM_f2cLOGICAL): Define as long or - int appropriately to ensure sizeof(real) == sizeof(integer). - - * PROJECTS: Library section. - - * runtime/libI77/endfile.c: Don't #include sys/types.h conditional - on NON_UNIX_STDIO since rawio.h needs size_t. - * runtime/libI77/uio.c: #include <sys/types.h> for size_t if not - KR_headers. - -Wed Jan 25 03:31:51 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.3 released. - - * INSTALL: Revise. - - * Make-lang.in: Comment out rules for building f2c itself (f/f2c/). - - * README: Revise. - - * com.c (ffecom_init_0): Warn if ftnlen or INTEGER not big enough - to hold a char *. - - * gbe/2.6.2.diff: Update. - -Mon Jan 23 17:10:49 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * TODO: Remove. - BUGS: New file. - PROJECTS: New file. - CREDITS: New file. - - * cktyps*: Remove. - Make-lang.in: Remove cktyps stuff. - Makefile.in: Remove cktyps stuff. - - * DOC: Add info on changes for 0.5.3. - - * bad.c: Put "warning:" &c on diagnostic messages. - Don't output informational messages if warnings disabled. - -Thu Jan 19 12:38:13 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * g77.c: Avoid putting out useless "-xnone -xf77" pairs so - larger command lines can be accommodated. - Recognize both `-xlang' and `-x lang'. - Recognize `-xnone' and `-x none' to mean what it does, instead - of treating "none" as any other language. - Some minor, slight improvements in the way args are handled - (hopefully for clearer, more maintainable code), including - consistency checks on arg count just in case. - -Wed Jan 18 16:41:57 1995 Craig Burley (burley@gnu.ai.mit.edu) - - * DOC: Explain -fautomatic better. - - * INSTALL: Describe libf2c.a better. - - * Make-lang.in, Makefile.in: Build f771 &c with gcc/ as cd instead - of gcc/f/ so debugging info is better (source file tracking). - Add new source file type.c. - - * Makefile.in: For nextstep3, link f771 with -segaddr __DATA - 6000000. Fix typo. Change deps-kinda target to handle building - from gcc/. Update dependencies. - - * bld-op.def, bld.h, bld.c: Remove opBACKEND and all related - stuff. - Remove consistency tests that cause compiler warnings. - - * cktyps.c: Remove all typing checking. - - * com-rt.def: Change all rttypeFLOAT_ intrinsics to rttypeDOUBLE_, - to precisely match how they're declared in libf2c. - - * com.h, com.c: Revise to more elegantly track related stuff - in the version of f2c.h used to build libf2c. - - * com.c: Increase FFECOM_sizeMAXSTACKITEM, and if 0 or undefined - when checked to determine where to put entity, treat as infinite. - Rewrite temporary mechanism to be based on trees instead of - ffeinfo stuff, and make it much simpler. Change interface - accordingly. - Fixes to better track types of things, make appropriate - conversions, etc. E.g. when making an arg for a libf2c - function, make sure it's of the right type (such as ftnlen). - Delete opBACKEND transformation code. - (ffecom_init_0): Smoother initialization of types, especially - paying attention to using consistent rules for making INTEGER, - REAL, DOUBLE PRECISION, etc., and for deciding their "*N" - and kind values that will work across all g77 platforms. - No longer require per-target configuration info in target.h - or config/*/*; use new type module to store size, alignment. - (ffecom_member_phase2): Declare COMMON/EQUIVALENCE group members - so debugger sees them. - (ffecom_finish_progunit): Transform all symbols in program unit, - so -g will show they all exist. - - * expr.c (ffeexpr_collapse_substr): Handle strange substring - range values. - - * info.h, info.c: Provide connection to new type module. - Remove tests that yield compiler warnings. - - * intrin.c (ffeintrin_is_intrinsic): Properly handle deleted - intrinsic. - - * lex.c (ffelex_file_fixed): Remove redundant/buggy code. - - * stc.c (ffestc_kindtype_kind_, ffestc_kindtype_star_): Replace - boring switch stmt with simple call to new type module. This - sort of thing is a reason to get up in the morning. - - * ste.c: Update to handle new interface for - ffecom_push/pop_tempvar. - Fixes to better track types of things. - Fixes to not crash for certain diagnosed constructs. - (ffeste_begin_iterdo_): Check only constants for overflow to avoid - spurious diagnostics. - Don't convert larger integer (say, INTEGER*8) to canonical integer - for iteration count. - - * stw.h: Track DO iteration count temporary variable. - - * symbol.c: Remove consistency tests that cause compiler warnings. - - * target.c (ffetarget_aggregate_info): Replace big switch with - little call to new type module. - (ffetarget_layout): Remove consistency tests that cause - compiler warnings. - (ffetarget_convert_character1_typeless): Pick up length of - typeless type from new type module. - - * target.h: Crash build if target float bit pattern cannot be - precisely determined. - Remove all the type cruft now determined by ffecom_init_0 - at invocation time and maintained in new type module. - Put casts on second arg of all REAL_VALUE_TO_TARGET_DOUBLE - uses so compiler warnings avoided (requires target float bit - pattern to be precisely determined, hence code to crash build). - - * top.c: Add inits/terminates for new type module. - - * type.h, type.c: New module. - - * gbe/2.6.2.diff: Remove all patches to files in gcc/config/ - directory and its subdirectories. - -Mon Jan 9 19:23:25 1995 Dave Love <d.love@dl.ac.uk> - - * com.h (FFECOM_F2C_INTEGER_TYPE_NODE): Define and use instead of - long_integer_type_node where appropriate. - -Tue Jan 3 14:56:18 1995 Dave Love <d.love@dl.ac.uk> - - * com.h: Make ffecom_f2c_logical_type_node long, consistent with - integer. - -Fri Dec 2 20:07:37 1994 Dave Love <d.love@dl.ac.uk> - - * config-lang.in (stagestuff): Add f2c conditionally. - * Make-lang.in: Add f2c and related targets. - * f2c: Add the directory. - -Fri Nov 25 22:17:26 1994 Dave Love <d.love@dl.ac.uk> - - * Makefile.in (FLAGS_TO_PASS): pass $(CROSS) - * Make-lang.in: more changes to runtime targets - -Thu Nov 24 18:03:21 1994 Dave Love <d.love@dl.ac.uk> - - * Makefile.in (FLAGS_TO_PASS): define for sub-makes - - * g77.c (main): change f77-cpp-output to f77-cpp-input (.F files) - -Wed Nov 23 15:22:53 1994 Dave Love <d.love@dl.ac.uk> - - * bad.c (ffebad_finish): kluge to fool emacs19 into finding errors: - add trailing space to <file>:<line>: - -Tue Nov 22 11:30:50 1994 Dave Love <d.love@dl.ac.uk> - - * runtime/libF77/signal_.c (RETSIGTYPE): added - -Mon Nov 21 13:04:13 1994 Dave Love <d.love@dl.ac.uk> - - * Makefile.in (compiler): add runtime - - * config-lang.in (stagestuff): add libf2c.a to stagestuff - - * Make-lang.in: - G77STAGESTUFF <- MORESTAGESTUFF - f77-runtime: new target, plus supporting ones - - * runtime: add the directory, containing libI77, libF77 and autoconf - stuff - - * g++.1: remove - - * g77.1: minor fixes - -Thu Nov 17 15:18:05 1994 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.2 released. - - * bad.def: Modify wording of FFEBAD_UNIMPL_STMT to indicate - that it covers a wide array of possible problems (that, someday, - should be handled via separate diagnostics). - - * lex.c: Allow $ in identifiers if -fdollar-ok. - * top.c: Support -fdollar-ok. - * top.h: Support -fdollar-ok. - * target.h: Support -fdollar-ok. - * DOC: Describe -fdollar-ok. - - * std.c (ffestd_R1229_finish): Fix bug so stand-alone build works. - * ste.c (ffeste_R819A): Fix bug so stand-alone build works. - - * Make: Improvements for stand-alone build. - - * Makefile.in: Fix copyright text at top of file. - - * LINK, SRCS, UNLINK: Removed. Not particularly useful now that - g77 sources live in their own subdirectory. - - * g77.c (main): Cast arg to bzero to avoid warning. (This is - identical to Kenner's fix to cp/g++.c.) - - * gbe/: New subdirectory, to contain .diff files for various - versions of the GNU CC back end. - - * gbe/README: New file. - * gbe/2.6.2.diff: New file. - -Tue Nov 8 10:23:10 1994 Dave Love <d.love@dl.ac.uk> - - * Make-lang.in: don't install as f77 as well as g77 to avoid - confusion with system's compiler (especially while testing) - - * g77.c (main): use -lf2c and -lm; fix sense of test for .f/.F files - -Fri Oct 28 09:45:00 1994 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.1 released. - - * gcc.c: Invoke f771 instead of f-771. - -Fri Oct 28 02:00:44 1994 Craig Burley (burley@gnu.ai.mit.edu) - - * Version 0.5.0 released. - -Fri Oct 14 15:03:35 1994 Craig Burley (burley@gnu.ai.mit.edu) - - * Makefile.in: Handle the Fortran-77 front-end in a subdirectory. - * f-*: Move Fortran-77 front-end to f/*. diff --git a/gcc/f/ChangeLog.Cygnus b/gcc/f/ChangeLog.Cygnus deleted file mode 100755 index e69de29..0000000 --- a/gcc/f/ChangeLog.Cygnus +++ /dev/null diff --git a/gcc/f/INSTALL b/gcc/f/INSTALL deleted file mode 100755 index 1ff51d7..0000000 --- a/gcc/f/INSTALL +++ /dev/null @@ -1,1558 +0,0 @@ -This file contains installation information for the GNU Fortran -compiler. Copyright (C) 1995, 1996 Free Software Foundation, Inc. You -may copy, distribute, and modify it freely as long as you preserve this -copyright notice and permission notice. - -Installing GNU Fortran -********************** - - The following information describes how to install `g77'. - - Note that, for `egcs' users, much of this information is obsolete, -and is superceded by the `egcs' installation procedures. Such -information is explicitly flagged as such. - - The information in this file generally pertains to dealing with -*source* distributions of `g77' and `gcc'. It is possible that some of -this information will be applicable to some *binary* distributions of -these products--however, since these distributions are not made by the -maintainers of `g77', responsibility for binary distributions rests with -whoever built and first distributed them. - - Nevertheless, efforts to make `g77' easier to both build and install -from source and package up as a binary distribution are ongoing. - -Prerequisites -============= - - *Version info:* For `egcs' users, the following information is -superceded by the `egcs' installation instructions. - - The procedures described to unpack, configure, build, and install -`g77' assume your system has certain programs already installed. - - The following prerequisites should be met by your system before you -follow the `g77' installation instructions: - -`gzip' and `tar' - To unpack the `gcc' and `g77' distributions, you'll need the - `gunzip' utility in the `gzip' distribution. Most UNIX systems - already have `gzip' installed. If yours doesn't, you can get it - from the FSF. - - Note that you'll need `tar' and other utilities as well, but all - UNIX systems have these. There are GNU versions of all these - available--in fact, a complete GNU UNIX system can be put together - on most systems, if desired. - - The version of GNU `gzip' used to package this release is - 1.2.4. (The version of GNU `tar' used to package this release is - 1.12.) - -`gcc-2.8.1.tar.gz' - You need to have this, or some other applicable, version of `gcc' - on your system. The version should be an exact copy of a - distribution from the FSF. Its size is approximately 8.4MB. - - If you've already unpacked `gcc-2.8.1.tar.gz' into a directory - (named `gcc-2.8.1') called the "source tree" for `gcc', you can - delete the distribution itself, but you'll need to remember to - skip any instructions to unpack this distribution. - - Without an applicable `gcc' source tree, you cannot build `g77'. - You can obtain an FSF distribution of `gcc' from the FSF. - -`g77-0.5.24.tar.gz' - You probably have already unpacked this package, or you are - reading an advance copy of these installation instructions, which - are contained in this distribution. The size of this package is - approximately 1.4MB. - - You can obtain an FSF distribution of `g77' from the FSF, the same - way you obtained `gcc'. - -Enough disk space - The amount of disk space needed to unpack, build, install, and use - `g77' depends on the type of system you're using, how you build - `g77', and how much of it you install (primarily, which languages - you install). - - The sizes shown below assume all languages distributed in - `gcc-2.8.1', plus `g77', will be built and installed. These sizes - are indicative of GNU/Linux systems on Intel x86 running COFF and - on Digital Alpha (AXP) systems running ELF. These should be - fairly representative of 32-bit and 64-bit systems, respectively. - - Note that all sizes are approximate and subject to change without - notice! They are based on preliminary releases of g77 made shortly - before the public beta release. - - -- `gcc' and `g77' distributions occupy 10MB packed, 40MB - unpacked. These consist of the source code and documentation, - plus some derived files (mostly documentation), for `gcc' and - `g77'. Any deviations from these numbers for different kinds - of systems are likely to be very minor. - - -- A "bootstrap" build requires an additional 91MB for a total - of 132MB on an ix86, and an additional 136MB for a total of - 177MB on an Alpha. - - -- Removing `gcc/stage1' after the build recovers 13MB for a - total of 119MB on an ix86, and recovers 21MB for a total of - 155MB on an Alpha. - - After doing this, the integrity of the build can still be - verified via `make compare', and the `gcc' compiler modified - and used to build itself for testing fairly quickly, using - the copy of the compiler kept in `gcc/stage2'. - - -- Removing `gcc/stage2' after the build further recovers 39MB - for a total of 80MB, and recovers 57MB for a total of 98MB on - an Alpha. - - After doing this, the compiler can still be installed, - especially if GNU `make' is used to avoid gratuitous rebuilds - (or, the installation can be done by hand). - - -- Installing `gcc' and `g77' copies 23MB onto the `--prefix' - disk for a total of 103MB on an ix86, and copies 31MB onto - the `--prefix' disk for a total of 130MB on an Alpha. - - After installation, if no further modifications and builds of - `gcc' or `g77' are planned, the source and build directory may be - removed, leaving the total impact on a system's disk storage as - that of the amount copied during installation. - - Systems with the appropriate version of `gcc' installed don't - require the complete bootstrap build. Doing a "straight build" - requires about as much space as does a bootstrap build followed by - removing both the `gcc/stage1' and `gcc/stage2' directories. - - Installing `gcc' and `g77' over existing versions might require - less *new* disk space, but note that, unlike many products, `gcc' - installs itself in a way that avoids overwriting other installed - versions of itself, so that other versions may easily be invoked - (via `gcc -V VERSION'). - - So, the amount of space saved as a result of having an existing - version of `gcc' and `g77' already installed is not - much--typically only the command drivers (`gcc', `g77', `g++', and - so on, which are small) and the documentation is overwritten by - the new installation. The rest of the new installation is done - without replacing existing installed versions (assuming they have - different version numbers). - -`make' - Your system must have `make', and you will probably save yourself - a lot of trouble if it is GNU `make' (sometimes referred to as - `gmake'). In particular, you probably need GNU `make' to build - outside the source directory (with `configure''s `--srcdir' - option.) - - The version of GNU `make' used to develop this release is - 3.76.1. - -`cc' - Your system must have a working C compiler. If it doesn't, you - might be able to obtain a prebuilt binary of some version of `gcc' - from the network or on CD-ROM, perhaps from the FSF. The best - source of information about binaries is probably a system-specific - Usenet news group, initially via its FAQ. - - *Note Installing GNU CC: (gcc)Installation, for more information - on prerequisites for installing `gcc'. - -`sed' - All UNIX systems have `sed', but some have a broken version that - cannot handle configuring, building, or installing `gcc' or `g77'. - - The version of GNU `sed' used to develop this release is - 2.05. (Note that GNU `sed' version 3.0 was withdrawn by the - FSF--if you happen to have this version installed, replace it with - version 2.05 immediately. See a GNU distribution site for further - explanation.) - -`root' access or equivalent - To perform the complete installation procedures on a system, you - need to have `root' access to that system, or equivalent access to - the `--prefix' directory tree specified on the `configure' command - line. - - Portions of the procedure (such as configuring and building `g77') - can be performed by any user with enough disk space and virtual - memory. - - However, these instructions are oriented towards less-experienced - users who want to install `g77' on their own personal systems. - - System administrators with more experience will want to determine - for themselves how they want to modify the procedures described - below to suit the needs of their installation. - -`autoconf' - The version of GNU `autoconf' used to develop this release is - 2.12. - - `autoconf' is not needed in the typical case of installing `gcc' - and `g77'. *Note Missing tools?::, for information on when it - might be needed and how to work around not having it. - -`bison' - The version of GNU `bison' used to develop this release is - 1.25. - - `bison' is not needed in the typical case of installing `gcc' and - `g77'. *Note Missing tools?::, for information on when it might - be needed and how to work around not having it. - -`gperf' - The version of GNU `gperf' used to develop this release is - 2.5. - - `gperf' is not needed in the typical case of installing `gcc' and - `g77'. *Note Missing tools?::, for information on when it might - be needed and how to work around not having it. - -`makeinfo' - The version of GNU `makeinfo' used to develop this release is - 1.68. - - `makeinfo' is part of the GNU `texinfo' package; `makeinfo' - version 1.68 is distributed as part of GNU `texinfo' version - 3.12. - - `makeinfo' is not needed in the typical case of installing `gcc' - and `g77'. *Note Missing tools?::, for information on when it - might be needed and how to work around not having it. - - An up-to-date version of GNU `makeinfo' is still convenient when - obtaining a new version of a GNU distribution such as `gcc' or - `g77', as it allows you to obtain the `.diff.gz' file instead of - the entire `.tar.gz' distribution (assuming you have installed - `patch'). - -`patch' - The version of GNU `patch' used to develop this release is - 2.5. - - Beginning with `g77' version 0.5.23, it is no longer necessary to - patch the `gcc' back end to build `g77'. - - An up-to-date version of GNU `patch' is still convenient when - obtaining a new version of a GNU distribution such as `gcc' or - `g77', as it allows you to obtain the `.diff.gz' file instead of - the entire `.tar.gz' distribution (assuming you have installed the - tools needed to rebuild derived files, such as `makeinfo'). - -Problems Installing -=================== - - This is a list of problems (and some apparent problems which don't -really mean anything is wrong) that show up when configuring, building, -installing, or porting GNU Fortran. - - *Note Installation Problems: (gcc)Installation Problems, for more -information on installation problems that can afflict either `gcc' or -`g77'. - -General Problems ----------------- - - These problems can occur on most or all systems. - -GNU C Required -.............. - - Compiling `g77' requires GNU C, not just ANSI C. Fixing this -wouldn't be very hard (just tedious), but the code using GNU extensions -to the C language is expected to be rewritten for 0.6 anyway, so there -are no plans for an interim fix. - - This requirement does not mean you must already have `gcc' installed -to build `g77'. As long as you have a working C compiler, you can use a -bootstrap build to automate the process of first building `gcc' using -the working C compiler you have, then building `g77' and rebuilding -`gcc' using that just-built `gcc', and so on. - -Patching GNU CC -............... - - `g77' no longer requires application of a patch file to the `gcc' -compiler tree. In fact, no such patch file is distributed with `g77'. -This is as of version 0.5.23 and `egcs' version 1.0. - -Building GNU CC Necessary -......................... - - It should be possible to build the runtime without building `cc1' -and other non-Fortran items, but, for now, an easy way to do that is -not yet established. - -Missing strtoul or bsearch -.......................... - - *Version info:* The following information does not apply to the -`egcs' version of `g77'. - - On SunOS4 systems, linking the `f771' program used to produce an -error message concerning an undefined symbol named `_strtoul', because -the `strtoul' library function is not provided on that system. - - Other systems have, in the past, been reported to not provide their -own `strtoul' or `bsearch' function. - - Some versions `g77' tried to default to providing bare-bones -versions of `bsearch' and `strtoul' automatically, but every attempt at -this has failed for at least one kind of system. - - To limit the failures to those few systems actually missing the -required routines, the bare-bones versions are still provided, in -`gcc/f/proj.c', if the appropriate macros are defined. These are -`NEED_BSEARCH' for `bsearch' and `NEED_STRTOUL' for `NEED_STRTOUL'. - - Therefore, if you are sure your system is missing `bsearch' or -`strtoul' in its library, define the relevant macro(s) before building -`g77'. This can be done by editing `gcc/f/proj.c' and inserting either -or both of the following `#define' statements before the comment shown: - - /* Insert #define statements here. */ - - #define NEED_BSEARCH - #define NEED_STRTOUL - - Then, continue configuring and building `g77' as usual. - - Or, you can define these on the `make' command line. To build with -the bundled `cc' on SunOS4, for example, try: - make bootstrap BOOT_CFLAGS='-O2 -g -DNEED_STRTOUL' - - If you then encounter problems compiling `gcc/f/proj.c', it might be -due to a discrepancy between how `bsearch' or `strtoul' are defined by -that file and how they're declared by your system's header files. - - In that case, you'll have to use some basic knowledge of C to work -around the problem, perhaps by editing `gcc/f/proj.c' somewhat. - -Cleanup Kills Stage Directories -............................... - - It'd be helpful if `g77''s `Makefile.in' or `Make-lang.in' would -create the various `stageN' directories and their subdirectories, so -developers and expert installers wouldn't have to reconfigure after -cleaning up. - - That help has arrived as of version 0.5.23 of `g77' and version 1.1 -of `egcs'. Configuration itself no longer creates any particular -directories that are unique to `g77'. The build procedures in -`Make-lang.in' take care of that, on demand. - -LANGUAGES Macro Ignored -....................... - - Prior to version 0.5.23 of `g77' and version 1.1 of `egcs', `g77' -would sometimes ignore the absence of `f77' and `F77' in the -`LANGUAGES' macro definition used for the `make' command being -processed. - - As of `g77' version 0.5.23 and `egcs' version 1.1, `g77' now obeys -this macro in all relevant situations. - - However, in versions of `gcc' through 2.8.1, non-`g77' portions of -`gcc', such as `g++', are known to go ahead and perform various -language-specific activities when their respective language strings do -not appear in the `LANGUAGES' macro in effect during that invocation of -`make'. - - It is expected that these remaining problems will be fixed in a -future version of `gcc'. - -System-specific Problems ------------------------- - - A linker bug on some versions of AIX 4.1 might prevent building when -`g77' is built within `gcc'. It might also occur when building within -`egcs'. *Note LINKFAIL::. - -Cross-compiler Problems ------------------------ - - `g77' has been in alpha testing since September of 1992, and in -public beta testing since February of 1995. Alpha testing was done by -a small number of people worldwide on a fairly wide variety of -machines, involving self-compilation in most or all cases. Beta -testing has been done primarily via self-compilation, but in more and -more cases, cross-compilation (and "criss-cross compilation", where a -version of a compiler is built on one machine to run on a second and -generate code that runs on a third) has been tried and has succeeded, -to varying extents. - - Generally, `g77' can be ported to any configuration to which `gcc', -`f2c', and `libf2c' can be ported and made to work together, aside from -the known problems described in this manual. If you want to port `g77' -to a particular configuration, you should first make sure `gcc' and -`libf2c' can be ported to that configuration before focusing on `g77', -because `g77' is so dependent on them. - - Even for cases where `gcc' and `libf2c' work, you might run into -problems with cross-compilation on certain machines, for several -reasons. - - * There is one known bug (a design bug to be fixed in 0.6) that - prevents configuration of `g77' as a cross-compiler in some cases, - though there are assumptions made during configuration that - probably make doing non-self-hosting builds a hassle, requiring - manual intervention. - - * `gcc' might still have some trouble being configured for certain - combinations of machines. For example, it might not know how to - handle floating-point constants. - - * Improvements to the way `libg2c' is built could make building - `g77' as a cross-compiler easier--for example, passing and using - `$(LD)' and `$(AR)' in the appropriate ways. (This is improved in - the `egcs' version of `g77', especially as of version 1.1.) - - * There are still some challenges putting together the right - run-time libraries (needed by `libg2c') for a target system, - depending on the systems involved in the configuration. (This is - a general problem with cross-compilation, and with `gcc' in - particular.) - -Changing Settings Before Building -================================= - - Here are some internal `g77' settings that can be changed by editing -source files in `gcc/f/' before building. - - This information, and perhaps even these settings, represent -stop-gap solutions to problems people doing various ports of `g77' have -encountered. As such, none of the following information is expected to -be pertinent in future versions of `g77'. - -Larger File Unit Numbers ------------------------- - - As distributed, whether as part of `f2c' or `g77', `libf2c' accepts -file unit numbers only in the range 0 through 99. For example, a -statement such as `WRITE (UNIT=100)' causes a run-time crash in -`libf2c', because the unit number, 100, is out of range. - - If you know that Fortran programs at your installation require the -use of unit numbers higher than 99, you can change the value of the -`MXUNIT' macro, which represents the maximum unit number, to an -appropriately higher value. - - To do this, edit the file `f/runtime/libI77/fio.h' in your `g77' -source tree, changing the following line: - - #define MXUNIT 100 - - Change the line so that the value of `MXUNIT' is defined to be at -least one *greater* than the maximum unit number used by the Fortran -programs on your system. - - (For example, a program that does `WRITE (UNIT=255)' would require -`MXUNIT' set to at least 256 to avoid crashing.) - - Then build or rebuild `g77' as appropriate. - - *Note:* Changing this macro has *no* effect on other limits your -system might place on the number of files open at the same time. That -is, the macro might allow a program to do `WRITE (UNIT=100)', but the -library and operating system underlying `libf2c' might disallow it if -many other files have already been opened (via `OPEN' or implicitly via -`READ', `WRITE', and so on). Information on how to increase these -other limits should be found in your system's documentation. - -Always Flush Output -------------------- - - Some Fortran programs require output (writes) to be flushed to the -operating system (under UNIX, via the `fflush()' library call) so that -errors, such as disk full, are immediately flagged via the relevant -`ERR=' and `IOSTAT=' mechanism, instead of such errors being flagged -later as subsequent writes occur, forcing the previously written data -to disk, or when the file is closed. - - Essentially, the difference can be viewed as synchronous error -reporting (immediate flagging of errors during writes) versus -asynchronous, or, more precisely, buffered error reporting (detection -of errors might be delayed). - - `libg2c' supports flagging write errors immediately when it is built -with the `ALWAYS_FLUSH' macro defined. This results in a `libg2c' that -runs slower, sometimes quite a bit slower, under certain -circumstances--for example, accessing files via the networked file -system NFS--but the effect can be more reliable, robust file I/O. - - If you know that Fortran programs requiring this level of precision -of error reporting are to be compiled using the version of `g77' you -are building, you might wish to modify the `g77' source tree so that -the version of `libg2c' is built with the `ALWAYS_FLUSH' macro defined, -enabling this behavior. - - To do this, find this line in `f/runtime/f2c.h' in your `g77' source -tree: - - /* #define ALWAYS_FLUSH */ - - Remove the leading `/* ', so the line begins with `#define', and the -trailing ` */'. - - Then build or rebuild `g77' as appropriate. - -Maximum Stackable Size ----------------------- - - `g77', on most machines, puts many variables and arrays on the stack -where possible, and can be configured (by changing -`FFECOM_sizeMAXSTACKITEM' in `gcc/f/com.c') to force smaller-sized -entities into static storage (saving on stack space) or permit -larger-sized entities to be put on the stack (which can improve -run-time performance, as it presents more opportunities for the GBE to -optimize the generated code). - - *Note:* Putting more variables and arrays on the stack might cause -problems due to system-dependent limits on stack size. Also, the value -of `FFECOM_sizeMAXSTACKITEM' has no effect on automatic variables and -arrays. *Note But-bugs::, for more information. - -Floating-point Bit Patterns ---------------------------- - - The `g77' build will crash if an attempt is made to build it as a -cross-compiler for a target when `g77' cannot reliably determine the -bit pattern of floating-point constants for the target. Planned -improvements for version 0.6 of `g77' will give it the capabilities it -needs to not have to crash the build but rather generate correct code -for the target. (Currently, `g77' would generate bad code under such -circumstances if it didn't crash during the build, e.g. when compiling -a source file that does something like `EQUIVALENCE (I,R)' and `DATA -R/9.43578/'.) - -Initialization of Large Aggregate Areas ---------------------------------------- - - A warning message is issued when `g77' sees code that provides -initial values (e.g. via `DATA') to an aggregate area (`COMMON' or -`EQUIVALENCE', or even a large enough array or `CHARACTER' variable) -that is large enough to increase `g77''s compile time by roughly a -factor of 10. - - This size currently is quite small, since `g77' currently has a -known bug requiring too much memory and time to handle such cases. In -`gcc/f/data.c', the macro `FFEDATA_sizeTOO_BIG_INIT_' is defined to the -minimum size for the warning to appear. The size is specified in -storage units, which can be bytes, words, or whatever, on a -case-by-case basis. - - After changing this macro definition, you must (of course) rebuild -and reinstall `g77' for the change to take effect. - - Note that, as of version 0.5.18, improvements have reduced the scope -of the problem for *sparse* initialization of large arrays, especially -those with large, contiguous uninitialized areas. However, the warning -is issued at a point prior to when `g77' knows whether the -initialization is sparse, and delaying the warning could mean it is -produced too late to be helpful. - - Therefore, the macro definition should not be adjusted to reflect -sparse cases. Instead, adjust it to generate the warning when densely -initialized arrays begin to cause responses noticeably slower than -linear performance would suggest. - -Alpha Problems Fixed --------------------- - - `g77' used to warn when it was used to compile Fortran code for a -target configuration that is not basically a 32-bit machine (such as an -Alpha, which is a 64-bit machine, especially if it has a 64-bit -operating system running on it). That was because `g77' was known to -not work properly on such configurations. - - As of version 0.5.20, `g77' is believed to work well enough on such -systems. So, the warning is no longer needed or provided. - - However, support for 64-bit systems, especially in areas such as -cross-compilation and handling of intrinsics, is still incomplete. The -symptoms are believed to be compile-time diagnostics rather than the -generation of bad code. It is hoped that version 0.6 will completely -support 64-bit systems. - -Quick Start -=========== - - *Version info:* For `egcs' users, the following information is -superceded by the `egcs' installation instructions. - - This procedure configures, builds, and installs `g77' "out of the -box" and works on most UNIX systems. Each command is identified by a -unique number, used in the explanatory text that follows. For the most -part, the output of each command is not shown, though indications of -the types of responses are given in a few cases. - - To perform this procedure, the installer must be logged in as user -`root'. Much of it can be done while not logged in as `root', and -users experienced with UNIX administration should be able to modify the -procedure properly to do so. - - Following traditional UNIX conventions, it is assumed that the -source trees for `g77' and `gcc' will be placed in `/usr/src'. It also -is assumed that the source distributions themselves already reside in -`/usr/FSF', a naming convention used by the author of `g77' on his own -system: - - /usr/FSF/gcc-2.8.1.tar.gz - /usr/FSF/g77-0.5.24.tar.gz - - If you vary *any* of the steps below, you might run into trouble, -including possibly breaking existing programs for other users of your -system. Before doing so, it is wise to review the explanations of some -of the steps. These explanations follow this list of steps. - - sh[ 1]# cd /usr/src - - sh[ 2]# gunzip -c < /usr/FSF/gcc-2.8.1.tar.gz | tar xf - - [Might say "Broken pipe"...that is normal on some systems.] - - sh[ 3]# gunzip -c < /usr/FSF/g77-0.5.24.tar.gz | tar xf - - ["Broken pipe" again possible.] - - sh[ 4]# ln -s gcc-2.8.1 gcc - - sh[ 5]# ln -s g77-0.5.24 g77 - - sh[ 6]# mv -i g77/* gcc - [No questions should be asked by mv here; or, you made a mistake.] - - sh[ 7]# cd gcc - sh[ 8]# ./configure --prefix=/usr - [Do not do the above if gcc is not installed in /usr/bin. - You might need a different --prefix=..., as - described below.] - - sh[ 9]# make bootstrap - [This takes a long time, and is where most problems occur.] - - sh[10]# make compare - [This verifies that the compiler is `sane'. - If any files are printed, you have likely found a g77 bug.] - - sh[11]# rm -fr stage1 - - sh[12]# make -k install - [The actual installation.] - - sh[13]# g77 -v - [Verify that g77 is installed, obtain version info.] - - sh[14]# - - *Note Updating Your Info Directory: Updating Documentation, for -information on how to update your system's top-level `info' directory -to contain a reference to this manual, so that users of `g77' can -easily find documentation instead of having to ask you for it. - - Elaborations of many of the above steps follows: - -Step 1: `cd /usr/src' - You can build `g77' pretty much anyplace. By convention, this - manual assumes `/usr/src'. It might be helpful if other users on - your system knew where to look for the source code for the - installed version of `g77' and `gcc' in any case. - -Step 3: `gunzip -d < /usr/FSF/g77-0.5.24.tar.gz | tar xf -' - It is not always necessary to obtain the latest version of `g77' - as a complete `.tar.gz' file if you have a complete, earlier - distribution of `g77'. If appropriate, you can unpack that earlier - version of `g77', and then apply the appropriate patches to - achieve the same result--a source tree containing version - 0.5.24 of `g77'. - -Step 4: `ln -s gcc-2.8.1 gcc' - -Step 5: `ln -s g77-0.5.24 g77' - These commands mainly help reduce typing, and help reduce visual - clutter in examples in this manual showing what to type to install - `g77'. - - *Note Unpacking::, for information on using distributions of `g77' - made by organizations other than the FSF. - -Step 6: `mv -i g77/* gcc' - After doing this, you can, if you like, type `rm g77' and `rmdir - g77-0.5.24' to remove the empty directory and the symbol link to - it. But, it might be helpful to leave them around as quick - reminders of which version(s) of `g77' are installed on your - system. - - *Note Unpacking::, for information on the contents of the `g77' - directory (as merged into the `gcc' directory). - -Step 8: `./configure --prefix=/usr' - This is where you specify that the `g77' and `gcc' executables are - to be installed in `/usr/bin/', the `g77' and `gcc' documentation - is to be installed in `/usr/info/' and `/usr/man/', and so on. - - You should ensure that any existing installation of the `gcc' - executable is in `/usr/bin/'. - - However, if that existing version of `gcc' is not 2.8.1, or if you - simply wish to avoid risking overwriting it with a newly built - copy of the same version, you can specify `--prefix=/usr/local' - (which is the default) or some other path, and invoke the newly - installed version directly from that path's `bin' directory. - - *Note Where in the World Does Fortran (and GNU CC) Go?: Where to - Install, for more information on determining where to install - `g77'. *Note Configuring gcc::, for more information on the - configuration process triggered by invoking the `./configure' - script. - -Step 9: `make bootstrap' - *Note Installing GNU CC: (gcc)Installation, for information on the - kinds of diagnostics you should expect during this procedure. - - *Note Building gcc::, for complete `g77'-specific information on - this step. - -Step 10: `make compare' - *Note Where to Port Bugs: Bug Lists, for information on where to - report that you observed files having different contents during - this phase. - - *Note How to Report Bugs: Bug Reporting, for information on *how* - to report bugs like this. - -Step 11: `rm -fr stage1' - You don't need to do this, but it frees up disk space. - -Step 12: `make -k install' - If this doesn't seem to work, try: - - make -k install install-libf77 - - Or, make sure you're using GNU `make'. - - *Note Installation of Binaries::, for more information. - - *Note Updating Your Info Directory: Updating Documentation, for - information on entering this manual into your system's list of - texinfo manuals. - -Step 13: `g77 -v' - If this command prints approximately 25 lines of output, including - the GNU Fortran Front End version number (which should be the same - as the version number for the version of `g77' you just built and - installed) and the version numbers for the three parts of the - `libf2c' library (`libF77', `libI77', `libU77'), and those version - numbers are all in agreement, then there is a high likelihood that - the installation has been successfully completed. - - You might consider doing further testing. For example, log in as - a non-privileged user, then create a small Fortran program, such - as: - - PROGRAM SMTEST - DO 10 I=1, 10 - PRINT *, 'Hello World #', I - 10 CONTINUE - END - - Compile, link, and run the above program, and, assuming you named - the source file `smtest.f', the session should look like this: - - sh# g77 -o smtest smtest.f - sh# ./smtest - Hello World # 1 - Hello World # 2 - Hello World # 3 - Hello World # 4 - Hello World # 5 - Hello World # 6 - Hello World # 7 - Hello World # 8 - Hello World # 9 - Hello World # 10 - sh# - - If invoking `g77' doesn't seem to work, the problem might be that - you've installed it in a location that is not in your shell's - search path. For example, if you specified `--prefix=/gnu', and - `/gnu/bin' is not in your `PATH' environment variable, you must - explicitly specify the location of the compiler via `/gnu/bin/g77 - -o smtest smtest.f'. - - After proper installation, you don't need to keep your gcc and g77 - source and build directories around anymore. Removing them can - free up a lot of disk space. - -Complete Installation -===================== - - *Version info:* For `egcs' users, the following information is -mostly superceded by the `egcs' installation instructions. - - Here is the complete `g77'-specific information on how to configure, -build, and install `g77'. - -Unpacking ---------- - - The `gcc' source distribution is a stand-alone distribution. It is -designed to be unpacked (producing the `gcc' source tree) and built as -is, assuming certain prerequisites are met (including the availability -of compatible UNIX programs such as `make', `cc', and so on). - - However, before building `gcc', you will want to unpack and merge -the `g77' distribution in with it, so that you build a Fortran-capable -version of `gcc', which includes the `g77' command, the necessary -run-time libraries, and this manual. - - Unlike `gcc', the `g77' source distribution is *not* a stand-alone -distribution. It is designed to be unpacked and, afterwards, -immediately merged into an applicable `gcc' source tree. That is, the -`g77' distribution *augments* a `gcc' distribution--without `gcc', -generally only the documentation is immediately usable. - - A sequence of commands typically used to unpack `gcc' and `g77' is: - - sh# cd /usr/src - sh# gunzip -c /usr/FSF/gcc-2.8.1.tar.gz | tar xf - - sh# gunzip -c /usr/FSF/g77-0.5.24.tar.gz | tar xf - - sh# ln -s gcc-2.8.1 gcc - sh# ln -s g77-0.5.24 g77 - sh# mv -i g77/* gcc - - *Notes:* The commands beginning with `gunzip...' might print `Broken -pipe...' as they complete. That is nothing to worry about, unless you -actually *hear* a pipe breaking. The `ln' commands are helpful in -reducing typing and clutter in installation examples in this manual. -Hereafter, the top level of `gcc' source tree is referred to as `gcc', -and the top level of just the `g77' source tree (prior to issuing the -`mv' command, above) is referred to as `g77'. - - There are three top-level names in a `g77' distribution: - - g77/COPYING.g77 - g77/README.g77 - g77/f - - All three entries should be moved (or copied) into a `gcc' source -tree (typically named after its version number and as it appears in the -FSF distributions--e.g. `gcc-2.8.1'). - - `g77/f' is the subdirectory containing all of the code, -documentation, and other information that is specific to `g77'. The -other two files exist to provide information on `g77' to someone -encountering a `gcc' source tree with `g77' already present, who has -not yet read these installation instructions and thus needs help -understanding that the source tree they are looking at does not come -from a single FSF distribution. They also help people encountering an -unmerged `g77' source tree for the first time. - - *Note:* Please use *only* `gcc' and `g77' source trees as -distributed by the FSF. Use of modified versions is likely to result -in problems that appear to be in the `g77' code but, in fact, are not. -Do not use such modified versions unless you understand all the -differences between them and the versions the FSF distributes--in which -case you should be able to modify the `g77' (or `gcc') source trees -appropriately so `g77' and `gcc' can coexist as they do in the stock -FSF distributions. - -Merging Distributions ---------------------- - - After merging the `g77' source tree into the `gcc' source tree, you -have put together a complete `g77' source tree. - - As of version 0.5.23, `g77' no longer modifies the version number of -`gcc', nor does it patch `gcc' itself. - - `g77' still depends on being merged with an appropriate version of -`gcc'. For version 0.5.24 of `g77', the specific version of `gcc' -supported is 2.8.1. - - However, other versions of `gcc' might be suitable "hosts" for this -version of `g77'. - - GNU version numbers make it easy to figure out whether a particular -version of a distribution is newer or older than some other version of -that distribution. The format is, generally, MAJOR.MINOR.PATCH, with -each field being a decimal number. (You can safely ignore leading -zeros; for example, 1.5.3 is the same as 1.5.03.) The MAJOR field only -increases with time. The other two fields are reset to 0 when the -field to their left is incremented; otherwise, they, too, only increase -with time. So, version 2.6.2 is newer than version 2.5.8, and version -3.0 is newer than both. (Trailing `.0' fields often are omitted in -announcements and in names for distributions and the directories they -create.) - - If your version of `gcc' is older than the oldest version supported -by `g77' (as casually determined by listing the contents of -`gcc/f/INSTALL/', which contains these installation instructions in -plain-text format), you should obtain a newer, supported version of -`gcc'. (You could instead obtain an older version of `g77', or try and -get your `g77' to work with the old `gcc', but neither approach is -recommended, and you shouldn't bother reporting any bugs you find if you -take either approach, because they're probably already fixed in the -newer versions you're not using.) - - If your version of `gcc' is newer than the newest version supported -by `g77', it is possible that your `g77' will work with it anyway. If -the version number for `gcc' differs only in the PATCH field, you might -as well try that version of `gcc'. Since it has the same MAJOR and -MINOR fields, the resulting combination is likely to work. - - So, for example, if a particular version of `g77' has support for -`gcc' versions 2.8.0 and 2.8.1, it is likely that `gcc-2.8.2' would -work well with `g77'. - - However, `gcc-2.9.0' would almost certainly not work with that -version of `g77' without appropriate modifications, so a new version of -`g77' would be needed (and you should wait for it rather than bothering -the maintainers--*note User-Visible Changes: Changes.). - - This complexity is the result of `gcc' and `g77' being separate -distributions. By keeping them separate, each product is able to be -independently improved and distributed to its user base more frequently. - - However, the GBE interface defined by `gcc' typically undergoes some -incompatible changes at least every time the MINOR field of the version -number is incremented, and such changes require corresponding changes to -the `g77' front end (FFE). - -Where in the World Does Fortran (and GNU CC) Go? ------------------------------------------------- - - Before configuring, you should make sure you know where you want the -`g77' and `gcc' binaries to be installed after they're built, because -this information is given to the configuration tool and used during the -build itself. - - A `g77' installation normally includes installation of a -Fortran-aware version of `gcc', so that the `gcc' command recognizes -Fortran source files and knows how to compile them. - - For this to work, the version of `gcc' that you will be building as -part of `g77' *must* be installed as the "active" version of `gcc' on -the system. - - Sometimes people make the mistake of installing `gcc' as -`/usr/local/bin/gcc', leaving an older, non-Fortran-aware version in -`/usr/bin/gcc'. (Or, the opposite happens.) This can result in `gcc' -being unable to compile Fortran source files, because when the older -version of `gcc' is invoked, it complains that it does not recognize -the language, or the file name suffix. - - So, determine whether `gcc' already is installed on your system, -and, if so, *where* it is installed, and prepare to configure the new -version of `gcc' you'll be building so that it installs over the -existing version of `gcc'. - - You might want to back up your existing copy of `/usr/bin/gcc', and -the entire `/usr/lib' directory, before you perform the actual -installation (as described in this manual). - - Existing `gcc' installations typically are found in `/usr' or -`/usr/local'. (This means the commands are installed in `/usr/bin' or -`/usr/local/bin', the libraries in `/usr/lib' or `/usr/local/lib', and -so on.) - - If you aren't certain where the currently installed version of `gcc' -and its related programs reside, look at the output of this command: - - gcc -v -o /tmp/delete-me -xc /dev/null -xnone - - All sorts of interesting information on the locations of various -`gcc'-related programs and data files should be visible in the output -of the above command. (The output also is likely to include a -diagnostic from the linker, since there's no `main_()' function.) -However, you do have to sift through it yourself; `gcc' currently -provides no easy way to ask it where it is installed and where it looks -for the various programs and data files it calls on to do its work. - - Just *building* `g77' should not overwrite any installed -programs--but, usually, after you build `g77', you will want to install -it, so backing up anything it might overwrite is a good idea. (This is -true for any package, not just `g77', though in this case it is -intentional that `g77' overwrites `gcc' if it is already installed--it -is unusual that the installation process for one distribution -intentionally overwrites a program or file installed by another -distribution, although, in this case, `g77' is an augmentation of the -`gcc' distribution.) - - Another reason to back up the existing version first, or make sure -you can restore it easily, is that it might be an older version on -which other users have come to depend for certain behaviors. However, -even the new version of `gcc' you install will offer users the ability -to specify an older version of the actual compilation programs if -desired, and these older versions need not include any `g77' components. -*Note Specifying Target Machine and Compiler Version: (gcc)Target -Options, for information on the `-V' option of `gcc'. - -Configuring GNU CC ------------------- - - `g77' is configured automatically when you configure `gcc'. There -are two parts of `g77' that are configured in two different -ways--`g77', which "camps on" to the `gcc' configuration mechanism, and -`libg2c', which uses a variation of the GNU `autoconf' configuration -system. - - Generally, you shouldn't have to be concerned with either `g77' or -`libg2c' configuration, unless you're configuring `g77' as a -cross-compiler. In this case, the `libg2c' configuration, and possibly -the `g77' and `gcc' configurations as well, might need special -attention. (This also might be the case if you're porting `gcc' to a -whole new system--even if it is just a new operating system on an -existing, supported CPU.) - - To configure the system, see *Note Installing GNU CC: -(gcc)Installation, following the instructions for running `./configure'. -Pay special attention to the `--prefix=' option, which you almost -certainly will need to specify. - - (Note that `gcc' installation information is provided as a -plain-text file in `gcc/INSTALL'.) - - The information printed by the invocation of `./configure' should -show that the `f' directory (the Fortran language) has been configured. -If it does not, there is a problem. - - *Note:* Configuring with the `--srcdir' argument, or by starting in -an empty directory and typing a command such as `../gcc/configure' to -build with separate build and source directories, is known to work with -GNU `make', but it is known to not work with other variants of `make'. -Irix5.2 and SunOS4.1 versions of `make' definitely won't work outside -the source directory at present. - - `g77''s portion of the `configure' script used to issue a warning -message about this when configuring for building binaries outside the -source directory, but no longer does this as of version 0.5.23. - - Instead, `g77' simply rejects most common attempts to build it using -a non-GNU `make' when the build directory is not the same as the source -directory, issuing an explanatory diagnostic. - -Building GNU CC ---------------- - - Building `g77' requires building enough of `gcc' that these -instructions assume you're going to build all of `gcc', including -`g++', `protoize', and so on. You can save a little time and disk -space by changes the `LANGUAGES' macro definition in `gcc/Makefile.in' -or `gcc/Makefile', but if you do that, you're on your own. One change -is almost *certainly* going to cause failures: removing `c' or `f77' -from the definition of the `LANGUAGES' macro. - - After configuring `gcc', which configures `g77' and `libg2c' -automatically, you're ready to start the actual build by invoking -`make'. - - *Note:* You *must* have run the `configure' script in `gcc' before -you run `make', even if you're using an already existing `gcc' -development directory, because `./configure' does the work to recognize -that you've added `g77' to the configuration. - - There are two general approaches to building GNU CC from scratch: - -"bootstrap" - This method uses minimal native system facilities to build a - barebones, unoptimized `gcc', that is then used to compile - ("bootstrap") the entire system. - -"straight" - This method assumes a more complete native system exists, and uses - that just once to build the entire system. - - On all systems without a recent version of `gcc' already installed, -the bootstrap method must be used. In particular, `g77' uses -extensions to the C language offered, apparently, only by `gcc'. - - On most systems with a recent version of `gcc' already installed, -the straight method can be used. This is an advantage, because it -takes less CPU time and disk space for the build. However, it does -require that the system have fairly recent versions of many GNU -programs and other programs, which are not enumerated here. - -Bootstrap Build -............... - - A complete bootstrap build is done by issuing a command beginning -with `make bootstrap ...', as described in *Note Installing GNU CC: -(gcc)Installation. This is the most reliable form of build, but it -does require the most disk space and CPU time, since the complete system -is built twice (in Stages 2 and 3), after an initial build (during -Stage 1) of a minimal `gcc' compiler using the native compiler and -libraries. - - You might have to, or want to, control the way a bootstrap build is -done by entering the `make' commands to build each stage one at a time, -as described in the `gcc' manual. For example, to save time or disk -space, you might want to not bother doing the Stage 3 build, in which -case you are assuming that the `gcc' compiler you have built is -basically sound (because you are giving up the opportunity to compare a -large number of object files to ensure they're identical). - - To save some disk space during installation, after Stage 2 is built, -you can type `rm -fr stage1' to remove the binaries built during Stage -1. - - Also, *Note Installing GNU CC: (gcc)Installation, for important -information on building `gcc' that is not described in this `g77' -manual. For example, explanations of diagnostic messages and whether -they're expected, or indicate trouble, are found there. - -Straight Build -.............. - - If you have a recent version of `gcc' already installed on your -system, and if you're reasonably certain it produces code that is -object-compatible with the version of `gcc' you want to build as part -of building `g77', you can save time and disk space by doing a straight -build. - - To build just the compilers along with the necessary run-time -libraries, issue the following command: - - make -k CC=gcc - - If you run into problems using this method, you have two options: - - * Abandon this approach and do a bootstrap build. - - * Try to make this approach work by diagnosing the problems you're - running into and retrying. - - Especially if you do the latter, you might consider submitting any -solutions as bug/fix reports. *Note Known Causes of Trouble with GNU -Fortran: Trouble. - - However, understand that many problems preventing a straight build -from working are not `g77' problems, and, in such cases, are not likely -to be addressed in future versions of `g77'. Consider treating them as -`gcc' bugs instead. - -Pre-installation Checks ------------------------ - - Before installing the system, which includes installing `gcc', you -might want to do some minimum checking to ensure that some basic things -work. - - Here are some commands you can try, and output typically printed by -them when they work: - - sh# cd /usr/src/gcc - sh# ./g77 -B./ -v - g77 version 0.5.24 - Driving: ./g77 -B./ -v -c -xf77-version /dev/null -xnone - Reading specs from ./specs - gcc version 2.8.1 - cpp -lang-c -v -isystem ./include -undef -D__GNUC__=2 ... - GNU CPP version 2.8.1 (Alpha GNU/Linux with ELF) - #include "..." search starts here: - #include <...> search starts here: - include - /usr/alpha-linux/include - /usr/lib/gcc-lib/alpha-linux/2.8.1/include - /usr/include - End of search list. - ./f771 -fnull-version -quiet -dumpbase g77-version.f -version ... - GNU F77 version 2.8.1 (alpha-linux) compiled ... - GNU Fortran Front End version 0.5.24 - as -nocpp -o /tmp/cca14485.o /tmp/cca14485.s - ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 ... - /tmp/cca14485 - __G77_LIBF77_VERSION__: 0.5.24 - @(#)LIBF77 VERSION 19970919 - __G77_LIBI77_VERSION__: 0.5.24 - @(#) LIBI77 VERSION pjw,dmg-mods 19980405 - __G77_LIBU77_VERSION__: 0.5.24 - @(#) LIBU77 VERSION 19970919 - sh# ./xgcc -B./ -v -o /tmp/delete-me -xc /dev/null -xnone - Reading specs from ./specs - gcc version 2.8.1 - ./cpp -lang-c -v -isystem ./include -undef ... - GNU CPP version 2.8.1 (Alpha GNU/Linux with ELF) - #include "..." search starts here: - #include <...> search starts here: - include - /usr/alpha-linux/include - /usr/lib/gcc-lib/alpha-linux/2.8.1/include - /usr/include - End of search list. - ./cc1 /tmp/cca18063.i -quiet -dumpbase null.c -version ... - GNU C version 2.8.1 (alpha-linux) compiled ... - as -nocpp -o /tmp/cca180631.o /tmp/cca18063.s - ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 ... - /usr/lib/crt1.o: In function `_start': - ../sysdeps/alpha/elf/start.S:77: undefined reference to `main' - ../sysdeps/alpha/elf/start.S:77: undefined reference to `main' - sh# - - (Note that long lines have been truncated, and `...' used to -indicate such truncations.) - - The above two commands test whether `g77' and `gcc', respectively, -are able to compile empty (null) source files, whether invocation of -the C preprocessor works, whether libraries can be linked, and so on. - - If the output you get from either of the above two commands is -noticeably different, especially if it is shorter or longer in ways -that do not look consistent with the above sample output, you probably -should not install `gcc' and `g77' until you have investigated further. - - For example, you could try compiling actual applications and seeing -how that works. (You might want to do that anyway, even if the above -tests work.) - - To compile using the not-yet-installed versions of `gcc' and `g77', -use the following commands to invoke them. - - To invoke `g77', type: - - /usr/src/gcc/g77 -B/usr/src/gcc/ ... - - To invoke `gcc', type: - - /usr/src/gcc/xgcc -B/usr/src/gcc/ ... - -Installation of Binaries ------------------------- - - After configuring, building, and testing `g77' and `gcc', when you -are ready to install them on your system, type: - - make -k CC=gcc install - - As described in *Note Installing GNU CC: (gcc)Installation, the -values for the `CC' and `LANGUAGES' macros should be the same as those -you supplied for the build itself. - - So, the details of the above command might vary if you used a -bootstrap build (where you might be able to omit both definitions, or -might have to supply the same definitions you used when building the -final stage) or if you deviated from the instructions for a straight -build. - - If the above command does not install `libg2c.a' as expected, try -this: - - make -k ... install install-libf77 - - We don't know why some non-GNU versions of `make' sometimes require -this alternate command, but they do. (Remember to supply the -appropriate definition for `CC' where you see `...' in the above -command.) - - Note that using the `-k' option tells `make' to continue after some -installation problems, like not having `makeinfo' installed on your -system. It might not be necessary for your system. - - *Note:* `g77' no longer installs files not directly part of `g77', -such as `/usr/bin/f77', `/usr/lib/libf2c.a', and `/usr/include/f2c.h', -or their `/usr/local' equivalents. - - *Note Distributing Binaries::, for information on how to accommodate -systems with no existing non-`g77' `f77' compiler and systems with -`f2c' installed. - -Updating Your Info Directory ----------------------------- - - As part of installing `g77', you should make sure users of `info' -can easily access this manual on-line. - - `g77' does this automatically by invoking the `install-info' command -when you use `make install' to install `g77'. - - If that fails, or if the `info' directory it updates is not the one -normally accessed by users, consider invoking it yourself. For example: - - install-info --info-dir=/usr/info /usr/info/g77.info - - The above example assumes the `g77' documentation already is -installed in `/usr/info' and that `/usr/info/dir' is the file you wish -to update. Adjust the command accordingly, if those assumptions are -wrong. - -Missing tools? --------------- - - A build of `gcc' might fail due to one or more tools being called -upon by `make' (during the build or install process), when those tools -are not installed on your system. - - This situation can result from any of the following actions -(performed by you or someone else): - - * Changing the source code or documentation yourself (as a developer - or technical writer). - - * Applying a patch that changes the source code or documentation - (including, sometimes, the official patches distributed by the - FSF). - - * Deleting the files that are created by the (missing) tools. - - The `make maintainer-clean' command is supposed to delete these - files, so invoking this command without having all the appropriate - tools installed is not recommended. - - * Creating the source directory using a method that does not - preserve the date-time-modified information in the original - distribution. - - For example, the UNIX `cp -r' command copies a directory tree - without preserving the date-time-modified information. Use `cp - -pr' instead. - - The reason these activities cause `make' to try and invoke tools -that it probably wouldn't when building from a perfectly "clean" source -directory containing `gcc' and `g77' is that some files in the source -directory (and the corresponding distribution) aren't really source -files, but *derived* files that are produced by running tools with the -corresponding source files as input. These derived files "depend", in -`make' terminology, on the corresponding source files. - - `make' determines that a file that depends on another needs to be -updated if the date-time-modified information for the source file shows -that it is newer than the corresponding information for the derived -file. - - If it makes that determination, `make' runs the appropriate commands -(specified in the "Makefile") to update the derived file, and this -process typically calls upon one or more installed tools to do the work. - - The "safest" approach to dealing with this situation is to recreate -the `gcc' and `g77' source directories from complete `gcc' and `g77' -distributions known to be provided by the FSF. - - Another fairly "safe" approach is to simply install the tools you -need to complete the build process. This is especially appropriate if -you've changed the source code or applied a patch to do so. - - However, if you're certain that the problem is limited entirely to -incorrect date-time-modified information, that there are no -discrepancies between the contents of source files and files derived -from them in the source directory, you can often update the -date-time-modified information for the derived files to work around the -problem of not having the appropriate tools installed. - - On UNIX systems, the simplest way to update the date-time-modified -information of a file is to use the use the `touch' command. - - How to use `touch' to update the derived files updated by each of -the tools is described below. *Note:* New versions of `g77' might -change the set of files it generates by invoking each of these tools. -If you cannot figure out for yourself how to handle such a situation, -try an older version of `g77' until you find someone who can (or until -you obtain and install the relevant tools). - -Missing `autoconf'? -................... - - If you cannot install `autoconf', make sure you have started with a -*fresh* distribution of `gcc' and `g77', do *not* do `make -maintainer-clean', and, to ensure that `autoconf' is not invoked by -`make' during the build, type these commands: - - sh# cd gcc/f/runtime - sh# touch configure libU77/configure - sh# cd ../../.. - sh# - -Missing `bison'? -................ - - If you cannot install `bison', make sure you have started with a -*fresh* distribution of `gcc', do *not* do `make maintainer-clean', -and, to ensure that `bison' is not invoked by `make' during the build, -type these commands: - - sh# cd gcc - sh# touch bi-parser.c bi-parser.h c-parse.c c-parse.h cexp.c - sh# touch cp/parse.c cp/parse.h objc-parse.c - sh# cd .. - sh# - -Missing `gperf'? -................ - - If you cannot install `gperf', make sure you have started with a -*fresh* distribution of `gcc', do *not* do `make maintainer-clean', -and, to ensure that `gperf' is not invoked by `make' during the build, -type these commands: - - sh# cd gcc - sh# touch c-gperf.h - sh# cd .. - sh# - -Missing `makeinfo'? -................... - - If `makeinfo' is needed but unavailable when installing (via `make -install'), some files, like `libg2c.a', might not be installed, because -once `make' determines that it cannot invoke `makeinfo', it cancels any -further processing. - - If you cannot install `makeinfo', an easy work-around is to specify -`MAKEINFO=true' on the `make' command line, or to specify the `-k' -option (`make -k install'). - - Another approach is to force the relevant files to be up-to-date by -typing these commands and then re-trying the installation step: - - sh# cd gcc - sh# touch f/g77.info f/BUGS f/INSTALL f/NEWS - sh# cd .. - sh# - -Distributing Binaries -===================== - - If you are building `g77' for distribution to others in binary form, -first make sure you are aware of your legal responsibilities (read the -file `gcc/COPYING' thoroughly). - - Then, consider your target audience and decide where `g77' should be -installed. - - For systems like GNU/Linux that have no native Fortran compiler (or -where `g77' could be considered the native compiler for Fortran and -`gcc' for C, etc.), you should definitely configure `g77' for -installation in `/usr/bin' instead of `/usr/local/bin'. Specify the -`--prefix=/usr' option when running `./configure'. - - You might also want to set up the distribution so the `f77' command -is a link to `g77', although a script that accepts "classic" UNIX `f77' -options and translates the command-line to the appropriate `g77' -command line would be more appropriate. If you do this, *please* also -provide a "man page" in `man/man1/f77.1' describing the command. (A -link to `man/man1/g77.1' is appropriate if `bin/f77' is a link to -`bin/g77'.) - - For a system that might already have `f2c' installed, consider -whether inter-operation with `g77' will be important to users of `f2c' -on that system. If you want to improve the likelihood that users will -be able to use both `f2c' and `g77' to compile code for a single program -without encountering link-time or run-time incompatibilities, make sure -that, whenever they intend to combine `f2c'-produced code with -`g77'-produced code in an executable, they: - - * Use the `lib/gcc-lib/.../include/g2c.h' file generated by the - `g77' build in place of the `f2c.h' file that normally comes with - `f2c' (or versions of `g77' prior to 0.5.23) when compiling *all* - of the `f2c'-produced C code - - * Link to the `lib/gcc-lib/.../libg2c.a' library built by the `g77' - build instead of the `libf2c.a' library that normally comes with - `f2c' (or versions of `g77' prior to 0.5.23) - - How you choose to effect the above depends on whether the existing -installation of `f2c' must be maintained. - - In any case, it is important to try and ensure that the installation -keeps working properly even after subsequent re-installation of `f2c', -which probably involves overwriting `/usr/local/lib/libf2c.a' and -`/usr/local/include/f2c.h', or similar. - - At least, copying `libg2c.a' and `g2c.h' into the appropriate -"public" directories allows users to more easily select the version of -`libf2c' they wish to use for a particular build. The names are -changed by `g77' to make this coexistence easier to maintain; even if -`f2c' is installed later, the `g77' files normally installed by its -installation process aren't disturbed. Use of symbolic links from one -set of files to another might result in problems after a subsequent -reinstallation of either `f2c' or `g77', so be sure to alert users of -your distribution accordingly. - - (Make sure you clearly document, in the description of your -distribution, how installation of your distribution will affect -existing installations of `gcc', `f2c', `f77', `libf2c.a', and so on. -Similarly, you should clearly document any requirements you assume will -be met by users of your distribution.) - - For other systems with native `f77' (and `cc') compilers, configure -`g77' as you (or most of your audience) would configure `gcc' for their -installations. Typically this is for installation in `/usr/local', and -would not include a new version of `/usr/bin/f77' or -`/usr/local/bin/f77', so users could still use the native `f77'. - - In any case, for `g77' to work properly, you *must* ensure that the -binaries you distribute include: - -`bin/g77' - This is the command most users use to compile Fortran. - -`bin/gcc' - This is the command some users use to compile Fortran, typically - when compiling programs written in other languages at the same - time. The `bin/gcc' executable file must have been built from a - `gcc' source tree into which a `g77' source tree was merged and - configured, or it will not know how to compile Fortran programs. - -`info/g77.info*' - This is the documentation for `g77'. If it is not included, users - will have trouble understanding diagnostics messages and other - such things, and will send you a lot of email asking questions. - - Please edit this documentation (by editing `gcc/f/*.texi' and - doing `make doc' from the `/usr/src/gcc' directory) to reflect any - changes you've made to `g77', or at least to encourage users of - your binary distribution to report bugs to you first. - - Also, whether you distribute binaries or install `g77' on your own - system, it might be helpful for everyone to add a line listing - this manual by name and topic to the top-level `info' node in - `/usr/info/dir'. That way, users can find `g77' documentation more - easily. *Note Updating Your Info Directory: Updating - Documentation. - -`man/man1/g77.1' - This is the short man page for `g77'. It is not always kept - up-to-date, but you might as well include it for people who really - like "man" pages. - -`lib/gcc-lib' - This is the directory containing the "private" files installed by - and for `gcc', `g77', `g++', and other GNU compilers. - -`lib/gcc-lib/.../f771' - This is the actual Fortran compiler. - -`lib/gcc-lib/.../libg2c.a' - This is the run-time library for `g77'-compiled programs. - - Whether you want to include the slightly updated (and possibly -improved) versions of `cc1', `cc1plus', and whatever other binaries get -rebuilt with the changes the GNU Fortran distribution makes to the GNU -back end, is up to you. These changes are highly unlikely to break any -compilers, because they involve doing things like adding to the list of -acceptable compiler options (so, for example, `cc1plus' accepts, and -ignores, options that only `f771' actually processes). - - Please assure users that unless they have a specific need for their -existing, older versions of `gcc' command, they are unlikely to -experience any problems by overwriting it with your version--though -they could certainly protect themselves by making backup copies first! - - Otherwise, users might try and install your binaries in a "safe" -place, find they cannot compile Fortran programs with your distribution -(because, perhaps, they're invoking their old version of the `gcc' -command, which does not recognize Fortran programs), and assume that -your binaries (or, more generally, GNU Fortran distributions in -general) are broken, at least for their system. - - Finally, *please* ask for bug reports to go to you first, at least -until you're sure your distribution is widely used and has been well -tested. This especially goes for those of you making any changes to -the `g77' sources to port `g77', e.g. to OS/2. <fortran@gnu.org> has -received a fair number of bug reports that turned out to be problems -with other peoples' ports and distributions, about which nothing could -be done for the user. Once you are quite certain a bug report does not -involve your efforts, you can forward it to us. - diff --git a/gcc/f/Make-lang.in b/gcc/f/Make-lang.in deleted file mode 100755 index df0a0a9..0000000 --- a/gcc/f/Make-lang.in +++ /dev/null @@ -1,472 +0,0 @@ -# Top level makefile fragment for GNU Fortran. -*-makefile-*- -# Copyright (C) 1995-1998 Free Software Foundation, Inc. - -#This file is part of GNU Fortran. - -#GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# This file provides the language dependent support in the main Makefile. -# Each language makefile fragment must provide the following targets: -# -# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap, -# foo.info, foo.dvi, -# foo.install-normal, foo.install-common, foo.install-info, foo.install-man, -# foo.uninstall, foo.distdir, -# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean, -# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4 -# -# where `foo' is the name of the language. -# -# It should also provide rules for: -# -# - making any compiler driver (eg: g++) -# - the compiler proper (eg: cc1plus) -# - define the names for selecting the language in LANGUAGES. -# -# $(srcdir) must be set to the gcc/ source directory (not gcc/f/). -# -# Actual name to use when installing a native compiler. -G77_INSTALL_NAME = `t='$(program_transform_name)'; echo g77 | sed $$t` - -# Actual name to use when installing a cross-compiler. -G77_CROSS_NAME = `t='$(program_transform_cross_name)'; echo g77 | sed $$t` -# -# Define the names for selecting f77 in LANGUAGES. -# Note that it would be nice to move the dependency on g77 -# into the F77 rule, but that needs a little bit of work -# to do the right thing within all.cross. -F77 f77: f771$(exeext) - -# Tell GNU make to ignore these if they exist. -.PHONY: F77 f77 f77.all.build f77.all.cross \ - f77.start.encap f77.rest.encap f77.info f77.dvi \ - f77.install-normal \ - f77.install-common f77.install-info f77.install-man \ - f77.uninstall f77.mostlyclean f77.clean f77.distclean \ - f77.extraclean f77.maintainer-clean f77.distdir f77.rebuilt \ - f77.stage1 f77.stage2 f77.stage3 f77.stage4 - -g77.c: $(srcdir)/gcc.c - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - rm -f g77.c; \ - $(LN_S) $(srcdir)/gcc.c g77.c; \ - else true; fi - -g77spec.o: $(srcdir)/f/g77spec.c $(srcdir)/f/version.h - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(srcdir)/f/g77spec.c; \ - else true; fi - -g77version.o: $(srcdir)/f/version.c - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -o g77version.o \ - $(srcdir)/f/version.c; \ - else true; fi - -# N.B.: This is a copy of the gcc.o rule, with -DLANG_SPECIFIC_DRIVER added. -# It'd be nice if we could find an easier way to do this---rather than have -# to track changes to the toplevel gcc Makefile as well. -# We depend on g77.c last, to make it obvious where it came from. -g77.o: $(CONFIG_H) multilib.h config.status $(lang_specs_files) g77.c prefix.h - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $(DRIVER_DEFINES) \ - -DLANG_SPECIFIC_DRIVER -c g77.c; \ - else true; fi - -# Create the compiler driver for g77. -g77$(exeext): g77.o g77spec.o g77version.o version.o choose-temp.o pexecute.o prefix.o mkstemp.o \ - $(LIBDEPS) $(EXTRA_GCC_OBJS) - if [ -f lang-f77 ]; then \ - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ g77.o g77spec.o g77version.o \ - version.o choose-temp.o pexecute.o prefix.o mkstemp.o $(EXTRA_GCC_OBJS) $(LIBS); \ - else true; fi - -# Create a version of the g77 driver which calls the cross-compiler. -g77-cross$(exeext): g77$(exeext) - if [ -f lang-f77 ]; then \ - rm -f g77-cross$(exeext); \ - cp g77$(exeext) g77-cross$(exeext); \ - else true; fi - -F77_SRCS = \ - $(srcdir)/f/assert.j \ - $(srcdir)/f/bad.c \ - $(srcdir)/f/bad.def \ - $(srcdir)/f/bad.h \ - $(srcdir)/f/bit.c \ - $(srcdir)/f/bit.h \ - $(srcdir)/f/bld-op.def \ - $(srcdir)/f/bld.c \ - $(srcdir)/f/bld.h \ - $(srcdir)/f/com-rt.def \ - $(srcdir)/f/com.c \ - $(srcdir)/f/com.h \ - $(srcdir)/f/config.j \ - $(srcdir)/f/convert.j \ - $(srcdir)/f/data.c \ - $(srcdir)/f/data.h \ - $(srcdir)/f/equiv.c \ - $(srcdir)/f/equiv.h \ - $(srcdir)/f/expr.c \ - $(srcdir)/f/expr.h \ - $(srcdir)/f/fini.c \ - $(srcdir)/f/flags.j \ - $(srcdir)/f/glimits.j \ - $(srcdir)/f/global.c \ - $(srcdir)/f/global.h \ - $(srcdir)/f/hconfig.j \ - $(srcdir)/f/implic.c \ - $(srcdir)/f/implic.h \ - $(srcdir)/f/input.j \ - $(srcdir)/f/info-b.def \ - $(srcdir)/f/info-k.def \ - $(srcdir)/f/info-w.def \ - $(srcdir)/f/info.c \ - $(srcdir)/f/info.h \ - $(srcdir)/f/intrin.c \ - $(srcdir)/f/intrin.def \ - $(srcdir)/f/intrin.h \ - $(srcdir)/f/lab.c \ - $(srcdir)/f/lab.h \ - $(srcdir)/f/lex.c \ - $(srcdir)/f/lex.h \ - $(srcdir)/f/malloc.c \ - $(srcdir)/f/malloc.h \ - $(srcdir)/f/name.c \ - $(srcdir)/f/name.h \ - $(srcdir)/f/output.j \ - $(srcdir)/f/parse.c \ - $(srcdir)/f/proj.c \ - $(srcdir)/f/proj.h \ - $(srcdir)/f/rtl.j \ - $(srcdir)/f/src.c \ - $(srcdir)/f/src.h \ - $(srcdir)/f/st.c \ - $(srcdir)/f/st.h \ - $(srcdir)/f/sta.c \ - $(srcdir)/f/sta.h \ - $(srcdir)/f/stb.c \ - $(srcdir)/f/stb.h \ - $(srcdir)/f/stc.c \ - $(srcdir)/f/stc.h \ - $(srcdir)/f/std.c \ - $(srcdir)/f/std.h \ - $(srcdir)/f/ste.c \ - $(srcdir)/f/ste.h \ - $(srcdir)/f/storag.c \ - $(srcdir)/f/storag.h \ - $(srcdir)/f/stp.c \ - $(srcdir)/f/stp.h \ - $(srcdir)/f/str-1t.fin \ - $(srcdir)/f/str-2t.fin \ - $(srcdir)/f/str-fo.fin \ - $(srcdir)/f/str-io.fin \ - $(srcdir)/f/str-nq.fin \ - $(srcdir)/f/str-op.fin \ - $(srcdir)/f/str-ot.fin \ - $(srcdir)/f/str.c \ - $(srcdir)/f/str.h \ - $(srcdir)/f/sts.c \ - $(srcdir)/f/sts.h \ - $(srcdir)/f/stt.c \ - $(srcdir)/f/stt.h \ - $(srcdir)/f/stu.c \ - $(srcdir)/f/stu.h \ - $(srcdir)/f/stv.c \ - $(srcdir)/f/stv.h \ - $(srcdir)/f/stw.c \ - $(srcdir)/f/stw.h \ - $(srcdir)/f/symbol.c \ - $(srcdir)/f/symbol.def \ - $(srcdir)/f/symbol.h \ - $(srcdir)/f/system.j \ - $(srcdir)/f/target.c \ - $(srcdir)/f/target.h \ - $(srcdir)/f/tconfig.j \ - $(srcdir)/f/tm.j \ - $(srcdir)/f/top.c \ - $(srcdir)/f/top.h \ - $(srcdir)/f/toplev.j \ - $(srcdir)/f/tree.j \ - $(srcdir)/f/type.c \ - $(srcdir)/f/type.h \ - $(srcdir)/f/version.c \ - $(srcdir)/f/version.h \ - $(srcdir)/f/where.c \ - $(srcdir)/f/where.h - -f771$(exeext): $(P) $(F77_SRCS) $(LIBDEPS) stamp-objlist - touch lang-f77 - cd f; $(MAKE) $(FLAGS_TO_PASS) \ - HOST_CC="$(HOST_CC)" HOST_CFLAGS="$(HOST_CFLAGS)" HOST_CPPFLAGS="$(HOST_CPPFLAGS)" \ - ../f771$(exeext) - -# -# Build hooks: - -f77.all.build: g77$(exeext) -f77.all.cross: g77-cross$(exeext) -f77.start.encap: g77$(exeext) -f77.rest.encap: - -f77.info: f/g77.info -f77.dvi: f/g77.dvi - -# g77 documentation. -f/g77.info: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \ - $(srcdir)/f/g77install.texi $(srcdir)/f/news.texi \ - $(srcdir)/f/intdoc.texi - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - rm -f $(srcdir)/f/g77.info-*; \ - $(MAKEINFO) -I$(srcdir)/f -o f/g77.info $(srcdir)/f/g77.texi; \ - else true; fi - -f/g77.dvi: $(srcdir)/f/g77.texi $(srcdir)/f/bugs.texi \ - $(srcdir)/f/g77install.texi $(srcdir)/f/news.texi \ - $(srcdir)/f/intdoc.texi - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac -# `tex2dvi' was used below, but the Texinfo 3.12 one won't work properly -# with the include files from $(srcdir). This use of TEXINPUTS may not -# be universally valid. `$(TEX)' should be used if it gets defined in -# gcc/Makefile.in. - if [ -f lang-f77 ]; then \ - TEXINPUTS=$(srcdir)/f:$$TEXINPUTS tex $(srcdir)/f/g77.texi; \ - texindex g77.??; \ - TEXINPUTS=$(srcdir)/f:$$TEXINPUTS tex $(srcdir)/f/g77.texi; \ - mv g77.dvi f; \ - else true; fi - -# This dance is all about producing accurate documentation for g77's -# intrinsics with minimum fuss. f/ansify appends "\n\" to C strings -# so ANSI C compilers can compile f/intdoc.h -- gcc can compile f/intdoc.in -# directly, if f/intdoc.c #include'd that, but we don't want to force -# people to install gcc just to build the documentation. We use the -# C format for f/intdoc.in in the first place to allow a fairly "free", -# but widely known format for documentation -- basically anyone who knows -# how to write texinfo source and enclose it in C constants can handle -# it, and f/ansify allows them to not even end lines with "\n\". So, -# essentially, the C preprocessor and compiler are used to enter the -# document snippets into a data base via name lookup, rather than duplicating -# that kind of code here. And we use f/intdoc.c instead of straight -# texinfo in the first place so that as much information as possible -# contained in f/intrin.def can be inserted directly and reliably into -# the documentation. That's better than replicating it, because it -# reduces the likelihood of discrepancies between the docs and the compiler -# itself, which uses f/intrin.def; in fact, many bugs in f/intrin.def have -# been found only upon reading the documentation that was automatically -# produced from it. -$(srcdir)/f/intdoc.texi: f/intdoc.c f/intdoc.in f/ansify.c f/intrin.def f/intrin.h - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 ]; then \ - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(INCLUDES) \ - `echo $(srcdir)/f/ansify.c | sed 's,^\./,,'` -o f/ansify; \ - f/ansify < $(srcdir)/f/intdoc.in > f/intdoc.h0 $(srcdir)/f/intdoc.in; \ - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) $(INCLUDES) -I./f \ - `echo $(srcdir)/f/intdoc.c | sed 's,^\./,,'` -o f/intdoc; \ - f/intdoc > $(srcdir)/f/intdoc.texi; \ - rm f/intdoc f/ansify f/intdoc.h0; \ - else true; fi - -$(srcdir)/f/BUGS: f/bugs0.texi f/bugs.texi - cd $(srcdir)/f; $(MAKEINFO) -D BUGSONLY --no-header --no-split \ - --no-validate -o BUGS bugs0.texi - -$(srcdir)/f/INSTALL: f/install0.texi f/g77install.texi - cd $(srcdir)/f; $(MAKEINFO) -D INSTALLONLY --no-header --no-split \ - --no-validate -o INSTALL install0.texi - -$(srcdir)/f/NEWS: f/news0.texi f/news.texi - cd $(srcdir)/f; $(MAKEINFO) -D NEWSONLY --no-header --no-split \ - --no-validate -o NEWS news0.texi - -f77.rebuilt: f/g77.info $(srcdir)/f/BUGS $(srcdir)/f/INSTALL \ - $(srcdir)/f/NEWS - -# -# Install hooks: -# f771 is installed elsewhere as part of $(COMPILERS). - -f77.install-normal: - -# Install the driver program as $(target)-g77 -# and also as either g77 (if native) or $(tooldir)/bin/g77. -f77.install-common: - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - -if [ -f lang-f77 -a -f f771$(exeext) ] ; then \ - if [ -f g77-cross$(exeext) ] ; then \ - rm -f $(bindir)/$(G77_CROSS_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g77-cross$(exeext) $(bindir)/$(G77_CROSS_NAME)$(exeext); \ - chmod a+x $(bindir)/$(G77_CROSS_NAME)$(exeext); \ - else \ - rm -f $(bindir)/$(G77_INSTALL_NAME)$(exeext); \ - $(INSTALL_PROGRAM) g77$(exeext) $(bindir)/$(G77_INSTALL_NAME)$(exeext); \ - chmod a+x $(bindir)/$(G77_INSTALL_NAME)$(exeext); \ - fi ; \ - else true; fi - @if [ -f f77-install-ok -o -f $(srcdir)/f77-install-ok ]; then \ - echo ''; \ - echo 'Warning: egcs no longer installs an f77 command.'; \ - echo ' You must do so yourself. For more information,'; \ - echo ' read "Distributing Binaries" in the egcs g77 docs.'; \ - echo ' (To turn off this warning, delete the file'; \ - echo ' f77-install-ok in the source or build directory.)'; \ - echo ''; \ - else true; fi - -# $(INSTALL_DATA) might be a relative pathname, so we can't cd into srcdir -# to do the install. The sed rule was copied from stmp-int-hdrs. -f77.install-info: f77.info - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - if [ -f lang-f77 -a -f f/g77.info ] ; then \ - rm -f $(infodir)/g77.info*; \ - for f in f/g77.info*; do \ - realfile=`echo $$f | sed -e 's|.*/\([^/]*\)$$|\1|'`; \ - $(INSTALL_DATA) $$f $(infodir)/$$realfile; \ - done; \ - chmod a-x $(infodir)/g77.info*; \ - else true; fi - @if [ -f lang-f77 -a -f $(srcdir)/f/g77.info ] ; then \ - if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ - echo " install-info --info-dir=$(infodir) $(infodir)/g77.info"; \ - install-info --info-dir=$(infodir) $(infodir)/g77.info || : ; \ - else : ; fi; \ - else : ; fi - -f77.install-man: $(srcdir)/f/g77.1 - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - -if [ -f lang-f77 -a -f f771$(exeext) ] ; then \ - if [ -f g77-cross$(exeext) ] ; then \ - rm -f $(man1dir)/$(G77_CROSS_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/f/g77.1 $(man1dir)/$(G77_CROSS_NAME)$(manext); \ - chmod a-x $(man1dir)/$(G77_CROSS_NAME)$(manext); \ - else \ - rm -f $(man1dir)/$(G77_INSTALL_NAME)$(manext); \ - $(INSTALL_DATA) $(srcdir)/f/g77.1 $(man1dir)/$(G77_INSTALL_NAME)$(manext); \ - chmod a-x $(man1dir)/$(G77_INSTALL_NAME)$(manext); \ - fi; \ - else true; fi - -f77.uninstall: - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - @if [ -f lang-f77 ] ; then \ - if $(SHELL) -c 'install-info --version | sed 1q | fgrep -s -v -i debian' >/dev/null 2>&1; then \ - echo " install-info --delete --info-dir=$(infodir) $(infodir)/g77.info"; \ - install-info --delete --info-dir=$(infodir) $(infodir)/g77.info || : ; \ - else : ; fi; \ - else : ; fi - -if [ -f lang-f77 ]; then \ - rm -rf $(bindir)/$(G77_INSTALL_NAME)$(exeext); \ - rm -rf $(bindir)/$(G77_CROSS_NAME)$(exeext); \ - rm -rf $(man1dir)/$(G77_INSTALL_NAME)$(manext); \ - rm -rf $(man1dir)/$(G77_CROSS_NAME)$(manext); \ - rm -rf $(infodir)/g77.info*; \ - fi -# -# Clean hooks: -# A lot of the ancillary files are deleted by the main makefile. -# We just have to delete files specific to us. - -f77.mostlyclean: - -rm -f f/*$(objext) - -rm -f f/fini f/stamp-str f/str-*.h f/str-*.j - -rm -f f/intdoc f/ansify f/intdoc.h0 - -rm -f g77.aux g77.cps g77.ky g77.toc g77.vr g77.fn g77.kys \ - g77.pg g77.tp g77.vrs g77.cp g77.fns g77.log g77.pgs g77.tps -f77.clean: - -rm -f g77.c g77.o g77spec.o g77version.o -f77.distclean: - -rm -f lang-f77 f/Makefile -f77.extraclean: -f77.maintainer-clean: - -rm -f f/g77.info* f/g77.*aux f/TAGS f/BUGS f/INSTALL f/NEWS f/intdoc.texi -# -# Stage hooks: -# The main makefile has already created stage?/f. - -G77STAGESTUFF = f/*$(objext) f/fini f/stamp-str f/str-*.h f/str-*.j \ - lang-f77 g77.c g77.o g77spec.o g77version.o - -f77.stage1: stage1-start - -if [ -f lang-f77 ]; then \ - mv -f $(G77STAGESTUFF) stage1/f; \ - fi -f77.stage2: stage2-start - -if [ -f lang-f77 ]; then \ - mv -f $(G77STAGESTUFF) stage2/f; \ - fi -f77.stage3: stage3-start - -if [ -f lang-f77 ]; then \ - mv -f $(G77STAGESTUFF) stage3/f; \ - fi -f77.stage4: stage4-start - -if [ -f lang-f77 ]; then \ - mv -f $(G77STAGESTUFF) stage4/f; \ - fi -# -# Maintenance hooks: - -# This target creates the files that can be rebuilt, but go in the -# distribution anyway. It then copies the files to the distdir directory. -f77.distdir: f77.rebuilt - case "$(LANGUAGES)" in \ - *[fF]77*) touch lang-f77;; \ - *) rm -f lang-f77;; \ - esac - -if [ -f lang-f77 ]; then \ - mkdir tmp/f; \ - cd f; \ - for file in *[0-9a-zA-Z+]; do \ - $(LN_S) $$file ../tmp/f; \ - done; \ - fi diff --git a/gcc/f/Makefile.in b/gcc/f/Makefile.in deleted file mode 100755 index 96975a5..0000000 --- a/gcc/f/Makefile.in +++ /dev/null @@ -1,529 +0,0 @@ -# Makefile for GNU F77 compiler. -# Copyright (C) 1995-1998 Free Software Foundation, Inc. - -#This file is part of GNU Fortran. - -#GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -#02111-1307, USA. - -# The makefile built from this file lives in the language subdirectory. -# Its purpose is to provide support for: -# -# 1) recursion where necessary, and only then (building .o's), and -# 2) building and debugging f771 from the language subdirectory, and -# 3) nothing else. -# -# The parent makefile handles all other chores, with help from the -# language makefile fragment, of course. -# -# The targets for external use are: -# all, TAGS, ???mostlyclean, ???clean. - -# Suppress smart makes who think they know how to automake Yacc files -.y.c: - -# Variables that exist for you to override. -# See below for how to change them for certain systems. - -ALLOCA = - -# Various ways of specifying flags for compilations: -# CFLAGS is for the user to override to, e.g., do a bootstrap with -O2. -# BOOT_CFLAGS is the value of CFLAGS to pass -# to the stage2 and stage3 compilations -# XCFLAGS is used for most compilations but not when using the GCC just built. -XCFLAGS = -CFLAGS = -g -BOOT_CFLAGS = -O $(CFLAGS) -# These exists to be overridden by the x-* and t-* files, respectively. -X_CFLAGS = -T_CFLAGS = - -X_CPPFLAGS = -T_CPPFLAGS = - -CC = @CC@ -BISON = bison -BISONFLAGS = -LEX = flex -LEXFLAGS = -AR = ar -AR_FLAGS = rc -SHELL = /bin/sh -MAKEINFO = makeinfo -TEXI2DVI = texi2dvi - -# Define this as & to perform parallel make on a Sequent. -# Note that this has some bugs, and it seems currently necessary -# to compile all the gen* files first by hand to avoid erroneous results. -P = - -# This is used in the definition of SUBDIR_USE_ALLOCA. -# ??? Perhaps it would be better if it just looked for *gcc*. -OLDCC = cc - -# This is used instead of ALL_CFLAGS when compiling with GCC_FOR_TARGET. -# It omits XCFLAGS, and specifies -B./. -# It also specifies -B$(tooldir)/ to find as and ld for a cross compiler. -GCC_CFLAGS=$(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) - -# Tools to use when building a cross-compiler. -# These are used because `configure' appends `cross-make' -# to the makefile when making a cross-compiler. - -target=@target@ -xmake_file=@dep_host_xmake_file@ -tmake_file=@dep_tmake_file@ - -# Directory where sources are, from where we are. -srcdir = @srcdir@ -VPATH = @srcdir@ - -# Additional system libraries to link with. -CLIB= - -# Change this to a null string if obstacks are installed in the -# system library. -OBSTACK=obstack.o - -# Choose the real default target. -ALL=all - -# End of variables for you to override. - -# Definition of `all' is here so that new rules inserted by sed -# do not specify the default target. -all: all.indirect - -# This tells GNU Make version 3 not to put all variables in the environment. -.NOEXPORT: - -# sed inserts variable overrides after the following line. -####target overrides -@target_overrides@ -####host overrides -@host_overrides@ -####cross overrides -@cross_defines@ -@cross_overrides@ -####build overrides -@build_overrides@ -# -# Now figure out from those variables how to compile and link. - -all.indirect: Makefile ../f771$(exeext) - -# IN_GCC tells obstack.h that we are using gcc's <stddef.h> file. -INTERNAL_CFLAGS = $(CROSS) -DIN_GCC @extra_c_flags@ - -# This is the variable actually used when we compile. -ALL_CFLAGS = $(INTERNAL_CFLAGS) $(X_CFLAGS) $(T_CFLAGS) $(CFLAGS) $(XCFLAGS) -W -Wall - -# Likewise. -ALL_CPPFLAGS = $(CPPFLAGS) $(X_CPPFLAGS) $(T_CPPFLAGS) - -# We should be compiling with the built compiler, for which -# BOOT_LDFLAGS is appropriate. (Formerly we had a separate -# F771_LDFLAGS, but the ld flags can be taken care of by the target -# configuration files in egcs.) -LDFLAGS=$(BOOT_LDFLAGS) - -# Even if ALLOCA is set, don't use it if compiling with GCC. - -SUBDIR_OBSTACK = `if [ x$(OBSTACK) != x ]; then echo ../$(OBSTACK); else true; fi` -SUBDIR_USE_ALLOCA = `case "${CC}" in "${OLDCC}") if [ x$(ALLOCA) != x ]; then echo ../$(ALLOCA); else true; fi ;; esac` -SUBDIR_MALLOC = `if [ x$(MALLOC) != x ]; then echo ../$(MALLOC); else true; fi` - -# How to link with both our special library facilities -# and the system's installed libraries. -LIBS = $(SUBDIR_OBSTACK) $(SUBDIR_USE_ALLOCA) $(SUBDIR_MALLOC) $(CLIB) - -# Specify the directories to be searched for header files. -# Both . and srcdir are used, in that order, -# so that tm.h and config.h will be found in the compilation -# subdirectory rather than in the source directory. -INCLUDES = -I. -I.. -I$(srcdir) -I$(srcdir)/.. -I$(srcdir)/../config -I$(srcdir)/../../include - -# Always use -I$(srcdir)/config when compiling. -.c.o: - $(CC) -c $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) $< - -# -# Lists of files for various purposes. - -# Language-specific object files for g77 - -F77_OBJS = \ - bad.o \ - bit.o \ - bld.o \ - com.o \ - data.o \ - equiv.o \ - expr.o \ - global.o \ - implic.o \ - info.o \ - intrin.o \ - lab.o \ - lex.o \ - malloc.o \ - name.o \ - parse.o \ - proj.o \ - src.o \ - st.o \ - sta.o \ - stb.o \ - stc.o \ - std.o \ - ste.o \ - storag.o \ - stp.o \ - str.o \ - sts.o \ - stt.o \ - stu.o \ - stv.o \ - stw.o \ - symbol.o \ - target.o \ - top.o \ - type.o \ - version.o \ - where.o - -# Language-independent object files. -OBJS = `cat ../stamp-objlist` -OBJDEPS = ../stamp-objlist - -compiler: ../f771$(exeext) -../f771$(exeext): $(P) $(F77_OBJS) $(OBJDEPS) $(LIBDEPS) - rm -f f771$(exeext) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(F77_OBJS) $(OBJS) $(LIBS) - -Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure - cd ..; $(SHELL) config.status - -native: config.status ../f771$(exeext) -# -# Compiling object files from source files. - -# Note that dependencies on obstack.h are not written -# because that file is not part of GCC. - -# F77 language-specific files. - -# These macros expand to the corresponding g77-source .j files plus -# the gcc-source files involved (each file itself, plus whatever -# files on which it depends, but without including stuff resulting -# from configuration, since we can't guess at that). The files -# that live in a distclean'd gcc source directory have "$(srcdir)/" -# prefixes, while the others don't because they'll be created -# only in the build directory. -ASSERT_H = $(srcdir)/assert.j $(srcdir)/../assert.h -CONFIG_H = $(srcdir)/config.j ../config.h -CONVERT_H = $(srcdir)/convert.j $(srcdir)/../convert.h -FLAGS_H = $(srcdir)/flags.j $(srcdir)/../flags.h -GLIMITS_H = $(srcdir)/glimits.j $(srcdir)/../glimits.h -HCONFIG_H = $(srcdir)/hconfig.j ../hconfig.h -INPUT_H = $(srcdir)/input.j $(srcdir)/../input.h -OUTPUT_H = $(srcdir)/output.j $(srcdir)/../output.h -RTL_H = $(srcdir)/rtl.j $(srcdir)/../rtl.h $(srcdir)/../rtl.def \ - $(srcdir)/../machmode.h $(srcdir)/../machmode.def -SYSTEM_H = $(srcdir)/system.j $(srcdir)/../system.h -TCONFIG_H = $(srcdir)/tconfig.j ../tconfig.h -TM_H = $(srcdir)/tm.j ../tm.h -TOPLEV_H = $(srcdir)/toplev.j $(srcdir)/../toplev.h -TREE_H = $(srcdir)/tree.j $(srcdir)/../tree.h $(srcdir)/../real.h \ - $(srcdir)/../tree.def $(srcdir)/../machmode.h $(srcdir)/../machmode.def - -#Build the first part of this list with the command line: -# cd gcc/; make deps-kinda -f f/Makefile.in -#Note that this command uses the host C compiler; -# use HOST_CC="./xgcc -B./" to use GCC in the build directory, for example. -#Also note that this particular build file seems to want to use -# substitions: $(CONFIG_H) for config.h; $(TREE_H) for tree.h; -# $(RTL_H) for rtl.h; etc.. deps-kinda uses a sed script to do those -# substitutions, plus others for elegance. - -ansify.o: ansify.c $(HCONFIG_H) $(SYSTEM_H) $(ASSERT_H) -bad.o: bad.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) bad.h bad.def where.h \ - $(GLIMITS_H) top.h malloc.h $(FLAGS_H) com.h com-rt.def $(TREE_H) bld.h \ - bld-op.def bit.h info.h info-b.def info-k.def info-w.def target.h \ - lex.h type.h intrin.h intrin.def lab.h symbol.h symbol.def equiv.h \ - storag.h global.h name.h $(TOPLEV_H) -bit.o: bit.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(GLIMITS_H) bit.h \ - malloc.h -bld.o: bld.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) bld.h bld-op.def bit.h \ - malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def -com.o: com.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(FLAGS_H) $(RTL_H) $(TOPLEV_H) \ - $(TREE_H) $(OUTPUT_H) $(CONVERT_H) com.h com-rt.def bld.h bld-op.def bit.h \ - malloc.h info.h info-b.def info-k.def info-w.def target.h bad.h \ - bad.def where.h $(GLIMITS_H) top.h lex.h type.h intrin.h intrin.def \ - lab.h symbol.h symbol.def equiv.h storag.h global.h name.h expr.h \ - implic.h src.h st.h -data.o: data.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) data.h bld.h \ - bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h \ - lex.h type.h lab.h storag.h symbol.h symbol.def equiv.h global.h \ - name.h intrin.h intrin.def expr.h st.h -equiv.o: equiv.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) equiv.h bld.h \ - bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h \ - lex.h type.h lab.h storag.h symbol.h symbol.def global.h name.h \ - intrin.h intrin.def data.h -expr.o: expr.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) expr.h bld.h \ - bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h \ - lex.h type.h lab.h storag.h symbol.h symbol.def equiv.h global.h \ - name.h intrin.h intrin.def implic.h src.h st.h stamp-str -fini.o: fini.c proj.h $(HCONFIG_H) $(SYSTEM_H) $(ASSERT_H) malloc.h -global.o: global.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) global.h info.h \ - info-b.def info-k.def info-w.def target.h $(TREE_H) bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h lex.h type.h name.h symbol.h \ - symbol.def bld.h bld-op.def bit.h com.h com-rt.def lab.h storag.h \ - intrin.h intrin.def equiv.h -implic.o: implic.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) implic.h info.h \ - info-b.def info-k.def info-w.def target.h $(TREE_H) bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h lex.h type.h symbol.h symbol.def \ - bld.h bld-op.def bit.h com.h com-rt.def lab.h storag.h intrin.h \ - intrin.def equiv.h global.h name.h src.h -info.o: info.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) info.h info-b.def \ - info-k.def info-w.def target.h $(TREE_H) bad.h bad.def where.h $(GLIMITS_H) \ - top.h malloc.h lex.h type.h -intdoc.o: intdoc.c $(HCONFIG_H) $(SYSTEM_H) $(ASSERT_H) intrin.h intrin.def \ - intdoc.h0 intdoc.h0 -intrin.o: intrin.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) intrin.h \ - intrin.def bld.h bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h lex.h type.h lab.h storag.h symbol.h \ - symbol.def equiv.h global.h name.h expr.h src.h -lab.o: lab.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) lab.h com.h com-rt.def \ - $(TREE_H) bld.h bld-op.def bit.h malloc.h info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h intrin.h intrin.def symbol.h symbol.def equiv.h storag.h \ - global.h name.h -lex.o: lex.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) top.h malloc.h where.h \ - $(GLIMITS_H) bad.h bad.def com.h com-rt.def $(TREE_H) bld.h bld-op.def \ - bit.h info.h info-b.def info-k.def info-w.def target.h lex.h type.h \ - intrin.h intrin.def lab.h symbol.h symbol.def equiv.h storag.h \ - global.h name.h src.h $(FLAGS_H) $(INPUT_H) $(TOPLEV_H) $(OUTPUT_H) -malloc.o: malloc.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) malloc.h -name.o: name.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) bad.h bad.def where.h \ - $(GLIMITS_H) top.h malloc.h name.h global.h info.h info-b.def info-k.def \ - info-w.def target.h $(TREE_H) lex.h type.h symbol.h symbol.def bld.h \ - bld-op.def bit.h com.h com-rt.def lab.h storag.h intrin.h intrin.def \ - equiv.h src.h -parse.o: parse.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) top.h malloc.h \ - where.h $(GLIMITS_H) com.h com-rt.def $(TREE_H) bld.h bld-op.def bit.h \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def lex.h \ - type.h intrin.h intrin.def lab.h symbol.h symbol.def equiv.h storag.h \ - global.h name.h version.h $(FLAGS_H) -proj.o: proj.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(GLIMITS_H) -src.o: src.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) src.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h -st.o: st.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) st.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h lex.h symbol.h symbol.def bld.h \ - bld-op.def bit.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h type.h lab.h storag.h intrin.h intrin.def equiv.h \ - global.h name.h sta.h stamp-str stb.h expr.h stp.h stt.h stc.h std.h \ - stv.h stw.h ste.h sts.h stu.h -sta.o: sta.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) sta.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h lex.h stamp-str symbol.h symbol.def \ - bld.h bld-op.def bit.h com.h com-rt.def $(TREE_H) info.h info-b.def \ - info-k.def info-w.def target.h type.h lab.h storag.h intrin.h \ - intrin.def equiv.h global.h name.h implic.h stb.h expr.h stp.h stt.h \ - stc.h std.h stv.h stw.h -stb.o: stb.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stb.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h expr.h bld.h bld-op.def bit.h com.h \ - com-rt.def $(TREE_H) info.h info-b.def info-k.def info-w.def target.h \ - lex.h type.h lab.h storag.h symbol.h symbol.def equiv.h global.h \ - name.h intrin.h intrin.def stp.h stt.h stamp-str src.h sta.h stc.h -stc.o: stc.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stc.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h bld.h bld-op.def bit.h com.h \ - com-rt.def $(TREE_H) info.h info-b.def info-k.def info-w.def target.h \ - lex.h type.h lab.h storag.h symbol.h symbol.def equiv.h global.h \ - name.h intrin.h intrin.def expr.h stp.h stt.h stamp-str data.h implic.h \ - src.h sta.h std.h stv.h stw.h -std.o: std.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) std.h bld.h bld-op.def \ - bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def stp.h stt.h stamp-str stv.h stw.h sta.h ste.h sts.h -ste.o: ste.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(RTL_H) $(TOPLEV_H) ste.h \ - bld.h bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) info.h \ - info-b.def info-k.def info-w.def target.h bad.h bad.def where.h \ - $(GLIMITS_H) top.h lex.h type.h lab.h storag.h symbol.h symbol.def \ - equiv.h global.h name.h intrin.h intrin.def stp.h stt.h stamp-str sts.h \ - stv.h stw.h expr.h sta.h -storag.o: storag.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) storag.h bld.h \ - bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h \ - lex.h type.h lab.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def data.h -stp.o: stp.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stp.h bld.h bld-op.def \ - bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def stt.h -str.o: str.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) src.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h malloc.h stamp-str lex.h -sts.o: sts.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) sts.h malloc.h com.h \ - com-rt.def $(TREE_H) bld.h bld-op.def bit.h info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h intrin.h intrin.def lab.h symbol.h symbol.def equiv.h storag.h \ - global.h name.h -stt.o: stt.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stt.h top.h malloc.h \ - where.h $(GLIMITS_H) bld.h bld-op.def bit.h com.h com-rt.def $(TREE_H) \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def stp.h expr.h sta.h stamp-str -stu.o: stu.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) bld.h bld-op.def bit.h \ - malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def implic.h stu.h sta.h stamp-str -stv.o: stv.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stv.h lab.h com.h \ - com-rt.def $(TREE_H) bld.h bld-op.def bit.h malloc.h info.h info-b.def \ - info-k.def info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h \ - lex.h type.h intrin.h intrin.def symbol.h symbol.def equiv.h storag.h \ - global.h name.h -stw.o: stw.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) stw.h bld.h bld-op.def \ - bit.h malloc.h com.h com-rt.def $(TREE_H) info.h info-b.def info-k.def \ - info-w.def target.h bad.h bad.def where.h $(GLIMITS_H) top.h lex.h \ - type.h lab.h storag.h symbol.h symbol.def equiv.h global.h name.h \ - intrin.h intrin.def stv.h sta.h stamp-str -symbol.o: symbol.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) symbol.h \ - symbol.def bld.h bld-op.def bit.h malloc.h com.h com-rt.def $(TREE_H) \ - info.h info-b.def info-k.def info-w.def target.h bad.h bad.def \ - where.h $(GLIMITS_H) top.h lex.h type.h lab.h storag.h intrin.h \ - intrin.def equiv.h global.h name.h src.h st.h -target.o: target.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(GLIMITS_H) \ - target.h $(TREE_H) bad.h bad.def where.h top.h malloc.h info.h \ - info-b.def info-k.def info-w.def type.h lex.h -top.o: top.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) top.h malloc.h where.h \ - $(GLIMITS_H) bad.h bad.def bit.h bld.h bld-op.def com.h com-rt.def \ - $(TREE_H) info.h info-b.def info-k.def info-w.def target.h lex.h type.h \ - lab.h storag.h symbol.h symbol.def equiv.h global.h name.h intrin.h \ - intrin.def data.h expr.h implic.h src.h st.h $(FLAGS_H) $(TOPLEV_H) -type.o: type.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) type.h malloc.h -version.o: version.c -where.o: where.c proj.h $(CONFIG_H) $(SYSTEM_H) $(ASSERT_H) where.h $(GLIMITS_H) \ - top.h malloc.h lex.h - -# The rest of this list (Fortran 77 language-specific files) is hand-generated. - -stamp-str: str-1t.h str-1t.j str-2t.h str-2t.j \ - str-fo.h str-fo.j str-io.h str-io.j str-nq.h str-nq.j \ - str-op.h str-op.j str-ot.h str-ot.j - touch stamp-str - -str-1t.h str-1t.j: fini str-1t.fin - ./fini `echo $(srcdir)/str-1t.fin | sed 's,^\./,,'` str-1t.j str-1t.h - -str-2t.h str-2t.j: fini str-2t.fin - ./fini `echo $(srcdir)/str-2t.fin | sed 's,^\./,,'` str-2t.j str-2t.h - -str-fo.h str-fo.j: fini str-fo.fin - ./fini `echo $(srcdir)/str-fo.fin | sed 's,^\./,,'` str-fo.j str-fo.h - -str-io.h str-io.j: fini str-io.fin - ./fini `echo $(srcdir)/str-io.fin | sed 's,^\./,,'` str-io.j str-io.h - -str-nq.h str-nq.j: fini str-nq.fin - ./fini `echo $(srcdir)/str-nq.fin | sed 's,^\./,,'` str-nq.j str-nq.h - -str-op.h str-op.j: fini str-op.fin - ./fini `echo $(srcdir)/str-op.fin | sed 's,^\./,,'` str-op.j str-op.h - -str-ot.h str-ot.j: fini str-ot.fin - ./fini `echo $(srcdir)/str-ot.fin | sed 's,^\./,,'` str-ot.j str-ot.h - -fini: fini.o proj-h.o - $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o fini fini.o proj-h.o - -fini.o: - $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ - `echo $(srcdir)/fini.c | sed 's,^\./,,'` -o $@ - -# Like proj.o, but depends on hconfig.h instead of config.h. -proj-h.o: proj.c proj.h $(HCONFIG_H) $(SYSTEM_H) $(ASSERT_H) $(GLIMITS_H) - $(HOST_CC) -c -DUSE_HCONFIG $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \ - `echo $(srcdir)/proj.c | sed 's,^\./,,'` -o $@ - -# Other than str-*.j, the *.j files are dummy #include files -# that normally just #include the corresponding back-end *.h -# files, but not if MAKING_DEPENDENCIES is #defined. The str-*.j -# files also are not actually included if MAKING_DEPENDENCIES -# is #defined. The point of all this is to come up with a clean -# dependencies list whether working in a clean directory, such -# that str-*.j and such do not exist, or in a directory full -# of already-built files. Any dependency on a str-*.j file -# implies a dependency on str.h, so we key on that to replace -# it with stamp-str, and dependencies on the other *.j files -# are generally left alone (modulo special macros like RTL_H) -# because we might not want to recompile all of g77 just -# because a back-end file changes. MG is usually "-MG" but -# should be defined with "make MG= deps-kinda..." if using -# a compiler that doesn't support -MG (gcc does as of 2.6) -- -# it prevents diagnostics when an #include file is missing, -# as will be the case with proj.h in a clean directory. -MG=-MG -deps-kinda: - $(HOST_CC) -DMAKING_DEPENDENCIES -MM $(MG) *.c 2>&1 | \ - sed -e 's: \([.]/\)*assert[.]j: $$(ASSERT_H):g' \ - -e 's: \([.]/\)*config[.]j: $$(CONFIG_H):g' \ - -e 's: \([.]/\)*convert[.]j: $$(CONVERT_H):g' \ - -e 's: \([.]/\)*flags[.]j: $$(FLAGS_H):g' \ - -e 's: \([.]/\)*glimits[.]j: $$(GLIMITS_H):g' \ - -e 's: \([.]/\)*hconfig[.]j: $$(HCONFIG_H):g' \ - -e 's: \([.]/\)*input[.]j: $$(INPUT_H):g' \ - -e 's: \([.]/\)*output[.]j: $$(OUTPUT_H):g' \ - -e 's: \([.]/\)*rtl[.]j: $$(RTL_H):g' \ - -e 's: \([.]/\)*system[.]j: $$(SYSTEM_H):g' \ - -e 's: \([.]/\)*tconfig[.]j: $$(TCONFIG_H):g' \ - -e 's: \([.]/\)*tm[.]j: $$(TM_H):g' \ - -e 's: \([.]/\)*toplev[.]j: $$(TOPLEV_H):g' \ - -e 's: \([.]/\)*tree[.]j: $$(TREE_H):g' \ - -e 's: \([.]/\)*str[.]h: stamp-str:g' \ - -e 's:.*g77spec.*::g' \ - -e 's%^\(.*\)[ ]*: %\1: %g' - -# This rule is just a handy way to build the g77 derived files without -# having the gcc source tree around. -g77-only: force - if [ -f g77.texi ] ; then \ - (cd ..; $(MAKE) srcdir=. HOST_CC=cc HOST_CFLAGS=-g -f f/Make-lang.in f77.rebuilt); \ - else \ - $(MAKE) srcdir=. HOST_CC=cc HOST_CFLAGS=-g -f f/Make-lang.in f77.rebuilt; \ - fi - -# -# These exist for maintenance purposes. - -# Update the tags table. -TAGS: force - cd $(srcdir)/f ; \ - etags *.c *.h ; \ - echo 'l' | tr 'l' '\f' >> TAGS ; \ - etags -a ../*.h ../*.c; - -.PHONY: none all all.indirect f77.rebuilt compiler native deps-kinda g77-only TAGS force - -force: diff --git a/gcc/f/NEWS b/gcc/f/NEWS deleted file mode 100755 index 1bbefc2..0000000 --- a/gcc/f/NEWS +++ /dev/null @@ -1,1603 +0,0 @@ -This file lists recent changes to the GNU Fortran compiler. Copyright -(C) 1995, 96, 97, 1998 Free Software Foundation, Inc. You may copy, -distribute, and modify it freely as long as you preserve this copyright -notice and permission notice. - -News About GNU Fortran -********************** - - Changes made to recent versions of GNU Fortran are listed below, -with the most recent version first. - - The changes are generally listed in order: - - 1. Code-generation and run-time-library bug-fixes - - 2. Compiler and run-time-library crashes involving valid code that - have been fixed - - 3. New features - - 4. Fixes and enhancements to existing features - - 5. New diagnostics - - 6. Internal improvements - - 7. Miscellany - - This order is not strict--for example, some items involve a -combination of these elements. - - Note that two variants of `g77' are tracked below. The `egcs' -variant is described vis-a-vis previous versions of `egcs' and/or an -official FSF version, as appropriate. - - Therefore, `egcs' versions sometimes have multiple listings to help -clarify how they differ from other versions, though this can make -getting a complete picture of what a particular `egcs' version contains -somewhat more difficult. - -In 0.5.24 and `egcs' 1.1.1 (versus 0.5.23 and 1.1): -=================================================== - - * Fix `libg2c' so it performs an implicit `ENDFILE' operation (as - appropriate) whenever a `REWIND' is done. - - (This bug was introduced in 0.5.23 and `egcs' 1.1 in `g77''s - version of `libf2c'.) - - * Fix `libg2c' so it no longer crashes with a spurious diagnostic - upon doing any I/O following a direct formatted write. - - (This bug was introduced in 0.5.23 and `egcs' 1.1 in `g77''s - version of `libf2c'.) - - * Fix `g77' so it no longer crashes compiling references to the - `Rand' intrinsic on some systems. - - * Fix `g77' portion of installation process so it works better on - some systems (those with shells requiring `else true' clauses on - `if' constructs for the completion code to be set properly). - -In `egcs' 1.1 (versus 0.5.24): -============================== - - * Fix `g77' crash compiling code containing the construct - `CMPLX(0.)' or similar. - - * Fix `g77' crash (or apparently infinite run-time) when compiling - certain complicated expressions involving `COMPLEX' arithmetic - (especially multiplication). - - * Fix a code-generation bug that afflicted Intel x86 targets when - `-O2' was specified compiling, for example, an old version of the - `DNRM2' routine. - - The x87 coprocessor stack was being mismanaged in cases involving - assigned `GOTO' and `ASSIGN'. - - * Align static double-precision variables and arrays on Intel x86 - targets regardless of whether `-malign-double' is specified. - - Generally, this affects only local variables and arrays having the - `SAVE' attribute or given initial values via `DATA'. - -In `egcs' 1.1 (versus `egcs' 1.0.3): -==================================== - - * Fix bugs in the `libU77' intrinsic `HostNm' that wrote one byte - beyond the end of its `CHARACTER' argument, and in the `libU77' - intrinsics `GMTime' and `LTime' that overwrote their arguments. - - * Assumed arrays with negative bounds (such as `REAL A(-1:*)') no - longer elicit spurious diagnostics from `g77', even on systems - with pointers having different sizes than integers. - - This bug is not known to have existed in any recent version of - `gcc'. It was introduced in an early release of `egcs'. - - * Valid combinations of `EXTERNAL', passing that external as a dummy - argument without explicitly giving it a type, and, in a subsequent - program unit, referencing that external as an external function - with a different type no longer crash `g77'. - - * `CASE DEFAULT' no longer crashes `g77'. - - * The `-Wunused' option no longer issues a spurious warning about - the "master" procedure generated by `g77' for procedures - containing `ENTRY' statements. - - * Support `FORMAT(I<EXPR>)' when EXPR is a compile-time constant - `INTEGER' expression. - - * Fix `g77' `-g' option so procedures that use `ENTRY' can be - stepped through, line by line, in `gdb'. - - * Allow any `REAL' argument to intrinsics `Second' and `CPU_Time'. - - * Use `tempnam', if available, to open scratch files (as in - `OPEN(STATUS='SCRATCH')') so that the `TMPDIR' environment - variable, if present, is used. - - * `g77''s version of `libf2c' separates out the setting of global - state (such as command-line arguments and signal handling) from - `main.o' into distinct, new library archive members. - - This should make it easier to write portable applications that - have their own (non-Fortran) `main()' routine properly set up the - `libf2c' environment, even when `libf2c' (now `libg2c') is a - shared library. - - * `g77' no longer installs the `f77' command and `f77.1' man page in - the `/usr' or `/usr/local' heirarchy, even if the `f77-install-ok' - file exists in the source or build directory. See the - installation documentation for more information. - - * `g77' no longer installs the `libf2c.a' library and `f2c.h' - include file in the `/usr' or `/usr/local' heirarchy, even if the - `f2c-install-ok' or `f2c-exists-ok' files exist in the source or - build directory. See the installation documentation for more - information. - - * The `libf2c.a' library produced by `g77' has been renamed to - `libg2c.a'. It is installed only in the `gcc' "private" directory - heirarchy, `gcc-lib'. This allows system administrators and users - to choose which version of the `libf2c' library from `netlib' they - wish to use on a case-by-case basis. See the installation - documentation for more information. - - * The `f2c.h' include (header) file produced by `g77' has been - renamed to `g2c.h'. It is installed only in the `gcc' "private" - directory heirarchy, `gcc-lib'. This allows system administrators - and users to choose which version of the include file from - `netlib' they wish to use on a case-by-case basis. See the - installation documentation for more information. - - * The `g77' command now expects the run-time library to be named - `libg2c.a' instead of `libf2c.a', to ensure that a version other - than the one built and installed as part of the same `g77' version - is picked up. - - * During the configuration and build process, `g77' creates - subdirectories it needs only as it needs them. Other cleaning up - of the configuration and build process has been performed as well. - - * `install-info' now used to update the directory of Info - documentation to contain an entry for `g77' (during installation). - - * Some diagnostics have been changed from warnings to errors, to - prevent inadvertent use of the resulting, probably buggy, programs. - These mostly include diagnostics about use of unsupported features - in the `OPEN', `INQUIRE', `READ', and `WRITE' statements, and - about truncations of various sorts of constants. - - * Improve compilation of `FORMAT' expressions so that a null byte is - appended to the last operand if it is a constant. This provides a - cleaner run-time diagnostic as provided by `libf2c' for statements - like `PRINT '(I1', 42'. - - * Improve documentation and indexing. - - * The upgrade to `libf2c' as of 1998-06-18 should fix a variety of - problems, including those involving some uses of the `T' format - specifier, and perhaps some build (porting) problems as well. - -In 0.5.24 and `egcs' 1.1 (versus 0.5.23): -========================================= - - * `g77' no longer produces incorrect code and initial values for - `EQUIVALENCE' and `COMMON' aggregates that, due to "unnatural" - ordering of members vis-a-vis their types, require initial padding. - - * `g77' no longer crashes when compiling code containing - specification statements such as `INTEGER(KIND=7) PTR'. - - * `g77' now treats `%LOC(EXPR)' and `LOC(EXPR)' as "ordinary" - expressions when they are used as arguments in procedure calls. - This change applies only to global (filewide) analysis, making it - consistent with how `g77' actually generates code for these cases. - - Previously, `g77' treated these expressions as denoting special - "pointer" arguments for the purposes of filewide analysis. - - * The `g77' driver now ensures that `-lg2c' is specified in the link - phase prior to any occurrence of `-lm'. This prevents - accidentally linking to a routine in the SunOS4 `-lm' library when - the generated code wants to link to the one in `libf2c' (`libg2c'). - - * `g77' emits more debugging information when `-g' is used. - - This new information allows, for example, `which __g77_length_a' - to be used in `gdb' to determine the type of the phantom length - argument supplied with `CHARACTER' variables. - - This information pertains to internally-generated type, variable, - and other information, not to the longstanding deficiencies - vis-a-vis `COMMON' and `EQUIVALENCE'. - - * The F90 `Date_and_Time' intrinsic now is supported. - - * The F90 `System_Clock' intrinsic allows the optional arguments - (except for the `Count' argument) to be omitted. - - * Upgrade to `libf2c' as of 1998-06-18. - - * Improve documentation and indexing. - -In 0.5.23 (versus 0.5.22): -========================== - - * This release contains several regressions against version 0.5.22 - of `g77', due to using the "vanilla" `gcc' back end instead of - patching it to fix a few bugs and improve performance in a few - cases. - - *Note Actual Bugs We Haven't Fixed Yet: Actual Bugs, available in - plain-text format in `gcc/f/BUGS', for information on the known - bugs in this version, including the regressions. - - Features that have been dropped from this version of `g77' due to - their being implemented via `g77'-specific patches to the `gcc' - back end in previous releases include: - - - Support for `__restrict__' keyword, the options - `-fargument-alias', `-fargument-noalias', and - `-fargument-noalias-global', and the corresponding - alias-analysis code. - - (`egcs' has the alias-analysis code, but not the - `__restrict__' keyword. `egcs' `g77' users benefit from the - alias-analysis code despite the lack of the `__restrict__' - keyword, which is a C-language construct.) - - - Support for the GNU compiler options `-fmove-all-movables', - `-freduce-all-givs', and `-frerun-loop-opt'. - - (`egcs' supports these options. `g77' users of `egcs' - benefit from them even if they are not explicitly specified, - because the defaults are optimized for `g77' users.) - - - Support for the `-W' option warning about integer division by - zero. - - - The Intel x86-specific option `-malign-double' applying to - stack-allocated data as well as statically-allocate data. - - Note that the `gcc/f/gbe/' subdirectory has been removed from this - distribution as a result of `g77' no longer including patches for - the `gcc' back end. - - * Fix bugs in the `libU77' intrinsic `HostNm' that wrote one byte - beyond the end of its `CHARACTER' argument, and in the `libU77' - intrinsics `GMTime' and `LTime' that overwrote their arguments. - - * Support `gcc' version 2.8, and remove support for prior versions - of `gcc'. - - * Remove support for the `--driver' option, as `g77' now does all - the driving, just like `gcc'. - - * `CASE DEFAULT' no longer crashes `g77'. - - * Valid combinations of `EXTERNAL', passing that external as a dummy - argument without explicitly giving it a type, and, in a subsequent - program unit, referencing that external as an external function - with a different type no longer crash `g77'. - - * `g77' no longer installs the `f77' command and `f77.1' man page in - the `/usr' or `/usr/local' heirarchy, even if the `f77-install-ok' - file exists in the source or build directory. See the - installation documentation for more information. - - * `g77' no longer installs the `libf2c.a' library and `f2c.h' - include file in the `/usr' or `/usr/local' heirarchy, even if the - `f2c-install-ok' or `f2c-exists-ok' files exist in the source or - build directory. See the installation documentation for more - information. - - * The `libf2c.a' library produced by `g77' has been renamed to - `libg2c.a'. It is installed only in the `gcc' "private" directory - heirarchy, `gcc-lib'. This allows system administrators and users - to choose which version of the `libf2c' library from `netlib' they - wish to use on a case-by-case basis. See the installation - documentation for more information. - - * The `f2c.h' include (header) file produced by `g77' has been - renamed to `g2c.h'. It is installed only in the `gcc' "private" - directory heirarchy, `gcc-lib'. This allows system administrators - and users to choose which version of the include file from - `netlib' they wish to use on a case-by-case basis. See the - installation documentation for more information. - - * The `g77' command now expects the run-time library to be named - `libg2c.a' instead of `libf2c.a', to ensure that a version other - than the one built and installed as part of the same `g77' version - is picked up. - - * The `-Wunused' option no longer issues a spurious warning about - the "master" procedure generated by `g77' for procedures - containing `ENTRY' statements. - - * `g77''s version of `libf2c' separates out the setting of global - state (such as command-line arguments and signal handling) from - `main.o' into distinct, new library archive members. - - This should make it easier to write portable applications that - have their own (non-Fortran) `main()' routine properly set up the - `libf2c' environment, even when `libf2c' (now `libg2c') is a - shared library. - - * During the configuration and build process, `g77' creates - subdirectories it needs only as it needs them, thus avoiding - unnecessary creation of, for example, `stage1/f/runtime' when - doing a non-bootstrap build. Other cleaning up of the - configuration and build process has been performed as well. - - * `install-info' now used to update the directory of Info - documentation to contain an entry for `g77' (during installation). - - * Some diagnostics have been changed from warnings to errors, to - prevent inadvertent use of the resulting, probably buggy, programs. - These mostly include diagnostics about use of unsupported features - in the `OPEN', `INQUIRE', `READ', and `WRITE' statements, and - about truncations of various sorts of constants. - - * Improve documentation and indexing. - - * Upgrade to `libf2c' as of 1998-04-20. - - This should fix a variety of problems, including those involving - some uses of the `T' format specifier, and perhaps some build - (porting) problems as well. - -In 0.5.22 (versus 0.5.21): -========================== - - * Fix code generation for iterative `DO' loops that have one or more - references to the iteration variable, or to aliases of it, in - their control expressions. For example, `DO 10 J=2,J' now is - compiled correctly. - - * Fix a code-generation bug that afflicted Intel x86 targets when - `-O2' was specified compiling, for example, an old version of the - `DNRM2' routine. - - The x87 coprocessor stack was being mismanaged in cases involving - assigned `GOTO' and `ASSIGN'. - - * Fix `DTime' intrinsic so as not to truncate results to integer - values (on some systems). - - * Fix `Signal' intrinsic so it offers portable support for 64-bit - systems (such as Digital Alphas running GNU/Linux). - - * Fix run-time crash involving `NAMELIST' on 64-bit machines such as - Alphas. - - * Fix `g77' version of `libf2c' so it no longer produces a spurious - `I/O recursion' diagnostic at run time when an I/O operation (such - as `READ *,I') is interrupted in a manner that causes the program - to be terminated via the `f_exit' routine (such as via `C-c'). - - * Fix `g77' crash triggered by `CASE' statement with an omitted - lower or upper bound. - - * Fix `g77' crash compiling references to `CPU_Time' intrinsic. - - * Fix `g77' crash (or apparently infinite run-time) when compiling - certain complicated expressions involving `COMPLEX' arithmetic - (especially multiplication). - - * Fix `g77' crash on statements such as `PRINT *, - (REAL(Z(I)),I=1,2)', where `Z' is `DOUBLE COMPLEX'. - - * Fix a `g++' crash. - - * Support `FORMAT(I<EXPR>)' when EXPR is a compile-time constant - `INTEGER' expression. - - * Fix `g77' `-g' option so procedures that use `ENTRY' can be - stepped through, line by line, in `gdb'. - - * Fix a profiling-related bug in `gcc' back end for Intel x86 - architecture. - - * Allow any `REAL' argument to intrinsics `Second' and `CPU_Time'. - - * Allow any numeric argument to intrinsics `Int2' and `Int8'. - - * Use `tempnam', if available, to open scratch files (as in - `OPEN(STATUS='SCRATCH')') so that the `TMPDIR' environment - variable, if present, is used. - - * Rename the `gcc' keyword `restrict' to `__restrict__', to avoid - rejecting valid, existing, C programs. Support for `restrict' is - now more like support for `complex'. - - * Fix `-fpedantic' to not reject procedure invocations such as - `I=J()' and `CALL FOO()'. - - * Fix `-fugly-comma' to affect invocations of only external - procedures. Restore rejection of gratuitous trailing omitted - arguments to intrinsics, as in `I=MAX(3,4,,)'. - - * Fix compiler so it accepts `-fgnu-intrinsics-*' and - `-fbadu77-intrinsics-*' options. - - * Improve diagnostic messages from `libf2c' so it is more likely - that the printing of the active format string is limited to the - string, with no trailing garbage being printed. - - (Unlike `f2c', `g77' did not append a null byte to its compiled - form of every format string specified via a `FORMAT' statement. - However, `f2c' would exhibit the problem anyway for a statement - like `PRINT '(I)garbage', 1' by printing `(I)garbage' as the - format string.) - - * Improve compilation of `FORMAT' expressions so that a null byte is - appended to the last operand if it is a constant. This provides a - cleaner run-time diagnostic as provided by `libf2c' for statements - like `PRINT '(I1', 42'. - - * Fix various crashes involving code with diagnosed errors. - - * Fix cross-compilation bug when configuring `libf2c'. - - * Improve diagnostics. - - * Improve documentation and indexing. - - * Upgrade to `libf2c' as of 1997-09-23. This fixes a formatted-I/O - bug that afflicted 64-bit systems with 32-bit integers (such as - Digital Alpha running GNU/Linux). - -In `egcs' 1.0.2 (versus `egcs' 1.0.1): -====================================== - - * Fix `g77' crash triggered by `CASE' statement with an omitted - lower or upper bound. - - * Fix `g77' crash on statements such as `PRINT *, - (REAL(Z(I)),I=1,2)', where `Z' is `DOUBLE COMPLEX'. - - * Fix `-fPIC' (such as compiling for ELF targets) on the Intel x86 - architecture target so invalid assembler code is no longer - produced. - - * Fix `-fpedantic' to not reject procedure invocations such as - `I=J()' and `CALL FOO()'. - - * Fix `-fugly-comma' to affect invocations of only external - procedures. Restore rejection of gratuitous trailing omitted - arguments to intrinsics, as in `I=MAX(3,4,,)'. - - * Fix compiler so it accepts `-fgnu-intrinsics-*' and - `-fbadu77-intrinsics-*' options. - -In `egcs' 1.0.1 (versus `egcs' 1.0): -==================================== - - * Fix run-time crash involving `NAMELIST' on 64-bit machines such as - Alphas. - -In `egcs' 1.0 (versus 0.5.21): -============================== - - * Version 1.0 of `egcs' contains several regressions against version - 0.5.21 of `g77', due to using the "vanilla" `gcc' back end instead - of patching it to fix a few bugs and improve performance in a few - cases. - - *Note Actual Bugs We Haven't Fixed Yet: Actual Bugs, available in - plain-text format in `gcc/f/BUGS', for information on the known - bugs in this version, including the regressions. - - Features that have been dropped from this version of `g77' due to - their being implemented via `g77'-specific patches to the `gcc' - back end in previous releases include: - - - Support for the C-language `restrict' keyword. - - - Support for the `-W' option warning about integer division by - zero. - - - The Intel x86-specific option `-malign-double' applying to - stack-allocated data as well as statically-allocate data. - - Note that the `gcc/f/gbe/' subdirectory has been removed from this - distribution as a result of `g77' being fully integrated with the - `egcs' variant of the `gcc' back end. - - * Fix code generation for iterative `DO' loops that have one or more - references to the iteration variable, or to aliases of it, in - their control expressions. For example, `DO 10 J=2,J' now is - compiled correctly. - - * Fix `DTime' intrinsic so as not to truncate results to integer - values (on some systems). - - * Remove support for non-`egcs' versions of `gcc'. - - * Remove support for the `--driver' option, as `g77' now does all - the driving, just like `gcc'. - - * Allow any numeric argument to intrinsics `Int2' and `Int8'. - - * Improve diagnostic messages from `libf2c' so it is more likely - that the printing of the active format string is limited to the - string, with no trailing garbage being printed. - - (Unlike `f2c', `g77' did not append a null byte to its compiled - form of every format string specified via a `FORMAT' statement. - However, `f2c' would exhibit the problem anyway for a statement - like `PRINT '(I)garbage', 1' by printing `(I)garbage' as the - format string.) - - * Upgrade to `libf2c' as of 1997-09-23. This fixes a formatted-I/O - bug that afflicted 64-bit systems with 32-bit integers (such as - Digital Alpha running GNU/Linux). - -In 0.5.21: -========== - - * Fix a code-generation bug introduced by 0.5.20 caused by loop - unrolling (by specifying `-funroll-loops' or similar). This bug - afflicted all code compiled by version 2.7.2.2.f.2 of `gcc' (C, - C++, Fortran, and so on). - - * Fix a code-generation bug manifested when combining local - `EQUIVALENCE' with a `DATA' statement that follows the first - executable statement (or is treated as an executable-context - statement as a result of using the `-fpedantic' option). - - * Fix a compiler crash that occured when an integer division by a - constant zero is detected. Instead, when the `-W' option is - specified, the `gcc' back end issues a warning about such a case. - This bug afflicted all code compiled by version 2.7.2.2.f.2 of - `gcc' (C, C++, Fortran, and so on). - - * Fix a compiler crash that occurred in some cases of procedure - inlining. (Such cases became more frequent in 0.5.20.) - - * Fix a compiler crash resulting from using `DATA' or similar to - initialize a `COMPLEX' variable or array to zero. - - * Fix compiler crashes involving use of `AND', `OR', or `XOR' - intrinsics. - - * Fix compiler bug triggered when using a `COMMON' or `EQUIVALENCE' - variable as the target of an `ASSIGN' or assigned-`GOTO' statement. - - * Fix compiler crashes due to using the name of a some non-standard - intrinsics (such as `FTELL' or `FPUTC') as such and as the name of - a procedure or common block. Such dual use of a name in a program - is allowed by the standard. - - * Place automatic arrays on the stack, even if `SAVE' or the - `-fno-automatic' option is in effect. This avoids a compiler - crash in some cases. - - * The `-malign-double' option now reliably aligns `DOUBLE PRECISION' - optimally on Pentium and Pentium Pro architectures (586 and 686 in - `gcc'). - - * New option `-Wno-globals' disables warnings about "suspicious" use - of a name both as a global name and as the implicit name of an - intrinsic, and warnings about disagreements over the number or - natures of arguments passed to global procedures, or the natures - of the procedures themselves. - - The default is to issue such warnings, which are new as of this - version of `g77'. - - * New option `-fno-globals' disables diagnostics about potentially - fatal disagreements analysis problems, such as disagreements over - the number or natures of arguments passed to global procedures, or - the natures of those procedures themselves. - - The default is to issue such diagnostics and flag the compilation - as unsuccessful. With this option, the diagnostics are issued as - warnings, or, if `-Wno-globals' is specified, are not issued at - all. - - This option also disables inlining of global procedures, to avoid - compiler crashes resulting from coding errors that these - diagnostics normally would identify. - - * Diagnose cases where a reference to a procedure disagrees with the - type of that procedure, or where disagreements about the number or - nature of arguments exist. This avoids a compiler crash. - - * Fix parsing bug whereby `g77' rejected a second initialization - specification immediately following the first's closing `/' without - an intervening comma in a `DATA' statement, and the second - specification was an implied-DO list. - - * Improve performance of the `gcc' back end so certain complicated - expressions involving `COMPLEX' arithmetic (especially - multiplication) don't appear to take forever to compile. - - * Fix a couple of profiling-related bugs in `gcc' back end. - - * Integrate GNU Ada's (GNAT's) changes to the back end, which - consist almost entirely of bug fixes. These fixes are circa - version 3.10p of GNAT. - - * Include some other `gcc' fixes that seem useful in `g77''s version - of `gcc'. (See `gcc/ChangeLog' for details--compare it to that - file in the vanilla `gcc-2.7.2.3.tar.gz' distribution.) - - * Fix `libU77' routines that accept file and other names to strip - trailing blanks from them, for consistency with other - implementations. Blanks may be forcibly appended to such names by - appending a single null character (`CHAR(0)') to the significant - trailing blanks. - - * Fix `CHMOD' intrinsic to work with file names that have embedded - blanks, commas, and so on. - - * Fix `SIGNAL' intrinsic so it accepts an optional third `Status' - argument. - - * Fix `IDATE()' intrinsic subroutine (VXT form) so it accepts - arguments in the correct order. Documentation fixed accordingly, - and for `GMTIME()' and `LTIME()' as well. - - * Make many changes to `libU77' intrinsics to support existing code - more directly. - - Such changes include allowing both subroutine and function forms - of many routines, changing `MCLOCK()' and `TIME()' to return - `INTEGER(KIND=1)' values, introducing `MCLOCK8()' and `TIME8()' to - return `INTEGER(KIND=2)' values, and placing functions that are - intended to perform side effects in a new intrinsic group, - `badu77'. - - * Improve `libU77' so it is more portable. - - * Add options `-fbadu77-intrinsics-delete', - `-fbadu77-intrinsics-hide', and so on. - - * Fix crashes involving diagnosed or invalid code. - - * `g77' and `gcc' now do a somewhat better job detecting and - diagnosing arrays that are too large to handle before these cause - diagnostics during the assembler or linker phase, a compiler - crash, or generation of incorrect code. - - * Make some fixes to alias analysis code. - - * Add support for `restrict' keyword in `gcc' front end. - - * Support `gcc' version 2.7.2.3 (modified by `g77' into version - 2.7.2.3.f.1), and remove support for prior versions of `gcc'. - - * Incorporate GNAT's patches to the `gcc' back end into `g77''s, so - GNAT users do not need to apply GNAT's patches to build both GNAT - and `g77' from the same source tree. - - * Modify `make' rules and related code so that generation of Info - documentation doesn't require compilation using `gcc'. Now, any - ANSI C compiler should be adequate to produce the `g77' - documentation (in particular, the tables of intrinsics) from - scratch. - - * Add `INT2' and `INT8' intrinsics. - - * Add `CPU_TIME' intrinsic. - - * Add `ALARM' intrinsic. - - * `CTIME' intrinsic now accepts any `INTEGER' argument, not just - `INTEGER(KIND=2)'. - - * Warn when explicit type declaration disagrees with the type of an - intrinsic invocation. - - * Support `*f771' entry in `gcc' `specs' file. - - * Fix typo in `make' rule `g77-cross', used only for cross-compiling. - - * Fix `libf2c' build procedure to re-archive library if previous - attempt to archive was interrupted. - - * Change `gcc' to unroll loops only during the last invocation (of - as many as two invocations) of loop optimization. - - * Improve handling of `-fno-f2c' so that code that attempts to pass - an intrinsic as an actual argument, such as `CALL FOO(ABS)', is - rejected due to the fact that the run-time-library routine is, - effectively, compiled with `-ff2c' in effect. - - * Fix `g77' driver to recognize `-fsyntax-only' as an option that - inhibits linking, just like `-c' or `-S', and to recognize and - properly handle the `-nostdlib', `-M', `-MM', `-nodefaultlibs', - and `-Xlinker' options. - - * Upgrade to `libf2c' as of 1997-08-16. - - * Modify `libf2c' to consistently and clearly diagnose recursive I/O - (at run time). - - * `g77' driver now prints version information (such as produced by - `g77 -v') to `stderr' instead of `stdout'. - - * The `.r' suffix now designates a Ratfor source file, to be - preprocessed via the `ratfor' command, available separately. - - * Fix some aspects of how `gcc' determines what kind of system is - being configured and what kinds are supported. For example, GNU - Linux/Alpha ELF systems now are directly supported. - - * Improve diagnostics. - - * Improve documentation and indexing. - - * Include all pertinent files for `libf2c' that come from - `netlib.bell-labs.com'; give any such files that aren't quite - accurate in `g77''s version of `libf2c' the suffix `.netlib'. - - * Reserve `INTEGER(KIND=0)' for future use. - -In 0.5.20: -========== - - * The `-fno-typeless-boz' option is now the default. - - This option specifies that non-decimal-radix constants using the - prefixed-radix form (such as `Z'1234'') are to be interpreted as - `INTEGER' constants. Specify `-ftypeless-boz' to cause such - constants to be interpreted as typeless. - - (Version 0.5.19 introduced `-fno-typeless-boz' and its inverse.) - - * Options `-ff90-intrinsics-enable' and `-fvxt-intrinsics-enable' - now are the defaults. - - Some programs might use names that clash with intrinsic names - defined (and now enabled) by these options or by the new `libU77' - intrinsics. Users of such programs might need to compile them - differently (using, for example, `-ff90-intrinsics-disable') or, - better yet, insert appropriate `EXTERNAL' statements specifying - that these names are not intended to be names of intrinsics. - - * The `ALWAYS_FLUSH' macro is no longer defined when building - `libf2c', which should result in improved I/O performance, - especially over NFS. - - *Note:* If you have code that depends on the behavior of `libf2c' - when built with `ALWAYS_FLUSH' defined, you will have to modify - `libf2c' accordingly before building it from this and future - versions of `g77'. - - * Dave Love's implementation of `libU77' has been added to the - version of `libf2c' distributed with and built as part of `g77'. - `g77' now knows about the routines in this library as intrinsics. - - * New option `-fvxt' specifies that the source file is written in - VXT Fortran, instead of GNU Fortran. - - * The `-fvxt-not-f90' option has been deleted, along with its - inverse, `-ff90-not-vxt'. - - If you used one of these deleted options, you should re-read the - pertinent documentation to determine which options, if any, are - appropriate for compiling your code with this version of `g77'. - - * The `-fugly' option now issues a warning, as it likely will be - removed in a future version. - - (Enabling all the `-fugly-*' options is unlikely to be feasible, - or sensible, in the future, so users should learn to specify only - those `-fugly-*' options they really need for a particular source - file.) - - * The `-fugly-assumed' option, introduced in version 0.5.19, has - been changed to better accommodate old and new code. - - * Make a number of fixes to the `g77' front end and the `gcc' back - end to better support Alpha (AXP) machines. This includes - providing at least one bug-fix to the `gcc' back end for Alphas. - - * Related to supporting Alpha (AXP) machines, the `LOC()' intrinsic - and `%LOC()' construct now return values of integer type that is - the same width (holds the same number of bits) as the pointer type - on the machine. - - On most machines, this won't make a difference, whereas on Alphas, - the type these constructs return is `INTEGER*8' instead of the - more common `INTEGER*4'. - - * Emulate `COMPLEX' arithmetic in the `g77' front end, to avoid bugs - in `complex' support in the `gcc' back end. New option - `-fno-emulate-complex' causes `g77' to revert the 0.5.19 behavior. - - * Fix bug whereby `REAL A(1)', for example, caused a compiler crash - if `-fugly-assumed' was in effect and A was a local (automatic) - array. That case is no longer affected by the new handling of - `-fugly-assumed'. - - * Fix `g77' command driver so that `g77 -o foo.f' no longer deletes - `foo.f' before issuing other diagnostics, and so the `-x' option - is properly handled. - - * Enable inlining of subroutines and functions by the `gcc' back end. - This works as it does for `gcc' itself--program units may be - inlined for invocations that follow them in the same program unit, - as long as the appropriate compile-time options are specified. - - * Dummy arguments are no longer assumed to potentially alias - (overlap) other dummy arguments or `COMMON' areas when any of - these are defined (assigned to) by Fortran code. - - This can result in faster and/or smaller programs when compiling - with optimization enabled, though on some systems this effect is - observed only when `-fforce-addr' also is specified. - - New options `-falias-check', `-fargument-alias', - `-fargument-noalias', and `-fno-argument-noalias-global' control - the way `g77' handles potential aliasing. - - * The `CONJG()' and `DCONJG()' intrinsics now are compiled in-line. - - * The bug-fix for 0.5.19.1 has been re-done. The `g77' compiler has - been changed back to assume `libf2c' has no aliasing problems in - its implementations of the `COMPLEX' (and `DOUBLE COMPLEX') - intrinsics. The `libf2c' has been changed to have no such - problems. - - As a result, 0.5.20 is expected to offer improved performance over - 0.5.19.1, perhaps as good as 0.5.19 in most or all cases, due to - this change alone. - - *Note:* This change requires version 0.5.20 of `libf2c', at least, - when linking code produced by any versions of `g77' other than - 0.5.19.1. Use `g77 -v' to determine the version numbers of the - `libF77', `libI77', and `libU77' components of the `libf2c' - library. (If these version numbers are not printed--in - particular, if the linker complains about unresolved references to - names like `g77__fvers__'--that strongly suggests your - installation has an obsolete version of `libf2c'.) - - * New option `-fugly-assign' specifies that the same memory - locations are to be used to hold the values assigned by both - statements `I = 3' and `ASSIGN 10 TO I', for example. (Normally, - `g77' uses a separate memory location to hold assigned statement - labels.) - - * `FORMAT' and `ENTRY' statements now are allowed to precede - `IMPLICIT NONE' statements. - - * Produce diagnostic for unsupported `SELECT CASE' on `CHARACTER' - type, instead of crashing, at compile time. - - * Fix crashes involving diagnosed or invalid code. - - * Change approach to building `libf2c' archive (`libf2c.a') so that - members are added to it only when truly necessary, so the user - that installs an already-built `g77' doesn't need to have write - access to the build tree (whereas the user doing the build might - not have access to install new software on the system). - - * Support `gcc' version 2.7.2.2 (modified by `g77' into version - 2.7.2.2.f.2), and remove support for prior versions of `gcc'. - - * Upgrade to `libf2c' as of 1997-02-08, and fix up some of the build - procedures. - - * Improve general build procedures for `g77', fixing minor bugs - (such as deletion of any file named `f771' in the parent directory - of `gcc/'). - - * Enable full support of `INTEGER*8' available in `libf2c' and - `f2c.h' so that `f2c' users may make full use of its features via - the `g77' version of `f2c.h' and the `INTEGER*8' support routines - in the `g77' version of `libf2c'. - - * Improve `g77' driver and `libf2c' so that `g77 -v' yields version - information on the library. - - * The `SNGL' and `FLOAT' intrinsics now are specific intrinsics, - instead of synonyms for the generic intrinsic `REAL'. - - * New intrinsics have been added. These are `REALPART', `IMAGPART', - `COMPLEX', `LONG', and `SHORT'. - - * A new group of intrinsics, `gnu', has been added to contain the - new `REALPART', `IMAGPART', and `COMPLEX' intrinsics. An old - group, `dcp', has been removed. - - * Complain about industry-wide ambiguous references `REAL(EXPR)' and - `AIMAG(EXPR)', where EXPR is `DOUBLE COMPLEX' (or any complex type - other than `COMPLEX'), unless `-ff90' option specifies Fortran 90 - interpretation or new `-fugly-complex' option, in conjunction with - `-fnot-f90', specifies `f2c' interpretation. - - * Make improvements to diagnostics. - - * Speed up compiler a bit. - - * Improvements to documentation and indexing, including a new - chapter containing information on one, later more, diagnostics - that users are directed to pull up automatically via a message in - the diagnostic itself. - - (Hence the menu item `M' for the node `Diagnostics' in the - top-level menu of the Info documentation.) - -In 0.5.19.1: -============ - - * Code-generation bugs afflicting operations on complex data have - been fixed. - - These bugs occurred when assigning the result of an operation to a - complex variable (or array element) that also served as an input - to that operation. - - The operations affected by this bug were: `CONJG()', `DCONJG()', - `CCOS()', `CDCOS()', `CLOG()', `CDLOG()', `CSIN()', `CDSIN()', - `CSQRT()', `CDSQRT()', complex division, and raising a `DOUBLE - COMPLEX' operand to an `INTEGER' power. (The related generic and - `Z'-prefixed intrinsics, such as `ZSIN()', also were affected.) - - For example, `C = CSQRT(C)', `Z = Z/C', and `Z = Z**I' (where `C' - is `COMPLEX' and `Z' is `DOUBLE COMPLEX') have been fixed. - -In 0.5.19: -========== - - * Fix `FORMAT' statement parsing so negative values for specifiers - such as `P' (e.g. `FORMAT(-1PF8.1)') are correctly processed as - negative. - - * Fix `SIGNAL' intrinsic so it once again accepts a procedure as its - second argument. - - * A temporary kludge option provides bare-bones information on - `COMMON' and `EQUIVALENCE' members at debug time. - - * New `-fonetrip' option specifies FORTRAN-66-style one-trip `DO' - loops. - - * New `-fno-silent' option causes names of program units to be - printed as they are compiled, in a fashion similar to UNIX `f77' - and `f2c'. - - * New `-fugly-assumed' option specifies that arrays dimensioned via - `DIMENSION X(1)', for example, are to be treated as assumed-size. - - * New `-fno-typeless-boz' option specifies that non-decimal-radix - constants using the prefixed-radix form (such as `Z'1234'') are to - be interpreted as `INTEGER' constants. - - * New `-ff66' option is a "shorthand" option that specifies - behaviors considered appropriate for FORTRAN 66 programs. - - * New `-ff77' option is a "shorthand" option that specifies - behaviors considered appropriate for UNIX `f77' programs. - - * New `-fugly-comma' and `-fugly-logint' options provided to perform - some of what `-fugly' used to do. `-fugly' and `-fno-ugly' are - now "shorthand" options, in that they do nothing more than enable - (or disable) other `-fugly-*' options. - - * Fix parsing of assignment statements involving targets that are - substrings of elements of `CHARACTER' arrays having names such as - `READ', `WRITE', `GOTO', and `REALFUNCTIONFOO'. - - * Fix crashes involving diagnosed code. - - * Fix handling of local `EQUIVALENCE' areas so certain cases of - valid Fortran programs are not misdiagnosed as improperly - extending the area backwards. - - * Support `gcc' version 2.7.2.1. - - * Upgrade to `libf2c' as of 1996-09-26, and fix up some of the build - procedures. - - * Change code generation for list-directed I/O so it allows for new - versions of `libf2c' that might return non-zero status codes for - some operations previously assumed to always return zero. - - This change not only affects how `IOSTAT=' variables are set by - list-directed I/O, it also affects whether `END=' and `ERR=' - labels are reached by these operations. - - * Add intrinsic support for new `FTELL' and `FSEEK' procedures in - `libf2c'. - - * Modify `fseek_()' in `libf2c' to be more portable (though, in - practice, there might be no systems where this matters) and to - catch invalid `whence' arguments. - - * Some useless warnings from the `-Wunused' option have been - eliminated. - - * Fix a problem building the `f771' executable on AIX systems by - linking with the `-bbigtoc' option. - - * Abort configuration if `gcc' has not been patched using the patch - file provided in the `gcc/f/gbe/' subdirectory. - - * Add options `--help' and `--version' to the `g77' command, to - conform to GNU coding guidelines. Also add printing of `g77' - version number when the `--verbose' (`-v') option is used. - - * Change internally generated name for local `EQUIVALENCE' areas to - one based on the alphabetically sorted first name in the list of - names for entities placed at the beginning of the areas. - - * Improvements to documentation and indexing. - -In 0.5.18: -========== - - * Add some rudimentary support for `INTEGER*1', `INTEGER*2', - `INTEGER*8', and their `LOGICAL' equivalents. (This support works - on most, maybe all, `gcc' targets.) - - Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing - the patch for this! - - Among the missing elements from the support for these features are - full intrinsic support and constants. - - * Add some rudimentary support for the `BYTE' and `WORD' - type-declaration statements. `BYTE' corresponds to `INTEGER*1', - while `WORD' corresponds to `INTEGER*2'. - - Thanks to Scott Snyder (<snyder@d0sgif.fnal.gov>) for providing - the patch for this! - - * The compiler code handling intrinsics has been largely rewritten - to accommodate the new types. No new intrinsics or arguments for - existing intrinsics have been added, so there is, at this point, - no intrinsic to convert to `INTEGER*8', for example. - - * Support automatic arrays in procedures. - - * Reduce space/time requirements for handling large *sparsely* - initialized aggregate arrays. This improvement applies to only a - subset of the general problem to be addressed in 0.6. - - * Treat initial values of zero as if they weren't specified (in DATA - and type-declaration statements). The initial values will be set - to zero anyway, but the amount of compile time processing them - will be reduced, in some cases significantly (though, again, this - is only a subset of the general problem to be addressed in 0.6). - - A new option, `-fzeros', is introduced to enable the traditional - treatment of zeros as any other value. - - * With `-ff90' in force, `g77' incorrectly interpreted `REAL(Z)' as - returning a `REAL' result, instead of as a `DOUBLE PRECISION' - result. (Here, `Z' is `DOUBLE COMPLEX'.) - - With `-fno-f90' in force, the interpretation remains unchanged, - since this appears to be how at least some F77 code using the - `DOUBLE COMPLEX' extension expected it to work. - - Essentially, `REAL(Z)' in F90 is the same as `DBLE(Z)', while in - extended F77, it appears to be the same as `REAL(REAL(Z))'. - - * An expression involving exponentiation, where both operands were - type `INTEGER' and the right-hand operand was negative, was - erroneously evaluated. - - * Fix bugs involving `DATA' implied-`DO' constructs (these involved - an errant diagnostic and a crash, both on good code, one involving - subsequent statement-function definition). - - * Close `INCLUDE' files after processing them, so compiling source - files with lots of `INCLUDE' statements does not result in being - unable to open `INCLUDE' files after all the available file - descriptors are used up. - - * Speed up compiling, especially of larger programs, and perhaps - slightly reduce memory utilization while compiling (this is *not* - the improvement planned for 0.6 involving large aggregate - areas)--these improvements result from simply turning off some - low-level code to do self-checking that hasn't been triggered in a - long time. - - * Introduce three new options that implement optimizations in the - `gcc' back end (GBE). These options are `-fmove-all-movables', - `-freduce-all-givs', and `-frerun-loop-opt', which are enabled, by - default, for Fortran compilations. These optimizations are - intended to help toon Fortran programs. - - * Patch the GBE to do a better job optimizing certain kinds of - references to array elements. - - * Due to patches to the GBE, the version number of `gcc' also is - patched to make it easier to manage installations, especially - useful if it turns out a `g77' change to the GBE has a bug. - - The `g77'-modified version number is the `gcc' version number with - the string `.f.N' appended, where `f' identifies the version as - enhanced for Fortran, and N is `1' for the first Fortran patch for - that version of `gcc', `2' for the second, and so on. - - So, this introduces version 2.7.2.f.1 of `gcc'. - - * Make several improvements and fixes to diagnostics, including the - removal of two that were inappropriate or inadequate. - - * Warning about two successive arithmetic operators, produced by - `-Wsurprising', now produced *only* when both operators are, - indeed, arithmetic (not relational/boolean). - - * `-Wsurprising' now warns about the remaining cases of using - non-integral variables for implied-`DO' loops, instead of these - being rejected unless `-fpedantic' or `-fugly' specified. - - * Allow `SAVE' of a local variable or array, even after it has been - given an initial value via `DATA', for example. - - * Introduce an Info version of `g77' documentation, which supercedes - `gcc/f/CREDITS', `gcc/f/DOC', and `gcc/f/PROJECTS'. These files - will be removed in a future release. The files `gcc/f/BUGS', - `gcc/f/INSTALL', and `gcc/f/NEWS' now are automatically built from - the texinfo source when distributions are made. - - This effort was inspired by a first pass at translating - `g77-0.5.16/f/DOC' that was contributed to Craig by David Ronis - (<ronis@onsager.chem.mcgill.ca>). - - * New `-fno-second-underscore' option to specify that, when - `-funderscoring' is in effect, a second underscore is not to be - appended to Fortran names already containing an underscore. - - * Change the way iterative `DO' loops work to follow the F90 - standard. In particular, calculation of the iteration count is - still done by converting the start, end, and increment parameters - to the type of the `DO' variable, but the result of the - calculation is always converted to the default `INTEGER' type. - - (This should have no effect on existing code compiled by `g77', - but code written to assume that use of a *wider* type for the `DO' - variable will result in an iteration count being fully calculated - using that wider type (wider than default `INTEGER') must be - rewritten.) - - * Support `gcc' version 2.7.2. - - * Upgrade to `libf2c' as of 1996-03-23, and fix up some of the build - procedures. - - Note that the email addresses related to `f2c' have changed--the - distribution site now is named `netlib.bell-labs.com', and the - maintainer's new address is <dmg@bell-labs.com>. - -In 0.5.17: -========== - - * *Fix serious bug* in `g77 -v' command that can cause removal of a - system's `/dev/null' special file if run by user `root'. - - *All users* of version 0.5.16 should ensure that they have not - removed `/dev/null' or replaced it with an ordinary file (e.g. by - comparing the output of `ls -l /dev/null' with `ls -l /dev/zero'. - If the output isn't basically the same, contact your system - administrator about restoring `/dev/null' to its proper status). - - This bug is particularly insidious because removing `/dev/null' as - a special file can go undetected for quite a while, aside from - various applications and programs exhibiting sudden, strange - behaviors. - - I sincerely apologize for not realizing the implications of the - fact that when `g77 -v' runs the `ld' command with `-o /dev/null' - that `ld' tries to *remove* the executable it is supposed to build - (especially if it reports unresolved references, which it should - in this case)! - - * Fix crash on `CHARACTER*(*) FOO' in a main or block data program - unit. - - * Fix crash that can occur when diagnostics given outside of any - program unit (such as when input file contains `@foo'). - - * Fix crashes, infinite loops (hangs), and such involving diagnosed - code. - - * Fix `ASSIGN''ed variables so they can be `SAVE''d or dummy - arguments, and issue clearer error message in cases where target - of `ASSIGN' or `ASSIGN'ed `GOTO'/`FORMAT' is too small (which - should never happen). - - * Make `libf2c' build procedures work on more systems again by - eliminating unnecessary invocations of `ld -r -x' and `mv'. - - * Fix omission of `-funix-intrinsics-...' options in list of - permitted options to compiler. - - * Fix failure to always diagnose missing type declaration for - `IMPLICIT NONE'. - - * Fix compile-time performance problem (which could sometimes crash - the compiler, cause a hang, or whatever, due to a bug in the back - end) involving exponentiation with a large `INTEGER' constant for - the right-hand operator (e.g. `I**32767'). - - * Fix build procedures so cross-compiling `g77' (the `fini' utility - in particular) is properly built using the host compiler. - - * Add new `-Wsurprising' option to warn about constructs that are - interpreted by the Fortran standard (and `g77') in ways that are - surprising to many programmers. - - * Add `ERF()' and `ERFC()' as generic intrinsics mapping to existing - `ERF'/`DERF' and `ERFC'/`DERFC' specific intrinsics. - - *Note:* You should specify `INTRINSIC ERF,ERFC' in any code where - you might use these as generic intrinsics, to improve likelihood - of diagnostics (instead of subtle run-time bugs) when using a - compiler that doesn't support these as intrinsics (e.g. `f2c'). - - * Remove from `-fno-pedantic' the diagnostic about `DO' with - non-`INTEGER' index variable; issue that under `-Wsurprising' - instead. - - * Clarify some diagnostics that say things like "ignored" when that's - misleading. - - * Clarify diagnostic on use of `.EQ.'/`.NE.' on `LOGICAL' operands. - - * Minor improvements to code generation for various operations on - `LOGICAL' operands. - - * Minor improvement to code generation for some `DO' loops on some - machines. - - * Support `gcc' version 2.7.1. - - * Upgrade to `libf2c' as of 1995-11-15. - -In 0.5.16: -========== - - * Fix a code-generation bug involving complicated `EQUIVALENCE' - statements not involving `COMMON'. - - * Fix code-generation bugs involving invoking "gratis" library - procedures in `libf2c' from code compiled with `-fno-f2c' by - making these procedures known to `g77' as intrinsics (not affected - by -fno-f2c). This is known to fix code invoking `ERF()', - `ERFC()', `DERF()', and `DERFC()'. - - * Update `libf2c' to include netlib patches through 1995-08-16, and - `#define' `WANT_LEAD_0' to 1 to make `g77'-compiled code more - consistent with other Fortran implementations by outputting - leading zeros in formatted and list-directed output. - - * Fix a code-generation bug involving adjustable dummy arrays with - high bounds whose primaries are changed during procedure - execution, and which might well improve code-generation - performance for such arrays compared to `f2c' plus `gcc' (but - apparently only when using `gcc-2.7.0' or later). - - * Fix a code-generation bug involving invocation of `COMPLEX' and - `DOUBLE COMPLEX' `FUNCTION's and doing `COMPLEX' and `DOUBLE - COMPLEX' divides, when the result of the invocation or divide is - assigned directly to a variable that overlaps one or more of the - arguments to the invocation or divide. - - * Fix crash by not generating new optimal code for `X**I' if `I' is - nonconstant and the expression is used to dimension a dummy array, - since the `gcc' back end does not support the necessary mechanics - (and the `gcc' front end rejects the equivalent construct, as it - turns out). - - * Fix crash on expressions like `COMPLEX**INTEGER'. - - * Fix crash on expressions like `(1D0,2D0)**2', i.e. raising a - `DOUBLE COMPLEX' constant to an `INTEGER' constant power. - - * Fix crashes and such involving diagnosed code. - - * Diagnose, instead of crashing on, statement function definitions - having duplicate dummy argument names. - - * Fix bug causing rejection of good code involving statement function - definitions. - - * Fix bug resulting in debugger not knowing size of local equivalence - area when any member of area has initial value (via `DATA', for - example). - - * Fix installation bug that prevented installation of `g77' driver. - Provide for easy selection of whether to install copy of `g77' as - `f77' to replace the broken code. - - * Fix `gcc' driver (affects `g77' thereby) to not gratuitously - invoke the `f771' program (e.g. when `-E' is specified). - - * Fix diagnostic to point to correct source line when it immediately - follows an `INCLUDE' statement. - - * Support more compiler options in `gcc'/`g77' when compiling - Fortran files. These options include `-p', `-pg', `-aux-info', - `-P', correct setting of version-number macros for preprocessing, - full recognition of `-O0', and automatic insertion of - configuration-specific linker specs. - - * Add new intrinsics that interface to existing routines in `libf2c': - `ABORT', `DERF', `DERFC', `ERF', `ERFC', `EXIT', `FLUSH', - `GETARG', `GETENV', `IARGC', `SIGNAL', and `SYSTEM'. Note that - `ABORT', `EXIT', `FLUSH', `SIGNAL', and `SYSTEM' are intrinsic - subroutines, not functions (since they have side effects), so to - get the return values from `SIGNAL' and `SYSTEM', append a final - argument specifying an `INTEGER' variable or array element (e.g. - `CALL SYSTEM('rm foo',ISTAT)'). - - * Add new intrinsic group named `unix' to contain the new intrinsics, - and by default enable this new group. - - * Move `LOC()' intrinsic out of the `vxt' group to the new `unix' - group. - - * Improve `g77' so that `g77 -v' by itself (or with certain other - options, including `-B', `-b', `-i', `-nostdlib', and `-V') - reports lots more useful version info, and so that long-form - options `gcc' accepts are understood by `g77' as well (even in - truncated, unambiguous forms). - - * Add new `g77' option `--driver=name' to specify driver when - default, `gcc', isn't appropriate. - - * Add support for `#' directives (as output by the preprocessor) in - the compiler, and enable generation of those directives by the - preprocessor (when compiling `.F' files) so diagnostics and - debugging info are more useful to users of the preprocessor. - - * Produce better diagnostics, more like `gcc', with info such as `In - function `foo':' and `In file included from...:'. - - * Support `gcc''s `-fident' and `-fno-ident' options. - - * When `-Wunused' in effect, don't warn about local variables used as - statement-function dummy arguments or `DATA' implied-`DO' iteration - variables, even though, strictly speaking, these are not uses of - the variables themselves. - - * When `-W -Wunused' in effect, don't warn about unused dummy - arguments at all, since there's no way to turn this off for - individual cases (`g77' might someday start warning about - these)--applies to `gcc' versions 2.7.0 and later, since earlier - versions didn't warn about unused dummy arguments. - - * New option `-fno-underscoring' that inhibits transformation of - names (by appending one or two underscores) so users may experiment - with implications of such an environment. - - * Minor improvement to `gcc/f/info' module to make it easier to build - `g77' using the native (non-`gcc') compiler on certain machines - (but definitely not all machines nor all non-`gcc' compilers). - Please do not report bugs showing problems compilers have with - macros defined in `gcc/f/target.h' and used in places like - `gcc/f/expr.c'. - - * Add warning to be printed for each invocation of the compiler if - the target machine `INTEGER', `REAL', or `LOGICAL' size is not 32 - bits, since `g77' is known to not work well for such cases (to be - fixed in Version 0.6--*note Actual Bugs We Haven't Fixed Yet: - Actual Bugs.). - - * Lots of new documentation (though work is still needed to put it - into canonical GNU format). - - * Build `libf2c' with `-g0', not `-g2', in effect (by default), to - produce smaller library without lots of debugging clutter. - -In 0.5.15: -========== - - * Fix bad code generation involving `X**I' and temporary, internal - variables generated by `g77' and the back end (such as for `DO' - loops). - - * Fix crash given `CHARACTER A;DATA A/.TRUE./'. - - * Replace crash with diagnostic given `CHARACTER A;DATA A/1.0/'. - - * Fix crash or other erratic behavior when null character constant - (`''') is encountered. - - * Fix crash or other erratic behavior involving diagnosed code. - - * Fix code generation for external functions returning type `REAL' - when the `-ff2c' option is in force (which it is by default) so - that `f2c' compatibility is indeed provided. - - * Disallow `COMMON I(10)' if `I' has previously been specified with - an array declarator. - - * New `-ffixed-line-length-N' option, where N is the maximum length - of a typical fixed-form line, defaulting to 72 columns, such that - characters beyond column N are ignored, or N is `none', meaning no - characters are ignored. does not affect lines with `&' in column - 1, which are always processed as if `-ffixed-line-length-none' was - in effect. - - * No longer generate better code for some kinds of array references, - as `gcc' back end is to be fixed to do this even better, and it - turned out to slow down some code in some cases after all. - - * In `COMMON' and `EQUIVALENCE' areas with any members given initial - values (e.g. via `DATA'), uninitialized members now always - initialized to binary zeros (though this is not required by the - standard, and might not be done in future versions of `g77'). - Previously, in some `COMMON'/`EQUIVALENCE' areas (essentially - those with members of more than one type), the uninitialized - members were initialized to spaces, to cater to `CHARACTER' types, - but it seems no existing code expects that, while much existing - code expects binary zeros. - -In 0.5.14: -========== - - * Don't emit bad code when low bound of adjustable array is - nonconstant and thus might vary as an expression at run time. - - * Emit correct code for calculation of number of trips in `DO' loops - for cases where the loop should not execute at all. (This bug - affected cases where the difference between the begin and end - values was less than the step count, though probably not for - floating-point cases.) - - * Fix crash when extra parentheses surround item in `DATA' - implied-`DO' list. - - * Fix crash over minor internal inconsistencies in handling - diagnostics, just substitute dummy strings where necessary. - - * Fix crash on some systems when compiling call to `MVBITS()' - intrinsic. - - * Fix crash on array assignment `TYPEDDD(...)=...', where DDD is a - string of one or more digits. - - * Fix crash on `DCMPLX()' with a single `INTEGER' argument. - - * Fix various crashes involving code with diagnosed errors. - - * Support `-I' option for `INCLUDE' statement, plus `gcc''s - `header.gcc' facility for handling systems like MS-DOS. - - * Allow `INCLUDE' statement to be continued across multiple lines, - even allow it to coexist with other statements on the same line. - - * Incorporate Bellcore fixes to `libf2c' through 1995-03-15--this - fixes a bug involving infinite loops reading EOF with empty - list-directed I/O list. - - * Remove all the `g77'-specific auto-configuration scripts, code, - and so on, except for temporary substitutes for bsearch() and - strtoul(), as too many configure/build problems were reported in - these areas. People will have to fix their systems' problems - themselves, or at least somewhere other than `g77', which expects - a working ANSI C environment (and, for now, a GNU C compiler to - compile `g77' itself). - - * Complain if initialized common redeclared as larger in subsequent - program unit. - - * Warn if blank common initialized, since its size can vary and hence - related warnings that might be helpful won't be seen. - - * New `-fbackslash' option, on by default, that causes `\' within - `CHARACTER' and Hollerith constants to be interpreted a la GNU C. - Note that this behavior is somewhat different from `f2c''s, which - supports only a limited subset of backslash (escape) sequences. - - * Make `-fugly-args' the default. - - * New `-fugly-init' option, on by default, that allows - typeless/Hollerith to be specified as initial values for variables - or named constants (`PARAMETER'), and also allows - character<->numeric conversion in those contexts--turn off via - `-fno-ugly-init'. - - * New `-finit-local-zero' option to initialize local variables to - binary zeros. This does not affect whether they are `SAVE'd, i.e. - made automatic or static. - - * New `-Wimplicit' option to warn about implicitly typed variables, - arrays, and functions. (Basically causes all program units to - default to `IMPLICIT NONE'.) - - * `-Wall' now implies `-Wuninitialized' as with `gcc' (i.e. unless - `-O' not specified, since `-Wuninitialized' requires `-O'), and - implies `-Wunused' as well. - - * `-Wunused' no longer gives spurious messages for unused `EXTERNAL' - names (since they are assumed to refer to block data program - units, to make use of libraries more reliable). - - * Support `%LOC()' and `LOC()' of character arguments. - - * Support null (zero-length) character constants and expressions. - - * Support `f2c''s `IMAG()' generic intrinsic. - - * Support `ICHAR()', `IACHAR()', and `LEN()' of character - expressions that are valid in assignments but not normally as - actual arguments. - - * Support `f2c'-style `&' in column 1 to mean continuation line. - - * Allow `NAMELIST', `EXTERNAL', `INTRINSIC', and `VOLATILE' in - `BLOCK DATA', even though these are not allowed by the standard. - - * Allow `RETURN' in main program unit. - - * Changes to Hollerith-constant support to obey Appendix C of the - standard: - - - Now padded on the right with zeros, not spaces. - - - Hollerith "format specifications" in the form of arrays of - non-character allowed. - - - Warnings issued when non-space truncation occurs when - converting to another type. - - - When specified as actual argument, now passed by reference to - `INTEGER' (padded on right with spaces if constant too small, - otherwise fully intact if constant wider the `INTEGER' type) - instead of by value. - - *Warning:* `f2c' differs on the interpretation of `CALL FOO(1HX)', - which it treats exactly the same as `CALL FOO('X')', but which the - standard and `g77' treat as `CALL FOO(%REF('X '))' (padded with - as many spaces as necessary to widen to `INTEGER'), essentially. - - * Changes and fixes to typeless-constant support: - - - Now treated as a typeless double-length `INTEGER' value. - - - Warnings issued when overflow occurs. - - - Padded on the left with zeros when converting to a larger - type. - - - Should be properly aligned and ordered on the target machine - for whatever type it is turned into. - - - When specified as actual argument, now passed as reference to - a default `INTEGER' constant. - - * `%DESCR()' of a non-`CHARACTER' expression now passes a pointer to - the expression plus a length for the expression just as if it were - a `CHARACTER' expression. For example, `CALL FOO(%DESCR(D))', - where `D' is `REAL*8', is the same as `CALL FOO(D,%VAL(8)))'. - - * Name of multi-entrypoint master function changed to incorporate - the name of the primary entry point instead of a decimal value, so - the name of the master function for `SUBROUTINE X' with alternate - entry points is now `__g77_masterfun_x'. - - * Remove redundant message about zero-step-count `DO' loops. - - * Clean up diagnostic messages, shortening many of them. - - * Fix typo in `g77' man page. - - * Clarify implications of constant-handling bugs in `f/BUGS'. - - * Generate better code for `**' operator with a right-hand operand of - type `INTEGER'. - - * Generate better code for `SQRT()' and `DSQRT()', also when - `-ffast-math' specified, enable better code generation for `SIN()' - and `COS()'. - - * Generate better code for some kinds of array references. - - * Speed up lexing somewhat (this makes the compilation phase - noticeably faster). - diff --git a/gcc/f/README b/gcc/f/README deleted file mode 100755 index fdebfdc..0000000 --- a/gcc/f/README +++ /dev/null @@ -1,7 +0,0 @@ -1995-02-15 - -This directory is the f/ subdirectory, which is designed to -be a subdirectory in a gcc development tree, i.e. named gcc/f/. - -Please see gcc/README.g77 for information on the contents of this -directory. diff --git a/gcc/f/ansify.c b/gcc/f/ansify.c deleted file mode 100755 index 3af68e5..0000000 --- a/gcc/f/ansify.c +++ /dev/null @@ -1,208 +0,0 @@ -/* ansify.c - Copyright (C) 1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -/* From f/proj.h, which uses #error -- not all C compilers - support that, and we want *this* program to be compilable - by pretty much any C compiler. */ -#include "hconfig.j" -#include "system.j" -#include "assert.j" -#if HAVE_STDDEF_H -#include <stddef.h> -#endif - -typedef enum - { -#if !defined(false) || !defined(true) - false = 0, true = 1, -#endif -#if !defined(FALSE) || !defined(TRUE) - FALSE = 0, TRUE = 1, -#endif - Doggone_Trailing_Comma_Dont_Work = 1 - } bool; - -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -#define die_unless(c) \ - do if (!(c)) \ - { \ - fprintf (stderr, "%s:%lu: " #c "\n", argv[1], lineno); \ - die (); \ - } \ - while(0) - -static void -die () -{ - exit (1); -} - -int -main(int argc, char **argv) -{ - int c; - static unsigned long lineno = 1; - - die_unless (argc == 2); - - printf ("\ -/* This file is automatically generated from `%s',\n\ - which you should modify instead. */\n\ -# 1 \"%s\"\n\ -", - argv[1], argv[1]); - - while ((c = getchar ()) != EOF) - { - switch (c) - { - default: - putchar (c); - break; - - case '\n': - ++lineno; - putchar (c); - break; - - case '"': - putchar (c); - for (;;) - { - c = getchar (); - die_unless (c != EOF); - switch (c) - { - case '"': - putchar (c); - goto next_char; - - case '\n': - putchar ('\\'); - putchar ('n'); - putchar ('\\'); - putchar ('\n'); - ++lineno; - break; - - case '\\': - putchar (c); - c = getchar (); - die_unless (c != EOF); - putchar (c); - if (c == '\n') - ++lineno; - break; - - default: - putchar (c); - break; - } - } - break; - - case '\'': - putchar (c); - for (;;) - { - c = getchar (); - die_unless (c != EOF); - switch (c) - { - case '\'': - putchar (c); - goto next_char; - - case '\n': - putchar ('\\'); - putchar ('n'); - putchar ('\\'); - putchar ('\n'); - ++lineno; - break; - - case '\\': - putchar (c); - c = getchar (); - die_unless (c != EOF); - putchar (c); - if (c == '\n') - ++lineno; - break; - - default: - putchar (c); - break; - } - } - break; - - case '/': - putchar (c); - c = getchar (); - putchar (c); - if (c != '*') - break; - for (;;) - { - c = getchar (); - die_unless (c != EOF); - - switch (c) - { - case '\n': - ++lineno; - putchar (c); - break; - - case '*': - c = getchar (); - die_unless (c != EOF); - if (c == '/') - { - putchar ('*'); - putchar ('/'); - goto next_char; - } - if (c == '\n') - { - ++lineno; - putchar (c); - } - break; - - default: - /* Don't bother outputting content of comments. */ - break; - } - } - break; - } - - next_char: - ; - } - - die_unless (c == EOF); - - return 0; -} diff --git a/gcc/f/assert.j b/gcc/f/assert.j deleted file mode 100755 index a24b66f..0000000 --- a/gcc/f/assert.j +++ /dev/null @@ -1,27 +0,0 @@ -/* assert.j -- Wrapper for GCC's assert.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_assert -#define _J_f_assert -#include "assert.h" -#endif -#endif diff --git a/gcc/f/bad.c b/gcc/f/bad.c deleted file mode 100755 index 8387c4a..0000000 --- a/gcc/f/bad.c +++ /dev/null @@ -1,544 +0,0 @@ -/* bad.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Handles the displaying of diagnostic messages regarding the user's source - files. - - Modifications: -*/ - -/* If there's a %E or %4 in the messages, set this to at least 5, - for example. */ - -#define FFEBAD_MAX_ 6 - -/* Include files. */ - -#include "proj.h" -#include "bad.h" -#include "flags.j" -#include "com.h" -#include "toplev.j" -#include "where.h" - -/* Externals defined here. */ - -bool ffebad_is_inhibited_ = FALSE; - -/* Simple definitions and enumerations. */ - -#define FFEBAD_LONG_MSGS_ 1 /* 0 to use short (or same) messages. */ - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffebad_message_ - { - ffebadSeverity severity; - char *message; - }; - -/* Static objects accessed by functions in this module. */ - -static struct _ffebad_message_ ffebad_messages_[] -= -{ -#define FFEBAD_MSGS1(KWD,SEV,MSG) { SEV, MSG }, -#if FFEBAD_LONG_MSGS_ == 0 -#define FFEBAD_MSGS2(KWD,SEV,LMSG,SMSG) { SEV, SMSG }, -#else -#define FFEBAD_MSGS2(KWD,SEV,LMSG,SMSG) { SEV, LMSG }, -#endif -#include "bad.def" -#undef FFEBAD_MSGS1 -#undef FFEBAD_MSGS2 -}; - -static struct - { - ffewhereLine line; - ffewhereColumn col; - ffebadIndex tag; - } - -ffebad_here_[FFEBAD_MAX_]; -static char *ffebad_string_[FFEBAD_MAX_]; -static ffebadIndex ffebad_order_[FFEBAD_MAX_]; -static ffebad ffebad_errnum_; -static ffebadSeverity ffebad_severity_; -static char *ffebad_message_; -static unsigned char ffebad_index_; -static ffebadIndex ffebad_places_; -static bool ffebad_is_temp_inhibited_; /* Effective setting of - _is_inhibited_ for this - _start/_finish invocation. */ - -/* Static functions (internal). */ - -static int ffebad_bufputs_ (char buf[], int bufi, char *s); - -/* Internal macros. */ - -#define ffebad_bufflush_(buf, bufi) \ - (((buf)[bufi] = '\0'), fputs ((buf), stderr), 0) -#define ffebad_bufputc_(buf, bufi, c) \ - (((bufi) == ARRAY_SIZE (buf)) \ - ? (ffebad_bufflush_ ((buf), (bufi)), ((buf)[0] = (c)), 1) \ - : (((buf)[bufi] = (c)), (bufi) + 1)) - - -static int -ffebad_bufputs_ (char buf[], int bufi, char *s) -{ - for (; *s != '\0'; ++s) - bufi = ffebad_bufputc_ (buf, bufi, *s); - return bufi; -} - -/* ffebad_init_0 -- Initialize - - ffebad_init_0(); */ - -void -ffebad_init_0 () -{ - assert (FFEBAD == ARRAY_SIZE (ffebad_messages_)); -} - -ffebadSeverity -ffebad_severity (ffebad errnum) -{ - return ffebad_messages_[errnum].severity; -} - -/* ffebad_start_ -- Start displaying an error message - - ffebad_start(FFEBAD_SOME_ERROR_CODE); - - Call ffebad_start to establish the message, ffebad_here and ffebad_string - to send run-time data to it as necessary, then ffebad_finish when through - to actually get it to print (to stderr). - - Note: ffebad_start(errnum) turns into ffebad_start_(FALSE,errnum). No - outside caller should call ffebad_start_ directly (as indicated by the - trailing underscore). - - Call ffebad_start to start a normal message, one that might be inhibited - by the current state of statement guessing. Call ffebad_start_lex - instead to start a message that is global to all statement guesses and - happens only once for all guesses (i.e. the lexer). - - sev and message are overrides for the severity and messages when errnum - is FFEBAD, meaning the caller didn't want to have to put a message in - bad.def to produce a diagnostic. */ - -bool -ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev, - char *message) -{ - unsigned char i; - - if (ffebad_is_inhibited_ && !lex_override) - { - ffebad_is_temp_inhibited_ = TRUE; - return FALSE; - } - - if (errnum != FFEBAD) - { - ffebad_severity_ = ffebad_messages_[errnum].severity; - ffebad_message_ = ffebad_messages_[errnum].message; - } - else - { - ffebad_severity_ = sev; - ffebad_message_ = message; - } - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - { - extern int inhibit_warnings; /* From toplev.c. */ - - switch (ffebad_severity_) - { /* Tell toplev.c about this message. */ - case FFEBAD_severityINFORMATIONAL: - case FFEBAD_severityTRIVIAL: - if (inhibit_warnings) - { /* User wants no warnings. */ - ffebad_is_temp_inhibited_ = TRUE; - return FALSE; - } - /* Fall through. */ - case FFEBAD_severityWARNING: - case FFEBAD_severityPECULIAR: - case FFEBAD_severityPEDANTIC: - if ((ffebad_severity_ != FFEBAD_severityPEDANTIC) - || !flag_pedantic_errors) - { - if (count_error (1) == 0) - { /* User wants no warnings. */ - ffebad_is_temp_inhibited_ = TRUE; - return FALSE; - } - break; - } - /* Fall through (PEDANTIC && flag_pedantic_errors). */ - case FFEBAD_severityFATAL: - case FFEBAD_severityWEIRD: - case FFEBAD_severitySEVERE: - case FFEBAD_severityDISASTER: - count_error (0); - break; - - default: - break; - } - } -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - - ffebad_is_temp_inhibited_ = FALSE; - ffebad_errnum_ = errnum; - ffebad_index_ = 0; - ffebad_places_ = 0; - for (i = 0; i < FFEBAD_MAX_; ++i) - { - ffebad_string_[i] = NULL; - ffebad_here_[i].line = ffewhere_line_unknown (); - ffebad_here_[i].col = ffewhere_column_unknown (); - } - - return TRUE; -} - -/* ffebad_here -- Establish source location of some diagnostic concern - - ffebad_here(ffebadIndex i,ffewhereLine line,ffewhereColumn col); - - Call ffebad_start to establish the message, ffebad_here and ffebad_string - to send run-time data to it as necessary, then ffebad_finish when through - to actually get it to print (to stderr). */ - -void -ffebad_here (ffebadIndex index, ffewhereLine line, ffewhereColumn col) -{ - ffewhereLineNumber line_num; - ffewhereLineNumber ln; - ffewhereColumnNumber col_num; - ffewhereColumnNumber cn; - ffebadIndex i; - ffebadIndex j; - - if (ffebad_is_temp_inhibited_) - return; - - assert (index < FFEBAD_MAX_); - ffebad_here_[index].line = ffewhere_line_use (line); - ffebad_here_[index].col = ffewhere_column_use (col); - if (ffewhere_line_is_unknown (line) - || ffewhere_column_is_unknown (col)) - { - ffebad_here_[index].tag = FFEBAD_MAX_; - return; - } - ffebad_here_[index].tag = 0; /* For now, though it shouldn't matter. */ - - /* Sort the source line/col points into the order they occur in the source - file. Deal with duplicates appropriately. */ - - line_num = ffewhere_line_number (line); - col_num = ffewhere_column_number (col); - - /* Determine where in the ffebad_order_ array this new place should go. */ - - for (i = 0; i < ffebad_places_; ++i) - { - ln = ffewhere_line_number (ffebad_here_[ffebad_order_[i]].line); - cn = ffewhere_column_number (ffebad_here_[ffebad_order_[i]].col); - if (line_num < ln) - break; - if (line_num == ln) - { - if (col_num == cn) - { - ffebad_here_[index].tag = i; - return; /* Shouldn't go in, has equivalent. */ - } - else if (col_num < cn) - break; - } - } - - /* Before putting new place in ffebad_order_[i], first increment all tags - that are i or greater. */ - - if (i != ffebad_places_) - { - for (j = 0; j < FFEBAD_MAX_; ++j) - { - if (ffebad_here_[j].tag >= i) - ++ffebad_here_[j].tag; - } - } - - /* Then slide all ffebad_order_[] entries at and above i up one entry. */ - - for (j = ffebad_places_; j > i; --j) - ffebad_order_[j] = ffebad_order_[j - 1]; - - /* Finally can put new info in ffebad_order_[i]. */ - - ffebad_order_[i] = index; - ffebad_here_[index].tag = i; - ++ffebad_places_; -} - -/* Establish string for next index (always in order) of message - - ffebad_string(char *string); - - Call ffebad_start to establish the message, ffebad_here and ffebad_string - to send run-time data to it as necessary, then ffebad_finish when through - to actually get it to print (to stderr). Note: don't trash the string - until after calling ffebad_finish, since we just maintain a pointer to - the argument passed in until then. */ - -void -ffebad_string (char *string) -{ - if (ffebad_is_temp_inhibited_) - return; - - assert (ffebad_index_ != FFEBAD_MAX_); - ffebad_string_[ffebad_index_++] = string; -} - -/* ffebad_finish -- Display error message with where & run-time info - - ffebad_finish(); - - Call ffebad_start to establish the message, ffebad_here and ffebad_string - to send run-time data to it as necessary, then ffebad_finish when through - to actually get it to print (to stderr). */ - -void -ffebad_finish () -{ -#define MAX_SPACES 132 - static char *spaces - = "...>\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\040\ -\040\040\040"; /* MAX_SPACES - 1 spaces. */ - ffewhereLineNumber last_line_num; - ffewhereLineNumber ln; - ffewhereLineNumber rn; - ffewhereColumnNumber last_col_num; - ffewhereColumnNumber cn; - ffewhereColumnNumber cnt; - ffewhereLine l; - ffebadIndex bi; - unsigned short i; - char pointer; - unsigned char c; - unsigned char *s; - char *fn; - static char buf[1024]; - int bufi; - int index; - - if (ffebad_is_temp_inhibited_) - return; - - switch (ffebad_severity_) - { - case FFEBAD_severityINFORMATIONAL: - s = "note:"; - break; - - case FFEBAD_severityWARNING: - s = "warning:"; - break; - - case FFEBAD_severitySEVERE: - s = "fatal:"; - break; - - default: - s = ""; - break; - } - - /* Display the annoying source references. */ - - last_line_num = 0; - last_col_num = 0; - - for (bi = 0; bi < ffebad_places_; ++bi) - { - if (ffebad_places_ == 1) - pointer = '^'; - else - pointer = '1' + bi; - - l = ffebad_here_[ffebad_order_[bi]].line; - ln = ffewhere_line_number (l); - rn = ffewhere_line_filelinenum (l); - cn = ffewhere_column_number (ffebad_here_[ffebad_order_[bi]].col); - fn = ffewhere_line_filename (l); - if (ln != last_line_num) - { - if (bi != 0) - fputc ('\n', stderr); -#if FFECOM_targetCURRENT == FFECOM_targetGCC - report_error_function (fn); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - fprintf (stderr, -#if 0 - "Line %" ffewhereLineNumber_f "u of %s:\n %s\n %s%c", - rn, fn, -#else - /* the trailing space on the <file>:<line>: line - fools emacs19 compilation mode into finding the - report */ - "%s:%" ffewhereLineNumber_f "u: %s\n %s\n %s%c", - fn, rn, -#endif - s, - ffewhere_line_content (l), - &spaces[cn > MAX_SPACES ? 0 : MAX_SPACES - cn + 4], - pointer); - last_line_num = ln; - last_col_num = cn; - s = "(continued):"; - } - else - { - cnt = cn - last_col_num; - fprintf (stderr, - "%s%c", &spaces[cnt > MAX_SPACES - ? 0 : MAX_SPACES - cnt + 4], - pointer); - last_col_num = cn; - } - } - if (ffebad_places_ == 0) - { - /* Didn't output "warning:" string, capitalize it for message. */ - if ((s[0] != '\0') && ISALPHA (s[0]) && ISLOWER (s[0])) - { - char c; - - c = toupper (s[0]); - fprintf (stderr, "%c%s ", c, &s[1]); - } - else if (s[0] != '\0') - fprintf (stderr, "%s ", s); - } - else - fputc ('\n', stderr); - - /* Release the ffewhere info. */ - - for (bi = 0; bi < FFEBAD_MAX_; ++bi) - { - ffewhere_line_kill (ffebad_here_[bi].line); - ffewhere_column_kill (ffebad_here_[bi].col); - } - - /* Now display the message. */ - - bufi = 0; - for (i = 0; (c = ffebad_message_[i]) != '\0'; ++i) - { - if (c == '%') - { - c = ffebad_message_[++i]; - if (ISALPHA (c) && ISUPPER (c)) - { - index = c - 'A'; - - if ((index < 0) || (index >= FFEBAD_MAX_)) - { - bufi = ffebad_bufputs_ (buf, bufi, "[REPORT BUG!!] %"); - bufi = ffebad_bufputc_ (buf, bufi, c); - } - else - { - s = ffebad_string_[index]; - if (s == NULL) - bufi = ffebad_bufputs_ (buf, bufi, "[REPORT BUG!!]"); - else - bufi = ffebad_bufputs_ (buf, bufi, s); - } - } - else if (ISDIGIT (c)) - { - index = c - '0'; - - if ((index < 0) || (index >= FFEBAD_MAX_)) - { - bufi = ffebad_bufputs_ (buf, bufi, "[REPORT BUG!!] %"); - bufi = ffebad_bufputc_ (buf, bufi, c); - } - else - { - pointer = ffebad_here_[index].tag + '1'; - if (pointer == FFEBAD_MAX_ + '1') - pointer = '?'; - else if (ffebad_places_ == 1) - pointer = '^'; - bufi = ffebad_bufputc_ (buf, bufi, '('); - bufi = ffebad_bufputc_ (buf, bufi, pointer); - bufi = ffebad_bufputc_ (buf, bufi, ')'); - } - } - else if (c == '\0') - break; - else if (c == '%') - bufi = ffebad_bufputc_ (buf, bufi, '%'); - else - { - bufi = ffebad_bufputs_ (buf, bufi, "[REPORT BUG!!]"); - bufi = ffebad_bufputc_ (buf, bufi, '%'); - bufi = ffebad_bufputc_ (buf, bufi, c); - } - } - else - bufi = ffebad_bufputc_ (buf, bufi, c); - } - bufi = ffebad_bufputc_ (buf, bufi, '\n'); - bufi = ffebad_bufflush_ (buf, bufi); -} diff --git a/gcc/f/bad.def b/gcc/f/bad.def deleted file mode 100755 index 3a86a1f..0000000 --- a/gcc/f/bad.def +++ /dev/null @@ -1,711 +0,0 @@ -/* bad.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - bad.c - - Modifications: -*/ - -#define INFORM FFEBAD_severityINFORMATIONAL -#define TRIVIAL FFEBAD_severityTRIVIAL -#define WARN FFEBAD_severityWARNING -#define PECULIAR FFEBAD_severityPECULIAR -#define FATAL FFEBAD_severityFATAL -#define WEIRD FFEBAD_severityWEIRD -#define SEVERE FFEBAD_severitySEVERE -#define DISASTER FFEBAD_severityDISASTER - -FFEBAD_MSGS1 (FFEBAD_MISSING_FIRST_BINARY_OPERAND, FATAL, -"Missing first operand for binary operator at %0") -FFEBAD_MSGS1 (FFEBAD_NULL_CHAR_CONST, WARN, -"Zero-length character constant at %0") -FFEBAD_MSGS1 (FFEBAD_INVALID_TOKEN_IN_EXPRESSION, FATAL, -"Invalid token at %0 in expression or subexpression at %1") -FFEBAD_MSGS1 (FFEBAD_MISSING_OPERAND_FOR_OPERATOR, FATAL, -"Missing operand for operator at %1 at end of expression at %0") -FFEBAD_MSGS1 (FFEBAD_LABEL_ALREADY_DEFINED, FATAL, -"Label %A already defined at %1 when redefined at %0") -FFEBAD_MSGS1 (FFEBAD_UNRECOGNIZED_CHARACTER, FATAL, -"Unrecognized character at %0 [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_LABEL_WITHOUT_STMT, WARN, -"Label definition %A at %0 on empty statement (as of %1)") -FFEBAD_MSGS2 (FFEBAD_EXTRA_LABEL_DEF, FATAL, -"Extra label definition %A at %0 -- perhaps previous label definition %B at %1 should have CONTINUE statement?", -"Extra label definition %A at %0 following label definition %B at %1") -FFEBAD_MSGS1 (FFEBAD_FIRST_CHAR_INVALID, FATAL, -"Invalid first character at %0 [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_LINE_TOO_LONG, FATAL, -"Line too long as of %0 [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_LABEL_FIELD_NOT_NUMERIC, FATAL, -"Non-numeric character at %0 in label field [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_LABEL_NUMBER_INVALID, FATAL, -"Label number at %0 not in range 1-99999") -FFEBAD_MSGS1 (FFEBAD_NON_ANSI_COMMENT, WARN, -"At %0, '!' and '/*' are not valid comment delimiters") -FFEBAD_MSGS1 (FFEBAD_NON_ANSI_CONTINUATION_COLUMN, WARN, -"Continuation indicator at %0 must appear in column 6 [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_LABEL_ON_CONTINUATION, FATAL, -"Label at %0 invalid with continuation line indicator at %1 [info -f g77 M LEX]") -FFEBAD_MSGS2 (FFEBAD_INVALID_CONTINUATION, FATAL, -"Continuation indicator at %0 invalid on first non-comment line of file or following END or INCLUDE [info -f g77 M LEX]", -"Continuation indicator at %0 invalid here [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_NO_CLOSING_APOSTROPHE, FATAL, -"Character constant at %0 has no closing apostrophe at %1") -FFEBAD_MSGS1 (FFEBAD_NOT_ENOUGH_HOLLERITH_CHARS, FATAL, -"Hollerith constant at %0 specified %A more characters than are present as of %1") -FFEBAD_MSGS1 (FFEBAD_MISSING_CLOSE_PAREN, FATAL, -"Missing close parenthese at %0 needed to match open parenthese at %1") -FFEBAD_MSGS1 (FFEBAD_INTEGER_TOO_LARGE, FATAL, -"Integer at %0 too large") -FFEBAD_MSGS2 (FFEBAD_BAD_MAGICAL, WARN, -"Integer at %0 too large except as negative number (preceded by unary minus sign)", -"Non-negative integer at %0 too large") -FFEBAD_MSGS2 (FFEBAD_BAD_MAGICAL_PRECEDENCE, WARN, -"Integer at %0 too large; even though preceded by unary minus sign at %1, subsequent operator at %2 has precedence over unary minus -- enclose unary minus sign and integer in parentheses to force precedence", -"Integer at %0 too large (%2 has precedence over %1)") -FFEBAD_MSGS2 (FFEBAD_BAD_MAGICAL_BINARY, WARN, -"Integer at %0 too large; even though preceded by minus sign at %1, because minus sign is a binary, not unary, operator -- insert plus sign before minus sign to change it to a unary minus sign", -"Integer at %0 too large (needs unary, not binary, minus at %1)") -FFEBAD_MSGS2 (FFEBAD_BAD_MAGICAL_PRECEDENCE_BINARY, WARN, -"Integer at %0 too large; even though preceded by minus sign at %1, subsequent operator at %2 has precedence over minus, and that minus sign should be a unary minus rather than a binary minus -- insert plus sign before minus sign to change it to a unary minus sign, and enclose unary minus sign and integer in parentheses to force precedence", -"Integer at %0 too large (%2 has precedence over %1, which needs to be unary, not binary, minus)") -FFEBAD_MSGS1 (FFEBAD_IGNORING_PERIOD, FATAL, -"Period at %0 not followed by digits for floating-point number or by `NOT.', `TRUE.', or `FALSE.'") -FFEBAD_MSGS1 (FFEBAD_INSERTING_PERIOD, FATAL, -"Missing close-period between `.%A' at %0 and %1") -FFEBAD_MSGS1 (FFEBAD_INVALID_EXPONENT, FATAL, -"Invalid exponent at %0 for real constant at %1; nondigit `%A' in exponent field") -FFEBAD_MSGS1 (FFEBAD_MISSING_EXPONENT_VALUE, FATAL, -"Missing value at %1 for real-number exponent at %0") -FFEBAD_MSGS1 (FFEBAD_MISSING_BINARY_OPERATOR, FATAL, -"Expected binary operator between expressions at %0 and at %1") -FFEBAD_MSGS2 (FFEBAD_INVALID_DOTDOT, FATAL, -"Period at %0 not followed by valid keyword forming a valid binary operator; `.%A.' is not a valid binary operator", -"`.%A.' at %0 not a binary operator") -FFEBAD_MSGS2 (FFEBAD_QUOTE_MISSES_DIGITS, FATAL, -"Double-quote at %0 not followed by a string of valid octal digits at %1", -"Invalid octal constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_BINARY_DIGIT, FATAL, -"Invalid binary digit(s) found in string of digits at %0", -"Invalid binary constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_HEX_DIGIT, FATAL, -"Invalid hexadecimal digit(s) found in string of digits at %0", -"Invalid hexadecimal constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_OCTAL_DIGIT, FATAL, -"Invalid octal digit(s) found in string of digits at %0", -"Invalid octal constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_RADIX_SPECIFIER, FATAL, -"Invalid radix specifier `%A' at %0 for typeless constant at %1", -"Invalid typeless constant at %1") -FFEBAD_MSGS2 (FFEBAD_INVALID_TYPELESS_BINARY_DIGIT, FATAL, -"Invalid binary digit(s) found in string of digits at %0", -"Invalid binary constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_TYPELESS_OCTAL_DIGIT, FATAL, -"Invalid octal digit(s) found in string of digits at %0", -"Invalid octal constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_TYPELESS_HEX_DIGIT, FATAL, -"Invalid hexadecimal digit(s) found in string of digits at %0", -"Invalid hexadecimal constant at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_COMPLEX_PART, FATAL, -"%A part of complex constant at %0 must be a real or integer constant -- otherwise use CMPLX() or COMPLEX() in place of ()", -"%A part of complex constant at %0 not a real or integer constant") -FFEBAD_MSGS2 (FFEBAD_INVALID_PERCENT, FATAL, -"Invalid keyword `%%%A' at %0 in this context", -"Invalid keyword `%%%A' at %0") -FFEBAD_MSGS2 (FFEBAD_NULL_EXPRESSION, FATAL, -"Null expression between %0 and %1 invalid in this context", -"Invalid null expression between %0 and %1") -FFEBAD_MSGS2 (FFEBAD_CONCAT_ARGS_TYPE, FATAL, -"Concatenation operator at %0 must operate on two subexpressions of character type, but neither subexpression at %1 or %2 is of character type", -"Invalid operands at %1 and %2 for concatenation operator at %0") -FFEBAD_MSGS2 (FFEBAD_CONCAT_ARG_TYPE, FATAL, -"Concatenation operator at %0 must operate on two subexpressions of character type, but the subexpression at %1 is not of character type", -"Invalid operand at %1 for concatenation operator at %0") -FFEBAD_MSGS2 (FFEBAD_CONCAT_ARG_KIND, FATAL, -"Concatenation operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning character scalars, or a combination of both -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for concatenation operator at %0") -FFEBAD_MSGS2 (FFEBAD_MATH_ARGS_TYPE, FATAL, -"Arithmetic operator at %0 must operate on two subexpressions of arithmetic type, but neither subexpression at %1 or %2 is of arithmetic type", -"Invalid operands at %1 and %2 for arithmetic operator at %0") -FFEBAD_MSGS2 (FFEBAD_MATH_ARG_TYPE, FATAL, -"Arithmetic operator at %0 must operate on two subexpressions of arithmetic type, but the subexpression at %1 is not of arithmetic type", -"Invalid operand at %1 for arithmetic operator at %0") -FFEBAD_MSGS2 (FFEBAD_MATH_ARG_KIND, FATAL, -"Arithmetic operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning arithmetic scalars, or a combination of both -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for arithmetic operator at %0") -FFEBAD_MSGS2 (FFEBAD_NO_CLOSING_QUOTE, FATAL, -"Character constant at %0 has no closing quote at %1 [info -f g77 M LEX]", -"Unterminated character constant at %0 [info -f g77 M LEX]") -FFEBAD_MSGS2 (FFEBAD_BAD_CHAR_CONTINUE, FATAL, -"Continuation line at %0 must have initial `&' since it continues a character context [info -f g77 M LEX]", -"Missing initial `&' on continuation line at %0 [info -f g77 M LEX]") -FFEBAD_MSGS2 (FFEBAD_BAD_LEXTOK_CONTINUE, FATAL, -"Continuation line at %0 must have initial `&' since it continues a split lexical token [info -f g77 M LEX]", -"Missing initial `&' on continuation line at %0 [info -f g77 M LEX]") -FFEBAD_MSGS2 (FFEBAD_BAD_FREE_CONTINUE, FATAL, -"Continuation line at %0 invalid because it consists only of a single `&' as the only nonblank character", -"Invalid continuation line at %0") -FFEBAD_MSGS2 (FFEBAD_STMT_BEGINS_BAD, FATAL, -"Statement at %0 begins with invalid token [info -f g77 M LEX]", -"Invalid statement at %0 [info -f g77 M LEX]") -FFEBAD_MSGS1 (FFEBAD_SEMICOLON, FATAL, -"Semicolon at %0 is an invalid token") -FFEBAD_MSGS2 (FFEBAD_UNREC_STMT, FATAL, -"Unrecognized statement name at %0 and invalid form for assignment or statement-function definition at %1", -"Invalid statement at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_STMT_FORM, FATAL, -"Invalid form for %A statement at %0", -"Invalid %A statement at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_HOLL_IN_STMT, FATAL, -"Invalid use of hollerith constant in statement at %0 -- enclose the constant in parentheses (for example, change BACKSPACE 2HAB to BACKSPACE (2HAB))", -"Enclose hollerith constant in statement at %0 in parentheses") -FFEBAD_MSGS1 (FFEBAD_FORMAT_EXTRA_COMMA, FATAL, -"Extraneous comma in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_MISSING_COMMA, WARN, -"Missing comma in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_SPURIOUS_SIGN, FATAL, -"Spurious sign in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_SPURIOUS_NUMBER, FATAL, -"Spurious number in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_TEXT_IN_NUMBER, FATAL, -"Spurious text trailing number in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_P_NOCOMMA, FATAL, -"nP control edit descriptor not followed by comma but followed by edit descriptor at %0 other than D, E, EN, F, or G", -"Invalid edit descriptor at %0 following nP control edit descriptor") -FFEBAD_MSGS1 (FFEBAD_FORMAT_BAD_SPEC, FATAL, -"Unrecognized FORMAT specifier at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_I_SPEC, FATAL, -"Invalid I specifier in FORMAT statement at %0 -- correct form: [r]Iw.[m]", -"Invalid I specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_B_SPEC, FATAL, -"Invalid B specifier in FORMAT statement at %0 -- correct form: [r]Bw.[m]", -"Invalid B specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_O_SPEC, FATAL, -"Invalid O specifier in FORMAT statement at %0 -- correct form: [r]Ow.[m]", -"Invalid O specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_Z_SPEC, FATAL, -"Invalid Z specifier in FORMAT statement at %0 -- correct form: [r]Zw.[m]", -"Invalid Z specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_F_SPEC, FATAL, -"Invalid F specifier in FORMAT statement at %0 -- correct form: [r]Fw.d", -"Invalid F specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_E_SPEC, FATAL, -"Invalid E specifier in FORMAT statement at %0 -- correct form: [r]Ew.d[Ee]", -"Invalid E specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_EN_SPEC, FATAL, -"Invalid EN specifier in FORMAT statement at %0 -- correct form: [r]ENw.d[Ee]", -"Invalid EN specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_G_SPEC, FATAL, -"Invalid G specifier in FORMAT statement at %0 -- correct form: [r]Gw.d[Ee]", -"Invalid G specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_L_SPEC, FATAL, -"Invalid L specifier in FORMAT statement at %0 -- correct form: [r]Lw", -"Invalid L specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_A_SPEC, FATAL, -"Invalid A specifier in FORMAT statement at %0 -- correct form: [r]A[w]", -"Invalid A specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_D_SPEC, FATAL, -"Invalid D specifier in FORMAT statement at %0 -- correct form: [r]Dw.d", -"Invalid D specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_Q_SPEC, FATAL, -"Invalid Q specifier in FORMAT statement at %0 -- correct form: Q", -"Invalid Q specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_DOLLAR_SPEC, FATAL, -"Invalid $ specifier in FORMAT statement at %0 -- correct form: $", -"Invalid $ specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_P_SPEC, FATAL, -"Invalid P specifier in FORMAT statement at %0 -- correct form: kP", -"Invalid P specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_T_SPEC, FATAL, -"Invalid T specifier in FORMAT statement at %0 -- correct form: Tn", -"Invalid T specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_TL_SPEC, FATAL, -"Invalid TL specifier in FORMAT statement at %0 -- correct form: TLn", -"Invalid TL specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_TR_SPEC, FATAL, -"Invalid TR specifier in FORMAT statement at %0 -- correct form: TRn", -"Invalid TR specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_X_SPEC, FATAL, -"Invalid X specifier in FORMAT statement at %0 -- correct form: nX", -"Invalid X specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_S_SPEC, FATAL, -"Invalid S specifier in FORMAT statement at %0 -- correct form: S", -"Invalid S specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_SP_SPEC, FATAL, -"Invalid SP specifier in FORMAT statement at %0 -- correct form: SP", -"Invalid SP specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_SS_SPEC, FATAL, -"Invalid SS specifier in FORMAT statement at %0 -- correct form: SS", -"Invalid SS specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_BN_SPEC, FATAL, -"Invalid BN specifier in FORMAT statement at %0 -- correct form: BN", -"Invalid BN specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_BZ_SPEC, FATAL, -"Invalid BZ specifier in FORMAT statement at %0 -- correct form: BZ", -"Invalid BZ specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_COLON_SPEC, FATAL, -"Invalid : specifier in FORMAT statement at %0 -- correct form: :", -"Invalid : specifier in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_BAD_H_SPEC, FATAL, -"Invalid H specifier in FORMAT statement at %0 -- correct form: nHcharacters !where n is an unsigned decimal constant, and characters !contains exactly n characters (including spaces)", -"Invalid H specifier in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_MISSING_PAREN, FATAL, -"Missing close-parenthese(s) in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_MISSING_DOT, FATAL, -"Missing number following period in FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_MISSING_EXP, FATAL, -"Missing number following `E' in FORMAT statement at %0") -FFEBAD_MSGS2 (FFEBAD_FORMAT_EXPR_TOKEN, FATAL, -"Invalid token with FORMAT run-time expression at %0 -- use the traditional operators .LT., .LE., .GT., .GE., .EQ., and .NE. in place of the newer tokens <, <=, >, >=, ==, and !=, because > ends an expression within a FORMAT statement", -"Invalid token with FORMAT run-time expression at %0") -FFEBAD_MSGS1 (FFEBAD_TRAILING_COMMA, WARN, -"Spurious trailing comma preceding terminator at %0") -FFEBAD_MSGS1 (FFEBAD_INTERFACE_ASSIGNMENT, WARN, -"At %0, specify OPERATOR instead of ASSIGNMENT for INTERFACE statement not specifying the assignment operator (=)") -FFEBAD_MSGS1 (FFEBAD_INTERFACE_OPERATOR, WARN, -"At %0, specify ASSIGNMENT instead of OPERATOR for INTERFACE statement specifying the assignment operator (=)") -FFEBAD_MSGS2 (FFEBAD_INTERFACE_NONLETTER, FATAL, -"Defined operator at %0 contains a nonletter -- must contain only letters A-Z (or a-z)", -"Nonletter in defined operator at %0") -FFEBAD_MSGS2 (FFEBAD_INVALID_TYPEDECL_ATTR, FATAL, -"Invalid type-declaration attribute at %0 -- must be one of: DIMENSION(array-spec), EXTERNAL, INTRINSIC, PARAMETER, or SAVE", -"Invalid type-declaration attribute at %0") -FFEBAD_MSGS1 (FFEBAD_INVALID_TYPEDECL_INIT, FATAL, -"Cannot specify =initialization-expr at %0 unless `::' appears before list of objects") -FFEBAD_MSGS1 (FFEBAD_LABEL_USE_DEF, FATAL, -"Reference to label at %1 inconsistent with its definition at %0") -FFEBAD_MSGS1 (FFEBAD_LABEL_USE_USE, FATAL, -"Reference to label at %1 inconsistent with earlier reference at %0") -FFEBAD_MSGS1 (FFEBAD_LABEL_DEF_DO, FATAL, -"DO-statement reference to label at %1 follows its definition at %0") -FFEBAD_MSGS1 (FFEBAD_LABEL_BLOCK, WARN, -"Reference to label at %1 is outside block containing definition at %0") -FFEBAD_MSGS1 (FFEBAD_LABEL_DO_BLOCK_DO, FATAL, -"DO-statement references to label at %0 and %2 separated by unterminated block starting at %1") -FFEBAD_MSGS1 (FFEBAD_LABEL_DO_BLOCK_END, FATAL, -"DO-statement reference to label at %0 and label definition at %2 separated by unterminated block starting at %1") -FFEBAD_MSGS1 (FFEBAD_INVALID_LABEL_DEF, FATAL, -"Label definition at %0 invalid on this kind of statement") -FFEBAD_MSGS1 (FFEBAD_ORDER_1, FATAL, -"Statement at %0 invalid in this context") -FFEBAD_MSGS1 (FFEBAD_ORDER_2, FATAL, -"Statement at %0 invalid in context established by statement at %1") -FFEBAD_MSGS1 (FFEBAD_CONSTRUCT_NAMED, FATAL, -"Statement at %0 must specify construct name specified at %1") -FFEBAD_MSGS1 (FFEBAD_CONSTRUCT_NOT_NAMED, FATAL, -"Construct name at %0 superfluous, no construct name specified at %1") -FFEBAD_MSGS1 (FFEBAD_CONSTRUCT_WRONG_NAME, FATAL, -"Construct name at %0 not the same as construct name at %1") -FFEBAD_MSGS1 (FFEBAD_CONSTRUCT_NO_DO_NAME, FATAL, -"Construct name at %0 does not match construct name for any containing DO constructs") -FFEBAD_MSGS1 (FFEBAD_DO_HAD_LABEL, FATAL, -"Label definition missing at %0 for DO construct specifying label at %1") -FFEBAD_MSGS1 (FFEBAD_AFTER_ELSE, FATAL, -"Statement at %0 follows ELSE block for IF construct at %1") -FFEBAD_MSGS1 (FFEBAD_FORMAT_NO_LABEL_DEF, FATAL, -"No label definition for FORMAT statement at %0") -FFEBAD_MSGS1 (FFEBAD_SECOND_ELSE_WHERE, FATAL, -"Second occurrence of ELSE WHERE at %0 within WHERE at %1") -FFEBAD_MSGS1 (FFEBAD_END_WO, WARN, -"END statement at %0 missing `%A' keyword required for internal or module procedure(s) bounded by %1") -FFEBAD_MSGS1 (FFEBAD_INVALID_MODULE_PROCEDURE, FATAL, -"MODULE PROCEDURE statement at %0 disallowed because INTERFACE at %1 specifies no generic name, operator, or assignment") -FFEBAD_MSGS1 (FFEBAD_BLOCKDATA_NOT_NAMED, FATAL, -"BLOCK DATA name at %0 superfluous, no name specified at %1") -FFEBAD_MSGS1 (FFEBAD_PROGRAM_NOT_NAMED, FATAL, -"Program name at %0 superfluous, no PROGRAM statement specified at %1") -FFEBAD_MSGS1 (FFEBAD_UNIT_WRONG_NAME, FATAL, -"Program unit name at %0 not the same as name at %1") -FFEBAD_MSGS1 (FFEBAD_TYPE_WRONG_NAME, FATAL, -"Type name at %0 not the same as name at %1") -FFEBAD_MSGS1 (FFEBAD_EOF_BEFORE_BLOCK_END, FATAL, -"End of source file before end of block started at %0") -FFEBAD_MSGS1 (FFEBAD_UNDEF_LABEL, FATAL, -"Undefined label, first referenced at %0") -FFEBAD_MSGS1 (FFEBAD_CONFLICTING_SAVES, WARN, -"SAVE statement or attribute at %1 cannot be specified along with SAVE statement or attribute at %0") -FFEBAD_MSGS1 (FFEBAD_CONFLICTING_ACCESSES, FATAL, -"PUBLIC or PRIVATE statement at %1 cannot be specified along with PUBLIC or PRIVATE statement at %0") -FFEBAD_MSGS1 (FFEBAD_RETURN_IN_MAIN, WARN, -"RETURN statement at %0 invalid within a main program unit") -FFEBAD_MSGS1 (FFEBAD_ALTRETURN_IN_PROGRAM, FATAL, -"Alternate return specifier at %0 invalid within a main program unit") -FFEBAD_MSGS1 (FFEBAD_ALTRETURN_IN_FUNCTION, FATAL, -"Alternate return specifier at %0 invalid within a function") -FFEBAD_MSGS1 (FFEBAD_DERIVTYP_ACCESS, FATAL, -"Access specifier or PRIVATE statement at %0 invalid for derived-type definition within other than the specification part of a module") -FFEBAD_MSGS1 (FFEBAD_DERIVTYP_ACCESS_FIRST, FATAL, -"Access specifier at %0 must immediately follow derived-type statement at %1 with no intervening statements") -FFEBAD_MSGS1 (FFEBAD_DERIVTYP_NO_COMPONENTS, FATAL, -"No components specified as of %0 for derived-type definition beginning at %1") -FFEBAD_MSGS1 (FFEBAD_STRUCT_NO_COMPONENTS, FATAL, -"No components specified as of %0 for structure definition beginning at %1") -FFEBAD_MSGS1 (FFEBAD_STRUCT_MISSING_NAME, FATAL, -"Missing structure name for outer structure definition at %0") -FFEBAD_MSGS1 (FFEBAD_STRUCT_IGNORING_FIELD, FATAL, -"Field names at %0 for outer structure definition -- specify them in a subsequent RECORD statement instead") -FFEBAD_MSGS1 (FFEBAD_STRUCT_MISSING_FIELD, FATAL, -"Missing field name(s) for structure definition at %0 within structure definition at %1") -FFEBAD_MSGS1 (FFEBAD_MAP_NO_COMPONENTS, FATAL, -"No components specified as of %0 for map beginning at %1") -FFEBAD_MSGS1 (FFEBAD_UNION_NO_TWO_MAPS, FATAL, -"Zero or one maps specified as of %0 for union beginning at %1 -- at least two are required") -FFEBAD_MSGS1 (FFEBAD_MISSING_SPECIFIER, FATAL, -"Missing %A specifier in statement at %0") -FFEBAD_MSGS1 (FFEBAD_NAMELIST_ITEMS, FATAL, -"Items in I/O list starting at %0 invalid for namelist-directed I/O") -FFEBAD_MSGS1 (FFEBAD_CONFLICTING_SPECS, FATAL, -"Conflicting I/O control specifications at %0 and %1") -FFEBAD_MSGS1 (FFEBAD_NO_UNIT_SPEC, FATAL, -"No UNIT= specifier in I/O control list at %0") -FFEBAD_MSGS1 (FFEBAD_MISSING_ADVANCE_SPEC, FATAL, -"Specification at %0 requires ADVANCE=`NO' specification in same I/O control list") -FFEBAD_MSGS1 (FFEBAD_MISSING_FORMAT_SPEC, FATAL, -"Specification at %0 requires explicit FMT= specification in same I/O control list") -FFEBAD_MSGS2 (FFEBAD_SPEC_VALUE, FATAL, -"Unrecognized value for character constant at %0 -- expecting %A", -"Unrecognized value for character constant at %0") -FFEBAD_MSGS1 (FFEBAD_CASE_SECOND_DEFAULT, FATAL, -"Second occurrence of CASE DEFAULT at %0 within SELECT CASE at %1") -FFEBAD_MSGS1 (FFEBAD_CASE_DUPLICATE, FATAL, -"Duplicate or overlapping case values/ranges at %0 and %1") -FFEBAD_MSGS1 (FFEBAD_CASE_TYPE_DISAGREE, FATAL, -"Type and/or kind-type parameter disagreement between CASE value or value within range at %0 and SELECT CASE at %1") -FFEBAD_MSGS1 (FFEBAD_CASE_LOGICAL_RANGE, FATAL, -"Range specification at %0 invalid for CASE statement within logical-type SELECT CASE statement") -FFEBAD_MSGS2 (FFEBAD_CASE_BAD_RANGE, FATAL, -"Range specification at %0 invalid -- at least one expression must be specified, or use CASE DEFAULT", -"Range specification at %0 invalid") -FFEBAD_MSGS2 (FFEBAD_CASE_RANGE_USELESS, INFORM, -"Range specification at %0 useless; first expression greater than second expression in range, so range can never be matched by any selection expression", -"Useless range at %0") -FFEBAD_MSGS1 (FFEBAD_F90, FATAL, -"Fortran 90 feature at %0 unsupported") -FFEBAD_MSGS2 (FFEBAD_KINDTYPE, FATAL, -"Invalid kind at %0 for type at %1 -- unsupported or not permitted", -"Invalid kind at %0 for type at %1") -FFEBAD_MSGS2 (FFEBAD_BAD_IMPLICIT, FATAL, -"Cannot establish implicit type for initial letter `%A' at %0 -- already explicitly established or used to set implicit type of some name, or backwards order of letters in letter range", -"Cannot establish implicit type for initial letter `%A' at %0") -FFEBAD_MSGS1 (FFEBAD_SYMERR, FATAL, -"Invalid declaration of or reference to symbol `%A' at %0 [initially seen at %1]") -FFEBAD_MSGS2 (FFEBAD_LABEL_WRONG_PLACE, FATAL, -"Label definition %A (at %0) invalid -- must be in columns 1-5", -"Invalid label definition %A (at %0)") -FFEBAD_MSGS1 (FFEBAD_NULL_ELEMENT, FATAL, -"Null element at %0 for array reference at %1") -FFEBAD_MSGS1 (FFEBAD_TOO_FEW_ELEMENTS, FATAL, -"Too few elements (%A missing) as of %0 for array reference at %1") -FFEBAD_MSGS1 (FFEBAD_TOO_MANY_ELEMENTS, FATAL, -"Too many elements as of %0 for array reference at %1") -FFEBAD_MSGS1 (FFEBAD_MISSING_COLON_IN_SUBSTR, FATAL, -"Missing colon as of %0 in substring reference for %1") -FFEBAD_MSGS1 (FFEBAD_BAD_SUBSTR, FATAL, -"Invalid use at %0 of substring operator on %1") -FFEBAD_MSGS1 (FFEBAD_RANGE_SUBSTR, WARN, -"Substring begin/end point at %0 out of defined range") -FFEBAD_MSGS1 (FFEBAD_RANGE_ARRAY, WARN, -"Array element value at %0 out of defined range") -FFEBAD_MSGS1 (FFEBAD_EXPR_WRONG, FATAL, -"Expression at %0 has incorrect data type or rank for its context") -FFEBAD_MSGS1 (FFEBAD_DIV_BY_ZERO, WARN, -"Division by 0 (zero) at %0 (IEEE not yet supported)") -FFEBAD_MSGS1 (FFEBAD_DO_STEP_ZERO, FATAL, -"%A step count known to be 0 (zero) at %0") -FFEBAD_MSGS1 (FFEBAD_DO_END_OVERFLOW, WARN, -"%A end value plus step count known to overflow at %0") -FFEBAD_MSGS1 (FFEBAD_DO_IMP_OVERFLOW, WARN, -"%A begin, end, and step-count values known to result in implementation-dependent behavior due to overflow(s) in intermediate calculations at %0") -FFEBAD_MSGS1 (FFEBAD_DO_NULL, WARN, -"%A begin, end, and step-count values known to result in no iterations at %0") -FFEBAD_MSGS1 (FFEBAD_BAD_TYPES, FATAL, -"Type disagreement between expressions at %0 and %1") -FFEBAD_MSGS2 (FFEBAD_FORMAT_EXPR_SPEC, FATAL, -"Run-time expression at %0 in FORMAT statement that does not follow the first executable statement in the program unit -- move the statement", -"FORMAT at %0 with run-time expression must follow first executable statement") -FFEBAD_MSGS2 (FFEBAD_BAD_IMPDO, FATAL, -"Unexpected token at %0 in implied-DO construct at %1 -- form of implied-DO is `(item-list,do-var=start,end[,incr])'", -"Unexpected token at %0 in implied-DO construct at %1") -FFEBAD_MSGS1 (FFEBAD_BAD_IMPDCL, FATAL, -"No specification for implied-DO iterator `%A' at %0") -FFEBAD_MSGS1 (FFEBAD_IMPDO_PAREN, WARN, -"Gratuitous parentheses surround implied-DO construct at %0") -FFEBAD_MSGS1 (FFEBAD_ZERO_SIZE, FATAL, -"Zero-size specification invalid at %0") -FFEBAD_MSGS1 (FFEBAD_ZERO_ARRAY, FATAL, -"Zero-size array at %0") -FFEBAD_MSGS1 (FFEBAD_BAD_COMPLEX, FATAL, -"Target machine does not support complex entity of kind specified at %0") -FFEBAD_MSGS1 (FFEBAD_BAD_DBLCMPLX, FATAL, -"Target machine does not support DOUBLE COMPLEX, specified at %0") -FFEBAD_MSGS1 (FFEBAD_BAD_POWER, WARN, -"Attempt to raise constant zero to a power at %0") -FFEBAD_MSGS2 (FFEBAD_BOOL_ARGS_TYPE, FATAL, -"Boolean/logical operator at %0 must operate on two subexpressions of logical type, but neither subexpression at %1 or %2 is of logical type", -"Invalid operands at %1 and %2 for boolean operator at %0") -FFEBAD_MSGS2 (FFEBAD_BOOL_ARG_TYPE, FATAL, -"Boolean/logical operator at %0 must operate on two subexpressions of logical type, but the subexpression at %1 is not of logical type", -"Invalid operand at %1 for boolean operator at %0") -FFEBAD_MSGS2 (FFEBAD_BOOL_ARG_KIND, FATAL, -"Boolean/logical operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning logical scalars, or a combination of both -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for boolean operator at %0") -FFEBAD_MSGS2 (FFEBAD_NOT_ARG_TYPE, FATAL, -".NOT. operator at %0 must operate on subexpression of logical type, but the subexpression at %1 is not of logical type", -"Invalid operand at %1 for .NOT. operator at %0") -FFEBAD_MSGS2 (FFEBAD_NOT_ARG_KIND, FATAL, -".NOT. operator at %0 must operate on scalar subexpressions -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for .NOT. operator at %0") -FFEBAD_MSGS2 (FFEBAD_EQOP_ARGS_TYPE, FATAL, -"Equality operator at %0 must operate on two subexpressions of arithmetic or character type, but neither subexpression at %1 or %2 is of arithmetic or character type", -"Invalid operands at %1 and %2 for equality operator at %0") -FFEBAD_MSGS2 (FFEBAD_EQOP_ARG_TYPE, FATAL, -"Equality operator at %0 must operate on two subexpressions of arithmetic or character type, but the subexpression at %1 is not of arithmetic or character type", -"Invalid operand at %1 for equality operator at %0") -FFEBAD_MSGS2 (FFEBAD_EQOP_ARG_KIND, FATAL, -"Equality operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning arithmetic or character scalars, or a combination of both -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for equality operator at %0") -FFEBAD_MSGS2 (FFEBAD_RELOP_ARGS_TYPE, FATAL, -"Relational operator at %0 must operate on two subexpressions of integer, real, or character type, but neither subexpression at %1 or %2 is of integer, real, or character type", -"Invalid operands at %1 and %2 for relational operator at %0") -FFEBAD_MSGS2 (FFEBAD_RELOP_ARG_TYPE, FATAL, -"Relational operator at %0 must operate on two subexpressions of integer, real, or character type, but the subexpression at %1 is not of integer, real, or character type", -"Invalid operand at %1 for relational operator at %0") -FFEBAD_MSGS2 (FFEBAD_RELOP_ARG_KIND, FATAL, -"Relational operator at %0 must operate on two scalar (not array) subexpressions, two function invocations returning integer, real, or character scalars, or a combination of both -- but the subexpression at %1 is %A", -"Invalid operand (is %A) at %1 for relational operator at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_REF, FATAL, -"Reference to intrinsic `%A' at %0 invalid -- one or more arguments have incorrect type", -"Invalid reference to intrinsic `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_TOOFEW, FATAL, -"Too few arguments passed to intrinsic `%A' at %0", -"Too few arguments for intrinsic `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_TOOMANY, FATAL, -"Too many arguments passed to intrinsic `%A' at %0", -"Too many arguments for intrinsic `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_DISABLED, FATAL, -"Reference to disabled intrinsic `%A' at %0", -"Disabled intrinsic `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_IS_SUBR, FATAL, -"Reference to intrinsic subroutine `%A' as if it were a function at %0", -"Function reference to intrinsic subroutine `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_IS_FUNC, FATAL, -"Reference to intrinsic function `%A' as if it were a subroutine at %0", -"Subroutine reference to intrinsic function `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_UNIMPL, FATAL, -"Reference to unimplemented intrinsic `%A' at %0 -- use EXTERNAL to reference user-written procedure with this name", -"Unimplemented intrinsic `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_INTRINSIC_UNIMPLW, WARN, -"Reference to unimplemented intrinsic `%A' at %0 (assumed EXTERNAL)", -"Unimplemented intrinsic `%A' at %0 (assumed EXTERNAL)") -FFEBAD_MSGS1 (FFEBAD_INTRINSIC_AMBIG, FATAL, -"Reference to generic intrinsic `%A' at %0 could be to form %B or %C") -FFEBAD_MSGS1 (FFEBAD_INTRINSIC_CMPAMBIG, FATAL, -"Ambiguous use of intrinsic `%A' at %0 [info -f g77 M CMPAMBIG]") -FFEBAD_MSGS1 (FFEBAD_INTRINSIC_EXPIMP, WARN, -"Intrinsic `%A' referenced %Bly at %0, %Cly at %1 [info -f g77 M EXPIMP]") -FFEBAD_MSGS1 (FFEBAD_INTRINSIC_GLOBAL, WARN, -"Same name `%A' used for %B at %0 and %C at %1 [info -f g77 M INTGLOB]") -FFEBAD_MSGS1 (FFEBAD_INTRINSIC_TYPE, WARN, -"Explicit type declaration for intrinsic `%A' disagrees with invocation at %0") -FFEBAD_MSGS1 (FFEBAD_OPEN_INCLUDE, FATAL, -"Unable to open INCLUDE file `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_DOITER, FATAL, -"Attempt to modify variable `%A' at %0 while it serves as DO-loop iterator at %1", -"Modification of DO-loop iterator `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_DOITER_IMPDO, FATAL, -"Attempt to modify variable `%A' via item #%B in list at %0 while it serves as implied-DO iterator at %1", -"Modification of DO-loop iterator `%A' at %0") -FFEBAD_MSGS2 (FFEBAD_TOO_MANY_DIMS, FATAL, -"Array has too many dimensions, as of dimension specifier at %0", -"Too many dimensions at %0") -FFEBAD_MSGS1 (FFEBAD_NULL_ARGUMENT, FATAL, -"Null argument at %0 for statement function reference at %1") -FFEBAD_MSGS1 (FFEBAD_NULL_ARGUMENT_W, WARN, -"Null argument at %0 for procedure invocation at %1") -FFEBAD_MSGS1 (FFEBAD_TOO_FEW_ARGUMENTS, FATAL, -"%A too few arguments (starting with dummy argument `%B') as of %0 for statement function reference at %1") -FFEBAD_MSGS1 (FFEBAD_TOO_MANY_ARGUMENTS, FATAL, -"%A too many arguments as of %0 for statement function reference at %1") -FFEBAD_MSGS1 (FFEBAD_ARRAY_AS_SFARG, FATAL, -"Array supplied at %1 for dummy argument `%A' in statement function reference at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_UNSUPPORTED, FATAL, -"Unsupported FORMAT specifier at %0") -FFEBAD_MSGS1 (FFEBAD_FORMAT_VARIABLE, FATAL, -"Variable-expression FORMAT specifier at %0 -- unsupported") -FFEBAD_MSGS2 (FFEBAD_OPEN_UNSUPPORTED, FATAL, -"Unsupported OPEN control item at %0 -- ACTION=, ASSOCIATEVARIABLE=, BLOCKSIZE=, BUFFERCOUNT=, CARRIAGECONTROL=, DEFAULTFILE=, DELIM=, DISPOSE=, EXTENDSIZE=, INITIALSIZE=, KEY=, MAXREC=, NOSPANBLOCKS, ORGANIZATION=, PAD=, POSITION=, READONLY=, RECORDTYPE=, SHARED=, and USEROPEN= are not supported", -"Unsupported OPEN control item at %0") -FFEBAD_MSGS2 (FFEBAD_INQUIRE_UNSUPPORTED, FATAL, -"Unsupported INQUIRE control item at %0 -- ACTION=, CARRIAGECONTROL=, DEFAULTFILE=, DELIM=, KEYED=, ORGANIZATION=, PAD=, POSITION=, READ=, READWRITE=, RECORDTYPE=, and WRITE= are not supported", -"Unsupported INQUIRE control item at %0") -FFEBAD_MSGS2 (FFEBAD_READ_UNSUPPORTED, FATAL, -"Unsupported READ control item at %0 -- ADVANCE=, EOR=, KEYEQ=, KEYGE=, KEYGT=, KEYID=, NULLS=, and SIZE= are not supported", -"Unsupported READ control item at %0") -FFEBAD_MSGS2 (FFEBAD_WRITE_UNSUPPORTED, FATAL, -"Unsupported WRITE control item at %0 -- ADVANCE= and EOR= are not supported", -"Unsupported WRITE control item at %0") -FFEBAD_MSGS1 (FFEBAD_VXT_UNSUPPORTED, FATAL, -"Unsupported VXT statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_REINIT, FATAL, -"Attempt to specify second initial value for `%A' at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_TOOFEW, FATAL, -"Too few initial values in list of initializers for `%A' at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_TOOMANY, FATAL, -"Too many initial values in list of initializers starting at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_RANGE, FATAL, -"Array or substring specification for `%A' out of range in statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_SUBSCRIPT, FATAL, -"Array subscript #%B out of range for initialization of `%A' in statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_ZERO, FATAL, -"Implied do-loop step count of 0 (zero) for iteration variable `%A' in statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_EMPTY, FATAL, -"Implied do-loop iteration count of 0 (zero) for iteration variable `%A' in statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_EVAL, FATAL, -"Not an integer constant expression in implied do-loop in statement at %0") -FFEBAD_MSGS1 (FFEBAD_DATA_MULTIPLE, FATAL, -"Attempt to specify second initial value for element of `%A' at %0") -FFEBAD_MSGS1 (FFEBAD_EQUIV_COMMON, FATAL, -"Attempt to EQUIVALENCE common areas `%A' and `%B' at %0") -FFEBAD_MSGS1 (FFEBAD_EQUIV_ALIGN, FATAL, -"Can't place `%A' as directed by EQUIVALENCE due to alignment restrictions") -FFEBAD_MSGS1 (FFEBAD_EQUIV_MISMATCH, FATAL, -"Mismatched EQUIVALENCE requirements for placement of `%A' at both %C and %D bytes offset from `%B'") -FFEBAD_MSGS1 (FFEBAD_EQUIV_RANGE, FATAL, -"Array or substring specification for `%A' out of range in EQUIVALENCE statement") -FFEBAD_MSGS1 (FFEBAD_EQUIV_SUBSTR, FATAL, -"Substring of non-CHARACTER entity `%A' in EQUIVALENCE statement") -FFEBAD_MSGS1 (FFEBAD_EQUIV_ARRAY, FATAL, -"Array reference to scalar variable `%A' in EQUIVALENCE statement") -FFEBAD_MSGS1 (FFEBAD_EQUIV_SUBSCRIPT, WARN, -"Array subscript #%B out of range for EQUIVALENCE of `%A'") -FFEBAD_MSGS2 (FFEBAD_COMMON_PAD, WARN, -"Padding of %A %D required before `%B' in common block `%C' at %0 -- consider reordering members, largest-type-size first", -"Padding of %A %D required before `%B' in common block `%C' at %0") -FFEBAD_MSGS1 (FFEBAD_COMMON_NEG, FATAL, -"Attempt to extend COMMON area beyond its starting point via EQUIVALENCE of `%A'") -FFEBAD_MSGS1 (FFEBAD_EQUIV_FEW, FATAL, -"Too few elements in reference to array `%A' in EQUIVALENCE statement") -FFEBAD_MSGS1 (FFEBAD_EQUIV_MANY, FATAL, -"Too many elements in reference to array `%A' in EQUIVALENCE statement") -FFEBAD_MSGS1 (FFEBAD_MIXED_TYPES, WARN, -"Mixed CHARACTER and non-CHARACTER types via COMMON/EQUIVALENCE -- for example, `%A' and `%B'") -FFEBAD_MSGS2 (FFEBAD_IMPLICIT_ADJLEN, FATAL, -"Invalid length specification at %0 for IMPLICIT statement -- must be integer constant expression", -"Invalid length specification at %0") -FFEBAD_MSGS2 (FFEBAD_ENTRY_CONFLICTS, FATAL, -"Type of ENTRY point at %0 to function conflicts with type(s) of previous entrypoint(s) -- must all be identical-length CHARACTER or none be CHARACTER type", -"Type of ENTRY point at %0 to function conflicts with type(s) of previous entrypoint(s)") -FFEBAD_MSGS1 (FFEBAD_RETURN_VALUE_UNSET, WARN, -"Return value `%A' for FUNCTION at %0 not referenced in subprogram") -FFEBAD_MSGS2 (FFEBAD_COMMON_ALREADY_INIT, FATAL, -"Common block `%A' initialized at %0 already initialized at %1 -- only one program unit may specify initial values for a particular common block", -"Common block `%A' initialized at %0 already initialized at %1") -FFEBAD_MSGS2 (FFEBAD_COMMON_INIT_PAD, WARN, -"Initial padding for common block `%A' is %B %C at %0 -- consider reordering members, largest-type-size first", -"Initial padding for common block `%A' is %B %C at %0") -FFEBAD_MSGS2 (FFEBAD_COMMON_DIFF_PAD, FATAL, -"Initial padding for common block `%A' is %B %D at %0 but %C %E at %1 -- consider reordering members, largest-type-size first", -"Initial padding for common block `%A' is %B %D at %0 but %C %E at %1") -FFEBAD_MSGS1 (FFEBAD_COMMON_DIFF_SAVE, WARN, -"Common block `%A' is SAVEd, explicitly or implicitly, at %0 but not SAVEd at %1") -FFEBAD_MSGS1 (FFEBAD_COMMON_DIFF_SIZE, WARN, -"Common block `%A' is %B %D in length at %0 but %C %E at %1") -FFEBAD_MSGS2 (FFEBAD_COMMON_ENLARGED, FATAL, -"Common block `%A' is initialized to %B %D long at %0 but enlarged to %C %E at %1 -- use consistent definitions or reorder program units in source file", -"Common block `%A' is initialized to %B %D long at %0 but enlarged to %C %E at %1") -FFEBAD_MSGS1 (FFEBAD_COMMON_BLANK_INIT, WARN, -"Blank common initialized at %0") -FFEBAD_MSGS1 (FFEBAD_NEED_INTRINSIC, WARN, -"Intrinsic `%A' is passed as actual argument at %0 but not explicitly declared INTRINSIC") -FFEBAD_MSGS1 (FFEBAD_NEED_EXTERNAL, WARN, -"External procedure `%A' is passed as actual argument at %0 but not explicitly declared EXTERNAL") -FFEBAD_MSGS1 (FFEBAD_SYMBOL_UPPER_CASE, WARN, -"Character `%A' (for example) is upper-case in symbol name at %0") -FFEBAD_MSGS1 (FFEBAD_SYMBOL_LOWER_CASE, WARN, -"Character `%A' (for example) is lower-case in symbol name at %0") -FFEBAD_MSGS1 (FFEBAD_SYMBOL_NOLOWER_INITCAP, WARN, -"Character `%A' not followed at some point by lower-case character in symbol name at %0") -FFEBAD_MSGS1 (FFEBAD_SYMBOL_LOWER_INITCAP, WARN, -"Initial character `%A' is lower-case in symbol name at %0") -FFEBAD_MSGS2 (FFEBAD_DO_REAL, WARN, -"DO-variable `%A' is type REAL or DOUBLE PRECISION at %0 -- unexpected behavior likely", -"DO-variable `%A' is type REAL or DOUBLE PRECISION at %0") -FFEBAD_MSGS1 (FFEBAD_NAMELIST_CASE, WARN, -"NAMELIST not adequately supported by run-time library for source files with case preserved") -FFEBAD_MSGS1 (FFEBAD_NESTED_PERCENT, WARN, -"Nested %% construct (%%VAL, %%REF, or %%DESCR) at %0") -FFEBAD_MSGS2 (FFEBAD_ACTUALARG, WARN, -"Invalid actual argument at %0 -- replace hollerith constants with %%REF('string') and typeless constants with INTEGER constant equivalents, or use -fugly-args or -fugly", -"Invalid actual argument at %0") -FFEBAD_MSGS2 (FFEBAD_QUAD_UNSUPPORTED, FATAL, -"Quadruple-precision floating-point unsupported -- treating constant at %0 as double-precision", -"Quadruple-precision floating-point unsupported") -FFEBAD_MSGS2 (FFEBAD_TOO_BIG_INIT, WARN, -"Initialization of large (%B-unit) aggregate area `%A' at %0 currently very slow and takes lots of memory during g77 compile -- to be improved in 0.6", -"This could take a while (initializing `%A' at %0)...") -FFEBAD_MSGS1 (FFEBAD_BLOCKDATA_STMT, FATAL, -"Statement at %0 invalid in BLOCK DATA program unit at %1") -FFEBAD_MSGS1 (FFEBAD_TRUNCATING_CHARACTER, FATAL, -"Truncating characters on right side of character constant at %0") -FFEBAD_MSGS1 (FFEBAD_TRUNCATING_HOLLERITH, FATAL, -"Truncating characters on right side of hollerith constant at %0") -FFEBAD_MSGS1 (FFEBAD_TRUNCATING_NUMERIC, FATAL, -"Truncating non-zero data on left side of numeric constant at %0") -FFEBAD_MSGS1 (FFEBAD_TRUNCATING_TYPELESS, FATAL, -"Truncating non-zero data on left side of typeless constant at %0") -FFEBAD_MSGS1 (FFEBAD_TYPELESS_OVERFLOW, FATAL, -"Typeless constant at %0 too large") -FFEBAD_MSGS1 (FFEBAD_AMPERSAND, WARN, -"First-column ampersand continuation at %0") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_ALREADY_SEEN, FATAL, -"Global name `%A' defined at %0 already defined at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_ALREADY_SEEN_W, WARN, -"Global name `%A' defined at %0 already defined at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_DISAGREEMENT, FATAL, -"Global name `%A' is %B at %0 but is %C at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_DISAGREEMENT_W, WARN, -"Global name `%A' is %B at %0 but is %C at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_TYPE_MISMATCH, FATAL, -"Global name `%A' at %0 has different type at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_TYPE_MISMATCH_W, WARN, -"Global name `%A' at %0 has different type at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_NARGS, FATAL, -"Too %B arguments passed to `%A' at %0 versus definition at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_NARGS_W, WARN, -"Too %B arguments for `%A' at %0 versus invocation at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_ARG, FATAL, -"Argument #%B of `%A' is %C at %0 but is %D at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_FILEWIDE_ARG_W, WARN, -"Argument #%B of `%A' is %C at %0 but is %D at %1 [info -f g77 M GLOBALS]") -FFEBAD_MSGS1 (FFEBAD_ARRAY_LARGE, FATAL, -"Array `%A' at %0 is too large to handle") -FFEBAD_MSGS1 (FFEBAD_SFUNC_UNUSED, WARN, -"Statement function `%A' defined at %0 is not used") - -#undef INFORM -#undef TRIVIAL -#undef WARN -#undef PECULIAR -#undef FATAL -#undef WEIRD -#undef SEVERE -#undef DISASTER diff --git a/gcc/f/bad.h b/gcc/f/bad.h deleted file mode 100755 index a52ff1f..0000000 --- a/gcc/f/bad.h +++ /dev/null @@ -1,108 +0,0 @@ -/* bad.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - bad.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_bad -#define _H_f_bad - -/* Simple definitions and enumerations. */ - -typedef enum - { -#define FFEBAD_MSGS1(KWD,SEV,MSG) KWD, -#define FFEBAD_MSGS2(KWD,SEV,LMSG,SMSG) KWD, -#include "bad.def" -#undef FFEBAD_MSGS1 -#undef FFEBAD_MSGS2 - FFEBAD - } ffebad; - -typedef enum - { - - /* Order important; must be increasing severity. */ - - FFEBAD_severityINFORMATIONAL, /* User notice. */ - FFEBAD_severityTRIVIAL, /* Internal notice. */ - FFEBAD_severityWARNING, /* User warning. */ - FFEBAD_severityPECULIAR, /* Internal warning. */ - FFEBAD_severityPEDANTIC, /* Pedantic, could be warning or error. */ - FFEBAD_severityFATAL, /* User error. */ - FFEBAD_severityWEIRD, /* Internal error. */ - FFEBAD_severitySEVERE, /* User error, cannot continue. */ - FFEBAD_severityDISASTER, /* Internal error, cannot continue. */ - FFEBAD_severity - } ffebadSeverity; - -/* Typedefs. */ - -typedef unsigned char ffebadIndex; - -/* Include files needed by this one. */ - -#include "where.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern bool ffebad_is_inhibited_; - -/* Declare functions with prototypes. */ - -void ffebad_finish (void); -void ffebad_here (ffebadIndex i, ffewhereLine wl, ffewhereColumn wc); -void ffebad_init_0 (void); -bool ffebad_is_fatal (ffebad errnum); -ffebadSeverity ffebad_severity (ffebad errnum); -bool ffebad_start_ (bool lex_override, ffebad errnum, ffebadSeverity sev, - char *message); -void ffebad_string (char *string); - -/* Define macros. */ - -#define ffebad_inhibit() (ffebad_is_inhibited_) -#define ffebad_init_1() -#define ffebad_init_2() -#define ffebad_init_3() -#define ffebad_init_4() -#define ffebad_set_inhibit(f) (ffebad_is_inhibited_ = (f)) -#define ffebad_start(e) ffebad_start_ (FALSE, (e), FFEBAD_severity, NULL) -#define ffebad_start_lex(e) ffebad_start_ (TRUE, (e), FFEBAD_severity, NULL) -#define ffebad_start_msg(m,s) ffebad_start_ (FALSE, FFEBAD, (s), (m)) -#define ffebad_start_msg_lex(m,s) ffebad_start_ (TRUE, FFEBAD, (s), (m)) -#define ffebad_terminate_0() -#define ffebad_terminate_1() -#define ffebad_terminate_2() -#define ffebad_terminate_3() -#define ffebad_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/bit.c b/gcc/f/bit.c deleted file mode 100755 index 71e74d7..0000000 --- a/gcc/f/bit.c +++ /dev/null @@ -1,201 +0,0 @@ -/* bit.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Tracks arrays of booleans in useful ways. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "glimits.j" -#include "bit.h" -#include "malloc.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffebit_count -- Count # of bits set a particular way - - ffebit b; // the ffebit object - ffebitCount offset; // 0..size-1 - bool value; // FALSE (0), TRUE (1) - ffebitCount range; // # bits to test - ffebitCount number; // # bits equal to value - ffebit_count(b,offset,value,range,&number); - - Sets <number> to # bits at <offset> through <offset + range - 1> set to - <value>. If <range> is 0, <number> is set to 0. */ - -void -ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range, - ffebitCount *number) -{ - ffebitCount element; - ffebitCount bitno; - - assert (offset + range <= b->size); - - for (*number = 0; range != 0; --range, ++offset) - { - element = offset / CHAR_BIT; - bitno = offset % CHAR_BIT; - if (value - == ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE)) - ++ * number; - } -} - -/* ffebit_new -- Create a new ffebit object - - ffebit b; - ffebit_kill(b); - - Destroys an ffebit object obtained via ffebit_new. */ - -void -ffebit_kill (ffebit b) -{ - malloc_kill_ks (b->pool, b, - offsetof (struct _ffebit_, bits) - + (b->size + CHAR_BIT - 1) / CHAR_BIT); -} - -/* ffebit_new -- Create a new ffebit object - - ffebit b; - mallocPool pool; - ffebitCount size; - b = ffebit_new(pool,size); - - Allocates an ffebit object that holds the values of <size> bits in pool - <pool>. */ - -ffebit -ffebit_new (mallocPool pool, ffebitCount size) -{ - ffebit b; - - b = malloc_new_zks (pool, "ffebit", - offsetof (struct _ffebit_, bits) - + (size + CHAR_BIT - 1) / CHAR_BIT, - 0); - b->pool = pool; - b->size = size; - - return b; -} - -/* ffebit_set -- Set value of # of bits - - ffebit b; // the ffebit object - ffebitCount offset; // 0..size-1 - bool value; // FALSE (0), TRUE (1) - ffebitCount length; // # bits to set starting at offset (usually 1) - ffebit_set(b,offset,value,length); - - Sets bit #s <offset> through <offset + length - 1> to <value>. */ - -void -ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length) -{ - ffebitCount i; - ffebitCount element; - ffebitCount bitno; - - assert (offset + length <= b->size); - - for (i = 0; i < length; ++i, ++offset) - { - element = offset / CHAR_BIT; - bitno = offset % CHAR_BIT; - b->bits[element] = (((unsigned char) (value ? 1 : 0)) << bitno) - | (b->bits[element] & ~((unsigned char) 1 << bitno)); - } -} - -/* ffebit_test -- Test value of # of bits - - ffebit b; // the ffebit object - ffebitCount offset; // 0..size-1 - bool value; // FALSE (0), TRUE (1) - ffebitCount length; // # bits with same value - ffebit_test(b,offset,&value,&length); - - Returns value of bits at <offset> through <offset + length - 1> in - <value>. If <offset> is already at the end of the bit array (if - offset == ffebit_size(b)), <length> is set to 0 and <value> is - undefined. */ - -void -ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length) -{ - ffebitCount i; - ffebitCount element; - ffebitCount bitno; - - if (offset >= b->size) - { - assert (offset == b->size); - *length = 0; - return; - } - - element = offset / CHAR_BIT; - bitno = offset % CHAR_BIT; - *value = (b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE; - *length = 1; - - for (i = b->size - offset - 1, ++offset; i != 0; --i, ++offset, ++*length) - { - element = offset / CHAR_BIT; - bitno = offset % CHAR_BIT; - if (*value - != ((b->bits[element] & ((unsigned char) 1 << bitno)) == 0 ? FALSE : TRUE)) - break; - } -} diff --git a/gcc/f/bit.h b/gcc/f/bit.h deleted file mode 100755 index 0e84499..0000000 --- a/gcc/f/bit.h +++ /dev/null @@ -1,84 +0,0 @@ -/* bit.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - bit.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_bit -#define _H_f_bit - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffebit_ *ffebit; -typedef unsigned long ffebitCount; -#define ffebitCount_f "l" - -/* Include files needed by this one. */ - -#include "malloc.h" - -/* Structure definitions. */ - -struct _ffebit_ - { - mallocPool pool; - ffebitCount size; - unsigned char bits[1]; - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffebit_count (ffebit b, ffebitCount offset, bool value, ffebitCount range, - ffebitCount *number); -void ffebit_kill (ffebit b); -ffebit ffebit_new (mallocPool pool, ffebitCount size); -void ffebit_set (ffebit b, ffebitCount offset, bool value, ffebitCount length); -void ffebit_test (ffebit b, ffebitCount offset, bool *value, ffebitCount *length); - -/* Define macros. */ - -#define ffebit_init_0() -#define ffebit_init_1() -#define ffebit_init_2() -#define ffebit_init_3() -#define ffebit_init_4() -#define ffebit_pool(b) ((b)->pool) -#define ffebit_size(b) ((b)->size) -#define ffebit_terminate_0() -#define ffebit_terminate_1() -#define ffebit_terminate_2() -#define ffebit_terminate_3() -#define ffebit_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/bld-op.def b/gcc/f/bld-op.def deleted file mode 100755 index 44cde44..0000000 --- a/gcc/f/bld-op.def +++ /dev/null @@ -1,69 +0,0 @@ -/* bld-op.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - bad.c - - Modifications: -*/ - -FFEBLD_OP (FFEBLD_opANY, "ANY", 0) -FFEBLD_OP (FFEBLD_opSTAR, "STAR", 0) /* For adjustable arrays, alternate return dummies, etc. */ -FFEBLD_OP (FFEBLD_opCONTER, "CONTER", 0) -FFEBLD_OP (FFEBLD_opARRTER, "ARRTER", 0) /* Array of constants (DATA...). */ -FFEBLD_OP (FFEBLD_opACCTER, "ACCTER", 0) /* Accreting ARRTER. */ -FFEBLD_OP (FFEBLD_opSYMTER, "SYMTER", 0) -FFEBLD_OP (FFEBLD_opITEM, "ITEM", 0) -FFEBLD_OP (FFEBLD_opUPLUS, "UPLUS", 1) -FFEBLD_OP (FFEBLD_opUMINUS, "UMINUS", 1) -FFEBLD_OP (FFEBLD_opADD, "ADD", 2) -FFEBLD_OP (FFEBLD_opSUBTRACT, "SUBTRACT", 2) -FFEBLD_OP (FFEBLD_opMULTIPLY, "MULTIPLY", 2) -FFEBLD_OP (FFEBLD_opDIVIDE, "DIVIDE", 2) -FFEBLD_OP (FFEBLD_opPOWER, "POWER", 2) -FFEBLD_OP (FFEBLD_opCONCATENATE, "CONCATENATE", 2) -FFEBLD_OP (FFEBLD_opNOT, "NOT", 1) -FFEBLD_OP (FFEBLD_opLT, "LT", 2) -FFEBLD_OP (FFEBLD_opLE, "LE", 2) -FFEBLD_OP (FFEBLD_opEQ, "EQ", 2) -FFEBLD_OP (FFEBLD_opNE, "NE", 2) -FFEBLD_OP (FFEBLD_opGT, "GT", 2) -FFEBLD_OP (FFEBLD_opGE, "GE", 2) -FFEBLD_OP (FFEBLD_opAND, "AND", 2) -FFEBLD_OP (FFEBLD_opOR, "OR", 2) -FFEBLD_OP (FFEBLD_opXOR, "XOR", 2) -FFEBLD_OP (FFEBLD_opEQV, "EQV", 2) -FFEBLD_OP (FFEBLD_opNEQV, "NEQV", 2) -FFEBLD_OP (FFEBLD_opPAREN, "PAREN", 1) -FFEBLD_OP (FFEBLD_opPERCENT_LOC, "%LOC", 1) -FFEBLD_OP (FFEBLD_opPERCENT_VAL, "%VAL", 1) -FFEBLD_OP (FFEBLD_opPERCENT_REF, "%REF", 1) -FFEBLD_OP (FFEBLD_opPERCENT_DESCR, "%DESCR", 1) -FFEBLD_OP (FFEBLD_opCONVERT, "CONVERT", 1) -FFEBLD_OP (FFEBLD_opREPEAT, "REPEAT", 2) -FFEBLD_OP (FFEBLD_opBOUNDS, "BOUNDS", 2) /* For low:high in dimension lists. */ -FFEBLD_OP (FFEBLD_opFUNCREF, "FUNCREF", 2) -FFEBLD_OP (FFEBLD_opSUBRREF, "SUBRREF", 2) -FFEBLD_OP (FFEBLD_opARRAYREF, "ARRAYREF", 2) -FFEBLD_OP (FFEBLD_opSUBSTR, "SUBSTR", 2) -FFEBLD_OP (FFEBLD_opLABTER, "LABTER", 0) -FFEBLD_OP (FFEBLD_opLABTOK, "LABTOK", 0) /* Like LABTER but contains ffelexToken instead. */ -FFEBLD_OP (FFEBLD_opIMPDO, "IMPDO", 2) diff --git a/gcc/f/bld.c b/gcc/f/bld.c deleted file mode 100755 index 6e75692..0000000 --- a/gcc/f/bld.c +++ /dev/null @@ -1,5794 +0,0 @@ -/* bld.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - The primary "output" of the FFE includes ffebld objects, which - connect expressions, operators, and operands together, along with - connecting lists of expressions together for argument or dimension - lists. - - Modifications: - 30-Aug-92 JCB 1.1 - Change names of some things for consistency. -*/ - -/* Include files. */ - -#include "proj.h" -#include "bld.h" -#include "bit.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" -#include "target.h" -#include "where.h" - -/* Externals defined here. */ - -ffebldArity ffebld_arity_op_[] -= -{ -#define FFEBLD_OP(KWD,NAME,ARITY) ARITY, -#include "bld-op.def" -#undef FFEBLD_OP -}; -struct _ffebld_pool_stack_ ffebld_pool_stack_; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -#if FFEBLD_BLANK_ -static struct _ffebld_ ffebld_blank_ -= -{ - 0, - {FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, FFEINFO_kindNONE, - FFEINFO_whereNONE, FFETARGET_charactersizeNONE}, - {NULL, NULL} -}; -#endif -#if FFETARGET_okCHARACTER1 -static ffebldConstant ffebld_constant_character1_; -#endif -#if FFETARGET_okCHARACTER2 -static ffebldConstant ffebld_constant_character2_; -#endif -#if FFETARGET_okCHARACTER3 -static ffebldConstant ffebld_constant_character3_; -#endif -#if FFETARGET_okCHARACTER4 -static ffebldConstant ffebld_constant_character4_; -#endif -#if FFETARGET_okCHARACTER5 -static ffebldConstant ffebld_constant_character5_; -#endif -#if FFETARGET_okCHARACTER6 -static ffebldConstant ffebld_constant_character6_; -#endif -#if FFETARGET_okCHARACTER7 -static ffebldConstant ffebld_constant_character7_; -#endif -#if FFETARGET_okCHARACTER8 -static ffebldConstant ffebld_constant_character8_; -#endif -#if FFETARGET_okCOMPLEX1 -static ffebldConstant ffebld_constant_complex1_; -#endif -#if FFETARGET_okCOMPLEX2 -static ffebldConstant ffebld_constant_complex2_; -#endif -#if FFETARGET_okCOMPLEX3 -static ffebldConstant ffebld_constant_complex3_; -#endif -#if FFETARGET_okCOMPLEX4 -static ffebldConstant ffebld_constant_complex4_; -#endif -#if FFETARGET_okCOMPLEX5 -static ffebldConstant ffebld_constant_complex5_; -#endif -#if FFETARGET_okCOMPLEX6 -static ffebldConstant ffebld_constant_complex6_; -#endif -#if FFETARGET_okCOMPLEX7 -static ffebldConstant ffebld_constant_complex7_; -#endif -#if FFETARGET_okCOMPLEX8 -static ffebldConstant ffebld_constant_complex8_; -#endif -#if FFETARGET_okINTEGER1 -static ffebldConstant ffebld_constant_integer1_; -#endif -#if FFETARGET_okINTEGER2 -static ffebldConstant ffebld_constant_integer2_; -#endif -#if FFETARGET_okINTEGER3 -static ffebldConstant ffebld_constant_integer3_; -#endif -#if FFETARGET_okINTEGER4 -static ffebldConstant ffebld_constant_integer4_; -#endif -#if FFETARGET_okINTEGER5 -static ffebldConstant ffebld_constant_integer5_; -#endif -#if FFETARGET_okINTEGER6 -static ffebldConstant ffebld_constant_integer6_; -#endif -#if FFETARGET_okINTEGER7 -static ffebldConstant ffebld_constant_integer7_; -#endif -#if FFETARGET_okINTEGER8 -static ffebldConstant ffebld_constant_integer8_; -#endif -#if FFETARGET_okLOGICAL1 -static ffebldConstant ffebld_constant_logical1_; -#endif -#if FFETARGET_okLOGICAL2 -static ffebldConstant ffebld_constant_logical2_; -#endif -#if FFETARGET_okLOGICAL3 -static ffebldConstant ffebld_constant_logical3_; -#endif -#if FFETARGET_okLOGICAL4 -static ffebldConstant ffebld_constant_logical4_; -#endif -#if FFETARGET_okLOGICAL5 -static ffebldConstant ffebld_constant_logical5_; -#endif -#if FFETARGET_okLOGICAL6 -static ffebldConstant ffebld_constant_logical6_; -#endif -#if FFETARGET_okLOGICAL7 -static ffebldConstant ffebld_constant_logical7_; -#endif -#if FFETARGET_okLOGICAL8 -static ffebldConstant ffebld_constant_logical8_; -#endif -#if FFETARGET_okREAL1 -static ffebldConstant ffebld_constant_real1_; -#endif -#if FFETARGET_okREAL2 -static ffebldConstant ffebld_constant_real2_; -#endif -#if FFETARGET_okREAL3 -static ffebldConstant ffebld_constant_real3_; -#endif -#if FFETARGET_okREAL4 -static ffebldConstant ffebld_constant_real4_; -#endif -#if FFETARGET_okREAL5 -static ffebldConstant ffebld_constant_real5_; -#endif -#if FFETARGET_okREAL6 -static ffebldConstant ffebld_constant_real6_; -#endif -#if FFETARGET_okREAL7 -static ffebldConstant ffebld_constant_real7_; -#endif -#if FFETARGET_okREAL8 -static ffebldConstant ffebld_constant_real8_; -#endif -static ffebldConstant ffebld_constant_hollerith_; -static ffebldConstant ffebld_constant_typeless_[FFEBLD_constTYPELESS_LAST - - FFEBLD_constTYPELESS_FIRST + 1]; - -static char *ffebld_op_string_[] -= -{ -#define FFEBLD_OP(KWD,NAME,ARITY) NAME, -#include "bld-op.def" -#undef FFEBLD_OP -}; - -/* Static functions (internal). */ - - -/* Internal macros. */ - -#define integerdefault_ CATX(integer,FFETARGET_ktINTEGERDEFAULT) -#define logicaldefault_ CATX(logical,FFETARGET_ktLOGICALDEFAULT) -#define realdefault_ CATX(real,FFETARGET_ktREALDEFAULT) -#define realdouble_ CATX(real,FFETARGET_ktREALDOUBLE) -#define realquad_ CATX(real,FFETARGET_ktREALQUAD) - -/* ffebld_constant_cmp -- Compare two constants a la strcmp - - ffebldConstant c1, c2; - if (ffebld_constant_cmp(c1,c2) == 0) - // they're equal, else they're not. - - Returns -1 if c1 < c2, 0 if c1 == c2, +1 if c1 == c2. */ - -int -ffebld_constant_cmp (ffebldConstant c1, ffebldConstant c2) -{ - if (c1 == c2) - return 0; - - assert (ffebld_constant_type (c1) == ffebld_constant_type (c2)); - - switch (ffebld_constant_type (c1)) - { -#if FFETARGET_okINTEGER1 - case FFEBLD_constINTEGER1: - return ffetarget_cmp_integer1 (ffebld_constant_integer1 (c1), - ffebld_constant_integer1 (c2)); -#endif - -#if FFETARGET_okINTEGER2 - case FFEBLD_constINTEGER2: - return ffetarget_cmp_integer2 (ffebld_constant_integer2 (c1), - ffebld_constant_integer2 (c2)); -#endif - -#if FFETARGET_okINTEGER3 - case FFEBLD_constINTEGER3: - return ffetarget_cmp_integer3 (ffebld_constant_integer3 (c1), - ffebld_constant_integer3 (c2)); -#endif - -#if FFETARGET_okINTEGER4 - case FFEBLD_constINTEGER4: - return ffetarget_cmp_integer4 (ffebld_constant_integer4 (c1), - ffebld_constant_integer4 (c2)); -#endif - -#if FFETARGET_okINTEGER5 - case FFEBLD_constINTEGER5: - return ffetarget_cmp_integer5 (ffebld_constant_integer5 (c1), - ffebld_constant_integer5 (c2)); -#endif - -#if FFETARGET_okINTEGER6 - case FFEBLD_constINTEGER6: - return ffetarget_cmp_integer6 (ffebld_constant_integer6 (c1), - ffebld_constant_integer6 (c2)); -#endif - -#if FFETARGET_okINTEGER7 - case FFEBLD_constINTEGER7: - return ffetarget_cmp_integer7 (ffebld_constant_integer7 (c1), - ffebld_constant_integer7 (c2)); -#endif - -#if FFETARGET_okINTEGER8 - case FFEBLD_constINTEGER8: - return ffetarget_cmp_integer8 (ffebld_constant_integer8 (c1), - ffebld_constant_integer8 (c2)); -#endif - -#if FFETARGET_okLOGICAL1 - case FFEBLD_constLOGICAL1: - return ffetarget_cmp_logical1 (ffebld_constant_logical1 (c1), - ffebld_constant_logical1 (c2)); -#endif - -#if FFETARGET_okLOGICAL2 - case FFEBLD_constLOGICAL2: - return ffetarget_cmp_logical2 (ffebld_constant_logical2 (c1), - ffebld_constant_logical2 (c2)); -#endif - -#if FFETARGET_okLOGICAL3 - case FFEBLD_constLOGICAL3: - return ffetarget_cmp_logical3 (ffebld_constant_logical3 (c1), - ffebld_constant_logical3 (c2)); -#endif - -#if FFETARGET_okLOGICAL4 - case FFEBLD_constLOGICAL4: - return ffetarget_cmp_logical4 (ffebld_constant_logical4 (c1), - ffebld_constant_logical4 (c2)); -#endif - -#if FFETARGET_okLOGICAL5 - case FFEBLD_constLOGICAL5: - return ffetarget_cmp_logical5 (ffebld_constant_logical5 (c1), - ffebld_constant_logical5 (c2)); -#endif - -#if FFETARGET_okLOGICAL6 - case FFEBLD_constLOGICAL6: - return ffetarget_cmp_logical6 (ffebld_constant_logical6 (c1), - ffebld_constant_logical6 (c2)); -#endif - -#if FFETARGET_okLOGICAL7 - case FFEBLD_constLOGICAL7: - return ffetarget_cmp_logical7 (ffebld_constant_logical7 (c1), - ffebld_constant_logical7 (c2)); -#endif - -#if FFETARGET_okLOGICAL8 - case FFEBLD_constLOGICAL8: - return ffetarget_cmp_logical8 (ffebld_constant_logical8 (c1), - ffebld_constant_logical8 (c2)); -#endif - -#if FFETARGET_okREAL1 - case FFEBLD_constREAL1: - return ffetarget_cmp_real1 (ffebld_constant_real1 (c1), - ffebld_constant_real1 (c2)); -#endif - -#if FFETARGET_okREAL2 - case FFEBLD_constREAL2: - return ffetarget_cmp_real2 (ffebld_constant_real2 (c1), - ffebld_constant_real2 (c2)); -#endif - -#if FFETARGET_okREAL3 - case FFEBLD_constREAL3: - return ffetarget_cmp_real3 (ffebld_constant_real3 (c1), - ffebld_constant_real3 (c2)); -#endif - -#if FFETARGET_okREAL4 - case FFEBLD_constREAL4: - return ffetarget_cmp_real4 (ffebld_constant_real4 (c1), - ffebld_constant_real4 (c2)); -#endif - -#if FFETARGET_okREAL5 - case FFEBLD_constREAL5: - return ffetarget_cmp_real5 (ffebld_constant_real5 (c1), - ffebld_constant_real5 (c2)); -#endif - -#if FFETARGET_okREAL6 - case FFEBLD_constREAL6: - return ffetarget_cmp_real6 (ffebld_constant_real6 (c1), - ffebld_constant_real6 (c2)); -#endif - -#if FFETARGET_okREAL7 - case FFEBLD_constREAL7: - return ffetarget_cmp_real7 (ffebld_constant_real7 (c1), - ffebld_constant_real7 (c2)); -#endif - -#if FFETARGET_okREAL8 - case FFEBLD_constREAL8: - return ffetarget_cmp_real8 (ffebld_constant_real8 (c1), - ffebld_constant_real8 (c2)); -#endif - -#if FFETARGET_okCHARACTER1 - case FFEBLD_constCHARACTER1: - return ffetarget_cmp_character1 (ffebld_constant_character1 (c1), - ffebld_constant_character1 (c2)); -#endif - -#if FFETARGET_okCHARACTER2 - case FFEBLD_constCHARACTER2: - return ffetarget_cmp_character2 (ffebld_constant_character2 (c1), - ffebld_constant_character2 (c2)); -#endif - -#if FFETARGET_okCHARACTER3 - case FFEBLD_constCHARACTER3: - return ffetarget_cmp_character3 (ffebld_constant_character3 (c1), - ffebld_constant_character3 (c2)); -#endif - -#if FFETARGET_okCHARACTER4 - case FFEBLD_constCHARACTER4: - return ffetarget_cmp_character4 (ffebld_constant_character4 (c1), - ffebld_constant_character4 (c2)); -#endif - -#if FFETARGET_okCHARACTER5 - case FFEBLD_constCHARACTER5: - return ffetarget_cmp_character5 (ffebld_constant_character5 (c1), - ffebld_constant_character5 (c2)); -#endif - -#if FFETARGET_okCHARACTER6 - case FFEBLD_constCHARACTER6: - return ffetarget_cmp_character6 (ffebld_constant_character6 (c1), - ffebld_constant_character6 (c2)); -#endif - -#if FFETARGET_okCHARACTER7 - case FFEBLD_constCHARACTER7: - return ffetarget_cmp_character7 (ffebld_constant_character7 (c1), - ffebld_constant_character7 (c2)); -#endif - -#if FFETARGET_okCHARACTER8 - case FFEBLD_constCHARACTER8: - return ffetarget_cmp_character8 (ffebld_constant_character8 (c1), - ffebld_constant_character8 (c2)); -#endif - - default: - assert ("bad constant type" == NULL); - return 0; - } -} - -/* ffebld_constant_dump -- Display summary of constant's contents - - ffebldConstant c; - ffebld_constant_dump(c); - - Displays the constant in summary form. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffebld_constant_dump (ffebldConstant c) -{ - switch (ffebld_constant_type (c)) - { -#if FFETARGET_okINTEGER1 - case FFEBLD_constINTEGER1: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER1); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEBLD_constINTEGER2: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER2); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEBLD_constINTEGER3: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER3); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEBLD_constINTEGER4: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER4); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEBLD_constINTEGER5: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER5); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER5); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEBLD_constINTEGER6: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER6); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER6); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEBLD_constINTEGER7: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER7); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER7); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEBLD_constINTEGER8: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER8); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER8); - break; -#endif - -#if FFETARGET_okLOGICAL1 - case FFEBLD_constLOGICAL1: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL1); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEBLD_constLOGICAL2: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL2); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEBLD_constLOGICAL3: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL3); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEBLD_constLOGICAL4: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL4); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEBLD_constLOGICAL5: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL5); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL5); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEBLD_constLOGICAL6: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL6); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL6); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEBLD_constLOGICAL7: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL7); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL7); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEBLD_constLOGICAL8: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICAL8); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL8); - break; -#endif - -#if FFETARGET_okREAL1 - case FFEBLD_constREAL1: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL1); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEBLD_constREAL2: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL2); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL2); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEBLD_constREAL3: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL3); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL3); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEBLD_constREAL4: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL4); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL4); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEBLD_constREAL5: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL5); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL5); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEBLD_constREAL6: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL6); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL6); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEBLD_constREAL7: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL7); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL7); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEBLD_constREAL8: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREAL8); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL8); - break; -#endif - -#if FFETARGET_okCOMPLEX1 - case FFEBLD_constCOMPLEX1: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL1); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEBLD_constCOMPLEX2: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL2); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL2); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEBLD_constCOMPLEX3: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL3); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL3); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEBLD_constCOMPLEX4: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL4); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL4); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEBLD_constCOMPLEX5: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL5); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL5); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEBLD_constCOMPLEX6: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL6); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL6); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEBLD_constCOMPLEX7: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL7); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL7); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEBLD_constCOMPLEX8: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREAL8); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL8); - break; -#endif - -#if FFETARGET_okCHARACTER1 - case FFEBLD_constCHARACTER1: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER1); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER1); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEBLD_constCHARACTER2: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER2); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER2); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEBLD_constCHARACTER3: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER3); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER3); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEBLD_constCHARACTER4: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER4); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER4); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEBLD_constCHARACTER5: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER5); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER5); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEBLD_constCHARACTER6: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER6); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER6); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEBLD_constCHARACTER7: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER7); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER7); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEBLD_constCHARACTER8: - ffebld_dump_prefix (dmpout, FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER8); - ffebld_constantunion_dump (ffebld_constant_union (c), - FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTER8); - break; -#endif - - case FFEBLD_constHOLLERITH: - fprintf (dmpout, "H%" ffetargetHollerithSize_f "u/", - ffebld_constant_hollerith (c).length); - ffetarget_print_hollerith (dmpout, ffebld_constant_hollerith (c)); - break; - - case FFEBLD_constBINARY_MIL: - fprintf (dmpout, "BM/"); - ffetarget_print_binarymil (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constBINARY_VXT: - fprintf (dmpout, "BV/"); - ffetarget_print_binaryvxt (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constOCTAL_MIL: - fprintf (dmpout, "OM/"); - ffetarget_print_octalmil (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constOCTAL_VXT: - fprintf (dmpout, "OV/"); - ffetarget_print_octalvxt (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constHEX_X_MIL: - fprintf (dmpout, "XM/"); - ffetarget_print_hexxmil (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constHEX_X_VXT: - fprintf (dmpout, "XV/"); - ffetarget_print_hexxvxt (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constHEX_Z_MIL: - fprintf (dmpout, "ZM/"); - ffetarget_print_hexzmil (dmpout, ffebld_constant_typeless (c)); - break; - - case FFEBLD_constHEX_Z_VXT: - fprintf (dmpout, "ZV/"); - ffetarget_print_hexzvxt (dmpout, ffebld_constant_typeless (c)); - break; - - default: - assert ("bad constant type" == NULL); - fprintf (dmpout, "?/?"); - break; - } -} -#endif - -/* ffebld_constant_is_magical -- Determine if integer is "magical" - - ffebldConstant c; - if (ffebld_constant_is_magical(c)) - // it is 2**(n-1), where n is # bits in ffetargetIntegerDefault type - // (this test is important for 2's-complement machines only). */ - -bool -ffebld_constant_is_magical (ffebldConstant c) -{ - switch (ffebld_constant_type (c)) - { - case FFEBLD_constINTEGERDEFAULT: - return ffetarget_integerdefault_is_magical (ffebld_constant_integer1 (c)); - - default: - return FALSE; - } -} - -/* Determine if constant is zero. Used to ensure step count - for DO loops isn't zero, also to determine if values will - be binary zeros, so not entirely portable at this point. */ - -bool -ffebld_constant_is_zero (ffebldConstant c) -{ - switch (ffebld_constant_type (c)) - { -#if FFETARGET_okINTEGER1 - case FFEBLD_constINTEGER1: - return ffebld_constant_integer1 (c) == 0; -#endif - -#if FFETARGET_okINTEGER2 - case FFEBLD_constINTEGER2: - return ffebld_constant_integer2 (c) == 0; -#endif - -#if FFETARGET_okINTEGER3 - case FFEBLD_constINTEGER3: - return ffebld_constant_integer3 (c) == 0; -#endif - -#if FFETARGET_okINTEGER4 - case FFEBLD_constINTEGER4: - return ffebld_constant_integer4 (c) == 0; -#endif - -#if FFETARGET_okINTEGER5 - case FFEBLD_constINTEGER5: - return ffebld_constant_integer5 (c) == 0; -#endif - -#if FFETARGET_okINTEGER6 - case FFEBLD_constINTEGER6: - return ffebld_constant_integer6 (c) == 0; -#endif - -#if FFETARGET_okINTEGER7 - case FFEBLD_constINTEGER7: - return ffebld_constant_integer7 (c) == 0; -#endif - -#if FFETARGET_okINTEGER8 - case FFEBLD_constINTEGER8: - return ffebld_constant_integer8 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL1 - case FFEBLD_constLOGICAL1: - return ffebld_constant_logical1 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEBLD_constLOGICAL2: - return ffebld_constant_logical2 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEBLD_constLOGICAL3: - return ffebld_constant_logical3 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEBLD_constLOGICAL4: - return ffebld_constant_logical4 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEBLD_constLOGICAL5: - return ffebld_constant_logical5 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEBLD_constLOGICAL6: - return ffebld_constant_logical6 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEBLD_constLOGICAL7: - return ffebld_constant_logical7 (c) == 0; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEBLD_constLOGICAL8: - return ffebld_constant_logical8 (c) == 0; -#endif - -#if FFETARGET_okREAL1 - case FFEBLD_constREAL1: - return ffetarget_iszero_real1 (ffebld_constant_real1 (c)); -#endif - -#if FFETARGET_okREAL2 - case FFEBLD_constREAL2: - return ffetarget_iszero_real2 (ffebld_constant_real2 (c)); -#endif - -#if FFETARGET_okREAL3 - case FFEBLD_constREAL3: - return ffetarget_iszero_real3 (ffebld_constant_real3 (c)); -#endif - -#if FFETARGET_okREAL4 - case FFEBLD_constREAL4: - return ffetarget_iszero_real4 (ffebld_constant_real4 (c)); -#endif - -#if FFETARGET_okREAL5 - case FFEBLD_constREAL5: - return ffetarget_iszero_real5 (ffebld_constant_real5 (c)); -#endif - -#if FFETARGET_okREAL6 - case FFEBLD_constREAL6: - return ffetarget_iszero_real6 (ffebld_constant_real6 (c)); -#endif - -#if FFETARGET_okREAL7 - case FFEBLD_constREAL7: - return ffetarget_iszero_real7 (ffebld_constant_real7 (c)); -#endif - -#if FFETARGET_okREAL8 - case FFEBLD_constREAL8: - return ffetarget_iszero_real8 (ffebld_constant_real8 (c)); -#endif - -#if FFETARGET_okCOMPLEX1 - case FFEBLD_constCOMPLEX1: - return ffetarget_iszero_real1 (ffebld_constant_complex1 (c).real) - && ffetarget_iszero_real1 (ffebld_constant_complex1 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEBLD_constCOMPLEX2: - return ffetarget_iszero_real2 (ffebld_constant_complex2 (c).real) - && ffetarget_iszero_real2 (ffebld_constant_complex2 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEBLD_constCOMPLEX3: - return ffetarget_iszero_real3 (ffebld_constant_complex3 (c).real) - && ffetarget_iszero_real3 (ffebld_constant_complex3 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEBLD_constCOMPLEX4: - return ffetarget_iszero_real4 (ffebld_constant_complex4 (c).real) - && ffetarget_iszero_real4 (ffebld_constant_complex4 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEBLD_constCOMPLEX5: - return ffetarget_iszero_real5 (ffebld_constant_complex5 (c).real) - && ffetarget_iszero_real5 (ffebld_constant_complex5 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEBLD_constCOMPLEX6: - return ffetarget_iszero_real6 (ffebld_constant_complex6 (c).real) - && ffetarget_iszero_real6 (ffebld_constant_complex6 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEBLD_constCOMPLEX7: - return ffetarget_iszero_real7 (ffebld_constant_complex7 (c).real) - && ffetarget_iszero_real7 (ffebld_constant_complex7 (c).imaginary); -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEBLD_constCOMPLEX8: - return ffetarget_iszero_real8 (ffebld_constant_complex8 (c).real) - && ffetarget_iszero_real8 (ffebld_constant_complex8 (c).imaginary); -#endif - -#if FFETARGET_okCHARACTER1 - case FFEBLD_constCHARACTER1: - return ffetarget_iszero_character1 (ffebld_constant_character1 (c)); -#endif - -#if FFETARGET_okCHARACTER2 || FFETARGET_okCHARACTER3 /* ... */ -#error "no support for these!!" -#endif - - case FFEBLD_constHOLLERITH: - return ffetarget_iszero_hollerith (ffebld_constant_hollerith (c)); - - case FFEBLD_constBINARY_MIL: - case FFEBLD_constBINARY_VXT: - case FFEBLD_constOCTAL_MIL: - case FFEBLD_constOCTAL_VXT: - case FFEBLD_constHEX_X_MIL: - case FFEBLD_constHEX_X_VXT: - case FFEBLD_constHEX_Z_MIL: - case FFEBLD_constHEX_Z_VXT: - return ffetarget_iszero_typeless (ffebld_constant_typeless (c)); - - default: - return FALSE; - } -} - -/* ffebld_constant_new_character1 -- Return character1 constant object from token - - See prototype. */ - -#if FFETARGET_okCHARACTER1 -ffebldConstant -ffebld_constant_new_character1 (ffelexToken t) -{ - ffetargetCharacter1 val; - - ffetarget_character1 (&val, t, ffebld_constant_pool()); - return ffebld_constant_new_character1_val (val); -} - -#endif -/* ffebld_constant_new_character1_val -- Return an character1 constant object - - See prototype. */ - -#if FFETARGET_okCHARACTER1 -ffebldConstant -ffebld_constant_new_character1_val (ffetargetCharacter1 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - ffetarget_verify_character1 (ffebld_constant_pool(), val); - - for (c = (ffebldConstant) &ffebld_constant_character1_; - c->next != NULL; - c = c->next) - { - malloc_verify_kp (ffebld_constant_pool(), - c->next, - sizeof (*(c->next))); - ffetarget_verify_character1 (ffebld_constant_pool(), - ffebld_constant_character1 (c->next)); - cmp = ffetarget_cmp_character1 (val, - ffebld_constant_character1 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constCHARACTER1", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constCHARACTER1; - nc->u.character1 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_complex1 -- Return complex1 constant object from token - - See prototype. */ - -#if FFETARGET_okCOMPLEX1 -ffebldConstant -ffebld_constant_new_complex1 (ffebldConstant real, - ffebldConstant imaginary) -{ - ffetargetComplex1 val; - - val.real = ffebld_constant_real1 (real); - val.imaginary = ffebld_constant_real1 (imaginary); - return ffebld_constant_new_complex1_val (val); -} - -#endif -/* ffebld_constant_new_complex1_val -- Return a complex1 constant object - - See prototype. */ - -#if FFETARGET_okCOMPLEX1 -ffebldConstant -ffebld_constant_new_complex1_val (ffetargetComplex1 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_complex1_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_real1 (val.real, ffebld_constant_complex1 (c->next).real); - if (cmp == 0) - cmp = ffetarget_cmp_real1 (val.imaginary, - ffebld_constant_complex1 (c->next).imaginary); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constCOMPLEX1", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constCOMPLEX1; - nc->u.complex1 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_complex2 -- Return complex2 constant object from token - - See prototype. */ - -#if FFETARGET_okCOMPLEX2 -ffebldConstant -ffebld_constant_new_complex2 (ffebldConstant real, - ffebldConstant imaginary) -{ - ffetargetComplex2 val; - - val.real = ffebld_constant_real2 (real); - val.imaginary = ffebld_constant_real2 (imaginary); - return ffebld_constant_new_complex2_val (val); -} - -#endif -/* ffebld_constant_new_complex2_val -- Return a complex2 constant object - - See prototype. */ - -#if FFETARGET_okCOMPLEX2 -ffebldConstant -ffebld_constant_new_complex2_val (ffetargetComplex2 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_complex2_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_real2 (val.real, ffebld_constant_complex2 (c->next).real); - if (cmp == 0) - cmp = ffetarget_cmp_real2 (val.imaginary, - ffebld_constant_complex2 (c->next).imaginary); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constCOMPLEX2", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constCOMPLEX2; - nc->u.complex2 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_hollerith -- Return hollerith constant object from token - - See prototype. */ - -ffebldConstant -ffebld_constant_new_hollerith (ffelexToken t) -{ - ffetargetHollerith val; - - ffetarget_hollerith (&val, t, ffebld_constant_pool()); - return ffebld_constant_new_hollerith_val (val); -} - -/* ffebld_constant_new_hollerith_val -- Return an hollerith constant object - - See prototype. */ - -ffebldConstant -ffebld_constant_new_hollerith_val (ffetargetHollerith val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_hollerith_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_hollerith (val, ffebld_constant_hollerith (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constHOLLERITH", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constHOLLERITH; - nc->u.hollerith = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -/* ffebld_constant_new_integer1 -- Return integer1 constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -#if FFETARGET_okINTEGER1 -ffebldConstant -ffebld_constant_new_integer1 (ffelexToken t) -{ - ffetargetInteger1 val; - - assert (ffelex_token_type (t) == FFELEX_typeNUMBER); - - ffetarget_integer1 (&val, t); - return ffebld_constant_new_integer1_val (val); -} - -#endif -/* ffebld_constant_new_integer1_val -- Return an integer1 constant object - - See prototype. */ - -#if FFETARGET_okINTEGER1 -ffebldConstant -ffebld_constant_new_integer1_val (ffetargetInteger1 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_integer1_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_integer1 (val, ffebld_constant_integer1 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constINTEGER1", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constINTEGER1; - nc->u.integer1 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_integer2_val -- Return an integer2 constant object - - See prototype. */ - -#if FFETARGET_okINTEGER2 -ffebldConstant -ffebld_constant_new_integer2_val (ffetargetInteger2 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_integer2_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_integer2 (val, ffebld_constant_integer2 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constINTEGER2", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constINTEGER2; - nc->u.integer2 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_integer3_val -- Return an integer3 constant object - - See prototype. */ - -#if FFETARGET_okINTEGER3 -ffebldConstant -ffebld_constant_new_integer3_val (ffetargetInteger3 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_integer3_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_integer3 (val, ffebld_constant_integer3 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constINTEGER3", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constINTEGER3; - nc->u.integer3 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_integer4_val -- Return an integer4 constant object - - See prototype. */ - -#if FFETARGET_okINTEGER4 -ffebldConstant -ffebld_constant_new_integer4_val (ffetargetInteger4 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_integer4_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_integer4 (val, ffebld_constant_integer4 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constINTEGER4", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constINTEGER4; - nc->u.integer4 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_integerbinary -- Return binary constant object from token - - See prototype. - - Parses the token as a binary integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_integerbinary (ffelexToken t) -{ - ffetargetIntegerDefault val; - - assert ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNUMBER)); - - ffetarget_integerbinary (&val, t); - return ffebld_constant_new_integerdefault_val (val); -} - -/* ffebld_constant_new_integerhex -- Return hex constant object from token - - See prototype. - - Parses the token as a hex integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_integerhex (ffelexToken t) -{ - ffetargetIntegerDefault val; - - assert ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNUMBER)); - - ffetarget_integerhex (&val, t); - return ffebld_constant_new_integerdefault_val (val); -} - -/* ffebld_constant_new_integeroctal -- Return octal constant object from token - - See prototype. - - Parses the token as a octal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_integeroctal (ffelexToken t) -{ - ffetargetIntegerDefault val; - - assert ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNUMBER)); - - ffetarget_integeroctal (&val, t); - return ffebld_constant_new_integerdefault_val (val); -} - -/* ffebld_constant_new_logical1 -- Return logical1 constant object from token - - See prototype. - - Parses the token as a decimal logical constant, thus it must be an - FFELEX_typeNUMBER. */ - -#if FFETARGET_okLOGICAL1 -ffebldConstant -ffebld_constant_new_logical1 (bool truth) -{ - ffetargetLogical1 val; - - ffetarget_logical1 (&val, truth); - return ffebld_constant_new_logical1_val (val); -} - -#endif -/* ffebld_constant_new_logical1_val -- Return a logical1 constant object - - See prototype. */ - -#if FFETARGET_okLOGICAL1 -ffebldConstant -ffebld_constant_new_logical1_val (ffetargetLogical1 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_logical1_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_logical1 (val, ffebld_constant_logical1 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constLOGICAL1", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constLOGICAL1; - nc->u.logical1 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_logical2_val -- Return a logical2 constant object - - See prototype. */ - -#if FFETARGET_okLOGICAL2 -ffebldConstant -ffebld_constant_new_logical2_val (ffetargetLogical2 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_logical2_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_logical2 (val, ffebld_constant_logical2 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constLOGICAL2", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constLOGICAL2; - nc->u.logical2 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_logical3_val -- Return a logical3 constant object - - See prototype. */ - -#if FFETARGET_okLOGICAL3 -ffebldConstant -ffebld_constant_new_logical3_val (ffetargetLogical3 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_logical3_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_logical3 (val, ffebld_constant_logical3 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constLOGICAL3", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constLOGICAL3; - nc->u.logical3 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_logical4_val -- Return a logical4 constant object - - See prototype. */ - -#if FFETARGET_okLOGICAL4 -ffebldConstant -ffebld_constant_new_logical4_val (ffetargetLogical4 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_logical4_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_logical4 (val, ffebld_constant_logical4 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constLOGICAL4", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constLOGICAL4; - nc->u.logical4 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_real1 -- Return real1 constant object from token - - See prototype. */ - -#if FFETARGET_okREAL1 -ffebldConstant -ffebld_constant_new_real1 (ffelexToken integer, ffelexToken decimal, - ffelexToken fraction, ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits) -{ - ffetargetReal1 val; - - ffetarget_real1 (&val, - integer, decimal, fraction, exponent, exponent_sign, exponent_digits); - return ffebld_constant_new_real1_val (val); -} - -#endif -/* ffebld_constant_new_real1_val -- Return an real1 constant object - - See prototype. */ - -#if FFETARGET_okREAL1 -ffebldConstant -ffebld_constant_new_real1_val (ffetargetReal1 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_real1_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_real1 (val, ffebld_constant_real1 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constREAL1", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constREAL1; - nc->u.real1 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_real2 -- Return real2 constant object from token - - See prototype. */ - -#if FFETARGET_okREAL2 -ffebldConstant -ffebld_constant_new_real2 (ffelexToken integer, ffelexToken decimal, - ffelexToken fraction, ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits) -{ - ffetargetReal2 val; - - ffetarget_real2 (&val, - integer, decimal, fraction, exponent, exponent_sign, exponent_digits); - return ffebld_constant_new_real2_val (val); -} - -#endif -/* ffebld_constant_new_real2_val -- Return an real2 constant object - - See prototype. */ - -#if FFETARGET_okREAL2 -ffebldConstant -ffebld_constant_new_real2_val (ffetargetReal2 val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_real2_; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_real2 (val, ffebld_constant_real2 (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constREAL2", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = FFEBLD_constREAL2; - nc->u.real2 = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -#endif -/* ffebld_constant_new_typeless_bm -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_bm (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_binarymil (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constBINARY_MIL, val); -} - -/* ffebld_constant_new_typeless_bv -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_bv (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_binaryvxt (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constBINARY_VXT, val); -} - -/* ffebld_constant_new_typeless_hxm -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_hxm (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_hexxmil (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constHEX_X_MIL, val); -} - -/* ffebld_constant_new_typeless_hxv -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_hxv (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_hexxvxt (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constHEX_X_VXT, val); -} - -/* ffebld_constant_new_typeless_hzm -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_hzm (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_hexzmil (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constHEX_Z_MIL, val); -} - -/* ffebld_constant_new_typeless_hzv -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_hzv (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_hexzvxt (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constHEX_Z_VXT, val); -} - -/* ffebld_constant_new_typeless_om -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_om (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_octalmil (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constOCTAL_MIL, val); -} - -/* ffebld_constant_new_typeless_ov -- Return typeless constant object from token - - See prototype. - - Parses the token as a decimal integer constant, thus it must be an - FFELEX_typeNUMBER. */ - -ffebldConstant -ffebld_constant_new_typeless_ov (ffelexToken t) -{ - ffetargetTypeless val; - - ffetarget_octalvxt (&val, t); - return ffebld_constant_new_typeless_val (FFEBLD_constOCTAL_VXT, val); -} - -/* ffebld_constant_new_typeless_val -- Return a typeless constant object - - See prototype. */ - -ffebldConstant -ffebld_constant_new_typeless_val (ffebldConst type, ffetargetTypeless val) -{ - ffebldConstant c; - ffebldConstant nc; - int cmp; - - for (c = (ffebldConstant) &ffebld_constant_typeless_[type - - FFEBLD_constTYPELESS_FIRST]; - c->next != NULL; - c = c->next) - { - cmp = ffetarget_cmp_typeless (val, ffebld_constant_typeless (c->next)); - if (cmp == 0) - return c->next; - if (cmp > 0) - break; - } - - nc = malloc_new_kp (ffebld_constant_pool(), - "FFEBLD_constTYPELESS", - sizeof (*nc)); - nc->next = c->next; - nc->consttype = type; - nc->u.typeless = val; -#ifdef FFECOM_constantHOOK - nc->hook = FFECOM_constantNULL; -#endif - c->next = nc; - - return nc; -} - -/* ffebld_constantarray_dump -- Display summary of array's contents - - ffebldConstantArray a; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetOffset size; - ffebld_constant_dump(a,bt,kt,size,NULL); - - Displays the constant array in summary form. The fifth argument, if - supplied, is an ffebit object that is consulted as to whether the - constant at a particular offset is valid. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffebld_constantarray_dump (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset size, ffebit bits) -{ - ffetargetOffset i; - ffebitCount j; - - ffebld_dump_prefix (dmpout, bt, kt); - - fprintf (dmpout, "\\("); - - if (bits == NULL) - { - for (i = 0; i < size; ++i) - { - ffebld_constantunion_dump (ffebld_constantarray_get (array, bt, kt, i), bt, - kt); - if (i != size - 1) - fputc (',', dmpout); - } - } - else - { - bool value; - ffebitCount length; - ffetargetOffset offset = 0; - - do - { - ffebit_test (bits, offset, &value, &length); - if (value && (length != 0)) - { - if (length == 1) - fprintf (dmpout, "[%" ffetargetOffset_f "d]:", offset); - else - fprintf (dmpout, - "[%" ffetargetOffset_f "u..%" ffetargetOffset_f "d]:", - offset, offset + (ffetargetOffset) length - 1); - for (j = 0; j < length; ++j, ++offset) - { - ffebld_constantunion_dump (ffebld_constantarray_get (array, bt, kt, - offset), bt, kt); - if (j != length - 1) - fputc (',', dmpout); - } - fprintf (dmpout, ";"); - } - else - offset += length; - } - while (length != 0); - } - fprintf (dmpout, "\\)"); - -} -#endif - -/* ffebld_constantarray_get -- Get a value from an array of constants - - See prototype. */ - -ffebldConstantUnion -ffebld_constantarray_get (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset offset) -{ - ffebldConstantUnion u; - - switch (bt) - { - case FFEINFO_basictypeINTEGER: - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - u.integer1 = *(array.integer1 + offset); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - u.integer2 = *(array.integer2 + offset); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - u.integer3 = *(array.integer3 + offset); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - u.integer4 = *(array.integer4 + offset); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - u.integer5 = *(array.integer5 + offset); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - u.integer6 = *(array.integer6 + offset); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - u.integer7 = *(array.integer7 + offset); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - u.integer8 = *(array.integer8 + offset); - break; -#endif - - default: - assert ("bad INTEGER kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - u.logical1 = *(array.logical1 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - u.logical2 = *(array.logical2 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - u.logical3 = *(array.logical3 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - u.logical4 = *(array.logical4 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - u.logical5 = *(array.logical5 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - u.logical6 = *(array.logical6 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - u.logical7 = *(array.logical7 + offset); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - u.logical8 = *(array.logical8 + offset); - break; -#endif - - default: - assert ("bad LOGICAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - u.real1 = *(array.real1 + offset); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - u.real2 = *(array.real2 + offset); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - u.real3 = *(array.real3 + offset); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - u.real4 = *(array.real4 + offset); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - u.real5 = *(array.real5 + offset); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - u.real6 = *(array.real6 + offset); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - u.real7 = *(array.real7 + offset); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - u.real8 = *(array.real8 + offset); - break; -#endif - - default: - assert ("bad REAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - u.complex1 = *(array.complex1 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - u.complex2 = *(array.complex2 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - u.complex3 = *(array.complex3 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - u.complex4 = *(array.complex4 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - u.complex5 = *(array.complex5 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - u.complex6 = *(array.complex6 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - u.complex7 = *(array.complex7 + offset); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - u.complex8 = *(array.complex8 + offset); - break; -#endif - - default: - assert ("bad COMPLEX kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - u.character1.length = 1; - u.character1.text = array.character1 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - u.character2.length = 1; - u.character2.text = array.character2 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - u.character3.length = 1; - u.character3.text = array.character3 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - u.character4.length = 1; - u.character4.text = array.character4 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - u.character5.length = 1; - u.character5.text = array.character5 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - u.character6.length = 1; - u.character6.text = array.character6 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - u.character7.length = 1; - u.character7.text = array.character7 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - u.character8.length = 1; - u.character8.text = array.character8 + offset; - break; -#endif - - default: - assert ("bad CHARACTER kindtype" == NULL); - break; - } - break; - - default: - assert ("bad basictype" == NULL); - break; - } - - return u; -} - -/* ffebld_constantarray_new -- Make an array of constants - - See prototype. */ - -ffebldConstantArray -ffebld_constantarray_new (ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset size) -{ - ffebldConstantArray ptr; - - switch (bt) - { - case FFEINFO_basictypeINTEGER: - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - ptr.integer1 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger1), - 0); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - ptr.integer2 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger2), - 0); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - ptr.integer3 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger3), - 0); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - ptr.integer4 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger4), - 0); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - ptr.integer5 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger5), - 0); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - ptr.integer6 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger6), - 0); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - ptr.integer7 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger7), - 0); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - ptr.integer8 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetInteger8), - 0); - break; -#endif - - default: - assert ("bad INTEGER kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - ptr.logical1 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical1), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - ptr.logical2 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical2), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - ptr.logical3 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical3), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - ptr.logical4 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical4), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - ptr.logical5 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical5), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - ptr.logical6 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical6), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - ptr.logical7 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical7), - 0); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - ptr.logical8 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetLogical8), - 0); - break; -#endif - - default: - assert ("bad LOGICAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - ptr.real1 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal1), - 0); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - ptr.real2 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal2), - 0); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - ptr.real3 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal3), - 0); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - ptr.real4 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal4), - 0); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - ptr.real5 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal5), - 0); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - ptr.real6 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal6), - 0); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - ptr.real7 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal7), - 0); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - ptr.real8 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetReal8), - 0); - break; -#endif - - default: - assert ("bad REAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - ptr.complex1 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex1), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - ptr.complex2 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex2), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - ptr.complex3 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex3), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - ptr.complex4 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex4), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - ptr.complex5 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex5), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - ptr.complex6 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex6), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - ptr.complex7 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex7), - 0); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - ptr.complex8 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size *= sizeof (ffetargetComplex8), - 0); - break; -#endif - - default: - assert ("bad COMPLEX kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - ptr.character1 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit1), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - ptr.character2 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit2), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - ptr.character3 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit3), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - ptr.character4 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit4), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - ptr.character5 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit5), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - ptr.character6 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit6), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - ptr.character7 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit7), - 0); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - ptr.character8 = malloc_new_zkp (ffebld_constant_pool(), - "ffebldConstantArray", - size - *= sizeof (ffetargetCharacterUnit8), - 0); - break; -#endif - - default: - assert ("bad CHARACTER kindtype" == NULL); - break; - } - break; - - default: - assert ("bad basictype" == NULL); - break; - } - - return ptr; -} - -/* ffebld_constantarray_preparray -- Prepare for copy between arrays - - See prototype. - - Like _prepare, but the source is an array instead of a single-value - constant. */ - -void -ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size, - ffebldConstantArray array, ffeinfoBasictype abt, ffeinfoKindtype akt, - ffetargetOffset offset, ffebldConstantArray source_array, - ffeinfoBasictype cbt, ffeinfoKindtype ckt) -{ - switch (abt) - { - case FFEINFO_basictypeINTEGER: - switch (akt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - *aptr = array.integer1 + offset; - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - *aptr = array.integer2 + offset; - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - *aptr = array.integer3 + offset; - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - *aptr = array.integer4 + offset; - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - *aptr = array.integer5 + offset; - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - *aptr = array.integer6 + offset; - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - *aptr = array.integer7 + offset; - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - *aptr = array.integer8 + offset; - break; -#endif - - default: - assert ("bad INTEGER akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (akt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - *aptr = array.logical1 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - *aptr = array.logical2 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - *aptr = array.logical3 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - *aptr = array.logical4 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - *aptr = array.logical5 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - *aptr = array.logical6 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - *aptr = array.logical7 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - *aptr = array.logical8 + offset; - break; -#endif - - default: - assert ("bad LOGICAL akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (akt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - *aptr = array.real1 + offset; - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - *aptr = array.real2 + offset; - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - *aptr = array.real3 + offset; - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - *aptr = array.real4 + offset; - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - *aptr = array.real5 + offset; - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - *aptr = array.real6 + offset; - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - *aptr = array.real7 + offset; - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - *aptr = array.real8 + offset; - break; -#endif - - default: - assert ("bad REAL akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (akt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - *aptr = array.complex1 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - *aptr = array.complex2 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - *aptr = array.complex3 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - *aptr = array.complex4 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - *aptr = array.complex5 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - *aptr = array.complex6 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - *aptr = array.complex7 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - *aptr = array.complex8 + offset; - break; -#endif - - default: - assert ("bad COMPLEX akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (akt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - *aptr = array.character1 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - *aptr = array.character2 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - *aptr = array.character3 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - *aptr = array.character4 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - *aptr = array.character5 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - *aptr = array.character6 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - *aptr = array.character7 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - *aptr = array.character8 + offset; - break; -#endif - - default: - assert ("bad CHARACTER akindtype" == NULL); - break; - } - break; - - default: - assert ("bad abasictype" == NULL); - break; - } - - switch (cbt) - { - case FFEINFO_basictypeINTEGER: - switch (ckt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - *cptr = source_array.integer1; - *size = sizeof (*source_array.integer1); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - *cptr = source_array.integer2; - *size = sizeof (*source_array.integer2); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - *cptr = source_array.integer3; - *size = sizeof (*source_array.integer3); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - *cptr = source_array.integer4; - *size = sizeof (*source_array.integer4); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - *cptr = source_array.integer5; - *size = sizeof (*source_array.integer5); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - *cptr = source_array.integer6; - *size = sizeof (*source_array.integer6); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - *cptr = source_array.integer7; - *size = sizeof (*source_array.integer7); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - *cptr = source_array.integer8; - *size = sizeof (*source_array.integer8); - break; -#endif - - default: - assert ("bad INTEGER ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ckt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - *cptr = source_array.logical1; - *size = sizeof (*source_array.logical1); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - *cptr = source_array.logical2; - *size = sizeof (*source_array.logical2); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - *cptr = source_array.logical3; - *size = sizeof (*source_array.logical3); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - *cptr = source_array.logical4; - *size = sizeof (*source_array.logical4); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - *cptr = source_array.logical5; - *size = sizeof (*source_array.logical5); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - *cptr = source_array.logical6; - *size = sizeof (*source_array.logical6); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - *cptr = source_array.logical7; - *size = sizeof (*source_array.logical7); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - *cptr = source_array.logical8; - *size = sizeof (*source_array.logical8); - break; -#endif - - default: - assert ("bad LOGICAL ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ckt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - *cptr = source_array.real1; - *size = sizeof (*source_array.real1); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - *cptr = source_array.real2; - *size = sizeof (*source_array.real2); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - *cptr = source_array.real3; - *size = sizeof (*source_array.real3); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - *cptr = source_array.real4; - *size = sizeof (*source_array.real4); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - *cptr = source_array.real5; - *size = sizeof (*source_array.real5); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - *cptr = source_array.real6; - *size = sizeof (*source_array.real6); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - *cptr = source_array.real7; - *size = sizeof (*source_array.real7); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - *cptr = source_array.real8; - *size = sizeof (*source_array.real8); - break; -#endif - - default: - assert ("bad REAL ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ckt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - *cptr = source_array.complex1; - *size = sizeof (*source_array.complex1); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - *cptr = source_array.complex2; - *size = sizeof (*source_array.complex2); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - *cptr = source_array.complex3; - *size = sizeof (*source_array.complex3); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - *cptr = source_array.complex4; - *size = sizeof (*source_array.complex4); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - *cptr = source_array.complex5; - *size = sizeof (*source_array.complex5); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - *cptr = source_array.complex6; - *size = sizeof (*source_array.complex6); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - *cptr = source_array.complex7; - *size = sizeof (*source_array.complex7); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - *cptr = source_array.complex8; - *size = sizeof (*source_array.complex8); - break; -#endif - - default: - assert ("bad COMPLEX ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ckt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - *cptr = source_array.character1; - *size = sizeof (*source_array.character1); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - *cptr = source_array.character2; - *size = sizeof (*source_array.character2); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - *cptr = source_array.character3; - *size = sizeof (*source_array.character3); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - *cptr = source_array.character4; - *size = sizeof (*source_array.character4); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - *cptr = source_array.character5; - *size = sizeof (*source_array.character5); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - *cptr = source_array.character6; - *size = sizeof (*source_array.character6); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - *cptr = source_array.character7; - *size = sizeof (*source_array.character7); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - *cptr = source_array.character8; - *size = sizeof (*source_array.character8); - break; -#endif - - default: - assert ("bad CHARACTER ckindtype" == NULL); - break; - } - break; - - default: - assert ("bad cbasictype" == NULL); - break; - } -} - -/* ffebld_constantarray_prepare -- Prepare for copy between value and array - - See prototype. - - Like _put, but just returns the pointers to the beginnings of the - array and the constant and returns the size (the amount of info to - copy). The idea is that the caller can use memcpy to accomplish the - same thing as _put (though slower), or the caller can use a different - function that swaps bytes, words, etc for a different target machine. - Also, the type of the array may be different from the type of the - constant; the array type is used to determine the meaning (scale) of - the offset field (to calculate the array pointer), the constant type is - used to determine the constant pointer and the size (amount of info to - copy). */ - -void -ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size, - ffebldConstantArray array, ffeinfoBasictype abt, ffeinfoKindtype akt, - ffetargetOffset offset, ffebldConstantUnion *constant, - ffeinfoBasictype cbt, ffeinfoKindtype ckt) -{ - switch (abt) - { - case FFEINFO_basictypeINTEGER: - switch (akt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - *aptr = array.integer1 + offset; - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - *aptr = array.integer2 + offset; - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - *aptr = array.integer3 + offset; - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - *aptr = array.integer4 + offset; - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - *aptr = array.integer5 + offset; - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - *aptr = array.integer6 + offset; - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - *aptr = array.integer7 + offset; - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - *aptr = array.integer8 + offset; - break; -#endif - - default: - assert ("bad INTEGER akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (akt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - *aptr = array.logical1 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - *aptr = array.logical2 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - *aptr = array.logical3 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - *aptr = array.logical4 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - *aptr = array.logical5 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - *aptr = array.logical6 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - *aptr = array.logical7 + offset; - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - *aptr = array.logical8 + offset; - break; -#endif - - default: - assert ("bad LOGICAL akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (akt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - *aptr = array.real1 + offset; - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - *aptr = array.real2 + offset; - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - *aptr = array.real3 + offset; - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - *aptr = array.real4 + offset; - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - *aptr = array.real5 + offset; - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - *aptr = array.real6 + offset; - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - *aptr = array.real7 + offset; - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - *aptr = array.real8 + offset; - break; -#endif - - default: - assert ("bad REAL akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (akt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - *aptr = array.complex1 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - *aptr = array.complex2 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - *aptr = array.complex3 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - *aptr = array.complex4 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - *aptr = array.complex5 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - *aptr = array.complex6 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - *aptr = array.complex7 + offset; - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - *aptr = array.complex8 + offset; - break; -#endif - - default: - assert ("bad COMPLEX akindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (akt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - *aptr = array.character1 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - *aptr = array.character2 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - *aptr = array.character3 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - *aptr = array.character4 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - *aptr = array.character5 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - *aptr = array.character6 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - *aptr = array.character7 + offset; - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - *aptr = array.character8 + offset; - break; -#endif - - default: - assert ("bad CHARACTER akindtype" == NULL); - break; - } - break; - - default: - assert ("bad abasictype" == NULL); - break; - } - - switch (cbt) - { - case FFEINFO_basictypeINTEGER: - switch (ckt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - *cptr = &constant->integer1; - *size = sizeof (constant->integer1); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - *cptr = &constant->integer2; - *size = sizeof (constant->integer2); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - *cptr = &constant->integer3; - *size = sizeof (constant->integer3); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - *cptr = &constant->integer4; - *size = sizeof (constant->integer4); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - *cptr = &constant->integer5; - *size = sizeof (constant->integer5); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - *cptr = &constant->integer6; - *size = sizeof (constant->integer6); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - *cptr = &constant->integer7; - *size = sizeof (constant->integer7); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - *cptr = &constant->integer8; - *size = sizeof (constant->integer8); - break; -#endif - - default: - assert ("bad INTEGER ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ckt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - *cptr = &constant->logical1; - *size = sizeof (constant->logical1); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - *cptr = &constant->logical2; - *size = sizeof (constant->logical2); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - *cptr = &constant->logical3; - *size = sizeof (constant->logical3); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - *cptr = &constant->logical4; - *size = sizeof (constant->logical4); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - *cptr = &constant->logical5; - *size = sizeof (constant->logical5); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - *cptr = &constant->logical6; - *size = sizeof (constant->logical6); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - *cptr = &constant->logical7; - *size = sizeof (constant->logical7); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - *cptr = &constant->logical8; - *size = sizeof (constant->logical8); - break; -#endif - - default: - assert ("bad LOGICAL ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ckt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - *cptr = &constant->real1; - *size = sizeof (constant->real1); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - *cptr = &constant->real2; - *size = sizeof (constant->real2); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - *cptr = &constant->real3; - *size = sizeof (constant->real3); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - *cptr = &constant->real4; - *size = sizeof (constant->real4); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - *cptr = &constant->real5; - *size = sizeof (constant->real5); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - *cptr = &constant->real6; - *size = sizeof (constant->real6); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - *cptr = &constant->real7; - *size = sizeof (constant->real7); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - *cptr = &constant->real8; - *size = sizeof (constant->real8); - break; -#endif - - default: - assert ("bad REAL ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ckt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - *cptr = &constant->complex1; - *size = sizeof (constant->complex1); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - *cptr = &constant->complex2; - *size = sizeof (constant->complex2); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - *cptr = &constant->complex3; - *size = sizeof (constant->complex3); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - *cptr = &constant->complex4; - *size = sizeof (constant->complex4); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - *cptr = &constant->complex5; - *size = sizeof (constant->complex5); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - *cptr = &constant->complex6; - *size = sizeof (constant->complex6); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - *cptr = &constant->complex7; - *size = sizeof (constant->complex7); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - *cptr = &constant->complex8; - *size = sizeof (constant->complex8); - break; -#endif - - default: - assert ("bad COMPLEX ckindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ckt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - *cptr = ffetarget_text_character1 (constant->character1); - *size = ffetarget_length_character1 (constant->character1); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - *cptr = ffetarget_text_character2 (constant->character2); - *size = ffetarget_length_character2 (constant->character2); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - *cptr = ffetarget_text_character3 (constant->character3); - *size = ffetarget_length_character3 (constant->character3); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - *cptr = ffetarget_text_character4 (constant->character4); - *size = ffetarget_length_character4 (constant->character4); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - *cptr = ffetarget_text_character5 (constant->character5); - *size = ffetarget_length_character5 (constant->character5); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - *cptr = ffetarget_text_character6 (constant->character6); - *size = ffetarget_length_character6 (constant->character6); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - *cptr = ffetarget_text_character7 (constant->character7); - *size = ffetarget_length_character7 (constant->character7); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - *cptr = ffetarget_text_character8 (constant->character8); - *size = ffetarget_length_character8 (constant->character8); - break; -#endif - - default: - assert ("bad CHARACTER ckindtype" == NULL); - break; - } - break; - - default: - assert ("bad cbasictype" == NULL); - break; - } -} - -/* ffebld_constantarray_put -- Put a value into an array of constants - - See prototype. */ - -void -ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset offset, ffebldConstantUnion constant) -{ - switch (bt) - { - case FFEINFO_basictypeINTEGER: - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - *(array.integer1 + offset) = constant.integer1; - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - *(array.integer2 + offset) = constant.integer2; - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - *(array.integer3 + offset) = constant.integer3; - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - *(array.integer4 + offset) = constant.integer4; - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - *(array.integer5 + offset) = constant.integer5; - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - *(array.integer6 + offset) = constant.integer6; - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - *(array.integer7 + offset) = constant.integer7; - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - *(array.integer8 + offset) = constant.integer8; - break; -#endif - - default: - assert ("bad INTEGER kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - *(array.logical1 + offset) = constant.logical1; - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - *(array.logical2 + offset) = constant.logical2; - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - *(array.logical3 + offset) = constant.logical3; - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - *(array.logical4 + offset) = constant.logical4; - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - *(array.logical5 + offset) = constant.logical5; - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - *(array.logical6 + offset) = constant.logical6; - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - *(array.logical7 + offset) = constant.logical7; - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - *(array.logical8 + offset) = constant.logical8; - break; -#endif - - default: - assert ("bad LOGICAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - *(array.real1 + offset) = constant.real1; - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - *(array.real2 + offset) = constant.real2; - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - *(array.real3 + offset) = constant.real3; - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - *(array.real4 + offset) = constant.real4; - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - *(array.real5 + offset) = constant.real5; - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - *(array.real6 + offset) = constant.real6; - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - *(array.real7 + offset) = constant.real7; - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - *(array.real8 + offset) = constant.real8; - break; -#endif - - default: - assert ("bad REAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - *(array.complex1 + offset) = constant.complex1; - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - *(array.complex2 + offset) = constant.complex2; - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - *(array.complex3 + offset) = constant.complex3; - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - *(array.complex4 + offset) = constant.complex4; - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - *(array.complex5 + offset) = constant.complex5; - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - *(array.complex6 + offset) = constant.complex6; - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - *(array.complex7 + offset) = constant.complex7; - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - *(array.complex8 + offset) = constant.complex8; - break; -#endif - - default: - assert ("bad COMPLEX kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - memcpy (array.character1 + offset, - ffetarget_text_character1 (constant.character1), - ffetarget_length_character1 (constant.character1)); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - memcpy (array.character2 + offset, - ffetarget_text_character2 (constant.character2), - ffetarget_length_character2 (constant.character2)); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - memcpy (array.character3 + offset, - ffetarget_text_character3 (constant.character3), - ffetarget_length_character3 (constant.character3)); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - memcpy (array.character4 + offset, - ffetarget_text_character4 (constant.character4), - ffetarget_length_character4 (constant.character4)); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - memcpy (array.character5 + offset, - ffetarget_text_character5 (constant.character5), - ffetarget_length_character5 (constant.character5)); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - memcpy (array.character6 + offset, - ffetarget_text_character6 (constant.character6), - ffetarget_length_character6 (constant.character6)); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - memcpy (array.character7 + offset, - ffetarget_text_character7 (constant.character7), - ffetarget_length_character7 (constant.character7)); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - memcpy (array.character8 + offset, - ffetarget_text_character8 (constant.character8), - ffetarget_length_character8 (constant.character8)); - break; -#endif - - default: - assert ("bad CHARACTER kindtype" == NULL); - break; - } - break; - - default: - assert ("bad basictype" == NULL); - break; - } -} - -/* ffebld_constantunion_dump -- Dump a constant - - See prototype. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffebld_constantunion_dump (ffebldConstantUnion u, ffeinfoBasictype bt, - ffeinfoKindtype kt) -{ - switch (bt) - { - case FFEINFO_basictypeINTEGER: - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - ffetarget_print_integer1 (dmpout, u.integer1); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - ffetarget_print_integer2 (dmpout, u.integer2); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - ffetarget_print_integer3 (dmpout, u.integer3); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - ffetarget_print_integer4 (dmpout, u.integer4); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - ffetarget_print_integer5 (dmpout, u.integer5); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - ffetarget_print_integer6 (dmpout, u.integer6); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - ffetarget_print_integer7 (dmpout, u.integer7); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - ffetarget_print_integer8 (dmpout, u.integer8); - break; -#endif - - default: - assert ("bad INTEGER kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - ffetarget_print_logical1 (dmpout, u.logical1); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - ffetarget_print_logical2 (dmpout, u.logical2); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - ffetarget_print_logical3 (dmpout, u.logical3); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - ffetarget_print_logical4 (dmpout, u.logical4); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - ffetarget_print_logical5 (dmpout, u.logical5); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - ffetarget_print_logical6 (dmpout, u.logical6); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - ffetarget_print_logical7 (dmpout, u.logical7); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - ffetarget_print_logical8 (dmpout, u.logical8); - break; -#endif - - default: - assert ("bad LOGICAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - ffetarget_print_real1 (dmpout, u.real1); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - ffetarget_print_real2 (dmpout, u.real2); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - ffetarget_print_real3 (dmpout, u.real3); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - ffetarget_print_real4 (dmpout, u.real4); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - ffetarget_print_real5 (dmpout, u.real5); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - ffetarget_print_real6 (dmpout, u.real6); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - ffetarget_print_real7 (dmpout, u.real7); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - ffetarget_print_real8 (dmpout, u.real8); - break; -#endif - - default: - assert ("bad REAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - fprintf (dmpout, "("); - ffetarget_print_real1 (dmpout, u.complex1.real); - fprintf (dmpout, ","); - ffetarget_print_real1 (dmpout, u.complex1.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - fprintf (dmpout, "("); - ffetarget_print_real2 (dmpout, u.complex2.real); - fprintf (dmpout, ","); - ffetarget_print_real2 (dmpout, u.complex2.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - fprintf (dmpout, "("); - ffetarget_print_real3 (dmpout, u.complex3.real); - fprintf (dmpout, ","); - ffetarget_print_real3 (dmpout, u.complex3.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - fprintf (dmpout, "("); - ffetarget_print_real4 (dmpout, u.complex4.real); - fprintf (dmpout, ","); - ffetarget_print_real4 (dmpout, u.complex4.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - fprintf (dmpout, "("); - ffetarget_print_real5 (dmpout, u.complex5.real); - fprintf (dmpout, ","); - ffetarget_print_real5 (dmpout, u.complex5.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - fprintf (dmpout, "("); - ffetarget_print_real6 (dmpout, u.complex6.real); - fprintf (dmpout, ","); - ffetarget_print_real6 (dmpout, u.complex6.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - fprintf (dmpout, "("); - ffetarget_print_real7 (dmpout, u.complex7.real); - fprintf (dmpout, ","); - ffetarget_print_real7 (dmpout, u.complex7.imaginary); - fprintf (dmpout, ")"); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - fprintf (dmpout, "("); - ffetarget_print_real8 (dmpout, u.complex8.real); - fprintf (dmpout, ","); - ffetarget_print_real8 (dmpout, u.complex8.imaginary); - fprintf (dmpout, ")"); - break; -#endif - - default: - assert ("bad COMPLEX kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - ffetarget_print_character1 (dmpout, u.character1); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - ffetarget_print_character2 (dmpout, u.character2); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - ffetarget_print_character3 (dmpout, u.character3); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - ffetarget_print_character4 (dmpout, u.character4); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - ffetarget_print_character5 (dmpout, u.character5); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - ffetarget_print_character6 (dmpout, u.character6); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - ffetarget_print_character7 (dmpout, u.character7); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - ffetarget_print_character8 (dmpout, u.character8); - break; -#endif - - default: - assert ("bad CHARACTER kindtype" == NULL); - break; - } - break; - - default: - assert ("bad basictype" == NULL); - break; - } -} -#endif - -/* ffebld_dump -- Dump expression tree in concise form - - ffebld b; - ffebld_dump(b); */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffebld_dump (ffebld b) -{ - ffeinfoKind k; - ffeinfoWhere w; - - if (b == NULL) - { - fprintf (dmpout, "(null)"); - return; - } - - switch (ffebld_op (b)) - { - case FFEBLD_opITEM: - fputs ("[", dmpout); - while (b != NULL) - { - ffebld_dump (ffebld_head (b)); - if ((b = ffebld_trail (b)) != NULL) - fputs (",", dmpout); - } - fputs ("]", dmpout); - return; - - case FFEBLD_opSTAR: - case FFEBLD_opBOUNDS: - case FFEBLD_opREPEAT: - case FFEBLD_opLABTER: - case FFEBLD_opLABTOK: - case FFEBLD_opIMPDO: - fputs (ffebld_op_string (ffebld_op (b)), dmpout); - break; - - default: - if (ffeinfo_size (ffebld_info (b)) != FFETARGET_charactersizeNONE) - fprintf (dmpout, "%s%d%s%s*%" ffetargetCharacterSize_f "u", - ffebld_op_string (ffebld_op (b)), - (int) ffeinfo_rank (ffebld_info (b)), - ffeinfo_basictype_string (ffeinfo_basictype (ffebld_info (b))), - ffeinfo_kindtype_string (ffeinfo_kindtype (ffebld_info (b))), - ffeinfo_size (ffebld_info (b))); - else - fprintf (dmpout, "%s%d%s%s", ffebld_op_string (ffebld_op (b)), - (int) ffeinfo_rank (ffebld_info (b)), - ffeinfo_basictype_string (ffeinfo_basictype (ffebld_info (b))), - ffeinfo_kindtype_string (ffeinfo_kindtype (ffebld_info (b)))); - if ((k = ffeinfo_kind (ffebld_info (b))) != FFEINFO_kindNONE) - fprintf (dmpout, "/%s", ffeinfo_kind_string (k)); - if ((w = ffeinfo_where (ffebld_info (b))) != FFEINFO_whereNONE) - fprintf (dmpout, "@%s", ffeinfo_where_string (w)); - break; - } - - switch (ffebld_arity (b)) - { - case 2: - fputs ("(", dmpout); - ffebld_dump (ffebld_left (b)); - fputs (",", dmpout); - ffebld_dump (ffebld_right (b)); - fputs (")", dmpout); - break; - - case 1: - fputs ("(", dmpout); - ffebld_dump (ffebld_left (b)); - fputs (")", dmpout); - break; - - default: - switch (ffebld_op (b)) - { - case FFEBLD_opCONTER: - fprintf (dmpout, "<"); - ffebld_constant_dump (b->u.conter.expr); - fprintf (dmpout, ">"); - break; - - case FFEBLD_opACCTER: - fprintf (dmpout, "<"); - ffebld_constantarray_dump (b->u.accter.array, - ffeinfo_basictype (ffebld_info (b)), - ffeinfo_kindtype (ffebld_info (b)), - ffebit_size (b->u.accter.bits), b->u.accter.bits); - fprintf (dmpout, ">"); - break; - - case FFEBLD_opARRTER: - fprintf (dmpout, "<"); - ffebld_constantarray_dump (b->u.arrter.array, - ffeinfo_basictype (ffebld_info (b)), - ffeinfo_kindtype (ffebld_info (b)), - b->u.arrter.size, NULL); - fprintf (dmpout, ">"); - break; - - case FFEBLD_opLABTER: - if (b->u.labter == NULL) - fprintf (dmpout, "<>"); - else - fprintf (dmpout, "<%" ffelabValue_f "u>", ffelab_value (b->u.labter)); - break; - - case FFEBLD_opLABTOK: - fprintf (dmpout, "<%s>", ffelex_token_text (b->u.labtok)); - break; - - case FFEBLD_opSYMTER: - fprintf (dmpout, "<"); - ffesymbol_dump (b->u.symter.symbol); - if ((b->u.symter.generic != FFEINTRIN_genNONE) - || (b->u.symter.specific != FFEINTRIN_specNONE)) - fprintf (dmpout, "{%s:%s:%s}", - ffeintrin_name_generic (b->u.symter.generic), - ffeintrin_name_specific (b->u.symter.specific), - ffeintrin_name_implementation (b->u.symter.implementation)); - if (b->u.symter.do_iter) - fprintf (dmpout, "{/do-iter}"); - fprintf (dmpout, ">"); - break; - - default: - break; - } - } -} -#endif - -/* ffebld_dump_prefix -- Dump the prefix for a constant of a given type - - ffebld_dump_prefix(dmpout,FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGER1); */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffebld_dump_prefix (FILE *out, ffeinfoBasictype bt, ffeinfoKindtype kt) -{ - switch (bt) - { - case FFEINFO_basictypeINTEGER: - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER1) "/"); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER2) "/"); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER3) "/"); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER4) "/"); - break; -#endif - -#if FFETARGET_okINTEGER5 - case FFEINFO_kindtypeINTEGER5: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER5) "/"); - break; -#endif - -#if FFETARGET_okINTEGER6 - case FFEINFO_kindtypeINTEGER6: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER6) "/"); - break; -#endif - -#if FFETARGET_okINTEGER7 - case FFEINFO_kindtypeINTEGER7: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER7) "/"); - break; -#endif - -#if FFETARGET_okINTEGER8 - case FFEINFO_kindtypeINTEGER8: - fprintf (out, "I" STRX (FFETARGET_kindINTEGER8) "/"); - break; -#endif - - default: - assert ("bad INTEGER kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL1) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL2) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL3) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL4) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL5 - case FFEINFO_kindtypeLOGICAL5: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL5) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL6 - case FFEINFO_kindtypeLOGICAL6: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL6) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL7 - case FFEINFO_kindtypeLOGICAL7: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL7) "/"); - break; -#endif - -#if FFETARGET_okLOGICAL8 - case FFEINFO_kindtypeLOGICAL8: - fprintf (out, "L" STRX (FFETARGET_kindLOGICAL8) "/"); - break; -#endif - - default: - assert ("bad LOGICAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - fprintf (out, "R" STRX (FFETARGET_kindREAL1) "/"); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - fprintf (out, "R" STRX (FFETARGET_kindREAL2) "/"); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - fprintf (out, "R" STRX (FFETARGET_kindREAL3) "/"); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - fprintf (out, "R" STRX (FFETARGET_kindREAL4) "/"); - break; -#endif - -#if FFETARGET_okREAL5 - case FFEINFO_kindtypeREAL5: - fprintf (out, "R" STRX (FFETARGET_kindREAL5) "/"); - break; -#endif - -#if FFETARGET_okREAL6 - case FFEINFO_kindtypeREAL6: - fprintf (out, "R" STRX (FFETARGET_kindREAL6) "/"); - break; -#endif - -#if FFETARGET_okREAL7 - case FFEINFO_kindtypeREAL7: - fprintf (out, "R" STRX (FFETARGET_kindREAL7) "/"); - break; -#endif - -#if FFETARGET_okREAL8 - case FFEINFO_kindtypeREAL8: - fprintf (out, "R" STRX (FFETARGET_kindREAL8) "/"); - break; -#endif - - default: - assert ("bad REAL kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX1) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX2) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX3) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX4) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX5 - case FFEINFO_kindtypeREAL5: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX5) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX6 - case FFEINFO_kindtypeREAL6: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX6) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX7 - case FFEINFO_kindtypeREAL7: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX7) "/"); - break; -#endif - -#if FFETARGET_okCOMPLEX8 - case FFEINFO_kindtypeREAL8: - fprintf (out, "C" STRX (FFETARGET_kindCOMPLEX8) "/"); - break; -#endif - - default: - assert ("bad COMPLEX kindtype" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER1) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER2) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER3) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER4) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER5 - case FFEINFO_kindtypeCHARACTER5: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER5) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER6 - case FFEINFO_kindtypeCHARACTER6: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER6) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER7 - case FFEINFO_kindtypeCHARACTER7: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER7) "/"); - break; -#endif - -#if FFETARGET_okCHARACTER8 - case FFEINFO_kindtypeCHARACTER8: - fprintf (out, "A" STRX (FFETARGET_kindCHARACTER8) "/"); - break; -#endif - - default: - assert ("bad CHARACTER kindtype" == NULL); - break; - } - break; - - default: - assert ("bad basictype" == NULL); - fprintf (out, "?/?"); - break; - } -} -#endif - -/* ffebld_init_0 -- Initialize the module - - ffebld_init_0(); */ - -void -ffebld_init_0 () -{ - assert (FFEBLD_op == ARRAY_SIZE (ffebld_op_string_)); - assert (FFEBLD_op == ARRAY_SIZE (ffebld_arity_op_)); -} - -/* ffebld_init_1 -- Initialize the module for a file - - ffebld_init_1(); */ - -void -ffebld_init_1 () -{ -#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstFILE_ - int i; - -#if FFETARGET_okCHARACTER1 - ffebld_constant_character1_ = NULL; -#endif -#if FFETARGET_okCHARACTER2 - ffebld_constant_character2_ = NULL; -#endif -#if FFETARGET_okCHARACTER3 - ffebld_constant_character3_ = NULL; -#endif -#if FFETARGET_okCHARACTER4 - ffebld_constant_character4_ = NULL; -#endif -#if FFETARGET_okCHARACTER5 - ffebld_constant_character5_ = NULL; -#endif -#if FFETARGET_okCHARACTER6 - ffebld_constant_character6_ = NULL; -#endif -#if FFETARGET_okCHARACTER7 - ffebld_constant_character7_ = NULL; -#endif -#if FFETARGET_okCHARACTER8 - ffebld_constant_character8_ = NULL; -#endif -#if FFETARGET_okCOMPLEX1 - ffebld_constant_complex1_ = NULL; -#endif -#if FFETARGET_okCOMPLEX2 - ffebld_constant_complex2_ = NULL; -#endif -#if FFETARGET_okCOMPLEX3 - ffebld_constant_complex3_ = NULL; -#endif -#if FFETARGET_okCOMPLEX4 - ffebld_constant_complex4_ = NULL; -#endif -#if FFETARGET_okCOMPLEX5 - ffebld_constant_complex5_ = NULL; -#endif -#if FFETARGET_okCOMPLEX6 - ffebld_constant_complex6_ = NULL; -#endif -#if FFETARGET_okCOMPLEX7 - ffebld_constant_complex7_ = NULL; -#endif -#if FFETARGET_okCOMPLEX8 - ffebld_constant_complex8_ = NULL; -#endif -#if FFETARGET_okINTEGER1 - ffebld_constant_integer1_ = NULL; -#endif -#if FFETARGET_okINTEGER2 - ffebld_constant_integer2_ = NULL; -#endif -#if FFETARGET_okINTEGER3 - ffebld_constant_integer3_ = NULL; -#endif -#if FFETARGET_okINTEGER4 - ffebld_constant_integer4_ = NULL; -#endif -#if FFETARGET_okINTEGER5 - ffebld_constant_integer5_ = NULL; -#endif -#if FFETARGET_okINTEGER6 - ffebld_constant_integer6_ = NULL; -#endif -#if FFETARGET_okINTEGER7 - ffebld_constant_integer7_ = NULL; -#endif -#if FFETARGET_okINTEGER8 - ffebld_constant_integer8_ = NULL; -#endif -#if FFETARGET_okLOGICAL1 - ffebld_constant_logical1_ = NULL; -#endif -#if FFETARGET_okLOGICAL2 - ffebld_constant_logical2_ = NULL; -#endif -#if FFETARGET_okLOGICAL3 - ffebld_constant_logical3_ = NULL; -#endif -#if FFETARGET_okLOGICAL4 - ffebld_constant_logical4_ = NULL; -#endif -#if FFETARGET_okLOGICAL5 - ffebld_constant_logical5_ = NULL; -#endif -#if FFETARGET_okLOGICAL6 - ffebld_constant_logical6_ = NULL; -#endif -#if FFETARGET_okLOGICAL7 - ffebld_constant_logical7_ = NULL; -#endif -#if FFETARGET_okLOGICAL8 - ffebld_constant_logical8_ = NULL; -#endif -#if FFETARGET_okREAL1 - ffebld_constant_real1_ = NULL; -#endif -#if FFETARGET_okREAL2 - ffebld_constant_real2_ = NULL; -#endif -#if FFETARGET_okREAL3 - ffebld_constant_real3_ = NULL; -#endif -#if FFETARGET_okREAL4 - ffebld_constant_real4_ = NULL; -#endif -#if FFETARGET_okREAL5 - ffebld_constant_real5_ = NULL; -#endif -#if FFETARGET_okREAL6 - ffebld_constant_real6_ = NULL; -#endif -#if FFETARGET_okREAL7 - ffebld_constant_real7_ = NULL; -#endif -#if FFETARGET_okREAL8 - ffebld_constant_real8_ = NULL; -#endif - ffebld_constant_hollerith_ = NULL; - for (i = FFEBLD_constTYPELESS_FIRST; i <= FFEBLD_constTYPELESS_LAST; ++i) - ffebld_constant_typeless_[i - FFEBLD_constTYPELESS_FIRST] = NULL; -#endif -} - -/* ffebld_init_2 -- Initialize the module - - ffebld_init_2(); */ - -void -ffebld_init_2 () -{ -#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstPROGUNIT_ - int i; -#endif - - ffebld_pool_stack_.next = NULL; - ffebld_pool_stack_.pool = ffe_pool_program_unit (); -#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstPROGUNIT_ -#if FFETARGET_okCHARACTER1 - ffebld_constant_character1_ = NULL; -#endif -#if FFETARGET_okCHARACTER2 - ffebld_constant_character2_ = NULL; -#endif -#if FFETARGET_okCHARACTER3 - ffebld_constant_character3_ = NULL; -#endif -#if FFETARGET_okCHARACTER4 - ffebld_constant_character4_ = NULL; -#endif -#if FFETARGET_okCHARACTER5 - ffebld_constant_character5_ = NULL; -#endif -#if FFETARGET_okCHARACTER6 - ffebld_constant_character6_ = NULL; -#endif -#if FFETARGET_okCHARACTER7 - ffebld_constant_character7_ = NULL; -#endif -#if FFETARGET_okCHARACTER8 - ffebld_constant_character8_ = NULL; -#endif -#if FFETARGET_okCOMPLEX1 - ffebld_constant_complex1_ = NULL; -#endif -#if FFETARGET_okCOMPLEX2 - ffebld_constant_complex2_ = NULL; -#endif -#if FFETARGET_okCOMPLEX3 - ffebld_constant_complex3_ = NULL; -#endif -#if FFETARGET_okCOMPLEX4 - ffebld_constant_complex4_ = NULL; -#endif -#if FFETARGET_okCOMPLEX5 - ffebld_constant_complex5_ = NULL; -#endif -#if FFETARGET_okCOMPLEX6 - ffebld_constant_complex6_ = NULL; -#endif -#if FFETARGET_okCOMPLEX7 - ffebld_constant_complex7_ = NULL; -#endif -#if FFETARGET_okCOMPLEX8 - ffebld_constant_complex8_ = NULL; -#endif -#if FFETARGET_okINTEGER1 - ffebld_constant_integer1_ = NULL; -#endif -#if FFETARGET_okINTEGER2 - ffebld_constant_integer2_ = NULL; -#endif -#if FFETARGET_okINTEGER3 - ffebld_constant_integer3_ = NULL; -#endif -#if FFETARGET_okINTEGER4 - ffebld_constant_integer4_ = NULL; -#endif -#if FFETARGET_okINTEGER5 - ffebld_constant_integer5_ = NULL; -#endif -#if FFETARGET_okINTEGER6 - ffebld_constant_integer6_ = NULL; -#endif -#if FFETARGET_okINTEGER7 - ffebld_constant_integer7_ = NULL; -#endif -#if FFETARGET_okINTEGER8 - ffebld_constant_integer8_ = NULL; -#endif -#if FFETARGET_okLOGICAL1 - ffebld_constant_logical1_ = NULL; -#endif -#if FFETARGET_okLOGICAL2 - ffebld_constant_logical2_ = NULL; -#endif -#if FFETARGET_okLOGICAL3 - ffebld_constant_logical3_ = NULL; -#endif -#if FFETARGET_okLOGICAL4 - ffebld_constant_logical4_ = NULL; -#endif -#if FFETARGET_okLOGICAL5 - ffebld_constant_logical5_ = NULL; -#endif -#if FFETARGET_okLOGICAL6 - ffebld_constant_logical6_ = NULL; -#endif -#if FFETARGET_okLOGICAL7 - ffebld_constant_logical7_ = NULL; -#endif -#if FFETARGET_okLOGICAL8 - ffebld_constant_logical8_ = NULL; -#endif -#if FFETARGET_okREAL1 - ffebld_constant_real1_ = NULL; -#endif -#if FFETARGET_okREAL2 - ffebld_constant_real2_ = NULL; -#endif -#if FFETARGET_okREAL3 - ffebld_constant_real3_ = NULL; -#endif -#if FFETARGET_okREAL4 - ffebld_constant_real4_ = NULL; -#endif -#if FFETARGET_okREAL5 - ffebld_constant_real5_ = NULL; -#endif -#if FFETARGET_okREAL6 - ffebld_constant_real6_ = NULL; -#endif -#if FFETARGET_okREAL7 - ffebld_constant_real7_ = NULL; -#endif -#if FFETARGET_okREAL8 - ffebld_constant_real8_ = NULL; -#endif - ffebld_constant_hollerith_ = NULL; - for (i = FFEBLD_constTYPELESS_FIRST; i <= FFEBLD_constTYPELESS_LAST; ++i) - ffebld_constant_typeless_[i - FFEBLD_constTYPELESS_FIRST] = NULL; -#endif -} - -/* ffebld_list_length -- Return # of opITEMs in list - - ffebld list; // Must be NULL or opITEM - ffebldListLength length; - length = ffebld_list_length(list); - - Returns 0 if list is NULL, 1 if it's ffebld_trail is NULL, and so on. */ - -ffebldListLength -ffebld_list_length (ffebld list) -{ - ffebldListLength length; - - for (length = 0; list != NULL; ++length, list = ffebld_trail (list)) - ; - - return length; -} - -/* ffebld_new_accter -- Create an ffebld object that is an array - - ffebld x; - ffebldConstantArray a; - ffebit b; - x = ffebld_new_accter(a,b); */ - -ffebld -ffebld_new_accter (ffebldConstantArray a, ffebit b) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opACCTER; - x->u.accter.array = a; - x->u.accter.bits = b; - x->u.accter.pad = 0; - return x; -} - -/* ffebld_new_arrter -- Create an ffebld object that is an array - - ffebld x; - ffebldConstantArray a; - ffetargetOffset size; - x = ffebld_new_arrter(a,size); */ - -ffebld -ffebld_new_arrter (ffebldConstantArray a, ffetargetOffset size) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opARRTER; - x->u.arrter.array = a; - x->u.arrter.size = size; - x->u.arrter.pad = 0; - return x; -} - -/* ffebld_new_conter_with_orig -- Create an ffebld object that is a constant - - ffebld x; - ffebldConstant c; - x = ffebld_new_conter_with_orig(c,NULL); */ - -ffebld -ffebld_new_conter_with_orig (ffebldConstant c, ffebld o) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opCONTER; - x->u.conter.expr = c; - x->u.conter.orig = o; - x->u.conter.pad = 0; - return x; -} - -/* ffebld_new_item -- Create an ffebld item object - - ffebld x,y,z; - x = ffebld_new_item(y,z); */ - -ffebld -ffebld_new_item (ffebld head, ffebld trail) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opITEM; - x->u.item.head = head; - x->u.item.trail = trail; - return x; -} - -/* ffebld_new_labter -- Create an ffebld object that is a label - - ffebld x; - ffelab l; - x = ffebld_new_labter(c); */ - -ffebld -ffebld_new_labter (ffelab l) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opLABTER; - x->u.labter = l; - return x; -} - -/* ffebld_new_labtok -- Create object that is a label's NUMBER token - - ffebld x; - ffelexToken t; - x = ffebld_new_labter(c); - - Like the other ffebld_new_ functions, the - supplied argument is stored exactly as is: ffelex_token_use is NOT - called, so the token is "consumed", if one is indeed supplied (it may - be NULL). */ - -ffebld -ffebld_new_labtok (ffelexToken t) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opLABTOK; - x->u.labtok = t; - return x; -} - -/* ffebld_new_none -- Create an ffebld object with no arguments - - ffebld x; - x = ffebld_new_none(FFEBLD_opWHATEVER); */ - -ffebld -ffebld_new_none (ffebldOp o) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = o; - return x; -} - -/* ffebld_new_one -- Create an ffebld object with one argument - - ffebld x,y; - x = ffebld_new_one(FFEBLD_opWHATEVER,y); */ - -ffebld -ffebld_new_one (ffebldOp o, ffebld left) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = o; - x->u.nonter.left = left; - return x; -} - -/* ffebld_new_symter -- Create an ffebld object that is a symbol - - ffebld x; - ffesymbol s; - ffeintrinGen gen; // Generic intrinsic id, if any - ffeintrinSpec spec; // Specific intrinsic id, if any - ffeintrinImp imp; // Implementation intrinsic id, if any - x = ffebld_new_symter (s, gen, spec, imp); */ - -ffebld -ffebld_new_symter (ffesymbol s, ffeintrinGen gen, ffeintrinSpec spec, - ffeintrinImp imp) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = FFEBLD_opSYMTER; - x->u.symter.symbol = s; - x->u.symter.generic = gen; - x->u.symter.specific = spec; - x->u.symter.implementation = imp; - x->u.symter.do_iter = FALSE; - return x; -} - -/* ffebld_new_two -- Create an ffebld object with two arguments - - ffebld x,y,z; - x = ffebld_new_two(FFEBLD_opWHATEVER,y,z); */ - -ffebld -ffebld_new_two (ffebldOp o, ffebld left, ffebld right) -{ - ffebld x; - - x = ffebld_new (); -#if FFEBLD_BLANK_ - *x = ffebld_blank_; -#endif - x->op = o; - x->u.nonter.left = left; - x->u.nonter.right = right; - return x; -} - -/* ffebld_pool_pop -- Pop ffebld's pool stack - - ffebld_pool_pop(); */ - -void -ffebld_pool_pop () -{ - ffebldPoolstack_ ps; - - assert (ffebld_pool_stack_.next != NULL); - ps = ffebld_pool_stack_.next; - ffebld_pool_stack_.next = ps->next; - ffebld_pool_stack_.pool = ps->pool; - malloc_kill_ks (malloc_pool_image (), ps, sizeof (*ps)); -} - -/* ffebld_pool_push -- Push ffebld's pool stack - - ffebld_pool_push(); */ - -void -ffebld_pool_push (mallocPool pool) -{ - ffebldPoolstack_ ps; - - ps = malloc_new_ks (malloc_pool_image (), "Pool stack", sizeof (*ps)); - ps->next = ffebld_pool_stack_.next; - ps->pool = ffebld_pool_stack_.pool; - ffebld_pool_stack_.next = ps; - ffebld_pool_stack_.pool = pool; -} - -/* ffebld_op_string -- Return short string describing op - - ffebldOp o; - ffebld_op_string(o); - - Returns a short string (uppercase) containing the name of the op. */ - -char * -ffebld_op_string (ffebldOp o) -{ - if (o >= ARRAY_SIZE (ffebld_op_string_)) - return "?\?\?"; - return ffebld_op_string_[o]; -} - -/* ffebld_size_max -- Return maximum possible size of CHARACTER-type expr - - ffetargetCharacterSize sz; - ffebld b; - sz = ffebld_size_max (b); - - Like ffebld_size_known, but if that would return NONE and the expression - is opSUBSTR, opCONVERT, opPAREN, or opCONCATENATE, returns ffebld_size_max - of the subexpression(s). */ - -ffetargetCharacterSize -ffebld_size_max (ffebld b) -{ - ffetargetCharacterSize sz; - -recurse: /* :::::::::::::::::::: */ - - sz = ffebld_size_known (b); - - if (sz != FFETARGET_charactersizeNONE) - return sz; - - switch (ffebld_op (b)) - { - case FFEBLD_opSUBSTR: - case FFEBLD_opCONVERT: - case FFEBLD_opPAREN: - b = ffebld_left (b); - goto recurse; /* :::::::::::::::::::: */ - - case FFEBLD_opCONCATENATE: - sz = ffebld_size_max (ffebld_left (b)) - + ffebld_size_max (ffebld_right (b)); - return sz; - - default: - return sz; - } -} diff --git a/gcc/f/bld.h b/gcc/f/bld.h deleted file mode 100755 index d3b613e..0000000 --- a/gcc/f/bld.h +++ /dev/null @@ -1,1024 +0,0 @@ -/* bld.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - bld.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_bld -#define _H_f_bld - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFEBLD_constNONE, - FFEBLD_constINTEGER1, - FFEBLD_constINTEGER2, - FFEBLD_constINTEGER3, - FFEBLD_constINTEGER4, - FFEBLD_constINTEGER5, - FFEBLD_constINTEGER6, - FFEBLD_constINTEGER7, - FFEBLD_constINTEGER8, - FFEBLD_constLOGICAL1, - FFEBLD_constLOGICAL2, - FFEBLD_constLOGICAL3, - FFEBLD_constLOGICAL4, - FFEBLD_constLOGICAL5, - FFEBLD_constLOGICAL6, - FFEBLD_constLOGICAL7, - FFEBLD_constLOGICAL8, - FFEBLD_constREAL1, - FFEBLD_constREAL2, - FFEBLD_constREAL3, - FFEBLD_constREAL4, - FFEBLD_constREAL5, - FFEBLD_constREAL6, - FFEBLD_constREAL7, - FFEBLD_constREAL8, - FFEBLD_constCOMPLEX1, - FFEBLD_constCOMPLEX2, - FFEBLD_constCOMPLEX3, - FFEBLD_constCOMPLEX4, - FFEBLD_constCOMPLEX5, - FFEBLD_constCOMPLEX6, - FFEBLD_constCOMPLEX7, - FFEBLD_constCOMPLEX8, - FFEBLD_constCHARACTER1, - FFEBLD_constCHARACTER2, - FFEBLD_constCHARACTER3, - FFEBLD_constCHARACTER4, - FFEBLD_constCHARACTER5, - FFEBLD_constCHARACTER6, - FFEBLD_constCHARACTER7, - FFEBLD_constCHARACTER8, - FFEBLD_constHOLLERITH, - FFEBLD_constTYPELESS_FIRST, - FFEBLD_constBINARY_MIL = FFEBLD_constTYPELESS_FIRST, - FFEBLD_constBINARY_VXT, - FFEBLD_constOCTAL_MIL, - FFEBLD_constOCTAL_VXT, - FFEBLD_constHEX_X_MIL, - FFEBLD_constHEX_X_VXT, - FFEBLD_constHEX_Z_MIL, - FFEBLD_constHEX_Z_VXT, - FFEBLD_constTYPELESS_LAST = FFEBLD_constHEX_Z_VXT, - FFEBLD_const - } ffebldConst; - -typedef enum - { -#define FFEBLD_OP(KWD,NAME,ARITY) KWD, -#include "bld-op.def" -#undef FFEBLD_OP - FFEBLD_op - } ffebldOp; - -/* Typedefs. */ - -typedef struct _ffebld_ *ffebld; -typedef unsigned char ffebldArity; -typedef union _ffebld_constant_array_ ffebldConstantArray; -typedef struct _ffebld_constant_ *ffebldConstant; -typedef union _ffebld_constant_union_ ffebldConstantUnion; -typedef ffebld *ffebldListBottom; -typedef unsigned int ffebldListLength; -#define ffebldListLength_f "" -typedef struct _ffebld_pool_stack_ *ffebldPoolstack_; - -/* Include files needed by this one. */ - -#include "bit.h" -#include "com.h" -#include "info.h" -#include "intrin.h" -#include "lab.h" -#include "lex.h" -#include "malloc.h" -#include "symbol.h" -#include "target.h" - -#define FFEBLD_whereconstPROGUNIT_ 1 -#define FFEBLD_whereconstFILE_ 2 - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -#define FFEBLD_whereconstCURRENT_ FFEBLD_whereconstPROGUNIT_ -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#define FFEBLD_whereconstCURRENT_ FFEBLD_whereconstFILE_ -#else -#error -#endif - -/* Structure definitions. */ - -#define FFEBLD_constINTEGERDEFAULT FFEBLD_constINTEGER1 -#define FFEBLD_constLOGICALDEFAULT FFEBLD_constLOGICAL1 -#define FFEBLD_constREALDEFAULT FFEBLD_constREAL1 -#define FFEBLD_constREALDOUBLE FFEBLD_constREAL2 -#define FFEBLD_constREALQUAD FFEBLD_constREAL3 -#define FFEBLD_constCOMPLEX FFEBLD_constCOMPLEX1 -#define FFEBLD_constCOMPLEXDOUBLE FFEBLD_constCOMPLEX2 -#define FFEBLD_constCOMPLEXQUAD FFEBLD_constCOMPLEX3 -#define FFEBLD_constCHARACTERDEFAULT FFEBLD_constCHARACTER1 - -union _ffebld_constant_union_ - { - ffetargetTypeless typeless; - ffetargetHollerith hollerith; -#if FFETARGET_okINTEGER1 - ffetargetInteger1 integer1; -#endif -#if FFETARGET_okINTEGER2 - ffetargetInteger2 integer2; -#endif -#if FFETARGET_okINTEGER3 - ffetargetInteger3 integer3; -#endif -#if FFETARGET_okINTEGER4 - ffetargetInteger4 integer4; -#endif -#if FFETARGET_okINTEGER5 - ffetargetInteger5 integer5; -#endif -#if FFETARGET_okINTEGER6 - ffetargetInteger6 integer6; -#endif -#if FFETARGET_okINTEGER7 - ffetargetInteger7 integer7; -#endif -#if FFETARGET_okINTEGER8 - ffetargetInteger8 integer8; -#endif -#if FFETARGET_okLOGICAL1 - ffetargetLogical1 logical1; -#endif -#if FFETARGET_okLOGICAL2 - ffetargetLogical2 logical2; -#endif -#if FFETARGET_okLOGICAL3 - ffetargetLogical3 logical3; -#endif -#if FFETARGET_okLOGICAL4 - ffetargetLogical4 logical4; -#endif -#if FFETARGET_okLOGICAL5 - ffetargetLogical5 logical5; -#endif -#if FFETARGET_okLOGICAL6 - ffetargetLogical6 logical6; -#endif -#if FFETARGET_okLOGICAL7 - ffetargetLogical7 logical7; -#endif -#if FFETARGET_okLOGICAL8 - ffetargetLogical8 logical8; -#endif -#if FFETARGET_okREAL1 - ffetargetReal1 real1; -#endif -#if FFETARGET_okREAL2 - ffetargetReal2 real2; -#endif -#if FFETARGET_okREAL3 - ffetargetReal3 real3; -#endif -#if FFETARGET_okREAL4 - ffetargetReal4 real4; -#endif -#if FFETARGET_okREAL5 - ffetargetReal5 real5; -#endif -#if FFETARGET_okREAL6 - ffetargetReal6 real6; -#endif -#if FFETARGET_okREAL7 - ffetargetReal7 real7; -#endif -#if FFETARGET_okREAL8 - ffetargetReal8 real8; -#endif -#if FFETARGET_okCOMPLEX1 - ffetargetComplex1 complex1; -#endif -#if FFETARGET_okCOMPLEX2 - ffetargetComplex2 complex2; -#endif -#if FFETARGET_okCOMPLEX3 - ffetargetComplex3 complex3; -#endif -#if FFETARGET_okCOMPLEX4 - ffetargetComplex4 complex4; -#endif -#if FFETARGET_okCOMPLEX5 - ffetargetComplex5 complex5; -#endif -#if FFETARGET_okCOMPLEX6 - ffetargetComplex6 complex6; -#endif -#if FFETARGET_okCOMPLEX7 - ffetargetComplex7 complex7; -#endif -#if FFETARGET_okCOMPLEX8 - ffetargetComplex8 complex8; -#endif -#if FFETARGET_okCHARACTER1 - ffetargetCharacter1 character1; -#endif -#if FFETARGET_okCHARACTER2 - ffetargetCharacter2 character2; -#endif -#if FFETARGET_okCHARACTER3 - ffetargetCharacter3 character3; -#endif -#if FFETARGET_okCHARACTER4 - ffetargetCharacter4 character4; -#endif -#if FFETARGET_okCHARACTER5 - ffetargetCharacter5 character5; -#endif -#if FFETARGET_okCHARACTER6 - ffetargetCharacter6 character6; -#endif -#if FFETARGET_okCHARACTER7 - ffetargetCharacter7 character7; -#endif -#if FFETARGET_okCHARACTER8 - ffetargetCharacter8 character8; -#endif - }; - -union _ffebld_constant_array_ - { -#if FFETARGET_okINTEGER1 - ffetargetInteger1 *integer1; -#endif -#if FFETARGET_okINTEGER2 - ffetargetInteger2 *integer2; -#endif -#if FFETARGET_okINTEGER3 - ffetargetInteger3 *integer3; -#endif -#if FFETARGET_okINTEGER4 - ffetargetInteger4 *integer4; -#endif -#if FFETARGET_okINTEGER5 - ffetargetInteger5 *integer5; -#endif -#if FFETARGET_okINTEGER6 - ffetargetInteger6 *integer6; -#endif -#if FFETARGET_okINTEGER7 - ffetargetInteger7 *integer7; -#endif -#if FFETARGET_okINTEGER8 - ffetargetInteger8 *integer8; -#endif -#if FFETARGET_okLOGICAL1 - ffetargetLogical1 *logical1; -#endif -#if FFETARGET_okLOGICAL2 - ffetargetLogical2 *logical2; -#endif -#if FFETARGET_okLOGICAL3 - ffetargetLogical3 *logical3; -#endif -#if FFETARGET_okLOGICAL4 - ffetargetLogical4 *logical4; -#endif -#if FFETARGET_okLOGICAL5 - ffetargetLogical5 *logical5; -#endif -#if FFETARGET_okLOGICAL6 - ffetargetLogical6 *logical6; -#endif -#if FFETARGET_okLOGICAL7 - ffetargetLogical7 *logical7; -#endif -#if FFETARGET_okLOGICAL8 - ffetargetLogical8 *logical8; -#endif -#if FFETARGET_okREAL1 - ffetargetReal1 *real1; -#endif -#if FFETARGET_okREAL2 - ffetargetReal2 *real2; -#endif -#if FFETARGET_okREAL3 - ffetargetReal3 *real3; -#endif -#if FFETARGET_okREAL4 - ffetargetReal4 *real4; -#endif -#if FFETARGET_okREAL5 - ffetargetReal5 *real5; -#endif -#if FFETARGET_okREAL6 - ffetargetReal6 *real6; -#endif -#if FFETARGET_okREAL7 - ffetargetReal7 *real7; -#endif -#if FFETARGET_okREAL8 - ffetargetReal8 *real8; -#endif -#if FFETARGET_okCOMPLEX1 - ffetargetComplex1 *complex1; -#endif -#if FFETARGET_okCOMPLEX2 - ffetargetComplex2 *complex2; -#endif -#if FFETARGET_okCOMPLEX3 - ffetargetComplex3 *complex3; -#endif -#if FFETARGET_okCOMPLEX4 - ffetargetComplex4 *complex4; -#endif -#if FFETARGET_okCOMPLEX5 - ffetargetComplex5 *complex5; -#endif -#if FFETARGET_okCOMPLEX6 - ffetargetComplex6 *complex6; -#endif -#if FFETARGET_okCOMPLEX7 - ffetargetComplex7 *complex7; -#endif -#if FFETARGET_okCOMPLEX8 - ffetargetComplex8 *complex8; -#endif -#if FFETARGET_okCHARACTER1 - ffetargetCharacterUnit1 *character1; -#endif -#if FFETARGET_okCHARACTER2 - ffetargetCharacterUnit2 *character2; -#endif -#if FFETARGET_okCHARACTER3 - ffetargetCharacterUnit3 *character3; -#endif -#if FFETARGET_okCHARACTER4 - ffetargetCharacterUnit4 *character4; -#endif -#if FFETARGET_okCHARACTER5 - ffetargetCharacterUnit5 *character5; -#endif -#if FFETARGET_okCHARACTER6 - ffetargetCharacterUnit6 *character6; -#endif -#if FFETARGET_okCHARACTER7 - ffetargetCharacterUnit7 *character7; -#endif -#if FFETARGET_okCHARACTER8 - ffetargetCharacterUnit8 *character8; -#endif - }; - -struct _ffebld_ - { - ffebldOp op; - ffeinfo info; /* Not used or valid for - op=={STAR,ITEM,BOUNDS,REPEAT,LABTER, - LABTOK,IMPDO}. */ - union - { - struct - { - ffebld left; - ffebld right; - } - nonter; - struct - { - ffebld head; - ffebld trail; - } - item; - struct - { - ffebldConstant expr; - ffebld orig; /* Original expression, or NULL if none. */ - ffetargetAlign pad; /* Initial padding (for DATA, etc.). */ - } - conter; - struct - { - ffebldConstantArray array; - ffetargetOffset size; - ffetargetAlign pad; /* Initial padding (for DATA, etc.). */ - } - arrter; - struct - { - ffebldConstantArray array; - ffebit bits; - ffetargetAlign pad; /* Initial padding (for DATA, etc.). */ - } - accter; - struct - { - ffesymbol symbol; - ffeintrinGen generic; /* Id for generic intrinsic. */ - ffeintrinSpec specific; /* Id for specific intrinsic. */ - ffeintrinImp implementation; /* Id for implementation. */ - bool do_iter; /* TRUE if this ref is a read-only ref by - definition (ref within DO loop using this - var as iterator). */ - } - symter; - ffelab labter; - ffelexToken labtok; - } - u; - }; - -struct _ffebld_constant_ - { - ffebldConstant next; - ffebldConstant first_complex; /* First complex const with me as - real. */ - ffebldConstant negated; /* We point to each other through here. */ - ffebldConst consttype; -#ifdef FFECOM_constantHOOK - ffecomConstant hook; /* Whatever the compiler/backend wants! */ -#endif - bool numeric; /* A numeric kind of constant. */ - ffebldConstantUnion u; - }; - -struct _ffebld_pool_stack_ - { - ffebldPoolstack_ next; - mallocPool pool; - }; - -/* Global objects accessed by users of this module. */ - -extern ffebldArity ffebld_arity_op_[]; -extern struct _ffebld_pool_stack_ ffebld_pool_stack_; - -/* Declare functions with prototypes. */ - -int ffebld_constant_cmp (ffebldConstant c1, ffebldConstant c2); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffebld_constant_dump (ffebldConstant c); -#endif -bool ffebld_constant_is_magical (ffebldConstant c); -bool ffebld_constant_is_zero (ffebldConstant c); -#if FFETARGET_okCHARACTER1 -ffebldConstant ffebld_constant_new_character1 (ffelexToken t); -ffebldConstant ffebld_constant_new_character1_val (ffetargetCharacter1 val); -#endif -#if FFETARGET_okCHARACTER2 -ffebldConstant ffebld_constant_new_character2 (ffelexToken t); -ffebldConstant ffebld_constant_new_character2_val (ffetargetCharacter2 val); -#endif -#if FFETARGET_okCHARACTER3 -ffebldConstant ffebld_constant_new_character3 (ffelexToken t); -ffebldConstant ffebld_constant_new_character3_val (ffetargetCharacter3 val); -#endif -#if FFETARGET_okCHARACTER4 -ffebldConstant ffebld_constant_new_character4 (ffelexToken t); -ffebldConstant ffebld_constant_new_character4_val (ffetargetCharacter4 val); -#endif -#if FFETARGET_okCHARACTER5 -ffebldConstant ffebld_constant_new_character5 (ffelexToken t); -ffebldConstant ffebld_constant_new_character5_val (ffetargetCharacter5 val); -#endif -#if FFETARGET_okCHARACTER6 -ffebldConstant ffebld_constant_new_character6 (ffelexToken t); -ffebldConstant ffebld_constant_new_character6_val (ffetargetCharacter6 val); -#endif -#if FFETARGET_okCHARACTER7 -ffebldConstant ffebld_constant_new_character7 (ffelexToken t); -ffebldConstant ffebld_constant_new_character7_val (ffetargetCharacter7 val); -#endif -#if FFETARGET_okCHARACTER8 -ffebldConstant ffebld_constant_new_character8 (ffelexToken t); -ffebldConstant ffebld_constant_new_character8_val (ffetargetCharacter8 val); -#endif -#if FFETARGET_okCOMPLEX1 -ffebldConstant ffebld_constant_new_complex1 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex1_val (ffetargetComplex1 val); -#endif -#if FFETARGET_okCOMPLEX2 -ffebldConstant ffebld_constant_new_complex2 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex2_val (ffetargetComplex2 val); -#endif -#if FFETARGET_okCOMPLEX3 -ffebldConstant ffebld_constant_new_complex3 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex3_val (ffetargetComplex3 val); -#endif -#if FFETARGET_okCOMPLEX4 -ffebldConstant ffebld_constant_new_complex4 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex4_val (ffetargetComplex4 val); -#endif -#if FFETARGET_okCOMPLEX5 -ffebldConstant ffebld_constant_new_complex5 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex5_val (ffetargetComplex5 val); -#endif -#if FFETARGET_okCOMPLEX6 -ffebldConstant ffebld_constant_new_complex6 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex6_val (ffetargetComplex6 val); -#endif -#if FFETARGET_okCOMPLEX7 -ffebldConstant ffebld_constant_new_complex7 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex7_val (ffetargetComplex7 val); -#endif -#if FFETARGET_okCOMPLEX8 -ffebldConstant ffebld_constant_new_complex8 (ffebldConstant real, - ffebldConstant imaginary); -ffebldConstant ffebld_constant_new_complex8_val (ffetargetComplex8 val); -#endif -ffebldConstant ffebld_constant_new_hollerith (ffelexToken t); -ffebldConstant ffebld_constant_new_hollerith_val (ffetargetHollerith val); -#if FFETARGET_okINTEGER1 -ffebldConstant ffebld_constant_new_integer1 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer1_val (ffetargetInteger1 val); -#endif -#if FFETARGET_okINTEGER2 -ffebldConstant ffebld_constant_new_integer2 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer2_val (ffetargetInteger2 val); -#endif -#if FFETARGET_okINTEGER3 -ffebldConstant ffebld_constant_new_integer3 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer3_val (ffetargetInteger3 val); -#endif -#if FFETARGET_okINTEGER4 -ffebldConstant ffebld_constant_new_integer4 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer4_val (ffetargetInteger4 val); -#endif -#if FFETARGET_okINTEGER5 -ffebldConstant ffebld_constant_new_integer5 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer5_val (ffetargetInteger5 val); -#endif -#if FFETARGET_okINTEGER6 -ffebldConstant ffebld_constant_new_integer6 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer6_val (ffetargetInteger6 val); -#endif -#if FFETARGET_okINTEGER7 -ffebldConstant ffebld_constant_new_integer7 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer7_val (ffetargetInteger7 val); -#endif -#if FFETARGET_okINTEGER8 -ffebldConstant ffebld_constant_new_integer8 (ffelexToken t); -ffebldConstant ffebld_constant_new_integer8_val (ffetargetInteger8 val); -#endif -ffebldConstant ffebld_constant_new_integerbinary (ffelexToken t); -ffebldConstant ffebld_constant_new_integerhex (ffelexToken t); -ffebldConstant ffebld_constant_new_integeroctal (ffelexToken t); -#if FFETARGET_okLOGICAL1 -ffebldConstant ffebld_constant_new_logical1 (bool truth); -ffebldConstant ffebld_constant_new_logical1_val (ffetargetLogical1 val); -#endif -#if FFETARGET_okLOGICAL2 -ffebldConstant ffebld_constant_new_logical2 (bool truth); -ffebldConstant ffebld_constant_new_logical2_val (ffetargetLogical2 val); -#endif -#if FFETARGET_okLOGICAL3 -ffebldConstant ffebld_constant_new_logical3 (bool truth); -ffebldConstant ffebld_constant_new_logical3_val (ffetargetLogical3 val); -#endif -#if FFETARGET_okLOGICAL4 -ffebldConstant ffebld_constant_new_logical4 (bool truth); -ffebldConstant ffebld_constant_new_logical4_val (ffetargetLogical4 val); -#endif -#if FFETARGET_okLOGICAL5 -ffebldConstant ffebld_constant_new_logical5 (bool truth); -ffebldConstant ffebld_constant_new_logical5_val (ffetargetLogical5 val); -#endif -#if FFETARGET_okLOGICAL6 -ffebldConstant ffebld_constant_new_logical6 (bool truth); -ffebldConstant ffebld_constant_new_logical6_val (ffetargetLogical6 val); -#endif -#if FFETARGET_okLOGICAL7 -ffebldConstant ffebld_constant_new_logical7 (bool truth); -ffebldConstant ffebld_constant_new_logical7_val (ffetargetLogical7 val); -#endif -#if FFETARGET_okLOGICAL8 -ffebldConstant ffebld_constant_new_logical8 (bool truth); -ffebldConstant ffebld_constant_new_logical8_val (ffetargetLogical8 val); -#endif -#if FFETARGET_okREAL1 -ffebldConstant ffebld_constant_new_real1 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real1_val (ffetargetReal1 val); -#endif -#if FFETARGET_okREAL2 -ffebldConstant ffebld_constant_new_real2 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real2_val (ffetargetReal2 val); -#endif -#if FFETARGET_okREAL3 -ffebldConstant ffebld_constant_new_real3 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real3_val (ffetargetReal3 val); -#endif -#if FFETARGET_okREAL4 -ffebldConstant ffebld_constant_new_real4 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real4_val (ffetargetReal4 val); -#endif -#if FFETARGET_okREAL5 -ffebldConstant ffebld_constant_new_real5 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real5_val (ffetargetReal5 val); -#endif -#if FFETARGET_okREAL6 -ffebldConstant ffebld_constant_new_real6 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real6_val (ffetargetReal6 val); -#endif -#if FFETARGET_okREAL7 -ffebldConstant ffebld_constant_new_real7 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real7_val (ffetargetReal7 val); -#endif -#if FFETARGET_okREAL8 -ffebldConstant ffebld_constant_new_real8 (ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -ffebldConstant ffebld_constant_new_real8_val (ffetargetReal8 val); -#endif -ffebldConstant ffebld_constant_new_typeless_bm (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_bv (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_hxm (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_hxv (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_hzm (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_hzv (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_om (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_ov (ffelexToken t); -ffebldConstant ffebld_constant_new_typeless_val (ffebldConst type, - ffetargetTypeless val); -ffebldConstant ffebld_constant_negated (ffebldConstant c); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffebld_constantarray_dump (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset size, ffebit bits); -#endif -ffebldConstantUnion ffebld_constantarray_get (ffebldConstantArray array, - ffeinfoBasictype bt, ffeinfoKindtype kt, ffetargetOffset offset); -void ffebld_constantarray_kill (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset size); -ffebldConstantArray ffebld_constantarray_new (ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset size); -void ffebld_constantarray_prepare (void **aptr, void **cptr, size_t *size, - ffebldConstantArray array, ffeinfoBasictype abt, ffeinfoKindtype akt, - ffetargetOffset offset, ffebldConstantUnion *constant, - ffeinfoBasictype cbt, ffeinfoKindtype ckt); -void ffebld_constantarray_preparray (void **aptr, void **cptr, size_t *size, - ffebldConstantArray array, ffeinfoBasictype abt, ffeinfoKindtype akt, - ffetargetOffset offset, ffebldConstantArray source_array, - ffeinfoBasictype cbt, ffeinfoKindtype ckt); -void ffebld_constantarray_put (ffebldConstantArray array, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffetargetOffset offset, ffebldConstantUnion constant); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffebld_constantunion_dump (ffebldConstantUnion u, ffeinfoBasictype bt, - ffeinfoKindtype kt); -void ffebld_dump (ffebld b); -void ffebld_dump_prefix (FILE *out, ffeinfoBasictype bt, ffeinfoKindtype kt); -#endif -void ffebld_init_0 (void); -void ffebld_init_1 (void); -void ffebld_init_2 (void); -ffebldListLength ffebld_list_length (ffebld l); -ffebld ffebld_new_accter (ffebldConstantArray array, ffebit b); -ffebld ffebld_new_arrter (ffebldConstantArray array, ffetargetOffset size); -ffebld ffebld_new_conter_with_orig (ffebldConstant c, ffebld orig); -ffebld ffebld_new_item (ffebld head, ffebld trail); -ffebld ffebld_new_labter (ffelab l); -ffebld ffebld_new_labtok (ffelexToken t); -ffebld ffebld_new_none (ffebldOp o); -ffebld ffebld_new_symter (ffesymbol s, ffeintrinGen gen, ffeintrinSpec spec, - ffeintrinImp imp); -ffebld ffebld_new_one (ffebldOp o, ffebld left); -ffebld ffebld_new_two (ffebldOp o, ffebld left, ffebld right); -char *ffebld_op_string (ffebldOp o); -void ffebld_pool_pop (void); -void ffebld_pool_push (mallocPool pool); -ffetargetCharacterSize ffebld_size_max (ffebld b); - -/* Define macros. */ - -#define ffebld_accter(b) ((b)->u.accter.array) -#define ffebld_accter_bits(b) ((b)->u.accter.bits) -#define ffebld_accter_pad(b) ((b)->u.accter.pad) -#define ffebld_accter_set_bits(b,bt) ((b)->u.accter.bits = (bt)) -#define ffebld_accter_set_pad(b,p) ((b)->u.accter.pad = (p)) -#define ffebld_accter_size(b) ffebit_size((b)->u.accter.bits) -#define ffebld_append_item(b,i) (**(b) = ffebld_new_item((i),NULL), \ - *(b) = &((**(b))->u.item.trail)) -#define ffebld_arity(b) ffebld_arity_op(ffebld_op(b)) -#define ffebld_arity_op(o) (ffebld_arity_op_[o]) -#define ffebld_arrter(b) ((b)->u.arrter.array) -#define ffebld_arrter_pad(b) ((b)->u.arrter.pad) -#define ffebld_arrter_set_pad(b,p) ((b)->u.arrter.pad = (p)) -#define ffebld_arrter_set_size(b,s) ((b)->u.arrter.size = (s)) -#define ffebld_arrter_size(b) ((b)->u.arrter.size) -#if FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstPROGUNIT_ -#define ffebld_constant_pool() ffe_pool_program_unit() -#elif FFEBLD_whereconstCURRENT_ == FFEBLD_whereconstFILE_ -#define ffebld_constant_pool() ffe_pool_file() -#else -#error -#endif -#define ffebld_constant_character1(c) ((c)->u.character1) -#define ffebld_constant_character2(c) ((c)->u.character2) -#define ffebld_constant_character3(c) ((c)->u.character3) -#define ffebld_constant_character4(c) ((c)->u.character4) -#define ffebld_constant_character5(c) ((c)->u.character5) -#define ffebld_constant_character6(c) ((c)->u.character6) -#define ffebld_constant_character7(c) ((c)->u.character7) -#define ffebld_constant_character8(c) ((c)->u.character8) -#define ffebld_constant_characterdefault ffebld_constant_character1 -#define ffebld_constant_complex1(c) ((c)->u.complex1) -#define ffebld_constant_complex2(c) ((c)->u.complex2) -#define ffebld_constant_complex3(c) ((c)->u.complex3) -#define ffebld_constant_complex4(c) ((c)->u.complex4) -#define ffebld_constant_complex5(c) ((c)->u.complex5) -#define ffebld_constant_complex6(c) ((c)->u.complex6) -#define ffebld_constant_complex7(c) ((c)->u.complex7) -#define ffebld_constant_complex8(c) ((c)->u.complex8) -#define ffebld_constant_complexdefault ffebld_constant_complex1 -#define ffebld_constant_complexdouble ffebld_constant_complex2 -#define ffebld_constant_complexquad ffebld_constant_complex3 -#define ffebld_constant_copy(c) (c) -#define ffebld_constant_hollerith(c) ((c)->u.hollerith) -#define ffebld_constant_hook(c) ((c)->hook) -#define ffebld_constant_integer1(c) ((c)->u.integer1) -#define ffebld_constant_integer2(c) ((c)->u.integer2) -#define ffebld_constant_integer3(c) ((c)->u.integer3) -#define ffebld_constant_integer4(c) ((c)->u.integer4) -#define ffebld_constant_integer5(c) ((c)->u.integer5) -#define ffebld_constant_integer6(c) ((c)->u.integer6) -#define ffebld_constant_integer7(c) ((c)->u.integer7) -#define ffebld_constant_integer8(c) ((c)->u.integer8) -#define ffebld_constant_integerdefault ffebld_constant_integer1 -#define ffebld_constant_is_numeric(c) ((c)->numeric) -#define ffebld_constant_logical1(c) ((c)->u.logical1) -#define ffebld_constant_logical2(c) ((c)->u.logical2) -#define ffebld_constant_logical3(c) ((c)->u.logical3) -#define ffebld_constant_logical4(c) ((c)->u.logical4) -#define ffebld_constant_logical5(c) ((c)->u.logical5) -#define ffebld_constant_logical6(c) ((c)->u.logical6) -#define ffebld_constant_logical7(c) ((c)->u.logical7) -#define ffebld_constant_logical8(c) ((c)->u.logical8) -#define ffebld_constant_logicaldefault ffebld_constant_logical1 -#define ffebld_constant_new_characterdefault ffebld_constant_new_character1 -#define ffebld_constant_new_characterdefault_val ffebld_constant_new_character1_val -#define ffebld_constant_new_complexdefault ffebld_constant_new_complex1 -#define ffebld_constant_new_complexdefault_val ffebld_constant_new_complex1_val -#define ffebld_constant_new_complexdouble ffebld_constant_new_complex2 -#define ffebld_constant_new_complexdouble_val ffebld_constant_new_complex2_val -#define ffebld_constant_new_complexquad ffebld_constant_new_complex3 -#define ffebld_constant_new_complexquad_valffebld_constant_new_complex3_val -#define ffebld_constant_new_integerdefault ffebld_constant_new_integer1 -#define ffebld_constant_new_integerdefault_val ffebld_constant_new_integer1_val -#define ffebld_constant_new_logicaldefault ffebld_constant_new_logical1 -#define ffebld_constant_new_logicaldefault_val ffebld_constant_new_logical1_val -#define ffebld_constant_new_realdefault ffebld_constant_new_real1 -#define ffebld_constant_new_realdefault_val ffebld_constant_new_real1_val -#define ffebld_constant_new_realdouble ffebld_constant_new_real2 -#define ffebld_constant_new_realdouble_val ffebld_constant_new_real2_val -#define ffebld_constant_new_realquad ffebld_constant_new_real3 -#define ffebld_constant_new_realquad_val ffebld_constant_new_real3_val -#define ffebld_constant_ptr_to_union(c) (&(c)->u) -#define ffebld_constant_real1(c) ((c)->u.real1) -#define ffebld_constant_real2(c) ((c)->u.real2) -#define ffebld_constant_real3(c) ((c)->u.real3) -#define ffebld_constant_real4(c) ((c)->u.real4) -#define ffebld_constant_real5(c) ((c)->u.real5) -#define ffebld_constant_real6(c) ((c)->u.real6) -#define ffebld_constant_real7(c) ((c)->u.real7) -#define ffebld_constant_real8(c) ((c)->u.real8) -#define ffebld_constant_realdefault ffebld_constant_real1 -#define ffebld_constant_realdouble ffebld_constant_real2 -#define ffebld_constant_realquad ffebld_constant_real3 -#define ffebld_constant_set_hook(c,h) ((c)->hook = (h)) -#define ffebld_constant_set_union(c,un) ((c)->u = (un)) -#define ffebld_constant_type(c) ((c)->consttype) -#define ffebld_constant_typeless(c) ((c)->u.typeless) -#define ffebld_constant_union(c) ((c)->u) -#define ffebld_conter(b) ((b)->u.conter.expr) -#define ffebld_conter_orig(b) ((b)->u.conter.orig) -#define ffebld_conter_pad(b) ((b)->u.conter.pad) -#define ffebld_conter_set_orig(b,o) ((b)->u.conter.orig = (o)) -#define ffebld_conter_set_pad(b,p) ((b)->u.conter.pad = (p)) -#define ffebld_copy(b) (b) /* ~~~Someday really make a copy. */ -#define ffebld_cu_ptr_typeless(u) &(u).typeless -#define ffebld_cu_ptr_hollerith(u) &(u).hollerith -#define ffebld_cu_ptr_integer1(u) &(u).integer1 -#define ffebld_cu_ptr_integer2(u) &(u).integer2 -#define ffebld_cu_ptr_integer3(u) &(u).integer3 -#define ffebld_cu_ptr_integer4(u) &(u).integer4 -#define ffebld_cu_ptr_integer5(u) &(u).integer5 -#define ffebld_cu_ptr_integer6(u) &(u).integer6 -#define ffebld_cu_ptr_integer7(u) &(u).integer7 -#define ffebld_cu_ptr_integer8(u) &(u).integer8 -#define ffebld_cu_ptr_integerdefault ffebld_cu_ptr_integer1 -#define ffebld_cu_ptr_logical1(u) &(u).logical1 -#define ffebld_cu_ptr_logical2(u) &(u).logical2 -#define ffebld_cu_ptr_logical3(u) &(u).logical3 -#define ffebld_cu_ptr_logical4(u) &(u).logical4 -#define ffebld_cu_ptr_logical5(u) &(u).logical5 -#define ffebld_cu_ptr_logical6(u) &(u).logical6 -#define ffebld_cu_ptr_logical7(u) &(u).logical7 -#define ffebld_cu_ptr_logical8(u) &(u).logical8 -#define ffebld_cu_ptr_logicaldefault ffebld_cu_ptr_logical1 -#define ffebld_cu_ptr_real1(u) &(u).real1 -#define ffebld_cu_ptr_real2(u) &(u).real2 -#define ffebld_cu_ptr_real3(u) &(u).real3 -#define ffebld_cu_ptr_real4(u) &(u).real4 -#define ffebld_cu_ptr_real5(u) &(u).real5 -#define ffebld_cu_ptr_real6(u) &(u).real6 -#define ffebld_cu_ptr_real7(u) &(u).real7 -#define ffebld_cu_ptr_real8(u) &(u).real8 -#define ffebld_cu_ptr_realdefault ffebld_cu_ptr_real1 -#define ffebld_cu_ptr_realdouble ffebld_cu_ptr_real2 -#define ffebld_cu_ptr_realquad ffebld_cu_ptr_real3 -#define ffebld_cu_ptr_complex1(u) &(u).complex1 -#define ffebld_cu_ptr_complex2(u) &(u).complex2 -#define ffebld_cu_ptr_complex3(u) &(u).complex3 -#define ffebld_cu_ptr_complex4(u) &(u).complex4 -#define ffebld_cu_ptr_complex5(u) &(u).complex5 -#define ffebld_cu_ptr_complex6(u) &(u).complex6 -#define ffebld_cu_ptr_complex7(u) &(u).complex7 -#define ffebld_cu_ptr_complex8(u) &(u).complex8 -#define ffebld_cu_ptr_complexdefault ffebld_cu_ptr_complex1 -#define ffebld_cu_ptr_complexdouble ffebld_cu_ptr_complex2 -#define ffebld_cu_ptr_complexquad ffebld_cu_ptr_complex3 -#define ffebld_cu_ptr_character1(u) &(u).character1 -#define ffebld_cu_ptr_character2(u) &(u).character2 -#define ffebld_cu_ptr_character3(u) &(u).character3 -#define ffebld_cu_ptr_character4(u) &(u).character4 -#define ffebld_cu_ptr_character5(u) &(u).character5 -#define ffebld_cu_ptr_character6(u) &(u).character6 -#define ffebld_cu_ptr_character7(u) &(u).character7 -#define ffebld_cu_ptr_character8(u) &(u).character8 -#define ffebld_cu_val_typeless(u) (u).typeless -#define ffebld_cu_val_hollerith(u) (u).hollerith -#define ffebld_cu_val_integer1(u) (u).integer1 -#define ffebld_cu_val_integer2(u) (u).integer2 -#define ffebld_cu_val_integer3(u) (u).integer3 -#define ffebld_cu_val_integer4(u) (u).integer4 -#define ffebld_cu_val_integer5(u) (u).integer5 -#define ffebld_cu_val_integer6(u) (u).integer6 -#define ffebld_cu_val_integer7(u) (u).integer7 -#define ffebld_cu_val_integer8(u) (u).integer8 -#define ffebld_cu_val_integerdefault ffebld_cu_val_integer1 -#define ffebld_cu_val_logical1(u) (u).logical1 -#define ffebld_cu_val_logical2(u) (u).logical2 -#define ffebld_cu_val_logical3(u) (u).logical3 -#define ffebld_cu_val_logical4(u) (u).logical4 -#define ffebld_cu_val_logical5(u) (u).logical5 -#define ffebld_cu_val_logical6(u) (u).logical6 -#define ffebld_cu_val_logical7(u) (u).logical7 -#define ffebld_cu_val_logical8(u) (u).logical8 -#define ffebld_cu_val_logicaldefault ffebld_cu_val_logical -#define ffebld_cu_val_real1(u) (u).real1 -#define ffebld_cu_val_real2(u) (u).real2 -#define ffebld_cu_val_real3(u) (u).real3 -#define ffebld_cu_val_real4(u) (u).real4 -#define ffebld_cu_val_real5(u) (u).real5 -#define ffebld_cu_val_real6(u) (u).real6 -#define ffebld_cu_val_real7(u) (u).real7 -#define ffebld_cu_val_real8(u) (u).real8 -#define ffebld_cu_val_realdefault ffebld_cu_val_real1 -#define ffebld_cu_val_realdouble ffebld_cu_val_real2 -#define ffebld_cu_val_realquad ffebld_cu_val_real3 -#define ffebld_cu_val_complex1(u) (u).complex1 -#define ffebld_cu_val_complex2(u) (u).complex2 -#define ffebld_cu_val_complex3(u) (u).complex3 -#define ffebld_cu_val_complex4(u) (u).complex4 -#define ffebld_cu_val_complex5(u) (u).complex5 -#define ffebld_cu_val_complex6(u) (u).complex6 -#define ffebld_cu_val_complex7(u) (u).complex7 -#define ffebld_cu_val_complex8(u) (u).complex8 -#define ffebld_cu_val_complexdefault ffebld_cu_val_complex1 -#define ffebld_cu_val_complexdouble ffebld_cu_val_complex2 -#define ffebld_cu_val_complexquad ffebld_cu_val_complex3 -#define ffebld_cu_val_character1(u) (u).character1 -#define ffebld_cu_val_character2(u) (u).character2 -#define ffebld_cu_val_character3(u) (u).character3 -#define ffebld_cu_val_character4(u) (u).character4 -#define ffebld_cu_val_character5(u) (u).character5 -#define ffebld_cu_val_character6(u) (u).character6 -#define ffebld_cu_val_character7(u) (u).character7 -#define ffebld_cu_val_character8(u) (u).character8 -#define ffebld_end_list(b) (*(b) = NULL) -#define ffebld_head(b) ((b)->u.item.head) -#define ffebld_info(b) ((b)->info) -#define ffebld_init_3() -#define ffebld_init_4() -#define ffebld_init_list(l,b) (*(l) = NULL, *(b) = (l)) -#define ffebld_labter(b) ((b)->u.labter) -#define ffebld_labtok(b) ((b)->u.labtok) -#define ffebld_left(b) ((b)->u.nonter.left) -#define ffebld_name_string(n) ((n)->name) -#define ffebld_new() \ - ((ffebld) malloc_new_kp(ffebld_pool(), "FFEBLD",sizeof(struct _ffebld_))) -#define ffebld_new_any() ffebld_new_none(FFEBLD_opANY) -#define ffebld_new_conter(c) ffebld_new_conter_with_orig((c),NULL) -#define ffebld_new_star() ffebld_new_none(FFEBLD_opSTAR) -#define ffebld_new_uplus(l) ffebld_new_one(FFEBLD_opUPLUS,(l)) -#define ffebld_new_uminus(l) ffebld_new_one(FFEBLD_opUMINUS,(l)) -#define ffebld_new_add(l,r) ffebld_new_two(FFEBLD_opADD,(l),(r)) -#define ffebld_new_subtract(l,r) ffebld_new_two(FFEBLD_opSUBTRACT,(l),(r)) -#define ffebld_new_multiply(l,r) ffebld_new_two(FFEBLD_opMULTIPLY,(l),(r)) -#define ffebld_new_divide(l,r) ffebld_new_two(FFEBLD_opDIVIDE,(l),(r)) -#define ffebld_new_power(l,r) ffebld_new_two(FFEBLD_opPOWER,(l),(r)) -#define ffebld_new_bounds(l,r) ffebld_new_two(FFEBLD_opBOUNDS,(l),(r)) -#define ffebld_new_concatenate(l,r) ffebld_new_two(FFEBLD_opCONCATENATE,(l),(r)) -#define ffebld_new_not(l) ffebld_new_one(FFEBLD_opNOT,(l)) -#define ffebld_new_lt(l,r) ffebld_new_two(FFEBLD_opLT,(l),(r)) -#define ffebld_new_le(l,r) ffebld_new_two(FFEBLD_opLE,(l),(r)) -#define ffebld_new_eq(l,r) ffebld_new_two(FFEBLD_opEQ,(l),(r)) -#define ffebld_new_ne(l,r) ffebld_new_two(FFEBLD_opNE,(l),(r)) -#define ffebld_new_gt(l,r) ffebld_new_two(FFEBLD_opGT,(l),(r)) -#define ffebld_new_ge(l,r) ffebld_new_two(FFEBLD_opGE,(l),(r)) -#define ffebld_new_and(l,r) ffebld_new_two(FFEBLD_opAND,(l),(r)) -#define ffebld_new_or(l,r) ffebld_new_two(FFEBLD_opOR,(l),(r)) -#define ffebld_new_xor(l,r) ffebld_new_two(FFEBLD_opXOR,(l),(r)) -#define ffebld_new_eqv(l,r) ffebld_new_two(FFEBLD_opEQV,(l),(r)) -#define ffebld_new_neqv(l,r) ffebld_new_two(FFEBLD_opNEQV,(l),(r)) -#define ffebld_new_paren(l) ffebld_new_one(FFEBLD_opPAREN,(l)) -#define ffebld_new_repeat(l,r) ffebld_new_two(FFEBLD_opREPEAT,(l),(r)) -#define ffebld_new_percent_descr(l) ffebld_new_one(FFEBLD_opPERCENT_DESCR,(l)) -#define ffebld_new_percent_loc(l) ffebld_new_one(FFEBLD_opPERCENT_LOC,(l)) -#define ffebld_new_percent_ref(l) ffebld_new_one(FFEBLD_opPERCENT_REF,(l)) -#define ffebld_new_percent_val(l) ffebld_new_one(FFEBLD_opPERCENT_VAL,(l)) -#define ffebld_new_complex(l,r) ffebld_new_two(FFEBLD_opCOMPLEX,(l),(r)) -#define ffebld_new_convert(l) ffebld_new_one(FFEBLD_opCONVERT,(l)) -#define ffebld_new_funcref(l,r) ffebld_new_two(FFEBLD_opFUNCREF,(l),(r)) -#define ffebld_new_subrref(l,r) ffebld_new_two(FFEBLD_opSUBRREF,(l),(r)) -#define ffebld_new_arrayref(l,r) ffebld_new_two(FFEBLD_opARRAYREF,(l),(r)) -#define ffebld_new_substr(l,r) ffebld_new_two(FFEBLD_opSUBSTR,(l),(r)) -#define ffebld_new_impdo(l,r) ffebld_new_two(FFEBLD_opIMPDO,(l),(r)) -#define ffebld_op(b) ((b)->op) -#define ffebld_pool() (ffebld_pool_stack_.pool) -#define ffebld_right(b) ((b)->u.nonter.right) -#define ffebld_set_accter(b,a) ((b)->u.accter.array = (a)) -#define ffebld_set_arrter(b,a) ((b)->u.arrter.array = (a)) -#define ffebld_set_conter(b,c) ((b)->u.conter.expr = (c)) -#define ffebld_set_info(b,i) ((b)->info = (i)) -#define ffebld_set_labter(b,l) ((b)->u.labter = (l)) -#define ffebld_set_op(b,o) ((b)->op = (o)) -#define ffebld_set_head(b,h) ((b)->u.item.head = (h)) -#define ffebld_set_left(b,l) ((b)->u.nonter.left = (l)) -#define ffebld_set_right(b,r) ((b)->u.nonter.right = (r)) -#define ffebld_set_trail(b,t) ((b)->u.item.trail = (t)) -#define ffebld_size(b) (ffeinfo_size((b)->info)) -#define ffebld_size_known(b) ffebld_size(b) -#define ffebld_symter(b) ((b)->u.symter.symbol) -#define ffebld_symter_generic(b) ((b)->u.symter.generic) -#define ffebld_symter_doiter(b) ((b)->u.symter.do_iter) -#define ffebld_symter_implementation(b) ((b)->u.symter.implementation) -#define ffebld_symter_specific(b) ((b)->u.symter.specific) -#define ffebld_symter_set_generic(b,g) ((b)->u.symter.generic = (g)) -#define ffebld_symter_set_implementation(b,i) \ - ((b)->u.symter.implementation = (i)) -#define ffebld_symter_set_is_doiter(b,f) ((b)->u.symter.do_iter = (f)) -#define ffebld_symter_set_specific(b,s) ((b)->u.symter.specific = (s)) -#define ffebld_terminate_0() -#define ffebld_terminate_1() -#define ffebld_terminate_2() -#define ffebld_terminate_3() -#define ffebld_terminate_4() -#define ffebld_trail(b) ((b)->u.item.trail) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/bugs.texi b/gcc/f/bugs.texi deleted file mode 100755 index b591cfc..0000000 --- a/gcc/f/bugs.texi +++ /dev/null @@ -1,320 +0,0 @@ -@c Copyright (C) 1995-1998 Free Software Foundation, Inc. -@c This is part of the G77 manual. -@c For copying conditions, see the file g77.texi. - -@c The text of this file appears in the file BUGS -@c in the G77 distribution, as well as in the G77 manual. - -@c 1998-09-01 - -@ifclear BUGSONLY -@node Actual Bugs -@section Actual Bugs We Haven't Fixed Yet -@end ifclear - -This section identifies bugs that @code{g77} @emph{users} -might run into. -This includes bugs that are actually in the @code{gcc} -back end (GBE) or in @code{libf2c}, because those -sets of code are at least somewhat under the control -of (and necessarily intertwined with) @code{g77}, so it -isn't worth separating them out. - -For information on bugs that might afflict people who -configure, port, build, and install @code{g77}, -@ref{Problems Installing}. - -@itemize @bullet -@item -@code{g77} sometimes crashes when compiling code -containing the construct @samp{CMPLX(0.)} or similar. -This is a @code{gcc} back-end bug. -It can be worked around using @samp{-fno-emulate-complex}, -though that might trigger other, older bugs. -Compiling without optimization is another work-around. - -Fixed in @code{egcs} 1.1. - -@item -@c Tim Prince discovered this. -Automatic arrays aren't working on HP-UX systems, -at least in HP-UX version 10.20. -Writing into them apparently causes over-writing -of statically declared data in the main program. -This probably means the arrays themselves are being under-allocated, -or pointers to them being improperly handled, -e.g. not passed to other procedures as they should be. - -@item -@c Toon Moene discovered these. -Some Fortran code has been found to be miscompiled -by @code{g77} built on @code{gcc} version 2.8.1 -on m68k-next-nextstep3 configurations -when using the @samp{-O2} option. -Even a C function is known to miscompile -on that configuration -when using the @samp{-O2 -funroll-loops} options. - -Fixed in @code{egcs}. - -@cindex DNRM2 -@cindex stack, 387 coprocessor -@cindex ix86 -@cindex -O2 -@item -A code-generation bug afflicts -Intel x86 targets when @samp{-O2} is specified -compiling, for example, an old version of -the @samp{DNRM2} routine. -The x87 coprocessor stack is being -mismanaged in cases where assigned @code{GOTO} -and @code{ASSIGN} are involved. - -Fixed in @code{egcs} version 1.1. - -@item -@code{g77} fails to warn about -use of a ``live'' iterative-DO variable -as an implied-DO variable -in a @samp{WRITE} or @samp{PRINT} statement -(although it does warn about this in a @samp{READ} statement). - -@item -A compiler crash, or apparently infinite run time, -can result when compiling complicated expressions -involving @code{COMPLEX} arithmetic -(especially multiplication). - -Fixed in @code{egcs} version 1.1. - -@item -Something about @code{g77}'s straightforward handling of -label references and definitions sometimes prevents the GBE -from unrolling loops. -Until this is solved, try inserting or removing @code{CONTINUE} -statements as the terminal statement, using the @code{END DO} -form instead, and so on. - -@item -Some confusion in diagnostics concerning failing @code{INCLUDE} -statements from within @code{INCLUDE}'d or @code{#include}'d files. - -@cindex integer constants -@cindex constants, integer -@item -@code{g77} assumes that @code{INTEGER(KIND=1)} constants range -from @samp{-2**31} to @samp{2**31-1} (the range for -two's-complement 32-bit values), -instead of determining their range from the actual range of the -type for the configuration (and, someday, for the constant). - -Further, it generally doesn't implement the handling -of constants very well in that it makes assumptions about the -configuration that it no longer makes regarding variables (types). - -Included with this item is the fact that @code{g77} doesn't recognize -that, on IEEE-754/854-compliant systems, @samp{0./0.} should produce a NaN -and no warning instead of the value @samp{0.} and a warning. -This is to be fixed in version 0.6, when @code{g77} will use the -@code{gcc} back end's constant-handling mechanisms to replace its own. - -@cindex compiler speed -@cindex speed, of compiler -@cindex compiler memory usage -@cindex memory usage, of compiler -@cindex large aggregate areas -@cindex initialization -@cindex DATA statement -@cindex statements, DATA -@item -@code{g77} uses way too much memory and CPU time to process large aggregate -areas having any initialized elements. - -For example, @samp{REAL A(1000000)} followed by @samp{DATA A(1)/1/} -takes up way too much time and space, including -the size of the generated assembler file. -This is to be mitigated somewhat in version 0.6. - -Version 0.5.18 improves cases like this---specifically, -cases of @emph{sparse} initialization that leave large, contiguous -areas uninitialized---significantly. -However, even with the improvements, these cases still -require too much memory and CPU time. - -(Version 0.5.18 also improves cases where the initial values are -zero to a much greater degree, so if the above example -ends with @samp{DATA A(1)/0/}, the compile-time performance -will be about as good as it will ever get, aside from unrelated -improvements to the compiler.) - -Note that @code{g77} does display a warning message to -notify the user before the compiler appears to hang. -@xref{Large Initialization,,Initialization of Large Aggregate Areas}, -for information on how to change the point at which -@code{g77} decides to issue this warning. - -@cindex debugging -@cindex common blocks -@cindex equivalence areas -@cindex local equivalence areas -@item -@code{g77} doesn't emit variable and array members of common blocks for use -with a debugger (the @samp{-g} command-line option). -The code is present to do this, but doesn't work with at least -one debug format---perhaps it works with others. -And it turns out there's a similar bug for -local equivalence areas, so that has been disabled as well. - -As of Version 0.5.19, a temporary kludge solution is provided whereby -some rudimentary information on a member is written as a string that -is the member's value as a character string. - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -@cindex code, displaying main source -@cindex displaying main source code -@cindex debugging main source code -@cindex printing main source -@item -When debugging, after starting up the debugger but before being able -to see the source code for the main program unit, the user must currently -set a breakpoint at @samp{MAIN__} (or @samp{MAIN___} or @samp{MAIN_} if -@samp{MAIN__} doesn't exist) -and run the program until it hits the breakpoint. -At that point, the -main program unit is activated and about to execute its first -executable statement, but that's the state in which the debugger should -start up, as is the case for languages like C. - -@cindex debugger -@item -Debugging @code{g77}-compiled code using debuggers other than -@code{gdb} is likely not to work. - -Getting @code{g77} and @code{gdb} to work together is a known -problem---getting @code{g77} to work properly with other -debuggers, for which source code often is unavailable to @code{g77} -developers, seems like a much larger, unknown problem, -and is a lower priority than making @code{g77} and @code{gdb} -work together properly. - -On the other hand, information about problems other debuggers -have with @code{g77} output might make it easier to properly -fix @code{g77}, and perhaps even improve @code{gdb}, so it -is definitely welcome. -Such information might even lead to all relevant products -working together properly sooner. - -@cindex Alpha, support -@cindex support, Alpha -@item -@code{g77} doesn't work perfectly on 64-bit configurations -such as the Digital Semiconductor (``DEC'') Alpha. - -This problem is largely resolved as of version 0.5.23. -Version 0.6 should solve most or all remaining problems -(such as cross-compiling involving 64-bit machines). - -@cindex COMPLEX support -@cindex support, COMPLEX -@item -Maintainers of @code{gcc} report that the back end definitely has ``broken'' -support for @code{COMPLEX} types. -Based on their input, it seems many of -the problems affect only the more-general facilities for gcc's -@code{__complex__} type, such as @code{__complex__ int} -(where the real and imaginary parts are integers) that GNU -Fortran does not use. - -Version 0.5.20 of @code{g77} works around this -problem by not using the back end's support for @code{COMPLEX}. -The new option @samp{-fno-emulate-complex} avoids the work-around, -reverting to using the same ``broken'' mechanism as that used -by versions of @code{g77} prior to 0.5.20. - -@cindex ELF support -@cindex support, ELF -@cindex -fPIC option -@cindex options, -fPIC -@item -@code{g77} sometimes produces invalid assembler code -when using the @samp{-fPIC} option (such as compiling for ELF targets) -on the Intel x86 architecture target. -The symptom is that the assembler complains about invalid opcodes. -This bug is in the @code{gcc} back end. - -Fixed in @code{egcs} version 1.0.2. - -@cindex padding -@cindex structures -@cindex common blocks -@cindex equivalence areas -@item -@code{g77} currently inserts needless padding for things like -@samp{COMMON A,IPAD} where @samp{A} is @code{CHARACTER*1} and @samp{IPAD} -is @code{INTEGER(KIND=1)} on machines like x86, -because the back end insists that @samp{IPAD} -be aligned to a 4-byte boundary, -but the processor has no such requirement -(though it is usually good for performance). - -The @code{gcc} back end needs to provide a wider array -of specifications of alignment requirements and preferences for targets, -and front ends like @code{g77} should take advantage of this -when it becomes available. - -@cindex alignment -@cindex double-precision performance -@cindex -malign-double -@item -The x86 target's @samp{-malign-double} option -no longer reliably aligns double-precision variables and arrays -when they are placed in the stack frame. - -This can significantly reduce the performance of some applications, -even on a run-to-run basis -(that is, performance measurements can vary fairly widely -depending on whether frequently used variables are properly aligned, -and that can change from one program run to the next, -even from one procedure call to the next). - -Versions 0.5.22 and earlier of @code{g77} -included a patch to @code{gcc} that enabled this, -but that patch has been deemed an improper (probably buggy) one -for version 2.8 of @code{gcc} and for @code{egcs}. - -Note that version 1.1 of @code{egcs} -aligns double-precision variables and arrays -when they are in static storage -even if @samp{-malign-double} is not specified. - -There is ongoing investigation into -how to make @samp{-malign-double} work properly, -also into how to make it unnecessary to get -all double-precision variables and arrays aligned -when such alignment would not violate -the relevant specifications for processor -and inter-procedural interfaces. - -For a suite of programs to test double-precision alignment, -see @uref{ftp://alpha.gnu.org/gnu/g77/align/}. - -@cindex complex performance -@cindex aliasing -@item -The @code{libf2c} routines that perform some run-time -arithmetic on @code{COMPLEX} operands -were modified circa version 0.5.20 of @code{g77} -to work properly even in the presence of aliased operands. - -While the @code{g77} and @code{netlib} versions of @code{libf2c} -differ on how this is accomplished, -the main differences are that we believe -the @code{g77} version works properly -even in the presence of @emph{partially} aliased operands. - -However, these modifications have reduced performance -on targets such as x86, -due to the extra copies of operands involved. -@end itemize diff --git a/gcc/f/bugs0.texi b/gcc/f/bugs0.texi deleted file mode 100755 index e8f6d22..0000000 --- a/gcc/f/bugs0.texi +++ /dev/null @@ -1,17 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c %**start of header -@setfilename BUGS -@set BUGSONLY -@c %**end of header - -@c The immediately following lines apply to the BUGS file -@c which is generated using this file. -This file lists known bugs in the GNU Fortran compiler. -Copyright (C) 1995, 1996 Free Software Foundation, Inc. -You may copy, distribute, and modify it freely as long as you preserve -this copyright notice and permission notice. - -@node Top,,, (dir) -@chapter Bugs in GNU Fortran -@include bugs.texi -@bye diff --git a/gcc/f/com-rt.def b/gcc/f/com-rt.def deleted file mode 100755 index 6ceaf17..0000000 --- a/gcc/f/com-rt.def +++ /dev/null @@ -1,282 +0,0 @@ -/* com-rt.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - com.c - - Modifications: -*/ - -/* DEFGFRT(CODE,NAME,TYPE,VOLATILE,COMPLEX): - - CODE -- the #define name to use to refer to the function in g77 code - - NAME -- the name as seen by the back end and, with whatever massaging - is normal, the linker - - TYPE -- a code for the tree for the type, assigned when first encountered - (NOTE: There's a distinction made between the semantic return - value for the function, and the actual return mechanism; e.g. - `r_abs()' computes a single-precision `float' return value - but returns it as a `double'. This distinction is important - and is flagged via the _F2C_ versus _GNU_ suffix.) - - ARGS -- a string of codes representing the types of the arguments; the - last type specifies the type for that and all following args, - and the null pointer (0) means the same as "0": - - 0 Not applicable at and beyond this point - & Pointer to type that follows - a char - c complex - d doublereal - e doublecomplex - f real - i integer - j longint - - VOLATILE -- TRUE if the function never returns (gen's emit_barrier in - g77 back end) - - COMPLEX -- TRUE if the return value is COMPLEX or DOUBLE COMPLEX and - thus might need to be returned as ptr-to-1st-arg - -*/ - -DEFGFRT (FFECOM_gfrtCAT, "s_cat", FFECOM_rttypeVOID_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCMP, "s_cmp", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCOPY, "s_copy", FFECOM_rttypeVOID_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPAUSE, "s_paus", FFECOM_rttypeVOID_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSTOP, "s_stop", FFECOM_rttypeVOID_, 0, TRUE, FALSE) - -DEFGFRT (FFECOM_gfrtSRDUE, "s_rdue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERDUE, "e_rdue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSUE, "s_rsue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERSUE, "e_rsue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRDFE, "s_rdfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERDFE, "e_rdfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSFI, "s_rsfi", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERSFI, "e_rsfi", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSFE, "s_rsfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERSFE, "e_rsfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSLI, "s_rsli", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERSLI, "e_rsli", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSLE, "s_rsle", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERSLE, "e_rsle", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRSNE, "s_rsne", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtSWDUE, "s_wdue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWDUE, "e_wdue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSUE, "s_wsue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWSUE, "e_wsue", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWDFE, "s_wdfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWDFE, "e_wdfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSFI, "s_wsfi", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWSFI, "e_wsfi", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSFE, "s_wsfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWSFE, "e_wsfe", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSLI, "s_wsli", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWSLI, "e_wsli", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSLE, "s_wsle", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEWSLE, "e_wsle", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSWSNE, "s_wsne", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtDOFIO, "do_fio", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDOLIO, "do_lio", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDOUIO, "do_uio", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtFOPEN, "f_open", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFCLOS, "f_clos", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFINQU, "f_inqu", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtFBACK, "f_back", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFEND, "f_end", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFREW, "f_rew", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtABORT, "G77_abort_0", FFECOM_rttypeVOID_, 0, TRUE, FALSE) -DEFGFRT (FFECOM_gfrtABS, "r_abs", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtACCESS, "G77_access_0", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtACOS, "r_acos", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtAIMAG, "r_imag", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtAINT, "r_int", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtALARM, "G77_alarm_0", FFECOM_rttypeINTEGER_, "&i0", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtALOG, "r_log", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtALOG10, "r_lg10", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtAMOD, "r_mod", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtANINT, "r_nint", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtASIN, "r_asin", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtATAN, "r_atan", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtATAN2, "r_atn2", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCABS, "c_abs", FFECOM_rttypeREAL_F2C_, "&c", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCCOS, "c_cos", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCEXP, "c_exp", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCHDIR, "G77_chdir_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCLOG, "c_log", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCHMOD, "G77_chmod_0", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCONJG, "r_cnjg", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCOS, "r_cos", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCOSH, "r_cosh", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCSIN, "c_sin", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCSQRT, "c_sqrt", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCTIME, "G77_ctime_0", FFECOM_rttypeCHARACTER_, "&j", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDABS, "d_abs", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDACOS, "d_acos", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDASIN, "d_asin", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDATAN, "d_atan", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDATAN2, "d_atn2", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDATE, "G77_date_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDATE_AND_TIME, "G77_date_and_time_0", FFECOM_rttypeVOID_, "&a&a&a&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESJ0, "j0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESJ1, "j1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESJN, "jn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESY0, "y0", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESY1, "y1", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_BESYN, "yn", FFECOM_rttypeDOUBLE_, "id", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDCOS, "d_cos", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDCOSH, "d_cosh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDDIM, "d_dim", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDERF, "G77_derf_0", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDERFC, "G77_derfc_0", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDEXP, "d_exp", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDIM, "r_dim", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDINT, "d_int", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDLOG, "d_log", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDLOG10, "d_lg10", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDMOD, "d_mod", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDNINT, "d_nint", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDPROD, "d_prod", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDSIGN, "d_sign", FFECOM_rttypeDOUBLE_, "&d&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDSIN, "d_sin", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDSINH, "d_sinh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDSQRT, "d_sqrt", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDTAN, "d_tan", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDTANH, "d_tanh", FFECOM_rttypeDOUBLE_, "&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtDTIME, "G77_dtime_0", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERF, "G77_erf_0", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtERFC, "G77_erfc_0", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtETIME, "G77_etime_0", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtEXIT, "G77_exit_0", FFECOM_rttypeVOID_, "&i", TRUE, FALSE) -DEFGFRT (FFECOM_gfrtEXP, "r_exp", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFDATE, "G77_fdate_0", FFECOM_rttypeCHARACTER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFGET, "G77_fget_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFGETC, "G77_fgetc_0", FFECOM_rttypeINTEGER_, "&i&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFLUSH, "G77_flush_0", FFECOM_rttypeVOID_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFLUSH1, "G77_flush1_0", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFNUM, "G77_fnum_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFPUT, "G77_fput_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFPUTC, "G77_fputc_0", FFECOM_rttypeINTEGER_, "&i&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFSTAT, "G77_fstat_0", FFECOM_rttypeINTEGER_, "&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFTELL, "G77_ftell_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtFSEEK, "G77_fseek_0", FFECOM_rttypeINTEGER_, "&i&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGERROR, "G77_gerror_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETARG, "G77_getarg_0", FFECOM_rttypeVOID_, "&i&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETCWD, "G77_getcwd_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETGID, "G77_getgid_0", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETLOG, "G77_getlog_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETPID, "G77_getpid_0", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETUID, "G77_getuid_0", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGETENV, "G77_getenv_0", FFECOM_rttypeVOID_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtGMTIME, "G77_gmtime_0", FFECOM_rttypeVOID_, "&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtHOSTNM, "G77_hostnm_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIABS, "i_abs", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIARGC, "G77_iargc_0", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIDATE, "G77_idate_0", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIDIM, "i_dim", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIDNINT, "i_dnnt", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIERRNO, "G77_ierrno_0", FFECOM_rttypeINTEGER_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtINDEX, "i_indx", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtIRAND, "G77_irand_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtISIGN, "i_sign", FFECOM_rttypeINTEGER_, "&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtISATTY, "G77_isatty_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtITIME, "G77_itime_0", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtKILL, "G77_kill_0", FFECOM_rttypeINTEGER_, "&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLEN, "i_len", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLGE, "l_ge", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLGT, "l_gt", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLINK, "G77_link_0", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLLE, "l_le", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLLT, "l_lt", FFECOM_rttypeLOGICAL_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLNBLNK, "G77_lnblnk_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLSTAT, "G77_lstat_0", FFECOM_rttypeINTEGER_, "&a&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtLTIME, "G77_ltime_0", FFECOM_rttypeVOID_, "&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtMCLOCK, "G77_mclock_0", FFECOM_rttypeLONGINT_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtMOD, "i_mod", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtNINT, "i_nint", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPERROR, "G77_perror_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtRAND, "G77_rand_0", FFECOM_rttypeREAL_F2C_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtRENAME, "G77_rename_0", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSECNDS, "G77_secnds_0", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSECOND, "G77_second_0", FFECOM_rttypeREAL_F2C_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSIGN, "r_sign", FFECOM_rttypeREAL_F2C_, "&f&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_SIGNAL, "G77_signal_0", FFECOM_rttypeVOIDSTAR_, "&i0", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSIN, "r_sin", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSINH, "r_sinh", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSLEEP, "G77_sleep_0", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSQRT, "r_sqrt", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSRAND, "G77_srand_0", FFECOM_rttypeVOID_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSTAT, "G77_stat_0", FFECOM_rttypeINTEGER_, "&a&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSYMLNK, "G77_symlnk_0", FFECOM_rttypeINTEGER_, "&a&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSYSTEM, "G77_system_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtSYSTEM_CLOCK, "G77_system_clock_0", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTAN, "r_tan", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTANH, "r_tanh", FFECOM_rttypeREAL_F2C_, "&f", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTIME, "G77_time_0", FFECOM_rttypeLONGINT_, 0, FALSE, FALSE) -DEFGFRT (FFECOM_gfrtTTYNAM, "G77_ttynam_0", FFECOM_rttypeCHARACTER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtUNLINK, "G77_unlink_0", FFECOM_rttypeINTEGER_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtUMASK, "G77_umask_0", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtVXTIDATE, "G77_vxtidate_0", FFECOM_rttypeVOID_, "&i&i&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtVXTTIME, "G77_vxttime_0", FFECOM_rttypeVOID_, "&a", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCDABS, "z_abs", FFECOM_rttypeDOUBLE_, "&e", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtCDCOS, "z_cos", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCDEXP, "z_exp", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCDLOG, "z_log", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtDCONJG, "d_cnjg", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCDSIN, "z_sin", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtCDSQRT, "z_sqrt", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtDIMAG, "d_imag", FFECOM_rttypeDOUBLE_, "&e", FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtL_ACOS, "acos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_ASIN, "asin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_ATAN, "atan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_ATAN2, "atan2", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_COS, "__builtin_cos", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_COSH, "cosh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_ERF, "erf", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_ERFC, "erfc", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_EXP, "exp", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_FLOOR, "floor", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_LOG, "log", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_SIN, "__builtin_sin", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_SINH, "sinh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_SQRT, "__builtin_fsqrt", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_TAN, "tan", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtL_TANH, "tanh", FFECOM_rttypeDOUBLE_, "d", FALSE, FALSE) - -DEFGFRT (FFECOM_gfrtPOW_CI, "pow_ci", FFECOM_rttypeCOMPLEX_F2C_, "&c&i", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtPOW_DD, "pow_dd", FFECOM_rttypeDOUBLE_, "&d&d", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_DI, "pow_di", FFECOM_rttypeDOUBLE_, "&d&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_II, "pow_ii", FFECOM_rttypeINTEGER_, "&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_QQ, "pow_qq", FFECOM_rttypeLONGINT_, "&j&j", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_RI, "pow_ri", FFECOM_rttypeREAL_F2C_, "&f&i", FALSE, FALSE) -DEFGFRT (FFECOM_gfrtPOW_ZI, "pow_zi", FFECOM_rttypeDBLCMPLX_F2C_, "&e&i", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtPOW_ZZ, "pow_zz", FFECOM_rttypeDBLCMPLX_F2C_, "&e&e", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtDIV_CC, "c_div", FFECOM_rttypeCOMPLEX_F2C_, "&c", FALSE, TRUE) -DEFGFRT (FFECOM_gfrtDIV_ZZ, "z_div", FFECOM_rttypeDBLCMPLX_F2C_, "&e", FALSE, TRUE) diff --git a/gcc/f/com.c b/gcc/f/com.c deleted file mode 100755 index c45c6b8..0000000 --- a/gcc/f/com.c +++ /dev/null @@ -1,16512 +0,0 @@ -/* com.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Contains compiler-specific functions. - - Modifications: -*/ - -/* Understanding this module means understanding the interface between - the g77 front end and the gcc back end (or, perhaps, some other - back end). In here are the functions called by the front end proper - to notify whatever back end is in place about certain things, and - also the back-end-specific functions. It's a bear to deal with, so - lately I've been trying to simplify things, especially with regard - to the gcc-back-end-specific stuff. - - Building expressions generally seems quite easy, but building decls - has been challenging and is undergoing revision. gcc has several - kinds of decls: - - TYPE_DECL -- a type (int, float, struct, function, etc.) - CONST_DECL -- a constant of some type other than function - LABEL_DECL -- a variable or a constant? - PARM_DECL -- an argument to a function (a variable that is a dummy) - RESULT_DECL -- the return value of a function (a variable) - VAR_DECL -- other variable (can hold a ptr-to-function, struct, int, etc.) - FUNCTION_DECL -- a function (either the actual function or an extern ref) - FIELD_DECL -- a field in a struct or union (goes into types) - - g77 has a set of functions that somewhat parallels the gcc front end - when it comes to building decls: - - Internal Function (one we define, not just declare as extern): - int yes; - yes = suspend_momentary (); - if (is_nested) push_f_function_context (); - start_function (get_identifier ("function_name"), function_type, - is_nested, is_public); - // for each arg, build PARM_DECL and call push_parm_decl (decl) with it; - store_parm_decls (is_main_program); - ffecom_start_compstmt_ (); - // for stmts and decls inside function, do appropriate things; - ffecom_end_compstmt_ (); - finish_function (is_nested); - if (is_nested) pop_f_function_context (); - if (is_nested) resume_momentary (yes); - - Everything Else: - int yes; - tree d; - tree init; - yes = suspend_momentary (); - // fill in external, public, static, &c for decl, and - // set DECL_INITIAL to error_mark_node if going to initialize - // set is_top_level TRUE only if not at top level and decl - // must go in top level (i.e. not within current function decl context) - d = start_decl (decl, is_top_level); - init = ...; // if have initializer - finish_decl (d, init, is_top_level); - resume_momentary (yes); - -*/ - -/* Include files. */ - -#include "proj.h" -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#include "flags.j" -#include "rtl.j" -#include "toplev.j" -#include "tree.j" -#include "output.j" /* Must follow tree.j so TREE_CODE is defined! */ -#include "convert.j" -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -#define FFECOM_GCC_INCLUDE 1 /* Enable -I. */ - -/* BEGIN stuff from gcc/cccp.c. */ - -/* The following symbols should be autoconfigured: - HAVE_FCNTL_H - HAVE_STDLIB_H - HAVE_SYS_TIME_H - HAVE_UNISTD_H - STDC_HEADERS - TIME_WITH_SYS_TIME - In the mean time, we'll get by with approximations based - on existing GCC configuration symbols. */ - -#ifdef POSIX -# ifndef HAVE_STDLIB_H -# define HAVE_STDLIB_H 1 -# endif -# ifndef HAVE_UNISTD_H -# define HAVE_UNISTD_H 1 -# endif -# ifndef STDC_HEADERS -# define STDC_HEADERS 1 -# endif -#endif /* defined (POSIX) */ - -#if defined (POSIX) || (defined (USG) && !defined (VMS)) -# ifndef HAVE_FCNTL_H -# define HAVE_FCNTL_H 1 -# endif -#endif - -#ifndef RLIMIT_STACK -# include <time.h> -#else -# if TIME_WITH_SYS_TIME -# include <sys/time.h> -# include <time.h> -# else -# if HAVE_SYS_TIME_H -# include <sys/time.h> -# else -# include <time.h> -# endif -# endif -# include <sys/resource.h> -#endif - -#if HAVE_FCNTL_H -# include <fcntl.h> -#endif - -/* This defines "errno" properly for VMS, and gives us EACCES. */ -#include <errno.h> - -#if HAVE_STDLIB_H -# include <stdlib.h> -#else -char *getenv (); -#endif - -#if HAVE_UNISTD_H -# include <unistd.h> -#endif - -/* VMS-specific definitions */ -#ifdef VMS -#include <descrip.h> -#define O_RDONLY 0 /* Open arg for Read/Only */ -#define O_WRONLY 1 /* Open arg for Write/Only */ -#define read(fd,buf,size) VMS_read (fd,buf,size) -#define write(fd,buf,size) VMS_write (fd,buf,size) -#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 strncat(dst,src,cnt) VMS_strncat (dst,src,cnt) -#define fstat(fd,stbuf) VMS_fstat (fd,stbuf) -static int VMS_fstat (), VMS_stat (); -static char * VMS_strncat (); -static int VMS_read (); -static int VMS_write (); -static int VMS_open (); -static FILE * VMS_fopen (); -static FILE * VMS_freopen (); -static void hack_vms_include_specification (); -typedef struct { unsigned :16, :16, :16; } vms_ino_t; -#define ino_t vms_ino_t -#define INCLUDE_LEN_FUDGE 10 /* leave room for VMS syntax conversion */ -#ifdef __GNUC__ -#define BSTRING /* VMS/GCC supplies the bstring routines */ -#endif /* __GNUC__ */ -#endif /* VMS */ - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -/* END stuff from gcc/cccp.c. */ - -#define FFECOM_DETERMINE_TYPES 1 /* for com.h */ -#include "com.h" -#include "bad.h" -#include "bld.h" -#include "equiv.h" -#include "expr.h" -#include "implic.h" -#include "info.h" -#include "malloc.h" -#include "src.h" -#include "st.h" -#include "storag.h" -#include "symbol.h" -#include "target.h" -#include "top.h" -#include "type.h" - -/* Externals defined here. */ - -#define FFECOM_FASTER_ARRAY_REFS 0 /* Generates faster code? */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - -/* tree.h declares a bunch of stuff that it expects the front end to - define. Here are the definitions, which in the C front end are - found in the file c-decl.c. */ - -tree integer_zero_node; -tree integer_one_node; -tree null_pointer_node; -tree error_mark_node; -tree void_type_node; -tree integer_type_node; -tree unsigned_type_node; -tree char_type_node; -tree current_function_decl; - -/* ~~tree.h SHOULD declare this, because toplev.c and dwarfout.c reference - it. */ - -char *language_string = "GNU F77"; - -/* Stream for reading from the input file. */ -FILE *finput; - -/* These definitions parallel those in c-decl.c so that code from that - module can be used pretty much as is. Much of these defs aren't - otherwise used, i.e. by g77 code per se, except some of them are used - to build some of them that are. The ones that are global (i.e. not - "static") are those that ste.c and such might use (directly - or by using com macros that reference them in their definitions). */ - -static tree short_integer_type_node; -tree long_integer_type_node; -static tree long_long_integer_type_node; - -static tree short_unsigned_type_node; -static tree long_unsigned_type_node; -static tree long_long_unsigned_type_node; - -static tree unsigned_char_type_node; -static tree signed_char_type_node; - -static tree float_type_node; -static tree double_type_node; -static tree complex_float_type_node; -tree complex_double_type_node; -static tree long_double_type_node; -static tree complex_integer_type_node; -static tree complex_long_double_type_node; - -tree string_type_node; - -static tree double_ftype_double; -static tree float_ftype_float; -static tree ldouble_ftype_ldouble; - -/* The rest of these are inventions for g77, though there might be - similar things in the C front end. As they are found, these - inventions should be renamed to be canonical. Note that only - the ones currently required to be global are so. */ - -static tree ffecom_tree_fun_type_void; -static tree ffecom_tree_ptr_to_fun_type_void; - -tree ffecom_integer_type_node; /* Abbrev for _tree_type[blah][blah]. */ -tree ffecom_integer_zero_node; /* Like *_*_* with g77's integer type. */ -tree ffecom_integer_one_node; /* " */ -tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype]; - -/* _fun_type things are the f2c-specific versions. For -fno-f2c, - just use build_function_type and build_pointer_type on the - appropriate _tree_type array element. */ - -static tree ffecom_tree_fun_type[FFEINFO_basictype][FFEINFO_kindtype]; -static tree ffecom_tree_ptr_to_fun_type[FFEINFO_basictype][FFEINFO_kindtype]; -static tree ffecom_tree_subr_type; -static tree ffecom_tree_ptr_to_subr_type; -static tree ffecom_tree_blockdata_type; - -static tree ffecom_tree_xargc_; - -ffecomSymbol ffecom_symbol_null_ -= -{ - NULL_TREE, - NULL_TREE, - NULL_TREE, - NULL_TREE, - false -}; -ffeinfoKindtype ffecom_pointer_kind_ = FFEINFO_basictypeNONE; -ffeinfoKindtype ffecom_label_kind_ = FFEINFO_basictypeNONE; - -int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype]; -tree ffecom_f2c_integer_type_node; -tree ffecom_f2c_ptr_to_integer_type_node; -tree ffecom_f2c_address_type_node; -tree ffecom_f2c_real_type_node; -tree ffecom_f2c_ptr_to_real_type_node; -tree ffecom_f2c_doublereal_type_node; -tree ffecom_f2c_complex_type_node; -tree ffecom_f2c_doublecomplex_type_node; -tree ffecom_f2c_longint_type_node; -tree ffecom_f2c_logical_type_node; -tree ffecom_f2c_flag_type_node; -tree ffecom_f2c_ftnlen_type_node; -tree ffecom_f2c_ftnlen_zero_node; -tree ffecom_f2c_ftnlen_one_node; -tree ffecom_f2c_ftnlen_two_node; -tree ffecom_f2c_ptr_to_ftnlen_type_node; -tree ffecom_f2c_ftnint_type_node; -tree ffecom_f2c_ptr_to_ftnint_type_node; -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Simple definitions and enumerations. */ - -#ifndef FFECOM_sizeMAXSTACKITEM -#define FFECOM_sizeMAXSTACKITEM 32*1024 /* Keep user-declared things - larger than this # bytes - off stack if possible. */ -#endif - -/* For systems that have large enough stacks, they should define - this to 0, and here, for ease of use later on, we just undefine - it if it is 0. */ - -#if FFECOM_sizeMAXSTACKITEM == 0 -#undef FFECOM_sizeMAXSTACKITEM -#endif - -typedef enum - { - FFECOM_rttypeVOID_, - FFECOM_rttypeVOIDSTAR_, /* C's `void *' type. */ - FFECOM_rttypeFTNINT_, /* f2c's `ftnint' type. */ - FFECOM_rttypeINTEGER_, /* f2c's `integer' type. */ - FFECOM_rttypeLONGINT_, /* f2c's `longint' type. */ - FFECOM_rttypeLOGICAL_, /* f2c's `logical' type. */ - FFECOM_rttypeREAL_F2C_, /* f2c's `real' returned as `double'. */ - FFECOM_rttypeREAL_GNU_, /* `real' returned as such. */ - FFECOM_rttypeCOMPLEX_F2C_, /* f2c's `complex' returned via 1st arg. */ - FFECOM_rttypeCOMPLEX_GNU_, /* f2c's `complex' returned directly. */ - FFECOM_rttypeDOUBLE_, /* C's `double' type. */ - FFECOM_rttypeDOUBLEREAL_, /* f2c's `doublereal' type. */ - FFECOM_rttypeDBLCMPLX_F2C_, /* f2c's `doublecomplex' returned via 1st arg. */ - FFECOM_rttypeDBLCMPLX_GNU_, /* f2c's `doublecomplex' returned directly. */ - FFECOM_rttypeCHARACTER_, /* f2c `char *'/`ftnlen' pair. */ - FFECOM_rttype_ - } ffecomRttype_; - -/* Internal typedefs. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -typedef struct _ffecom_concat_list_ ffecomConcatList_; -typedef struct _ffecom_temp_ *ffecomTemp_; -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Private include files. */ - - -/* Internal structure definitions. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -struct _ffecom_concat_list_ - { - ffebld *exprs; - int count; - int max; - ffetargetCharacterSize minlen; - ffetargetCharacterSize maxlen; - }; - -struct _ffecom_temp_ - { - ffecomTemp_ next; - tree type; /* Base type (w/o size/array applied). */ - tree t; - ffetargetCharacterSize size; - int elements; - bool in_use; - bool auto_pop; - }; - -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Static functions (internal). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree ffecom_arglist_expr_ (char *argstring, ffebld args); -static tree ffecom_widest_expr_type_ (ffebld list); -static bool ffecom_overlap_ (tree dest_decl, tree dest_offset, - tree dest_size, tree source_tree, - ffebld source, bool scalar_arg); -static bool ffecom_args_overlapping_ (tree dest_tree, ffebld dest, - tree args, tree callee_commons, - bool scalar_args); -static tree ffecom_build_f2c_string_ (int i, char *s); -static tree ffecom_call_ (tree fn, ffeinfoKindtype kt, - bool is_f2c_complex, tree type, - tree args, tree dest_tree, - ffebld dest, bool *dest_used, - tree callee_commons, bool scalar_args); -static tree ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, - bool is_f2c_complex, tree type, - ffebld left, ffebld right, - tree dest_tree, ffebld dest, - bool *dest_used, tree callee_commons, - bool scalar_args); -static void ffecom_char_args_x_ (tree *xitem, tree *length, - ffebld expr, bool with_null); -static tree ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy); -static tree ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s); -static ffecomConcatList_ - ffecom_concat_list_gather_ (ffecomConcatList_ catlist, - ffebld expr, - ffetargetCharacterSize max); -static void ffecom_concat_list_kill_ (ffecomConcatList_ catlist); -static ffecomConcatList_ ffecom_concat_list_new_ (ffebld expr, - ffetargetCharacterSize max); -static void ffecom_debug_kludge_ (tree aggr, char *aggr_type, ffesymbol member, - tree member_type, ffetargetOffset offset); -static void ffecom_do_entry_ (ffesymbol fn, int entrynum); -static tree ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest, - bool *dest_used, bool assignp, bool widenp); -static tree ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, - ffebld dest, bool *dest_used); -static tree ffecom_expr_power_integer_ (ffebld left, ffebld right); -static void ffecom_expr_transform_ (ffebld expr); -static void ffecom_f2c_make_type_ (tree *type, int tcode, char *name); -static void ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size, - int code); -static ffeglobal ffecom_finish_global_ (ffeglobal global); -static ffesymbol ffecom_finish_symbol_transform_ (ffesymbol s); -static tree ffecom_get_appended_identifier_ (char us, char *text); -static tree ffecom_get_external_identifier_ (ffesymbol s); -static tree ffecom_get_identifier_ (char *text); -static tree ffecom_gen_sfuncdef_ (ffesymbol s, - ffeinfoBasictype bt, - ffeinfoKindtype kt); -static char *ffecom_gfrt_args_ (ffecomGfrt ix); -static tree ffecom_gfrt_tree_ (ffecomGfrt ix); -static tree ffecom_init_zero_ (tree decl); -static tree ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg, - tree *maybe_tree); -static tree ffecom_intrinsic_len_ (ffebld expr); -static void ffecom_let_char_ (tree dest_tree, - tree dest_length, - ffetargetCharacterSize dest_size, - ffebld source); -static void ffecom_make_gfrt_ (ffecomGfrt ix); -static void ffecom_member_phase1_ (ffestorag mst, ffestorag st); -#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING -static void ffecom_member_phase2_ (ffestorag mst, ffestorag st); -#endif -static void ffecom_push_dummy_decls_ (ffebld dumlist, - bool stmtfunc); -static void ffecom_start_progunit_ (void); -static ffesymbol ffecom_sym_transform_ (ffesymbol s); -static ffesymbol ffecom_sym_transform_assign_ (ffesymbol s); -static void ffecom_transform_common_ (ffesymbol s); -static void ffecom_transform_equiv_ (ffestorag st); -static tree ffecom_transform_namelist_ (ffesymbol s); -static void ffecom_tree_canonize_ptr_ (tree *decl, tree *offset, - tree t); -static void ffecom_tree_canonize_ref_ (tree *decl, tree *offset, - tree *size, tree tree); -static tree ffecom_tree_divide_ (tree tree_type, tree left, tree right, - tree dest_tree, ffebld dest, - bool *dest_used); -static tree ffecom_type_localvar_ (ffesymbol s, - ffeinfoBasictype bt, - ffeinfoKindtype kt); -static tree ffecom_type_namelist_ (void); -#if 0 -static tree ffecom_type_permanent_copy_ (tree t); -#endif -static tree ffecom_type_vardesc_ (void); -static tree ffecom_vardesc_ (ffebld expr); -static tree ffecom_vardesc_array_ (ffesymbol s); -static tree ffecom_vardesc_dims_ (ffesymbol s); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* These are static functions that parallel those found in the C front - end and thus have the same names. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void bison_rule_compstmt_ (void); -static void bison_rule_pushlevel_ (void); -static tree builtin_function (char *name, tree type, - enum built_in_function function_code, - char *library_name); -static int duplicate_decls (tree newdecl, tree olddecl); -static void finish_decl (tree decl, tree init, bool is_top_level); -static void finish_function (int nested); -static char *lang_printable_name (tree decl, int v); -static tree lookup_name_current_level (tree name); -static struct binding_level *make_binding_level (void); -static void pop_f_function_context (void); -static void push_f_function_context (void); -static void push_parm_decl (tree parm); -static tree pushdecl_top_level (tree decl); -static tree storedecls (tree decls); -static void store_parm_decls (int is_main_program); -static tree start_decl (tree decl, bool is_top_level); -static void start_function (tree name, tree type, int nested, int public); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -#if FFECOM_GCC_INCLUDE -static void ffecom_file_ (char *name); -static void ffecom_initialize_char_syntax_ (void); -static void ffecom_close_include_ (FILE *f); -static int ffecom_decode_include_option_ (char *spec); -static FILE *ffecom_open_include_ (char *name, ffewhereLine l, - ffewhereColumn c); -#endif /* FFECOM_GCC_INCLUDE */ - -/* Static objects accessed by functions in this module. */ - -static ffesymbol ffecom_primary_entry_ = NULL; -static ffesymbol ffecom_nested_entry_ = NULL; -static ffeinfoKind ffecom_primary_entry_kind_; -static bool ffecom_primary_entry_is_proc_; -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree ffecom_outer_function_decl_; -static tree ffecom_previous_function_decl_; -static tree ffecom_which_entrypoint_decl_; -static ffecomTemp_ ffecom_latest_temp_; -static int ffecom_pending_calls_ = 0; -static tree ffecom_float_zero_ = NULL_TREE; -static tree ffecom_float_half_ = NULL_TREE; -static tree ffecom_double_zero_ = NULL_TREE; -static tree ffecom_double_half_ = NULL_TREE; -static tree ffecom_func_result_;/* For functions. */ -static tree ffecom_func_length_;/* For CHARACTER fns. */ -static ffebld ffecom_list_blockdata_; -static ffebld ffecom_list_common_; -static ffebld ffecom_master_arglist_; -static ffeinfoBasictype ffecom_master_bt_; -static ffeinfoKindtype ffecom_master_kt_; -static ffetargetCharacterSize ffecom_master_size_; -static int ffecom_num_fns_ = 0; -static int ffecom_num_entrypoints_ = 0; -static bool ffecom_is_altreturning_ = FALSE; -static tree ffecom_multi_type_node_; -static tree ffecom_multi_retval_; -static tree - ffecom_multi_fields_[FFEINFO_basictype][FFEINFO_kindtype]; -static bool ffecom_member_namelisted_; /* _member_phase1_ namelisted? */ -static bool ffecom_doing_entry_ = FALSE; -static bool ffecom_transform_only_dummies_ = FALSE; - -/* Holds pointer-to-function expressions. */ - -static tree ffecom_gfrt_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NULL_TREE, -#include "com-rt.def" -#undef DEFGFRT -}; - -/* Holds the external names of the functions. */ - -static char *ffecom_gfrt_name_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) NAME, -#include "com-rt.def" -#undef DEFGFRT -}; - -/* Whether the function returns. */ - -static bool ffecom_gfrt_volatile_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) VOLATILE, -#include "com-rt.def" -#undef DEFGFRT -}; - -/* Whether the function returns type complex. */ - -static bool ffecom_gfrt_complex_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) COMPLEX, -#include "com-rt.def" -#undef DEFGFRT -}; - -/* Type code for the function return value. */ - -static ffecomRttype_ ffecom_gfrt_type_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) TYPE, -#include "com-rt.def" -#undef DEFGFRT -}; - -/* String of codes for the function's arguments. */ - -static char *ffecom_gfrt_argstring_[FFECOM_gfrt] -= -{ -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) ARGS, -#include "com-rt.def" -#undef DEFGFRT -}; -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Internal macros. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - -/* 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. */ - -/* NOTE: g77 currently doesn't use these; see setting of sizetype and - change that if you need to. -- jcb 09/01/91. */ - -#define ffecom_concat_list_count_(catlist) ((catlist).count) -#define ffecom_concat_list_expr_(catlist,i) ((catlist).exprs[(i)]) -#define ffecom_concat_list_maxlen_(catlist) ((catlist).maxlen) -#define ffecom_concat_list_minlen_(catlist) ((catlist).minlen) - -#define ffecom_start_compstmt_ bison_rule_pushlevel_ -#define ffecom_end_compstmt_ bison_rule_compstmt_ - -#define ffecom_char_args_(i,l,e) ffecom_char_args_x_((i),(l),(e),FALSE) -#define ffecom_char_args_with_null_(i,l,e) ffecom_char_args_x_((i),(l),(e),TRUE) - -/* For each binding contour we allocate a binding_level structure - * which records the names defined in that contour. - * Contours include: - * 0) the global one - * 1) one for each function definition, - * where internal declarations of the parameters appear. - * - * The current meaning of a name can be found by searching the levels from - * the current one out to the global one. - */ - -/* Note that the information in the `names' component of the global contour - is duplicated in the IDENTIFIER_GLOBAL_VALUEs of all identifiers. */ - -struct binding_level - { - /* A chain of _DECL nodes for all variables, constants, functions, and - typedef types. These are in the reverse of the order supplied. */ - tree names; - - /* For each level (except not the global one), a chain of BLOCK nodes for - all the levels that were entered and exited one level down. */ - tree blocks; - - /* The BLOCK node for this level, if one has been preallocated. If 0, the - BLOCK is allocated (if needed) when the level is popped. */ - tree this_block; - - /* The binding level which this one is contained in (inherits from). */ - struct binding_level *level_chain; - }; - -#define NULL_BINDING_LEVEL (struct binding_level *) NULL - -/* The binding level currently in effect. */ - -static struct binding_level *current_binding_level; - -/* A chain of binding_level structures awaiting reuse. */ - -static struct binding_level *free_binding_level; - -/* The outermost binding level, for names of file scope. - This is created when the compiler is started and exists - through the entire run. */ - -static struct binding_level *global_binding_level; - -/* Binding level structures are initialized by copying this one. */ - -static struct binding_level clear_binding_level -= -{NULL, NULL, NULL, NULL_BINDING_LEVEL}; - -/* Language-dependent contents of an identifier. */ - -struct lang_identifier - { - struct tree_identifier ignore; - tree global_value, local_value, label_value; - bool invented; - }; - -/* Macros for access to language-specific slots in an identifier. */ -/* Each of these slots contains a DECL node or null. */ - -/* This represents the value which the identifier has in the - file-scope namespace. */ -#define IDENTIFIER_GLOBAL_VALUE(NODE) \ - (((struct lang_identifier *)(NODE))->global_value) -/* This represents the value which the identifier has in the current - scope. */ -#define IDENTIFIER_LOCAL_VALUE(NODE) \ - (((struct lang_identifier *)(NODE))->local_value) -/* This represents the value which the identifier has as a label in - the current label scope. */ -#define IDENTIFIER_LABEL_VALUE(NODE) \ - (((struct lang_identifier *)(NODE))->label_value) -/* This is nonzero if the identifier was "made up" by g77 code. */ -#define IDENTIFIER_INVENTED(NODE) \ - (((struct lang_identifier *)(NODE))->invented) - -/* In identifiers, C uses the following fields in a special way: - TREE_PUBLIC to record that there was a previous local extern decl. - TREE_USED to record that such a decl was used. - TREE_ADDRESSABLE to record that the address of such a decl was used. */ - -/* A list (chain of TREE_LIST nodes) of all LABEL_DECLs in the function - that have names. Here so we can clear out their names' definitions - at the end of the function. */ - -static tree named_labels; - -/* A list of LABEL_DECLs from outer contexts that are currently shadowed. */ - -static tree shadowed_labels; - -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - - -/* This is like gcc's stabilize_reference -- in fact, most of the code - comes from that -- but it handles the situation where the reference - is going to have its subparts picked at, and it shouldn't change - (or trigger extra invocations of functions in the subtrees) due to - this. save_expr is a bit overzealous, because we don't need the - entire thing calculated and saved like a temp. So, for DECLs, no - change is needed, because these are stable aggregates, and ARRAY_REF - and such might well be stable too, but for things like calculations, - we do need to calculate a snapshot of a value before picking at it. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_stabilize_aggregate_ (tree ref) -{ - tree result; - enum tree_code code = TREE_CODE (ref); - - switch (code) - { - case VAR_DECL: - case PARM_DECL: - case RESULT_DECL: - /* No action is needed in this case. */ - return ref; - - case NOP_EXPR: - case CONVERT_EXPR: - case FLOAT_EXPR: - case FIX_TRUNC_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FIX_CEIL_EXPR: - result = build_nt (code, stabilize_reference (TREE_OPERAND (ref, 0))); - break; - - case INDIRECT_REF: - result = build_nt (INDIRECT_REF, - stabilize_reference_1 (TREE_OPERAND (ref, 0))); - break; - - case COMPONENT_REF: - result = build_nt (COMPONENT_REF, - stabilize_reference (TREE_OPERAND (ref, 0)), - TREE_OPERAND (ref, 1)); - break; - - case BIT_FIELD_REF: - result = build_nt (BIT_FIELD_REF, - stabilize_reference (TREE_OPERAND (ref, 0)), - stabilize_reference_1 (TREE_OPERAND (ref, 1)), - stabilize_reference_1 (TREE_OPERAND (ref, 2))); - break; - - case ARRAY_REF: - result = build_nt (ARRAY_REF, - stabilize_reference (TREE_OPERAND (ref, 0)), - stabilize_reference_1 (TREE_OPERAND (ref, 1))); - break; - - case COMPOUND_EXPR: - result = build_nt (COMPOUND_EXPR, - stabilize_reference_1 (TREE_OPERAND (ref, 0)), - stabilize_reference (TREE_OPERAND (ref, 1))); - break; - - case RTL_EXPR: - result = build1 (INDIRECT_REF, TREE_TYPE (ref), - save_expr (build1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (ref)), - ref))); - break; - - - default: - return save_expr (ref); - - case ERROR_MARK: - return error_mark_node; - } - - TREE_TYPE (result) = TREE_TYPE (ref); - TREE_READONLY (result) = TREE_READONLY (ref); - TREE_SIDE_EFFECTS (result) = TREE_SIDE_EFFECTS (ref); - TREE_THIS_VOLATILE (result) = TREE_THIS_VOLATILE (ref); - TREE_RAISES (result) = TREE_RAISES (ref); - - return result; -} -#endif - -/* A rip-off of gcc's convert.c convert_to_complex function, - reworked to handle complex implemented as C structures - (RECORD_TYPE with two fields, real and imaginary `r' and `i'). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_convert_to_complex_ (tree type, tree expr) -{ - register enum tree_code form = TREE_CODE (TREE_TYPE (expr)); - tree subtype; - - assert (TREE_CODE (type) == RECORD_TYPE); - - subtype = TREE_TYPE (TYPE_FIELDS (type)); - - if (form == REAL_TYPE || form == INTEGER_TYPE || form == ENUMERAL_TYPE) - { - expr = convert (subtype, expr); - return ffecom_2 (COMPLEX_EXPR, type, expr, - convert (subtype, integer_zero_node)); - } - - if (form == RECORD_TYPE) - { - tree elt_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))); - if (TYPE_MAIN_VARIANT (elt_type) == TYPE_MAIN_VARIANT (subtype)) - return expr; - else - { - expr = save_expr (expr); - return ffecom_2 (COMPLEX_EXPR, - type, - convert (subtype, - ffecom_1 (REALPART_EXPR, - TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))), - expr)), - convert (subtype, - ffecom_1 (IMAGPART_EXPR, - TREE_TYPE (TYPE_FIELDS (TREE_TYPE (expr))), - expr))); - } - } - - if (form == POINTER_TYPE || form == REFERENCE_TYPE) - error ("pointer value used where a complex was expected"); - else - error ("aggregate value used where a complex was expected"); - - return ffecom_2 (COMPLEX_EXPR, type, - convert (subtype, integer_zero_node), - convert (subtype, integer_zero_node)); -} -#endif - -/* Like gcc's convert(), but crashes if widening might happen. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_convert_narrow_ (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (e) - || TREE_CODE (e) == ERROR_MARK) - return e; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) - return fold (build1 (NOP_EXPR, type, e)); - if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK - || code == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE) - { - assert ("void value not ignored as it ought to be" == NULL); - return error_mark_node; - } - assert (code != VOID_TYPE); - if ((code != RECORD_TYPE) - && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE)) - assert ("converting COMPLEX to REAL" == NULL); - assert (code != ENUMERAL_TYPE); - if (code == INTEGER_TYPE) - { - assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE - && TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e))) - || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE - && (TYPE_PRECISION (type) - == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e)))))); - return fold (convert_to_integer (type, e)); - } - if (code == POINTER_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE); - return fold (convert_to_pointer (type, e)); - } - if (code == REAL_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE); - assert (TYPE_PRECISION (type) <= TYPE_PRECISION (TREE_TYPE (e))); - return fold (convert_to_real (type, e)); - } - if (code == COMPLEX_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE); - assert (TYPE_PRECISION (TREE_TYPE (type)) <= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e)))); - return fold (convert_to_complex (type, e)); - } - if (code == RECORD_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE); - /* Check that at least the first field name agrees. */ - assert (DECL_NAME (TYPE_FIELDS (type)) - == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e)))); - assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type))) - <= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))))); - if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type))) - == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))))) - return e; - return fold (ffecom_convert_to_complex_ (type, e)); - } - - assert ("conversion to non-scalar type requested" == NULL); - return error_mark_node; -} -#endif - -/* Like gcc's convert(), but crashes if narrowing might happen. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_convert_widen_ (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (e) - || TREE_CODE (e) == ERROR_MARK) - return e; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) - return fold (build1 (NOP_EXPR, type, e)); - if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK - || code == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE) - { - assert ("void value not ignored as it ought to be" == NULL); - return error_mark_node; - } - assert (code != VOID_TYPE); - if ((code != RECORD_TYPE) - && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE)) - assert ("narrowing COMPLEX to REAL" == NULL); - assert (code != ENUMERAL_TYPE); - if (code == INTEGER_TYPE) - { - assert ((TREE_CODE (TREE_TYPE (e)) == INTEGER_TYPE - && TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e))) - || (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE - && (TYPE_PRECISION (type) - == TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (e)))))); - return fold (convert_to_integer (type, e)); - } - if (code == POINTER_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == POINTER_TYPE); - return fold (convert_to_pointer (type, e)); - } - if (code == REAL_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == REAL_TYPE); - assert (TYPE_PRECISION (type) >= TYPE_PRECISION (TREE_TYPE (e))); - return fold (convert_to_real (type, e)); - } - if (code == COMPLEX_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == COMPLEX_TYPE); - assert (TYPE_PRECISION (TREE_TYPE (type)) >= TYPE_PRECISION (TREE_TYPE (TREE_TYPE (e)))); - return fold (convert_to_complex (type, e)); - } - if (code == RECORD_TYPE) - { - assert (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE); - /* Check that at least the first field name agrees. */ - assert (DECL_NAME (TYPE_FIELDS (type)) - == DECL_NAME (TYPE_FIELDS (TREE_TYPE (e)))); - assert (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type))) - >= TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))))); - if (TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (type))) - == TYPE_PRECISION (TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))))) - return e; - return fold (ffecom_convert_to_complex_ (type, e)); - } - - assert ("conversion to non-scalar type requested" == NULL); - return error_mark_node; -} -#endif - -/* Handles making a COMPLEX type, either the standard - (but buggy?) gbe way, or the safer (but less elegant?) - f2c way. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_make_complex_type_ (tree subtype) -{ - tree type; - tree realfield; - tree imagfield; - - if (ffe_is_emulate_complex ()) - { - type = make_node (RECORD_TYPE); - realfield = ffecom_decl_field (type, NULL_TREE, "r", subtype); - imagfield = ffecom_decl_field (type, realfield, "i", subtype); - TYPE_FIELDS (type) = realfield; - layout_type (type); - } - else - { - type = make_node (COMPLEX_TYPE); - TREE_TYPE (type) = subtype; - layout_type (type); - } - - return type; -} -#endif - -/* Chooses either the gbe or the f2c way to build a - complex constant. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_build_complex_constant_ (tree type, tree realpart, tree imagpart) -{ - tree bothparts; - - if (ffe_is_emulate_complex ()) - { - bothparts = build_tree_list (TYPE_FIELDS (type), realpart); - TREE_CHAIN (bothparts) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), imagpart); - bothparts = build (CONSTRUCTOR, type, NULL_TREE, bothparts); - } - else - { - bothparts = build_complex (type, realpart, imagpart); - } - - return bothparts; -} -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_arglist_expr_ (char *c, ffebld expr) -{ - tree list; - tree *plist = &list; - tree trail = NULL_TREE; /* Append char length args here. */ - tree *ptrail = &trail; - tree length; - ffebld exprh; - tree item; - bool ptr = FALSE; - tree wanted = NULL_TREE; - static char zed[] = "0"; - - if (c == NULL) - c = &zed[0]; - - while (expr != NULL) - { - if (*c != '\0') - { - ptr = FALSE; - if (*c == '&') - { - ptr = TRUE; - ++c; - } - switch (*(c++)) - { - case '\0': - ptr = TRUE; - wanted = NULL_TREE; - break; - - case 'a': - assert (ptr); - wanted = NULL_TREE; - break; - - case 'c': - wanted = ffecom_f2c_complex_type_node; - break; - - case 'd': - wanted = ffecom_f2c_doublereal_type_node; - break; - - case 'e': - wanted = ffecom_f2c_doublecomplex_type_node; - break; - - case 'f': - wanted = ffecom_f2c_real_type_node; - break; - - case 'i': - wanted = ffecom_f2c_integer_type_node; - break; - - case 'j': - wanted = ffecom_f2c_longint_type_node; - break; - - default: - assert ("bad argstring code" == NULL); - wanted = NULL_TREE; - break; - } - } - - exprh = ffebld_head (expr); - if (exprh == NULL) - wanted = NULL_TREE; - - if ((wanted == NULL_TREE) - || (ptr - && (TYPE_MODE - (ffecom_tree_type[ffeinfo_basictype (ffebld_info (exprh))] - [ffeinfo_kindtype (ffebld_info (exprh))]) - == TYPE_MODE (wanted)))) - *plist - = build_tree_list (NULL_TREE, - ffecom_arg_ptr_to_expr (exprh, - &length)); - else - { - item = ffecom_arg_expr (exprh, &length); - item = ffecom_convert_widen_ (wanted, item); - if (ptr) - { - item = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (item)), - item); - } - *plist - = build_tree_list (NULL_TREE, - item); - } - - plist = &TREE_CHAIN (*plist); - expr = ffebld_trail (expr); - if (length != NULL_TREE) - { - *ptrail = build_tree_list (NULL_TREE, length); - ptrail = &TREE_CHAIN (*ptrail); - } - } - - /* We've run out of args in the call; if the implementation expects - more, supply null pointers for them, which the implementation can - check to see if an arg was omitted. */ - - while (*c != '\0' && *c != '0') - { - if (*c == '&') - ++c; - else - assert ("missing arg to run-time routine!" == NULL); - - switch (*(c++)) - { - case '\0': - case 'a': - case 'c': - case 'd': - case 'e': - case 'f': - case 'i': - case 'j': - break; - - default: - assert ("bad arg string code" == NULL); - break; - } - *plist - = build_tree_list (NULL_TREE, - null_pointer_node); - plist = &TREE_CHAIN (*plist); - } - - *plist = trail; - - return list; -} -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_widest_expr_type_ (ffebld list) -{ - ffebld item; - ffebld widest = NULL; - ffetype type; - ffetype widest_type = NULL; - tree t; - - for (; list != NULL; list = ffebld_trail (list)) - { - item = ffebld_head (list); - if (item == NULL) - continue; - if ((widest != NULL) - && (ffeinfo_basictype (ffebld_info (item)) - != ffeinfo_basictype (ffebld_info (widest)))) - continue; - type = ffeinfo_type (ffeinfo_basictype (ffebld_info (item)), - ffeinfo_kindtype (ffebld_info (item))); - if ((widest == FFEINFO_kindtypeNONE) - || (ffetype_size (type) - > ffetype_size (widest_type))) - { - widest = item; - widest_type = type; - } - } - - assert (widest != NULL); - t = ffecom_tree_type[ffeinfo_basictype (ffebld_info (widest))] - [ffeinfo_kindtype (ffebld_info (widest))]; - assert (t != NULL_TREE); - return t; -} -#endif - -/* Check whether dest and source might overlap. ffebld versions of these - might or might not be passed, will be NULL if not. - - The test is really whether source_tree is modifiable and, if modified, - might overlap destination such that the value(s) in the destination might - change before it is finally modified. dest_* are the canonized - destination itself. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static bool -ffecom_overlap_ (tree dest_decl, tree dest_offset, tree dest_size, - tree source_tree, ffebld source UNUSED, - bool scalar_arg) -{ - tree source_decl; - tree source_offset; - tree source_size; - tree t; - - if (source_tree == NULL_TREE) - return FALSE; - - switch (TREE_CODE (source_tree)) - { - case ERROR_MARK: - case IDENTIFIER_NODE: - case INTEGER_CST: - case REAL_CST: - case COMPLEX_CST: - case STRING_CST: - case CONST_DECL: - case VAR_DECL: - case RESULT_DECL: - case FIELD_DECL: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case TRUNC_MOD_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case RDIV_EXPR: - case EXACT_DIV_EXPR: - case FIX_TRUNC_EXPR: - case FIX_CEIL_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FLOAT_EXPR: - case EXPON_EXPR: - case NEGATE_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case ABS_EXPR: - case FFS_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case LROTATE_EXPR: - case RROTATE_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_NOT_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case TRUTH_NOT_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case COMPLEX_EXPR: - case CONJ_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - case LABEL_EXPR: - case COMPONENT_REF: - return FALSE; - - case COMPOUND_EXPR: - return ffecom_overlap_ (dest_decl, dest_offset, dest_size, - TREE_OPERAND (source_tree, 1), NULL, - scalar_arg); - - case MODIFY_EXPR: - return ffecom_overlap_ (dest_decl, dest_offset, dest_size, - TREE_OPERAND (source_tree, 0), NULL, - scalar_arg); - - case CONVERT_EXPR: - case NOP_EXPR: - case NON_LVALUE_EXPR: - case PLUS_EXPR: - if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE) - return TRUE; - - ffecom_tree_canonize_ptr_ (&source_decl, &source_offset, - source_tree); - source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree))); - break; - - case COND_EXPR: - return - ffecom_overlap_ (dest_decl, dest_offset, dest_size, - TREE_OPERAND (source_tree, 1), NULL, - scalar_arg) - || ffecom_overlap_ (dest_decl, dest_offset, dest_size, - TREE_OPERAND (source_tree, 2), NULL, - scalar_arg); - - - case ADDR_EXPR: - ffecom_tree_canonize_ref_ (&source_decl, &source_offset, - &source_size, - TREE_OPERAND (source_tree, 0)); - break; - - case PARM_DECL: - if (TREE_CODE (TREE_TYPE (source_tree)) != POINTER_TYPE) - return TRUE; - - source_decl = source_tree; - source_offset = size_zero_node; - source_size = TYPE_SIZE (TREE_TYPE (TREE_TYPE (source_tree))); - break; - - case SAVE_EXPR: - case REFERENCE_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case INDIRECT_REF: - case ARRAY_REF: - case CALL_EXPR: - default: - return TRUE; - } - - /* Come here when source_decl, source_offset, and source_size filled - in appropriately. */ - - if (source_decl == NULL_TREE) - return FALSE; /* No decl involved, so no overlap. */ - - if (source_decl != dest_decl) - return FALSE; /* Different decl, no overlap. */ - - if (TREE_CODE (dest_size) == ERROR_MARK) - return TRUE; /* Assignment into entire assumed-size - array? Shouldn't happen.... */ - - t = ffecom_2 (LE_EXPR, integer_type_node, - ffecom_2 (PLUS_EXPR, TREE_TYPE (dest_offset), - dest_offset, - convert (TREE_TYPE (dest_offset), - dest_size)), - convert (TREE_TYPE (dest_offset), - source_offset)); - - if (integer_onep (t)) - return FALSE; /* Destination precedes source. */ - - if (!scalar_arg - || (source_size == NULL_TREE) - || (TREE_CODE (source_size) == ERROR_MARK) - || integer_zerop (source_size)) - return TRUE; /* No way to tell if dest follows source. */ - - t = ffecom_2 (LE_EXPR, integer_type_node, - ffecom_2 (PLUS_EXPR, TREE_TYPE (source_offset), - source_offset, - convert (TREE_TYPE (source_offset), - source_size)), - convert (TREE_TYPE (source_offset), - dest_offset)); - - if (integer_onep (t)) - return FALSE; /* Destination follows source. */ - - return TRUE; /* Destination and source overlap. */ -} -#endif - -/* Check whether dest might overlap any of a list of arguments or is - in a COMMON area the callee might know about (and thus modify). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static bool -ffecom_args_overlapping_ (tree dest_tree, ffebld dest UNUSED, - tree args, tree callee_commons, - bool scalar_args) -{ - tree arg; - tree dest_decl; - tree dest_offset; - tree dest_size; - - ffecom_tree_canonize_ref_ (&dest_decl, &dest_offset, &dest_size, - dest_tree); - - if (dest_decl == NULL_TREE) - return FALSE; /* Seems unlikely! */ - - /* If the decl cannot be determined reliably, or if its in COMMON - and the callee isn't known to not futz with COMMON via other - means, overlap might happen. */ - - if ((TREE_CODE (dest_decl) == ERROR_MARK) - || ((callee_commons != NULL_TREE) - && TREE_PUBLIC (dest_decl))) - return TRUE; - - for (; args != NULL_TREE; args = TREE_CHAIN (args)) - { - if (((arg = TREE_VALUE (args)) != NULL_TREE) - && ffecom_overlap_ (dest_decl, dest_offset, dest_size, - arg, NULL, scalar_args)) - return TRUE; - } - - return FALSE; -} -#endif - -/* Build a string for a variable name as used by NAMELIST. This means that - if we're using the f2c library, we build an uppercase string, since - f2c does this. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_build_f2c_string_ (int i, char *s) -{ - if (!ffe_is_f2c_library ()) - return build_string (i, s); - - { - char *tmp; - char *p; - char *q; - char space[34]; - tree t; - - if (((size_t) i) > ARRAY_SIZE (space)) - tmp = malloc_new_ks (malloc_pool_image (), "f2c_string", i); - else - tmp = &space[0]; - - for (p = s, q = tmp; *p != '\0'; ++p, ++q) - *q = ffesrc_toupper (*p); - *q = '\0'; - - t = build_string (i, tmp); - - if (((size_t) i) > ARRAY_SIZE (space)) - malloc_kill_ks (malloc_pool_image (), tmp, i); - - return t; - } -} - -#endif -/* Returns CALL_EXPR or equivalent with given type (pass NULL_TREE for - type to just get whatever the function returns), handling the - f2c value-returning convention, if required, by prepending - to the arglist a pointer to a temporary to receive the return value. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_call_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex, - tree type, tree args, tree dest_tree, - ffebld dest, bool *dest_used, tree callee_commons, - bool scalar_args) -{ - tree item; - tree tempvar; - - if (dest_used != NULL) - *dest_used = FALSE; - - if (is_f2c_complex) - { - if ((dest_used == NULL) - || (dest == NULL) - || (ffeinfo_basictype (ffebld_info (dest)) - != FFEINFO_basictypeCOMPLEX) - || (ffeinfo_kindtype (ffebld_info (dest)) != kt) - || ((type != NULL_TREE) && (TREE_TYPE (dest_tree) != type)) - || ffecom_args_overlapping_ (dest_tree, dest, args, - callee_commons, - scalar_args)) - { - tempvar = ffecom_push_tempvar (ffecom_tree_type - [FFEINFO_basictypeCOMPLEX][kt], - FFETARGET_charactersizeNONE, - -1, TRUE); - } - else - { - *dest_used = TRUE; - tempvar = dest_tree; - type = NULL_TREE; - } - - item - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (tempvar)), - tempvar)); - TREE_CHAIN (item) = args; - - item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn, - item, NULL_TREE); - - if (tempvar != dest_tree) - item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, tempvar); - } - else - item = ffecom_3s (CALL_EXPR, TREE_TYPE (TREE_TYPE (TREE_TYPE (fn))), fn, - args, NULL_TREE); - - if ((type != NULL_TREE) && (TREE_TYPE (item) != type)) - item = ffecom_convert_narrow_ (type, item); - - return item; -} -#endif - -/* Given two arguments, transform them and make a call to the given - function via ffecom_call_. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_call_binop_ (tree fn, ffeinfoKindtype kt, bool is_f2c_complex, - tree type, ffebld left, ffebld right, - tree dest_tree, ffebld dest, bool *dest_used, - tree callee_commons, bool scalar_args) -{ - tree left_tree; - tree right_tree; - tree left_length; - tree right_length; - - ffecom_push_calltemps (); - left_tree = ffecom_arg_ptr_to_expr (left, &left_length); - right_tree = ffecom_arg_ptr_to_expr (right, &right_length); - ffecom_pop_calltemps (); - - left_tree = build_tree_list (NULL_TREE, left_tree); - right_tree = build_tree_list (NULL_TREE, right_tree); - TREE_CHAIN (left_tree) = right_tree; - - if (left_length != NULL_TREE) - { - left_length = build_tree_list (NULL_TREE, left_length); - TREE_CHAIN (right_tree) = left_length; - } - - if (right_length != NULL_TREE) - { - right_length = build_tree_list (NULL_TREE, right_length); - if (left_length != NULL_TREE) - TREE_CHAIN (left_length) = right_length; - else - TREE_CHAIN (right_tree) = right_length; - } - - return ffecom_call_ (fn, kt, is_f2c_complex, type, left_tree, - dest_tree, dest, dest_used, callee_commons, - scalar_args); -} -#endif - -/* ffecom_char_args_x_ -- Return ptr/length args for char subexpression - - tree ptr_arg; - tree length_arg; - ffebld expr; - bool with_null; - ffecom_char_args_x_(&ptr_arg,&length_arg,expr,with_null); - - Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF - subexpressions by constructing the appropriate trees for the ptr-to- - character-text and length-of-character-text arguments in a calling - sequence. - - Note that if with_null is TRUE, and the expression is an opCONTER, - a null byte is appended to the string. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_char_args_x_ (tree *xitem, tree *length, ffebld expr, bool with_null) -{ - tree item; - tree high; - ffetargetCharacter1 val; - ffetargetCharacterSize newlen; - - switch (ffebld_op (expr)) - { - case FFEBLD_opCONTER: - val = ffebld_constant_character1 (ffebld_conter (expr)); - newlen = ffetarget_length_character1 (val); - if (with_null) - { - if (newlen != 0) - ++newlen; /* begin FFETARGET-NULL-KLUDGE. */ - } - *length = build_int_2 (newlen, 0); - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - high = build_int_2 (newlen, 0); - TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node; - item = build_string (newlen, /* end FFETARGET-NULL-KLUDGE. */ - ffetarget_text_character1 (val)); - TREE_TYPE (item) - = build_type_variant - (build_array_type - (char_type_node, - build_range_type - (ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - high)), - 1, 0); - TREE_CONSTANT (item) = 1; - TREE_STATIC (item) = 1; - item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)), - item); - break; - - case FFEBLD_opSYMTER: - { - ffesymbol s = ffebld_symter (expr); - - item = ffesymbol_hook (s).decl_tree; - if (item == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - item = ffesymbol_hook (s).decl_tree; - } - if (ffesymbol_kind (s) == FFEINFO_kindENTITY) - { - if (ffesymbol_size (s) == FFETARGET_charactersizeNONE) - *length = ffesymbol_hook (s).length_tree; - else - { - *length = build_int_2 (ffesymbol_size (s), 0); - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - } - } - else if (item == error_mark_node) - *length = error_mark_node; - else /* FFEINFO_kindFUNCTION: */ - *length = NULL_TREE; - if (!ffesymbol_hook (s).addr - && (item != error_mark_node)) - item = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (item)), - item); - } - break; - - case FFEBLD_opARRAYREF: - { - ffebld dims[FFECOM_dimensionsMAX]; - tree array; - int i; - - ffecom_push_calltemps (); - ffecom_char_args_ (&item, length, ffebld_left (expr)); - ffecom_pop_calltemps (); - - if (item == error_mark_node || *length == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - /* Build up ARRAY_REFs in reverse order (since we're column major - here in Fortran land). */ - - for (i = 0, expr = ffebld_right (expr); - expr != NULL; - expr = ffebld_trail (expr)) - dims[i++] = ffebld_head (expr); - - for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))); - i >= 0; - --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array))) - { - item = ffecom_2 (PLUS_EXPR, build_pointer_type (TREE_TYPE (array)), - item, - size_binop (MULT_EXPR, - size_in_bytes (TREE_TYPE (array)), - size_binop (MINUS_EXPR, - ffecom_expr (dims[i]), - TYPE_MIN_VALUE (TYPE_DOMAIN (array))))); - } - } - break; - - case FFEBLD_opSUBSTR: - { - ffebld start; - ffebld end; - ffebld thing = ffebld_right (expr); - tree start_tree; - tree end_tree; - - assert (ffebld_op (thing) == FFEBLD_opITEM); - start = ffebld_head (thing); - thing = ffebld_trail (thing); - assert (ffebld_trail (thing) == NULL); - end = ffebld_head (thing); - - ffecom_push_calltemps (); - ffecom_char_args_ (&item, length, ffebld_left (expr)); - ffecom_pop_calltemps (); - - if (item == error_mark_node || *length == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - if (start == NULL) - { - if (end == NULL) - ; - else - { - end_tree = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (end)); - - if (end_tree == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - *length = end_tree; - } - } - else - { - start_tree = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (start)); - - if (start_tree == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - start_tree = ffecom_save_tree (start_tree); - - item = ffecom_2 (PLUS_EXPR, TREE_TYPE (item), - item, - ffecom_2 (MINUS_EXPR, - TREE_TYPE (start_tree), - start_tree, - ffecom_f2c_ftnlen_one_node)); - - if (end == NULL) - { - *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - ffecom_2 (MINUS_EXPR, - ffecom_f2c_ftnlen_type_node, - *length, - start_tree)); - } - else - { - end_tree = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (end)); - - if (end_tree == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - *length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - ffecom_2 (MINUS_EXPR, - ffecom_f2c_ftnlen_type_node, - end_tree, start_tree)); - } - } - } - break; - - case FFEBLD_opFUNCREF: - { - ffesymbol s = ffebld_symter (ffebld_left (expr)); - tree tempvar; - tree args; - ffetargetCharacterSize size = ffeinfo_size (ffebld_info (expr)); - ffecomGfrt ix; - - if (size == FFETARGET_charactersizeNONE) - size = 24; /* ~~~~ Kludge alert! This should someday be fixed. */ - - *length = build_int_2 (size, 0); - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - - if (ffeinfo_where (ffebld_info (ffebld_left (expr))) - == FFEINFO_whereINTRINSIC) - { - if (size == 1) - { /* Invocation of an intrinsic returning CHARACTER*1. */ - item = ffecom_expr_intrinsic_ (expr, NULL_TREE, - NULL, NULL); - break; - } - ix = ffeintrin_gfrt_direct (ffebld_symter_implementation (ffebld_left (expr))); - assert (ix != FFECOM_gfrt); - item = ffecom_gfrt_tree_ (ix); - } - else - { - ix = FFECOM_gfrt; - item = ffesymbol_hook (s).decl_tree; - if (item == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - item = ffesymbol_hook (s).decl_tree; - } - if (item == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - if (!ffesymbol_hook (s).addr) - item = ffecom_1_fn (item); - } - - assert (ffecom_pending_calls_ != 0); - tempvar = ffecom_push_tempvar (char_type_node, size, -1, TRUE); - tempvar = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (tempvar)), - tempvar); - - ffecom_push_calltemps (); - - args = build_tree_list (NULL_TREE, tempvar); - - if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) /* Sfunc args by value. */ - TREE_CHAIN (args) = ffecom_list_expr (ffebld_right (expr)); - else - { - TREE_CHAIN (args) = build_tree_list (NULL_TREE, *length); - if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) - { - TREE_CHAIN (TREE_CHAIN (args)) - = ffecom_arglist_expr_ (ffecom_gfrt_args_ (ix), - ffebld_right (expr)); - } - else - { - TREE_CHAIN (TREE_CHAIN (args)) - = ffecom_list_ptr_to_expr (ffebld_right (expr)); - } - } - - item = ffecom_3s (CALL_EXPR, - TREE_TYPE (TREE_TYPE (TREE_TYPE (item))), - item, args, NULL_TREE); - item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), item, - tempvar); - - ffecom_pop_calltemps (); - } - break; - - case FFEBLD_opCONVERT: - - ffecom_push_calltemps (); - ffecom_char_args_ (&item, length, ffebld_left (expr)); - ffecom_pop_calltemps (); - - if (item == error_mark_node || *length == error_mark_node) - { - item = *length = error_mark_node; - break; - } - - if ((ffebld_size_known (ffebld_left (expr)) - == FFETARGET_charactersizeNONE) - || (ffebld_size_known (ffebld_left (expr)) < (ffebld_size (expr)))) - { /* Possible blank-padding needed, copy into - temporary. */ - tree tempvar; - tree args; - tree newlen; - - assert (ffecom_pending_calls_ != 0); - tempvar = ffecom_push_tempvar (char_type_node, - ffebld_size (expr), -1, TRUE); - tempvar = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (tempvar)), - tempvar); - - newlen = build_int_2 (ffebld_size (expr), 0); - TREE_TYPE (newlen) = ffecom_f2c_ftnlen_type_node; - - args = build_tree_list (NULL_TREE, tempvar); - TREE_CHAIN (args) = build_tree_list (NULL_TREE, item); - TREE_CHAIN (TREE_CHAIN (args)) = build_tree_list (NULL_TREE, newlen); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (args))) - = build_tree_list (NULL_TREE, *length); - - item = ffecom_call_gfrt (FFECOM_gfrtCOPY, args); - TREE_SIDE_EFFECTS (item) = 1; - item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), fold (item), - tempvar); - *length = newlen; - } - else - { /* Just truncate the length. */ - *length = build_int_2 (ffebld_size (expr), 0); - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - } - break; - - default: - assert ("bad op for single char arg expr" == NULL); - item = NULL_TREE; - break; - } - - *xitem = item; -} -#endif - -/* Check the size of the type to be sure it doesn't overflow the - "portable" capacities of the compiler back end. `dummy' types - can generally overflow the normal sizes as long as the computations - themselves don't overflow. A particular target of the back end - must still enforce its size requirements, though, and the back - end takes care of this in stor-layout.c. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_check_size_overflow_ (ffesymbol s, tree type, bool dummy) -{ - if (TREE_CODE (type) == ERROR_MARK) - return type; - - if (TYPE_SIZE (type) == NULL_TREE) - return type; - - if (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST) - return type; - - if ((tree_int_cst_sgn (TYPE_SIZE (type)) < 0) - || (!dummy && (((TREE_INT_CST_HIGH (TYPE_SIZE (type)) != 0)) - || TREE_OVERFLOW (TYPE_SIZE (type))))) - { - ffebad_start (FFEBAD_ARRAY_LARGE); - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s)); - ffebad_finish (); - - return error_mark_node; - } - - return type; -} -#endif - -/* Builds a length argument (PARM_DECL). Also wraps type in an array type - where the dimension info is (1:size) where <size> is ffesymbol_size(s) if - known, length_arg if not known (FFETARGET_charactersizeNONE). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_char_enhance_arg_ (tree *xtype, ffesymbol s) -{ - ffetargetCharacterSize sz = ffesymbol_size (s); - tree highval; - tree tlen; - tree type = *xtype; - - if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) - tlen = NULL_TREE; /* A statement function, no length passed. */ - else - { - if (ffesymbol_where (s) == FFEINFO_whereDUMMY) - tlen = ffecom_get_invented_identifier ("__g77_length_%s", - ffesymbol_text (s), 0); - else - tlen = ffecom_get_invented_identifier ("__g77_%s", - "length", 0); - tlen = build_decl (PARM_DECL, tlen, ffecom_f2c_ftnlen_type_node); -#if BUILT_FOR_270 - DECL_ARTIFICIAL (tlen) = 1; -#endif - } - - if (sz == FFETARGET_charactersizeNONE) - { - assert (tlen != NULL_TREE); - highval = variable_size (tlen); - } - else - { - highval = build_int_2 (sz, 0); - TREE_TYPE (highval) = ffecom_f2c_ftnlen_type_node; - } - - type = build_array_type (type, - build_range_type (ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - highval)); - - *xtype = type; - return tlen; -} - -#endif -/* ffecom_concat_list_gather_ -- Gather list of concatenated string exprs - - ffecomConcatList_ catlist; - ffebld expr; // expr of CHARACTER basictype. - ffetargetCharacterSize max; // max chars to gather or _...NONE if no max - catlist = ffecom_concat_list_gather_(catlist,expr,max); - - Scans expr for character subexpressions, updates and returns catlist - accordingly. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffecomConcatList_ -ffecom_concat_list_gather_ (ffecomConcatList_ catlist, ffebld expr, - ffetargetCharacterSize max) -{ - ffetargetCharacterSize sz; - -recurse: /* :::::::::::::::::::: */ - - if (expr == NULL) - return catlist; - - if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen >= max)) - return catlist; /* Don't append any more items. */ - - switch (ffebld_op (expr)) - { - case FFEBLD_opCONTER: - case FFEBLD_opSYMTER: - case FFEBLD_opARRAYREF: - case FFEBLD_opFUNCREF: - case FFEBLD_opSUBSTR: - case FFEBLD_opCONVERT: /* Callers should strip this off beforehand - if they don't need to preserve it. */ - if (catlist.count == catlist.max) - { /* Make a (larger) list. */ - ffebld *newx; - int newmax; - - newmax = (catlist.max == 0) ? 8 : catlist.max * 2; - newx = malloc_new_ks (malloc_pool_image (), "catlist", - newmax * sizeof (newx[0])); - if (catlist.max != 0) - { - memcpy (newx, catlist.exprs, catlist.max * sizeof (newx[0])); - malloc_kill_ks (malloc_pool_image (), catlist.exprs, - catlist.max * sizeof (newx[0])); - } - catlist.max = newmax; - catlist.exprs = newx; - } - if ((sz = ffebld_size_known (expr)) != FFETARGET_charactersizeNONE) - catlist.minlen += sz; - else - ++catlist.minlen; /* Not true for F90; can be 0 length. */ - if ((sz = ffebld_size_max (expr)) == FFETARGET_charactersizeNONE) - catlist.maxlen = sz; - else - catlist.maxlen += sz; - if ((max != FFETARGET_charactersizeNONE) && (catlist.minlen > max)) - { /* This item overlaps (or is beyond) the end - of the destination. */ - switch (ffebld_op (expr)) - { - case FFEBLD_opCONTER: - case FFEBLD_opSYMTER: - case FFEBLD_opARRAYREF: - case FFEBLD_opFUNCREF: - case FFEBLD_opSUBSTR: - break; /* ~~Do useful truncations here. */ - - default: - assert ("op changed or inconsistent switches!" == NULL); - break; - } - } - catlist.exprs[catlist.count++] = expr; - return catlist; - - case FFEBLD_opPAREN: - expr = ffebld_left (expr); - goto recurse; /* :::::::::::::::::::: */ - - case FFEBLD_opCONCATENATE: - catlist = ffecom_concat_list_gather_ (catlist, ffebld_left (expr), max); - expr = ffebld_right (expr); - goto recurse; /* :::::::::::::::::::: */ - -#if 0 /* Breaks passing small actual arg to larger - dummy arg of sfunc */ - case FFEBLD_opCONVERT: - expr = ffebld_left (expr); - { - ffetargetCharacterSize cmax; - - cmax = catlist.len + ffebld_size_known (expr); - - if ((max == FFETARGET_charactersizeNONE) || (max > cmax)) - max = cmax; - } - goto recurse; /* :::::::::::::::::::: */ -#endif - - case FFEBLD_opANY: - return catlist; - - default: - assert ("bad op in _gather_" == NULL); - return catlist; - } -} - -#endif -/* ffecom_concat_list_kill_ -- Kill list of concatenated string exprs - - ffecomConcatList_ catlist; - ffecom_concat_list_kill_(catlist); - - Anything allocated within the list info is deallocated. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_concat_list_kill_ (ffecomConcatList_ catlist) -{ - if (catlist.max != 0) - malloc_kill_ks (malloc_pool_image (), catlist.exprs, - catlist.max * sizeof (catlist.exprs[0])); -} - -#endif -/* ffecom_concat_list_new_ -- Make list of concatenated string exprs - - ffecomConcatList_ catlist; - ffebld expr; // Root expr of CHARACTER basictype. - ffetargetCharacterSize max; // max chars to gather or _...NONE if no max - catlist = ffecom_concat_list_new_(expr,max); - - Returns a flattened list of concatenated subexpressions given a - tree of such expressions. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffecomConcatList_ -ffecom_concat_list_new_ (ffebld expr, ffetargetCharacterSize max) -{ - ffecomConcatList_ catlist; - - catlist.maxlen = catlist.minlen = catlist.max = catlist.count = 0; - return ffecom_concat_list_gather_ (catlist, expr, max); -} - -#endif - -/* Provide some kind of useful info on member of aggregate area, - since current g77/gcc technology does not provide debug info - on these members. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_debug_kludge_ (tree aggr, char *aggr_type, ffesymbol member, - tree member_type UNUSED, ffetargetOffset offset) -{ - tree value; - tree decl; - int len; - char *buff; - char space[120]; -#if 0 - tree type_id; - - for (type_id = member_type; - TREE_CODE (type_id) != IDENTIFIER_NODE; - ) - { - switch (TREE_CODE (type_id)) - { - case INTEGER_TYPE: - case REAL_TYPE: - type_id = TYPE_NAME (type_id); - break; - - case ARRAY_TYPE: - case COMPLEX_TYPE: - type_id = TREE_TYPE (type_id); - break; - - default: - assert ("no IDENTIFIER_NODE for type!" == NULL); - type_id = error_mark_node; - break; - } - } -#endif - - if (ffecom_transform_only_dummies_ - || !ffe_is_debug_kludge ()) - return; /* Can't do this yet, maybe later. */ - - len = 60 - + strlen (aggr_type) - + IDENTIFIER_LENGTH (DECL_NAME (aggr)); -#if 0 - + IDENTIFIER_LENGTH (type_id); -#endif - - if (((size_t) len) >= ARRAY_SIZE (space)) - buff = malloc_new_ks (malloc_pool_image (), "debug_kludge", len + 1); - else - buff = &space[0]; - - sprintf (&buff[0], "At (%s) `%s' plus %ld bytes", - aggr_type, - IDENTIFIER_POINTER (DECL_NAME (aggr)), - (long int) offset); - - value = build_string (len, buff); - TREE_TYPE (value) - = build_type_variant (build_array_type (char_type_node, - build_range_type - (integer_type_node, - integer_one_node, - build_int_2 (strlen (buff), 0))), - 1, 0); - decl = build_decl (VAR_DECL, - ffecom_get_identifier_ (ffesymbol_text (member)), - TREE_TYPE (value)); - TREE_CONSTANT (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_INITIAL (decl) = error_mark_node; - DECL_IN_SYSTEM_HEADER (decl) = 1; /* Don't let -Wunused complain. */ - decl = start_decl (decl, FALSE); - finish_decl (decl, value, FALSE); - - if (buff != &space[0]) - malloc_kill_ks (malloc_pool_image (), buff, len + 1); -} -#endif - -/* ffecom_do_entry_ -- Do compilation of a particular entrypoint - - ffesymbol fn; // the SUBROUTINE, FUNCTION, or ENTRY symbol itself - int i; // entry# for this entrypoint (used by master fn) - ffecom_do_entrypoint_(s,i); - - Makes a public entry point that calls our private master fn (already - compiled). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_do_entry_ (ffesymbol fn, int entrynum) -{ - ffebld item; - tree type; /* Type of function. */ - tree multi_retval; /* Var holding return value (union). */ - tree result; /* Var holding result. */ - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffeglobal g; - ffeglobalType gt; - bool charfunc; /* All entry points return same type - CHARACTER. */ - bool cmplxfunc; /* Use f2c way of returning COMPLEX. */ - bool multi; /* Master fn has multiple return types. */ - bool altreturning = FALSE; /* This entry point has alternate returns. */ - int yes; - int old_lineno = lineno; - char *old_input_filename = input_filename; - - input_filename = ffesymbol_where_filename (fn); - lineno = ffesymbol_where_filelinenum (fn); - - /* c-parse.y indeed does call suspend_momentary and not only ignores the - return value, but also never calls resume_momentary, when starting an - outer function (see "fndef:", "setspecs:", and so on). So g77 does the - same thing. It shouldn't be a problem since start_function calls - temporary_allocation, but it might be necessary. If it causes a problem - here, then maybe there's a bug lurking in gcc. NOTE: This identical - comment appears twice in thist file. */ - - suspend_momentary (); - - ffecom_doing_entry_ = TRUE; /* Don't bother with array dimensions. */ - - switch (ffecom_primary_entry_kind_) - { - case FFEINFO_kindFUNCTION: - - /* Determine actual return type for function. */ - - gt = FFEGLOBAL_typeFUNC; - bt = ffesymbol_basictype (fn); - kt = ffesymbol_kindtype (fn); - if (bt == FFEINFO_basictypeNONE) - { - ffeimplic_establish_symbol (fn); - if (ffesymbol_funcresult (fn) != NULL) - ffeimplic_establish_symbol (ffesymbol_funcresult (fn)); - bt = ffesymbol_basictype (fn); - kt = ffesymbol_kindtype (fn); - } - - if (bt == FFEINFO_basictypeCHARACTER) - charfunc = TRUE, cmplxfunc = FALSE; - else if ((bt == FFEINFO_basictypeCOMPLEX) - && ffesymbol_is_f2c (fn)) - charfunc = FALSE, cmplxfunc = TRUE; - else - charfunc = cmplxfunc = FALSE; - - if (charfunc) - type = ffecom_tree_fun_type_void; - else if (ffesymbol_is_f2c (fn)) - type = ffecom_tree_fun_type[bt][kt]; - else - type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE); - - if ((type == NULL_TREE) - || (TREE_TYPE (type) == NULL_TREE)) - type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */ - - multi = (ffecom_master_bt_ == FFEINFO_basictypeNONE); - break; - - case FFEINFO_kindSUBROUTINE: - gt = FFEGLOBAL_typeSUBR; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - if (ffecom_is_altreturning_) - { /* Am _I_ altreturning? */ - for (item = ffesymbol_dummyargs (fn); - item != NULL; - item = ffebld_trail (item)) - { - if (ffebld_op (ffebld_head (item)) == FFEBLD_opSTAR) - { - altreturning = TRUE; - break; - } - } - if (altreturning) - type = ffecom_tree_subr_type; - else - type = ffecom_tree_fun_type_void; - } - else - type = ffecom_tree_fun_type_void; - charfunc = FALSE; - cmplxfunc = FALSE; - multi = FALSE; - break; - - default: - assert ("say what??" == NULL); - /* Fall through. */ - case FFEINFO_kindANY: - gt = FFEGLOBAL_typeANY; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - type = error_mark_node; - charfunc = FALSE; - cmplxfunc = FALSE; - multi = FALSE; - break; - } - - /* build_decl uses the current lineno and input_filename to set the decl - source info. So, I've putzed with ffestd and ffeste code to update that - source info to point to the appropriate statement just before calling - ffecom_do_entrypoint (which calls this fn). */ - - start_function (ffecom_get_external_identifier_ (fn), - type, - 0, /* nested/inline */ - 1); /* TREE_PUBLIC */ - - if (((g = ffesymbol_global (fn)) != NULL) - && ((ffeglobal_type (g) == gt) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))) - { - ffeglobal_set_hook (g, current_function_decl); - } - - /* Reset args in master arg list so they get retransitioned. */ - - for (item = ffecom_master_arglist_; - item != NULL; - item = ffebld_trail (item)) - { - ffebld arg; - ffesymbol s; - - arg = ffebld_head (item); - if (ffebld_op (arg) != FFEBLD_opSYMTER) - continue; /* Alternate return or some such thing. */ - s = ffebld_symter (arg); - ffesymbol_hook (s).decl_tree = NULL_TREE; - ffesymbol_hook (s).length_tree = NULL_TREE; - } - - /* Build dummy arg list for this entry point. */ - - yes = suspend_momentary (); - - if (charfunc || cmplxfunc) - { /* Prepend arg for where result goes. */ - tree type; - tree length; - - if (charfunc) - type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt]; - else - type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt]; - - result = ffecom_get_invented_identifier ("__g77_%s", - "result", 0); - - /* Make length arg _and_ enhance type info for CHAR arg itself. */ - - if (charfunc) - length = ffecom_char_enhance_arg_ (&type, fn); - else - length = NULL_TREE; /* Not ref'd if !charfunc. */ - - type = build_pointer_type (type); - result = build_decl (PARM_DECL, result, type); - - push_parm_decl (result); - ffecom_func_result_ = result; - - if (charfunc) - { - push_parm_decl (length); - ffecom_func_length_ = length; - } - } - else - result = DECL_RESULT (current_function_decl); - - ffecom_push_dummy_decls_ (ffesymbol_dummyargs (fn), FALSE); - - resume_momentary (yes); - - store_parm_decls (0); - - ffecom_start_compstmt_ (); - - /* Make local var to hold return type for multi-type master fn. */ - - if (multi) - { - yes = suspend_momentary (); - - multi_retval = ffecom_get_invented_identifier ("__g77_%s", - "multi_retval", 0); - multi_retval = build_decl (VAR_DECL, multi_retval, - ffecom_multi_type_node_); - multi_retval = start_decl (multi_retval, FALSE); - finish_decl (multi_retval, NULL_TREE, FALSE); - - resume_momentary (yes); - } - else - multi_retval = NULL_TREE; /* Not actually ref'd if !multi. */ - - /* Here we emit the actual code for the entry point. */ - - { - ffebld list; - ffebld arg; - ffesymbol s; - tree arglist = NULL_TREE; - tree *plist = &arglist; - tree prepend; - tree call; - tree actarg; - tree master_fn; - - /* Prepare actual arg list based on master arg list. */ - - for (list = ffecom_master_arglist_; - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) != FFEBLD_opSYMTER) - continue; - s = ffebld_symter (arg); - if (ffesymbol_hook (s).decl_tree == NULL_TREE) - actarg = null_pointer_node; /* We don't have this arg. */ - else - actarg = ffesymbol_hook (s).decl_tree; - *plist = build_tree_list (NULL_TREE, actarg); - plist = &TREE_CHAIN (*plist); - } - - /* This code appends the length arguments for character - variables/arrays. */ - - for (list = ffecom_master_arglist_; - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) != FFEBLD_opSYMTER) - continue; - s = ffebld_symter (arg); - if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER) - continue; /* Only looking for CHARACTER arguments. */ - if (ffesymbol_kind (s) != FFEINFO_kindENTITY) - continue; /* Only looking for variables and arrays. */ - if (ffesymbol_hook (s).length_tree == NULL_TREE) - actarg = ffecom_f2c_ftnlen_zero_node; /* We don't have this arg. */ - else - actarg = ffesymbol_hook (s).length_tree; - *plist = build_tree_list (NULL_TREE, actarg); - plist = &TREE_CHAIN (*plist); - } - - /* Prepend character-value return info to actual arg list. */ - - if (charfunc) - { - prepend = build_tree_list (NULL_TREE, ffecom_func_result_); - TREE_CHAIN (prepend) - = build_tree_list (NULL_TREE, ffecom_func_length_); - TREE_CHAIN (TREE_CHAIN (prepend)) = arglist; - arglist = prepend; - } - - /* Prepend multi-type return value to actual arg list. */ - - if (multi) - { - prepend - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (multi_retval)), - multi_retval)); - TREE_CHAIN (prepend) = arglist; - arglist = prepend; - } - - /* Prepend my entry-point number to the actual arg list. */ - - prepend = build_tree_list (NULL_TREE, build_int_2 (entrynum, 0)); - TREE_CHAIN (prepend) = arglist; - arglist = prepend; - - /* Build the call to the master function. */ - - master_fn = ffecom_1_fn (ffecom_previous_function_decl_); - call = ffecom_3s (CALL_EXPR, - TREE_TYPE (TREE_TYPE (TREE_TYPE (master_fn))), - master_fn, arglist, NULL_TREE); - - /* Decide whether the master function is a function or subroutine, and - handle the return value for my entry point. */ - - if (charfunc || ((ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE) - && !altreturning)) - { - expand_expr_stmt (call); - expand_null_return (); - } - else if (multi && cmplxfunc) - { - expand_expr_stmt (call); - result - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))), - result); - result = ffecom_modify (NULL_TREE, result, - ffecom_2 (COMPONENT_REF, TREE_TYPE (result), - multi_retval, - ffecom_multi_fields_[bt][kt])); - expand_expr_stmt (result); - expand_null_return (); - } - else if (multi) - { - expand_expr_stmt (call); - result - = ffecom_modify (NULL_TREE, result, - convert (TREE_TYPE (result), - ffecom_2 (COMPONENT_REF, - ffecom_tree_type[bt][kt], - multi_retval, - ffecom_multi_fields_[bt][kt]))); - expand_return (result); - } - else if (cmplxfunc) - { - result - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (result))), - result); - result = ffecom_modify (NULL_TREE, result, call); - expand_expr_stmt (result); - expand_null_return (); - } - else - { - result = ffecom_modify (NULL_TREE, - result, - convert (TREE_TYPE (result), - call)); - expand_return (result); - } - - clear_momentary (); - } - - ffecom_end_compstmt_ (); - - finish_function (0); - - lineno = old_lineno; - input_filename = old_input_filename; - - ffecom_doing_entry_ = FALSE; -} - -#endif -/* Transform expr into gcc tree with possible destination - - Recursive descent on expr while making corresponding tree nodes and - attaching type info and such. If destination supplied and compatible - with temporary that would be made in certain cases, temporary isn't - made, destination used instead, and dest_used flag set TRUE. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_expr_ (ffebld expr, tree dest_tree, ffebld dest, - bool *dest_used, bool assignp, bool widenp) -{ - tree item; - tree list; - tree args; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - tree t; - tree dt; /* decl_tree for an ffesymbol. */ - tree tree_type, tree_type_x; - tree left, right; - ffesymbol s; - enum tree_code code; - - assert (expr != NULL); - - if (dest_used != NULL) - *dest_used = FALSE; - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - tree_type = ffecom_tree_type[bt][kt]; - - /* Widen integral arithmetic as desired while preserving signedness. */ - tree_type_x = NULL_TREE; - if (widenp && tree_type - && GET_MODE_CLASS (TYPE_MODE (tree_type)) == MODE_INT - && TYPE_PRECISION (tree_type) < TYPE_PRECISION (sizetype)) - tree_type_x = (TREE_UNSIGNED (tree_type) ? usizetype : ssizetype); - - switch (ffebld_op (expr)) - { - case FFEBLD_opACCTER: - { - ffebitCount i; - ffebit bits = ffebld_accter_bits (expr); - ffetargetOffset source_offset = 0; - ffetargetOffset dest_offset = ffebld_accter_pad (expr); - tree purpose; - - assert (dest_offset == 0 - || (bt == FFEINFO_basictypeCHARACTER - && kt == FFEINFO_kindtypeCHARACTER1)); - - list = item = NULL; - for (;;) - { - ffebldConstantUnion cu; - ffebitCount length; - bool value; - ffebldConstantArray ca = ffebld_accter (expr); - - ffebit_test (bits, source_offset, &value, &length); - if (length == 0) - break; - - if (value) - { - for (i = 0; i < length; ++i) - { - cu = ffebld_constantarray_get (ca, bt, kt, - source_offset + i); - - t = ffecom_constantunion (&cu, bt, kt, tree_type); - - if (i == 0 - && dest_offset != 0) - purpose = build_int_2 (dest_offset, 0); - else - purpose = NULL_TREE; - - if (list == NULL_TREE) - list = item = build_tree_list (purpose, t); - else - { - TREE_CHAIN (item) = build_tree_list (purpose, t); - item = TREE_CHAIN (item); - } - } - } - source_offset += length; - dest_offset += length; - } - } - - item = build_int_2 ((ffebld_accter_size (expr) - + ffebld_accter_pad (expr)) - 1, 0); - ffebit_kill (ffebld_accter_bits (expr)); - TREE_TYPE (item) = ffecom_integer_type_node; - item - = build_array_type - (tree_type, - build_range_type (ffecom_integer_type_node, - ffecom_integer_zero_node, - item)); - list = build (CONSTRUCTOR, item, NULL_TREE, list); - TREE_CONSTANT (list) = 1; - TREE_STATIC (list) = 1; - return list; - - case FFEBLD_opARRTER: - { - ffetargetOffset i; - - list = NULL_TREE; - if (ffebld_arrter_pad (expr) == 0) - item = NULL_TREE; - else - { - assert (bt == FFEINFO_basictypeCHARACTER - && kt == FFEINFO_kindtypeCHARACTER1); - - /* Becomes PURPOSE first time through loop. */ - item = build_int_2 (ffebld_arrter_pad (expr), 0); - } - - for (i = 0; i < ffebld_arrter_size (expr); ++i) - { - ffebldConstantUnion cu - = ffebld_constantarray_get (ffebld_arrter (expr), bt, kt, i); - - t = ffecom_constantunion (&cu, bt, kt, tree_type); - - if (list == NULL_TREE) - /* Assume item is PURPOSE first time through loop. */ - list = item = build_tree_list (item, t); - else - { - TREE_CHAIN (item) = build_tree_list (NULL_TREE, t); - item = TREE_CHAIN (item); - } - } - } - - item = build_int_2 ((ffebld_arrter_size (expr) - + ffebld_arrter_pad (expr)) - 1, 0); - TREE_TYPE (item) = ffecom_integer_type_node; - item - = build_array_type - (tree_type, - build_range_type (ffecom_integer_type_node, - ffecom_integer_zero_node, - item)); - list = build (CONSTRUCTOR, item, NULL_TREE, list); - TREE_CONSTANT (list) = 1; - TREE_STATIC (list) = 1; - return list; - - case FFEBLD_opCONTER: - assert (ffebld_conter_pad (expr) == 0); - item - = ffecom_constantunion (&ffebld_constant_union (ffebld_conter (expr)), - bt, kt, tree_type); - return item; - - case FFEBLD_opSYMTER: - if ((ffebld_symter_generic (expr) != FFEINTRIN_genNONE) - || (ffebld_symter_specific (expr) != FFEINTRIN_specNONE)) - return ffecom_ptr_to_expr (expr); /* Same as %REF(intrinsic). */ - s = ffebld_symter (expr); - t = ffesymbol_hook (s).decl_tree; - - if (assignp) - { /* ASSIGN'ed-label expr. */ - if (ffe_is_ugly_assign ()) - { - /* User explicitly wants ASSIGN'ed variables to be at the same - memory address as the variables when used in non-ASSIGN - contexts. That can make old, arcane, non-standard code - work, but don't try to do it when a pointer wouldn't fit - in the normal variable (take other approach, and warn, - instead). */ - - if (t == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - t = ffesymbol_hook (s).decl_tree; - assert (t != NULL_TREE); - } - - if (t == error_mark_node) - return t; - - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t))) - >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) - { - if (ffesymbol_hook (s).addr) - t = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t); - return t; - } - - if (ffesymbol_hook (s).assign_tree == NULL_TREE) - { - ffebad_start_msg ("ASSIGN'ed label cannot fit into `%A' at %0 -- using wider sibling", - FFEBAD_severityWARNING); - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_finish (); - } - } - - /* Don't use the normal variable's tree for ASSIGN, though mark - it as in the system header (housekeeping). Use an explicit, - specially created sibling that is known to be wide enough - to hold pointers to labels. */ - - if (t != NULL_TREE - && TREE_CODE (t) == VAR_DECL) - DECL_IN_SYSTEM_HEADER (t) = 1; /* Don't let -Wunused complain. */ - - t = ffesymbol_hook (s).assign_tree; - if (t == NULL_TREE) - { - s = ffecom_sym_transform_assign_ (s); - t = ffesymbol_hook (s).assign_tree; - assert (t != NULL_TREE); - } - } - else - { - if (t == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - t = ffesymbol_hook (s).decl_tree; - assert (t != NULL_TREE); - } - if (ffesymbol_hook (s).addr) - t = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), t); - } - return t; - - case FFEBLD_opARRAYREF: - { - ffebld dims[FFECOM_dimensionsMAX]; -#if FFECOM_FASTER_ARRAY_REFS - tree array; -#endif - int i; - -#if FFECOM_FASTER_ARRAY_REFS - t = ffecom_ptr_to_expr (ffebld_left (expr)); -#else - t = ffecom_expr (ffebld_left (expr)); -#endif - if (t == error_mark_node) - return t; - - if ((ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING) - && !mark_addressable (t)) - return error_mark_node; /* Make sure non-const ref is to - non-reg. */ - - /* Build up ARRAY_REFs in reverse order (since we're column major - here in Fortran land). */ - - for (i = 0, expr = ffebld_right (expr); - expr != NULL; - expr = ffebld_trail (expr)) - dims[i++] = ffebld_head (expr); - -#if FFECOM_FASTER_ARRAY_REFS - for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))); - i >= 0; - --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array))) - t = ffecom_2 (PLUS_EXPR, - build_pointer_type (TREE_TYPE (array)), - t, - size_binop (MULT_EXPR, - size_in_bytes (TREE_TYPE (array)), - size_binop (MINUS_EXPR, - ffecom_expr (dims[i]), - TYPE_MIN_VALUE (TYPE_DOMAIN (array))))); - t = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), - t); -#else - while (i > 0) - t = ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (t))), - t, - ffecom_expr_ (dims[--i], NULL, NULL, NULL, FALSE, TRUE)); -#endif - - return t; - } - - case FFEBLD_opUPLUS: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - return ffecom_1 (NOP_EXPR, tree_type, left); - - case FFEBLD_opPAREN: /* ~~~Make sure Fortran rules respected here */ - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - return ffecom_1 (NOP_EXPR, tree_type, left); - - case FFEBLD_opUMINUS: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - if (tree_type_x) - { - tree_type = tree_type_x; - left = convert (tree_type, left); - } - return ffecom_1 (NEGATE_EXPR, tree_type, left); - - case FFEBLD_opADD: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp); - if (tree_type_x) - { - tree_type = tree_type_x; - left = convert (tree_type, left); - right = convert (tree_type, right); - } - return ffecom_2 (PLUS_EXPR, tree_type, left, right); - - case FFEBLD_opSUBTRACT: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp); - if (tree_type_x) - { - tree_type = tree_type_x; - left = convert (tree_type, left); - right = convert (tree_type, right); - } - return ffecom_2 (MINUS_EXPR, tree_type, left, right); - - case FFEBLD_opMULTIPLY: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp); - if (tree_type_x) - { - tree_type = tree_type_x; - left = convert (tree_type, left); - right = convert (tree_type, right); - } - return ffecom_2 (MULT_EXPR, tree_type, left, right); - - case FFEBLD_opDIVIDE: - left = ffecom_expr_ (ffebld_left (expr), NULL, NULL, NULL, FALSE, widenp); - right = ffecom_expr_ (ffebld_right (expr), NULL, NULL, NULL, FALSE, widenp); - if (tree_type_x) - { - tree_type = tree_type_x; - left = convert (tree_type, left); - right = convert (tree_type, right); - } - return ffecom_tree_divide_ (tree_type, left, right, - dest_tree, dest, dest_used); - - case FFEBLD_opPOWER: - { - ffebld left = ffebld_left (expr); - ffebld right = ffebld_right (expr); - ffecomGfrt code; - ffeinfoKindtype rtkt; - ffeinfoKindtype ltkt; - - switch (ffeinfo_basictype (ffebld_info (right))) - { - case FFEINFO_basictypeINTEGER: - if (1 || optimize) - { - item = ffecom_expr_power_integer_ (left, right); - if (item != NULL_TREE) - return item; - } - - rtkt = FFEINFO_kindtypeINTEGER1; - switch (ffeinfo_basictype (ffebld_info (left))) - { - case FFEINFO_basictypeINTEGER: - if ((ffeinfo_kindtype (ffebld_info (left)) - == FFEINFO_kindtypeINTEGER4) - || (ffeinfo_kindtype (ffebld_info (right)) - == FFEINFO_kindtypeINTEGER4)) - { - code = FFECOM_gfrtPOW_QQ; - ltkt = FFEINFO_kindtypeINTEGER4; - rtkt = FFEINFO_kindtypeINTEGER4; - } - else - { - code = FFECOM_gfrtPOW_II; - ltkt = FFEINFO_kindtypeINTEGER1; - } - break; - - case FFEINFO_basictypeREAL: - if (ffeinfo_kindtype (ffebld_info (left)) - == FFEINFO_kindtypeREAL1) - { - code = FFECOM_gfrtPOW_RI; - ltkt = FFEINFO_kindtypeREAL1; - } - else - { - code = FFECOM_gfrtPOW_DI; - ltkt = FFEINFO_kindtypeREAL2; - } - break; - - case FFEINFO_basictypeCOMPLEX: - if (ffeinfo_kindtype (ffebld_info (left)) - == FFEINFO_kindtypeREAL1) - { - code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */ - ltkt = FFEINFO_kindtypeREAL1; - } - else - { - code = FFECOM_gfrtPOW_ZI; /* Overlapping result okay. */ - ltkt = FFEINFO_kindtypeREAL2; - } - break; - - default: - assert ("bad pow_*i" == NULL); - code = FFECOM_gfrtPOW_CI; /* Overlapping result okay. */ - ltkt = FFEINFO_kindtypeREAL1; - break; - } - if (ffeinfo_kindtype (ffebld_info (left)) != ltkt) - left = ffeexpr_convert (left, NULL, NULL, - ffeinfo_basictype (ffebld_info (left)), - ltkt, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - if (ffeinfo_kindtype (ffebld_info (right)) != rtkt) - right = ffeexpr_convert (right, NULL, NULL, - FFEINFO_basictypeINTEGER, - rtkt, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeREAL: - if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1) - left = ffeexpr_convert (left, NULL, NULL, FFEINFO_basictypeREAL, - FFEINFO_kindtypeREALDOUBLE, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - if (ffeinfo_kindtype (ffebld_info (right)) - == FFEINFO_kindtypeREAL1) - right = ffeexpr_convert (right, NULL, NULL, - FFEINFO_basictypeREAL, - FFEINFO_kindtypeREALDOUBLE, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - code = FFECOM_gfrtPOW_DD; - break; - - case FFEINFO_basictypeCOMPLEX: - if (ffeinfo_kindtype (ffebld_info (left)) == FFEINFO_kindtypeREAL1) - left = ffeexpr_convert (left, NULL, NULL, - FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREALDOUBLE, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - if (ffeinfo_kindtype (ffebld_info (right)) - == FFEINFO_kindtypeREAL1) - right = ffeexpr_convert (right, NULL, NULL, - FFEINFO_basictypeCOMPLEX, - FFEINFO_kindtypeREALDOUBLE, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - code = FFECOM_gfrtPOW_ZZ; /* Overlapping result okay. */ - break; - - default: - assert ("bad pow_x*" == NULL); - code = FFECOM_gfrtPOW_II; - break; - } - return ffecom_call_binop_ (ffecom_gfrt_tree_ (code), - ffecom_gfrt_kindtype (code), - (ffe_is_f2c_library () - && ffecom_gfrt_complex_[code]), - tree_type, left, right, - dest_tree, dest, dest_used, - NULL_TREE, FALSE); - } - - case FFEBLD_opNOT: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - item = ffecom_truth_value_invert (ffecom_expr (ffebld_left (expr))); - return convert (tree_type, item); - - case FFEINFO_basictypeINTEGER: - return ffecom_1 (BIT_NOT_EXPR, tree_type, - ffecom_expr (ffebld_left (expr))); - - default: - assert ("NOT bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opFUNCREF: - assert (ffeinfo_basictype (ffebld_info (expr)) - != FFEINFO_basictypeCHARACTER); - /* Fall through. */ - case FFEBLD_opSUBRREF: - if (ffeinfo_where (ffebld_info (ffebld_left (expr))) - == FFEINFO_whereINTRINSIC) - { /* Invocation of an intrinsic. */ - item = ffecom_expr_intrinsic_ (expr, dest_tree, dest, - dest_used); - return item; - } - s = ffebld_symter (ffebld_left (expr)); - dt = ffesymbol_hook (s).decl_tree; - if (dt == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - dt = ffesymbol_hook (s).decl_tree; - } - if (dt == error_mark_node) - return dt; - - if (ffesymbol_hook (s).addr) - item = dt; - else - item = ffecom_1_fn (dt); - - ffecom_push_calltemps (); - if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) - args = ffecom_list_expr (ffebld_right (expr)); - else - args = ffecom_list_ptr_to_expr (ffebld_right (expr)); - ffecom_pop_calltemps (); - - item = ffecom_call_ (item, kt, - ffesymbol_is_f2c (s) - && (bt == FFEINFO_basictypeCOMPLEX) - && (ffesymbol_where (s) - != FFEINFO_whereCONSTANT), - tree_type, - args, - dest_tree, dest, dest_used, - error_mark_node, FALSE); - TREE_SIDE_EFFECTS (item) = 1; - return item; - - case FFEBLD_opAND: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - item - = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node, - ffecom_truth_value (ffecom_expr (ffebld_left (expr))), - ffecom_truth_value (ffecom_expr (ffebld_right (expr)))); - return convert (tree_type, item); - - case FFEINFO_basictypeINTEGER: - return ffecom_2 (BIT_AND_EXPR, tree_type, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - - default: - assert ("AND bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opOR: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - item - = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node, - ffecom_truth_value (ffecom_expr (ffebld_left (expr))), - ffecom_truth_value (ffecom_expr (ffebld_right (expr)))); - return convert (tree_type, item); - - case FFEINFO_basictypeINTEGER: - return ffecom_2 (BIT_IOR_EXPR, tree_type, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - - default: - assert ("OR bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opXOR: - case FFEBLD_opNEQV: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - item - = ffecom_2 (NE_EXPR, integer_type_node, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - return convert (tree_type, ffecom_truth_value (item)); - - case FFEINFO_basictypeINTEGER: - return ffecom_2 (BIT_XOR_EXPR, tree_type, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - - default: - assert ("XOR/NEQV bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opEQV: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - item - = ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - return convert (tree_type, ffecom_truth_value (item)); - - case FFEINFO_basictypeINTEGER: - return - ffecom_1 (BIT_NOT_EXPR, tree_type, - ffecom_2 (BIT_XOR_EXPR, tree_type, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr)))); - - default: - assert ("EQV bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opCONVERT: - if (ffebld_op (ffebld_left (expr)) == FFEBLD_opANY) - return error_mark_node; - - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - return convert (tree_type, ffecom_expr (ffebld_left (expr))); - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeLOGICAL: - case FFEINFO_basictypeREAL: - item = ffecom_expr (ffebld_left (expr)); - if (item == error_mark_node) - return error_mark_node; - /* convert() takes care of converting to the subtype first, - at least in gcc-2.7.2. */ - item = convert (tree_type, item); - return item; - - case FFEINFO_basictypeCOMPLEX: - return convert (tree_type, ffecom_expr (ffebld_left (expr))); - - default: - assert ("CONVERT COMPLEX bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - default: - assert ("CONVERT bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opLT: - code = LT_EXPR; - goto relational; /* :::::::::::::::::::: */ - - case FFEBLD_opLE: - code = LE_EXPR; - goto relational; /* :::::::::::::::::::: */ - - case FFEBLD_opEQ: - code = EQ_EXPR; - goto relational; /* :::::::::::::::::::: */ - - case FFEBLD_opNE: - code = NE_EXPR; - goto relational; /* :::::::::::::::::::: */ - - case FFEBLD_opGT: - code = GT_EXPR; - goto relational; /* :::::::::::::::::::: */ - - case FFEBLD_opGE: - code = GE_EXPR; - - relational: /* :::::::::::::::::::: */ - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeLOGICAL: - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - item = ffecom_2 (code, integer_type_node, - ffecom_expr (ffebld_left (expr)), - ffecom_expr (ffebld_right (expr))); - return convert (tree_type, item); - - case FFEINFO_basictypeCOMPLEX: - assert (code == EQ_EXPR || code == NE_EXPR); - { - tree real_type; - tree arg1 = ffecom_expr (ffebld_left (expr)); - tree arg2 = ffecom_expr (ffebld_right (expr)); - - if (arg1 == error_mark_node || arg2 == error_mark_node) - return error_mark_node; - - arg1 = ffecom_save_tree (arg1); - arg2 = ffecom_save_tree (arg2); - - if (TREE_CODE (TREE_TYPE (arg1)) == COMPLEX_TYPE) - { - real_type = TREE_TYPE (TREE_TYPE (arg1)); - assert (real_type == TREE_TYPE (TREE_TYPE (arg2))); - } - else - { - real_type = TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg1))); - assert (real_type == TREE_TYPE (TYPE_FIELDS (TREE_TYPE (arg2)))); - } - - item - = ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node, - ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_1 (REALPART_EXPR, real_type, arg1), - ffecom_1 (REALPART_EXPR, real_type, arg2)), - ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_1 (IMAGPART_EXPR, real_type, arg1), - ffecom_1 (IMAGPART_EXPR, real_type, - arg2))); - if (code == EQ_EXPR) - item = ffecom_truth_value (item); - else - item = ffecom_truth_value_invert (item); - return convert (tree_type, item); - } - - case FFEINFO_basictypeCHARACTER: - ffecom_push_calltemps (); /* Even though we might not call. */ - - { - ffebld left = ffebld_left (expr); - ffebld right = ffebld_right (expr); - tree left_tree; - tree right_tree; - tree left_length; - tree right_length; - - /* f2c run-time functions do the implicit blank-padding for us, - so we don't usually have to implement blank-padding ourselves. - (The exception is when we pass an argument to a separately - compiled statement function -- if we know the arg is not the - same length as the dummy, we must truncate or extend it. If - we "inline" statement functions, that necessity goes away as - well.) - - Strip off the CONVERT operators that blank-pad. (Truncation by - CONVERT shouldn't happen here, but it can happen in - assignments.) */ - - while (ffebld_op (left) == FFEBLD_opCONVERT) - left = ffebld_left (left); - while (ffebld_op (right) == FFEBLD_opCONVERT) - right = ffebld_left (right); - - left_tree = ffecom_arg_ptr_to_expr (left, &left_length); - right_tree = ffecom_arg_ptr_to_expr (right, &right_length); - - if (left_tree == error_mark_node || left_length == error_mark_node - || right_tree == error_mark_node - || right_length == error_mark_node) - { - ffecom_pop_calltemps (); - return error_mark_node; - } - - if ((ffebld_size_known (left) == 1) - && (ffebld_size_known (right) == 1)) - { - left_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))), - left_tree); - right_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))), - right_tree); - - item - = ffecom_2 (code, integer_type_node, - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (left_tree))), - left_tree, - integer_one_node), - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (right_tree))), - right_tree, - integer_one_node)); - } - else - { - item = build_tree_list (NULL_TREE, left_tree); - TREE_CHAIN (item) = build_tree_list (NULL_TREE, right_tree); - TREE_CHAIN (TREE_CHAIN (item)) = build_tree_list (NULL_TREE, - left_length); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))) - = build_tree_list (NULL_TREE, right_length); - item = ffecom_call_gfrt (FFECOM_gfrtCMP, item); - item = ffecom_2 (code, integer_type_node, - item, - convert (TREE_TYPE (item), - integer_zero_node)); - } - item = convert (tree_type, item); - } - - ffecom_pop_calltemps (); - return item; - - default: - assert ("relational bad basictype" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - break; - - case FFEBLD_opPERCENT_LOC: - item = ffecom_arg_ptr_to_expr (ffebld_left (expr), &list); - return convert (tree_type, item); - - case FFEBLD_opITEM: - case FFEBLD_opSTAR: - case FFEBLD_opBOUNDS: - case FFEBLD_opREPEAT: - case FFEBLD_opLABTER: - case FFEBLD_opLABTOK: - case FFEBLD_opIMPDO: - case FFEBLD_opCONCATENATE: - case FFEBLD_opSUBSTR: - default: - assert ("bad op" == NULL); - /* Fall through. */ - case FFEBLD_opANY: - return error_mark_node; - } - -#if 1 - assert ("didn't think anything got here anymore!!" == NULL); -#else - switch (ffebld_arity (expr)) - { - case 2: - TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr)); - TREE_OPERAND (item, 1) = ffecom_expr (ffebld_right (expr)); - if (TREE_OPERAND (item, 0) == error_mark_node - || TREE_OPERAND (item, 1) == error_mark_node) - return error_mark_node; - break; - - case 1: - TREE_OPERAND (item, 0) = ffecom_expr (ffebld_left (expr)); - if (TREE_OPERAND (item, 0) == error_mark_node) - return error_mark_node; - break; - - default: - break; - } - - return fold (item); -#endif -} - -#endif -/* Returns the tree that does the intrinsic invocation. - - Note: this function applies only to intrinsics returning - CHARACTER*1 or non-CHARACTER results, and to intrinsic - subroutines. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_expr_intrinsic_ (ffebld expr, tree dest_tree, - ffebld dest, bool *dest_used) -{ - tree expr_tree; - tree saved_expr1; /* For those who need it. */ - tree saved_expr2; /* For those who need it. */ - ffeinfoBasictype bt; - ffeinfoKindtype kt; - tree tree_type; - tree arg1_type; - tree real_type; /* REAL type corresponding to COMPLEX. */ - tree tempvar; - ffebld list = ffebld_right (expr); /* List of (some) args. */ - ffebld arg1; /* For handy reference. */ - ffebld arg2; - ffebld arg3; - ffeintrinImp codegen_imp; - ffecomGfrt gfrt; - - assert (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER); - - if (dest_used != NULL) - *dest_used = FALSE; - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - tree_type = ffecom_tree_type[bt][kt]; - - if (list != NULL) - { - arg1 = ffebld_head (list); - if (arg1 != NULL && ffebld_op (arg1) == FFEBLD_opANY) - return error_mark_node; - if ((list = ffebld_trail (list)) != NULL) - { - arg2 = ffebld_head (list); - if (arg2 != NULL && ffebld_op (arg2) == FFEBLD_opANY) - return error_mark_node; - if ((list = ffebld_trail (list)) != NULL) - { - arg3 = ffebld_head (list); - if (arg3 != NULL && ffebld_op (arg3) == FFEBLD_opANY) - return error_mark_node; - } - else - arg3 = NULL; - } - else - arg2 = arg3 = NULL; - } - else - arg1 = arg2 = arg3 = NULL; - - /* <list> ends up at the opITEM of the 3rd arg, or NULL if there are < 3 - args. This is used by the MAX/MIN expansions. */ - - if (arg1 != NULL) - arg1_type = ffecom_tree_type - [ffeinfo_basictype (ffebld_info (arg1))] - [ffeinfo_kindtype (ffebld_info (arg1))]; - else - arg1_type = NULL_TREE; /* Really not needed, but might catch bugs - here. */ - - /* There are several ways for each of the cases in the following switch - statements to exit (from simplest to use to most complicated): - - break; (when expr_tree == NULL) - - A standard call is made to the specific intrinsic just as if it had been - passed in as a dummy procedure and called as any old procedure. This - method can produce slower code but in some cases it's the easiest way for - now. However, if a (presumably faster) direct call is available, - that is used, so this is the easiest way in many more cases now. - - gfrt = FFECOM_gfrtWHATEVER; - break; - - gfrt contains the gfrt index of a library function to call, passing the - argument(s) by value rather than by reference. Used when a more - careful choice of library function is needed than that provided - by the vanilla `break;'. - - return expr_tree; - - The expr_tree has been completely set up and is ready to be returned - as is. No further actions are taken. Use this when the tree is not - in the simple form for one of the arity_n labels. */ - - /* For info on how the switch statement cases were written, see the files - enclosed in comments below the switch statement. */ - - codegen_imp = ffebld_symter_implementation (ffebld_left (expr)); - gfrt = ffeintrin_gfrt_direct (codegen_imp); - if (gfrt == FFECOM_gfrt) - gfrt = ffeintrin_gfrt_indirect (codegen_imp); - - switch (codegen_imp) - { - case FFEINTRIN_impABS: - case FFEINTRIN_impCABS: - case FFEINTRIN_impCDABS: - case FFEINTRIN_impDABS: - case FFEINTRIN_impIABS: - if (ffeinfo_basictype (ffebld_info (arg1)) - == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCABS; - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDABS; - break; - } - return ffecom_1 (ABS_EXPR, tree_type, - convert (tree_type, ffecom_expr (arg1))); - - case FFEINTRIN_impACOS: - case FFEINTRIN_impDACOS: - break; - - case FFEINTRIN_impAIMAG: - case FFEINTRIN_impDIMAG: - case FFEINTRIN_impIMAGPART: - if (TREE_CODE (arg1_type) == COMPLEX_TYPE) - arg1_type = TREE_TYPE (arg1_type); - else - arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type)); - - return - convert (tree_type, - ffecom_1 (IMAGPART_EXPR, arg1_type, - ffecom_expr (arg1))); - - case FFEINTRIN_impAINT: - case FFEINTRIN_impDINT: -#if 0 /* ~~ someday implement FIX_TRUNC_EXPR - yielding same type as arg */ - return ffecom_1 (FIX_TRUNC_EXPR, tree_type, ffecom_expr (arg1)); -#else /* in the meantime, must use floor to avoid range problems with ints */ - /* r__1 = r1 >= 0 ? floor(r1) : -floor(-r1); */ - saved_expr1 = ffecom_save_tree (ffecom_expr (arg1)); - return - convert (tree_type, - ffecom_3 (COND_EXPR, double_type_node, - ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - saved_expr1, - convert (arg1_type, - ffecom_float_zero_))), - ffecom_call_gfrt (FFECOM_gfrtL_FLOOR, - build_tree_list (NULL_TREE, - convert (double_type_node, - saved_expr1))), - ffecom_1 (NEGATE_EXPR, double_type_node, - ffecom_call_gfrt (FFECOM_gfrtL_FLOOR, - build_tree_list (NULL_TREE, - convert (double_type_node, - ffecom_1 (NEGATE_EXPR, - arg1_type, - saved_expr1)))) - )) - ); -#endif - - case FFEINTRIN_impANINT: - case FFEINTRIN_impDNINT: -#if 0 /* This way of doing it won't handle real - numbers of large magnitudes. */ - saved_expr1 = ffecom_save_tree (ffecom_expr (arg1)); - expr_tree = convert (tree_type, - convert (integer_type_node, - ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (GE_EXPR, - integer_type_node, - saved_expr1, - ffecom_float_zero_)), - ffecom_2 (PLUS_EXPR, - tree_type, - saved_expr1, - ffecom_float_half_), - ffecom_2 (MINUS_EXPR, - tree_type, - saved_expr1, - ffecom_float_half_)))); - return expr_tree; -#else /* So we instead call floor. */ - /* r__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1) */ - saved_expr1 = ffecom_save_tree (ffecom_expr (arg1)); - return - convert (tree_type, - ffecom_3 (COND_EXPR, double_type_node, - ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - saved_expr1, - convert (arg1_type, - ffecom_float_zero_))), - ffecom_call_gfrt (FFECOM_gfrtL_FLOOR, - build_tree_list (NULL_TREE, - convert (double_type_node, - ffecom_2 (PLUS_EXPR, - arg1_type, - saved_expr1, - convert (arg1_type, - ffecom_float_half_))))), - ffecom_1 (NEGATE_EXPR, double_type_node, - ffecom_call_gfrt (FFECOM_gfrtL_FLOOR, - build_tree_list (NULL_TREE, - convert (double_type_node, - ffecom_2 (MINUS_EXPR, - arg1_type, - convert (arg1_type, - ffecom_float_half_), - saved_expr1))))) - ) - ); -#endif - - case FFEINTRIN_impASIN: - case FFEINTRIN_impDASIN: - case FFEINTRIN_impATAN: - case FFEINTRIN_impDATAN: - case FFEINTRIN_impATAN2: - case FFEINTRIN_impDATAN2: - break; - - case FFEINTRIN_impCHAR: - case FFEINTRIN_impACHAR: - assert (ffecom_pending_calls_ != 0); - tempvar = ffecom_push_tempvar (char_type_node, - 1, -1, TRUE); - { - tree tmv = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (tempvar))); - - expr_tree = ffecom_modify (tmv, - ffecom_2 (ARRAY_REF, tmv, tempvar, - integer_one_node), - convert (tmv, ffecom_expr (arg1))); - } - expr_tree = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (tempvar), - expr_tree, - tempvar); - expr_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (expr_tree)), - expr_tree); - return expr_tree; - - case FFEINTRIN_impCMPLX: - case FFEINTRIN_impDCMPLX: - if (arg2 == NULL) - return - convert (tree_type, ffecom_expr (arg1)); - - real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; - return - ffecom_2 (COMPLEX_EXPR, tree_type, - convert (real_type, ffecom_expr (arg1)), - convert (real_type, - ffecom_expr (arg2))); - - case FFEINTRIN_impCOMPLEX: - return - ffecom_2 (COMPLEX_EXPR, tree_type, - ffecom_expr (arg1), - ffecom_expr (arg2)); - - case FFEINTRIN_impCONJG: - case FFEINTRIN_impDCONJG: - { - tree arg1_tree; - - real_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; - arg1_tree = ffecom_save_tree (ffecom_expr (arg1)); - return - ffecom_2 (COMPLEX_EXPR, tree_type, - ffecom_1 (REALPART_EXPR, real_type, arg1_tree), - ffecom_1 (NEGATE_EXPR, real_type, - ffecom_1 (IMAGPART_EXPR, real_type, arg1_tree))); - } - - case FFEINTRIN_impCOS: - case FFEINTRIN_impCCOS: - case FFEINTRIN_impCDCOS: - case FFEINTRIN_impDCOS: - if (bt == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCCOS; /* Overlapping result okay. */ - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDCOS; /* Overlapping result okay. */ - } - break; - - case FFEINTRIN_impCOSH: - case FFEINTRIN_impDCOSH: - break; - - case FFEINTRIN_impDBLE: - case FFEINTRIN_impDFLOAT: - case FFEINTRIN_impDREAL: - case FFEINTRIN_impFLOAT: - case FFEINTRIN_impIDINT: - case FFEINTRIN_impIFIX: - case FFEINTRIN_impINT2: - case FFEINTRIN_impINT8: - case FFEINTRIN_impINT: - case FFEINTRIN_impLONG: - case FFEINTRIN_impREAL: - case FFEINTRIN_impSHORT: - case FFEINTRIN_impSNGL: - return convert (tree_type, ffecom_expr (arg1)); - - case FFEINTRIN_impDIM: - case FFEINTRIN_impDDIM: - case FFEINTRIN_impIDIM: - saved_expr1 = ffecom_save_tree (convert (tree_type, - ffecom_expr (arg1))); - saved_expr2 = ffecom_save_tree (convert (tree_type, - ffecom_expr (arg2))); - return - ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (GT_EXPR, integer_type_node, - saved_expr1, - saved_expr2)), - ffecom_2 (MINUS_EXPR, tree_type, - saved_expr1, - saved_expr2), - convert (tree_type, ffecom_float_zero_)); - - case FFEINTRIN_impDPROD: - return - ffecom_2 (MULT_EXPR, tree_type, - convert (tree_type, ffecom_expr (arg1)), - convert (tree_type, ffecom_expr (arg2))); - - case FFEINTRIN_impEXP: - case FFEINTRIN_impCDEXP: - case FFEINTRIN_impCEXP: - case FFEINTRIN_impDEXP: - if (bt == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCEXP; /* Overlapping result okay. */ - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDEXP; /* Overlapping result okay. */ - } - break; - - case FFEINTRIN_impICHAR: - case FFEINTRIN_impIACHAR: -#if 0 /* The simple approach. */ - ffecom_char_args_ (&expr_tree, &saved_expr1 /* Ignored */ , arg1); - expr_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))), - expr_tree); - expr_tree - = ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))), - expr_tree, - integer_one_node); - return convert (tree_type, expr_tree); -#else /* The more interesting (and more optimal) approach. */ - expr_tree = ffecom_intrinsic_ichar_ (tree_type, arg1, &saved_expr1); - expr_tree = ffecom_3 (COND_EXPR, tree_type, - saved_expr1, - expr_tree, - convert (tree_type, integer_zero_node)); - return expr_tree; -#endif - - case FFEINTRIN_impINDEX: - break; - - case FFEINTRIN_impLEN: -#if 0 - break; /* The simple approach. */ -#else - return ffecom_intrinsic_len_ (arg1); /* The more optimal approach. */ -#endif - - case FFEINTRIN_impLGE: - case FFEINTRIN_impLGT: - case FFEINTRIN_impLLE: - case FFEINTRIN_impLLT: - break; - - case FFEINTRIN_impLOG: - case FFEINTRIN_impALOG: - case FFEINTRIN_impCDLOG: - case FFEINTRIN_impCLOG: - case FFEINTRIN_impDLOG: - if (bt == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCLOG; /* Overlapping result okay. */ - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDLOG; /* Overlapping result okay. */ - } - break; - - case FFEINTRIN_impLOG10: - case FFEINTRIN_impALOG10: - case FFEINTRIN_impDLOG10: - if (gfrt != FFECOM_gfrt) - break; /* Already picked one, stick with it. */ - - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtALOG10; - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtDLOG10; - break; - - case FFEINTRIN_impMAX: - case FFEINTRIN_impAMAX0: - case FFEINTRIN_impAMAX1: - case FFEINTRIN_impDMAX1: - case FFEINTRIN_impMAX0: - case FFEINTRIN_impMAX1: - if (bt != ffeinfo_basictype (ffebld_info (arg1))) - arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr)); - else - arg1_type = tree_type; - expr_tree = ffecom_2 (MAX_EXPR, arg1_type, - convert (arg1_type, ffecom_expr (arg1)), - convert (arg1_type, ffecom_expr (arg2))); - for (; list != NULL; list = ffebld_trail (list)) - { - if ((ffebld_head (list) == NULL) - || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY)) - continue; - expr_tree = ffecom_2 (MAX_EXPR, arg1_type, - expr_tree, - convert (arg1_type, - ffecom_expr (ffebld_head (list)))); - } - return convert (tree_type, expr_tree); - - case FFEINTRIN_impMIN: - case FFEINTRIN_impAMIN0: - case FFEINTRIN_impAMIN1: - case FFEINTRIN_impDMIN1: - case FFEINTRIN_impMIN0: - case FFEINTRIN_impMIN1: - if (bt != ffeinfo_basictype (ffebld_info (arg1))) - arg1_type = ffecom_widest_expr_type_ (ffebld_right (expr)); - else - arg1_type = tree_type; - expr_tree = ffecom_2 (MIN_EXPR, arg1_type, - convert (arg1_type, ffecom_expr (arg1)), - convert (arg1_type, ffecom_expr (arg2))); - for (; list != NULL; list = ffebld_trail (list)) - { - if ((ffebld_head (list) == NULL) - || (ffebld_op (ffebld_head (list)) == FFEBLD_opANY)) - continue; - expr_tree = ffecom_2 (MIN_EXPR, arg1_type, - expr_tree, - convert (arg1_type, - ffecom_expr (ffebld_head (list)))); - } - return convert (tree_type, expr_tree); - - case FFEINTRIN_impMOD: - case FFEINTRIN_impAMOD: - case FFEINTRIN_impDMOD: - if (bt != FFEINFO_basictypeREAL) - return ffecom_2 (TRUNC_MOD_EXPR, tree_type, - convert (tree_type, ffecom_expr (arg1)), - convert (tree_type, ffecom_expr (arg2))); - - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtAMOD; - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtDMOD; - break; - - case FFEINTRIN_impNINT: - case FFEINTRIN_impIDNINT: -#if 0 /* ~~ ideally FIX_ROUND_EXPR would be - implemented, but it ain't yet */ - return ffecom_1 (FIX_ROUND_EXPR, tree_type, ffecom_expr (arg1)); -#else - /* i__1 = r1 >= 0 ? floor(r1 + .5) : -floor(.5 - r1); */ - saved_expr1 = ffecom_save_tree (ffecom_expr (arg1)); - return - convert (ffecom_integer_type_node, - ffecom_3 (COND_EXPR, arg1_type, - ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - saved_expr1, - convert (arg1_type, - ffecom_float_zero_))), - ffecom_2 (PLUS_EXPR, arg1_type, - saved_expr1, - convert (arg1_type, - ffecom_float_half_)), - ffecom_2 (MINUS_EXPR, arg1_type, - saved_expr1, - convert (arg1_type, - ffecom_float_half_)))); -#endif - - case FFEINTRIN_impSIGN: - case FFEINTRIN_impDSIGN: - case FFEINTRIN_impISIGN: - { - tree arg2_tree = ffecom_expr (arg2); - - saved_expr1 - = ffecom_save_tree - (ffecom_1 (ABS_EXPR, tree_type, - convert (tree_type, - ffecom_expr (arg1)))); - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - arg2_tree, - convert (TREE_TYPE (arg2_tree), - integer_zero_node))), - saved_expr1, - ffecom_1 (NEGATE_EXPR, tree_type, saved_expr1)); - /* Make sure SAVE_EXPRs get referenced early enough. */ - expr_tree - = ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, saved_expr1), - expr_tree); - } - return expr_tree; - - case FFEINTRIN_impSIN: - case FFEINTRIN_impCDSIN: - case FFEINTRIN_impCSIN: - case FFEINTRIN_impDSIN: - if (bt == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCSIN; /* Overlapping result okay. */ - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDSIN; /* Overlapping result okay. */ - } - break; - - case FFEINTRIN_impSINH: - case FFEINTRIN_impDSINH: - break; - - case FFEINTRIN_impSQRT: - case FFEINTRIN_impCDSQRT: - case FFEINTRIN_impCSQRT: - case FFEINTRIN_impDSQRT: - if (bt == FFEINFO_basictypeCOMPLEX) - { - if (kt == FFEINFO_kindtypeREAL1) - gfrt = FFECOM_gfrtCSQRT; /* Overlapping result okay. */ - else if (kt == FFEINFO_kindtypeREAL2) - gfrt = FFECOM_gfrtCDSQRT; /* Overlapping result okay. */ - } - break; - - case FFEINTRIN_impTAN: - case FFEINTRIN_impDTAN: - case FFEINTRIN_impTANH: - case FFEINTRIN_impDTANH: - break; - - case FFEINTRIN_impREALPART: - if (TREE_CODE (arg1_type) == COMPLEX_TYPE) - arg1_type = TREE_TYPE (arg1_type); - else - arg1_type = TREE_TYPE (TYPE_FIELDS (arg1_type)); - - return - convert (tree_type, - ffecom_1 (REALPART_EXPR, arg1_type, - ffecom_expr (arg1))); - - case FFEINTRIN_impIAND: - case FFEINTRIN_impAND: - return ffecom_2 (BIT_AND_EXPR, tree_type, - convert (tree_type, - ffecom_expr (arg1)), - convert (tree_type, - ffecom_expr (arg2))); - - case FFEINTRIN_impIOR: - case FFEINTRIN_impOR: - return ffecom_2 (BIT_IOR_EXPR, tree_type, - convert (tree_type, - ffecom_expr (arg1)), - convert (tree_type, - ffecom_expr (arg2))); - - case FFEINTRIN_impIEOR: - case FFEINTRIN_impXOR: - return ffecom_2 (BIT_XOR_EXPR, tree_type, - convert (tree_type, - ffecom_expr (arg1)), - convert (tree_type, - ffecom_expr (arg2))); - - case FFEINTRIN_impLSHIFT: - return ffecom_2 (LSHIFT_EXPR, tree_type, - ffecom_expr (arg1), - convert (integer_type_node, - ffecom_expr (arg2))); - - case FFEINTRIN_impRSHIFT: - return ffecom_2 (RSHIFT_EXPR, tree_type, - ffecom_expr (arg1), - convert (integer_type_node, - ffecom_expr (arg2))); - - case FFEINTRIN_impNOT: - return ffecom_1 (BIT_NOT_EXPR, tree_type, ffecom_expr (arg1)); - - case FFEINTRIN_impBIT_SIZE: - return convert (tree_type, TYPE_SIZE (arg1_type)); - - case FFEINTRIN_impBTEST: - { - ffetargetLogical1 true; - ffetargetLogical1 false; - tree true_tree; - tree false_tree; - - ffetarget_logical1 (&true, TRUE); - ffetarget_logical1 (&false, FALSE); - if (true == 1) - true_tree = convert (tree_type, integer_one_node); - else - true_tree = convert (tree_type, build_int_2 (true, 0)); - if (false == 0) - false_tree = convert (tree_type, integer_zero_node); - else - false_tree = convert (tree_type, build_int_2 (false, 0)); - - return - ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_2 (BIT_AND_EXPR, arg1_type, - ffecom_expr (arg1), - ffecom_2 (LSHIFT_EXPR, arg1_type, - convert (arg1_type, - integer_one_node), - convert (integer_type_node, - ffecom_expr (arg2)))), - convert (arg1_type, - integer_zero_node))), - false_tree, - true_tree); - } - - case FFEINTRIN_impIBCLR: - return - ffecom_2 (BIT_AND_EXPR, tree_type, - ffecom_expr (arg1), - ffecom_1 (BIT_NOT_EXPR, tree_type, - ffecom_2 (LSHIFT_EXPR, tree_type, - convert (tree_type, - integer_one_node), - convert (integer_type_node, - ffecom_expr (arg2))))); - - case FFEINTRIN_impIBITS: - { - tree arg3_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg3))); - tree uns_type - = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]; - - expr_tree - = ffecom_2 (BIT_AND_EXPR, tree_type, - ffecom_2 (RSHIFT_EXPR, tree_type, - ffecom_expr (arg1), - convert (integer_type_node, - ffecom_expr (arg2))), - convert (tree_type, - ffecom_2 (RSHIFT_EXPR, uns_type, - ffecom_1 (BIT_NOT_EXPR, - uns_type, - convert (uns_type, - integer_zero_node)), - ffecom_2 (MINUS_EXPR, - integer_type_node, - TYPE_SIZE (uns_type), - arg3_tree)))); -#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg3_tree, - integer_zero_node)), - expr_tree, - convert (tree_type, integer_zero_node)); -#endif - } - return expr_tree; - - case FFEINTRIN_impIBSET: - return - ffecom_2 (BIT_IOR_EXPR, tree_type, - ffecom_expr (arg1), - ffecom_2 (LSHIFT_EXPR, tree_type, - convert (tree_type, integer_one_node), - convert (integer_type_node, - ffecom_expr (arg2)))); - - case FFEINTRIN_impISHFT: - { - tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1)); - tree arg2_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg2))); - tree uns_type - = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]; - - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - arg2_tree, - integer_zero_node)), - ffecom_2 (LSHIFT_EXPR, tree_type, - arg1_tree, - arg2_tree), - convert (tree_type, - ffecom_2 (RSHIFT_EXPR, uns_type, - convert (uns_type, arg1_tree), - ffecom_1 (NEGATE_EXPR, - integer_type_node, - arg2_tree)))); -#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg2_tree, - TYPE_SIZE (uns_type))), - expr_tree, - convert (tree_type, integer_zero_node)); -#endif - /* Make sure SAVE_EXPRs get referenced early enough. */ - expr_tree - = ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, arg1_tree), - ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, arg2_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impISHFTC: - { - tree arg1_tree = ffecom_save_tree (ffecom_expr (arg1)); - tree arg2_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg2))); - tree arg3_tree = (arg3 == NULL) ? TYPE_SIZE (tree_type) - : ffecom_save_tree (convert (integer_type_node, ffecom_expr (arg3))); - tree shift_neg; - tree shift_pos; - tree mask_arg1; - tree masked_arg1; - tree uns_type - = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]; - - mask_arg1 - = ffecom_2 (LSHIFT_EXPR, tree_type, - ffecom_1 (BIT_NOT_EXPR, tree_type, - convert (tree_type, integer_zero_node)), - arg3_tree); -#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH - mask_arg1 - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg3_tree, - TYPE_SIZE (uns_type))), - mask_arg1, - convert (tree_type, integer_zero_node)); -#endif - mask_arg1 = ffecom_save_tree (mask_arg1); - masked_arg1 - = ffecom_2 (BIT_AND_EXPR, tree_type, - arg1_tree, - ffecom_1 (BIT_NOT_EXPR, tree_type, - mask_arg1)); - masked_arg1 = ffecom_save_tree (masked_arg1); - shift_neg - = ffecom_2 (BIT_IOR_EXPR, tree_type, - convert (tree_type, - ffecom_2 (RSHIFT_EXPR, uns_type, - convert (uns_type, masked_arg1), - ffecom_1 (NEGATE_EXPR, - integer_type_node, - arg2_tree))), - ffecom_2 (LSHIFT_EXPR, tree_type, - arg1_tree, - ffecom_2 (PLUS_EXPR, integer_type_node, - arg2_tree, - arg3_tree))); - shift_pos - = ffecom_2 (BIT_IOR_EXPR, tree_type, - ffecom_2 (LSHIFT_EXPR, tree_type, - arg1_tree, - arg2_tree), - convert (tree_type, - ffecom_2 (RSHIFT_EXPR, uns_type, - convert (uns_type, masked_arg1), - ffecom_2 (MINUS_EXPR, - integer_type_node, - arg3_tree, - arg2_tree)))); - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (LT_EXPR, integer_type_node, - arg2_tree, - integer_zero_node)), - shift_neg, - shift_pos); - expr_tree - = ffecom_2 (BIT_IOR_EXPR, tree_type, - ffecom_2 (BIT_AND_EXPR, tree_type, - mask_arg1, - arg1_tree), - ffecom_2 (BIT_AND_EXPR, tree_type, - ffecom_1 (BIT_NOT_EXPR, tree_type, - mask_arg1), - expr_tree)); - expr_tree - = ffecom_3 (COND_EXPR, tree_type, - ffecom_truth_value - (ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node, - ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_1 (ABS_EXPR, - integer_type_node, - arg2_tree), - arg3_tree), - ffecom_2 (EQ_EXPR, integer_type_node, - arg2_tree, - integer_zero_node))), - arg1_tree, - expr_tree); - /* Make sure SAVE_EXPRs get referenced early enough. */ - expr_tree - = ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, arg1_tree), - ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, arg2_tree), - ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, - mask_arg1), - ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, - masked_arg1), - expr_tree)))); - expr_tree - = ffecom_2 (COMPOUND_EXPR, tree_type, - convert (void_type_node, - arg3_tree), - expr_tree); - } - return expr_tree; - - case FFEINTRIN_impLOC: - { - tree arg1_tree = ffecom_expr (arg1); - - expr_tree - = convert (tree_type, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree)); - } - return expr_tree; - - case FFEINTRIN_impMVBITS: - { - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - ffebld arg4 = ffebld_head (ffebld_trail (list)); - tree arg4_tree; - tree arg4_type; - ffebld arg5 = ffebld_head (ffebld_trail (ffebld_trail (list))); - tree arg5_tree; - tree prep_arg1; - tree prep_arg4; - tree arg5_plus_arg3; - - ffecom_push_calltemps (); - - arg2_tree = convert (integer_type_node, - ffecom_expr (arg2)); - arg3_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg3))); - arg4_tree = ffecom_expr_rw (arg4); - arg4_type = TREE_TYPE (arg4_tree); - - arg1_tree = ffecom_save_tree (convert (arg4_type, - ffecom_expr (arg1))); - - arg5_tree = ffecom_save_tree (convert (integer_type_node, - ffecom_expr (arg5))); - - ffecom_pop_calltemps (); - - prep_arg1 - = ffecom_2 (LSHIFT_EXPR, arg4_type, - ffecom_2 (BIT_AND_EXPR, arg4_type, - ffecom_2 (RSHIFT_EXPR, arg4_type, - arg1_tree, - arg2_tree), - ffecom_1 (BIT_NOT_EXPR, arg4_type, - ffecom_2 (LSHIFT_EXPR, arg4_type, - ffecom_1 (BIT_NOT_EXPR, - arg4_type, - convert - (arg4_type, - integer_zero_node)), - arg3_tree))), - arg5_tree); - arg5_plus_arg3 - = ffecom_save_tree (ffecom_2 (PLUS_EXPR, arg4_type, - arg5_tree, - arg3_tree)); - prep_arg4 - = ffecom_2 (LSHIFT_EXPR, arg4_type, - ffecom_1 (BIT_NOT_EXPR, arg4_type, - convert (arg4_type, - integer_zero_node)), - arg5_plus_arg3); -#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH - prep_arg4 - = ffecom_3 (COND_EXPR, arg4_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg5_plus_arg3, - convert (TREE_TYPE (arg5_plus_arg3), - TYPE_SIZE (arg4_type)))), - prep_arg4, - convert (arg4_type, integer_zero_node)); -#endif - prep_arg4 - = ffecom_2 (BIT_AND_EXPR, arg4_type, - arg4_tree, - ffecom_2 (BIT_IOR_EXPR, arg4_type, - prep_arg4, - ffecom_1 (BIT_NOT_EXPR, arg4_type, - ffecom_2 (LSHIFT_EXPR, arg4_type, - ffecom_1 (BIT_NOT_EXPR, - arg4_type, - convert - (arg4_type, - integer_zero_node)), - arg5_tree)))); - prep_arg1 - = ffecom_2 (BIT_IOR_EXPR, arg4_type, - prep_arg1, - prep_arg4); -#if !defined(TREE_SHIFT_FULLWIDTH) || !TREE_SHIFT_FULLWIDTH - prep_arg1 - = ffecom_3 (COND_EXPR, arg4_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg3_tree, - convert (TREE_TYPE (arg3_tree), - integer_zero_node))), - prep_arg1, - arg4_tree); - prep_arg1 - = ffecom_3 (COND_EXPR, arg4_type, - ffecom_truth_value - (ffecom_2 (NE_EXPR, integer_type_node, - arg3_tree, - convert (TREE_TYPE (arg3_tree), - TYPE_SIZE (arg4_type)))), - prep_arg1, - arg1_tree); -#endif - expr_tree - = ffecom_2s (MODIFY_EXPR, void_type_node, - arg4_tree, - prep_arg1); - /* Make sure SAVE_EXPRs get referenced early enough. */ - expr_tree - = ffecom_2 (COMPOUND_EXPR, void_type_node, - arg1_tree, - ffecom_2 (COMPOUND_EXPR, void_type_node, - arg3_tree, - ffecom_2 (COMPOUND_EXPR, void_type_node, - arg5_tree, - ffecom_2 (COMPOUND_EXPR, void_type_node, - arg5_plus_arg3, - expr_tree)))); - expr_tree - = ffecom_2 (COMPOUND_EXPR, void_type_node, - arg4_tree, - expr_tree); - - } - return expr_tree; - - case FFEINTRIN_impDERF: - case FFEINTRIN_impERF: - case FFEINTRIN_impDERFC: - case FFEINTRIN_impERFC: - break; - - case FFEINTRIN_impIARGC: - /* extern int xargc; i__1 = xargc - 1; */ - expr_tree = ffecom_2 (MINUS_EXPR, TREE_TYPE (ffecom_tree_xargc_), - ffecom_tree_xargc_, - convert (TREE_TYPE (ffecom_tree_xargc_), - integer_one_node)); - return expr_tree; - - case FFEINTRIN_impSIGNAL_func: - case FFEINTRIN_impSIGNAL_subr: - { - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - /* Pass procedure as a pointer to it, anything else by value. */ - if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY) - arg2_tree = convert (integer_type_node, ffecom_expr (arg2)); - else - arg2_tree = ffecom_ptr_to_expr (arg2); - arg2_tree = convert (TREE_TYPE (null_pointer_node), - arg2_tree); - - if (arg3 != NULL) - arg3_tree = ffecom_expr_rw (arg3); - else - arg3_tree = NULL_TREE; - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_tree) = arg2_tree; - - expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - ((codegen_imp == FFEINTRIN_impSIGNAL_subr) ? - NULL_TREE : - tree_type), - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - - if (arg3_tree != NULL_TREE) - expr_tree - = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impALARM: - { - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - /* Pass procedure as a pointer to it, anything else by value. */ - if (ffeinfo_kind (ffebld_info (arg2)) == FFEINFO_kindENTITY) - arg2_tree = convert (integer_type_node, ffecom_expr (arg2)); - else - arg2_tree = ffecom_ptr_to_expr (arg2); - arg2_tree = convert (TREE_TYPE (null_pointer_node), - arg2_tree); - - if (arg3 != NULL) - arg3_tree = ffecom_expr_rw (arg3); - else - arg3_tree = NULL_TREE; - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_tree) = arg2_tree; - - expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - - if (arg3_tree != NULL_TREE) - expr_tree - = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impCHDIR_subr: - case FFEINTRIN_impFDATE_subr: - case FFEINTRIN_impFGET_subr: - case FFEINTRIN_impFPUT_subr: - case FFEINTRIN_impGETCWD_subr: - case FFEINTRIN_impHOSTNM_subr: - case FFEINTRIN_impSYSTEM_subr: - case FFEINTRIN_impUNLINK_subr: - { - tree arg1_len = integer_zero_node; - tree arg1_tree; - tree arg2_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len); - - if (arg2 != NULL) - arg2_tree = ffecom_expr_rw (arg2); - else - arg2_tree = NULL_TREE; - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg1_len = build_tree_list (NULL_TREE, arg1_len); - TREE_CHAIN (arg1_tree) = arg1_len; - - expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - - if (arg2_tree != NULL_TREE) - expr_tree - = ffecom_modify (NULL_TREE, arg2_tree, - convert (TREE_TYPE (arg2_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impEXIT: - if (arg1 != NULL) - break; - - expr_tree = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type - (ffecom_integer_type_node), - integer_zero_node)); - - return - ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - void_type_node, - expr_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - - case FFEINTRIN_impFLUSH: - if (arg1 == NULL) - gfrt = FFECOM_gfrtFLUSH; - else - gfrt = FFECOM_gfrtFLUSH1; - break; - - case FFEINTRIN_impCHMOD_subr: - case FFEINTRIN_impLINK_subr: - case FFEINTRIN_impRENAME_subr: - case FFEINTRIN_impSYMLNK_subr: - { - tree arg1_len = integer_zero_node; - tree arg1_tree; - tree arg2_len = integer_zero_node; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len); - arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len); - if (arg3 != NULL) - arg3_tree = ffecom_expr_rw (arg3); - else - arg3_tree = NULL_TREE; - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg1_len = build_tree_list (NULL_TREE, arg1_len); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - arg2_len = build_tree_list (NULL_TREE, arg2_len); - TREE_CHAIN (arg1_tree) = arg2_tree; - TREE_CHAIN (arg2_tree) = arg1_len; - TREE_CHAIN (arg1_len) = arg2_len; - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - if (arg3_tree != NULL_TREE) - expr_tree = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impLSTAT_subr: - case FFEINTRIN_impSTAT_subr: - { - tree arg1_len = integer_zero_node; - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len); - - arg2_tree = ffecom_ptr_to_expr (arg2); - - if (arg3 != NULL) - arg3_tree = ffecom_expr_rw (arg3); - else - arg3_tree = NULL_TREE; - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg1_len = build_tree_list (NULL_TREE, arg1_len); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_tree) = arg2_tree; - TREE_CHAIN (arg2_tree) = arg1_len; - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - if (arg3_tree != NULL_TREE) - expr_tree = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impFGETC_subr: - case FFEINTRIN_impFPUTC_subr: - { - tree arg1_tree; - tree arg2_tree; - tree arg2_len = integer_zero_node; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - arg2_tree = ffecom_arg_ptr_to_expr (arg2, &arg2_len); - arg3_tree = ffecom_expr_rw (arg3); - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - arg2_len = build_tree_list (NULL_TREE, arg2_len); - TREE_CHAIN (arg1_tree) = arg2_tree; - TREE_CHAIN (arg2_tree) = arg2_len; - - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - expr_tree = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impFSTAT_subr: - { - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - arg2_tree = convert (ffecom_f2c_ptr_to_integer_type_node, - ffecom_ptr_to_expr (arg2)); - - if (arg3 == NULL) - arg3_tree = NULL_TREE; - else - arg3_tree = ffecom_expr_rw (arg3); - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_tree) = arg2_tree; - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - if (arg3_tree != NULL_TREE) { - expr_tree = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - } - return expr_tree; - - case FFEINTRIN_impKILL_subr: - { - tree arg1_tree; - tree arg2_tree; - tree arg3_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - arg2_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg2)); - arg2_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg2_tree)), - arg2_tree); - - if (arg3 == NULL) - arg3_tree = NULL_TREE; - else - arg3_tree = ffecom_expr_rw (arg3); - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_tree) = arg2_tree; - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - if (arg3_tree != NULL_TREE) { - expr_tree = ffecom_modify (NULL_TREE, arg3_tree, - convert (TREE_TYPE (arg3_tree), - expr_tree)); - } - } - return expr_tree; - - case FFEINTRIN_impCTIME_subr: - case FFEINTRIN_impTTYNAM_subr: - { - tree arg1_len = integer_zero_node; - tree arg1_tree; - tree arg2_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_arg_ptr_to_expr (arg1, &arg1_len); - - arg2_tree = convert (((gfrt == FFEINTRIN_impCTIME_subr) ? - ffecom_f2c_longint_type_node : - ffecom_f2c_integer_type_node), - ffecom_expr (arg2)); - arg2_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg2_tree)), - arg2_tree); - - ffecom_pop_calltemps (); - - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - arg1_len = build_tree_list (NULL_TREE, arg1_len); - arg2_tree = build_tree_list (NULL_TREE, arg2_tree); - TREE_CHAIN (arg1_len) = arg2_tree; - TREE_CHAIN (arg1_tree) = arg1_len; - - expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - arg1_tree, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - } - return expr_tree; - - case FFEINTRIN_impIRAND: - case FFEINTRIN_impRAND: - /* Arg defaults to 0 (normal random case) */ - { - tree arg1_tree; - - if (arg1 == NULL) - arg1_tree = ffecom_integer_zero_node; - else - arg1_tree = ffecom_expr (arg1); - arg1_tree = convert (ffecom_f2c_integer_type_node, - arg1_tree); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - arg1_tree = build_tree_list (NULL_TREE, arg1_tree); - - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - ((codegen_imp == FFEINTRIN_impIRAND) ? - ffecom_f2c_integer_type_node : - ffecom_f2c_real_type_node), - arg1_tree, - dest_tree, dest, dest_used, - NULL_TREE, TRUE); - } - return expr_tree; - - case FFEINTRIN_impFTELL_subr: - case FFEINTRIN_impUMASK_subr: - { - tree arg1_tree; - tree arg2_tree; - - ffecom_push_calltemps (); - - arg1_tree = convert (ffecom_f2c_integer_type_node, - ffecom_expr (arg1)); - arg1_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (arg1_tree)), - arg1_tree); - - if (arg2 == NULL) - arg2_tree = NULL_TREE; - else - arg2_tree = ffecom_expr_rw (arg2); - - ffecom_pop_calltemps (); - - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - build_tree_list (NULL_TREE, arg1_tree), - NULL_TREE, NULL, NULL, NULL_TREE, - TRUE); - if (arg2_tree != NULL_TREE) { - expr_tree = ffecom_modify (NULL_TREE, arg2_tree, - convert (TREE_TYPE (arg2_tree), - expr_tree)); - } - } - return expr_tree; - - case FFEINTRIN_impCPU_TIME: - case FFEINTRIN_impSECOND_subr: - { - tree arg1_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_expr_rw (arg1); - - ffecom_pop_calltemps (); - - expr_tree - = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - NULL_TREE, - NULL_TREE, NULL, NULL, NULL_TREE, TRUE); - - expr_tree - = ffecom_modify (NULL_TREE, arg1_tree, - convert (TREE_TYPE (arg1_tree), - expr_tree)); - } - return expr_tree; - - case FFEINTRIN_impDTIME_subr: - case FFEINTRIN_impETIME_subr: - { - tree arg1_tree; - tree arg2_tree; - - ffecom_push_calltemps (); - - arg1_tree = ffecom_expr_rw (arg1); - - arg2_tree = ffecom_ptr_to_expr (arg2); - - ffecom_pop_calltemps (); - - expr_tree = ffecom_call_ (ffecom_gfrt_tree_ (gfrt), - ffecom_gfrt_kindtype (gfrt), - FALSE, - NULL_TREE, - build_tree_list (NULL_TREE, arg2_tree), - NULL_TREE, NULL, NULL, NULL_TREE, - TRUE); - expr_tree = ffecom_modify (NULL_TREE, arg1_tree, - convert (TREE_TYPE (arg1_tree), - expr_tree)); - } - return expr_tree; - - /* Straightforward calls of libf2c routines: */ - case FFEINTRIN_impABORT: - case FFEINTRIN_impACCESS: - case FFEINTRIN_impBESJ0: - case FFEINTRIN_impBESJ1: - case FFEINTRIN_impBESJN: - case FFEINTRIN_impBESY0: - case FFEINTRIN_impBESY1: - case FFEINTRIN_impBESYN: - case FFEINTRIN_impCHDIR_func: - case FFEINTRIN_impCHMOD_func: - case FFEINTRIN_impDATE: - case FFEINTRIN_impDATE_AND_TIME: - case FFEINTRIN_impDBESJ0: - case FFEINTRIN_impDBESJ1: - case FFEINTRIN_impDBESJN: - case FFEINTRIN_impDBESY0: - case FFEINTRIN_impDBESY1: - case FFEINTRIN_impDBESYN: - case FFEINTRIN_impDTIME_func: - case FFEINTRIN_impETIME_func: - case FFEINTRIN_impFGETC_func: - case FFEINTRIN_impFGET_func: - case FFEINTRIN_impFNUM: - case FFEINTRIN_impFPUTC_func: - case FFEINTRIN_impFPUT_func: - case FFEINTRIN_impFSEEK: - case FFEINTRIN_impFSTAT_func: - case FFEINTRIN_impFTELL_func: - case FFEINTRIN_impGERROR: - case FFEINTRIN_impGETARG: - case FFEINTRIN_impGETCWD_func: - case FFEINTRIN_impGETENV: - case FFEINTRIN_impGETGID: - case FFEINTRIN_impGETLOG: - case FFEINTRIN_impGETPID: - case FFEINTRIN_impGETUID: - case FFEINTRIN_impGMTIME: - case FFEINTRIN_impHOSTNM_func: - case FFEINTRIN_impIDATE_unix: - case FFEINTRIN_impIDATE_vxt: - case FFEINTRIN_impIERRNO: - case FFEINTRIN_impISATTY: - case FFEINTRIN_impITIME: - case FFEINTRIN_impKILL_func: - case FFEINTRIN_impLINK_func: - case FFEINTRIN_impLNBLNK: - case FFEINTRIN_impLSTAT_func: - case FFEINTRIN_impLTIME: - case FFEINTRIN_impMCLOCK8: - case FFEINTRIN_impMCLOCK: - case FFEINTRIN_impPERROR: - case FFEINTRIN_impRENAME_func: - case FFEINTRIN_impSECNDS: - case FFEINTRIN_impSECOND_func: - case FFEINTRIN_impSLEEP: - case FFEINTRIN_impSRAND: - case FFEINTRIN_impSTAT_func: - case FFEINTRIN_impSYMLNK_func: - case FFEINTRIN_impSYSTEM_CLOCK: - case FFEINTRIN_impSYSTEM_func: - case FFEINTRIN_impTIME8: - case FFEINTRIN_impTIME_unix: - case FFEINTRIN_impTIME_vxt: - case FFEINTRIN_impUMASK_func: - case FFEINTRIN_impUNLINK_func: - break; - - case FFEINTRIN_impCTIME_func: /* CHARACTER functions not handled here. */ - case FFEINTRIN_impFDATE_func: /* CHARACTER functions not handled here. */ - case FFEINTRIN_impTTYNAM_func: /* CHARACTER functions not handled here. */ - case FFEINTRIN_impNONE: - case FFEINTRIN_imp: /* Hush up gcc warning. */ - fprintf (stderr, "No %s implementation.\n", - ffeintrin_name_implementation (ffebld_symter_implementation (ffebld_left (expr)))); - assert ("unimplemented intrinsic" == NULL); - return error_mark_node; - } - - assert (gfrt != FFECOM_gfrt); /* Must have an implementation! */ - - ffecom_push_calltemps (); - expr_tree = ffecom_arglist_expr_ (ffecom_gfrt_args_ (gfrt), - ffebld_right (expr)); - ffecom_pop_calltemps (); - - return ffecom_call_ (ffecom_gfrt_tree_ (gfrt), ffecom_gfrt_kindtype (gfrt), - (ffe_is_f2c_library () && ffecom_gfrt_complex_[gfrt]), - tree_type, - expr_tree, dest_tree, dest, dest_used, - NULL_TREE, TRUE); - - /**INDENT* (Do not reformat this comment even with -fca option.) - Data-gathering files: Given the source file listed below, compiled with - f2c I obtained the output file listed after that, and from the output - file I derived the above code. - --------- (begin input file to f2c) - implicit none - character*10 A1,A2 - complex C1,C2 - integer I1,I2 - real R1,R2 - double precision D1,D2 -C - call getem(A1,A2,C1,C2,I1,I2,R1,R2,D1,D2) -c / - call fooI(I1/I2) - call fooR(R1/I1) - call fooD(D1/I1) - call fooC(C1/I1) - call fooR(R1/R2) - call fooD(R1/D1) - call fooD(D1/D2) - call fooD(D1/R1) - call fooC(C1/C2) - call fooC(C1/R1) - call fooZ(C1/D1) -c ** - call fooI(I1**I2) - call fooR(R1**I1) - call fooD(D1**I1) - call fooC(C1**I1) - call fooR(R1**R2) - call fooD(R1**D1) - call fooD(D1**D2) - call fooD(D1**R1) - call fooC(C1**C2) - call fooC(C1**R1) - call fooZ(C1**D1) -c FFEINTRIN_impABS - call fooR(ABS(R1)) -c FFEINTRIN_impACOS - call fooR(ACOS(R1)) -c FFEINTRIN_impAIMAG - call fooR(AIMAG(C1)) -c FFEINTRIN_impAINT - call fooR(AINT(R1)) -c FFEINTRIN_impALOG - call fooR(ALOG(R1)) -c FFEINTRIN_impALOG10 - call fooR(ALOG10(R1)) -c FFEINTRIN_impAMAX0 - call fooR(AMAX0(I1,I2)) -c FFEINTRIN_impAMAX1 - call fooR(AMAX1(R1,R2)) -c FFEINTRIN_impAMIN0 - call fooR(AMIN0(I1,I2)) -c FFEINTRIN_impAMIN1 - call fooR(AMIN1(R1,R2)) -c FFEINTRIN_impAMOD - call fooR(AMOD(R1,R2)) -c FFEINTRIN_impANINT - call fooR(ANINT(R1)) -c FFEINTRIN_impASIN - call fooR(ASIN(R1)) -c FFEINTRIN_impATAN - call fooR(ATAN(R1)) -c FFEINTRIN_impATAN2 - call fooR(ATAN2(R1,R2)) -c FFEINTRIN_impCABS - call fooR(CABS(C1)) -c FFEINTRIN_impCCOS - call fooC(CCOS(C1)) -c FFEINTRIN_impCEXP - call fooC(CEXP(C1)) -c FFEINTRIN_impCHAR - call fooA(CHAR(I1)) -c FFEINTRIN_impCLOG - call fooC(CLOG(C1)) -c FFEINTRIN_impCONJG - call fooC(CONJG(C1)) -c FFEINTRIN_impCOS - call fooR(COS(R1)) -c FFEINTRIN_impCOSH - call fooR(COSH(R1)) -c FFEINTRIN_impCSIN - call fooC(CSIN(C1)) -c FFEINTRIN_impCSQRT - call fooC(CSQRT(C1)) -c FFEINTRIN_impDABS - call fooD(DABS(D1)) -c FFEINTRIN_impDACOS - call fooD(DACOS(D1)) -c FFEINTRIN_impDASIN - call fooD(DASIN(D1)) -c FFEINTRIN_impDATAN - call fooD(DATAN(D1)) -c FFEINTRIN_impDATAN2 - call fooD(DATAN2(D1,D2)) -c FFEINTRIN_impDCOS - call fooD(DCOS(D1)) -c FFEINTRIN_impDCOSH - call fooD(DCOSH(D1)) -c FFEINTRIN_impDDIM - call fooD(DDIM(D1,D2)) -c FFEINTRIN_impDEXP - call fooD(DEXP(D1)) -c FFEINTRIN_impDIM - call fooR(DIM(R1,R2)) -c FFEINTRIN_impDINT - call fooD(DINT(D1)) -c FFEINTRIN_impDLOG - call fooD(DLOG(D1)) -c FFEINTRIN_impDLOG10 - call fooD(DLOG10(D1)) -c FFEINTRIN_impDMAX1 - call fooD(DMAX1(D1,D2)) -c FFEINTRIN_impDMIN1 - call fooD(DMIN1(D1,D2)) -c FFEINTRIN_impDMOD - call fooD(DMOD(D1,D2)) -c FFEINTRIN_impDNINT - call fooD(DNINT(D1)) -c FFEINTRIN_impDPROD - call fooD(DPROD(R1,R2)) -c FFEINTRIN_impDSIGN - call fooD(DSIGN(D1,D2)) -c FFEINTRIN_impDSIN - call fooD(DSIN(D1)) -c FFEINTRIN_impDSINH - call fooD(DSINH(D1)) -c FFEINTRIN_impDSQRT - call fooD(DSQRT(D1)) -c FFEINTRIN_impDTAN - call fooD(DTAN(D1)) -c FFEINTRIN_impDTANH - call fooD(DTANH(D1)) -c FFEINTRIN_impEXP - call fooR(EXP(R1)) -c FFEINTRIN_impIABS - call fooI(IABS(I1)) -c FFEINTRIN_impICHAR - call fooI(ICHAR(A1)) -c FFEINTRIN_impIDIM - call fooI(IDIM(I1,I2)) -c FFEINTRIN_impIDNINT - call fooI(IDNINT(D1)) -c FFEINTRIN_impINDEX - call fooI(INDEX(A1,A2)) -c FFEINTRIN_impISIGN - call fooI(ISIGN(I1,I2)) -c FFEINTRIN_impLEN - call fooI(LEN(A1)) -c FFEINTRIN_impLGE - call fooL(LGE(A1,A2)) -c FFEINTRIN_impLGT - call fooL(LGT(A1,A2)) -c FFEINTRIN_impLLE - call fooL(LLE(A1,A2)) -c FFEINTRIN_impLLT - call fooL(LLT(A1,A2)) -c FFEINTRIN_impMAX0 - call fooI(MAX0(I1,I2)) -c FFEINTRIN_impMAX1 - call fooI(MAX1(R1,R2)) -c FFEINTRIN_impMIN0 - call fooI(MIN0(I1,I2)) -c FFEINTRIN_impMIN1 - call fooI(MIN1(R1,R2)) -c FFEINTRIN_impMOD - call fooI(MOD(I1,I2)) -c FFEINTRIN_impNINT - call fooI(NINT(R1)) -c FFEINTRIN_impSIGN - call fooR(SIGN(R1,R2)) -c FFEINTRIN_impSIN - call fooR(SIN(R1)) -c FFEINTRIN_impSINH - call fooR(SINH(R1)) -c FFEINTRIN_impSQRT - call fooR(SQRT(R1)) -c FFEINTRIN_impTAN - call fooR(TAN(R1)) -c FFEINTRIN_impTANH - call fooR(TANH(R1)) -c FFEINTRIN_imp_CMPLX_C - call fooC(cmplx(C1,C2)) -c FFEINTRIN_imp_CMPLX_D - call fooZ(cmplx(D1,D2)) -c FFEINTRIN_imp_CMPLX_I - call fooC(cmplx(I1,I2)) -c FFEINTRIN_imp_CMPLX_R - call fooC(cmplx(R1,R2)) -c FFEINTRIN_imp_DBLE_C - call fooD(dble(C1)) -c FFEINTRIN_imp_DBLE_D - call fooD(dble(D1)) -c FFEINTRIN_imp_DBLE_I - call fooD(dble(I1)) -c FFEINTRIN_imp_DBLE_R - call fooD(dble(R1)) -c FFEINTRIN_imp_INT_C - call fooI(int(C1)) -c FFEINTRIN_imp_INT_D - call fooI(int(D1)) -c FFEINTRIN_imp_INT_I - call fooI(int(I1)) -c FFEINTRIN_imp_INT_R - call fooI(int(R1)) -c FFEINTRIN_imp_REAL_C - call fooR(real(C1)) -c FFEINTRIN_imp_REAL_D - call fooR(real(D1)) -c FFEINTRIN_imp_REAL_I - call fooR(real(I1)) -c FFEINTRIN_imp_REAL_R - call fooR(real(R1)) -c -c FFEINTRIN_imp_INT_D: -c -c FFEINTRIN_specIDINT - call fooI(IDINT(D1)) -c -c FFEINTRIN_imp_INT_R: -c -c FFEINTRIN_specIFIX - call fooI(IFIX(R1)) -c FFEINTRIN_specINT - call fooI(INT(R1)) -c -c FFEINTRIN_imp_REAL_D: -c -c FFEINTRIN_specSNGL - call fooR(SNGL(D1)) -c -c FFEINTRIN_imp_REAL_I: -c -c FFEINTRIN_specFLOAT - call fooR(FLOAT(I1)) -c FFEINTRIN_specREAL - call fooR(REAL(I1)) -c - end --------- (end input file to f2c) - --------- (begin output from providing above input file as input to: --------- `f2c | gcc -E -C - | sed -e "s:/[*]*://:g" -e "s:[*]*[/]://:g" \ --------- -e "s:^#.*$::g"') - -// -- translated by f2c (version 19950223). - You must link the resulting object file with the libraries: - -lf2c -lm (in that order) -// - - -// f2c.h -- Standard Fortran to C header file // - -/// barf [ba:rf] 2. "He suggested using FORTRAN, and everybody barfed." - - - From The Shogakukan DICTIONARY OF NEW ENGLISH (Second edition) // - - - - -// F2C_INTEGER will normally be `int' but would be `long' on 16-bit systems // -// we assume short, float are OK // -typedef long int // long int // integer; -typedef char *address; -typedef short int shortint; -typedef float real; -typedef double doublereal; -typedef struct { real r, i; } complex; -typedef struct { doublereal r, i; } doublecomplex; -typedef long int // long int // logical; -typedef short int shortlogical; -typedef char logical1; -typedef char integer1; -// typedef long long longint; // // system-dependent // - - - - -// Extern is for use with -E // - - - - -// I/O stuff // - - - - - - - - -typedef long int // int or long int // flag; -typedef long int // int or long int // ftnlen; -typedef long int // int or long int // ftnint; - - -//external read, write// -typedef struct -{ flag cierr; - ftnint ciunit; - flag ciend; - char *cifmt; - ftnint cirec; -} cilist; - -//internal read, write// -typedef struct -{ flag icierr; - char *iciunit; - flag iciend; - char *icifmt; - ftnint icirlen; - ftnint icirnum; -} icilist; - -//open// -typedef struct -{ flag oerr; - ftnint ounit; - char *ofnm; - ftnlen ofnmlen; - char *osta; - char *oacc; - char *ofm; - ftnint orl; - char *oblnk; -} olist; - -//close// -typedef struct -{ flag cerr; - ftnint cunit; - char *csta; -} cllist; - -//rewind, backspace, endfile// -typedef struct -{ flag aerr; - ftnint aunit; -} alist; - -// inquire // -typedef struct -{ flag inerr; - ftnint inunit; - char *infile; - ftnlen infilen; - ftnint *inex; //parameters in standard's order// - ftnint *inopen; - ftnint *innum; - ftnint *innamed; - char *inname; - ftnlen innamlen; - char *inacc; - ftnlen inacclen; - char *inseq; - ftnlen inseqlen; - char *indir; - ftnlen indirlen; - char *infmt; - ftnlen infmtlen; - char *inform; - ftnint informlen; - char *inunf; - ftnlen inunflen; - ftnint *inrecl; - ftnint *innrec; - char *inblank; - ftnlen inblanklen; -} inlist; - - - -union Multitype { // for multiple entry points // - integer1 g; - shortint h; - integer i; - // longint j; // - real r; - doublereal d; - complex c; - doublecomplex z; - }; - -typedef union Multitype Multitype; - -typedef long Long; // No longer used; formerly in Namelist // - -struct Vardesc { // for Namelist // - char *name; - char *addr; - ftnlen *dims; - int type; - }; -typedef struct Vardesc Vardesc; - -struct Namelist { - char *name; - Vardesc **vars; - int nvars; - }; -typedef struct Namelist Namelist; - - - - - - - - -// procedure parameter types for -A and -C++ // - - - - -typedef int // Unknown procedure type // (*U_fp)(); -typedef shortint (*J_fp)(); -typedef integer (*I_fp)(); -typedef real (*R_fp)(); -typedef doublereal (*D_fp)(), (*E_fp)(); -typedef // Complex // void (*C_fp)(); -typedef // Double Complex // void (*Z_fp)(); -typedef logical (*L_fp)(); -typedef shortlogical (*K_fp)(); -typedef // Character // void (*H_fp)(); -typedef // Subroutine // int (*S_fp)(); - -// E_fp is for real functions when -R is not specified // -typedef void C_f; // complex function // -typedef void H_f; // character function // -typedef void Z_f; // double complex function // -typedef doublereal E_f; // real function with -R not specified // - -// undef any lower-case symbols that your C compiler predefines, e.g.: // - - -// (No such symbols should be defined in a strict ANSI C compiler. - We can avoid trouble with f2c-translated code by using - gcc -ansi [-traditional].) // - - - - - - - - - - - - - - - - - - - - - - - -// Main program // MAIN__() -{ - // System generated locals // - integer i__1; - real r__1, r__2; - doublereal d__1, d__2; - complex q__1; - doublecomplex z__1, z__2, z__3; - logical L__1; - char ch__1[1]; - - // Builtin functions // - void c_div(); - integer pow_ii(); - double pow_ri(), pow_di(); - void pow_ci(); - double pow_dd(); - void pow_zz(); - double acos(), r_imag(), r_int(), log(), r_lg10(), r_mod(), r_nint(), - asin(), atan(), atan2(), c_abs(); - void c_cos(), c_exp(), c_log(), r_cnjg(); - double cos(), cosh(); - void c_sin(), c_sqrt(); - double d_dim(), exp(), r_dim(), d_int(), d_lg10(), d_mod(), d_nint(), - d_sign(), sin(), sinh(), sqrt(), tan(), tanh(); - integer i_dim(), i_dnnt(), i_indx(), i_sign(), i_len(); - logical l_ge(), l_gt(), l_le(), l_lt(); - integer i_nint(); - double r_sign(); - - // Local variables // - extern // Subroutine // int fooa_(), fooc_(), food_(), fooi_(), foor_(), - fool_(), fooz_(), getem_(); - static char a1[10], a2[10]; - static complex c1, c2; - static doublereal d1, d2; - static integer i1, i2; - static real r1, r2; - - - getem_(a1, a2, &c1, &c2, &i1, &i2, &r1, &r2, &d1, &d2, 10L, 10L); -// / // - i__1 = i1 / i2; - fooi_(&i__1); - r__1 = r1 / i1; - foor_(&r__1); - d__1 = d1 / i1; - food_(&d__1); - d__1 = (doublereal) i1; - q__1.r = c1.r / d__1, q__1.i = c1.i / d__1; - fooc_(&q__1); - r__1 = r1 / r2; - foor_(&r__1); - d__1 = r1 / d1; - food_(&d__1); - d__1 = d1 / d2; - food_(&d__1); - d__1 = d1 / r1; - food_(&d__1); - c_div(&q__1, &c1, &c2); - fooc_(&q__1); - q__1.r = c1.r / r1, q__1.i = c1.i / r1; - fooc_(&q__1); - z__1.r = c1.r / d1, z__1.i = c1.i / d1; - fooz_(&z__1); -// ** // - i__1 = pow_ii(&i1, &i2); - fooi_(&i__1); - r__1 = pow_ri(&r1, &i1); - foor_(&r__1); - d__1 = pow_di(&d1, &i1); - food_(&d__1); - pow_ci(&q__1, &c1, &i1); - fooc_(&q__1); - d__1 = (doublereal) r1; - d__2 = (doublereal) r2; - r__1 = pow_dd(&d__1, &d__2); - foor_(&r__1); - d__2 = (doublereal) r1; - d__1 = pow_dd(&d__2, &d1); - food_(&d__1); - d__1 = pow_dd(&d1, &d2); - food_(&d__1); - d__2 = (doublereal) r1; - d__1 = pow_dd(&d1, &d__2); - food_(&d__1); - z__2.r = c1.r, z__2.i = c1.i; - z__3.r = c2.r, z__3.i = c2.i; - pow_zz(&z__1, &z__2, &z__3); - q__1.r = z__1.r, q__1.i = z__1.i; - fooc_(&q__1); - z__2.r = c1.r, z__2.i = c1.i; - z__3.r = r1, z__3.i = 0.; - pow_zz(&z__1, &z__2, &z__3); - q__1.r = z__1.r, q__1.i = z__1.i; - fooc_(&q__1); - z__2.r = c1.r, z__2.i = c1.i; - z__3.r = d1, z__3.i = 0.; - pow_zz(&z__1, &z__2, &z__3); - fooz_(&z__1); -// FFEINTRIN_impABS // - r__1 = (doublereal)(( r1 ) >= 0 ? ( r1 ) : -( r1 )) ; - foor_(&r__1); -// FFEINTRIN_impACOS // - r__1 = acos(r1); - foor_(&r__1); -// FFEINTRIN_impAIMAG // - r__1 = r_imag(&c1); - foor_(&r__1); -// FFEINTRIN_impAINT // - r__1 = r_int(&r1); - foor_(&r__1); -// FFEINTRIN_impALOG // - r__1 = log(r1); - foor_(&r__1); -// FFEINTRIN_impALOG10 // - r__1 = r_lg10(&r1); - foor_(&r__1); -// FFEINTRIN_impAMAX0 // - r__1 = (real) (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ; - foor_(&r__1); -// FFEINTRIN_impAMAX1 // - r__1 = (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ; - foor_(&r__1); -// FFEINTRIN_impAMIN0 // - r__1 = (real) (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ; - foor_(&r__1); -// FFEINTRIN_impAMIN1 // - r__1 = (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ; - foor_(&r__1); -// FFEINTRIN_impAMOD // - r__1 = r_mod(&r1, &r2); - foor_(&r__1); -// FFEINTRIN_impANINT // - r__1 = r_nint(&r1); - foor_(&r__1); -// FFEINTRIN_impASIN // - r__1 = asin(r1); - foor_(&r__1); -// FFEINTRIN_impATAN // - r__1 = atan(r1); - foor_(&r__1); -// FFEINTRIN_impATAN2 // - r__1 = atan2(r1, r2); - foor_(&r__1); -// FFEINTRIN_impCABS // - r__1 = c_abs(&c1); - foor_(&r__1); -// FFEINTRIN_impCCOS // - c_cos(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impCEXP // - c_exp(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impCHAR // - *(unsigned char *)&ch__1[0] = i1; - fooa_(ch__1, 1L); -// FFEINTRIN_impCLOG // - c_log(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impCONJG // - r_cnjg(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impCOS // - r__1 = cos(r1); - foor_(&r__1); -// FFEINTRIN_impCOSH // - r__1 = cosh(r1); - foor_(&r__1); -// FFEINTRIN_impCSIN // - c_sin(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impCSQRT // - c_sqrt(&q__1, &c1); - fooc_(&q__1); -// FFEINTRIN_impDABS // - d__1 = (( d1 ) >= 0 ? ( d1 ) : -( d1 )) ; - food_(&d__1); -// FFEINTRIN_impDACOS // - d__1 = acos(d1); - food_(&d__1); -// FFEINTRIN_impDASIN // - d__1 = asin(d1); - food_(&d__1); -// FFEINTRIN_impDATAN // - d__1 = atan(d1); - food_(&d__1); -// FFEINTRIN_impDATAN2 // - d__1 = atan2(d1, d2); - food_(&d__1); -// FFEINTRIN_impDCOS // - d__1 = cos(d1); - food_(&d__1); -// FFEINTRIN_impDCOSH // - d__1 = cosh(d1); - food_(&d__1); -// FFEINTRIN_impDDIM // - d__1 = d_dim(&d1, &d2); - food_(&d__1); -// FFEINTRIN_impDEXP // - d__1 = exp(d1); - food_(&d__1); -// FFEINTRIN_impDIM // - r__1 = r_dim(&r1, &r2); - foor_(&r__1); -// FFEINTRIN_impDINT // - d__1 = d_int(&d1); - food_(&d__1); -// FFEINTRIN_impDLOG // - d__1 = log(d1); - food_(&d__1); -// FFEINTRIN_impDLOG10 // - d__1 = d_lg10(&d1); - food_(&d__1); -// FFEINTRIN_impDMAX1 // - d__1 = (( d1 ) >= ( d2 ) ? ( d1 ) : ( d2 )) ; - food_(&d__1); -// FFEINTRIN_impDMIN1 // - d__1 = (( d1 ) <= ( d2 ) ? ( d1 ) : ( d2 )) ; - food_(&d__1); -// FFEINTRIN_impDMOD // - d__1 = d_mod(&d1, &d2); - food_(&d__1); -// FFEINTRIN_impDNINT // - d__1 = d_nint(&d1); - food_(&d__1); -// FFEINTRIN_impDPROD // - d__1 = (doublereal) r1 * r2; - food_(&d__1); -// FFEINTRIN_impDSIGN // - d__1 = d_sign(&d1, &d2); - food_(&d__1); -// FFEINTRIN_impDSIN // - d__1 = sin(d1); - food_(&d__1); -// FFEINTRIN_impDSINH // - d__1 = sinh(d1); - food_(&d__1); -// FFEINTRIN_impDSQRT // - d__1 = sqrt(d1); - food_(&d__1); -// FFEINTRIN_impDTAN // - d__1 = tan(d1); - food_(&d__1); -// FFEINTRIN_impDTANH // - d__1 = tanh(d1); - food_(&d__1); -// FFEINTRIN_impEXP // - r__1 = exp(r1); - foor_(&r__1); -// FFEINTRIN_impIABS // - i__1 = (( i1 ) >= 0 ? ( i1 ) : -( i1 )) ; - fooi_(&i__1); -// FFEINTRIN_impICHAR // - i__1 = *(unsigned char *)a1; - fooi_(&i__1); -// FFEINTRIN_impIDIM // - i__1 = i_dim(&i1, &i2); - fooi_(&i__1); -// FFEINTRIN_impIDNINT // - i__1 = i_dnnt(&d1); - fooi_(&i__1); -// FFEINTRIN_impINDEX // - i__1 = i_indx(a1, a2, 10L, 10L); - fooi_(&i__1); -// FFEINTRIN_impISIGN // - i__1 = i_sign(&i1, &i2); - fooi_(&i__1); -// FFEINTRIN_impLEN // - i__1 = i_len(a1, 10L); - fooi_(&i__1); -// FFEINTRIN_impLGE // - L__1 = l_ge(a1, a2, 10L, 10L); - fool_(&L__1); -// FFEINTRIN_impLGT // - L__1 = l_gt(a1, a2, 10L, 10L); - fool_(&L__1); -// FFEINTRIN_impLLE // - L__1 = l_le(a1, a2, 10L, 10L); - fool_(&L__1); -// FFEINTRIN_impLLT // - L__1 = l_lt(a1, a2, 10L, 10L); - fool_(&L__1); -// FFEINTRIN_impMAX0 // - i__1 = (( i1 ) >= ( i2 ) ? ( i1 ) : ( i2 )) ; - fooi_(&i__1); -// FFEINTRIN_impMAX1 // - i__1 = (integer) (doublereal)(( r1 ) >= ( r2 ) ? ( r1 ) : ( r2 )) ; - fooi_(&i__1); -// FFEINTRIN_impMIN0 // - i__1 = (( i1 ) <= ( i2 ) ? ( i1 ) : ( i2 )) ; - fooi_(&i__1); -// FFEINTRIN_impMIN1 // - i__1 = (integer) (doublereal)(( r1 ) <= ( r2 ) ? ( r1 ) : ( r2 )) ; - fooi_(&i__1); -// FFEINTRIN_impMOD // - i__1 = i1 % i2; - fooi_(&i__1); -// FFEINTRIN_impNINT // - i__1 = i_nint(&r1); - fooi_(&i__1); -// FFEINTRIN_impSIGN // - r__1 = r_sign(&r1, &r2); - foor_(&r__1); -// FFEINTRIN_impSIN // - r__1 = sin(r1); - foor_(&r__1); -// FFEINTRIN_impSINH // - r__1 = sinh(r1); - foor_(&r__1); -// FFEINTRIN_impSQRT // - r__1 = sqrt(r1); - foor_(&r__1); -// FFEINTRIN_impTAN // - r__1 = tan(r1); - foor_(&r__1); -// FFEINTRIN_impTANH // - r__1 = tanh(r1); - foor_(&r__1); -// FFEINTRIN_imp_CMPLX_C // - r__1 = c1.r; - r__2 = c2.r; - q__1.r = r__1, q__1.i = r__2; - fooc_(&q__1); -// FFEINTRIN_imp_CMPLX_D // - z__1.r = d1, z__1.i = d2; - fooz_(&z__1); -// FFEINTRIN_imp_CMPLX_I // - r__1 = (real) i1; - r__2 = (real) i2; - q__1.r = r__1, q__1.i = r__2; - fooc_(&q__1); -// FFEINTRIN_imp_CMPLX_R // - q__1.r = r1, q__1.i = r2; - fooc_(&q__1); -// FFEINTRIN_imp_DBLE_C // - d__1 = (doublereal) c1.r; - food_(&d__1); -// FFEINTRIN_imp_DBLE_D // - d__1 = d1; - food_(&d__1); -// FFEINTRIN_imp_DBLE_I // - d__1 = (doublereal) i1; - food_(&d__1); -// FFEINTRIN_imp_DBLE_R // - d__1 = (doublereal) r1; - food_(&d__1); -// FFEINTRIN_imp_INT_C // - i__1 = (integer) c1.r; - fooi_(&i__1); -// FFEINTRIN_imp_INT_D // - i__1 = (integer) d1; - fooi_(&i__1); -// FFEINTRIN_imp_INT_I // - i__1 = i1; - fooi_(&i__1); -// FFEINTRIN_imp_INT_R // - i__1 = (integer) r1; - fooi_(&i__1); -// FFEINTRIN_imp_REAL_C // - r__1 = c1.r; - foor_(&r__1); -// FFEINTRIN_imp_REAL_D // - r__1 = (real) d1; - foor_(&r__1); -// FFEINTRIN_imp_REAL_I // - r__1 = (real) i1; - foor_(&r__1); -// FFEINTRIN_imp_REAL_R // - r__1 = r1; - foor_(&r__1); - -// FFEINTRIN_imp_INT_D: // - -// FFEINTRIN_specIDINT // - i__1 = (integer) d1; - fooi_(&i__1); - -// FFEINTRIN_imp_INT_R: // - -// FFEINTRIN_specIFIX // - i__1 = (integer) r1; - fooi_(&i__1); -// FFEINTRIN_specINT // - i__1 = (integer) r1; - fooi_(&i__1); - -// FFEINTRIN_imp_REAL_D: // - -// FFEINTRIN_specSNGL // - r__1 = (real) d1; - foor_(&r__1); - -// FFEINTRIN_imp_REAL_I: // - -// FFEINTRIN_specFLOAT // - r__1 = (real) i1; - foor_(&r__1); -// FFEINTRIN_specREAL // - r__1 = (real) i1; - foor_(&r__1); - -} // MAIN__ // - --------- (end output file from f2c) - -*/ -} - -#endif -/* For power (exponentiation) where right-hand operand is type INTEGER, - generate in-line code to do it the fast way (which, if the operand - is a constant, might just mean a series of multiplies). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_expr_power_integer_ (ffebld left, ffebld right) -{ - tree l = ffecom_expr (left); - tree r = ffecom_expr (right); - tree ltype = TREE_TYPE (l); - tree rtype = TREE_TYPE (r); - tree result = NULL_TREE; - - if (l == error_mark_node - || r == error_mark_node) - return error_mark_node; - - if (TREE_CODE (r) == INTEGER_CST) - { - int sgn = tree_int_cst_sgn (r); - - if (sgn == 0) - return convert (ltype, integer_one_node); - - if ((TREE_CODE (ltype) == INTEGER_TYPE) - && (sgn < 0)) - { - /* Reciprocal of integer is either 0, -1, or 1, so after - calculating that (which we leave to the back end to do - or not do optimally), don't bother with any multiplying. */ - - result = ffecom_tree_divide_ (ltype, - convert (ltype, integer_one_node), - l, - NULL_TREE, NULL, NULL); - r = ffecom_1 (NEGATE_EXPR, - rtype, - r); - if ((TREE_INT_CST_LOW (r) & 1) == 0) - result = ffecom_1 (ABS_EXPR, rtype, - result); - } - - /* Generate appropriate series of multiplies, preceded - by divide if the exponent is negative. */ - - l = save_expr (l); - - if (sgn < 0) - { - l = ffecom_tree_divide_ (ltype, - convert (ltype, integer_one_node), - l, - NULL_TREE, NULL, NULL); - r = ffecom_1 (NEGATE_EXPR, rtype, r); - assert (TREE_CODE (r) == INTEGER_CST); - - if (tree_int_cst_sgn (r) < 0) - { /* The "most negative" number. */ - r = ffecom_1 (NEGATE_EXPR, rtype, - ffecom_2 (RSHIFT_EXPR, rtype, - r, - integer_one_node)); - l = save_expr (l); - l = ffecom_2 (MULT_EXPR, ltype, - l, - l); - } - } - - for (;;) - { - if (TREE_INT_CST_LOW (r) & 1) - { - if (result == NULL_TREE) - result = l; - else - result = ffecom_2 (MULT_EXPR, ltype, - result, - l); - } - - r = ffecom_2 (RSHIFT_EXPR, rtype, - r, - integer_one_node); - if (integer_zerop (r)) - break; - assert (TREE_CODE (r) == INTEGER_CST); - - l = save_expr (l); - l = ffecom_2 (MULT_EXPR, ltype, - l, - l); - } - return result; - } - - /* Though rhs isn't a constant, in-line code cannot be expanded - while transforming dummies - because the back end cannot be easily convinced to generate - stores (MODIFY_EXPR), handle temporaries, and so on before - all the appropriate rtx's have been generated for things like - dummy args referenced in rhs -- which doesn't happen until - store_parm_decls() is called (expand_function_start, I believe, - does the actual rtx-stuffing of PARM_DECLs). - - So, in this case, let the caller generate the call to the - run-time-library function to evaluate the power for us. */ - - if (ffecom_transform_only_dummies_) - return NULL_TREE; - - /* Right-hand operand not a constant, expand in-line code to figure - out how to do the multiplies, &c. - - The returned expression is expressed this way in GNU C, where l and - r are the "inputs": - - ({ typeof (r) rtmp = r; - typeof (l) ltmp = l; - typeof (l) result; - - if (rtmp == 0) - result = 1; - else - { - if ((basetypeof (l) == basetypeof (int)) - && (rtmp < 0)) - { - result = ((typeof (l)) 1) / ltmp; - if ((ltmp < 0) && (((-rtmp) & 1) == 0)) - result = -result; - } - else - { - result = 1; - if ((basetypeof (l) != basetypeof (int)) - && (rtmp < 0)) - { - ltmp = ((typeof (l)) 1) / ltmp; - rtmp = -rtmp; - if (rtmp < 0) - { - rtmp = -(rtmp >> 1); - ltmp *= ltmp; - } - } - for (;;) - { - if (rtmp & 1) - result *= ltmp; - if ((rtmp >>= 1) == 0) - break; - ltmp *= ltmp; - } - } - } - result; - }) - - Note that some of the above is compile-time collapsable, such as - the first part of the if statements that checks the base type of - l against int. The if statements are phrased that way to suggest - an easy way to generate the if/else constructs here, knowing that - the back end should (and probably does) eliminate the resulting - dead code (either the int case or the non-int case), something - it couldn't do without the redundant phrasing, requiring explicit - dead-code elimination here, which would be kind of difficult to - read. */ - - { - tree rtmp; - tree ltmp; - tree basetypeof_l_is_int; - tree se; - - basetypeof_l_is_int - = build_int_2 ((TREE_CODE (ltype) == INTEGER_TYPE), 0); - - se = expand_start_stmt_expr (); - ffecom_push_calltemps (); - - rtmp = ffecom_push_tempvar (rtype, FFETARGET_charactersizeNONE, -1, - TRUE); - ltmp = ffecom_push_tempvar (ltype, FFETARGET_charactersizeNONE, -1, - TRUE); - result = ffecom_push_tempvar (ltype, FFETARGET_charactersizeNONE, -1, - TRUE); - - expand_expr_stmt (ffecom_modify (void_type_node, - rtmp, - r)); - expand_expr_stmt (ffecom_modify (void_type_node, - ltmp, - l)); - expand_start_cond (ffecom_truth_value - (ffecom_2 (EQ_EXPR, integer_type_node, - rtmp, - convert (rtype, integer_zero_node))), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - result, - convert (ltype, integer_one_node))); - expand_start_else (); - if (!integer_zerop (basetypeof_l_is_int)) - { - expand_start_cond (ffecom_2 (LT_EXPR, integer_type_node, - rtmp, - convert (rtype, - integer_zero_node)), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - result, - ffecom_tree_divide_ - (ltype, - convert (ltype, integer_one_node), - ltmp, - NULL_TREE, NULL, NULL))); - expand_start_cond (ffecom_truth_value - (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node, - ffecom_2 (LT_EXPR, integer_type_node, - ltmp, - convert (ltype, - integer_zero_node)), - ffecom_2 (EQ_EXPR, integer_type_node, - ffecom_2 (BIT_AND_EXPR, - rtype, - ffecom_1 (NEGATE_EXPR, - rtype, - rtmp), - convert (rtype, - integer_one_node)), - convert (rtype, - integer_zero_node)))), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - result, - ffecom_1 (NEGATE_EXPR, - ltype, - result))); - expand_end_cond (); - expand_start_else (); - } - expand_expr_stmt (ffecom_modify (void_type_node, - result, - convert (ltype, integer_one_node))); - expand_start_cond (ffecom_truth_value - (ffecom_2 (TRUTH_ANDIF_EXPR, integer_type_node, - ffecom_truth_value_invert - (basetypeof_l_is_int), - ffecom_2 (LT_EXPR, integer_type_node, - rtmp, - convert (rtype, - integer_zero_node)))), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - ltmp, - ffecom_tree_divide_ - (ltype, - convert (ltype, integer_one_node), - ltmp, - NULL_TREE, NULL, NULL))); - expand_expr_stmt (ffecom_modify (void_type_node, - rtmp, - ffecom_1 (NEGATE_EXPR, rtype, - rtmp))); - expand_start_cond (ffecom_truth_value - (ffecom_2 (LT_EXPR, integer_type_node, - rtmp, - convert (rtype, integer_zero_node))), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - rtmp, - ffecom_1 (NEGATE_EXPR, rtype, - ffecom_2 (RSHIFT_EXPR, - rtype, - rtmp, - integer_one_node)))); - expand_expr_stmt (ffecom_modify (void_type_node, - ltmp, - ffecom_2 (MULT_EXPR, ltype, - ltmp, - ltmp))); - expand_end_cond (); - expand_end_cond (); - expand_start_loop (1); - expand_start_cond (ffecom_truth_value - (ffecom_2 (BIT_AND_EXPR, rtype, - rtmp, - convert (rtype, integer_one_node))), - 0); - expand_expr_stmt (ffecom_modify (void_type_node, - result, - ffecom_2 (MULT_EXPR, ltype, - result, - ltmp))); - expand_end_cond (); - expand_exit_loop_if_false (NULL, - ffecom_truth_value - (ffecom_modify (rtype, - rtmp, - ffecom_2 (RSHIFT_EXPR, - rtype, - rtmp, - integer_one_node)))); - expand_expr_stmt (ffecom_modify (void_type_node, - ltmp, - ffecom_2 (MULT_EXPR, ltype, - ltmp, - ltmp))); - expand_end_loop (); - expand_end_cond (); - if (!integer_zerop (basetypeof_l_is_int)) - expand_end_cond (); - expand_expr_stmt (result); - - ffecom_pop_calltemps (); - result = expand_end_stmt_expr (se); - TREE_SIDE_EFFECTS (result) = 1; - } - - return result; -} - -#endif -/* ffecom_expr_transform_ -- Transform symbols in expr - - ffebld expr; // FFE expression. - ffecom_expr_transform_ (expr); - - Recursive descent on expr while transforming any untransformed SYMTERs. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_expr_transform_ (ffebld expr) -{ - tree t; - ffesymbol s; - -tail_recurse: /* :::::::::::::::::::: */ - - if (expr == NULL) - return; - - switch (ffebld_op (expr)) - { - case FFEBLD_opSYMTER: - s = ffebld_symter (expr); - t = ffesymbol_hook (s).decl_tree; - if ((t == NULL_TREE) - && ((ffesymbol_kind (s) != FFEINFO_kindNONE) - || ((ffesymbol_where (s) != FFEINFO_whereNONE) - && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC)))) - { - s = ffecom_sym_transform_ (s); - t = ffesymbol_hook (s).decl_tree; /* Sfunc expr non-dummy, - DIMENSION expr? */ - } - break; /* Ok if (t == NULL) here. */ - - case FFEBLD_opITEM: - ffecom_expr_transform_ (ffebld_head (expr)); - expr = ffebld_trail (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - default: - break; - } - - switch (ffebld_arity (expr)) - { - case 2: - ffecom_expr_transform_ (ffebld_left (expr)); - expr = ffebld_right (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - case 1: - expr = ffebld_left (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - default: - break; - } - - return; -} - -#endif -/* Make a type based on info in live f2c.h file. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_f2c_make_type_ (tree *type, int tcode, char *name) -{ - switch (tcode) - { - case FFECOM_f2ccodeCHAR: - *type = make_signed_type (CHAR_TYPE_SIZE); - break; - - case FFECOM_f2ccodeSHORT: - *type = make_signed_type (SHORT_TYPE_SIZE); - break; - - case FFECOM_f2ccodeINT: - *type = make_signed_type (INT_TYPE_SIZE); - break; - - case FFECOM_f2ccodeLONG: - *type = make_signed_type (LONG_TYPE_SIZE); - break; - - case FFECOM_f2ccodeLONGLONG: - *type = make_signed_type (LONG_LONG_TYPE_SIZE); - break; - - case FFECOM_f2ccodeCHARPTR: - *type = build_pointer_type (DEFAULT_SIGNED_CHAR - ? signed_char_type_node - : unsigned_char_type_node); - break; - - case FFECOM_f2ccodeFLOAT: - *type = make_node (REAL_TYPE); - TYPE_PRECISION (*type) = FLOAT_TYPE_SIZE; - layout_type (*type); - break; - - case FFECOM_f2ccodeDOUBLE: - *type = make_node (REAL_TYPE); - TYPE_PRECISION (*type) = DOUBLE_TYPE_SIZE; - layout_type (*type); - break; - - case FFECOM_f2ccodeLONGDOUBLE: - *type = make_node (REAL_TYPE); - TYPE_PRECISION (*type) = LONG_DOUBLE_TYPE_SIZE; - layout_type (*type); - break; - - case FFECOM_f2ccodeTWOREALS: - *type = ffecom_make_complex_type_ (ffecom_f2c_real_type_node); - break; - - case FFECOM_f2ccodeTWODOUBLEREALS: - *type = ffecom_make_complex_type_ (ffecom_f2c_doublereal_type_node); - break; - - default: - assert ("unexpected FFECOM_f2ccodeXYZZY!" == NULL); - *type = error_mark_node; - return; - } - - pushdecl (build_decl (TYPE_DECL, - ffecom_get_invented_identifier ("__g77_f2c_%s", - name, 0), - *type)); -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -/* Set the f2c list-directed-I/O code for whatever (integral) type has the - given size. */ - -static void -ffecom_f2c_set_lio_code_ (ffeinfoBasictype bt, int size, - int code) -{ - int j; - tree t; - - for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) - if (((t = ffecom_tree_type[bt][j]) != NULL_TREE) - && (TREE_INT_CST_LOW (TYPE_SIZE (t)) == size)) - { - assert (code != -1); - ffecom_f2c_typecode_[bt][j] = code; - code = -1; - } -} - -#endif -/* Finish up globals after doing all program units in file - - Need to handle only uninitialized COMMON areas. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffeglobal -ffecom_finish_global_ (ffeglobal global) -{ - tree cbtype; - tree cbt; - tree size; - - if (ffeglobal_type (global) != FFEGLOBAL_typeCOMMON) - return global; - - if (ffeglobal_common_init (global)) - return global; - - cbt = ffeglobal_hook (global); - if ((cbt == NULL_TREE) - || !ffeglobal_common_have_size (global)) - return global; /* No need to make common, never ref'd. */ - - suspend_momentary (); - - DECL_EXTERNAL (cbt) = 0; - - /* Give the array a size now. */ - - size = build_int_2 ((ffeglobal_common_size (global) - + ffeglobal_common_pad (global)) - 1, - 0); - - cbtype = TREE_TYPE (cbt); - TYPE_DOMAIN (cbtype) = build_range_type (integer_type_node, - integer_zero_node, - size); - if (!TREE_TYPE (size)) - TREE_TYPE (size) = TYPE_DOMAIN (cbtype); - layout_type (cbtype); - - cbt = start_decl (cbt, FALSE); - assert (cbt == ffeglobal_hook (global)); - - finish_decl (cbt, NULL_TREE, FALSE); - - return global; -} - -#endif -/* Finish up any untransformed symbols. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffesymbol -ffecom_finish_symbol_transform_ (ffesymbol s) -{ - if ((s == NULL) || (TREE_CODE (current_function_decl) == ERROR_MARK)) - return s; - - /* It's easy to know to transform an untransformed symbol, to make sure - we put out debugging info for it. But COMMON variables, unlike - EQUIVALENCE ones, aren't given declarations in addition to the - tree expressions that specify offsets, because COMMON variables - can be referenced in the outer scope where only dummy arguments - (PARM_DECLs) should really be seen. To be safe, just don't do any - VAR_DECLs for COMMON variables when we transform them for real - use, and therefore we do all the VAR_DECL creating here. */ - - if (ffesymbol_hook (s).decl_tree == NULL_TREE) - { - if (ffesymbol_kind (s) != FFEINFO_kindNONE - || (ffesymbol_where (s) != FFEINFO_whereNONE - && ffesymbol_where (s) != FFEINFO_whereINTRINSIC - && ffesymbol_where (s) != FFEINFO_whereDUMMY)) - /* Not transformed, and not CHARACTER*(*), and not a dummy - argument, which can happen only if the entry point names - it "rides in on" are all invalidated for other reasons. */ - s = ffecom_sym_transform_ (s); - } - - if ((ffesymbol_where (s) == FFEINFO_whereCOMMON) - && (ffesymbol_hook (s).decl_tree != error_mark_node)) - { -#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING - int yes = suspend_momentary (); - - /* This isn't working, at least for dbxout. The .s file looks - okay to me (burley), but in gdb 4.9 at least, the variables - appear to reside somewhere outside of the common area, so - it doesn't make sense to mislead anyone by generating the info - on those variables until this is fixed. NOTE: Same problem - with EQUIVALENCE, sadly...see similar #if later. */ - ffecom_member_phase2_ (ffesymbol_storage (ffesymbol_common (s)), - ffesymbol_storage (s)); - - resume_momentary (yes); -#endif - } - - return s; -} - -#endif -/* Append underscore(s) to name before calling get_identifier. "us" - is nonzero if the name already contains an underscore and thus - needs two underscores appended. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_get_appended_identifier_ (char us, char *name) -{ - int i; - char *newname; - tree id; - - newname = xmalloc ((i = strlen (name)) + 1 - + ffe_is_underscoring () - + us); - memcpy (newname, name, i); - newname[i] = '_'; - newname[i + us] = '_'; - newname[i + 1 + us] = '\0'; - id = get_identifier (newname); - - free (newname); - - return id; -} - -#endif -/* Decide whether to append underscore to name before calling - get_identifier. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_get_external_identifier_ (ffesymbol s) -{ - char us; - char *name = ffesymbol_text (s); - - /* If name is a built-in name, just return it as is. */ - - if (!ffe_is_underscoring () - || (strcmp (name, FFETARGET_nameBLANK_COMMON) == 0) -#if FFETARGET_isENFORCED_MAIN_NAME - || (strcmp (name, FFETARGET_nameENFORCED_NAME) == 0) -#else - || (strcmp (name, FFETARGET_nameUNNAMED_MAIN) == 0) -#endif - || (strcmp (name, FFETARGET_nameUNNAMED_BLOCK_DATA) == 0)) - return get_identifier (name); - - us = ffe_is_second_underscore () - ? (strchr (name, '_') != NULL) - : 0; - - return ffecom_get_appended_identifier_ (us, name); -} - -#endif -/* Decide whether to append underscore to internal name before calling - get_identifier. - - This is for non-external, top-function-context names only. Transform - identifier so it doesn't conflict with the transformed result - of using a _different_ external name. E.g. if "CALL FOO" is - transformed into "FOO_();", then the variable in "FOO_ = 3" - must be transformed into something that does not conflict, since - these two things should be independent. - - The transformation is as follows. If the name does not contain - an underscore, there is no possible conflict, so just return. - If the name does contain an underscore, then transform it just - like we transform an external identifier. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_get_identifier_ (char *name) -{ - /* If name does not contain an underscore, just return it as is. */ - - if (!ffe_is_underscoring () - || (strchr (name, '_') == NULL)) - return get_identifier (name); - - return ffecom_get_appended_identifier_ (ffe_is_second_underscore (), - name); -} - -#endif -/* ffecom_gen_sfuncdef_ -- Generate definition of statement function - - tree t; - ffesymbol s; // kindFUNCTION, whereIMMEDIATE. - t = ffecom_gen_sfuncdef_(s,ffesymbol_basictype(s), - ffesymbol_kindtype(s)); - - Call after setting up containing function and getting trees for all - other symbols. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_gen_sfuncdef_ (ffesymbol s, ffeinfoBasictype bt, ffeinfoKindtype kt) -{ - ffebld expr = ffesymbol_sfexpr (s); - tree type; - tree func; - tree result; - bool charfunc = (bt == FFEINFO_basictypeCHARACTER); - static bool recurse = FALSE; - int yes; - int old_lineno = lineno; - char *old_input_filename = input_filename; - - ffecom_nested_entry_ = s; - - /* For now, we don't have a handy pointer to where the sfunc is actually - defined, though that should be easy to add to an ffesymbol. (The - token/where info available might well point to the place where the type - of the sfunc is declared, especially if that precedes the place where - the sfunc itself is defined, which is typically the case.) We should - put out a null pointer rather than point somewhere wrong, but I want to - see how it works at this point. */ - - input_filename = ffesymbol_where_filename (s); - lineno = ffesymbol_where_filelinenum (s); - - /* Pretransform the expression so any newly discovered things belong to the - outer program unit, not to the statement function. */ - - ffecom_expr_transform_ (expr); - - /* Make sure no recursive invocation of this fn (a specific case of failing - to pretransform an sfunc's expression, i.e. where its expression - references another untransformed sfunc) happens. */ - - assert (!recurse); - recurse = TRUE; - - yes = suspend_momentary (); - - push_f_function_context (); - - ffecom_push_calltemps (); - - if (charfunc) - type = void_type_node; - else - { - type = ffecom_tree_type[bt][kt]; - if (type == NULL_TREE) - type = integer_type_node; /* _sym_exec_transition reports - error. */ - } - - start_function (ffecom_get_identifier_ (ffesymbol_text (s)), - build_function_type (type, NULL_TREE), - 1, /* nested/inline */ - 0); /* TREE_PUBLIC */ - - /* We don't worry about COMPLEX return values here, because this is - entirely internal to our code, and gcc has the ability to return COMPLEX - directly as a value. */ - - yes = suspend_momentary (); - - if (charfunc) - { /* Prepend arg for where result goes. */ - tree type; - - type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt]; - - result = ffecom_get_invented_identifier ("__g77_%s", - "result", 0); - - ffecom_char_enhance_arg_ (&type, s); /* Ignore returned length. */ - - type = build_pointer_type (type); - result = build_decl (PARM_DECL, result, type); - - push_parm_decl (result); - } - else - result = NULL_TREE; /* Not ref'd if !charfunc. */ - - ffecom_push_dummy_decls_ (ffesymbol_dummyargs (s), TRUE); - - resume_momentary (yes); - - store_parm_decls (0); - - ffecom_start_compstmt_ (); - - if (expr != NULL) - { - if (charfunc) - { - ffetargetCharacterSize sz = ffesymbol_size (s); - tree result_length; - - result_length = build_int_2 (sz, 0); - TREE_TYPE (result_length) = ffecom_f2c_ftnlen_type_node; - - ffecom_let_char_ (result, result_length, sz, expr); - expand_null_return (); - } - else - expand_return (ffecom_modify (NULL_TREE, - DECL_RESULT (current_function_decl), - ffecom_expr (expr))); - - clear_momentary (); - } - - ffecom_end_compstmt_ (); - - func = current_function_decl; - finish_function (1); - - ffecom_pop_calltemps (); - - pop_f_function_context (); - - resume_momentary (yes); - - recurse = FALSE; - - lineno = old_lineno; - input_filename = old_input_filename; - - ffecom_nested_entry_ = NULL; - - return func; -} - -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static char * -ffecom_gfrt_args_ (ffecomGfrt ix) -{ - return ffecom_gfrt_argstring_[ix]; -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_gfrt_tree_ (ffecomGfrt ix) -{ - if (ffecom_gfrt_[ix] == NULL_TREE) - ffecom_make_gfrt_ (ix); - - return ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (ffecom_gfrt_[ix])), - ffecom_gfrt_[ix]); -} - -#endif -/* Return initialize-to-zero expression for this VAR_DECL. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_init_zero_ (tree decl) -{ - tree init; - int incremental = TREE_STATIC (decl); - tree type = TREE_TYPE (decl); - - if (incremental) - { - int momentary = suspend_momentary (); - push_obstacks_nochange (); - if (TREE_PERMANENT (decl)) - end_temporary_allocation (); - make_decl_rtl (decl, NULL, TREE_PUBLIC (decl) ? 1 : 0); - assemble_variable (decl, TREE_PUBLIC (decl) ? 1 : 0, 0, 1); - pop_obstacks (); - resume_momentary (momentary); - } - - push_momentary (); - - if ((TREE_CODE (type) != ARRAY_TYPE) - && (TREE_CODE (type) != RECORD_TYPE) - && (TREE_CODE (type) != UNION_TYPE) - && !incremental) - init = convert (type, integer_zero_node); - else if (!incremental) - { - int momentary = suspend_momentary (); - - init = build (CONSTRUCTOR, type, NULL_TREE, NULL_TREE); - TREE_CONSTANT (init) = 1; - TREE_STATIC (init) = 1; - - resume_momentary (momentary); - } - else - { - int momentary = suspend_momentary (); - - assemble_zeros (int_size_in_bytes (type)); - init = error_mark_node; - - resume_momentary (momentary); - } - - pop_momentary_nofree (); - - return init; -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_intrinsic_ichar_ (tree tree_type, ffebld arg, - tree *maybe_tree) -{ - tree expr_tree; - tree length_tree; - - switch (ffebld_op (arg)) - { - case FFEBLD_opCONTER: /* For F90, check 0-length. */ - if (ffetarget_length_character1 - (ffebld_constant_character1 - (ffebld_conter (arg))) == 0) - { - *maybe_tree = integer_zero_node; - return convert (tree_type, integer_zero_node); - } - - *maybe_tree = integer_one_node; - expr_tree = build_int_2 (*ffetarget_text_character1 - (ffebld_constant_character1 - (ffebld_conter (arg))), - 0); - TREE_TYPE (expr_tree) = tree_type; - return expr_tree; - - case FFEBLD_opSYMTER: - case FFEBLD_opARRAYREF: - case FFEBLD_opFUNCREF: - case FFEBLD_opSUBSTR: - ffecom_push_calltemps (); - ffecom_char_args_ (&expr_tree, &length_tree, arg); - ffecom_pop_calltemps (); - - if ((expr_tree == error_mark_node) - || (length_tree == error_mark_node)) - { - *maybe_tree = error_mark_node; - return error_mark_node; - } - - if (integer_zerop (length_tree)) - { - *maybe_tree = integer_zero_node; - return convert (tree_type, integer_zero_node); - } - - expr_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))), - expr_tree); - expr_tree - = ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (expr_tree))), - expr_tree, - integer_one_node); - expr_tree = convert (tree_type, expr_tree); - - if (TREE_CODE (length_tree) == INTEGER_CST) - *maybe_tree = integer_one_node; - else /* Must check length at run time. */ - *maybe_tree - = ffecom_truth_value - (ffecom_2 (GT_EXPR, integer_type_node, - length_tree, - ffecom_f2c_ftnlen_zero_node)); - return expr_tree; - - case FFEBLD_opPAREN: - case FFEBLD_opCONVERT: - if (ffeinfo_size (ffebld_info (arg)) == 0) - { - *maybe_tree = integer_zero_node; - return convert (tree_type, integer_zero_node); - } - return ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg), - maybe_tree); - - case FFEBLD_opCONCATENATE: - { - tree maybe_left; - tree maybe_right; - tree expr_left; - tree expr_right; - - expr_left = ffecom_intrinsic_ichar_ (tree_type, ffebld_left (arg), - &maybe_left); - expr_right = ffecom_intrinsic_ichar_ (tree_type, ffebld_right (arg), - &maybe_right); - *maybe_tree = ffecom_2 (TRUTH_ORIF_EXPR, integer_type_node, - maybe_left, - maybe_right); - expr_tree = ffecom_3 (COND_EXPR, tree_type, - maybe_left, - expr_left, - expr_right); - return expr_tree; - } - - default: - assert ("bad op in ICHAR" == NULL); - return error_mark_node; - } -} - -#endif -/* ffecom_intrinsic_len_ -- Return length info for char arg (LEN()) - - tree length_arg; - ffebld expr; - length_arg = ffecom_intrinsic_len_ (expr); - - Handles CHARACTER-type CONTER, SYMTER, SUBSTR, ARRAYREF, and FUNCREF - subexpressions by constructing the appropriate tree for the - length-of-character-text argument in a calling sequence. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_intrinsic_len_ (ffebld expr) -{ - ffetargetCharacter1 val; - tree length; - - switch (ffebld_op (expr)) - { - case FFEBLD_opCONTER: - val = ffebld_constant_character1 (ffebld_conter (expr)); - length = build_int_2 (ffetarget_length_character1 (val), 0); - TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node; - break; - - case FFEBLD_opSYMTER: - { - ffesymbol s = ffebld_symter (expr); - tree item; - - item = ffesymbol_hook (s).decl_tree; - if (item == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - item = ffesymbol_hook (s).decl_tree; - } - if (ffesymbol_kind (s) == FFEINFO_kindENTITY) - { - if (ffesymbol_size (s) == FFETARGET_charactersizeNONE) - length = ffesymbol_hook (s).length_tree; - else - { - length = build_int_2 (ffesymbol_size (s), 0); - TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node; - } - } - else if (item == error_mark_node) - length = error_mark_node; - else /* FFEINFO_kindFUNCTION: */ - length = NULL_TREE; - } - break; - - case FFEBLD_opARRAYREF: - length = ffecom_intrinsic_len_ (ffebld_left (expr)); - break; - - case FFEBLD_opSUBSTR: - { - ffebld start; - ffebld end; - ffebld thing = ffebld_right (expr); - tree start_tree; - tree end_tree; - - assert (ffebld_op (thing) == FFEBLD_opITEM); - start = ffebld_head (thing); - thing = ffebld_trail (thing); - assert (ffebld_trail (thing) == NULL); - end = ffebld_head (thing); - - length = ffecom_intrinsic_len_ (ffebld_left (expr)); - - if (length == error_mark_node) - break; - - if (start == NULL) - { - if (end == NULL) - ; - else - { - length = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (end)); - } - } - else - { - start_tree = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (start)); - - if (start_tree == error_mark_node) - { - length = error_mark_node; - break; - } - - if (end == NULL) - { - length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - ffecom_2 (MINUS_EXPR, - ffecom_f2c_ftnlen_type_node, - length, - start_tree)); - } - else - { - end_tree = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (end)); - - if (end_tree == error_mark_node) - { - length = error_mark_node; - break; - } - - length = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - ffecom_2 (MINUS_EXPR, - ffecom_f2c_ftnlen_type_node, - end_tree, start_tree)); - } - } - } - break; - - case FFEBLD_opCONCATENATE: - length - = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - ffecom_intrinsic_len_ (ffebld_left (expr)), - ffecom_intrinsic_len_ (ffebld_right (expr))); - break; - - case FFEBLD_opFUNCREF: - case FFEBLD_opCONVERT: - length = build_int_2 (ffebld_size (expr), 0); - TREE_TYPE (length) = ffecom_f2c_ftnlen_type_node; - break; - - default: - assert ("bad op for single char arg expr" == NULL); - length = ffecom_f2c_ftnlen_zero_node; - break; - } - - assert (length != NULL_TREE); - - return length; -} - -#endif -/* ffecom_let_char_ -- Do assignment stuff for character type - - tree dest_tree; // destination (ADDR_EXPR) - tree dest_length; // length (INT_CST/INDIRECT_REF(PARM_DECL)) - ffetargetCharacterSize dest_size; // length - ffebld source; // source expression - ffecom_let_char_(dest_tree,dest_length,dest_size,source); - - Generates code to do the assignment. Used by ordinary assignment - statement handler ffecom_let_stmt and by statement-function - handler to generate code for a statement function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_let_char_ (tree dest_tree, tree dest_length, - ffetargetCharacterSize dest_size, ffebld source) -{ - ffecomConcatList_ catlist; - tree source_length; - tree source_tree; - tree expr_tree; - - if ((dest_tree == error_mark_node) - || (dest_length == error_mark_node)) - return; - - assert (dest_tree != NULL_TREE); - assert (dest_length != NULL_TREE); - - /* Source might be an opCONVERT, which just means it is a different size - than the destination. Since the underlying implementation here handles - that (directly or via the s_copy or s_cat run-time-library functions), - we don't need the "convenience" of an opCONVERT that tells us to - truncate or blank-pad, particularly since the resulting implementation - would probably be slower than otherwise. */ - - while (ffebld_op (source) == FFEBLD_opCONVERT) - source = ffebld_left (source); - - catlist = ffecom_concat_list_new_ (source, dest_size); - switch (ffecom_concat_list_count_ (catlist)) - { - case 0: /* Shouldn't happen, but in case it does... */ - ffecom_concat_list_kill_ (catlist); - source_tree = null_pointer_node; - source_length = ffecom_f2c_ftnlen_zero_node; - expr_tree = build_tree_list (NULL_TREE, dest_tree); - TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree); - TREE_CHAIN (TREE_CHAIN (expr_tree)) - = build_tree_list (NULL_TREE, dest_length); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))) - = build_tree_list (NULL_TREE, source_length); - - expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree); - TREE_SIDE_EFFECTS (expr_tree) = 1; - - expand_expr_stmt (expr_tree); - - return; - - case 1: /* The (fairly) easy case. */ - ffecom_char_args_ (&source_tree, &source_length, - ffecom_concat_list_expr_ (catlist, 0)); - ffecom_concat_list_kill_ (catlist); - assert (source_tree != NULL_TREE); - assert (source_length != NULL_TREE); - - if ((source_tree == error_mark_node) - || (source_length == error_mark_node)) - return; - - if (dest_size == 1) - { - dest_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE - (dest_tree))), - dest_tree); - dest_tree - = ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE - (dest_tree))), - dest_tree, - integer_one_node); - source_tree - = ffecom_1 (INDIRECT_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE - (source_tree))), - source_tree); - source_tree - = ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE - (source_tree))), - source_tree, - integer_one_node); - - expr_tree = ffecom_modify (void_type_node, dest_tree, source_tree); - - expand_expr_stmt (expr_tree); - - return; - } - - expr_tree = build_tree_list (NULL_TREE, dest_tree); - TREE_CHAIN (expr_tree) = build_tree_list (NULL_TREE, source_tree); - TREE_CHAIN (TREE_CHAIN (expr_tree)) - = build_tree_list (NULL_TREE, dest_length); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))) - = build_tree_list (NULL_TREE, source_length); - - expr_tree = ffecom_call_gfrt (FFECOM_gfrtCOPY, expr_tree); - TREE_SIDE_EFFECTS (expr_tree) = 1; - - expand_expr_stmt (expr_tree); - - return; - - default: /* Must actually concatenate things. */ - break; - } - - /* Heavy-duty concatenation. */ - - { - int count = ffecom_concat_list_count_ (catlist); - int i; - tree lengths; - tree items; - tree length_array; - tree item_array; - tree citem; - tree clength; - - length_array - = lengths - = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node, - FFETARGET_charactersizeNONE, count, TRUE); - item_array = items = ffecom_push_tempvar (ffecom_f2c_address_type_node, - FFETARGET_charactersizeNONE, - count, TRUE); - - for (i = 0; i < count; ++i) - { - ffecom_char_args_ (&citem, &clength, - ffecom_concat_list_expr_ (catlist, i)); - if ((citem == error_mark_node) - || (clength == error_mark_node)) - { - ffecom_concat_list_kill_ (catlist); - return; - } - - items - = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items), - ffecom_modify (void_type_node, - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))), - item_array, - build_int_2 (i, 0)), - citem), - items); - lengths - = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths), - ffecom_modify (void_type_node, - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))), - length_array, - build_int_2 (i, 0)), - clength), - lengths); - } - - expr_tree = build_tree_list (NULL_TREE, dest_tree); - TREE_CHAIN (expr_tree) - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (items)), - items)); - TREE_CHAIN (TREE_CHAIN (expr_tree)) - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (lengths)), - lengths)); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree))) - = build_tree_list - (NULL_TREE, - ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node, - convert (ffecom_f2c_ftnlen_type_node, - build_int_2 (count, 0)))); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (expr_tree)))) - = build_tree_list (NULL_TREE, dest_length); - - expr_tree = ffecom_call_gfrt (FFECOM_gfrtCAT, expr_tree); - TREE_SIDE_EFFECTS (expr_tree) = 1; - - expand_expr_stmt (expr_tree); - } - - ffecom_concat_list_kill_ (catlist); -} - -#endif -/* ffecom_make_gfrt_ -- Make initial info for run-time routine - - ffecomGfrt ix; - ffecom_make_gfrt_(ix); - - Assumes gfrt_[ix] is NULL_TREE, and replaces it with the FUNCTION_DECL - for the indicated run-time routine (ix). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_make_gfrt_ (ffecomGfrt ix) -{ - tree t; - tree ttype; - - push_obstacks_nochange (); - end_temporary_allocation (); - - switch (ffecom_gfrt_type_[ix]) - { - case FFECOM_rttypeVOID_: - ttype = void_type_node; - break; - - case FFECOM_rttypeVOIDSTAR_: - ttype = TREE_TYPE (null_pointer_node); /* `void *'. */ - break; - - case FFECOM_rttypeFTNINT_: - ttype = ffecom_f2c_ftnint_type_node; - break; - - case FFECOM_rttypeINTEGER_: - ttype = ffecom_f2c_integer_type_node; - break; - - case FFECOM_rttypeLONGINT_: - ttype = ffecom_f2c_longint_type_node; - break; - - case FFECOM_rttypeLOGICAL_: - ttype = ffecom_f2c_logical_type_node; - break; - - case FFECOM_rttypeREAL_F2C_: - ttype = double_type_node; - break; - - case FFECOM_rttypeREAL_GNU_: - ttype = float_type_node; - break; - - case FFECOM_rttypeCOMPLEX_F2C_: - ttype = void_type_node; - break; - - case FFECOM_rttypeCOMPLEX_GNU_: - ttype = ffecom_f2c_complex_type_node; - break; - - case FFECOM_rttypeDOUBLE_: - ttype = double_type_node; - break; - - case FFECOM_rttypeDOUBLEREAL_: - ttype = ffecom_f2c_doublereal_type_node; - break; - - case FFECOM_rttypeDBLCMPLX_F2C_: - ttype = void_type_node; - break; - - case FFECOM_rttypeDBLCMPLX_GNU_: - ttype = ffecom_f2c_doublecomplex_type_node; - break; - - case FFECOM_rttypeCHARACTER_: - ttype = void_type_node; - break; - - default: - ttype = NULL; - assert ("bad rttype" == NULL); - break; - } - - ttype = build_function_type (ttype, NULL_TREE); - t = build_decl (FUNCTION_DECL, - get_identifier (ffecom_gfrt_name_[ix]), - ttype); - DECL_EXTERNAL (t) = 1; - TREE_PUBLIC (t) = 1; - TREE_THIS_VOLATILE (t) = ffecom_gfrt_volatile_[ix] ? 1 : 0; - - t = start_decl (t, TRUE); - - finish_decl (t, NULL_TREE, TRUE); - - resume_temporary_allocation (); - pop_obstacks (); - - ffecom_gfrt_[ix] = t; -} - -#endif -/* Phase 1 pass over each member of a COMMON/EQUIVALENCE group. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_member_phase1_ (ffestorag mst UNUSED, ffestorag st) -{ - ffesymbol s = ffestorag_symbol (st); - - if (ffesymbol_namelisted (s)) - ffecom_member_namelisted_ = TRUE; -} - -#endif -/* Phase 2 pass over each member of a COMMON/EQUIVALENCE group. Declare - the member so debugger will see it. Otherwise nobody should be - referencing the member. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING -static void -ffecom_member_phase2_ (ffestorag mst, ffestorag st) -{ - ffesymbol s; - tree t; - tree mt; - tree type; - - if ((mst == NULL) - || ((mt = ffestorag_hook (mst)) == NULL) - || (mt == error_mark_node)) - return; - - if ((st == NULL) - || ((s = ffestorag_symbol (st)) == NULL)) - return; - - type = ffecom_type_localvar_ (s, - ffesymbol_basictype (s), - ffesymbol_kindtype (s)); - if (type == error_mark_node) - return; - - t = build_decl (VAR_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - type); - - TREE_STATIC (t) = TREE_STATIC (mt); - DECL_INITIAL (t) = NULL_TREE; - TREE_ASM_WRITTEN (t) = 1; - - DECL_RTL (t) - = gen_rtx (MEM, TYPE_MODE (type), - plus_constant (XEXP (DECL_RTL (mt), 0), - ffestorag_modulo (mst) - + ffestorag_offset (st) - - ffestorag_offset (mst))); - - t = start_decl (t, FALSE); - - finish_decl (t, NULL_TREE, FALSE); -} - -#endif -#endif -/* ffecom_push_dummy_decls_ -- Transform dummy args, push parm decls in order - - Ignores STAR (alternate-return) dummies. All other get exec-transitioned - (which generates their trees) and then their trees get push_parm_decl'd. - - The second arg is TRUE if the dummies are for a statement function, in - which case lengths are not pushed for character arguments (since they are - always known by both the caller and the callee, though the code allows - for someday permitting CHAR*(*) stmtfunc dummies). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_push_dummy_decls_ (ffebld dummy_list, bool stmtfunc) -{ - ffebld dummy; - ffebld dumlist; - ffesymbol s; - tree parm; - - ffecom_transform_only_dummies_ = TRUE; - - /* First push the parms corresponding to actual dummy "contents". */ - - for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist)) - { - dummy = ffebld_head (dumlist); - switch (ffebld_op (dummy)) - { - case FFEBLD_opSTAR: - case FFEBLD_opANY: - continue; /* Forget alternate returns. */ - - default: - break; - } - assert (ffebld_op (dummy) == FFEBLD_opSYMTER); - s = ffebld_symter (dummy); - parm = ffesymbol_hook (s).decl_tree; - if (parm == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - parm = ffesymbol_hook (s).decl_tree; - assert (parm != NULL_TREE); - } - if (parm != error_mark_node) - push_parm_decl (parm); - } - - /* Then, for CHARACTER dummies, push the parms giving their lengths. */ - - for (dumlist = dummy_list; dumlist != NULL; dumlist = ffebld_trail (dumlist)) - { - dummy = ffebld_head (dumlist); - switch (ffebld_op (dummy)) - { - case FFEBLD_opSTAR: - case FFEBLD_opANY: - continue; /* Forget alternate returns, they mean - NOTHING! */ - - default: - break; - } - s = ffebld_symter (dummy); - if (ffesymbol_basictype (s) != FFEINFO_basictypeCHARACTER) - continue; /* Only looking for CHARACTER arguments. */ - if (stmtfunc && (ffesymbol_size (s) != FFETARGET_charactersizeNONE)) - continue; /* Stmtfunc arg with known size needs no - length param. */ - if (ffesymbol_kind (s) != FFEINFO_kindENTITY) - continue; /* Only looking for variables and arrays. */ - parm = ffesymbol_hook (s).length_tree; - assert (parm != NULL_TREE); - if (parm != error_mark_node) - push_parm_decl (parm); - } - - ffecom_transform_only_dummies_ = FALSE; -} - -#endif -/* ffecom_start_progunit_ -- Beginning of program unit - - Does GNU back end stuff necessary to teach it about the start of its - equivalent of a Fortran program unit. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_start_progunit_ () -{ - ffesymbol fn = ffecom_primary_entry_; - ffebld arglist; - tree id; /* Identifier (name) of function. */ - tree type; /* Type of function. */ - tree result; /* Result of function. */ - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffeglobal g; - ffeglobalType gt; - ffeglobalType egt = FFEGLOBAL_type; - bool charfunc; - bool cmplxfunc; - bool altentries = (ffecom_num_entrypoints_ != 0); - bool multi - = altentries - && (ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION) - && (ffecom_master_bt_ == FFEINFO_basictypeNONE); - bool main_program = FALSE; - int old_lineno = lineno; - char *old_input_filename = input_filename; - int yes; - - assert (fn != NULL); - assert (ffesymbol_hook (fn).decl_tree == NULL_TREE); - - input_filename = ffesymbol_where_filename (fn); - lineno = ffesymbol_where_filelinenum (fn); - - /* c-parse.y indeed does call suspend_momentary and not only ignores the - return value, but also never calls resume_momentary, when starting an - outer function (see "fndef:", "setspecs:", and so on). So g77 does the - same thing. It shouldn't be a problem since start_function calls - temporary_allocation, but it might be necessary. If it causes a problem - here, then maybe there's a bug lurking in gcc. NOTE: This identical - comment appears twice in thist file. */ - - suspend_momentary (); - - switch (ffecom_primary_entry_kind_) - { - case FFEINFO_kindPROGRAM: - main_program = TRUE; - gt = FFEGLOBAL_typeMAIN; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - type = ffecom_tree_fun_type_void; - charfunc = FALSE; - cmplxfunc = FALSE; - break; - - case FFEINFO_kindBLOCKDATA: - gt = FFEGLOBAL_typeBDATA; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - type = ffecom_tree_fun_type_void; - charfunc = FALSE; - cmplxfunc = FALSE; - break; - - case FFEINFO_kindFUNCTION: - gt = FFEGLOBAL_typeFUNC; - egt = FFEGLOBAL_typeEXT; - bt = ffesymbol_basictype (fn); - kt = ffesymbol_kindtype (fn); - if (bt == FFEINFO_basictypeNONE) - { - ffeimplic_establish_symbol (fn); - if (ffesymbol_funcresult (fn) != NULL) - ffeimplic_establish_symbol (ffesymbol_funcresult (fn)); - bt = ffesymbol_basictype (fn); - kt = ffesymbol_kindtype (fn); - } - - if (multi) - charfunc = cmplxfunc = FALSE; - else if (bt == FFEINFO_basictypeCHARACTER) - charfunc = TRUE, cmplxfunc = FALSE; - else if ((bt == FFEINFO_basictypeCOMPLEX) - && ffesymbol_is_f2c (fn) - && !altentries) - charfunc = FALSE, cmplxfunc = TRUE; - else - charfunc = cmplxfunc = FALSE; - - if (multi || charfunc) - type = ffecom_tree_fun_type_void; - else if (ffesymbol_is_f2c (fn) && !altentries) - type = ffecom_tree_fun_type[bt][kt]; - else - type = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE); - - if ((type == NULL_TREE) - || (TREE_TYPE (type) == NULL_TREE)) - type = ffecom_tree_fun_type_void; /* _sym_exec_transition. */ - break; - - case FFEINFO_kindSUBROUTINE: - gt = FFEGLOBAL_typeSUBR; - egt = FFEGLOBAL_typeEXT; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - if (ffecom_is_altreturning_) - type = ffecom_tree_subr_type; - else - type = ffecom_tree_fun_type_void; - charfunc = FALSE; - cmplxfunc = FALSE; - break; - - default: - assert ("say what??" == NULL); - /* Fall through. */ - case FFEINFO_kindANY: - gt = FFEGLOBAL_typeANY; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - type = error_mark_node; - charfunc = FALSE; - cmplxfunc = FALSE; - break; - } - - if (altentries) - { - id = ffecom_get_invented_identifier ("__g77_masterfun_%s", - ffesymbol_text (fn), - 0); - } -#if FFETARGET_isENFORCED_MAIN - else if (main_program) - id = get_identifier (FFETARGET_nameENFORCED_MAIN_NAME); -#endif - else - id = ffecom_get_external_identifier_ (fn); - - start_function (id, - type, - 0, /* nested/inline */ - !altentries); /* TREE_PUBLIC */ - - TREE_USED (current_function_decl) = 1; /* Avoid spurious warning if altentries. */ - - if (!altentries - && ((g = ffesymbol_global (fn)) != NULL) - && ((ffeglobal_type (g) == gt) - || (ffeglobal_type (g) == egt))) - { - ffeglobal_set_hook (g, current_function_decl); - } - - yes = suspend_momentary (); - - /* Arg handling needs exec-transitioned ffesymbols to work with. But - exec-transitioning needs current_function_decl to be filled in. So we - do these things in two phases. */ - - if (altentries) - { /* 1st arg identifies which entrypoint. */ - ffecom_which_entrypoint_decl_ - = build_decl (PARM_DECL, - ffecom_get_invented_identifier ("__g77_%s", - "which_entrypoint", - 0), - integer_type_node); - push_parm_decl (ffecom_which_entrypoint_decl_); - } - - if (charfunc - || cmplxfunc - || multi) - { /* Arg for result (return value). */ - tree type; - tree length; - - if (charfunc) - type = ffecom_tree_type[FFEINFO_basictypeCHARACTER][kt]; - else if (cmplxfunc) - type = ffecom_tree_type[FFEINFO_basictypeCOMPLEX][kt]; - else - type = ffecom_multi_type_node_; - - result = ffecom_get_invented_identifier ("__g77_%s", - "result", 0); - - /* Make length arg _and_ enhance type info for CHAR arg itself. */ - - if (charfunc) - length = ffecom_char_enhance_arg_ (&type, fn); - else - length = NULL_TREE; /* Not ref'd if !charfunc. */ - - type = build_pointer_type (type); - result = build_decl (PARM_DECL, result, type); - - push_parm_decl (result); - if (multi) - ffecom_multi_retval_ = result; - else - ffecom_func_result_ = result; - - if (charfunc) - { - push_parm_decl (length); - ffecom_func_length_ = length; - } - } - - if (ffecom_primary_entry_is_proc_) - { - if (altentries) - arglist = ffecom_master_arglist_; - else - arglist = ffesymbol_dummyargs (fn); - ffecom_push_dummy_decls_ (arglist, FALSE); - } - - resume_momentary (yes); - - if (TREE_CODE (current_function_decl) != ERROR_MARK) - store_parm_decls (main_program ? 1 : 0); - - ffecom_start_compstmt_ (); - - lineno = old_lineno; - input_filename = old_input_filename; - - /* This handles any symbols still untransformed, in case -g specified. - This used to be done in ffecom_finish_progunit, but it turns out to - be necessary to do it here so that statement functions are - expanded before code. But don't bother for BLOCK DATA. */ - - if (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA) - ffesymbol_drive (ffecom_finish_symbol_transform_); -} - -#endif -/* ffecom_sym_transform_ -- Transform FFE sym into backend sym - - ffesymbol s; - ffecom_sym_transform_(s); - - The ffesymbol_hook info for s is updated with appropriate backend info - on the symbol. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffesymbol -ffecom_sym_transform_ (ffesymbol s) -{ - tree t; /* Transformed thingy. */ - tree tlen; /* Length if CHAR*(*). */ - bool addr; /* Is t the address of the thingy? */ - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffeglobal g; - int yes; - int old_lineno = lineno; - char *old_input_filename = input_filename; - - if (ffesymbol_sfdummyparent (s) == NULL) - { - input_filename = ffesymbol_where_filename (s); - lineno = ffesymbol_where_filelinenum (s); - } - else - { - ffesymbol sf = ffesymbol_sfdummyparent (s); - - input_filename = ffesymbol_where_filename (sf); - lineno = ffesymbol_where_filelinenum (sf); - } - - bt = ffeinfo_basictype (ffebld_info (s)); - kt = ffeinfo_kindtype (ffebld_info (s)); - - t = NULL_TREE; - tlen = NULL_TREE; - addr = FALSE; - - switch (ffesymbol_kind (s)) - { - case FFEINFO_kindNONE: - switch (ffesymbol_where (s)) - { - case FFEINFO_whereDUMMY: /* Subroutine or function. */ - assert (ffecom_transform_only_dummies_); - - /* Before 0.4, this could be ENTITY/DUMMY, but see - ffestu_sym_end_transition -- no longer true (in particular, if - it could be an ENTITY, it _will_ be made one, so that - possibility won't come through here). So we never make length - arg for CHARACTER type. */ - - t = build_decl (PARM_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - ffecom_tree_ptr_to_subr_type); -#if BUILT_FOR_270 - DECL_ARTIFICIAL (t) = 1; -#endif - addr = TRUE; - break; - - case FFEINFO_whereGLOBAL: /* Subroutine or function. */ - assert (!ffecom_transform_only_dummies_); - - if (((g = ffesymbol_global (s)) != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) - || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)) - && (ffeglobal_hook (g) != NULL_TREE) - && ffe_is_globals ()) - { - t = ffeglobal_hook (g); - break; - } - - push_obstacks_nochange (); - end_temporary_allocation (); - - t = build_decl (FUNCTION_DECL, - ffecom_get_external_identifier_ (s), - ffecom_tree_subr_type); /* Assume subr. */ - DECL_EXTERNAL (t) = 1; - TREE_PUBLIC (t) = 1; - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - if ((g != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) - || (ffeglobal_type (g) == FFEGLOBAL_typeFUNC) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))) - ffeglobal_set_hook (g, t); - - resume_temporary_allocation (); - pop_obstacks (); - - break; - - default: - assert ("NONE where unexpected" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - break; - } - break; - - case FFEINFO_kindENTITY: - switch (ffeinfo_where (ffesymbol_info (s))) - { - - case FFEINFO_whereCONSTANT: /* ~~debugging info needed? */ - assert (!ffecom_transform_only_dummies_); - t = error_mark_node; /* Shouldn't ever see this in expr. */ - break; - - case FFEINFO_whereLOCAL: - assert (!ffecom_transform_only_dummies_); - - { - ffestorag st = ffesymbol_storage (s); - tree type; - - if ((st != NULL) - && (ffestorag_size (st) == 0)) - { - t = error_mark_node; - break; - } - - yes = suspend_momentary (); - type = ffecom_type_localvar_ (s, bt, kt); - resume_momentary (yes); - - if (type == error_mark_node) - { - t = error_mark_node; - break; - } - - if ((st != NULL) - && (ffestorag_parent (st) != NULL)) - { /* Child of EQUIVALENCE parent. */ - ffestorag est; - tree et; - int yes; - ffetargetOffset offset; - - est = ffestorag_parent (st); - ffecom_transform_equiv_ (est); - - et = ffestorag_hook (est); - assert (et != NULL_TREE); - - if (! TREE_STATIC (et)) - put_var_into_stack (et); - - yes = suspend_momentary (); - - offset = ffestorag_modulo (est) - + ffestorag_offset (ffesymbol_storage (s)) - - ffestorag_offset (est); - - ffecom_debug_kludge_ (et, "EQUIVALENCE", s, type, offset); - - /* (t_type *) (((char *) &et) + offset) */ - - t = convert (string_type_node, /* (char *) */ - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (et)), - et)); - t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t), - t, - build_int_2 (offset, 0)); - t = convert (build_pointer_type (type), - t); - - addr = TRUE; - - resume_momentary (yes); - } - else - { - tree initexpr; - bool init = ffesymbol_is_init (s); - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - type); - - if (init - || ffesymbol_namelisted (s) -#ifdef FFECOM_sizeMAXSTACKITEM - || ((st != NULL) - && (ffestorag_size (st) > FFECOM_sizeMAXSTACKITEM)) -#endif - || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM) - && (ffecom_primary_entry_kind_ - != FFEINFO_kindBLOCKDATA) - && (ffesymbol_is_save (s) || ffe_is_saveall ()))) - TREE_STATIC (t) = !ffesymbol_attr (s, FFESYMBOL_attrADJUSTABLE); - else - TREE_STATIC (t) = 0; /* No need to make static. */ - - if (init || ffe_is_init_local_zero ()) - DECL_INITIAL (t) = error_mark_node; - - /* Keep -Wunused from complaining about var if it - is used as sfunc arg or DATA implied-DO. */ - if (ffesymbol_attrs (s) & FFESYMBOL_attrsSFARG) - DECL_IN_SYSTEM_HEADER (t) = 1; - - t = start_decl (t, FALSE); - - if (init) - { - if (ffesymbol_init (s) != NULL) - initexpr = ffecom_expr (ffesymbol_init (s)); - else - initexpr = ffecom_init_zero_ (t); - } - else if (ffe_is_init_local_zero ()) - initexpr = ffecom_init_zero_ (t); - else - initexpr = NULL_TREE; /* Not ref'd if !init. */ - - finish_decl (t, initexpr, FALSE); - - if ((st != NULL) && (DECL_SIZE (t) != error_mark_node)) - { - tree size_tree; - - size_tree = size_binop (CEIL_DIV_EXPR, - DECL_SIZE (t), - size_int (BITS_PER_UNIT)); - assert (TREE_INT_CST_HIGH (size_tree) == 0); - assert (TREE_INT_CST_LOW (size_tree) == ffestorag_size (st)); - } - - resume_momentary (yes); - } - } - break; - - case FFEINFO_whereRESULT: - assert (!ffecom_transform_only_dummies_); - - if (bt == FFEINFO_basictypeCHARACTER) - { /* Result is already in list of dummies, use - it (& length). */ - t = ffecom_func_result_; - tlen = ffecom_func_length_; - addr = TRUE; - break; - } - if ((ffecom_num_entrypoints_ == 0) - && (bt == FFEINFO_basictypeCOMPLEX) - && (ffesymbol_is_f2c (ffecom_primary_entry_))) - { /* Result is already in list of dummies, use - it. */ - t = ffecom_func_result_; - addr = TRUE; - break; - } - if (ffecom_func_result_ != NULL_TREE) - { - t = ffecom_func_result_; - break; - } - if ((ffecom_num_entrypoints_ != 0) - && (ffecom_master_bt_ == FFEINFO_basictypeNONE)) - { - yes = suspend_momentary (); - - assert (ffecom_multi_retval_ != NULL_TREE); - t = ffecom_1 (INDIRECT_REF, ffecom_multi_type_node_, - ffecom_multi_retval_); - t = ffecom_2 (COMPONENT_REF, ffecom_tree_type[bt][kt], - t, ffecom_multi_fields_[bt][kt]); - - resume_momentary (yes); - break; - } - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - ffecom_tree_type[bt][kt]); - TREE_STATIC (t) = 0; /* Put result on stack. */ - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - ffecom_func_result_ = t; - - resume_momentary (yes); - break; - - case FFEINFO_whereDUMMY: - { - tree type; - ffebld dl; - ffebld dim; - tree low; - tree high; - tree old_sizes; - bool adjustable = FALSE; /* Conditionally adjustable? */ - - type = ffecom_tree_type[bt][kt]; - if (ffesymbol_sfdummyparent (s) != NULL) - { - if (current_function_decl == ffecom_outer_function_decl_) - { /* Exec transition before sfunc - context; get it later. */ - break; - } - t = ffecom_get_identifier_ (ffesymbol_text - (ffesymbol_sfdummyparent (s))); - } - else - t = ffecom_get_identifier_ (ffesymbol_text (s)); - - assert (ffecom_transform_only_dummies_); - - old_sizes = get_pending_sizes (); - put_pending_sizes (old_sizes); - - if (bt == FFEINFO_basictypeCHARACTER) - tlen = ffecom_char_enhance_arg_ (&type, s); - type = ffecom_check_size_overflow_ (s, type, TRUE); - - for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl)) - { - if (type == error_mark_node) - break; - - dim = ffebld_head (dl); - assert (ffebld_op (dim) == FFEBLD_opBOUNDS); - if ((ffebld_left (dim) == NULL) || ffecom_doing_entry_) - low = ffecom_integer_one_node; - else - low = ffecom_expr (ffebld_left (dim)); - assert (ffebld_right (dim) != NULL); - if ((ffebld_op (ffebld_right (dim)) == FFEBLD_opSTAR) - || ffecom_doing_entry_) - { - /* Used to just do high=low. But for ffecom_tree_ - canonize_ref_, it probably is important to correctly - assess the size. E.g. given COMPLEX C(*),CFUNC and - C(2)=CFUNC(C), overlap can happen, while it can't - for, say, C(1)=CFUNC(C(2)). */ - /* Even more recently used to set to INT_MAX, but that - broke when some overflow checking went into the back - end. Now we just leave the upper bound unspecified. */ - high = NULL; - } - else - high = ffecom_expr (ffebld_right (dim)); - - /* Determine whether array is conditionally adjustable, - to decide whether back-end magic is needed. - - Normally the front end uses the back-end function - variable_size to wrap SAVE_EXPR's around expressions - affecting the size/shape of an array so that the - size/shape info doesn't change during execution - of the compiled code even though variables and - functions referenced in those expressions might. - - variable_size also makes sure those saved expressions - get evaluated immediately upon entry to the - compiled procedure -- the front end normally doesn't - have to worry about that. - - However, there is a problem with this that affects - g77's implementation of entry points, and that is - that it is _not_ true that each invocation of the - compiled procedure is permitted to evaluate - array size/shape info -- because it is possible - that, for some invocations, that info is invalid (in - which case it is "promised" -- i.e. a violation of - the Fortran standard -- that the compiled code - won't reference the array or its size/shape - during that particular invocation). - - To phrase this in C terms, consider this gcc function: - - void foo (int *n, float (*a)[*n]) - { - // a is "pointer to array ...", fyi. - } - - Suppose that, for some invocations, it is permitted - for a caller of foo to do this: - - foo (NULL, NULL); - - Now the _written_ code for foo can take such a call - into account by either testing explicitly for whether - (a == NULL) || (n == NULL) -- presumably it is - not permitted to reference *a in various fashions - if (n == NULL) I suppose -- or it can avoid it by - looking at other info (other arguments, static/global - data, etc.). - - However, this won't work in gcc 2.5.8 because it'll - automatically emit the code to save the "*n" - expression, which'll yield a NULL dereference for - the "foo (NULL, NULL)" call, something the code - for foo cannot prevent. - - g77 definitely needs to avoid executing such - code anytime the pointer to the adjustable array - is NULL, because even if its bounds expressions - don't have any references to possible "absent" - variables like "*n" -- say all variable references - are to COMMON variables, i.e. global (though in C, - local static could actually make sense) -- the - expressions could yield other run-time problems - for allowably "dead" values in those variables. - - For example, let's consider a more complicated - version of foo: - - extern int i; - extern int j; - - void foo (float (*a)[i/j]) - { - ... - } - - The above is (essentially) quite valid for Fortran - but, again, for a call like "foo (NULL);", it is - permitted for i and j to be undefined when the - call is made. If j happened to be zero, for - example, emitting the code to evaluate "i/j" - could result in a run-time error. - - Offhand, though I don't have my F77 or F90 - standards handy, it might even be valid for a - bounds expression to contain a function reference, - in which case I doubt it is permitted for an - implementation to invoke that function in the - Fortran case involved here (invocation of an - alternate ENTRY point that doesn't have the adjustable - array as one of its arguments). - - So, the code that the compiler would normally emit - to preevaluate the size/shape info for an - adjustable array _must not_ be executed at run time - in certain cases. Specifically, for Fortran, - the case is when the pointer to the adjustable - array == NULL. (For gnu-ish C, it might be nice - for the source code itself to specify an expression - that, if TRUE, inhibits execution of the code. Or - reverse the sense for elegance.) - - (Note that g77 could use a different test than NULL, - actually, since it happens to always pass an - integer to the called function that specifies which - entry point is being invoked. Hmm, this might - solve the next problem.) - - One way a user could, I suppose, write "foo" so - it works is to insert COND_EXPR's for the - size/shape info so the dangerous stuff isn't - actually done, as in: - - void foo (int *n, float (*a)[(a == NULL) ? 0 : *n]) - { - ... - } - - The next problem is that the front end needs to - be able to tell the back end about the array's - decl _before_ it tells it about the conditional - expression to inhibit evaluation of size/shape info, - as shown above. - - To solve this, the front end needs to be able - to give the back end the expression to inhibit - generation of the preevaluation code _after_ - it makes the decl for the adjustable array. - - Until then, the above example using the COND_EXPR - doesn't pass muster with gcc because the "(a == NULL)" - part has a reference to "a", which is still - undefined at that point. - - g77 will therefore use a different mechanism in the - meantime. */ - - if (!adjustable - && ((TREE_CODE (low) != INTEGER_CST) - || (high && TREE_CODE (high) != INTEGER_CST))) - adjustable = TRUE; - -#if 0 /* Old approach -- see below. */ - if (TREE_CODE (low) != INTEGER_CST) - low = ffecom_3 (COND_EXPR, integer_type_node, - ffecom_adjarray_passed_ (s), - low, - ffecom_integer_zero_node); - - if (high && TREE_CODE (high) != INTEGER_CST) - high = ffecom_3 (COND_EXPR, integer_type_node, - ffecom_adjarray_passed_ (s), - high, - ffecom_integer_zero_node); -#endif - - /* ~~~gcc/stor-layout.c/layout_type should do this, - probably. Fixes 950302-1.f. */ - - if (TREE_CODE (low) != INTEGER_CST) - low = variable_size (low); - - /* ~~~similarly, this fixes dumb0.f. The C front end - does this, which is why dumb0.c would work. */ - - if (high && TREE_CODE (high) != INTEGER_CST) - high = variable_size (high); - - type - = build_array_type - (type, - build_range_type (ffecom_integer_type_node, - low, high)); - type = ffecom_check_size_overflow_ (s, type, TRUE); - } - - if (type == error_mark_node) - { - t = error_mark_node; - break; - } - - if ((ffesymbol_sfdummyparent (s) == NULL) - || (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER)) - { - type = build_pointer_type (type); - addr = TRUE; - } - - t = build_decl (PARM_DECL, t, type); -#if BUILT_FOR_270 - DECL_ARTIFICIAL (t) = 1; -#endif - - /* If this arg is present in every entry point's list of - dummy args, then we're done. */ - - if (ffesymbol_numentries (s) - == (ffecom_num_entrypoints_ + 1)) - break; - -#if 1 - - /* If variable_size in stor-layout has been called during - the above, then get_pending_sizes should have the - yet-to-be-evaluated saved expressions pending. - Make the whole lot of them get emitted, conditionally - on whether the array decl ("t" above) is not NULL. */ - - { - tree sizes = get_pending_sizes (); - tree tem; - - for (tem = sizes; - tem != old_sizes; - tem = TREE_CHAIN (tem)) - { - tree temv = TREE_VALUE (tem); - - if (sizes == tem) - sizes = temv; - else - sizes - = ffecom_2 (COMPOUND_EXPR, - TREE_TYPE (sizes), - temv, - sizes); - } - - if (sizes != tem) - { - sizes - = ffecom_3 (COND_EXPR, - TREE_TYPE (sizes), - ffecom_2 (NE_EXPR, - integer_type_node, - t, - null_pointer_node), - sizes, - convert (TREE_TYPE (sizes), - integer_zero_node)); - sizes = ffecom_save_tree (sizes); - - sizes - = tree_cons (NULL_TREE, sizes, tem); - } - - if (sizes) - put_pending_sizes (sizes); - } - -#else -#if 0 - if (adjustable - && (ffesymbol_numentries (s) - != ffecom_num_entrypoints_ + 1)) - DECL_SOMETHING (t) - = ffecom_2 (NE_EXPR, integer_type_node, - t, - null_pointer_node); -#else -#if 0 - if (adjustable - && (ffesymbol_numentries (s) - != ffecom_num_entrypoints_ + 1)) - { - ffebad_start (FFEBAD_MISSING_ADJARRAY_UNSUPPORTED); - ffebad_here (0, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } -#endif -#endif -#endif - } - break; - - case FFEINFO_whereCOMMON: - { - ffesymbol cs; - ffeglobal cg; - tree ct; - ffestorag st = ffesymbol_storage (s); - tree type; - int yes; - - cs = ffesymbol_common (s); /* The COMMON area itself. */ - if (st != NULL) /* Else not laid out. */ - { - ffecom_transform_common_ (cs); - st = ffesymbol_storage (s); - } - - yes = suspend_momentary (); - - type = ffecom_type_localvar_ (s, bt, kt); - - cg = ffesymbol_global (cs); /* The global COMMON info. */ - if ((cg == NULL) - || (ffeglobal_type (cg) != FFEGLOBAL_typeCOMMON)) - ct = NULL_TREE; - else - ct = ffeglobal_hook (cg); /* The common area's tree. */ - - if ((ct == NULL_TREE) - || (st == NULL) - || (type == error_mark_node)) - t = error_mark_node; - else - { - ffetargetOffset offset; - ffestorag cst; - - cst = ffestorag_parent (st); - assert (cst == ffesymbol_storage (cs)); - - offset = ffestorag_modulo (cst) - + ffestorag_offset (st) - - ffestorag_offset (cst); - - ffecom_debug_kludge_ (ct, "COMMON", s, type, offset); - - /* (t_type *) (((char *) &ct) + offset) */ - - t = convert (string_type_node, /* (char *) */ - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (ct)), - ct)); - t = ffecom_2 (PLUS_EXPR, TREE_TYPE (t), - t, - build_int_2 (offset, 0)); - t = convert (build_pointer_type (type), - t); - - addr = TRUE; - } - - resume_momentary (yes); - } - break; - - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereGLOBAL: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("ENTITY where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindFUNCTION: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: /* Me. */ - assert (!ffecom_transform_only_dummies_); - t = current_function_decl; - break; - - case FFEINFO_whereGLOBAL: - assert (!ffecom_transform_only_dummies_); - - if (((g = ffesymbol_global (s)) != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)) - && (ffeglobal_hook (g) != NULL_TREE) - && ffe_is_globals ()) - { - t = ffeglobal_hook (g); - break; - } - - push_obstacks_nochange (); - end_temporary_allocation (); - - if (ffesymbol_is_f2c (s) - && (ffesymbol_where (s) != FFEINFO_whereCONSTANT)) - t = ffecom_tree_fun_type[bt][kt]; - else - t = build_function_type (ffecom_tree_type[bt][kt], NULL_TREE); - - t = build_decl (FUNCTION_DECL, - ffecom_get_external_identifier_ (s), - t); - DECL_EXTERNAL (t) = 1; - TREE_PUBLIC (t) = 1; - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - if ((g != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeFUNC) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))) - ffeglobal_set_hook (g, t); - - resume_temporary_allocation (); - pop_obstacks (); - - break; - - case FFEINFO_whereDUMMY: - assert (ffecom_transform_only_dummies_); - - if (ffesymbol_is_f2c (s) - && (ffesymbol_where (s) != FFEINFO_whereCONSTANT)) - t = ffecom_tree_ptr_to_fun_type[bt][kt]; - else - t = build_pointer_type - (build_function_type (ffecom_tree_type[bt][kt], NULL_TREE)); - - t = build_decl (PARM_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - t); -#if BUILT_FOR_270 - DECL_ARTIFICIAL (t) = 1; -#endif - addr = TRUE; - break; - - case FFEINFO_whereCONSTANT: /* Statement function. */ - assert (!ffecom_transform_only_dummies_); - t = ffecom_gen_sfuncdef_ (s, bt, kt); - break; - - case FFEINFO_whereINTRINSIC: - assert (!ffecom_transform_only_dummies_); - break; /* Let actual references generate their - decls. */ - - default: - assert ("FUNCTION where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindSUBROUTINE: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: /* Me. */ - assert (!ffecom_transform_only_dummies_); - t = current_function_decl; - break; - - case FFEINFO_whereGLOBAL: - assert (!ffecom_transform_only_dummies_); - - if (((g = ffesymbol_global (s)) != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT)) - && (ffeglobal_hook (g) != NULL_TREE) - && ffe_is_globals ()) - { - t = ffeglobal_hook (g); - break; - } - - push_obstacks_nochange (); - end_temporary_allocation (); - - t = build_decl (FUNCTION_DECL, - ffecom_get_external_identifier_ (s), - ffecom_tree_subr_type); - DECL_EXTERNAL (t) = 1; - TREE_PUBLIC (t) = 1; - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - if ((g != NULL) - && ((ffeglobal_type (g) == FFEGLOBAL_typeSUBR) - || (ffeglobal_type (g) == FFEGLOBAL_typeEXT))) - ffeglobal_set_hook (g, t); - - resume_temporary_allocation (); - pop_obstacks (); - - break; - - case FFEINFO_whereDUMMY: - assert (ffecom_transform_only_dummies_); - - t = build_decl (PARM_DECL, - ffecom_get_identifier_ (ffesymbol_text (s)), - ffecom_tree_ptr_to_subr_type); -#if BUILT_FOR_270 - DECL_ARTIFICIAL (t) = 1; -#endif - addr = TRUE; - break; - - case FFEINFO_whereINTRINSIC: - assert (!ffecom_transform_only_dummies_); - break; /* Let actual references generate their - decls. */ - - default: - assert ("SUBROUTINE where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindPROGRAM: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: /* Me. */ - assert (!ffecom_transform_only_dummies_); - t = current_function_decl; - break; - - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereGLOBAL: - case FFEINFO_whereRESULT: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("PROGRAM where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindBLOCKDATA: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: /* Me. */ - assert (!ffecom_transform_only_dummies_); - t = current_function_decl; - break; - - case FFEINFO_whereGLOBAL: - assert (!ffecom_transform_only_dummies_); - - push_obstacks_nochange (); - end_temporary_allocation (); - - t = build_decl (FUNCTION_DECL, - ffecom_get_external_identifier_ (s), - ffecom_tree_blockdata_type); - DECL_EXTERNAL (t) = 1; - TREE_PUBLIC (t) = 1; - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - resume_temporary_allocation (); - pop_obstacks (); - - break; - - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereRESULT: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("BLOCKDATA where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindCOMMON: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: - assert (!ffecom_transform_only_dummies_); - ffecom_transform_common_ (s); - break; - - case FFEINFO_whereNONE: - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereGLOBAL: - case FFEINFO_whereRESULT: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("COMMON where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindCONSTRUCT: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: - assert (!ffecom_transform_only_dummies_); - break; - - case FFEINFO_whereNONE: - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereGLOBAL: - case FFEINFO_whereRESULT: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("CONSTRUCT where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - case FFEINFO_kindNAMELIST: - switch (ffeinfo_where (ffesymbol_info (s))) - { - case FFEINFO_whereLOCAL: - assert (!ffecom_transform_only_dummies_); - t = ffecom_transform_namelist_ (s); - break; - - case FFEINFO_whereNONE: - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereGLOBAL: - case FFEINFO_whereRESULT: - case FFEINFO_whereFLEETING: - case FFEINFO_whereFLEETING_CADDR: - case FFEINFO_whereFLEETING_IADDR: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereCONSTANT_SUBOBJECT: - default: - assert ("NAMELIST where unheard of" == NULL); - /* Fall through. */ - case FFEINFO_whereANY: - t = error_mark_node; - break; - } - break; - - default: - assert ("kind unheard of" == NULL); - /* Fall through. */ - case FFEINFO_kindANY: - t = error_mark_node; - break; - } - - ffesymbol_hook (s).decl_tree = t; - ffesymbol_hook (s).length_tree = tlen; - ffesymbol_hook (s).addr = addr; - - lineno = old_lineno; - input_filename = old_input_filename; - - return s; -} - -#endif -/* Transform into ASSIGNable symbol. - - Symbol has already been transformed, but for whatever reason, the - resulting decl_tree has been deemed not usable for an ASSIGN target. - (E.g. it isn't wide enough to hold a pointer.) So, here we invent - another local symbol of type void * and stuff that in the assign_tree - argument. The F77/F90 standards allow this implementation. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffesymbol -ffecom_sym_transform_assign_ (ffesymbol s) -{ - tree t; /* Transformed thingy. */ - int yes; - int old_lineno = lineno; - char *old_input_filename = input_filename; - - if (ffesymbol_sfdummyparent (s) == NULL) - { - input_filename = ffesymbol_where_filename (s); - lineno = ffesymbol_where_filelinenum (s); - } - else - { - ffesymbol sf = ffesymbol_sfdummyparent (s); - - input_filename = ffesymbol_where_filename (sf); - lineno = ffesymbol_where_filelinenum (sf); - } - - assert (!ffecom_transform_only_dummies_); - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_ASSIGN_%s", - ffesymbol_text (s), - 0), - TREE_TYPE (null_pointer_node)); - - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - /* Unlike for regular vars, SAVE status is easy to determine for - ASSIGNed vars, since there's no initialization, there's no - effective storage association (so "SAVE J" does not apply to - K even given "EQUIVALENCE (J,K)"), there's no size issue - to worry about, etc. */ - if ((ffesymbol_is_save (s) || ffe_is_saveall ()) - && (ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM) - && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA)) - TREE_STATIC (t) = 1; /* SAVEd in proc, make static. */ - else - TREE_STATIC (t) = 0; /* No need to make static. */ - break; - - case FFEINFO_whereCOMMON: - TREE_STATIC (t) = 1; /* Assume COMMONs always SAVEd. */ - break; - - case FFEINFO_whereDUMMY: - /* Note that twinning a DUMMY means the caller won't see - the ASSIGNed value. But both F77 and F90 allow implementations - to do this, i.e. disallow Fortran code that would try and - take advantage of actually putting a label into a variable - via a dummy argument (or any other storage association, for - that matter). */ - TREE_STATIC (t) = 0; - break; - - default: - TREE_STATIC (t) = 0; - break; - } - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - resume_momentary (yes); - - ffesymbol_hook (s).assign_tree = t; - - lineno = old_lineno; - input_filename = old_input_filename; - - return s; -} - -#endif -/* Implement COMMON area in back end. - - Because COMMON-based variables can be referenced in the dimension - expressions of dummy (adjustable) arrays, and because dummies - (in the gcc back end) need to be put in the outer binding level - of a function (which has two binding levels, the outer holding - the dummies and the inner holding the other vars), special care - must be taken to handle COMMON areas. - - The current strategy is basically to always tell the back end about - the COMMON area as a top-level external reference to just a block - of storage of the master type of that area (e.g. integer, real, - character, whatever -- not a structure). As a distinct action, - if initial values are provided, tell the back end about the area - as a top-level non-external (initialized) area and remember not to - allow further initialization or expansion of the area. Meanwhile, - if no initialization happens at all, tell the back end about - the largest size we've seen declared so the space does get reserved. - (This function doesn't handle all that stuff, but it does some - of the important things.) - - Meanwhile, for COMMON variables themselves, just keep creating - references like *((float *) (&common_area + offset)) each time - we reference the variable. In other words, don't make a VAR_DECL - or any kind of component reference (like we used to do before 0.4), - though we might do that as well just for debugging purposes (and - stuff the rtl with the appropriate offset expression). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_transform_common_ (ffesymbol s) -{ - ffestorag st = ffesymbol_storage (s); - ffeglobal g = ffesymbol_global (s); - tree cbt; - tree cbtype; - tree init; - tree high; - bool is_init = ffestorag_is_init (st); - - assert (st != NULL); - - if ((g == NULL) - || (ffeglobal_type (g) != FFEGLOBAL_typeCOMMON)) - return; - - /* First update the size of the area in global terms. */ - - ffeglobal_size_common (s, ffestorag_size (st)); - - if (!ffeglobal_common_init (g)) - is_init = FALSE; /* No explicit init, don't let erroneous joins init. */ - - cbt = ffeglobal_hook (g); - - /* If we already have declared this common block for a previous program - unit, and either we already initialized it or we don't have new - initialization for it, just return what we have without changing it. */ - - if ((cbt != NULL_TREE) - && (!is_init - || !DECL_EXTERNAL (cbt))) - return; - - /* Process inits. */ - - if (is_init) - { - if (ffestorag_init (st) != NULL) - { - ffebld sexp; - - /* Set the padding for the expression, so ffecom_expr - knows to insert that many zeros. */ - switch (ffebld_op (sexp = ffestorag_init (st))) - { - case FFEBLD_opCONTER: - ffebld_conter_set_pad (sexp, ffestorag_modulo (st)); - break; - - case FFEBLD_opARRTER: - ffebld_arrter_set_pad (sexp, ffestorag_modulo (st)); - break; - - case FFEBLD_opACCTER: - ffebld_accter_set_pad (sexp, ffestorag_modulo (st)); - break; - - default: - assert ("bad op for cmn init (pad)" == NULL); - break; - } - - init = ffecom_expr (sexp); - if (init == error_mark_node) - { /* Hopefully the back end complained! */ - init = NULL_TREE; - if (cbt != NULL_TREE) - return; - } - } - else - init = error_mark_node; - } - else - init = NULL_TREE; - - push_obstacks_nochange (); - end_temporary_allocation (); - - /* cbtype must be permanently allocated! */ - - /* Allocate the MAX of the areas so far, seen filewide. */ - high = build_int_2 ((ffeglobal_common_size (g) - + ffeglobal_common_pad (g)) - 1, 0); - TREE_TYPE (high) = ffecom_integer_type_node; - - if (init) - cbtype = build_array_type (char_type_node, - build_range_type (integer_type_node, - integer_zero_node, - high)); - else - cbtype = build_array_type (char_type_node, NULL_TREE); - - if (cbt == NULL_TREE) - { - cbt - = build_decl (VAR_DECL, - ffecom_get_external_identifier_ (s), - cbtype); - TREE_STATIC (cbt) = 1; - TREE_PUBLIC (cbt) = 1; - } - else - { - assert (is_init); - TREE_TYPE (cbt) = cbtype; - } - DECL_EXTERNAL (cbt) = init ? 0 : 1; - DECL_INITIAL (cbt) = init ? error_mark_node : NULL_TREE; - - cbt = start_decl (cbt, TRUE); - if (ffeglobal_hook (g) != NULL) - assert (cbt == ffeglobal_hook (g)); - - assert (!init || !DECL_EXTERNAL (cbt)); - - /* Make sure that any type can live in COMMON and be referenced - without getting a bus error. We could pick the most restrictive - alignment of all entities actually placed in the COMMON, but - this seems easy enough. */ - - DECL_ALIGN (cbt) = BIGGEST_ALIGNMENT; - - if (is_init && (ffestorag_init (st) == NULL)) - init = ffecom_init_zero_ (cbt); - - finish_decl (cbt, init, TRUE); - - if (is_init) - ffestorag_set_init (st, ffebld_new_any ()); - - if (init) - { - tree size_tree; - - assert (DECL_SIZE (cbt) != NULL_TREE); - assert (TREE_CODE (DECL_SIZE (cbt)) == INTEGER_CST); - size_tree = size_binop (CEIL_DIV_EXPR, - DECL_SIZE (cbt), - size_int (BITS_PER_UNIT)); - assert (TREE_INT_CST_HIGH (size_tree) == 0); - assert (TREE_INT_CST_LOW (size_tree) - == ffeglobal_common_size (g) + ffeglobal_common_pad (g)); - } - - ffeglobal_set_hook (g, cbt); - - ffestorag_set_hook (st, cbt); - - resume_temporary_allocation (); - pop_obstacks (); -} - -#endif -/* Make master area for local EQUIVALENCE. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_transform_equiv_ (ffestorag eqst) -{ - tree eqt; - tree eqtype; - tree init; - tree high; - bool is_init = ffestorag_is_init (eqst); - int yes; - - assert (eqst != NULL); - - eqt = ffestorag_hook (eqst); - - if (eqt != NULL_TREE) - return; - - /* Process inits. */ - - if (is_init) - { - if (ffestorag_init (eqst) != NULL) - { - ffebld sexp; - - /* Set the padding for the expression, so ffecom_expr - knows to insert that many zeros. */ - switch (ffebld_op (sexp = ffestorag_init (eqst))) - { - case FFEBLD_opCONTER: - ffebld_conter_set_pad (sexp, ffestorag_modulo (eqst)); - break; - - case FFEBLD_opARRTER: - ffebld_arrter_set_pad (sexp, ffestorag_modulo (eqst)); - break; - - case FFEBLD_opACCTER: - ffebld_accter_set_pad (sexp, ffestorag_modulo (eqst)); - break; - - default: - assert ("bad op for eqv init (pad)" == NULL); - break; - } - - init = ffecom_expr (sexp); - if (init == error_mark_node) - init = NULL_TREE; /* Hopefully the back end complained! */ - } - else - init = error_mark_node; - } - else if (ffe_is_init_local_zero ()) - init = error_mark_node; - else - init = NULL_TREE; - - ffecom_member_namelisted_ = FALSE; - ffestorag_drive (ffestorag_list_equivs (eqst), - &ffecom_member_phase1_, - eqst); - - yes = suspend_momentary (); - - high = build_int_2 ((ffestorag_size (eqst) - + ffestorag_modulo (eqst)) - 1, 0); - TREE_TYPE (high) = ffecom_integer_type_node; - - eqtype = build_array_type (char_type_node, - build_range_type (ffecom_integer_type_node, - ffecom_integer_zero_node, - high)); - - eqt = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_equiv_%s", - ffesymbol_text - (ffestorag_symbol - (eqst)), - 0), - eqtype); - DECL_EXTERNAL (eqt) = 0; - if (is_init - || ffecom_member_namelisted_ -#ifdef FFECOM_sizeMAXSTACKITEM - || (ffestorag_size (eqst) > FFECOM_sizeMAXSTACKITEM) -#endif - || ((ffecom_primary_entry_kind_ != FFEINFO_kindPROGRAM) - && (ffecom_primary_entry_kind_ != FFEINFO_kindBLOCKDATA) - && (ffestorag_is_save (eqst) || ffe_is_saveall ()))) - TREE_STATIC (eqt) = 1; - else - TREE_STATIC (eqt) = 0; - TREE_PUBLIC (eqt) = 0; - DECL_CONTEXT (eqt) = current_function_decl; - if (init) - DECL_INITIAL (eqt) = error_mark_node; - else - DECL_INITIAL (eqt) = NULL_TREE; - - eqt = start_decl (eqt, FALSE); - - /* Make sure that any type can live in EQUIVALENCE and be referenced - without getting a bus error. We could pick the most restrictive - alignment of all entities actually placed in the EQUIVALENCE, but - this seems easy enough. */ - - DECL_ALIGN (eqt) = BIGGEST_ALIGNMENT; - - if ((!is_init && ffe_is_init_local_zero ()) - || (is_init && (ffestorag_init (eqst) == NULL))) - init = ffecom_init_zero_ (eqt); - - finish_decl (eqt, init, FALSE); - - if (is_init) - ffestorag_set_init (eqst, ffebld_new_any ()); - - { - tree size_tree; - - size_tree = size_binop (CEIL_DIV_EXPR, - DECL_SIZE (eqt), - size_int (BITS_PER_UNIT)); - assert (TREE_INT_CST_HIGH (size_tree) == 0); - assert (TREE_INT_CST_LOW (size_tree) - == ffestorag_size (eqst) + ffestorag_modulo (eqst)); - } - - ffestorag_set_hook (eqst, eqt); - -#ifdef SOMEONE_GETS_DEBUG_SUPPORT_WORKING - ffestorag_drive (ffestorag_list_equivs (eqst), - &ffecom_member_phase2_, - eqst); -#endif - - resume_momentary (yes); -} - -#endif -/* Implement NAMELIST in back end. See f2c/format.c for more info. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_transform_namelist_ (ffesymbol s) -{ - tree nmlt; - tree nmltype = ffecom_type_namelist_ (); - tree nmlinits; - tree nameinit; - tree varsinit; - tree nvarsinit; - tree field; - tree high; - int yes; - int i; - static int mynumber = 0; - - yes = suspend_momentary (); - - nmlt = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_namelist_%d", - NULL, mynumber++), - nmltype); - TREE_STATIC (nmlt) = 1; - DECL_INITIAL (nmlt) = error_mark_node; - - nmlt = start_decl (nmlt, FALSE); - - /* Process inits. */ - - i = strlen (ffesymbol_text (s)); - - high = build_int_2 (i, 0); - TREE_TYPE (high) = ffecom_f2c_ftnlen_type_node; - - nameinit = ffecom_build_f2c_string_ (i + 1, - ffesymbol_text (s)); - TREE_TYPE (nameinit) - = build_type_variant - (build_array_type - (char_type_node, - build_range_type (ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - high)), - 1, 0); - TREE_CONSTANT (nameinit) = 1; - TREE_STATIC (nameinit) = 1; - nameinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (nameinit)), - nameinit); - - varsinit = ffecom_vardesc_array_ (s); - varsinit = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (varsinit)), - varsinit); - TREE_CONSTANT (varsinit) = 1; - TREE_STATIC (varsinit) = 1; - - { - ffebld b; - - for (i = 0, b = ffesymbol_namelist (s); b != NULL; b = ffebld_trail (b)) - ++i; - } - nvarsinit = build_int_2 (i, 0); - TREE_TYPE (nvarsinit) = integer_type_node; - TREE_CONSTANT (nvarsinit) = 1; - TREE_STATIC (nvarsinit) = 1; - - nmlinits = build_tree_list ((field = TYPE_FIELDS (nmltype)), nameinit); - TREE_CHAIN (nmlinits) = build_tree_list ((field = TREE_CHAIN (field)), - varsinit); - TREE_CHAIN (TREE_CHAIN (nmlinits)) - = build_tree_list ((field = TREE_CHAIN (field)), nvarsinit); - - nmlinits = build (CONSTRUCTOR, nmltype, NULL_TREE, nmlinits); - TREE_CONSTANT (nmlinits) = 1; - TREE_STATIC (nmlinits) = 1; - - finish_decl (nmlt, nmlinits, FALSE); - - nmlt = ffecom_1 (ADDR_EXPR, build_pointer_type (nmltype), nmlt); - - resume_momentary (yes); - - return nmlt; -} - -#endif - -/* A subroutine of ffecom_tree_canonize_ref_. The incoming tree is - analyzed on the assumption it is calculating a pointer to be - indirected through. It must return the proper decl and offset, - taking into account different units of measurements for offsets. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_tree_canonize_ptr_ (tree *decl, tree *offset, - tree t) -{ - switch (TREE_CODE (t)) - { - case NOP_EXPR: - case CONVERT_EXPR: - case NON_LVALUE_EXPR: - ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0)); - break; - - case PLUS_EXPR: - ffecom_tree_canonize_ptr_ (decl, offset, TREE_OPERAND (t, 0)); - if ((*decl == NULL_TREE) - || (*decl == error_mark_node)) - break; - - if (TREE_CODE (TREE_OPERAND (t, 1)) == INTEGER_CST) - { - /* An offset into COMMON. */ - *offset = size_binop (PLUS_EXPR, - *offset, - TREE_OPERAND (t, 1)); - /* Convert offset (presumably in bytes) into canonical units - (presumably bits). */ - *offset = size_binop (MULT_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (t))), - *offset); - break; - } - /* Not a COMMON reference, so an unrecognized pattern. */ - *decl = error_mark_node; - break; - - case PARM_DECL: - *decl = t; - *offset = bitsize_int (0L, 0L); - break; - - case ADDR_EXPR: - if (TREE_CODE (TREE_OPERAND (t, 0)) == VAR_DECL) - { - /* A reference to COMMON. */ - *decl = TREE_OPERAND (t, 0); - *offset = bitsize_int (0L, 0L); - break; - } - /* Fall through. */ - default: - /* Not a COMMON reference, so an unrecognized pattern. */ - *decl = error_mark_node; - break; - } -} -#endif - -/* Given a tree that is possibly intended for use as an lvalue, return - information representing a canonical view of that tree as a decl, an - offset into that decl, and a size for the lvalue. - - If there's no applicable decl, NULL_TREE is returned for the decl, - and the other fields are left undefined. - - If the tree doesn't fit the recognizable forms, an ERROR_MARK node - is returned for the decl, and the other fields are left undefined. - - Otherwise, the decl returned currently is either a VAR_DECL or a - PARM_DECL. - - The offset returned is always valid, but of course not necessarily - a constant, and not necessarily converted into the appropriate - type, leaving that up to the caller (so as to avoid that overhead - if the decls being looked at are different anyway). - - If the size cannot be determined (e.g. an adjustable array), - an ERROR_MARK node is returned for the size. Otherwise, the - size returned is valid, not necessarily a constant, and not - necessarily converted into the appropriate type as with the - offset. - - Note that the offset and size expressions are expressed in the - base storage units (usually bits) rather than in the units of - the type of the decl, because two decls with different types - might overlap but with apparently non-overlapping array offsets, - whereas converting the array offsets to consistant offsets will - reveal the overlap. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffecom_tree_canonize_ref_ (tree *decl, tree *offset, - tree *size, tree t) -{ - /* The default path is to report a nonexistant decl. */ - *decl = NULL_TREE; - - if (t == NULL_TREE) - return; - - switch (TREE_CODE (t)) - { - case ERROR_MARK: - case IDENTIFIER_NODE: - case INTEGER_CST: - case REAL_CST: - case COMPLEX_CST: - case STRING_CST: - case CONST_DECL: - case PLUS_EXPR: - case MINUS_EXPR: - case MULT_EXPR: - case TRUNC_DIV_EXPR: - case CEIL_DIV_EXPR: - case FLOOR_DIV_EXPR: - case ROUND_DIV_EXPR: - case TRUNC_MOD_EXPR: - case CEIL_MOD_EXPR: - case FLOOR_MOD_EXPR: - case ROUND_MOD_EXPR: - case RDIV_EXPR: - case EXACT_DIV_EXPR: - case FIX_TRUNC_EXPR: - case FIX_CEIL_EXPR: - case FIX_FLOOR_EXPR: - case FIX_ROUND_EXPR: - case FLOAT_EXPR: - case EXPON_EXPR: - case NEGATE_EXPR: - case MIN_EXPR: - case MAX_EXPR: - case ABS_EXPR: - case FFS_EXPR: - case LSHIFT_EXPR: - case RSHIFT_EXPR: - case LROTATE_EXPR: - case RROTATE_EXPR: - case BIT_IOR_EXPR: - case BIT_XOR_EXPR: - case BIT_AND_EXPR: - case BIT_ANDTC_EXPR: - case BIT_NOT_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - case TRUTH_NOT_EXPR: - case LT_EXPR: - case LE_EXPR: - case GT_EXPR: - case GE_EXPR: - case EQ_EXPR: - case NE_EXPR: - case COMPLEX_EXPR: - case CONJ_EXPR: - case REALPART_EXPR: - case IMAGPART_EXPR: - case LABEL_EXPR: - case COMPONENT_REF: - case COMPOUND_EXPR: - case ADDR_EXPR: - return; - - case VAR_DECL: - case PARM_DECL: - *decl = t; - *offset = bitsize_int (0L, 0L); - *size = TYPE_SIZE (TREE_TYPE (t)); - return; - - case ARRAY_REF: - { - tree array = TREE_OPERAND (t, 0); - tree element = TREE_OPERAND (t, 1); - tree init_offset; - - if ((array == NULL_TREE) - || (element == NULL_TREE)) - { - *decl = error_mark_node; - return; - } - - ffecom_tree_canonize_ref_ (decl, &init_offset, size, - array); - if ((*decl == NULL_TREE) - || (*decl == error_mark_node)) - return; - - *offset = size_binop (MULT_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (array))), - size_binop (MINUS_EXPR, - element, - TYPE_MIN_VALUE - (TYPE_DOMAIN - (TREE_TYPE (array))))); - - *offset = size_binop (PLUS_EXPR, - init_offset, - *offset); - - *size = TYPE_SIZE (TREE_TYPE (t)); - return; - } - - case INDIRECT_REF: - - /* Most of this code is to handle references to COMMON. And so - far that is useful only for calling library functions, since - external (user) functions might reference common areas. But - even calling an external function, it's worthwhile to decode - COMMON references because if not storing into COMMON, we don't - want COMMON-based arguments to gratuitously force use of a - temporary. */ - - *size = TYPE_SIZE (TREE_TYPE (t)); - - ffecom_tree_canonize_ptr_ (decl, offset, - TREE_OPERAND (t, 0)); - - return; - - case CONVERT_EXPR: - case NOP_EXPR: - case MODIFY_EXPR: - case NON_LVALUE_EXPR: - case RESULT_DECL: - case FIELD_DECL: - case COND_EXPR: /* More cases than we can handle. */ - case SAVE_EXPR: - case REFERENCE_EXPR: - case PREDECREMENT_EXPR: - case PREINCREMENT_EXPR: - case POSTDECREMENT_EXPR: - case POSTINCREMENT_EXPR: - case CALL_EXPR: - default: - *decl = error_mark_node; - return; - } -} -#endif - -/* Do divide operation appropriate to type of operands. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_tree_divide_ (tree tree_type, tree left, tree right, - tree dest_tree, ffebld dest, bool *dest_used) -{ - if ((left == error_mark_node) - || (right == error_mark_node)) - return error_mark_node; - - switch (TREE_CODE (tree_type)) - { - case INTEGER_TYPE: - return ffecom_2 (TRUNC_DIV_EXPR, tree_type, - left, - right); - - case COMPLEX_TYPE: - { - ffecomGfrt ix; - - if (TREE_TYPE (tree_type) - == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]) - ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */ - else - ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */ - - left = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (left)), - left); - left = build_tree_list (NULL_TREE, left); - right = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (right)), - right); - right = build_tree_list (NULL_TREE, right); - TREE_CHAIN (left) = right; - - return ffecom_call_ (ffecom_gfrt_tree_ (ix), - ffecom_gfrt_kindtype (ix), - ffe_is_f2c_library (), - tree_type, - left, - dest_tree, dest, dest_used, - NULL_TREE, TRUE); - } - break; - - case RECORD_TYPE: - { - ffecomGfrt ix; - - if (TREE_TYPE (TYPE_FIELDS (tree_type)) - == ffecom_tree_type [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]) - ix = FFECOM_gfrtDIV_CC; /* Overlapping result okay. */ - else - ix = FFECOM_gfrtDIV_ZZ; /* Overlapping result okay. */ - - left = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (left)), - left); - left = build_tree_list (NULL_TREE, left); - right = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (right)), - right); - right = build_tree_list (NULL_TREE, right); - TREE_CHAIN (left) = right; - - return ffecom_call_ (ffecom_gfrt_tree_ (ix), - ffecom_gfrt_kindtype (ix), - ffe_is_f2c_library (), - tree_type, - left, - dest_tree, dest, dest_used, - NULL_TREE, TRUE); - } - break; - - default: - return ffecom_2 (RDIV_EXPR, tree_type, - left, - right); - } -} - -#endif -/* ffecom_type_localvar_ -- Build type info for non-dummy variable - - tree type; - ffesymbol s; // the variable's symbol - ffeinfoBasictype bt; // it's basictype - ffeinfoKindtype kt; // it's kindtype - - type = ffecom_type_localvar_(s,bt,kt); - - Handles static arrays, CHARACTER type, etc. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_type_localvar_ (ffesymbol s, ffeinfoBasictype bt, - ffeinfoKindtype kt) -{ - tree type; - ffebld dl; - ffebld dim; - tree lowt; - tree hight; - - type = ffecom_tree_type[bt][kt]; - if (bt == FFEINFO_basictypeCHARACTER) - { - hight = build_int_2 (ffesymbol_size (s), 0); - TREE_TYPE (hight) = ffecom_f2c_ftnlen_type_node; - - type - = build_array_type - (type, - build_range_type (ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - hight)); - type = ffecom_check_size_overflow_ (s, type, FALSE); - } - - for (dl = ffesymbol_dims (s); dl != NULL; dl = ffebld_trail (dl)) - { - if (type == error_mark_node) - break; - - dim = ffebld_head (dl); - assert (ffebld_op (dim) == FFEBLD_opBOUNDS); - - if (ffebld_left (dim) == NULL) - lowt = integer_one_node; - else - lowt = ffecom_expr (ffebld_left (dim)); - - if (TREE_CODE (lowt) != INTEGER_CST) - lowt = variable_size (lowt); - - assert (ffebld_right (dim) != NULL); - hight = ffecom_expr (ffebld_right (dim)); - - if (TREE_CODE (hight) != INTEGER_CST) - hight = variable_size (hight); - - type = build_array_type (type, - build_range_type (ffecom_integer_type_node, - lowt, hight)); - type = ffecom_check_size_overflow_ (s, type, FALSE); - } - - return type; -} - -#endif -/* Build Namelist type. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_type_namelist_ () -{ - static tree type = NULL_TREE; - - if (type == NULL_TREE) - { - static tree namefield, varsfield, nvarsfield; - tree vardesctype; - - vardesctype = ffecom_type_vardesc_ (); - - push_obstacks_nochange (); - end_temporary_allocation (); - - type = make_node (RECORD_TYPE); - - vardesctype = build_pointer_type (build_pointer_type (vardesctype)); - - namefield = ffecom_decl_field (type, NULL_TREE, "name", - string_type_node); - varsfield = ffecom_decl_field (type, namefield, "vars", vardesctype); - nvarsfield = ffecom_decl_field (type, varsfield, "nvars", - integer_type_node); - - TYPE_FIELDS (type) = namefield; - layout_type (type); - - resume_temporary_allocation (); - pop_obstacks (); - } - - return type; -} - -#endif - -/* Make a copy of a type, assuming caller has switched to the permanent - obstacks and that the type is for an aggregate (array) initializer. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC && 0 /* Not used now. */ -static tree -ffecom_type_permanent_copy_ (tree t) -{ - tree domain; - tree max; - - assert (TREE_TYPE (t) != NULL_TREE); - - domain = TYPE_DOMAIN (t); - - assert (TREE_CODE (t) == ARRAY_TYPE); - assert (TREE_PERMANENT (TREE_TYPE (t))); - assert (TREE_PERMANENT (TREE_TYPE (domain))); - assert (TREE_PERMANENT (TYPE_MIN_VALUE (domain))); - - max = TYPE_MAX_VALUE (domain); - if (!TREE_PERMANENT (max)) - { - assert (TREE_CODE (max) == INTEGER_CST); - - max = build_int_2 (TREE_INT_CST_LOW (max), TREE_INT_CST_HIGH (max)); - TREE_TYPE (max) = TREE_TYPE (TYPE_MIN_VALUE (domain)); - } - - return build_array_type (TREE_TYPE (t), - build_range_type (TREE_TYPE (domain), - TYPE_MIN_VALUE (domain), - max)); -} -#endif - -/* Build Vardesc type. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_type_vardesc_ () -{ - static tree type = NULL_TREE; - static tree namefield, addrfield, dimsfield, typefield; - - if (type == NULL_TREE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - - type = make_node (RECORD_TYPE); - - namefield = ffecom_decl_field (type, NULL_TREE, "name", - string_type_node); - addrfield = ffecom_decl_field (type, namefield, "addr", - string_type_node); - dimsfield = ffecom_decl_field (type, addrfield, "dims", - ffecom_f2c_ptr_to_ftnlen_type_node); - typefield = ffecom_decl_field (type, dimsfield, "type", - integer_type_node); - - TYPE_FIELDS (type) = namefield; - layout_type (type); - - resume_temporary_allocation (); - pop_obstacks (); - } - - return type; -} - -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_vardesc_ (ffebld expr) -{ - ffesymbol s; - - assert (ffebld_op (expr) == FFEBLD_opSYMTER); - s = ffebld_symter (expr); - - if (ffesymbol_hook (s).vardesc_tree == NULL_TREE) - { - int i; - tree vardesctype = ffecom_type_vardesc_ (); - tree var; - tree nameinit; - tree dimsinit; - tree addrinit; - tree typeinit; - tree field; - tree varinits; - int yes; - static int mynumber = 0; - - yes = suspend_momentary (); - - var = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_vardesc_%d", - NULL, mynumber++), - vardesctype); - TREE_STATIC (var) = 1; - DECL_INITIAL (var) = error_mark_node; - - var = start_decl (var, FALSE); - - /* Process inits. */ - - nameinit = ffecom_build_f2c_string_ ((i = strlen (ffesymbol_text (s))) - + 1, - ffesymbol_text (s)); - TREE_TYPE (nameinit) - = build_type_variant - (build_array_type - (char_type_node, - build_range_type (integer_type_node, - integer_one_node, - build_int_2 (i, 0))), - 1, 0); - TREE_CONSTANT (nameinit) = 1; - TREE_STATIC (nameinit) = 1; - nameinit = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (nameinit)), - nameinit); - - addrinit = ffecom_arg_ptr_to_expr (expr, &typeinit); - - dimsinit = ffecom_vardesc_dims_ (s); - - if (typeinit == NULL_TREE) - { - ffeinfoBasictype bt = ffesymbol_basictype (s); - ffeinfoKindtype kt = ffesymbol_kindtype (s); - int tc = ffecom_f2c_typecode (bt, kt); - - assert (tc != -1); - typeinit = build_int_2 (tc, (tc < 0) ? -1 : 0); - } - else - typeinit = ffecom_1 (NEGATE_EXPR, TREE_TYPE (typeinit), typeinit); - - varinits = build_tree_list ((field = TYPE_FIELDS (vardesctype)), - nameinit); - TREE_CHAIN (varinits) = build_tree_list ((field = TREE_CHAIN (field)), - addrinit); - TREE_CHAIN (TREE_CHAIN (varinits)) - = build_tree_list ((field = TREE_CHAIN (field)), dimsinit); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (varinits))) - = build_tree_list ((field = TREE_CHAIN (field)), typeinit); - - varinits = build (CONSTRUCTOR, vardesctype, NULL_TREE, varinits); - TREE_CONSTANT (varinits) = 1; - TREE_STATIC (varinits) = 1; - - finish_decl (var, varinits, FALSE); - - var = ffecom_1 (ADDR_EXPR, build_pointer_type (vardesctype), var); - - resume_momentary (yes); - - ffesymbol_hook (s).vardesc_tree = var; - } - - return ffesymbol_hook (s).vardesc_tree; -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_vardesc_array_ (ffesymbol s) -{ - ffebld b; - tree list; - tree item = NULL_TREE; - tree var; - int i; - int yes; - static int mynumber = 0; - - for (i = 0, list = NULL_TREE, b = ffesymbol_namelist (s); - b != NULL; - b = ffebld_trail (b), ++i) - { - tree t; - - t = ffecom_vardesc_ (ffebld_head (b)); - - if (list == NULL_TREE) - list = item = build_tree_list (NULL_TREE, t); - else - { - TREE_CHAIN (item) = build_tree_list (NULL_TREE, t); - item = TREE_CHAIN (item); - } - } - - yes = suspend_momentary (); - - item = build_array_type (build_pointer_type (ffecom_type_vardesc_ ()), - build_range_type (integer_type_node, - integer_one_node, - build_int_2 (i, 0))); - list = build (CONSTRUCTOR, item, NULL_TREE, list); - TREE_CONSTANT (list) = 1; - TREE_STATIC (list) = 1; - - var = ffecom_get_invented_identifier ("__g77_vardesc_array_%d", NULL, - mynumber++); - var = build_decl (VAR_DECL, var, item); - TREE_STATIC (var) = 1; - DECL_INITIAL (var) = error_mark_node; - var = start_decl (var, FALSE); - finish_decl (var, list, FALSE); - - resume_momentary (yes); - - return var; -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffecom_vardesc_dims_ (ffesymbol s) -{ - if (ffesymbol_dims (s) == NULL) - return convert (ffecom_f2c_ptr_to_ftnlen_type_node, - integer_zero_node); - - { - ffebld b; - ffebld e; - tree list; - tree backlist; - tree item = NULL_TREE; - tree var; - int yes; - tree numdim; - tree numelem; - tree baseoff = NULL_TREE; - static int mynumber = 0; - - numdim = build_int_2 ((int) ffesymbol_rank (s), 0); - TREE_TYPE (numdim) = ffecom_f2c_ftnlen_type_node; - - numelem = ffecom_expr (ffesymbol_arraysize (s)); - TREE_TYPE (numelem) = ffecom_f2c_ftnlen_type_node; - - list = NULL_TREE; - backlist = NULL_TREE; - for (b = ffesymbol_dims (s), e = ffesymbol_extents (s); - b != NULL; - b = ffebld_trail (b), e = ffebld_trail (e)) - { - tree t; - tree low; - tree back; - - if (ffebld_trail (b) == NULL) - t = NULL_TREE; - else - { - t = convert (ffecom_f2c_ftnlen_type_node, - ffecom_expr (ffebld_head (e))); - - if (list == NULL_TREE) - list = item = build_tree_list (NULL_TREE, t); - else - { - TREE_CHAIN (item) = build_tree_list (NULL_TREE, t); - item = TREE_CHAIN (item); - } - } - - if (ffebld_left (ffebld_head (b)) == NULL) - low = ffecom_integer_one_node; - else - low = ffecom_expr (ffebld_left (ffebld_head (b))); - low = convert (ffecom_f2c_ftnlen_type_node, low); - - back = build_tree_list (low, t); - TREE_CHAIN (back) = backlist; - backlist = back; - } - - for (item = backlist; item != NULL_TREE; item = TREE_CHAIN (item)) - { - if (TREE_VALUE (item) == NULL_TREE) - baseoff = TREE_PURPOSE (item); - else - baseoff = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - TREE_PURPOSE (item), - ffecom_2 (MULT_EXPR, - ffecom_f2c_ftnlen_type_node, - TREE_VALUE (item), - baseoff)); - } - - /* backlist now dead, along with all TREE_PURPOSEs on it. */ - - baseoff = build_tree_list (NULL_TREE, baseoff); - TREE_CHAIN (baseoff) = list; - - numelem = build_tree_list (NULL_TREE, numelem); - TREE_CHAIN (numelem) = baseoff; - - numdim = build_tree_list (NULL_TREE, numdim); - TREE_CHAIN (numdim) = numelem; - - yes = suspend_momentary (); - - item = build_array_type (ffecom_f2c_ftnlen_type_node, - build_range_type (integer_type_node, - integer_zero_node, - build_int_2 - ((int) ffesymbol_rank (s) - + 2, 0))); - list = build (CONSTRUCTOR, item, NULL_TREE, numdim); - TREE_CONSTANT (list) = 1; - TREE_STATIC (list) = 1; - - var = ffecom_get_invented_identifier ("__g77_dims_%d", NULL, - mynumber++); - var = build_decl (VAR_DECL, var, item); - TREE_STATIC (var) = 1; - DECL_INITIAL (var) = error_mark_node; - var = start_decl (var, FALSE); - finish_decl (var, list, FALSE); - - var = ffecom_1 (ADDR_EXPR, build_pointer_type (item), var); - - resume_momentary (yes); - - return var; - } -} - -#endif -/* Essentially does a "fold (build1 (code, type, node))" while checking - for certain housekeeping things. - - NOTE: for building an ADDR_EXPR around a FUNCTION_DECL, use - ffecom_1_fn instead. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_1 (enum tree_code code, tree type, tree node) -{ - tree item; - - if ((node == error_mark_node) - || (type == error_mark_node)) - return error_mark_node; - - if (code == ADDR_EXPR) - { - if (!mark_addressable (node)) - assert ("can't mark_addressable this node!" == NULL); - } - - switch (ffe_is_emulate_complex () ? code : NOP_EXPR) - { - tree realtype; - - case REALPART_EXPR: - item = build (COMPONENT_REF, type, node, TYPE_FIELDS (TREE_TYPE (node))); - break; - - case IMAGPART_EXPR: - item = build (COMPONENT_REF, type, node, TREE_CHAIN (TYPE_FIELDS (TREE_TYPE (node)))); - break; - - - case NEGATE_EXPR: - if (TREE_CODE (type) != RECORD_TYPE) - { - item = build1 (code, type, node); - break; - } - node = ffecom_stabilize_aggregate_ (node); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - item = - ffecom_2 (COMPLEX_EXPR, type, - ffecom_1 (NEGATE_EXPR, realtype, - ffecom_1 (REALPART_EXPR, realtype, - node)), - ffecom_1 (NEGATE_EXPR, realtype, - ffecom_1 (IMAGPART_EXPR, realtype, - node))); - break; - - default: - item = build1 (code, type, node); - break; - } - - if (TREE_SIDE_EFFECTS (node)) - TREE_SIDE_EFFECTS (item) = 1; - if ((code == ADDR_EXPR) && staticp (node)) - TREE_CONSTANT (item) = 1; - return fold (item); -} -#endif - -/* Like ffecom_1 (ADDR_EXPR, TREE_TYPE (node), node), except - handles TREE_CODE (node) == FUNCTION_DECL. In particular, - does not set TREE_ADDRESSABLE (because calling an inline - function does not mean the function needs to be separately - compiled). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_1_fn (tree node) -{ - tree item; - tree type; - - if (node == error_mark_node) - return error_mark_node; - - type = build_type_variant (TREE_TYPE (node), - TREE_READONLY (node), - TREE_THIS_VOLATILE (node)); - item = build1 (ADDR_EXPR, - build_pointer_type (type), node); - if (TREE_SIDE_EFFECTS (node)) - TREE_SIDE_EFFECTS (item) = 1; - if (staticp (node)) - TREE_CONSTANT (item) = 1; - return fold (item); -} -#endif - -/* Essentially does a "fold (build (code, type, node1, node2))" while - checking for certain housekeeping things. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_2 (enum tree_code code, tree type, tree node1, - tree node2) -{ - tree item; - - if ((node1 == error_mark_node) - || (node2 == error_mark_node) - || (type == error_mark_node)) - return error_mark_node; - - switch (ffe_is_emulate_complex () ? code : NOP_EXPR) - { - tree a, b, c, d, realtype; - - case CONJ_EXPR: - assert ("no CONJ_EXPR support yet" == NULL); - return error_mark_node; - - case COMPLEX_EXPR: - item = build_tree_list (TYPE_FIELDS (type), node1); - TREE_CHAIN (item) = build_tree_list (TREE_CHAIN (TYPE_FIELDS (type)), node2); - item = build (CONSTRUCTOR, type, NULL_TREE, item); - break; - - case PLUS_EXPR: - if (TREE_CODE (type) != RECORD_TYPE) - { - item = build (code, type, node1, node2); - break; - } - node1 = ffecom_stabilize_aggregate_ (node1); - node2 = ffecom_stabilize_aggregate_ (node2); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - item = - ffecom_2 (COMPLEX_EXPR, type, - ffecom_2 (PLUS_EXPR, realtype, - ffecom_1 (REALPART_EXPR, realtype, - node1), - ffecom_1 (REALPART_EXPR, realtype, - node2)), - ffecom_2 (PLUS_EXPR, realtype, - ffecom_1 (IMAGPART_EXPR, realtype, - node1), - ffecom_1 (IMAGPART_EXPR, realtype, - node2))); - break; - - case MINUS_EXPR: - if (TREE_CODE (type) != RECORD_TYPE) - { - item = build (code, type, node1, node2); - break; - } - node1 = ffecom_stabilize_aggregate_ (node1); - node2 = ffecom_stabilize_aggregate_ (node2); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - item = - ffecom_2 (COMPLEX_EXPR, type, - ffecom_2 (MINUS_EXPR, realtype, - ffecom_1 (REALPART_EXPR, realtype, - node1), - ffecom_1 (REALPART_EXPR, realtype, - node2)), - ffecom_2 (MINUS_EXPR, realtype, - ffecom_1 (IMAGPART_EXPR, realtype, - node1), - ffecom_1 (IMAGPART_EXPR, realtype, - node2))); - break; - - case MULT_EXPR: - if (TREE_CODE (type) != RECORD_TYPE) - { - item = build (code, type, node1, node2); - break; - } - node1 = ffecom_stabilize_aggregate_ (node1); - node2 = ffecom_stabilize_aggregate_ (node2); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - a = save_expr (ffecom_1 (REALPART_EXPR, realtype, - node1)); - b = save_expr (ffecom_1 (IMAGPART_EXPR, realtype, - node1)); - c = save_expr (ffecom_1 (REALPART_EXPR, realtype, - node2)); - d = save_expr (ffecom_1 (IMAGPART_EXPR, realtype, - node2)); - item = - ffecom_2 (COMPLEX_EXPR, type, - ffecom_2 (MINUS_EXPR, realtype, - ffecom_2 (MULT_EXPR, realtype, - a, - c), - ffecom_2 (MULT_EXPR, realtype, - b, - d)), - ffecom_2 (PLUS_EXPR, realtype, - ffecom_2 (MULT_EXPR, realtype, - a, - d), - ffecom_2 (MULT_EXPR, realtype, - c, - b))); - break; - - case EQ_EXPR: - if ((TREE_CODE (node1) != RECORD_TYPE) - && (TREE_CODE (node2) != RECORD_TYPE)) - { - item = build (code, type, node1, node2); - break; - } - assert (TREE_CODE (node1) == RECORD_TYPE); - assert (TREE_CODE (node2) == RECORD_TYPE); - node1 = ffecom_stabilize_aggregate_ (node1); - node2 = ffecom_stabilize_aggregate_ (node2); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - item = - ffecom_2 (TRUTH_ANDIF_EXPR, type, - ffecom_2 (code, type, - ffecom_1 (REALPART_EXPR, realtype, - node1), - ffecom_1 (REALPART_EXPR, realtype, - node2)), - ffecom_2 (code, type, - ffecom_1 (IMAGPART_EXPR, realtype, - node1), - ffecom_1 (IMAGPART_EXPR, realtype, - node2))); - break; - - case NE_EXPR: - if ((TREE_CODE (node1) != RECORD_TYPE) - && (TREE_CODE (node2) != RECORD_TYPE)) - { - item = build (code, type, node1, node2); - break; - } - assert (TREE_CODE (node1) == RECORD_TYPE); - assert (TREE_CODE (node2) == RECORD_TYPE); - node1 = ffecom_stabilize_aggregate_ (node1); - node2 = ffecom_stabilize_aggregate_ (node2); - realtype = TREE_TYPE (TYPE_FIELDS (type)); - item = - ffecom_2 (TRUTH_ORIF_EXPR, type, - ffecom_2 (code, type, - ffecom_1 (REALPART_EXPR, realtype, - node1), - ffecom_1 (REALPART_EXPR, realtype, - node2)), - ffecom_2 (code, type, - ffecom_1 (IMAGPART_EXPR, realtype, - node1), - ffecom_1 (IMAGPART_EXPR, realtype, - node2))); - break; - - default: - item = build (code, type, node1, node2); - break; - } - - if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2)) - TREE_SIDE_EFFECTS (item) = 1; - return fold (item); -} - -#endif -/* ffecom_2pass_advise_entrypoint -- Advise that there's this entrypoint - - ffesymbol s; // the ENTRY point itself - if (ffecom_2pass_advise_entrypoint(s)) - // the ENTRY point has been accepted - - Does whatever compiler needs to do when it learns about the entrypoint, - like determine the return type of the master function, count the - number of entrypoints, etc. Returns FALSE if the return type is - not compatible with the return type(s) of other entrypoint(s). - - NOTE: for every call to this fn that returns TRUE, _do_entrypoint must - later (after _finish_progunit) be called with the same entrypoint(s) - as passed to this fn for which TRUE was returned. - - 03-Jan-92 JCB 2.0 - Return FALSE if the return type conflicts with previous entrypoints. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -bool -ffecom_2pass_advise_entrypoint (ffesymbol entry) -{ - ffebld list; /* opITEM. */ - ffebld mlist; /* opITEM. */ - ffebld plist; /* opITEM. */ - ffebld arg; /* ffebld_head(opITEM). */ - ffebld item; /* opITEM. */ - ffesymbol s; /* ffebld_symter(arg). */ - ffeinfoBasictype bt = ffesymbol_basictype (entry); - ffeinfoKindtype kt = ffesymbol_kindtype (entry); - ffetargetCharacterSize size = ffesymbol_size (entry); - bool ok; - - if (ffecom_num_entrypoints_ == 0) - { /* First entrypoint, make list of main - arglist's dummies. */ - assert (ffecom_primary_entry_ != NULL); - - ffecom_master_bt_ = ffesymbol_basictype (ffecom_primary_entry_); - ffecom_master_kt_ = ffesymbol_kindtype (ffecom_primary_entry_); - ffecom_master_size_ = ffesymbol_size (ffecom_primary_entry_); - - for (plist = NULL, list = ffesymbol_dummyargs (ffecom_primary_entry_); - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) != FFEBLD_opSYMTER) - continue; /* Alternate return or some such thing. */ - item = ffebld_new_item (arg, NULL); - if (plist == NULL) - ffecom_master_arglist_ = item; - else - ffebld_set_trail (plist, item); - plist = item; - } - } - - /* If necessary, scan entry arglist for alternate returns. Do this scan - apparently redundantly (it's done below to UNIONize the arglists) so - that we don't complain about RETURN 1 if an offending ENTRY is the only - one with an alternate return. */ - - if (!ffecom_is_altreturning_) - { - for (list = ffesymbol_dummyargs (entry); - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) == FFEBLD_opSTAR) - { - ffecom_is_altreturning_ = TRUE; - break; - } - } - } - - /* Now check type compatibility. */ - - switch (ffecom_master_bt_) - { - case FFEINFO_basictypeNONE: - ok = (bt != FFEINFO_basictypeCHARACTER); - break; - - case FFEINFO_basictypeCHARACTER: - ok - = (bt == FFEINFO_basictypeCHARACTER) - && (kt == ffecom_master_kt_) - && (size == ffecom_master_size_); - break; - - case FFEINFO_basictypeANY: - return FALSE; /* Just don't bother. */ - - default: - if (bt == FFEINFO_basictypeCHARACTER) - { - ok = FALSE; - break; - } - ok = TRUE; - if ((bt != ffecom_master_bt_) || (kt != ffecom_master_kt_)) - { - ffecom_master_bt_ = FFEINFO_basictypeNONE; - ffecom_master_kt_ = FFEINFO_kindtypeNONE; - } - break; - } - - if (!ok) - { - ffebad_start (FFEBAD_ENTRY_CONFLICTS); - ffest_ffebad_here_current_stmt (0); - ffebad_finish (); - return FALSE; /* Can't handle entrypoint. */ - } - - /* Entrypoint type compatible with previous types. */ - - ++ffecom_num_entrypoints_; - - /* Master-arg-list = UNION(Master-arg-list,entry-arg-list). */ - - for (list = ffesymbol_dummyargs (entry); - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) != FFEBLD_opSYMTER) - continue; /* Alternate return or some such thing. */ - s = ffebld_symter (arg); - for (plist = NULL, mlist = ffecom_master_arglist_; - mlist != NULL; - plist = mlist, mlist = ffebld_trail (mlist)) - { /* plist points to previous item for easy - appending of arg. */ - if (ffebld_symter (ffebld_head (mlist)) == s) - break; /* Already have this arg in the master list. */ - } - if (mlist != NULL) - continue; /* Already have this arg in the master list. */ - - /* Append this arg to the master list. */ - - item = ffebld_new_item (arg, NULL); - if (plist == NULL) - ffecom_master_arglist_ = item; - else - ffebld_set_trail (plist, item); - } - - return TRUE; -} - -#endif -/* ffecom_2pass_do_entrypoint -- Do compilation of entrypoint - - ffesymbol s; // the ENTRY point itself - ffecom_2pass_do_entrypoint(s); - - Does whatever compiler needs to do to make the entrypoint actually - happen. Must be called for each entrypoint after - ffecom_finish_progunit is called. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_2pass_do_entrypoint (ffesymbol entry) -{ - static int mfn_num = 0; - static int ent_num; - - if (mfn_num != ffecom_num_fns_) - { /* First entrypoint for this program unit. */ - ent_num = 1; - mfn_num = ffecom_num_fns_; - ffecom_do_entry_ (ffecom_primary_entry_, 0); - } - else - ++ent_num; - - --ffecom_num_entrypoints_; - - ffecom_do_entry_ (entry, ent_num); -} - -#endif - -/* Essentially does a "fold (build (code, type, node1, node2))" while - checking for certain housekeeping things. Always sets - TREE_SIDE_EFFECTS. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_2s (enum tree_code code, tree type, tree node1, - tree node2) -{ - tree item; - - if ((node1 == error_mark_node) - || (node2 == error_mark_node) - || (type == error_mark_node)) - return error_mark_node; - - item = build (code, type, node1, node2); - TREE_SIDE_EFFECTS (item) = 1; - return fold (item); -} - -#endif -/* Essentially does a "fold (build (code, type, node1, node2, node3))" while - checking for certain housekeeping things. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_3 (enum tree_code code, tree type, tree node1, - tree node2, tree node3) -{ - tree item; - - if ((node1 == error_mark_node) - || (node2 == error_mark_node) - || (node3 == error_mark_node) - || (type == error_mark_node)) - return error_mark_node; - - item = build (code, type, node1, node2, node3); - if (TREE_SIDE_EFFECTS (node1) || TREE_SIDE_EFFECTS (node2) - || (node3 != NULL_TREE && TREE_SIDE_EFFECTS (node3))) - TREE_SIDE_EFFECTS (item) = 1; - return fold (item); -} - -#endif -/* Essentially does a "fold (build (code, type, node1, node2, node3))" while - checking for certain housekeeping things. Always sets - TREE_SIDE_EFFECTS. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_3s (enum tree_code code, tree type, tree node1, - tree node2, tree node3) -{ - tree item; - - if ((node1 == error_mark_node) - || (node2 == error_mark_node) - || (node3 == error_mark_node) - || (type == error_mark_node)) - return error_mark_node; - - item = build (code, type, node1, node2, node3); - TREE_SIDE_EFFECTS (item) = 1; - return fold (item); -} - -#endif -/* ffecom_arg_expr -- Transform argument expr into gcc tree - - See use by ffecom_list_expr. - - If expression is NULL, returns an integer zero tree. If it is not - a CHARACTER expression, returns whatever ffecom_expr - returns and sets the length return value to NULL_TREE. Otherwise - generates code to evaluate the character expression, returns the proper - pointer to the result, but does NOT set the length return value to a tree - that specifies the length of the result. (In other words, the length - variable is always set to NULL_TREE, because a length is never passed.) - - 21-Dec-91 JCB 1.1 - Don't set returned length, since nobody needs it (yet; someday if - we allow CHARACTER*(*) dummies to statement functions, we'll need - it). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_arg_expr (ffebld expr, tree *length) -{ - tree ign; - - *length = NULL_TREE; - - if (expr == NULL) - return integer_zero_node; - - if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER) - return ffecom_expr (expr); - - return ffecom_arg_ptr_to_expr (expr, &ign); -} - -#endif -/* ffecom_arg_ptr_to_expr -- Transform argument expr into gcc tree - - See use by ffecom_list_ptr_to_expr. - - If expression is NULL, returns an integer zero tree. If it is not - a CHARACTER expression, returns whatever ffecom_ptr_to_expr - returns and sets the length return value to NULL_TREE. Otherwise - generates code to evaluate the character expression, returns the proper - pointer to the result, AND sets the length return value to a tree that - specifies the length of the result. - - If the length argument is NULL, this is a slightly special - case of building a FORMAT expression, that is, an expression that - will be used at run time without regard to length. For the current - implementation, which uses the libf2c library, this means it is nice - to append a null byte to the end of the expression, where feasible, - to make sure any diagnostic about the FORMAT string terminates at - some useful point. - - For now, treat %REF(char-expr) as the same as char-expr with a NULL - length argument. This might even be seen as a feature, if a null - byte can always be appended. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_arg_ptr_to_expr (ffebld expr, tree *length) -{ - tree item; - tree ign_length; - ffecomConcatList_ catlist; - - if (length != NULL) - *length = NULL_TREE; - - if (expr == NULL) - return integer_zero_node; - - switch (ffebld_op (expr)) - { - case FFEBLD_opPERCENT_VAL: - if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER) - return ffecom_expr (ffebld_left (expr)); - { - tree temp_exp; - tree temp_length; - - temp_exp = ffecom_arg_ptr_to_expr (ffebld_left (expr), &temp_length); - return ffecom_1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (temp_exp)), - temp_exp); - } - - case FFEBLD_opPERCENT_REF: - if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER) - return ffecom_ptr_to_expr (ffebld_left (expr)); - if (length != NULL) - { - ign_length = NULL_TREE; - length = &ign_length; - } - expr = ffebld_left (expr); - break; - - case FFEBLD_opPERCENT_DESCR: - switch (ffeinfo_basictype (ffebld_info (expr))) - { -#ifdef PASS_HOLLERITH_BY_DESCRIPTOR - case FFEINFO_basictypeHOLLERITH: -#endif - case FFEINFO_basictypeCHARACTER: - break; /* Passed by descriptor anyway. */ - - default: - item = ffecom_ptr_to_expr (expr); - if (item != error_mark_node) - *length = TYPE_SIZE (TREE_TYPE (TREE_TYPE (item))); - break; - } - break; - - default: - break; - } - -#ifdef PASS_HOLLERITH_BY_DESCRIPTOR - if ((ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeHOLLERITH) - && (length != NULL)) - { /* Pass Hollerith by descriptor. */ - ffetargetHollerith h; - - assert (ffebld_op (expr) == FFEBLD_opCONTER); - h = ffebld_cu_val_hollerith (ffebld_constant_union - (ffebld_conter (expr))); - *length - = build_int_2 (h.length, 0); - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - } -#endif - - if (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeCHARACTER) - return ffecom_ptr_to_expr (expr); - - assert (ffeinfo_kindtype (ffebld_info (expr)) - == FFEINFO_kindtypeCHARACTER1); - - catlist = ffecom_concat_list_new_ (expr, FFETARGET_charactersizeNONE); - switch (ffecom_concat_list_count_ (catlist)) - { - case 0: /* Shouldn't happen, but in case it does... */ - if (length != NULL) - { - *length = ffecom_f2c_ftnlen_zero_node; - TREE_TYPE (*length) = ffecom_f2c_ftnlen_type_node; - } - ffecom_concat_list_kill_ (catlist); - return null_pointer_node; - - case 1: /* The (fairly) easy case. */ - if (length == NULL) - ffecom_char_args_with_null_ (&item, &ign_length, - ffecom_concat_list_expr_ (catlist, 0)); - else - ffecom_char_args_ (&item, length, - ffecom_concat_list_expr_ (catlist, 0)); - ffecom_concat_list_kill_ (catlist); - assert (item != NULL_TREE); - return item; - - default: /* Must actually concatenate things. */ - break; - } - - { - int count = ffecom_concat_list_count_ (catlist); - int i; - tree lengths; - tree items; - tree length_array; - tree item_array; - tree citem; - tree clength; - tree temporary; - tree num; - tree known_length; - ffetargetCharacterSize sz; - - length_array - = lengths - = ffecom_push_tempvar (ffecom_f2c_ftnlen_type_node, - FFETARGET_charactersizeNONE, count, TRUE); - item_array - = items - = ffecom_push_tempvar (ffecom_f2c_address_type_node, - FFETARGET_charactersizeNONE, count, TRUE); - - known_length = ffecom_f2c_ftnlen_zero_node; - - for (i = 0; i < count; ++i) - { - if ((i == count) - && (length == NULL)) - ffecom_char_args_with_null_ (&citem, &clength, - ffecom_concat_list_expr_ (catlist, i)); - else - ffecom_char_args_ (&citem, &clength, - ffecom_concat_list_expr_ (catlist, i)); - if ((citem == error_mark_node) - || (clength == error_mark_node)) - { - ffecom_concat_list_kill_ (catlist); - *length = error_mark_node; - return error_mark_node; - } - - items - = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (items), - ffecom_modify (void_type_node, - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item_array))), - item_array, - build_int_2 (i, 0)), - citem), - items); - clength = ffecom_save_tree (clength); - if (length != NULL) - known_length - = ffecom_2 (PLUS_EXPR, ffecom_f2c_ftnlen_type_node, - known_length, - clength); - lengths - = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (lengths), - ffecom_modify (void_type_node, - ffecom_2 (ARRAY_REF, - TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (length_array))), - length_array, - build_int_2 (i, 0)), - clength), - lengths); - } - - sz = ffecom_concat_list_maxlen_ (catlist); - assert (sz != FFETARGET_charactersizeNONE); - - temporary = ffecom_push_tempvar (char_type_node, - sz, -1, TRUE); - temporary = ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (temporary)), - temporary); - - item = build_tree_list (NULL_TREE, temporary); - TREE_CHAIN (item) - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (items)), - items)); - TREE_CHAIN (TREE_CHAIN (item)) - = build_tree_list (NULL_TREE, - ffecom_1 (ADDR_EXPR, - build_pointer_type (TREE_TYPE (lengths)), - lengths)); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item))) - = build_tree_list - (NULL_TREE, - ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node, - convert (ffecom_f2c_ftnlen_type_node, - build_int_2 (count, 0)))); - num = build_int_2 (sz, 0); - TREE_TYPE (num) = ffecom_f2c_ftnlen_type_node; - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (item)))) - = build_tree_list (NULL_TREE, num); - - item = ffecom_call_gfrt (FFECOM_gfrtCAT, item); - TREE_SIDE_EFFECTS (item) = 1; - item = ffecom_2 (COMPOUND_EXPR, TREE_TYPE (temporary), - item, - temporary); - - if (length != NULL) - *length = known_length; - } - - ffecom_concat_list_kill_ (catlist); - assert (item != NULL_TREE); - return item; -} - -#endif -/* ffecom_call_gfrt -- Generate call to run-time function - - tree expr; - expr = ffecom_call_gfrt(FFECOM_gfrtSTOPNIL,NULL_TREE); - - The first arg is the GNU Fortran Run-Time function index, the second - arg is the list of arguments to pass to it. Returned is the expression - (WITHOUT TREE_SIDE_EFFECTS set!) that makes the call and returns the - result (which may be void). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_call_gfrt (ffecomGfrt ix, tree args) -{ - return ffecom_call_ (ffecom_gfrt_tree_ (ix), - ffecom_gfrt_kindtype (ix), - ffe_is_f2c_library () && ffecom_gfrt_complex_[ix], - NULL_TREE, args, NULL_TREE, NULL, - NULL, NULL_TREE, TRUE); -} -#endif - -/* ffecom_constantunion -- Transform constant-union to tree - - ffebldConstantUnion cu; // the constant to transform - ffeinfoBasictype bt; // its basic type - ffeinfoKindtype kt; // its kind type - tree tree_type; // ffecom_tree_type[bt][kt] - ffecom_constantunion(&cu,bt,kt,tree_type); */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt, - ffeinfoKindtype kt, tree tree_type) -{ - tree item; - - switch (bt) - { - case FFEINFO_basictypeINTEGER: - { - int val; - - switch (kt) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - val = ffebld_cu_val_integer1 (*cu); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - val = ffebld_cu_val_integer2 (*cu); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - val = ffebld_cu_val_integer3 (*cu); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - val = ffebld_cu_val_integer4 (*cu); - break; -#endif - - default: - assert ("bad INTEGER constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return error_mark_node; - } - item = build_int_2 (val, (val < 0) ? -1 : 0); - TREE_TYPE (item) = tree_type; - } - break; - - case FFEINFO_basictypeLOGICAL: - { - int val; - - switch (kt) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - val = ffebld_cu_val_logical1 (*cu); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - val = ffebld_cu_val_logical2 (*cu); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - val = ffebld_cu_val_logical3 (*cu); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - val = ffebld_cu_val_logical4 (*cu); - break; -#endif - - default: - assert ("bad LOGICAL constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return error_mark_node; - } - item = build_int_2 (val, (val < 0) ? -1 : 0); - TREE_TYPE (item) = tree_type; - } - break; - - case FFEINFO_basictypeREAL: - { - REAL_VALUE_TYPE val; - - switch (kt) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - val = ffetarget_value_real1 (ffebld_cu_val_real1 (*cu)); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - val = ffetarget_value_real2 (ffebld_cu_val_real2 (*cu)); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - val = ffetarget_value_real3 (ffebld_cu_val_real3 (*cu)); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - val = ffetarget_value_real4 (ffebld_cu_val_real4 (*cu)); - break; -#endif - - default: - assert ("bad REAL constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return error_mark_node; - } - item = build_real (tree_type, val); - } - break; - - case FFEINFO_basictypeCOMPLEX: - { - REAL_VALUE_TYPE real; - REAL_VALUE_TYPE imag; - tree el_type = ffecom_tree_type[FFEINFO_basictypeREAL][kt]; - - switch (kt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - real = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).real); - imag = ffetarget_value_real1 (ffebld_cu_val_complex1 (*cu).imaginary); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - real = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).real); - imag = ffetarget_value_real2 (ffebld_cu_val_complex2 (*cu).imaginary); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - real = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).real); - imag = ffetarget_value_real3 (ffebld_cu_val_complex3 (*cu).imaginary); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - real = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).real); - imag = ffetarget_value_real4 (ffebld_cu_val_complex4 (*cu).imaginary); - break; -#endif - - default: - assert ("bad REAL constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return error_mark_node; - } - item = ffecom_build_complex_constant_ (tree_type, - build_real (el_type, real), - build_real (el_type, imag)); - } - break; - - case FFEINFO_basictypeCHARACTER: - { /* Happens only in DATA and similar contexts. */ - ffetargetCharacter1 val; - - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeLOGICAL1: - val = ffebld_cu_val_character1 (*cu); - break; -#endif - - default: - assert ("bad CHARACTER constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return error_mark_node; - } - item = build_string (ffetarget_length_character1 (val), - ffetarget_text_character1 (val)); - TREE_TYPE (item) - = build_type_variant (build_array_type (char_type_node, - build_range_type - (integer_type_node, - integer_one_node, - build_int_2 - (ffetarget_length_character1 - (val), 0))), - 1, 0); - } - break; - - case FFEINFO_basictypeHOLLERITH: - { - ffetargetHollerith h; - - h = ffebld_cu_val_hollerith (*cu); - - /* If not at least as wide as default INTEGER, widen it. */ - if (h.length >= FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE) - item = build_string (h.length, h.text); - else - { - char str[FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE]; - - memcpy (str, h.text, h.length); - memset (&str[h.length], ' ', - FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE - - h.length); - item = build_string (FLOAT_TYPE_SIZE / CHAR_TYPE_SIZE, - str); - } - TREE_TYPE (item) - = build_type_variant (build_array_type (char_type_node, - build_range_type - (integer_type_node, - integer_one_node, - build_int_2 - (h.length, 0))), - 1, 0); - } - break; - - case FFEINFO_basictypeTYPELESS: - { - ffetargetInteger1 ival; - ffetargetTypeless tless; - ffebad error; - - tless = ffebld_cu_val_typeless (*cu); - error = ffetarget_convert_integer1_typeless (&ival, tless); - assert (error == FFEBAD); - - item = build_int_2 ((int) ival, 0); - } - break; - - default: - assert ("not yet on constant type" == NULL); - /* Fall through. */ - case FFEINFO_basictypeANY: - return error_mark_node; - } - - TREE_CONSTANT (item) = 1; - - return item; -} - -#endif - -/* Handy way to make a field in a struct/union. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_decl_field (tree context, tree prevfield, - char *name, tree type) -{ - tree field; - - field = build_decl (FIELD_DECL, get_identifier (name), type); - DECL_CONTEXT (field) = context; - DECL_FRAME_SIZE (field) = 0; - if (prevfield != NULL_TREE) - TREE_CHAIN (prevfield) = field; - - return field; -} - -#endif - -void -ffecom_close_include (FILE *f) -{ -#if FFECOM_GCC_INCLUDE - ffecom_close_include_ (f); -#endif -} - -int -ffecom_decode_include_option (char *spec) -{ -#if FFECOM_GCC_INCLUDE - return ffecom_decode_include_option_ (spec); -#else - return 1; -#endif -} - -/* ffecom_end_transition -- Perform end transition on all symbols - - ffecom_end_transition(); - - Calls ffecom_sym_end_transition for each global and local symbol. */ - -void -ffecom_end_transition () -{ -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffebld item; -#endif - - if (ffe_is_ffedebug ()) - fprintf (dmpout, "; end_stmt_transition\n"); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffecom_list_blockdata_ = NULL; - ffecom_list_common_ = NULL; -#endif - - ffesymbol_drive (ffecom_sym_end_transition); - if (ffe_is_ffedebug ()) - { - ffestorag_report (); -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffesymbol_report_all (); -#endif - } - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffecom_start_progunit_ (); - - for (item = ffecom_list_blockdata_; - item != NULL; - item = ffebld_trail (item)) - { - ffebld callee; - ffesymbol s; - tree dt; - tree t; - tree var; - int yes; - static int number = 0; - - callee = ffebld_head (item); - s = ffebld_symter (callee); - t = ffesymbol_hook (s).decl_tree; - if (t == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - t = ffesymbol_hook (s).decl_tree; - } - - yes = suspend_momentary (); - - dt = build_pointer_type (TREE_TYPE (t)); - - var = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_forceload_%d", - NULL, number++), - dt); - DECL_EXTERNAL (var) = 0; - TREE_STATIC (var) = 1; - TREE_PUBLIC (var) = 0; - DECL_INITIAL (var) = error_mark_node; - TREE_USED (var) = 1; - - var = start_decl (var, FALSE); - - t = ffecom_1 (ADDR_EXPR, dt, t); - - finish_decl (var, t, FALSE); - - resume_momentary (yes); - } - - /* This handles any COMMON areas that weren't referenced but have, for - example, important initial data. */ - - for (item = ffecom_list_common_; - item != NULL; - item = ffebld_trail (item)) - ffecom_transform_common_ (ffebld_symter (ffebld_head (item))); - - ffecom_list_common_ = NULL; -#endif -} - -/* ffecom_exec_transition -- Perform exec transition on all symbols - - ffecom_exec_transition(); - - Calls ffecom_sym_exec_transition for each global and local symbol. - Make sure error updating not inhibited. */ - -void -ffecom_exec_transition () -{ - bool inhibited; - - if (ffe_is_ffedebug ()) - fprintf (dmpout, "; exec_stmt_transition\n"); - - inhibited = ffebad_inhibit (); - ffebad_set_inhibit (FALSE); - - ffesymbol_drive (ffecom_sym_exec_transition); /* Don't retract! */ - ffeequiv_exec_transition (); /* Handle all pending EQUIVALENCEs. */ - if (ffe_is_ffedebug ()) - { - ffestorag_report (); -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffesymbol_report_all (); -#endif - } - - if (inhibited) - ffebad_set_inhibit (TRUE); -} - -/* ffecom_expand_let_stmt -- Compile let (assignment) statement - - ffebld dest; - ffebld source; - ffecom_expand_let_stmt(dest,source); - - Convert dest and source using ffecom_expr, then join them - with an ASSIGN op and pass the whole thing to expand_expr_stmt. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_expand_let_stmt (ffebld dest, ffebld source) -{ - tree dest_tree; - tree dest_length; - tree source_tree; - tree expr_tree; - - if (ffeinfo_basictype (ffebld_info (dest)) != FFEINFO_basictypeCHARACTER) - { - bool dest_used; - - dest_tree = ffecom_expr_rw (dest); - if (dest_tree == error_mark_node) - return; - - if ((TREE_CODE (dest_tree) != VAR_DECL) - || TREE_ADDRESSABLE (dest_tree)) - source_tree = ffecom_expr_ (source, dest_tree, dest, &dest_used, - FALSE, FALSE); - else - { - source_tree = ffecom_expr (source); - dest_used = FALSE; - } - if (source_tree == error_mark_node) - return; - - if (dest_used) - expr_tree = source_tree; - else - expr_tree = ffecom_2s (MODIFY_EXPR, void_type_node, - dest_tree, - source_tree); - - expand_expr_stmt (expr_tree); - return; - } - - ffecom_push_calltemps (); - ffecom_char_args_ (&dest_tree, &dest_length, dest); - ffecom_let_char_ (dest_tree, dest_length, ffebld_size_known (dest), - source); - ffecom_pop_calltemps (); -} - -#endif -/* ffecom_expr -- Transform expr into gcc tree - - tree t; - ffebld expr; // FFE expression. - tree = ffecom_expr(expr); - - Recursive descent on expr while making corresponding tree nodes and - attaching type info and such. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_expr (ffebld expr) -{ - return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, FALSE, FALSE); -} - -#endif -/* Like ffecom_expr, but return tree usable for assigned GOTO or FORMAT. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_expr_assign (ffebld expr) -{ - return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE); -} - -#endif -/* Like ffecom_expr_rw, but return tree usable for ASSIGN. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_expr_assign_w (ffebld expr) -{ - return ffecom_expr_ (expr, NULL_TREE, NULL, NULL, TRUE, FALSE); -} - -#endif -/* Transform expr for use as into read/write tree and stabilize the - reference. Not for use on CHARACTER expressions. - - Recursive descent on expr while making corresponding tree nodes and - attaching type info and such. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_expr_rw (ffebld expr) -{ - assert (expr != NULL); - - return stabilize_reference (ffecom_expr (expr)); -} - -#endif -/* Do global stuff. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_finish_compile () -{ - assert (ffecom_outer_function_decl_ == NULL_TREE); - assert (current_function_decl == NULL_TREE); - - ffeglobal_drive (ffecom_finish_global_); -} - -#endif -/* Public entry point for front end to access finish_decl. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_finish_decl (tree decl, tree init, bool is_top_level) -{ - assert (!is_top_level); - finish_decl (decl, init, FALSE); -} - -#endif -/* Finish a program unit. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_finish_progunit () -{ - ffecom_end_compstmt_ (); - - ffecom_previous_function_decl_ = current_function_decl; - ffecom_which_entrypoint_decl_ = NULL_TREE; - - finish_function (0); -} - -#endif -/* Wrapper for get_identifier. pattern is like "...%s...", text is - inserted into final name in place of "%s", or if text is NULL, - pattern is like "...%d..." and text form of number is inserted - in place of "%d". */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_get_invented_identifier (char *pattern, char *text, int number) -{ - tree decl; - char *nam; - mallocSize lenlen; - char space[66]; - - if (text == NULL) - lenlen = strlen (pattern) + 20; - else - lenlen = strlen (pattern) + strlen (text) - 1; - if (lenlen > ARRAY_SIZE (space)) - nam = malloc_new_ks (malloc_pool_image (), pattern, lenlen); - else - nam = &space[0]; - if (text == NULL) - sprintf (&nam[0], pattern, number); - else - sprintf (&nam[0], pattern, text); - decl = get_identifier (nam); - if (lenlen > ARRAY_SIZE (space)) - malloc_kill_ks (malloc_pool_image (), nam, lenlen); - - IDENTIFIER_INVENTED (decl) = 1; - - return decl; -} - -ffeinfoBasictype -ffecom_gfrt_basictype (ffecomGfrt gfrt) -{ - assert (gfrt < FFECOM_gfrt); - - switch (ffecom_gfrt_type_[gfrt]) - { - case FFECOM_rttypeVOID_: - case FFECOM_rttypeVOIDSTAR_: - return FFEINFO_basictypeNONE; - - case FFECOM_rttypeFTNINT_: - return FFEINFO_basictypeINTEGER; - - case FFECOM_rttypeINTEGER_: - return FFEINFO_basictypeINTEGER; - - case FFECOM_rttypeLONGINT_: - return FFEINFO_basictypeINTEGER; - - case FFECOM_rttypeLOGICAL_: - return FFEINFO_basictypeLOGICAL; - - case FFECOM_rttypeREAL_F2C_: - case FFECOM_rttypeREAL_GNU_: - return FFEINFO_basictypeREAL; - - case FFECOM_rttypeCOMPLEX_F2C_: - case FFECOM_rttypeCOMPLEX_GNU_: - return FFEINFO_basictypeCOMPLEX; - - case FFECOM_rttypeDOUBLE_: - case FFECOM_rttypeDOUBLEREAL_: - return FFEINFO_basictypeREAL; - - case FFECOM_rttypeDBLCMPLX_F2C_: - case FFECOM_rttypeDBLCMPLX_GNU_: - return FFEINFO_basictypeCOMPLEX; - - case FFECOM_rttypeCHARACTER_: - return FFEINFO_basictypeCHARACTER; - - default: - return FFEINFO_basictypeANY; - } -} - -ffeinfoKindtype -ffecom_gfrt_kindtype (ffecomGfrt gfrt) -{ - assert (gfrt < FFECOM_gfrt); - - switch (ffecom_gfrt_type_[gfrt]) - { - case FFECOM_rttypeVOID_: - case FFECOM_rttypeVOIDSTAR_: - return FFEINFO_kindtypeNONE; - - case FFECOM_rttypeFTNINT_: - return FFEINFO_kindtypeINTEGER1; - - case FFECOM_rttypeINTEGER_: - return FFEINFO_kindtypeINTEGER1; - - case FFECOM_rttypeLONGINT_: - return FFEINFO_kindtypeINTEGER4; - - case FFECOM_rttypeLOGICAL_: - return FFEINFO_kindtypeLOGICAL1; - - case FFECOM_rttypeREAL_F2C_: - case FFECOM_rttypeREAL_GNU_: - return FFEINFO_kindtypeREAL1; - - case FFECOM_rttypeCOMPLEX_F2C_: - case FFECOM_rttypeCOMPLEX_GNU_: - return FFEINFO_kindtypeREAL1; - - case FFECOM_rttypeDOUBLE_: - case FFECOM_rttypeDOUBLEREAL_: - return FFEINFO_kindtypeREAL2; - - case FFECOM_rttypeDBLCMPLX_F2C_: - case FFECOM_rttypeDBLCMPLX_GNU_: - return FFEINFO_kindtypeREAL2; - - case FFECOM_rttypeCHARACTER_: - return FFEINFO_kindtypeCHARACTER1; - - default: - return FFEINFO_kindtypeANY; - } -} - -void -ffecom_init_0 () -{ - tree endlink; - int i; - int j; - tree t; - tree field; - ffetype type; - ffetype base_type; - - /* This block of code comes from the now-obsolete cktyps.c. It checks - whether the compiler environment is buggy in known ways, some of which - would, if not explicitly checked here, result in subtle bugs in g77. */ - - if (ffe_is_do_internal_checks ()) - { - static char names[][12] - = - {"bar", "bletch", "foo", "foobar"}; - char *name; - unsigned long ul; - double fl; - - name = bsearch ("foo", &names[0], ARRAY_SIZE (names), sizeof (names[0]), - (int (*)()) strcmp); - if (name != (char *) &names[2]) - { - assert ("bsearch doesn't work, #define FFEPROJ_BSEARCH 0 in proj.h" - == NULL); - abort (); - } - - ul = strtoul ("123456789", NULL, 10); - if (ul != 123456789L) - { - assert ("strtoul doesn't have enough range, #define FFEPROJ_STRTOUL 0\ - in proj.h" == NULL); - abort (); - } - - fl = atof ("56.789"); - if ((fl < 56.788) || (fl > 56.79)) - { - assert ("atof not type double, fix your #include <stdio.h>" - == NULL); - abort (); - } - } - - /* Set the sizetype before we do anything else. This _should_ be the - first type we create. */ - - t = make_unsigned_type (POINTER_SIZE); - assert (t == sizetype); - -#if FFECOM_GCC_INCLUDE - ffecom_initialize_char_syntax_ (); -#endif - - ffecom_outer_function_decl_ = NULL_TREE; - current_function_decl = NULL_TREE; - named_labels = NULL_TREE; - current_binding_level = NULL_BINDING_LEVEL; - free_binding_level = NULL_BINDING_LEVEL; - pushlevel (0); /* make the binding_level structure for - global names */ - global_binding_level = current_binding_level; - - /* Define `int' and `char' first so that dbx will output them first. */ - - integer_type_node = make_signed_type (INT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("int"), - integer_type_node)); - - char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("char"), - char_type_node)); - - long_integer_type_node = make_signed_type (LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long int"), - long_integer_type_node)); - - unsigned_type_node = make_unsigned_type (INT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned int"), - unsigned_type_node)); - - long_unsigned_type_node = make_unsigned_type (LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long unsigned int"), - long_unsigned_type_node)); - - long_long_integer_type_node = make_signed_type (LONG_LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long int"), - long_long_integer_type_node)); - - long_long_unsigned_type_node = make_unsigned_type (LONG_LONG_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long long unsigned int"), - long_long_unsigned_type_node)); - - error_mark_node = make_node (ERROR_MARK); - TREE_TYPE (error_mark_node) = error_mark_node; - - short_integer_type_node = make_signed_type (SHORT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short int"), - short_integer_type_node)); - - short_unsigned_type_node = make_unsigned_type (SHORT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("short unsigned int"), - short_unsigned_type_node)); - - /* Define both `signed char' and `unsigned char'. */ - signed_char_type_node = make_signed_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("signed char"), - signed_char_type_node)); - - unsigned_char_type_node = make_unsigned_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned char"), - unsigned_char_type_node)); - - float_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (float_type_node) = FLOAT_TYPE_SIZE; - layout_type (float_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("float"), - float_type_node)); - - double_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (double_type_node) = DOUBLE_TYPE_SIZE; - layout_type (double_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("double"), - double_type_node)); - - long_double_type_node = make_node (REAL_TYPE); - TYPE_PRECISION (long_double_type_node) = LONG_DOUBLE_TYPE_SIZE; - layout_type (long_double_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("long double"), - long_double_type_node)); - - complex_integer_type_node = ffecom_make_complex_type_ (integer_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex int"), - complex_integer_type_node)); - - complex_float_type_node = ffecom_make_complex_type_ (float_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex float"), - complex_float_type_node)); - - complex_double_type_node = ffecom_make_complex_type_ (double_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex double"), - complex_double_type_node)); - - complex_long_double_type_node = ffecom_make_complex_type_ (long_double_type_node); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex long double"), - complex_long_double_type_node)); - - integer_zero_node = build_int_2 (0, 0); - TREE_TYPE (integer_zero_node) = integer_type_node; - integer_one_node = build_int_2 (1, 0); - TREE_TYPE (integer_one_node) = integer_type_node; - - size_zero_node = build_int_2 (0, 0); - TREE_TYPE (size_zero_node) = sizetype; - size_one_node = build_int_2 (1, 0); - TREE_TYPE (size_one_node) = sizetype; - - void_type_node = make_node (VOID_TYPE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("void"), - void_type_node)); - layout_type (void_type_node); /* Uses integer_zero_node */ - /* We are not going to have real types in C with less than byte alignment, - so we might as well not have any types that claim to have it. */ - TYPE_ALIGN (void_type_node) = BITS_PER_UNIT; - - null_pointer_node = build_int_2 (0, 0); - TREE_TYPE (null_pointer_node) = build_pointer_type (void_type_node); - layout_type (TREE_TYPE (null_pointer_node)); - - string_type_node = build_pointer_type (char_type_node); - - ffecom_tree_fun_type_void - = build_function_type (void_type_node, NULL_TREE); - - ffecom_tree_ptr_to_fun_type_void - = build_pointer_type (ffecom_tree_fun_type_void); - - endlink = tree_cons (NULL_TREE, void_type_node, NULL_TREE); - - float_ftype_float - = build_function_type (float_type_node, - tree_cons (NULL_TREE, float_type_node, endlink)); - - double_ftype_double - = build_function_type (double_type_node, - tree_cons (NULL_TREE, double_type_node, endlink)); - - ldouble_ftype_ldouble - = build_function_type (long_double_type_node, - tree_cons (NULL_TREE, long_double_type_node, - endlink)); - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i) - for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) - { - ffecom_tree_type[i][j] = NULL_TREE; - ffecom_tree_fun_type[i][j] = NULL_TREE; - ffecom_tree_ptr_to_fun_type[i][j] = NULL_TREE; - ffecom_f2c_typecode_[i][j] = -1; - } - - /* Set up standard g77 types. Note that INTEGER and LOGICAL are set - to size FLOAT_TYPE_SIZE because they have to be the same size as - REAL, which also is FLOAT_TYPE_SIZE, according to the standard. - Compiler options and other such stuff that change the ways these - types are set should not affect this particular setup. */ - - ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1] - = t = make_signed_type (FLOAT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("integer"), - t)); - type = ffetype_new (); - base_type = type; - ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER1, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 1, type); - assert (ffetype_size (type) == sizeof (ffetargetInteger1)); - - ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER1] - = t = make_unsigned_type (FLOAT_TYPE_SIZE); /* HOLLERITH means unsigned. */ - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned"), - t)); - - ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER2] - = t = make_signed_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("byte"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER2, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 3, type); - assert (ffetype_size (type) == sizeof (ffetargetInteger2)); - - ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER2] - = t = make_unsigned_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned byte"), - t)); - - ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER3] - = t = make_signed_type (CHAR_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("word"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER3, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 6, type); - assert (ffetype_size (type) == sizeof (ffetargetInteger3)); - - ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER3] - = t = make_unsigned_type (CHAR_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned word"), - t)); - - ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER4] - = t = make_signed_type (FLOAT_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("integer4"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGER4, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 2, type); - assert (ffetype_size (type) == sizeof (ffetargetInteger4)); - - ffecom_tree_type[FFEINFO_basictypeHOLLERITH][FFEINFO_kindtypeINTEGER4] - = t = make_unsigned_type (FLOAT_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("unsigned4"), - t)); - -#if 0 - if (ffe_is_do_internal_checks () - && LONG_TYPE_SIZE != FLOAT_TYPE_SIZE - && LONG_TYPE_SIZE != CHAR_TYPE_SIZE - && LONG_TYPE_SIZE != SHORT_TYPE_SIZE - && LONG_TYPE_SIZE != LONG_LONG_TYPE_SIZE) - { - fprintf (stderr, "Sorry, no g77 support for LONG_TYPE_SIZE (%d bits) yet.\n", - LONG_TYPE_SIZE); - } -#endif - - ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL1] - = t = make_signed_type (FLOAT_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("logical"), - t)); - type = ffetype_new (); - base_type = type; - ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL1, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 1, type); - assert (ffetype_size (type) == sizeof (ffetargetLogical1)); - - ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL2] - = t = make_signed_type (CHAR_TYPE_SIZE); - pushdecl (build_decl (TYPE_DECL, get_identifier ("logical2"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL2, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 3, type); - assert (ffetype_size (type) == sizeof (ffetargetLogical2)); - - ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL3] - = t = make_signed_type (CHAR_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("logical3"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL3, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 6, type); - assert (ffetype_size (type) == sizeof (ffetargetLogical3)); - - ffecom_tree_type[FFEINFO_basictypeLOGICAL][FFEINFO_kindtypeLOGICAL4] - = t = make_signed_type (FLOAT_TYPE_SIZE * 2); - pushdecl (build_decl (TYPE_DECL, get_identifier ("logical4"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICAL4, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 2, type); - assert (ffetype_size (type) == sizeof (ffetargetLogical4)); - - ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1] - = t = make_node (REAL_TYPE); - TYPE_PRECISION (t) = FLOAT_TYPE_SIZE; - pushdecl (build_decl (TYPE_DECL, get_identifier ("real"), - t)); - layout_type (t); - type = ffetype_new (); - base_type = type; - ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREAL1, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 1, type); - ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1] - = FFETARGET_f2cTYREAL; - assert (ffetype_size (type) == sizeof (ffetargetReal1)); - - ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREALDOUBLE] - = t = make_node (REAL_TYPE); - TYPE_PRECISION (t) = FLOAT_TYPE_SIZE * 2; /* Always twice REAL. */ - pushdecl (build_decl (TYPE_DECL, get_identifier ("double precision"), - t)); - layout_type (t); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 2, type); - ffecom_f2c_typecode_[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2] - = FFETARGET_f2cTYDREAL; - assert (ffetype_size (type) == sizeof (ffetargetReal2)); - - ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1] - = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL1]); - pushdecl (build_decl (TYPE_DECL, get_identifier ("complex"), - t)); - type = ffetype_new (); - base_type = type; - ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREAL1, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 1, type); - ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL1] - = FFETARGET_f2cTYCOMPLEX; - assert (ffetype_size (type) == sizeof (ffetargetComplex1)); - - ffecom_tree_type[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREALDOUBLE] - = t = ffecom_make_complex_type_ (ffecom_tree_type[FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]); - pushdecl (build_decl (TYPE_DECL, get_identifier ("double complex"), - t)); - type = ffetype_new (); - ffeinfo_set_type (FFEINFO_basictypeCOMPLEX, FFEINFO_kindtypeREALDOUBLE, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_star (base_type, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / CHAR_TYPE_SIZE, - type); - ffetype_set_kind (base_type, 2, - type); - ffecom_f2c_typecode_[FFEINFO_basictypeCOMPLEX][FFEINFO_kindtypeREAL2] - = FFETARGET_f2cTYDCOMPLEX; - assert (ffetype_size (type) == sizeof (ffetargetComplex2)); - - /* Make function and ptr-to-function types for non-CHARACTER types. */ - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i) - for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) - { - if ((t = ffecom_tree_type[i][j]) != NULL_TREE) - { - if (i == FFEINFO_basictypeINTEGER) - { - /* Figure out the smallest INTEGER type that can hold - a pointer on this machine. */ - if (GET_MODE_SIZE (TYPE_MODE (t)) - >= GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) - { - if ((ffecom_pointer_kind_ == FFEINFO_kindtypeNONE) - || (GET_MODE_SIZE (TYPE_MODE (ffecom_tree_type[i][ffecom_pointer_kind_])) - > GET_MODE_SIZE (TYPE_MODE (t)))) - ffecom_pointer_kind_ = j; - } - } - else if (i == FFEINFO_basictypeCOMPLEX) - t = void_type_node; - /* For f2c compatibility, REAL functions are really - implemented as DOUBLE PRECISION. */ - else if ((i == FFEINFO_basictypeREAL) - && (j == FFEINFO_kindtypeREAL1)) - t = ffecom_tree_type - [FFEINFO_basictypeREAL][FFEINFO_kindtypeREAL2]; - - t = ffecom_tree_fun_type[i][j] = build_function_type (t, - NULL_TREE); - ffecom_tree_ptr_to_fun_type[i][j] = build_pointer_type (t); - } - } - - /* Set up pointer types. */ - - if (ffecom_pointer_kind_ == FFEINFO_basictypeNONE) - fatal ("no INTEGER type can hold a pointer on this configuration"); - else if (0 && ffe_is_do_internal_checks ()) - fprintf (stderr, "Pointer type kt=%d\n", ffecom_pointer_kind_); - ffetype_set_kind (ffeinfo_type (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT), - 7, - ffeinfo_type (FFEINFO_basictypeINTEGER, - ffecom_pointer_kind_)); - - if (ffe_is_ugly_assign ()) - ffecom_label_kind_ = ffecom_pointer_kind_; /* Require ASSIGN etc to this. */ - else - ffecom_label_kind_ = FFEINFO_kindtypeINTEGERDEFAULT; - if (0 && ffe_is_do_internal_checks ()) - fprintf (stderr, "Label type kt=%d\n", ffecom_label_kind_); - - ffecom_integer_type_node - = ffecom_tree_type[FFEINFO_basictypeINTEGER][FFEINFO_kindtypeINTEGER1]; - ffecom_integer_zero_node = convert (ffecom_integer_type_node, - integer_zero_node); - ffecom_integer_one_node = convert (ffecom_integer_type_node, - integer_one_node); - - /* Yes, the "FLOAT_TYPE_SIZE" references below are intentional. - Turns out that by TYLONG, runtime/libI77/lio.h really means - "whatever size an ftnint is". For consistency and sanity, - com.h and runtime/f2c.h.in agree that flag, ftnint, and ftlen - all are INTEGER, which we also make out of whatever back-end - integer type is FLOAT_TYPE_SIZE bits wide. This change, from - LONG_TYPE_SIZE, for TYLONG and TYLOGICAL, was necessary to - accommodate machines like the Alpha. Note that this suggests - f2c and libf2c are missing a distinction perhaps needed on - some machines between "int" and "long int". -- burley 0.5.5 950215 */ - - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, FLOAT_TYPE_SIZE, - FFETARGET_f2cTYLONG); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, SHORT_TYPE_SIZE, - FFETARGET_f2cTYSHORT); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, CHAR_TYPE_SIZE, - FFETARGET_f2cTYINT1); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeINTEGER, LONG_LONG_TYPE_SIZE, - FFETARGET_f2cTYQUAD); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, FLOAT_TYPE_SIZE, - FFETARGET_f2cTYLOGICAL); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, SHORT_TYPE_SIZE, - FFETARGET_f2cTYLOGICAL2); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, CHAR_TYPE_SIZE, - FFETARGET_f2cTYLOGICAL1); - ffecom_f2c_set_lio_code_ (FFEINFO_basictypeLOGICAL, LONG_LONG_TYPE_SIZE, - FFETARGET_f2cTYQUAD /* ~~~ */); - - /* CHARACTER stuff is all special-cased, so it is not handled in the above - loop. CHARACTER items are built as arrays of unsigned char. */ - - ffecom_tree_type[FFEINFO_basictypeCHARACTER] - [FFEINFO_kindtypeCHARACTER1] = t = char_type_node; - type = ffetype_new (); - base_type = type; - ffeinfo_set_type (FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTER1, - type); - ffetype_set_ams (type, - TYPE_ALIGN (t) / BITS_PER_UNIT, 0, - TREE_INT_CST_LOW (TYPE_SIZE (t)) / BITS_PER_UNIT); - ffetype_set_kind (base_type, 1, type); - assert (ffetype_size (type) - == sizeof (((ffetargetCharacter1) { 0, NULL }).text[0])); - - ffecom_tree_fun_type[FFEINFO_basictypeCHARACTER] - [FFEINFO_kindtypeCHARACTER1] = ffecom_tree_fun_type_void; - ffecom_tree_ptr_to_fun_type[FFEINFO_basictypeCHARACTER] - [FFEINFO_kindtypeCHARACTER1] - = ffecom_tree_ptr_to_fun_type_void; - ffecom_f2c_typecode_[FFEINFO_basictypeCHARACTER][FFEINFO_kindtypeCHARACTER1] - = FFETARGET_f2cTYCHAR; - - ffecom_f2c_typecode_[FFEINFO_basictypeANY][FFEINFO_kindtypeANY] - = 0; - - /* Make multi-return-value type and fields. */ - - ffecom_multi_type_node_ = make_node (UNION_TYPE); - - field = NULL_TREE; - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i) - for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) - { - char name[30]; - - if (ffecom_tree_type[i][j] == NULL_TREE) - continue; /* Not supported. */ - sprintf (&name[0], "bt_%s_kt_%s", - ffeinfo_basictype_string ((ffeinfoBasictype) i), - ffeinfo_kindtype_string ((ffeinfoKindtype) j)); - ffecom_multi_fields_[i][j] = build_decl (FIELD_DECL, - get_identifier (name), - ffecom_tree_type[i][j]); - DECL_CONTEXT (ffecom_multi_fields_[i][j]) - = ffecom_multi_type_node_; - DECL_FRAME_SIZE (ffecom_multi_fields_[i][j]) = 0; - TREE_CHAIN (ffecom_multi_fields_[i][j]) = field; - field = ffecom_multi_fields_[i][j]; - } - - TYPE_FIELDS (ffecom_multi_type_node_) = field; - layout_type (ffecom_multi_type_node_); - - /* Subroutines usually return integer because they might have alternate - returns. */ - - ffecom_tree_subr_type - = build_function_type (integer_type_node, NULL_TREE); - ffecom_tree_ptr_to_subr_type - = build_pointer_type (ffecom_tree_subr_type); - ffecom_tree_blockdata_type - = build_function_type (void_type_node, NULL_TREE); - - builtin_function ("__builtin_sqrtf", float_ftype_float, - BUILT_IN_FSQRT, "sqrtf"); - builtin_function ("__builtin_fsqrt", double_ftype_double, - BUILT_IN_FSQRT, "sqrt"); - builtin_function ("__builtin_sqrtl", ldouble_ftype_ldouble, - BUILT_IN_FSQRT, "sqrtl"); - builtin_function ("__builtin_sinf", float_ftype_float, - BUILT_IN_SIN, "sinf"); - builtin_function ("__builtin_sin", double_ftype_double, - BUILT_IN_SIN, "sin"); - builtin_function ("__builtin_sinl", ldouble_ftype_ldouble, - BUILT_IN_SIN, "sinl"); - builtin_function ("__builtin_cosf", float_ftype_float, - BUILT_IN_COS, "cosf"); - builtin_function ("__builtin_cos", double_ftype_double, - BUILT_IN_COS, "cos"); - builtin_function ("__builtin_cosl", ldouble_ftype_ldouble, - BUILT_IN_COS, "cosl"); - -#if BUILT_FOR_270 - pedantic_lvalues = FALSE; -#endif - - ffecom_f2c_make_type_ (&ffecom_f2c_integer_type_node, - FFECOM_f2cINTEGER, - "integer"); - ffecom_f2c_make_type_ (&ffecom_f2c_address_type_node, - FFECOM_f2cADDRESS, - "address"); - ffecom_f2c_make_type_ (&ffecom_f2c_real_type_node, - FFECOM_f2cREAL, - "real"); - ffecom_f2c_make_type_ (&ffecom_f2c_doublereal_type_node, - FFECOM_f2cDOUBLEREAL, - "doublereal"); - ffecom_f2c_make_type_ (&ffecom_f2c_complex_type_node, - FFECOM_f2cCOMPLEX, - "complex"); - ffecom_f2c_make_type_ (&ffecom_f2c_doublecomplex_type_node, - FFECOM_f2cDOUBLECOMPLEX, - "doublecomplex"); - ffecom_f2c_make_type_ (&ffecom_f2c_longint_type_node, - FFECOM_f2cLONGINT, - "longint"); - ffecom_f2c_make_type_ (&ffecom_f2c_logical_type_node, - FFECOM_f2cLOGICAL, - "logical"); - ffecom_f2c_make_type_ (&ffecom_f2c_flag_type_node, - FFECOM_f2cFLAG, - "flag"); - ffecom_f2c_make_type_ (&ffecom_f2c_ftnlen_type_node, - FFECOM_f2cFTNLEN, - "ftnlen"); - ffecom_f2c_make_type_ (&ffecom_f2c_ftnint_type_node, - FFECOM_f2cFTNINT, - "ftnint"); - - ffecom_f2c_ftnlen_zero_node - = convert (ffecom_f2c_ftnlen_type_node, integer_zero_node); - - ffecom_f2c_ftnlen_one_node - = convert (ffecom_f2c_ftnlen_type_node, integer_one_node); - - ffecom_f2c_ftnlen_two_node = build_int_2 (2, 0); - TREE_TYPE (ffecom_f2c_ftnlen_two_node) = ffecom_integer_type_node; - - ffecom_f2c_ptr_to_ftnlen_type_node - = build_pointer_type (ffecom_f2c_ftnlen_type_node); - - ffecom_f2c_ptr_to_ftnint_type_node - = build_pointer_type (ffecom_f2c_ftnint_type_node); - - ffecom_f2c_ptr_to_integer_type_node - = build_pointer_type (ffecom_f2c_integer_type_node); - - ffecom_f2c_ptr_to_real_type_node - = build_pointer_type (ffecom_f2c_real_type_node); - - ffecom_float_zero_ = build_real (float_type_node, dconst0); - ffecom_double_zero_ = build_real (double_type_node, dconst0); - { - REAL_VALUE_TYPE point_5; - -#ifdef REAL_ARITHMETIC - REAL_ARITHMETIC (point_5, RDIV_EXPR, dconst1, dconst2); -#else - point_5 = .5; -#endif - ffecom_float_half_ = build_real (float_type_node, point_5); - ffecom_double_half_ = build_real (double_type_node, point_5); - } - - /* Do "extern int xargc;". */ - - ffecom_tree_xargc_ = build_decl (VAR_DECL, - get_identifier ("f__xargc"), - integer_type_node); - DECL_EXTERNAL (ffecom_tree_xargc_) = 1; - TREE_STATIC (ffecom_tree_xargc_) = 1; - TREE_PUBLIC (ffecom_tree_xargc_) = 1; - ffecom_tree_xargc_ = start_decl (ffecom_tree_xargc_, FALSE); - finish_decl (ffecom_tree_xargc_, NULL_TREE, FALSE); - -#if 0 /* This is being fixed, and seems to be working now. */ - if ((FLOAT_TYPE_SIZE != 32) - || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node))) != 32)) - { - warning ("configuration: REAL, INTEGER, and LOGICAL are %d bits wide,", - (int) FLOAT_TYPE_SIZE); - warning ("and pointers are %d bits wide, but g77 doesn't yet work", - (int) TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (null_pointer_node)))); - warning ("properly unless they all are 32 bits wide."); - warning ("Please keep this in mind before you report bugs. g77 should"); - warning ("support non-32-bit machines better as of version 0.6."); - } -#endif - -#if 0 /* Code in ste.c that would crash has been commented out. */ - if (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node) - < TYPE_PRECISION (string_type_node)) - /* I/O will probably crash. */ - warning ("configuration: char * holds %d bits, but ftnlen only %d", - TYPE_PRECISION (string_type_node), - TYPE_PRECISION (ffecom_f2c_ftnlen_type_node)); -#endif - -#if 0 /* ASSIGN-related stuff has been changed to accommodate this. */ - if (TYPE_PRECISION (ffecom_integer_type_node) - < TYPE_PRECISION (string_type_node)) - /* ASSIGN 10 TO I will crash. */ - warning ("configuration: char * holds %d bits, but INTEGER only %d --\n\ - ASSIGN statement might fail", - TYPE_PRECISION (string_type_node), - TYPE_PRECISION (ffecom_integer_type_node)); -#endif -} - -#endif -/* ffecom_init_2 -- Initialize - - ffecom_init_2(); */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_init_2 () -{ - assert (ffecom_outer_function_decl_ == NULL_TREE); - assert (current_function_decl == NULL_TREE); - assert (ffecom_which_entrypoint_decl_ == NULL_TREE); - - ffecom_master_arglist_ = NULL; - ++ffecom_num_fns_; - ffecom_latest_temp_ = NULL; - ffecom_primary_entry_ = NULL; - ffecom_is_altreturning_ = FALSE; - ffecom_func_result_ = NULL_TREE; - ffecom_multi_retval_ = NULL_TREE; -} - -#endif -/* ffecom_list_expr -- Transform list of exprs into gcc tree - - tree t; - ffebld expr; // FFE opITEM list. - tree = ffecom_list_expr(expr); - - List of actual args is transformed into corresponding gcc backend list. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_list_expr (ffebld expr) -{ - tree list; - tree *plist = &list; - tree trail = NULL_TREE; /* Append char length args here. */ - tree *ptrail = &trail; - tree length; - - while (expr != NULL) - { - *plist - = build_tree_list (NULL_TREE, ffecom_arg_expr (ffebld_head (expr), - &length)); - plist = &TREE_CHAIN (*plist); - expr = ffebld_trail (expr); - if (length != NULL_TREE) - { - *ptrail = build_tree_list (NULL_TREE, length); - ptrail = &TREE_CHAIN (*ptrail); - } - } - - *plist = trail; - - return list; -} - -#endif -/* ffecom_list_ptr_to_expr -- Transform list of exprs into gcc tree - - tree t; - ffebld expr; // FFE opITEM list. - tree = ffecom_list_ptr_to_expr(expr); - - List of actual args is transformed into corresponding gcc backend list for - use in calling an external procedure (vs. a statement function). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_list_ptr_to_expr (ffebld expr) -{ - tree list; - tree *plist = &list; - tree trail = NULL_TREE; /* Append char length args here. */ - tree *ptrail = &trail; - tree length; - - while (expr != NULL) - { - *plist - = build_tree_list (NULL_TREE, - ffecom_arg_ptr_to_expr (ffebld_head (expr), - &length)); - plist = &TREE_CHAIN (*plist); - expr = ffebld_trail (expr); - if (length != NULL_TREE) - { - *ptrail = build_tree_list (NULL_TREE, length); - ptrail = &TREE_CHAIN (*ptrail); - } - } - - *plist = trail; - - return list; -} - -#endif -/* Obtain gcc's LABEL_DECL tree for label. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_lookup_label (ffelab label) -{ - tree glabel; - - if (ffelab_hook (label) == NULL_TREE) - { - char labelname[16]; - - switch (ffelab_type (label)) - { - case FFELAB_typeLOOPEND: - case FFELAB_typeNOTLOOP: - case FFELAB_typeENDIF: - sprintf (labelname, "%" ffelabValue_f "u", ffelab_value (label)); - glabel = build_decl (LABEL_DECL, get_identifier (labelname), - void_type_node); - DECL_CONTEXT (glabel) = current_function_decl; - DECL_MODE (glabel) = VOIDmode; - break; - - case FFELAB_typeFORMAT: - push_obstacks_nochange (); - end_temporary_allocation (); - - glabel = build_decl (VAR_DECL, - ffecom_get_invented_identifier - ("__g77_format_%d", NULL, - (int) ffelab_value (label)), - build_type_variant (build_array_type - (char_type_node, - NULL_TREE), - 1, 0)); - TREE_CONSTANT (glabel) = 1; - TREE_STATIC (glabel) = 1; - DECL_CONTEXT (glabel) = 0; - DECL_INITIAL (glabel) = NULL; - make_decl_rtl (glabel, NULL, 0); - expand_decl (glabel); - - resume_temporary_allocation (); - pop_obstacks (); - - break; - - case FFELAB_typeANY: - glabel = error_mark_node; - break; - - default: - assert ("bad label type" == NULL); - glabel = NULL; - break; - } - ffelab_set_hook (label, glabel); - } - else - { - glabel = ffelab_hook (label); - } - - return glabel; -} - -#endif -/* Stabilizes the arguments. Don't use this if the lhs and rhs come from - a single source specification (as in the fourth argument of MVBITS). - If the type is NULL_TREE, the type of lhs is used to make the type of - the MODIFY_EXPR. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_modify (tree newtype, tree lhs, - tree rhs) -{ - if (lhs == error_mark_node || rhs == error_mark_node) - return error_mark_node; - - if (newtype == NULL_TREE) - newtype = TREE_TYPE (lhs); - - if (TREE_SIDE_EFFECTS (lhs)) - lhs = stabilize_reference (lhs); - - return ffecom_2s (MODIFY_EXPR, newtype, lhs, rhs); -} - -#endif - -/* Register source file name. */ - -void -ffecom_file (char *name) -{ -#if FFECOM_GCC_INCLUDE - ffecom_file_ (name); -#endif -} - -/* ffecom_notify_init_storage -- An aggregate storage is now fully init'ed - - ffestorag st; - ffecom_notify_init_storage(st); - - Gets called when all possible units in an aggregate storage area (a LOCAL - with equivalences or a COMMON) have been initialized. The initialization - info either is in ffestorag_init or, if that is NULL, - ffestorag_accretion: - - ffestorag_init may contain an opCONTER or opARRTER. opCONTER may occur - even for an array if the array is one element in length! - - ffestorag_accretion will contain an opACCTER. It is much like an - opARRTER except it has an ffebit object in it instead of just a size. - The back end can use the info in the ffebit object, if it wants, to - reduce the amount of actual initialization, but in any case it should - kill the ffebit object when done. Also, set accretion to NULL but - init to a non-NULL value. - - After performing initialization, DO NOT set init to NULL, because that'll - tell the front end it is ok for more initialization to happen. Instead, - set init to an opANY expression or some such thing that you can use to - tell that you've already initialized the object. - - 27-Oct-91 JCB 1.1 - Support two-pass FFE. */ - -void -ffecom_notify_init_storage (ffestorag st) -{ - ffebld init; /* The initialization expression. */ -#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC - ffetargetOffset size; /* The size of the entity. */ - ffetargetAlign pad; /* Its initial padding. */ -#endif - - if (ffestorag_init (st) == NULL) - { - init = ffestorag_accretion (st); - assert (init != NULL); - ffestorag_set_accretion (st, NULL); - ffestorag_set_accretes (st, 0); - -#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC - /* For GNU backend, just turn ACCTER into ARRTER and proceed. */ - size = ffebld_accter_size (init); - pad = ffebld_accter_pad (init); - ffebit_kill (ffebld_accter_bits (init)); - ffebld_set_op (init, FFEBLD_opARRTER); - ffebld_set_arrter (init, ffebld_accter (init)); - ffebld_arrter_set_size (init, size); - ffebld_arrter_set_pad (init, size); -#endif - -#if FFECOM_TWOPASS - ffestorag_set_init (st, init); -#endif - } -#if FFECOM_ONEPASS - else - init = ffestorag_init (st); -#endif - -#if FFECOM_ONEPASS /* Process the inits, wipe 'em out. */ - ffestorag_set_init (st, ffebld_new_any ()); - - if (ffebld_op (init) == FFEBLD_opANY) - return; /* Oh, we already did this! */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - { - ffesymbol s; - - if (ffestorag_symbol (st) != NULL) - s = ffestorag_symbol (st); - else - s = ffestorag_typesymbol (st); - - fprintf (dmpout, "= initialize_storage \"%s\" ", - (s != NULL) ? ffesymbol_text (s) : "(unnamed)"); - ffebld_dump (init); - fputc ('\n', dmpout); - } -#endif - -#endif /* if FFECOM_ONEPASS */ -} - -/* ffecom_notify_init_symbol -- A symbol is now fully init'ed - - ffesymbol s; - ffecom_notify_init_symbol(s); - - Gets called when all possible units in a symbol (not placed in COMMON - or involved in EQUIVALENCE, unless it as yet has no ffestorag object) - have been initialized. The initialization info either is in - ffesymbol_init or, if that is NULL, ffesymbol_accretion: - - ffesymbol_init may contain an opCONTER or opARRTER. opCONTER may occur - even for an array if the array is one element in length! - - ffesymbol_accretion will contain an opACCTER. It is much like an - opARRTER except it has an ffebit object in it instead of just a size. - The back end can use the info in the ffebit object, if it wants, to - reduce the amount of actual initialization, but in any case it should - kill the ffebit object when done. Also, set accretion to NULL but - init to a non-NULL value. - - After performing initialization, DO NOT set init to NULL, because that'll - tell the front end it is ok for more initialization to happen. Instead, - set init to an opANY expression or some such thing that you can use to - tell that you've already initialized the object. - - 27-Oct-91 JCB 1.1 - Support two-pass FFE. */ - -void -ffecom_notify_init_symbol (ffesymbol s) -{ - ffebld init; /* The initialization expression. */ -#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC - ffetargetOffset size; /* The size of the entity. */ - ffetargetAlign pad; /* Its initial padding. */ -#endif - - if (ffesymbol_storage (s) == NULL) - return; /* Do nothing until COMMON/EQUIVALENCE - possibilities checked. */ - - if ((ffesymbol_init (s) == NULL) - && ((init = ffesymbol_accretion (s)) != NULL)) - { - ffesymbol_set_accretion (s, NULL); - ffesymbol_set_accretes (s, 0); - -#if 0 && FFECOM_targetCURRENT == FFECOM_targetGCC - /* For GNU backend, just turn ACCTER into ARRTER and proceed. */ - size = ffebld_accter_size (init); - pad = ffebld_accter_pad (init); - ffebit_kill (ffebld_accter_bits (init)); - ffebld_set_op (init, FFEBLD_opARRTER); - ffebld_set_arrter (init, ffebld_accter (init)); - ffebld_arrter_set_size (init, size); - ffebld_arrter_set_pad (init, size); -#endif - -#if FFECOM_TWOPASS - ffesymbol_set_init (s, init); -#endif - } -#if FFECOM_ONEPASS - else - init = ffesymbol_init (s); -#endif - -#if FFECOM_ONEPASS - ffesymbol_set_init (s, ffebld_new_any ()); - - if (ffebld_op (init) == FFEBLD_opANY) - return; /* Oh, we already did this! */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "= initialize_symbol \"%s\" ", ffesymbol_text (s)); - ffebld_dump (init); - fputc ('\n', dmpout); -#endif - -#endif /* if FFECOM_ONEPASS */ -} - -/* ffecom_notify_primary_entry -- Learn which is the primary entry point - - ffesymbol s; - ffecom_notify_primary_entry(s); - - Gets called when implicit or explicit PROGRAM statement seen or when - FUNCTION, SUBROUTINE, or BLOCK DATA statement seen, with the primary - global symbol that serves as the entry point. */ - -void -ffecom_notify_primary_entry (ffesymbol s) -{ - ffecom_primary_entry_ = s; - ffecom_primary_entry_kind_ = ffesymbol_kind (s); - - if ((ffecom_primary_entry_kind_ == FFEINFO_kindFUNCTION) - || (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE)) - ffecom_primary_entry_is_proc_ = TRUE; - else - ffecom_primary_entry_is_proc_ = FALSE; - - if (!ffe_is_silent ()) - { - if (ffecom_primary_entry_kind_ == FFEINFO_kindPROGRAM) - fprintf (stderr, "%s:\n", ffesymbol_text (s)); - else - fprintf (stderr, " %s:\n", ffesymbol_text (s)); - } - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - if (ffecom_primary_entry_kind_ == FFEINFO_kindSUBROUTINE) - { - ffebld list; - ffebld arg; - - for (list = ffesymbol_dummyargs (s); - list != NULL; - list = ffebld_trail (list)) - { - arg = ffebld_head (list); - if (ffebld_op (arg) == FFEBLD_opSTAR) - { - ffecom_is_altreturning_ = TRUE; - break; - } - } - } -#endif -} - -FILE * -ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c) -{ -#if FFECOM_GCC_INCLUDE - return ffecom_open_include_ (name, l, c); -#else - return fopen (name, "r"); -#endif -} - -/* Clean up after making automatically popped call-arg temps. - - Call this in pairs with push_calltemps around calls to - ffecom_arg_ptr_to_expr if the latter might use temporaries. - Any temporaries made within the outermost sequence of - push_calltemps and pop_calltemps, that are marked as "auto-pop" - meaning they won't be explicitly popped (freed), are popped - at this point so they can be reused later. - - NOTE: when called by ffecom_gen_sfuncdef_, ffecom_pending_calls_ - should come in == 1, and all of the in-use auto-pop temps - should have DECL_CONTEXT (temp->t) == current_function_decl. - Moreover, these temps should _never_ be re-used in future - calls to ffecom_push_tempvar -- since current_function_decl will - never be the same again. - - SO, it could be a minor win in terms of compile time to just - strip these temps off the list. That is, if the above assumptions - are correct, just remove from the list of temps any temp - that is both in-use and has DECL_CONTEXT (temp->t) - == current_function_decl, when called from ffecom_gen_sfuncdef_. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_pop_calltemps () -{ - ffecomTemp_ temp; - - assert (ffecom_pending_calls_ > 0); - - if (--ffecom_pending_calls_ == 0) - for (temp = ffecom_latest_temp_; temp != NULL; temp = temp->next) - if (temp->auto_pop) - temp->in_use = FALSE; -} - -#endif -/* Mark latest temp with given tree as no longer in use. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_pop_tempvar (tree t) -{ - ffecomTemp_ temp; - - for (temp = ffecom_latest_temp_; temp != NULL; temp = temp->next) - if (temp->in_use && (temp->t == t)) - { - assert (!temp->auto_pop); - temp->in_use = FALSE; - return; - } - else - assert (temp->t != t); - - assert ("couldn't ffecom_pop_tempvar!" != NULL); -} - -#endif -/* ffecom_ptr_to_expr -- Transform expr into gcc tree with & in front - - tree t; - ffebld expr; // FFE expression. - tree = ffecom_ptr_to_expr(expr); - - Like ffecom_expr, but sticks address-of in front of most things. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_ptr_to_expr (ffebld expr) -{ - tree item; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffesymbol s; - - assert (expr != NULL); - - switch (ffebld_op (expr)) - { - case FFEBLD_opSYMTER: - s = ffebld_symter (expr); - if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) - { - ffecomGfrt ix; - - ix = ffeintrin_gfrt_indirect (ffebld_symter_implementation (expr)); - assert (ix != FFECOM_gfrt); - if ((item = ffecom_gfrt_[ix]) == NULL_TREE) - { - ffecom_make_gfrt_ (ix); - item = ffecom_gfrt_[ix]; - } - } - else - { - item = ffesymbol_hook (s).decl_tree; - if (item == NULL_TREE) - { - s = ffecom_sym_transform_ (s); - item = ffesymbol_hook (s).decl_tree; - } - } - assert (item != NULL); - if (item == error_mark_node) - return item; - if (!ffesymbol_hook (s).addr) - item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)), - item); - return item; - - case FFEBLD_opARRAYREF: - { - ffebld dims[FFECOM_dimensionsMAX]; - tree array; - int i; - - item = ffecom_ptr_to_expr (ffebld_left (expr)); - - if (item == error_mark_node) - return item; - - if ((ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereFLEETING) - && !mark_addressable (item)) - return error_mark_node; /* Make sure non-const ref is to - non-reg. */ - - /* Build up ARRAY_REFs in reverse order (since we're column major - here in Fortran land). */ - - for (i = 0, expr = ffebld_right (expr); - expr != NULL; - expr = ffebld_trail (expr)) - dims[i++] = ffebld_head (expr); - - for (--i, array = TYPE_MAIN_VARIANT (TREE_TYPE (TREE_TYPE (item))); - i >= 0; - --i, array = TYPE_MAIN_VARIANT (TREE_TYPE (array))) - { - /* The initial subtraction should happen in the original type so - that (possible) negative values are handled appropriately. */ - item - = ffecom_2 (PLUS_EXPR, - build_pointer_type (TREE_TYPE (array)), - item, - size_binop (MULT_EXPR, - size_in_bytes (TREE_TYPE (array)), - convert (sizetype, - fold (build (MINUS_EXPR, - TREE_TYPE (TYPE_MIN_VALUE (TYPE_DOMAIN (array))), - ffecom_expr (dims[i]), - TYPE_MIN_VALUE (TYPE_DOMAIN (array))))))); - } - } - return item; - - case FFEBLD_opCONTER: - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - - item = ffecom_constantunion (&ffebld_constant_union - (ffebld_conter (expr)), bt, kt, - ffecom_tree_type[bt][kt]); - if (item == error_mark_node) - return error_mark_node; - item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)), - item); - return item; - - case FFEBLD_opANY: - return error_mark_node; - - default: - assert (ffecom_pending_calls_ > 0); - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - - item = ffecom_expr (expr); - if (item == error_mark_node) - return error_mark_node; - - /* The back end currently optimizes a bit too zealously for us, in that - we fail JCB001 if the following block of code is omitted. It checks - to see if the transformed expression is a symbol or array reference, - and encloses it in a SAVE_EXPR if that is the case. */ - - STRIP_NOPS (item); - if ((TREE_CODE (item) == VAR_DECL) - || (TREE_CODE (item) == PARM_DECL) - || (TREE_CODE (item) == RESULT_DECL) - || (TREE_CODE (item) == INDIRECT_REF) - || (TREE_CODE (item) == ARRAY_REF) - || (TREE_CODE (item) == COMPONENT_REF) -#ifdef OFFSET_REF - || (TREE_CODE (item) == OFFSET_REF) -#endif - || (TREE_CODE (item) == BUFFER_REF) - || (TREE_CODE (item) == REALPART_EXPR) - || (TREE_CODE (item) == IMAGPART_EXPR)) - { - item = ffecom_save_tree (item); - } - - item = ffecom_1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (item)), - item); - return item; - } - - assert ("fall-through error" == NULL); - return error_mark_node; -} - -#endif -/* Prepare to make call-arg temps. - - Call this in pairs with pop_calltemps around calls to - ffecom_arg_ptr_to_expr if the latter might use temporaries. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_push_calltemps () -{ - ffecom_pending_calls_++; -} - -#endif -/* Obtain a temp var with given data type. - - Returns a VAR_DECL tree of a currently (that is, at the current - statement being compiled) not in use and having the given data type, - making a new one if necessary. size is FFETARGET_charactersizeNONE - for a non-CHARACTER type or >= 0 for a CHARACTER type. elements is - -1 for a scalar or > 0 for an array of type. auto_pop is TRUE if - ffecom_pop_tempvar won't be called, meaning temp will be freed - when #pending calls goes to zero. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_push_tempvar (tree type, ffetargetCharacterSize size, int elements, - bool auto_pop) -{ - ffecomTemp_ temp; - int yes; - tree t; - static int mynumber; - - assert (!auto_pop || (ffecom_pending_calls_ > 0)); - - if (type == error_mark_node) - return error_mark_node; - - for (temp = ffecom_latest_temp_; temp != NULL; temp = temp->next) - { - if (temp->in_use - || (temp->type != type) - || (temp->size != size) - || (temp->elements != elements) - || (DECL_CONTEXT (temp->t) != current_function_decl)) - continue; - - temp->in_use = TRUE; - temp->auto_pop = auto_pop; - return temp->t; - } - - /* Create a new temp. */ - - yes = suspend_momentary (); - - if (size != FFETARGET_charactersizeNONE) - type = build_array_type (type, - build_range_type (ffecom_f2c_ftnlen_type_node, - ffecom_f2c_ftnlen_one_node, - build_int_2 (size, 0))); - if (elements != -1) - type = build_array_type (type, - build_range_type (integer_type_node, - integer_zero_node, - build_int_2 (elements - 1, - 0))); - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_expr_%d", NULL, - mynumber++), - type); - - /* This temp must be put in the same scope as the containing BLOCK - (aka function), but for reasons that should be explained elsewhere, - the GBE normally decides it should be in a "phantom BLOCK" associated - with the expand_start_stmt_expr() call. So push the topmost - sequence back onto the GBE's internal stack before telling it - about the decl, then restore it afterwards. */ - push_topmost_sequence (); - - t = start_decl (t, FALSE); - finish_decl (t, NULL_TREE, FALSE); - - pop_topmost_sequence (); - - resume_momentary (yes); - - temp = malloc_new_kp (ffe_pool_program_unit (), "ffecomTemp_", - sizeof (*temp)); - - temp->next = ffecom_latest_temp_; - temp->type = type; - temp->t = t; - temp->size = size; - temp->elements = elements; - temp->in_use = TRUE; - temp->auto_pop = auto_pop; - - ffecom_latest_temp_ = temp; - - return t; -} - -#endif -/* ffecom_return_expr -- Returns return-value expr given alt return expr - - tree rtn; // NULL_TREE means use expand_null_return() - ffebld expr; // NULL if no alt return expr to RETURN stmt - rtn = ffecom_return_expr(expr); - - Based on the program unit type and other info (like return function - type, return master function type when alternate ENTRY points, - whether subroutine has any alternate RETURN points, etc), returns the - appropriate expression to be returned to the caller, or NULL_TREE - meaning no return value or the caller expects it to be returned somewhere - else (which is handled by other parts of this module). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_return_expr (ffebld expr) -{ - tree rtn; - - switch (ffecom_primary_entry_kind_) - { - case FFEINFO_kindPROGRAM: - case FFEINFO_kindBLOCKDATA: - rtn = NULL_TREE; - break; - - case FFEINFO_kindSUBROUTINE: - if (!ffecom_is_altreturning_) - rtn = NULL_TREE; /* No alt returns, never an expr. */ - else if (expr == NULL) - rtn = integer_zero_node; - else - rtn = ffecom_expr (expr); - break; - - case FFEINFO_kindFUNCTION: - if ((ffecom_multi_retval_ != NULL_TREE) - || (ffesymbol_basictype (ffecom_primary_entry_) - == FFEINFO_basictypeCHARACTER) - || ((ffesymbol_basictype (ffecom_primary_entry_) - == FFEINFO_basictypeCOMPLEX) - && (ffecom_num_entrypoints_ == 0) - && ffesymbol_is_f2c (ffecom_primary_entry_))) - { /* Value is returned by direct assignment - into (implicit) dummy. */ - rtn = NULL_TREE; - break; - } - rtn = ffecom_func_result_; -#if 0 - /* Spurious error if RETURN happens before first reference! So elide - this code. In particular, for debugging registry, rtn should always - be non-null after all, but TREE_USED won't be set until we encounter - a reference in the code. Perfectly okay (but weird) code that, - e.g., has "GOTO 20;10 RETURN;20 RTN=0;GOTO 10", would result in - this diagnostic for no reason. Have people use -O -Wuninitialized - and leave it to the back end to find obviously weird cases. */ - - /* Used to "assert(rtn != NULL_TREE);" here, but it's kind of a valid - situation; if the return value has never been referenced, it won't - have a tree under 2pass mode. */ - if ((rtn == NULL_TREE) - || !TREE_USED (rtn)) - { - ffebad_start (FFEBAD_RETURN_VALUE_UNSET); - ffebad_here (0, ffesymbol_where_line (ffecom_primary_entry_), - ffesymbol_where_column (ffecom_primary_entry_)); - ffebad_string (ffesymbol_text (ffesymbol_funcresult - (ffecom_primary_entry_))); - ffebad_finish (); - } -#endif - break; - - default: - assert ("bad unit kind" == NULL); - case FFEINFO_kindANY: - rtn = error_mark_node; - break; - } - - return rtn; -} - -#endif -/* Do save_expr only if tree is not error_mark_node. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_save_tree (tree t) -{ - return save_expr (t); -} -#endif - -/* Public entry point for front end to access start_decl. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_start_decl (tree decl, bool is_initialized) -{ - DECL_INITIAL (decl) = is_initialized ? error_mark_node : NULL_TREE; - return start_decl (decl, FALSE); -} - -#endif -/* ffecom_sym_commit -- Symbol's state being committed to reality - - ffesymbol s; - ffecom_sym_commit(s); - - Does whatever the backend needs when a symbol is committed after having - been backtrackable for a period of time. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_sym_commit (ffesymbol s UNUSED) -{ - assert (!ffesymbol_retractable ()); -} - -#endif -/* ffecom_sym_end_transition -- Perform end transition on all symbols - - ffecom_sym_end_transition(); - - Does backend-specific stuff and also calls ffest_sym_end_transition - to do the necessary FFE stuff. - - Backtracking is never enabled when this fn is called, so don't worry - about it. */ - -ffesymbol -ffecom_sym_end_transition (ffesymbol s) -{ - ffestorag st; - - assert (!ffesymbol_retractable ()); - - s = ffest_sym_end_transition (s); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - if ((ffesymbol_kind (s) == FFEINFO_kindBLOCKDATA) - && (ffesymbol_where (s) == FFEINFO_whereGLOBAL)) - { - ffecom_list_blockdata_ - = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE, - FFEINTRIN_specNONE, - FFEINTRIN_impNONE), - ffecom_list_blockdata_); - } -#endif - - /* This is where we finally notice that a symbol has partial initialization - and finalize it. */ - - if (ffesymbol_accretion (s) != NULL) - { - assert (ffesymbol_init (s) == NULL); - ffecom_notify_init_symbol (s); - } - else if (((st = ffesymbol_storage (s)) != NULL) - && ((st = ffestorag_parent (st)) != NULL) - && (ffestorag_accretion (st) != NULL)) - { - assert (ffestorag_init (st) == NULL); - ffecom_notify_init_storage (st); - } - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - if ((ffesymbol_kind (s) == FFEINFO_kindCOMMON) - && (ffesymbol_where (s) == FFEINFO_whereLOCAL) - && (ffesymbol_storage (s) != NULL)) - { - ffecom_list_common_ - = ffebld_new_item (ffebld_new_symter (s, FFEINTRIN_genNONE, - FFEINTRIN_specNONE, - FFEINTRIN_impNONE), - ffecom_list_common_); - } -#endif - - return s; -} - -/* ffecom_sym_exec_transition -- Perform exec transition on all symbols - - ffecom_sym_exec_transition(); - - Does backend-specific stuff and also calls ffest_sym_exec_transition - to do the necessary FFE stuff. - - See the long-winded description in ffecom_sym_learned for info - on handling the situation where backtracking is inhibited. */ - -ffesymbol -ffecom_sym_exec_transition (ffesymbol s) -{ - s = ffest_sym_exec_transition (s); - - return s; -} - -/* ffecom_sym_learned -- Initial or more info gained on symbol after exec - - ffesymbol s; - s = ffecom_sym_learned(s); - - Called when a new symbol is seen after the exec transition or when more - info (perhaps) is gained for an UNCERTAIN symbol. The symbol state when - it arrives here is that all its latest info is updated already, so its - state may be UNCERTAIN or UNDERSTOOD, it might already have the hook - field filled in if its gone through here or exec_transition first, and - so on. - - The backend probably wants to check ffesymbol_retractable() to see if - backtracking is in effect. If so, the FFE's changes to the symbol may - be retracted (undone) or committed (ratified), at which time the - appropriate ffecom_sym_retract or _commit function will be called - for that function. - - If the backend has its own backtracking mechanism, great, use it so that - committal is a simple operation. Though it doesn't make much difference, - I suppose: the reason for tentative symbol evolution in the FFE is to - enable error detection in weird incorrect statements early and to disable - incorrect error detection on a correct statement. The backend is not - likely to introduce any information that'll get involved in these - considerations, so it is probably just fine that the implementation - model for this fn and for _exec_transition is to not do anything - (besides the required FFE stuff) if ffesymbol_retractable() returns TRUE - and instead wait until ffecom_sym_commit is called (which it never - will be as long as we're using ambiguity-detecting statement analysis in - the FFE, which we are initially to shake out the code, but don't depend - on this), otherwise go ahead and do whatever is needed. - - In essence, then, when this fn and _exec_transition get called while - backtracking is enabled, a general mechanism would be to flag which (or - both) of these were called (and in what order? neat question as to what - might happen that I'm too lame to think through right now) and then when - _commit is called reproduce the original calling sequence, if any, for - the two fns (at which point backtracking will, of course, be disabled). */ - -ffesymbol -ffecom_sym_learned (ffesymbol s) -{ - ffestorag_exec_layout (s); - - return s; -} - -/* ffecom_sym_retract -- Symbol's state being retracted from reality - - ffesymbol s; - ffecom_sym_retract(s); - - Does whatever the backend needs when a symbol is retracted after having - been backtrackable for a period of time. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffecom_sym_retract (ffesymbol s UNUSED) -{ - assert (!ffesymbol_retractable ()); - -#if 0 /* GCC doesn't commit any backtrackable sins, - so nothing needed here. */ - switch (ffesymbol_hook (s).state) - { - case 0: /* nothing happened yet. */ - break; - - case 1: /* exec transition happened. */ - break; - - case 2: /* learned happened. */ - break; - - case 3: /* learned then exec. */ - break; - - case 4: /* exec then learned. */ - break; - - default: - assert ("bad hook state" == NULL); - break; - } -#endif -} - -#endif -/* Create temporary gcc label. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_temp_label () -{ - tree glabel; - static int mynumber = 0; - - glabel = build_decl (LABEL_DECL, - ffecom_get_invented_identifier ("__g77_label_%d", - NULL, - mynumber++), - void_type_node); - DECL_CONTEXT (glabel) = current_function_decl; - DECL_MODE (glabel) = VOIDmode; - - return glabel; -} - -#endif -/* Return an expression that is usable as an arg in a conditional context - (IF, DO WHILE, .NOT., and so on). - - Use the one provided for the back end as of >2.6.0. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_truth_value (tree expr) -{ - return truthvalue_conversion (expr); -} - -#endif -/* Return the inversion of a truth value (the inversion of what - ffecom_truth_value builds). - - Apparently invert_truthvalue, which is properly in the back end, is - enough for now, so just use it. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_truth_value_invert (tree expr) -{ - return invert_truthvalue (ffecom_truth_value (expr)); -} - -#endif -/* Return PARM_DECL for arg#1 of master fn containing alternate ENTRY points - - If the PARM_DECL already exists, return it, else create it. It's an - integer_type_node argument for the master function that implements a - subroutine or function with more than one entrypoint and is bound at - run time with the entrypoint number (0 for SUBROUTINE/FUNCTION, 1 for - first ENTRY statement, and so on). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree -ffecom_which_entrypoint_decl () -{ - assert (ffecom_which_entrypoint_decl_ != NULL_TREE); - - return ffecom_which_entrypoint_decl_; -} - -#endif - -/* The following sections consists of private and public functions - that have the same names and perform roughly the same functions - as counterparts in the C front end. Changes in the C front end - might affect how things should be done here. Only functions - needed by the back end should be public here; the rest should - be private (static in the C sense). Functions needed by other - g77 front-end modules should be accessed by them via public - ffecom_* names, which should themselves call private versions - in this section so the private versions are easy to recognize - when upgrading to a new gcc and finding interesting changes - in the front end. - - Functions named after rule "foo:" in c-parse.y are named - "bison_rule_foo_" so they are easy to find. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - -static void -bison_rule_compstmt_ () -{ - emit_line_note (input_filename, lineno); - expand_end_bindings (getdecls (), 1, 1); - poplevel (1, 1, 0); - pop_momentary (); -} - -static void -bison_rule_pushlevel_ () -{ - emit_line_note (input_filename, lineno); - pushlevel (0); - clear_last_expr (); - push_momentary (); - expand_start_bindings (0); -} - -/* Return a definition for a builtin function named NAME and whose data type - is TYPE. TYPE should be a function type with argument types. - FUNCTION_CODE tells later passes how to compile calls to this function. - See tree.h for its possible values. - - If LIBRARY_NAME is nonzero, use that for DECL_ASSEMBLER_NAME, - the name to be called if we can't opencode the function. */ - -static tree -builtin_function (char *name, tree type, - enum built_in_function function_code, char *library_name) -{ - tree decl = build_decl (FUNCTION_DECL, get_identifier (name), type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - if (library_name) - DECL_ASSEMBLER_NAME (decl) = get_identifier (library_name); - make_decl_rtl (decl, NULL_PTR, 1); - pushdecl (decl); - if (function_code != NOT_BUILT_IN) - { - DECL_BUILT_IN (decl) = 1; - DECL_FUNCTION_CODE (decl) = function_code; - } - - return decl; -} - -/* Handle when a new declaration NEWDECL - has the same name as an old one OLDDECL - in the same binding contour. - Prints an error message if appropriate. - - If safely possible, alter OLDDECL to look like NEWDECL, and return 1. - Otherwise, return 0. */ - -static int -duplicate_decls (tree newdecl, tree olddecl) -{ - int types_match = 1; - int new_is_definition = (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_INITIAL (newdecl) != 0); - tree oldtype = TREE_TYPE (olddecl); - tree newtype = TREE_TYPE (newdecl); - - if (olddecl == newdecl) - return 1; - - if (TREE_CODE (newtype) == ERROR_MARK - || TREE_CODE (oldtype) == ERROR_MARK) - types_match = 0; - - /* New decl is completely inconsistent with the old one => - tell caller to replace the old one. - This is always an error except in the case of shadowing a builtin. */ - if (TREE_CODE (olddecl) != TREE_CODE (newdecl)) - return 0; - - /* For real parm decl following a forward decl, - return 1 so old decl will be reused. */ - if (types_match && TREE_CODE (newdecl) == PARM_DECL - && TREE_ASM_WRITTEN (olddecl) && ! TREE_ASM_WRITTEN (newdecl)) - return 1; - - /* The new declaration is the same kind of object as the old one. - The declarations may partially match. Print warnings if they don't - match enough. Ultimately, copy most of the information from the new - decl to the old one, and keep using the old one. */ - - if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl)) - { - /* A function declaration for a built-in function. */ - if (!TREE_PUBLIC (newdecl)) - return 0; - else if (!types_match) - { - /* Accept the return type of the new declaration if same modes. */ - tree oldreturntype = TREE_TYPE (TREE_TYPE (olddecl)); - tree newreturntype = TREE_TYPE (TREE_TYPE (newdecl)); - - /* Make sure we put the new type in the same obstack as the old ones. - If the old types are not both in the same obstack, use the - permanent one. */ - if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype)) - push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); - else - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - if (TYPE_MODE (oldreturntype) == TYPE_MODE (newreturntype)) - { - /* Function types may be shared, so we can't just modify - the return type of olddecl's function type. */ - tree newtype - = build_function_type (newreturntype, - TYPE_ARG_TYPES (TREE_TYPE (olddecl))); - - types_match = 1; - if (types_match) - TREE_TYPE (olddecl) = newtype; - } - - pop_obstacks (); - } - if (!types_match) - return 0; - } - else if (TREE_CODE (olddecl) == FUNCTION_DECL - && DECL_SOURCE_LINE (olddecl) == 0) - { - /* A function declaration for a predeclared function - that isn't actually built in. */ - if (!TREE_PUBLIC (newdecl)) - return 0; - else if (!types_match) - { - /* If the types don't match, preserve volatility indication. - Later on, we will discard everything else about the - default declaration. */ - TREE_THIS_VOLATILE (newdecl) |= TREE_THIS_VOLATILE (olddecl); - } - } - - /* Copy all the DECL_... slots specified in the new decl - except for any that we copy here from the old type. - - Past this point, we don't change OLDTYPE and NEWTYPE - even if we change the types of NEWDECL and OLDDECL. */ - - if (types_match) - { - /* Make sure we put the new type in the same obstack as the old ones. - If the old types are not both in the same obstack, use the permanent - one. */ - if (TYPE_OBSTACK (oldtype) == TYPE_OBSTACK (newtype)) - push_obstacks (TYPE_OBSTACK (oldtype), TYPE_OBSTACK (oldtype)); - else - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - /* Merge the data types specified in the two decls. */ - if (TREE_CODE (newdecl) != FUNCTION_DECL || !DECL_BUILT_IN (olddecl)) - TREE_TYPE (newdecl) - = TREE_TYPE (olddecl) - = TREE_TYPE (newdecl); - - /* Lay the type out, unless already done. */ - if (oldtype != TREE_TYPE (newdecl)) - { - if (TREE_TYPE (newdecl) != error_mark_node) - layout_type (TREE_TYPE (newdecl)); - if (TREE_CODE (newdecl) != FUNCTION_DECL - && TREE_CODE (newdecl) != TYPE_DECL - && TREE_CODE (newdecl) != CONST_DECL) - layout_decl (newdecl, 0); - } - else - { - /* Since the type is OLDDECL's, make OLDDECL's size go with. */ - DECL_SIZE (newdecl) = DECL_SIZE (olddecl); - if (TREE_CODE (olddecl) != FUNCTION_DECL) - if (DECL_ALIGN (olddecl) > DECL_ALIGN (newdecl)) - DECL_ALIGN (newdecl) = DECL_ALIGN (olddecl); - } - - /* Keep the old rtl since we can safely use it. */ - DECL_RTL (newdecl) = DECL_RTL (olddecl); - - /* Merge the type qualifiers. */ - if (DECL_BUILT_IN_NONANSI (olddecl) && TREE_THIS_VOLATILE (olddecl) - && !TREE_THIS_VOLATILE (newdecl)) - TREE_THIS_VOLATILE (olddecl) = 0; - if (TREE_READONLY (newdecl)) - TREE_READONLY (olddecl) = 1; - if (TREE_THIS_VOLATILE (newdecl)) - { - TREE_THIS_VOLATILE (olddecl) = 1; - if (TREE_CODE (newdecl) == VAR_DECL) - make_var_volatile (newdecl); - } - - /* Keep source location of definition rather than declaration. - Likewise, keep decl at outer scope. */ - if ((DECL_INITIAL (newdecl) == 0 && DECL_INITIAL (olddecl) != 0) - || (DECL_CONTEXT (newdecl) != 0 && DECL_CONTEXT (olddecl) == 0)) - { - DECL_SOURCE_LINE (newdecl) = DECL_SOURCE_LINE (olddecl); - DECL_SOURCE_FILE (newdecl) = DECL_SOURCE_FILE (olddecl); - - if (DECL_CONTEXT (olddecl) == 0 - && TREE_CODE (newdecl) != FUNCTION_DECL) - DECL_CONTEXT (newdecl) = 0; - } - - /* Merge the unused-warning information. */ - if (DECL_IN_SYSTEM_HEADER (olddecl)) - DECL_IN_SYSTEM_HEADER (newdecl) = 1; - else if (DECL_IN_SYSTEM_HEADER (newdecl)) - DECL_IN_SYSTEM_HEADER (olddecl) = 1; - - /* Merge the initialization information. */ - if (DECL_INITIAL (newdecl) == 0) - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - - /* Merge the section attribute. - We want to issue an error if the sections conflict but that must be - done later in decl_attributes since we are called before attributes - are assigned. */ - if (DECL_SECTION_NAME (newdecl) == NULL_TREE) - DECL_SECTION_NAME (newdecl) = DECL_SECTION_NAME (olddecl); - -#if BUILT_FOR_270 - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - DECL_STATIC_CONSTRUCTOR(newdecl) |= DECL_STATIC_CONSTRUCTOR(olddecl); - DECL_STATIC_DESTRUCTOR (newdecl) |= DECL_STATIC_DESTRUCTOR (olddecl); - } -#endif - - pop_obstacks (); - } - /* If cannot merge, then use the new type and qualifiers, - and don't preserve the old rtl. */ - else - { - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - TREE_READONLY (olddecl) = TREE_READONLY (newdecl); - TREE_THIS_VOLATILE (olddecl) = TREE_THIS_VOLATILE (newdecl); - TREE_SIDE_EFFECTS (olddecl) = TREE_SIDE_EFFECTS (newdecl); - } - - /* Merge the storage class information. */ - /* For functions, static overrides non-static. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL) - { - TREE_PUBLIC (newdecl) &= TREE_PUBLIC (olddecl); - /* This is since we don't automatically - copy the attributes of NEWDECL into OLDDECL. */ - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - /* If this clears `static', clear it in the identifier too. */ - if (! TREE_PUBLIC (olddecl)) - TREE_PUBLIC (DECL_NAME (olddecl)) = 0; - } - if (DECL_EXTERNAL (newdecl)) - { - TREE_STATIC (newdecl) = TREE_STATIC (olddecl); - DECL_EXTERNAL (newdecl) = DECL_EXTERNAL (olddecl); - /* An extern decl does not override previous storage class. */ - TREE_PUBLIC (newdecl) = TREE_PUBLIC (olddecl); - } - else - { - TREE_STATIC (olddecl) = TREE_STATIC (newdecl); - TREE_PUBLIC (olddecl) = TREE_PUBLIC (newdecl); - } - - /* If either decl says `inline', this fn is inline, - unless its definition was passed already. */ - if (DECL_INLINE (newdecl) && DECL_INITIAL (olddecl) == 0) - DECL_INLINE (olddecl) = 1; - DECL_INLINE (newdecl) = DECL_INLINE (olddecl); - - /* Get rid of any built-in function if new arg types don't match it - or if we have a function definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL - && DECL_BUILT_IN (olddecl) - && (!types_match || new_is_definition)) - { - TREE_TYPE (olddecl) = TREE_TYPE (newdecl); - DECL_BUILT_IN (olddecl) = 0; - } - - /* If redeclaring a builtin function, and not a definition, - it stays built in. - Also preserve various other info from the definition. */ - if (TREE_CODE (newdecl) == FUNCTION_DECL && !new_is_definition) - { - if (DECL_BUILT_IN (olddecl)) - { - DECL_BUILT_IN (newdecl) = 1; - DECL_FUNCTION_CODE (newdecl) = DECL_FUNCTION_CODE (olddecl); - } - else - DECL_FRAME_SIZE (newdecl) = DECL_FRAME_SIZE (olddecl); - - DECL_RESULT (newdecl) = DECL_RESULT (olddecl); - DECL_INITIAL (newdecl) = DECL_INITIAL (olddecl); - DECL_SAVED_INSNS (newdecl) = DECL_SAVED_INSNS (olddecl); - DECL_ARGUMENTS (newdecl) = DECL_ARGUMENTS (olddecl); - } - - /* Copy most of the decl-specific fields of NEWDECL into OLDDECL. - But preserve olddecl's DECL_UID. */ - { - register unsigned olddecl_uid = DECL_UID (olddecl); - - memcpy ((char *) olddecl + sizeof (struct tree_common), - (char *) newdecl + sizeof (struct tree_common), - sizeof (struct tree_decl) - sizeof (struct tree_common)); - DECL_UID (olddecl) = olddecl_uid; - } - - return 1; -} - -/* Finish processing of a declaration; - install its initial value. - If the length of an array type is not known before, - it must be determined now, from the initial value, or it is an error. */ - -static void -finish_decl (tree decl, tree init, bool is_top_level) -{ - register tree type = TREE_TYPE (decl); - int was_incomplete = (DECL_SIZE (decl) == 0); - int temporary = allocation_temporary_p (); - bool at_top_level = (current_binding_level == global_binding_level); - bool top_level = is_top_level || at_top_level; - - /* Caller should pass TRUE for is_top_level only if we wouldn't be at top - level anyway. */ - assert (!is_top_level || !at_top_level); - - if (TREE_CODE (decl) == PARM_DECL) - assert (init == NULL_TREE); - /* Remember that PARM_DECL doesn't have a DECL_INITIAL field per se -- it - overlaps DECL_ARG_TYPE. */ - else if (init == NULL_TREE) - assert (DECL_INITIAL (decl) == NULL_TREE); - else - assert (DECL_INITIAL (decl) == error_mark_node); - - if (init != NULL_TREE) - { - if (TREE_CODE (decl) != TYPE_DECL) - DECL_INITIAL (decl) = init; - else - { - /* typedef foo = bar; store the type of bar as the type of foo. */ - TREE_TYPE (decl) = TREE_TYPE (init); - DECL_INITIAL (decl) = init = 0; - } - } - - /* Pop back to the obstack that is current for this binding level. This is - because MAXINDEX, rtl, etc. to be made below must go in the permanent - obstack. But don't discard the temporary data yet. */ - pop_obstacks (); - - /* Deduce size of array from initialization, if not already known */ - - if (TREE_CODE (type) == ARRAY_TYPE - && TYPE_DOMAIN (type) == 0 - && TREE_CODE (decl) != TYPE_DECL) - { - assert (top_level); - assert (was_incomplete); - - layout_decl (decl, 0); - } - - if (TREE_CODE (decl) == VAR_DECL) - { - if (DECL_SIZE (decl) == NULL_TREE - && TYPE_SIZE (TREE_TYPE (decl)) != NULL_TREE) - layout_decl (decl, 0); - - if (DECL_SIZE (decl) == NULL_TREE - && (TREE_STATIC (decl) - ? - /* A static variable with an incomplete type is an error if it is - initialized. Also if it is not file scope. Otherwise, let it - through, but if it is not `extern' then it may cause an error - message later. */ - (DECL_INITIAL (decl) != 0 || DECL_CONTEXT (decl) != 0) - : - /* An automatic variable with an incomplete type is an error. */ - !DECL_EXTERNAL (decl))) - { - assert ("storage size not known" == NULL); - abort (); - } - - if ((DECL_EXTERNAL (decl) || TREE_STATIC (decl)) - && (DECL_SIZE (decl) != 0) - && (TREE_CODE (DECL_SIZE (decl)) != INTEGER_CST)) - { - assert ("storage size not constant" == NULL); - abort (); - } - } - - /* Output the assembler code and/or RTL code for variables and functions, - unless the type is an undefined structure or union. If not, it will get - done when the type is completed. */ - - if (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL) - { - rest_of_decl_compilation (decl, NULL, - DECL_CONTEXT (decl) == 0, - 0); - - if (DECL_CONTEXT (decl) != 0) - { - /* Recompute the RTL of a local array now if it used to be an - incomplete type. */ - if (was_incomplete - && !TREE_STATIC (decl) && !DECL_EXTERNAL (decl)) - { - /* If we used it already as memory, it must stay in memory. */ - TREE_ADDRESSABLE (decl) = TREE_USED (decl); - /* If it's still incomplete now, no init will save it. */ - if (DECL_SIZE (decl) == 0) - DECL_INITIAL (decl) = 0; - expand_decl (decl); - } - /* Compute and store the initial value. */ - if (TREE_CODE (decl) != FUNCTION_DECL) - expand_decl_init (decl); - } - } - else if (TREE_CODE (decl) == TYPE_DECL) - { - rest_of_decl_compilation (decl, NULL_PTR, - DECL_CONTEXT (decl) == 0, - 0); - } - - /* This test used to include TREE_PERMANENT, however, we have the same - problem with initializers at the function level. Such initializers get - saved until the end of the function on the momentary_obstack. */ - if (!(TREE_CODE (decl) == FUNCTION_DECL && DECL_INLINE (decl)) - && temporary - /* DECL_INITIAL is not defined in PARM_DECLs, since it shares space with - DECL_ARG_TYPE. */ - && TREE_CODE (decl) != PARM_DECL) - { - /* We need to remember that this array HAD an initialization, but - discard the actual temporary nodes, since we can't have a permanent - node keep pointing to them. */ - /* We make an exception for inline functions, since it's normal for a - local extern redeclaration of an inline function to have a copy of - the top-level decl's DECL_INLINE. */ - if ((DECL_INITIAL (decl) != 0) - && (DECL_INITIAL (decl) != error_mark_node)) - { - /* If this is a const variable, then preserve the - initializer instead of discarding it so that we can optimize - references to it. */ - /* This test used to include TREE_STATIC, but this won't be set - for function level initializers. */ - if (TREE_READONLY (decl)) - { - preserve_initializer (); - /* Hack? Set the permanent bit for something that is - permanent, but not on the permenent obstack, so as to - convince output_constant_def to make its rtl on the - permanent obstack. */ - TREE_PERMANENT (DECL_INITIAL (decl)) = 1; - - /* The initializer and DECL must have the same (or equivalent - types), but if the initializer is a STRING_CST, its type - might not be on the right obstack, so copy the type - of DECL. */ - TREE_TYPE (DECL_INITIAL (decl)) = type; - } - else - DECL_INITIAL (decl) = error_mark_node; - } - } - - /* If requested, warn about definitions of large data objects. */ - - if (warn_larger_than - && (TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == PARM_DECL) - && !DECL_EXTERNAL (decl)) - { - register tree decl_size = DECL_SIZE (decl); - - if (decl_size && TREE_CODE (decl_size) == INTEGER_CST) - { - unsigned units = TREE_INT_CST_LOW (decl_size) / BITS_PER_UNIT; - - if (units > larger_than_size) - warning_with_decl (decl, "size of `%s' is %u bytes", units); - } - } - - /* If we have gone back from temporary to permanent allocation, actually - free the temporary space that we no longer need. */ - if (temporary && !allocation_temporary_p ()) - permanent_allocation (0); - - /* At the end of a declaration, throw away any variable type sizes of types - defined inside that declaration. There is no use computing them in the - following function definition. */ - if (current_binding_level == global_binding_level) - get_pending_sizes (); -} - -/* Finish up a function declaration and compile that function - all the way to assembler language output. The free the storage - for the function definition. - - This is called after parsing the body of the function definition. - - NESTED is nonzero if the function being finished is nested in another. */ - -static void -finish_function (int nested) -{ - register tree fndecl = current_function_decl; - - assert (fndecl != NULL_TREE); - if (TREE_CODE (fndecl) != ERROR_MARK) - { - if (nested) - assert (DECL_CONTEXT (fndecl) != NULL_TREE); - else - assert (DECL_CONTEXT (fndecl) == NULL_TREE); - } - -/* TREE_READONLY (fndecl) = 1; - This caused &foo to be of type ptr-to-const-function - which then got a warning when stored in a ptr-to-function variable. */ - - poplevel (1, 0, 1); - - if (TREE_CODE (fndecl) != ERROR_MARK) - { - BLOCK_SUPERCONTEXT (DECL_INITIAL (fndecl)) = fndecl; - - /* Must mark the RESULT_DECL as being in this function. */ - - DECL_CONTEXT (DECL_RESULT (fndecl)) = fndecl; - - /* Obey `register' declarations if `setjmp' is called in this fn. */ - /* Generate rtl for function exit. */ - expand_function_end (input_filename, lineno, 0); - - /* So we can tell if jump_optimize sets it to 1. */ - can_reach_end = 0; - - /* Run the optimizers and output the assembler code for this function. */ - rest_of_compilation (fndecl); - } - - /* Free all the tree nodes making up this function. */ - /* Switch back to allocating nodes permanently until we start another - function. */ - if (!nested) - permanent_allocation (1); - - if (DECL_SAVED_INSNS (fndecl) == 0 && !nested && (TREE_CODE (fndecl) != ERROR_MARK)) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this was an actual - function definition. */ - /* For a nested function, this is done in pop_f_function_context. */ - /* If rest_of_compilation set this to 0, leave it 0. */ - if (DECL_INITIAL (fndecl) != 0) - DECL_INITIAL (fndecl) = error_mark_node; - DECL_ARGUMENTS (fndecl) = 0; - } - - if (!nested) - { - /* Let the error reporting routines know that we're outside a function. - For a nested function, this value is used in pop_c_function_context - and then reset via pop_function_context. */ - ffecom_outer_function_decl_ = current_function_decl = NULL; - } -} - -/* Plug-in replacement for identifying the name of a decl and, for a - function, what we call it in diagnostics. For now, "program unit" - should suffice, since it's a bit of a hassle to figure out which - of several kinds of things it is. Note that it could conceivably - be a statement function, which probably isn't really a program unit - per se, but if that comes up, it should be easy to check (being a - nested function and all). */ - -static char * -lang_printable_name (tree decl, int v) -{ - /* Just to keep GCC quiet about the unused variable. - In theory, differing values of V should produce different - output. */ - switch (v) - { - default: - if (TREE_CODE (decl) == ERROR_MARK) - return "erroneous code"; - return IDENTIFIER_POINTER (DECL_NAME (decl)); - } -} - -/* g77's function to print out name of current function that caused - an error. */ - -#if BUILT_FOR_270 -void -lang_print_error_function (file) - char *file; -{ - static ffeglobal last_g = NULL; - static ffesymbol last_s = NULL; - ffeglobal g; - ffesymbol s; - char *kind; - - if ((ffecom_primary_entry_ == NULL) - || (ffesymbol_global (ffecom_primary_entry_) == NULL)) - { - g = NULL; - s = NULL; - kind = NULL; - } - else - { - g = ffesymbol_global (ffecom_primary_entry_); - if (ffecom_nested_entry_ == NULL) - { - s = ffecom_primary_entry_; - switch (ffesymbol_kind (s)) - { - case FFEINFO_kindFUNCTION: - kind = "function"; - break; - - case FFEINFO_kindSUBROUTINE: - kind = "subroutine"; - break; - - case FFEINFO_kindPROGRAM: - kind = "program"; - break; - - case FFEINFO_kindBLOCKDATA: - kind = "block-data"; - break; - - default: - kind = ffeinfo_kind_message (ffesymbol_kind (s)); - break; - } - } - else - { - s = ffecom_nested_entry_; - kind = "statement function"; - } - } - - if ((last_g != g) || (last_s != s)) - { - if (file) - fprintf (stderr, "%s: ", file); - - if (s == NULL) - fprintf (stderr, "Outside of any program unit:\n"); - else - { - char *name = ffesymbol_text (s); - - fprintf (stderr, "In %s `%s':\n", kind, name); - } - - last_g = g; - last_s = s; - } -} -#endif - -/* Similar to `lookup_name' but look only at current binding level. */ - -static tree -lookup_name_current_level (tree name) -{ - register tree t; - - if (current_binding_level == global_binding_level) - return IDENTIFIER_GLOBAL_VALUE (name); - - if (IDENTIFIER_LOCAL_VALUE (name) == 0) - return 0; - - for (t = current_binding_level->names; t; t = TREE_CHAIN (t)) - if (DECL_NAME (t) == name) - break; - - return t; -} - -/* Create a new `struct binding_level'. */ - -static struct binding_level * -make_binding_level () -{ - /* NOSTRICT */ - return (struct binding_level *) xmalloc (sizeof (struct binding_level)); -} - -/* Save and restore the variables in this file and elsewhere - that keep track of the progress of compilation of the current function. - Used for nested functions. */ - -struct f_function -{ - struct f_function *next; - tree named_labels; - tree shadowed_labels; - struct binding_level *binding_level; -}; - -struct f_function *f_function_chain; - -/* Restore the variables used during compilation of a C function. */ - -static void -pop_f_function_context () -{ - struct f_function *p = f_function_chain; - tree link; - - /* Bring back all the labels that were shadowed. */ - for (link = shadowed_labels; link; link = TREE_CHAIN (link)) - if (DECL_NAME (TREE_VALUE (link)) != 0) - IDENTIFIER_LABEL_VALUE (DECL_NAME (TREE_VALUE (link))) - = TREE_VALUE (link); - - if (DECL_SAVED_INSNS (current_function_decl) == 0) - { - /* Stop pointing to the local nodes about to be freed. */ - /* But DECL_INITIAL must remain nonzero so we know this was an actual - function definition. */ - DECL_INITIAL (current_function_decl) = error_mark_node; - DECL_ARGUMENTS (current_function_decl) = 0; - } - - pop_function_context (); - - f_function_chain = p->next; - - named_labels = p->named_labels; - shadowed_labels = p->shadowed_labels; - current_binding_level = p->binding_level; - - free (p); -} - -/* Save and reinitialize the variables - used during compilation of a C function. */ - -static void -push_f_function_context () -{ - struct f_function *p - = (struct f_function *) xmalloc (sizeof (struct f_function)); - - push_function_context (); - - p->next = f_function_chain; - f_function_chain = p; - - p->named_labels = named_labels; - p->shadowed_labels = shadowed_labels; - p->binding_level = current_binding_level; -} - -static void -push_parm_decl (tree parm) -{ - int old_immediate_size_expand = immediate_size_expand; - - /* Don't try computing parm sizes now -- wait till fn is called. */ - - immediate_size_expand = 0; - - push_obstacks_nochange (); - - /* Fill in arg stuff. */ - - DECL_ARG_TYPE (parm) = TREE_TYPE (parm); - DECL_ARG_TYPE_AS_WRITTEN (parm) = TREE_TYPE (parm); - TREE_READONLY (parm) = 1; /* All implementation args are read-only. */ - - parm = pushdecl (parm); - - immediate_size_expand = old_immediate_size_expand; - - finish_decl (parm, NULL_TREE, FALSE); -} - -/* Like pushdecl, only it places X in GLOBAL_BINDING_LEVEL, if appropriate. */ - -static tree -pushdecl_top_level (x) - tree x; -{ - register tree t; - register struct binding_level *b = current_binding_level; - register tree f = current_function_decl; - - current_binding_level = global_binding_level; - current_function_decl = NULL_TREE; - t = pushdecl (x); - current_binding_level = b; - current_function_decl = f; - return t; -} - -/* Store the list of declarations of the current level. - This is done for the parameter declarations of a function being defined, - after they are modified in the light of any missing parameters. */ - -static tree -storedecls (decls) - tree decls; -{ - return current_binding_level->names = decls; -} - -/* Store the parameter declarations into the current function declaration. - This is called after parsing the parameter declarations, before - digesting the body of the function. - - For an old-style definition, modify the function's type - to specify at least the number of arguments. */ - -static void -store_parm_decls (int is_main_program UNUSED) -{ - register tree fndecl = current_function_decl; - - /* This is a chain of PARM_DECLs from old-style parm declarations. */ - DECL_ARGUMENTS (fndecl) = storedecls (nreverse (getdecls ())); - - /* Initialize the RTL code for the function. */ - - init_function_start (fndecl, input_filename, lineno); - - /* Set up parameters and prepare for return, for the function. */ - - expand_function_start (fndecl, 0); -} - -static tree -start_decl (tree decl, bool is_top_level) -{ - register tree tem; - bool at_top_level = (current_binding_level == global_binding_level); - bool top_level = is_top_level || at_top_level; - - /* Caller should pass TRUE for is_top_level only if we wouldn't be at top - level anyway. */ - assert (!is_top_level || !at_top_level); - - /* The corresponding pop_obstacks is in finish_decl. */ - push_obstacks_nochange (); - - if (DECL_INITIAL (decl) != NULL_TREE) - { - assert (DECL_INITIAL (decl) == error_mark_node); - assert (!DECL_EXTERNAL (decl)); - } - else if (top_level) - assert ((TREE_STATIC (decl) == 1) || DECL_EXTERNAL (decl) == 1); - - /* For Fortran, we by default put things in .common when possible. */ - DECL_COMMON (decl) = 1; - - /* Add this decl to the current binding level. TEM may equal DECL or it may - be a previous decl of the same name. */ - if (is_top_level) - tem = pushdecl_top_level (decl); - else - tem = pushdecl (decl); - - /* For a local variable, define the RTL now. */ - if (!top_level - /* But not if this is a duplicate decl and we preserved the rtl from the - previous one (which may or may not happen). */ - && DECL_RTL (tem) == 0) - { - if (TYPE_SIZE (TREE_TYPE (tem)) != 0) - expand_decl (tem); - else if (TREE_CODE (TREE_TYPE (tem)) == ARRAY_TYPE - && DECL_INITIAL (tem) != 0) - expand_decl (tem); - } - - if (DECL_INITIAL (tem) != NULL_TREE) - { - /* When parsing and digesting the initializer, use temporary storage. - Do this even if we will ignore the value. */ - if (at_top_level) - temporary_allocation (); - } - - return tem; -} - -/* Create the FUNCTION_DECL for a function definition. - DECLSPECS and DECLARATOR are the parts of the declaration; - they describe the function's name and the type it returns, - but twisted together in a fashion that parallels the syntax of C. - - This function creates a binding context for the function body - as well as setting up the FUNCTION_DECL in current_function_decl. - - Returns 1 on success. If the DECLARATOR is not suitable for a function - (it defines a datum instead), we return 0, which tells - yyparse to report a parse error. - - NESTED is nonzero for a function nested within another function. */ - -static void -start_function (tree name, tree type, int nested, int public) -{ - tree decl1; - tree restype; - int old_immediate_size_expand = immediate_size_expand; - - named_labels = 0; - shadowed_labels = 0; - - /* Don't expand any sizes in the return type of the function. */ - immediate_size_expand = 0; - - if (nested) - { - assert (!public); - assert (current_function_decl != NULL_TREE); - assert (DECL_CONTEXT (current_function_decl) == NULL_TREE); - } - else - { - assert (current_function_decl == NULL_TREE); - } - - if (TREE_CODE (type) == ERROR_MARK) - decl1 = current_function_decl = error_mark_node; - else - { - decl1 = build_decl (FUNCTION_DECL, - name, - type); - TREE_PUBLIC (decl1) = public ? 1 : 0; - if (nested) - DECL_INLINE (decl1) = 1; - TREE_STATIC (decl1) = 1; - DECL_EXTERNAL (decl1) = 0; - - announce_function (decl1); - - /* Make the init_value nonzero so pushdecl knows this is not tentative. - error_mark_node is replaced below (in poplevel) with the BLOCK. */ - DECL_INITIAL (decl1) = error_mark_node; - - /* Record the decl so that the function name is defined. If we already have - a decl for this name, and it is a FUNCTION_DECL, use the old decl. */ - - current_function_decl = pushdecl (decl1); - } - - if (!nested) - ffecom_outer_function_decl_ = current_function_decl; - - pushlevel (0); - - if (TREE_CODE (current_function_decl) != ERROR_MARK) - { - make_function_rtl (current_function_decl); - - restype = TREE_TYPE (TREE_TYPE (current_function_decl)); - DECL_RESULT (current_function_decl) - = build_decl (RESULT_DECL, NULL_TREE, restype); - } - - if (!nested) - /* Allocate further tree nodes temporarily during compilation of this - function only. */ - temporary_allocation (); - - if (!nested && (TREE_CODE (current_function_decl) != ERROR_MARK)) - TREE_ADDRESSABLE (current_function_decl) = 1; - - immediate_size_expand = old_immediate_size_expand; -} - -/* Here are the public functions the GNU back end needs. */ - -tree -convert (type, expr) - tree type, expr; -{ - register tree e = expr; - register enum tree_code code = TREE_CODE (type); - - if (type == TREE_TYPE (e) - || TREE_CODE (e) == ERROR_MARK) - return e; - if (TYPE_MAIN_VARIANT (type) == TYPE_MAIN_VARIANT (TREE_TYPE (e))) - return fold (build1 (NOP_EXPR, type, e)); - if (TREE_CODE (TREE_TYPE (e)) == ERROR_MARK - || code == ERROR_MARK) - return error_mark_node; - if (TREE_CODE (TREE_TYPE (e)) == VOID_TYPE) - { - assert ("void value not ignored as it ought to be" == NULL); - return error_mark_node; - } - if (code == VOID_TYPE) - return build1 (CONVERT_EXPR, type, e); - if ((code != RECORD_TYPE) - && (TREE_CODE (TREE_TYPE (e)) == RECORD_TYPE)) - e = ffecom_1 (REALPART_EXPR, TREE_TYPE (TYPE_FIELDS (TREE_TYPE (e))), - e); - if (code == INTEGER_TYPE || code == ENUMERAL_TYPE) - return fold (convert_to_integer (type, e)); - if (code == POINTER_TYPE) - return fold (convert_to_pointer (type, e)); - if (code == REAL_TYPE) - return fold (convert_to_real (type, e)); - if (code == COMPLEX_TYPE) - return fold (convert_to_complex (type, e)); - if (code == RECORD_TYPE) - return fold (ffecom_convert_to_complex_ (type, e)); - - assert ("conversion to non-scalar type requested" == NULL); - return error_mark_node; -} - -/* integrate_decl_tree calls this function, but since we don't use the - DECL_LANG_SPECIFIC field, this is a no-op. */ - -void -copy_lang_decl (node) - tree node UNUSED; -{ -} - -/* Return the list of declarations of the current level. - Note that this list is in reverse order unless/until - you nreverse it; and when you do nreverse it, you must - store the result back using `storedecls' or you will lose. */ - -tree -getdecls () -{ - return current_binding_level->names; -} - -/* Nonzero if we are currently in the global binding level. */ - -int -global_bindings_p () -{ - return current_binding_level == global_binding_level; -} - -/* Insert BLOCK at the end of the list of subblocks of the - current binding level. This is used when a BIND_EXPR is expanded, - to handle the BLOCK node inside the BIND_EXPR. */ - -void -incomplete_type_error (value, type) - tree value UNUSED; - tree type; -{ - if (TREE_CODE (type) == ERROR_MARK) - return; - - assert ("incomplete type?!?" == NULL); -} - -void -init_decl_processing () -{ - malloc_init (); - ffe_init_0 (); -} - -char * -init_parse (filename) - char *filename; -{ -#if BUILT_FOR_270 - extern void (*print_error_function) (char *); -#endif - - /* Open input file. */ - if (filename == 0 || !strcmp (filename, "-")) - { - finput = stdin; - filename = "stdin"; - } - else - finput = fopen (filename, "r"); - if (finput == 0) - pfatal_with_name (filename); - -#ifdef IO_BUFFER_SIZE - setvbuf (finput, (char *) xmalloc (IO_BUFFER_SIZE), _IOFBF, IO_BUFFER_SIZE); -#endif - - /* Make identifier nodes long enough for the language-specific slots. */ - set_identifier_size (sizeof (struct lang_identifier)); - decl_printable_name = lang_printable_name; -#if BUILT_FOR_270 - print_error_function = lang_print_error_function; -#endif - - return filename; -} - -void -finish_parse () -{ - fclose (finput); -} - -void -insert_block (block) - tree block; -{ - TREE_USED (block) = 1; - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); -} - -int -lang_decode_option (argc, argv) - int argc; - char **argv; -{ - return ffe_decode_option (argc, argv); -} - -/* used by print-tree.c */ - -void -lang_print_xnode (file, node, indent) - FILE *file UNUSED; - tree node UNUSED; - int indent UNUSED; -{ -} - -void -lang_finish () -{ - ffe_terminate_0 (); - - if (ffe_is_ffedebug ()) - malloc_pool_display (malloc_pool_image ()); -} - -char * -lang_identify () -{ - return "f77"; -} - -void -lang_init_options () -{ - /* Set default options for Fortran. */ - flag_move_all_movables = 1; - flag_reduce_all_givs = 1; - flag_argument_noalias = 2; -} - -void -lang_init () -{ - /* If the file is output from cpp, it should contain a first line - `# 1 "real-filename"', and the current design of gcc (toplev.c - in particular and the way it sets up information relied on by - INCLUDE) requires that we read this now, and store the - "real-filename" info in master_input_filename. Ask the lexer - to try doing this. */ - ffelex_hash_kludge (finput); -} - -int -mark_addressable (exp) - tree exp; -{ - register tree x = exp; - while (1) - switch (TREE_CODE (x)) - { - case ADDR_EXPR: - case COMPONENT_REF: - case ARRAY_REF: - x = TREE_OPERAND (x, 0); - break; - - case CONSTRUCTOR: - TREE_ADDRESSABLE (x) = 1; - return 1; - - case VAR_DECL: - case CONST_DECL: - case PARM_DECL: - case RESULT_DECL: - if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x) - && DECL_NONLOCAL (x)) - { - if (TREE_PUBLIC (x)) - { - assert ("address of global register var requested" == NULL); - return 0; - } - assert ("address of register variable requested" == NULL); - } - else if (DECL_REGISTER (x) && !TREE_ADDRESSABLE (x)) - { - if (TREE_PUBLIC (x)) - { - assert ("address of global register var requested" == NULL); - return 0; - } - assert ("address of register var requested" == NULL); - } - put_var_into_stack (x); - - /* drops in */ - case FUNCTION_DECL: - TREE_ADDRESSABLE (x) = 1; -#if 0 /* poplevel deals with this now. */ - if (DECL_CONTEXT (x) == 0) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (x)) = 1; -#endif - - default: - return 1; - } -} - -/* If DECL has a cleanup, build and return that cleanup here. - This is a callback called by expand_expr. */ - -tree -maybe_build_cleanup (decl) - tree decl UNUSED; -{ - /* There are no cleanups in Fortran. */ - return NULL_TREE; -} - -/* Exit a binding level. - Pop the level off, and restore the state of the identifier-decl mappings - that were in effect when this level was entered. - - If KEEP is nonzero, this level had explicit declarations, so - and create a "block" (a BLOCK node) for the level - to record its declarations and subblocks for symbol table output. - - If FUNCTIONBODY is nonzero, this level is the body of a function, - so create a block as if KEEP were set and also clear out all - label names. - - If REVERSE is nonzero, reverse the order of decls before putting - them into the BLOCK. */ - -tree -poplevel (keep, reverse, functionbody) - int keep; - int reverse; - int functionbody; -{ - register tree link; - /* The chain of decls was accumulated in reverse order. Put it into forward - order, just for cleanliness. */ - tree decls; - tree subblocks = current_binding_level->blocks; - tree block = 0; - tree decl; - int block_previously_created; - - /* Get the decls in the order they were written. Usually - current_binding_level->names is in reverse order. But parameter decls - were previously put in forward order. */ - - if (reverse) - current_binding_level->names - = decls = nreverse (current_binding_level->names); - else - decls = current_binding_level->names; - - /* Output any nested inline functions within this block if they weren't - already output. */ - - for (decl = decls; decl; decl = TREE_CHAIN (decl)) - if (TREE_CODE (decl) == FUNCTION_DECL - && !TREE_ASM_WRITTEN (decl) - && DECL_INITIAL (decl) != 0 - && TREE_ADDRESSABLE (decl)) - { - /* If this decl was copied from a file-scope decl on account of a - block-scope extern decl, propagate TREE_ADDRESSABLE to the - file-scope decl. */ - if (DECL_ABSTRACT_ORIGIN (decl) != 0) - TREE_ADDRESSABLE (DECL_ABSTRACT_ORIGIN (decl)) = 1; - else - { - push_function_context (); - output_inline_function (decl); - pop_function_context (); - } - } - - /* If there were any declarations or structure tags in that level, or if - this level is a function body, create a BLOCK to record them for the - life of this function. */ - - block = 0; - block_previously_created = (current_binding_level->this_block != 0); - if (block_previously_created) - block = current_binding_level->this_block; - else if (keep || functionbody) - block = make_node (BLOCK); - if (block != 0) - { - BLOCK_VARS (block) = decls; - BLOCK_SUBBLOCKS (block) = subblocks; - remember_end_note (block); - } - - /* In each subblock, record that this is its superior. */ - - for (link = subblocks; link; link = TREE_CHAIN (link)) - BLOCK_SUPERCONTEXT (link) = block; - - /* Clear out the meanings of the local variables of this level. */ - - for (link = decls; link; link = TREE_CHAIN (link)) - { - if (DECL_NAME (link) != 0) - { - /* If the ident. was used or addressed via a local extern decl, - don't forget that fact. */ - if (DECL_EXTERNAL (link)) - { - if (TREE_USED (link)) - TREE_USED (DECL_NAME (link)) = 1; - if (TREE_ADDRESSABLE (link)) - TREE_ADDRESSABLE (DECL_ASSEMBLER_NAME (link)) = 1; - } - IDENTIFIER_LOCAL_VALUE (DECL_NAME (link)) = 0; - } - } - - /* If the level being exited is the top level of a function, check over all - the labels, and clear out the current (function local) meanings of their - names. */ - - if (functionbody) - { - /* If this is the top level block of a function, the vars are the - function's parameters. Don't leave them in the BLOCK because they - are found in the FUNCTION_DECL instead. */ - - BLOCK_VARS (block) = 0; - } - - /* Pop the current level, and free the structure for reuse. */ - - { - register struct binding_level *level = current_binding_level; - current_binding_level = current_binding_level->level_chain; - - level->level_chain = free_binding_level; - free_binding_level = level; - } - - /* Dispose of the block that we just made inside some higher level. */ - if (functionbody) - DECL_INITIAL (current_function_decl) = block; - else if (block) - { - if (!block_previously_created) - current_binding_level->blocks - = chainon (current_binding_level->blocks, block); - } - /* If we did not make a block for the level just exited, any blocks made - for inner levels (since they cannot be recorded as subblocks in that - level) must be carried forward so they will later become subblocks of - something else. */ - else if (subblocks) - current_binding_level->blocks - = chainon (current_binding_level->blocks, subblocks); - - /* Set the TYPE_CONTEXTs for all of the tagged types belonging to this - binding contour so that they point to the appropriate construct, i.e. - either to the current FUNCTION_DECL node, or else to the BLOCK node we - just constructed. - - Note that for tagged types whose scope is just the formal parameter list - for some function type specification, we can't properly set their - TYPE_CONTEXTs here, because we don't have a pointer to the appropriate - FUNCTION_TYPE node readily available to us. For those cases, the - TYPE_CONTEXTs of the relevant tagged type nodes get set in - `grokdeclarator' as soon as we have created the FUNCTION_TYPE node which - will represent the "scope" for these "parameter list local" tagged - types. */ - - if (block) - TREE_USED (block) = 1; - return block; -} - -void -print_lang_decl (file, node, indent) - FILE *file UNUSED; - tree node UNUSED; - int indent UNUSED; -{ -} - -void -print_lang_identifier (file, node, indent) - FILE *file; - tree node; - int indent; -{ - print_node (file, "global", IDENTIFIER_GLOBAL_VALUE (node), indent + 4); - print_node (file, "local", IDENTIFIER_LOCAL_VALUE (node), indent + 4); -} - -void -print_lang_statistics () -{ -} - -void -print_lang_type (file, node, indent) - FILE *file UNUSED; - tree node UNUSED; - int indent UNUSED; -{ -} - -/* Record a decl-node X as belonging to the current lexical scope. - Check for errors (such as an incompatible declaration for the same - name already seen in the same scope). - - Returns either X or an old decl for the same name. - If an old decl is returned, it may have been smashed - to agree with what X says. */ - -tree -pushdecl (x) - tree x; -{ - register tree t; - register tree name = DECL_NAME (x); - register struct binding_level *b = current_binding_level; - - if ((TREE_CODE (x) == FUNCTION_DECL) - && (DECL_INITIAL (x) == 0) - && DECL_EXTERNAL (x)) - DECL_CONTEXT (x) = NULL_TREE; - else - DECL_CONTEXT (x) = current_function_decl; - - if (name) - { - if (IDENTIFIER_INVENTED (name)) - { -#if BUILT_FOR_270 - DECL_ARTIFICIAL (x) = 1; -#endif - DECL_IN_SYSTEM_HEADER (x) = 1; - } - - t = lookup_name_current_level (name); - - assert ((t == NULL_TREE) || (DECL_CONTEXT (x) == NULL_TREE)); - - /* Don't push non-parms onto list for parms until we understand - why we're doing this and whether it works. */ - - assert ((b == global_binding_level) - || !ffecom_transform_only_dummies_ - || TREE_CODE (x) == PARM_DECL); - - if ((t != NULL_TREE) && duplicate_decls (x, t)) - return t; - - /* If we are processing a typedef statement, generate a whole new - ..._TYPE node (which will be just an variant of the existing - ..._TYPE node with identical properties) and then install the - TYPE_DECL node generated to represent the typedef name as the - TYPE_NAME of this brand new (duplicate) ..._TYPE node. - - The whole point here is to end up with a situation where each and every - ..._TYPE node the compiler creates will be uniquely associated with - AT MOST one node representing a typedef name. This way, even though - the compiler substitutes corresponding ..._TYPE nodes for TYPE_DECL - (i.e. "typedef name") nodes very early on, later parts of the - compiler can always do the reverse translation and get back the - corresponding typedef name. For example, given: - - typedef struct S MY_TYPE; MY_TYPE object; - - Later parts of the compiler might only know that `object' was of type - `struct S' if it were not for code just below. With this code - however, later parts of the compiler see something like: - - struct S' == struct S typedef struct S' MY_TYPE; struct S' object; - - And they can then deduce (from the node for type struct S') that the - original object declaration was: - - MY_TYPE object; - - Being able to do this is important for proper support of protoize, and - also for generating precise symbolic debugging information which - takes full account of the programmer's (typedef) vocabulary. - - Obviously, we don't want to generate a duplicate ..._TYPE node if the - TYPE_DECL node that we are now processing really represents a - standard built-in type. - - Since all standard types are effectively declared at line zero in the - source file, we can easily check to see if we are working on a - standard type by checking the current value of lineno. */ - - if (TREE_CODE (x) == TYPE_DECL) - { - if (DECL_SOURCE_LINE (x) == 0) - { - if (TYPE_NAME (TREE_TYPE (x)) == 0) - TYPE_NAME (TREE_TYPE (x)) = x; - } - else if (TREE_TYPE (x) != error_mark_node) - { - tree tt = TREE_TYPE (x); - - tt = build_type_copy (tt); - TYPE_NAME (tt) = x; - TREE_TYPE (x) = tt; - } - } - - /* This name is new in its binding level. Install the new declaration - and return it. */ - if (b == global_binding_level) - IDENTIFIER_GLOBAL_VALUE (name) = x; - else - IDENTIFIER_LOCAL_VALUE (name) = x; - } - - /* Put decls on list in reverse order. We will reverse them later if - necessary. */ - TREE_CHAIN (x) = b->names; - b->names = x; - - return x; -} - -/* Enter a new binding level. - If TAG_TRANSPARENT is nonzero, do so only for the name space of variables, - not for that of tags. */ - -void -pushlevel (tag_transparent) - int tag_transparent; -{ - register struct binding_level *newlevel = NULL_BINDING_LEVEL; - - assert (!tag_transparent); - - /* Reuse or create a struct for this binding level. */ - - if (free_binding_level) - { - newlevel = free_binding_level; - free_binding_level = free_binding_level->level_chain; - } - else - { - newlevel = make_binding_level (); - } - - /* Add this level to the front of the chain (stack) of levels that are - active. */ - - *newlevel = clear_binding_level; - newlevel->level_chain = current_binding_level; - current_binding_level = newlevel; -} - -/* Set the BLOCK node for the innermost scope - (the one we are currently in). */ - -void -set_block (block) - register tree block; -{ - current_binding_level->this_block = block; -} - -/* ~~tree.h SHOULD declare this, because toplev.c references it. */ - -/* Can't 'yydebug' a front end not generated by yacc/bison! */ - -void -set_yydebug (value) - int value; -{ - if (value) - fprintf (stderr, "warning: no yacc/bison-generated output to debug!\n"); -} - -tree -signed_or_unsigned_type (unsignedp, type) - int unsignedp; - tree type; -{ - tree type2; - - if (! INTEGRAL_TYPE_P (type)) - return type; - if (TYPE_PRECISION (type) == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - if (TYPE_PRECISION (type) == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - - type2 = type_for_size (TYPE_PRECISION (type), unsignedp); - if (type2 == NULL_TREE) - return type; - - return type2; -} - -tree -signed_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - ffeinfoKindtype kt; - tree type2; - - if (type1 == unsigned_char_type_node || type1 == char_type_node) - return signed_char_type_node; - if (type1 == unsigned_type_node) - return integer_type_node; - if (type1 == short_unsigned_type_node) - return short_integer_type_node; - if (type1 == long_unsigned_type_node) - return long_integer_type_node; - if (type1 == long_long_unsigned_type_node) - return long_long_integer_type_node; -#if 0 /* gcc/c-* files only */ - if (type1 == unsigned_intDI_type_node) - return intDI_type_node; - if (type1 == unsigned_intSI_type_node) - return intSI_type_node; - if (type1 == unsigned_intHI_type_node) - return intHI_type_node; - if (type1 == unsigned_intQI_type_node) - return intQI_type_node; -#endif - - type2 = type_for_size (TYPE_PRECISION (type1), 0); - if (type2 != NULL_TREE) - return type2; - - for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt) - { - type2 = ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]; - - if (type1 == type2) - return ffecom_tree_type[FFEINFO_basictypeINTEGER][kt]; - } - - return type; -} - -/* Prepare expr to be an argument of a TRUTH_NOT_EXPR, - or validate its data type for an `if' or `while' statement or ?..: exp. - - This preparation consists of taking the ordinary - representation of an expression expr and producing a valid tree - boolean expression describing whether expr is nonzero. We could - simply always do build_binary_op (NE_EXPR, expr, integer_zero_node, 1), - but we optimize comparisons, &&, ||, and !. - - The resulting type should always be `integer_type_node'. */ - -tree -truthvalue_conversion (expr) - tree expr; -{ - if (TREE_CODE (expr) == ERROR_MARK) - return expr; - -#if 0 /* This appears to be wrong for C++. */ - /* These really should return error_mark_node after 2.4 is stable. - But not all callers handle ERROR_MARK properly. */ - switch (TREE_CODE (TREE_TYPE (expr))) - { - case RECORD_TYPE: - error ("struct type value used where scalar is required"); - return integer_zero_node; - - case UNION_TYPE: - error ("union type value used where scalar is required"); - return integer_zero_node; - - case ARRAY_TYPE: - error ("array type value used where scalar is required"); - return integer_zero_node; - - default: - break; - } -#endif /* 0 */ - - switch (TREE_CODE (expr)) - { - /* It is simpler and generates better code to have only TRUTH_*_EXPR - or comparison expressions as truth values at this level. */ -#if 0 - case COMPONENT_REF: - /* A one-bit unsigned bit-field is already acceptable. */ - if (1 == TREE_INT_CST_LOW (DECL_SIZE (TREE_OPERAND (expr, 1))) - && TREE_UNSIGNED (TREE_OPERAND (expr, 1))) - return expr; - break; -#endif - - case EQ_EXPR: - /* It is simpler and generates better code to have only TRUTH_*_EXPR - or comparison expressions as truth values at this level. */ -#if 0 - if (integer_zerop (TREE_OPERAND (expr, 1))) - return build_unary_op (TRUTH_NOT_EXPR, TREE_OPERAND (expr, 0), 0); -#endif - case NE_EXPR: case LE_EXPR: case GE_EXPR: case LT_EXPR: case GT_EXPR: - case TRUTH_ANDIF_EXPR: - case TRUTH_ORIF_EXPR: - case TRUTH_AND_EXPR: - case TRUTH_OR_EXPR: - case TRUTH_XOR_EXPR: - TREE_TYPE (expr) = integer_type_node; - return expr; - - case ERROR_MARK: - return expr; - - case INTEGER_CST: - return integer_zerop (expr) ? integer_zero_node : integer_one_node; - - case REAL_CST: - return real_zerop (expr) ? integer_zero_node : integer_one_node; - - case ADDR_EXPR: - if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 0))) - return build (COMPOUND_EXPR, integer_type_node, - TREE_OPERAND (expr, 0), integer_one_node); - else - return integer_one_node; - - case COMPLEX_EXPR: - return ffecom_2 ((TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1)) - ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - integer_type_node, - truthvalue_conversion (TREE_OPERAND (expr, 0)), - truthvalue_conversion (TREE_OPERAND (expr, 1))); - - case NEGATE_EXPR: - case ABS_EXPR: - case FLOAT_EXPR: - case FFS_EXPR: - /* These don't change whether an object is non-zero or zero. */ - return truthvalue_conversion (TREE_OPERAND (expr, 0)); - - case LROTATE_EXPR: - case RROTATE_EXPR: - /* These don't change whether an object is zero or non-zero, but - we can't ignore them if their second arg has side-effects. */ - if (TREE_SIDE_EFFECTS (TREE_OPERAND (expr, 1))) - return build (COMPOUND_EXPR, integer_type_node, TREE_OPERAND (expr, 1), - truthvalue_conversion (TREE_OPERAND (expr, 0))); - else - return truthvalue_conversion (TREE_OPERAND (expr, 0)); - - case COND_EXPR: - /* Distribute the conversion into the arms of a COND_EXPR. */ - return fold (build (COND_EXPR, integer_type_node, TREE_OPERAND (expr, 0), - truthvalue_conversion (TREE_OPERAND (expr, 1)), - truthvalue_conversion (TREE_OPERAND (expr, 2)))); - - case CONVERT_EXPR: - /* Don't cancel the effect of a CONVERT_EXPR from a REFERENCE_TYPE, - since that affects how `default_conversion' will behave. */ - if (TREE_CODE (TREE_TYPE (expr)) == REFERENCE_TYPE - || TREE_CODE (TREE_TYPE (TREE_OPERAND (expr, 0))) == REFERENCE_TYPE) - break; - /* fall through... */ - case NOP_EXPR: - /* If this is widening the argument, we can ignore it. */ - if (TYPE_PRECISION (TREE_TYPE (expr)) - >= TYPE_PRECISION (TREE_TYPE (TREE_OPERAND (expr, 0)))) - return truthvalue_conversion (TREE_OPERAND (expr, 0)); - break; - - case MINUS_EXPR: - /* With IEEE arithmetic, x - x may not equal 0, so we can't optimize - this case. */ - if (TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT - && TREE_CODE (TREE_TYPE (expr)) == REAL_TYPE) - break; - /* fall through... */ - case BIT_XOR_EXPR: - /* This and MINUS_EXPR can be changed into a comparison of the - two objects. */ - if (TREE_TYPE (TREE_OPERAND (expr, 0)) - == TREE_TYPE (TREE_OPERAND (expr, 1))) - return ffecom_2 (NE_EXPR, integer_type_node, - TREE_OPERAND (expr, 0), - TREE_OPERAND (expr, 1)); - return ffecom_2 (NE_EXPR, integer_type_node, - TREE_OPERAND (expr, 0), - fold (build1 (NOP_EXPR, - TREE_TYPE (TREE_OPERAND (expr, 0)), - TREE_OPERAND (expr, 1)))); - - case BIT_AND_EXPR: - if (integer_onep (TREE_OPERAND (expr, 1))) - return expr; - break; - - case MODIFY_EXPR: -#if 0 /* No such thing in Fortran. */ - if (warn_parentheses && C_EXP_ORIGINAL_CODE (expr) == MODIFY_EXPR) - warning ("suggest parentheses around assignment used as truth value"); -#endif - break; - - default: - break; - } - - if (TREE_CODE (TREE_TYPE (expr)) == COMPLEX_TYPE) - return (ffecom_2 - ((TREE_SIDE_EFFECTS (expr) - ? TRUTH_OR_EXPR : TRUTH_ORIF_EXPR), - integer_type_node, - truthvalue_conversion (ffecom_1 (REALPART_EXPR, - TREE_TYPE (TREE_TYPE (expr)), - expr)), - truthvalue_conversion (ffecom_1 (IMAGPART_EXPR, - TREE_TYPE (TREE_TYPE (expr)), - expr)))); - - return ffecom_2 (NE_EXPR, integer_type_node, - expr, - convert (TREE_TYPE (expr), integer_zero_node)); -} - -tree -type_for_mode (mode, unsignedp) - enum machine_mode mode; - int unsignedp; -{ - int i; - int j; - tree t; - - if (mode == TYPE_MODE (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - - if (mode == TYPE_MODE (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - - if (mode == TYPE_MODE (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - - if (mode == TYPE_MODE (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - - if (mode == TYPE_MODE (long_long_integer_type_node)) - return unsignedp ? long_long_unsigned_type_node : long_long_integer_type_node; - - if (mode == TYPE_MODE (float_type_node)) - return float_type_node; - - if (mode == TYPE_MODE (double_type_node)) - return double_type_node; - - if (mode == TYPE_MODE (build_pointer_type (char_type_node))) - return build_pointer_type (char_type_node); - - if (mode == TYPE_MODE (build_pointer_type (integer_type_node))) - return build_pointer_type (integer_type_node); - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffecom_tree_type); ++i) - for (j = 0; ((size_t) j) < ARRAY_SIZE (ffecom_tree_type[0]); ++j) - { - if (((t = ffecom_tree_type[i][j]) != NULL_TREE) - && (mode == TYPE_MODE (t))) - { - if ((i == FFEINFO_basictypeINTEGER) && unsignedp) - return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][j]; - else - return t; - } - } - - return 0; -} - -tree -type_for_size (bits, unsignedp) - unsigned bits; - int unsignedp; -{ - ffeinfoKindtype kt; - tree type_node; - - if (bits == TYPE_PRECISION (integer_type_node)) - return unsignedp ? unsigned_type_node : integer_type_node; - - if (bits == TYPE_PRECISION (signed_char_type_node)) - return unsignedp ? unsigned_char_type_node : signed_char_type_node; - - if (bits == TYPE_PRECISION (short_integer_type_node)) - return unsignedp ? short_unsigned_type_node : short_integer_type_node; - - if (bits == TYPE_PRECISION (long_integer_type_node)) - return unsignedp ? long_unsigned_type_node : long_integer_type_node; - - if (bits == TYPE_PRECISION (long_long_integer_type_node)) - return (unsignedp ? long_long_unsigned_type_node - : long_long_integer_type_node); - - for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt) - { - type_node = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt]; - - if ((type_node != NULL_TREE) && (bits == TYPE_PRECISION (type_node))) - return unsignedp ? ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt] - : type_node; - } - - return 0; -} - -tree -unsigned_type (type) - tree type; -{ - tree type1 = TYPE_MAIN_VARIANT (type); - ffeinfoKindtype kt; - tree type2; - - if (type1 == signed_char_type_node || type1 == char_type_node) - return unsigned_char_type_node; - if (type1 == integer_type_node) - return unsigned_type_node; - if (type1 == short_integer_type_node) - return short_unsigned_type_node; - if (type1 == long_integer_type_node) - return long_unsigned_type_node; - if (type1 == long_long_integer_type_node) - return long_long_unsigned_type_node; -#if 0 /* gcc/c-* files only */ - if (type1 == intDI_type_node) - return unsigned_intDI_type_node; - if (type1 == intSI_type_node) - return unsigned_intSI_type_node; - if (type1 == intHI_type_node) - return unsigned_intHI_type_node; - if (type1 == intQI_type_node) - return unsigned_intQI_type_node; -#endif - - type2 = type_for_size (TYPE_PRECISION (type1), 1); - if (type2 != NULL_TREE) - return type2; - - for (kt = 0; kt < ARRAY_SIZE (ffecom_tree_type[0]); ++kt) - { - type2 = ffecom_tree_type[FFEINFO_basictypeINTEGER][kt]; - - if (type1 == type2) - return ffecom_tree_type[FFEINFO_basictypeHOLLERITH][kt]; - } - - return type; -} - -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -#if FFECOM_GCC_INCLUDE - -/* From gcc/cccp.c, the code to handle -I. */ - -/* Skip leading "./" from a directory name. - This may yield the empty string, which represents the current directory. */ - -static char * -skip_redundant_dir_prefix (char *dir) -{ - while (dir[0] == '.' && dir[1] == '/') - for (dir += 2; *dir == '/'; dir++) - continue; - if (dir[0] == '.' && !dir[1]) - dir++; - return dir; -} - -/* 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" - -/* 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 = 0; - -struct file_name_list - { - struct file_name_list *next; - char *fname; - /* Mapping of file names for this directory. */ - struct file_name_map *name_map; - /* Non-zero if name_map is valid. */ - int got_name_map; - }; - -static struct file_name_list *include = NULL; /* First dir to search */ -static struct file_name_list *last_include = NULL; /* Last in chain */ - -/* 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 { - char *fname; - /* Filename specified with #line command. */ - char *nominal_fname; - /* Record where in the search path this file was found. - For #include_next. */ - struct file_name_list *dir; - ffewhereLine line; - ffewhereColumn column; -} instack[INPUT_STACK_MAX]; - -static int last_error_tick = 0; /* Incremented each time we print it. */ -static int input_file_stack_tick = 0; /* Incremented when status changes. */ - -/* Current nesting level of input sources. - `instack[indepth]' is the level currently being read. */ -static int indepth = -1; - -typedef struct file_buf FILE_BUF; - -typedef unsigned char U_CHAR; - -/* 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. */ -U_CHAR is_hor_space[256]; -/* table to tell if c is horizontal or vertical space. */ -static 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) - -/* Nonzero means -I- has been seen, - so don't look for #include "foo" the source-file directory. */ -static int ignore_srcdir; - -#ifndef INCLUDE_LEN_FUDGE -#define INCLUDE_LEN_FUDGE 0 -#endif - -static void append_include_chain (struct file_name_list *first, - struct file_name_list *last); -static FILE *open_include_file (char *filename, - struct file_name_list *searchptr); -static void print_containing_files (ffebadSeverity sev); -static char *skip_redundant_dir_prefix (char *); -static char *read_filename_string (int ch, FILE *f); -static struct file_name_map *read_name_map (char *dirname); -static char *savestring (char *input); - -/* 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; - - 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; -} - -/* Try to open include file FILENAME. SEARCHPTR is the directory - being tried from the include file search path. This function maps - filenames on file systems based on information read by - read_name_map. */ - -static FILE * -open_include_file (filename, searchptr) - char *filename; - struct file_name_list *searchptr; -{ - register struct file_name_map *map; - register char *from; - char *p, *dir; - - if (searchptr && ! searchptr->got_name_map) - { - searchptr->name_map = read_name_map (searchptr->fname - ? searchptr->fname : "."); - searchptr->got_name_map = 1; - } - - /* First check the mapping for the directory we are using. */ - if (searchptr && searchptr->name_map) - { - from = filename; - if (searchptr->fname) - from += strlen (searchptr->fname) + 1; - for (map = searchptr->name_map; map; map = map->map_next) - { - if (! strcmp (map->map_from, from)) - { - /* Found a match. */ - return fopen (map->map_to, "r"); - } - } - } - - /* 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. */ - p = rindex (filename, '/'); -#ifdef DIR_SEPARATOR - if (! p) p = rindex (filename, DIR_SEPARATOR); - else { - char *tmp = rindex (filename, DIR_SEPARATOR); - if (tmp != NULL && tmp > p) p = tmp; - } -#endif - if (! p) - p = filename; - if (searchptr - && searchptr->fname - && strlen (searchptr->fname) == (size_t) (p - filename) - && ! strncmp (searchptr->fname, filename, (int) (p - filename))) - { - /* FILENAME is in SEARCHPTR, which we've already checked. */ - return fopen (filename, "r"); - } - - if (p == filename) - { - from = filename; - map = read_name_map ("."); - } - else - { - dir = (char *) xmalloc (p - filename + 1); - memcpy (dir, filename, p - filename); - dir[p - filename] = '\0'; - from = p + 1; - map = read_name_map (dir); - free (dir); - } - for (; map; map = map->map_next) - if (! strcmp (map->map_from, from)) - return fopen (map->map_to, "r"); - - return fopen (filename, "r"); -} - -/* Print the file names and line numbers of the #include - commands which led to the current file. */ - -static void -print_containing_files (ffebadSeverity sev) -{ - FILE_BUF *ip = NULL; - int i; - int first = 1; - char *str1; - char *str2; - - /* 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; - str1 = "In file included"; - } - else - { - str1 = "... ..."; - } - - if (i == 1) - str2 = ":"; - else - str2 = ""; - - ffebad_start_msg ("%A from %B at %0%C", sev); - ffebad_here (0, ip->line, ip->column); - ffebad_string (str1); - ffebad_string (ip->nominal_fname); - ffebad_string (str2); - ffebad_finish (); - } - - /* Record we have printed the status as of this time. */ - last_error_tick = input_file_stack_tick; -} - -/* 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. */ - -static struct file_name_map * -read_name_map (dirname) - 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; - int separator_needed; - - dirname = skip_redundant_dir_prefix (dirname); - - 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 = savestring (dirname); - map_list_ptr->map_list_map = NULL; - - dirlen = strlen (dirname); - separator_needed = dirlen != 0 && dirname[dirlen - 1] != '/'; - name = (char *) xmalloc (dirlen + strlen (FILE_NAME_MAP_FILE) + 2); - strcpy (name, dirname); - name[dirlen] = '/'; - strcpy (name + dirlen + separator_needed, FILE_NAME_MAP_FILE); - f = fopen (name, "r"); - free (name); - 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; - - 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); - - ptr = ((struct file_name_map *) - xmalloc (sizeof (struct file_name_map))); - ptr->map_from = from; - - /* Make the real filename absolute. */ - if (*to == '/') - ptr->map_to = to; - else - { - ptr->map_to = xmalloc (dirlen + strlen (to) + 2); - strcpy (ptr->map_to, dirname); - ptr->map_to[dirlen] = '/'; - strcpy (ptr->map_to + dirlen + separator_needed, 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; -} - -static char * -savestring (input) - char *input; -{ - unsigned size = strlen (input); - char *output = xmalloc (size + 1); - strcpy (output, input); - return output; -} - -static void -ffecom_file_ (char *name) -{ - FILE_BUF *fp; - - /* Do partial setup of input buffer for the sake of generating - early #line directives (when -g is in effect). */ - - fp = &instack[++indepth]; - memset ((char *) fp, 0, sizeof (FILE_BUF)); - if (name == NULL) - name = ""; - fp->nominal_fname = fp->fname = name; -} - -/* Initialize syntactic classifications of characters. */ - -static void -ffecom_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[i - 'a' + 'A'] = 1; - is_idchar[i] = 1; - is_idstart[i - 'a' + 'A'] = 1; - is_idstart[i] = 1; - } - for (i = '0'; i <= '9'; i++) - is_idchar[i] = 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; -} - -static void -ffecom_close_include_ (FILE *f) -{ - fclose (f); - - indepth--; - input_file_stack_tick++; - - ffewhere_line_kill (instack[indepth].line); - ffewhere_column_kill (instack[indepth].column); -} - -static int -ffecom_decode_include_option_ (char *spec) -{ - struct file_name_list *dirtmp; - - if (! ignore_srcdir && !strcmp (spec, "-")) - ignore_srcdir = 1; - else - { - dirtmp = (struct file_name_list *) - xmalloc (sizeof (struct file_name_list)); - dirtmp->next = 0; /* New one goes on the end */ - if (spec[0] != 0) - dirtmp->fname = spec; - else - fatal ("Directory name must immediately follow -I option with no intervening spaces, as in `-Idir', not `-I dir'"); - dirtmp->got_name_map = 0; - append_include_chain (dirtmp, dirtmp); - } - return 1; -} - -/* Open INCLUDEd file. */ - -static FILE * -ffecom_open_include_ (char *name, ffewhereLine l, ffewhereColumn c) -{ - char *fbeg = name; - size_t flen = strlen (fbeg); - struct file_name_list *search_start = include; /* Chain of dirs to search */ - struct file_name_list dsp[1]; /* First in chain, if #include "..." */ - struct file_name_list *searchptr = 0; - char *fname; /* Dynamically allocated fname buffer */ - FILE *f; - FILE_BUF *fp; - - if (flen == 0) - return NULL; - - dsp[0].fname = NULL; - - /* If -I- was specified, don't search current dir, only spec'd ones. */ - if (!ignore_srcdir) - { - for (fp = &instack[indepth]; fp >= instack; fp--) - { - int n; - char *ep; - char *nam; - - if ((nam = fp->nominal_fname) != NULL) - { - /* Found a named file. Figure out dir of the file, - and put it in front of the search list. */ - dsp[0].next = search_start; - search_start = dsp; -#ifndef VMS - ep = rindex (nam, '/'); -#ifdef DIR_SEPARATOR - if (ep == NULL) ep = rindex (nam, DIR_SEPARATOR); - else { - char *tmp = rindex (nam, DIR_SEPARATOR); - if (tmp != NULL && tmp > ep) ep = tmp; - } -#endif -#else /* VMS */ - ep = rindex (nam, ']'); - if (ep == NULL) ep = rindex (nam, '>'); - if (ep == NULL) ep = rindex (nam, ':'); - if (ep != NULL) ep++; -#endif /* VMS */ - if (ep != NULL) - { - n = ep - nam; - dsp[0].fname = (char *) xmalloc (n + 1); - strncpy (dsp[0].fname, nam, n); - dsp[0].fname[n] = '\0'; - if (n + INCLUDE_LEN_FUDGE > max_include_len) - max_include_len = n + INCLUDE_LEN_FUDGE; - } - else - dsp[0].fname = NULL; /* Current directory */ - dsp[0].got_name_map = 0; - break; - } - } - } - - /* Allocate this permanently, because it gets stored in the definitions - of macros. */ - fname = xmalloc (max_include_len + flen + 4); - /* + 2 above for slash and terminating null. */ - /* + 2 added for '.h' on VMS (to support '#include filename') (NOT USED - for g77 yet). */ - - /* If specified file name is absolute, just open it. */ - - if (*fbeg == '/' -#ifdef DIR_SEPARATOR - || *fbeg == DIR_SEPARATOR -#endif - ) - { - strncpy (fname, (char *) fbeg, flen); - fname[flen] = 0; - f = open_include_file (fname, NULL_PTR); - } - else - { - f = NULL; - - /* Search directory path, trying to open the file. - Copy each filename tried into FNAME. */ - - for (searchptr = search_start; searchptr; searchptr = searchptr->next) - { - if (searchptr->fname) - { - /* The empty string in a search path is ignored. - This makes it possible to turn off entirely - a standard piece of the list. */ - if (searchptr->fname[0] == 0) - continue; - strcpy (fname, skip_redundant_dir_prefix (searchptr->fname)); - if (fname[0] && fname[strlen (fname) - 1] != '/') - strcat (fname, "/"); - fname[strlen (fname) + flen] = 0; - } - else - fname[0] = 0; - - strncat (fname, fbeg, flen); -#ifdef VMS - /* Change this 1/2 Unix 1/2 VMS file specification into a - full VMS file specification */ - if (searchptr->fname && (searchptr->fname[0] != 0)) - { - /* Fix up the filename */ - hack_vms_include_specification (fname); - } - else - { - /* This is a normal VMS filespec, so use it unchanged. */ - strncpy (fname, (char *) fbeg, flen); - fname[flen] = 0; -#if 0 /* Not for g77. */ - /* if it's '#include filename', add the missing .h */ - if (index (fname, '.') == NULL) - strcat (fname, ".h"); -#endif - } -#endif /* VMS */ - f = open_include_file (fname, searchptr); -#ifdef EACCES - if (f == NULL && errno == EACCES) - { - print_containing_files (FFEBAD_severityWARNING); - ffebad_start_msg ("At %0, INCLUDE file %A exists, but is not readable", - FFEBAD_severityWARNING); - ffebad_string (fname); - ffebad_here (0, l, c); - ffebad_finish (); - } -#endif - if (f != NULL) - break; - } - } - - if (f == NULL) - { - /* A file that was not found. */ - - strncpy (fname, (char *) fbeg, flen); - fname[flen] = 0; - print_containing_files (ffebad_severity (FFEBAD_OPEN_INCLUDE)); - ffebad_start (FFEBAD_OPEN_INCLUDE); - ffebad_here (0, l, c); - ffebad_string (fname); - ffebad_finish (); - } - - if (dsp[0].fname != NULL) - free (dsp[0].fname); - - if (f == NULL) - return NULL; - - if (indepth >= (INPUT_STACK_MAX - 1)) - { - print_containing_files (FFEBAD_severityFATAL); - ffebad_start_msg ("At %0, INCLUDE nesting too deep", - FFEBAD_severityFATAL); - ffebad_string (fname); - ffebad_here (0, l, c); - ffebad_finish (); - return NULL; - } - - instack[indepth].line = ffewhere_line_use (l); - instack[indepth].column = ffewhere_column_use (c); - - fp = &instack[indepth + 1]; - memset ((char *) fp, 0, sizeof (FILE_BUF)); - fp->nominal_fname = fp->fname = fname; - fp->dir = searchptr; - - indepth++; - input_file_stack_tick++; - - return f; -} -#endif /* FFECOM_GCC_INCLUDE */ diff --git a/gcc/f/com.h b/gcc/f/com.h deleted file mode 100755 index db8f469..0000000 --- a/gcc/f/com.h +++ /dev/null @@ -1,376 +0,0 @@ -/* com.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - com.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_com -#define _H_f_com - -/* Simple definitions and enumerations. */ - -#define FFECOM_dimensionsMAX 7 /* Max # dimensions (quick hack). */ - -#define FFECOM_targetFFE 1 -#define FFECOM_targetGCC 2 - -#ifndef FFE_STANDALONE -#define FFECOM_targetCURRENT FFECOM_targetGCC /* Backend! */ -#define FFECOM_ONEPASS 0 -#else -#define FFECOM_targetCURRENT FFECOM_targetFFE -#define FFECOM_ONEPASS 0 -#endif - -#if FFECOM_ONEPASS -#define FFECOM_TWOPASS 0 -#else -#define FFECOM_TWOPASS 1 -#endif - -#define FFECOM_SIZE_UNIT "byte" /* Singular form. */ -#define FFECOM_SIZE_UNITS "bytes" /* Plural form. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define FFECOM_constantNULL NULL_TREE -#define FFECOM_globalNULL NULL_TREE -#define FFECOM_labelNULL NULL_TREE -#define FFECOM_storageNULL NULL_TREE -#define FFECOM_symbolNULL ffecom_symbol_null_ - -/* Shorthand for types used in f2c.h and that g77 perhaps allows some - flexibility regarding in the section below. I.e. the actual numbers - below aren't important, as long as they're unique. */ - -#define FFECOM_f2ccodeCHAR 1 -#define FFECOM_f2ccodeSHORT 2 -#define FFECOM_f2ccodeINT 3 -#define FFECOM_f2ccodeLONG 4 -#define FFECOM_f2ccodeLONGLONG 5 -#define FFECOM_f2ccodeCHARPTR 6 /* char * */ -#define FFECOM_f2ccodeFLOAT 7 -#define FFECOM_f2ccodeDOUBLE 8 -#define FFECOM_f2ccodeLONGDOUBLE 9 -#define FFECOM_f2ccodeTWOREALS 10 -#define FFECOM_f2ccodeTWODOUBLEREALS 11 - -#if FFECOM_DETERMINE_TYPES /* only for com.c and configure */ - -/* Begin f2c.h information. This must match the info in the f2c.h used - to build the libf2c with which g77-generated code is linked, or there - will probably be bugs, some of them difficult to detect or even trigger. */ - -/* Do we need int (for 32-bit or 64-bit systems) or long (16-bit or - normally 32-bit) for f2c-type integers? */ - -#ifndef BITS_PER_WORD -#define BITS_PER_WORD 32 -#endif - -#ifndef CHAR_TYPE_SIZE -#define CHAR_TYPE_SIZE BITS_PER_UNIT -#endif - -#ifndef SHORT_TYPE_SIZE -#define SHORT_TYPE_SIZE (BITS_PER_UNIT * MIN ((UNITS_PER_WORD + 1) / 2, 2)) -#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 LONG_LONG_TYPE_SIZE -#define LONG_LONG_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef WCHAR_UNSIGNED -#define WCHAR_UNSIGNED 0 -#endif - -#ifndef FLOAT_TYPE_SIZE -#define FLOAT_TYPE_SIZE BITS_PER_WORD -#endif - -#ifndef DOUBLE_TYPE_SIZE -#define DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#ifndef LONG_DOUBLE_TYPE_SIZE -#define LONG_DOUBLE_TYPE_SIZE (BITS_PER_WORD * 2) -#endif - -#if LONG_TYPE_SIZE == FLOAT_TYPE_SIZE -# define FFECOM_f2cINTEGER FFECOM_f2ccodeLONG -# define FFECOM_f2cLOGICAL FFECOM_f2ccodeLONG -#elif INT_TYPE_SIZE == FLOAT_TYPE_SIZE -# define FFECOM_f2cINTEGER FFECOM_f2ccodeINT -# define FFECOM_f2cLOGICAL FFECOM_f2ccodeINT -#else -# error Cannot find a suitable type for FFECOM_f2cINTEGER -#endif - -#if LONG_TYPE_SIZE == (FLOAT_TYPE_SIZE * 2) -# define FFECOM_f2cLONGINT FFECOM_f2ccodeLONG -#elif LONG_LONG_TYPE_SIZE == (FLOAT_TYPE_SIZE * 2) -# define FFECOM_f2cLONGINT FFECOM_f2ccodeLONGLONG -#else -# error Cannot find a suitable type for FFECOM_f2cLONGINT -#endif - -#define FFECOM_f2cADDRESS FFECOM_f2ccodeCHARPTR -#define FFECOM_f2cSHORTINT FFECOM_f2ccodeSHORT -#define FFECOM_f2cREAL FFECOM_f2ccodeFLOAT -#define FFECOM_f2cDOUBLEREAL FFECOM_f2ccodeDOUBLE -#define FFECOM_f2cCOMPLEX FFECOM_f2ccodeTWOREALS -#define FFECOM_f2cDOUBLECOMPLEX FFECOM_f2ccodeTWODOUBLEREALS -#define FFECOM_f2cSHORTLOGICAL FFECOM_f2ccodeSHORT -#define FFECOM_f2cLOGICAL1 FFECOM_f2ccodeCHAR -#define FFECOM_f2cINTEGER1 FFECOM_f2ccodeCHAR - -/* These must be f2c's INTEGER type, to match runtime/f2c.h.in. */ - -#define FFECOM_f2cFLAG FFECOM_f2cINTEGER -#define FFECOM_f2cFTNINT FFECOM_f2cINTEGER -#define FFECOM_f2cFTNLEN FFECOM_f2cINTEGER - -#endif /* #if FFECOM_DETERMINE_TYPES */ - -/* Everything else in f2c.h, specifically the structures used in - interfacing compiled code with the library, must remain exactly - as delivered, or g77 internals (mostly com.c and ste.c) must - be modified accordingly to compensate. Or there will be...trouble. */ - -typedef enum - { -#define DEFGFRT(CODE,NAME,TYPE,ARGS,VOLATILE,COMPLEX) CODE, -#include "com-rt.def" -#undef DEFGFRT - FFECOM_gfrt - } ffecomGfrt; - -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Typedefs. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#ifndef TREE_CODE -#include "tree.j" -#endif - -#ifndef BUILT_FOR_270 -#ifdef DECL_STATIC_CONSTRUCTOR /* In gcc/tree.h. */ -#define BUILT_FOR_270 1 -#else -#define BUILT_FOR_270 0 -#endif -#endif /* !defined (BUILT_FOR_270) */ - -#ifndef BUILT_FOR_280 -#ifdef DECL_ONE_ONLY /* In gcc/tree.h. */ -#define BUILT_FOR_280 1 -#else -#define BUILT_FOR_280 0 -#endif -#endif /* !defined (BUILT_FOR_280) */ - -typedef tree ffecomConstant; -#define FFECOM_constantHOOK -typedef tree ffecomLabel; -#define FFECOM_globalHOOK -typedef tree ffecomGlobal; -#define FFECOM_labelHOOK -typedef tree ffecomStorage; -#define FFECOM_storageHOOK -typedef struct _ffecom_symbol_ ffecomSymbol; -#define FFECOM_symbolHOOK - -struct _ffecom_symbol_ - { - tree decl_tree; - tree length_tree; /* For CHARACTER dummies. */ - tree vardesc_tree; /* For NAMELIST. */ - tree assign_tree; /* For ASSIGN'ed vars. */ - bool addr; /* Is address of item instead of item. */ - }; -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Include files needed by this one. */ - -#include "bld.h" -#include "info.h" -#include "lab.h" -#include "storag.h" -#include "symbol.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -extern tree long_integer_type_node; -extern tree complex_double_type_node; -extern tree string_type_node; -extern tree ffecom_integer_type_node; -extern tree ffecom_integer_zero_node; -extern tree ffecom_integer_one_node; -extern tree ffecom_tree_type[FFEINFO_basictype][FFEINFO_kindtype]; -extern ffecomSymbol ffecom_symbol_null_; -extern ffeinfoKindtype ffecom_pointer_kind_; -extern ffeinfoKindtype ffecom_label_kind_; - -extern int ffecom_f2c_typecode_[FFEINFO_basictype][FFEINFO_kindtype]; -extern tree ffecom_f2c_integer_type_node; -extern tree ffecom_f2c_address_type_node; -extern tree ffecom_f2c_real_type_node; -extern tree ffecom_f2c_doublereal_type_node; -extern tree ffecom_f2c_complex_type_node; -extern tree ffecom_f2c_doublecomplex_type_node; -extern tree ffecom_f2c_longint_type_node; -extern tree ffecom_f2c_logical_type_node; -extern tree ffecom_f2c_flag_type_node; -extern tree ffecom_f2c_ftnlen_type_node; -extern tree ffecom_f2c_ftnlen_zero_node; -extern tree ffecom_f2c_ftnlen_one_node; -extern tree ffecom_f2c_ftnlen_two_node; -extern tree ffecom_f2c_ptr_to_ftnlen_type_node; -extern tree ffecom_f2c_ftnint_type_node; -extern tree ffecom_f2c_ptr_to_ftnint_type_node; -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Declare functions with prototypes. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree ffecom_1 (enum tree_code code, tree type, tree node); -tree ffecom_1_fn (tree node); -tree ffecom_2 (enum tree_code code, tree type, tree node1, tree node2); -bool ffecom_2pass_advise_entrypoint (ffesymbol entry); -void ffecom_2pass_do_entrypoint (ffesymbol entry); -tree ffecom_2s (enum tree_code code, tree type, tree node1, tree node2); -tree ffecom_3 (enum tree_code code, tree type, tree node1, tree node2, - tree node3); -tree ffecom_3s (enum tree_code code, tree type, tree node1, tree node2, - tree node3); -tree ffecom_arg_expr (ffebld expr, tree *length); -tree ffecom_arg_ptr_to_expr (ffebld expr, tree *length); -tree ffecom_call_gfrt (ffecomGfrt ix, tree args); -tree ffecom_constantunion (ffebldConstantUnion *cu, ffeinfoBasictype bt, - ffeinfoKindtype kt, tree tree_type); -tree ffecom_decl_field (tree context, tree prevfield, char *name, - tree type); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -void ffecom_close_include (FILE *f); -int ffecom_decode_include_option (char *spec); -void ffecom_end_transition (void); -void ffecom_exec_transition (void); -void ffecom_expand_let_stmt (ffebld dest, ffebld source); -#if FFECOM_targetCURRENT == FFECOM_targetGCC -tree ffecom_expr (ffebld expr); -tree ffecom_expr_assign (ffebld expr); -tree ffecom_expr_assign_w (ffebld expr); -tree ffecom_expr_rw (ffebld expr); -void ffecom_finish_compile (void); -void ffecom_finish_decl (tree decl, tree init, bool is_top_level); -void ffecom_finish_progunit (void); -tree ffecom_get_invented_identifier (char *pattern, char *text, - int number); -ffeinfoKindtype ffecom_gfrt_basictype (ffecomGfrt ix); -ffeinfoKindtype ffecom_gfrt_kindtype (ffecomGfrt ix); -void ffecom_init_0 (void); -void ffecom_init_2 (void); -tree ffecom_list_expr (ffebld list); -tree ffecom_list_ptr_to_expr (ffebld list); -tree ffecom_lookup_label (ffelab label); -tree ffecom_modify (tree newtype, tree lhs, tree rhs); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -void ffecom_file (char *name); -void ffecom_notify_init_storage (ffestorag st); -void ffecom_notify_init_symbol (ffesymbol s); -void ffecom_notify_primary_entry (ffesymbol fn); -FILE *ffecom_open_include (char *name, ffewhereLine l, ffewhereColumn c); -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void ffecom_pop_calltemps (void); -void ffecom_pop_tempvar (tree var); -tree ffecom_ptr_to_expr (ffebld expr); -void ffecom_push_calltemps (void); -tree ffecom_push_tempvar (tree type, ffetargetCharacterSize size, - int elements, bool auto_pop); -tree ffecom_return_expr (ffebld expr); -tree ffecom_save_tree (tree t); -tree ffecom_start_decl (tree decl, bool is_init); -void ffecom_sym_commit (ffesymbol s); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -ffesymbol ffecom_sym_end_transition (ffesymbol s); -ffesymbol ffecom_sym_exec_transition (ffesymbol s); -ffesymbol ffecom_sym_learned (ffesymbol s); -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void ffecom_sym_retract (ffesymbol s); -tree ffecom_temp_label (void); -tree ffecom_truth_value (tree expr); -tree ffecom_truth_value_invert (tree expr); -tree ffecom_which_entrypoint_decl (void); - -/* These need to be in the front end with exactly these interfaces, - as they're called by the back end. */ - -int mark_addressable (tree expr); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* Define macros. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -#define ffecom_expr(e) (e) -#define ffecom_init_0() -#define ffecom_init_2() -#define ffecom_label_kind() FFEINFO_kindtypeINTEGERDEFAULT -#define ffecom_pointer_kind() FFEINFO_kindtypeINTEGERDEFAULT -#define ffecom_ptr_to_expr(e) (e) -#define ffecom_sym_commit(s) -#define ffecom_sym_retract(s) -#endif /* FFECOM_targetCURRENT == FFECOM_targetFFE */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define ffecom_f2c_typecode(bt,kt) ffecom_f2c_typecode_[(bt)][(kt)] -#define ffecom_label_kind() ffecom_label_kind_ -#define ffecom_pointer_kind() ffecom_pointer_kind_ -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -#define ffecom_init_1() -#define ffecom_init_3() -#define ffecom_init_4() -#define ffecom_terminate_0() -#define ffecom_terminate_1() -#define ffecom_terminate_2() -#define ffecom_terminate_3() -#define ffecom_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/config-lang.in b/gcc/f/config-lang.in deleted file mode 100755 index 504bc20..0000000 --- a/gcc/f/config-lang.in +++ /dev/null @@ -1,37 +0,0 @@ -# Top level configure fragment for GNU FORTRAN. -# Copyright (C) 1995-1997 Free Software Foundation, Inc. - -#This file is part of GNU Fortran. - -#GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -#the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -#02111-1307, USA. - -# Configure looks for the existence of this file to auto-config each language. -# We define several parameters used by configure: -# -# language - name of language as it would appear in $(LANGUAGES) -# compilers - value to add to $(COMPILERS) -# stagestuff - files to add to $(STAGESTUFF) -# diff_excludes - files to ignore when building diffs between two versions. - -language="f77" - -compilers="f771\$(exeext)" - -stagestuff="g77\$(exeext) g77-cross\$(exeext) f771\$(exeext)" - -diff_excludes="-x f/BUGS -x f/NEWS -x f/INSTALL -x f/intdoc.texi" - -outputs=f/Makefile diff --git a/gcc/f/config.j b/gcc/f/config.j deleted file mode 100755 index 3fd1c11..0000000 --- a/gcc/f/config.j +++ /dev/null @@ -1,27 +0,0 @@ -/* config.j -- Wrapper for GCC's config.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_config -#define _J_f_config -#include "config.h" -#endif -#endif diff --git a/gcc/f/convert.j b/gcc/f/convert.j deleted file mode 100755 index 85e3af8..0000000 --- a/gcc/f/convert.j +++ /dev/null @@ -1,28 +0,0 @@ -/* convert.j -- Wrapper for GCC's convert.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_convert -#define _J_f_convert -#include "tree.j" -#include "convert.h" -#endif -#endif diff --git a/gcc/f/data.c b/gcc/f/data.c deleted file mode 100755 index a8acd5c..0000000 --- a/gcc/f/data.c +++ /dev/null @@ -1,1816 +0,0 @@ -/* data.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - - Description: - Do the tough things for DATA statement (and INTEGER FOO/.../-style - initializations), like implied-DO and suchlike. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "data.h" -#include "bit.h" -#include "bld.h" -#include "com.h" -#include "expr.h" -#include "global.h" -#include "malloc.h" -#include "st.h" -#include "storag.h" -#include "top.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - -/* I picked this value as one that, when plugged into a couple of small - but nearly identical test cases I have called BIG-0.f and BIG-1.f, - causes BIG-1.f to take about 10 times as long (elapsed) to compile - (in f771 only) as BIG-0.f. These test cases differ in that BIG-0.f - doesn't put the one initialized variable in a common area that has - a large uninitialized array in it, while BIG-1.f does. The size of - the array is this many elements, as long as they all are INTEGER - type. Note that, as of 0.5.18, sparse cases are better handled, - so BIG-2.f now is used; it provides nonzero initial - values for all elements of the same array BIG-0 has. */ -#ifndef FFEDATA_sizeTOO_BIG_INIT_ -#define FFEDATA_sizeTOO_BIG_INIT_ 75*1024 -#endif - -/* Internal typedefs. */ - -typedef struct _ffedata_convert_cache_ *ffedataConvertCache_; -typedef struct _ffedata_impdo_ *ffedataImpdo_; - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffedata_convert_cache_ - { - ffebld converted; /* Results of converting expr to following - type. */ - ffeinfoBasictype basic_type; - ffeinfoKindtype kind_type; - ffetargetCharacterSize size; - ffeinfoRank rank; - }; - -struct _ffedata_impdo_ - { - ffedataImpdo_ outer; /* Enclosing IMPDO construct. */ - ffebld outer_list; /* Item after my IMPDO on the outer list. */ - ffebld my_list; /* Beginning of list in my IMPDO. */ - ffesymbol itervar; /* Iteration variable. */ - ffetargetIntegerDefault increment; - ffetargetIntegerDefault final; - }; - -/* Static objects accessed by functions in this module. */ - -static ffedataImpdo_ ffedata_stack_ = NULL; -static ffebld ffedata_list_ = NULL; -static bool ffedata_reinit_; /* value_ should report REINIT error. */ -static bool ffedata_reported_error_; /* Error has been reported. */ -static ffesymbol ffedata_symbol_ = NULL; /* Symbol being initialized. */ -static ffeinfoBasictype ffedata_basictype_; /* Info on symbol. */ -static ffeinfoKindtype ffedata_kindtype_; -static ffestorag ffedata_storage_; /* If non-NULL, inits go into this parent. */ -static ffeinfoBasictype ffedata_storage_bt_; /* Info on storage. */ -static ffeinfoKindtype ffedata_storage_kt_; -static ffetargetOffset ffedata_storage_size_; /* Size of entire storage. */ -static ffetargetAlign ffedata_storage_units_; /* #units per storage unit. */ -static ffetargetOffset ffedata_arraysize_; /* Size of array being - inited. */ -static ffetargetOffset ffedata_expected_; /* Number of elements to - init. */ -static ffetargetOffset ffedata_number_; /* #elements inited so far. */ -static ffetargetOffset ffedata_offset_; /* Offset of next element. */ -static ffetargetOffset ffedata_symbolsize_; /* Size of entire sym. */ -static ffetargetCharacterSize ffedata_size_; /* Size of an element. */ -static ffetargetCharacterSize ffedata_charexpected_; /* #char to init. */ -static ffetargetCharacterSize ffedata_charnumber_; /* #chars inited. */ -static ffetargetCharacterSize ffedata_charoffset_; /* Offset of next char. */ -static ffedataConvertCache_ ffedata_convert_cache_; /* Fewer conversions. */ -static int ffedata_convert_cache_max_ = 0; /* #entries available. */ -static int ffedata_convert_cache_use_ = 0; /* #entries in use. */ - -/* Static functions (internal). */ - -static bool ffedata_advance_ (void); -static ffebld ffedata_convert_ (ffebld source, ffelexToken source_token, - ffelexToken dest_token, ffeinfoBasictype bt, ffeinfoKindtype kt, - ffeinfoRank rk, ffetargetCharacterSize sz); -static ffetargetInteger1 ffedata_eval_integer1_ (ffebld expr); -static ffetargetOffset ffedata_eval_offset_ (ffebld subscripts, - ffebld dims); -static ffetargetCharacterSize ffedata_eval_substr_begin_ (ffebld expr); -static ffetargetCharacterSize ffedata_eval_substr_end_ (ffebld expr, - ffetargetCharacterSize min, ffetargetCharacterSize max); -static void ffedata_gather_ (ffestorag mst, ffestorag st); -static void ffedata_pop_ (void); -static void ffedata_push_ (void); -static bool ffedata_value_ (ffebld value, ffelexToken token); - -/* Internal macros. */ - - -/* ffedata_begin -- Initialize with list of targets - - ffebld list; - ffedata_begin(list); // ITEM... list of SYMTERs, ARRAYs, SUBSTRs, ... - - Remember the list. After this call, 0...n calls to ffedata_value must - follow, and then a single call to ffedata_end. */ - -void -ffedata_begin (ffebld list) -{ - assert (ffedata_list_ == NULL); - ffedata_list_ = list; - ffedata_symbol_ = NULL; - ffedata_reported_error_ = FALSE; - ffedata_reinit_ = FALSE; - ffedata_advance_ (); -} - -/* ffedata_end -- End of initialization sequence - - if (ffedata_end(FALSE)) - // everything's ok - - Make sure the end of the list is valid here. */ - -bool -ffedata_end (bool reported_error, ffelexToken t) -{ - reported_error |= ffedata_reported_error_; - - /* If still targets to initialize, too few initializers, so complain. */ - - if ((ffedata_symbol_ != NULL) && !reported_error) - { - reported_error = TRUE; - ffebad_start (FFEBAD_DATA_TOOFEW); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - } - - /* Pop off any impdo stacks (present only if ffedata_symbol_ != NULL). */ - - while (ffedata_stack_ != NULL) - ffedata_pop_ (); - - if (ffedata_list_ != NULL) - { - assert (reported_error); - ffedata_list_ = NULL; - } - - return TRUE; -} - -/* ffedata_gather -- Gather previously disparate initializations into one place - - ffestorag st; // A typeCBLOCK or typeLOCAL aggregate. - ffedata_gather(st); - - Prior to this call, st has no init or accretion info, but (presumably - at least one of) its subordinate storage areas has init or accretion - info. After this call, none of the subordinate storage areas has inits, - because they've all been moved into the newly created init/accretion - info for st. During this call, conflicting inits produce only one - error message. */ - -void -ffedata_gather (ffestorag st) -{ - ffesymbol s; - ffebld b; - - /* Prepare info on the storage area we're putting init info into. */ - - ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_, - &ffedata_storage_units_, ffestorag_basictype (st), - ffestorag_kindtype (st)); - ffedata_storage_size_ = ffestorag_size (st) / ffedata_storage_units_; - assert (ffestorag_size (st) % ffedata_storage_units_ == 0); - - /* If a CBLOCK, gather all the init info for its explicit members. */ - - if ((ffestorag_type (st) == FFESTORAG_typeCBLOCK) - && (ffestorag_symbol (st) != NULL)) - { - s = ffestorag_symbol (st); - for (b = ffesymbol_commonlist (s); b != NULL; b = ffebld_trail (b)) - ffedata_gather_ (st, - ffesymbol_storage (ffebld_symter (ffebld_head (b)))); - } - - /* For CBLOCK or LOCAL, gather all the init info for equivalenced members. */ - - ffestorag_drive (ffestorag_list_equivs (st), ffedata_gather_, st); -} - -/* ffedata_value -- Provide some number of initial values - - ffebld value; - ffelexToken t; // Points to the value. - if (ffedata_value(1,value,t)) - // Everything's ok - - Makes sure the value is ok, then remembers it according to the list - provided to ffedata_begin. As many instances of the value may be - supplied as desired, as indicated by the first argument. */ - -bool -ffedata_value (ffetargetIntegerDefault rpt, ffebld value, ffelexToken token) -{ - ffetargetIntegerDefault i; - - /* Maybe ignore zero values, to speed up compiling, even though we lose - checking for multiple initializations for now. */ - - if (!ffe_is_zeros () - && (value != NULL) - && (ffebld_op (value) == FFEBLD_opCONTER) - && ffebld_constant_is_zero (ffebld_conter (value))) - value = NULL; - else if ((value != NULL) - && (ffebld_op (value) == FFEBLD_opANY)) - value = NULL; - else - { - /* Must be a constant. */ - assert (value != NULL); - assert (ffebld_op (value) == FFEBLD_opCONTER); - } - - /* Later we can optimize certain cases by seeing that the target array can - take some number of values, and provide this number to _value_. */ - - if (rpt == 1) - ffedata_convert_cache_use_ = -1; /* Don't bother caching. */ - else - ffedata_convert_cache_use_ = 0; /* Maybe use the cache. */ - - for (i = 0; i < rpt; ++i) - { - if ((ffedata_symbol_ != NULL) - && !ffesymbol_is_init (ffedata_symbol_)) - { - ffesymbol_signal_change (ffedata_symbol_); - ffesymbol_update_init (ffedata_symbol_); - if (1 || ffe_is_90 ()) - ffesymbol_update_save (ffedata_symbol_); -#if FFEGLOBAL_ENABLED - if (ffesymbol_common (ffedata_symbol_) != NULL) - ffeglobal_init_common (ffesymbol_common (ffedata_symbol_), - token); -#endif - ffesymbol_signal_unreported (ffedata_symbol_); - } - if (!ffedata_value_ (value, token)) - return FALSE; - } - - return TRUE; -} - -/* ffedata_advance_ -- Advance initialization target to next item in list - - if (ffedata_advance_()) - // everything's ok - - Sets common info to characterize the next item in the list. Handles - IMPDO constructs accordingly. Does not handle advances within a single - item, as in the common extension "DATA CHARTYPE/33,34,35/", where - CHARTYPE is CHARACTER*3, for example. */ - -static bool -ffedata_advance_ () -{ - ffebld next; - - /* Come here after handling an IMPDO. */ - -tail_recurse: /* :::::::::::::::::::: */ - - /* Assume we're not going to find a new target for now. */ - - ffedata_symbol_ = NULL; - - /* If at the end of the list, we're done. */ - - if (ffedata_list_ == NULL) - { - ffetargetIntegerDefault newval; - - if (ffedata_stack_ == NULL) - return TRUE; /* No IMPDO in progress, we is done! */ - - /* Iterate the IMPDO. */ - - newval = ffesymbol_value (ffedata_stack_->itervar) - + ffedata_stack_->increment; - - /* See if we're still in the loop. */ - - if (((ffedata_stack_->increment > 0) - ? newval > ffedata_stack_->final - : newval < ffedata_stack_->final) - || (((ffesymbol_value (ffedata_stack_->itervar) < 0) - == (ffedata_stack_->increment < 0)) - && ((ffesymbol_value (ffedata_stack_->itervar) < 0) - != (newval < 0)))) /* Overflow/underflow? */ - { /* Done with the loop. */ - ffedata_list_ = ffedata_stack_->outer_list; /* Restore list. */ - ffedata_pop_ (); /* Pop me off the impdo stack. */ - } - else - { /* Still in the loop, reset the list and - update the iter var. */ - ffedata_list_ = ffedata_stack_->my_list; /* Reset list. */ - ffesymbol_set_value (ffedata_stack_->itervar, newval); - } - goto tail_recurse; /* :::::::::::::::::::: */ - } - - /* Move to the next item in the list. */ - - next = ffebld_head (ffedata_list_); - ffedata_list_ = ffebld_trail (ffedata_list_); - - /* Really shouldn't happen. */ - - if (next == NULL) - return TRUE; - - /* See what kind of target this is. */ - - switch (ffebld_op (next)) - { - case FFEBLD_opSYMTER: /* Simple reference to scalar or array. */ - ffedata_symbol_ = ffebld_symter (next); - ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL - : ffestorag_parent (ffesymbol_storage (ffedata_symbol_)); - if (ffedata_storage_ != NULL) - { - ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_, - &ffedata_storage_units_, - ffestorag_basictype (ffedata_storage_), - ffestorag_kindtype (ffedata_storage_)); - ffedata_storage_size_ = ffestorag_size (ffedata_storage_) - / ffedata_storage_units_; - assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0); - } - - if ((ffesymbol_init (ffedata_symbol_) != NULL) - || (ffesymbol_accretion (ffedata_symbol_) != NULL) - || ((ffedata_storage_ != NULL) - && (ffestorag_init (ffedata_storage_) != NULL))) - { -#if 0 - ffebad_start (FFEBAD_DATA_REINIT); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; -#else - ffedata_reinit_ = TRUE; - return TRUE; -#endif - } - ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_); - ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_); - if (ffesymbol_rank (ffedata_symbol_) == 0) - ffedata_arraysize_ = 1; - else - { - ffebld size = ffesymbol_arraysize (ffedata_symbol_); - - assert (size != NULL); - assert (ffebld_op (size) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (size)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (size)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter - (size)); - } - ffedata_expected_ = ffedata_arraysize_; - ffedata_number_ = 0; - ffedata_offset_ = 0; - ffedata_size_ = (ffedata_basictype_ == FFEINFO_basictypeCHARACTER) - ? ffesymbol_size (ffedata_symbol_) : 1; - ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_; - ffedata_charexpected_ = ffedata_size_; - ffedata_charnumber_ = 0; - ffedata_charoffset_ = 0; - break; - - case FFEBLD_opARRAYREF: /* Reference to element of array. */ - ffedata_symbol_ = ffebld_symter (ffebld_left (next)); - ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL - : ffestorag_parent (ffesymbol_storage (ffedata_symbol_)); - if (ffedata_storage_ != NULL) - { - ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_, - &ffedata_storage_units_, - ffestorag_basictype (ffedata_storage_), - ffestorag_kindtype (ffedata_storage_)); - ffedata_storage_size_ = ffestorag_size (ffedata_storage_) - / ffedata_storage_units_; - assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0); - } - - if ((ffesymbol_init (ffedata_symbol_) != NULL) - || ((ffedata_storage_ != NULL) - && (ffestorag_init (ffedata_storage_) != NULL))) - { -#if 0 - ffebad_start (FFEBAD_DATA_REINIT); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; -#else - ffedata_reinit_ = TRUE; - return TRUE; -#endif - } - ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_); - ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_); - if (ffesymbol_rank (ffedata_symbol_) == 0) - ffedata_arraysize_ = 1; /* Shouldn't happen in this case... */ - else - { - ffebld size = ffesymbol_arraysize (ffedata_symbol_); - - assert (size != NULL); - assert (ffebld_op (size) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (size)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (size)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter - (size)); - } - ffedata_expected_ = 1; - ffedata_number_ = 0; - ffedata_offset_ = ffedata_eval_offset_ (ffebld_right (next), - ffesymbol_dims (ffedata_symbol_)); - ffedata_size_ = (ffedata_basictype_ == FFEINFO_basictypeCHARACTER) - ? ffesymbol_size (ffedata_symbol_) : 1; - ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_; - ffedata_charexpected_ = ffedata_size_; - ffedata_charnumber_ = 0; - ffedata_charoffset_ = 0; - break; - - case FFEBLD_opSUBSTR: /* Substring reference to scalar or array - element. */ - { - bool arrayref = ffebld_op (ffebld_left (next)) == FFEBLD_opARRAYREF; - ffebld colon = ffebld_right (next); - - assert (colon != NULL); - - ffedata_symbol_ = ffebld_symter (ffebld_left (arrayref - ? ffebld_left (next) : next)); - ffedata_storage_ = (ffesymbol_storage (ffedata_symbol_) == NULL) ? NULL - : ffestorag_parent (ffesymbol_storage (ffedata_symbol_)); - if (ffedata_storage_ != NULL) - { - ffetarget_aggregate_info (&ffedata_storage_bt_, &ffedata_storage_kt_, - &ffedata_storage_units_, - ffestorag_basictype (ffedata_storage_), - ffestorag_kindtype (ffedata_storage_)); - ffedata_storage_size_ = ffestorag_size (ffedata_storage_) - / ffedata_storage_units_; - assert (ffestorag_size (ffedata_storage_) % ffedata_storage_units_ == 0); - } - - if ((ffesymbol_init (ffedata_symbol_) != NULL) - || ((ffedata_storage_ != NULL) - && (ffestorag_init (ffedata_storage_) != NULL))) - { -#if 0 - ffebad_start (FFEBAD_DATA_REINIT); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; -#else - ffedata_reinit_ = TRUE; - return TRUE; -#endif - } - ffedata_basictype_ = ffesymbol_basictype (ffedata_symbol_); - ffedata_kindtype_ = ffesymbol_kindtype (ffedata_symbol_); - if (ffesymbol_rank (ffedata_symbol_) == 0) - ffedata_arraysize_ = 1; - else - { - ffebld size = ffesymbol_arraysize (ffedata_symbol_); - - assert (size != NULL); - assert (ffebld_op (size) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (size)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (size)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_arraysize_ = ffebld_constant_integerdefault (ffebld_conter - (size)); - } - ffedata_expected_ = arrayref ? 1 : ffedata_arraysize_; - ffedata_number_ = 0; - ffedata_offset_ = arrayref ? ffedata_eval_offset_ (ffebld_right - (ffebld_left (next)), ffesymbol_dims (ffedata_symbol_)) : 0; - ffedata_size_ = ffesymbol_size (ffedata_symbol_); - ffedata_symbolsize_ = ffedata_size_ * ffedata_arraysize_; - ffedata_charnumber_ = 0; - ffedata_charoffset_ = ffedata_eval_substr_begin_ (ffebld_head (colon)); - ffedata_charexpected_ = ffedata_eval_substr_end_ (ffebld_head - (ffebld_trail (colon)), ffedata_charoffset_, - ffedata_size_) - ffedata_charoffset_ + 1; - } - break; - - case FFEBLD_opIMPDO: /* Implied-DO construct. */ - { - ffebld itervar; - ffebld start; - ffebld end; - ffebld incr; - ffebld item = ffebld_right (next); - - itervar = ffebld_head (item); - item = ffebld_trail (item); - start = ffebld_head (item); - item = ffebld_trail (item); - end = ffebld_head (item); - item = ffebld_trail (item); - incr = ffebld_head (item); - - ffedata_push_ (); - ffedata_stack_->outer_list = ffedata_list_; - ffedata_stack_->my_list = ffedata_list_ = ffebld_left (next); - - assert (ffeinfo_basictype (ffebld_info (itervar)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (itervar)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_stack_->itervar = ffebld_symter (itervar); - - assert (ffeinfo_basictype (ffebld_info (start)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (start)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffesymbol_set_value (ffedata_stack_->itervar, ffedata_eval_integer1_ (start)); - - assert (ffeinfo_basictype (ffebld_info (end)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (end)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_stack_->final = ffedata_eval_integer1_ (end); - - if (incr == NULL) - ffedata_stack_->increment = 1; - else - { - assert (ffeinfo_basictype (ffebld_info (incr)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (incr)) - == FFEINFO_kindtypeINTEGERDEFAULT); - ffedata_stack_->increment = ffedata_eval_integer1_ (incr); - if (ffedata_stack_->increment == 0) - { - ffebad_start (FFEBAD_DATA_ZERO); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_stack_->itervar)); - ffebad_finish (); - ffedata_pop_ (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - } - - if ((ffedata_stack_->increment > 0) - ? ffesymbol_value (ffedata_stack_->itervar) - > ffedata_stack_->final - : ffesymbol_value (ffedata_stack_->itervar) - < ffedata_stack_->final) - { - ffedata_reported_error_ = TRUE; - ffebad_start (FFEBAD_DATA_EMPTY); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_stack_->itervar)); - ffebad_finish (); - ffedata_pop_ (); - return FALSE; - } - } - goto tail_recurse; /* :::::::::::::::::::: */ - - case FFEBLD_opANY: - ffedata_reported_error_ = TRUE; - return FALSE; - - default: - assert ("bad op" == NULL); - break; - } - - return TRUE; -} - -/* ffedata_convert_ -- Convert source expression to given type using cache - - ffebld source; - ffelexToken source_token; - ffelexToken dest_token; // Any appropriate token for "destination". - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharactersize sz; - source = ffedata_convert_(source,source_token,dest_token,bt,kt,sz); - - Like ffeexpr_convert, but calls it only if necessary (if the converted - expression doesn't already exist in the cache) and then puts the result - in the cache. */ - -ffebld -ffedata_convert_ (ffebld source, ffelexToken source_token, - ffelexToken dest_token, ffeinfoBasictype bt, - ffeinfoKindtype kt, ffeinfoRank rk, - ffetargetCharacterSize sz) -{ - ffebld converted; - int i; - int max; - ffedataConvertCache_ cache; - - for (i = 0; i < ffedata_convert_cache_use_; ++i) - if ((bt == ffedata_convert_cache_[i].basic_type) - && (kt == ffedata_convert_cache_[i].kind_type) - && (sz == ffedata_convert_cache_[i].size) - && (rk == ffedata_convert_cache_[i].rank)) - return ffedata_convert_cache_[i].converted; - - converted = ffeexpr_convert (source, source_token, dest_token, bt, kt, rk, - sz, FFEEXPR_contextDATA); - - if (ffedata_convert_cache_use_ >= ffedata_convert_cache_max_) - { - if (ffedata_convert_cache_max_ == 0) - max = 4; - else - max = ffedata_convert_cache_max_ << 1; - - if (max > ffedata_convert_cache_max_) - { - cache = (ffedataConvertCache_) malloc_new_ks (malloc_pool_image (), - "FFEDATA cache", max * sizeof (*cache)); - if (ffedata_convert_cache_max_ != 0) - { - memcpy (cache, ffedata_convert_cache_, - ffedata_convert_cache_max_ * sizeof (*cache)); - malloc_kill_ks (malloc_pool_image (), ffedata_convert_cache_, - ffedata_convert_cache_max_ * sizeof (*cache)); - } - ffedata_convert_cache_ = cache; - ffedata_convert_cache_max_ = max; - } - else - return converted; /* In case int overflows! */ - } - - i = ffedata_convert_cache_use_++; - - ffedata_convert_cache_[i].converted = converted; - ffedata_convert_cache_[i].basic_type = bt; - ffedata_convert_cache_[i].kind_type = kt; - ffedata_convert_cache_[i].size = sz; - ffedata_convert_cache_[i].rank = rk; - - return converted; -} - -/* ffedata_eval_integer1_ -- Evaluate expression - - ffetargetIntegerDefault result; - ffebld expr; // must be kindtypeINTEGER1. - - result = ffedata_eval_integer1_(expr); - - Evalues the expression (which yields a kindtypeINTEGER1 result) and - returns the result. */ - -static ffetargetIntegerDefault -ffedata_eval_integer1_ (ffebld expr) -{ - ffetargetInteger1 result; - ffebad error; - - assert (expr != NULL); - - switch (ffebld_op (expr)) - { - case FFEBLD_opCONTER: - return ffebld_constant_integer1 (ffebld_conter (expr)); - - case FFEBLD_opSYMTER: - return ffesymbol_value (ffebld_symter (expr)); - - case FFEBLD_opUPLUS: - return ffedata_eval_integer1_ (ffebld_left (expr)); - - case FFEBLD_opUMINUS: - error = ffetarget_uminus_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr))); - break; - - case FFEBLD_opADD: - error = ffetarget_add_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opSUBTRACT: - error = ffetarget_subtract_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opMULTIPLY: - error = ffetarget_multiply_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opDIVIDE: - error = ffetarget_divide_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opPOWER: - { - ffebld r = ffebld_right (expr); - - if ((ffeinfo_basictype (ffebld_info (r)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (r)) != FFEINFO_kindtypeINTEGERDEFAULT)) - error = FFEBAD_DATA_EVAL; - else - error = ffetarget_power_integerdefault_integerdefault (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (r)); - } - break; - -#if 0 /* Only for character basictype. */ - case FFEBLD_opCONCATENATE: - error =; - break; -#endif - - case FFEBLD_opNOT: - error = ffetarget_not_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr))); - break; - -#if 0 /* Only for logical basictype. */ - case FFEBLD_opLT: - error =; - break; - - case FFEBLD_opLE: - error =; - break; - - case FFEBLD_opEQ: - error =; - break; - - case FFEBLD_opNE: - error =; - break; - - case FFEBLD_opGT: - error =; - break; - - case FFEBLD_opGE: - error =; - break; -#endif - - case FFEBLD_opAND: - error = ffetarget_and_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opOR: - error = ffetarget_or_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opXOR: - error = ffetarget_xor_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opEQV: - error = ffetarget_eqv_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opNEQV: - error = ffetarget_neqv_integer1 (&result, - ffedata_eval_integer1_ (ffebld_left (expr)), - ffedata_eval_integer1_ (ffebld_right (expr))); - break; - - case FFEBLD_opPAREN: - return ffedata_eval_integer1_ (ffebld_left (expr)); - -#if 0 /* ~~ no idea how to do this */ - case FFEBLD_opPERCENT_LOC: - error =; - break; -#endif - -#if 0 /* not allowed by ANSI, but perhaps as an - extension someday? */ - case FFEBLD_opCONVERT: - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { - default: - error = FFEBAD_DATA_EVAL; - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { - default: - error = FFEBAD_DATA_EVAL; - break; - } - break; - } - break; -#endif - -#if 0 /* not valid ops */ - case FFEBLD_opREPEAT: - error =; - break; - - case FFEBLD_opBOUNDS: - error =; - break; -#endif - -#if 0 /* not allowed by ANSI, but perhaps as an - extension someday? */ - case FFEBLD_opFUNCREF: - error =; - break; -#endif - -#if 0 /* not valid ops */ - case FFEBLD_opSUBRREF: - error =; - break; - - case FFEBLD_opARRAYREF: - error =; - break; -#endif - -#if 0 /* not valid for integer1 */ - case FFEBLD_opSUBSTR: - error =; - break; -#endif - - default: - error = FFEBAD_DATA_EVAL; - break; - } - - if (error != FFEBAD) - { - ffebad_start (error); - ffest_ffebad_here_current_stmt (0); - ffebad_finish (); - result = 0; - } - - return result; -} - -/* ffedata_eval_offset_ -- Evaluate offset info array - - ffetargetOffset offset; // 0...max-1. - ffebld subscripts; // an opITEM list of subscript exprs. - ffebld dims; // an opITEM list of opBOUNDS exprs. - - result = ffedata_eval_offset_(expr); - - Evalues the expression (which yields a kindtypeINTEGER1 result) and - returns the result. */ - -static ffetargetOffset -ffedata_eval_offset_ (ffebld subscripts, ffebld dims) -{ - ffetargetIntegerDefault offset = 0; - ffetargetIntegerDefault width = 1; - ffetargetIntegerDefault value; - ffetargetIntegerDefault lowbound; - ffetargetIntegerDefault highbound; - ffetargetOffset final; - ffebld subscript; - ffebld dim; - ffebld low; - ffebld high; - int rank = 0; - bool ok; - - while (subscripts != NULL) - { - ++rank; - assert (dims != NULL); - - subscript = ffebld_head (subscripts); - dim = ffebld_head (dims); - - assert (ffeinfo_basictype (ffebld_info (subscript)) == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (subscript)) == FFEINFO_kindtypeINTEGER1); - value = ffedata_eval_integer1_ (subscript); - - assert (ffebld_op (dim) == FFEBLD_opBOUNDS); - low = ffebld_left (dim); - high = ffebld_right (dim); - - if (low == NULL) - lowbound = 1; - else - { - assert (ffeinfo_basictype (ffebld_info (low)) == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (low)) == FFEINFO_kindtypeINTEGERDEFAULT); - lowbound = ffedata_eval_integer1_ (low); - } - - assert (ffeinfo_basictype (ffebld_info (high)) == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (high)) == FFEINFO_kindtypeINTEGERDEFAULT); - highbound = ffedata_eval_integer1_ (high); - - if ((value < lowbound) || (value > highbound)) - { - char rankstr[10]; - - sprintf (rankstr, "%d", rank); - value = lowbound; - ffebad_start (FFEBAD_DATA_SUBSCRIPT); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_string (rankstr); - ffebad_finish (); - } - - subscripts = ffebld_trail (subscripts); - dims = ffebld_trail (dims); - - offset += width * (value - lowbound); - if (subscripts != NULL) - width *= highbound - lowbound + 1; - } - - assert (dims == NULL); - - ok = ffetarget_offset (&final, offset); - assert (ok); - - return final; -} - -/* ffedata_eval_substr_begin_ -- Evaluate begin-point of substr reference - - ffetargetCharacterSize beginpoint; - ffebld endval; // head(colon). - - beginpoint = ffedata_eval_substr_end_(endval); - - If beginval is NULL, returns 0. Otherwise makes sure beginval is - kindtypeINTEGERDEFAULT, makes sure its value is > 0, - and returns its value minus one, or issues an error message. */ - -static ffetargetCharacterSize -ffedata_eval_substr_begin_ (ffebld expr) -{ - ffetargetIntegerDefault val; - - if (expr == NULL) - return 0; - - assert (ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (expr)) == FFEINFO_kindtypeINTEGERDEFAULT); - - val = ffedata_eval_integer1_ (expr); - - if (val < 1) - { - val = 1; - ffebad_start (FFEBAD_DATA_RANGE); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - } - - return val - 1; -} - -/* ffedata_eval_substr_end_ -- Evaluate end-point of substr reference - - ffetargetCharacterSize endpoint; - ffebld endval; // head(trail(colon)). - ffetargetCharacterSize min; // beginpoint of substr reference. - ffetargetCharacterSize max; // size of entity. - - endpoint = ffedata_eval_substr_end_(endval,dflt); - - If endval is NULL, returns max. Otherwise makes sure endval is - kindtypeINTEGERDEFAULT, makes sure its value is > min and <= max, - and returns its value minus one, or issues an error message. */ - -static ffetargetCharacterSize -ffedata_eval_substr_end_ (ffebld expr, ffetargetCharacterSize min, - ffetargetCharacterSize max) -{ - ffetargetIntegerDefault val; - - if (expr == NULL) - return max - 1; - - assert (ffeinfo_basictype (ffebld_info (expr)) == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (expr)) == FFEINFO_kindtypeINTEGER1); - - val = ffedata_eval_integer1_ (expr); - - if ((val < (ffetargetIntegerDefault) min) - || (val > (ffetargetIntegerDefault) max)) - { - val = 1; - ffebad_start (FFEBAD_DATA_RANGE); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - } - - return val - 1; -} - -/* ffedata_gather_ -- Gather initial values for sym into master sym inits - - ffestorag mst; // A typeCBLOCK or typeLOCAL aggregate. - ffestorag st; // A typeCOMMON or typeEQUIV member. - ffedata_gather_(mst,st); - - If st has any initialization info, transfer that info into mst and - clear st's info. */ - -void -ffedata_gather_ (ffestorag mst, ffestorag st) -{ - ffesymbol s; - ffesymbol s_whine; /* Symbol to complain about in diagnostics. */ - ffebld b; - ffetargetOffset offset; - ffetargetOffset units_expected; - ffebitCount actual; - ffebldConstantArray array; - ffebld accter; - ffetargetCopyfunc fn; - void *ptr1; - void *ptr2; - size_t size; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffeinfoBasictype ign_bt; - ffeinfoKindtype ign_kt; - ffetargetAlign units; - ffebit bits; - ffetargetOffset source_offset; - bool whine = FALSE; - - if (st == NULL) - return; /* Nothing to do. */ - - s = ffestorag_symbol (st); - - assert (s != NULL); /* Must have a corresponding symbol (else how - inited?). */ - assert (ffestorag_init (st) == NULL); /* No init info on storage itself. */ - assert (ffestorag_accretion (st) == NULL); - - if ((((b = ffesymbol_init (s)) == NULL) - && ((b = ffesymbol_accretion (s)) == NULL)) - || (ffebld_op (b) == FFEBLD_opANY) - || ((ffebld_op (b) == FFEBLD_opCONVERT) - && (ffebld_op (ffebld_left (b)) == FFEBLD_opANY))) - return; /* Nothing to do. */ - - /* b now holds the init/accretion expr. */ - - ffesymbol_set_init (s, NULL); - ffesymbol_set_accretion (s, NULL); - ffesymbol_set_accretes (s, 0); - - s_whine = ffestorag_symbol (mst); - if (s_whine == NULL) - s_whine = s; - - /* Make sure we haven't fully accreted during an array init. */ - - if (ffestorag_init (mst) != NULL) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); - ffebad_string (ffesymbol_text (s_whine)); - ffebad_finish (); - return; - } - - bt = ffeinfo_basictype (ffebld_info (b)); - kt = ffeinfo_kindtype (ffebld_info (b)); - - /* Calculate offset for aggregate area. */ - - ffedata_charexpected_ = (bt == FFEINFO_basictypeCHARACTER) - ? ffebld_size (b) : 1; - ffetarget_aggregate_info (&ign_bt, &ign_kt, &units, bt, - kt);/* Find out unit size of source datum. */ - assert (units % ffedata_storage_units_ == 0); - units_expected = ffedata_charexpected_ * units / ffedata_storage_units_; - offset = (ffestorag_offset (st) - ffestorag_offset (mst)) - / ffedata_storage_units_; - - /* Does an accretion array exist? If not, create it. */ - - if (ffestorag_accretion (mst) == NULL) - { -#if FFEDATA_sizeTOO_BIG_INIT_ != 0 - if (ffedata_storage_size_ >= FFEDATA_sizeTOO_BIG_INIT_) - { - char bignum[40]; - - sprintf (&bignum[0], "%ld", (long) ffedata_storage_size_); - ffebad_start (FFEBAD_TOO_BIG_INIT); - ffebad_here (0, ffesymbol_where_line (s_whine), - ffesymbol_where_column (s_whine)); - ffebad_string (ffesymbol_text (s_whine)); - ffebad_string (bignum); - ffebad_finish (); - } -#endif - array = ffebld_constantarray_new (ffedata_storage_bt_, - ffedata_storage_kt_, ffedata_storage_size_); - accter = ffebld_new_accter (array, ffebit_new (ffe_pool_program_unit (), - ffedata_storage_size_)); - ffebld_set_info (accter, ffeinfo_new - (ffedata_storage_bt_, - ffedata_storage_kt_, - 1, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - (ffedata_basictype_ == FFEINFO_basictypeCHARACTER) - ? 1 : FFETARGET_charactersizeNONE)); - ffestorag_set_accretion (mst, accter); - ffestorag_set_accretes (mst, ffedata_storage_size_); - } - else - { - accter = ffestorag_accretion (mst); - assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter)); - array = ffebld_accter (accter); - } - - /* Put value in accretion array at desired offset. */ - - fn = ffetarget_aggregate_ptr_memcpy (ffedata_storage_bt_, ffedata_storage_kt_, - bt, kt); - - switch (ffebld_op (b)) - { - case FFEBLD_opCONTER: - ffebld_constantarray_prepare (&ptr1, &ptr2, &size, array, ffedata_storage_bt_, - ffedata_storage_kt_, offset, - ffebld_constant_ptr_to_union (ffebld_conter (b)), - bt, kt); - (*fn) (ptr1, ptr2, size); /* Does the appropriate memcpy-like - operation. */ - ffebit_count (ffebld_accter_bits (accter), - offset, FALSE, units_expected, &actual); /* How many FALSE? */ - if (units_expected != (ffetargetOffset) actual) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } - ffestorag_set_accretes (mst, - ffestorag_accretes (mst) - - actual); /* Decrement # of values - actually accreted. */ - ffebit_set (ffebld_accter_bits (accter), offset, 1, units_expected); - - /* If done accreting for this storage area, establish as initialized. */ - - if (ffestorag_accretes (mst) == 0) - { - ffestorag_set_init (mst, accter); - ffestorag_set_accretion (mst, NULL); - ffebit_kill (ffebld_accter_bits (ffestorag_init (mst))); - ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER); - ffebld_set_arrter (ffestorag_init (mst), - ffebld_accter (ffestorag_init (mst))); - ffebld_arrter_set_size (ffestorag_init (mst), - ffedata_storage_size_); - ffebld_arrter_set_pad (ffestorag_init (mst), 0); - ffecom_notify_init_storage (mst); - } - - return; - - case FFEBLD_opARRTER: - ffebld_constantarray_preparray (&ptr1, &ptr2, &size, array, ffedata_storage_bt_, - ffedata_storage_kt_, offset, ffebld_arrter (b), - bt, kt); - size *= ffebld_arrter_size (b); - units_expected *= ffebld_arrter_size (b); - (*fn) (ptr1, ptr2, size); /* Does the appropriate memcpy-like - operation. */ - ffebit_count (ffebld_accter_bits (accter), - offset, FALSE, units_expected, &actual); /* How many FALSE? */ - if (units_expected != (ffetargetOffset) actual) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } - ffestorag_set_accretes (mst, - ffestorag_accretes (mst) - - actual); /* Decrement # of values - actually accreted. */ - ffebit_set (ffebld_accter_bits (accter), offset, 1, units_expected); - - /* If done accreting for this storage area, establish as initialized. */ - - if (ffestorag_accretes (mst) == 0) - { - ffestorag_set_init (mst, accter); - ffestorag_set_accretion (mst, NULL); - ffebit_kill (ffebld_accter_bits (ffestorag_init (mst))); - ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER); - ffebld_set_arrter (ffestorag_init (mst), - ffebld_accter (ffestorag_init (mst))); - ffebld_arrter_set_size (ffestorag_init (mst), - ffedata_storage_size_); - ffebld_arrter_set_pad (ffestorag_init (mst), 0); - ffecom_notify_init_storage (mst); - } - - return; - - case FFEBLD_opACCTER: - ffebld_constantarray_preparray (&ptr1, &ptr2, &size, array, ffedata_storage_bt_, - ffedata_storage_kt_, offset, ffebld_accter (b), - bt, kt); - bits = ffebld_accter_bits (b); - source_offset = 0; - - for (;;) - { - ffetargetOffset unexp; - ffetargetOffset siz; - ffebitCount length; - bool value; - - ffebit_test (bits, source_offset, &value, &length); - if (length == 0) - break; /* Exit the loop early. */ - siz = size * length; - unexp = units_expected * length; - if (value) - { - (*fn) (ptr1, ptr2, siz); /* Does memcpy-like operation. */ - ffebit_count (ffebld_accter_bits (accter), /* How many FALSE? */ - offset, FALSE, unexp, &actual); - if (!whine && (unexp != (ffetargetOffset) actual)) - { - whine = TRUE; /* Don't whine more than once for one gather. */ - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffewhere_line_unknown (), ffewhere_column_unknown ()); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } - ffestorag_set_accretes (mst, - ffestorag_accretes (mst) - - actual); /* Decrement # of values - actually accreted. */ - ffebit_set (ffebld_accter_bits (accter), offset, 1, unexp); - } - source_offset += length; - offset += unexp; - ptr1 = ((char *) ptr1) + siz; - ptr2 = ((char *) ptr2) + siz; - } - - /* If done accreting for this storage area, establish as initialized. */ - - if (ffestorag_accretes (mst) == 0) - { - ffestorag_set_init (mst, accter); - ffestorag_set_accretion (mst, NULL); - ffebit_kill (ffebld_accter_bits (ffestorag_init (mst))); - ffebld_set_op (ffestorag_init (mst), FFEBLD_opARRTER); - ffebld_set_arrter (ffestorag_init (mst), - ffebld_accter (ffestorag_init (mst))); - ffebld_arrter_set_size (ffestorag_init (mst), - ffedata_storage_size_); - ffebld_arrter_set_pad (ffestorag_init (mst), 0); - ffecom_notify_init_storage (mst); - } - - return; - - default: - assert ("bad init op in gather_" == NULL); - return; - } -} - -/* ffedata_pop_ -- Pop an impdo stack entry - - ffedata_pop_(); */ - -static void -ffedata_pop_ () -{ - ffedataImpdo_ victim = ffedata_stack_; - - assert (victim != NULL); - - ffedata_stack_ = ffedata_stack_->outer; - - malloc_kill_ks (ffe_pool_program_unit (), victim, sizeof (*victim)); -} - -/* ffedata_push_ -- Push an impdo stack entry - - ffedata_push_(); */ - -static void -ffedata_push_ () -{ - ffedataImpdo_ baby; - - baby = malloc_new_ks (ffe_pool_program_unit (), "ffedataImpdo_", sizeof (*baby)); - - baby->outer = ffedata_stack_; - ffedata_stack_ = baby; -} - -/* ffedata_value_ -- Provide an initial value - - ffebld value; - ffelexToken t; // Points to the value. - if (ffedata_value(value,t)) - // Everything's ok - - Makes sure the value is ok, then remembers it according to the list - provided to ffedata_begin. */ - -static bool -ffedata_value_ (ffebld value, ffelexToken token) -{ - - /* If already reported an error, don't do anything. */ - - if (ffedata_reported_error_) - return FALSE; - - /* If the value is an error marker, remember we've seen one and do nothing - else. */ - - if ((value != NULL) - && (ffebld_op (value) == FFEBLD_opANY)) - { - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* If too many values (no more targets), complain. */ - - if (ffedata_symbol_ == NULL) - { - ffebad_start (FFEBAD_DATA_TOOMANY); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* If ffedata_advance_ wanted to register a complaint, do it now - that we have the token to point at instead of just the start - of the whole statement. */ - - if (ffedata_reinit_) - { - ffebad_start (FFEBAD_DATA_REINIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - -#if FFEGLOBAL_ENABLED - if (ffesymbol_common (ffedata_symbol_) != NULL) - ffeglobal_init_common (ffesymbol_common (ffedata_symbol_), token); -#endif - - /* Convert value to desired type. */ - - if (value != NULL) - { - if (ffedata_convert_cache_use_ == -1) - value = ffeexpr_convert - (value, token, NULL, ffedata_basictype_, - ffedata_kindtype_, 0, - (ffedata_basictype_ == FFEINFO_basictypeCHARACTER) - ? ffedata_charexpected_ : FFETARGET_charactersizeNONE, - FFEEXPR_contextDATA); - else /* Use the cache. */ - value = ffedata_convert_ - (value, token, NULL, ffedata_basictype_, - ffedata_kindtype_, 0, - (ffedata_basictype_ == FFEINFO_basictypeCHARACTER) - ? ffedata_charexpected_ : FFETARGET_charactersizeNONE); - } - - /* If we couldn't, bug out. */ - - if ((value != NULL) && (ffebld_op (value) == FFEBLD_opANY)) - { - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* Handle the case where initializes go to a parent's storage area. */ - - if (ffedata_storage_ != NULL) - { - ffetargetOffset offset; - ffetargetOffset units_expected; - ffebitCount actual; - ffebldConstantArray array; - ffebld accter; - ffetargetCopyfunc fn; - void *ptr1; - void *ptr2; - size_t size; - ffeinfoBasictype ign_bt; - ffeinfoKindtype ign_kt; - ffetargetAlign units; - - /* Make sure we haven't fully accreted during an array init. */ - - if (ffestorag_init (ffedata_storage_) != NULL) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* Calculate offset. */ - - offset = ffedata_offset_ * ffedata_size_ + ffedata_charoffset_; - - /* Is offset within range? If not, whine, but don't do anything else. */ - - if (offset + ffedata_charexpected_ - 1 > ffedata_symbolsize_) - { - ffebad_start (FFEBAD_DATA_RANGE); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* Now calculate offset for aggregate area. */ - - ffetarget_aggregate_info (&ign_bt, &ign_kt, &units, ffedata_basictype_, - ffedata_kindtype_); /* Find out unit size of - source datum. */ - assert (units % ffedata_storage_units_ == 0); - units_expected = ffedata_charexpected_ * units / ffedata_storage_units_; - offset *= units / ffedata_storage_units_; - offset += (ffestorag_offset (ffesymbol_storage (ffedata_symbol_)) - - ffestorag_offset (ffedata_storage_)) - / ffedata_storage_units_; - - assert (offset + units_expected - 1 <= ffedata_storage_size_); - - /* Does an accretion array exist? If not, create it. */ - - if (value != NULL) - { - if (ffestorag_accretion (ffedata_storage_) == NULL) - { -#if FFEDATA_sizeTOO_BIG_INIT_ != 0 - if (ffedata_storage_size_ >= FFEDATA_sizeTOO_BIG_INIT_) - { - char bignum[40]; - - sprintf (&bignum[0], "%ld", (long) ffedata_storage_size_); - ffebad_start (FFEBAD_TOO_BIG_INIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_string (bignum); - ffebad_finish (); - } -#endif - array = ffebld_constantarray_new - (ffedata_storage_bt_, ffedata_storage_kt_, - ffedata_storage_size_); - accter = ffebld_new_accter (array, - ffebit_new (ffe_pool_program_unit (), - ffedata_storage_size_)); - ffebld_set_info (accter, ffeinfo_new - (ffedata_storage_bt_, - ffedata_storage_kt_, - 1, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - (ffedata_basictype_ - == FFEINFO_basictypeCHARACTER) - ? 1 : FFETARGET_charactersizeNONE)); - ffestorag_set_accretion (ffedata_storage_, accter); - ffestorag_set_accretes (ffedata_storage_, ffedata_storage_size_); - } - else - { - accter = ffestorag_accretion (ffedata_storage_); - assert (ffedata_storage_size_ == (ffetargetOffset) ffebld_accter_size (accter)); - array = ffebld_accter (accter); - } - - /* Put value in accretion array at desired offset. */ - - fn = ffetarget_aggregate_ptr_memcpy - (ffedata_storage_bt_, ffedata_storage_kt_, - ffedata_basictype_, ffedata_kindtype_); - ffebld_constantarray_prepare - (&ptr1, &ptr2, &size, array, ffedata_storage_bt_, - ffedata_storage_kt_, offset, - ffebld_constant_ptr_to_union (ffebld_conter (value)), - ffedata_basictype_, ffedata_kindtype_); - (*fn) (ptr1, ptr2, size); /* Does the appropriate memcpy-like - operation. */ - ffebit_count (ffebld_accter_bits (accter), - offset, FALSE, units_expected, - &actual); /* How many FALSE? */ - if (units_expected != (ffetargetOffset) actual) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - } - ffestorag_set_accretes (ffedata_storage_, - ffestorag_accretes (ffedata_storage_) - - actual); /* Decrement # of values - actually accreted. */ - ffebit_set (ffebld_accter_bits (accter), offset, - 1, units_expected); - - /* If done accreting for this storage area, establish as - initialized. */ - - if (ffestorag_accretes (ffedata_storage_) == 0) - { - ffestorag_set_init (ffedata_storage_, accter); - ffestorag_set_accretion (ffedata_storage_, NULL); - ffebit_kill (ffebld_accter_bits - (ffestorag_init (ffedata_storage_))); - ffebld_set_op (ffestorag_init (ffedata_storage_), - FFEBLD_opARRTER); - ffebld_set_arrter - (ffestorag_init (ffedata_storage_), - ffebld_accter (ffestorag_init (ffedata_storage_))); - ffebld_arrter_set_size (ffestorag_init (ffedata_storage_), - ffedata_storage_size_); - ffebld_arrter_set_pad (ffestorag_init (ffedata_storage_), - 0); - ffecom_notify_init_storage (ffedata_storage_); - } - } - - /* If still accreting, adjust specs accordingly and return. */ - - if (++ffedata_number_ < ffedata_expected_) - { - ++ffedata_offset_; - return TRUE; - } - - return ffedata_advance_ (); - } - - /* Figure out where the value goes -- in an accretion array or directly - into the final initial-value slot for the symbol. */ - - if ((ffedata_number_ != 0) - || (ffedata_arraysize_ > 1) - || (ffedata_charnumber_ != 0) - || (ffedata_size_ > ffedata_charexpected_)) - { /* Accrete this value. */ - ffetargetOffset offset; - ffebitCount actual; - ffebldConstantArray array; - ffebld accter = NULL; - - /* Calculate offset. */ - - offset = ffedata_offset_ * ffedata_size_ + ffedata_charoffset_; - - /* Is offset within range? If not, whine, but don't do anything else. */ - - if (offset + ffedata_charexpected_ - 1 > ffedata_symbolsize_) - { - ffebad_start (FFEBAD_DATA_RANGE); - ffest_ffebad_here_current_stmt (0); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - ffedata_reported_error_ = TRUE; - return FALSE; - } - - /* Does an accretion array exist? If not, create it. */ - - if (value != NULL) - { - if (ffesymbol_accretion (ffedata_symbol_) == NULL) - { -#if FFEDATA_sizeTOO_BIG_INIT_ != 0 - if (ffedata_symbolsize_ >= FFEDATA_sizeTOO_BIG_INIT_ ) - { - char bignum[40]; - - sprintf (&bignum[0], "%ld", (long) ffedata_symbolsize_); - ffebad_start (FFEBAD_TOO_BIG_INIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_string (bignum); - ffebad_finish (); - } -#endif - array = ffebld_constantarray_new - (ffedata_basictype_, ffedata_kindtype_, - ffedata_symbolsize_); - accter = ffebld_new_accter (array, - ffebit_new (ffe_pool_program_unit (), - ffedata_symbolsize_)); - ffebld_set_info (accter, ffeinfo_new - (ffedata_basictype_, - ffedata_kindtype_, - 1, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - (ffedata_basictype_ - == FFEINFO_basictypeCHARACTER) - ? 1 : FFETARGET_charactersizeNONE)); - ffesymbol_set_accretion (ffedata_symbol_, accter); - ffesymbol_set_accretes (ffedata_symbol_, ffedata_symbolsize_); - } - else - { - accter = ffesymbol_accretion (ffedata_symbol_); - assert (ffedata_symbolsize_ - == (ffetargetOffset) ffebld_accter_size (accter)); - array = ffebld_accter (accter); - } - - /* Put value in accretion array at desired offset. */ - - ffebld_constantarray_put - (array, ffedata_basictype_, ffedata_kindtype_, - offset, ffebld_constant_union (ffebld_conter (value))); - ffebit_count (ffebld_accter_bits (accter), offset, FALSE, - ffedata_charexpected_, - &actual); /* How many FALSE? */ - if (actual != (unsigned long int) ffedata_charexpected_) - { - ffebad_start (FFEBAD_DATA_MULTIPLE); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_string (ffesymbol_text (ffedata_symbol_)); - ffebad_finish (); - } - ffesymbol_set_accretes (ffedata_symbol_, - ffesymbol_accretes (ffedata_symbol_) - - actual); /* Decrement # of values - actually accreted. */ - ffebit_set (ffebld_accter_bits (accter), offset, - 1, ffedata_charexpected_); - ffesymbol_signal_unreported (ffedata_symbol_); - } - - /* If still accreting, adjust specs accordingly and return. */ - - if (++ffedata_number_ < ffedata_expected_) - { - ++ffedata_offset_; - return TRUE; - } - - /* Else, if done accreting for this symbol, establish as initialized. */ - - if ((value != NULL) - && (ffesymbol_accretes (ffedata_symbol_) == 0)) - { - ffesymbol_set_init (ffedata_symbol_, accter); - ffesymbol_set_accretion (ffedata_symbol_, NULL); - ffebit_kill (ffebld_accter_bits (ffesymbol_init (ffedata_symbol_))); - ffebld_set_op (ffesymbol_init (ffedata_symbol_), FFEBLD_opARRTER); - ffebld_set_arrter (ffesymbol_init (ffedata_symbol_), - ffebld_accter (ffesymbol_init (ffedata_symbol_))); - ffebld_arrter_set_size (ffesymbol_init (ffedata_symbol_), - ffedata_symbolsize_); - ffebld_arrter_set_pad (ffestorag_init (ffedata_symbol_), 0); - ffecom_notify_init_symbol (ffedata_symbol_); - } - } - else if (value != NULL) - { - /* Simple, direct, one-shot assignment. */ - ffesymbol_set_init (ffedata_symbol_, value); - ffecom_notify_init_symbol (ffedata_symbol_); - } - - /* Call on advance function to get next target in list. */ - - return ffedata_advance_ (); -} diff --git a/gcc/f/data.h b/gcc/f/data.h deleted file mode 100755 index 26c4f54..0000000 --- a/gcc/f/data.h +++ /dev/null @@ -1,74 +0,0 @@ -/* data.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - data.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_data -#define _H_f_data - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lex.h" -#include "storag.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffedata_begin (ffebld list); -bool ffedata_end (bool report_errors, ffelexToken t); -void ffedata_gather (ffestorag st); -bool ffedata_value (ffetargetIntegerDefault rpt, ffebld value, - ffelexToken value_token); - -/* Define macros. */ - -#define ffedata_init_0() -#define ffedata_init_1() -#define ffedata_init_2() -#define ffedata_init_3() -#define ffedata_init_4() -#define ffedata_terminate_0() -#define ffedata_terminate_1() -#define ffedata_terminate_2() -#define ffedata_terminate_3() -#define ffedata_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/equiv.c b/gcc/f/equiv.c deleted file mode 100755 index a9de49d..0000000 --- a/gcc/f/equiv.c +++ /dev/null @@ -1,1498 +0,0 @@ -/* equiv.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Handles the EQUIVALENCE relationships in a program unit. - - Modifications: -*/ - -#define FFEEQUIV_DEBUG 0 - -/* Include files. */ - -#include "proj.h" -#include "equiv.h" -#include "bad.h" -#include "bld.h" -#include "com.h" -#include "data.h" -#include "global.h" -#include "lex.h" -#include "malloc.h" -#include "symbol.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffeequiv_list_ - { - ffeequiv first; - ffeequiv last; - }; - -/* Static objects accessed by functions in this module. */ - -static struct _ffeequiv_list_ ffeequiv_list_; - -/* Static functions (internal). */ - -static void ffeequiv_destroy_ (ffeequiv eq); -static void ffeequiv_layout_local_ (ffeequiv eq); -static bool ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s, - ffebld expr, bool subtract, - ffetargetOffset adjust, bool no_precede); - -/* Internal macros. */ - - -static void -ffeequiv_destroy_ (ffeequiv victim) -{ - ffebld list; - ffebld item; - ffebld expr; - - for (list = victim->list; list != NULL; list = ffebld_trail (list)) - { - for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) - { - ffesymbol sym; - - expr = ffebld_head (item); - sym = ffeequiv_symbol (expr); - if (sym == NULL) - continue; - if (ffesymbol_equiv (sym) != NULL) - ffesymbol_set_equiv (sym, NULL); - } - } - ffeequiv_kill (victim); -} - -/* ffeequiv_layout_local_ -- Lay out storage for local equivalenced vars - - ffeequiv eq; - ffeequiv_layout_local_(eq); - - Makes a single master ffestorag object that contains all the vars - in the equivalence, and makes subordinate ffestorag objects for the - vars with the correct offsets. - - The resulting var offsets are relative not necessarily to 0 -- the - are relative to the offset of the master area, which might be 0 or - negative, but should never be positive. */ - -static void -ffeequiv_layout_local_ (ffeequiv eq) -{ - ffestorag st; /* Equivalence storage area. */ - ffebld list; /* List of list of equivalences. */ - ffebld item; /* List of equivalences. */ - ffebld root_exp; /* Expression for root sym. */ - ffestorag root_st; /* Storage for root. */ - ffesymbol root_sym; /* Root itself. */ - ffebld rooted_exp; /* Expression for rooted sym in an eqlist. */ - ffestorag rooted_st; /* Storage for rooted. */ - ffesymbol rooted_sym; /* Rooted symbol itself. */ - ffetargetOffset eqlist_offset;/* Offset for eqlist from rooted sym. */ - ffetargetAlign alignment; - ffetargetAlign modulo; - ffetargetAlign pad; - ffetargetOffset size; - ffetargetOffset num_elements; - bool new_storage; /* Established new storage info. */ - bool need_storage; /* Have need for more storage info. */ - bool init; - - assert (eq != NULL); - - if (ffeequiv_common (eq) != NULL) - { /* Put in common due to programmer error. */ - ffeequiv_destroy_ (eq); - return; - } - - /* Find the symbol for the first valid item in the list of lists, use that - as the root symbol. Doesn't matter if it won't end up at the beginning - of the list, though. */ - -#if FFEEQUIV_DEBUG - fprintf (stderr, "Equiv1:\n"); -#endif - - root_sym = NULL; - root_exp = NULL; - - for (list = ffeequiv_list (eq); - list != NULL; - list = ffebld_trail (list)) - { /* For every equivalence list in the list of - equivs */ - for (item = ffebld_head (list); - item != NULL; - item = ffebld_trail (item)) - { /* For every equivalence item in the list */ - ffetargetOffset ign; /* Ignored. */ - - root_exp = ffebld_head (item); - root_sym = ffeequiv_symbol (root_exp); - if (root_sym == NULL) - continue; /* Ignore me. */ - - assert (ffesymbol_storage (root_sym) == NULL); /* No storage yet. */ - - if (!ffeequiv_offset_ (&ign, root_sym, root_exp, FALSE, 0, FALSE)) - { - /* We can't just eliminate this one symbol from the list - of candidates, because it might be the only one that - ties all these equivs together. So just destroy the - whole list. */ - - ffeequiv_destroy_ (eq); - return; - } - - break; /* Use first valid eqv expr for root exp/sym. */ - } - if (root_sym != NULL) - break; - } - - if (root_sym == NULL) - { - ffeequiv_destroy_ (eq); - return; - } - - -#if FFEEQUIV_DEBUG - fprintf (stderr, " Root: `%s'\n", ffesymbol_text (root_sym)); -#endif - - /* We've got work to do, so make the LOCAL storage object that'll hold all - the equivalenced vars inside it. */ - - st = ffestorag_new (ffestorag_list_master ()); - ffestorag_set_parent (st, NULL); /* Initializations happen here. */ - ffestorag_set_init (st, NULL); - ffestorag_set_accretion (st, NULL); - ffestorag_set_offset (st, 0); /* Assume equiv will be at root offset 0 for now. */ - ffestorag_set_alignment (st, 1); - ffestorag_set_modulo (st, 0); - ffestorag_set_type (st, FFESTORAG_typeLOCAL); - ffestorag_set_basictype (st, ffesymbol_basictype (root_sym)); - ffestorag_set_kindtype (st, ffesymbol_kindtype (root_sym)); - ffestorag_set_typesymbol (st, root_sym); - ffestorag_set_is_save (st, ffeequiv_is_save (eq)); - if (ffesymbol_is_save (root_sym)) - ffestorag_update_save (st); - ffestorag_set_is_init (st, ffeequiv_is_init (eq)); - if (ffesymbol_is_init (root_sym)) - ffestorag_update_init (st); - ffestorag_set_symbol (st, root_sym); /* Assume this will be the root until - we know better (used only to generate - the internal name for the aggregate area, - e.g. for debugging). */ - - /* Make the EQUIV storage object for the root symbol. */ - - if (ffesymbol_rank (root_sym) == 0) - num_elements = 1; - else - num_elements = ffebld_constant_integerdefault (ffebld_conter - (ffesymbol_arraysize (root_sym))); - ffetarget_layout (ffesymbol_text (root_sym), &alignment, &modulo, &size, - ffesymbol_basictype (root_sym), ffesymbol_kindtype (root_sym), - ffesymbol_size (root_sym), num_elements); - ffestorag_set_size (st, size); /* Set initial size of aggregate area. */ - - pad = ffetarget_align (ffestorag_ptr_to_alignment (st), - ffestorag_ptr_to_modulo (st), 0, alignment, - modulo); - assert (pad == 0); - - root_st = ffestorag_new (ffestorag_list_equivs (st)); - ffestorag_set_parent (root_st, st); /* Initializations happen there. */ - ffestorag_set_init (root_st, NULL); - ffestorag_set_accretion (root_st, NULL); - ffestorag_set_symbol (root_st, root_sym); - ffestorag_set_size (root_st, size); - ffestorag_set_offset (root_st, 0); /* Will not change; always 0 relative to itself! */ - ffestorag_set_alignment (root_st, alignment); - ffestorag_set_modulo (root_st, modulo); - ffestorag_set_type (root_st, FFESTORAG_typeEQUIV); - ffestorag_set_basictype (root_st, ffesymbol_basictype (root_sym)); - ffestorag_set_kindtype (root_st, ffesymbol_kindtype (root_sym)); - ffestorag_set_typesymbol (root_st, root_sym); - ffestorag_set_is_save (root_st, FALSE); /* Assume FALSE, then... */ - if (ffestorag_is_save (st)) /* ...update to TRUE if needed. */ - ffestorag_update_save (root_st); - ffestorag_set_is_init (root_st, FALSE); /* Assume FALSE, then... */ - if (ffestorag_is_init (st)) /* ...update to TRUE if needed. */ - ffestorag_update_init (root_st); - ffesymbol_set_storage (root_sym, root_st); - ffesymbol_signal_unreported (root_sym); - init = ffesymbol_is_init (root_sym); - - /* Now that we know the root (offset=0) symbol, revisit all the lists and - do the actual storage allocation. Keep doing this until we've gone - through them all without making any new storage objects. */ - - do - { - new_storage = FALSE; - need_storage = FALSE; - for (list = ffeequiv_list (eq); - list != NULL; - list = ffebld_trail (list)) - { /* For every equivalence list in the list of - equivs */ - /* Now find a "rooted" symbol in this list. That is, find the - first item we can that is valid and whose symbol already - has a storage area, because that means we know where it - belongs in the equivalence area and can then allocate the - rest of the items in the list accordingly. */ - - rooted_sym = NULL; - rooted_exp = NULL; - eqlist_offset = 0; - - for (item = ffebld_head (list); - item != NULL; - item = ffebld_trail (item)) - { /* For every equivalence item in the list */ - rooted_exp = ffebld_head (item); - rooted_sym = ffeequiv_symbol (rooted_exp); - if ((rooted_sym == NULL) - || ((rooted_st = ffesymbol_storage (rooted_sym)) == NULL)) - { - rooted_sym = NULL; - continue; /* Ignore me. */ - } - - need_storage = TRUE; /* Somebody is likely to need - storage. */ - -#if FFEEQUIV_DEBUG - fprintf (stderr, " Rooted: `%s' at %" ffetargetOffset_f "d\n", - ffesymbol_text (rooted_sym), - ffestorag_offset (rooted_st)); -#endif - - /* The offset of this symbol from the equiv's root symbol - is already known, and the size of this symbol is already - incorporated in the size of the equiv's aggregate area. - What we now determine is the offset of this equivalence - _list_ from the equiv's root symbol. - - For example, if we know that A is at offset 16 from the - root symbol, given EQUIVALENCE (B(24),A(2)), we're looking - at A(2), meaning that the offset for this equivalence list - is 20 (4 bytes beyond the beginning of A, assuming typical - array types, dimensions, and type info). */ - - if (!ffeequiv_offset_ (&eqlist_offset, rooted_sym, rooted_exp, FALSE, - ffestorag_offset (rooted_st), FALSE)) - - { /* Can't use this one. */ - ffesymbol_set_equiv (rooted_sym, NULL);/* Equiv area slated for - death. */ - rooted_sym = NULL; - continue; /* Something's wrong with eqv expr, try another. */ - } - -#if FFEEQUIV_DEBUG - fprintf (stderr, " Eqlist offset: %" ffetargetOffset_f "d\n", - eqlist_offset); -#endif - - break; - } - - /* If no rooted symbol, it means this list has no roots -- yet. - So, forget this list this time around, but we'll get back - to it after the outer loop iterates at least one more time, - and, ultimately, it will have a root. */ - - if (rooted_sym == NULL) - { -#if FFEEQUIV_DEBUG - fprintf (stderr, "No roots.\n"); -#endif - continue; - } - - /* We now have a rooted symbol/expr and the offset of this equivalence - list from the root symbol. The other expressions in this - list all identify an initial storage unit that must have the - same offset. */ - - for (item = ffebld_head (list); - item != NULL; - item = ffebld_trail (item)) - { /* For every equivalence item in the list */ - ffebld item_exp; /* Expression for equivalence. */ - ffestorag item_st; /* Storage for var. */ - ffesymbol item_sym; /* Var itself. */ - ffetargetOffset item_offset; /* Offset for var from root. */ - ffetargetOffset new_size; - - item_exp = ffebld_head (item); - item_sym = ffeequiv_symbol (item_exp); - if ((item_sym == NULL) - || (ffesymbol_equiv (item_sym) == NULL)) - continue; /* Ignore me. */ - - if (item_sym == rooted_sym) - continue; /* Rooted sym already set up. */ - - if (!ffeequiv_offset_ (&item_offset, item_sym, item_exp, TRUE, - eqlist_offset, FALSE)) - { - ffesymbol_set_equiv (item_sym, NULL); /* Don't bother with me anymore. */ - continue; - } - -#if FFEEQUIV_DEBUG - fprintf (stderr, " Item `%s' at %" ffetargetOffset_f "d", - ffesymbol_text (item_sym), item_offset); -#endif - - if (ffesymbol_rank (item_sym) == 0) - num_elements = 1; - else - num_elements = ffebld_constant_integerdefault (ffebld_conter - (ffesymbol_arraysize (item_sym))); - ffetarget_layout (ffesymbol_text (item_sym), &alignment, &modulo, - &size, ffesymbol_basictype (item_sym), - ffesymbol_kindtype (item_sym), ffesymbol_size (item_sym), - num_elements); - pad = ffetarget_align (ffestorag_ptr_to_alignment (st), - ffestorag_ptr_to_modulo (st), - item_offset, alignment, modulo); - if (pad != 0) - { - ffebad_start (FFEBAD_EQUIV_ALIGN); - ffebad_string (ffesymbol_text (item_sym)); - ffebad_finish (); - ffesymbol_set_equiv (item_sym, NULL); /* Don't bother with me anymore. */ - continue; - } - - /* If the variable's offset is less than the offset for the - aggregate storage area, it means it has to expand backwards - -- i.e. the new known starting point of the area precedes the - old one. This can't happen with COMMON areas (the standard, - and common sense, disallow it), but it is normal for local - EQUIVALENCE areas. - - Also handle choosing the "documented" rooted symbol for this - area here. It's the symbol at the bottom (lowest offset) - of the aggregate area, with ties going to the name that would - sort to the top of the list of ties. */ - - if (item_offset == ffestorag_offset (st)) - { - if ((item_sym != ffestorag_symbol (st)) - && (strcmp (ffesymbol_text (item_sym), - ffesymbol_text (ffestorag_symbol (st))) - < 0)) - ffestorag_set_symbol (st, item_sym); - } - else if (item_offset < ffestorag_offset (st)) - { - /* Increase size of equiv area to start for lower offset - relative to root symbol. */ - if (! ffetarget_offset_add (&new_size, - ffestorag_offset (st) - - item_offset, - ffestorag_size (st))) - ffetarget_offset_overflow (ffesymbol_text (s)); - else - ffestorag_set_size (st, new_size); - - ffestorag_set_symbol (st, item_sym); - ffestorag_set_offset (st, item_offset); - -#if FFEEQUIV_DEBUG - fprintf (stderr, " [eq offset=%" ffetargetOffset_f - "d, size=%" ffetargetOffset_f "d]", - item_offset, new_size); -#endif - } - - if ((item_st = ffesymbol_storage (item_sym)) == NULL) - { /* Create new ffestorag object, extend equiv - area. */ -#if FFEEQUIV_DEBUG - fprintf (stderr, ".\n"); -#endif - new_storage = TRUE; - item_st = ffestorag_new (ffestorag_list_equivs (st)); - ffestorag_set_parent (item_st, st); /* Initializations - happen there. */ - ffestorag_set_init (item_st, NULL); - ffestorag_set_accretion (item_st, NULL); - ffestorag_set_symbol (item_st, item_sym); - ffestorag_set_size (item_st, size); - ffestorag_set_offset (item_st, item_offset); - ffestorag_set_alignment (item_st, alignment); - ffestorag_set_modulo (item_st, modulo); - ffestorag_set_type (item_st, FFESTORAG_typeEQUIV); - ffestorag_set_basictype (item_st, ffesymbol_basictype (item_sym)); - ffestorag_set_kindtype (item_st, ffesymbol_kindtype (item_sym)); - ffestorag_set_typesymbol (item_st, item_sym); - ffestorag_set_is_save (item_st, FALSE); /* Assume FALSE... */ - if (ffestorag_is_save (st)) /* ...update TRUE */ - ffestorag_update_save (item_st); /* if needed. */ - ffestorag_set_is_init (item_st, FALSE); /* Assume FALSE... */ - if (ffestorag_is_init (st)) /* ...update TRUE */ - ffestorag_update_init (item_st); /* if needed. */ - ffesymbol_set_storage (item_sym, item_st); - ffesymbol_signal_unreported (item_sym); - if (ffesymbol_is_init (item_sym)) - init = TRUE; - - /* Determine new size of equiv area, complain if overflow. */ - - if (!ffetarget_offset_add (&size, item_offset, size) - || !ffetarget_offset_add (&size, -ffestorag_offset (st), size)) - ffetarget_offset_overflow (ffesymbol_text (s)); - else if (size > ffestorag_size (st)) - ffestorag_set_size (st, size); - ffestorag_update (st, item_sym, ffesymbol_basictype (item_sym), - ffesymbol_kindtype (item_sym)); - } - else - { -#if FFEEQUIV_DEBUG - fprintf (stderr, " (was %" ffetargetOffset_f "d).\n", - ffestorag_offset (item_st)); -#endif - /* Make sure offset agrees with known offset. */ - if (item_offset != ffestorag_offset (item_st)) - { - char io1[40]; - char io2[40]; - - sprintf (&io1[0], "%" ffetargetOffset_f "d", item_offset); - sprintf (&io2[0], "%" ffetargetOffset_f "d", ffestorag_offset (item_st)); - ffebad_start (FFEBAD_EQUIV_MISMATCH); - ffebad_string (ffesymbol_text (item_sym)); - ffebad_string (ffesymbol_text (root_sym)); - ffebad_string (io1); - ffebad_string (io2); - ffebad_finish (); - } - } - ffesymbol_set_equiv (item_sym, NULL); /* Don't bother with me anymore. */ - } /* (For every equivalence item in the list) */ - ffebld_set_head (list, NULL); /* Don't do this list again. */ - } /* (For every equivalence list in the list of - equivs) */ - } while (new_storage && need_storage); - - ffesymbol_set_equiv (root_sym, NULL); /* This one has storage now. */ - - ffeequiv_kill (eq); /* Fully processed, no longer needed. */ - - /* If the offset for this storage area is zero (it cannot be positive), - that means the alignment/modulo info is already correct. Otherwise, - the alignment info is correct, but the modulo info reflects a - zero offset, so fix it. */ - - if (ffestorag_offset (st) < 0) - { - /* Calculate the initial padding necessary to preserve - the alignment/modulo requirements for the storage area. - These requirements are themselves kept track of in the - record for the storage area as a whole, but really pertain - to offset 0 of that area, which is where the root symbol - was originally placed. - - The goal here is to have the offset and size for the area - faithfully reflect the area itself, not extra requirements - like alignment. So to meet the alignment requirements, - the modulo for the area should be set as if the area had an - alignment requirement of alignment/0 and was aligned/padded - downward to meet the alignment requirements of the area at - offset zero, the amount of padding needed being the desired - value for the modulo of the area. */ - - alignment = ffestorag_alignment (st); - modulo = ffestorag_modulo (st); - - /* Since we want to move the whole area *down* (lower memory - addresses) as required by the alignment/modulo paid, negate - the offset to ffetarget_align, which assumes aligning *up* - is desired. */ - pad = ffetarget_align (&alignment, &modulo, - - ffestorag_offset (st), - alignment, 0); - ffestorag_set_modulo (st, pad); - } - - if (init) - ffedata_gather (st); /* Gather subordinate inits into one init. */ -} - -/* ffeequiv_offset_ -- Determine offset from start of symbol - - ffetargetOffset offset; - ffesymbol s; // Symbol for error reporting. - ffebld expr; // opSUBSTR, opARRAYREF, opSYMTER, opANY. - bool subtract; // FALSE means add to adjust, TRUE means subtract from it. - ffetargetOffset adjust; // Helps keep answer in pos range (unsigned). - if (!ffeequiv_offset_(&offset,s,expr,subtract,adjust)) - // error doing the calculation, message already printed - - Returns the offset represented by the SUBSTR, ARRAYREF, or SUBSTR/ARRAYREF - combination added-to/subtracted-from the adjustment specified. If there - is an error of some kind, returns FALSE, else returns TRUE. Note that - only the first storage unit specified is considered; A(1:1) and A(1:2000) - have the same first storage unit and so return the same offset. */ - -static bool -ffeequiv_offset_ (ffetargetOffset *offset, ffesymbol s UNUSED, - ffebld expr, bool subtract, ffetargetOffset adjust, - bool no_precede) -{ - ffetargetIntegerDefault value = 0; - ffetargetOffset cval; /* Converted value. */ - ffesymbol sym; - - if (expr == NULL) - return FALSE; - -again: /* :::::::::::::::::::: */ - - switch (ffebld_op (expr)) - { - case FFEBLD_opANY: - return FALSE; - - case FFEBLD_opSYMTER: - { - ffetargetOffset size; /* Size of a single unit. */ - ffetargetAlign a; /* Ignored. */ - ffetargetAlign m; /* Ignored. */ - - sym = ffebld_symter (expr); - if (ffesymbol_basictype (sym) == FFEINFO_basictypeANY) - return FALSE; - - ffetarget_layout (ffesymbol_text (sym), &a, &m, &size, - ffesymbol_basictype (sym), - ffesymbol_kindtype (sym), 1, 1); - - if (value < 0) - { /* Really invalid, as in A(-2:5), but in case - it's wanted.... */ - if (!ffetarget_offset (&cval, -value)) - return FALSE; - - if (!ffetarget_offset_multiply (&cval, cval, size)) - return FALSE; - - if (subtract) - return ffetarget_offset_add (offset, cval, adjust); - - if (no_precede && (cval > adjust)) - { - neg: /* :::::::::::::::::::: */ - ffebad_start (FFEBAD_COMMON_NEG); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - return FALSE; - } - return ffetarget_offset_add (offset, -cval, adjust); - } - - if (!ffetarget_offset (&cval, value)) - return FALSE; - - if (!ffetarget_offset_multiply (&cval, cval, size)) - return FALSE; - - if (!subtract) - return ffetarget_offset_add (offset, cval, adjust); - - if (no_precede && (cval > adjust)) - goto neg; /* :::::::::::::::::::: */ - - return ffetarget_offset_add (offset, -cval, adjust); - } - - case FFEBLD_opARRAYREF: - { - ffebld symexp = ffebld_left (expr); - ffebld subscripts = ffebld_right (expr); - ffebld dims; - ffetargetIntegerDefault width; - ffetargetIntegerDefault arrayval; - ffetargetIntegerDefault lowbound; - ffetargetIntegerDefault highbound; - ffebld subscript; - ffebld dim; - ffebld low; - ffebld high; - int rank = 0; - - if (ffebld_op (symexp) != FFEBLD_opSYMTER) - return FALSE; - - sym = ffebld_symter (symexp); - if (ffesymbol_basictype (sym) == FFEINFO_basictypeANY) - return FALSE; - - if (ffesymbol_size (sym) == FFETARGET_charactersizeNONE) - width = 1; - else - width = ffesymbol_size (sym); - dims = ffesymbol_dims (sym); - - while (subscripts != NULL) - { - ++rank; - if (dims == NULL) - { - ffebad_start (FFEBAD_EQUIV_MANY); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - return FALSE; - } - - subscript = ffebld_head (subscripts); - dim = ffebld_head (dims); - - if (ffebld_op (subscript) == FFEBLD_opANY) - return FALSE; - - assert (ffebld_op (subscript) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (subscript)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (subscript)) - == FFEINFO_kindtypeINTEGERDEFAULT); - arrayval = ffebld_constant_integerdefault (ffebld_conter - (subscript)); - - if (ffebld_op (dim) == FFEBLD_opANY) - return FALSE; - - assert (ffebld_op (dim) == FFEBLD_opBOUNDS); - low = ffebld_left (dim); - high = ffebld_right (dim); - - if (low == NULL) - lowbound = 1; - else - { - if (ffebld_op (low) == FFEBLD_opANY) - return FALSE; - - assert (ffebld_op (low) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (low)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (low)) - == FFEINFO_kindtypeINTEGERDEFAULT); - lowbound - = ffebld_constant_integerdefault (ffebld_conter (low)); - } - - if (ffebld_op (high) == FFEBLD_opANY) - return FALSE; - - assert (ffebld_op (high) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (high)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (high)) - == FFEINFO_kindtypeINTEGER1); - highbound - = ffebld_constant_integerdefault (ffebld_conter (high)); - - if ((arrayval < lowbound) || (arrayval > highbound)) - { - char rankstr[10]; - - sprintf (rankstr, "%d", rank); - ffebad_start (FFEBAD_EQUIV_SUBSCRIPT); - ffebad_string (ffesymbol_text (sym)); - ffebad_string (rankstr); - ffebad_finish (); - } - - subscripts = ffebld_trail (subscripts); - dims = ffebld_trail (dims); - - value += width * (arrayval - lowbound); - if (subscripts != NULL) - width *= highbound - lowbound + 1; - } - - if (dims != NULL) - { - ffebad_start (FFEBAD_EQUIV_FEW); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - return FALSE; - } - - expr = symexp; - } - goto again; /* :::::::::::::::::::: */ - - case FFEBLD_opSUBSTR: - { - ffebld begin = ffebld_head (ffebld_right (expr)); - - expr = ffebld_left (expr); - if (ffebld_op (expr) == FFEBLD_opANY) - return FALSE; - if (ffebld_op (expr) == FFEBLD_opARRAYREF) - sym = ffebld_symter (ffebld_left (expr)); - else if (ffebld_op (expr) == FFEBLD_opSYMTER) - sym = ffebld_symter (expr); - else - sym = NULL; - - if ((sym != NULL) - && (ffesymbol_basictype (sym) == FFEINFO_basictypeANY)) - return FALSE; - - if (begin == NULL) - value = 0; - else - { - if (ffebld_op (begin) == FFEBLD_opANY) - return FALSE; - assert (ffebld_op (begin) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (begin)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (begin)) - == FFEINFO_kindtypeINTEGERDEFAULT); - - value = ffebld_constant_integerdefault (ffebld_conter (begin)); - - if ((value < 1) - || ((sym != NULL) - && (value > ffesymbol_size (sym)))) - { - ffebad_start (FFEBAD_EQUIV_RANGE); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - } - - --value; - } - if ((sym != NULL) - && (ffesymbol_basictype (sym) != FFEINFO_basictypeCHARACTER)) - { - ffebad_start (FFEBAD_EQUIV_SUBSTR); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - value = 0; - } - } - goto again; /* :::::::::::::::::::: */ - - default: - assert ("bad op" == NULL); - return FALSE; - } - -} - -/* ffeequiv_add -- Add list of equivalences to list of lists for eq object - - ffeequiv eq; - ffebld list; - ffelexToken t; // points to first item in equivalence list - ffeequiv_add(eq,list,t); - - Check the list to make sure only one common symbol is involved (even - if multiple times) and agrees with the common symbol for the equivalence - object (or it has no common symbol until now). Prepend (or append, it - doesn't matter) the list to the list of lists for the equivalence object. - Otherwise report an error and return. */ - -void -ffeequiv_add (ffeequiv eq, ffebld list, ffelexToken t) -{ - ffebld item; - ffesymbol symbol; - ffesymbol common = ffeequiv_common (eq); - - for (item = list; item != NULL; item = ffebld_trail (item)) - { - symbol = ffeequiv_symbol (ffebld_head (item)); - - if (ffesymbol_common (symbol) != NULL) /* Is symbol known in COMMON yet? */ - { - if (common == NULL) - common = ffesymbol_common (symbol); - else if (common != ffesymbol_common (symbol)) - { - /* Yes, and symbol disagrees with others on the COMMON area. */ - ffebad_start (FFEBAD_EQUIV_COMMON); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffesymbol_text (common)); - ffebad_string (ffesymbol_text (ffesymbol_common (symbol))); - ffebad_finish (); - return; - } - } - } - - if ((common != NULL) - && (ffeequiv_common (eq) == NULL)) /* Is COMMON involved already? */ - ffeequiv_set_common (eq, common); /* No, but it is now. */ - - for (item = list; item != NULL; item = ffebld_trail (item)) - { - symbol = ffeequiv_symbol (ffebld_head (item)); - - if (ffesymbol_equiv (symbol) == NULL) - ffesymbol_set_equiv (symbol, eq); - else - assert (ffesymbol_equiv (symbol) == eq); - - if (ffesymbol_common (symbol) == NULL) /* Is symbol in a COMMON - area? */ - { /* No (at least not yet). */ - if (ffesymbol_is_save (symbol)) - ffeequiv_update_save (eq); /* EQUIVALENCE has >=1 SAVEd entity. */ - if (ffesymbol_is_init (symbol)) - ffeequiv_update_init (eq); /* EQUIVALENCE has >=1 init'd entity. */ - continue; /* Nothing more to do here. */ - } - -#if FFEGLOBAL_ENABLED - if (ffesymbol_is_init (symbol)) - ffeglobal_init_common (ffesymbol_common (symbol), t); -#endif - - if (ffesymbol_is_save (ffesymbol_common (symbol))) - ffeequiv_update_save (eq); /* EQUIVALENCE is in a SAVEd COMMON block. */ - if (ffesymbol_is_init (ffesymbol_common (symbol))) - ffeequiv_update_init (eq); /* EQUIVALENCE is in a init'd COMMON block. */ - } - - ffeequiv_set_list (eq, ffebld_new_item (list, ffeequiv_list (eq))); -} - -/* ffeequiv_dump -- Dump info on equivalence object - - ffeequiv eq; - ffeequiv_dump(eq); */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffeequiv_dump (ffeequiv eq) -{ - if (ffeequiv_common (eq) != NULL) - fprintf (dmpout, "(common %s) ", ffesymbol_text (ffeequiv_common (eq))); - ffebld_dump (ffeequiv_list (eq)); -} -#endif - -/* ffeequiv_exec_transition -- Do the hard work on all the equivalence objects - - ffeequiv_exec_transition(); */ - -void -ffeequiv_exec_transition () -{ - while (ffeequiv_list_.first != (ffeequiv) &ffeequiv_list_.first) - ffeequiv_layout_local_ (ffeequiv_list_.first); -} - -/* ffeequiv_init_2 -- Initialize for new program unit - - ffeequiv_init_2(); - - Initializes the list of equivalences. */ - -void -ffeequiv_init_2 () -{ - ffeequiv_list_.first = (ffeequiv) &ffeequiv_list_.first; - ffeequiv_list_.last = (ffeequiv) &ffeequiv_list_.first; -} - -/* ffeequiv_kill -- Kill equivalence object after removing from list - - ffeequiv eq; - ffeequiv_kill(eq); - - Removes equivalence object from master list, then kills it. */ - -void -ffeequiv_kill (ffeequiv victim) -{ - victim->next->previous = victim->previous; - victim->previous->next = victim->next; - if (ffe_is_do_internal_checks ()) - { - ffebld list; - ffebld item; - ffebld expr; - - /* Assert that nobody our victim points to still points to it. */ - - assert ((victim->common == NULL) - || (ffesymbol_equiv (victim->common) == NULL)); - - for (list = victim->list; list != NULL; list = ffebld_trail (list)) - { - for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) - { - ffesymbol sym; - - expr = ffebld_head (item); - sym = ffeequiv_symbol (expr); - if (sym == NULL) - continue; - assert (ffesymbol_equiv (sym) != victim); - } - } - } - malloc_kill_ks (ffe_pool_program_unit (), victim, sizeof (*victim)); -} - -/* ffeequiv_layout_cblock -- Lay out storage for common area - - ffestorag st; - if (ffeequiv_layout_cblock(st)) - // at least one equiv'd symbol has init/accretion expr. - - Now that the explicitly COMMONed variables in the common area (whose - ffestorag object is passed) have been laid out, lay out the storage - for all variables equivalenced into the area by making subordinate - ffestorag objects for them. */ - -bool -ffeequiv_layout_cblock (ffestorag st) -{ - ffesymbol s = ffestorag_symbol (st); /* CBLOCK symbol. */ - ffebld list; /* List of explicit common vars, in order, in - s. */ - ffebld item; /* List of list of equivalences in a given - explicit common var. */ - ffebld root; /* Expression for (1st) explicit common var - in list of eqs. */ - ffestorag rst; /* Storage for root. */ - ffetargetOffset root_offset; /* Offset for root into common area. */ - ffesymbol sr; /* Root itself. */ - ffeequiv seq; /* Its equivalence object, if any. */ - ffebld var; /* Expression for equivalence. */ - ffestorag vst; /* Storage for var. */ - ffetargetOffset var_offset; /* Offset for var into common area. */ - ffesymbol sv; /* Var itself. */ - ffebld altroot; /* Alternate root. */ - ffesymbol altrootsym; /* Alternate root symbol. */ - ffetargetAlign alignment; - ffetargetAlign modulo; - ffetargetAlign pad; - ffetargetOffset size; - ffetargetOffset num_elements; - bool new_storage; /* Established new storage info. */ - bool need_storage; /* Have need for more storage info. */ - bool ok; - bool init = FALSE; - - assert (st != NULL); - assert (ffestorag_type (st) == FFESTORAG_typeCBLOCK); - assert (ffesymbol_kind (ffestorag_symbol (st)) == FFEINFO_kindCOMMON); - - for (list = ffesymbol_commonlist (ffestorag_symbol (st)); - list != NULL; - list = ffebld_trail (list)) - { /* For every variable in the common area */ - assert (ffebld_op (ffebld_head (list)) == FFEBLD_opSYMTER); - sr = ffebld_symter (ffebld_head (list)); - if ((seq = ffesymbol_equiv (sr)) == NULL) - continue; /* No equivalences to process. */ - rst = ffesymbol_storage (sr); - if (rst == NULL) - { - assert (ffesymbol_kind (sr) == FFEINFO_kindANY); - continue; - } - ffesymbol_set_equiv (sr, NULL); /* Cancel ref to equiv obj. */ - do - { - new_storage = FALSE; - need_storage = FALSE; - for (item = ffeequiv_list (seq); /* Get list of equivs. */ - item != NULL; - item = ffebld_trail (item)) - { /* For every eqv list in the list of equivs - for the variable */ - altroot = NULL; - altrootsym = NULL; - for (root = ffebld_head (item); - root != NULL; - root = ffebld_trail (root)) - { /* For every equivalence item in the list */ - sv = ffeequiv_symbol (ffebld_head (root)); - if (sv == sr) - break; /* Found first mention of "rooted" symbol. */ - if (ffesymbol_storage (sv) != NULL) - { - altroot = root; /* If no mention, use this guy - instead. */ - altrootsym = sv; - } - } - if (root != NULL) - { - root = ffebld_head (root); /* Lose its opITEM. */ - ok = ffeequiv_offset_ (&root_offset, sr, root, FALSE, - ffestorag_offset (rst), TRUE); - /* Equiv point prior to start of common area? */ - } - else if (altroot != NULL) - { - /* Equiv point prior to start of common area? */ - root = ffebld_head (altroot); - ok = ffeequiv_offset_ (&root_offset, altrootsym, root, - FALSE, - ffestorag_offset (ffesymbol_storage (altrootsym)), - TRUE); - ffesymbol_set_equiv (altrootsym, NULL); - } - else - /* No rooted symbol in list of equivalences! */ - { /* Assume this was due to opANY and ignore - this list for now. */ - need_storage = TRUE; - continue; - } - - /* We now know the root symbol and the operating offset of that - root into the common area. The other expressions in the - list all identify an initial storage unit that must have the - same offset. */ - - for (var = ffebld_head (item); - var != NULL; - var = ffebld_trail (var)) - { /* For every equivalence item in the list */ - if (ffebld_head (var) == root) - continue; /* Except root, of course. */ - sv = ffeequiv_symbol (ffebld_head (var)); - if (sv == NULL) - continue; /* Except erroneous stuff (opANY). */ - ffesymbol_set_equiv (sv, NULL); /* Don't need this ref - anymore. */ - if (!ok - || !ffeequiv_offset_ (&var_offset, sv, - ffebld_head (var), TRUE, - root_offset, TRUE)) - continue; /* Can't do negative offset wrt COMMON. */ - - if (ffesymbol_rank (sv) == 0) - num_elements = 1; - else - num_elements = ffebld_constant_integerdefault - (ffebld_conter (ffesymbol_arraysize (sv))); - ffetarget_layout (ffesymbol_text (sv), &alignment, - &modulo, &size, - ffesymbol_basictype (sv), - ffesymbol_kindtype (sv), - ffesymbol_size (sv), num_elements); - pad = ffetarget_align (ffestorag_ptr_to_alignment (st), - ffestorag_ptr_to_modulo (st), - var_offset, alignment, modulo); - if (pad != 0) - { - ffebad_start (FFEBAD_EQUIV_ALIGN); - ffebad_string (ffesymbol_text (sv)); - ffebad_finish (); - continue; - } - - if ((vst = ffesymbol_storage (sv)) == NULL) - { /* Create new ffestorag object, extend - cblock. */ - new_storage = TRUE; - vst = ffestorag_new (ffestorag_list_equivs (st)); - ffestorag_set_parent (vst, st); /* Initializations - happen there. */ - ffestorag_set_init (vst, NULL); - ffestorag_set_accretion (vst, NULL); - ffestorag_set_symbol (vst, sv); - ffestorag_set_size (vst, size); - ffestorag_set_offset (vst, var_offset); - ffestorag_set_alignment (vst, alignment); - ffestorag_set_modulo (vst, modulo); - ffestorag_set_type (vst, FFESTORAG_typeEQUIV); - ffestorag_set_basictype (vst, ffesymbol_basictype (sv)); - ffestorag_set_kindtype (vst, ffesymbol_kindtype (sv)); - ffestorag_set_typesymbol (vst, sv); - ffestorag_set_is_save (vst, FALSE); /* Assume FALSE... */ - if (ffestorag_is_save (st)) /* ...update TRUE */ - ffestorag_update_save (vst); /* if needed. */ - ffestorag_set_is_init (vst, FALSE); /* Assume FALSE... */ - if (ffestorag_is_init (st)) /* ...update TRUE */ - ffestorag_update_init (vst); /* if needed. */ - if (!ffetarget_offset_add (&size, var_offset, size)) - /* Find one size of common block, complain if - overflow. */ - ffetarget_offset_overflow (ffesymbol_text (s)); - else if (size > ffestorag_size (st)) - /* Extend common. */ - ffestorag_set_size (st, size); - ffesymbol_set_storage (sv, vst); - ffesymbol_set_common (sv, s); - ffesymbol_signal_unreported (sv); - ffestorag_update (st, sv, ffesymbol_basictype (sv), - ffesymbol_kindtype (sv)); - if (ffesymbol_is_init (sv)) - init = TRUE; - } - else - { - /* Make sure offset agrees with known offset. */ - if (var_offset != ffestorag_offset (vst)) - { - char io1[40]; - char io2[40]; - - sprintf (&io1[0], "%" ffetargetOffset_f "d", var_offset); - sprintf (&io2[0], "%" ffetargetOffset_f "d", ffestorag_offset (vst)); - ffebad_start (FFEBAD_EQUIV_MISMATCH); - ffebad_string (ffesymbol_text (sv)); - ffebad_string (ffesymbol_text (s)); - ffebad_string (io1); - ffebad_string (io2); - ffebad_finish (); - } - } - } /* (For every equivalence item in the list) */ - } /* (For every eqv list in the list of equivs - for the variable) */ - } - while (new_storage && need_storage); - - ffeequiv_kill (seq); /* Kill equiv obj. */ - } /* (For every variable in the common area) */ - - return init; -} - -/* ffeequiv_merge -- Merge two equivalence objects, return the merged result - - ffeequiv eq1; - ffeequiv eq2; - ffelexToken t; // points to current equivalence item forcing the merge. - eq1 = ffeequiv_merge(eq1,eq2,t); - - If the two equivalence objects can be merged, they are, all the - ffesymbols in their lists of lists are adjusted to point to the merged - equivalence object, and the merged object is returned. - - Otherwise, the two equivalence objects have different non-NULL common - symbols, so the merge cannot take place. An error message is issued and - NULL is returned. */ - -ffeequiv -ffeequiv_merge (ffeequiv eq1, ffeequiv eq2, ffelexToken t) -{ - ffebld list; - ffebld eqs; - ffesymbol symbol; - ffebld last = NULL; - - /* If both equivalence objects point to different common-based symbols, - complain. Of course, one or both might have NULL common symbols now, - and get COMMONed later, but the COMMON statement handler checks for - this. */ - - if ((ffeequiv_common (eq1) != NULL) && (ffeequiv_common (eq2) != NULL) - && (ffeequiv_common (eq1) != ffeequiv_common (eq2))) - { - ffebad_start (FFEBAD_EQUIV_COMMON); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffesymbol_text (ffeequiv_common (eq1))); - ffebad_string (ffesymbol_text (ffeequiv_common (eq2))); - ffebad_finish (); - return NULL; - } - - /* Make eq1 the new, merged object (arbitrarily). */ - - if (ffeequiv_common (eq1) == NULL) - ffeequiv_set_common (eq1, ffeequiv_common (eq2)); - - /* If the victim object has any init'ed entities, so does the new object. */ - - if (eq2->is_init) - eq1->is_init = TRUE; - -#if FFEGLOBAL_ENABLED - if (eq1->is_init && (ffeequiv_common (eq1) != NULL)) - ffeglobal_init_common (ffeequiv_common (eq1), t); -#endif - - /* If the victim object has any SAVEd entities, then the new object has - some. */ - - if (ffeequiv_is_save (eq2)) - ffeequiv_update_save (eq1); - - /* If the victim object has any init'd entities, then the new object has - some. */ - - if (ffeequiv_is_init (eq2)) - ffeequiv_update_init (eq1); - - /* Adjust all the symbols in the list of lists of equivalences for the - victim equivalence object so they point to the new merged object - instead. */ - - for (list = ffeequiv_list (eq2); list != NULL; list = ffebld_trail (list)) - { - for (eqs = ffebld_head (list); eqs != NULL; eqs = ffebld_trail (eqs)) - { - symbol = ffeequiv_symbol (ffebld_head (eqs)); - if (ffesymbol_equiv (symbol) == eq2) - ffesymbol_set_equiv (symbol, eq1); - else - assert (ffesymbol_equiv (symbol) == eq1); /* Can see a sym > once. */ - } - - /* For convenience, remember where the last ITEM in the outer list is. */ - - if (ffebld_trail (list) == NULL) - { - last = list; - break; - } - } - - /* Append the list of lists in the new, merged object to the list of lists - in the victim object, then use the new combined list in the new merged - object. */ - - ffebld_set_trail (last, ffeequiv_list (eq1)); - ffeequiv_set_list (eq1, ffeequiv_list (eq2)); - - /* Unlink and kill the victim object. */ - - ffeequiv_kill (eq2); - - return eq1; /* Return the new merged object. */ -} - -/* ffeequiv_new -- Create new equivalence object, put in list - - ffeequiv eq; - eq = ffeequiv_new(); - - Creates a new equivalence object and adds it to the list of equivalence - objects. */ - -ffeequiv -ffeequiv_new () -{ - ffeequiv eq; - - eq = malloc_new_ks (ffe_pool_program_unit (), "ffeequiv", sizeof (*eq)); - eq->next = (ffeequiv) &ffeequiv_list_.first; - eq->previous = ffeequiv_list_.last; - ffeequiv_set_common (eq, NULL); /* No COMMON area yet. */ - ffeequiv_set_list (eq, NULL); /* No list of lists of equivalences yet. */ - ffeequiv_set_is_save (eq, FALSE); - ffeequiv_set_is_init (eq, FALSE); - eq->next->previous = eq; - eq->previous->next = eq; - - return eq; -} - -/* ffeequiv_symbol -- Return symbol for equivalence expression - - ffesymbol symbol; - ffebld expr; - symbol = ffeequiv_symbol(expr); - - Finds the terminal SYMTER in an equivalence expression and returns the - ffesymbol for it. */ - -ffesymbol -ffeequiv_symbol (ffebld expr) -{ - assert (expr != NULL); - -again: /* :::::::::::::::::::: */ - - switch (ffebld_op (expr)) - { - case FFEBLD_opARRAYREF: - case FFEBLD_opSUBSTR: - expr = ffebld_left (expr); - goto again; /* :::::::::::::::::::: */ - - case FFEBLD_opSYMTER: - return ffebld_symter (expr); - - case FFEBLD_opANY: - return NULL; - - default: - assert ("bad eq expr" == NULL); - return NULL; - } -} - -/* ffeequiv_update_init -- Update the INIT flag for the area to TRUE - - ffeequiv eq; - ffeequiv_update_init(eq); - - If the INIT flag for the <eq> object is already set, return. Else, - set it TRUE and call ffe*_update_init for all objects contained in - this one. */ - -void -ffeequiv_update_init (ffeequiv eq) -{ - ffebld list; /* Current list in list of lists. */ - ffebld item; /* Current item in current list. */ - ffebld expr; /* Expression in head of current item. */ - - if (eq->is_init) - return; - - eq->is_init = TRUE; - - if ((eq->common != NULL) - && !ffesymbol_is_init (eq->common)) - ffesymbol_update_init (eq->common); /* Shouldn't be needed. */ - - for (list = eq->list; list != NULL; list = ffebld_trail (list)) - { - for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) - { - expr = ffebld_head (item); - - again: /* :::::::::::::::::::: */ - - switch (ffebld_op (expr)) - { - case FFEBLD_opANY: - break; - - case FFEBLD_opSYMTER: - if (!ffesymbol_is_init (ffebld_symter (expr))) - ffesymbol_update_init (ffebld_symter (expr)); - break; - - case FFEBLD_opARRAYREF: - expr = ffebld_left (expr); - goto again; /* :::::::::::::::::::: */ - - case FFEBLD_opSUBSTR: - expr = ffebld_left (expr); - goto again; /* :::::::::::::::::::: */ - - default: - assert ("bad op for ffeequiv_update_init" == NULL); - break; - } - } - } -} - -/* ffeequiv_update_save -- Update the SAVE flag for the area to TRUE - - ffeequiv eq; - ffeequiv_update_save(eq); - - If the SAVE flag for the <eq> object is already set, return. Else, - set it TRUE and call ffe*_update_save for all objects contained in - this one. */ - -void -ffeequiv_update_save (ffeequiv eq) -{ - ffebld list; /* Current list in list of lists. */ - ffebld item; /* Current item in current list. */ - ffebld expr; /* Expression in head of current item. */ - - if (eq->is_save) - return; - - eq->is_save = TRUE; - - if ((eq->common != NULL) - && !ffesymbol_is_save (eq->common)) - ffesymbol_update_save (eq->common); /* Shouldn't be needed. */ - - for (list = eq->list; list != NULL; list = ffebld_trail (list)) - { - for (item = ffebld_head (list); item != NULL; item = ffebld_trail (item)) - { - expr = ffebld_head (item); - - again: /* :::::::::::::::::::: */ - - switch (ffebld_op (expr)) - { - case FFEBLD_opANY: - break; - - case FFEBLD_opSYMTER: - if (!ffesymbol_is_save (ffebld_symter (expr))) - ffesymbol_update_save (ffebld_symter (expr)); - break; - - case FFEBLD_opARRAYREF: - expr = ffebld_left (expr); - goto again; /* :::::::::::::::::::: */ - - case FFEBLD_opSUBSTR: - expr = ffebld_left (expr); - goto again; /* :::::::::::::::::::: */ - - default: - assert ("bad op for ffeequiv_update_save" == NULL); - break; - } - } - } -} diff --git a/gcc/f/equiv.h b/gcc/f/equiv.h deleted file mode 100755 index daf0cee..0000000 --- a/gcc/f/equiv.h +++ /dev/null @@ -1,103 +0,0 @@ -/* equiv.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - equiv.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_equiv -#define _H_f_equiv - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffeequiv_ *ffeequiv; - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lex.h" -#include "storag.h" -#include "symbol.h" - -/* Structure definitions. */ - -struct _ffeequiv_ - { - ffeequiv next; - ffeequiv previous; - ffesymbol common; /* Common area for this equiv, if any. */ - ffebld list; /* List of lists of equiv exprs. */ - bool is_save; /* Any SAVEd members? */ - bool is_init; /* Any initialized members? */ - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffeequiv_add (ffeequiv eq, ffebld list, ffelexToken t); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffeequiv_dump (ffeequiv eq); -#endif -void ffeequiv_exec_transition (void); -void ffeequiv_init_2 (void); -void ffeequiv_kill (ffeequiv victim); -bool ffeequiv_layout_cblock (ffestorag st); -ffeequiv ffeequiv_merge (ffeequiv eq1, ffeequiv eq2, ffelexToken t); -ffeequiv ffeequiv_new (void); -ffesymbol ffeequiv_symbol (ffebld expr); -void ffeequiv_update_init (ffeequiv eq); -void ffeequiv_update_save (ffeequiv eq); - -/* Define macros. */ - -#define ffeequiv_common(e) ((e)->common) -#define ffeequiv_init_0() -#define ffeequiv_init_1() -#define ffeequiv_init_3() -#define ffeequiv_init_4() -#define ffeequiv_is_init(e) ((e)->is_init) -#define ffeequiv_is_save(e) ((e)->is_save) -#define ffeequiv_list(e) ((e)->list) -#define ffeequiv_next(e) ((e)->next) -#define ffeequiv_previous(e) ((e)->previous) -#define ffeequiv_set_common(e,c) ((e)->common = (c)) -#define ffeequiv_set_init(e,i) ((e)->init = (i)) -#define ffeequiv_set_is_init(e,in) ((e)->is_init = (in)) -#define ffeequiv_set_is_save(e,sa) ((e)->is_save = (sa)) -#define ffeequiv_set_list(e,l) ((e)->list = (l)) -#define ffeequiv_terminate_0() -#define ffeequiv_terminate_1() -#define ffeequiv_terminate_2() -#define ffeequiv_terminate_3() -#define ffeequiv_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/expr.c b/gcc/f/expr.c deleted file mode 100755 index 7e7bf86..0000000 --- a/gcc/f/expr.c +++ /dev/null @@ -1,19304 +0,0 @@ -/* expr.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None. - - Description: - Handles syntactic and semantic analysis of Fortran expressions. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "expr.h" -#include "bad.h" -#include "bld.h" -#include "com.h" -#include "global.h" -#include "implic.h" -#include "intrin.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#include "st.h" -#include "symbol.h" -#include "str.h" -#include "target.h" -#include "where.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFEEXPR_exprtypeUNKNOWN_, - FFEEXPR_exprtypeOPERAND_, - FFEEXPR_exprtypeUNARY_, - FFEEXPR_exprtypeBINARY_, - FFEEXPR_exprtype_ - } ffeexprExprtype_; - -typedef enum - { - FFEEXPR_operatorPOWER_, - FFEEXPR_operatorMULTIPLY_, - FFEEXPR_operatorDIVIDE_, - FFEEXPR_operatorADD_, - FFEEXPR_operatorSUBTRACT_, - FFEEXPR_operatorCONCATENATE_, - FFEEXPR_operatorLT_, - FFEEXPR_operatorLE_, - FFEEXPR_operatorEQ_, - FFEEXPR_operatorNE_, - FFEEXPR_operatorGT_, - FFEEXPR_operatorGE_, - FFEEXPR_operatorNOT_, - FFEEXPR_operatorAND_, - FFEEXPR_operatorOR_, - FFEEXPR_operatorXOR_, - FFEEXPR_operatorEQV_, - FFEEXPR_operatorNEQV_, - FFEEXPR_operator_ - } ffeexprOperator_; - -typedef enum - { - FFEEXPR_operatorprecedenceHIGHEST_ = 1, - FFEEXPR_operatorprecedencePOWER_ = 1, - FFEEXPR_operatorprecedenceMULTIPLY_ = 2, - FFEEXPR_operatorprecedenceDIVIDE_ = 2, - FFEEXPR_operatorprecedenceADD_ = 3, - FFEEXPR_operatorprecedenceSUBTRACT_ = 3, - FFEEXPR_operatorprecedenceLOWARITH_ = 3, - FFEEXPR_operatorprecedenceCONCATENATE_ = 3, - FFEEXPR_operatorprecedenceLT_ = 4, - FFEEXPR_operatorprecedenceLE_ = 4, - FFEEXPR_operatorprecedenceEQ_ = 4, - FFEEXPR_operatorprecedenceNE_ = 4, - FFEEXPR_operatorprecedenceGT_ = 4, - FFEEXPR_operatorprecedenceGE_ = 4, - FFEEXPR_operatorprecedenceNOT_ = 5, - FFEEXPR_operatorprecedenceAND_ = 6, - FFEEXPR_operatorprecedenceOR_ = 7, - FFEEXPR_operatorprecedenceXOR_ = 8, - FFEEXPR_operatorprecedenceEQV_ = 8, - FFEEXPR_operatorprecedenceNEQV_ = 8, - FFEEXPR_operatorprecedenceLOWEST_ = 8, - FFEEXPR_operatorprecedence_ - } ffeexprOperatorPrecedence_; - -#define FFEEXPR_operatorassociativityL2R_ TRUE -#define FFEEXPR_operatorassociativityR2L_ FALSE -#define FFEEXPR_operatorassociativityPOWER_ FFEEXPR_operatorassociativityR2L_ -#define FFEEXPR_operatorassociativityMULTIPLY_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityDIVIDE_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityADD_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativitySUBTRACT_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityCONCATENATE_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityLT_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityLE_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityEQ_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityNE_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityGT_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityGE_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityNOT_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityAND_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityOR_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityXOR_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityEQV_ FFEEXPR_operatorassociativityL2R_ -#define FFEEXPR_operatorassociativityNEQV_ FFEEXPR_operatorassociativityL2R_ - -typedef enum - { - FFEEXPR_parentypeFUNCTION_, - FFEEXPR_parentypeSUBROUTINE_, - FFEEXPR_parentypeARRAY_, - FFEEXPR_parentypeSUBSTRING_, - FFEEXPR_parentypeFUNSUBSTR_,/* Ambig: check for colon after first expr. */ - FFEEXPR_parentypeEQUIVALENCE_, /* Ambig: ARRAY_ or SUBSTRING_. */ - FFEEXPR_parentypeANY_, /* Allow basically anything. */ - FFEEXPR_parentype_ - } ffeexprParenType_; - -typedef enum - { - FFEEXPR_percentNONE_, - FFEEXPR_percentLOC_, - FFEEXPR_percentVAL_, - FFEEXPR_percentREF_, - FFEEXPR_percentDESCR_, - FFEEXPR_percent_ - } ffeexprPercent_; - -/* Internal typedefs. */ - -typedef struct _ffeexpr_expr_ *ffeexprExpr_; -typedef bool ffeexprOperatorAssociativity_; -typedef struct _ffeexpr_stack_ *ffeexprStack_; - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffeexpr_expr_ - { - ffeexprExpr_ previous; - ffelexToken token; - ffeexprExprtype_ type; - union - { - struct - { - ffeexprOperator_ op; - ffeexprOperatorPrecedence_ prec; - ffeexprOperatorAssociativity_ as; - } - operator; - ffebld operand; - } - u; - }; - -struct _ffeexpr_stack_ - { - ffeexprStack_ previous; - mallocPool pool; - ffeexprContext context; - ffeexprCallback callback; - ffelexToken first_token; - ffeexprExpr_ exprstack; - ffelexToken tokens[10]; /* Used in certain cases, like (unary) - open-paren. */ - ffebld expr; /* For first of - complex/implied-do/substring/array-elements - / actual-args expression. */ - ffebld bound_list; /* For tracking dimension bounds list of - array. */ - ffebldListBottom bottom; /* For building lists. */ - ffeinfoRank rank; /* For elements in an array reference. */ - bool constant; /* TRUE while elements seen so far are - constants. */ - bool immediate; /* TRUE while elements seen so far are - immediate/constants. */ - ffebld next_dummy; /* Next SFUNC dummy arg in arg list. */ - ffebldListLength num_args; /* Number of dummy args expected in arg list. */ - bool is_rhs; /* TRUE if rhs context, FALSE otherwise. */ - ffeexprPercent_ percent; /* Current %FOO keyword. */ - }; - -struct _ffeexpr_find_ - { - ffelexToken t; - ffelexHandler after; - int level; - }; - -/* Static objects accessed by functions in this module. */ - -static ffeexprStack_ ffeexpr_stack_; /* Expression stack for semantic. */ -static ffelexToken ffeexpr_tokens_[10]; /* Scratchpad tokens for syntactic. */ -static ffestrOther ffeexpr_current_dotdot_; /* Current .FOO. keyword. */ -static long ffeexpr_hollerith_count_; /* ffeexpr_token_number_ and caller. */ -static int ffeexpr_level_; /* Level of DATA implied-DO construct. */ -static bool ffeexpr_is_substr_ok_; /* If OPEN_PAREN as binary "op" ok. */ -static struct _ffeexpr_find_ ffeexpr_find_; - -/* Static functions (internal). */ - -static ffelexHandler ffeexpr_cb_close_paren_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_close_paren_ambig_ (ffelexToken ft, - ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_close_paren_ambig_1_ (ffelexToken t); -static ffelexHandler ffeexpr_cb_close_paren_c_ (ffelexToken ft, - ffebld expr, ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_c_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_close_paren_ci_ (ffelexToken ft, - ffebld expr, ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_ci_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_3_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_comma_i_5_ (ffelexToken t); -static ffelexHandler ffeexpr_cb_end_loc_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_end_notloc_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_cb_end_notloc_1_ (ffelexToken t); -static ffesymbol ffeexpr_check_impctrl_ (ffesymbol s); -static void ffeexpr_check_impdo_ (ffebld list, ffelexToken list_t, - ffebld dovar, ffelexToken dovar_t); -static void ffeexpr_update_impdo_ (ffebld expr, ffebld dovar); -static void ffeexpr_update_impdo_sym_ (ffebld expr, ffesymbol dovar); -static ffeexprContext ffeexpr_context_outer_ (ffeexprStack_ s); -static ffeexprExpr_ ffeexpr_expr_new_ (void); -static void ffeexpr_fulfill_call_ (ffebld *expr, ffelexToken t); -static bool ffeexpr_isdigits_ (char *p); -static ffelexHandler ffeexpr_token_first_lhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_lhs_1_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_1_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_2_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_3_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_4_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_5_ (ffelexToken t); -static ffelexHandler ffeexpr_token_first_rhs_6_ (ffelexToken t); -static ffelexHandler ffeexpr_token_namelist_ (ffelexToken t); -static void ffeexpr_expr_kill_ (ffeexprExpr_ e); -static void ffeexpr_exprstack_push_ (ffeexprExpr_ e); -static void ffeexpr_exprstack_push_binary_ (ffeexprExpr_ e); -static void ffeexpr_exprstack_push_operand_ (ffeexprExpr_ e); -static void ffeexpr_exprstack_push_unary_ (ffeexprExpr_ e); -static void ffeexpr_reduce_ (void); -static ffebld ffeexpr_reduced_bool1_ (ffebld reduced, ffeexprExpr_ op, - ffeexprExpr_ r); -static ffebld ffeexpr_reduced_bool2_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_concatenate_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_eqop2_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_math1_ (ffebld reduced, ffeexprExpr_ op, - ffeexprExpr_ r); -static ffebld ffeexpr_reduced_math2_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_power_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_relop2_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_ugly1_ (ffebld reduced, ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_ugly1log_ (ffebld reduced, ffeexprExpr_ op, - ffeexprExpr_ r); -static ffebld ffeexpr_reduced_ugly2_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffebld ffeexpr_reduced_ugly2log_ (ffebld reduced, ffeexprExpr_ l, - ffeexprExpr_ op, ffeexprExpr_ r); -static ffelexHandler ffeexpr_find_close_paren_ (ffelexToken t, - ffelexHandler after); -static ffelexHandler ffeexpr_nil_finished_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_rhs_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_period_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_end_period_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_swallow_period_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_real_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_real_exponent_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_real_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_exponent_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_period_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_per_exp_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_real_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_num_per_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_number_real_exp_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_num_real_exp_sn_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_binary_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_binary_period_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_binary_end_per_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_binary_sw_per_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_quote_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_apostrophe_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_apos_char_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_name_rhs_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_name_apos_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_name_apos_name_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_percent_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_percent_name_ (ffelexToken t); -static ffelexHandler ffeexpr_nil_substrp_ (ffelexToken t); -static ffelexHandler ffeexpr_finished_ (ffelexToken t); -static ffebld ffeexpr_finished_ambig_ (ffelexToken t, ffebld expr); -static ffelexHandler ffeexpr_token_lhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_rhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_binary_ (ffelexToken t); -static ffelexHandler ffeexpr_token_period_ (ffelexToken t); -static ffelexHandler ffeexpr_token_end_period_ (ffelexToken t); -static ffelexHandler ffeexpr_token_swallow_period_ (ffelexToken t); -static ffelexHandler ffeexpr_token_real_ (ffelexToken t); -static ffelexHandler ffeexpr_token_real_exponent_ (ffelexToken t); -static ffelexHandler ffeexpr_token_real_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_exponent_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_period_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_per_exp_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_real_ (ffelexToken t); -static ffelexHandler ffeexpr_token_num_per_exp_sign_ (ffelexToken t); -static ffelexHandler ffeexpr_token_number_real_exp_ (ffelexToken t); -static ffelexHandler ffeexpr_token_num_real_exp_sn_ (ffelexToken t); -static ffelexHandler ffeexpr_token_binary_period_ (ffelexToken t); -static ffelexHandler ffeexpr_token_binary_end_per_ (ffelexToken t); -static ffelexHandler ffeexpr_token_binary_sw_per_ (ffelexToken t); -static ffelexHandler ffeexpr_token_quote_ (ffelexToken t); -static ffelexHandler ffeexpr_token_apostrophe_ (ffelexToken t); -static ffelexHandler ffeexpr_token_apos_char_ (ffelexToken t); -static ffelexHandler ffeexpr_token_name_lhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_name_arg_ (ffelexToken t); -static ffelexHandler ffeexpr_token_name_rhs_ (ffelexToken t); -static ffelexHandler ffeexpr_token_name_apos_ (ffelexToken t); -static ffelexHandler ffeexpr_token_name_apos_name_ (ffelexToken t); -static ffelexHandler ffeexpr_token_percent_ (ffelexToken t); -static ffelexHandler ffeexpr_token_percent_name_ (ffelexToken t); -static ffelexHandler ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_elements_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_equivalence_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_substring_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_substring_1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_substrp_ (ffelexToken t); -static ffelexHandler ffeexpr_token_intrincheck_ (ffelexToken t); -static ffelexHandler ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffeexpr_token_anything_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static void ffeexpr_make_float_const_ (char exp_letter, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, ffelexToken exponent, - ffelexToken exponent_sign, ffelexToken exponent_digits); -static ffesymbol ffeexpr_declare_unadorned_ (ffelexToken t, bool maybe_intrin); -static ffesymbol ffeexpr_sym_impdoitem_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_call_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_data_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_equivalence_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_extfunc_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_impdoctrl_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_lhs_parameter_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_rhs_actualarg_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_rhs_dimlist_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_sym_rhs_let_ (ffesymbol s, ffelexToken t); -static ffesymbol ffeexpr_declare_parenthesized_ (ffelexToken t, - bool maybe_intrin, - ffeexprParenType_ *paren_type); -static ffesymbol ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t); - -/* Internal macros. */ - -#define ffeexpr_paren_lhs_let_(s,t) ffeexpr_sym_rhs_let_(s,t) -#define ffeexpr_sym_lhs_let_(s,t) ffeexpr_sym_rhs_let_(s,t) - -/* ffeexpr_collapse_convert -- Collapse convert expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_convert(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_convert (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharacterSize sz; - ffetargetCharacterSize sz2; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - sz = FFETARGET_charactersizeNONE; - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_integer1_integer2 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_integer1_integer3 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_integer1_integer4 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER1/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer1_real1 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer1_real2 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer1_real3 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer1_real4 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER1/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer1_complex1 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer1_complex2 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer1_complex3 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer1_complex4 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER1/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_integer1_logical1 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_integer1_logical2 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_integer1_logical3 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_integer1_logical4 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER1/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_integer1_character1 - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_integer1_hollerith - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_integer1_typeless - (ffebld_cu_ptr_integer1 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("INTEGER1 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_integer2_integer1 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_integer2_integer3 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_integer2_integer4 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER2/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer2_real1 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer2_real2 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer2_real3 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer2_real4 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER2/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer2_complex1 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer2_complex2 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer2_complex3 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer2_complex4 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER2/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_integer2_logical1 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_integer2_logical2 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_integer2_logical3 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_integer2_logical4 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER2/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_integer2_character1 - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_integer2_hollerith - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_integer2_typeless - (ffebld_cu_ptr_integer2 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("INTEGER2 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_integer3_integer1 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_integer3_integer2 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_integer3_integer4 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER3/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer3_real1 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer3_real2 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer3_real3 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer3_real4 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER3/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer3_complex1 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer3_complex2 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer3_complex3 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer3_complex4 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER3/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_integer3_logical1 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_integer3_logical2 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_integer3_logical3 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_integer3_logical4 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER3/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_integer3_character1 - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_integer3_hollerith - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_integer3_typeless - (ffebld_cu_ptr_integer3 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("INTEGER3 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_integer4_integer1 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_integer4_integer2 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_integer4_integer3 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER4/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer4_real1 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer4_real2 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer4_real3 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer4_real4 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER4/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_integer4_complex1 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_integer4_complex2 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_integer4_complex3 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_integer4_complex4 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER3/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_integer4_logical1 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_integer4_logical2 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_integer4_logical3 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_integer4_logical4 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("INTEGER4/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_integer4_character1 - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_integer4_hollerith - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_integer4_typeless - (ffebld_cu_ptr_integer4 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("INTEGER4 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - sz = FFETARGET_charactersizeNONE; - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_logical1_logical2 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_logical1_logical3 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_logical1_logical4 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL1/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_logical1_integer1 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_logical1_integer2 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_logical1_integer3 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_logical1_integer4 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL1/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_logical1_character1 - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_logical1_hollerith - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_logical1_typeless - (ffebld_cu_ptr_logical1 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("LOGICAL1 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_logical2_logical1 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_logical2_logical3 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_logical2_logical4 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL2/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_logical2_integer1 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_logical2_integer2 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_logical2_integer3 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_logical2_integer4 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL2/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_logical2_character1 - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_logical2_hollerith - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_logical2_typeless - (ffebld_cu_ptr_logical2 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("LOGICAL2 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_logical3_logical1 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_logical3_logical2 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_convert_logical3_logical4 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL3/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_logical3_integer1 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_logical3_integer2 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_logical3_integer3 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_logical3_integer4 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL3/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_logical3_character1 - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_logical3_hollerith - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_logical3_typeless - (ffebld_cu_ptr_logical3 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("LOGICAL3 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_convert_logical4_logical1 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_convert_logical4_logical2 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_convert_logical4_logical3 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical3 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL4/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_logical4_integer1 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_logical4_integer2 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_logical4_integer3 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_logical4_integer4 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("LOGICAL4/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_logical4_character1 - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_logical4_hollerith - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_logical4_typeless - (ffebld_cu_ptr_logical4 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("LOGICAL4 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - sz = FFETARGET_charactersizeNONE; - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_real1_integer1 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_real1_integer2 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_real1_integer3 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_real1_integer4 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL1/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real1_real2 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real1_real3 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real1_real4 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL1/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real1_complex1 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real1_complex2 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real1_complex3 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real1_complex4 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL1/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_real1_character1 - (ffebld_cu_ptr_real1 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_real1_hollerith - (ffebld_cu_ptr_real1 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_real1_typeless - (ffebld_cu_ptr_real1 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("REAL1 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_real2_integer1 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_real2_integer2 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_real2_integer3 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_real2_integer4 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL2/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real2_real1 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real2_real3 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real2_real4 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL2/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real2_complex1 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real2_complex2 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real2_complex3 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real2_complex4 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL2/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_real2_character1 - (ffebld_cu_ptr_real2 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_real2_hollerith - (ffebld_cu_ptr_real2 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_real2_typeless - (ffebld_cu_ptr_real2 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("REAL2 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_real3_integer1 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_real3_integer2 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_real3_integer3 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_real3_integer4 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL3/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real3_real1 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real3_real2 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real3_real4 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL3/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real3_complex1 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real3_complex2 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real3_complex3 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real3_complex4 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL3/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_real3_character1 - (ffebld_cu_ptr_real3 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_real3_hollerith - (ffebld_cu_ptr_real3 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_real3_typeless - (ffebld_cu_ptr_real3 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("REAL3 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_real4_integer1 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_real4_integer2 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_real4_integer3 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_real4_integer4 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL4/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real4_real1 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real4_real2 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real4_real3 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL4/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_real4_complex1 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_real4_complex2 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_real4_complex3 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_real4_complex4 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("REAL4/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_real4_character1 - (ffebld_cu_ptr_real4 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_real4_hollerith - (ffebld_cu_ptr_real4 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_real4_typeless - (ffebld_cu_ptr_real4 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("REAL4 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - sz = FFETARGET_charactersizeNONE; - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_complex1_integer1 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_complex1_integer2 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_complex1_integer3 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_complex1_integer4 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX1/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex1_real1 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex1_real2 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex1_real3 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex1_real4 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX1/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex1_complex2 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex1_complex3 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex1_complex4 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX1/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_complex1_character1 - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_complex1_hollerith - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_complex1_typeless - (ffebld_cu_ptr_complex1 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("COMPLEX1 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_complex2_integer1 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_complex2_integer2 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_complex2_integer3 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_complex2_integer4 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX2/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex2_real1 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex2_real2 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex2_real3 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex2_real4 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX2/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex2_complex1 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex2_complex3 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex2_complex4 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX2/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_complex2_character1 - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_complex2_hollerith - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_complex2_typeless - (ffebld_cu_ptr_complex2 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("COMPLEX2 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_complex3_integer1 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_complex3_integer2 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_complex3_integer3 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_complex3_integer4 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX3/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex3_real1 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex3_real2 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex3_real3 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex3_real4 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX3/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex3_complex1 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex3_complex2 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex3_complex4 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX3/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_complex3_character1 - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_complex3_hollerith - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_complex3_typeless - (ffebld_cu_ptr_complex3 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("COMPLEX3 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_convert_complex4_integer1 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_integer1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_convert_complex4_integer2 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_integer2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_convert_complex4_integer3 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_integer3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_convert_complex4_integer4 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_integer4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX4/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex4_real1 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_real1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex4_real2 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_real2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex4_real3 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_real3 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_convert_complex4_real4 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_real4 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX4/REAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_convert_complex4_complex1 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex1 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_convert_complex4_complex2 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex2 (ffebld_conter (l))); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_convert_complex4_complex3 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex3 (ffebld_conter (l))); - break; -#endif - - default: - assert ("COMPLEX4/COMPLEX bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - error = ffetarget_convert_complex4_character1 - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_character1 (ffebld_conter (l))); - break; - - case FFEINFO_basictypeHOLLERITH: - error = ffetarget_convert_complex4_hollerith - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_hollerith (ffebld_conter (l))); - break; - - case FFEINFO_basictypeTYPELESS: - error = ffetarget_convert_complex4_typeless - (ffebld_cu_ptr_complex4 (u), - ffebld_constant_typeless (ffebld_conter (l))); - break; - - default: - assert ("COMPLEX4 bad type" == NULL); - break; - } - - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - if ((sz = ffebld_size (expr)) == FFETARGET_charactersizeNONE) - return expr; - kt = ffeinfo_kindtype (ffebld_info (expr)); - switch (kt) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - switch (ffeinfo_basictype (ffebld_info (l))) - { - case FFEINFO_basictypeCHARACTER: - if ((sz2 = ffebld_size (l)) == FFETARGET_charactersizeNONE) - return expr; - assert (kt == ffeinfo_kindtype (ffebld_info (l))); - assert (sz2 == ffetarget_length_character1 - (ffebld_constant_character1 - (ffebld_conter (l)))); - error - = ffetarget_convert_character1_character1 - (ffebld_cu_ptr_character1 (u), sz, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error - = ffetarget_convert_character1_integer1 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error - = ffetarget_convert_character1_integer2 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error - = ffetarget_convert_character1_integer3 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error - = ffetarget_convert_character1_integer4 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - - default: - assert ("CHARACTER1/INTEGER bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (ffeinfo_kindtype (ffebld_info (l))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error - = ffetarget_convert_character1_logical1 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error - = ffetarget_convert_character1_logical2 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error - = ffetarget_convert_character1_logical3 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error - = ffetarget_convert_character1_logical4 - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_pool ()); - break; -#endif - - default: - assert ("CHARACTER1/LOGICAL bad source kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeHOLLERITH: - error - = ffetarget_convert_character1_hollerith - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_hollerith (ffebld_conter (l)), - ffebld_constant_pool ()); - break; - - case FFEINFO_basictypeTYPELESS: - error - = ffetarget_convert_character1_typeless - (ffebld_cu_ptr_character1 (u), - sz, - ffebld_constant_typeless (ffebld_conter (l)), - ffebld_constant_pool ()); - break; - - default: - assert ("CHARACTER1 bad type" == NULL); - } - - expr - = ffebld_new_conter_with_orig - (ffebld_constant_new_character1_val - (ffebld_cu_val_character1 (u)), - expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - sz)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - assert (t != NULL); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_paren -- Collapse paren expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_paren(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_paren (ffebld expr, ffelexToken t UNUSED) -{ - ffebld r; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharacterSize len; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - r = ffebld_left (expr); - - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - bt = ffeinfo_basictype (ffebld_info (r)); - kt = ffeinfo_kindtype (ffebld_info (r)); - len = ffebld_size (r); - - expr = ffebld_new_conter_with_orig (ffebld_constant_copy (ffebld_conter (r)), - expr); - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - return expr; -} - -/* ffeexpr_collapse_uplus -- Collapse uplus expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_uplus(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_uplus (ffebld expr, ffelexToken t UNUSED) -{ - ffebld r; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharacterSize len; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - r = ffebld_left (expr); - - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - bt = ffeinfo_basictype (ffebld_info (r)); - kt = ffeinfo_kindtype (ffebld_info (r)); - len = ffebld_size (r); - - expr = ffebld_new_conter_with_orig (ffebld_constant_copy (ffebld_conter (r)), - expr); - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - return expr; -} - -/* ffeexpr_collapse_uminus -- Collapse uminus expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_uminus(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_uminus (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - r = ffebld_left (expr); - - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_uminus_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_uminus_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_uminus_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_uminus_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_uminus_real1 (ffebld_cu_ptr_real1 (u), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_uminus_real2 (ffebld_cu_ptr_real2 (u), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_uminus_real3 (ffebld_cu_ptr_real3 (u), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_uminus_real4 (ffebld_cu_ptr_real4 (u), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_uminus_complex1 (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_uminus_complex2 (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_uminus_complex3 (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_uminus_complex4 (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_not -- Collapse not expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_not(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_not (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - r = ffebld_left (expr); - - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_not_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_not_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_not_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_not_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_not_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_not_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_not_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_not_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_add -- Collapse add expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_add(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_add (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_add_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_add_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_add_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_add_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_add_real1 (ffebld_cu_ptr_real1 (u), - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_add_real2 (ffebld_cu_ptr_real2 (u), - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_add_real3 (ffebld_cu_ptr_real3 (u), - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_add_real4 (ffebld_cu_ptr_real4 (u), - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_add_complex1 (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_add_complex2 (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_add_complex3 (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_add_complex4 (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_subtract -- Collapse subtract expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_subtract(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_subtract (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_subtract_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_subtract_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_subtract_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_subtract_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_subtract_real1 (ffebld_cu_ptr_real1 (u), - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_subtract_real2 (ffebld_cu_ptr_real2 (u), - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_subtract_real3 (ffebld_cu_ptr_real3 (u), - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_subtract_real4 (ffebld_cu_ptr_real4 (u), - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_subtract_complex1 (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_subtract_complex2 (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_subtract_complex3 (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_subtract_complex4 (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_multiply -- Collapse multiply expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_multiply(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_multiply (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_multiply_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_multiply_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_multiply_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_multiply_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_multiply_real1 (ffebld_cu_ptr_real1 (u), - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_multiply_real2 (ffebld_cu_ptr_real2 (u), - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_multiply_real3 (ffebld_cu_ptr_real3 (u), - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_multiply_real4 (ffebld_cu_ptr_real4 (u), - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_multiply_complex1 (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_multiply_complex2 (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_multiply_complex3 (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_multiply_complex4 (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_divide -- Collapse divide expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_divide(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_divide (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_divide_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_divide_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_divide_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_divide_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_divide_real1 (ffebld_cu_ptr_real1 (u), - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real1_val - (ffebld_cu_val_real1 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_divide_real2 (ffebld_cu_ptr_real2 (u), - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real2_val - (ffebld_cu_val_real2 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_divide_real3 (ffebld_cu_ptr_real3 (u), - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real3_val - (ffebld_cu_val_real3 (u)), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_divide_real4 (ffebld_cu_ptr_real4 (u), - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_real4_val - (ffebld_cu_val_real4 (u)), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_divide_complex1 (ffebld_cu_ptr_complex1 (u), - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex1_val - (ffebld_cu_val_complex1 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_divide_complex2 (ffebld_cu_ptr_complex2 (u), - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex2_val - (ffebld_cu_val_complex2 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_divide_complex3 (ffebld_cu_ptr_complex3 (u), - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex3_val - (ffebld_cu_val_complex3 (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_divide_complex4 (ffebld_cu_ptr_complex4 (u), - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_complex4_val - (ffebld_cu_val_complex4 (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_power -- Collapse power expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_power(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_power (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - if ((ffeinfo_basictype (ffebld_info (r)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (r)) != FFEINFO_kindtypeINTEGERDEFAULT)) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { - case FFEINFO_kindtypeINTEGERDEFAULT: - error = ffetarget_power_integerdefault_integerdefault - (ffebld_cu_ptr_integerdefault (u), - ffebld_constant_integerdefault (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_integerdefault_val - (ffebld_cu_val_integerdefault (u)), expr); - break; - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { - case FFEINFO_kindtypeREALDEFAULT: - error = ffetarget_power_realdefault_integerdefault - (ffebld_cu_ptr_realdefault (u), - ffebld_constant_realdefault (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_realdefault_val - (ffebld_cu_val_realdefault (u)), expr); - break; - - case FFEINFO_kindtypeREALDOUBLE: - error = ffetarget_power_realdouble_integerdefault - (ffebld_cu_ptr_realdouble (u), - ffebld_constant_realdouble (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_realdouble_val - (ffebld_cu_val_realdouble (u)), expr); - break; - -#if FFETARGET_okREALQUAD - case FFEINFO_kindtypeREALQUAD: - error = ffetarget_power_realquad_integerdefault - (ffebld_cu_ptr_realquad (u), - ffebld_constant_realquad (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_realquad_val - (ffebld_cu_val_realquad (u)), expr); - break; -#endif - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { - case FFEINFO_kindtypeREALDEFAULT: - error = ffetarget_power_complexdefault_integerdefault - (ffebld_cu_ptr_complexdefault (u), - ffebld_constant_complexdefault (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complexdefault_val - (ffebld_cu_val_complexdefault (u)), expr); - break; - -#if FFETARGET_okCOMPLEXDOUBLE - case FFEINFO_kindtypeREALDOUBLE: - error = ffetarget_power_complexdouble_integerdefault - (ffebld_cu_ptr_complexdouble (u), - ffebld_constant_complexdouble (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complexdouble_val - (ffebld_cu_val_complexdouble (u)), expr); - break; -#endif - -#if FFETARGET_okCOMPLEXQUAD - case FFEINFO_kindtypeREALQUAD: - error = ffetarget_power_complexquad_integerdefault - (ffebld_cu_ptr_complexquad (u), - ffebld_constant_complexquad (ffebld_conter (l)), - ffebld_constant_integerdefault (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_complexquad_val - (ffebld_cu_val_complexquad (u)), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_concatenate -- Collapse concatenate expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_concatenate(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_concatenate (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoKindtype kt; - ffetargetCharacterSize len; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeCHARACTER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_concatenate_character1 (ffebld_cu_ptr_character1 (u), - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r)), - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character1_val - (ffebld_cu_val_character1 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_concatenate_character2 (ffebld_cu_ptr_character2 (u), - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r)), - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character2_val - (ffebld_cu_val_character2 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_concatenate_character3 (ffebld_cu_ptr_character3 (u), - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r)), - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character3_val - (ffebld_cu_val_character3 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_concatenate_character4 (ffebld_cu_ptr_character4 (u), - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r)), - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character4_val - (ffebld_cu_val_character4 (u)), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeCHARACTER, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_eq -- Collapse eq expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_eq(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_eq (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_eq_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_eq_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_eq_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_eq_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_eq_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_eq_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_eq_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_eq_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_eq_complex1 (&val, - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_eq_complex2 (&val, - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_eq_complex3 (&val, - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_eq_complex4 (&val, - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_eq_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_eq_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_eq_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_eq_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_ne -- Collapse ne expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_ne(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_ne (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_ne_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_ne_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_ne_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_ne_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_ne_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_ne_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_ne_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_ne_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCOMPLEX: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_ne_complex1 (&val, - ffebld_constant_complex1 (ffebld_conter (l)), - ffebld_constant_complex1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_ne_complex2 (&val, - ffebld_constant_complex2 (ffebld_conter (l)), - ffebld_constant_complex2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_ne_complex3 (&val, - ffebld_constant_complex3 (ffebld_conter (l)), - ffebld_constant_complex3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_ne_complex4 (&val, - ffebld_constant_complex4 (ffebld_conter (l)), - ffebld_constant_complex4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad complex kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_ne_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_ne_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_ne_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_ne_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_ge -- Collapse ge expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_ge(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_ge (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_ge_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_ge_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_ge_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_ge_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_ge_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_ge_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_ge_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_ge_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_ge_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_ge_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_ge_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_ge_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_gt -- Collapse gt expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_gt(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_gt (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_gt_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_gt_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_gt_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_gt_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_gt_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_gt_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_gt_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_gt_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_gt_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_gt_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_gt_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_gt_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_le -- Collapse le expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_le(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_le (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_le_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_le_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_le_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_le_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_le_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_le_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_le_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_le_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_le_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_le_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_le_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_le_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_lt -- Collapse lt expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_lt(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_lt (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - bool val; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (ffeinfo_basictype (ffebld_info (ffebld_left (expr)))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_lt_integer1 (&val, - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_lt_integer2 (&val, - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_lt_integer3 (&val, - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_lt_integer4 (&val, - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeREAL: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okREAL1 - case FFEINFO_kindtypeREAL1: - error = ffetarget_lt_real1 (&val, - ffebld_constant_real1 (ffebld_conter (l)), - ffebld_constant_real1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL2 - case FFEINFO_kindtypeREAL2: - error = ffetarget_lt_real2 (&val, - ffebld_constant_real2 (ffebld_conter (l)), - ffebld_constant_real2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL3 - case FFEINFO_kindtypeREAL3: - error = ffetarget_lt_real3 (&val, - ffebld_constant_real3 (ffebld_conter (l)), - ffebld_constant_real3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okREAL4 - case FFEINFO_kindtypeREAL4: - error = ffetarget_lt_real4 (&val, - ffebld_constant_real4 (ffebld_conter (l)), - ffebld_constant_real4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad real kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffeinfo_kindtype (ffebld_info (ffebld_left (expr)))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_lt_character1 (&val, - ffebld_constant_character1 (ffebld_conter (l)), - ffebld_constant_character1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_lt_character2 (&val, - ffebld_constant_character2 (ffebld_conter (l)), - ffebld_constant_character2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_lt_character3 (&val, - ffebld_constant_character3 (ffebld_conter (l)), - ffebld_constant_character3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_lt_character4 (&val, - ffebld_constant_character4 (ffebld_conter (l)), - ffebld_constant_character4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig - (ffebld_constant_new_logicaldefault (val), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_and -- Collapse and expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_and(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_and (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_and_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_and_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_and_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_and_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_and_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_and_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_and_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_and_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_or -- Collapse or expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_or(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_or (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_or_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_or_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_or_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_or_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_or_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_or_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_or_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_or_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_xor -- Collapse xor expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_xor(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_xor (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_xor_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_xor_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_xor_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_xor_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_xor_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_xor_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_xor_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_xor_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_eqv -- Collapse eqv expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_eqv(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_eqv (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_eqv_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_eqv_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_eqv_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_eqv_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_eqv_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_eqv_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_eqv_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_eqv_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_neqv -- Collapse neqv expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_neqv(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_neqv (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebldConstantUnion u; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - if (ffebld_op (r) != FFEBLD_opCONTER) - return expr; - - switch (bt = ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeINTEGER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - error = ffetarget_neqv_integer1 (ffebld_cu_ptr_integer1 (u), - ffebld_constant_integer1 (ffebld_conter (l)), - ffebld_constant_integer1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer1_val - (ffebld_cu_val_integer1 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - error = ffetarget_neqv_integer2 (ffebld_cu_ptr_integer2 (u), - ffebld_constant_integer2 (ffebld_conter (l)), - ffebld_constant_integer2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer2_val - (ffebld_cu_val_integer2 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - error = ffetarget_neqv_integer3 (ffebld_cu_ptr_integer3 (u), - ffebld_constant_integer3 (ffebld_conter (l)), - ffebld_constant_integer3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer3_val - (ffebld_cu_val_integer3 (u)), expr); - break; -#endif - -#if FFETARGET_okINTEGER4 - case FFEINFO_kindtypeINTEGER4: - error = ffetarget_neqv_integer4 (ffebld_cu_ptr_integer4 (u), - ffebld_constant_integer4 (ffebld_conter (l)), - ffebld_constant_integer4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_integer4_val - (ffebld_cu_val_integer4 (u)), expr); - break; -#endif - - default: - assert ("bad integer kind type" == NULL); - break; - } - break; - - case FFEINFO_basictypeLOGICAL: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okLOGICAL1 - case FFEINFO_kindtypeLOGICAL1: - error = ffetarget_neqv_logical1 (ffebld_cu_ptr_logical1 (u), - ffebld_constant_logical1 (ffebld_conter (l)), - ffebld_constant_logical1 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical1_val - (ffebld_cu_val_logical1 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL2 - case FFEINFO_kindtypeLOGICAL2: - error = ffetarget_neqv_logical2 (ffebld_cu_ptr_logical2 (u), - ffebld_constant_logical2 (ffebld_conter (l)), - ffebld_constant_logical2 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical2_val - (ffebld_cu_val_logical2 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL3 - case FFEINFO_kindtypeLOGICAL3: - error = ffetarget_neqv_logical3 (ffebld_cu_ptr_logical3 (u), - ffebld_constant_logical3 (ffebld_conter (l)), - ffebld_constant_logical3 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical3_val - (ffebld_cu_val_logical3 (u)), expr); - break; -#endif - -#if FFETARGET_okLOGICAL4 - case FFEINFO_kindtypeLOGICAL4: - error = ffetarget_neqv_logical4 (ffebld_cu_ptr_logical4 (u), - ffebld_constant_logical4 (ffebld_conter (l)), - ffebld_constant_logical4 (ffebld_conter (r))); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_logical4_val - (ffebld_cu_val_logical4 (u)), expr); - break; -#endif - - default: - assert ("bad logical kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_collapse_symter -- Collapse symter expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_symter(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_symter (ffebld expr, ffelexToken t UNUSED) -{ - ffebld r; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharacterSize len; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - if ((r = ffesymbol_init (ffebld_symter (expr))) == NULL) - return expr; /* A PARAMETER lhs in progress. */ - - switch (ffebld_op (r)) - { - case FFEBLD_opCONTER: - break; - - case FFEBLD_opANY: - return r; - - default: - return expr; - } - - bt = ffeinfo_basictype (ffebld_info (r)); - kt = ffeinfo_kindtype (ffebld_info (r)); - len = ffebld_size (r); - - expr = ffebld_new_conter_with_orig (ffebld_constant_copy (ffebld_conter (r)), - expr); - - ffebld_set_info (expr, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - return expr; -} - -/* ffeexpr_collapse_funcref -- Collapse funcref expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_funcref(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_funcref (ffebld expr, ffelexToken t UNUSED) -{ - return expr; /* ~~someday go ahead and collapse these, - though not required */ -} - -/* ffeexpr_collapse_arrayref -- Collapse arrayref expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_arrayref(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_arrayref (ffebld expr, ffelexToken t UNUSED) -{ - return expr; -} - -/* ffeexpr_collapse_substr -- Collapse substr expr - - ffebld expr; - ffelexToken token; - expr = ffeexpr_collapse_substr(expr,token); - - If the result of the expr is a constant, replaces the expr with the - computed constant. */ - -ffebld -ffeexpr_collapse_substr (ffebld expr, ffelexToken t) -{ - ffebad error = FFEBAD; - ffebld l; - ffebld r; - ffebld start; - ffebld stop; - ffebldConstantUnion u; - ffeinfoKindtype kt; - ffetargetCharacterSize len; - ffetargetIntegerDefault first; - ffetargetIntegerDefault last; - - if (ffeinfo_where (ffebld_info (expr)) != FFEINFO_whereCONSTANT) - return expr; - - l = ffebld_left (expr); - r = ffebld_right (expr); /* opITEM. */ - - if (ffebld_op (l) != FFEBLD_opCONTER) - return expr; - - kt = ffeinfo_kindtype (ffebld_info (l)); - len = ffebld_size (l); - - start = ffebld_head (r); - stop = ffebld_head (ffebld_trail (r)); - if (start == NULL) - first = 1; - else - { - if ((ffebld_op (start) != FFEBLD_opCONTER) - || (ffeinfo_basictype (ffebld_info (start)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (start)) - != FFEINFO_kindtypeINTEGERDEFAULT)) - return expr; - first = ffebld_constant_integerdefault (ffebld_conter (start)); - } - if (stop == NULL) - last = len; - else - { - if ((ffebld_op (stop) != FFEBLD_opCONTER) - || (ffeinfo_basictype (ffebld_info (stop)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (stop)) - != FFEINFO_kindtypeINTEGERDEFAULT)) - return expr; - last = ffebld_constant_integerdefault (ffebld_conter (stop)); - } - - /* Handle problems that should have already been diagnosed, but - left in the expression tree. */ - - if (first <= 0) - first = 1; - if (last < first) - last = first + len - 1; - - if ((first == 1) && (last == len)) - { /* Same as original. */ - expr = ffebld_new_conter_with_orig (ffebld_constant_copy - (ffebld_conter (l)), expr); - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeCHARACTER, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - return expr; - } - - switch (ffeinfo_basictype (ffebld_info (expr))) - { - case FFEINFO_basictypeANY: - return expr; - - case FFEINFO_basictypeCHARACTER: - switch (kt = ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okCHARACTER1 - case FFEINFO_kindtypeCHARACTER1: - error = ffetarget_substr_character1 (ffebld_cu_ptr_character1 (u), - ffebld_constant_character1 (ffebld_conter (l)), first, last, - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character1_val - (ffebld_cu_val_character1 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER2 - case FFEINFO_kindtypeCHARACTER2: - error = ffetarget_substr_character2 (ffebld_cu_ptr_character2 (u), - ffebld_constant_character2 (ffebld_conter (l)), first, last, - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character2_val - (ffebld_cu_val_character2 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER3 - case FFEINFO_kindtypeCHARACTER3: - error = ffetarget_substr_character3 (ffebld_cu_ptr_character3 (u), - ffebld_constant_character3 (ffebld_conter (l)), first, last, - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character3_val - (ffebld_cu_val_character3 (u)), expr); - break; -#endif - -#if FFETARGET_okCHARACTER4 - case FFEINFO_kindtypeCHARACTER4: - error = ffetarget_substr_character4 (ffebld_cu_ptr_character4 (u), - ffebld_constant_character4 (ffebld_conter (l)), first, last, - ffebld_constant_pool (), &len); - expr = ffebld_new_conter_with_orig (ffebld_constant_new_character4_val - (ffebld_cu_val_character4 (u)), expr); - break; -#endif - - default: - assert ("bad character kind type" == NULL); - break; - } - break; - - default: - assert ("bad type" == NULL); - return expr; - } - - ffebld_set_info (expr, ffeinfo_new - (FFEINFO_basictypeCHARACTER, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - len)); - - if ((error != FFEBAD) - && ffebad_start (error)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - return expr; -} - -/* ffeexpr_convert -- Convert source expression to given type - - ffebld source; - ffelexToken source_token; - ffelexToken dest_token; // Any appropriate token for "destination". - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharactersize sz; - ffeexprContext context; // Mainly LET or DATA. - source = ffeexpr_convert(source,source_token,dest_token,bt,kt,sz,context); - - If the expression conforms, returns the source expression. Otherwise - returns source wrapped in a convert node doing the conversion, or - ANY wrapped in convert if there is a conversion error (and issues an - error message). Be sensitive to the context for certain aspects of - the conversion. */ - -ffebld -ffeexpr_convert (ffebld source, ffelexToken source_token, ffelexToken dest_token, - ffeinfoBasictype bt, ffeinfoKindtype kt, ffeinfoRank rk, - ffetargetCharacterSize sz, ffeexprContext context) -{ - bool bad; - ffeinfo info; - ffeinfoWhere wh; - - info = ffebld_info (source); - if ((bt != ffeinfo_basictype (info)) - || (kt != ffeinfo_kindtype (info)) - || (rk != 0) /* Can't convert from or to arrays yet. */ - || (ffeinfo_rank (info) != 0) - || (sz != ffebld_size_known (source))) -#if 0 /* Nobody seems to need this spurious CONVERT node. */ - || ((context != FFEEXPR_contextLET) - && (bt == FFEINFO_basictypeCHARACTER) - && (sz == FFETARGET_charactersizeNONE))) -#endif - { - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - switch (bt) - { - case FFEINFO_basictypeLOGICAL: - bad = FALSE; - break; - - case FFEINFO_basictypeINTEGER: - bad = !ffe_is_ugly_logint (); - break; - - case FFEINFO_basictypeCHARACTER: - bad = ffe_is_pedantic () - || !(ffe_is_ugly_init () - && (context == FFEEXPR_contextDATA)); - break; - - default: - bad = TRUE; - break; - } - break; - - case FFEINFO_basictypeINTEGER: - switch (bt) - { - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - bad = FALSE; - break; - - case FFEINFO_basictypeLOGICAL: - bad = !ffe_is_ugly_logint (); - break; - - case FFEINFO_basictypeCHARACTER: - bad = ffe_is_pedantic () - || !(ffe_is_ugly_init () - && (context == FFEEXPR_contextDATA)); - break; - - default: - bad = TRUE; - break; - } - break; - - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - switch (bt) - { - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - bad = FALSE; - break; - - case FFEINFO_basictypeCHARACTER: - bad = TRUE; - break; - - default: - bad = TRUE; - break; - } - break; - - case FFEINFO_basictypeCHARACTER: - bad = (bt != FFEINFO_basictypeCHARACTER) - && (ffe_is_pedantic () - || (bt != FFEINFO_basictypeINTEGER) - || !(ffe_is_ugly_init () - && (context == FFEEXPR_contextDATA))); - break; - - case FFEINFO_basictypeTYPELESS: - case FFEINFO_basictypeHOLLERITH: - bad = ffe_is_pedantic () - || !(ffe_is_ugly_init () - && ((context == FFEEXPR_contextDATA) - || (context == FFEEXPR_contextLET))); - break; - - default: - bad = TRUE; - break; - } - - if (!bad && ((rk != 0) || (ffeinfo_rank (info) != 0))) - bad = TRUE; - - if (bad && (bt != FFEINFO_basictypeANY) && (kt != FFEINFO_kindtypeANY) - && (ffeinfo_basictype (info) != FFEINFO_basictypeANY) - && (ffeinfo_kindtype (info) != FFEINFO_kindtypeANY) - && (ffeinfo_where (info) != FFEINFO_whereANY)) - { - if (ffebad_start (FFEBAD_BAD_TYPES)) - { - if (dest_token == NULL) - ffebad_here (0, ffewhere_line_unknown (), - ffewhere_column_unknown ()); - else - ffebad_here (0, ffelex_token_where_line (dest_token), - ffelex_token_where_column (dest_token)); - assert (source_token != NULL); - ffebad_here (1, ffelex_token_where_line (source_token), - ffelex_token_where_column (source_token)); - ffebad_finish (); - } - - source = ffebld_new_any (); - ffebld_set_info (source, ffeinfo_new_any ()); - } - else - { - switch (ffeinfo_where (info)) - { - case FFEINFO_whereCONSTANT: - wh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - wh = FFEINFO_whereIMMEDIATE; - break; - - default: - wh = FFEINFO_whereFLEETING; - break; - } - source = ffebld_new_convert (source); - ffebld_set_info (source, ffeinfo_new - (bt, - kt, - 0, - FFEINFO_kindENTITY, - wh, - sz)); - source = ffeexpr_collapse_convert (source, source_token); - } - } - - return source; -} - -/* ffeexpr_convert_expr -- Convert source expr to conform to dest expr - - ffebld source; - ffebld dest; - ffelexToken source_token; - ffelexToken dest_token; - ffeexprContext context; - source = ffeexpr_convert_expr(source,source_token,dest,dest_token,context); - - If the expressions conform, returns the source expression. Otherwise - returns source wrapped in a convert node doing the conversion, or - ANY wrapped in convert if there is a conversion error (and issues an - error message). Be sensitive to the context, such as LET or DATA. */ - -ffebld -ffeexpr_convert_expr (ffebld source, ffelexToken source_token, ffebld dest, - ffelexToken dest_token, ffeexprContext context) -{ - ffeinfo info; - - info = ffebld_info (dest); - return ffeexpr_convert (source, source_token, dest_token, - ffeinfo_basictype (info), - ffeinfo_kindtype (info), - ffeinfo_rank (info), - ffebld_size_known (dest), - context); -} - -/* ffeexpr_convert_to_sym -- Convert source expression to conform to symbol - - ffebld source; - ffesymbol dest; - ffelexToken source_token; - ffelexToken dest_token; - source = ffeexpr_convert_to_sym(source,source_token,dest,dest_token); - - If the expressions conform, returns the source expression. Otherwise - returns source wrapped in a convert node doing the conversion, or - ANY wrapped in convert if there is a conversion error (and issues an - error message). */ - -ffebld -ffeexpr_convert_to_sym (ffebld source, ffelexToken source_token, - ffesymbol dest, ffelexToken dest_token) -{ - return ffeexpr_convert (source, source_token, dest_token, ffesymbol_basictype (dest), - ffesymbol_kindtype (dest), ffesymbol_rank (dest), ffesymbol_size (dest), - FFEEXPR_contextLET); -} - -/* Initializes the module. */ - -void -ffeexpr_init_2 () -{ - ffeexpr_stack_ = NULL; - ffeexpr_level_ = 0; -} - -/* ffeexpr_lhs -- Begin processing left-hand-side-context expression - - Prepares cluster for delivery of lexer tokens representing an expression - in a left-hand-side context (A in A=B, for example). ffebld is used - to build expressions in the given pool. The appropriate lexer-token - handling routine within ffeexpr is returned. When the end of the - expression is detected, mycallbackroutine is called with the resulting - single ffebld object specifying the entire expression and the first - lexer token that is not considered part of the expression. This caller- - supplied routine itself returns a lexer-token handling routine. Thus, - if necessary, ffeexpr can return several tokens as end-of-expression - tokens if it needs to scan forward more than one in any instance. */ - -ffelexHandler -ffeexpr_lhs (mallocPool pool, ffeexprContext context, ffeexprCallback callback) -{ - ffeexprStack_ s; - - ffebld_pool_push (pool); - s = malloc_new_ks (ffe_pool_program_unit (), "FFEEXPR stack", sizeof (*s)); - s->previous = ffeexpr_stack_; - s->pool = pool; - s->context = context; - s->callback = callback; - s->first_token = NULL; - s->exprstack = NULL; - s->is_rhs = FALSE; - ffeexpr_stack_ = s; - return (ffelexHandler) ffeexpr_token_first_lhs_; -} - -/* ffeexpr_rhs -- Begin processing right-hand-side-context expression - - return ffeexpr_rhs(malloc_pool_image(),mycallbackroutine); // to lexer. - - Prepares cluster for delivery of lexer tokens representing an expression - in a right-hand-side context (B in A=B, for example). ffebld is used - to build expressions in the given pool. The appropriate lexer-token - handling routine within ffeexpr is returned. When the end of the - expression is detected, mycallbackroutine is called with the resulting - single ffebld object specifying the entire expression and the first - lexer token that is not considered part of the expression. This caller- - supplied routine itself returns a lexer-token handling routine. Thus, - if necessary, ffeexpr can return several tokens as end-of-expression - tokens if it needs to scan forward more than one in any instance. */ - -ffelexHandler -ffeexpr_rhs (mallocPool pool, ffeexprContext context, ffeexprCallback callback) -{ - ffeexprStack_ s; - - ffebld_pool_push (pool); - s = malloc_new_ks (ffe_pool_program_unit (), "FFEEXPR stack", sizeof (*s)); - s->previous = ffeexpr_stack_; - s->pool = pool; - s->context = context; - s->callback = callback; - s->first_token = NULL; - s->exprstack = NULL; - s->is_rhs = TRUE; - ffeexpr_stack_ = s; - return (ffelexHandler) ffeexpr_token_first_rhs_; -} - -/* ffeexpr_cb_close_paren_ -- OPEN_PAREN expr - - Pass it to ffeexpr_rhs as the callback routine. - - Makes sure the end token is close-paren and swallows it, else issues - an error message and doesn't swallow the token (passing it along instead). - In either case wraps up subexpression construction by enclosing the - ffebld expression in a paren. */ - -static ffelexHandler -ffeexpr_cb_close_paren_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ e; - - if (ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - { - /* Oops, naughty user didn't specify the close paren! */ - - if (ffest_ffebad_start (FFEBAD_MISSING_CLOSE_PAREN)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - ffeexpr_exprstack_push_operand_ (e); - - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_binary_); - } - - if (expr->op == FFEBLD_opIMPDO) - { - if (ffest_ffebad_start (FFEBAD_IMPDO_PAREN)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - } - else - { - expr = ffebld_new_paren (expr); - ffebld_set_info (expr, ffeinfo_use (ffebld_info (ffebld_left (expr)))); - } - - /* Now push the (parenthesized) expression as an operand onto the - expression stack. */ - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand = expr; - e->u.operand = ffeexpr_collapse_paren (e->u.operand, ft); - e->token = ffeexpr_stack_->tokens[0]; - ffeexpr_exprstack_push_operand_ (e); - - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_cb_close_paren_ambig_ -- OPEN_PAREN expr - - Pass it to ffeexpr_rhs as the callback routine. - - We get here in the READ/BACKEND/ENDFILE/REWIND case "READ(expr)" - with the next token in t. If the next token is possibly a binary - operator, continue processing the outer expression. If the next - token is COMMA, then the expression is a unit specifier, and - parentheses should not be added to it because it surrounds the - I/O control list that starts with the unit specifier (and continues - on from here -- we haven't seen the CLOSE_PAREN that matches the - OPEN_PAREN, it is up to the callback function to expect to see it - at some point). In this case, we notify the callback function that - the COMMA is inside, not outside, the parens by wrapping the expression - in an opITEM (with a NULL trail) -- the callback function presumably - unwraps it after seeing this kludgey indicator. - - If the next token is CLOSE_PAREN, then we go to the _1_ state to - decide what to do with the token after that. - - 15-Feb-91 JCB 1.1 - Use an extra state for the CLOSE_PAREN case to make READ &co really - work right. */ - -static ffelexHandler -ffeexpr_cb_close_paren_ambig_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - { /* Need to see the next token before we - decide anything. */ - ffeexpr_stack_->expr = expr; - ffeexpr_tokens_[0] = ffelex_token_use (ft); - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_cb_close_paren_ambig_1_; - } - - expr = ffeexpr_finished_ambig_ (ft, expr); - - /* Let the callback function handle the case where t isn't COMMA. */ - - /* Here is a kludge whereby we tell the callback function the OPEN_PAREN - that preceded the expression starts a list of expressions, and the expr - hasn't been wrapped in a corresponding (and possibly collapsed) opPAREN - node. The callback function should extract the real expr from the head - of this opITEM node after testing it. */ - - expr = ffebld_new_item (expr, NULL); - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ffelex_token_kill (ffeexpr_stack_->first_token); - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - return (ffelexHandler) (*callback) (ft, expr, t); -} - -/* ffeexpr_cb_close_paren_ambig_1_ -- OPEN_PAREN expr CLOSE_PAREN - - See ffeexpr_cb_close_paren_ambig_. - - We get here in the READ/BACKEND/ENDFILE/REWIND case "READ(expr)" - with the next token in t. If the next token is possibly a binary - operator, continue processing the outer expression. If the next - token is COMMA, the expression is a parenthesized format specifier. - If the next token is not EOS or SEMICOLON, then because it is not a - binary operator (it is NAME, OPEN_PAREN, &c), the expression is - a unit specifier, and parentheses should not be added to it because - they surround the I/O control list that consists of only the unit - specifier. If the next token is EOS or SEMICOLON, the statement - must be disambiguated by looking at the type of the expression -- a - character expression is a parenthesized format specifier, while a - non-character expression is a unit specifier. - - Another issue is how to do the callback so the recipient of the - next token knows how to handle it if it is a COMMA. In all other - cases, disambiguation is straightforward: the same approach as the - above is used. - - EXTENSION: in COMMA case, if not pedantic, use same disambiguation - as for EOS/SEMICOLON case; f2c allows "READ (cilist) [[,]iolist]" - and apparently other compilers do, as well, and some code out there - uses this "feature". - - 19-Feb-91 JCB 1.1 - Extend to allow COMMA as nondisambiguating by itself. Remember - to not try and check info field for opSTAR, since that expr doesn't - have a valid info field. */ - -static ffelexHandler -ffeexpr_cb_close_paren_ambig_1_ (ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken orig_ft = ffeexpr_tokens_[0]; /* In case callback clobbers - these. */ - ffelexToken orig_t = ffeexpr_tokens_[1]; - ffebld expr = ffeexpr_stack_->expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: /* Subexpr is parenthesized format specifier. */ - if (ffe_is_pedantic ()) - goto pedantic_comma; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFELEX_typeEOS: /* Ambiguous; use type of expr to - disambiguate. */ - case FFELEX_typeSEMICOLON: - if ((expr == NULL) || (ffebld_op (expr) == FFEBLD_opANY) - || (ffebld_op (expr) == FFEBLD_opSTAR) - || (ffeinfo_basictype (ffebld_info (expr)) - != FFEINFO_basictypeCHARACTER)) - break; /* Not a valid CHARACTER entity, can't be a - format spec. */ - /* Fall through. */ - default: /* Binary op (we assume; error otherwise); - format specifier. */ - - pedantic_comma: /* :::::::::::::::::::: */ - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILENUMAMBIG: - ffeexpr_stack_->context = FFEEXPR_contextFILENUM; - break; - - case FFEEXPR_contextFILEUNITAMBIG: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - break; - - default: - assert ("bad context" == NULL); - break; - } - - ffeexpr_stack_->tokens[0] = ffelex_token_use (ffeexpr_stack_->first_token); - next = (ffelexHandler) ffeexpr_cb_close_paren_ (orig_ft, expr, orig_t); - ffelex_token_kill (orig_ft); - ffelex_token_kill (orig_t); - return (ffelexHandler) (*next) (t); - - case FFELEX_typeOPEN_PAREN:/* Non-binary op; beginning of I/O list. */ - case FFELEX_typeNAME: - break; - } - - expr = ffeexpr_finished_ambig_ (orig_ft, expr); - - /* Here is a kludge whereby we tell the callback function the OPEN_PAREN - that preceded the expression starts a list of expressions, and the expr - hasn't been wrapped in a corresponding (and possibly collapsed) opPAREN - node. The callback function should extract the real expr from the head - of this opITEM node after testing it. */ - - expr = ffebld_new_item (expr, NULL); - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ffelex_token_kill (ffeexpr_stack_->first_token); - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (orig_ft, expr, orig_t); - ffelex_token_kill (orig_ft); - ffelex_token_kill (orig_t); - return (ffelexHandler) (*next) (t); -} - -/* ffeexpr_cb_close_paren_c_ -- OPEN_PAREN expr (possible complex) - - Pass it to ffeexpr_rhs as the callback routine. - - Makes sure the end token is close-paren and swallows it, or a comma - and handles complex/implied-do possibilities, else issues - an error message and doesn't swallow the token (passing it along instead). */ - -static ffelexHandler -ffeexpr_cb_close_paren_c_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - /* First check to see if this is a possible complex entity. It is if the - token is a comma. */ - - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - { - ffeexpr_stack_->tokens[1] = ffelex_token_use (ft); - ffeexpr_stack_->expr = expr; - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextPAREN_, ffeexpr_cb_comma_c_); - } - - return (ffelexHandler) ffeexpr_cb_close_paren_ (ft, expr, t); -} - -/* ffeexpr_cb_comma_c_ -- OPEN_PAREN expr COMMA expr - - Pass it to ffeexpr_rhs as the callback routine. - - If this token is not a comma, we have a complex constant (or an attempt - at one), so handle it accordingly, displaying error messages if the token - is not a close-paren. */ - -static ffelexHandler -ffeexpr_cb_comma_c_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ e; - ffeinfoBasictype lty = (ffeexpr_stack_->expr == NULL) - ? FFEINFO_basictypeNONE : ffeinfo_basictype (ffebld_info (ffeexpr_stack_->expr)); - ffeinfoBasictype rty = (expr == NULL) - ? FFEINFO_basictypeNONE : ffeinfo_basictype (ffebld_info (expr)); - ffeinfoKindtype lkt; - ffeinfoKindtype rkt; - ffeinfoKindtype nkt; - bool ok = TRUE; - ffebld orig; - - if ((ffeexpr_stack_->expr == NULL) - || (ffebld_op (ffeexpr_stack_->expr) != FFEBLD_opCONTER) - || (((orig = ffebld_conter_orig (ffeexpr_stack_->expr)) != NULL) - && (((ffebld_op (orig) != FFEBLD_opUMINUS) - && (ffebld_op (orig) != FFEBLD_opUPLUS)) - || (ffebld_conter_orig (ffebld_left (orig)) != NULL))) - || ((lty != FFEINFO_basictypeINTEGER) - && (lty != FFEINFO_basictypeREAL))) - { - if ((lty != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_INVALID_COMPLEX_PART)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[1]), - ffelex_token_where_column (ffeexpr_stack_->tokens[1])); - ffebad_string ("Real"); - ffebad_finish (); - } - ok = FALSE; - } - if ((expr == NULL) - || (ffebld_op (expr) != FFEBLD_opCONTER) - || (((orig = ffebld_conter_orig (expr)) != NULL) - && (((ffebld_op (orig) != FFEBLD_opUMINUS) - && (ffebld_op (orig) != FFEBLD_opUPLUS)) - || (ffebld_conter_orig (ffebld_left (orig)) != NULL))) - || ((rty != FFEINFO_basictypeINTEGER) - && (rty != FFEINFO_basictypeREAL))) - { - if ((rty != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_INVALID_COMPLEX_PART)) - { - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_string ("Imaginary"); - ffebad_finish (); - } - ok = FALSE; - } - - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - - /* Push the (parenthesized) expression as an operand onto the expression - stack. */ - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_stack_->tokens[0]; - - if (ok) - { - if (lty == FFEINFO_basictypeINTEGER) - lkt = FFEINFO_kindtypeREALDEFAULT; - else - lkt = ffeinfo_kindtype (ffebld_info (ffeexpr_stack_->expr)); - if (rty == FFEINFO_basictypeINTEGER) - rkt = FFEINFO_kindtypeREALDEFAULT; - else - rkt = ffeinfo_kindtype (ffebld_info (expr)); - - nkt = ffeinfo_kindtype_max (FFEINFO_basictypeCOMPLEX, lkt, rkt); - ffeexpr_stack_->expr = ffeexpr_convert (ffeexpr_stack_->expr, - ffeexpr_stack_->tokens[1], ffeexpr_stack_->tokens[0], - FFEINFO_basictypeREAL, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - expr = ffeexpr_convert (expr, - ffeexpr_stack_->tokens[1], ffeexpr_stack_->tokens[0], - FFEINFO_basictypeREAL, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - } - else - nkt = FFEINFO_kindtypeANY; - - switch (nkt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: - e->u.operand = ffebld_new_conter (ffebld_constant_new_complex1 - (ffebld_conter (ffeexpr_stack_->expr), ffebld_conter (expr))); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeCOMPLEX, nkt, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - break; -#endif - -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: - e->u.operand = ffebld_new_conter (ffebld_constant_new_complex2 - (ffebld_conter (ffeexpr_stack_->expr), ffebld_conter (expr))); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeCOMPLEX, nkt, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - break; -#endif - -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: - e->u.operand = ffebld_new_conter (ffebld_constant_new_complex3 - (ffebld_conter (ffeexpr_stack_->expr), ffebld_conter (expr))); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeCOMPLEX, nkt, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - break; -#endif - -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: - e->u.operand = ffebld_new_conter (ffebld_constant_new_complex4 - (ffebld_conter (ffeexpr_stack_->expr), ffebld_conter (expr))); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeCOMPLEX, nkt, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - break; -#endif - - default: - if (ffebad_start ((nkt == FFEINFO_kindtypeREALDOUBLE) - ? FFEBAD_BAD_DBLCMPLX : FFEBAD_BAD_COMPLEX)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - /* Fall through. */ - case FFEINFO_kindtypeANY: - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - break; - } - ffeexpr_exprstack_push_operand_ (e); - - /* Now, if the token is a close parenthese, we're in great shape so return - the next handler. */ - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_token_binary_; - - /* Oops, naughty user didn't specify the close paren! */ - - if (ffest_ffebad_start (FFEBAD_MISSING_CLOSE_PAREN)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_binary_); -} - -/* ffeexpr_cb_close_paren_ci_ -- OPEN_PAREN expr (possible complex or - implied-DO construct) - - Pass it to ffeexpr_rhs as the callback routine. - - Makes sure the end token is close-paren and swallows it, or a comma - and handles complex/implied-do possibilities, else issues - an error message and doesn't swallow the token (passing it along instead). */ - -static ffelexHandler -ffeexpr_cb_close_paren_ci_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprContext ctx; - - /* First check to see if this is a possible complex or implied-DO entity. - It is if the token is a comma. */ - - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - { - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIMPDOITEM_: - ctx = FFEEXPR_contextIMPDOITEM_; - break; - - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEMDF_: - ctx = FFEEXPR_contextIMPDOITEMDF_; - break; - - default: - assert ("bad context" == NULL); - ctx = FFEEXPR_contextIMPDOITEM_; - break; - } - - ffeexpr_stack_->tokens[0] = ffelex_token_use (ft); - ffeexpr_stack_->expr = expr; - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ctx, ffeexpr_cb_comma_ci_); - } - - ffeexpr_stack_->tokens[0] = ffelex_token_use (ffeexpr_stack_->first_token); - return (ffelexHandler) ffeexpr_cb_close_paren_ (ft, expr, t); -} - -/* ffeexpr_cb_comma_ci_ -- OPEN_PAREN expr COMMA expr - - Pass it to ffeexpr_rhs as the callback routine. - - If this token is not a comma, we have a complex constant (or an attempt - at one), so handle it accordingly, displaying error messages if the token - is not a close-paren. If we have a comma here, it is an attempt at an - implied-DO, so start making a list accordingly. Oh, it might be an - equal sign also, meaning an implied-DO with only one item in its list. */ - -static ffelexHandler -ffeexpr_cb_comma_ci_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffebld fexpr; - - /* First check to see if this is a possible complex constant. It is if the - token is not a comma or an equals sign, in which case it should be a - close-paren. */ - - if ((ffelex_token_type (t) != FFELEX_typeCOMMA) - && (ffelex_token_type (t) != FFELEX_typeEQUALS)) - { - ffeexpr_stack_->tokens[1] = ffeexpr_stack_->tokens[0]; - ffeexpr_stack_->tokens[0] = ffelex_token_use (ffeexpr_stack_->first_token); - return (ffelexHandler) ffeexpr_cb_comma_c_ (ft, expr, t); - } - - /* Here we have either EQUALS or COMMA, meaning we are in an implied-DO - construct. Make a list and handle accordingly. */ - - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - fexpr = ffeexpr_stack_->expr; - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - ffebld_append_item (&ffeexpr_stack_->bottom, fexpr); - return (ffelexHandler) ffeexpr_cb_comma_i_1_ (ft, expr, t); -} - -/* ffeexpr_cb_comma_i_ -- OPEN_PAREN expr - - Pass it to ffeexpr_rhs as the callback routine. - - Handle first item in an implied-DO construct. */ - -static ffelexHandler -ffeexpr_cb_comma_i_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeCOMMA) - { - if (ffest_ffebad_start (FFEBAD_BAD_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - ffeexpr_stack_->expr = ffebld_new_any (); - ffebld_set_info (ffeexpr_stack_->expr, ffeinfo_new_any ()); - if (ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_comma_i_5_ (t); - return (ffelexHandler) ffeexpr_cb_comma_i_5_; - } - - return (ffelexHandler) ffeexpr_cb_comma_i_1_ (ft, expr, t); -} - -/* ffeexpr_cb_comma_i_1_ -- OPEN_PAREN expr - - Pass it to ffeexpr_rhs as the callback routine. - - Handle first item in an implied-DO construct. */ - -static ffelexHandler -ffeexpr_cb_comma_i_1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprContext ctxi; - ffeexprContext ctxc; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - case FFEEXPR_contextDATAIMPDOITEM_: - ctxi = FFEEXPR_contextDATAIMPDOITEM_; - ctxc = FFEEXPR_contextDATAIMPDOCTRL_; - break; - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIMPDOITEM_: - ctxi = FFEEXPR_contextIMPDOITEM_; - ctxc = FFEEXPR_contextIMPDOCTRL_; - break; - - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEMDF_: - ctxi = FFEEXPR_contextIMPDOITEMDF_; - ctxc = FFEEXPR_contextIMPDOCTRL_; - break; - - default: - assert ("bad context" == NULL); - ctxi = FFEEXPR_context; - ctxc = FFEEXPR_context; - break; - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - if (ffeexpr_stack_->is_rhs) - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ctxi, ffeexpr_cb_comma_i_1_); - return (ffelexHandler) ffeexpr_lhs (ffeexpr_stack_->pool, - ctxi, ffeexpr_cb_comma_i_1_); - - case FFELEX_typeEQUALS: - ffebld_end_list (&ffeexpr_stack_->bottom); - - /* Complain if implied-DO variable in list of items to be read. */ - - if ((ctxc == FFEEXPR_contextIMPDOCTRL_) && !ffeexpr_stack_->is_rhs) - ffeexpr_check_impdo_ (ffeexpr_stack_->expr, - ffeexpr_stack_->first_token, expr, ft); - - /* Set doiter flag for all appropriate SYMTERs. */ - - ffeexpr_update_impdo_ (ffeexpr_stack_->expr, expr); - - ffeexpr_stack_->expr = ffebld_new_impdo (ffeexpr_stack_->expr, NULL); - ffebld_set_info (ffeexpr_stack_->expr, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE)); - ffebld_init_list (&(ffebld_right (ffeexpr_stack_->expr)), - &ffeexpr_stack_->bottom); - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ctxc, ffeexpr_cb_comma_i_2_); - - default: - if (ffest_ffebad_start (FFEBAD_BAD_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - ffeexpr_stack_->expr = ffebld_new_any (); - ffebld_set_info (ffeexpr_stack_->expr, ffeinfo_new_any ()); - if (ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_comma_i_5_ (t); - return (ffelexHandler) ffeexpr_cb_comma_i_5_; - } -} - -/* ffeexpr_cb_comma_i_2_ -- OPEN_PAREN expr-list EQUALS expr - - Pass it to ffeexpr_rhs as the callback routine. - - Handle start-value in an implied-DO construct. */ - -static ffelexHandler -ffeexpr_cb_comma_i_2_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - ffeexprContext ctx; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - case FFEEXPR_contextDATAIMPDOITEM_: - ctx = FFEEXPR_contextDATAIMPDOCTRL_; - break; - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - ctx = FFEEXPR_contextIMPDOCTRL_; - break; - - default: - assert ("bad context" == NULL); - ctx = FFEEXPR_context; - break; - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ctx, ffeexpr_cb_comma_i_3_); - break; - - default: - if (ffest_ffebad_start (FFEBAD_BAD_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - ffeexpr_stack_->expr = ffebld_new_any (); - ffebld_set_info (ffeexpr_stack_->expr, ffeinfo_new_any ()); - if (ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_comma_i_5_ (t); - return (ffelexHandler) ffeexpr_cb_comma_i_5_; - } -} - -/* ffeexpr_cb_comma_i_3_ -- OPEN_PAREN expr-list EQUALS expr COMMA expr - - Pass it to ffeexpr_rhs as the callback routine. - - Handle end-value in an implied-DO construct. */ - -static ffelexHandler -ffeexpr_cb_comma_i_3_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - ffeexprContext ctx; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - case FFEEXPR_contextDATAIMPDOITEM_: - ctx = FFEEXPR_contextDATAIMPDOCTRL_; - break; - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - ctx = FFEEXPR_contextIMPDOCTRL_; - break; - - default: - assert ("bad context" == NULL); - ctx = FFEEXPR_context; - break; - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ctx, ffeexpr_cb_comma_i_4_); - break; - - case FFELEX_typeCLOSE_PAREN: - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - return (ffelexHandler) ffeexpr_cb_comma_i_4_ (NULL, NULL, t); - break; - - default: - if (ffest_ffebad_start (FFEBAD_BAD_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - ffeexpr_stack_->expr = ffebld_new_any (); - ffebld_set_info (ffeexpr_stack_->expr, ffeinfo_new_any ()); - if (ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_comma_i_5_ (t); - return (ffelexHandler) ffeexpr_cb_comma_i_5_; - } -} - -/* ffeexpr_cb_comma_i_4_ -- OPEN_PAREN expr-list EQUALS expr COMMA expr - [COMMA expr] - - Pass it to ffeexpr_rhs as the callback routine. - - Handle incr-value in an implied-DO construct. */ - -static ffelexHandler -ffeexpr_cb_comma_i_4_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - ffebld_end_list (&ffeexpr_stack_->bottom); - { - ffebld item; - - for (item = ffebld_left (ffeexpr_stack_->expr); - item != NULL; - item = ffebld_trail (item)) - if (ffebld_op (ffebld_head (item)) == FFEBLD_opANY) - goto replace_with_any; /* :::::::::::::::::::: */ - - for (item = ffebld_right (ffeexpr_stack_->expr); - item != NULL; - item = ffebld_trail (item)) - if ((ffebld_head (item) != NULL) /* Increment may be NULL. */ - && (ffebld_op (ffebld_head (item)) == FFEBLD_opANY)) - goto replace_with_any; /* :::::::::::::::::::: */ - } - break; - - default: - if (ffest_ffebad_start (FFEBAD_BAD_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - - replace_with_any: /* :::::::::::::::::::: */ - - ffeexpr_stack_->expr = ffebld_new_any (); - ffebld_set_info (ffeexpr_stack_->expr, ffeinfo_new_any ()); - break; - } - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_comma_i_5_; - return (ffelexHandler) ffeexpr_cb_comma_i_5_ (t); -} - -/* ffeexpr_cb_comma_i_5_ -- OPEN_PAREN expr-list EQUALS expr COMMA expr - [COMMA expr] CLOSE_PAREN - - Pass it to ffeexpr_rhs as the callback routine. - - Collects token following implied-DO construct for callback function. */ - -static ffelexHandler -ffeexpr_cb_comma_i_5_ (ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - ffebld expr; - bool terminate; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - case FFEEXPR_contextDATAIMPDOITEM_: - terminate = TRUE; - break; - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - terminate = FALSE; - break; - - default: - assert ("bad context" == NULL); - terminate = FALSE; - break; - } - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - expr = ffeexpr_stack_->expr; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, - sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - if (terminate) - { - ffesymbol_drive_sfnames (ffeexpr_check_impctrl_); - --ffeexpr_level_; - if (ffeexpr_level_ == 0) - ffe_terminate_4 (); - } - return (ffelexHandler) next; -} - -/* ffeexpr_cb_end_loc_ -- Handle end of %LOC subexpression - - Makes sure the end token is close-paren and swallows it, else issues - an error message and doesn't swallow the token (passing it along instead). - In either case wraps up subexpression construction by enclosing the - ffebld expression in a %LOC. */ - -static ffelexHandler -ffeexpr_cb_end_loc_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ e; - - /* First push the (%LOC) expression as an operand onto the expression - stack. */ - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_stack_->tokens[0]; - e->u.operand = ffebld_new_percent_loc (expr); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeINTEGER, - ffecom_pointer_kind (), - 0, - FFEINFO_kindENTITY, - FFEINFO_whereFLEETING, - FFETARGET_charactersizeNONE)); -#if 0 /* ~~ */ - e->u.operand = ffeexpr_collapse_percent_loc (e->u.operand, ft); -#endif - ffeexpr_exprstack_push_operand_ (e); - - /* Now, if the token is a close parenthese, we're in great shape so return - the next handler. */ - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - { - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - return (ffelexHandler) ffeexpr_token_binary_; - } - - /* Oops, naughty user didn't specify the close paren! */ - - if (ffest_ffebad_start (FFEBAD_MISSING_CLOSE_PAREN)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[1]), - ffelex_token_where_column (ffeexpr_stack_->tokens[1])); - ffebad_finish (); - } - - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_binary_); -} - -/* ffeexpr_cb_end_notloc_ -- PERCENT NAME(VAL,REF,DESCR) OPEN_PAREN expr - - Should be CLOSE_PAREN, and make sure expr isn't a %(VAL,REF,DESCR). */ - -static ffelexHandler -ffeexpr_cb_end_notloc_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ e; - ffebldOp op; - - /* If expression is itself a %(VAL,REF,DESCR), complain and strip off all - such things until the lowest-level expression is reached. */ - - op = ffebld_op (expr); - if ((op == FFEBLD_opPERCENT_VAL) || (op == FFEBLD_opPERCENT_REF) - || (op == FFEBLD_opPERCENT_DESCR)) - { - if (ffebad_start (FFEBAD_NESTED_PERCENT)) - { - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - - do - { - expr = ffebld_left (expr); - op = ffebld_op (expr); - } - while ((op == FFEBLD_opPERCENT_VAL) || (op == FFEBLD_opPERCENT_REF) - || (op == FFEBLD_opPERCENT_DESCR)); - } - - /* Push the expression as an operand onto the expression stack. */ - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_stack_->tokens[0]; - switch (ffeexpr_stack_->percent) - { - case FFEEXPR_percentVAL_: - e->u.operand = ffebld_new_percent_val (expr); - break; - - case FFEEXPR_percentREF_: - e->u.operand = ffebld_new_percent_ref (expr); - break; - - case FFEEXPR_percentDESCR_: - e->u.operand = ffebld_new_percent_descr (expr); - break; - - default: - assert ("%lossage" == NULL); - e->u.operand = expr; - break; - } - ffebld_set_info (e->u.operand, ffebld_info (expr)); -#if 0 /* ~~ */ - e->u.operand = ffeexpr_collapse_percent_ ? ? ? (e->u.operand, ft); -#endif - ffeexpr_exprstack_push_operand_ (e); - - /* Now, if the token is a close parenthese, we're in great shape so return - the next handler. */ - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_cb_end_notloc_1_; - - /* Oops, naughty user didn't specify the close paren! */ - - if (ffest_ffebad_start (FFEBAD_MISSING_CLOSE_PAREN)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[1]), - ffelex_token_where_column (ffeexpr_stack_->tokens[1])); - ffebad_finish (); - } - - ffebld_set_op (e->u.operand, FFEBLD_opPERCENT_LOC); - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - assert ("bad context?!?!" == NULL); - break; - } - - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_cb_end_notloc_1_); -} - -/* ffeexpr_cb_end_notloc_1_ -- PERCENT NAME(VAL,REF,DESCR) OPEN_PAREN expr - CLOSE_PAREN - - Should be COMMA or CLOSE_PAREN, else change back to %LOC. */ - -static ffelexHandler -ffeexpr_cb_end_notloc_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextSFUNCDEFACTUALARG_: - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARG_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARG_; - break; - - default: - assert ("bad context?!?!" == NULL); - break; - } - break; - - default: - if (ffebad_start (FFEBAD_INVALID_PERCENT)) - { - ffebad_here (0, - ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_string (ffelex_token_text (ffeexpr_stack_->tokens[1])); - ffebad_finish (); - } - - ffebld_set_op (ffeexpr_stack_->exprstack->u.operand, - FFEBLD_opPERCENT_LOC); - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - assert ("bad context?!?!" == NULL); - break; - } - } - - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - return - (ffelexHandler) ffeexpr_token_binary_ (t); -} - -/* Process DATA implied-DO iterator variables as this implied-DO level - terminates. At this point, ffeexpr_level_ == 1 when we see the - last right-paren in "DATA (A(I),I=1,10)/.../". */ - -static ffesymbol -ffeexpr_check_impctrl_ (ffesymbol s) -{ - assert (s != NULL); - assert (ffesymbol_sfdummyparent (s) != NULL); - - switch (ffesymbol_state (s)) - { - case FFESYMBOL_stateNONE: /* Used as iterator already. Now let symbol - be used as iterator at any level at or - innermore than the outermost of the - current level and the symbol's current - level. */ - if (ffeexpr_level_ < ffesymbol_maxentrynum (s)) - { - ffesymbol_signal_change (s); - ffesymbol_set_maxentrynum (s, ffeexpr_level_); - ffesymbol_signal_unreported (s); - } - break; - - case FFESYMBOL_stateSEEN: /* Seen already in this or other implied-DO. - Error if at outermost level, else it can - still become an iterator. */ - if ((ffeexpr_level_ == 1) - && ffebad_start (FFEBAD_BAD_IMPDCL)) - { - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s)); - ffebad_finish (); - } - break; - - case FFESYMBOL_stateUNCERTAIN: /* Iterator. */ - assert (ffeexpr_level_ <= ffesymbol_maxentrynum (s)); - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateNONE); - ffesymbol_signal_unreported (s); - break; - - case FFESYMBOL_stateUNDERSTOOD: - break; /* ANY. */ - - default: - assert ("Sasha Foo!!" == NULL); - break; - } - - return s; -} - -/* Issue diagnostic if implied-DO variable appears in list of lhs - expressions (as in "READ *, (I,I=1,10)"). */ - -static void -ffeexpr_check_impdo_ (ffebld list, ffelexToken list_t, - ffebld dovar, ffelexToken dovar_t) -{ - ffebld item; - ffesymbol dovar_sym; - int itemnum; - - if (ffebld_op (dovar) != FFEBLD_opSYMTER) - return; /* Presumably opANY. */ - - dovar_sym = ffebld_symter (dovar); - - for (itemnum = 1; list != NULL; list = ffebld_trail (list), ++itemnum) - { - if (((item = ffebld_head (list)) != NULL) - && (ffebld_op (item) == FFEBLD_opSYMTER) - && (ffebld_symter (item) == dovar_sym)) - { - char itemno[20]; - - sprintf (&itemno[0], "%d", itemnum); - if (ffebad_start (FFEBAD_DOITER_IMPDO)) - { - ffebad_here (0, ffelex_token_where_line (list_t), - ffelex_token_where_column (list_t)); - ffebad_here (1, ffelex_token_where_line (dovar_t), - ffelex_token_where_column (dovar_t)); - ffebad_string (ffesymbol_text (dovar_sym)); - ffebad_string (itemno); - ffebad_finish (); - } - } - } -} - -/* Decorate any SYMTERs referencing the DO variable with the "doiter" - flag. */ - -static void -ffeexpr_update_impdo_ (ffebld list, ffebld dovar) -{ - ffesymbol dovar_sym; - - if (ffebld_op (dovar) != FFEBLD_opSYMTER) - return; /* Presumably opANY. */ - - dovar_sym = ffebld_symter (dovar); - - ffeexpr_update_impdo_sym_ (list, dovar_sym); /* Recurse! */ -} - -/* Recursive function to update any expr so SYMTERs have "doiter" flag - if they refer to the given variable. */ - -static void -ffeexpr_update_impdo_sym_ (ffebld expr, ffesymbol dovar) -{ - tail_recurse: /* :::::::::::::::::::: */ - - if (expr == NULL) - return; - - switch (ffebld_op (expr)) - { - case FFEBLD_opSYMTER: - if (ffebld_symter (expr) == dovar) - ffebld_symter_set_is_doiter (expr, TRUE); - break; - - case FFEBLD_opITEM: - ffeexpr_update_impdo_sym_ (ffebld_head (expr), dovar); - expr = ffebld_trail (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - default: - break; - } - - switch (ffebld_arity (expr)) - { - case 2: - ffeexpr_update_impdo_sym_ (ffebld_left (expr), dovar); - expr = ffebld_right (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - case 1: - expr = ffebld_left (expr); - goto tail_recurse; /* :::::::::::::::::::: */ - - default: - break; - } - - return; -} - -/* ffeexpr_context_outer_ -- Determine context of stack entry, skipping PARENs - - if (ffeexpr_context_outer_(ffeexpr_stack_) == FFEEXPR_contextIF) - // After zero or more PAREN_ contexts, an IF context exists */ - -static ffeexprContext -ffeexpr_context_outer_ (ffeexprStack_ s) -{ - assert (s != NULL); - - for (;;) - { - switch (s->context) - { - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextPARENFILENUM_: - case FFEEXPR_contextPARENFILEUNIT_: - break; - - default: - return s->context; - } - s = s->previous; - assert (s != NULL); - } -} - -/* ffeexpr_percent_ -- Look up name in list of %FOO possibilities - - ffeexprPercent_ p; - ffelexToken t; - p = ffeexpr_percent_(t); - - Returns the identifier for the name, or the NONE identifier. */ - -static ffeexprPercent_ -ffeexpr_percent_ (ffelexToken t) -{ - char *p; - - switch (ffelex_token_length (t)) - { - case 3: - switch (*(p = ffelex_token_text (t))) - { - case FFESRC_CASE_MATCH_INIT ('L', 'l', match_3l, no_match_3): - if ((ffesrc_char_match_noninit (*++p, 'O', 'o')) - && (ffesrc_char_match_noninit (*++p, 'C', 'c'))) - return FFEEXPR_percentLOC_; - return FFEEXPR_percentNONE_; - - case FFESRC_CASE_MATCH_INIT ('R', 'r', match_3r, no_match_3): - if ((ffesrc_char_match_noninit (*++p, 'E', 'e')) - && (ffesrc_char_match_noninit (*++p, 'F', 'f'))) - return FFEEXPR_percentREF_; - return FFEEXPR_percentNONE_; - - case FFESRC_CASE_MATCH_INIT ('V', 'v', match_3v, no_match_3): - if ((ffesrc_char_match_noninit (*++p, 'A', 'a')) - && (ffesrc_char_match_noninit (*++p, 'L', 'l'))) - return FFEEXPR_percentVAL_; - return FFEEXPR_percentNONE_; - - default: - no_match_3: /* :::::::::::::::::::: */ - return FFEEXPR_percentNONE_; - } - - case 5: - if (ffesrc_strcmp_2c (ffe_case_match (), ffelex_token_text (t), "DESCR", - "descr", "Descr") == 0) - return FFEEXPR_percentDESCR_; - return FFEEXPR_percentNONE_; - - default: - return FFEEXPR_percentNONE_; - } -} - -/* ffeexpr_type_combine -- Binop combine types, check for mythical new COMPLEX - - See prototype. - - If combining the two basictype/kindtype pairs produces a COMPLEX with an - unsupported kind type, complain and use the default kind type for - COMPLEX. */ - -void -ffeexpr_type_combine (ffeinfoBasictype *xnbt, ffeinfoKindtype *xnkt, - ffeinfoBasictype lbt, ffeinfoKindtype lkt, - ffeinfoBasictype rbt, ffeinfoKindtype rkt, - ffelexToken t) -{ - ffeinfoBasictype nbt; - ffeinfoKindtype nkt; - - nbt = ffeinfo_basictype_combine (lbt, rbt); - if ((nbt == FFEINFO_basictypeCOMPLEX) - && ((lbt == nbt) || (lbt == FFEINFO_basictypeREAL)) - && ((rbt == nbt) || (rbt == FFEINFO_basictypeREAL))) - { - nkt = ffeinfo_kindtype_max (nbt, lkt, rkt); - if (ffe_is_pedantic_not_90 () && (nkt == FFEINFO_kindtypeREALDOUBLE)) - nkt = FFEINFO_kindtypeNONE; /* Force error. */ - switch (nkt) - { -#if FFETARGET_okCOMPLEX1 - case FFEINFO_kindtypeREAL1: -#endif -#if FFETARGET_okCOMPLEX2 - case FFEINFO_kindtypeREAL2: -#endif -#if FFETARGET_okCOMPLEX3 - case FFEINFO_kindtypeREAL3: -#endif -#if FFETARGET_okCOMPLEX4 - case FFEINFO_kindtypeREAL4: -#endif - break; /* Fine and dandy. */ - - default: - if (t != NULL) - { - ffebad_start ((nkt == FFEINFO_kindtypeREALDOUBLE) - ? FFEBAD_BAD_DBLCMPLX : FFEBAD_BAD_COMPLEX); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - nbt = FFEINFO_basictypeNONE; - nkt = FFEINFO_kindtypeNONE; - break; - - case FFEINFO_kindtypeANY: - nkt = FFEINFO_kindtypeREALDEFAULT; - break; - } - } - else - { /* The normal stuff. */ - if (nbt == lbt) - { - if (nbt == rbt) - nkt = ffeinfo_kindtype_max (nbt, lkt, rkt); - else - nkt = lkt; - } - else if (nbt == rbt) - nkt = rkt; - else - { /* Let the caller do the complaining. */ - nbt = FFEINFO_basictypeNONE; - nkt = FFEINFO_kindtypeNONE; - } - } - - /* Always a good idea to avoid aliasing problems. */ - - *xnbt = nbt; - *xnkt = nkt; -} - -/* ffeexpr_token_first_lhs_ -- First state for lhs expression - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Record line and column of first token in expression, then invoke the - initial-state lhs handler. */ - -static ffelexHandler -ffeexpr_token_first_lhs_ (ffelexToken t) -{ - ffeexpr_stack_->first_token = ffelex_token_use (t); - - /* When changing the list of valid initial lhs tokens, check whether to - update a corresponding list in ffeexpr_cb_close_paren_ambig_1_ for the - READ (expr) <token> case -- it assumes it knows which tokens <token> can - be to indicate an lhs (or implied DO), which right now is the set - {NAME,OPEN_PAREN}. - - This comment also appears in ffeexpr_token_lhs_. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - ffe_init_4 (); - ffeexpr_level_ = 1; /* Level of DATA implied-DO construct. */ - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return (ffelexHandler) ffeexpr_lhs (ffeexpr_stack_->pool, - FFEEXPR_contextDATAIMPDOITEM_, ffeexpr_cb_comma_i_); - - case FFEEXPR_contextDATAIMPDOITEM_: - ++ffeexpr_level_; /* Level of DATA implied-DO construct. */ - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return (ffelexHandler) ffeexpr_lhs (ffeexpr_stack_->pool, - FFEEXPR_contextDATAIMPDOITEM_, ffeexpr_cb_comma_i_); - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIMPDOITEM_: - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return (ffelexHandler) ffeexpr_lhs (ffeexpr_stack_->pool, - FFEEXPR_contextIMPDOITEM_, ffeexpr_cb_comma_i_); - - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEMDF_: - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return (ffelexHandler) ffeexpr_lhs (ffeexpr_stack_->pool, - FFEEXPR_contextIMPDOITEMDF_, ffeexpr_cb_comma_i_); - - case FFEEXPR_contextFILEEXTFUNC: - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_lhs_1_; - - default: - break; - } - break; - - case FFELEX_typeNAME: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILENAMELIST: - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_namelist_; - - case FFEEXPR_contextFILEEXTFUNC: - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_lhs_1_; - - default: - break; - } - break; - - default: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILEEXTFUNC: - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_lhs_1_; - - default: - break; - } - break; - } - - return (ffelexHandler) ffeexpr_token_lhs_ (t); -} - -/* ffeexpr_token_first_lhs_1_ -- NAME - - return ffeexpr_token_first_lhs_1_; // to lexer - - Handle NAME as an external function (USEROPEN= VXT extension to OPEN - statement). */ - -static ffelexHandler -ffeexpr_token_first_lhs_1_ (ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - ffesymbol sy = NULL; - ffebld expr; - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - s = ffeexpr_stack_->previous; - - if ((ffelex_token_type (ft) != FFELEX_typeNAME) - || (ffesymbol_attrs (sy = ffeexpr_declare_unadorned_ (ft, FALSE)) - & FFESYMBOL_attrANY)) - { - if ((ffelex_token_type (ft) != FFELEX_typeNAME) - || !(ffesymbol_attrs (sy) & FFESYMBOL_attrsANY)) - { - ffebad_start (FFEBAD_EXPR_WRONG); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - expr = ffebld_new_any (); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - else - { - expr = ffebld_new_symter (sy, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (expr, ffesymbol_info (sy)); - } - - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, - sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_token_first_rhs_ -- First state for rhs expression - - Record line and column of first token in expression, then invoke the - initial-state rhs handler. - - 19-Feb-91 JCB 1.1 - Allow ASTERISK in PARENFILEUNIT_ case, but only on second level only - (i.e. only as in READ(*), not READ((*))). */ - -static ffelexHandler -ffeexpr_token_first_rhs_ (ffelexToken t) -{ - ffesymbol s; - - ffeexpr_stack_->first_token = ffelex_token_use (t); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeASTERISK: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILEFORMATNML: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - /* Fall through. */ - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextCHARACTERSIZE: - if (ffeexpr_stack_->previous != NULL) - break; /* Valid only on first level. */ - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_rhs_1_; - - case FFEEXPR_contextPARENFILEUNIT_: - if (ffeexpr_stack_->previous->previous != NULL) - break; /* Valid only on second level. */ - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_rhs_1_; - - case FFEEXPR_contextACTUALARG_: - if (ffeexpr_stack_->previous->context - != FFEEXPR_contextSUBROUTINEREF) - { - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - } - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_rhs_3_; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - break; - } - break; - - case FFELEX_typeOPEN_PAREN: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILENUMAMBIG: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextPARENFILENUM_, - ffeexpr_cb_close_paren_ambig_); - - case FFEEXPR_contextFILEUNITAMBIG: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextPARENFILEUNIT_, - ffeexpr_cb_close_paren_ambig_); - - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIMPDOITEM_: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextIMPDOITEM_, - ffeexpr_cb_close_paren_ci_); - - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextIMPDOITEMDF_: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextIMPDOITEMDF_, - ffeexpr_cb_close_paren_ci_); - - case FFEEXPR_contextFILEFORMATNML: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - break; - - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - break; - } - break; - - case FFELEX_typeNUMBER: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILEFORMATNML: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - /* Fall through. */ - case FFEEXPR_contextFILEFORMAT: - if (ffeexpr_stack_->previous != NULL) - break; /* Valid only on first level. */ - assert (ffeexpr_stack_->exprstack == NULL); - return (ffelexHandler) ffeexpr_token_first_rhs_2_; - - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - break; - } - break; - - case FFELEX_typeNAME: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILEFORMATNML: - assert (ffeexpr_stack_->exprstack == NULL); - s = ffesymbol_lookup_local (t); - if ((s != NULL) && (ffesymbol_kind (s) == FFEINFO_kindNAMELIST)) - return (ffelexHandler) ffeexpr_token_namelist_; - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - break; - - default: - break; - } - break; - - case FFELEX_typePERCENT: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextINDEXORACTUALARG_: - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - return (ffelexHandler) ffeexpr_token_first_rhs_5_; - - case FFEEXPR_contextFILEFORMATNML: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - break; - - default: - break; - } - - default: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextFILEFORMATNML: - ffeexpr_stack_->context = FFEEXPR_contextFILEFORMAT; - break; - - default: - break; - } - break; - } - - return (ffelexHandler) ffeexpr_token_rhs_ (t); -} - -/* ffeexpr_token_first_rhs_1_ -- ASTERISK - - return ffeexpr_token_first_rhs_1_; // to lexer - - Return STAR as expression. */ - -static ffelexHandler -ffeexpr_token_first_rhs_1_ (ffelexToken t) -{ - ffebld expr; - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - - expr = ffebld_new_star (); - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_token_first_rhs_2_ -- NUMBER - - return ffeexpr_token_first_rhs_2_; // to lexer - - Return NULL as expression; NUMBER as first (and only) token, unless the - current token is not a terminating token, in which case run normal - expression handling. */ - -static ffelexHandler -ffeexpr_token_first_rhs_2_ (ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - next = (ffelexHandler) ffeexpr_token_rhs_ (ffeexpr_stack_->first_token); - return (ffelexHandler) (*next) (t); - } - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, - sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (ft, NULL, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_token_first_rhs_3_ -- ASTERISK - - return ffeexpr_token_first_rhs_3_; // to lexer - - Expect NUMBER, make LABTOK (with copy of token if not inhibited after - confirming, else NULL). */ - -static ffelexHandler -ffeexpr_token_first_rhs_3_ (ffelexToken t) -{ - ffelexHandler next; - - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { /* An error, but let normal processing handle - it. */ - next = (ffelexHandler) ffeexpr_token_rhs_ (ffeexpr_stack_->first_token); - return (ffelexHandler) (*next) (t); - } - - /* Special case: when we see "*10" as an argument to a subroutine - reference, we confirm the current statement and, if not inhibited at - this point, put a copy of the token into a LABTOK node. We do this - instead of just resolving the label directly via ffelab and putting it - into a LABTER simply to improve error reporting and consistency in - ffestc. We put NULL in the LABTOK if we're still inhibited, so ffestb - doesn't have to worry about killing off any tokens when retracting. */ - - ffest_confirmed (); - if (ffest_is_inhibited ()) - ffeexpr_stack_->expr = ffebld_new_labtok (NULL); - else - ffeexpr_stack_->expr = ffebld_new_labtok (ffelex_token_use (t)); - ffebld_set_info (ffeexpr_stack_->expr, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE)); - - return (ffelexHandler) ffeexpr_token_first_rhs_4_; -} - -/* ffeexpr_token_first_rhs_4_ -- ASTERISK NUMBER - - return ffeexpr_token_first_rhs_4_; // to lexer - - Collect/flush appropriate stuff, send token to callback function. */ - -static ffelexHandler -ffeexpr_token_first_rhs_4_ (ffelexToken t) -{ - ffebld expr; - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - - expr = ffeexpr_stack_->expr; - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_token_first_rhs_5_ -- PERCENT - - Should be NAME, or pass through original mechanism. If NAME is LOC, - pass through original mechanism, otherwise must be VAL, REF, or DESCR, - in which case handle the argument (in parentheses), etc. */ - -static ffelexHandler -ffeexpr_token_first_rhs_5_ (ffelexToken t) -{ - ffelexHandler next; - - if (ffelex_token_type (t) == FFELEX_typeNAME) - { - ffeexprPercent_ p = ffeexpr_percent_ (t); - - switch (p) - { - case FFEEXPR_percentNONE_: - case FFEEXPR_percentLOC_: - break; /* Treat %LOC as any other expression. */ - - case FFEEXPR_percentVAL_: - case FFEEXPR_percentREF_: - case FFEEXPR_percentDESCR_: - ffeexpr_stack_->percent = p; - ffeexpr_stack_->tokens[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_first_rhs_6_; - - default: - assert ("bad percent?!?" == NULL); - break; - } - } - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - assert ("bad context?!?!" == NULL); - break; - } - - next = (ffelexHandler) ffeexpr_token_rhs_ (ffeexpr_stack_->first_token); - return (ffelexHandler) (*next) (t); -} - -/* ffeexpr_token_first_rhs_6_ -- PERCENT NAME(VAL,REF,DESCR) - - Should be OPEN_PAREN, or pass through original mechanism. */ - -static ffelexHandler -ffeexpr_token_first_rhs_6_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken ft; - - if (ffelex_token_type (t) == FFELEX_typeOPEN_PAREN) - { - ffeexpr_stack_->tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - ffeexpr_stack_->context, - ffeexpr_cb_end_notloc_); - } - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - assert ("bad context?!?!" == NULL); - break; - } - - ft = ffeexpr_stack_->tokens[0]; - next = (ffelexHandler) ffeexpr_token_rhs_ (ffeexpr_stack_->first_token); - next = (ffelexHandler) (*next) (ft); - ffelex_token_kill (ft); - return (ffelexHandler) (*next) (t); -} - -/* ffeexpr_token_namelist_ -- NAME - - return ffeexpr_token_namelist_; // to lexer - - Make sure NAME was a valid namelist object, wrap it in a SYMTER and - return. */ - -static ffelexHandler -ffeexpr_token_namelist_ (ffelexToken t) -{ - ffeexprCallback callback; - ffeexprStack_ s; - ffelexHandler next; - ffelexToken ft; - ffesymbol sy; - ffebld expr; - - ffebld_pool_pop (); - callback = ffeexpr_stack_->callback; - ft = ffeexpr_stack_->first_token; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - - sy = ffesymbol_lookup_local (ft); - if ((sy == NULL) || (ffesymbol_kind (sy) != FFEINFO_kindNAMELIST)) - { - ffebad_start (FFEBAD_EXPR_WRONG); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - expr = ffebld_new_any (); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - else - { - expr = ffebld_new_symter (sy, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (expr, ffesymbol_info (sy)); - } - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_expr_kill_ -- Kill an existing internal expression object - - ffeexprExpr_ e; - ffeexpr_expr_kill_(e); - - Kills the ffewhere info, if necessary, then kills the object. */ - -static void -ffeexpr_expr_kill_ (ffeexprExpr_ e) -{ - if (e->token != NULL) - ffelex_token_kill (e->token); - malloc_kill_ks (ffe_pool_program_unit (), e, sizeof (*e)); -} - -/* ffeexpr_expr_new_ -- Make a new internal expression object - - ffeexprExpr_ e; - e = ffeexpr_expr_new_(); - - Allocates and initializes a new expression object, returns it. */ - -static ffeexprExpr_ -ffeexpr_expr_new_ () -{ - ffeexprExpr_ e; - - e = (ffeexprExpr_) malloc_new_ks (ffe_pool_program_unit (), "FFEEXPR expr", - sizeof (*e)); - e->previous = NULL; - e->type = FFEEXPR_exprtypeUNKNOWN_; - e->token = NULL; - return e; -} - -/* Verify that call to global is valid, and register whatever - new information about a global might be discoverable by looking - at the call. */ - -static void -ffeexpr_fulfill_call_ (ffebld *expr, ffelexToken t) -{ - int n_args; - ffebld list; - ffebld item; - ffesymbol s; - - assert ((ffebld_op (*expr) == FFEBLD_opSUBRREF) - || (ffebld_op (*expr) == FFEBLD_opFUNCREF)); - - if (ffebld_op (ffebld_left (*expr)) != FFEBLD_opSYMTER) - return; - - if (ffesymbol_retractable ()) - return; - - s = ffebld_symter (ffebld_left (*expr)); - if (ffesymbol_global (s) == NULL) - return; - - for (n_args = 0, list = ffebld_right (*expr); - list != NULL; - list = ffebld_trail (list), ++n_args) - ; - - if (ffeglobal_proc_ref_nargs (s, n_args, t)) - { - ffeglobalArgSummary as; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - bool array; - bool fail = FALSE; - - for (n_args = 0, list = ffebld_right (*expr); - list != NULL; - list = ffebld_trail (list), ++n_args) - { - item = ffebld_head (list); - if (item != NULL) - { - bt = ffeinfo_basictype (ffebld_info (item)); - kt = ffeinfo_kindtype (ffebld_info (item)); - array = (ffeinfo_rank (ffebld_info (item)) > 0); - switch (ffebld_op (item)) - { - case FFEBLD_opLABTOK: - case FFEBLD_opLABTER: - as = FFEGLOBAL_argsummaryALTRTN; - break; - -#if 0 - /* No, %LOC(foo) is just like any INTEGER(KIND=7) - expression, so don't treat it specially. */ - case FFEBLD_opPERCENT_LOC: - as = FFEGLOBAL_argsummaryPTR; - break; -#endif - - case FFEBLD_opPERCENT_VAL: - as = FFEGLOBAL_argsummaryVAL; - break; - - case FFEBLD_opPERCENT_REF: - as = FFEGLOBAL_argsummaryREF; - break; - - case FFEBLD_opPERCENT_DESCR: - as = FFEGLOBAL_argsummaryDESCR; - break; - - case FFEBLD_opFUNCREF: -#if 0 - /* No, LOC(foo) is just like any INTEGER(KIND=7) - expression, so don't treat it specially. */ - if ((ffebld_op (ffebld_left (item)) == FFEBLD_opSYMTER) - && (ffesymbol_specific (ffebld_symter (ffebld_left (item))) - == FFEINTRIN_specLOC)) - { - as = FFEGLOBAL_argsummaryPTR; - break; - } -#endif - /* Fall through. */ - default: - if (ffebld_op (item) == FFEBLD_opSYMTER) - { - as = FFEGLOBAL_argsummaryNONE; - - switch (ffeinfo_kind (ffebld_info (item))) - { - case FFEINFO_kindFUNCTION: - as = FFEGLOBAL_argsummaryFUNC; - break; - - case FFEINFO_kindSUBROUTINE: - as = FFEGLOBAL_argsummarySUBR; - break; - - case FFEINFO_kindNONE: - as = FFEGLOBAL_argsummaryPROC; - break; - - default: - break; - } - - if (as != FFEGLOBAL_argsummaryNONE) - break; - } - - if (bt == FFEINFO_basictypeCHARACTER) - as = FFEGLOBAL_argsummaryDESCR; - else - as = FFEGLOBAL_argsummaryREF; - break; - } - } - else - { - array = FALSE; - as = FFEGLOBAL_argsummaryNONE; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - } - - if (! ffeglobal_proc_ref_arg (s, n_args, as, bt, kt, array, t)) - fail = TRUE; - } - if (! fail) - return; - } - - *expr = ffebld_new_any (); - ffebld_set_info (*expr, ffeinfo_new_any ()); -} - -/* Check whether rest of string is all decimal digits. */ - -static bool -ffeexpr_isdigits_ (char *p) -{ - for (; *p != '\0'; ++p) - if (! ISDIGIT (*p)) - return FALSE; - return TRUE; -} - -/* ffeexpr_exprstack_push_ -- Push an arbitrary expression object onto the stack - - ffeexprExpr_ e; - ffeexpr_exprstack_push_(e); - - Pushes the expression onto the stack without any analysis of the existing - contents of the stack. */ - -static void -ffeexpr_exprstack_push_ (ffeexprExpr_ e) -{ - e->previous = ffeexpr_stack_->exprstack; - ffeexpr_stack_->exprstack = e; -} - -/* ffeexpr_exprstack_push_operand_ -- Push an operand onto the stack, reduce? - - ffeexprExpr_ e; - ffeexpr_exprstack_push_operand_(e); - - Pushes the expression already containing an operand (a constant, variable, - or more complicated expression that has already been fully resolved) after - analyzing the stack and checking for possible reduction (which will never - happen here since the highest precedence operator is ** and it has right- - to-left associativity). */ - -static void -ffeexpr_exprstack_push_operand_ (ffeexprExpr_ e) -{ - ffeexpr_exprstack_push_ (e); -#ifdef WEIRD_NONFORTRAN_RULES - if ((ffeexpr_stack_->exprstack != NULL) - && (ffeexpr_stack_->exprstack->expr->type == FFEEXPR_exprtypeBINARY_) - && (ffeexpr_stack_->exprstack->expr->u.operator.prec - == FFEEXPR_operatorprecedenceHIGHEST_) - && (ffeexpr_stack_->exprstack->expr->u.operator.as - == FFEEXPR_operatorassociativityL2R_)) - ffeexpr_reduce_ (); -#endif -} - -/* ffeexpr_exprstack_push_unary_ -- Push a unary operator onto the stack - - ffeexprExpr_ e; - ffeexpr_exprstack_push_unary_(e); - - Pushes the expression already containing a unary operator. Reduction can - never happen since unary operators are themselves always R-L; that is, the - top of the expression stack is not an operand, in that it is either empty, - has a binary operator at the top, or a unary operator at the top. In any - of these cases, reduction is impossible. */ - -static void -ffeexpr_exprstack_push_unary_ (ffeexprExpr_ e) -{ - if ((ffe_is_pedantic () - || ffe_is_warn_surprising ()) - && (ffeexpr_stack_->exprstack != NULL) - && (ffeexpr_stack_->exprstack->type != FFEEXPR_exprtypeOPERAND_) - && (ffeexpr_stack_->exprstack->u.operator.prec - <= FFEEXPR_operatorprecedenceLOWARITH_) - && (e->u.operator.prec <= FFEEXPR_operatorprecedenceLOWARITH_)) - { - ffebad_start_msg ("Two arithmetic operators in a row at %0 and %1 -- use parentheses", - ffe_is_pedantic () - ? FFEBAD_severityPEDANTIC - : FFEBAD_severityWARNING); - ffebad_here (0, - ffelex_token_where_line (ffeexpr_stack_->exprstack->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); - ffebad_here (1, - ffelex_token_where_line (e->token), - ffelex_token_where_column (e->token)); - ffebad_finish (); - } - - ffeexpr_exprstack_push_ (e); -} - -/* ffeexpr_exprstack_push_binary_ -- Push a binary operator onto the stack, reduce? - - ffeexprExpr_ e; - ffeexpr_exprstack_push_binary_(e); - - Pushes the expression already containing a binary operator after checking - whether reduction is possible. If the stack is not empty, the top of the - stack must be an operand or syntactic analysis has failed somehow. If - the operand is preceded by a unary operator of higher (or equal and L-R - associativity) precedence than the new binary operator, then reduce that - preceding operator and its operand(s) before pushing the new binary - operator. */ - -static void -ffeexpr_exprstack_push_binary_ (ffeexprExpr_ e) -{ - ffeexprExpr_ ce; - - if (ffe_is_warn_surprising () - /* These next two are always true (see assertions below). */ - && (ffeexpr_stack_->exprstack != NULL) - && (ffeexpr_stack_->exprstack->type == FFEEXPR_exprtypeOPERAND_) - /* If the previous operator is a unary minus, and the binary op - is of higher precedence, might not do what user expects, - e.g. "-2**2" is "-(2**2)", i.e. "-4", not "(-2)**2", which would - yield "4". */ - && (ffeexpr_stack_->exprstack->previous != NULL) - && (ffeexpr_stack_->exprstack->previous->type == FFEEXPR_exprtypeUNARY_) - && (ffeexpr_stack_->exprstack->previous->u.operator.op - == FFEEXPR_operatorSUBTRACT_) - && (e->u.operator.prec - < ffeexpr_stack_->exprstack->previous->u.operator.prec)) - { - ffebad_start_msg ("Operator at %0 has lower precedence than that at %1 -- use parentheses", FFEBAD_severityWARNING); - ffebad_here (0, - ffelex_token_where_line (ffeexpr_stack_->exprstack->previous->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->previous->token)); - ffebad_here (1, - ffelex_token_where_line (e->token), - ffelex_token_where_column (e->token)); - ffebad_finish (); - } - -again: - assert (ffeexpr_stack_->exprstack != NULL); - assert (ffeexpr_stack_->exprstack->type == FFEEXPR_exprtypeOPERAND_); - if ((ce = ffeexpr_stack_->exprstack->previous) != NULL) - { - assert (ce->type != FFEEXPR_exprtypeOPERAND_); - if ((ce->u.operator.prec < e->u.operator.prec) - || ((ce->u.operator.prec == e->u.operator.prec) - && (e->u.operator.as == FFEEXPR_operatorassociativityL2R_))) - { - ffeexpr_reduce_ (); - goto again; /* :::::::::::::::::::: */ - } - } - - ffeexpr_exprstack_push_ (e); -} - -/* ffeexpr_reduce_ -- Reduce highest operator w/operands on stack - - ffeexpr_reduce_(); - - Converts operand binop operand or unop operand at top of stack to a - single operand having the appropriate ffebld expression, and makes - sure that the expression is proper (like not trying to add two character - variables, not trying to concatenate two numbers). Also does the - requisite type-assignment. */ - -static void -ffeexpr_reduce_ () -{ - ffeexprExpr_ operand; /* This is B in -B or A+B. */ - ffeexprExpr_ left_operand; /* When operator is binary, this is A in A+B. */ - ffeexprExpr_ operator; /* This is + in A+B. */ - ffebld reduced; /* This is +(A,B) in A+B or u-(B) in -B. */ - ffebldConstant constnode; /* For checking magical numbers (where mag == - -mag). */ - ffebld expr; - ffebld left_expr; - bool submag = FALSE; - - operand = ffeexpr_stack_->exprstack; - assert (operand != NULL); - assert (operand->type == FFEEXPR_exprtypeOPERAND_); - operator = operand->previous; - assert (operator != NULL); - assert (operator->type != FFEEXPR_exprtypeOPERAND_); - if (operator->type == FFEEXPR_exprtypeUNARY_) - { - expr = operand->u.operand; - switch (operator->u.operator.op) - { - case FFEEXPR_operatorADD_: - reduced = ffebld_new_uplus (expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly1_ (reduced, operator, operand); - reduced = ffeexpr_reduced_math1_ (reduced, operator, operand); - reduced = ffeexpr_collapse_uplus (reduced, operator->token); - break; - - case FFEEXPR_operatorSUBTRACT_: - submag = TRUE; /* Ok to negate a magic number. */ - reduced = ffebld_new_uminus (expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly1_ (reduced, operator, operand); - reduced = ffeexpr_reduced_math1_ (reduced, operator, operand); - reduced = ffeexpr_collapse_uminus (reduced, operator->token); - break; - - case FFEEXPR_operatorNOT_: - reduced = ffebld_new_not (expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly1log_ (reduced, operator, operand); - reduced = ffeexpr_reduced_bool1_ (reduced, operator, operand); - reduced = ffeexpr_collapse_not (reduced, operator->token); - break; - - default: - assert ("unexpected unary op" != NULL); - reduced = NULL; - break; - } - if (!submag - && (ffebld_op (expr) == FFEBLD_opCONTER) - && (ffebld_conter_orig (expr) == NULL) - && ffebld_constant_is_magical (constnode = ffebld_conter (expr))) - { - ffetarget_integer_bad_magical (operand->token); - } - ffeexpr_stack_->exprstack = operator->previous; /* Pops unary-op operand - off stack. */ - ffeexpr_expr_kill_ (operand); - operator->type = FFEEXPR_exprtypeOPERAND_; /* Convert operator, but - save */ - operator->u.operand = reduced; /* the line/column ffewhere info. */ - ffeexpr_exprstack_push_operand_ (operator); /* Push it back on - stack. */ - } - else - { - assert (operator->type == FFEEXPR_exprtypeBINARY_); - left_operand = operator->previous; - assert (left_operand != NULL); - assert (left_operand->type == FFEEXPR_exprtypeOPERAND_); - expr = operand->u.operand; - left_expr = left_operand->u.operand; - switch (operator->u.operator.op) - { - case FFEEXPR_operatorADD_: - reduced = ffebld_new_add (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_math2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_add (reduced, operator->token); - break; - - case FFEEXPR_operatorSUBTRACT_: - submag = TRUE; /* Just to pick the right error if magic - number. */ - reduced = ffebld_new_subtract (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_math2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_subtract (reduced, operator->token); - break; - - case FFEEXPR_operatorMULTIPLY_: - reduced = ffebld_new_multiply (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_math2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_multiply (reduced, operator->token); - break; - - case FFEEXPR_operatorDIVIDE_: - reduced = ffebld_new_divide (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_math2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_divide (reduced, operator->token); - break; - - case FFEEXPR_operatorPOWER_: - reduced = ffebld_new_power (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_power_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_power (reduced, operator->token); - break; - - case FFEEXPR_operatorCONCATENATE_: - reduced = ffebld_new_concatenate (left_expr, expr); - reduced = ffeexpr_reduced_concatenate_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_concatenate (reduced, operator->token); - break; - - case FFEEXPR_operatorLT_: - reduced = ffebld_new_lt (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_relop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_lt (reduced, operator->token); - break; - - case FFEEXPR_operatorLE_: - reduced = ffebld_new_le (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_relop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_le (reduced, operator->token); - break; - - case FFEEXPR_operatorEQ_: - reduced = ffebld_new_eq (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_eqop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_eq (reduced, operator->token); - break; - - case FFEEXPR_operatorNE_: - reduced = ffebld_new_ne (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_eqop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_ne (reduced, operator->token); - break; - - case FFEEXPR_operatorGT_: - reduced = ffebld_new_gt (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_relop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_gt (reduced, operator->token); - break; - - case FFEEXPR_operatorGE_: - reduced = ffebld_new_ge (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_relop2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_ge (reduced, operator->token); - break; - - case FFEEXPR_operatorAND_: - reduced = ffebld_new_and (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_and (reduced, operator->token); - break; - - case FFEEXPR_operatorOR_: - reduced = ffebld_new_or (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_or (reduced, operator->token); - break; - - case FFEEXPR_operatorXOR_: - reduced = ffebld_new_xor (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_xor (reduced, operator->token); - break; - - case FFEEXPR_operatorEQV_: - reduced = ffebld_new_eqv (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_eqv (reduced, operator->token); - break; - - case FFEEXPR_operatorNEQV_: - reduced = ffebld_new_neqv (left_expr, expr); - if (ffe_is_ugly_logint ()) - reduced = ffeexpr_reduced_ugly2log_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_reduced_bool2_ (reduced, left_operand, operator, - operand); - reduced = ffeexpr_collapse_neqv (reduced, operator->token); - break; - - default: - assert ("bad bin op" == NULL); - reduced = expr; - break; - } - if ((ffebld_op (left_expr) == FFEBLD_opCONTER) - && (ffebld_conter_orig (expr) == NULL) - && ffebld_constant_is_magical (constnode = ffebld_conter (left_expr))) - { - if ((left_operand->previous != NULL) - && (left_operand->previous->type != FFEEXPR_exprtypeOPERAND_) - && (left_operand->previous->u.operator.op - == FFEEXPR_operatorSUBTRACT_)) - { - if (left_operand->previous->type == FFEEXPR_exprtypeUNARY_) - ffetarget_integer_bad_magical_precedence (left_operand->token, - left_operand->previous->token, - operator->token); - else - ffetarget_integer_bad_magical_precedence_binary - (left_operand->token, - left_operand->previous->token, - operator->token); - } - else - ffetarget_integer_bad_magical (left_operand->token); - } - if ((ffebld_op (expr) == FFEBLD_opCONTER) - && (ffebld_conter_orig (expr) == NULL) - && ffebld_constant_is_magical (constnode = ffebld_conter (expr))) - { - if (submag) - ffetarget_integer_bad_magical_binary (operand->token, - operator->token); - else - ffetarget_integer_bad_magical (operand->token); - } - ffeexpr_stack_->exprstack = left_operand->previous; /* Pops binary-op - operands off stack. */ - ffeexpr_expr_kill_ (left_operand); - ffeexpr_expr_kill_ (operand); - operator->type = FFEEXPR_exprtypeOPERAND_; /* Convert operator, but - save */ - operator->u.operand = reduced; /* the line/column ffewhere info. */ - ffeexpr_exprstack_push_operand_ (operator); /* Push it back on - stack. */ - } -} - -/* ffeexpr_reduced_bool1_ -- Wrap up reduction of NOT operator - - reduced = ffeexpr_reduced_bool1_(reduced,op,r); - - Makes sure the argument for reduced has basictype of - LOGICAL or (ugly) INTEGER. If - argument has where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_bool1_ (ffebld reduced, ffeexprExpr_ op, ffeexprExpr_ r) -{ - ffeinfo rinfo, ninfo; - ffeinfoBasictype rbt; - ffeinfoKindtype rkt; - ffeinfoRank rrk; - ffeinfoKind rkd; - ffeinfoWhere rwh, nwh; - - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if (((rbt == FFEINFO_basictypeLOGICAL) - || (ffe_is_ugly_logint () && (rbt == FFEINFO_basictypeINTEGER))) - && (rrk == 0)) - { - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - ninfo = ffeinfo_new (rbt, rkt, 0, FFEINFO_kindENTITY, nwh, - FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - return reduced; - } - - if ((rbt != FFEINFO_basictypeLOGICAL) - && (!ffe_is_ugly_logint () || (rbt != FFEINFO_basictypeINTEGER))) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_NOT_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_NOT_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_bool2_ -- Wrap up reduction of boolean operators - - reduced = ffeexpr_reduced_bool2_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - LOGICAL or (ugly) INTEGER. Determine common basictype and - size for reduction (flag expression for combined hollerith/typeless - situations for later determination of effective basictype). If both left - and right arguments have where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. Create CONVERT ops for args where - needed. Convert typeless - constants to the desired type/size explicitly. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_bool2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh, nwh; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - ffeexpr_type_combine (&nbt, &nkt, lbt, lkt, rbt, rkt, op->token); - - if (((nbt == FFEINFO_basictypeLOGICAL) - || (ffe_is_ugly_logint () && (nbt == FFEINFO_basictypeINTEGER))) - && (lrk == 0) && (rrk == 0)) - { - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - ninfo = ffeinfo_new (nbt, nkt, 0, FFEINFO_kindENTITY, nwh, - FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - return reduced; - } - - if ((lbt != FFEINFO_basictypeLOGICAL) - && (!ffe_is_ugly_logint () || (lbt != FFEINFO_basictypeINTEGER))) - { - if ((rbt != FFEINFO_basictypeLOGICAL) - && (!ffe_is_ugly_logint () || (rbt != FFEINFO_basictypeINTEGER))) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_BOOL_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_BOOL_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - } - else if ((rbt != FFEINFO_basictypeLOGICAL) - && (!ffe_is_ugly_logint () || (rbt != FFEINFO_basictypeINTEGER))) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_BOOL_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lrk != 0) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_BOOL_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_BOOL_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_concatenate_ -- Wrap up reduction of concatenate operator - - reduced = ffeexpr_reduced_concatenate_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - CHARACTER and kind of SCALAR, FUNCTION, or STATEMENT FUNCTION. Assign - basictype of CHARACTER and kind of SCALAR to reduced. Calculate effective - size of concatenation and assign that size to reduced. If both left and - right arguments have where of CONSTANT, assign where CONSTANT to reduced, - else assign where FLEETING. - - If these requirements cannot be met, generate error message using the - info in l, op, and r arguments and assign basictype, size, kind, and where - of ANY. */ - -static ffebld -ffeexpr_reduced_concatenate_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd, nkd; - ffeinfoWhere lwh, rwh, nwh; - ffetargetCharacterSize lszm, lszk, rszm, rszk, nszk; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - lszk = ffeinfo_size (linfo); /* Known size. */ - lszm = ffebld_size_max (ffebld_left (reduced)); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - rszk = ffeinfo_size (rinfo); /* Known size. */ - rszm = ffebld_size_max (ffebld_right (reduced)); - - if ((lbt == FFEINFO_basictypeCHARACTER) && (rbt == FFEINFO_basictypeCHARACTER) - && (lkt == rkt) && (lrk == 0) && (rrk == 0) - && (((lszm != FFETARGET_charactersizeNONE) - && (rszm != FFETARGET_charactersizeNONE)) - || (ffeexpr_context_outer_ (ffeexpr_stack_) - == FFEEXPR_contextLET) - || (ffeexpr_context_outer_ (ffeexpr_stack_) - == FFEEXPR_contextSFUNCDEF))) - { - nbt = FFEINFO_basictypeCHARACTER; - nkd = FFEINFO_kindENTITY; - if ((lszk == FFETARGET_charactersizeNONE) - || (rszk == FFETARGET_charactersizeNONE)) - nszk = FFETARGET_charactersizeNONE; /* Ok only in rhs of LET - stmt. */ - else - nszk = lszk + rszk; - - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - nkt = lkt; - ninfo = ffeinfo_new (nbt, nkt, 0, nkd, nwh, nszk); - ffebld_set_info (reduced, ninfo); - return reduced; - } - - if ((lbt != FFEINFO_basictypeCHARACTER) && (rbt != FFEINFO_basictypeCHARACTER)) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_CONCAT_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lbt != FFEINFO_basictypeCHARACTER) - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_CONCAT_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - else if (rbt != FFEINFO_basictypeCHARACTER) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_CONCAT_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if ((lrk != 0) || (lszm == FFETARGET_charactersizeNONE)) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_CONCAT_ARG_KIND)) - { - char *what; - - if (lrk != 0) - what = "an array"; - else - what = "of indeterminate length"; - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string (what); - ffebad_finish (); - } - } - else - { - if (ffebad_start (FFEBAD_CONCAT_ARG_KIND)) - { - char *what; - - if (rrk != 0) - what = "an array"; - else - what = "of indeterminate length"; - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string (what); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_eqop2_ -- Wrap up reduction of EQ and NE operators - - reduced = ffeexpr_reduced_eqop2_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - INTEGER, REAL, COMPLEX, or CHARACTER. Determine common basictype and - size for reduction. If both left - and right arguments have where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. Create CONVERT ops for args where - needed. Convert typeless - constants to the desired type/size explicitly. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_eqop2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh, nwh; - ffetargetCharacterSize lsz, rsz; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - lsz = ffebld_size_known (ffebld_left (reduced)); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - rsz = ffebld_size_known (ffebld_right (reduced)); - - ffeexpr_type_combine (&nbt, &nkt, lbt, lkt, rbt, rkt, op->token); - - if (((nbt == FFEINFO_basictypeINTEGER) || (nbt == FFEINFO_basictypeREAL) - || (nbt == FFEINFO_basictypeCOMPLEX) || (nbt == FFEINFO_basictypeCHARACTER)) - && (lrk == 0) && (rrk == 0)) - { - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - if ((lsz != FFETARGET_charactersizeNONE) - && (rsz != FFETARGET_charactersizeNONE)) - lsz = rsz = (lsz > rsz) ? lsz : rsz; - - ninfo = ffeinfo_new (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICALDEFAULT, - 0, FFEINFO_kindENTITY, nwh, FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, nbt, nkt, 0, lsz, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, nbt, nkt, 0, rsz, - FFEEXPR_contextLET)); - return reduced; - } - - if ((lbt == FFEINFO_basictypeLOGICAL) - && (rbt == FFEINFO_basictypeLOGICAL)) - { - if (ffebad_start_msg ("Use .EQV./.NEQV. instead of .EQ./.NE. at %0 for LOGICAL operands at %1 and %2", - FFEBAD_severityFATAL)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if ((lbt != FFEINFO_basictypeINTEGER) && (lbt != FFEINFO_basictypeREAL) - && (lbt != FFEINFO_basictypeCOMPLEX) && (lbt != FFEINFO_basictypeCHARACTER)) - { - if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCOMPLEX) && (rbt != FFEINFO_basictypeCHARACTER)) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_EQOP_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_EQOP_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - } - else if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCOMPLEX) && (rbt != FFEINFO_basictypeCHARACTER)) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_EQOP_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lrk != 0) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_EQOP_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_EQOP_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_math1_ -- Wrap up reduction of + - unary operators - - reduced = ffeexpr_reduced_math1_(reduced,op,r); - - Makes sure the argument for reduced has basictype of - INTEGER, REAL, or COMPLEX. If the argument has where of CONSTANT, - assign where CONSTANT to - reduced, else assign where FLEETING. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_math1_ (ffebld reduced, ffeexprExpr_ op, ffeexprExpr_ r) -{ - ffeinfo rinfo, ninfo; - ffeinfoBasictype rbt; - ffeinfoKindtype rkt; - ffeinfoRank rrk; - ffeinfoKind rkd; - ffeinfoWhere rwh, nwh; - - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if (((rbt == FFEINFO_basictypeINTEGER) || (rbt == FFEINFO_basictypeREAL) - || (rbt == FFEINFO_basictypeCOMPLEX)) && (rrk == 0)) - { - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - ninfo = ffeinfo_new (rbt, rkt, 0, FFEINFO_kindENTITY, nwh, - FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - return reduced; - } - - if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCOMPLEX)) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_MATH_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_math2_ -- Wrap up reduction of + - * / operators - - reduced = ffeexpr_reduced_math2_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - INTEGER, REAL, or COMPLEX. Determine common basictype and - size for reduction (flag expression for combined hollerith/typeless - situations for later determination of effective basictype). If both left - and right arguments have where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. Create CONVERT ops for args where - needed. Convert typeless - constants to the desired type/size explicitly. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_math2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh, nwh; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - ffeexpr_type_combine (&nbt, &nkt, lbt, lkt, rbt, rkt, op->token); - - if (((nbt == FFEINFO_basictypeINTEGER) || (nbt == FFEINFO_basictypeREAL) - || (nbt == FFEINFO_basictypeCOMPLEX)) && (lrk == 0) && (rrk == 0)) - { - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - ninfo = ffeinfo_new (nbt, nkt, 0, FFEINFO_kindENTITY, nwh, - FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - return reduced; - } - - if ((lbt != FFEINFO_basictypeINTEGER) && (lbt != FFEINFO_basictypeREAL) - && (lbt != FFEINFO_basictypeCOMPLEX)) - { - if ((rbt != FFEINFO_basictypeINTEGER) - && (rbt != FFEINFO_basictypeREAL) && (rbt != FFEINFO_basictypeCOMPLEX)) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - } - else if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCOMPLEX)) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lrk != 0) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_MATH_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_MATH_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_power_ -- Wrap up reduction of ** operator - - reduced = ffeexpr_reduced_power_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - INTEGER, REAL, or COMPLEX. Determine common basictype and - size for reduction (flag expression for combined hollerith/typeless - situations for later determination of effective basictype). If both left - and right arguments have where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. Create CONVERT ops for args where - needed. Note that real**int or complex**int - comes out as int = real**int etc with no conversions. - - If these requirements cannot be met, generate error message using the - info in l, op, and r arguments and assign basictype, size, kind, and where - of ANY. */ - -static ffebld -ffeexpr_reduced_power_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh, nwh; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if ((rbt == FFEINFO_basictypeINTEGER) - && ((lbt == FFEINFO_basictypeREAL) - || (lbt == FFEINFO_basictypeCOMPLEX))) - { - nbt = lbt; - nkt = ffeinfo_kindtype_max (nbt, lkt, FFEINFO_kindtypeREALDEFAULT); - if (nkt != FFEINFO_kindtypeREALDEFAULT) - { - nkt = ffeinfo_kindtype_max (nbt, lkt, FFEINFO_kindtypeREALDOUBLE); - if (nkt != FFEINFO_kindtypeREALDOUBLE) - nkt = FFEINFO_kindtypeREALDOUBLE; /* Highest kt we can power! */ - } - if (rkt == FFEINFO_kindtypeINTEGER4) - { - ffebad_start_msg ("Unsupported operand for ** at %1 -- converting to default INTEGER", - FFEBAD_severityWARNING); - ffebad_here (0, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - if (rkt != FFEINFO_kindtypeINTEGERDEFAULT) - { - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, - FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - rkt = FFEINFO_kindtypeINTEGERDEFAULT; - } - } - else - { - ffeexpr_type_combine (&nbt, &nkt, lbt, lkt, rbt, rkt, op->token); - -#if 0 /* INTEGER4**INTEGER4 works now. */ - if ((nbt == FFEINFO_basictypeINTEGER) - && (nkt != FFEINFO_kindtypeINTEGERDEFAULT)) - nkt = FFEINFO_kindtypeINTEGERDEFAULT; /* Highest kt we can power! */ -#endif - if (((nbt == FFEINFO_basictypeREAL) - || (nbt == FFEINFO_basictypeCOMPLEX)) - && (nkt != FFEINFO_kindtypeREALDEFAULT)) - { - nkt = ffeinfo_kindtype_max (nbt, nkt, FFEINFO_kindtypeREALDOUBLE); - if (nkt != FFEINFO_kindtypeREALDOUBLE) - nkt = FFEINFO_kindtypeREALDOUBLE; /* Highest kt we can power! */ - } - /* else Gonna turn into an error below. */ - } - - if (((nbt == FFEINFO_basictypeINTEGER) || (nbt == FFEINFO_basictypeREAL) - || (nbt == FFEINFO_basictypeCOMPLEX)) && (lrk == 0) && (rrk == 0)) - { - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - ninfo = ffeinfo_new (nbt, nkt, 0, FFEINFO_kindENTITY, nwh, - FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - if (rbt != FFEINFO_basictypeINTEGER) - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, nbt, nkt, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - return reduced; - } - - if ((lbt != FFEINFO_basictypeINTEGER) && (lbt != FFEINFO_basictypeREAL) - && (lbt != FFEINFO_basictypeCOMPLEX)) - { - if ((rbt != FFEINFO_basictypeINTEGER) - && (rbt != FFEINFO_basictypeREAL) && (rbt != FFEINFO_basictypeCOMPLEX)) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - } - else if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCOMPLEX)) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_MATH_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lrk != 0) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_MATH_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_MATH_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_relop2_ -- Wrap up reduction of LT, LE, GE, and GT operators - - reduced = ffeexpr_reduced_relop2_(reduced,l,op,r); - - Makes sure the left and right arguments for reduced have basictype of - INTEGER, REAL, or CHARACTER. Determine common basictype and - size for reduction. If both left - and right arguments have where of CONSTANT, assign where CONSTANT to - reduced, else assign where FLEETING. Create CONVERT ops for args where - needed. Convert typeless - constants to the desired type/size explicitly. - - If these requirements cannot be met, generate error message. */ - -static ffebld -ffeexpr_reduced_relop2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo, ninfo; - ffeinfoBasictype lbt, rbt, nbt; - ffeinfoKindtype lkt, rkt, nkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh, nwh; - ffetargetCharacterSize lsz, rsz; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - lsz = ffebld_size_known (ffebld_left (reduced)); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - rsz = ffebld_size_known (ffebld_right (reduced)); - - ffeexpr_type_combine (&nbt, &nkt, lbt, lkt, rbt, rkt, op->token); - - if (((nbt == FFEINFO_basictypeINTEGER) || (nbt == FFEINFO_basictypeREAL) - || (nbt == FFEINFO_basictypeCHARACTER)) - && (lrk == 0) && (rrk == 0)) - { - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - nwh = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - nwh = FFEINFO_whereIMMEDIATE; - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - break; - - default: - nwh = FFEINFO_whereFLEETING; - break; - } - - if ((lsz != FFETARGET_charactersizeNONE) - && (rsz != FFETARGET_charactersizeNONE)) - lsz = rsz = (lsz > rsz) ? lsz : rsz; - - ninfo = ffeinfo_new (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICALDEFAULT, - 0, FFEINFO_kindENTITY, nwh, FFETARGET_charactersizeNONE); - ffebld_set_info (reduced, ninfo); - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, nbt, nkt, 0, lsz, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, nbt, nkt, 0, rsz, - FFEEXPR_contextLET)); - return reduced; - } - - if ((lbt != FFEINFO_basictypeINTEGER) && (lbt != FFEINFO_basictypeREAL) - && (lbt != FFEINFO_basictypeCHARACTER)) - { - if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCHARACTER)) - { - if ((lbt != FFEINFO_basictypeANY) && (rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_RELOP_ARGS_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_here (2, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else - { - if ((lbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_RELOP_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_finish (); - } - } - } - else if ((rbt != FFEINFO_basictypeINTEGER) && (rbt != FFEINFO_basictypeREAL) - && (rbt != FFEINFO_basictypeCHARACTER)) - { - if ((rbt != FFEINFO_basictypeANY) - && ffebad_start (FFEBAD_RELOP_ARG_TYPE)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_finish (); - } - } - else if (lrk != 0) - { - if ((lkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_RELOP_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (l->token), ffelex_token_where_column (l->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - else - { - if ((rkd != FFEINFO_kindANY) - && ffebad_start (FFEBAD_RELOP_ARG_KIND)) - { - ffebad_here (0, ffelex_token_where_line (op->token), ffelex_token_where_column (op->token)); - ffebad_here (1, ffelex_token_where_line (r->token), ffelex_token_where_column (r->token)); - ffebad_string ("an array"); - ffebad_finish (); - } - } - - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - return reduced; -} - -/* ffeexpr_reduced_ugly1_ -- Deal with TYPELESS, HOLLERITH, and LOGICAL - - reduced = ffeexpr_reduced_ugly1_(reduced,op,r); - - Sigh. */ - -static ffebld -ffeexpr_reduced_ugly1_ (ffebld reduced, ffeexprExpr_ op, ffeexprExpr_ r) -{ - ffeinfo rinfo; - ffeinfoBasictype rbt; - ffeinfoKindtype rkt; - ffeinfoRank rrk; - ffeinfoKind rkd; - ffeinfoWhere rwh; - - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - r->token, op->token, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = FFEINFO_basictypeINTEGER; - rkt = FFEINFO_kindtypeINTEGERDEFAULT; - rrk = 0; - rkd = FFEINFO_kindENTITY; - rwh = ffeinfo_where (rinfo); - } - - if (rbt == FFEINFO_basictypeLOGICAL) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - r->token, op->token, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - } - - return reduced; -} - -/* ffeexpr_reduced_ugly1log_ -- Deal with TYPELESS and HOLLERITH - - reduced = ffeexpr_reduced_ugly1log_(reduced,op,r); - - Sigh. */ - -static ffebld -ffeexpr_reduced_ugly1log_ (ffebld reduced, ffeexprExpr_ op, ffeexprExpr_ r) -{ - ffeinfo rinfo; - ffeinfoBasictype rbt; - ffeinfoKindtype rkt; - ffeinfoRank rrk; - ffeinfoKind rkd; - ffeinfoWhere rwh; - - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - r->token, op->token, FFEINFO_basictypeLOGICAL, 0, - FFEINFO_kindtypeLOGICALDEFAULT, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - rinfo = ffebld_info (ffebld_left (reduced)); - rbt = FFEINFO_basictypeLOGICAL; - rkt = FFEINFO_kindtypeLOGICALDEFAULT; - rrk = 0; - rkd = FFEINFO_kindENTITY; - rwh = ffeinfo_where (rinfo); - } - - return reduced; -} - -/* ffeexpr_reduced_ugly2_ -- Deal with TYPELESS, HOLLERITH, and LOGICAL - - reduced = ffeexpr_reduced_ugly2_(reduced,l,op,r); - - Sigh. */ - -static ffebld -ffeexpr_reduced_ugly2_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo; - ffeinfoBasictype lbt, rbt; - ffeinfoKindtype lkt, rkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if ((lbt == FFEINFO_basictypeTYPELESS) - || (lbt == FFEINFO_basictypeHOLLERITH)) - { - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, FFEINFO_basictypeINTEGER, 0, - FFEINFO_kindtypeINTEGERDEFAULT, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - linfo = ffebld_info (ffebld_left (reduced)); - rinfo = ffebld_info (ffebld_right (reduced)); - lbt = rbt = FFEINFO_basictypeINTEGER; - lkt = rkt = FFEINFO_kindtypeINTEGERDEFAULT; - lrk = rrk = 0; - lkd = rkd = FFEINFO_kindENTITY; - lwh = ffeinfo_where (linfo); - rwh = ffeinfo_where (rinfo); - } - else - { - ffebld_set_left (reduced, ffeexpr_convert_expr (ffebld_left (reduced), - l->token, ffebld_right (reduced), r->token, - FFEEXPR_contextLET)); - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - } - } - else - { - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_right (reduced, ffeexpr_convert_expr (ffebld_right (reduced), - r->token, ffebld_left (reduced), l->token, - FFEEXPR_contextLET)); - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - } - /* else Leave it alone. */ - } - - if (lbt == FFEINFO_basictypeLOGICAL) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - } - - if (rbt == FFEINFO_basictypeLOGICAL) - { - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - } - - return reduced; -} - -/* ffeexpr_reduced_ugly2log_ -- Deal with TYPELESS and HOLLERITH - - reduced = ffeexpr_reduced_ugly2log_(reduced,l,op,r); - - Sigh. */ - -static ffebld -ffeexpr_reduced_ugly2log_ (ffebld reduced, ffeexprExpr_ l, ffeexprExpr_ op, - ffeexprExpr_ r) -{ - ffeinfo linfo, rinfo; - ffeinfoBasictype lbt, rbt; - ffeinfoKindtype lkt, rkt; - ffeinfoRank lrk, rrk; - ffeinfoKind lkd, rkd; - ffeinfoWhere lwh, rwh; - - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - - if ((lbt == FFEINFO_basictypeTYPELESS) - || (lbt == FFEINFO_basictypeHOLLERITH)) - { - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_left (reduced, ffeexpr_convert (ffebld_left (reduced), - l->token, op->token, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - ffebld_set_right (reduced, ffeexpr_convert (ffebld_right (reduced), - r->token, op->token, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET)); - linfo = ffebld_info (ffebld_left (reduced)); - rinfo = ffebld_info (ffebld_right (reduced)); - lbt = rbt = FFEINFO_basictypeLOGICAL; - lkt = rkt = FFEINFO_kindtypeLOGICALDEFAULT; - lrk = rrk = 0; - lkd = rkd = FFEINFO_kindENTITY; - lwh = ffeinfo_where (linfo); - rwh = ffeinfo_where (rinfo); - } - else - { - ffebld_set_left (reduced, ffeexpr_convert_expr (ffebld_left (reduced), - l->token, ffebld_right (reduced), r->token, - FFEEXPR_contextLET)); - linfo = ffebld_info (ffebld_left (reduced)); - lbt = ffeinfo_basictype (linfo); - lkt = ffeinfo_kindtype (linfo); - lrk = ffeinfo_rank (linfo); - lkd = ffeinfo_kind (linfo); - lwh = ffeinfo_where (linfo); - } - } - else - { - if ((rbt == FFEINFO_basictypeTYPELESS) - || (rbt == FFEINFO_basictypeHOLLERITH)) - { - ffebld_set_right (reduced, ffeexpr_convert_expr (ffebld_right (reduced), - r->token, ffebld_left (reduced), l->token, - FFEEXPR_contextLET)); - rinfo = ffebld_info (ffebld_right (reduced)); - rbt = ffeinfo_basictype (rinfo); - rkt = ffeinfo_kindtype (rinfo); - rrk = ffeinfo_rank (rinfo); - rkd = ffeinfo_kind (rinfo); - rwh = ffeinfo_where (rinfo); - } - /* else Leave it alone. */ - } - - return reduced; -} - -/* Fumble through tokens until a nonmatching CLOSE_PAREN, EOS, or SEMICOLON - is found. - - The idea is to process the tokens as they would be done by normal - expression processing, with the key things being telling the lexer - when hollerith/character constants are about to happen, until the - true closing token is found. */ - -static ffelexHandler -ffeexpr_find_close_paren_ (ffelexToken t, - ffelexHandler after) -{ - ffeexpr_find_.after = after; - ffeexpr_find_.level = 1; - return (ffelexHandler) ffeexpr_nil_rhs_ (t); -} - -static ffelexHandler -ffeexpr_nil_finished_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (--ffeexpr_find_.level == 0) - return (ffelexHandler) ffeexpr_find_.after; - return (ffelexHandler) ffeexpr_nil_binary_; - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLON: - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - return (ffelexHandler) ffeexpr_nil_rhs_; - - default: - if (--ffeexpr_find_.level == 0) - return (ffelexHandler) ffeexpr_find_.after (t); - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_rhs_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeQUOTE: - if (ffe_is_vxt ()) - return (ffelexHandler) ffeexpr_nil_quote_; - ffelex_set_expecting_hollerith (-1, '\"', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - return (ffelexHandler) ffeexpr_nil_apostrophe_; - - case FFELEX_typeAPOSTROPHE: - ffelex_set_expecting_hollerith (-1, '\'', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - return (ffelexHandler) ffeexpr_nil_apostrophe_; - - case FFELEX_typePERCENT: - return (ffelexHandler) ffeexpr_nil_percent_; - - case FFELEX_typeOPEN_PAREN: - ++ffeexpr_find_.level; - return (ffelexHandler) ffeexpr_nil_rhs_; - - case FFELEX_typePLUS: - case FFELEX_typeMINUS: - return (ffelexHandler) ffeexpr_nil_rhs_; - - case FFELEX_typePERIOD: - return (ffelexHandler) ffeexpr_nil_period_; - - case FFELEX_typeNUMBER: - ffeexpr_hollerith_count_ = atol (ffelex_token_text (t)); - if (ffeexpr_hollerith_count_ > 0) - ffelex_set_expecting_hollerith (ffeexpr_hollerith_count_, - '\0', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - return (ffelexHandler) ffeexpr_nil_number_; - - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - return (ffelexHandler) ffeexpr_nil_name_rhs_; - - case FFELEX_typeASTERISK: - case FFELEX_typeSLASH: - case FFELEX_typePOWER: - case FFELEX_typeCONCAT: - case FFELEX_typeREL_EQ: - case FFELEX_typeREL_NE: - case FFELEX_typeREL_LE: - case FFELEX_typeREL_GE: - return (ffelexHandler) ffeexpr_nil_rhs_; - - default: - return (ffelexHandler) ffeexpr_nil_finished_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_period_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_current_dotdot_ = ffestr_other (t); - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherNone: - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - - case FFESTR_otherTRUE: - case FFESTR_otherFALSE: - case FFESTR_otherNOT: - return (ffelexHandler) ffeexpr_nil_end_period_; - - default: - return (ffelexHandler) ffeexpr_nil_swallow_period_; - } - break; /* Nothing really reaches here. */ - - case FFELEX_typeNUMBER: - return (ffelexHandler) ffeexpr_nil_real_; - - default: - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_end_period_ (ffelexToken t) -{ - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherNOT: - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - return (ffelexHandler) ffeexpr_nil_rhs_; - - case FFESTR_otherTRUE: - case FFESTR_otherFALSE: - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; - - default: - assert ("Bad [nil] unary dotdot in ffeexpr_current_dotdot_" == NULL); - exit (0); - return NULL; - } -} - -static ffelexHandler -ffeexpr_nil_swallow_period_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - return (ffelexHandler) ffeexpr_nil_rhs_; -} - -static ffelexHandler -ffeexpr_nil_real_ (ffelexToken t) -{ - char d; - char *p; - - if (((ffelex_token_type (t) != FFELEX_typeNAME) - && (ffelex_token_type (t) != FFELEX_typeNAMES)) - || !(((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q'))) - && ffeexpr_isdigits_ (++p))) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - - if (*p == '\0') - return (ffelexHandler) ffeexpr_nil_real_exponent_; - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_real_exponent_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - - return (ffelexHandler) ffeexpr_nil_real_exp_sign_; -} - -static ffelexHandler -ffeexpr_nil_real_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_number_ (ffelexToken t) -{ - char d; - char *p; - - if (ffeexpr_hollerith_count_ > 0) - ffelex_set_expecting_hollerith (0, '\0', - ffewhere_line_unknown (), - ffewhere_column_unknown ()); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - if ((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q')) - && ffeexpr_isdigits_ (++p)) - { - if (*p == '\0') - { - ffeexpr_find_.t = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_nil_number_exponent_; - } - return (ffelexHandler) ffeexpr_nil_binary_; - } - break; - - case FFELEX_typePERIOD: - ffeexpr_find_.t = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_nil_number_period_; - - case FFELEX_typeHOLLERITH: - return (ffelexHandler) ffeexpr_nil_binary_; - - default: - break; - } - return (ffelexHandler) ffeexpr_nil_binary_ (t); -} - -/* Expects ffeexpr_find_.t. */ - -static ffelexHandler -ffeexpr_nil_number_exponent_ (ffelexToken t) -{ - ffelexHandler nexthandler; - - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - nexthandler - = (ffelexHandler) ffeexpr_nil_binary_ (ffeexpr_find_.t); - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) (*nexthandler) (t); - } - - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) ffeexpr_nil_number_exp_sign_; -} - -static ffelexHandler -ffeexpr_nil_number_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - - return (ffelexHandler) ffeexpr_nil_binary_; -} - -/* Expects ffeexpr_find_.t. */ - -static ffelexHandler -ffeexpr_nil_number_period_ (ffelexToken t) -{ - ffelexHandler nexthandler; - char d; - char *p; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - if ((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q')) - && ffeexpr_isdigits_ (++p)) - { - if (*p == '\0') - return (ffelexHandler) ffeexpr_nil_number_per_exp_; - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) ffeexpr_nil_binary_; - } - nexthandler - = (ffelexHandler) ffeexpr_nil_binary_ (ffeexpr_find_.t); - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) (*nexthandler) (t); - - case FFELEX_typeNUMBER: - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) ffeexpr_nil_number_real_; - - default: - break; - } - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) ffeexpr_nil_binary_ (t); -} - -/* Expects ffeexpr_find_.t. */ - -static ffelexHandler -ffeexpr_nil_number_per_exp_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - ffelexHandler nexthandler; - - nexthandler - = (ffelexHandler) ffeexpr_nil_binary_ (ffeexpr_find_.t); - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) (*nexthandler) (t); - } - - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) ffeexpr_nil_num_per_exp_sign_; -} - -static ffelexHandler -ffeexpr_nil_number_real_ (ffelexToken t) -{ - char d; - char *p; - - if (((ffelex_token_type (t) != FFELEX_typeNAME) - && (ffelex_token_type (t) != FFELEX_typeNAMES)) - || !(((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q'))) - && ffeexpr_isdigits_ (++p))) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - - if (*p == '\0') - return (ffelexHandler) ffeexpr_nil_number_real_exp_; - - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_num_per_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_number_real_exp_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_num_real_exp_sn_; -} - -static ffelexHandler -ffeexpr_nil_num_real_exp_sn_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_binary_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typePLUS: - case FFELEX_typeMINUS: - case FFELEX_typeASTERISK: - case FFELEX_typeSLASH: - case FFELEX_typePOWER: - case FFELEX_typeCONCAT: - case FFELEX_typeOPEN_ANGLE: - case FFELEX_typeCLOSE_ANGLE: - case FFELEX_typeREL_EQ: - case FFELEX_typeREL_NE: - case FFELEX_typeREL_GE: - case FFELEX_typeREL_LE: - return (ffelexHandler) ffeexpr_nil_rhs_; - - case FFELEX_typePERIOD: - return (ffelexHandler) ffeexpr_nil_binary_period_; - - default: - return (ffelexHandler) ffeexpr_nil_finished_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_binary_period_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_current_dotdot_ = ffestr_other (t); - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherTRUE: - case FFESTR_otherFALSE: - case FFESTR_otherNOT: - return (ffelexHandler) ffeexpr_nil_binary_sw_per_; - - default: - return (ffelexHandler) ffeexpr_nil_binary_end_per_; - } - break; /* Nothing really reaches here. */ - - default: - return (ffelexHandler) ffeexpr_nil_binary_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_binary_end_per_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - return (ffelexHandler) ffeexpr_nil_rhs_; -} - -static ffelexHandler -ffeexpr_nil_binary_sw_per_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_quote_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - return (ffelexHandler) ffeexpr_nil_binary_; -} - -static ffelexHandler -ffeexpr_nil_apostrophe_ (ffelexToken t) -{ - assert (ffelex_token_type (t) == FFELEX_typeCHARACTER); - return (ffelexHandler) ffeexpr_nil_apos_char_; -} - -static ffelexHandler -ffeexpr_nil_apos_char_ (ffelexToken t) -{ - char c; - - if ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - { - if ((ffelex_token_length (t) == 1) - && (ffesrc_char_match_init ((c = ffelex_token_text (t)[0]), - 'B', 'b') - || ffesrc_char_match_init (c, 'O', 'o') - || ffesrc_char_match_init (c, 'X', 'x') - || ffesrc_char_match_init (c, 'Z', 'z'))) - return (ffelexHandler) ffeexpr_nil_binary_; - } - if ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - return (ffelexHandler) ffeexpr_nil_substrp_ (t); -} - -static ffelexHandler -ffeexpr_nil_name_rhs_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeQUOTE: - case FFELEX_typeAPOSTROPHE: - ffelex_set_hexnum (TRUE); - return (ffelexHandler) ffeexpr_nil_name_apos_; - - case FFELEX_typeOPEN_PAREN: - ++ffeexpr_find_.level; - return (ffelexHandler) ffeexpr_nil_rhs_; - - default: - return (ffelexHandler) ffeexpr_nil_binary_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_name_apos_ (ffelexToken t) -{ - if (ffelex_token_type (t) == FFELEX_typeNAME) - return (ffelexHandler) ffeexpr_nil_name_apos_name_; - return (ffelexHandler) ffeexpr_nil_binary_ (t); -} - -static ffelexHandler -ffeexpr_nil_name_apos_name_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - return (ffelexHandler) ffeexpr_nil_finished_; - - default: - return (ffelexHandler) ffeexpr_nil_finished_ (t); - } -} - -static ffelexHandler -ffeexpr_nil_percent_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_stack_->percent = ffeexpr_percent_ (t); - ffeexpr_find_.t = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_nil_percent_name_; - - default: - return (ffelexHandler) ffeexpr_nil_rhs_ (t); - } -} - -/* Expects ffeexpr_find_.t. */ - -static ffelexHandler -ffeexpr_nil_percent_name_ (ffelexToken t) -{ - ffelexHandler nexthandler; - - if (ffelex_token_type (t) != FFELEX_typeOPEN_PAREN) - { - nexthandler - = (ffelexHandler) ffeexpr_nil_rhs_ (ffeexpr_find_.t); - ffelex_token_kill (ffeexpr_find_.t); - return (ffelexHandler) (*nexthandler) (t); - } - - ffelex_token_kill (ffeexpr_find_.t); - ++ffeexpr_find_.level; - return (ffelexHandler) ffeexpr_nil_rhs_; -} - -static ffelexHandler -ffeexpr_nil_substrp_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeOPEN_PAREN) - return (ffelexHandler) ffeexpr_nil_binary_ (t); - - ++ffeexpr_find_.level; - return (ffelexHandler) ffeexpr_nil_rhs_; -} - -/* ffeexpr_finished_ -- Reduce expression stack to one expr, finish - - ffelexToken t; - return ffeexpr_finished_(t); - - Reduces expression stack to one (or zero) elements by repeatedly reducing - the top operator on the stack (or, if the top element on the stack is - itself an operator, issuing an error message and discarding it). Calls - finishing routine with the expression, returning the ffelexHandler it - returns to the caller. */ - -static ffelexHandler -ffeexpr_finished_ (ffelexToken t) -{ - ffeexprExpr_ operand; /* This is B in -B or A+B. */ - ffebld expr; - ffeexprCallback callback; - ffeexprStack_ s; - ffebldConstant constnode; /* For detecting magical number. */ - ffelexToken ft; /* Temporary copy of first token in - expression. */ - ffelexHandler next; - ffeinfo info; - bool error = FALSE; - - while (((operand = ffeexpr_stack_->exprstack) != NULL) - && ((operand->previous != NULL) || (operand->type != FFEEXPR_exprtypeOPERAND_))) - { - if (operand->type == FFEEXPR_exprtypeOPERAND_) - ffeexpr_reduce_ (); - else - { - if (ffest_ffebad_start (FFEBAD_MISSING_OPERAND_FOR_OPERATOR)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); - ffebad_finish (); - } - ffeexpr_stack_->exprstack = operand->previous; /* Pop the useless - operator. */ - ffeexpr_expr_kill_ (operand); - } - } - - assert ((operand == NULL) || (operand->previous == NULL)); - - ffebld_pool_pop (); - if (operand == NULL) - expr = NULL; - else - { - expr = operand->u.operand; - info = ffebld_info (expr); - if ((ffebld_op (expr) == FFEBLD_opCONTER) - && (ffebld_conter_orig (expr) == NULL) - && ffebld_constant_is_magical (constnode = ffebld_conter (expr))) - { - ffetarget_integer_bad_magical (operand->token); - } - ffeexpr_expr_kill_ (operand); - ffeexpr_stack_->exprstack = NULL; - } - - ft = ffeexpr_stack_->first_token; - -again: /* :::::::::::::::::::: */ - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextLET: - case FFEEXPR_contextSFUNCDEF: - error = (expr == NULL) - || (ffeinfo_rank (info) != 0); - break; - - case FFEEXPR_contextPAREN_: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - break; - } - break; - - case FFEEXPR_contextPARENFILENUM_: - if (ffelex_token_type (t) != FFELEX_typeCOMMA) - ffeexpr_stack_->context = FFEEXPR_contextPAREN_; - else - ffeexpr_stack_->context = FFEEXPR_contextFILENUM; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextPARENFILEUNIT_: - if (ffelex_token_type (t) != FFELEX_typeCOMMA) - ffeexpr_stack_->context = FFEEXPR_contextPAREN_; - else - ffeexpr_stack_->context = FFEEXPR_contextFILEUNIT; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - if (!ffe_is_ugly_args () - && ffebad_start (FFEBAD_ACTUALARG)) - { - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - break; - - default: - break; - } - error = (expr != NULL) && (ffeinfo_rank (info) != 0); - break; - - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextSFUNCDEFACTUALARG_: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: -#if 0 /* Should never get here. */ - expr = ffeexpr_convert (expr, ft, ft, - FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); -#else - assert ("why hollerith/typeless in actualarg_?" == NULL); -#endif - break; - - default: - break; - } - switch ((expr == NULL) ? FFEBLD_opANY : ffebld_op (expr)) - { - case FFEBLD_opSYMTER: - case FFEBLD_opPERCENT_LOC: - case FFEBLD_opPERCENT_VAL: - case FFEBLD_opPERCENT_REF: - case FFEBLD_opPERCENT_DESCR: - error = FALSE; - break; - - default: - error = (expr != NULL) && (ffeinfo_rank (info) != 0); - break; - } - { - ffesymbol s; - ffeinfoWhere where; - ffeinfoKind kind; - - if (!error - && (expr != NULL) - && (ffebld_op (expr) == FFEBLD_opSYMTER) - && ((s = ffebld_symter (expr)), (where = ffesymbol_where (s)), - (where == FFEINFO_whereINTRINSIC) - || (where == FFEINFO_whereGLOBAL) - || ((where == FFEINFO_whereDUMMY) - && ((kind = ffesymbol_kind (s)), - (kind == FFEINFO_kindFUNCTION) - || (kind == FFEINFO_kindSUBROUTINE)))) - && !ffesymbol_explicitwhere (s)) - { - ffebad_start (where == FFEINFO_whereINTRINSIC - ? FFEBAD_NEED_INTRINSIC : FFEBAD_NEED_EXTERNAL); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - ffesymbol_signal_change (s); - ffesymbol_set_explicitwhere (s, TRUE); - ffesymbol_signal_unreported (s); - } - } - break; - - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextRETURN: - if ((error = (expr != NULL) && (ffeinfo_rank (info) != 0))) - break; - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeNONE: - error = FALSE; - break; - - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - break; /* expr==NULL ok for substring; element case - caught by callback. */ - - case FFEEXPR_contextDO: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - error = !ffe_is_ugly_logint (); - if (!ffeexpr_stack_->is_rhs) - break; /* Don't convert lhs variable. */ - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - ffeinfo_kindtype (ffebld_info (expr)), 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - if (!ffeexpr_stack_->is_rhs) - { - error = TRUE; - break; /* Don't convert lhs variable. */ - } - break; - - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - break; - - default: - error = TRUE; - break; - } - if (!ffeexpr_stack_->is_rhs - && (ffebld_op (expr) != FFEBLD_opSYMTER)) - error = TRUE; - break; - - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextIF: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeLOGICAL: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextAGOTO: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = (ffeinfo_kindtype (info) != ffecom_label_kind ()); - break; - - case FFEINFO_basictypeLOGICAL: - error = !ffe_is_ugly_logint () - || (ffeinfo_kindtype (info) != ffecom_label_kind ()); - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0) - || (ffebld_op (expr) != FFEBLD_opSYMTER)) - error = TRUE; - break; - - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextFILENUM: /* See equiv code in _ambig_. */ - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextARITHIF: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeREAL: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextSTOP: - if ((error = (expr != NULL) && (ffeinfo_rank (info) != 0))) - break; - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = (ffeinfo_kindtype (info) != FFEINFO_kindtypeINTEGERDEFAULT); - break; - - case FFEINFO_basictypeCHARACTER: - error = (ffeinfo_kindtype (info) != FFEINFO_kindtypeCHARACTERDEFAULT); - break; - - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeNONE: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - if ((expr != NULL) && ((ffebld_op (expr) != FFEBLD_opCONTER) - || (ffebld_conter_orig (expr) != NULL))) - error = TRUE; - break; - - case FFEEXPR_contextINCLUDE: - error = (expr == NULL) || (ffeinfo_rank (info) != 0) - || (ffeinfo_basictype (info) != FFEINFO_basictypeCHARACTER) - || (ffebld_op (expr) != FFEBLD_opCONTER) - || (ffebld_conter_orig (expr) != NULL); - break; - - case FFEEXPR_contextSELECTCASE: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeCHARACTER: - case FFEINFO_basictypeLOGICAL: - error = FALSE; - break; - - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextCASE: - if ((error = (expr != NULL) && (ffeinfo_rank (info) != 0))) - break; - switch ((expr == NULL) ? FFEINFO_basictypeINTEGER - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeCHARACTER: - case FFEINFO_basictypeLOGICAL: - error = FALSE; - break; - - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - if ((expr != NULL) && (ffebld_op (expr) != FFEBLD_opCONTER)) - error = TRUE; - break; - - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextDIMLISTCOMMON: - if ((error = (expr != NULL) && (ffeinfo_rank (info) != 0))) - break; - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - if ((expr != NULL) && (ffebld_op (expr) != FFEBLD_opCONTER)) - error = TRUE; - break; - - case FFEEXPR_contextEQVINDEX_: - if ((error = (expr != NULL) && (ffeinfo_rank (info) != 0))) - break; - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeNONE: - error = FALSE; - break; - - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - if ((expr != NULL) && (ffebld_op (expr) != FFEBLD_opCONTER)) - error = TRUE; - break; - - case FFEEXPR_contextPARAMETER: - if (ffeexpr_stack_->is_rhs) - error = (expr == NULL) || (ffeinfo_rank (info) != 0) - || (ffebld_op (expr) != FFEBLD_opCONTER); - else - error = (expr == NULL) || (ffeinfo_rank (info) != 0) - || (ffebld_op (expr) != FFEBLD_opSYMTER); - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - if (ffelex_token_type (t) == FFELEX_typeCOLON) - ffeexpr_stack_->context = FFEEXPR_contextINDEX_; - else - ffeexpr_stack_->context = FFEEXPR_contextACTUALARG_; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - if (ffelex_token_type (t) == FFELEX_typeCOLON) - ffeexpr_stack_->context = FFEEXPR_contextINDEX_; - else - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - if (ffelex_token_type (t) == FFELEX_typeCOLON) - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEX_; - else - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARG_; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - if (ffelex_token_type (t) == FFELEX_typeCOLON) - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFINDEX_; - else - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - goto again; /* :::::::::::::::::::: */ - - case FFEEXPR_contextIMPDOCTRL_: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - if (!ffeexpr_stack_->is_rhs - && (ffebld_op (expr) != FFEBLD_opSYMTER)) - error = TRUE; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - error = error && !ffe_is_ugly_logint (); - if (!ffeexpr_stack_->is_rhs) - break; /* Don't convert lhs variable. */ - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - ffeinfo_kindtype (ffebld_info (expr)), 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - break; - - case FFEINFO_basictypeREAL: - if (!ffeexpr_stack_->is_rhs - && ffe_is_warn_surprising () - && !error) - { - ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_string (ffelex_token_text (ft)); - ffebad_finish (); - } - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextDATAIMPDOCTRL_: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - if (ffeexpr_stack_->is_rhs) - { - if ((ffebld_op (expr) != FFEBLD_opCONTER) - && (ffeinfo_where (info) != FFEINFO_whereIMMEDIATE)) - error = TRUE; - } - else if ((ffebld_op (expr) != FFEBLD_opSYMTER) - || (ffeinfo_where (info) != FFEINFO_whereIMMEDIATE)) - error = TRUE; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - error = error - && (ffeinfo_kindtype (info) != FFEINFO_kindtypeLOGICALDEFAULT); - if (!ffeexpr_stack_->is_rhs) - break; /* Don't convert lhs variable. */ - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeINTEGER: - error = error && - (ffeinfo_kindtype (info) != FFEINFO_kindtypeINTEGERDEFAULT); - break; - - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeREAL: - if (!ffeexpr_stack_->is_rhs - && ffe_is_warn_surprising () - && !error) - { - ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_string (ffelex_token_text (ft)); - ffebad_finish (); - } - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextIMPDOITEM_: - if (ffelex_token_type (t) == FFELEX_typeEQUALS) - { - ffeexpr_stack_->is_rhs = FALSE; - ffeexpr_stack_->context = FFEEXPR_contextIMPDOCTRL_; - goto again; /* :::::::::::::::::::: */ - } - /* Fall through. */ - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextFILEVXTCODE: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - break; - } - error = (expr == NULL) - || ((ffeinfo_rank (info) != 0) - && ((ffebld_op (expr) != FFEBLD_opSYMTER) - || (ffesymbol_arraysize (ffebld_symter (expr)) == NULL) - || (ffebld_op (ffesymbol_arraysize (ffebld_symter (expr))) - == FFEBLD_opSTAR))); /* Bad if null expr, or if - array that is not a SYMTER - (can't happen yet, I - think) or has a NULL or - STAR (assumed) array - size. */ - break; - - case FFEEXPR_contextIMPDOITEMDF_: - if (ffelex_token_type (t) == FFELEX_typeEQUALS) - { - ffeexpr_stack_->is_rhs = FALSE; - ffeexpr_stack_->context = FFEEXPR_contextIMPDOCTRL_; - goto again; /* :::::::::::::::::::: */ - } - /* Fall through. */ - case FFEEXPR_contextIOLISTDF: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - break; - } - error - = (expr == NULL) - || ((ffeinfo_basictype (info) == FFEINFO_basictypeCHARACTER) - && (ffeinfo_kindtype (info) != FFEINFO_kindtypeCHARACTERDEFAULT)) - || ((ffeinfo_rank (info) != 0) - && ((ffebld_op (expr) != FFEBLD_opSYMTER) - || (ffesymbol_arraysize (ffebld_symter (expr)) == NULL) - || (ffebld_op (ffesymbol_arraysize (ffebld_symter (expr))) - == FFEBLD_opSTAR))); /* Bad if null expr, - non-default-kindtype - character expr, or if - array that is not a SYMTER - (can't happen yet, I - think) or has a NULL or - STAR (assumed) array - size. */ - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - error = (expr == NULL) - || (ffebld_op (expr) != FFEBLD_opARRAYREF) - || ((ffeinfo_where (info) != FFEINFO_whereFLEETING_CADDR) - && (ffeinfo_where (info) != FFEINFO_whereFLEETING_IADDR)); - break; - - case FFEEXPR_contextDATAIMPDOINDEX_: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - if ((ffeinfo_where (info) != FFEINFO_whereCONSTANT) - && (ffeinfo_where (info) != FFEINFO_whereIMMEDIATE)) - error = TRUE; - break; - - case FFEEXPR_contextDATA: - if (expr == NULL) - error = TRUE; - else if (ffeexpr_stack_->is_rhs) - error = (ffebld_op (expr) != FFEBLD_opCONTER); - else if (ffebld_op (expr) == FFEBLD_opSYMTER) - error = FALSE; - else - error = (ffeinfo_where (info) != FFEINFO_whereFLEETING_CADDR); - break; - - case FFEEXPR_contextINITVAL: - error = (expr == NULL) || (ffebld_op (expr) != FFEBLD_opCONTER); - break; - - case FFEEXPR_contextEQUIVALENCE: - if (expr == NULL) - error = TRUE; - else if (ffebld_op (expr) == FFEBLD_opSYMTER) - error = FALSE; - else - error = (ffeinfo_where (info) != FFEINFO_whereFLEETING_CADDR); - break; - - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0)) - error = TRUE; - break; - - case FFEEXPR_contextFILEDFINT: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = (ffeinfo_kindtype (info) != FFEINFO_kindtypeINTEGERDEFAULT); - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0)) - error = TRUE; - break; - - case FFEEXPR_contextFILELOG: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0)) - error = TRUE; - break; - - case FFEEXPR_contextFILECHAR: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeCHARACTER: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0)) - error = TRUE; - break; - - case FFEEXPR_contextFILENUMCHAR: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeCHARACTER: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextFILEDFCHAR: - if ((error = (expr == NULL) || (ffeinfo_rank (info) != 0))) - break; - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeCHARACTER: - error - = (ffeinfo_kindtype (info) - != FFEINFO_kindtypeCHARACTERDEFAULT); - break; - - default: - error = TRUE; - break; - } - if (!ffeexpr_stack_->is_rhs - && (ffebld_op (expr) == FFEBLD_opSUBSTR)) - error = TRUE; - break; - - case FFEEXPR_contextFILEUNIT: /* See equiv code in _ambig_. */ - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - if ((error = (ffeinfo_rank (info) != 0))) - break; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if ((error = (ffeinfo_rank (info) != 0))) - break; - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - if ((error = (ffeinfo_rank (info) != 0))) - break; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffebld_op (expr)) - { /* As if _lhs had been called instead of - _rhs. */ - case FFEBLD_opSYMTER: - error - = (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereCONSTANT); - break; - - case FFEBLD_opSUBSTR: - error = (ffeinfo_where (ffebld_info (expr)) - == FFEINFO_whereCONSTANT_SUBOBJECT); - break; - - case FFEBLD_opARRAYREF: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - if (!error - && ((ffeinfo_kindtype (info) != FFEINFO_kindtypeCHARACTERDEFAULT) - || ((ffeinfo_rank (info) != 0) - && ((ffebld_op (expr) != FFEBLD_opSYMTER) - || (ffesymbol_arraysize (ffebld_symter (expr)) == NULL) - || (ffebld_op (ffesymbol_arraysize (ffebld_symter (expr))) - == FFEBLD_opSTAR))))) /* Bad if - non-default-kindtype - character expr, or if - array that is not a SYMTER - (can't happen yet, I - think), or has a NULL or - STAR (assumed) array - size. */ - error = TRUE; - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextFILEFORMAT: - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeINTEGER: - error = (expr == NULL) - || ((ffeinfo_rank (info) != 0) ? - ffe_is_pedantic () /* F77 C5. */ - : (ffeinfo_kindtype (info) != ffecom_label_kind ())) - || (ffebld_op (expr) != FFEBLD_opSYMTER); - break; - - case FFEINFO_basictypeLOGICAL: - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - /* F77 C5 -- must be an array of hollerith. */ - error - = ffe_is_pedantic () - || (ffeinfo_rank (info) == 0); - break; - - case FFEINFO_basictypeCHARACTER: - if ((ffeinfo_kindtype (info) != FFEINFO_kindtypeCHARACTERDEFAULT) - || ((ffeinfo_rank (info) != 0) - && ((ffebld_op (expr) != FFEBLD_opSYMTER) - || (ffesymbol_arraysize (ffebld_symter (expr)) == NULL) - || (ffebld_op (ffesymbol_arraysize (ffebld_symter (expr))) - == FFEBLD_opSTAR)))) /* Bad if - non-default-kindtype - character expr, or if - array that is not a SYMTER - (can't happen yet, I - think), or has a NULL or - STAR (assumed) array - size. */ - error = TRUE; - else - error = FALSE; - break; - - default: - error = TRUE; - break; - } - break; - - case FFEEXPR_contextLOC_: - /* See also ffeintrin_check_loc_. */ - if ((expr == NULL) - || (ffeinfo_kind (info) != FFEINFO_kindENTITY) - || ((ffebld_op (expr) != FFEBLD_opSYMTER) - && (ffebld_op (expr) != FFEBLD_opSUBSTR) - && (ffebld_op (expr) != FFEBLD_opARRAYREF))) - error = TRUE; - break; - - default: - error = FALSE; - break; - } - - if (error && ((expr == NULL) || (ffebld_op (expr) != FFEBLD_opANY))) - { - ffebad_start (FFEBAD_EXPR_WRONG); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - expr = ffebld_new_any (); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - - callback = ffeexpr_stack_->callback; - s = ffeexpr_stack_->previous; - malloc_kill_ks (ffe_pool_program_unit (), ffeexpr_stack_, - sizeof (*ffeexpr_stack_)); - ffeexpr_stack_ = s; - next = (ffelexHandler) (*callback) (ft, expr, t); - ffelex_token_kill (ft); - return (ffelexHandler) next; -} - -/* ffeexpr_finished_ambig_ -- Check validity of ambiguous unit/form spec - - ffebld expr; - expr = ffeexpr_finished_ambig_(expr); - - Replicates a bit of ffeexpr_finished_'s task when in a context - of UNIT or FORMAT. */ - -static ffebld -ffeexpr_finished_ambig_ (ffelexToken ft, ffebld expr) -{ - ffeinfo info = ffebld_info (expr); - bool error; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFILENUMAMBIG: /* Same as FILENUM in _finished_. */ - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = FALSE; - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - default: - error = TRUE; - break; - } - if ((expr == NULL) || (ffeinfo_rank (info) != 0)) - error = TRUE; - break; - - case FFEEXPR_contextFILEUNITAMBIG: /* Same as FILEUNIT in _finished_. */ - if ((expr != NULL) && (ffebld_op (expr) == FFEBLD_opSTAR)) - { - error = FALSE; - break; - } - switch ((expr == NULL) ? FFEINFO_basictypeNONE - : ffeinfo_basictype (info)) - { - case FFEINFO_basictypeLOGICAL: - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeLOGICAL, - FFEINFO_kindtypeLOGICALDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - /* Fall through. */ - case FFEINFO_basictypeREAL: - case FFEINFO_basictypeCOMPLEX: - if (ffe_is_pedantic ()) - { - error = TRUE; - break; - } - /* Fall through. */ - case FFEINFO_basictypeINTEGER: - case FFEINFO_basictypeHOLLERITH: - case FFEINFO_basictypeTYPELESS: - error = (ffeinfo_rank (info) != 0); - expr = ffeexpr_convert (expr, ft, ft, FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - break; - - case FFEINFO_basictypeCHARACTER: - switch (ffebld_op (expr)) - { /* As if _lhs had been called instead of - _rhs. */ - case FFEBLD_opSYMTER: - error - = (ffeinfo_where (ffebld_info (expr)) == FFEINFO_whereCONSTANT); - break; - - case FFEBLD_opSUBSTR: - error = (ffeinfo_where (ffebld_info (expr)) - == FFEINFO_whereCONSTANT_SUBOBJECT); - break; - - case FFEBLD_opARRAYREF: - error = FALSE; - break; - - default: - error = TRUE; - break; - } - break; - - default: - error = TRUE; - break; - } - break; - - default: - assert ("bad context" == NULL); - error = TRUE; - break; - } - - if (error && ((expr == NULL) || (ffebld_op (expr) != FFEBLD_opANY))) - { - ffebad_start (FFEBAD_EXPR_WRONG); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - expr = ffebld_new_any (); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - - return expr; -} - -/* ffeexpr_token_lhs_ -- Initial state for lhs expression - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Basically a smaller version of _rhs_; keep them both in sync, of course. */ - -static ffelexHandler -ffeexpr_token_lhs_ (ffelexToken t) -{ - - /* When changing the list of valid initial lhs tokens, check whether to - update a corresponding list in ffeexpr_cb_close_paren_ambig_1_ for the - READ (expr) <token> case -- it assumes it knows which tokens <token> can - be to indicate an lhs (or implied DO), which right now is the set - {NAME,OPEN_PAREN}. - - This comment also appears in ffeexpr_token_first_lhs_. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_tokens_[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_name_lhs_; - - default: - return (ffelexHandler) ffeexpr_finished_ (t); - } -} - -/* ffeexpr_token_rhs_ -- Initial state for rhs expression - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - The initial state and the post-binary-operator state are the same and - both handled here, with the expression stack used to distinguish - between them. Binary operators are invalid here; unary operators, - constants, subexpressions, and name references are valid. */ - -static ffelexHandler -ffeexpr_token_rhs_ (ffelexToken t) -{ - ffeexprExpr_ e; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeQUOTE: - if (ffe_is_vxt ()) - { - ffeexpr_tokens_[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_quote_; - } - ffeexpr_tokens_[0] = ffelex_token_use (t); - ffelex_set_expecting_hollerith (-1, '\"', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - /* Don't have to unset this one. */ - return (ffelexHandler) ffeexpr_token_apostrophe_; - - case FFELEX_typeAPOSTROPHE: - ffeexpr_tokens_[0] = ffelex_token_use (t); - ffelex_set_expecting_hollerith (-1, '\'', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - /* Don't have to unset this one. */ - return (ffelexHandler) ffeexpr_token_apostrophe_; - - case FFELEX_typePERCENT: - ffeexpr_tokens_[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_percent_; - - case FFELEX_typeOPEN_PAREN: - ffeexpr_stack_->tokens[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextPAREN_, - ffeexpr_cb_close_paren_c_); - - case FFELEX_typePLUS: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeUNARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorADD_; - e->u.operator.prec = FFEEXPR_operatorprecedenceADD_; - e->u.operator.as = FFEEXPR_operatorassociativityADD_; - ffeexpr_exprstack_push_unary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeMINUS: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeUNARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorSUBTRACT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceSUBTRACT_; - e->u.operator.as = FFEEXPR_operatorassociativitySUBTRACT_; - ffeexpr_exprstack_push_unary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typePERIOD: - ffeexpr_tokens_[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_period_; - - case FFELEX_typeNUMBER: - ffeexpr_tokens_[0] = ffelex_token_use (t); - ffeexpr_hollerith_count_ = atol (ffelex_token_text (t)); - if (ffeexpr_hollerith_count_ > 0) - ffelex_set_expecting_hollerith (ffeexpr_hollerith_count_, - '\0', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - return (ffelexHandler) ffeexpr_token_number_; - - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_tokens_[0] = ffelex_token_use (t); - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextINDEXORACTUALARG_: - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - return (ffelexHandler) ffeexpr_token_name_arg_; - - default: - return (ffelexHandler) ffeexpr_token_name_rhs_; - } - - case FFELEX_typeASTERISK: - case FFELEX_typeSLASH: - case FFELEX_typePOWER: - case FFELEX_typeCONCAT: - case FFELEX_typeREL_EQ: - case FFELEX_typeREL_NE: - case FFELEX_typeREL_LE: - case FFELEX_typeREL_GE: - if (ffest_ffebad_start (FFEBAD_MISSING_FIRST_BINARY_OPERAND)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffeexpr_token_rhs_; - -#if 0 - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCLOSE_ANGLE: - case FFELEX_typeCLOSE_PAREN: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: -#endif - default: - return (ffelexHandler) ffeexpr_finished_ (t); - } -} - -/* ffeexpr_token_period_ -- Rhs PERIOD - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle a period detected at rhs (expecting unary op or operand) state. - Must begin a floating-point value (as in .12) or a dot-dot name, of - which only .NOT., .TRUE., and .FALSE. are truly valid. Other sort-of- - valid names represent binary operators, which are invalid here because - there isn't an operand at the top of the stack. */ - -static ffelexHandler -ffeexpr_token_period_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_current_dotdot_ = ffestr_other (t); - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherNone: - if (ffest_ffebad_start (FFEBAD_IGNORING_PERIOD)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_rhs_ (t); - - case FFESTR_otherTRUE: - case FFESTR_otherFALSE: - case FFESTR_otherNOT: - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_end_period_; - - default: - if (ffest_ffebad_start (FFEBAD_MISSING_FIRST_BINARY_OPERAND)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_swallow_period_; - } - break; /* Nothing really reaches here. */ - - case FFELEX_typeNUMBER: - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_real_; - - default: - if (ffest_ffebad_start (FFEBAD_IGNORING_PERIOD)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_rhs_ (t); - } -} - -/* ffeexpr_token_end_period_ -- Rhs PERIOD NAME(NOT, TRUE, or FALSE) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Expecting a period to close a .NOT, .TRUE, or .FALSE at rhs (unary op - or operator) state. If period isn't found, issue a diagnostic but - pretend we saw one. ffeexpr_current_dotdot_ must already contained the - dotdot representation of the name in between the two PERIOD tokens. */ - -static ffelexHandler -ffeexpr_token_end_period_ (ffelexToken t) -{ - ffeexprExpr_ e; - - if (ffelex_token_type (t) != FFELEX_typePERIOD) - { - if (ffest_ffebad_start (FFEBAD_INSERTING_PERIOD)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffelex_token_text (ffeexpr_tokens_[1])); - ffebad_finish (); - } - } - - ffelex_token_kill (ffeexpr_tokens_[1]); /* Kill "NOT"/"TRUE"/"FALSE" - token. */ - - e = ffeexpr_expr_new_ (); - e->token = ffeexpr_tokens_[0]; - - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherNOT: - e->type = FFEEXPR_exprtypeUNARY_; - e->u.operator.op = FFEEXPR_operatorNOT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceNOT_; - e->u.operator.as = FFEEXPR_operatorassociativityNOT_; - ffeexpr_exprstack_push_unary_ (e); - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_token_rhs_ (t); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFESTR_otherTRUE: - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand - = ffebld_new_conter (ffebld_constant_new_logicaldefault (TRUE)); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICALDEFAULT, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_token_binary_ (t); - return (ffelexHandler) ffeexpr_token_binary_; - - case FFESTR_otherFALSE: - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand - = ffebld_new_conter (ffebld_constant_new_logicaldefault (FALSE)); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeLOGICAL, FFEINFO_kindtypeLOGICALDEFAULT, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_token_binary_ (t); - return (ffelexHandler) ffeexpr_token_binary_; - - default: - assert ("Bad unary dotdot in ffeexpr_current_dotdot_" == NULL); - exit (0); - return NULL; - } -} - -/* ffeexpr_token_swallow_period_ -- Rhs PERIOD NAME(not NOT, TRUE, or FALSE) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - A diagnostic has already been issued; just swallow a period if there is - one, then continue with ffeexpr_token_rhs_. */ - -static ffelexHandler -ffeexpr_token_swallow_period_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_token_rhs_ (t); - - return (ffelexHandler) ffeexpr_token_rhs_; -} - -/* ffeexpr_token_real_ -- Rhs PERIOD NUMBER - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - After a period and a string of digits, check next token for possible - exponent designation (D, E, or Q as first/only character) and continue - real-number handling accordingly. Else form basic real constant, push - onto expression stack, and enter binary state using current token (which, - if it is a name not beginning with D, E, or Q, will certainly result - in an error, but that's not for this routine to deal with). */ - -static ffelexHandler -ffeexpr_token_real_ (ffelexToken t) -{ - char d; - char *p; - - if (((ffelex_token_type (t) != FFELEX_typeNAME) - && (ffelex_token_type (t) != FFELEX_typeNAMES)) - || !(((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q'))) - && ffeexpr_isdigits_ (++p))) - { -#if 0 - /* This code has been removed because it seems inconsistent to - produce a diagnostic in this case, but not all of the other - ones that look for an exponent and cannot recognize one. */ - if (((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - && ffest_ffebad_start (FFEBAD_INVALID_EXPONENT)) - { - char bad[2]; - - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - bad[0] = *(p - 1); - bad[1] = '\0'; - ffebad_string (bad); - ffebad_finish (); - } -#endif - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), NULL, - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - /* Just exponent character by itself? In which case, PLUS or MINUS must - surely be next, followed by a NUMBER token. */ - - if (*p == '\0') - { - ffeexpr_tokens_[2] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_real_exponent_; - } - - ffeexpr_make_float_const_ (d, NULL, ffeexpr_tokens_[0], ffeexpr_tokens_[1], - t, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_real_exponent_ -- Rhs PERIOD NUMBER NAME(D, E, or Q) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Ensures this token is PLUS or MINUS, preserves it, goes to final state - for real number (exponent digits). Else issues diagnostic, assumes a - zero exponent field for number, passes token on to binary state as if - previous token had been "E0" instead of "E", for example. */ - -static ffelexHandler -ffeexpr_token_real_exponent_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[2]), - ffelex_token_where_column (ffeexpr_tokens_[2])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), NULL, - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_tokens_[3] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_real_exp_sign_; -} - -/* ffeexpr_token_real_exp_sign_ -- Rhs PERIOD NUMBER NAME(D,E,Q) PLUS/MINUS - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Make sure token is a NUMBER, make a real constant out of all we have and - push it onto the expression stack. Else issue diagnostic and pretend - exponent field was a zero. */ - -static ffelexHandler -ffeexpr_token_real_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[2]), - ffelex_token_where_column (ffeexpr_tokens_[2])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), NULL, - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_make_float_const_ (ffelex_token_text (ffeexpr_tokens_[2])[0], NULL, - ffeexpr_tokens_[0], ffeexpr_tokens_[1], ffeexpr_tokens_[2], - ffeexpr_tokens_[3], t); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_number_ -- Rhs NUMBER - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - If the token is a period, we may have a floating-point number, or an - integer followed by a dotdot binary operator. If the token is a name - beginning with D, E, or Q, we definitely have a floating-point number. - If the token is a hollerith constant, that's what we've got, so push - it onto the expression stack and continue with the binary state. - - Otherwise, we have an integer followed by something the binary state - should be able to swallow. */ - -static ffelexHandler -ffeexpr_token_number_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffeinfo ni; - char d; - char *p; - - if (ffeexpr_hollerith_count_ > 0) - ffelex_set_expecting_hollerith (0, '\0', - ffewhere_line_unknown (), - ffewhere_column_unknown ()); - - /* See if we've got a floating-point number here. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - if ((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q')) - && ffeexpr_isdigits_ (++p)) - { - - /* Just exponent character by itself? In which case, PLUS or MINUS - must surely be next, followed by a NUMBER token. */ - - if (*p == '\0') - { - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_exponent_; - } - ffeexpr_make_float_const_ (d, ffeexpr_tokens_[0], NULL, NULL, t, - NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_binary_; - } - break; - - case FFELEX_typePERIOD: - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_period_; - - case FFELEX_typeHOLLERITH: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - e->u.operand = ffebld_new_conter (ffebld_constant_new_hollerith (t)); - ni = ffeinfo_new (FFEINFO_basictypeHOLLERITH, FFEINFO_kindtypeNONE, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - ffelex_token_length (t)); - ffebld_set_info (e->u.operand, ni); - ffeexpr_exprstack_push_operand_ (e); - return (ffelexHandler) ffeexpr_token_binary_; - - default: - break; - } - - /* Nothing specific we were looking for, so make an integer and pass the - current token to the binary state. */ - - ffeexpr_make_float_const_ ('I', ffeexpr_tokens_[0], NULL, NULL, - NULL, NULL, NULL); - return (ffelexHandler) ffeexpr_token_binary_ (t); -} - -/* ffeexpr_token_number_exponent_ -- Rhs NUMBER NAME(D, E, or Q) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Ensures this token is PLUS or MINUS, preserves it, goes to final state - for real number (exponent digits). Else treats number as integer, passes - name to binary, passes current token to subsequent handler. */ - -static ffelexHandler -ffeexpr_token_number_exponent_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - ffeexprExpr_ e; - ffelexHandler nexthandler; - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerdefault - (ffeexpr_tokens_[0])); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeINTEGER, FFEINFO_kindtypeINTEGERDEFAULT, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - nexthandler = (ffelexHandler) ffeexpr_token_binary_ (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) (*nexthandler) (t); - } - - ffeexpr_tokens_[2] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_exp_sign_; -} - -/* ffeexpr_token_number_exp_sign_ -- Rhs NUMBER NAME(D,E,Q) PLUS/MINUS - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Make sure token is a NUMBER, make a real constant out of all we have and - push it onto the expression stack. Else issue diagnostic and pretend - exponent field was a zero. */ - -static ffelexHandler -ffeexpr_token_number_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[1]), - ffelex_token_where_column (ffeexpr_tokens_[1])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffelex_token_text (ffeexpr_tokens_[1])[0], - ffeexpr_tokens_[0], NULL, NULL, - ffeexpr_tokens_[1], ffeexpr_tokens_[2], - NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_make_float_const_ (ffelex_token_text (ffeexpr_tokens_[1])[0], - ffeexpr_tokens_[0], NULL, NULL, - ffeexpr_tokens_[1], ffeexpr_tokens_[2], t); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_number_period_ -- Rhs NUMBER PERIOD - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle a period detected following a number at rhs state. Must begin a - floating-point value (as in 1., 1.2, 1.E3, or 1.E+3) or a dot-dot name. */ - -static ffelexHandler -ffeexpr_token_number_period_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffelexHandler nexthandler; - char *p; - char d; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - if ((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q')) - && ffeexpr_isdigits_ (++p)) - { - - /* Just exponent character by itself? In which case, PLUS or MINUS - must surely be next, followed by a NUMBER token. */ - - if (*p == '\0') - { - ffeexpr_tokens_[2] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_per_exp_; - } - ffeexpr_make_float_const_ (d, ffeexpr_tokens_[0], - ffeexpr_tokens_[1], NULL, t, NULL, - NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) ffeexpr_token_binary_; - } - /* A name not representing an exponent, so assume it will be something - like EQ, make an integer from the number, pass the period to binary - state and the current token to the resulting state. */ - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerdefault - (ffeexpr_tokens_[0])); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - nexthandler = (ffelexHandler) ffeexpr_token_binary_ - (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) (*nexthandler) (t); - - case FFELEX_typeNUMBER: - ffeexpr_tokens_[2] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_real_; - - default: - break; - } - - /* Nothing specific we were looking for, so make a real number and pass the - period and then the current token to the binary state. */ - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) ffeexpr_token_binary_ (t); -} - -/* ffeexpr_token_number_per_exp_ -- Rhs NUMBER PERIOD NAME(D, E, or Q) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Ensures this token is PLUS or MINUS, preserves it, goes to final state - for real number (exponent digits). Else treats number as real, passes - name to binary, passes current token to subsequent handler. */ - -static ffelexHandler -ffeexpr_token_number_per_exp_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - ffelexHandler nexthandler; - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - nexthandler = (ffelexHandler) ffeexpr_token_binary_ (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) (*nexthandler) (t); - } - - ffeexpr_tokens_[3] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_num_per_exp_sign_; -} - -/* ffeexpr_token_number_real_ -- Rhs NUMBER PERIOD NUMBER - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - After a number, period, and number, check next token for possible - exponent designation (D, E, or Q as first/only character) and continue - real-number handling accordingly. Else form basic real constant, push - onto expression stack, and enter binary state using current token (which, - if it is a name not beginning with D, E, or Q, will certainly result - in an error, but that's not for this routine to deal with). */ - -static ffelexHandler -ffeexpr_token_number_real_ (ffelexToken t) -{ - char d; - char *p; - - if (((ffelex_token_type (t) != FFELEX_typeNAME) - && (ffelex_token_type (t) != FFELEX_typeNAMES)) - || !(((ffesrc_char_match_init ((d = *(p = ffelex_token_text (t))), - 'D', 'd') - || ffesrc_char_match_init (d, 'E', 'e') - || ffesrc_char_match_init (d, 'Q', 'q'))) - && ffeexpr_isdigits_ (++p))) - { -#if 0 - /* This code has been removed because it seems inconsistent to - produce a diagnostic in this case, but not all of the other - ones that look for an exponent and cannot recognize one. */ - if (((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - && ffest_ffebad_start (FFEBAD_INVALID_EXPONENT)) - { - char bad[2]; - - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - bad[0] = *(p - 1); - bad[1] = '\0'; - ffebad_string (bad); - ffebad_finish (); - } -#endif - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - ffeexpr_tokens_[2], NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - /* Just exponent character by itself? In which case, PLUS or MINUS must - surely be next, followed by a NUMBER token. */ - - if (*p == '\0') - { - ffeexpr_tokens_[3] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_number_real_exp_; - } - - ffeexpr_make_float_const_ (d, ffeexpr_tokens_[0], ffeexpr_tokens_[1], - ffeexpr_tokens_[2], t, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_num_per_exp_sign_ -- Rhs NUMBER PERIOD NAME(D,E,Q) PLUS/MINUS - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Make sure token is a NUMBER, make a real constant out of all we have and - push it onto the expression stack. Else issue diagnostic and pretend - exponent field was a zero. */ - -static ffelexHandler -ffeexpr_token_num_per_exp_sign_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[2]), - ffelex_token_where_column (ffeexpr_tokens_[2])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - NULL, NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_make_float_const_ (ffelex_token_text (ffeexpr_tokens_[2])[0], - ffeexpr_tokens_[0], ffeexpr_tokens_[1], NULL, - ffeexpr_tokens_[2], ffeexpr_tokens_[3], t); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_number_real_exp_ -- Rhs NUMBER PERIOD NUMBER NAME(D, E, or Q) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Ensures this token is PLUS or MINUS, preserves it, goes to final state - for real number (exponent digits). Else issues diagnostic, assumes a - zero exponent field for number, passes token on to binary state as if - previous token had been "E0" instead of "E", for example. */ - -static ffelexHandler -ffeexpr_token_number_real_exp_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typePLUS) - && (ffelex_token_type (t) != FFELEX_typeMINUS)) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[3]), - ffelex_token_where_column (ffeexpr_tokens_[3])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - ffeexpr_tokens_[2], NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_tokens_[4] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_num_real_exp_sn_; -} - -/* ffeexpr_token_num_real_exp_sn_ -- Rhs NUMBER PERIOD NUMBER NAME(D,E,Q) - PLUS/MINUS - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Make sure token is a NUMBER, make a real constant out of all we have and - push it onto the expression stack. Else issue diagnostic and pretend - exponent field was a zero. */ - -static ffelexHandler -ffeexpr_token_num_real_exp_sn_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { - if (ffest_ffebad_start (FFEBAD_MISSING_EXPONENT_VALUE)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[3]), - ffelex_token_where_column (ffeexpr_tokens_[3])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffeexpr_make_float_const_ (ffesrc_char_internal_init ('E', 'e'), - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - ffeexpr_tokens_[2], NULL, NULL, NULL); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - ffelex_token_kill (ffeexpr_tokens_[4]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } - - ffeexpr_make_float_const_ (ffelex_token_text (ffeexpr_tokens_[3])[0], - ffeexpr_tokens_[0], ffeexpr_tokens_[1], - ffeexpr_tokens_[2], ffeexpr_tokens_[3], - ffeexpr_tokens_[4], t); - - ffelex_token_kill (ffeexpr_tokens_[0]); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - ffelex_token_kill (ffeexpr_tokens_[3]); - ffelex_token_kill (ffeexpr_tokens_[4]); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_binary_ -- Handle binary operator possibility - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - The possibility of a binary operator is handled here, meaning the previous - token was an operand. */ - -static ffelexHandler -ffeexpr_token_binary_ (ffelexToken t) -{ - ffeexprExpr_ e; - - if (!ffeexpr_stack_->is_rhs) - return (ffelexHandler) ffeexpr_finished_ (t); /* For now. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typePLUS: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorADD_; - e->u.operator.prec = FFEEXPR_operatorprecedenceADD_; - e->u.operator.as = FFEEXPR_operatorassociativityADD_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeMINUS: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorSUBTRACT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceSUBTRACT_; - e->u.operator.as = FFEEXPR_operatorassociativitySUBTRACT_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeASTERISK: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - return (ffelexHandler) ffeexpr_finished_ (t); - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorMULTIPLY_; - e->u.operator.prec = FFEEXPR_operatorprecedenceMULTIPLY_; - e->u.operator.as = FFEEXPR_operatorassociativityMULTIPLY_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeSLASH: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATA: - return (ffelexHandler) ffeexpr_finished_ (t); - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorDIVIDE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceDIVIDE_; - e->u.operator.as = FFEEXPR_operatorassociativityDIVIDE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typePOWER: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorPOWER_; - e->u.operator.prec = FFEEXPR_operatorprecedencePOWER_; - e->u.operator.as = FFEEXPR_operatorassociativityPOWER_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeCONCAT: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorCONCATENATE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceCONCATENATE_; - e->u.operator.as = FFEEXPR_operatorassociativityCONCATENATE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeOPEN_ANGLE: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - ffebad_start (FFEBAD_FORMAT_EXPR_TOKEN); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - break; - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorLT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceLT_; - e->u.operator.as = FFEEXPR_operatorassociativityLT_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeCLOSE_ANGLE: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - return ffeexpr_finished_ (t); - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorGT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceGT_; - e->u.operator.as = FFEEXPR_operatorassociativityGT_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeREL_EQ: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - ffebad_start (FFEBAD_FORMAT_EXPR_TOKEN); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - break; - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorEQ_; - e->u.operator.prec = FFEEXPR_operatorprecedenceEQ_; - e->u.operator.as = FFEEXPR_operatorassociativityEQ_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeREL_NE: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - ffebad_start (FFEBAD_FORMAT_EXPR_TOKEN); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - break; - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorNE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceNE_; - e->u.operator.as = FFEEXPR_operatorassociativityNE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeREL_LE: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - ffebad_start (FFEBAD_FORMAT_EXPR_TOKEN); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - break; - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorLE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceLE_; - e->u.operator.as = FFEEXPR_operatorassociativityLE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typeREL_GE: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextFORMAT: - ffebad_start (FFEBAD_FORMAT_EXPR_TOKEN); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - break; - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorGE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceGE_; - e->u.operator.as = FFEEXPR_operatorassociativityGE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_; - - case FFELEX_typePERIOD: - ffeexpr_tokens_[0] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_binary_period_; - -#if 0 - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeCLOSE_PAREN: - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNAMES: -#endif - default: - return (ffelexHandler) ffeexpr_finished_ (t); - } -} - -/* ffeexpr_token_binary_period_ -- Binary PERIOD - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle a period detected at binary (expecting binary op or end) state. - Must begin a dot-dot name, of which .NOT., .TRUE., and .FALSE. are not - valid. */ - -static ffelexHandler -ffeexpr_token_binary_period_ (ffelexToken t) -{ - ffeexprExpr_ operand; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_current_dotdot_ = ffestr_other (t); - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherTRUE: - case FFESTR_otherFALSE: - case FFESTR_otherNOT: - if (ffest_ffebad_start (FFEBAD_MISSING_BINARY_OPERATOR)) - { - operand = ffeexpr_stack_->exprstack; - assert (operand != NULL); - assert (operand->type == FFEEXPR_exprtypeOPERAND_); - ffebad_here (0, ffelex_token_where_line (operand->token), ffelex_token_where_column (operand->token)); - ffebad_here (1, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_binary_sw_per_; - - default: - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_binary_end_per_; - } - break; /* Nothing really reaches here. */ - - default: - if (ffest_ffebad_start (FFEBAD_IGNORING_PERIOD)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_binary_ (t); - } -} - -/* ffeexpr_token_binary_end_per_ -- Binary PERIOD NAME(not NOT, TRUE, or FALSE) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Expecting a period to close a dot-dot at binary (binary op - or operator) state. If period isn't found, issue a diagnostic but - pretend we saw one. ffeexpr_current_dotdot_ must already contained the - dotdot representation of the name in between the two PERIOD tokens. */ - -static ffelexHandler -ffeexpr_token_binary_end_per_ (ffelexToken t) -{ - ffeexprExpr_ e; - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffeexpr_tokens_[0]; - - switch (ffeexpr_current_dotdot_) - { - case FFESTR_otherAND: - e->u.operator.op = FFEEXPR_operatorAND_; - e->u.operator.prec = FFEEXPR_operatorprecedenceAND_; - e->u.operator.as = FFEEXPR_operatorassociativityAND_; - break; - - case FFESTR_otherOR: - e->u.operator.op = FFEEXPR_operatorOR_; - e->u.operator.prec = FFEEXPR_operatorprecedenceOR_; - e->u.operator.as = FFEEXPR_operatorassociativityOR_; - break; - - case FFESTR_otherXOR: - e->u.operator.op = FFEEXPR_operatorXOR_; - e->u.operator.prec = FFEEXPR_operatorprecedenceXOR_; - e->u.operator.as = FFEEXPR_operatorassociativityXOR_; - break; - - case FFESTR_otherEQV: - e->u.operator.op = FFEEXPR_operatorEQV_; - e->u.operator.prec = FFEEXPR_operatorprecedenceEQV_; - e->u.operator.as = FFEEXPR_operatorassociativityEQV_; - break; - - case FFESTR_otherNEQV: - e->u.operator.op = FFEEXPR_operatorNEQV_; - e->u.operator.prec = FFEEXPR_operatorprecedenceNEQV_; - e->u.operator.as = FFEEXPR_operatorassociativityNEQV_; - break; - - case FFESTR_otherLT: - e->u.operator.op = FFEEXPR_operatorLT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceLT_; - e->u.operator.as = FFEEXPR_operatorassociativityLT_; - break; - - case FFESTR_otherLE: - e->u.operator.op = FFEEXPR_operatorLE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceLE_; - e->u.operator.as = FFEEXPR_operatorassociativityLE_; - break; - - case FFESTR_otherEQ: - e->u.operator.op = FFEEXPR_operatorEQ_; - e->u.operator.prec = FFEEXPR_operatorprecedenceEQ_; - e->u.operator.as = FFEEXPR_operatorassociativityEQ_; - break; - - case FFESTR_otherNE: - e->u.operator.op = FFEEXPR_operatorNE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceNE_; - e->u.operator.as = FFEEXPR_operatorassociativityNE_; - break; - - case FFESTR_otherGT: - e->u.operator.op = FFEEXPR_operatorGT_; - e->u.operator.prec = FFEEXPR_operatorprecedenceGT_; - e->u.operator.as = FFEEXPR_operatorassociativityGT_; - break; - - case FFESTR_otherGE: - e->u.operator.op = FFEEXPR_operatorGE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceGE_; - e->u.operator.as = FFEEXPR_operatorassociativityGE_; - break; - - default: - if (ffest_ffebad_start (FFEBAD_INVALID_DOTDOT)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_string (ffelex_token_text (ffeexpr_tokens_[1])); - ffebad_finish (); - } - e->u.operator.op = FFEEXPR_operatorEQ_; - e->u.operator.prec = FFEEXPR_operatorprecedenceEQ_; - e->u.operator.as = FFEEXPR_operatorassociativityEQ_; - break; - } - - ffeexpr_exprstack_push_binary_ (e); - - if (ffelex_token_type (t) != FFELEX_typePERIOD) - { - if (ffest_ffebad_start (FFEBAD_INSERTING_PERIOD)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffelex_token_text (ffeexpr_tokens_[1])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[1]); /* Kill dot-dot token. */ - return (ffelexHandler) ffeexpr_token_rhs_ (t); - } - - ffelex_token_kill (ffeexpr_tokens_[1]); /* Kill dot-dot token. */ - return (ffelexHandler) ffeexpr_token_rhs_; -} - -/* ffeexpr_token_binary_sw_per_ -- Rhs PERIOD NAME(NOT, TRUE, or FALSE) - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - A diagnostic has already been issued; just swallow a period if there is - one, then continue with ffeexpr_token_binary_. */ - -static ffelexHandler -ffeexpr_token_binary_sw_per_ (ffelexToken t) -{ - if (ffelex_token_type (t) != FFELEX_typePERIOD) - return (ffelexHandler) ffeexpr_token_binary_ (t); - - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_quote_ -- Rhs QUOTE - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Expecting a NUMBER that we'll treat as an octal integer. */ - -static ffelexHandler -ffeexpr_token_quote_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffebld anyexpr; - - if (ffelex_token_type (t) != FFELEX_typeNUMBER) - { - if (ffest_ffebad_start (FFEBAD_QUOTE_MISSES_DIGITS)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_rhs_ (t); - } - - /* This is kind of a kludge to prevent any whining about magical numbers - that start out as these octal integers, so "20000000000 (on a 32-bit - 2's-complement machine) by itself won't produce an error. */ - - anyexpr = ffebld_new_any (); - ffebld_set_info (anyexpr, ffeinfo_new_any ()); - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - e->u.operand = ffebld_new_conter_with_orig - (ffebld_constant_new_integeroctal (t), anyexpr); - ffebld_set_info (e->u.operand, ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - return (ffelexHandler) ffeexpr_token_binary_; -} - -/* ffeexpr_token_apostrophe_ -- Rhs APOSTROPHE - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle an open-apostrophe, which begins either a character ('char-const'), - typeless octal ('octal-const'O), or typeless hexadecimal ('hex-const'Z or - 'hex-const'X) constant. */ - -static ffelexHandler -ffeexpr_token_apostrophe_ (ffelexToken t) -{ - assert (ffelex_token_type (t) == FFELEX_typeCHARACTER); - if (ffe_is_pedantic_not_90 () && (ffelex_token_length (t) == 0)) - { - ffebad_start (FFEBAD_NULL_CHAR_CONST); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_apos_char_; -} - -/* ffeexpr_token_apos_char_ -- Rhs APOSTROPHE CHARACTER - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Close-apostrophe is implicit; if this token is NAME, it is a possible - typeless-constant radix specifier. */ - -static ffelexHandler -ffeexpr_token_apos_char_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffeinfo ni; - char c; - ffetargetCharacterSize size; - - if ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - { - if ((ffelex_token_length (t) == 1) - && (ffesrc_char_match_init ((c = ffelex_token_text (t)[0]), 'B', - 'b') - || ffesrc_char_match_init (c, 'O', 'o') - || ffesrc_char_match_init (c, 'X', 'x') - || ffesrc_char_match_init (c, 'Z', 'z'))) - { - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - switch (c) - { - case FFESRC_CASE_MATCH_INIT ('B', 'b', match_b, no_match): - e->u.operand = ffebld_new_conter - (ffebld_constant_new_typeless_bv (ffeexpr_tokens_[1])); - size = ffetarget_size_typeless_binary (ffeexpr_tokens_[1]); - break; - - case FFESRC_CASE_MATCH_INIT ('O', 'o', match_o, no_match): - e->u.operand = ffebld_new_conter - (ffebld_constant_new_typeless_ov (ffeexpr_tokens_[1])); - size = ffetarget_size_typeless_octal (ffeexpr_tokens_[1]); - break; - - case FFESRC_CASE_MATCH_INIT ('X', 'x', match_x, no_match): - e->u.operand = ffebld_new_conter - (ffebld_constant_new_typeless_hxv (ffeexpr_tokens_[1])); - size = ffetarget_size_typeless_hex (ffeexpr_tokens_[1]); - break; - - case FFESRC_CASE_MATCH_INIT ('Z', 'z', match_z, no_match): - e->u.operand = ffebld_new_conter - (ffebld_constant_new_typeless_hzv (ffeexpr_tokens_[1])); - size = ffetarget_size_typeless_hex (ffeexpr_tokens_[1]); - break; - - default: - no_match: /* :::::::::::::::::::: */ - assert ("not BOXZ!" == NULL); - size = 0; - break; - } - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeTYPELESS, FFEINFO_kindtypeNONE, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, size)); - ffeexpr_exprstack_push_operand_ (e); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) ffeexpr_token_binary_; - } - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - e->u.operand = ffebld_new_conter (ffebld_constant_new_characterdefault - (ffeexpr_tokens_[1])); - ni = ffeinfo_new (FFEINFO_basictypeCHARACTER, FFEINFO_kindtypeCHARACTERDEFAULT, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - ffelex_token_length (ffeexpr_tokens_[1])); - ffebld_set_info (e->u.operand, ni); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffeexpr_exprstack_push_operand_ (e); - if ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES)) - { - if (ffest_ffebad_start (FFEBAD_INVALID_RADIX_SPECIFIER)) - { - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_finish (); - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeBINARY_; - e->token = ffelex_token_use (t); - e->u.operator.op = FFEEXPR_operatorCONCATENATE_; - e->u.operator.prec = FFEEXPR_operatorprecedenceCONCATENATE_; - e->u.operator.as = FFEEXPR_operatorassociativityCONCATENATE_; - ffeexpr_exprstack_push_binary_ (e); - return (ffelexHandler) ffeexpr_token_rhs_ (t); - } - ffeexpr_is_substr_ok_ = !ffe_is_pedantic_not_90 (); /* Allow "'hello'(3:5)". */ - return (ffelexHandler) ffeexpr_token_substrp_ (t); -} - -/* ffeexpr_token_name_lhs_ -- Lhs NAME - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle a name followed by open-paren, period (RECORD.MEMBER), percent - (RECORD%MEMBER), or nothing at all. */ - -static ffelexHandler -ffeexpr_token_name_lhs_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffeexprParenType_ paren_type; - ffesymbol s; - ffebld expr; - ffeinfo info; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextFILEUNIT_DF: - goto just_name; /* :::::::::::::::::::: */ - - default: - break; - } - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffelex_token_use (ffeexpr_tokens_[0]); - s = ffeexpr_declare_parenthesized_ (ffeexpr_tokens_[0], FALSE, - &paren_type); - - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - if (ffeexpr_stack_->context == FFEEXPR_contextSUBROUTINEREF) - ffesymbol_error (s, ffeexpr_tokens_[0]); /* Recursion. */ - break; - - case FFEINFO_whereINTRINSIC: - case FFEINFO_whereGLOBAL: - if (ffeexpr_stack_->context != FFEEXPR_contextSUBROUTINEREF) - ffesymbol_error (s, ffeexpr_tokens_[0]); /* Can call intrin. */ - break; - - case FFEINFO_whereCOMMON: - case FFEINFO_whereDUMMY: - case FFEINFO_whereRESULT: - break; - - case FFEINFO_whereNONE: - case FFEINFO_whereANY: - break; - - default: - ffesymbol_error (s, ffeexpr_tokens_[0]); - break; - } - - if (ffesymbol_attrs (s) & FFESYMBOL_attrsANY) - { - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - } - else - { - e->u.operand = ffebld_new_symter (s, - ffesymbol_generic (s), - ffesymbol_specific (s), - ffesymbol_implementation (s)); - ffebld_set_info (e->u.operand, ffesymbol_info (s)); - } - ffeexpr_exprstack_push_ (e); /* Not a complete operand yet. */ - ffeexpr_stack_->tokens[0] = ffeexpr_tokens_[0]; - switch (paren_type) - { - case FFEEXPR_parentypeSUBROUTINE_: - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextACTUALARG_, - ffeexpr_token_arguments_); - - case FFEEXPR_parentypeARRAY_: - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - ffeexpr_stack_->bound_list = ffesymbol_dims (s); - ffeexpr_stack_->rank = 0; - ffeexpr_stack_->constant = TRUE; - ffeexpr_stack_->immediate = TRUE; - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextDATAIMPDOITEM_: - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextDATAIMPDOINDEX_, - ffeexpr_token_elements_); - - case FFEEXPR_contextEQUIVALENCE: - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextEQVINDEX_, - ffeexpr_token_elements_); - - default: - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextINDEX_, - ffeexpr_token_elements_); - } - - case FFEEXPR_parentypeSUBSTRING_: - e->u.operand = ffeexpr_collapse_symter (e->u.operand, - ffeexpr_tokens_[0]); - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextINDEX_, - ffeexpr_token_substring_); - - case FFEEXPR_parentypeEQUIVALENCE_: - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - ffeexpr_stack_->bound_list = ffesymbol_dims (s); - ffeexpr_stack_->rank = 0; - ffeexpr_stack_->constant = TRUE; - ffeexpr_stack_->immediate = TRUE; - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextEQVINDEX_, - ffeexpr_token_equivalence_); - - case FFEEXPR_parentypeFUNCTION_: /* Invalid case. */ - case FFEEXPR_parentypeFUNSUBSTR_: /* Invalid case. */ - ffesymbol_error (s, ffeexpr_tokens_[0]); - /* Fall through. */ - case FFEEXPR_parentypeANY_: - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextACTUALARG_, - ffeexpr_token_anything_); - - default: - assert ("bad paren type" == NULL); - break; - } - - case FFELEX_typeEQUALS: /* As in "VAR=". */ - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextIMPDOITEM_: /* within - "(,VAR=start,end[,incr])". */ - case FFEEXPR_contextIMPDOITEMDF_: - ffeexpr_stack_->context = FFEEXPR_contextIMPDOCTRL_; - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - ffeexpr_stack_->context = FFEEXPR_contextDATAIMPDOCTRL_; - break; - - default: - break; - } - break; - -#if 0 - case FFELEX_typePERIOD: - case FFELEX_typePERCENT: - assert ("FOO%, FOO. not yet supported!~~" == NULL); - break; -#endif - - default: - break; - } - -just_name: /* :::::::::::::::::::: */ - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - s = ffeexpr_declare_unadorned_ (ffeexpr_tokens_[0], - (ffeexpr_stack_->context - == FFEEXPR_contextSUBROUTINEREF)); - - switch (ffesymbol_where (s)) - { - case FFEINFO_whereCONSTANT: - if ((ffeexpr_stack_->context != FFEEXPR_contextPARAMETER) - || (ffesymbol_kind (s) != FFEINFO_kindENTITY)) - ffesymbol_error (s, ffeexpr_tokens_[0]); - break; - - case FFEINFO_whereIMMEDIATE: - if ((ffeexpr_stack_->context != FFEEXPR_contextDATAIMPDOCTRL_) - && (ffeexpr_stack_->context != FFEEXPR_contextDATAIMPDOINDEX_)) - ffesymbol_error (s, ffeexpr_tokens_[0]); - break; - - case FFEINFO_whereLOCAL: - if (ffeexpr_stack_->context == FFEEXPR_contextSUBROUTINEREF) - ffesymbol_error (s, ffeexpr_tokens_[0]); /* Recurse!. */ - break; - - case FFEINFO_whereINTRINSIC: - if (ffeexpr_stack_->context != FFEEXPR_contextSUBROUTINEREF) - ffesymbol_error (s, ffeexpr_tokens_[0]); /* Can call intrin. */ - break; - - default: - break; - } - - if (ffesymbol_attrs (s) & FFESYMBOL_attrsANY) - { - expr = ffebld_new_any (); - info = ffeinfo_new_any (); - ffebld_set_info (expr, info); - } - else - { - expr = ffebld_new_symter (s, - ffesymbol_generic (s), - ffesymbol_specific (s), - ffesymbol_implementation (s)); - info = ffesymbol_info (s); - ffebld_set_info (expr, info); - if (ffesymbol_is_doiter (s)) - { - ffebad_start (FFEBAD_DOITER); - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffest_ffebad_here_doiter (1, s); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } - expr = ffeexpr_collapse_symter (expr, ffeexpr_tokens_[0]); - } - - if (ffeexpr_stack_->context == FFEEXPR_contextSUBROUTINEREF) - { - if (ffebld_op (expr) == FFEBLD_opANY) - { - expr = ffebld_new_any (); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - else - { - expr = ffebld_new_subrref (expr, NULL); /* No argument list. */ - if (ffesymbol_generic (s) != FFEINTRIN_genNONE) - ffeintrin_fulfill_generic (&expr, &info, e->token); - else if (ffesymbol_specific (s) != FFEINTRIN_specNONE) - ffeintrin_fulfill_specific (&expr, &info, NULL, e->token); - else - ffeexpr_fulfill_call_ (&expr, e->token); - - if (ffebld_op (expr) != FFEBLD_opANY) - ffebld_set_info (expr, - ffeinfo_new (ffeinfo_basictype (info), - ffeinfo_kindtype (info), - 0, - FFEINFO_kindENTITY, - FFEINFO_whereFLEETING, - ffeinfo_size (info))); - else - ffebld_set_info (expr, ffeinfo_new_any ()); - } - } - - e->u.operand = expr; - ffeexpr_exprstack_push_operand_ (e); - return (ffelexHandler) ffeexpr_finished_ (t); -} - -/* ffeexpr_token_name_arg_ -- Rhs NAME - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle first token in an actual-arg (or possible actual-arg) context - being a NAME, and use second token to refine the context. */ - -static ffelexHandler -ffeexpr_token_name_arg_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - case FFELEX_typeCOMMA: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARG_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARG_; - break; - - default: - break; - } - break; - - default: - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextACTUALARGEXPR_; - break; - - case FFEEXPR_contextINDEXORACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextINDEXORACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - ffeexpr_stack_->context = FFEEXPR_contextSFUNCDEFACTUALARGEXPR_; - break; - - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - ffeexpr_stack_->context - = FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_; - break; - - default: - assert ("bad context in _name_arg_" == NULL); - break; - } - break; - } - - return (ffelexHandler) ffeexpr_token_name_rhs_ (t); -} - -/* ffeexpr_token_name_rhs_ -- Rhs NAME - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle a name followed by open-paren, apostrophe (O'octal-const', - Z'hex-const', or X'hex-const'), period (RECORD.MEMBER). - - 26-Nov-91 JCB 1.2 - When followed by apostrophe or quote, set lex hexnum flag on so - [0-9] as first char of next token seen as starting a potentially - hex number (NAME). - 04-Oct-91 JCB 1.1 - In case of intrinsic, decorate its SYMTER with the type info for - the specific intrinsic. */ - -static ffelexHandler -ffeexpr_token_name_rhs_ (ffelexToken t) -{ - ffeexprExpr_ e; - ffeexprParenType_ paren_type; - ffesymbol s; - bool sfdef; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeQUOTE: - case FFELEX_typeAPOSTROPHE: - ffeexpr_tokens_[1] = ffelex_token_use (t); - ffelex_set_hexnum (TRUE); - return (ffelexHandler) ffeexpr_token_name_apos_; - - case FFELEX_typeOPEN_PAREN: - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffelex_token_use (ffeexpr_tokens_[0]); - s = ffeexpr_declare_parenthesized_ (ffeexpr_tokens_[0], TRUE, - &paren_type); - if (ffesymbol_attrs (s) & FFESYMBOL_attrsANY) - e->u.operand = ffebld_new_any (); - else - e->u.operand = ffebld_new_symter (s, ffesymbol_generic (s), - ffesymbol_specific (s), - ffesymbol_implementation (s)); - ffeexpr_exprstack_push_ (e); /* Not a complete operand yet. */ - ffeexpr_stack_->tokens[0] = ffeexpr_tokens_[0]; - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - sfdef = TRUE; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("weird context!" == NULL); - sfdef = FALSE; - break; - - default: - sfdef = FALSE; - break; - } - switch (paren_type) - { - case FFEEXPR_parentypeFUNCTION_: - ffebld_set_info (e->u.operand, ffesymbol_info (s)); - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - if (ffesymbol_where (s) == FFEINFO_whereCONSTANT) - { /* A statement function. */ - ffeexpr_stack_->num_args - = ffebld_list_length - (ffeexpr_stack_->next_dummy - = ffesymbol_dummyargs (s)); - ffeexpr_stack_->tokens[1] = NULL; /* !=NULL when > num_args. */ - } - else if ((ffesymbol_where (s) == FFEINFO_whereINTRINSIC) - && !ffe_is_pedantic_not_90 () - && ((ffesymbol_implementation (s) - == FFEINTRIN_impICHAR) - || (ffesymbol_implementation (s) - == FFEINTRIN_impIACHAR) - || (ffesymbol_implementation (s) - == FFEINTRIN_impLEN))) - { /* Allow arbitrary concatenations. */ - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEF - : FFEEXPR_contextLET, - ffeexpr_token_arguments_); - } - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEFACTUALARG_ - : FFEEXPR_contextACTUALARG_, - ffeexpr_token_arguments_); - - case FFEEXPR_parentypeARRAY_: - ffebld_set_info (e->u.operand, - ffesymbol_info (ffebld_symter (e->u.operand))); - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - ffeexpr_stack_->bound_list = ffesymbol_dims (s); - ffeexpr_stack_->rank = 0; - ffeexpr_stack_->constant = TRUE; - ffeexpr_stack_->immediate = TRUE; - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEFINDEX_ - : FFEEXPR_contextINDEX_, - ffeexpr_token_elements_); - - case FFEEXPR_parentypeSUBSTRING_: - ffebld_set_info (e->u.operand, - ffesymbol_info (ffebld_symter (e->u.operand))); - e->u.operand = ffeexpr_collapse_symter (e->u.operand, - ffeexpr_tokens_[0]); - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEFINDEX_ - : FFEEXPR_contextINDEX_, - ffeexpr_token_substring_); - - case FFEEXPR_parentypeFUNSUBSTR_: - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_ - : FFEEXPR_contextINDEXORACTUALARG_, - ffeexpr_token_funsubstr_); - - case FFEEXPR_parentypeANY_: - ffebld_set_info (e->u.operand, ffesymbol_info (s)); - return - (ffelexHandler) - ffeexpr_rhs (ffeexpr_stack_->pool, - sfdef - ? FFEEXPR_contextSFUNCDEFACTUALARG_ - : FFEEXPR_contextACTUALARG_, - ffeexpr_token_anything_); - - default: - assert ("bad paren type" == NULL); - break; - } - - case FFELEX_typeEQUALS: /* As in "VAR=". */ - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextIMPDOITEM_: /* "(,VAR=start,end[,incr])". */ - case FFEEXPR_contextIMPDOITEMDF_: - ffeexpr_stack_->is_rhs = FALSE; /* Really an lhs construct. */ - ffeexpr_stack_->context = FFEEXPR_contextIMPDOCTRL_; - break; - - default: - break; - } - break; - -#if 0 - case FFELEX_typePERIOD: - case FFELEX_typePERCENT: - ~~Support these two someday, though not required - assert ("FOO%, FOO. not yet supported!~~" == NULL); - break; -#endif - - default: - break; - } - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextINDEXORACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("strange context" == NULL); - break; - - default: - break; - } - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - s = ffeexpr_declare_unadorned_ (ffeexpr_tokens_[0], FALSE); - if (ffesymbol_attrs (s) & FFESYMBOL_attrsANY) - { - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - } - else - { - e->u.operand = ffebld_new_symter (s, FFEINTRIN_genNONE, - ffesymbol_specific (s), - ffesymbol_implementation (s)); - if (ffesymbol_specific (s) == FFEINTRIN_specNONE) - ffebld_set_info (e->u.operand, ffeinfo_use (ffesymbol_info (s))); - else - { /* Decorate the SYMTER with the actual type - of the intrinsic. */ - ffebld_set_info (e->u.operand, ffeinfo_new - (ffeintrin_basictype (ffesymbol_specific (s)), - ffeintrin_kindtype (ffesymbol_specific (s)), - 0, - ffesymbol_kind (s), - ffesymbol_where (s), - FFETARGET_charactersizeNONE)); - } - if (ffesymbol_is_doiter (s)) - ffebld_symter_set_is_doiter (e->u.operand, TRUE); - e->u.operand = ffeexpr_collapse_symter (e->u.operand, - ffeexpr_tokens_[0]); - } - ffeexpr_exprstack_push_operand_ (e); - return (ffelexHandler) ffeexpr_token_binary_ (t); -} - -/* ffeexpr_token_name_apos_ -- Rhs NAME APOSTROPHE - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Expecting a NAME token, analyze the previous NAME token to see what kind, - if any, typeless constant we've got. - - 01-Sep-90 JCB 1.1 - Expect a NAME instead of CHARACTER in this situation. */ - -static ffelexHandler -ffeexpr_token_name_apos_ (ffelexToken t) -{ - ffeexprExpr_ e; - - ffelex_set_hexnum (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffeexpr_tokens_[2] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_name_apos_name_; - - default: - break; - } - - if (ffest_ffebad_start (FFEBAD_INVALID_RADIX_SPECIFIER)) - { - ffebad_string (ffelex_token_text (ffeexpr_tokens_[0])); - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffelex_token_kill (ffeexpr_tokens_[1]); - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - e->token = ffeexpr_tokens_[0]; - ffeexpr_exprstack_push_operand_ (e); - - return (ffelexHandler) ffeexpr_token_binary_ (t); -} - -/* ffeexpr_token_name_apos_name_ -- Rhs NAME APOSTROPHE NAME - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Expecting an APOSTROPHE token, analyze the previous NAME token to see - what kind, if any, typeless constant we've got. */ - -static ffelexHandler -ffeexpr_token_name_apos_name_ (ffelexToken t) -{ - ffeexprExpr_ e; - char c; - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - e->token = ffeexpr_tokens_[0]; - - if ((ffelex_token_type (t) == ffelex_token_type (ffeexpr_tokens_[1])) - && (ffelex_token_length (ffeexpr_tokens_[0]) == 1) - && (ffesrc_char_match_init ((c = ffelex_token_text (ffeexpr_tokens_[0])[0]), - 'B', 'b') - || ffesrc_char_match_init (c, 'O', 'o') - || ffesrc_char_match_init (c, 'X', 'x') - || ffesrc_char_match_init (c, 'Z', 'z'))) - { - ffetargetCharacterSize size; - - if (!ffe_is_typeless_boz ()) { - - switch (c) - { - case FFESRC_CASE_MATCH_INIT ('B', 'b', imatch_b, no_imatch): - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerbinary - (ffeexpr_tokens_[2])); - break; - - case FFESRC_CASE_MATCH_INIT ('O', 'o', imatch_o, no_imatch): - e->u.operand = ffebld_new_conter (ffebld_constant_new_integeroctal - (ffeexpr_tokens_[2])); - break; - - case FFESRC_CASE_MATCH_INIT ('X', 'x', imatch_x, no_imatch): - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerhex - (ffeexpr_tokens_[2])); - break; - - case FFESRC_CASE_MATCH_INIT ('Z', 'z', imatch_z, no_imatch): - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerhex - (ffeexpr_tokens_[2])); - break; - - default: - no_imatch: /* :::::::::::::::::::: */ - assert ("not BOXZ!" == NULL); - abort (); - } - - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - ffeexpr_exprstack_push_operand_ (e); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_; - } - - switch (c) - { - case FFESRC_CASE_MATCH_INIT ('B', 'b', match_b, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_typeless_bm - (ffeexpr_tokens_[2])); - size = ffetarget_size_typeless_binary (ffeexpr_tokens_[2]); - break; - - case FFESRC_CASE_MATCH_INIT ('O', 'o', match_o, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_typeless_om - (ffeexpr_tokens_[2])); - size = ffetarget_size_typeless_octal (ffeexpr_tokens_[2]); - break; - - case FFESRC_CASE_MATCH_INIT ('X', 'x', match_x, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_typeless_hxm - (ffeexpr_tokens_[2])); - size = ffetarget_size_typeless_hex (ffeexpr_tokens_[2]); - break; - - case FFESRC_CASE_MATCH_INIT ('Z', 'z', match_z, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_typeless_hzm - (ffeexpr_tokens_[2])); - size = ffetarget_size_typeless_hex (ffeexpr_tokens_[2]); - break; - - default: - no_match: /* :::::::::::::::::::: */ - assert ("not BOXZ!" == NULL); - e->u.operand = ffebld_new_conter (ffebld_constant_new_typeless_hzm - (ffeexpr_tokens_[2])); - size = ffetarget_size_typeless_hex (ffeexpr_tokens_[2]); - break; - } - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeTYPELESS, FFEINFO_kindtypeNONE, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, size)); - ffeexpr_exprstack_push_operand_ (e); - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - return (ffelexHandler) ffeexpr_token_binary_; - } - - if (ffest_ffebad_start (FFEBAD_INVALID_RADIX_SPECIFIER)) - { - ffebad_string (ffelex_token_text (ffeexpr_tokens_[0])); - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - ffelex_token_kill (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[2]); - - e->type = FFEEXPR_exprtypeOPERAND_; - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - e->token = ffeexpr_tokens_[0]; - ffeexpr_exprstack_push_operand_ (e); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - return (ffelexHandler) ffeexpr_token_binary_; - - default: - return (ffelexHandler) ffeexpr_token_binary_ (t); - } -} - -/* ffeexpr_token_percent_ -- Rhs PERCENT - - Handle a percent sign possibly followed by "LOC". If followed instead - by "VAL", "REF", or "DESCR", issue an error message and substitute - "LOC". If followed by something else, treat the percent sign as a - spurious incorrect token and reprocess the token via _rhs_. */ - -static ffelexHandler -ffeexpr_token_percent_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffeexpr_stack_->percent = ffeexpr_percent_ (t); - ffeexpr_tokens_[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_token_percent_name_; - - default: - if (ffest_ffebad_start (FFEBAD_INVALID_TOKEN_IN_EXPRESSION)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - return (ffelexHandler) ffeexpr_token_rhs_ (t); - } -} - -/* ffeexpr_token_percent_name_ -- Rhs PERCENT NAME - - Make sure the token is OPEN_PAREN and prepare for the one-item list of - LHS expressions. Else display an error message. */ - -static ffelexHandler -ffeexpr_token_percent_name_ (ffelexToken t) -{ - ffelexHandler nexthandler; - - if (ffelex_token_type (t) != FFELEX_typeOPEN_PAREN) - { - if (ffest_ffebad_start (FFEBAD_INVALID_TOKEN_IN_EXPRESSION)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->first_token), - ffelex_token_where_column (ffeexpr_stack_->first_token)); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_tokens_[0]); - nexthandler = (ffelexHandler) ffeexpr_token_rhs_ (ffeexpr_tokens_[1]); - ffelex_token_kill (ffeexpr_tokens_[1]); - return (ffelexHandler) (*nexthandler) (t); - } - - switch (ffeexpr_stack_->percent) - { - default: - if (ffest_ffebad_start (FFEBAD_INVALID_PERCENT)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_tokens_[0]), - ffelex_token_where_column (ffeexpr_tokens_[0])); - ffebad_string (ffelex_token_text (ffeexpr_tokens_[1])); - ffebad_finish (); - } - ffeexpr_stack_->percent = FFEEXPR_percentLOC_; - /* Fall through. */ - case FFEEXPR_percentLOC_: - ffeexpr_stack_->tokens[0] = ffeexpr_tokens_[0]; - ffelex_token_kill (ffeexpr_tokens_[1]); - ffeexpr_stack_->tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextLOC_, - ffeexpr_cb_end_loc_); - } -} - -/* ffeexpr_make_float_const_ -- Make a floating-point constant - - See prototype. - - Pass 'E', 'D', or 'Q' for exponent letter. */ - -static void -ffeexpr_make_float_const_ (char exp_letter, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits) -{ - ffeexprExpr_ e; - - e = ffeexpr_expr_new_ (); - e->type = FFEEXPR_exprtypeOPERAND_; - if (integer != NULL) - e->token = ffelex_token_use (integer); - else - { - assert (decimal != NULL); - e->token = ffelex_token_use (decimal); - } - - switch (exp_letter) - { -#if !FFETARGET_okREALQUAD - case FFESRC_CASE_MATCH_INIT ('Q', 'q', match_q, no_match): - if (ffebad_start (FFEBAD_QUAD_UNSUPPORTED)) - { - ffebad_here (0, ffelex_token_where_line (e->token), - ffelex_token_where_column (e->token)); - ffebad_finish (); - } - goto match_d; /* The FFESRC_CASE_* macros don't - allow fall-through! */ -#endif - - case FFESRC_CASE_MATCH_INIT ('D', 'd', match_d, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_realdouble - (integer, decimal, fraction, exponent, exponent_sign, exponent_digits)); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALDOUBLE, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - break; - - case FFESRC_CASE_MATCH_INIT ('E', 'e', match_e, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_realdefault - (integer, decimal, fraction, exponent, exponent_sign, exponent_digits)); - ffebld_set_info (e->u.operand, ffeinfo_new (FFEINFO_basictypeREAL, - FFEINFO_kindtypeREALDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - break; - -#if FFETARGET_okREALQUAD - case FFESRC_CASE_MATCH_INIT ('Q', 'q', match_q, no_match): - e->u.operand = ffebld_new_conter (ffebld_constant_new_realquad - (integer, decimal, fraction, exponent, exponent_sign, exponent_digits)); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeREAL, FFEINFO_kindtypeREALQUAD, - 0, FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, FFETARGET_charactersizeNONE)); - break; -#endif - - case 'I': /* Make an integer. */ - e->u.operand = ffebld_new_conter (ffebld_constant_new_integerdefault - (ffeexpr_tokens_[0])); - ffebld_set_info (e->u.operand, - ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFEINFO_kindENTITY, FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - break; - - default: - no_match: /* :::::::::::::::::::: */ - assert ("Lost the exponent letter!" == NULL); - } - - ffeexpr_exprstack_push_operand_ (e); -} - -/* Just like ffesymbol_declare_local, except performs any implicit info - assignment necessary. */ - -static ffesymbol -ffeexpr_declare_unadorned_ (ffelexToken t, bool maybe_intrin) -{ - ffesymbol s; - ffeinfoKind k; - bool bad; - - s = ffesymbol_declare_local (t, maybe_intrin); - - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - /* Special-case these since they can involve a different concept - of "state" (in the stmtfunc name space). */ - { - case FFEEXPR_contextDATAIMPDOINDEX_: - case FFEEXPR_contextDATAIMPDOCTRL_: - if (ffeexpr_context_outer_ (ffeexpr_stack_) - == FFEEXPR_contextDATAIMPDOINDEX_) - s = ffeexpr_sym_impdoitem_ (s, t); - else - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_sym_impdoitem_ (s, t); - else - s = ffeexpr_sym_lhs_impdoctrl_ (s, t); - bad = (ffesymbol_kind (s) != FFEINFO_kindENTITY) - || ((ffesymbol_where (s) != FFEINFO_whereCONSTANT) - && (ffesymbol_where (s) != FFEINFO_whereIMMEDIATE)); - if (bad && (ffesymbol_kind (s) != FFEINFO_kindANY)) - ffesymbol_error (s, t); - return s; - - default: - break; - } - - switch ((ffesymbol_sfdummyparent (s) == NULL) - ? ffesymbol_state (s) - : FFESYMBOL_stateUNDERSTOOD) - { - case FFESYMBOL_stateNONE: /* Before first exec, not seen in expr - context. */ - if (!ffest_seen_first_exec ()) - goto seen; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFESYMBOL_stateUNCERTAIN: /* Unseen since first exec. */ - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSUBROUTINEREF: - s = ffeexpr_sym_lhs_call_ (s, t); - break; - - case FFEEXPR_contextFILEEXTFUNC: - s = ffeexpr_sym_lhs_extfunc_ (s, t); - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFEEXPR_contextACTUALARG_: - s = ffeexpr_sym_rhs_actualarg_ (s, t); - break; - - case FFEEXPR_contextDATA: - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_sym_rhs_let_ (s, t); - else - s = ffeexpr_sym_lhs_data_ (s, t); - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - s = ffeexpr_sym_lhs_data_ (s, t); - break; - - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFEEXPR_contextLET: - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextDO: - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextIF: - case FFEEXPR_contextARITHIF: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextSTOP: - case FFEEXPR_contextRETURN: - case FFEEXPR_contextSELECTCASE: - case FFEEXPR_contextCASE: - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - case FFEEXPR_contextFILEDFINT: - case FFEEXPR_contextFILELOG: - case FFEEXPR_contextFILENUM: - case FFEEXPR_contextFILENUMAMBIG: - case FFEEXPR_contextFILECHAR: - case FFEEXPR_contextFILENUMCHAR: - case FFEEXPR_contextFILEDFCHAR: - case FFEEXPR_contextFILEKEY: - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextFILEUNIT_DF: - case FFEEXPR_contextFILEUNITAMBIG: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextFILENAMELIST: - case FFEEXPR_contextFILEVXTCODE: - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - case FFEEXPR_contextIMPDOCTRL_: - case FFEEXPR_contextLOC_: - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_sym_rhs_let_ (s, t); - else - s = ffeexpr_sym_lhs_let_ (s, t); - break; - - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextEQUIVALENCE: - case FFEEXPR_contextINCLUDE: - case FFEEXPR_contextPARAMETER: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - break; /* Will turn into errors below. */ - - default: - ffesymbol_error (s, t); - break; - } - /* Fall through. */ - case FFESYMBOL_stateUNDERSTOOD: /* Nothing much more to learn. */ - understood: /* :::::::::::::::::::: */ - k = ffesymbol_kind (s); - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSUBROUTINEREF: - bad = ((k != FFEINFO_kindSUBROUTINE) - && ((ffesymbol_where (s) != FFEINFO_whereINTRINSIC) - || (k != FFEINFO_kindNONE))); - break; - - case FFEEXPR_contextFILEEXTFUNC: - bad = (k != FFEINFO_kindFUNCTION) - || (ffesymbol_where (s) != FFEINFO_whereGLOBAL); - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextACTUALARG_: - switch (k) - { - case FFEINFO_kindENTITY: - bad = FALSE; - break; - - case FFEINFO_kindFUNCTION: - case FFEINFO_kindSUBROUTINE: - bad - = ((ffesymbol_where (s) != FFEINFO_whereGLOBAL) - && (ffesymbol_where (s) != FFEINFO_whereDUMMY) - && ((ffesymbol_where (s) != FFEINFO_whereINTRINSIC) - || !ffeintrin_is_actualarg (ffesymbol_specific (s)))); - break; - - case FFEINFO_kindNONE: - if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) - { - bad = !(ffeintrin_is_actualarg (ffesymbol_specific (s))); - break; - } - - /* If state is UNDERSTOOD here, it's CHAR*(*) or attrsANY, - and in the former case, attrsTYPE is set, so we - see this as an error as we should, since CHAR*(*) - cannot be actually referenced in a main/block data - program unit. */ - - if ((ffesymbol_attrs (s) & (FFESYMBOL_attrsANY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE)) - == FFESYMBOL_attrsEXTERNAL) - bad = FALSE; - else - bad = TRUE; - break; - - default: - bad = TRUE; - break; - } - break; - - case FFEEXPR_contextDATA: - if (ffeexpr_stack_->is_rhs) - bad = (k != FFEINFO_kindENTITY) - || (ffesymbol_where (s) != FFEINFO_whereCONSTANT); - else - bad = (k != FFEINFO_kindENTITY) - || ((ffesymbol_where (s) != FFEINFO_whereNONE) - && (ffesymbol_where (s) != FFEINFO_whereLOCAL) - && (ffesymbol_where (s) != FFEINFO_whereCOMMON)); - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - bad = TRUE; /* Unadorned item never valid. */ - break; - - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - case FFEEXPR_contextLET: - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextDO: - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextIF: - case FFEEXPR_contextARITHIF: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextSTOP: - case FFEEXPR_contextRETURN: - case FFEEXPR_contextSELECTCASE: - case FFEEXPR_contextCASE: - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - case FFEEXPR_contextFILEDFINT: - case FFEEXPR_contextFILELOG: - case FFEEXPR_contextFILENUM: - case FFEEXPR_contextFILENUMAMBIG: - case FFEEXPR_contextFILECHAR: - case FFEEXPR_contextFILENUMCHAR: - case FFEEXPR_contextFILEDFCHAR: - case FFEEXPR_contextFILEKEY: - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextFILEUNIT_DF: - case FFEEXPR_contextFILEUNITAMBIG: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextFILENAMELIST: - case FFEEXPR_contextFILEVXTCODE: - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - case FFEEXPR_contextIMPDOCTRL_: - case FFEEXPR_contextLOC_: - bad = (k != FFEINFO_kindENTITY); /* This catches "SUBROUTINE - X(A);EXTERNAL A;CALL - Y(A);B=A", for example. */ - break; - - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextEQUIVALENCE: - case FFEEXPR_contextPARAMETER: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - bad = (k != FFEINFO_kindENTITY) - || (ffesymbol_where (s) != FFEINFO_whereCONSTANT); - break; - - case FFEEXPR_contextINCLUDE: - bad = TRUE; - break; - - default: - bad = TRUE; - break; - } - if (bad && (k != FFEINFO_kindANY)) - ffesymbol_error (s, t); - return s; - - case FFESYMBOL_stateSEEN: /* Seen but not yet in exec portion. */ - seen: /* :::::::::::::::::::: */ - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextPARAMETER: - if (ffeexpr_stack_->is_rhs) - ffesymbol_error (s, t); - else - s = ffeexpr_sym_lhs_parameter_ (s, t); - break; - - case FFEEXPR_contextDATA: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - if (ffeexpr_stack_->is_rhs) - ffesymbol_error (s, t); - else - s = ffeexpr_sym_lhs_data_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - case FFEEXPR_contextDATAIMPDOITEM_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - s = ffeexpr_sym_lhs_data_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - case FFEEXPR_contextEQUIVALENCE: - s = ffeexpr_sym_lhs_equivalence_ (s, t); - break; - - case FFEEXPR_contextDIMLIST: - s = ffeexpr_sym_rhs_dimlist_ (s, t); - break; - - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - ffesymbol_error (s, t); - break; - - case FFEEXPR_contextINCLUDE: - ffesymbol_error (s, t); - break; - - case FFEEXPR_contextACTUALARG_: /* E.g. I in REAL A(Y(I)). */ - case FFEEXPR_contextSFUNCDEFACTUALARG_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - s = ffeexpr_sym_rhs_actualarg_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - assert (ffeexpr_stack_->is_rhs); - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - s = ffeexpr_sym_rhs_let_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - default: - ffesymbol_error (s, t); - break; - } - return s; - - default: - assert ("bad symbol state" == NULL); - return NULL; - break; - } -} - -/* Have FOO in DATA (XYZ(FOO),...)/.../ or DATA (...,XYZ=FOO,BAR,BLETCH). - Could be found via the "statement-function" name space (in which case - it should become an iterator) or the local name space (in which case - it should be either a named constant, or a variable that will have an - sfunc name space sibling that should become an iterator). */ - -static ffesymbol -ffeexpr_sym_impdoitem_ (ffesymbol sp, ffelexToken t) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffesymbolState ss; - ffesymbolState ns; - ffeinfoKind kind; - ffeinfoWhere where; - - ss = ffesymbol_state (sp); - - if (ffesymbol_sfdummyparent (sp) != NULL) - { /* Have symbol in sfunc name space. */ - switch (ss) - { - case FFESYMBOL_stateNONE: /* Used as iterator already. */ - if (ffeexpr_level_ < ffesymbol_maxentrynum (sp)) - ffesymbol_error (sp, t); /* Can't use dead iterator. */ - else - { /* Can use dead iterator because we're at at - least an innermore (higher-numbered) level - than the iterator's outermost - (lowest-numbered) level. */ - ffesymbol_signal_change (sp); - ffesymbol_set_state (sp, FFESYMBOL_stateSEEN); - ffesymbol_set_maxentrynum (sp, ffeexpr_level_); - ffesymbol_signal_unreported (sp); - } - break; - - case FFESYMBOL_stateSEEN: /* Seen already in this or other - implied-DO. Set symbol level - number to outermost value, as that - tells us we can see it as iterator - at that level at the innermost. */ - if (ffeexpr_level_ < ffesymbol_maxentrynum (sp)) - { - ffesymbol_signal_change (sp); - ffesymbol_set_maxentrynum (sp, ffeexpr_level_); - ffesymbol_signal_unreported (sp); - } - break; - - case FFESYMBOL_stateUNCERTAIN: /* Iterator. */ - assert (ffeexpr_level_ == ffesymbol_maxentrynum (sp)); - ffesymbol_error (sp, t); /* (,,,I=I,10). */ - break; - - case FFESYMBOL_stateUNDERSTOOD: - break; /* ANY. */ - - default: - assert ("Foo Bar!!" == NULL); - break; - } - - return sp; - } - - /* Got symbol in local name space, so we haven't seen it in impdo yet. - First, if it is brand-new and we're in executable statements, set the - attributes and exec-transition it to set state UNCERTAIN or UNDERSTOOD. - Second, if it is now a constant (PARAMETER), then just return it, it - can't be an implied-do iterator. If it is understood, complain if it is - not a valid variable, but make the inner name space iterator anyway and - return that. If it is not understood, improve understanding of the - symbol accordingly, complain accordingly, in either case make the inner - name space iterator and return that. */ - - sa = ffesymbol_attrs (sp); - - if (ffesymbol_state_is_specable (ss) - && ffest_seen_first_exec ()) - { - assert (sa == FFESYMBOL_attrsetNONE); - ffesymbol_signal_change (sp); - ffesymbol_set_state (sp, FFESYMBOL_stateSEEN); - ffesymbol_resolve_intrin (sp); - if (ffeimplic_establish_symbol (sp)) - ffesymbol_set_attr (sp, FFESYMBOL_attrSFARG); - else - ffesymbol_error (sp, t); - - /* After the exec transition, the state will either be UNCERTAIN (could - be a dummy or local var) or UNDERSTOOD (local var, because this is a - PROGRAM/BLOCKDATA program unit). */ - - sp = ffecom_sym_exec_transition (sp); - sa = ffesymbol_attrs (sp); - ss = ffesymbol_state (sp); - } - - ns = ss; - kind = ffesymbol_kind (sp); - where = ffesymbol_where (sp); - - if (ss == FFESYMBOL_stateUNDERSTOOD) - { - if (kind != FFEINFO_kindENTITY) - ffesymbol_error (sp, t); - if (where == FFEINFO_whereCONSTANT) - return sp; - } - else - { - /* Enhance understanding of local symbol. This used to imply exec - transition, but that doesn't seem necessary, since the local symbol - doesn't actually get put into an ffebld tree here -- we just learn - more about it, just like when we see a local symbol's name in the - dummy-arg list of a statement function. */ - - if (ss != FFESYMBOL_stateUNCERTAIN) - { - /* Figure out what kind of object we've got based on previous - declarations of or references to the object. */ - - ns = FFESYMBOL_stateSEEN; - - if (sa & FFESYMBOL_attrsANY) - na = sa; - else if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsANY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsSFARG; - else - na = FFESYMBOL_attrsetNONE; - } - else - { /* stateUNCERTAIN. */ - na = sa | FFESYMBOL_attrsSFARG; - ns = FFESYMBOL_stateUNDERSTOOD; - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - na = FFESYMBOL_attrsetNONE; - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - kind = FFEINFO_kindENTITY; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - na = FFESYMBOL_attrsetNONE; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - ns = FFESYMBOL_stateUNCERTAIN; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - kind = FFEINFO_kindENTITY; - - if (sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN)) - na = FFESYMBOL_attrsetNONE; - else if (ffest_is_entry_valid ()) - ns = FFESYMBOL_stateUNCERTAIN; /* Could be DUMMY or LOCAL. */ - else - where = FFEINFO_whereLOCAL; - } - else - na = FFESYMBOL_attrsetNONE; /* Error. */ - } - - /* Now see what we've got for a new object: NONE means a new error - cropped up; ANY means an old error to be ignored; otherwise, - everything's ok, update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (sp, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (sp); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (sp)) - ffesymbol_error (sp, t); - else - { - ffesymbol_set_info (sp, - ffeinfo_new (ffesymbol_basictype (sp), - ffesymbol_kindtype (sp), - ffesymbol_rank (sp), - kind, - where, - ffesymbol_size (sp))); - ffesymbol_set_attrs (sp, na); - ffesymbol_set_state (sp, ns); - ffesymbol_resolve_intrin (sp); - if (!ffesymbol_state_is_specable (ns)) - sp = ffecom_sym_learned (sp); - ffesymbol_signal_unreported (sp); /* For debugging purposes. */ - } - } - } - - /* Here we create the sfunc-name-space symbol representing what should - become an iterator in this name space at this or an outermore (lower- - numbered) expression level, else the implied-DO construct is in error. */ - - s = ffesymbol_declare_sfdummy (t); /* Sets maxentrynum to 0 for new obj; - also sets sfa_dummy_parent to - parent symbol. */ - assert (sp == ffesymbol_sfdummyparent (s)); - - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_maxentrynum (s, ffeexpr_level_); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereIMMEDIATE, - FFETARGET_charactersizeNONE)); - ffesymbol_signal_unreported (s); - - if (((ffesymbol_basictype (sp) != FFEINFO_basictypeINTEGER) - && (ffesymbol_basictype (sp) != FFEINFO_basictypeANY)) - || ((ffesymbol_kindtype (sp) != FFEINFO_kindtypeINTEGERDEFAULT) - && (ffesymbol_kindtype (sp) != FFEINFO_kindtypeANY))) - ffesymbol_error (s, t); - - return s; -} - -/* Have FOO in CALL FOO. Local name space, executable context only. */ - -static ffesymbol -ffeexpr_sym_lhs_call_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - bool error = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - error = TRUE; - else - /* Not TYPE. */ - { - kind = FFEINFO_kindSUBROUTINE; - - if (sa & FFESYMBOL_attrsDUMMY) - ; /* Not TYPE. */ - else if (sa & FFESYMBOL_attrsACTUALARG) - ; /* Not DUMMY or TYPE. */ - else /* Not ACTUALARG, DUMMY, or TYPE. */ - where = FFEINFO_whereGLOBAL; - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - error = TRUE; - else - kind = FFEINFO_kindSUBROUTINE; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - error = TRUE; - } - else if (sa == FFESYMBOL_attrsetNONE) - { - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - - if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindSUBROUTINE, - FFEINFO_whereINTRINSIC, - FFETARGET_charactersizeNONE)); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, t, FALSE); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - - return s; - } - - kind = FFEINFO_kindSUBROUTINE; - where = FFEINFO_whereGLOBAL; - } - else - error = TRUE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (error) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* SUBROUTINE. */ - where, /* GLOBAL or DUMMY. */ - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, t, FALSE); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in DATA FOO/.../. Local name space and executable context - only. (This will change in the future when DATA FOO may be followed - by COMMON FOO or even INTEGER FOO(10), etc.) */ - -static ffesymbol -ffeexpr_sym_lhs_data_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - bool error = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsADJUSTABLE) - error = TRUE; - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN)) - error = TRUE; - else - { - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - } - else if (sa == FFESYMBOL_attrsetNONE) - { - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - else - error = TRUE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (error) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* ENTITY. */ - where, /* LOCAL. */ - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in EQUIVALENCE (...,FOO,...). Does not include - EQUIVALENCE (...,BAR(FOO),...). */ - -static ffesymbol -ffeexpr_sym_lhs_equivalence_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - - na = sa = ffesymbol_attrs (s); - kind = FFEINFO_kindENTITY; - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsEQUIV; - else - na = FFESYMBOL_attrsetNONE; - - /* Don't know why we're bothering to set kind and where in this code, but - added the following to make it complete, in case it's really important. - Generally this is left up to symbol exec transition. */ - - if (where == FFEINFO_whereNONE) - { - if (na & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON)) - where = FFEINFO_whereCOMMON; - else if (na & FFESYMBOL_attrsSAVE) - where = FFEINFO_whereLOCAL; - } - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* Always ENTITY. */ - where, /* NONE, COMMON, or LOCAL. */ - ffesymbol_size (s))); - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_resolve_intrin (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in OPEN(...,USEROPEN=FOO,...). Executable context only. - - Note that I think this should be considered semantically similar to - doing CALL XYZ(FOO), in that it should be considered like an - ACTUALARG context. In particular, without EXTERNAL being specified, - it should not be allowed. */ - -static ffesymbol -ffeexpr_sym_lhs_extfunc_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - bool needs_type = FALSE; - bool error = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - where = FFEINFO_whereGLOBAL; - else - /* Not TYPE. */ - { - kind = FFEINFO_kindFUNCTION; - needs_type = TRUE; - - if (sa & FFESYMBOL_attrsDUMMY) - ; /* Not TYPE. */ - else if (sa & FFESYMBOL_attrsACTUALARG) - ; /* Not DUMMY or TYPE. */ - else /* Not ACTUALARG, DUMMY, or TYPE. */ - where = FFEINFO_whereGLOBAL; - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - kind = FFEINFO_kindFUNCTION; - if (!(sa & FFESYMBOL_attrsTYPE)) - needs_type = TRUE; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYLEN)) - error = TRUE; - else - { - kind = FFEINFO_kindFUNCTION; - where = FFEINFO_whereGLOBAL; - } - } - else if (sa == FFESYMBOL_attrsetNONE) - { - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - kind = FFEINFO_kindFUNCTION; - where = FFEINFO_whereGLOBAL; - needs_type = TRUE; - } - else - error = TRUE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (error) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (needs_type && !ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - if (!ffesymbol_explicitwhere (s)) - { - ffebad_start (FFEBAD_NEED_EXTERNAL); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - ffesymbol_set_explicitwhere (s, TRUE); - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* FUNCTION. */ - where, /* GLOBAL or DUMMY. */ - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, t, FALSE); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in DATA (stuff,FOO=1,10)/.../. */ - -static ffesymbol -ffeexpr_sym_lhs_impdoctrl_ (ffesymbol s, ffelexToken t) -{ - ffesymbolState ss; - - /* If the symbol isn't in the sfunc name space, pretend as though we saw a - reference to it already within the imp-DO construct at this level, so as - to get a symbol that is in the sfunc name space. But this is an - erroneous construct, and should be caught elsewhere. */ - - if (ffesymbol_sfdummyparent (s) == NULL) - { - s = ffeexpr_sym_impdoitem_ (s, t); - if (ffesymbol_sfdummyparent (s) == NULL) - { /* PARAMETER FOO...DATA (A(I),FOO=...). */ - ffesymbol_error (s, t); - return s; - } - } - - ss = ffesymbol_state (s); - - switch (ss) - { - case FFESYMBOL_stateNONE: /* Used as iterator already. */ - if (ffeexpr_level_ < ffesymbol_maxentrynum (s)) - ffesymbol_error (s, t); /* Can't reuse dead iterator. F90 disallows - this; F77 allows it but it is a stupid - feature. */ - else - { /* Can use dead iterator because we're at at - least a innermore (higher-numbered) level - than the iterator's outermost - (lowest-numbered) level. This should be - diagnosed later, because it means an item - in this list didn't reference this - iterator. */ -#if 1 - ffesymbol_error (s, t); /* For now, complain. */ -#else /* Someday will detect all cases where initializer doesn't reference - all applicable iterators, in which case reenable this code. */ - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateUNCERTAIN); - ffesymbol_set_maxentrynum (s, ffeexpr_level_); - ffesymbol_signal_unreported (s); -#endif - } - break; - - case FFESYMBOL_stateSEEN: /* Seen already in this or other implied-DO. - If seen in outermore level, can't be an - iterator here, so complain. If not seen - at current level, complain for now, - because that indicates something F90 - rejects (though we currently don't detect - all such cases for now). */ - if (ffeexpr_level_ <= ffesymbol_maxentrynum (s)) - { - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateUNCERTAIN); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, t); - break; - - case FFESYMBOL_stateUNCERTAIN: /* Already iterator! */ - assert ("DATA implied-DO control var seen twice!!" == NULL); - ffesymbol_error (s, t); - break; - - case FFESYMBOL_stateUNDERSTOOD: - break; /* ANY. */ - - default: - assert ("Foo Bletch!!" == NULL); - break; - } - - return s; -} - -/* Have FOO in PARAMETER (FOO=...). */ - -static ffesymbol -ffeexpr_sym_lhs_parameter_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & ~(FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsTYPE)) - { - if (!(sa & FFESYMBOL_attrsANY)) - ffesymbol_error (s, t); - } - else - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in CALL XYZ(...,FOO,...). Does not include any other - embedding of FOO, such as CALL XYZ((FOO)) or CALL XYZ(FOO+1). */ - -static ffesymbol -ffeexpr_sym_rhs_actualarg_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - ffesymbolState ns; - bool needs_type = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - ns = FFESYMBOL_stateUNDERSTOOD; - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - where = FFEINFO_whereGLOBAL; - else - /* Not TYPE. */ - { - ns = FFESYMBOL_stateUNCERTAIN; - - if (sa & FFESYMBOL_attrsDUMMY) - assert (kind == FFEINFO_kindNONE); /* FUNCTION, SUBROUTINE. */ - else if (sa & FFESYMBOL_attrsACTUALARG) - ; /* Not DUMMY or TYPE. */ - else - /* Not ACTUALARG, DUMMY, or TYPE. */ - { - assert (kind == FFEINFO_kindNONE); /* FUNCTION, SUBROUTINE. */ - na |= FFESYMBOL_attrsACTUALARG; - where = FFEINFO_whereGLOBAL; - } - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - kind = FFEINFO_kindENTITY; - if (!(sa & FFESYMBOL_attrsTYPE)) - needs_type = TRUE; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (sa & FFESYMBOL_attrsANYLEN) - ns = FFESYMBOL_stateNONE; - else - { - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - } - else if (sa == FFESYMBOL_attrsetNONE) - { - /* New state is left empty because there isn't any state flag to - set for this case, and it's UNDERSTOOD after all. */ - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - needs_type = TRUE; - } - else - ns = FFESYMBOL_stateNONE; /* Error. */ - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (ns == FFESYMBOL_stateNONE) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (needs_type && !ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, - where, - ffesymbol_size (s))); - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, ns); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, t, FALSE); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in DIMENSION XYZ(FOO) or any array declarator containing - a reference to FOO. */ - -static ffesymbol -ffeexpr_sym_rhs_dimlist_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - - na = sa = ffesymbol_attrs (s); - kind = FFEINFO_kindENTITY; - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsADJUSTS; - else - na = FFESYMBOL_attrsetNONE; - - /* Since this symbol definitely is going into an expression (the - dimension-list for some dummy array, presumably), figure out WHERE if - possible. */ - - if (where == FFEINFO_whereNONE) - { - if (na & (FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST)) - where = FFEINFO_whereCOMMON; - else if (na & FFESYMBOL_attrsDUMMY) - where = FFEINFO_whereDUMMY; - } - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* Always ENTITY. */ - where, /* NONE, COMMON, or DUMMY. */ - ffesymbol_size (s))); - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_resolve_intrin (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* Have FOO in XYZ = ...FOO.... Does not include cases like FOO in - XYZ = BAR(FOO), as such cases are handled elsewhere. */ - -static ffesymbol -ffeexpr_sym_rhs_let_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - bool error = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - error = TRUE; - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - kind = FFEINFO_kindENTITY; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (sa & FFESYMBOL_attrsANYLEN) - error = TRUE; - else - { - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - } - else if (sa == FFESYMBOL_attrsetNONE) - { - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - else - error = TRUE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (error) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, /* ENTITY. */ - where, /* LOCAL. */ - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* ffeexpr_declare_parenthesized_ -- ffesymbol wrapper for NAME(...) operand - - ffelexToken t; - bool maybe_intrin; - ffeexprParenType_ paren_type; - ffesymbol s; - s = ffeexpr_declare_parenthesized_ (t, maybe_intrin, &paren_type); - - Just like ffesymbol_declare_local, except performs any implicit info - assignment necessary, and it returns the type of the parenthesized list - (list of function args, list of array args, or substring spec). */ - -static ffesymbol -ffeexpr_declare_parenthesized_ (ffelexToken t, bool maybe_intrin, - ffeexprParenType_ *paren_type) -{ - ffesymbol s; - ffesymbolState st; /* Effective state. */ - ffeinfoKind k; - bool bad; - - if (maybe_intrin && ffesrc_check_symbol ()) - { /* Knock off some easy cases. */ - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextSUBROUTINEREF: - case FFEEXPR_contextDATA: - case FFEEXPR_contextDATAIMPDOINDEX_: - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - case FFEEXPR_contextLET: - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextDO: - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextIF: - case FFEEXPR_contextARITHIF: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextSTOP: - case FFEEXPR_contextRETURN: - case FFEEXPR_contextSELECTCASE: - case FFEEXPR_contextCASE: - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - case FFEEXPR_contextFILEDFINT: - case FFEEXPR_contextFILELOG: - case FFEEXPR_contextFILENUM: - case FFEEXPR_contextFILENUMAMBIG: - case FFEEXPR_contextFILECHAR: - case FFEEXPR_contextFILENUMCHAR: - case FFEEXPR_contextFILEDFCHAR: - case FFEEXPR_contextFILEKEY: - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextFILEUNIT_DF: - case FFEEXPR_contextFILEUNITAMBIG: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextFILENAMELIST: - case FFEEXPR_contextFILEVXTCODE: - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - case FFEEXPR_contextIMPDOCTRL_: - case FFEEXPR_contextDATAIMPDOCTRL_: - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextPARAMETER: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - break; /* These could be intrinsic invocations. */ - - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextFILEFORMATNML: - case FFEEXPR_contextALLOCATE: - case FFEEXPR_contextDEALLOCATE: - case FFEEXPR_contextHEAPSTAT: - case FFEEXPR_contextNULLIFY: - case FFEEXPR_contextINCLUDE: - case FFEEXPR_contextDATAIMPDOITEM_: - case FFEEXPR_contextLOC_: - case FFEEXPR_contextINDEXORACTUALARG_: - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - case FFEEXPR_contextPARENFILENUM_: - case FFEEXPR_contextPARENFILEUNIT_: - maybe_intrin = FALSE; - break; /* Can't be intrinsic invocation. */ - - default: - assert ("blah! blah! waaauuggh!" == NULL); - break; - } - } - - s = ffesymbol_declare_local (t, maybe_intrin); - - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - /* Special-case these since they can involve a different concept - of "state" (in the stmtfunc name space). */ - { - case FFEEXPR_contextDATAIMPDOINDEX_: - case FFEEXPR_contextDATAIMPDOCTRL_: - if (ffeexpr_context_outer_ (ffeexpr_stack_) - == FFEEXPR_contextDATAIMPDOINDEX_) - s = ffeexpr_sym_impdoitem_ (s, t); - else - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_sym_impdoitem_ (s, t); - else - s = ffeexpr_sym_lhs_impdoctrl_ (s, t); - if (ffesymbol_kind (s) != FFEINFO_kindANY) - ffesymbol_error (s, t); - return s; - - default: - break; - } - - switch ((ffesymbol_sfdummyparent (s) == NULL) - ? ffesymbol_state (s) - : FFESYMBOL_stateUNDERSTOOD) - { - case FFESYMBOL_stateNONE: /* Before first exec, not seen in expr - context. */ - if (!ffest_seen_first_exec ()) - goto seen; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFESYMBOL_stateUNCERTAIN: /* Unseen since first exec. */ - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSUBROUTINEREF: - s = ffeexpr_sym_lhs_call_ (s, t); /* "CALL FOO"=="CALL - FOO(...)". */ - break; - - case FFEEXPR_contextDATA: - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_sym_rhs_let_ (s, t); - else - s = ffeexpr_sym_lhs_data_ (s, t); - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - s = ffeexpr_sym_lhs_data_ (s, t); - break; - - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - /* Fall through. */ - case FFEEXPR_contextLET: - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextDO: - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextIF: - case FFEEXPR_contextARITHIF: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextSTOP: - case FFEEXPR_contextRETURN: - case FFEEXPR_contextSELECTCASE: - case FFEEXPR_contextCASE: - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - case FFEEXPR_contextFILEDFINT: - case FFEEXPR_contextFILELOG: - case FFEEXPR_contextFILENUM: - case FFEEXPR_contextFILENUMAMBIG: - case FFEEXPR_contextFILECHAR: - case FFEEXPR_contextFILENUMCHAR: - case FFEEXPR_contextFILEDFCHAR: - case FFEEXPR_contextFILEKEY: - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextFILEUNIT_DF: - case FFEEXPR_contextFILEUNITAMBIG: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextFILENAMELIST: - case FFEEXPR_contextFILEVXTCODE: - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - case FFEEXPR_contextIMPDOCTRL_: - case FFEEXPR_contextLOC_: - if (ffeexpr_stack_->is_rhs) - s = ffeexpr_paren_rhs_let_ (s, t); - else - s = ffeexpr_paren_lhs_let_ (s, t); - break; - - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextEQUIVALENCE: - case FFEEXPR_contextINCLUDE: - case FFEEXPR_contextPARAMETER: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - break; /* Will turn into errors below. */ - - default: - ffesymbol_error (s, t); - break; - } - /* Fall through. */ - case FFESYMBOL_stateUNDERSTOOD: /* Nothing much more to learn. */ - understood: /* :::::::::::::::::::: */ - - /* State might have changed, update it. */ - st = ((ffesymbol_sfdummyparent (s) == NULL) - ? ffesymbol_state (s) - : FFESYMBOL_stateUNDERSTOOD); - - k = ffesymbol_kind (s); - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSUBROUTINEREF: - bad = ((k != FFEINFO_kindSUBROUTINE) - && ((ffesymbol_where (s) != FFEINFO_whereINTRINSIC) - || (k != FFEINFO_kindNONE))); - break; - - case FFEEXPR_contextDATA: - if (ffeexpr_stack_->is_rhs) - bad = (k != FFEINFO_kindENTITY) - || (ffesymbol_where (s) != FFEINFO_whereCONSTANT); - else - bad = (k != FFEINFO_kindENTITY) - || ((ffesymbol_where (s) != FFEINFO_whereNONE) - && (ffesymbol_where (s) != FFEINFO_whereLOCAL) - && (ffesymbol_where (s) != FFEINFO_whereCOMMON)); - break; - - case FFEEXPR_contextDATAIMPDOITEM_: - bad = (k != FFEINFO_kindENTITY) || (ffesymbol_rank (s) == 0) - || ((ffesymbol_where (s) != FFEINFO_whereNONE) - && (ffesymbol_where (s) != FFEINFO_whereLOCAL) - && (ffesymbol_where (s) != FFEINFO_whereCOMMON)); - break; - - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - case FFEEXPR_contextLET: - case FFEEXPR_contextPAREN_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextIOLIST: - case FFEEXPR_contextIOLISTDF: - case FFEEXPR_contextDO: - case FFEEXPR_contextDOWHILE: - case FFEEXPR_contextACTUALARG_: - case FFEEXPR_contextCGOTO: - case FFEEXPR_contextIF: - case FFEEXPR_contextARITHIF: - case FFEEXPR_contextFORMAT: - case FFEEXPR_contextSTOP: - case FFEEXPR_contextRETURN: - case FFEEXPR_contextSELECTCASE: - case FFEEXPR_contextCASE: - case FFEEXPR_contextFILEASSOC: - case FFEEXPR_contextFILEINT: - case FFEEXPR_contextFILEDFINT: - case FFEEXPR_contextFILELOG: - case FFEEXPR_contextFILENUM: - case FFEEXPR_contextFILENUMAMBIG: - case FFEEXPR_contextFILECHAR: - case FFEEXPR_contextFILENUMCHAR: - case FFEEXPR_contextFILEDFCHAR: - case FFEEXPR_contextFILEKEY: - case FFEEXPR_contextFILEUNIT: - case FFEEXPR_contextFILEUNIT_DF: - case FFEEXPR_contextFILEUNITAMBIG: - case FFEEXPR_contextFILEFORMAT: - case FFEEXPR_contextFILENAMELIST: - case FFEEXPR_contextFILEVXTCODE: - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextIMPDOITEM_: - case FFEEXPR_contextIMPDOITEMDF_: - case FFEEXPR_contextIMPDOCTRL_: - case FFEEXPR_contextLOC_: - bad = FALSE; /* Let paren-switch handle the cases. */ - break; - - case FFEEXPR_contextASSIGN: - case FFEEXPR_contextAGOTO: - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextEQUIVALENCE: - case FFEEXPR_contextPARAMETER: - case FFEEXPR_contextDIMLIST: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - bad = (k != FFEINFO_kindENTITY) - || (ffesymbol_where (s) != FFEINFO_whereCONSTANT); - break; - - case FFEEXPR_contextINCLUDE: - bad = TRUE; - break; - - default: - bad = TRUE; - break; - } - - switch (bad ? FFEINFO_kindANY : k) - { - case FFEINFO_kindNONE: /* Case "CHARACTER X,Y; Y=X(?". */ - if (ffesymbol_where (s) == FFEINFO_whereINTRINSIC) - { - if (ffeexpr_context_outer_ (ffeexpr_stack_) - == FFEEXPR_contextSUBROUTINEREF) - *paren_type = FFEEXPR_parentypeSUBROUTINE_; - else - *paren_type = FFEEXPR_parentypeFUNCTION_; - break; - } - if (st == FFESYMBOL_stateUNDERSTOOD) - { - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - } - else - *paren_type = FFEEXPR_parentypeFUNSUBSTR_; - break; - - case FFEINFO_kindFUNCTION: - *paren_type = FFEEXPR_parentypeFUNCTION_; - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - bad = TRUE; /* Attempt to recurse! */ - break; - - case FFEINFO_whereCONSTANT: - bad = ((ffesymbol_sfexpr (s) == NULL) - || (ffebld_op (ffesymbol_sfexpr (s)) - == FFEBLD_opANY)); /* Attempt to recurse! */ - break; - - default: - break; - } - break; - - case FFEINFO_kindSUBROUTINE: - if ((ffeexpr_stack_->context != FFEEXPR_contextSUBROUTINEREF) - || (ffeexpr_stack_->previous != NULL)) - { - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - break; - } - - *paren_type = FFEEXPR_parentypeSUBROUTINE_; - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - case FFEINFO_whereCONSTANT: - bad = TRUE; /* Attempt to recurse! */ - break; - - default: - break; - } - break; - - case FFEINFO_kindENTITY: - if (ffesymbol_rank (s) == 0) - { - if (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) - *paren_type = FFEEXPR_parentypeSUBSTRING_; - else - { - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - } - } - else - *paren_type = FFEEXPR_parentypeARRAY_; - break; - - default: - case FFEINFO_kindANY: - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - break; - } - - if (bad) - { - if (k == FFEINFO_kindANY) - ffest_shutdown (); - else - ffesymbol_error (s, t); - } - - return s; - - case FFESYMBOL_stateSEEN: /* Seen but not yet in exec portion. */ - seen: /* :::::::::::::::::::: */ - bad = TRUE; - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextPARAMETER: - if (ffeexpr_stack_->is_rhs) - ffesymbol_error (s, t); - else - s = ffeexpr_sym_lhs_parameter_ (s, t); - break; - - case FFEEXPR_contextDATA: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - if (ffeexpr_stack_->is_rhs) - ffesymbol_error (s, t); - else - s = ffeexpr_sym_lhs_data_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - case FFEEXPR_contextDATAIMPDOITEM_: - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - s = ffeexpr_sym_lhs_data_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - case FFEEXPR_contextEQUIVALENCE: - s = ffeexpr_sym_lhs_equivalence_ (s, t); - bad = FALSE; - break; - - case FFEEXPR_contextDIMLIST: - s = ffeexpr_sym_rhs_dimlist_ (s, t); - break; - - case FFEEXPR_contextCHARACTERSIZE: - case FFEEXPR_contextKINDTYPE: - case FFEEXPR_contextDIMLISTCOMMON: - case FFEEXPR_contextINITVAL: - case FFEEXPR_contextEQVINDEX_: - break; - - case FFEEXPR_contextINCLUDE: - break; - - case FFEEXPR_contextINDEX_: - case FFEEXPR_contextACTUALARGEXPR_: - case FFEEXPR_contextINDEXORACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - assert (ffeexpr_stack_->is_rhs); - s = ffecom_sym_exec_transition (s); - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - goto understood; /* :::::::::::::::::::: */ - s = ffeexpr_paren_rhs_let_ (s, t); - goto understood; /* :::::::::::::::::::: */ - - default: - break; - } - k = ffesymbol_kind (s); - switch (bad ? FFEINFO_kindANY : k) - { - case FFEINFO_kindNONE: /* Case "CHARACTER X,Y; Y=X(?". */ - *paren_type = FFEEXPR_parentypeFUNSUBSTR_; - break; - - case FFEINFO_kindFUNCTION: - *paren_type = FFEEXPR_parentypeFUNCTION_; - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - bad = TRUE; /* Attempt to recurse! */ - break; - - case FFEINFO_whereCONSTANT: - bad = ((ffesymbol_sfexpr (s) == NULL) - || (ffebld_op (ffesymbol_sfexpr (s)) - == FFEBLD_opANY)); /* Attempt to recurse! */ - break; - - default: - break; - } - break; - - case FFEINFO_kindSUBROUTINE: - *paren_type = FFEEXPR_parentypeANY_; - bad = TRUE; /* Cannot possibly be in - contextSUBROUTINEREF. */ - break; - - case FFEINFO_kindENTITY: - if (ffesymbol_rank (s) == 0) - { - if (ffeexpr_stack_->context == FFEEXPR_contextEQUIVALENCE) - *paren_type = FFEEXPR_parentypeEQUIVALENCE_; - else if (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) - *paren_type = FFEEXPR_parentypeSUBSTRING_; - else - { - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - } - } - else - *paren_type = FFEEXPR_parentypeARRAY_; - break; - - default: - case FFEINFO_kindANY: - bad = TRUE; - *paren_type = FFEEXPR_parentypeANY_; - break; - } - - if (bad) - { - if (k == FFEINFO_kindANY) - ffest_shutdown (); - else - ffesymbol_error (s, t); - } - - return s; - - default: - assert ("bad symbol state" == NULL); - return NULL; - } -} - -/* Have FOO in XYZ = ...FOO(...).... Executable context only. */ - -static ffesymbol -ffeexpr_paren_rhs_let_ (ffesymbol s, ffelexToken t) -{ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeinfoKind kind; - ffeinfoWhere where; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - bool maybe_ambig = FALSE; - bool error = FALSE; - - assert ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN)); - - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - where = FFEINFO_whereGLOBAL; - else - /* Not TYPE. */ - { - kind = FFEINFO_kindFUNCTION; - - if (sa & FFESYMBOL_attrsDUMMY) - ; /* Not TYPE. */ - else if (sa & FFESYMBOL_attrsACTUALARG) - ; /* Not DUMMY or TYPE. */ - else /* Not ACTUALARG, DUMMY, or TYPE. */ - where = FFEINFO_whereGLOBAL; - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - kind = FFEINFO_kindFUNCTION; - maybe_ambig = TRUE; /* If basictypeCHARACTER, can't be sure; kind - could be ENTITY w/substring ref. */ - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - where = FFEINFO_whereLOCAL; /* Actually an error, but at least we - know it's a local var. */ - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp)) - { - if (!(sa & FFESYMBOL_attrsANYLEN) - && (ffeimplic_peek_symbol_type (s, NULL) - == FFEINFO_basictypeCHARACTER)) - return s; /* Haven't learned anything yet. */ - - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindFUNCTION, - FFEINFO_whereINTRINSIC, - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, t, FALSE); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - - return s; - } - if (sa & FFESYMBOL_attrsANYLEN) - error = TRUE; /* Error, since the only way we can, - given CHARACTER*(*) FOO, accept - FOO(...) is for FOO to be a dummy - arg or constant, but it can't - become either now. */ - else if (sa & FFESYMBOL_attrsADJUSTABLE) - { - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereLOCAL; - } - else - { - kind = FFEINFO_kindFUNCTION; - where = FFEINFO_whereGLOBAL; - maybe_ambig = TRUE; /* If basictypeCHARACTER, can't be sure; - could be ENTITY/LOCAL w/substring ref. */ - } - } - else if (sa == FFESYMBOL_attrsetNONE) - { - assert (ffesymbol_state (s) == FFESYMBOL_stateNONE); - - if (ffeintrin_is_intrinsic (ffesymbol_text (s), t, FALSE, - &gen, &spec, &imp)) - { - if (ffeimplic_peek_symbol_type (s, NULL) - == FFEINFO_basictypeCHARACTER) - return s; /* Haven't learned anything yet. */ - - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindFUNCTION, - FFEINFO_whereINTRINSIC, - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, t, FALSE); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - } - - kind = FFEINFO_kindFUNCTION; - where = FFEINFO_whereGLOBAL; - maybe_ambig = TRUE; /* If basictypeCHARACTER, can't be sure; - could be ENTITY/LOCAL w/substring ref. */ - } - else - error = TRUE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (error) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); /* May need to back up to previous - version. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return s; - } - if (maybe_ambig - && (ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER)) - return s; /* Still not sure, let caller deal with it - based on (...). */ - - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, - where, - ffesymbol_size (s))); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, t, FALSE); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* ffeexpr_token_arguments_ -- OPEN_PAREN [expr COMMA]...expr - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle expression (which might be null) and COMMA or CLOSE_PAREN. */ - -static ffelexHandler -ffeexpr_token_arguments_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ procedure; - ffebld reduced; - ffeinfo info; - ffeexprContext ctx; - bool check_intrin = FALSE; /* Set TRUE if intrinsic is REAL(Z) or AIMAG(Z). */ - - procedure = ffeexpr_stack_->exprstack; - info = ffebld_info (procedure->u.operand); - - /* Is there an expression to add? If the expression is nil, - it might still be an argument. It is if: - - - The current token is comma, or - - - The -fugly-comma flag was specified *and* the procedure - being invoked is external. - - Otherwise, if neither of the above is the case, just - ignore this (nil) expression. */ - - if ((expr != NULL) - || (ffelex_token_type (t) == FFELEX_typeCOMMA) - || (ffe_is_ugly_comma () - && (ffeinfo_where (info) == FFEINFO_whereGLOBAL))) - { - /* This expression, even if nil, is apparently intended as an argument. */ - - /* Internal procedure (CONTAINS, or statement function)? */ - - if (ffeinfo_where (info) == FFEINFO_whereCONSTANT) - { - if ((expr == NULL) - && ffebad_start (FFEBAD_NULL_ARGUMENT)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_here (1, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - - if (expr == NULL) - ; - else - { - if (ffeexpr_stack_->next_dummy == NULL) - { /* Report later which was the first extra argument. */ - if (ffeexpr_stack_->tokens[1] == NULL) - { - ffeexpr_stack_->tokens[1] = ffelex_token_use (ft); - ffeexpr_stack_->num_args = 0; - } - ++ffeexpr_stack_->num_args; /* Count # of extra arguments. */ - } - else - { - if ((ffeinfo_rank (ffebld_info (expr)) != 0) - && ffebad_start (FFEBAD_ARRAY_AS_SFARG)) - { - ffebad_here (0, - ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_here (1, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_string (ffesymbol_text (ffesymbol_sfdummyparent - (ffebld_symter (ffebld_head - (ffeexpr_stack_->next_dummy))))); - ffebad_finish (); - } - else - { - expr = ffeexpr_convert_expr (expr, ft, - ffebld_head (ffeexpr_stack_->next_dummy), - ffeexpr_stack_->tokens[0], - FFEEXPR_contextLET); - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - } - --ffeexpr_stack_->num_args; /* Count down # of args. */ - ffeexpr_stack_->next_dummy - = ffebld_trail (ffeexpr_stack_->next_dummy); - } - } - } - else - { - if ((expr == NULL) - && ffe_is_pedantic () - && ffebad_start (FFEBAD_NULL_ARGUMENT_W)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_here (1, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - } - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFACTUALARGEXPR_: - case FFEEXPR_contextSFUNCDEFINDEX_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_: - ctx = FFEEXPR_contextSFUNCDEFACTUALARG_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("bad context" == NULL); - ctx = FFEEXPR_context; - break; - - default: - ctx = FFEEXPR_contextACTUALARG_; - break; - } - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, ctx, - ffeexpr_token_arguments_); - - default: - break; - } - - if ((ffeinfo_where (info) == FFEINFO_whereCONSTANT) - && (ffeexpr_stack_->next_dummy != NULL)) - { /* Too few arguments. */ - if (ffebad_start (FFEBAD_TOO_FEW_ARGUMENTS)) - { - char num[10]; - - sprintf (num, "%" ffebldListLength_f "u", ffeexpr_stack_->num_args); - - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_string (num); - ffebad_string (ffesymbol_text (ffesymbol_sfdummyparent (ffebld_symter - (ffebld_head (ffeexpr_stack_->next_dummy))))); - ffebad_finish (); - } - for (; - ffeexpr_stack_->next_dummy != NULL; - ffeexpr_stack_->next_dummy - = ffebld_trail (ffeexpr_stack_->next_dummy)) - { - expr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (0)); - ffebld_set_info (expr, ffeinfo_new_any ()); - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - } - } - - if ((ffeinfo_where (info) == FFEINFO_whereCONSTANT) - && (ffeexpr_stack_->tokens[1] != NULL)) - { /* Too many arguments to statement function. */ - if (ffebad_start (FFEBAD_TOO_MANY_ARGUMENTS)) - { - char num[10]; - - sprintf (num, "%" ffebldListLength_f "u", ffeexpr_stack_->num_args); - - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[1]), - ffelex_token_where_column (ffeexpr_stack_->tokens[1])); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_string (num); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - } - ffebld_end_list (&ffeexpr_stack_->bottom); - - if (ffebld_op (procedure->u.operand) == FFEBLD_opANY) - { - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - } - else - { - if (ffeexpr_stack_->context != FFEEXPR_contextSUBROUTINEREF) - reduced = ffebld_new_funcref (procedure->u.operand, - ffeexpr_stack_->expr); - else - reduced = ffebld_new_subrref (procedure->u.operand, - ffeexpr_stack_->expr); - if (ffebld_symter_generic (procedure->u.operand) != FFEINTRIN_genNONE) - ffeintrin_fulfill_generic (&reduced, &info, ffeexpr_stack_->tokens[0]); - else if (ffebld_symter_specific (procedure->u.operand) - != FFEINTRIN_specNONE) - ffeintrin_fulfill_specific (&reduced, &info, &check_intrin, - ffeexpr_stack_->tokens[0]); - else - ffeexpr_fulfill_call_ (&reduced, ffeexpr_stack_->tokens[0]); - - if (ffebld_op (reduced) != FFEBLD_opANY) - ffebld_set_info (reduced, - ffeinfo_new (ffeinfo_basictype (info), - ffeinfo_kindtype (info), - 0, - FFEINFO_kindENTITY, - FFEINFO_whereFLEETING, - ffeinfo_size (info))); - else - ffebld_set_info (reduced, ffeinfo_new_any ()); - } - if (ffebld_op (reduced) == FFEBLD_opFUNCREF) - reduced = ffeexpr_collapse_funcref (reduced, ffeexpr_stack_->tokens[0]); - ffeexpr_stack_->exprstack = procedure->previous; /* Pops - not-quite-operand off - stack. */ - procedure->u.operand = reduced; /* Save the line/column ffewhere - info. */ - ffeexpr_exprstack_push_operand_ (procedure); /* Push it back on stack. */ - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - { - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - ffeexpr_is_substr_ok_ = FALSE; /* Nobody likes "FUNC(3)(1:1)".... */ - - /* If the intrinsic needs checking (is REAL(Z) or AIMAG(Z), where - Z is DOUBLE COMPLEX), and a command-line option doesn't already - establish interpretation, probably complain. */ - - if (check_intrin - && !ffe_is_90 () - && !ffe_is_ugly_complex ()) - { - /* If the outer expression is REAL(me...), issue diagnostic - only if next token isn't the close-paren for REAL(me). */ - - if ((ffeexpr_stack_->previous != NULL) - && (ffeexpr_stack_->previous->exprstack != NULL) - && (ffeexpr_stack_->previous->exprstack->type == FFEEXPR_exprtypeOPERAND_) - && ((reduced = ffeexpr_stack_->previous->exprstack->u.operand) != NULL) - && (ffebld_op (reduced) == FFEBLD_opSYMTER) - && (ffebld_symter_implementation (reduced) == FFEINTRIN_impREAL)) - return (ffelexHandler) ffeexpr_token_intrincheck_; - - /* Diagnose the ambiguity now. */ - - if (ffebad_start (FFEBAD_INTRINSIC_CMPAMBIG)) - { - ffebad_string (ffeintrin_name_implementation - (ffebld_symter_implementation - (ffebld_left - (ffeexpr_stack_->exprstack->u.operand)))); - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); - ffebad_finish (); - } - } - return (ffelexHandler) ffeexpr_token_substrp_; - } - - if (ffest_ffebad_start (FFEBAD_INVALID_TOKEN_IN_EXPRESSION)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - ffeexpr_is_substr_ok_ = FALSE;/* Nobody likes "FUNC(3)(1:1)".... */ - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_substrp_); -} - -/* ffeexpr_token_elements_ -- OPEN_PAREN [expr COMMA]...expr - - Return a pointer to this array to the lexer (ffelex), which will - invoke it for the next token. - - Handle expression and COMMA or CLOSE_PAREN. */ - -static ffelexHandler -ffeexpr_token_elements_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ array; - ffebld reduced; - ffeinfo info; - ffeinfoWhere where; - ffetargetIntegerDefault val; - ffetargetIntegerDefault lval = 0; - ffetargetIntegerDefault uval = 0; - ffebld lbound; - ffebld ubound; - bool lcheck; - bool ucheck; - - array = ffeexpr_stack_->exprstack; - info = ffebld_info (array->u.operand); - - if ((expr == NULL) /* && ((ffeexpr_stack_->rank != 0) || - (ffelex_token_type(t) == - FFELEX_typeCOMMA)) */ ) - { - if (ffebad_start (FFEBAD_NULL_ELEMENT)) - { - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_here (1, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - if (ffeexpr_stack_->rank < ffeinfo_rank (info)) - { /* Don't bother if we're going to complain - later! */ - expr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); - ffebld_set_info (expr, ffeinfo_new_any ()); - } - } - - if (expr == NULL) - ; - else if (ffeinfo_rank (info) == 0) - { /* In EQUIVALENCE context, ffeinfo_rank(info) - may == 0. */ - ++ffeexpr_stack_->rank; /* Track anyway, may need for new VXT - feature. */ - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - } - else - { - ++ffeexpr_stack_->rank; - if (ffeexpr_stack_->rank > ffeinfo_rank (info)) - { /* Report later which was the first extra - element. */ - if (ffeexpr_stack_->rank == ffeinfo_rank (info) + 1) - ffeexpr_stack_->tokens[1] = ffelex_token_use (ft); - } - else - { - switch (ffeinfo_where (ffebld_info (expr))) - { - case FFEINFO_whereCONSTANT: - break; - - case FFEINFO_whereIMMEDIATE: - ffeexpr_stack_->constant = FALSE; - break; - - default: - ffeexpr_stack_->constant = FALSE; - ffeexpr_stack_->immediate = FALSE; - break; - } - if (ffebld_op (expr) == FFEBLD_opCONTER) - { - val = ffebld_constant_integerdefault (ffebld_conter (expr)); - - lbound = ffebld_left (ffebld_head (ffeexpr_stack_->bound_list)); - if (lbound == NULL) - { - lcheck = TRUE; - lval = 1; - } - else if (ffebld_op (lbound) == FFEBLD_opCONTER) - { - lcheck = TRUE; - lval = ffebld_constant_integerdefault (ffebld_conter (lbound)); - } - else - lcheck = FALSE; - - ubound = ffebld_right (ffebld_head (ffeexpr_stack_->bound_list)); - assert (ubound != NULL); - if (ffebld_op (ubound) == FFEBLD_opCONTER) - { - ucheck = TRUE; - uval = ffebld_constant_integerdefault (ffebld_conter (ubound)); - } - else - ucheck = FALSE; - - if ((lcheck && (val < lval)) || (ucheck && (val > uval))) - { - ffebad_start (FFEBAD_RANGE_ARRAY); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - } - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - ffeexpr_stack_->bound_list = ffebld_trail (ffeexpr_stack_->bound_list); - } - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - switch (ffeexpr_context_outer_ (ffeexpr_stack_)) - { - case FFEEXPR_contextDATAIMPDOITEM_: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextDATAIMPDOINDEX_, - ffeexpr_token_elements_); - - case FFEEXPR_contextEQUIVALENCE: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextEQVINDEX_, - ffeexpr_token_elements_); - - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextSFUNCDEFINDEX_, - ffeexpr_token_elements_); - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("bad context" == NULL); - break; - - default: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextINDEX_, - ffeexpr_token_elements_); - } - - default: - break; - } - - if ((ffeexpr_stack_->rank != ffeinfo_rank (info)) - && (ffeinfo_rank (info) != 0)) - { - char num[10]; - - if (ffeexpr_stack_->rank < ffeinfo_rank (info)) - { - if (ffebad_start (FFEBAD_TOO_FEW_ELEMENTS)) - { - sprintf (num, "%d", - (int) (ffeinfo_rank (info) - ffeexpr_stack_->rank)); - - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, - ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_string (num); - ffebad_finish (); - } - } - else - { - if (ffebad_start (FFEBAD_TOO_MANY_ELEMENTS)) - { - sprintf (num, "%d", - (int) (ffeexpr_stack_->rank - ffeinfo_rank (info))); - - ffebad_here (0, - ffelex_token_where_line (ffeexpr_stack_->tokens[1]), - ffelex_token_where_column (ffeexpr_stack_->tokens[1])); - ffebad_here (1, - ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_string (num); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_stack_->tokens[1]); - } - while (ffeexpr_stack_->rank++ < ffeinfo_rank (info)) - { - expr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); - ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - ffebld_append_item (&ffeexpr_stack_->bottom, expr); - } - } - ffebld_end_list (&ffeexpr_stack_->bottom); - - if (ffebld_op (array->u.operand) == FFEBLD_opANY) - { - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - } - else - { - reduced = ffebld_new_arrayref (array->u.operand, ffeexpr_stack_->expr); - if (ffeexpr_stack_->constant) - where = FFEINFO_whereFLEETING_CADDR; - else if (ffeexpr_stack_->immediate) - where = FFEINFO_whereFLEETING_IADDR; - else - where = FFEINFO_whereFLEETING; - ffebld_set_info (reduced, - ffeinfo_new (ffeinfo_basictype (info), - ffeinfo_kindtype (info), - 0, - FFEINFO_kindENTITY, - where, - ffeinfo_size (info))); - reduced = ffeexpr_collapse_arrayref (reduced, ffeexpr_stack_->tokens[0]); - } - - ffeexpr_stack_->exprstack = array->previous; /* Pops not-quite-operand off - stack. */ - array->u.operand = reduced; /* Save the line/column ffewhere info. */ - ffeexpr_exprstack_push_operand_ (array); /* Push it back on stack. */ - - switch (ffeinfo_basictype (info)) - { - case FFEINFO_basictypeCHARACTER: - ffeexpr_is_substr_ok_ = TRUE; /* Everyone likes "FOO(3)(1:1)".... */ - break; - - case FFEINFO_basictypeNONE: - ffeexpr_is_substr_ok_ = TRUE; - assert (ffeexpr_stack_->context == FFEEXPR_contextEQUIVALENCE); - break; - - default: - ffeexpr_is_substr_ok_ = FALSE; - break; - } - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - { - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - return (ffelexHandler) ffeexpr_token_substrp_; - } - - if (ffest_ffebad_start (FFEBAD_INVALID_TOKEN_IN_EXPRESSION)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_substrp_); -} - -/* ffeexpr_token_equivalence_ -- OPEN_PAREN expr - - Return a pointer to this array to the lexer (ffelex), which will - invoke it for the next token. - - If token is COLON, pass off to _substr_, else init list and pass off - to _elements_. This handles the case "EQUIVALENCE (FOO(expr?", where - ? marks the token, and where FOO's rank/type has not yet been established, - meaning we could be in a list of indices or in a substring - specification. */ - -static ffelexHandler -ffeexpr_token_equivalence_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - if (ffelex_token_type (t) == FFELEX_typeCOLON) - return ffeexpr_token_substring_ (ft, expr, t); - - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return ffeexpr_token_elements_ (ft, expr, t); -} - -/* ffeexpr_token_substring_ -- NAME(of kindENTITY) OPEN_PAREN expr - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle expression (which may be null) and COLON. */ - -static ffelexHandler -ffeexpr_token_substring_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeexprExpr_ string; - ffeinfo info; - ffetargetIntegerDefault i; - ffeexprContext ctx; - ffetargetCharacterSize size; - - string = ffeexpr_stack_->exprstack; - info = ffebld_info (string->u.operand); - size = ffebld_size_max (string->u.operand); - - if (ffelex_token_type (t) == FFELEX_typeCOLON) - { - if ((expr != NULL) - && (ffebld_op (expr) == FFEBLD_opCONTER) - && (((i = ffebld_constant_integerdefault (ffebld_conter (expr))) - < 1) - || ((size != FFETARGET_charactersizeNONE) && (i > size)))) - { - ffebad_start (FFEBAD_RANGE_SUBSTR); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - ffeexpr_stack_->expr = expr; - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - ctx = FFEEXPR_contextSFUNCDEFINDEX_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("bad context" == NULL); - ctx = FFEEXPR_context; - break; - - default: - ctx = FFEEXPR_contextINDEX_; - break; - } - - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, ctx, - ffeexpr_token_substring_1_); - } - - if (ffest_ffebad_start (FFEBAD_MISSING_COLON_IN_SUBSTR)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - - ffeexpr_stack_->expr = NULL; - return (ffelexHandler) ffeexpr_token_substring_1_ (ft, expr, t); -} - -/* ffeexpr_token_substring_1_ -- NAME OPEN_PAREN [expr COMMA]...expr - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - Handle expression (which might be null) and CLOSE_PAREN. */ - -static ffelexHandler -ffeexpr_token_substring_1_ (ffelexToken ft, ffebld last, ffelexToken t) -{ - ffeexprExpr_ string; - ffebld reduced; - ffebld substrlist; - ffebld first = ffeexpr_stack_->expr; - ffebld strop; - ffeinfo info; - ffeinfoWhere lwh; - ffeinfoWhere rwh; - ffeinfoWhere where; - ffeinfoKindtype first_kt; - ffeinfoKindtype last_kt; - ffetargetIntegerDefault first_val; - ffetargetIntegerDefault last_val; - ffetargetCharacterSize size; - ffetargetCharacterSize strop_size_max; - - string = ffeexpr_stack_->exprstack; - strop = string->u.operand; - info = ffebld_info (strop); - - if ((first == NULL) || (ffebld_op (first) == FFEBLD_opCONTER)) - { /* The starting point is known. */ - first_val = (first == NULL) ? 1 - : ffebld_constant_integerdefault (ffebld_conter (first)); - } - else - { /* Assume start of the entity. */ - first_val = 1; - } - - if ((last != NULL) && (ffebld_op (last) == FFEBLD_opCONTER)) - { /* The ending point is known. */ - last_val = ffebld_constant_integerdefault (ffebld_conter (last)); - - if ((first == NULL) || (ffebld_op (first) == FFEBLD_opCONTER)) - { /* The beginning point is a constant. */ - if (first_val <= last_val) - size = last_val - first_val + 1; - else - { - if (0 && ffe_is_90 ()) - size = 0; - else - { - size = 1; - ffebad_start (FFEBAD_ZERO_SIZE); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - } - } - else - size = FFETARGET_charactersizeNONE; - - strop_size_max = ffebld_size_max (strop); - - if ((strop_size_max != FFETARGET_charactersizeNONE) - && (last_val > strop_size_max)) - { /* Beyond maximum possible end of string. */ - ffebad_start (FFEBAD_RANGE_SUBSTR); - ffebad_here (0, ffelex_token_where_line (ft), - ffelex_token_where_column (ft)); - ffebad_finish (); - } - } - else - size = FFETARGET_charactersizeNONE; /* The size is not known. */ - -#if 0 /* Don't do this, or "is size of target - known?" would no longer be easily - answerable. To see if there is a max - size, use ffebld_size_max; to get only the - known size, else NONE, use - ffebld_size_known; use ffebld_size if - values are sure to be the same (not - opSUBSTR or opCONCATENATE or known to have - known length). By getting rid of this - "useful info" stuff, we don't end up - blank-padding the constant in the - assignment "A(I:J)='XYZ'" to the known - length of A. */ - if (size == FFETARGET_charactersizeNONE) - size = strop_size_max; /* Assume we use the entire string. */ -#endif - - substrlist - = ffebld_new_item - (first, - ffebld_new_item - (last, - NULL - ) - ) - ; - - if (first == NULL) - lwh = FFEINFO_whereCONSTANT; - else - lwh = ffeinfo_where (ffebld_info (first)); - if (last == NULL) - rwh = FFEINFO_whereCONSTANT; - else - rwh = ffeinfo_where (ffebld_info (last)); - - switch (lwh) - { - case FFEINFO_whereCONSTANT: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - where = FFEINFO_whereCONSTANT; - break; - - case FFEINFO_whereIMMEDIATE: - where = FFEINFO_whereIMMEDIATE; - break; - - default: - where = FFEINFO_whereFLEETING; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (rwh) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: - where = FFEINFO_whereIMMEDIATE; - break; - - default: - where = FFEINFO_whereFLEETING; - break; - } - break; - - default: - where = FFEINFO_whereFLEETING; - break; - } - - if (first == NULL) - first_kt = FFEINFO_kindtypeINTEGERDEFAULT; - else - first_kt = ffeinfo_kindtype (ffebld_info (first)); - if (last == NULL) - last_kt = FFEINFO_kindtypeINTEGERDEFAULT; - else - last_kt = ffeinfo_kindtype (ffebld_info (last)); - - switch (where) - { - case FFEINFO_whereCONSTANT: - switch (ffeinfo_where (info)) - { - case FFEINFO_whereCONSTANT: - break; - - case FFEINFO_whereIMMEDIATE: /* Not possible, actually. */ - where = FFEINFO_whereIMMEDIATE; - break; - - default: - where = FFEINFO_whereFLEETING_CADDR; - break; - } - break; - - case FFEINFO_whereIMMEDIATE: - switch (ffeinfo_where (info)) - { - case FFEINFO_whereCONSTANT: - case FFEINFO_whereIMMEDIATE: /* Not possible, actually. */ - break; - - default: - where = FFEINFO_whereFLEETING_IADDR; - break; - } - break; - - default: - switch (ffeinfo_where (info)) - { - case FFEINFO_whereCONSTANT: - where = FFEINFO_whereCONSTANT_SUBOBJECT; /* An F90 concept. */ - break; - - case FFEINFO_whereIMMEDIATE: /* Not possible, actually. */ - default: - where = FFEINFO_whereFLEETING; - break; - } - break; - } - - if (ffebld_op (strop) == FFEBLD_opANY) - { - reduced = ffebld_new_any (); - ffebld_set_info (reduced, ffeinfo_new_any ()); - } - else - { - reduced = ffebld_new_substr (strop, substrlist); - ffebld_set_info (reduced, ffeinfo_new - (FFEINFO_basictypeCHARACTER, - ffeinfo_kindtype (info), - 0, - FFEINFO_kindENTITY, - where, - size)); - reduced = ffeexpr_collapse_substr (reduced, ffeexpr_stack_->tokens[0]); - } - - ffeexpr_stack_->exprstack = string->previous; /* Pops not-quite-operand off - stack. */ - string->u.operand = reduced; /* Save the line/column ffewhere info. */ - ffeexpr_exprstack_push_operand_ (string); /* Push it back on stack. */ - - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - { - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - ffeexpr_is_substr_ok_ = FALSE; /* Nobody likes "FOO(3:5)(1:1)".... */ - return (ffelexHandler) ffeexpr_token_substrp_; - } - - if (ffest_ffebad_start (FFEBAD_INVALID_TOKEN_IN_EXPRESSION)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->tokens[0]), - ffelex_token_where_column (ffeexpr_stack_->tokens[0])); - ffebad_finish (); - } - - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - ffeexpr_is_substr_ok_ = FALSE;/* Nobody likes "FOO(3:5)(1:1)".... */ - return - (ffelexHandler) ffeexpr_find_close_paren_ (t, - (ffelexHandler) - ffeexpr_token_substrp_); -} - -/* ffeexpr_token_substrp_ -- Rhs <character entity> - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - If OPEN_PAREN, treat as start of a substring ("(3:4)") construct, and - issue error message if flag (serves as argument) is set. Else, just - forward token to binary_. */ - -static ffelexHandler -ffeexpr_token_substrp_ (ffelexToken t) -{ - ffeexprContext ctx; - - if (ffelex_token_type (t) != FFELEX_typeOPEN_PAREN) - return (ffelexHandler) ffeexpr_token_binary_ (t); - - ffeexpr_stack_->tokens[0] = ffelex_token_use (t); - - switch (ffeexpr_stack_->context) - { - case FFEEXPR_contextSFUNCDEF: - case FFEEXPR_contextSFUNCDEFINDEX_: - ctx = FFEEXPR_contextSFUNCDEFINDEX_; - break; - - case FFEEXPR_contextSFUNCDEFACTUALARG_: - case FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_: - assert ("bad context" == NULL); - ctx = FFEEXPR_context; - break; - - default: - ctx = FFEEXPR_contextINDEX_; - break; - } - - if (!ffeexpr_is_substr_ok_) - { - if (ffebad_start (FFEBAD_BAD_SUBSTR)) - { - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); - ffebad_finish (); - } - - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, ctx, - ffeexpr_token_anything_); - } - - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, ctx, - ffeexpr_token_substring_); -} - -static ffelexHandler -ffeexpr_token_intrincheck_ (ffelexToken t) -{ - if ((ffelex_token_type (t) != FFELEX_typeCLOSE_PAREN) - && ffebad_start (FFEBAD_INTRINSIC_CMPAMBIG)) - { - ffebad_string (ffeintrin_name_implementation - (ffebld_symter_implementation - (ffebld_left - (ffeexpr_stack_->exprstack->u.operand)))); - ffebad_here (0, ffelex_token_where_line (ffeexpr_stack_->exprstack->token), - ffelex_token_where_column (ffeexpr_stack_->exprstack->token)); - ffebad_finish (); - } - - return (ffelexHandler) ffeexpr_token_substrp_ (t); -} - -/* ffeexpr_token_funsubstr_ -- NAME OPEN_PAREN expr - - Return a pointer to this function to the lexer (ffelex), which will - invoke it for the next token. - - If COLON, do everything we would have done since _parenthesized_ if - we had known NAME represented a kindENTITY instead of a kindFUNCTION. - If not COLON, do likewise for kindFUNCTION instead. */ - -static ffelexHandler -ffeexpr_token_funsubstr_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffeinfoWhere where; - ffesymbol s; - ffesymbolAttrs sa; - ffebld symter = ffeexpr_stack_->exprstack->u.operand; - bool needs_type; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - - s = ffebld_symter (symter); - sa = ffesymbol_attrs (s); - where = ffesymbol_where (s); - - /* We get here only if we don't already know enough about FOO when seeing a - FOO(stuff) reference, and FOO might turn out to be a CHARACTER type. If - "stuff" is a substring reference, then FOO is a CHARACTER scalar type. - Else FOO is a function, either intrinsic or external. If intrinsic, it - wouldn't necessarily be CHARACTER type, so unless it has already been - declared DUMMY, it hasn't had its type established yet. It can't be - CHAR*(*) in any case, though it can have an explicit CHAR*n type. */ - - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsTYPE))); - - needs_type = !(ffesymbol_attrs (s) & FFESYMBOL_attrsDUMMY); - - ffesymbol_signal_change (s); /* Probably already done, but in case.... */ - - if (ffelex_token_type (t) == FFELEX_typeCOLON) - { /* Definitely an ENTITY (char substring). */ - if (needs_type && !ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, ffeexpr_stack_->tokens[0]); - return (ffelexHandler) ffeexpr_token_arguments_ (ft, expr, t); - } - - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - FFEINFO_kindENTITY, - (where == FFEINFO_whereNONE) - ? FFEINFO_whereLOCAL - : where, - ffesymbol_size (s))); - ffebld_set_info (symter, ffeinfo_use (ffesymbol_info (s))); - - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - - ffeexpr_stack_->exprstack->u.operand - = ffeexpr_collapse_symter (symter, ffeexpr_tokens_[0]); - - return (ffelexHandler) ffeexpr_token_substring_ (ft, expr, t); - } - - /* The "stuff" isn't a substring notation, so we now know the overall - reference is to a function. */ - - if (ffeintrin_is_intrinsic (ffesymbol_text (s), ffeexpr_stack_->tokens[0], - FALSE, &gen, &spec, &imp)) - { - ffebld_symter_set_generic (symter, gen); - ffebld_symter_set_specific (symter, spec); - ffebld_symter_set_implementation (symter, imp); - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindFUNCTION, - FFEINFO_whereINTRINSIC, - ffesymbol_size (s))); - } - else - { /* Not intrinsic, now needs CHAR type. */ - if (!ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, ffeexpr_stack_->tokens[0]); - return (ffelexHandler) ffeexpr_token_arguments_ (ft, expr, t); - } - - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - FFEINFO_kindFUNCTION, - (where == FFEINFO_whereNONE) - ? FFEINFO_whereGLOBAL - : where, - ffesymbol_size (s))); - } - - ffebld_set_info (symter, ffeinfo_use (ffesymbol_info (s))); - - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, ffeexpr_stack_->tokens[0], FALSE); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - ffebld_init_list (&ffeexpr_stack_->expr, &ffeexpr_stack_->bottom); - return (ffelexHandler) ffeexpr_token_arguments_ (ft, expr, t); -} - -/* ffeexpr_token_anything_ -- NAME OPEN_PAREN any-expr - - Handle basically any expression, looking for CLOSE_PAREN. */ - -static ffelexHandler -ffeexpr_token_anything_ (ffelexToken ft UNUSED, ffebld expr UNUSED, - ffelexToken t) -{ - ffeexprExpr_ e = ffeexpr_stack_->exprstack; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLON: - return (ffelexHandler) ffeexpr_rhs (ffeexpr_stack_->pool, - FFEEXPR_contextACTUALARG_, - ffeexpr_token_anything_); - - default: - e->u.operand = ffebld_new_any (); - ffebld_set_info (e->u.operand, ffeinfo_new_any ()); - ffelex_token_kill (ffeexpr_stack_->tokens[0]); - ffeexpr_is_substr_ok_ = FALSE; - if (ffelex_token_type (t) == FFELEX_typeCLOSE_PAREN) - return (ffelexHandler) ffeexpr_token_substrp_; - return (ffelexHandler) ffeexpr_token_substrp_ (t); - } -} - -/* Terminate module. */ - -void -ffeexpr_terminate_2 () -{ - assert (ffeexpr_stack_ == NULL); - assert (ffeexpr_level_ == 0); -} diff --git a/gcc/f/expr.h b/gcc/f/expr.h deleted file mode 100755 index 04143e6..0000000 --- a/gcc/f/expr.h +++ /dev/null @@ -1,194 +0,0 @@ -/* expr.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - expr.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_expr -#define _H_f_expr - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFEEXPR_contextLET, - FFEEXPR_contextASSIGN, - FFEEXPR_contextIOLIST, - FFEEXPR_contextPARAMETER, - FFEEXPR_contextSUBROUTINEREF, - FFEEXPR_contextDATA, - FFEEXPR_contextIF, - FFEEXPR_contextARITHIF, - FFEEXPR_contextDO, - FFEEXPR_contextDOWHILE, - FFEEXPR_contextFORMAT, - FFEEXPR_contextAGOTO, - FFEEXPR_contextCGOTO, - FFEEXPR_contextCHARACTERSIZE, - FFEEXPR_contextEQUIVALENCE, - FFEEXPR_contextSTOP, - FFEEXPR_contextRETURN, - FFEEXPR_contextSFUNCDEF, - FFEEXPR_contextINCLUDE, - FFEEXPR_contextWHERE, - FFEEXPR_contextSELECTCASE, - FFEEXPR_contextCASE, - FFEEXPR_contextDIMLIST, - FFEEXPR_contextDIMLISTCOMMON, /* Dim list in COMMON stmt. */ - FFEEXPR_contextFILEASSOC, /* ASSOCIATEVARIABLE=. */ - FFEEXPR_contextFILEINT, /* IOSTAT=. */ - FFEEXPR_contextFILEDFINT, /* NEXTREC=. */ - FFEEXPR_contextFILELOG, /* NAMED=. */ - FFEEXPR_contextFILENUM, /* Numerical expression. */ - FFEEXPR_contextFILECHAR, /* Character expression. */ - FFEEXPR_contextFILENUMCHAR, /* READ KEYxyz=. */ - FFEEXPR_contextFILEDFCHAR, /* Default kind character expression. */ - FFEEXPR_contextFILEKEY, /* OPEN KEY=. */ - FFEEXPR_contextFILEEXTFUNC, /* USEROPEN=. */ - FFEEXPR_contextFILEUNIT, /* READ/WRITE UNIT=. */ - FFEEXPR_contextFILEUNIT_DF, /* DEFINE FILE unit (no "(" after it). */ - FFEEXPR_contextFILEFORMATNML, /* [FMT=] or [NML=]. */ - FFEEXPR_contextFILEFORMAT, /* FMT=. */ - FFEEXPR_contextFILENAMELIST,/* NML=. */ - FFEEXPR_contextFILENUMAMBIG,/* BACKSPACE, ENDFILE, REWIND, UNLOCK... - where at e.g. BACKSPACE(, if COMMA seen - before ), it is ok. */ - FFEEXPR_contextFILEUNITAMBIG, /* READ(, if COMMA seen before ), ok. */ - FFEEXPR_contextFILEVXTCODE, /* ENCODE/DECODE third arg (scalar/array). */ - FFEEXPR_contextALLOCATE, /* ALLOCATE objects (weird). */ - FFEEXPR_contextDEALLOCATE, /* DEALLOCATE objects (weird). */ - FFEEXPR_contextHEAPSTAT, /* ALLOCATE/DEALLOCATE STAT= variable. */ - FFEEXPR_contextKINDTYPE, /* KIND=. */ - FFEEXPR_contextINITVAL, /* R426 =initialization-expr. */ - FFEEXPR_contextNULLIFY, /* Pointer names only (F90) or pointers. */ - FFEEXPR_contextIOLISTDF, /* IOLIST w/internal file (V112 9-14 30,31). */ - FFEEXPR_contextINDEX_, /* Element dimension or substring value. */ - FFEEXPR_contextEQVINDEX_, /* EQUIVALENCE element dimension. */ - FFEEXPR_contextDATAIMPDOINDEX_, /* INDEX in DATAIMPDO context. */ - FFEEXPR_contextIMPDOITEM_, - FFEEXPR_contextIMPDOITEMDF_,/* to ...ITEM_ as IOLISTDF is to IOLIST. */ - FFEEXPR_contextIMPDOCTRL_, - FFEEXPR_contextDATAIMPDOITEM_, - FFEEXPR_contextDATAIMPDOCTRL_, - FFEEXPR_contextLOC_, - FFEEXPR_contextACTUALARG_, /* Actual arg to function or subroutine; - turns into ACTUALARGEXPR_ if tokens not - NAME (CLOSE_PAREN/COMMA) or PERCENT.... */ - FFEEXPR_contextACTUALARGEXPR_, /* Like LET but disallow CHAR*(*) - concats. */ - FFEEXPR_contextINDEXORACTUALARG_, /* "CHARACTER FOO; PRINT *,FOO(?". */ - FFEEXPR_contextINDEXORACTUALARGEXPR_, /* ? not NAME - (CLOSE_PAREN/COMMA). */ - FFEEXPR_contextSFUNCDEFINDEX_, /* INDEX_ within stmt-func def. */ - FFEEXPR_contextSFUNCDEFACTUALARG_, - FFEEXPR_contextSFUNCDEFACTUALARGEXPR_, - FFEEXPR_contextSFUNCDEFINDEXORACTUALARG_, - FFEEXPR_contextSFUNCDEFINDEXORACTUALARGEXPR_, - FFEEXPR_contextPAREN_, /* Rhs paren except in LET context. */ - FFEEXPR_contextPARENFILENUM_, /* Either PAREN or FILENUM context. */ - FFEEXPR_contextPARENFILEUNIT_, /* Either PAREN or FILEUNIT context. */ - FFEEXPR_context - } ffeexprContext; - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lex.h" -#include "malloc.h" - -/* Structure definitions. */ - -typedef ffelexHandler (*ffeexprCallback) (ffelexToken ft, ffebld expr, - ffelexToken t); - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -ffebld ffeexpr_collapse_convert (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_paren (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_uplus (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_uminus (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_not (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_add (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_subtract (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_multiply (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_divide (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_power (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_concatenate (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_lt (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_le (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_eq (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_ne (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_gt (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_ge (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_and (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_or (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_xor (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_eqv (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_neqv (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_symter (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_funcref (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_arrayref (ffebld expr, ffelexToken t); -ffebld ffeexpr_collapse_substr (ffebld expr, ffelexToken t); -ffebld ffeexpr_convert (ffebld source, ffelexToken source_token, - ffelexToken dest_token, ffeinfoBasictype bt, ffeinfoKindtype kt, - ffeinfoRank rk, ffetargetCharacterSize sz, - ffeexprContext context); -ffebld ffeexpr_convert_expr (ffebld source, ffelexToken source_token, - ffebld dest, ffelexToken dest_token, - ffeexprContext context); -ffebld ffeexpr_convert_to_sym (ffebld source, ffelexToken source_token, - ffesymbol dest, ffelexToken dest_token); -void ffeexpr_init_2 (void); -ffelexHandler ffeexpr_rhs (mallocPool pool, ffeexprContext context, - ffeexprCallback callback); -ffelexHandler ffeexpr_lhs (mallocPool pool, ffeexprContext context, - ffeexprCallback callback); -void ffeexpr_terminate_2 (void); -void ffeexpr_type_combine (ffeinfoBasictype *nbt, ffeinfoKindtype *nkt, - ffeinfoBasictype lbt, ffeinfoKindtype lkt, - ffeinfoBasictype rbt, ffeinfoKindtype rkt, - ffelexToken t); - -/* Define macros. */ - -#define ffeexpr_init_0() -#define ffeexpr_init_1() -#define ffeexpr_init_3() -#define ffeexpr_init_4() -#define ffeexpr_terminate_0() -#define ffeexpr_terminate_1() -#define ffeexpr_terminate_3() -#define ffeexpr_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/fini.c b/gcc/f/fini.c deleted file mode 100755 index a51000b..0000000 --- a/gcc/f/fini.c +++ /dev/null @@ -1,776 +0,0 @@ -/* fini.c - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#define USE_HCONFIG - -#include "proj.h" -#include "malloc.h" - -#undef MAXNAMELEN -#define MAXNAMELEN 100 - -typedef struct _name_ *name; - -struct _name_ - { - name next; - name previous; - name next_alpha; - name previous_alpha; - int namelen; - int kwlen; - char kwname[MAXNAMELEN]; - char name_uc[MAXNAMELEN]; - char name_lc[MAXNAMELEN]; - char name_ic[MAXNAMELEN]; - }; - -struct _name_root_ - { - name first; - name last; - }; - -struct _name_alpha_ - { - name ign1; - name ign2; - name first; - name last; - }; - -static FILE *in; -static FILE *out; -static char prefix[32]; -static char postfix[32]; -static char storage[32]; -static char *xspaces[] -= -{ - "", /* 0 */ - " ", /* 1 */ - " ", /* 2 */ - " ", /* 3 */ - " ", /* 4 */ - " ", /* 5 */ - " ", /* 6 */ - " ", /* 7 */ - "\t", /* 8 */ - "\t ", /* 9 */ - "\t ", /* 10 */ - "\t ", /* 11 */ - "\t ", /* 12 */ - "\t ", /* 13 */ - "\t ", /* 14 */ - "\t ", /* 15 */ - "\t\t", /* 16 */ - "\t\t ", /* 17 */ - "\t\t ", /* 18 */ - "\t\t ", /* 19 */ - "\t\t ", /* 20 */ - "\t\t ", /* 21 */ - "\t\t ", /* 22 */ - "\t\t ", /* 23 */ - "\t\t\t", /* 24 */ - "\t\t\t ", /* 25 */ - "\t\t\t ", /* 26 */ - "\t\t\t ", /* 27 */ - "\t\t\t ", /* 28 */ - "\t\t\t ", /* 29 */ - "\t\t\t ", /* 30 */ - "\t\t\t ", /* 31 */ - "\t\t\t\t", /* 32 */ - "\t\t\t\t ", /* 33 */ - "\t\t\t\t ", /* 34 */ - "\t\t\t\t ", /* 35 */ - "\t\t\t\t ", /* 36 */ - "\t\t\t\t ", /* 37 */ - "\t\t\t\t ", /* 38 */ - "\t\t\t\t ", /* 39 */ - "\t\t\t\t\t", /* 40 */ - "\t\t\t\t\t ", /* 41 */ - "\t\t\t\t\t ", /* 42 */ - "\t\t\t\t\t ", /* 43 */ - "\t\t\t\t\t ", /* 44 */ - "\t\t\t\t\t ", /* 45 */ - "\t\t\t\t\t ", /* 46 */ - "\t\t\t\t\t ", /* 47 */ - "\t\t\t\t\t\t", /* 48 */ - "\t\t\t\t\t\t ", /* 49 */ - "\t\t\t\t\t\t ", /* 50 */ - "\t\t\t\t\t\t ", /* 51 */ - "\t\t\t\t\t\t ", /* 52 */ - "\t\t\t\t\t\t ", /* 53 */ - "\t\t\t\t\t\t ", /* 54 */ - "\t\t\t\t\t\t ", /* 55 */ - "\t\t\t\t\t\t\t", /* 56 */ - "\t\t\t\t\t\t\t ", /* 57 */ - "\t\t\t\t\t\t\t ", /* 58 */ - "\t\t\t\t\t\t\t ", /* 59 */ - "\t\t\t\t\t\t\t ", /* 60 */ - "\t\t\t\t\t\t\t ", /* 61 */ - "\t\t\t\t\t\t\t ", /* 62 */ - "\t\t\t\t\t\t\t ", /* 63 */ - "\t\t\t\t\t\t\t\t", /* 64 */ - "\t\t\t\t\t\t\t\t ", /* 65 */ - "\t\t\t\t\t\t\t\t ", /* 66 */ - "\t\t\t\t\t\t\t\t ", /* 67 */ - "\t\t\t\t\t\t\t\t ", /* 68 */ - "\t\t\t\t\t\t\t\t ", /* 69 */ - "\t\t\t\t\t\t\t\t ", /* 70 */ - "\t\t\t\t\t\t\t\t ", /* 71 */ - "\t\t\t\t\t\t\t\t\t", /* 72 */ - "\t\t\t\t\t\t\t\t\t ", /* 73 */ - "\t\t\t\t\t\t\t\t\t ", /* 74 */ - "\t\t\t\t\t\t\t\t\t ", /* 75 */ - "\t\t\t\t\t\t\t\t\t ", /* 76 */ - "\t\t\t\t\t\t\t\t\t ", /* 77 */ - "\t\t\t\t\t\t\t\t\t ", /* 78 */ - "\t\t\t\t\t\t\t\t\t ", /* 79 */ - "\t\t\t\t\t\t\t\t\t\t", /* 80 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 81 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 82 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 83 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 84 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 85 */ - "\t\t\t\t\t\t\t\t\t\t ", /* 86 */ - "\t\t\t\t\t\t\t\t\t\t ",/* 87 */ - "\t\t\t\t\t\t\t\t\t\t\t", /* 88 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 89 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 90 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 91 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 92 */ - "\t\t\t\t\t\t\t\t\t\t\t ",/* 93 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 94 */ - "\t\t\t\t\t\t\t\t\t\t\t ", /* 95 */ - "\t\t\t\t\t\t\t\t\t\t\t\t", /* 96 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 97 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 98 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ",/* 99 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 100 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 101 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 102 */ - "\t\t\t\t\t\t\t\t\t\t\t\t ", /* 103 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 104 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ",/* 105 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 106 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 107 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 108 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 109 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 110 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 111 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 112 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 113 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 114 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 115 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 116 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 117 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 118 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 119 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 120 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 121 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 122 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 123 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 124 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 125 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 126 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 127 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 128 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 129 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 130 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 131 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 132 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 133 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 134 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 135 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 136 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 137 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 138 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 139 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 140 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 141 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 142 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 143 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 144 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 145 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 146 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 147 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 148 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 149 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 150 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 151 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t", /* 152 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 153 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 154 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 155 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 156 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 157 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 158 */ - "\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t ", /* 159 */ -}; - -void testname (bool nested, int indent, name first, name last); -void testnames (bool nested, int indent, int len, name first, name last); - -int -main (int argc, char **argv) -{ - char buf[MAXNAMELEN]; - char last_buf[MAXNAMELEN] = ""; - char kwname[MAXNAMELEN]; - char routine[32]; - char type[32]; - int i; - int count; - int len; - struct _name_root_ names[200]; - struct _name_alpha_ names_alpha; - name n; - name newname; - char *input_name; - char *output_name; - char *include_name; - FILE *incl; - int fixlengths; - int total_length; - int do_name; /* TRUE if token may be NAME. */ - int do_names; /* TRUE if token may be NAMES. */ - int cc; - bool do_exit = FALSE; - - for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i) - { /* Initialize length/name ordered list roots. */ - names[i].first = (name) &names[i]; - names[i].last = (name) &names[i]; - } - names_alpha.first = (name) &names_alpha; /* Initialize name order. */ - names_alpha.last = (name) &names_alpha; - - if (argc != 4) - { - fprintf (stderr, "Command form: fini input output-code output-include\n"); - exit (1); - } - - input_name = argv[1]; - output_name = argv[2]; - include_name = argv[3]; - - in = fopen (input_name, "r"); - if (in == NULL) - { - fprintf (stderr, "Cannot open \"%s\"\n", input_name); - exit (1); - } - out = fopen (output_name, "w"); - if (out == NULL) - { - fclose (in); - fprintf (stderr, "Cannot open \"%s\"\n", output_name); - exit (1); - } - incl = fopen (include_name, "w"); - if (incl == NULL) - { - fclose (in); - fprintf (stderr, "Cannot open \"%s\"\n", include_name); - exit (1); - } - - /* Get past the initial block-style comment (man, this parsing code is just - _so_ lame, but I'm too lazy to improve it). */ - - for (;;) - { - cc = getc (in); - if (cc == '{') - { - while (((cc = getc (in)) != '}') && (cc != EOF)) - ; - } - else if (cc != EOF) - { - while (((cc = getc (in)) != EOF) && (! ISALNUM (cc))) - ; - ungetc (cc, in); - break; - } - else - { - assert ("EOF too soon!" == NULL); - exit (1); - } - } - - fscanf (in, "%s %s %s %s %s %d %d", prefix, postfix, storage, type, routine, - &do_name, &do_names); - - if (storage[0] == '\0') - storage[1] = '\0'; - else - /* Assume string is quoted somehow, replace ending quote with space. */ - { - if (storage[2] == '\0') - storage[1] = '\0'; - else - storage[strlen (storage) - 1] = ' '; - } - - if (postfix[0] == '\0') - postfix[1] = '\0'; - else /* Assume string is quoted somehow, strip off - ending quote. */ - postfix[strlen (postfix) - 1] = '\0'; - - for (i = 1; storage[i] != '\0'; ++i) - storage[i - 1] = storage[i]; - storage[i - 1] = '\0'; - - for (i = 1; postfix[i] != '\0'; ++i) - postfix[i - 1] = postfix[i]; - postfix[i - 1] = '\0'; - - fixlengths = strlen (prefix) + strlen (postfix); - - while (TRUE) - { - count = fscanf (in, "%s %s", buf, kwname); - if (count == EOF) - break; - len = strlen (buf); - if (len == 0) - continue; /* Skip empty lines. */ - if (buf[0] == ';') - continue; /* Skip commented-out lines. */ - for (i = strlen (buf) - 1; i > 0; --i) - cc = buf[i]; - - /* Make new name object to store name and its keyword. */ - - newname = (name) malloc (sizeof (*newname)); - newname->namelen = strlen (buf); - newname->kwlen = strlen (kwname); - total_length = newname->kwlen + fixlengths; - if (total_length >= 32) /* Else resulting keyword name too long. */ - { - fprintf (stderr, "%s: %s%s%s is 31+%d chars long\n", input_name, - prefix, kwname, postfix, total_length - 31); - do_exit = TRUE; - } - strcpy (newname->kwname, kwname); - for (i = 0; i < newname->namelen; ++i) - { - cc = buf[i]; - if (ISALPHA (cc)) - { - newname->name_uc[i] = toupper (cc); - newname->name_lc[i] = tolower (cc); - newname->name_ic[i] = cc; - } - else - newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] - = cc; - } - newname->name_uc[i] = newname->name_lc[i] = newname->name_ic[i] = '\0'; - - /* Warn user if names aren't alphabetically ordered. */ - - if ((last_buf[0] != '\0') - && (strcmp (last_buf, newname->name_uc) >= 0)) - { - fprintf (stderr, "%s: \"%s\" precedes \"%s\"\n", input_name, - last_buf, newname->name_uc); - do_exit = TRUE; - } - strcpy (last_buf, newname->name_uc); - - /* Append name to end of alpha-sorted list (assumes names entered in - alpha order wrt name, not kwname, even though kwname is output from - this list). */ - - n = names_alpha.last; - newname->next_alpha = n->next_alpha; - newname->previous_alpha = n; - n->next_alpha->previous_alpha = newname; - n->next_alpha = newname; - - /* Insert name in appropriate length/name ordered list. */ - - n = (name) &names[len]; - while ((n->next != (name) &names[len]) - && (strcmp (buf, n->next->name_uc) > 0)) - n = n->next; - if (strcmp (buf, n->next->name_uc) == 0) - { - fprintf (stderr, "%s: extraneous \"%s\"\n", input_name, buf); - do_exit = TRUE; - } - newname->next = n->next; - newname->previous = n; - n->next->previous = newname; - n->next = newname; - } - -#if 0 - for (len = 0; len < ARRAY_SIZE (name); ++len) - { - if (names[len].first == (name) &names[len]) - continue; - printf ("Length %d:\n", len); - for (n = names[len].first; n != (name) &names[len]; n = n->next) - printf (" %s %s %s\n", n->name_uc, n->name_lc, n->name_ic); - } -#endif - - if (do_exit) - exit (1); - - /* First output the #include file. */ - - for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha) - { - fprintf (incl, "#define %sl%s%s %d\n", prefix, n->kwname, postfix, - n->namelen); - } - - fprintf (incl, - "\ -\n\ -enum %s_\n\ -{\n\ -%sNone%s,\n\ -", - type, prefix, postfix); - - for (n = names_alpha.first; n != (name) &names_alpha; n = n->next_alpha) - { - fprintf (incl, - "\ -%s%s%s,\n\ -", - prefix, n->kwname, postfix); - } - - fprintf (incl, - "\ -%s%s\n\ -};\n\ -typedef enum %s_ %s;\n\ -", - prefix, postfix, type, type); - - /* Now output the C program. */ - - fprintf (out, - "\ -%s%s\n\ -%s (ffelexToken t)\n\ -%c\n\ - char *p;\n\ - int c;\n\ -\n\ - p = ffelex_token_text (t);\n\ -\n\ -", - storage, type, routine, '{'); - - if (do_name) - { - if (do_names) - fprintf (out, - "\ - if (ffelex_token_type (t) == FFELEX_typeNAME)\n\ - {\n\ - switch (ffelex_token_length (t))\n\ -\t{\n\ -" - ); - else - fprintf (out, - "\ - assert (ffelex_token_type (t) == FFELEX_typeNAME);\n\ -\n\ - switch (ffelex_token_length (t))\n\ - {\n\ -" - ); - -/* Now output the length as a case, followed by the binary search within that length. */ - - for (len = 0; ((size_t) len) < ARRAY_SIZE (names); ++len) - { - if (names[len].first != (name) &names[len]) - { - if (do_names) - fprintf (out, - "\ -\tcase %d:\n\ -", - len); - else - fprintf (out, - "\ - case %d:\n\ -", - len); - testname (FALSE, do_names ? 10 : 6, names[len].first, names[len].last); - if (do_names) - fprintf (out, - "\ -\t break;\n\ -" - ); - else - fprintf (out, - "\ - break;\n\ -" - ); - } - } - - if (do_names) - fprintf (out, - "\ -\t}\n\ - return %sNone%s;\n\ - }\n\ -\n\ -", - prefix, postfix); - else - fprintf (out, - "\ - }\n\ -\n\ - return %sNone%s;\n\ -}\n\ -", - prefix, postfix); - } - - if (do_names) - { - fputs ("\ - assert (ffelex_token_type (t) == FFELEX_typeNAMES);\n\ -\n\ - switch (ffelex_token_length (t))\n\ - {\n\ - default:\n\ -", - out); - - /* Find greatest non-empty length list. */ - - for (len = ARRAY_SIZE (names) - 1; - names[len].first == (name) &names[len]; - --len) - ; - -/* Now output the length as a case, followed by the binary search within that length. */ - - if (len > 0) - { - for (; len != 0; --len) - { - fprintf (out, - "\ - case %d:\n\ -", - len); - if (names[len].first != (name) &names[len]) - testnames (FALSE, 6, len, names[len].first, names[len].last); - } - if (names[1].first == (name) &names[1]) - fprintf (out, - "\ - ;\n\ -" - ); /* Need empty statement after an empty case - 1: */ - } - - fprintf (out, - "\ - }\n\ -\n\ - return %sNone%s;\n\ -}\n\ -", - prefix, postfix); - } - - if (out != stdout) - fclose (out); - if (incl != stdout) - fclose (incl); - if (in != stdin) - fclose (in); - exit (0); -} - -void -testname (bool nested, int indent, name first, name last) -{ - name n; - name nhalf; - int num; - int numhalf; - - assert (!nested || indent >= 2); - assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces)); - - num = 0; - numhalf = 0; - for (n = first, nhalf = first; n != last->next; n = n->next) - { - if ((++num & 1) == 0) - { - nhalf = nhalf->next; - ++numhalf; - } - } - - if (nested) - fprintf (out, - "\ -%s{\n\ -", - xspaces[indent - 2]); - - fprintf (out, - "\ -%sif ((c = ffesrc_strcmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\")) == 0)\n\ -%sreturn %s%s%s;\n\ -", - xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic, - xspaces[indent + 2], prefix, nhalf->kwname, postfix); - - if (num != 1) - { - fprintf (out, - "\ -%selse if (c < 0)\n\ -", - xspaces[indent]); - - if (numhalf == 0) - fprintf (out, - "\ -%s;\n\ -", - xspaces[indent + 2]); - else - testname (TRUE, indent + 4, first, nhalf->previous); - - if (num - numhalf > 1) - { - fprintf (out, - "\ -%selse\n\ -", - xspaces[indent]); - - testname (TRUE, indent + 4, nhalf->next, last); - } - } - - if (nested) - fprintf (out, - "\ -%s}\n\ -", - xspaces[indent - 2]); -} - -void -testnames (bool nested, int indent, int len, name first, name last) -{ - name n; - name nhalf; - int num; - int numhalf; - - assert (!nested || indent >= 2); - assert (((size_t) indent) + 4 < ARRAY_SIZE (xspaces)); - - num = 0; - numhalf = 0; - for (n = first, nhalf = first; n != last->next; n = n->next) - { - if ((++num & 1) == 0) - { - nhalf = nhalf->next; - ++numhalf; - } - } - - if (nested) - fprintf (out, - "\ -%s{\n\ -", - xspaces[indent - 2]); - - fprintf (out, - "\ -%sif ((c = ffesrc_strncmp_2c (ffe_case_match (), p, \"%s\", \"%s\", \"%s\", %d)) == 0)\n\ -%sreturn %s%s%s;\n\ -", - xspaces[indent], nhalf->name_uc, nhalf->name_lc, nhalf->name_ic, - len, xspaces[indent + 2], prefix, nhalf->kwname, postfix); - - if (num != 1) - { - fprintf (out, - "\ -%selse if (c < 0)\n\ -", - xspaces[indent]); - - if (numhalf == 0) - fprintf (out, - "\ -%s;\n\ -", - xspaces[indent + 2]); - else - testnames (TRUE, indent + 4, len, first, nhalf->previous); - - if (num - numhalf > 1) - { - fprintf (out, - "\ -%selse\n\ -", - xspaces[indent]); - - testnames (TRUE, indent + 4, len, nhalf->next, last); - } - } - - if (nested) - fprintf (out, - "\ -%s}\n\ -", - xspaces[indent - 2]); -} diff --git a/gcc/f/flags.j b/gcc/f/flags.j deleted file mode 100755 index 02742d8..0000000 --- a/gcc/f/flags.j +++ /dev/null @@ -1,27 +0,0 @@ -/* flags.j -- Wrapper for GCC's flags.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_flags -#define _J_f_flags -#include "flags.h" -#endif -#endif diff --git a/gcc/f/g77.1 b/gcc/f/g77.1 deleted file mode 100755 index d6a465b..0000000 --- a/gcc/f/g77.1 +++ /dev/null @@ -1,357 +0,0 @@ -.\" Copyright (c) 1995-1997 Free Software Foundation -*-Text-*- -.\" See section COPYING for conditions for redistribution -.\" FIXME: no info here on predefines. Should there be? extra for F77... -.TH G77 1 "1998-09-01" "GNU Tools" "GNU Tools" -.de BP -.sp -.ti \-.2i -\(** -.. -.SH NAME -g77 \- GNU project Fortran Compiler (v0.5.24) -.SH SYNOPSIS -.RB g77 " [" \c -.IR option " | " "filename " ].\|.\|. -.SH WARNING -The information in this man page is an extract from the full -documentation of the GNU Fortran compiler (version 0.5.24), -and is limited to the meaning of some of the options. -.PP -This man page is not up to date, since no volunteers want to -maintain it. If you find a discrepancy between the man page and the -software, please check the Info file, which is the authoritative -documentation. -.\" .PP -.\" The version of GNU Fortran documented by the Info file is 0.5.24, -.\" which includes substantial improvements and changes since 0.5.24, -.\" the version documented in this man page. -.PP -If we find that the things in this man page that are out of date cause -significant confusion or complaints, we will stop distributing the man -page. The alternative, updating the man page when we update the Info -file, is impractical because the rest of the work of maintaining GNU Fortran -leaves us no time for that. The GNU project regards man pages as -obsolete and should not let them take time away from other things. -.PP -For complete and current documentation, refer to the Info file `\|\c -.B g77\c -\&\|' or the manual -.I -Using and Porting GNU Fortran (for version 0.5.24)\c -\&. Both are made from the Texinfo source file -.BR g77.texi . -.PP -If your system has the `\|\c -.B info\c -\&\|' command installed, the command `\|\c -.B info g77\c -\&\|' should work, unless -.B g77 -has not been properly installed. -If your system lacks `\|\c -.B info\c -\&\|', or you wish to avoid using it for now, -the command `\|\c -.B more /usr/info/g77.info*\c -\&\|' should work, unless -.B g77 -has not been properly installed. -.PP -If -.B g77 -has not been properly installed, so that you -cannot easily access the Info file for it, -ask your system administrator, or the installer -of -.B g77 -(if you know who that is) to fix the problem. -.SH DESCRIPTION -The C and F77 compilers are integrated; -.B g77 -is a program to call -.B gcc -with options to recognize programs written in Fortran (ANSI FORTRAN 77, -also called F77). -.B gcc -processes input files -through one or more of four stages: preprocessing, compilation, -assembly, and linking. This man page contains full descriptions for -.I only -F77-specific aspects of the compiler, though it also contains -summaries of some general-purpose options. For a fuller explanation -of the compiler, see -.BR gcc ( 1 ). - -For complete documentation on GNU Fortran, type `\|\c -.B info g77\c -\&\|'. - -F77 source files use the suffix `\|\c -.B .f\c -\&\|' or `\|\c -.B .for\c -\&\|'; F77 files to be preprocessed by -.BR cpp ( 1 ) -use the suffix `\|\c -.B .F\c -\&\|' or `\|\c -.B .fpp\c -\&\|'; Ratfor source files use the suffix `\|\c -.B .r\c -\&\|' (though -.B ratfor -itself is not supplied as part of -.B g77\c -\&). -.SH OPTIONS -There are many command-line options, including options to control -details of optimization, warnings, and code generation, which are -common to both -.B gcc -and -.B g77\c -\&. For full information on all options, see -.BR gcc ( 1 ). - -Options must be separate: `\|\c -.B \-dr\c -\&\|' is quite different from `\|\c -.B \-d \-r -\&\|'. - -Most `\|\c -.B \-f\c -\&\|' and `\|\c -.B \-W\c -\&\|' options have two contrary forms: -.BI \-f name -and -.BI \-fno\- name\c -\& (or -.BI \-W name -and -.BI \-Wno\- name\c -\&). Only the non-default forms are shown here. - -.TP -.B \-c -Compile or assemble the source files, but do not link. The compiler -output is an object file corresponding to each source file. -.TP -.BI \-D macro -Define macro \c -.I macro\c -\& with the string `\|\c -.B 1\c -\&\|' as its definition. -.TP -.BI \-D macro = defn -Define macro \c -.I macro\c -\& as \c -.I defn\c -\&. -.TP -.B \-E -Stop after the preprocessing stage; do not run the compiler proper. The -output is preprocessed source code, which is sent to the -standard output. -.TP -.B \-g -Produce debugging information in the operating system's native format -(for DBX or SDB or DWARF). GDB also can work with this debugging -information. On most systems that use DBX format, `\|\c -.B \-g\c -\&\|' enables use -of extra debugging information that only GDB can use. - -Unlike most other Fortran compilers, GNU Fortran allows you to use `\|\c -.B \-g\c -\&\|' with -`\|\c -.B \-O\c -\&\|'. The shortcuts taken by optimized code may occasionally -produce surprising results: some variables you declared may not exist -at all; flow of control may briefly move where you did not expect it; -some statements may not be executed because they compute constant -results or their values were already at hand; some statements may -execute in different places because they were moved out of loops. - -Nevertheless it proves possible to debug optimized output. This makes -it reasonable to use the optimizer for programs that might have bugs. -.TP -.BI "\-I" "dir"\c -\& -Append directory \c -.I dir\c -\& to the list of directories searched for include files. -.TP -.BI "\-L" "dir"\c -\& -Add directory \c -.I dir\c -\& to the list of directories to be searched -for `\|\c -.B \-l\c -\&\|'. -.TP -.BI \-l library\c -\& -Use the library named \c -.I library\c -\& when linking. -.TP -.B \-nostdinc -Do not search the standard system directories for header files. Only -the directories you have specified with -.B \-I -options (and the current directory, if appropriate) are searched. -.TP -.B \-O -Optimize. Optimizing compilation takes somewhat more time, and a lot -more memory for a large function. See the GCC documentation for -further optimisation options. Loop unrolling, in particular, may be -worth investigating for typical numerical Fortran programs. -.TP -.BI "\-o " file\c -\& -Place output in file \c -.I file\c -\&. -.TP -.B \-S -Stop after the stage of compilation proper; do not assemble. The output -is an assembler code file for each non-assembler input -file specified. -.TP -.BI \-U macro -Undefine macro \c -.I macro\c -\&. -.TP -.B \-v -Print (on standard error output) the commands executed to run the -stages of compilation. Also print the version number of the compiler -driver program and of the preprocessor and the compiler proper. The -version numbers of g77 itself and the GCC distribution on which it is -based are distinct. -.TP -.B \-Wall -Issue warnings for conditions which pertain to usage that we recommend -avoiding and that we believe is easy to avoid, even in conjunction -with macros. -.PP - -.SH FILES -.ta \w'LIBDIR/g77\-include 'u -file.h C header (preprocessor) file -.br -file.f Fortran source file -.br -file.for Fortran source file -.br -file.F preprocessed Fortran source file -.br -file.fpp preprocessed Fortran source file -.br -file.r Ratfor source file (ratfor not included) -.br -file.s assembly language file -.br -file.o object file -.br -a.out link edited output -.br -\fITMPDIR\fR/cc\(** temporary files -.br -\fILIBDIR\fR/cpp preprocessor -.br -\fILIBDIR\fR/f771 compiler -.br -\fILIBDIR\fR/libg2c.a Fortran run-time library -.br -\fILIBDIR\fR/libgcc.a GCC subroutine library -.br -/lib/crt[01n].o start-up routine -.br -/lib/libc.a standard C library, see -.IR intro (3) -.br -/usr/include standard directory for -.B #include -files -.br -\fILIBDIR\fR/include standard gcc directory for -.B #include -.br - files. -.sp -.I LIBDIR -is usually -.B /usr/local/lib/\c -.IR machine / version . -.sp -.I TMPDIR -comes from the environment variable -.B TMPDIR -(default -.B /usr/tmp -if available, else -.B /tmp\c -\&). -.SH "SEE ALSO" -gcc(1), cpp(1), as(1), ld(1), gdb(1), adb(1), dbx(1), sdb(1). -.br -.RB "`\|" g77 "\|', `\|" gcc "\|', `\|" cpp "\|'," -.RB "`\|" as "\|', `\|" ld "\|'," -and -.RB "`\|" gdb "\|'" -entries in -.B info\c -\&. -.br -.I -Using and Porting GNU Fortran (for version 0.5.24)\c -, James Craig Burley; -.I -Using and Porting GNU CC (for version 2.0)\c -, Richard M. Stallman; -.I -The C Preprocessor\c -, Richard M. Stallman; -.I -Debugging with GDB: the GNU Source-Level Debugger\c -, Richard M. Stallman and Roland H. Pesch; -.I -Using as: the GNU Assembler\c -, Dean Elsner, Jay Fenlason & friends; -.I -gld: the GNU linker\c -, Steve Chamberlain and Roland Pesch. - -.SH BUGS -For instructions on how to report bugs, type `\|\c -.B info g77 -n Bugs\c -\&\|'. - -.SH COPYING -Copyright (c) 1991-1998 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. -.SH AUTHORS -See the GNU CC Manual for the contributors to GNU CC. -See the GNU Fortran Manual for the contributors to -GNU Fortran. diff --git a/gcc/f/g77.texi b/gcc/f/g77.texi deleted file mode 100755 index 9773c9f..0000000 --- a/gcc/f/g77.texi +++ /dev/null @@ -1,14971 +0,0 @@ -\input texinfo @c -*-texinfo-*- -@c fix @set inside @example: -@tex -\gdef\set{\begingroup\catcode` =10 \parsearg\setxxx} -\gdef\setyyy#1 #2\endsetyyy{% - \def\temp{#2}% - \ifx\temp\empty \global\expandafter\let\csname SET#1\endcsname = \empty - \else \setzzz{#1}#2\endsetzzz % Remove the trailing space \setxxx inserted. - \fi - \endgroup -} -@end tex - -@c %**start of header -@setfilename g77.info - -@set last-up-date 1998-09-01 -@set version-g77 0.5.24 -@set email-general egcs@@cygnus.com -@set email-bugs egcs-bugs@@cygnus.com -@set path-g77 egcs/gcc/f -@set path-libf2c egcs/libf2c - -@c @setfilename useg77.info -@c @setfilename portg77.info -@c To produce the full manual, use the "g77.info" setfilename, and -@c make sure the following do NOT begin with '@c' (and the @clear lines DO) -@set INTERNALS -@set USING -@c To produce a user-only manual, use the "useg77.info" setfilename, and -@c make sure the following does NOT begin with '@c': -@c @clear INTERNALS -@c To produce a porter-only manual, use the "portg77.info" setfilename, -@c and make sure the following does NOT begin with '@c': -@c @clear USING - -@c (For FSF printing, turn on smallbook; that is all that is needed.) - -@c smallbook - -@ifset INTERNALS -@ifset USING -@settitle Using and Porting GNU Fortran -@end ifset -@end ifset -@c seems reasonable to assume at least one of INTERNALS or USING is set... -@ifclear INTERNALS -@settitle Using GNU Fortran -@end ifclear -@ifclear USING -@settitle Porting GNU Fortran -@end ifclear -@c then again, have some fun -@ifclear INTERNALS -@ifclear USING -@settitle Doing Squat with GNU Fortran -@end ifclear -@end ifclear - -@syncodeindex fn cp -@syncodeindex vr cp -@c %**end of header -@setchapternewpage odd - -@ifinfo -This file explains how to use the GNU Fortran system. - -Published by the Free Software Foundation -59 Temple Place - Suite 330 -Boston, MA 02111-1307 USA - -Copyright (C) 1995-1997 Free Software Foundation, Inc. - -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. - -@ignore -Permission is granted to process this file through Tex and print the -results, provided the printed document carries copying permission -notice identical to this one except for the removal of this paragraph -(this paragraph not being relevant to the printed manual). - -@end ignore -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -sections entitled ``GNU General Public License,'' ``Funding for Free -Software,'' and ``Protect Your Freedom---Fight `Look And Feel'@w{}'' are -included exactly as in the original, and provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the sections entitled ``GNU General Public License,'' -``Funding for Free Software,'' and ``Protect Your Freedom---Fight `Look -And Feel'@w{}'', and this permission notice, may be included in -translations approved by the Free Software Foundation instead of in the -original English. -@end ifinfo - -Contributed by James Craig Burley (@email{burley@@gnu.org}). -Inspired by a first pass at translating @file{g77-0.5.16/f/DOC} that -was contributed to Craig by David Ronis (@email{ronis@@onsager.chem.mcgill.ca}). - -@finalout -@titlepage -@comment The title is printed in a large font. -@center @titlefont{Using GNU Fortran} -@sp 2 -@center James Craig Burley -@sp 3 -@center Last updated @value{last-up-date} -@sp 1 -@c The version number appears some more times in this file. - -@center for version @value{version-g77} -@page -@vskip 0pt plus 1filll -Copyright @copyright{} 1995-1997 Free Software Foundation, Inc. -@sp 2 -For GNU Fortran Version @value{version-g77}* -@sp 1 -Published by the Free Software Foundation @* -59 Temple Place - Suite 330@* -Boston, MA 02111-1307, USA@* -@c Last printed ??ber, 19??.@* -@c Printed copies are available for $? each.@* -@c ISBN ??? -@sp 1 -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. - -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided also that the -sections entitled ``GNU General Public License,'' ``Funding for Free -Software,'' and ``Protect Your Freedom---Fight `Look And Feel'@w{}'' are -included exactly as in the original, and provided that the entire -resulting derived work is distributed under the terms of a permission -notice identical to this one. - -Permission is granted to copy and distribute translations of this manual -into another language, under the above conditions for modified versions, -except that the sections entitled ``GNU General Public License,'' -``Funding for Free Software,'' and ``Protect Your Freedom---Fight `Look -And Feel'@w{}'', and this permission notice, may be included in -translations approved by the Free Software Foundation instead of in the -original English. -@end titlepage -@page - -@ifinfo - -@dircategory Programming -@direntry -* g77: (g77). The GNU Fortran compiler. -@end direntry -@node Top, Copying,, (DIR) -@top Introduction -@cindex Introduction - -@ifset INTERNALS -@ifset USING -This manual documents how to run, install and port the GNU Fortran -compiler, as well as its new features and incompatibilities, and how to -report bugs. It corresponds to GNU Fortran version @value{version-g77}. -@end ifset -@end ifset - -@ifclear INTERNALS -This manual documents how to run and install the GNU Fortran compiler, -as well as its new features and incompatibilities, and how to report -bugs. It corresponds to GNU Fortran version @value{version-g77}. -@end ifclear -@ifclear USING -This manual documents how to port the GNU Fortran compiler, -as well as its new features and incompatibilities, and how to report -bugs. It corresponds to GNU Fortran version @value{version-g77}. -@end ifclear - -@end ifinfo -@menu -* Copying:: GNU General Public License says - how you can copy and share GNU Fortran. -* Contributors:: People who have contributed to GNU Fortran. -* Funding:: How to help assure continued work for free software. -* Funding GNU Fortran:: How to help assure continued work on GNU Fortran. -* Look and Feel:: Protect your freedom---fight ``look and feel''. -@ifset USING -* Getting Started:: Finding your way around this manual. -* What is GNU Fortran?:: How @code{g77} fits into the universe. -* G77 and GCC:: You can compile Fortran, C, or other programs. -* Invoking G77:: Command options supported by @code{g77}. -* News:: News about recent releases of @code{g77}. -* Changes:: User-visible changes to recent releases of @code{g77}. -* Language:: The GNU Fortran language. -* Compiler:: The GNU Fortran compiler. -* Other Dialects:: Dialects of Fortran supported by @code{g77}. -* Other Compilers:: Fortran compilers other than @code{g77}. -* Other Languages:: Languages other than Fortran. -* Installation:: How to configure, compile and install GNU Fortran. -* Debugging and Interfacing:: How @code{g77} generates code. -* Collected Fortran Wisdom:: How to avoid Trouble. -* Trouble:: If you have trouble with GNU Fortran. -* Open Questions:: Things we'd like to know. -* Bugs:: How, why, and where to report bugs. -* Service:: How to find suppliers of support for GNU Fortran. -@end ifset -@ifset INTERNALS -* Adding Options:: Guidance on teaching @code{g77} about new options. -* Projects:: Projects for @code{g77} internals hackers. -@end ifset - -* M: Diagnostics. Diagnostics produced by @code{g77}. - -* Index:: Index of concepts and symbol names. -@end menu -@c yes, the "M: " @emph{is} intentional -- bad.def references it (CMPAMBIG)! - -@node Copying -@unnumbered GNU GENERAL PUBLIC LICENSE -@center Version 2, June 1991 - -@display -Copyright @copyright{} 1989, 1991 Free Software Foundation, Inc. -59 Temple Place - Suite 330, Boston, MA 02111-1307, USA - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@unnumberedsec Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software---to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - -@iftex -@unnumberedsec TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end iftex -@ifinfo -@center TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION -@end ifinfo - -@enumerate 0 -@item -This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The ``Program'', below, -refers to any such program or work, and a ``work based on the Program'' -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term ``modification''.) Each licensee is addressed as ``you''. - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - -@item -You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - -@item -You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - -@enumerate a -@item -You must cause the modified files to carry prominent notices -stating that you changed the files and the date of any change. - -@item -You must cause any work that you distribute or publish, that in -whole or in part contains or is derived from the Program or any -part thereof, to be licensed as a whole at no charge to all third -parties under the terms of this License. - -@item -If the modified program normally reads commands interactively -when run, you must cause it, when started running for such -interactive use in the most ordinary way, to print or display an -announcement including an appropriate copyright notice and a -notice that there is no warranty (or else, saying that you provide -a warranty) and that users may redistribute the program under -these conditions, and telling the user how to view a copy of this -License. (Exception: if the Program itself is interactive but -does not normally print such an announcement, your work based on -the Program is not required to print an announcement.) -@end enumerate - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - -@item -You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - -@enumerate a -@item -Accompany it with the complete corresponding machine-readable -source code, which must be distributed under the terms of Sections -1 and 2 above on a medium customarily used for software interchange; or, - -@item -Accompany it with a written offer, valid for at least three -years, to give any third party, for a charge no more than your -cost of physically performing source distribution, a complete -machine-readable copy of the corresponding source code, to be -distributed under the terms of Sections 1 and 2 above on a medium -customarily used for software interchange; or, - -@item -Accompany it with the information you received as to the offer -to distribute corresponding source code. (This alternative is -allowed only for noncommercial distribution and only if you -received the program in object code or executable form with such -an offer, in accord with Subsection b above.) -@end enumerate - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - -@item -You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - -@item -You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - -@item -Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - -@item -If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - -@item -If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - -@item -The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and ``any -later version'', you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - -@item -If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - -@iftex -@heading NO WARRANTY -@end iftex -@ifinfo -@center NO WARRANTY -@end ifinfo - -@item -BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM ``AS IS'' WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - -@item -IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. -@end enumerate - -@iftex -@heading END OF TERMS AND CONDITIONS -@end iftex -@ifinfo -@center END OF TERMS AND CONDITIONS -@end ifinfo - -@page -@unnumberedsec How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the ``copyright'' line and a pointer to where the full notice is found. - -@smallexample -@var{one line to give the program's name and a brief idea of what it does.} -Copyright (C) 19@var{yy} @var{name of author} - -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 of the License, 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. -@end smallexample - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - -@smallexample -Gnomovision version 69, Copyright (C) 19@var{yy} @var{name of author} -Gnomovision comes with ABSOLUTELY NO WARRANTY; for details -type `show w'. -This is free software, and you are welcome to redistribute it -under certain conditions; type `show c' for details. -@end smallexample - -The hypothetical commands @samp{show w} and @samp{show c} should show -the appropriate parts of the General Public License. Of course, the -commands you use may be called something other than @samp{show w} and -@samp{show c}; they could even be mouse-clicks or menu items---whatever -suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a ``copyright disclaimer'' for the program, if -necessary. Here is a sample; alter the names: - -@smallexample -Yoyodyne, Inc., hereby disclaims all copyright interest in the program -`Gnomovision' (which makes passes at compilers) written by James Hacker. - -@var{signature of Ty Coon}, 1 April 1989 -Ty Coon, President of Vice -@end smallexample - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - -@node Contributors -@unnumbered Contributors to GNU Fortran -@cindex contributors -@cindex credits - -In addition to James Craig Burley, who wrote the front end, -many people have helped create and improve GNU Fortran. - -@itemize @bullet -@item -The packaging and compiler portions of GNU Fortran are based largely -on the GNU CC compiler. -@xref{Contributors,,Contributors to GNU CC,gcc,Using and Porting GNU CC}, -for more information. - -@item -The run-time library used by GNU Fortran is a repackaged version -of the @code{libf2c} library (combined from the @code{libF77} and -@code{libI77} libraries) provided as part of @code{f2c}, available for -free from @code{netlib} sites on the Internet. - -@item -Cygnus Support and The Free Software Foundation contributed -significant money and/or equipment to Craig's efforts. - -@item -The following individuals served as alpha testers prior to @code{g77}'s -public release. This work consisted of testing, researching, sometimes -debugging, and occasionally providing small amounts of code and fixes -for @code{g77}, plus offering plenty of helpful advice to Craig: - -@itemize @w{} -@item -Jonathan Corbet -@item -Dr.@: Mark Fernyhough -@item -Takafumi Hayashi (The University of Aizu)---@email{takafumi@@u-aizu.ac.jp} -@item -Kate Hedstrom -@item -Michel Kern (INRIA and Rice University)---@email{Michel.Kern@@inria.fr} -@item -Dr.@: A. O. V. Le Blanc -@item -Dave Love -@item -Rick Lutowski -@item -Toon Moene -@item -Rick Niles -@item -Derk Reefman -@item -Wayne K. Schroll -@item -Bill Thorson -@item -Pedro A. M. Vazquez -@item -Ian Watson -@end itemize - -@item -Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) -provided the patch to add rudimentary support -for @code{INTEGER*1}, @code{INTEGER*2}, and -@code{LOGICAL*1}. -This inspired Craig to add further support, -even though the resulting support -would still be incomplete, because version 0.6 is still -a ways off. - -@item -David Ronis (@email{ronis@@onsager.chem.mcgill.ca}) inspired -and encouraged Craig to rewrite the documentation in texinfo -format by contributing a first pass at a translation of the -old @file{g77-0.5.16/f/DOC} file. - -@item -Toon Moene (@email{toon@@moene.indiv.nluug.nl}) performed -some analysis of generated code as part of an overall project -to improve @code{g77} code generation to at least be as good -as @code{f2c} used in conjunction with @code{gcc}. -So far, this has resulted in the three, somewhat -experimental, options added by @code{g77} to the @code{gcc} -compiler and its back end. - -(These, in turn, have made their way into the @code{egcs} -version of the compiler, and do not exist in @code{gcc} -version 2.8 or versions of @code{g77} based on that version -of @code{gcc}.) - -@item -John Carr (@email{jfc@@mit.edu}) wrote the alias analysis improvements. - -@item -Thanks to Mary Cortani and the staff at Craftwork Solutions -(@email{support@@craftwork.com}) for all of their support. - -@item -Many other individuals have helped debug, test, and improve @code{g77} -over the past several years, and undoubtedly more people -will be doing so in the future. -If you have done so, and would like -to see your name listed in the above list, please ask! -The default is that people wish to remain anonymous. -@end itemize - -@node Funding -@chapter Funding Free Software - -If you want to have more free software a few years from now, it makes -sense for you to help encourage people to contribute funds for its -development. The most effective approach known is to encourage -commercial redistributors to donate. - -Users of free software systems can boost the pace of development by -encouraging for-a-fee distributors to donate part of their selling price -to free software developers---the Free Software Foundation, and others. - -The way to convince distributors to do this is to demand it and expect -it from them. So when you compare distributors, judge them partly by -how much they give to free software development. Show distributors -they must compete to be the one who gives the most. - -To make this approach work, you must insist on numbers that you can -compare, such as, ``We will donate ten dollars to the Frobnitz project -for each disk sold.'' Don't be satisfied with a vague promise, such as -``A portion of the profits are donated,'' since it doesn't give a basis -for comparison. - -Even a precise fraction ``of the profits from this disk'' is not very -meaningful, since creative accounting and unrelated business decisions -can greatly alter what fraction of the sales price counts as profit. -If the price you pay is $50, ten percent of the profit is probably -less than a dollar; it might be a few cents, or nothing at all. - -Some redistributors do development work themselves. This is useful too; -but to keep everyone honest, you need to inquire how much they do, and -what kind. Some kinds of development make much more long-term -difference than others. For example, maintaining a separate version of -a program contributes very little; maintaining the standard version of a -program for the whole community contributes much. Easy new ports -contribute little, since someone else would surely do them; difficult -ports such as adding a new CPU to the GNU C compiler contribute more; -major new features or packages contribute the most. - -By establishing the idea that supporting further development is ``the -proper thing to do'' when distributing free software for a fee, we can -assure a steady flow of resources into making more free software. - -@display -Copyright (C) 1994 Free Software Foundation, Inc. -Verbatim copying and redistribution of this section is permitted -without royalty; alteration is not permitted. -@end display - -@node Funding GNU Fortran -@chapter Funding GNU Fortran -@cindex funding improvements -@cindex improvements, funding - -Work on GNU Fortran is still being done mostly by its author, -James Craig Burley (@email{burley@@gnu.org}), who is a volunteer -for, not an employee of, the Free Software Foundation (FSF). -As with other GNU software, funding is important because it can pay for -needed equipment, personnel, and so on. - -@cindex FSF, funding the -@cindex funding the FSF -The FSF provides information on the best way to fund ongoing -development of GNU software (such as GNU Fortran) in documents -such as the ``GNUS Bulletin''. -Email @email{gnu@@gnu.org} for information on funding the FSF. - -To fund specific GNU Fortran work in particular, the FSF might -provide a means for that, but the FSF does not provide direct funding -to the author of GNU Fortran to continue his work. The FSF has -employee salary restrictions that can be incompatible with the -financial needs of some volunteers, who therefore choose to -remain volunteers and thus be able to be free to do contract work -and otherwise make their own schedules for doing GNU work. - -Still, funding the FSF at least indirectly benefits work -on specific projects like GNU Fortran because it ensures the -continuing operation of the FSF offices, their workstations, their -network connections, and so on, which are invaluable to volunteers. -(Similarly, hiring Cygnus Support can help a project like GNU -Fortran---Cygnus has been a long-time donor of equipment usage to the author -of GNU Fortran, and this too has been invaluable---@xref{Contributors}.) - -Currently, the only way to directly fund the author of GNU Fortran -in his work on that project is to hire him for the work you want -him to do, or donate money to him. -Several people have done this -already, with the result that he has not needed to immediately find -contract work on a few occasions. -If more people did this, he -would be able to plan on not doing contract work for many months and -could thus devote that time to work on projects (such as the planned -changes for 0.6) that require longer timeframes to complete. -For the latest information on the status of the author, do -@kbd{finger -l burley@@gnu.org} on a UNIX system -(or any system with a command like UNIX @code{finger}). - -Another important way to support work on GNU Fortran is to volunteer -to help out. -Work is needed on documentation, testing, porting -to various machines, and in some cases, coding (although major -changes planned for version 0.6 make it difficult to add manpower to this -area). -Email @email{@value{email-general}} to volunteer for this work. - -@xref{Funding,,Funding Free Software}, for more information. - -@node Look and Feel -@chapter Protect Your Freedom---Fight ``Look And Feel'' -@c the above chapter heading overflows onto the next line. --mew 1/26/93 - -To preserve the ability to write free software, including replacements -for proprietary software, authors must be free to replicate the -user interface to which users of existing software have become -accustomed. - -@xref{Look and Feel,,Protect Your Freedom---Fight ``Look And Feel'', -gcc,Using and Porting GNU CC}, for more information. - -@node Getting Started -@chapter Getting Started -@cindex getting started -@cindex new users -@cindex newbies -@cindex beginners - -If you don't need help getting started reading the portions -of this manual that are most important to you, you should skip -this portion of the manual. - -If you are new to compilers, especially Fortran compilers, or -new to how compilers are structured under UNIX and UNIX-like -systems, you'll want to see @ref{What is GNU Fortran?}. - -If you are new to GNU compilers, or have used only one GNU -compiler in the past and not had to delve into how it lets -you manage various versions and configurations of @code{gcc}, -you should see @ref{G77 and GCC}. - -Everyone except experienced @code{g77} users should -see @ref{Invoking G77}. - -If you're acquainted with previous versions of @code{g77}, -you should see @ref{News}. -Further, if you've actually used previous versions of @code{g77}, -especially if you've written or modified Fortran code to -be compiled by previous versions of @code{g77}, you -should see @ref{Changes}. - -If you intend to write or otherwise compile code that is -not already strictly conforming ANSI FORTRAN 77---and this -is probably everyone---you should see @ref{Language}. - -If you don't already have @code{g77} installed on your -system, you must see @ref{Installation}. - -If you run into trouble getting Fortran code to compile, -link, run, or work properly, you might find answers -if you see @ref{Debugging and Interfacing}, -see @ref{Collected Fortran Wisdom}, -and see @ref{Trouble}. -You might also find that the problems you are encountering -are bugs in @code{g77}---see @ref{Bugs}, for information on -reporting them, after reading the other material. - -If you need further help with @code{g77}, or with -freely redistributable software in general, -see @ref{Service}. - -If you would like to help the @code{g77} project, -see @ref{Funding GNU Fortran}, for information on -helping financially, and see @ref{Projects}, for information -on helping in other ways. - -If you're generally curious about the future of -@code{g77}, see @ref{Projects}. -If you're curious about its past, -see @ref{Contributors}, -and see @ref{Funding GNU Fortran}. - -To see a few of the questions maintainers of @code{g77} have, -and that you might be able to answer, -see @ref{Open Questions}. - -@ifset USING -@node What is GNU Fortran? -@chapter What is GNU Fortran? -@cindex concepts, basic -@cindex basic concepts - -GNU Fortran, or @code{g77}, is designed initially as a free replacement -for, or alternative to, the UNIX @code{f77} command. -(Similarly, @code{gcc} is designed as a replacement -for the UNIX @code{cc} command.) - -@code{g77} also is designed to fit in well with the other -fine GNU compilers and tools. - -Sometimes these design goals conflict---in such cases, resolution -often is made in favor of fitting in well with Project GNU. -These cases are usually identified in the appropriate -sections of this manual. - -@cindex compilers -As compilers, @code{g77}, @code{gcc}, and @code{f77} -share the following characteristics: - -@itemize @bullet -@cindex source code -@cindex file, source -@cindex code, source -@cindex source file -@item -They read a user's program, stored in a file and -containing instructions written in the appropriate -language (Fortran, C, and so on). -This file contains @dfn{source code}. - -@cindex translation of user programs -@cindex machine code -@cindex code, machine -@cindex mistakes -@item -They translate the user's program into instructions -a computer can carry out more quickly than it takes -to translate the instructions in the first place. -These instructions are called @dfn{machine code}---code -designed to be efficiently translated and processed -by a machine such as a computer. -Humans usually aren't as good writing machine code -as they are at writing Fortran or C, because -it is easy to make tiny mistakes writing machine code. -When writing Fortran or C, it is easy -to make big mistakes. - -@cindex debugger -@cindex bugs, finding -@cindex gdb command -@cindex commands, gdb -@item -They provide information in the generated machine code -that can make it easier to find bugs in the program -(using a debugging tool, called a @dfn{debugger}, -such as @code{gdb}). - -@cindex libraries -@cindex linking -@cindex ld command -@cindex commands, ld -@item -They locate and gather machine code already generated -to perform actions requested by statements in -the user's program. -This machine code is organized -into @dfn{libraries} and is located and gathered -during the @dfn{link} phase of the compilation -process. -(Linking often is thought of as a separate -step, because it can be directly invoked via the -@code{ld} command. -However, the @code{g77} and @code{gcc} -commands, as with most compiler commands, automatically -perform the linking step by calling on @code{ld} -directly, unless asked to not do so by the user.) - -@cindex language, incorrect use of -@cindex incorrect use of language -@item -They attempt to diagnose cases where the user's -program contains incorrect usages of the language. -The @dfn{diagnostics} produced by the compiler -indicate the problem and the location in the user's -source file where the problem was first noticed. -The user can use this information to locate and -fix the problem. -@cindex diagnostics, incorrect -@cindex incorrect diagnostics -@cindex error messages, incorrect -@cindex incorrect error messages -(Sometimes an incorrect usage -of the language leads to a situation where the -compiler can no longer make any sense of what -follows---while a human might be able to---and -thus ends up complaining about many ``problems'' -it encounters that, in fact, stem from just one -problem, usually the first one reported.) - -@cindex warnings -@cindex questionable instructions -@item -They attempt to diagnose cases where the user's -program contains a correct usage of the language, -but instructs the computer to do something questionable. -These diagnostics often are in the form of @dfn{warnings}, -instead of the @dfn{errors} that indicate incorrect -usage of the language. -@end itemize - -How these actions are performed is generally under the -control of the user. -Using command-line options, the user can specify -how persnickety the compiler is to be regarding -the program (whether to diagnose questionable usage -of the language), how much time to spend making -the generated machine code run faster, and so on. - -@cindex components of g77 -@cindex g77, components of -@code{g77} consists of several components: - -@cindex gcc command -@cindex commands, gcc -@itemize @bullet -@item -A modified version of the @code{gcc} command, which also might be -installed as the system's @code{cc} command. -(In many cases, @code{cc} refers to the -system's ``native'' C compiler, which -might be a non-GNU compiler, or an older version -of @code{gcc} considered more stable or that is -used to build the operating system kernel.) - -@cindex g77 command -@cindex commands, g77 -@item -The @code{g77} command itself, which also might be installed as the -system's @code{f77} command. - -@cindex libg2c library -@cindex libf2c library -@cindex libraries, libf2c -@cindex libraries, libg2c -@cindex run-time library -@item -The @code{libg2c} run-time library. -This library contains the machine code needed to support -capabilities of the Fortran language that are not directly -provided by the machine code generated by the @code{g77} -compilation phase. - -@code{libg2c} is just the unique name @code{g77} gives -to its version of @code{libf2c} to distinguish it from -any copy of @code{libf2c} installed from @code{f2c} -(or versions of @code{g77} that built @code{libf2c} under -that same name) -on the system. - -The maintainer of @code{libf2c} currently is -@email{dmg@@bell-labs.com}. - -@cindex f771 program -@cindex programs, f771 -@cindex assembler -@cindex as command -@cindex commands, as -@cindex assembly code -@cindex code, assembly -@item -The compiler itself, internally named @code{f771}. - -Note that @code{f771} does not generate machine code directly---it -generates @dfn{assembly code} that is a more readable form -of machine code, leaving the conversion to actual machine code -to an @dfn{assembler}, usually named @code{as}. -@end itemize - -@code{gcc} is often thought of as ``the C compiler'' only, -but it does more than that. -Based on command-line options and the names given for files -on the command line, @code{gcc} determines which actions to perform, including -preprocessing, compiling (in a variety of possible languages), assembling, -and linking. - -@cindex driver, gcc command as -@cindex gcc command as driver -@cindex executable file -@cindex files, executable -@cindex cc1 program -@cindex programs, cc1 -@cindex preprocessor -@cindex cpp program -@cindex programs, cpp -For example, the command @samp{gcc foo.c} @dfn{drives} the file -@file{foo.c} through the preprocessor @code{cpp}, then -the C compiler (internally named -@code{cc1}), then the assembler (usually @code{as}), then the linker -(@code{ld}), producing an executable program named @file{a.out} (on -UNIX systems). - -@cindex cc1plus program -@cindex programs, cc1plus -As another example, the command @samp{gcc foo.cc} would do much the same as -@samp{gcc foo.c}, but instead of using the C compiler named @code{cc1}, -@code{gcc} would use the C++ compiler (named @code{cc1plus}). - -@cindex f771 program -@cindex programs, f771 -In a GNU Fortran installation, @code{gcc} recognizes Fortran source -files by name just like it does C and C++ source files. -It knows to use the Fortran compiler named @code{f771}, instead of -@code{cc1} or @code{cc1plus}, to compile Fortran files. - -@cindex gcc not recognizing Fortran source -@cindex unrecognized file format -@cindex file format not recognized -Non-Fortran-related operation of @code{gcc} is generally -unaffected by installing the GNU Fortran version of @code{gcc}. -However, without the installed version of @code{gcc} being the -GNU Fortran version, @code{gcc} will not be able to compile -and link Fortran programs---and since @code{g77} uses @code{gcc} -to do most of the actual work, neither will @code{g77}! - -@cindex g77 command -@cindex commands, g77 -The @code{g77} command is essentially just a front-end for -the @code{gcc} command. -Fortran users will normally use @code{g77} instead of @code{gcc}, -because @code{g77} -knows how to specify the libraries needed to link with Fortran programs -(@code{libg2c} and @code{lm}). -@code{g77} can still compile and link programs and -source files written in other languages, just like @code{gcc}. - -@cindex printing version information -@cindex version information, printing -The command @samp{g77 -v} is a quick -way to display lots of version information for the various programs -used to compile a typical preprocessed Fortran source file---this -produces much more output than @samp{gcc -v} currently does. -(If it produces an error message near the end of the output---diagnostics -from the linker, usually @code{ld}---you might -have an out-of-date @code{libf2c} that improperly handles -complex arithmetic.) -In the output of this command, the line beginning @samp{GNU Fortran Front -End} identifies the version number of GNU Fortran; immediately -preceding that line is a line identifying the version of @code{gcc} -with which that version of @code{g77} was built. - -@cindex libf2c library -@cindex libraries, libf2c -The @code{libf2c} library is distributed with GNU Fortran for -the convenience of its users, but is not part of GNU Fortran. -It contains the procedures -needed by Fortran programs while they are running. - -@cindex in-line code -@cindex code, in-line -For example, while code generated by @code{g77} is likely -to do additions, subtractions, and multiplications @dfn{in line}---in -the actual compiled code---it is not likely to do trigonometric -functions this way. - -Instead, operations like trigonometric -functions are compiled by the @code{f771} compiler -(invoked by @code{g77} when compiling Fortran code) into machine -code that, when run, calls on functions in @code{libg2c}, so -@code{libg2c} must be linked with almost every useful program -having any component compiled by GNU Fortran. -(As mentioned above, the @code{g77} command takes -care of all this for you.) - -The @code{f771} program represents most of what is unique to GNU Fortran. -While much of the @code{libg2c} component comes from -the @code{libf2c} component of @code{f2c}, -a free Fortran-to-C converter distributed by Bellcore (AT&T), -plus @code{libU77}, provided by Dave Love, -and the @code{g77} command is just a small front-end to @code{gcc}, -@code{f771} is a combination of two rather -large chunks of code. - -@cindex GNU Back End (GBE) -@cindex GBE -@cindex gcc back end -@cindex back end, gcc -@cindex code generator -One chunk is the so-called @dfn{GNU Back End}, or GBE, -which knows how to generate fast code for a wide variety of processors. -The same GBE is used by the C, C++, and Fortran compiler programs @code{cc1}, -@code{cc1plus}, and @code{f771}, plus others. -Often the GBE is referred to as the ``gcc back end'' or -even just ``gcc''---in this manual, the term GBE is used -whenever the distinction is important. - -@cindex GNU Fortran Front End (FFE) -@cindex FFE -@cindex g77 front end -@cindex front end, g77 -The other chunk of @code{f771} is the -majority of what is unique about GNU Fortran---the code that knows how -to interpret Fortran programs to determine what they are intending to -do, and then communicate that knowledge to the GBE for actual compilation -of those programs. -This chunk is called the @dfn{Fortran Front End} (FFE). -The @code{cc1} and @code{cc1plus} programs have their own front ends, -for the C and C++ languages, respectively. -These fronts ends are responsible for diagnosing -incorrect usage of their respective languages by the -programs the process, and are responsible for most of -the warnings about questionable constructs as well. -(The GBE handles producing some warnings, like those -concerning possible references to undefined variables.) - -Because so much is shared among the compilers for various languages, -much of the behavior and many of the user-selectable options for these -compilers are similar. -For example, diagnostics (error messages and -warnings) are similar in appearance; command-line -options like @samp{-Wall} have generally similar effects; and the quality -of generated code (in terms of speed and size) is roughly similar -(since that work is done by the shared GBE). - -@node G77 and GCC -@chapter Compile Fortran, C, or Other Programs -@cindex compiling programs -@cindex programs, compiling - -@cindex gcc command -@cindex commands, gcc -A GNU Fortran installation includes a modified version of the @code{gcc} -command. - -In a non-Fortran installation, @code{gcc} recognizes C, C++, -and Objective-C source files. - -In a GNU Fortran installation, @code{gcc} also recognizes Fortran source -files and accepts Fortran-specific command-line options, plus some -command-line options that are designed to cater to Fortran users -but apply to other languages as well. - -@xref{G++ and GCC,,Compile C; C++; or Objective-C,gcc,Using and Porting GNU CC}, -for information on the way different languages are handled -by the GNU CC compiler (@code{gcc}). - -@cindex g77 command -@cindex commands, g77 -Also provided as part of GNU Fortran is the @code{g77} command. -The @code{g77} command is designed to make compiling and linking Fortran -programs somewhat easier than when using the @code{gcc} command for -these tasks. -It does this by analyzing the command line somewhat and changing it -appropriately before submitting it to the @code{gcc} command. - -@cindex -v option -@cindex g77 options, -v -@cindex options, -v -Use the @samp{-v} option with @code{g77} -to see what is going on---the first line of output is the invocation -of the @code{gcc} command. - -@node Invoking G77 -@chapter GNU Fortran Command Options -@cindex GNU Fortran command options -@cindex command options -@cindex options, GNU Fortran command - -The @code{g77} command supports all the options supported by the -@code{gcc} command. -@xref{Invoking GCC,,GNU CC Command Options,gcc,Using and Porting GNU CC}, -for information -on the non-Fortran-specific aspects of the @code{gcc} command (and, -therefore, the @code{g77} command). - -@cindex options, negative forms -@cindex negative forms of options -All @code{gcc} and @code{g77} options -are accepted both by @code{g77} and by @code{gcc} -(as well as any other drivers built at the same time, -such as @code{g++}), -since adding @code{g77} to the @code{gcc} distribution -enables acceptance of @code{g77}-specific options -by all of the relevant drivers. - -In some cases, options have positive and negative forms; -the negative form of @samp{-ffoo} would be @samp{-fno-foo}. -This manual documents only one of these two forms, whichever -one is not the default. - -@menu -* Option Summary:: Brief list of all @code{g77} options, - without explanations. -* Overall Options:: Controlling the kind of output: - an executable, object files, assembler files, - or preprocessed source. -* Shorthand Options:: Options that are shorthand for other options. -* Fortran Dialect Options:: Controlling the variant of Fortran language - compiled. -* Warning Options:: How picky should the compiler be? -* Debugging Options:: Symbol tables, measurements, and debugging dumps. -* Optimize Options:: How much optimization? -* Preprocessor Options:: Controlling header files and macro definitions. - Also, getting dependency information for Make. -* Directory Options:: Where to find header files and libraries. - Where to find the compiler executable files. -* Code Gen Options:: Specifying conventions for function calls, data layout - and register usage. -* Environment Variables:: Env vars that affect GNU Fortran. -@end menu - -@node Option Summary -@section Option Summary - -Here is a summary of all the options specific to GNU Fortran, grouped -by type. Explanations are in the following sections. - -@table @emph -@item Overall Options -@xref{Overall Options,,Options Controlling the Kind of Output}. -@smallexample --fversion -fset-g77-defaults -fno-silent -@end smallexample - -@item Shorthand Options -@xref{Shorthand Options}. -@smallexample --ff66 -fno-f66 -ff77 -fno-f77 -fugly -fno-ugly -@end smallexample - -@item Fortran Language Options -@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}. -@smallexample --ffree-form -fno-fixed-form -ff90 --fvxt -fdollar-ok -fno-backslash --fno-ugly-args -fno-ugly-assign -fno-ugly-assumed --fugly-comma -fugly-complex -fugly-init -fugly-logint --fonetrip -ftypeless-boz --fintrin-case-initcap -fintrin-case-upper --fintrin-case-lower -fintrin-case-any --fmatch-case-initcap -fmatch-case-upper --fmatch-case-lower -fmatch-case-any --fsource-case-upper -fsource-case-lower -fsource-case-preserve --fsymbol-case-initcap -fsymbol-case-upper --fsymbol-case-lower -fsymbol-case-any --fcase-strict-upper -fcase-strict-lower --fcase-initcap -fcase-upper -fcase-lower -fcase-preserve --ff2c-intrinsics-delete -ff2c-intrinsics-hide --ff2c-intrinsics-disable -ff2c-intrinsics-enable --fbadu77-intrinsics-delete -fbadu77-intrinsics-hide --fbadu77-intrinsics-disable -fbadu77-intrinsics-enable --ff90-intrinsics-delete -ff90-intrinsics-hide --ff90-intrinsics-disable -ff90-intrinsics-enable --fgnu-intrinsics-delete -fgnu-intrinsics-hide --fgnu-intrinsics-disable -fgnu-intrinsics-enable --fmil-intrinsics-delete -fmil-intrinsics-hide --fmil-intrinsics-disable -fmil-intrinsics-enable --funix-intrinsics-delete -funix-intrinsics-hide --funix-intrinsics-disable -funix-intrinsics-enable --fvxt-intrinsics-delete -fvxt-intrinsics-hide --fvxt-intrinsics-disable -fvxt-intrinsics-enable --ffixed-line-length-@var{n} -ffixed-line-length-none -@end smallexample - -@item Warning Options -@xref{Warning Options,,Options to Request or Suppress Warnings}. -@smallexample --fsyntax-only -pedantic -pedantic-errors -fpedantic --w -Wno-globals -Wimplicit -Wunused -Wuninitialized --Wall -Wsurprising --Werror -W -@end smallexample - -@item Debugging Options -@xref{Debugging Options,,Options for Debugging Your Program or GCC}. -@smallexample --g -@end smallexample - -@item Optimization Options -@xref{Optimize Options,,Options that Control Optimization}. -@smallexample --malign-double --ffloat-store -fforce-mem -fforce-addr -fno-inline --ffast-math -fstrength-reduce -frerun-cse-after-loop --fexpensive-optimizations -fdelayed-branch --fschedule-insns -fschedule-insn2 -fcaller-saves --funroll-loops -funroll-all-loops --fno-move-all-movables -fno-reduce-all-givs --fno-rerun-loop-opt -@end smallexample - -@item Directory Options -@xref{Directory Options,,Options for Directory Search}. -@smallexample --I@var{dir} -I- -@end smallexample - -@item Code Generation Options -@xref{Code Gen Options,,Options for Code Generation Conventions}. -@smallexample --fno-automatic -finit-local-zero -fno-f2c --ff2c-library -fno-underscoring -fno-ident --fpcc-struct-return -freg-struct-return --fshort-double -fno-common -fpack-struct --fzeros -fno-second-underscore --fdebug-kludge -fno-emulate-complex --falias-check -fargument-alias --fargument-noalias -fno-argument-noalias-global --fno-globals -@end smallexample -@end table - -@menu -* Overall Options:: Controlling the kind of output: - an executable, object files, assembler files, - or preprocessed source. -* Shorthand Options:: Options that are shorthand for other options. -* Fortran Dialect Options:: Controlling the variant of Fortran language - compiled. -* Warning Options:: How picky should the compiler be? -* Debugging Options:: Symbol tables, measurements, and debugging dumps. -* Optimize Options:: How much optimization? -* Preprocessor Options:: Controlling header files and macro definitions. - Also, getting dependency information for Make. -* Directory Options:: Where to find header files and libraries. - Where to find the compiler executable files. -* Code Gen Options:: Specifying conventions for function calls, data layout - and register usage. -@end menu - -@node Overall Options -@section Options Controlling the Kind of Output -@cindex overall options -@cindex options, overall - -Compilation can involve as many as four stages: preprocessing, code -generation (often what is really meant by the term ``compilation''), -assembly, and linking, always in that order. The first three -stages apply to an individual source file, and end by producing an -object file; linking combines all the object files (those newly -compiled, and those specified as input) into an executable file. - -@cindex file name suffix -@cindex suffixes, file name -@cindex file name extension -@cindex extensions, file name -@cindex file type -@cindex types, file -For any given input file, the file name suffix determines what kind of -program is contained in the file---that is, the language in which the -program is written is generally indicated by the suffix. -Suffixes specific to GNU Fortran are listed below. -@xref{Overall Options,,gcc,Using and Porting GNU CC}, for -information on suffixes recognized by GNU CC. - -@table @code -@item @var{file}.f -@item @var{file}.for -Fortran source code that should not be preprocessed. - -Such source code cannot contain any preprocessor directives, such -as @code{#include}, @code{#define}, @code{#if}, and so on. - -You can force @samp{.f} files to be preprocessed by @samp{cpp} by using -@samp{-x f77-cpp-input}, @ref{LEX}. - -@cindex preprocessor -@cindex C preprocessor -@cindex cpp preprocessor -@cindex Fortran preprocessor -@cindex cpp program -@cindex programs, cpp -@cindex .F filename suffix -@cindex .fpp filename suffix -@item @var{file}.F -@item @var{file}.fpp -Fortran source code that must be preprocessed (by the C preprocessor -@code{cpp}, which is part of GNU CC). - -Note that preprocessing is not extended to the contents of -files included by the @code{INCLUDE} directive---the @code{#include} -preprocessor directive must be used instead. - -@cindex Ratfor preprocessor -@cindex programs, ratfor -@cindex .r filename suffix -@pindex ratfor -@item @var{file}.r -Ratfor source code, which must be preprocessed by the @code{ratfor} -command, which is available separately (as it is not yet part of the GNU -Fortran distribution). -One version in Fortran, adapted for use with @code{g77}, is at -@uref{ftp://members.aol.com/n8tm/rat7.uue} (of uncertain copyright -status). Another, public domain version in C is at -@uref{http://sepwww.stanford.edu/sep/prof/ratfor.shar.2}. -@end table - -UNIX users typically use the @file{@var{file}.f} and @file{@var{file}.F} -nomenclature. -Users of other operating systems, especially those that cannot -distinguish upper-case -letters from lower-case letters in their file names, typically use -the @file{@var{file}.for} and @file{@var{file}.fpp} nomenclature. - -@cindex #define -@cindex #include -@cindex #if -Use of the preprocessor @code{cpp} allows use of C-like -constructs such as @code{#define} and @code{#include}, but can -lead to unexpected, even mistaken, results due to Fortran's source file -format. -It is recommended that use of the C preprocessor -be limited to @code{#include} and, in -conjunction with @code{#define}, only @code{#if} and related directives, -thus avoiding in-line macro expansion entirely. -This recommendation applies especially -when using the traditional fixed source form. -With free source form, -fewer unexpected transformations are likely to happen, but use of -constructs such as Hollerith and character constants can nevertheless -present problems, especially when these are continued across multiple -source lines. -These problems result, primarily, from differences between the way -such constants are interpreted by the C preprocessor and by a Fortran -compiler. - -Another example of a problem that results from using the C preprocessor -is that a Fortran comment line that happens to contain any -characters ``interesting'' to the C preprocessor, -such as a backslash at the end of the line, -is not recognized by the preprocessor as a comment line, -so instead of being passed through ``raw'', -the line is edited according to the rules for the preprocessor. -For example, the backslash at the end of the line is removed, -along with the subsequent newline, resulting in the next -line being effectively commented out---unfortunate if that -line is a non-comment line of important code! - -@emph{Note:} The @samp{-traditional} and @samp{-undef} flags are supplied -to @code{cpp} by default, to help avoid unpleasant surprises. -@xref{Preprocessor Options,,Options Controlling the Preprocessor, -gcc,Using and Porting GNU CC}. -This means that ANSI C preprocessor features (such as the @samp{#} -operator) aren't available, and only variables in the C reserved -namespace (generally, names with a leading underscore) are liable to -substitution by C predefines. -Thus, if you want to do system-specific -tests, use, for example, @samp{#ifdef __linux__} rather than @samp{#ifdef linux}. -Use the @samp{-v} option to see exactly how the preprocessor is invoked. - -@cindex /* -Unfortunately, the @samp{-traditional} flag will not avoid an error from -anything that @code{cpp} sees as an unterminated C comment, such as: -@smallexample -C Some Fortran compilers accept /* as starting -C an inline comment. -@end smallexample -@xref{Trailing Comment}. - -The following options that affect overall processing are recognized -by the @code{g77} and @code{gcc} commands in a GNU Fortran installation: - -@table @code -@cindex -fversion option -@cindex options, -fversion -@cindex printing version information -@cindex version information, printing -@item -fversion -Ensure that the @code{g77}-specific version of the compiler phase is reported, -if run. -(This is supplied automatically when @samp{-v} or @samp{--verbose} -is specified as a command-line option for @code{g77} or @code{gcc} -and when the resulting commands compile Fortran source files.) - -@cindex -fset-g77-defaults option -@cindex options, -fset-g77-defaults -@item -fset-g77-defaults -@emph{Version info:} -This option is obsolete in @code{egcs} -as of version 1.1. - -Set up whatever @code{gcc} options are to apply to Fortran -compilations, and avoid running internal consistency checks -that might take some time. - -This option is supplied automatically when compiling Fortran code -via the @code{g77} or @code{gcc} command. -The description of this option is provided so that users seeing -it in the output of, say, @samp{g77 -v} understand why it is -there. - -@cindex modifying g77 -@cindex code, modifying -Also, developers who run @code{f771} directly might want to specify it -by hand to get the same defaults as they would running @code{f771} -via @code{g77} or @code{gcc}. -However, such developers should, after linking a new @code{f771} -executable, invoke it without this option once, -e.g. via @kbd{./f771 -quiet < /dev/null}, -to ensure that they have not introduced any -internal inconsistencies (such as in the table of -intrinsics) before proceeding---@code{g77} will crash -with a diagnostic if it detects an inconsistency. - -@cindex -fno-silent option -@cindex options, -fno-silent -@cindex @code{f2c} compatibility -@cindex compatibility, @code{f2c} -@cindex status, compilation -@cindex compilation status -@cindex reporting compilation status -@cindex printing compilation status -@item -fno-silent -Print (to @code{stderr}) the names of the program units as -they are compiled, in a form similar to that used by popular -UNIX @code{f77} implementations and @code{f2c}. -@end table - -@xref{Overall Options,,Options Controlling the Kind of Output, -gcc,Using and Porting GNU CC}, for information -on more options that control the overall operation of the @code{gcc} command -(and, by extension, the @code{g77} command). - -@node Shorthand Options -@section Shorthand Options -@cindex shorthand options -@cindex options, shorthand -@cindex macro options -@cindex options, macro - -The following options serve as ``shorthand'' -for other options accepted by the compiler: - -@table @code -@cindex -fugly option -@cindex options, -fugly -@item -fugly -@cindex ugly features -@cindex features, ugly -Specify that certain ``ugly'' constructs are to be quietly accepted. -Same as: - -@smallexample --fugly-args -fugly-assign -fugly-assumed --fugly-comma -fugly-complex -fugly-init --fugly-logint -@end smallexample - -These constructs are considered inappropriate to use in new -or well-maintained portable Fortran code, but widely used -in old code. -@xref{Distensions}, for more information. - -@emph{Note:} The @samp{-fugly} option is likely to -be removed in a future version. -Implicitly enabling all the @samp{-fugly-*} options -is unlikely to be feasible, or sensible, in the future, -so users should learn to specify only those -@samp{-fugly-*} options they really need for a -particular source file. - -@cindex -fno-ugly option -@cindex options, -fno-ugly -@item -fno-ugly -@cindex ugly features -@cindex features, ugly -Specify that all ``ugly'' constructs are to be noisily rejected. -Same as: - -@smallexample --fno-ugly-args -fno-ugly-assign -fno-ugly-assumed --fno-ugly-comma -fno-ugly-complex -fno-ugly-init --fno-ugly-logint -@end smallexample - -@xref{Distensions}, for more information. - -@cindex -ff66 option -@cindex options, -ff66 -@item -ff66 -@cindex FORTRAN 66 -@cindex compatibility, FORTRAN 66 -Specify that the program is written in idiomatic FORTRAN 66. -Same as @samp{-fonetrip -fugly-assumed}. - -The @samp{-fno-f66} option is the inverse of @samp{-ff66}. -As such, it is the same as @samp{-fno-onetrip -fno-ugly-assumed}. - -The meaning of this option is likely to be refined as future -versions of @code{g77} provide more compatibility with other -existing and obsolete Fortran implementations. - -@cindex -ff77 option -@cindex options, -ff77 -@item -ff77 -@cindex UNIX f77 -@cindex @code{f2c} compatibility -@cindex compatibility, @code{f2c} -@cindex @code{f77} compatibility -@cindex compatibility, @code{f77} -Specify that the program is written in idiomatic UNIX FORTRAN 77 -and/or the dialect accepted by the @code{f2c} product. -Same as @samp{-fbackslash -fno-typeless-boz}. - -The meaning of this option is likely to be refined as future -versions of @code{g77} provide more compatibility with other -existing and obsolete Fortran implementations. - -@cindex -fno-f77 option -@cindex options, -fno-f77 -@item -fno-f77 -@cindex UNIX f77 -The @samp{-fno-f77} option is @emph{not} the inverse -of @samp{-ff77}. -It specifies that the program is not written in idiomatic UNIX -FORTRAN 77 or @code{f2c}, but in a more widely portable dialect. -@samp{-fno-f77} is the same as @samp{-fno-backslash}. - -The meaning of this option is likely to be refined as future -versions of @code{g77} provide more compatibility with other -existing and obsolete Fortran implementations. -@end table - -@node Fortran Dialect Options -@section Options Controlling Fortran Dialect -@cindex dialect options -@cindex language dialect options -@cindex options, dialect - -The following options control the dialect of Fortran -that the compiler accepts: - -@table @code -@cindex -ffree-form option -@cindex options, -ffree-form -@cindex -fno-fixed-form option -@cindex options, -fno-fixed-form -@cindex source file form -@cindex free form -@cindex fixed form -@cindex Fortran 90 features -@item -ffree-form -@item -fno-fixed-form -Specify that the source file is written in free form -(introduced in Fortran 90) instead of the more-traditional fixed form. - -@cindex -ff90 option -@cindex options, -ff90 -@cindex Fortran 90 features -@item -ff90 -Allow certain Fortran-90 constructs. - -This option controls whether certain -Fortran 90 constructs are recognized. -(Other Fortran 90 constructs -might or might not be recognized depending on other options such as -@samp{-fvxt}, @samp{-ff90-intrinsics-enable}, and the -current level of support for Fortran 90.) - -@xref{Fortran 90}, for more information. - -@cindex -fvxt option -@cindex options, -fvxt -@item -fvxt -@cindex Fortran 90 features -@cindex VXT features -Specify the treatment of certain constructs that have different -meanings depending on whether the code is written in -GNU Fortran (based on FORTRAN 77 and akin to Fortran 90) -or VXT Fortran (more like VAX FORTRAN). - -The default is @samp{-fno-vxt}. -@samp{-fvxt} specifies that the VXT Fortran interpretations -for those constructs are to be chosen. - -@xref{VXT Fortran}, for more information. - -@cindex -fdollar-ok option -@cindex options, -fdollar-ok -@item -fdollar-ok -@cindex dollar sign -@cindex symbol names -@cindex character set -Allow @samp{$} as a valid character in a symbol name. - -@cindex -fno-backslash option -@cindex options, -fno-backslash -@item -fno-backslash -@cindex backslash -@cindex character constants -@cindex Hollerith constants -Specify that @samp{\} is not to be specially interpreted in character -and Hollerith constants a la C and many UNIX Fortran compilers. - -For example, with @samp{-fbackslash} in effect, @samp{A\nB} specifies -three characters, with the second one being newline. -With @samp{-fno-backslash}, it specifies four characters, -@samp{A}, @samp{\}, @samp{n}, and @samp{B}. - -Note that @code{g77} implements a fairly general form of backslash -processing that is incompatible with the narrower forms supported -by some other compilers. -For example, @samp{'A\003B'} is a three-character string in @code{g77}, -whereas other compilers that support backslash might not support -the three-octal-digit form, and thus treat that string as longer -than three characters. - -@xref{Backslash in Constants}, for -information on why @samp{-fbackslash} is the default -instead of @samp{-fno-backslash}. - -@cindex -fno-ugly-args option -@cindex options, -fno-ugly-args -@item -fno-ugly-args -Disallow passing Hollerith and typeless constants as actual -arguments (for example, @samp{CALL FOO(4HABCD)}). - -@xref{Ugly Implicit Argument Conversion}, for more information. - -@cindex -fugly-assign option -@cindex options, -fugly-assign -@item -fugly-assign -Use the same storage for a given variable regardless of -whether it is used to hold an assigned-statement label -(as in @samp{ASSIGN 10 TO I}) or used to hold numeric data -(as in @samp{I = 3}). - -@xref{Ugly Assigned Labels}, for more information. - -@cindex -fugly-assumed option -@cindex options, -fugly-assumed -@item -fugly-assumed -Assume any dummy array with a final dimension specified as @samp{1} -is really an assumed-size array, as if @samp{*} had been specified -for the final dimension instead of @samp{1}. - -For example, @samp{DIMENSION X(1)} is treated as if it -had read @samp{DIMENSION X(*)}. - -@xref{Ugly Assumed-Size Arrays}, for more information. - -@cindex -fugly-comma option -@cindex options, -fugly-comma -@item -fugly-comma -In an external-procedure invocation, -treat a trailing comma in the argument list -as specification of a trailing null argument, -and treat an empty argument list -as specification of a single null argument. - -For example, @samp{CALL FOO(,)} is treated as -@samp{CALL FOO(%VAL(0), %VAL(0))}. -That is, @emph{two} null arguments are specified -by the procedure call when @samp{-fugly-comma} is in force. -And @samp{F = FUNC()} is treated as @samp{F = FUNC(%VAL(0))}. - -The default behavior, @samp{-fno-ugly-comma}, is to ignore -a single trailing comma in an argument list. -So, by default, @samp{CALL FOO(X,)} is treated -exactly the same as @samp{CALL FOO(X)}. - -@xref{Ugly Null Arguments}, for more information. - -@cindex -fugly-complex option -@cindex options, -fugly-complex -@item -fugly-complex -Do not complain about @samp{REAL(@var{expr})} or -@samp{AIMAG(@var{expr})} when @var{expr} is a @code{COMPLEX} -type other than @code{COMPLEX(KIND=1)}---usually -this is used to permit @code{COMPLEX(KIND=2)} -(@code{DOUBLE COMPLEX}) operands. - -The @samp{-ff90} option controls the interpretation -of this construct. - -@xref{Ugly Complex Part Extraction}, for more information. - -@cindex -fno-ugly-init option -@cindex options, -fno-ugly-init -@item -fno-ugly-init -Disallow use of Hollerith and typeless constants as initial -values (in @code{PARAMETER} and @code{DATA} statements), and -use of character constants to -initialize numeric types and vice versa. - -For example, @samp{DATA I/'F'/, CHRVAR/65/, J/4HABCD/} is disallowed by -@samp{-fno-ugly-init}. - -@xref{Ugly Conversion of Initializers}, for more information. - -@cindex -fugly-logint option -@cindex options, -fugly-logint -@item -fugly-logint -Treat @code{INTEGER} and @code{LOGICAL} variables and -expressions as potential stand-ins for each other. - -For example, automatic conversion between @code{INTEGER} and -@code{LOGICAL} is enabled, for many contexts, via this option. - -@xref{Ugly Integer Conversions}, for more information. - -@cindex -fonetrip option -@cindex options, -fonetrip -@item -fonetrip -@cindex FORTRAN 66 -@cindex DO loops, one-trip -@cindex one-trip DO loops -@cindex compatibility, FORTRAN 66 -Imperative executable @code{DO} loops are to be executed at -least once each time they are reached. - -ANSI FORTRAN 77 and more recent versions of the Fortran standard -specify that the body of an imperative @code{DO} loop is not executed -if the number of iterations calculated from the parameters of the -loop is less than 1. -(For example, @samp{DO 10 I = 1, 0}.) -Such a loop is called a @dfn{zero-trip loop}. - -Prior to ANSI FORTRAN 77, many compilers implemented @code{DO} loops -such that the body of a loop would be executed at least once, even -if the iteration count was zero. -Fortran code written assuming this behavior is said to require -@dfn{one-trip loops}. -For example, some code written to the FORTRAN 66 standard -expects this behavior from its @code{DO} loops, although that -standard did not specify this behavior. - -The @samp{-fonetrip} option specifies that the source file(s) being -compiled require one-trip loops. - -This option affects only those loops specified by the (imperative) @code{DO} -statement and by implied-@code{DO} lists in I/O statements. -Loops specified by implied-@code{DO} lists in @code{DATA} and -specification (non-executable) statements are not affected. - -@cindex -ftypeless-boz option -@cindex options, -ftypeless-boz -@cindex prefix-radix constants -@cindex constants, prefix-radix -@cindex constants, types -@cindex types, constants -@item -ftypeless-boz -Specifies that prefix-radix non-decimal constants, such as -@samp{Z'ABCD'}, are typeless instead of @code{INTEGER(KIND=1)}. - -You can test for yourself whether a particular compiler treats -the prefix form as @code{INTEGER(KIND=1)} or typeless by running the -following program: - -@smallexample -EQUIVALENCE (I, R) -R = Z'ABCD1234' -J = Z'ABCD1234' -IF (J .EQ. I) PRINT *, 'Prefix form is TYPELESS' -IF (J .NE. I) PRINT *, 'Prefix form is INTEGER' -END -@end smallexample - -Reports indicate that many compilers process this form as -@code{INTEGER(KIND=1)}, though a few as typeless, and at least one -based on a command-line option specifying some kind of -compatibility. - -@cindex -fintrin-case-initcap option -@cindex options, -fintrin-case-initcap -@item -fintrin-case-initcap -@cindex -fintrin-case-upper option -@cindex options, -fintrin-case-upper -@item -fintrin-case-upper -@cindex -fintrin-case-lower option -@cindex options, -fintrin-case-lower -@item -fintrin-case-lower -@cindex -fintrin-case-any option -@cindex options, -fintrin-case-any -@item -fintrin-case-any -Specify expected case for intrinsic names. -@samp{-fintrin-case-lower} is the default. - -@cindex -fmatch-case-initcap option -@cindex options, -fmatch-case-initcap -@item -fmatch-case-initcap -@cindex -fmatch-case-upper option -@cindex options, -fmatch-case-upper -@item -fmatch-case-upper -@cindex -fmatch-case-lower option -@cindex options, -fmatch-case-lower -@item -fmatch-case-lower -@cindex -fmatch-case-any option -@cindex options, -fmatch-case-any -@item -fmatch-case-any -Specify expected case for keywords. -@samp{-fmatch-case-lower} is the default. - -@cindex -fsource-case-upper option -@cindex options, -fsource-case-upper -@item -fsource-case-upper -@cindex -fsource-case-lower option -@cindex options, -fsource-case-lower -@item -fsource-case-lower -@cindex -fsource-case-preserve option -@cindex options, -fsource-case-preserve -@item -fsource-case-preserve -Specify whether source text other than character and Hollerith constants -is to be translated to uppercase, to lowercase, or preserved as is. -@samp{-fsource-case-lower} is the default. - -@cindex -fsymbol-case-initcap option -@cindex options, -fsymbol-case-initcap -@item -fsymbol-case-initcap -@cindex -fsymbol-case-upper option -@cindex options, -fsymbol-case-upper -@item -fsymbol-case-upper -@cindex -fsymbol-case-lower option -@cindex options, -fsymbol-case-lower -@item -fsymbol-case-lower -@cindex -fsymbol-case-any option -@cindex options, -fsymbol-case-any -@item -fsymbol-case-any -Specify valid cases for user-defined symbol names. -@samp{-fsymbol-case-any} is the default. - -@cindex -fcase-strict-upper option -@cindex options, -fcase-strict-upper -@item -fcase-strict-upper -Same as @samp{-fintrin-case-upper -fmatch-case-upper -fsource-case-preserve --fsymbol-case-upper}. -(Requires all pertinent source to be in uppercase.) - -@cindex -fcase-strict-lower option -@cindex options, -fcase-strict-lower -@item -fcase-strict-lower -Same as @samp{-fintrin-case-lower -fmatch-case-lower -fsource-case-preserve --fsymbol-case-lower}. -(Requires all pertinent source to be in lowercase.) - -@cindex -fcase-initcap option -@cindex options, -fcase-initcap -@item -fcase-initcap -Same as @samp{-fintrin-case-initcap -fmatch-case-initcap -fsource-case-preserve --fsymbol-case-initcap}. -(Requires all pertinent source to be in initial capitals, -as in @samp{Print *,SqRt(Value)}.) - -@cindex -fcase-upper option -@cindex options, -fcase-upper -@item -fcase-upper -Same as @samp{-fintrin-case-any -fmatch-case-any -fsource-case-upper --fsymbol-case-any}. -(Maps all pertinent source to uppercase.) - -@cindex -fcase-lower option -@cindex options, -fcase-lower -@item -fcase-lower -Same as @samp{-fintrin-case-any -fmatch-case-any -fsource-case-lower --fsymbol-case-any}. -(Maps all pertinent source to lowercase.) - -@cindex -fcase-preserve option -@cindex options, -fcase-preserve -@item -fcase-preserve -Same as @samp{-fintrin-case-any -fmatch-case-any -fsource-case-preserve --fsymbol-case-any}. -(Preserves all case in user-defined symbols, -while allowing any-case matching of intrinsics and keywords. -For example, @samp{call Foo(i,I)} would pass two @emph{different} -variables named @samp{i} and @samp{I} to a procedure named @samp{Foo}.) - -@cindex -fbadu77-intrinsics-delete option -@cindex options, -fbadu77-intrinsics-delete -@item -fbadu77-intrinsics-delete -@cindex -fbadu77-intrinsics-hide option -@cindex options, -fbadu77-intrinsics-hide -@item -fbadu77-intrinsics-hide -@cindex -fbadu77-intrinsics-disable option -@cindex options, -fbadu77-intrinsics-disable -@item -fbadu77-intrinsics-disable -@cindex -fbadu77-intrinsics-enable option -@cindex options, -fbadu77-intrinsics-enable -@item -fbadu77-intrinsics-enable -@cindex badu77 intrinsics -@cindex intrinsics, badu77 -Specify status of UNIX intrinsics having inappropriate forms. -@samp{-fbadu77-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -ff2c-intrinsics-delete option -@cindex options, -ff2c-intrinsics-delete -@item -ff2c-intrinsics-delete -@cindex -ff2c-intrinsics-hide option -@cindex options, -ff2c-intrinsics-hide -@item -ff2c-intrinsics-hide -@cindex -ff2c-intrinsics-disable option -@cindex options, -ff2c-intrinsics-disable -@item -ff2c-intrinsics-disable -@cindex -ff2c-intrinsics-enable option -@cindex options, -ff2c-intrinsics-enable -@item -ff2c-intrinsics-enable -@cindex f2c intrinsics -@cindex intrinsics, f2c -Specify status of f2c-specific intrinsics. -@samp{-ff2c-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -ff90-intrinsics-delete option -@cindex options, -ff90-intrinsics-delete -@item -ff90-intrinsics-delete -@cindex -ff90-intrinsics-hide option -@cindex options, -ff90-intrinsics-hide -@item -ff90-intrinsics-hide -@cindex -ff90-intrinsics-disable option -@cindex options, -ff90-intrinsics-disable -@item -ff90-intrinsics-disable -@cindex -ff90-intrinsics-enable option -@cindex options, -ff90-intrinsics-enable -@item -ff90-intrinsics-enable -@cindex Fortran 90 intrinsics -@cindex intrinsics, Fortran 90 -Specify status of F90-specific intrinsics. -@samp{-ff90-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -fgnu-intrinsics-delete option -@cindex options, -fgnu-intrinsics-delete -@item -fgnu-intrinsics-delete -@cindex -fgnu-intrinsics-hide option -@cindex options, -fgnu-intrinsics-hide -@item -fgnu-intrinsics-hide -@cindex -fgnu-intrinsics-disable option -@cindex options, -fgnu-intrinsics-disable -@item -fgnu-intrinsics-disable -@cindex -fgnu-intrinsics-enable option -@cindex options, -fgnu-intrinsics-enable -@item -fgnu-intrinsics-enable -@cindex Digital Fortran features -@cindex COMPLEX intrinsics -@cindex intrinsics, COMPLEX -Specify status of Digital's COMPLEX-related intrinsics. -@samp{-fgnu-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -fmil-intrinsics-delete option -@cindex options, -fmil-intrinsics-delete -@item -fmil-intrinsics-delete -@cindex -fmil-intrinsics-hide option -@cindex options, -fmil-intrinsics-hide -@item -fmil-intrinsics-hide -@cindex -fmil-intrinsics-disable option -@cindex options, -fmil-intrinsics-disable -@item -fmil-intrinsics-disable -@cindex -fmil-intrinsics-enable option -@cindex options, -fmil-intrinsics-enable -@item -fmil-intrinsics-enable -@cindex MIL-STD 1753 -@cindex intrinsics, MIL-STD 1753 -Specify status of MIL-STD-1753-specific intrinsics. -@samp{-fmil-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -funix-intrinsics-delete option -@cindex options, -funix-intrinsics-delete -@item -funix-intrinsics-delete -@cindex -funix-intrinsics-hide option -@cindex options, -funix-intrinsics-hide -@item -funix-intrinsics-hide -@cindex -funix-intrinsics-disable option -@cindex options, -funix-intrinsics-disable -@item -funix-intrinsics-disable -@cindex -funix-intrinsics-enable option -@cindex options, -funix-intrinsics-enable -@item -funix-intrinsics-enable -@cindex UNIX intrinsics -@cindex intrinsics, UNIX -Specify status of UNIX intrinsics. -@samp{-funix-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -fvxt-intrinsics-delete option -@cindex options, -fvxt-intrinsics-delete -@item -fvxt-intrinsics-delete -@cindex -fvxt-intrinsics-hide option -@cindex options, -fvxt-intrinsics-hide -@item -fvxt-intrinsics-hide -@cindex -fvxt-intrinsics-disable option -@cindex options, -fvxt-intrinsics-disable -@item -fvxt-intrinsics-disable -@cindex -fvxt-intrinsics-enable option -@cindex options, -fvxt-intrinsics-enable -@item -fvxt-intrinsics-enable -@cindex VXT intrinsics -@cindex intrinsics, VXT -Specify status of VXT intrinsics. -@samp{-fvxt-intrinsics-enable} is the default. -@xref{Intrinsic Groups}. - -@cindex -ffixed-line-length-@var{n} option -@cindex options, -ffixed-line-length-@var{n} -@item -ffixed-line-length-@var{n} -@cindex source file format -@cindex line length -@cindex length of source lines -@cindex fixed-form line length -Set column after which characters are ignored in typical fixed-form -lines in the source file, and through which spaces are assumed (as -if padded to that length) after the ends of short fixed-form lines. - -@cindex card image -@cindex extended-source option -Popular values for @var{n} include 72 (the -standard and the default), 80 (card image), and 132 (corresponds -to ``extended-source'' options in some popular compilers). -@var{n} may be @samp{none}, meaning that the entire line is meaningful -and that continued character constants never have implicit spaces appended -to them to fill out the line. -@samp{-ffixed-line-length-0} means the same thing as -@samp{-ffixed-line-length-none}. - -@xref{Source Form}, for more information. -@end table - -@node Warning Options -@section Options to Request or Suppress Warnings -@cindex options to control warnings -@cindex warning messages -@cindex messages, warning -@cindex suppressing warnings - -Warnings are diagnostic messages that report constructions which -are not inherently erroneous but which are risky or suggest there -might have been an error. - -You can request many specific warnings with options beginning @samp{-W}, -for example @samp{-Wimplicit} to request warnings on implicit -declarations. Each of these specific warning options also has a -negative form beginning @samp{-Wno-} to turn off warnings; -for example, @samp{-Wno-implicit}. This manual lists only one of the -two forms, whichever is not the default. - -These options control the amount and kinds of warnings produced by GNU -Fortran: - -@table @code -@cindex syntax checking -@cindex -fsyntax-only option -@cindex options, -fsyntax-only -@item -fsyntax-only -Check the code for syntax errors, but don't do anything beyond that. - -@cindex -pedantic option -@cindex options, -pedantic -@item -pedantic -Issue warnings for uses of extensions to ANSI FORTRAN 77. -@samp{-pedantic} also applies to C-language constructs where they -occur in GNU Fortran source files, such as use of @samp{\e} in a -character constant within a directive like @samp{#include}. - -Valid ANSI FORTRAN 77 programs should compile properly with or without -this option. -However, without this option, certain GNU extensions and traditional -Fortran features are supported as well. -With this option, many of them are rejected. - -Some users try to use @samp{-pedantic} to check programs for strict ANSI -conformance. -They soon find that it does not do quite what they want---it finds some -non-ANSI practices, but not all. -However, improvements to @code{g77} in this area are welcome. - -@cindex -pedantic-errors option -@cindex options, -pedantic-errors -@item -pedantic-errors -Like @samp{-pedantic}, except that errors are produced rather than -warnings. - -@cindex -fpedantic option -@cindex options, -fpedantic -@item -fpedantic -Like @samp{-pedantic}, but applies only to Fortran constructs. - -@cindex -w option -@cindex options, -w -@item -w -Inhibit all warning messages. - -@cindex -Wno-globals option -@cindex options, -Wno-globals -@item -Wno-globals -@cindex global names, warning -@cindex warnings, global names -Inhibit warnings about use of a name as both a global name -(a subroutine, function, or block data program unit, or a -common block) and implicitly as the name of an intrinsic -in a source file. - -Also inhibit warnings about inconsistent invocations and/or -definitions of global procedures (function and subroutines). -Such inconsistencies include different numbers of arguments -and different types of arguments. - -@cindex -Wimplicit option -@cindex options, -Wimplicit -@item -Wimplicit -@cindex implicit declaration, warning -@cindex warnings, implicit declaration -@cindex -u option -@cindex /WARNINGS=DECLARATIONS switch -@cindex IMPLICIT NONE, similar effect -@cindex effecting IMPLICIT NONE -Warn whenever a variable, array, or function is implicitly -declared. -Has an effect similar to using the @code{IMPLICIT NONE} statement -in every program unit. -(Some Fortran compilers provide this feature by an option -named @samp{-u} or @samp{/WARNINGS=DECLARATIONS}.) - -@cindex -Wunused option -@cindex options, -Wunused -@item -Wunused -@cindex unused variables -@cindex variables, unused -Warn whenever a variable is unused aside from its declaration. - -@cindex -Wuninitialized option -@cindex options, -Wuninitialized -@item -Wuninitialized -@cindex uninitialized variables -@cindex variables, uninitialized -Warn whenever an automatic variable is used without first being initialized. - -These warnings are possible only in optimizing compilation, -because they require data-flow information that is computed only -when optimizing. If you don't specify @samp{-O}, you simply won't -get these warnings. - -These warnings occur only for variables that are candidates for -register allocation. Therefore, they do not occur for a variable -@c that is declared @code{VOLATILE}, or -whose address is taken, or whose size -is other than 1, 2, 4 or 8 bytes. Also, they do not occur for -arrays, even when they are in registers. - -Note that there might be no warning about a variable that is used only -to compute a value that itself is never used, because such -computations may be deleted by data-flow analysis before the warnings -are printed. - -These warnings are made optional because GNU Fortran is not smart -enough to see all the reasons why the code might be correct -despite appearing to have an error. Here is one example of how -this can happen: - -@example -SUBROUTINE DISPAT(J) -IF (J.EQ.1) I=1 -IF (J.EQ.2) I=4 -IF (J.EQ.3) I=5 -CALL FOO(I) -END -@end example - -@noindent -If the value of @code{J} is always 1, 2 or 3, then @code{I} is -always initialized, but GNU Fortran doesn't know this. Here is -another common case: - -@example -SUBROUTINE MAYBE(FLAG) -LOGICAL FLAG -IF (FLAG) VALUE = 9.4 -@dots{} -IF (FLAG) PRINT *, VALUE -END -@end example - -@noindent -This has no bug because @code{VALUE} is used only if it is set. - -@cindex -Wall option -@cindex options, -Wall -@item -Wall -@cindex all warnings -@cindex warnings, all -The @samp{-Wunused} and @samp{-Wuninitialized} options combined. -These are all the -options which pertain to usage that we recommend avoiding and that we -believe is easy to avoid. -(As more warnings are added to @code{g77}, some might -be added to the list enabled by @samp{-Wall}.) -@end table - -The remaining @samp{-W@dots{}} options are not implied by @samp{-Wall} -because they warn about constructions that we consider reasonable to -use, on occasion, in clean programs. - -@table @code -@c @item -W -@c Print extra warning messages for these events: -@c -@c @itemize @bullet -@c @item -@c If @samp{-Wall} or @samp{-Wunused} is also specified, warn about unused -@c arguments. -@c -@c @end itemize -@c -@cindex -Wsurprising option -@cindex options, -Wsurprising -@item -Wsurprising -Warn about ``suspicious'' constructs that are interpreted -by the compiler in a way that might well be surprising to -someone reading the code. -These differences can result in subtle, compiler-dependent -(even machine-dependent) behavioral differences. -The constructs warned about include: - -@itemize @bullet -@item -Expressions having two arithmetic operators in a row, such -as @samp{X*-Y}. -Such a construct is nonstandard, and can produce -unexpected results in more complicated situations such -as @samp{X**-Y*Z}. -@code{g77}, along with many other compilers, interprets -this example differently than many programmers, and a few -other compilers. -Specifically, @code{g77} interprets @samp{X**-Y*Z} as -@samp{(X**(-Y))*Z}, while others might think it should -be interpreted as @samp{X**(-(Y*Z))}. - -A revealing example is the constant expression @samp{2**-2*1.}, -which @code{g77} evaluates to .25, while others might evaluate -it to 0., the difference resulting from the way precedence affects -type promotion. - -(The @samp{-fpedantic} option also warns about expressions -having two arithmetic operators in a row.) - -@item -Expressions with a unary minus followed by an operand and then -a binary operator other than plus or minus. -For example, @samp{-2**2} produces a warning, because -the precedence is @samp{-(2**2)}, yielding -4, not -@samp{(-2)**2}, which yields 4, and which might represent -what a programmer expects. - -An example of an expression producing different results -in a surprising way is @samp{-I*S}, where @var{I} holds -the value @samp{-2147483648} and @var{S} holds @samp{0.5}. -On many systems, negating @var{I} results in the same -value, not a positive number, because it is already the -lower bound of what an @code{INTEGER(KIND=1)} variable can hold. -So, the expression evaluates to a positive number, while -the ``expected'' interpretation, @samp{(-I)*S}, would -evaluate to a negative number. - -Even cases such as @samp{-I*J} produce warnings, -even though, in most configurations and situations, -there is no computational difference between the -results of the two interpretations---the purpose -of this warning is to warn about differing interpretations -and encourage a better style of coding, not to identify -only those places where bugs might exist in the user's -code. - -@cindex DO statement -@cindex statements, DO -@item -@code{DO} loops with @code{DO} variables that are not -of integral type---that is, using @code{REAL} -variables as loop control variables. -Although such loops can be written to work in the -``obvious'' way, the way @code{g77} is required by the -Fortran standard to interpret such code is likely to -be quite different from the way many programmers expect. -(This is true of all @code{DO} loops, but the differences -are pronounced for non-integral loop control variables.) - -@xref{Loops}, for more information. -@end itemize - -@cindex -Werror option -@cindex options, -Werror -@item -Werror -Make all warnings into errors. - -@cindex -W option -@cindex options, -W -@item -W -@cindex extra warnings -@cindex warnings, extra -Turns on ``extra warnings'' and, if optimization is specified -via @samp{-O}, the @samp{-Wuninitialized} option. -(This might change in future versions of @code{g77}.) - -``Extra warnings'' are issued for: - -@itemize @bullet -@item -@cindex unused parameters -@cindex parameters, unused -@cindex unused arguments -@cindex arguments, unused -@cindex unused dummies -@cindex dummies, unused -Unused parameters to a procedure (when @samp{-Wunused} also is -specified). - -@item -@cindex overflow -Overflows involving floating-point constants (not available -for certain configurations). -@end itemize -@end table - -@xref{Warning Options,,Options to Request or Suppress Warnings, -gcc,Using and Porting GNU CC}, for information on more options offered -by the GBE shared by @code{g77}, @code{gcc}, and other GNU compilers. - -Some of these have no effect when compiling programs written in Fortran: - -@table @code -@cindex -Wcomment option -@cindex options, -Wcomment -@item -Wcomment -@cindex -Wformat option -@cindex options, -Wformat -@item -Wformat -@cindex -Wparentheses option -@cindex options, -Wparentheses -@item -Wparentheses -@cindex -Wswitch option -@cindex options, -Wswitch -@item -Wswitch -@cindex -Wtraditional option -@cindex options, -Wtraditional -@item -Wtraditional -@cindex -Wshadow option -@cindex options, -Wshadow -@item -Wshadow -@cindex -Wid-clash-@var{len} option -@cindex options, -Wid-clash-@var{len} -@item -Wid-clash-@var{len} -@cindex -Wlarger-than-@var{len} option -@cindex options, -Wlarger-than-@var{len} -@item -Wlarger-than-@var{len} -@cindex -Wconversion option -@cindex options, -Wconversion -@item -Wconversion -@cindex -Waggregate-return option -@cindex options, -Waggregate-return -@item -Waggregate-return -@cindex -Wredundant-decls option -@cindex options, -Wredundant-decls -@item -Wredundant-decls -@cindex unsupported warnings -@cindex warnings, unsupported -These options all could have some relevant meaning for -GNU Fortran programs, but are not yet supported. -@end table - -@node Debugging Options -@section Options for Debugging Your Program or GNU Fortran -@cindex options, debugging -@cindex debugging information options - -GNU Fortran has various special options that are used for debugging -either your program or @code{g77}. - -@table @code -@cindex -g option -@cindex options, -g -@item -g -Produce debugging information in the operating system's native format -(stabs, COFF, XCOFF, or DWARF). GDB can work with this debugging -information. - -@cindex common blocks -@cindex equivalence areas -@cindex missing debug features -Support for this option in Fortran programs is incomplete. -In particular, names of variables and arrays in common blocks -or that are storage-associated via @code{EQUIVALENCE} are -unavailable to the debugger. - -However, version 0.5.19 of @code{g77} does provide this information -in a rudimentary way, as controlled by the -@samp{-fdebug-kludge} option. - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for more information. -@end table - -@xref{Debugging Options,,Options for Debugging Your Program or GNU CC, -gcc,Using and Porting GNU CC}, for more information on debugging options. - -@node Optimize Options -@section Options That Control Optimization -@cindex optimize options -@cindex options, optimization - -Most Fortran users will want to use no optimization when -developing and testing programs, and use @samp{-O} or @samp{-O2} when -compiling programs for late-cycle testing and for production use. -However, note that certain diagnostics---such as for uninitialized -variables---depend on the flow analysis done by @samp{-O}, i.e.@: you -must use @samp{-O} or @samp{-O2} to get such diagnostics. - -The following flags have particular applicability when -compiling Fortran programs: - -@table @code -@cindex -malign-double option -@cindex options, -malign-double -@item -malign-double -(Intel x86 architecture only.) - -Noticeably improves performance of @code{g77} programs making -heavy use of @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) data -on some systems. -In particular, systems using Pentium, Pentium Pro, 586, and -686 implementations -of the i386 architecture execute programs faster when -@code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) data are -aligned on 64-bit boundaries -in memory. - -This option can, at least, make benchmark results more consistent -across various system configurations, versions of the program, -and data sets. - -@emph{Note:} The warning in the @code{gcc} documentation about -this option does not apply, generally speaking, to Fortran -code compiled by @code{g77}. - -@emph{Also note:} @samp{-malign-double} applies only to -statically-allocated data. -Double-precision data on the stack can still -cause problems due to misalignment. -@xref{Aligned Data}. - -@emph{Also also note:} The negative form of @samp{-malign-double} -is @samp{-mno-align-double}, not @samp{-benign-double}. - -@cindex -ffloat-store option -@cindex options, -ffloat-store -@item -ffloat-store -@cindex IEEE conformance -@cindex conformance, IEEE -@cindex floating point precision -Might help a Fortran program that depends on exact IEEE conformance on -some machines, but might slow down a program that doesn't. - -This option is effective when the floating point unit is set to work in -IEEE 854 `extended precision'---as it typically is on x86 and m68k GNU -systems---rather than IEEE 754 double precision. @code{-ffloat-store} -tries to remove the extra precision by spilling data from floating point -registers into memory and this typically involves a big performance -hit. However, it doesn't affect intermediate results, so that it is -only partially effective. `Excess precision' is avoided in code like: -@smallexample -a = b + c -d = a * e -@end smallexample -but not in code like: -@smallexample - d = (b + c) * e -@end smallexample - -For another, potentially better, way of controlling the precision -@ref{Floating point precision}. - -@cindex -fforce-mem option -@cindex options, -fforce-mem -@item -fforce-mem -@cindex -fforce-addr option -@cindex options, -fforce-addr -@item -fforce-addr -@cindex loops, speeding up -@cindex speeding up loops -Might improve optimization of loops. - -@cindex -fno-inline option -@cindex options, -fno-inline -@item -fno-inline -@cindex in-line compilation -@cindex compilation, in-line -@c DL: Only relevant for -O3? -Don't compile statement functions inline. -Might reduce the size of a program unit---which might be at -expense of some speed (though it should compile faster). -Note that if you are not optimizing, no functions can be expanded inline. - -@cindex -ffast-math option -@cindex options, -ffast-math -@item -ffast-math -@cindex IEEE conformance -@cindex conformance, IEEE -Might allow some programs designed to not be too dependent -on IEEE behavior for floating-point to run faster, or die trying. - -@cindex -fstrength-reduce option -@cindex options, -fstrength-reduce -@item -fstrength-reduce -@cindex loops, speeding up -@cindex speeding up loops -@c DL: normally defaulted? -Might make some loops run faster. - -@cindex -frerun-cse-after-loop option -@cindex options, -frerun-cse-after-loop -@item -frerun-cse-after-loop -@cindex -fexpensive-optimizations option -@cindex options, -fexpensive-optimizations -@c DL: This is -O2? -@item -fexpensive-optimizations -@cindex -fdelayed-branch option -@cindex options, -fdelayed-branch -@item -fdelayed-branch -@cindex -fschedule-insns option -@cindex options, -fschedule-insns -@item -fschedule-insns -@cindex -fschedule-insns2 option -@cindex options, -fschedule-insns2 -@item -fschedule-insns2 -@cindex -fcaller-saves option -@cindex options, -fcaller-saves -@item -fcaller-saves -Might improve performance on some code. - -@cindex -funroll-loops option -@cindex options, -funroll-loops -@item -funroll-loops -@cindex loops, unrolling -@cindex unrolling loops -@cindex loop optimization -@c DL: fixme: Craig doesn't like `indexed' but f95 doesn't seem to -@c provide a suitable term -Typically improves performance on code using indexed @code{DO} loops by -unrolling them and is probably generally appropriate for Fortran, though -it is not turned on at any optimization level. -Note that outer loop unrolling isn't done specifically; decisions about -whether to unroll a loop are made on the basis of its instruction count. - -@c DL: Fixme: This should obviously go somewhere else... -Also, no `loop discovery'@footnote{@dfn{loop discovery} refers to the -process by which a compiler, or indeed any reader of a program, -determines which portions of the program are more likely to be executed -repeatedly as it is being run. Such discovery typically is done early -when compiling using optimization techniques, so the ``discovered'' -loops get more attention---and more run-time resources, such as -registers---from the compiler. It is easy to ``discover'' loops that are -constructed out of looping constructs in the language -(such as Fortran's @code{DO}). For some programs, ``discovering'' loops -constructed out of lower-level constructs (such as @code{IF} and -@code{GOTO}) can lead to generation of more optimal code -than otherwise.} is done, so only loops written with @code{DO} -benefit from loop optimizations, including---but not limited -to---unrolling. Loops written with @code{IF} and @code{GOTO} will not -be recognized as such. This option only unrolls indexed @code{DO} -loops, not @code{DO WHILE} loops. - -@cindex -funroll-all-loops option -@cindex options, -funroll-all-loops -@cindex @code{DO WHILE} -@item -funroll-all-loops -@c DL: Check my understanding of -funroll-all-loops v. -funroll-loops is correct. -Probably improves performance on code using @code{DO WHILE} loops by -unrolling them in addition to indexed @code{DO} loops. In the absence -of @code{DO WHILE}, this option is equivalent to @code{-funroll-loops} -but possibly slower. - -@item -fno-move-all-movables -@cindex -fno-move-all-movables option -@cindex options, -fno-move-all-movables -@item -fno-reduce-all-givs -@cindex -fno-reduce-all-givs option -@cindex options, -fno-reduce-all-givs -@item -fno-rerun-loop-opt -@cindex -fno-rerun-loop-opt option -@cindex options, -fno-rerun-loop-opt -@emph{Version info:} -These options are not supported by -versions of @code{g77} based on @code{gcc} version 2.8. - -Each of these might improve performance on some code. - -Analysis of Fortran code optimization and the resulting -optimizations triggered by the above options were -contributed by Toon Moene (@email{toon@@moene.indiv.nluug.nl}). - -These three options are intended to be removed someday, once -they have helped determine the efficacy of various -approaches to improving the performance of Fortran code. - -Please let us know how use of these options affects -the performance of your production code. -We're particularly interested in code that runs faster -when these options are @emph{disabled}, and in -non-Fortran code that benefits when they are -@emph{enabled} via the above @code{gcc} command-line options. -@end table - -@xref{Optimize Options,,Options That Control Optimization, -gcc,Using and Porting GNU CC}, for more information on options -to optimize the generated machine code. - -@node Preprocessor Options -@section Options Controlling the Preprocessor -@cindex preprocessor options -@cindex options, preprocessor -@cindex cpp program -@cindex programs, cpp - -These options control the C preprocessor, which is run on each C source -file before actual compilation. - -@xref{Preprocessor Options,,Options Controlling the Preprocessor, -gcc,Using and Porting GNU CC}, for information on C preprocessor options. - -@cindex INCLUDE directive -@cindex directive, INCLUDE -Some of these options also affect how @code{g77} processes the -@code{INCLUDE} directive. -Since this directive is processed even when preprocessing -is not requested, it is not described in this section. -@xref{Directory Options,,Options for Directory Search}, for -information on how @code{g77} processes the @code{INCLUDE} directive. - -However, the @code{INCLUDE} directive does not apply -preprocessing to the contents of the included file itself. - -Therefore, any file that contains preprocessor directives -(such as @code{#include}, @code{#define}, and @code{#if}) -must be included via the @code{#include} directive, not -via the @code{INCLUDE} directive. -Therefore, any file containing preprocessor directives, -if included, is necessarily included by a file that itself -contains preprocessor directives. - -@node Directory Options -@section Options for Directory Search -@cindex directory options -@cindex options, directory search -@cindex search path - -These options affect how the @code{cpp} preprocessor searches -for files specified via the @code{#include} directive. -Therefore, when compiling Fortran programs, they are meaningful -when the preprocessor is used. - -@cindex INCLUDE directive -@cindex directive, INCLUDE -Some of these options also affect how @code{g77} searches -for files specified via the @code{INCLUDE} directive, -although files included by that directive are not, -themselves, preprocessed. -These options are: - -@table @code -@cindex -I- option -@cindex options, -I- -@item -I- -@cindex -Idir option -@cindex options, -Idir -@item -I@var{dir} -@cindex directory search paths for inclusion -@cindex inclusion, directory search paths for -@cindex searching for included files -These affect interpretation of the @code{INCLUDE} directive -(as well as of the @code{#include} directive of the @code{cpp} -preprocessor). - -Note that @samp{-I@var{dir}} must be specified @emph{without} any -spaces between @samp{-I} and the directory name---that is, -@samp{-Ifoo/bar} is valid, but @samp{-I foo/bar} -is rejected by the @code{g77} compiler (though the preprocessor supports -the latter form). -@c this is due to toplev.c's inflexible option processing -Also note that the general behavior of @samp{-I} and -@code{INCLUDE} is pretty much the same as of @samp{-I} with -@code{#include} in the @code{cpp} preprocessor, with regard to -looking for @file{header.gcc} files and other such things. - -@xref{Directory Options,,Options for Directory Search, -gcc,Using and Porting GNU CC}, for information on the @samp{-I} option. -@end table - -@node Code Gen Options -@section Options for Code Generation Conventions -@cindex code generation conventions -@cindex options, code generation -@cindex run-time options - -These machine-independent options control the interface conventions -used in code generation. - -Most of them have both positive and negative forms; the negative form -of @samp{-ffoo} would be @samp{-fno-foo}. In the table below, only -one of the forms is listed---the one which is not the default. You -can figure out the other form by either removing @samp{no-} or adding -it. - -@table @code -@cindex -fno-automatic option -@cindex options, -fno-automatic -@item -fno-automatic -@cindex SAVE statement -@cindex statements, SAVE -Treat each program unit as if the @code{SAVE} statement was specified -for every local variable and array referenced in it. -Does not affect common blocks. -(Some Fortran compilers provide this option under -the name @samp{-static}.) - -@cindex -finit-local-zero option -@cindex options, -finit-local-zero -@item -finit-local-zero -@cindex DATA statement -@cindex statements, DATA -@cindex initialization of local variables -@cindex variables, initialization of -@cindex uninitialized variables -@cindex variables, uninitialized -Specify that variables and arrays that are local to a program unit -(not in a common block and not passed as an argument) are to be initialized -to binary zeros. - -Since there is a run-time penalty for initialization of variables -that are not given the @code{SAVE} attribute, it might be a -good idea to also use @samp{-fno-automatic} with @samp{-finit-local-zero}. - -@cindex -fno-f2c option -@cindex options, -fno-f2c -@item -fno-f2c -@cindex @code{f2c} compatibility -@cindex compatibility, @code{f2c} -Do not generate code designed to be compatible with code generated -by @code{f2c}; use the GNU calling conventions instead. - -The @code{f2c} calling conventions require functions that return -type @code{REAL(KIND=1)} to actually return the C type @code{double}, -and functions that return type @code{COMPLEX} to return the -values via an extra argument in the calling sequence that points -to where to store the return value. -Under the GNU calling conventions, such functions simply return -their results as they would in GNU C---@code{REAL(KIND=1)} functions -return the C type @code{float}, and @code{COMPLEX} functions -return the GNU C type @code{complex} (or its @code{struct} -equivalent). - -This does not affect the generation of code that interfaces with the -@code{libg2c} library. - -However, because the @code{libg2c} library uses @code{f2c} -calling conventions, @code{g77} rejects attempts to pass -intrinsics implemented by routines in this library as actual -arguments when @samp{-fno-f2c} is used, to avoid bugs when -they are actually called by code expecting the GNU calling -conventions to work. - -For example, @samp{INTRINSIC ABS;CALL FOO(ABS)} is -rejected when @samp{-fno-f2c} is in force. -(Future versions of the @code{g77} run-time library might -offer routines that provide GNU-callable versions of the -routines that implement the @code{f2c}-callable intrinsics -that may be passed as actual arguments, so that -valid programs need not be rejected when @samp{-fno-f2c} -is used.) - -@strong{Caution:} If @samp{-fno-f2c} is used when compiling any -source file used in a program, it must be used when compiling -@emph{all} Fortran source files used in that program. - -@c seems kinda dumb to tell people about an option they can't use -- jcb -@c then again, we want users building future-compatible libraries with it. -@cindex -ff2c-library option -@cindex options, -ff2c-library -@item -ff2c-library -Specify that use of @code{libg2c} (or the original @code{libf2c}) -is required. -This is the default for the current version of @code{g77}. - -Currently it is not -valid to specify @samp{-fno-f2c-library}. -This option is provided so users can specify it in shell -scripts that build programs and libraries that require the -@code{libf2c} library, even when being compiled by future -versions of @code{g77} that might otherwise default to -generating code for an incompatible library. - -@cindex -fno-underscoring option -@cindex options, -fno-underscoring -@item -fno-underscoring -@cindex underscores -@cindex symbol names, underscores -@cindex transforming symbol names -@cindex symbol names, transforming -Do not transform names of entities specified in the Fortran -source file by appending underscores to them. - -With @samp{-funderscoring} in effect, @code{g77} appends two underscores -to names with underscores and one underscore to external names with -no underscores. (@code{g77} also appends two underscores to internal -names with underscores to avoid naming collisions with external names. -The @samp{-fno-second-underscore} option disables appending of the -second underscore in all cases.) - -This is done to ensure compatibility with code produced by many -UNIX Fortran compilers, including @code{f2c}, which perform the -same transformations. - -Use of @samp{-fno-underscoring} is not recommended unless you are -experimenting with issues such as integration of (GNU) Fortran into -existing system environments (vis-a-vis existing libraries, tools, and -so on). - -For example, with @samp{-funderscoring}, and assuming other defaults like -@samp{-fcase-lower} and that @samp{j()} and @samp{max_count()} are -external functions while @samp{my_var} and @samp{lvar} are local variables, -a statement like - -@smallexample -I = J() + MAX_COUNT (MY_VAR, LVAR) -@end smallexample - -@noindent -is implemented as something akin to: - -@smallexample -i = j_() + max_count__(&my_var__, &lvar); -@end smallexample - -With @samp{-fno-underscoring}, the same statement is implemented as: - -@smallexample -i = j() + max_count(&my_var, &lvar); -@end smallexample - -Use of @samp{-fno-underscoring} allows direct specification of -user-defined names while debugging and when interfacing @code{g77}-compiled -code with other languages. - -Note that just because the names match does @emph{not} mean that the -interface implemented by @code{g77} for an external name matches the -interface implemented by some other language for that same name. -That is, getting code produced by @code{g77} to link to code produced -by some other compiler using this or any other method can be only a -small part of the overall solution---getting the code generated by -both compilers to agree on issues other than naming can require -significant effort, and, unlike naming disagreements, linkers normally -cannot detect disagreements in these other areas. - -Also, note that with @samp{-fno-underscoring}, the lack of appended -underscores introduces the very real possibility that a user-defined -external name will conflict with a name in a system library, which -could make finding unresolved-reference bugs quite difficult in some -cases---they might occur at program run time, and show up only as -buggy behavior at run time. - -In future versions of @code{g77}, we hope to improve naming and linking -issues so that debugging always involves using the names as they appear -in the source, even if the names as seen by the linker are mangled to -prevent accidental linking between procedures with incompatible -interfaces. - -@cindex -fno-second-underscore option -@cindex options, -fno-second-underscore -@item -fno-second-underscore -@cindex underscores -@cindex symbol names, underscores -@cindex transforming symbol names -@cindex symbol names, transforming -Do not append a second underscore to names of entities specified -in the Fortran source file. - -This option has no effect if @samp{-fno-underscoring} is -in effect. - -Otherwise, with this option, an external name such as @samp{MAX_COUNT} -is implemented as a reference to the link-time external symbol -@samp{max_count_}, instead of @samp{max_count__}. - -@cindex -fno-ident option -@cindex options, -fno-ident -@item -fno-ident -Ignore the @samp{#ident} directive. - -@cindex -fzeros option -@cindex options, -fzeros -@item -fzeros -Treat initial values of zero as if they were any other value. - -As of version 0.5.18, @code{g77} normally treats @code{DATA} and -other statements that are used to specify initial values of zero -for variables and arrays as if no values were actually specified, -in the sense that no diagnostics regarding multiple initializations -are produced. - -This is done to speed up compiling of programs that initialize -large arrays to zeros. - -Use @samp{-fzeros} to revert to the simpler, slower behavior -that can catch multiple initializations by keeping track of -all initializations, zero or otherwise. - -@emph{Caution:} Future versions of @code{g77} might disregard this option -(and its negative form, the default) or interpret it somewhat -differently. -The interpretation changes will affect only non-standard -programs; standard-conforming programs should not be affected. - -@cindex -fdebug-kludge option -@cindex options, -fdebug-kludge -@item -fdebug-kludge -Emit information on @code{COMMON} and @code{EQUIVALENCE} members -that might help users of debuggers work around lack of proper debugging -information on such members. - -As of version 0.5.19, @code{g77} offers this option to emit -information on members of aggregate areas to help users while debugging. -This information consists of establishing the type and contents of each -such member so that, when a debugger is asked to print the contents, -the printed information provides rudimentary debugging information. -This information identifies the name of the aggregate area (either the -@code{COMMON} block name, or the @code{g77}-assigned name for the -@code{EQUIVALENCE} name) and the offset, in bytes, of the member from -the beginning of the area. - -Using @code{gdb}, this information is not coherently displayed in the Fortran -language mode, so temporarily switching to the C language mode to display the -information is suggested. -Use @samp{set language c} and @samp{set language fortran} to accomplish this. - -For example: - -@smallexample - COMMON /X/A,B - EQUIVALENCE (C,D) - CHARACTER XX*50 - EQUIVALENCE (I,XX(20:20)) - END - -GDB is free software and you are welcome to distribute copies of it - under certain conditions; type "show copying" to see the conditions. -There is absolutely no warranty for GDB; type "show warranty" for details. -GDB 4.16 (lm-gnits-dwim), Copyright 1996 Free Software Foundation, Inc... -(gdb) b MAIN__ -Breakpoint 1 at 0t1200000201120112: file cd.f, line 5. -(gdb) r -Starting program: /home/user/a.out - -Breakpoint 1, MAIN__ () at cd.f:5 -Current language: auto; currently fortran -(gdb) set language c -Warning: the current language does not match this frame. -(gdb) p a -$2 = "At (COMMON) `x_' plus 0 bytes" -(gdb) p b -$3 = "At (COMMON) `x_' plus 4 bytes" -(gdb) p c -$4 = "At (EQUIVALENCE) `__g77_equiv_c' plus 0 bytes" -(gdb) p d -$5 = "At (EQUIVALENCE) `__g77_equiv_c' plus 0 bytes" -(gdb) p i -$6 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 20 bytes" -(gdb) p xx -$7 = "At (EQUIVALENCE) `__g77_equiv_xx' plus 1 bytes" -(gdb) set language fortran -(gdb) -@end smallexample - -@noindent -Use @samp{-fdebug-kludge} to generate this information, -which might make some programs noticeably larger. - -@emph{Caution:} Future versions of @code{g77} might disregard this option -(and its negative form). -Current plans call for this to happen when published versions of @code{g77} -and @code{gdb} exist that provide proper access to debugging information on -@code{COMMON} and @code{EQUIVALENCE} members. - -@cindex -fno-emulate-complex option -@cindex options, -fno-emulate-complex -@item -fno-emulate-complex -Implement @code{COMPLEX} arithmetic using the facilities in -the @code{gcc} back end that provide direct support of -@code{complex} arithmetic, instead of emulating the arithmetic. - -@code{gcc} has some known problems in its back-end support -for @code{complex} arithmetic, due primarily to the support not being -completed as of version 2.7.2.2. -Other front ends for the @code{gcc} back end avoid this problem -by emulating @code{complex} arithmetic at a higher level, so the -back end sees arithmetic on the real and imaginary components. -To make @code{g77} more portable to systems where @code{complex} -support in the @code{gcc} back end is particularly troublesome, -@code{g77} now defaults to performing the same kinds of emulations -done by these other front ends. - -Use @samp{-fno-emulate-complex} to try the @code{complex} support -in the @code{gcc} back end, in case it works and produces faster -programs. -So far, all the known bugs seem to involve compile-time crashes, -rather than the generation of incorrect code. - -Use of this option should not affect how Fortran code compiled -by @code{g77} works in terms of its interfaces to other code, -e.g. that compiled by @code{f2c}. - -@emph{Caution:} Future versions of @code{g77} are likely to change -the default for this option to -@samp{-fno-emulate-complex}, and perhaps someday ignore both forms -of this option. - -Also, it is possible that use of the @samp{-fno-emulate-complex} option -could result in incorrect code being silently produced by @code{g77}. -But, this is generally true of compilers anyway, so, as usual, test -the programs you compile before assuming they are working. - -@cindex -falias-check option -@cindex options, -falias-check -@cindex -fargument-alias option -@cindex options, -fargument-alias -@cindex -fargument-noalias option -@cindex options, -fargument-noalias -@cindex -fno-argument-noalias-global option -@cindex options, -fno-argument-noalias-global -@item -falias-check -@item -fargument-alias -@item -fargument-noalias -@item -fno-argument-noalias-global -@emph{Version info:} -These options are not supported by -versions of @code{g77} based on @code{gcc} version 2.8. - -These options specify to what degree aliasing -(overlap) -is permitted between -arguments (passed as pointers) and @code{COMMON} (external, or -public) storage. - -The default for Fortran code, as mandated by the FORTRAN 77 and -Fortran 90 standards, is @samp{-fargument-noalias-global}. -The default for code written in the C language family is -@samp{-fargument-alias}. - -Note that, on some systems, compiling with @samp{-fforce-addr} in -effect can produce more optimal code when the default aliasing -options are in effect (and when optimization is enabled). - -@xref{Aliasing Assumed To Work}, for detailed information on the implications -of compiling Fortran code that depends on the ability to alias dummy -arguments. - -@cindex -fno-globals option -@cindex options, -fno-globals -@item -fno-globals -@cindex global names, warning -@cindex warnings, global names -Disable diagnostics about inter-procedural -analysis problems, such as disagreements about the -type of a function or a procedure's argument, -that might cause a compiler crash when attempting -to inline a reference to a procedure within a -program unit. -(The diagnostics themselves are still produced, but -as warnings, unless @samp{-Wno-globals} is specified, -in which case no relevant diagnostics are produced.) - -Further, this option disables such inlining, to -avoid compiler crashes resulting from incorrect -code that would otherwise be diagnosed. - -As such, this option might be quite useful when -compiling existing, ``working'' code that happens -to have a few bugs that do not generally show -themselves, but @code{g77} exposes via a -diagnostic. - -Use of this option therefore has the effect of -instructing @code{g77} to behave more like it did -up through version 0.5.19.1, when it paid little or -no attention to disagreements between program units -about a procedure's type and argument information, -and when it performed no inlining of procedures -(except statement functions). - -Without this option, @code{g77} defaults to performing -the potentially inlining procedures as it started doing -in version 0.5.20, but as of version 0.5.21, it also -diagnoses disagreements that might cause such inlining -to crash the compiler. -@end table - -@xref{Code Gen Options,,Options for Code Generation Conventions, -gcc,Using and Porting GNU CC}, for information on more options -offered by the GBE -shared by @code{g77}, @code{gcc}, and other GNU compilers. - -Some of these do @emph{not} work when compiling programs written in Fortran: - -@table @code -@cindex -fpcc-struct-return option -@cindex options, -fpcc-struct-return -@item -fpcc-struct-return -@cindex -freg-struct-return option -@cindex options, -freg-struct-return -@item -freg-struct-return -You should not use these except strictly the same way as you -used them to build the version of @code{libg2c} with which -you will be linking all code compiled by @code{g77} with the -same option. - -@cindex -fshort-double option -@cindex options, -fshort-double -@item -fshort-double -This probably either has no effect on Fortran programs, or -makes them act loopy. - -@cindex -fno-common option -@cindex options, -fno-common -@item -fno-common -Do not use this when compiling Fortran programs, -or there will be Trouble. - -@cindex -fpack-struct option -@cindex options, -fpack-struct -@item -fpack-struct -This probably will break any calls to the @code{libg2c} library, -at the very least, even if it is built with the same option. -@end table - -@node Environment Variables -@section Environment Variables Affecting GNU Fortran -@cindex environment variables - -GNU Fortran currently does not make use of any environment -variables to control its operation above and beyond those -that affect the operation of @code{gcc}. - -@xref{Environment Variables,,Environment Variables Affecting GNU CC, -gcc,Using and Porting GNU CC}, for information on environment -variables. - -@include news.texi - -@node Changes -@chapter User-visible Changes -@cindex versions, recent -@cindex recent versions -@cindex changes, user-visible -@cindex user-visible changes - -This section describes changes to @code{g77} that are visible -to the programmers who actually write and maintain Fortran -code they compile with @code{g77}. -Information on changes to installation procedures, -changes to the documentation, and bug fixes is -not provided here, unless it is likely to affect how -users use @code{g77}. -@xref{News,,News About GNU Fortran}, for information on -such changes to @code{g77}. - -To find out about existing bugs and ongoing plans for GNU -Fortran, retrieve @uref{ftp://alpha.gnu.org/g77.plan} -or, if you cannot do that, email -@email{fortran@@gnu.org} asking for a recent copy of the -GNU Fortran @file{.plan} file. - -@heading In @code{egcs} 1.1 (versus 0.5.24): -@itemize @bullet -@cindex alignment -@cindex double-precision performance -@cindex -malign-double -@item -Align static double-precision variables and arrays -on Intel x86 targets -regardless of whether @samp{-malign-double} is specified. - -Generally, this affects only local variables and arrays -having the @code{SAVE} attribute -or given initial values via @code{DATA}. -@end itemize - -@heading In @code{egcs} 1.1 (versus @code{egcs} 1.0.3): -@itemize @bullet -@item -Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a -compile-time constant @code{INTEGER} expression. - -@item -Fix @code{g77} @samp{-g} option so procedures that -use @samp{ENTRY} can be stepped through, line by line, -in @code{gdb}. - -@item -Allow any @code{REAL} argument to intrinsics -@code{Second} and @code{CPU_Time}. - -@item -Use @code{tempnam}, if available, to open scratch files -(as in @samp{OPEN(STATUS='SCRATCH')}) -so that the @code{TMPDIR} environment variable, -if present, is used. - -@item -@code{g77}'s version of @code{libf2c} separates out -the setting of global state -(such as command-line arguments and signal handling) -from @file{main.o} into distinct, new library -archive members. - -This should make it easier to write portable applications -that have their own (non-Fortran) @code{main()} routine -properly set up the @code{libf2c} environment, even -when @code{libf2c} (now @code{libg2c}) is a shared library. - -@item -The @code{g77} command now expects the run-time library -to be named @code{libg2c.a} instead of @code{libf2c.a}, -to ensure that a version other than the one built and -installed as part of the same @code{g77} version is picked up. - -@item -Some diagnostics have been changed from warnings to errors, -to prevent inadvertent use of the resulting, probably buggy, -programs. -These mostly include diagnostics about use of unsupported features -in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and -@code{WRITE} statements, -and about truncations of various sorts of constants. -@end itemize - -@heading In 0.5.24 and @code{egcs} 1.1 (versus 0.5.23): -@itemize @bullet -@item -@code{g77} now treats @samp{%LOC(@var{expr})} and -@samp{LOC(@var{expr})} as ``ordinary'' expressions -when they are used as arguments in procedure calls. -This change applies only to global (filewide) analysis, -making it consistent with -how @code{g77} actually generates code -for these cases. - -Previously, @code{g77} treated these expressions -as denoting special ``pointer'' arguments -for the purposes of filewide analysis. - -@item -The @code{g77} driver now ensures that @samp{-lg2c} -is specified in the link phase prior to any -occurrence of @samp{-lm}. -This prevents accidentally linking to a routine -in the SunOS4 @samp{-lm} library -when the generated code wants to link to the one -in @code{libf2c} (@code{libg2c}). - -@item -@code{g77} emits more debugging information when -@samp{-g} is used. - -This new information allows, for example, -@kbd{which __g77_length_a} to be used in @code{gdb} -to determine the type of the phantom length argument -supplied with @samp{CHARACTER} variables. - -This information pertains to internally-generated -type, variable, and other information, -not to the longstanding deficiencies vis-a-vis -@samp{COMMON} and @samp{EQUIVALENCE}. - -@item -The F90 @samp{Date_and_Time} intrinsic now is -supported. - -@item -The F90 @samp{System_Clock} intrinsic allows -the optional arguments (except for the @samp{Count} -argument) to be omitted. -@end itemize - -@heading In 0.5.23: -@itemize @bullet -@item -This release contains several regressions against -version 0.5.22 of @code{g77}, due to using the -``vanilla'' @code{gcc} back end instead of patching -it to fix a few bugs and improve performance in a -few cases. - -@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}, -available in plain-text format in @code{gcc/f/BUGS}, -for information on the known bugs in this version, -including the regressions. - -Features that have been dropped from this version -of @code{g77} due to their being implemented -via @code{g77}-specific patches to the @code{gcc} -back end in previous releases include: - -@itemize -- -@item -Support for @code{__restrict__} keyword, -the options @samp{-fargument-alias}, @samp{-fargument-noalias}, -and @samp{-fargument-noalias-global}, -and the corresponding alias-analysis code. - -(@code{egcs} has the alias-analysis -code, but not the @code{__restrict__} keyword. -@code{egcs} @code{g77} users benefit from the alias-analysis -code despite the lack of the @code{__restrict__} keyword, -which is a C-language construct.) - -@item -Support for the GNU compiler options -@samp{-fmove-all-movables}, -@samp{-freduce-all-givs}, -and @samp{-frerun-loop-opt}. - -(@code{egcs} supports these options. -@code{g77} users of @code{egcs} benefit from them even if -they are not explicitly specified, -because the defaults are optimized for @code{g77} users.) - -@item -Support for the @samp{-W} option warning about -integer division by zero. - -@item -The Intel x86-specific option @samp{-malign-double} -applying to stack-allocated data -as well as statically-allocate data. -@end itemize - -@item -Support @code{gcc} version 2.8, -and remove support for prior versions of @code{gcc}. - -@cindex -@w{}-driver option -@cindex g77 options, -@w{}-driver -@cindex options, -@w{}-driver -@item -Remove support for the @samp{--driver} option, -as @code{g77} now does all the driving, -just like @code{gcc}. - -@item -The @code{g77} command now expects the run-time library -to be named @code{libg2c.a} instead of @code{libf2c.a}, -to ensure that a version other than the one built and -installed as part of the same @code{g77} version is picked up. - -@item -@code{g77}'s version of @code{libf2c} separates out -the setting of global state -(such as command-line arguments and signal handling) -from @file{main.o} into distinct, new library -archive members. - -This should make it easier to write portable applications -that have their own (non-Fortran) @code{main()} routine -properly set up the @code{libf2c} environment, even -when @code{libf2c} (now @code{libg2c}) is a shared library. - -@item -Some diagnostics have been changed from warnings to errors, -to prevent inadvertent use of the resulting, probably buggy, -programs. -These mostly include diagnostics about use of unsupported features -in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and -@code{WRITE} statements, -and about truncations of various sorts of constants. -@end itemize - -@heading In 0.5.22: -@itemize @bullet -@item -Fix @code{Signal} intrinsic so it offers portable -support for 64-bit systems (such as Digital Alphas -running GNU/Linux). - -@item -Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a -compile-time constant @code{INTEGER} expression. - -@item -Fix @code{g77} @samp{-g} option so procedures that -use @samp{ENTRY} can be stepped through, line by line, -in @code{gdb}. - -@item -Allow any @code{REAL} argument to intrinsics -@code{Second} and @code{CPU_Time}. - -@item -Allow any numeric argument to intrinsics -@code{Int2} and @code{Int8}. - -@item -Use @code{tempnam}, if available, to open scratch files -(as in @samp{OPEN(STATUS='SCRATCH')}) -so that the @code{TMPDIR} environment variable, -if present, is used. - -@item -Rename the @code{gcc} keyword @code{restrict} to -@code{__restrict__}, to avoid rejecting valid, existing, -C programs. -Support for @code{restrict} is now more like support -for @code{complex}. - -@item -Fix @samp{-fugly-comma} to affect invocations of -only external procedures. -Restore rejection of gratuitous trailing omitted -arguments to intrinsics, as in @samp{I=MAX(3,4,,)}. - -@item -Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and -@samp{-fbadu77-intrinsics-*} options. -@end itemize - -@heading In @code{egcs} 1.0.2 (versus @code{egcs} 1.0.1): -@itemize @bullet -@item -Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and -@samp{-fbadu77-intrinsics-*} options. -@end itemize - -@heading In @code{egcs} 1.0 (versus 0.5.21): -@itemize @bullet -@item -Version 1.0 of @code{egcs} -contains several regressions against -version 0.5.21 of @code{g77}, -due to using the -``vanilla'' @code{gcc} back end instead of patching -it to fix a few bugs and improve performance in a -few cases. - -@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}, -available in plain-text format in @code{gcc/f/BUGS}, -for information on the known bugs in this version, -including the regressions. - -Features that have been dropped from this version -of @code{g77} due to their being implemented -via @code{g77}-specific patches to the @code{gcc} -back end in previous releases include: - -@itemize -- -@item -Support for the C-language @code{restrict} keyword. - -@item -Support for the @samp{-W} option warning about -integer division by zero. - -@item -The Intel x86-specific option @samp{-malign-double} -applying to stack-allocated data -as well as statically-allocate data. -@end itemize - -@cindex -@w{}-driver option -@cindex g77 options, -@w{}-driver -@cindex options, -@w{}-driver -@item -Remove support for the @samp{--driver} option, -as @code{g77} now does all the driving, -just like @code{gcc}. - -@item -Allow any numeric argument to intrinsics -@code{Int2} and @code{Int8}. -@end itemize - -@heading In 0.5.21: -@itemize @bullet -@item -When the @samp{-W} option is specified, @code{gcc}, @code{g77}, -and other GNU compilers that incorporate the @code{gcc} -back end as modified by @code{g77}, issue -a warning about integer division by constant zero. - -@item -New option @samp{-Wno-globals} disables warnings -about ``suspicious'' use of a name both as a global -name and as the implicit name of an intrinsic, and -warnings about disagreements over the number or natures of -arguments passed to global procedures, or the -natures of the procedures themselves. - -The default is to issue such warnings, which are -new as of this version of @code{g77}. - -@item -New option @samp{-fno-globals} disables diagnostics -about potentially fatal disagreements -analysis problems, such as disagreements over the -number or natures of arguments passed to global -procedures, or the natures of those procedures themselves. - -The default is to issue such diagnostics and flag -the compilation as unsuccessful. -With this option, the diagnostics are issued as -warnings, or, if @samp{-Wno-globals} is specified, -are not issued at all. - -This option also disables inlining of global procedures, -to avoid compiler crashes resulting from coding errors -that these diagnostics normally would identify. - -@item -Fix @code{libU77} routines that accept file and other names -to strip trailing blanks from them, for consistency -with other implementations. -Blanks may be forcibly appended to such names by -appending a single null character (@samp{CHAR(0)}) -to the significant trailing blanks. - -@item -Fix @code{CHMOD} intrinsic to work with file names -that have embedded blanks, commas, and so on. - -@item -Fix @code{SIGNAL} intrinsic so it accepts an -optional third @samp{Status} argument. - -@item -Make many changes to @code{libU77} intrinsics to -support existing code more directly. - -Such changes include allowing both subroutine and -function forms of many routines, changing @code{MCLOCK()} -and @code{TIME()} to return @code{INTEGER(KIND=1)} values, -introducing @code{MCLOCK8()} and @code{TIME8()} to -return @code{INTEGER(KIND=2)} values, -and placing functions that are intended to perform -side effects in a new intrinsic group, @code{badu77}. - -@item -Add options @samp{-fbadu77-intrinsics-delete}, -@samp{-fbadu77-intrinsics-hide}, and so on. - -@item -Add @code{INT2} and @code{INT8} intrinsics. - -@item -Add @code{CPU_TIME} intrinsic. - -@item -Add @code{ALARM} intrinsic. - -@item -@code{CTIME} intrinsic now accepts any @code{INTEGER} -argument, not just @code{INTEGER(KIND=2)}. - -@item -@code{g77} driver now prints version information (such as produced -by @kbd{g77 -v}) to @code{stderr} instead of @code{stdout}. - -@item -The @samp{.r} suffix now designates a Ratfor source file, -to be preprocessed via the @code{ratfor} command, available -separately. -@end itemize - -@heading In 0.5.20: -@itemize @bullet -@item -The @samp{-fno-typeless-boz} option is now the default. - -This option specifies that non-decimal-radix -constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @code{INTEGER(KIND=1)} constants. -Specify @samp{-ftypeless-boz} to cause such -constants to be interpreted as typeless. - -(Version 0.5.19 introduced @samp{-fno-typeless-boz} and -its inverse.) - -@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}, -for information on the @samp{-ftypeless-boz} option. - -@item -Options @samp{-ff90-intrinsics-enable} and -@samp{-fvxt-intrinsics-enable} now are the -defaults. - -Some programs might use names that clash with -intrinsic names defined (and now enabled) by these -options or by the new @code{libU77} intrinsics. -Users of such programs might need to compile them -differently (using, for example, @samp{-ff90-intrinsics-disable}) -or, better yet, insert appropriate @code{EXTERNAL} -statements specifying that these names are not intended -to be names of intrinsics. - -@item -The @samp{ALWAYS_FLUSH} macro is no longer defined when -building @code{libf2c}, which should result in improved -I/O performance, especially over NFS. - -@emph{Note:} If you have code that depends on the behavior -of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined, -you will have to modify @code{libf2c} accordingly before -building it from this and future versions of @code{g77}. - -@xref{Output Assumed To Flush}, for more information. - -@item -Dave Love's implementation of @code{libU77} has been -added to the version of @code{libf2c} distributed with -and built as part of @code{g77}. -@code{g77} now knows about the routines in this library -as intrinsics. - -@item -New option @samp{-fvxt} specifies that the -source file is written in VXT Fortran, instead of GNU Fortran. - -@xref{VXT Fortran}, for more information on the constructs -recognized when the @samp{-fvxt} option is specified. - -@item -The @samp{-fvxt-not-f90} option has been deleted, -along with its inverse, @samp{-ff90-not-vxt}. - -If you used one of these deleted options, you should -re-read the pertinent documentation to determine which -options, if any, are appropriate for compiling your -code with this version of @code{g77}. - -@xref{Other Dialects}, for more information. - -@item -The @samp{-fugly} option now issues a warning, as it -likely will be removed in a future version. - -(Enabling all the @samp{-fugly-*} options is unlikely -to be feasible, or sensible, in the future, -so users should learn to specify only those -@samp{-fugly-*} options they really need for a -particular source file.) - -@item -The @samp{-fugly-assumed} option, introduced in -version 0.5.19, has been changed to -better accommodate old and new code. -@xref{Ugly Assumed-Size Arrays}, for more information. - -@item -Related to supporting Alpha (AXP) machines, the @code{LOC()} -intrinsic and @code{%LOC()} construct now return -values of @code{INTEGER(KIND=0)} type, -as defined by the GNU Fortran language. - -This type is wide enough -(holds the same number of bits) -as the character-pointer type on the machine. - -On most machines, this won't make a difference, -whereas, on Alphas and other systems with 64-bit pointers, -the @code{INTEGER(KIND=0)} type is equivalent to @code{INTEGER(KIND=2)} -(often referred to as @code{INTEGER*8}) -instead of the more common @code{INTEGER(KIND=1)} -(often referred to as @code{INTEGER*4}). - -@item -Emulate @code{COMPLEX} arithmetic in the @code{g77} front -end, to avoid bugs in @code{complex} support in the -@code{gcc} back end. -New option @samp{-fno-emulate-complex} -causes @code{g77} to revert the 0.5.19 behavior. - -@item -Dummy arguments are no longer assumed to potentially alias -(overlap) -other dummy arguments or @code{COMMON} areas when any of -these are defined (assigned to) by Fortran code. - -This can result in faster and/or smaller programs when -compiling with optimization enabled, though on some -systems this effect is observed only when @samp{-fforce-addr} -also is specified. - -New options @samp{-falias-check}, @samp{-fargument-alias}, -@samp{-fargument-noalias}, -and @samp{-fno-argument-noalias-global} control the -way @code{g77} handles potential aliasing. - -@xref{Aliasing Assumed To Work}, for detailed information on why the -new defaults might result in some programs no longer working the way they -did when compiled by previous versions of @code{g77}. - -@item -New option @samp{-fugly-assign} specifies that the -same memory locations are to be used to hold the -values assigned by both statements @samp{I = 3} and -@samp{ASSIGN 10 TO I}, for example. -(Normally, @code{g77} uses a separate memory location -to hold assigned statement labels.) - -@xref{Ugly Assigned Labels}, for more information. - -@item -@code{FORMAT} and @code{ENTRY} statements now are allowed to -precede @code{IMPLICIT NONE} statements. - -@item -Enable full support of @code{INTEGER(KIND=2)} -(often referred to as @code{INTEGER*8}) -available in -@code{libf2c} and @file{f2c.h} so that @code{f2c} users -may make full use of its features via the @code{g77} -version of @file{f2c.h} and the @code{INTEGER(KIND=2)} -support routines in the @code{g77} version of @code{libf2c}. - -@item -Improve @code{g77} driver and @code{libf2c} so that @samp{g77 -v} -yields version information on the library. - -@item -The @code{SNGL} and @code{FLOAT} intrinsics now are -specific intrinsics, instead of synonyms for the -generic intrinsic @code{REAL}. - -@item -New intrinsics have been added. -These are @code{REALPART}, @code{IMAGPART}, -@code{COMPLEX}, -@code{LONG}, and @code{SHORT}. - -@item -A new group of intrinsics, @samp{gnu}, has been added -to contain the new @code{REALPART}, @code{IMAGPART}, -and @code{COMPLEX} intrinsics. -An old group, @samp{dcp}, has been removed. - -@item -Complain about industry-wide ambiguous references -@samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})}, -where @var{expr} is @code{DOUBLE COMPLEX} (or any -complex type other than @code{COMPLEX}), unless -@samp{-ff90} option specifies Fortran 90 interpretation -or new @samp{-fugly-complex} option, in conjunction with -@samp{-fnot-f90}, specifies @code{f2c} interpretation. -@end itemize - -@heading In 0.5.19: - -@itemize @bullet -@item -A temporary kludge option provides bare-bones information on -@code{COMMON} and @code{EQUIVALENCE} members at debug time. -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -@item -New @samp{-fonetrip} option specifies FORTRAN-66-style -one-trip @code{DO} loops. - -@item -New @samp{-fno-silent} option causes names of program units -to be printed as they are compiled, in a fashion similar to -UNIX @code{f77} and @code{f2c}. - -@item -New @samp{-fugly-assumed} option specifies that arrays -dimensioned via @samp{DIMENSION X(1)}, for example, are to be -treated as assumed-size. - -@item -New @samp{-fno-typeless-boz} option specifies that non-decimal-radix -constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @code{INTEGER(KIND=1)} constants. - -@item -New @samp{-ff66} option is a ``shorthand'' option that specifies -behaviors considered appropriate for FORTRAN 66 programs. - -@item -New @samp{-ff77} option is a ``shorthand'' option that specifies -behaviors considered appropriate for UNIX @code{f77} programs. - -@item -New @samp{-fugly-comma} and @samp{-fugly-logint} options provided -to perform some of what @samp{-fugly} used to do. -@samp{-fugly} and @samp{-fno-ugly} are now ``shorthand'' options, -in that they do nothing more than enable (or disable) other -@samp{-fugly-*} options. - -@item -Change code generation for list-directed I/O so it allows -for new versions of @code{libf2c} that might return non-zero -status codes for some operations previously assumed to always -return zero. - -This change not only affects how @code{IOSTAT=} variables -are set by list-directed I/O, it also affects whether -@code{END=} and @code{ERR=} labels are reached by these -operations. - -@item -Add intrinsic support for new @code{FTELL} and @code{FSEEK} -procedures in @code{libf2c}. - -@item -Add options @samp{--help} and @samp{--version} to the -@code{g77} command, to conform to GNU coding guidelines. -Also add printing of @code{g77} version number when -the @samp{--verbose} (@samp{-v}) option is used. -@end itemize - -@heading In 0.5.18: - -@itemize @bullet -@item -The @code{BYTE} and @code{WORD} statements now are supported, -to a limited extent. - -@item -@code{INTEGER*1}, @code{INTEGER*2}, @code{INTEGER*8}, -and their @code{LOGICAL} -equivalents, now are supported to a limited extent. -Among the missing elements are complete intrinsic and constant -support. - -@item -Support automatic arrays in procedures. -For example, @samp{REAL A(N)}, where @samp{A} is -not a dummy argument, specifies that @samp{A} is -an automatic array. -The size of @samp{A} is calculated from the value -of @samp{N} each time the procedure is called, -that amount of space is allocated, and that space -is freed when the procedure returns to its caller. - -@item -Add @samp{-fno-zeros} option, enabled by default, -to reduce compile-time CPU and memory usage for -code that provides initial zero values for variables -and arrays. - -@item -Introduce three new options that apply to all compilations -by @code{g77}-aware GNU compilers---@samp{-fmove-all-movables}, -@samp{-freduce-all-givs}, and @samp{-frerun-loop-opt}---which -can improve the run-time performance of some programs. - -@item -Replace much of the existing documentation with a single -Info document. - -@item -New option @samp{-fno-second-underscore}. -@end itemize - -@heading In 0.5.17: - -@itemize @bullet -@item -The @code{ERF()} and @code{ERFC()} intrinsics now are generic -intrinsics, mapping to @code{ERF}/@code{DERF} and -@code{ERFC}/@code{DERFC}, respectively. -@emph{Note:} Use @samp{INTRINSIC ERF,ERFC} in any code that -might reference these as generic intrinsics, to -improve the likelihood of diagnostics (instead of subtle run-time -bugs) when using compilers that don't support these as intrinsics. - -@item -New option @samp{-Wsurprising}. - -@item -DO loops with non-@code{INTEGER} variables now diagnosed only when -@samp{-Wsurprising} specified. -Previously, this was diagnosed @emph{unless} @samp{-fpedantic} or -@samp{-fugly} was specified. -@end itemize - -@heading In 0.5.16: - -@itemize @bullet -@item -@code{libf2c} changed to output a leading zero (0) digit for floating-point -values output via list-directed and formatted output (to bring @code{g77} -more into line with many existing Fortran implementations---the -ANSI FORTRAN 77 standard leaves this choice to the implementation). - -@item -@code{libf2c} no longer built with debugging information -intact, making it much smaller. - -@item -Automatic installation of the @code{g77} command now works. - -@item -Diagnostic messages now more informative, a la @code{gcc}, -including messages like @samp{In function `foo':} and @samp{In file -included from...:}. - -@item -New group of intrinsics called @samp{unix}, including @code{ABORT}, -@code{DERF}, @code{DERFC}, @code{ERF}, @code{ERFC}, @code{EXIT}, -@code{FLUSH}, @code{GETARG}, @code{GETENV}, @code{SIGNAL}, and -@code{SYSTEM}. - -@item -@samp{-funix-intrinsics-@{delete,hide,disable,enable@}} -options added. - -@item -@samp{-fno-underscoring} option added. - -@item -@samp{--driver} option added to the @code{g77} command. - -@item -Support for the @code{gcc} options @samp{-fident} and @samp{-fno-ident} -added. - -@item -@samp{g77 -v} returns much more version info, making the submission -of better bug reports easily. - -@item -Many improvements to the @code{g77} command to better fulfill its role as -a front-end to the @code{gcc} driver. -For example, @code{g77} now -recognizes @samp{--verbose} as a verbose way of specifying @samp{-v}. - -@item -Compiling preprocessed (@file{*.F} and @file{*.fpp}) files now -results in better diagnostics and debugging information, as the -source-location info now is passed all the -way through the compilation process instead of being lost. -@end itemize - -@node Language -@chapter The GNU Fortran Language - -@cindex standard, ANSI FORTRAN 77 -@cindex ANSI FORTRAN 77 standard -@cindex reference works -GNU Fortran supports a variety of extensions to, and dialects -of, the Fortran language. -Its primary base is the ANSI FORTRAN 77 standard, currently available on -the network at -@uref{http://www.fortran.com/fortran/F77_std/rjcnf0001.html} -or as monolithic text at -@uref{http://www.fortran.com/fortran/F77_std/f77_std.html}. -It offers some extensions that are popular among users -of UNIX @code{f77} and @code{f2c} compilers, some that -are popular among users of other compilers (such as Digital -products), some that are popular among users of the -newer Fortran 90 standard, and some that are introduced -by GNU Fortran. - -@cindex textbooks -(If you need a text on Fortran, -a few freely available electronic references have pointers from -@uref{http://www.fortran.com/fortran/Books/}. There is a `cooperative -net project', @cite{User Notes on Fortran Programming} at -@uref{ftp://vms.huji.ac.il/fortran/} and mirrors elsewhere; some of this -material might not apply specifically to @code{g77}.) - -Part of what defines a particular implementation of a Fortran -system, such as @code{g77}, is the particular characteristics -of how it supports types, constants, and so on. -Much of this is left up to the implementation by the various -Fortran standards and accepted practice in the industry. - -The GNU Fortran @emph{language} is described below. -Much of the material is organized along the same lines -as the ANSI FORTRAN 77 standard itself. - -@xref{Other Dialects}, for information on features @code{g77} supports -that are not part of the GNU Fortran language. - -@emph{Note}: This portion of the documentation definitely needs a lot -of work! - -@menu -Relationship to the ANSI FORTRAN 77 standard: -* Direction of Language Development:: Where GNU Fortran is headed. -* Standard Support:: Degree of support for the standard. - -Extensions to the ANSI FORTRAN 77 standard: -* Conformance:: -* Notation Used:: -* Terms and Concepts:: -* Characters Lines Sequence:: -* Data Types and Constants:: -* Expressions:: -* Specification Statements:: -* Control Statements:: -* Functions and Subroutines:: -* Scope and Classes of Names:: -* I/O:: -* Fortran 90 Features:: -@end menu - -@node Direction of Language Development -@section Direction of Language Development -@cindex direction of language development -@cindex features, language -@cindex language features - -The purpose of the following description of the GNU Fortran -language is to promote wide portability of GNU Fortran programs. - -GNU Fortran is an evolving language, due to the -fact that @code{g77} itself is in beta test. -Some current features of the language might later -be redefined as dialects of Fortran supported by @code{g77} -when better ways to express these features are added to @code{g77}, -for example. -Such features would still be supported by -@code{g77}, but would be available only when -one or more command-line options were used. - -The GNU Fortran @emph{language} is distinct from the -GNU Fortran @emph{compilation system} (@code{g77}). - -For example, @code{g77} supports various dialects of -Fortran---in a sense, these are languages other than -GNU Fortran---though its primary -purpose is to support the GNU Fortran language, which also is -described in its documentation and by its implementation. - -On the other hand, non-GNU compilers might offer -support for the GNU Fortran language, and are encouraged -to do so. - -Currently, the GNU Fortran language is a fairly fuzzy object. -It represents something of a cross between what @code{g77} accepts -when compiling using the prevailing defaults and what this -document describes as being part of the language. - -Future versions of @code{g77} are expected to clarify the -definition of the language in the documentation. -Often, this will mean adding new features to the language, in the form -of both new documentation and new support in @code{g77}. -However, it might occasionally mean removing a feature -from the language itself to ``dialect'' status. -In such a case, the documentation would be adjusted -to reflect the change, and @code{g77} itself would likely be changed -to require one or more command-line options to continue supporting -the feature. - -The development of the GNU Fortran language is intended to strike -a balance between: - -@itemize @bullet -@item -Serving as a mostly-upwards-compatible language from the -de facto UNIX Fortran dialect as supported by @code{f77}. - -@item -Offering new, well-designed language features. -Attributes of such features include -not making existing code any harder to read -(for those who might be unaware that the new -features are not in use) and -not making state-of-the-art -compilers take longer to issue diagnostics, -among others. - -@item -Supporting existing, well-written code without gratuitously -rejecting non-standard constructs, regardless of the origin -of the code (its dialect). - -@item -Offering default behavior and command-line options to reduce -and, where reasonable, eliminate the need for programmers to make -any modifications to code that already works in existing -production environments. - -@item -Diagnosing constructs that have different meanings in different -systems, languages, and dialects, while offering clear, -less ambiguous ways to express each of the different meanings -so programmers can change their code appropriately. -@end itemize - -One of the biggest practical challenges for the developers of the -GNU Fortran language is meeting the sometimes contradictory demands -of the above items. - -For example, a feature might be widely used in one popular environment, -but the exact same code that utilizes that feature might not work -as expected---perhaps it might mean something entirely different---in -another popular environment. - -Traditionally, Fortran compilers---even portable ones---have solved this -problem by simply offering the appropriate feature to users of -the respective systems. -This approach treats users of various Fortran systems and dialects -as remote ``islands'', or camps, of programmers, and assume that these -camps rarely come into contact with each other (or, -especially, with each other's code). - -Project GNU takes a radically different approach to software and language -design, in that it assumes that users of GNU software do not necessarily -care what kind of underlying system they are using, regardless -of whether they are using software (at the user-interface -level) or writing it (for example, writing Fortran or C code). - -As such, GNU users rarely need consider just what kind of underlying -hardware (or, in many cases, operating system) they are using at any -particular time. -They can use and write software designed for a general-purpose, -widely portable, heterogenous environment---the GNU environment. - -In line with this philosophy, GNU Fortran must evolve into a product -that is widely ported and portable not only in the sense that it can -be successfully built, installed, and run by users, but in the larger -sense that its users can use it in the same way, and expect largely the -same behaviors from it, regardless of the kind of system they are using -at any particular time. - -This approach constrains the solutions @code{g77} can use to resolve -conflicts between various camps of Fortran users. -If these two camps disagree about what a particular construct should -mean, @code{g77} cannot simply be changed to treat that particular construct as -having one meaning without comment (such as a warning), lest the users -expecting it to have the other meaning are unpleasantly surprised that -their code misbehaves when executed. - -The use of the ASCII backslash character in character constants is -an excellent (and still somewhat unresolved) example of this kind of -controversy. -@xref{Backslash in Constants}. -Other examples are likely to arise in the future, as @code{g77} developers -strive to improve its ability to accept an ever-wider variety of existing -Fortran code without requiring significant modifications to said code. - -Development of GNU Fortran is further constrained by the desire -to avoid requiring programmers to change their code. -This is important because it allows programmers, administrators, -and others to more faithfully evaluate and validate @code{g77} -(as an overall product and as new versions are distributed) -without having to support multiple versions of their programs -so that they continue to work the same way on their existing -systems (non-GNU perhaps, but possibly also earlier versions -of @code{g77}). - -@node Standard Support -@section ANSI FORTRAN 77 Standard Support -@cindex ANSI FORTRAN 77 support -@cindex standard support -@cindex support for ANSI FORTRAN 77 -@cindex compatibility, FORTRAN 77 -@cindex FORTRAN 77 compatibility - -GNU Fortran supports ANSI FORTRAN 77 with the following caveats. -In summary, the only ANSI FORTRAN 77 features @code{g77} doesn't -support are those that are probably rarely used in actual code, -some of which are explicitly disallowed by the Fortran 90 standard. - -@menu -* No Passing External Assumed-length:: CHAR*(*) CFUNC restriction. -* No Passing Dummy Assumed-length:: CHAR*(*) CFUNC restriction. -* No Pathological Implied-DO:: No @samp{((@dots{}, I=@dots{}), I=@dots{})}. -* No Useless Implied-DO:: No @samp{(A, I=1, 1)}. -@end menu - -@node No Passing External Assumed-length -@subsection No Passing External Assumed-length - -@code{g77} disallows passing of an external procedure -as an actual argument if the procedure's -type is declared @code{CHARACTER*(*)}. For example: - -@example -CHARACTER*(*) CFUNC -EXTERNAL CFUNC -CALL FOO(CFUNC) -END -@end example - -@noindent -It isn't clear whether the standard considers this conforming. - -@node No Passing Dummy Assumed-length -@subsection No Passing Dummy Assumed-length - -@code{g77} disallows passing of a dummy procedure -as an actual argument if the procedure's -type is declared @code{CHARACTER*(*)}. - -@example -SUBROUTINE BAR(CFUNC) -CHARACTER*(*) CFUNC -EXTERNAL CFUNC -CALL FOO(CFUNC) -END -@end example - -@noindent -It isn't clear whether the standard considers this conforming. - -@node No Pathological Implied-DO -@subsection No Pathological Implied-DO - -The @code{DO} variable for an implied-@code{DO} construct in a -@code{DATA} statement may not be used as the @code{DO} variable -for an outer implied-@code{DO} construct. For example, this -fragment is disallowed by @code{g77}: - -@smallexample -DATA ((A(I, I), I= 1, 10), I= 1, 10) /@dots{}/ -@end smallexample - -@noindent -This also is disallowed by Fortran 90, as it offers no additional -capabilities and would have a variety of possible meanings. - -Note that it is @emph{very} unlikely that any production Fortran code -tries to use this unsupported construct. - -@node No Useless Implied-DO -@subsection No Useless Implied-DO - -An array element initializer in an implied-@code{DO} construct in a -@code{DATA} statement must contain at least one reference to the @code{DO} -variables of each outer implied-@code{DO} construct. For example, -this fragment is disallowed by @code{g77}: - -@smallexample -DATA (A, I= 1, 1) /1./ -@end smallexample - -@noindent -This also is disallowed by Fortran 90, as FORTRAN 77's more permissive -requirements offer no additional capabilities. -However, @code{g77} doesn't necessarily diagnose all cases -where this requirement is not met. - -Note that it is @emph{very} unlikely that any production Fortran code -tries to use this unsupported construct. - -@node Conformance -@section Conformance - -(The following information augments or overrides the information in -Section 1.4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 1 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -The definition of the GNU Fortran language is akin to that of -the ANSI FORTRAN 77 language in that it does not generally require -conforming implementations to diagnose cases where programs do -not conform to the language. - -However, @code{g77} as a compiler is being developed in a way that -is intended to enable it to diagnose such cases in an easy-to-understand -manner. - -A program that conforms to the GNU Fortran language should, when -compiled, linked, and executed using a properly installed @code{g77} -system, perform as described by the GNU Fortran language definition. -Reasons for different behavior include, among others: - -@itemize @bullet -@item -Use of resources (memory---heap, stack, and so on; disk space; CPU -time; etc.) exceeds those of the system. - -@item -Range and/or precision of calculations required by the program -exceeds that of the system. - -@item -Excessive reliance on behaviors that are system-dependent -(non-portable Fortran code). - -@item -Bugs in the program. - -@item -Bug in @code{g77}. - -@item -Bugs in the system. -@end itemize - -Despite these ``loopholes'', the availability of a clear specification -of the language of programs submitted to @code{g77}, as this document -is intended to provide, is considered an important aspect of providing -a robust, clean, predictable Fortran implementation. - -The definition of the GNU Fortran language, while having no special -legal status, can therefore be viewed as a sort of contract, or agreement. -This agreement says, in essence, ``if you write a program in this language, -and run it in an environment (such as a @code{g77} system) that supports -this language, the program should behave in a largely predictable way''. - -@node Notation Used -@section Notation Used in This Chapter - -(The following information augments or overrides the information in -Section 1.5 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 1 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -In this chapter, ``must'' denotes a requirement, ``may'' denotes permission, -and ``must not'' and ``may not'' denote prohibition. -Terms such as ``might'', ``should'', and ``can'' generally add little or -nothing in the way of weight to the GNU Fortran language itself, -but are used to explain or illustrate the language. - -For example: - -@display -``The @code{FROBNITZ} statement must precede all executable -statements in a program unit, and may not specify any dummy -arguments. It may specify local or common variables and arrays. -Its use should be limited to portions of the program designed to -be non-portable and system-specific, because it might cause the -containing program unit to behave quite differently on different -systems.'' -@end display - -Insofar as the GNU Fortran language is specified, -the requirements and permissions denoted by the above sample statement -are limited to the placement of the statement and the kinds of -things it may specify. -The rest of the statement---the content regarding non-portable portions -of the program and the differing behavior of program units containing -the @code{FROBNITZ} statement---does not pertain the GNU Fortran -language itself. -That content offers advice and warnings about the @code{FROBNITZ} -statement. - -@emph{Remember:} The GNU Fortran language definition specifies -both what constitutes a valid GNU Fortran program and how, -given such a program, a valid GNU Fortran implementation is -to interpret that program. - -It is @emph{not} incumbent upon a valid GNU Fortran implementation -to behave in any particular way, any consistent way, or any -predictable way when it is asked to interpret input that is -@emph{not} a valid GNU Fortran program. - -Such input is said to have @dfn{undefined} behavior when -interpreted by a valid GNU Fortran implementation, though -an implementation may choose to specify behaviors for some -cases of inputs that are not valid GNU Fortran programs. - -Other notation used herein is that of the GNU texinfo format, -which is used to generate printed hardcopy, on-line hypertext -(Info), and on-line HTML versions, all from a single source -document. -This notation is used as follows: - -@itemize @bullet -@item -Keywords defined by the GNU Fortran language are shown -in uppercase, as in: @code{COMMON}, @code{INTEGER}, and -@code{BLOCK DATA}. - -Note that, in practice, many Fortran programs are written -in lowercase---uppercase is used in this manual as a -means to readily distinguish keywords and sample Fortran-related -text from the prose in this document. - -@item -Portions of actual sample program, input, or output text -look like this: @samp{Actual program text}. - -Generally, uppercase is used for all Fortran-specific and -Fortran-related text, though this does not always include -literal text within Fortran code. - -For example: @samp{PRINT *, 'My name is Bob'}. - -@item -A metasyntactic variable---that is, a name used in this document -to serve as a placeholder for whatever text is used by the -user or programmer--appears as shown in the following example: - -``The @code{INTEGER @var{ivar}} statement specifies that -@var{ivar} is a variable or array of type @code{INTEGER}.'' - -In the above example, any valid text may be substituted for -the metasyntactic variable @var{ivar} to make the statement -apply to a specific instance, as long as the same text is -substituted for @emph{both} occurrences of @var{ivar}. - -@item -Ellipses (``@dots{}'') are used to indicate further text that -is either unimportant or expanded upon further, elsewhere. - -@item -Names of data types are in the style of Fortran 90, in most -cases. - -@xref{Kind Notation}, for information on the relationship -between Fortran 90 nomenclature (such as @code{INTEGER(KIND=1)}) -and the more traditional, less portably concise nomenclature -(such as @code{INTEGER*4}). -@end itemize - -@node Terms and Concepts -@section Fortran Terms and Concepts - -(The following information augments or overrides the information in -Chapter 2 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 2 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* Syntactic Items:: -* Statements Comments Lines:: -* Scope of Names and Labels:: -@end menu - -@node Syntactic Items -@subsection Syntactic Items - -(Corresponds to Section 2.2 of ANSI X3.9-1978 FORTRAN 77.) - -In GNU Fortran, a symbolic name is at least one character long, -and has no arbitrary upper limit on length. -However, names of entities requiring external linkage (such as -external functions, external subroutines, and @code{COMMON} areas) -might be restricted to some arbitrary length by the system. -Such a restriction is no more constrained than that of one -through six characters. - -Underscores (@samp{_}) are accepted in symbol names after the first -character (which must be a letter). - -@node Statements Comments Lines -@subsection Statements, Comments, and Lines - -(Corresponds to Section 2.3 of ANSI X3.9-1978 FORTRAN 77.) - -@cindex comments, trailing -@cindex trailing comments -Use of an exclamation point (@samp{!}) to begin a -trailing comment (a comment that extends to the end of the same -source line) is permitted under the following conditions: - -@itemize @bullet -@item -The exclamation point does not appear in column 6. -Otherwise, it is treated as an indicator of a continuation -line. - -@item -The exclamation point appears outside a character or Hollerith -constant. -Otherwise, the exclamation point is considered part of the -constant. - -@item -The exclamation point appears to the left of any other possible -trailing comment. -That is, a trailing comment may contain exclamation points -in their commentary text. -@end itemize - -@cindex semicolons -@cindex statements, separated by semicolon -Use of a semicolon (@samp{;}) as a statement separator -is permitted under the following conditions: - -@itemize @bullet -@item -The semicolon appears outside a character or Hollerith -constant. -Otherwise, the semicolon is considered part of the -constant. - -@item -The semicolon appears to the left of a trailing comment. -Otherwise, the semicolon is considered part of that -comment. - -@item -Neither a logical @code{IF} statement nor a non-construct -@code{WHERE} statement (a Fortran 90 feature) may be -followed (in the same, possibly continued, line) by -a semicolon used as a statement separator. - -This restriction avoids the confusion -that can result when reading a line such as: - -@smallexample -IF (VALIDP) CALL FOO; CALL BAR -@end smallexample - -@noindent -Some readers might think the @samp{CALL BAR} is executed -only if @samp{VALIDP} is @code{.TRUE.}, while others might -assume its execution is unconditional. - -(At present, @code{g77} does not diagnose code that -violates this restriction.) -@end itemize - -@node Scope of Names and Labels -@subsection Scope of Symbolic Names and Statement Labels -@cindex scope - -(Corresponds to Section 2.9 of ANSI X3.9-1978 FORTRAN 77.) - -Included in the list of entities that have a scope of a -program unit are construct names (a Fortran 90 feature). -@xref{Construct Names}, for more information. - -@node Characters Lines Sequence -@section Characters, Lines, and Execution Sequence - -(The following information augments or overrides the information in -Chapter 3 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 3 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* Character Set:: -* Lines:: -* Continuation Line:: -* Statements:: -* Statement Labels:: -* Order:: -* INCLUDE:: -* Cpp-style directives:: -@end menu - -@node Character Set -@subsection GNU Fortran Character Set -@cindex characters - -(Corresponds to Section 3.1 of ANSI X3.9-1978 FORTRAN 77.) - -Letters include uppercase letters (the twenty-six characters -of the English alphabet) and lowercase letters (their lowercase -equivalent). -Generally, lowercase letters may be used in place of uppercase -letters, though in character and Hollerith constants, they -are distinct. - -Special characters include: - -@itemize @bullet -@item -Semicolon (@samp{;}) - -@item -Exclamation point (@samp{!}) - -@item -Double quote (@samp{"}) - -@item -Backslash (@samp{\}) - -@item -Question mark (@samp{?}) - -@item -Hash mark (@samp{#}) - -@item -Ampersand (@samp{&}) - -@item -Percent sign (@samp{%}) - -@item -Underscore (@samp{_}) - -@item -Open angle (@samp{<}) - -@item -Close angle (@samp{>}) - -@item -The FORTRAN 77 special characters (@key{SPC}, @samp{=}, -@samp{+}, @samp{-}, @samp{*}, @samp{/}, @samp{(}, -@samp{)}, @samp{,}, @samp{.}, @samp{$}, @samp{'}, -and @samp{:}) -@end itemize - -@cindex blanks (spaces) -Note that this document refers to @key{SPC} as @dfn{space}, -while X3.9-1978 FORTRAN 77 refers to it as @dfn{blank}. - -@node Lines -@subsection Lines -@cindex lines -@cindex source file format -@cindex source form -@cindex files, source -@cindex source code -@cindex code, source -@cindex fixed form -@cindex free form - -(Corresponds to Section 3.2 of ANSI X3.9-1978 FORTRAN 77.) - -The way a Fortran compiler views source files depends entirely on the -implementation choices made for the compiler, since those choices -are explicitly left to the implementation by the published Fortran -standards. - -The GNU Fortran language mandates a view applicable to UNIX-like -text files---files that are made up of an arbitrary number of lines, -each with an arbitrary number of characters (sometimes called stream-based -files). - -This view does not apply to types of files that are specified as -having a particular number of characters on every single line (sometimes -referred to as record-based files). - -Because a ``line in a program unit is a sequence of 72 characters'', -to quote X3.9-1978, the GNU Fortran language specifies that a -stream-based text file is translated to GNU Fortran lines as follows: - -@itemize @bullet -@item -A newline in the file is the character that represents the end of -a line of text to the underlying system. -For example, on ASCII-based systems, a newline is the @key{NL} -character, which has ASCII value 12 (decimal). - -@item -Each newline in the file serves to end the line of text that precedes -it (and that does not contain a newline). - -@item -The end-of-file marker (@code{EOF}) also serves to end the line -of text that precedes it (and that does not contain a newline). - -@item -@cindex blanks (spaces) -Any line of text that is shorter than 72 characters is padded to that length -with spaces (called ``blanks'' in the standard). - -@item -Any line of text that is longer than 72 characters is truncated to that -length, but the truncated remainder must consist entirely of spaces. - -@item -Characters other than newline and the GNU Fortran character set -are invalid. -@end itemize - -For the purposes of the remainder of this description of the GNU -Fortran language, the translation described above has already -taken place, unless otherwise specified. - -The result of the above translation is that the source file appears, -in terms of the remainder of this description of the GNU Fortran language, -as if it had an arbitrary -number of 72-character lines, each character being among the GNU Fortran -character set. - -For example, if the source file itself has two newlines in a row, -the second newline becomes, after the above translation, a single -line containing 72 spaces. - -@node Continuation Line -@subsection Continuation Line -@cindex continuation lines, number of -@cindex lines, continuation -@cindex number of continuation lines -@cindex limits on continuation lines - -(Corresponds to Section 3.2.3 of ANSI X3.9-1978 FORTRAN 77.) - -A continuation line is any line that both - -@itemize @bullet -@item -Contains a continuation character, and - -@item -Contains only spaces in columns 1 through 5 -@end itemize - -A continuation character is any character of the GNU Fortran character set -other than space (@key{SPC}) or zero (@samp{0}) -in column 6, or a digit (@samp{0} through @samp{9}) in column -7 through 72 of a line that has only spaces to the left of that -digit. - -The continuation character is ignored as far as the content of -the statement is concerned. - -The GNU Fortran language places no limit on the number of -continuation lines in a statement. -In practice, the limit depends on a variety of factors, such as -available memory, statement content, and so on, but no -GNU Fortran system may impose an arbitrary limit. - -@node Statements -@subsection Statements - -(Corresponds to Section 3.3 of ANSI X3.9-1978 FORTRAN 77.) - -Statements may be written using an arbitrary number of continuation -lines. - -Statements may be separated using the semicolon (@samp{;}), except -that the logical @code{IF} and non-construct @code{WHERE} statements -may not be separated from subsequent statements using only a semicolon -as statement separator. - -The @code{END PROGRAM}, @code{END SUBROUTINE}, @code{END FUNCTION}, -and @code{END BLOCK DATA} statements are alternatives to the @code{END} -statement. -These alternatives may be written as normal statements---they are not -subject to the restrictions of the @code{END} statement. - -However, no statement other than @code{END} may have an initial line -that appears to be an @code{END} statement---even @code{END PROGRAM}, -for example, must not be written as: - -@example - END - &PROGRAM -@end example - -@node Statement Labels -@subsection Statement Labels - -(Corresponds to Section 3.4 of ANSI X3.9-1978 FORTRAN 77.) - -A statement separated from its predecessor via a semicolon may be -labeled as follows: - -@itemize @bullet -@item -The semicolon is followed by the label for the statement, -which in turn follows the label. - -@item -The label must be no more than five digits in length. - -@item -The first digit of the label for the statement is not -the first non-space character on a line. -Otherwise, that character is treated as a continuation -character. -@end itemize - -A statement may have only one label defined for it. - -@node Order -@subsection Order of Statements and Lines - -(Corresponds to Section 3.5 of ANSI X3.9-1978 FORTRAN 77.) - -Generally, @code{DATA} statements may precede executable statements. -However, specification statements pertaining to any entities -initialized by a @code{DATA} statement must precede that @code{DATA} -statement. -For example, -after @samp{DATA I/1/}, @samp{INTEGER I} is not permitted, but -@samp{INTEGER J} is permitted. - -The last line of a program unit may be an @code{END} statement, -or may be: - -@itemize @bullet -@item -An @code{END PROGRAM} statement, if the program unit is a main program. - -@item -An @code{END SUBROUTINE} statement, if the program unit is a subroutine. - -@item -An @code{END FUNCTION} statement, if the program unit is a function. - -@item -An @code{END BLOCK DATA} statement, if the program unit is a block data. -@end itemize - -@node INCLUDE -@subsection Including Source Text -@cindex INCLUDE - -Additional source text may be included in the processing of -the source file via the @code{INCLUDE} directive: - -@example -INCLUDE @var{filename} -@end example - -@noindent -The source text to be included is identified by @var{filename}, -which is a literal GNU Fortran character constant. -The meaning and interpretation of @var{filename} depends on the -implementation, but typically is a filename. - -(@code{g77} treats it as a filename that it searches for -in the current directory and/or directories specified -via the @samp{-I} command-line option.) - -The effect of the @code{INCLUDE} directive is as if the -included text directly replaced the directive in the source -file prior to interpretation of the program. -Included text may itself use @code{INCLUDE}. -The depth of nested @code{INCLUDE} references depends on -the implementation, but typically is a positive integer. - -This virtual replacement treats the statements and @code{INCLUDE} -directives in the included text as syntactically distinct from -those in the including text. - -Therefore, the first non-comment line of the included text -must not be a continuation line. -The included text must therefore have, after the non-comment -lines, either an initial line (statement), an @code{INCLUDE} -directive, or nothing (the end of the included text). - -Similarly, the including text may end the @code{INCLUDE} -directive with a semicolon or the end of the line, but it -cannot follow an @code{INCLUDE} directive at the end of its -line with a continuation line. -Thus, the last statement in an included text may not be -continued. - -Any statements between two @code{INCLUDE} directives on the -same line are treated as if they appeared in between the -respective included texts. -For example: - -@smallexample -INCLUDE 'A'; PRINT *, 'B'; INCLUDE 'C'; END PROGRAM -@end smallexample - -@noindent -If the text included by @samp{INCLUDE 'A'} constitutes -a @samp{PRINT *, 'A'} statement and the text included by -@samp{INCLUDE 'C'} constitutes a @samp{PRINT *, 'C'} statement, -then the output of the above sample program would be - -@example -A -B -C -@end example - -@noindent -(with suitable allowances for how an implementation defines -its handling of output). - -Included text must not include itself directly or indirectly, -regardless of whether the @var{filename} used to reference -the text is the same. - -Note that @code{INCLUDE} is @emph{not} a statement. -As such, it is neither a non-executable or executable -statement. -However, if the text it includes constitutes one or more -executable statements, then the placement of @code{INCLUDE} -is subject to effectively the same restrictions as those -on executable statements. - -An @code{INCLUDE} directive may be continued across multiple -lines as if it were a statement. -This permits long names to be used for @var{filename}. - -@node Cpp-style directives -@subsection Cpp-style directives -@cindex # -@cindex preprocessor - -@code{cpp} output-style @code{#} directives @xref{C Preprocessor -Output,,, cpp, The C Preprocessor}, are recognized by the compiler even -when the preprocessor isn't run on the input (as it is when compiling -@samp{.F} files). (Note the distinction between these @code{cpp} -@code{#} @emph{output} directives and @code{#line} @emph{input} -directives.) - -@node Data Types and Constants -@section Data Types and Constants - -(The following information augments or overrides the information in -Chapter 4 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 4 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -To more concisely express the appropriate types for -entities, this document uses the more concise -Fortran 90 nomenclature such as @code{INTEGER(KIND=1)} -instead of the more traditional, but less portably concise, -byte-size-based nomenclature such as @code{INTEGER*4}, -wherever reasonable. - -When referring to generic types---in contexts where the -specific precision and range of a type are not important---this -document uses the generic type names @code{INTEGER}, @code{LOGICAL}, -@code{REAL}, @code{COMPLEX}, and @code{CHARACTER}. - -In some cases, the context requires specification of a -particular type. -This document uses the @samp{KIND=} notation to accomplish -this throughout, sometimes supplying the more traditional -notation for clarification, though the traditional notation -might not work the same way on all GNU Fortran implementations. - -Use of @samp{KIND=} makes this document more concise because -@code{g77} is able to define values for @samp{KIND=} that -have the same meanings on all systems, due to the way the -Fortran 90 standard specifies these values are to be used. - -(In particular, that standard permits an implementation to -arbitrarily assign nonnegative values. -There are four distinct sets of assignments: one to the @code{CHARACTER} -type; one to the @code{INTEGER} type; one to the @code{LOGICAL} type; -and the fourth to both the @code{REAL} and @code{COMPLEX} types. -Implementations are free to assign these values in any order, -leave gaps in the ordering of assignments, and assign more than -one value to a representation.) - -This makes @samp{KIND=} values superior to the values used -in non-standard statements such as @samp{INTEGER*4}, because -the meanings of the values in those statements vary from machine -to machine, compiler to compiler, even operating system to -operating system. - -However, use of @samp{KIND=} is @emph{not} generally recommended -when writing portable code (unless, for example, the code is -going to be compiled only via @code{g77}, which is a widely -ported compiler). -GNU Fortran does not yet have adequate language constructs to -permit use of @samp{KIND=} in a fashion that would make the -code portable to Fortran 90 implementations; and, this construct -is known to @emph{not} be accepted by many popular FORTRAN 77 -implementations, so it cannot be used in code that is to be ported -to those. - -The distinction here is that this document is able to use -specific values for @samp{KIND=} to concisely document the -types of various operations and operands. - -A Fortran program should use the FORTRAN 77 designations for the -appropriate GNU Fortran types---such as @code{INTEGER} for -@code{INTEGER(KIND=1)}, @code{REAL} for @code{REAL(KIND=1)}, -and @code{DOUBLE COMPLEX} for @code{COMPLEX(KIND=2)}---and, -where no such designations exist, make use of appropriate -techniques (preprocessor macros, parameters, and so on) -to specify the types in a fashion that may be easily adjusted -to suit each particular implementation to which the program -is ported. -(These types generally won't need to be adjusted for ports of -@code{g77}.) - -Further details regarding GNU Fortran data types and constants -are provided below. - -@menu -* Types:: -* Constants:: -* Integer Type:: -* Character Type:: -@end menu - -@node Types -@subsection Data Types - -(Corresponds to Section 4.1 of ANSI X3.9-1978 FORTRAN 77.) - -GNU Fortran supports these types: - -@enumerate -@item -Integer (generic type @code{INTEGER}) - -@item -Real (generic type @code{REAL}) - -@item -Double precision - -@item -Complex (generic type @code{COMPLEX}) - -@item -Logical (generic type @code{LOGICAL}) - -@item -Character (generic type @code{CHARACTER}) - -@item -Double Complex -@end enumerate - -(The types numbered 1 through 6 above are standard FORTRAN 77 types.) - -The generic types shown above are referred to in this document -using only their generic type names. -Such references usually indicate that any specific type (kind) -of that generic type is valid. - -For example, a context described in this document as accepting -the @code{COMPLEX} type also is likely to accept the -@code{DOUBLE COMPLEX} type. - -The GNU Fortran language supports three ways to specify -a specific kind of a generic type. - -@menu -* Double Notation:: As in @code{DOUBLE COMPLEX}. -* Star Notation:: As in @code{INTEGER*4}. -* Kind Notation:: As in @code{INTEGER(KIND=1)}. -@end menu - -@node Double Notation -@subsubsection Double Notation - -The GNU Fortran language supports two uses of the keyword -@code{DOUBLE} to specify a specific kind of type: - -@itemize @bullet -@item -@code{DOUBLE PRECISION}, equivalent to @code{REAL(KIND=2)} - -@item -@code{DOUBLE COMPLEX}, equivalent to @code{COMPLEX(KIND=2)} -@end itemize - -Use one of the above forms where a type name is valid. - -While use of this notation is popular, it doesn't scale -well in a language or dialect rich in intrinsic types, -as is the case for the GNU Fortran language (especially -planned future versions of it). - -After all, one rarely sees type names such as @samp{DOUBLE INTEGER}, -@samp{QUADRUPLE REAL}, or @samp{QUARTER INTEGER}. -Instead, @code{INTEGER*8}, @code{REAL*16}, and @code{INTEGER*1} -often are substituted for these, respectively, even though they -do not always have the same meanings on all systems. -(And, the fact that @samp{DOUBLE REAL} does not exist as such -is an inconsistency.) - -Therefore, this document uses ``double notation'' only on occasion -for the benefit of those readers who are accustomed to it. - -@node Star Notation -@subsubsection Star Notation -@cindex *@var{n} notation - -The following notation specifies the storage size for a type: - -@smallexample -@var{generic-type}*@var{n} -@end smallexample - -@noindent -@var{generic-type} must be a generic type---one of -@code{INTEGER}, @code{REAL}, @code{COMPLEX}, @code{LOGICAL}, -or @code{CHARACTER}. -@var{n} must be one or more digits comprising a decimal -integer number greater than zero. - -Use the above form where a type name is valid. - -The @samp{*@var{n}} notation specifies that the amount of storage -occupied by variables and array elements of that type is @var{n} -times the storage occupied by a @code{CHARACTER*1} variable. - -This notation might indicate a different degree of precision and/or -range for such variables and array elements, and the functions that -return values of types using this notation. -It does not limit the precision or range of values of that type -in any particular way---use explicit code to do that. - -Further, the GNU Fortran language requires no particular values -for @var{n} to be supported by an implementation via the @samp{*@var{n}} -notation. -@code{g77} supports @code{INTEGER*1} (as @code{INTEGER(KIND=3)}) -on all systems, for example, -but not all implementations are required to do so, and @code{g77} -is known to not support @code{REAL*1} on most (or all) systems. - -As a result, except for @var{generic-type} of @code{CHARACTER}, -uses of this notation should be limited to isolated -portions of a program that are intended to handle system-specific -tasks and are expected to be non-portable. - -(Standard FORTRAN 77 supports the @samp{*@var{n}} notation for -only @code{CHARACTER}, where it signifies not only the amount -of storage occupied, but the number of characters in entities -of that type. -However, almost all Fortran compilers have supported this -notation for generic types, though with a variety of meanings -for @var{n}.) - -Specifications of types using the @samp{*@var{n}} notation -always are interpreted as specifications of the appropriate -types described in this document using the @samp{KIND=@var{n}} -notation, described below. - -While use of this notation is popular, it doesn't serve well -in the context of a widely portable dialect of Fortran, such as -the GNU Fortran language. - -For example, even on one particular machine, two or more popular -Fortran compilers might well disagree on the size of a type -declared @code{INTEGER*2} or @code{REAL*16}. -Certainly there -is known to be disagreement over such things among Fortran -compilers on @emph{different} systems. - -Further, this notation offers no elegant way to specify sizes -that are not even multiples of the ``byte size'' typically -designated by @code{INTEGER*1}. -Use of ``absurd'' values (such as @code{INTEGER*1000}) would -certainly be possible, but would perhaps be stretching the original -intent of this notation beyond the breaking point in terms -of widespread readability of documentation and code making use -of it. - -Therefore, this document uses ``star notation'' only on occasion -for the benefit of those readers who are accustomed to it. - -@node Kind Notation -@subsubsection Kind Notation -@cindex KIND= notation - -The following notation specifies the kind-type selector of a type: - -@smallexample -@var{generic-type}(KIND=@var{n}) -@end smallexample - -@noindent -Use the above form where a type name is valid. - -@var{generic-type} must be a generic type---one of -@code{INTEGER}, @code{REAL}, @code{COMPLEX}, @code{LOGICAL}, -or @code{CHARACTER}. -@var{n} must be an integer initialization expression that -is a positive, nonzero value. - -Programmers are discouraged from writing these values directly -into their code. -Future versions of the GNU Fortran language will offer -facilities that will make the writing of code portable -to @code{g77} @emph{and} Fortran 90 implementations simpler. - -However, writing code that ports to existing FORTRAN 77 -implementations depends on avoiding the @samp{KIND=} construct. - -The @samp{KIND=} construct is thus useful in the context -of GNU Fortran for two reasons: - -@itemize @bullet -@item -It provides a means to specify a type in a fashion that -is portable across all GNU Fortran implementations (though -not other FORTRAN 77 and Fortran 90 implementations). - -@item -It provides a sort of Rosetta stone for this document to use -to concisely describe the types of various operations and -operands. -@end itemize - -The values of @var{n} in the GNU Fortran language are -assigned using a scheme that: - -@itemize @bullet -@item -Attempts to maximize the ability of readers -of this document to quickly familiarize themselves -with assignments for popular types - -@item -Provides a unique value for each specific desired -meaning - -@item -Provides a means to automatically assign new values so -they have a ``natural'' relationship to existing values, -if appropriate, or, if no such relationship exists, will -not interfere with future values assigned on the basis -of such relationships - -@item -Avoids using values that are similar to values used -in the existing, popular @samp{*@var{n}} notation, -to prevent readers from expecting that these implied -correspondences work on all GNU Fortran implementations -@end itemize - -The assignment system accomplishes this by assigning -to each ``fundamental meaning'' of a specific type a -unique prime number. -Combinations of fundamental meanings---for example, a type -that is two times the size of some other type---are assigned -values of @var{n} that are the products of the values for -those fundamental meanings. - -A prime value of @var{n} is never given more than one fundamental -meaning, to avoid situations where some code or system -cannot reasonably provide those meanings in the form of a -single type. - -The values of @var{n} assigned so far are: - -@table @code -@item KIND=0 -This value is reserved for future use. - -The planned future use is for this value to designate, -explicitly, context-sensitive kind-type selection. -For example, the expression @samp{1D0 * 0.1_0} would -be equivalent to @samp{1D0 * 0.1D0}. - -@item KIND=1 -This corresponds to the default types for -@code{REAL}, @code{INTEGER}, @code{LOGICAL}, @code{COMPLEX}, -and @code{CHARACTER}, as appropriate. - -These are the ``default'' types described in the Fortran 90 standard, -though that standard does not assign any particular @samp{KIND=} -value to these types. - -(Typically, these are @code{REAL*4}, @code{INTEGER*4}, -@code{LOGICAL*4}, and @code{COMPLEX*8}.) - -@item KIND=2 -This corresponds to types that occupy twice as much -storage as the default types. -@code{REAL(KIND=2)} is @code{DOUBLE PRECISION} (typically @code{REAL*8}), -@code{COMPLEX(KIND=2)} is @code{DOUBLE COMPLEX} (typically @code{COMPLEX*16}), - -These are the ``double precision'' types described in the Fortran 90 -standard, -though that standard does not assign any particular @samp{KIND=} -value to these types. - -@var{n} of 4 thus corresponds to types that occupy four times -as much storage as the default types, @var{n} of 8 to types that -occupy eight times as much storage, and so on. - -The @code{INTEGER(KIND=2)} and @code{LOGICAL(KIND=2)} types -are not necessarily supported by every GNU Fortran implementation. - -@item KIND=3 -This corresponds to types that occupy as much -storage as the default @code{CHARACTER} type, -which is the same effective type as @code{CHARACTER(KIND=1)} -(making that type effectively the same as @code{CHARACTER(KIND=3)}). - -(Typically, these are @code{INTEGER*1} and @code{LOGICAL*1}.) - -@var{n} of 6 thus corresponds to types that occupy twice as -much storage as the @var{n}=3 types, @var{n} of 12 to types -that occupy four times as much storage, and so on. - -These are not necessarily supported by every GNU Fortran -implementation. - -@item KIND=5 -This corresponds to types that occupy half the -storage as the default (@var{n}=1) types. - -(Typically, these are @code{INTEGER*2} and @code{LOGICAL*2}.) - -@var{n} of 25 thus corresponds to types that occupy one-quarter -as much storage as the default types. - -These are not necessarily supported by every GNU Fortran -implementation. - -@item KIND=7 -@cindex pointers -This is valid only as @code{INTEGER(KIND=7)} and -denotes the @code{INTEGER} type that has the smallest -storage size that holds a pointer on the system. - -A pointer representable by this type is capable of uniquely -addressing a @code{CHARACTER*1} variable, array, array element, -or substring. - -(Typically this is equivalent to @code{INTEGER*4} or, -on 64-bit systems, @code{INTEGER*8}. -In a compatible C implementation, it typically would -be the same size and semantics of the C type @code{void *}.) -@end table - -Note that these are @emph{proposed} correspondences and might change -in future versions of @code{g77}---avoid writing code depending -on them while @code{g77}, and therefore the GNU Fortran language -it defines, is in beta testing. - -Values not specified in the above list are reserved to -future versions of the GNU Fortran language. - -Implementation-dependent meanings will be assigned new, -unique prime numbers so as to not interfere with other -implementation-dependent meanings, and offer the possibility -of increasing the portability of code depending on such -types by offering support for them in other GNU Fortran -implementations. - -Other meanings that might be given unique values are: - -@itemize @bullet -@item -Types that make use of only half their storage size for -representing precision and range. - -For example, some compilers offer options that cause -@code{INTEGER} types to occupy the amount of storage -that would be needed for @code{INTEGER(KIND=2)} types, but the -range remains that of @code{INTEGER(KIND=1)}. - -@item -The IEEE single floating-point type. - -@item -Types with a specific bit pattern (endianness), such as the -little-endian form of @code{INTEGER(KIND=1)}. -These could permit, conceptually, use of portable code and -implementations on data files written by existing systems. -@end itemize - -Future @emph{prime} numbers should be given meanings in as incremental -a fashion as possible, to allow for flexibility and -expressiveness in combining types. - -For example, instead of defining a prime number for little-endian -IEEE doubles, one prime number might be assigned the meaning -``little-endian'', another the meaning ``IEEE double'', and the -value of @var{n} for a little-endian IEEE double would thus -naturally be the product of those two respective assigned values. -(It could even be reasonable to have IEEE values result from the -products of prime values denoting exponent and fraction sizes -and meanings, hidden bit usage, availability and representations -of special values such as subnormals, infinities, and Not-A-Numbers -(NaNs), and so on.) - -This assignment mechanism, while not inherently required for -future versions of the GNU Fortran language, is worth using -because it could ease management of the ``space'' of supported -types much easier in the long run. - -The above approach suggests a mechanism for specifying inheritance -of intrinsic (built-in) types for an entire, widely portable -product line. -It is certainly reasonable that, unlike programmers of other languages -offering inheritance mechanisms that employ verbose names for classes -and subclasses, along with graphical browsers to elucidate the -relationships, Fortran programmers would employ -a mechanism that works by multiplying prime numbers together -and finding the prime factors of such products. - -Most of the advantages for the above scheme have been explained -above. -One disadvantage is that it could lead to the defining, -by the GNU Fortran language, of some fairly large prime numbers. -This could lead to the GNU Fortran language being declared -``munitions'' by the United States Department of Defense. - -@node Constants -@subsection Constants -@cindex constants -@cindex types, constants - -(Corresponds to Section 4.2 of ANSI X3.9-1978 FORTRAN 77.) - -A @dfn{typeless constant} has one of the following forms: - -@smallexample -'@var{binary-digits}'B -'@var{octal-digits}'O -'@var{hexadecimal-digits}'Z -'@var{hexadecimal-digits}'X -@end smallexample - -@noindent -@var{binary-digits}, @var{octal-digits}, and @var{hexadecimal-digits} -are nonempty strings of characters in the set @samp{01}, @samp{01234567}, -and @samp{0123456789ABCDEFabcdef}, respectively. -(The value for @samp{A} (and @samp{a}) is 10, for @samp{B} and @samp{b} -is 11, and so on.) - -A prefix-radix constant, such as @samp{Z'ABCD'}, can optionally be -treated as typeless. @xref{Fortran Dialect Options,, Options -Controlling Fortran Dialect}, for information on the -@samp{-ftypeless-boz} option. - -Typeless constants have values that depend on the context in which -they are used. - -All other constants, called @dfn{typed constants}, are interpreted---converted -to internal form---according to their inherent type. -Thus, context is @emph{never} a determining factor for the type, and hence -the interpretation, of a typed constant. -(All constants in the ANSI FORTRAN 77 language are typed constants.) - -For example, @samp{1} is always type @code{INTEGER(KIND=1)} in GNU -Fortran (called default INTEGER in Fortran 90), -@samp{9.435784839284958} is always type @code{REAL(KIND=1)} (even if the -additional precision specified is lost, and even when used in a -@code{REAL(KIND=2)} context), @samp{1E0} is always type @code{REAL(KIND=2)}, -and @samp{1D0} is always type @code{REAL(KIND=2)}. - -@node Integer Type -@subsection Integer Type - -(Corresponds to Section 4.3 of ANSI X3.9-1978 FORTRAN 77.) - -An integer constant also may have one of the following forms: - -@smallexample -B'@var{binary-digits}' -O'@var{octal-digits}' -Z'@var{hexadecimal-digits}' -X'@var{hexadecimal-digits}' -@end smallexample - -@noindent -@var{binary-digits}, @var{octal-digits}, and @var{hexadecimal-digits} -are nonempty strings of characters in the set @samp{01}, @samp{01234567}, -and @samp{0123456789ABCDEFabcdef}, respectively. -(The value for @samp{A} (and @samp{a}) is 10, for @samp{B} and @samp{b} -is 11, and so on.) - -@node Character Type -@subsection Character Type - -(Corresponds to Section 4.8 of ANSI X3.9-1978 FORTRAN 77.) - -@cindex double quoted character constants -A character constant may be delimited by a pair of double quotes -(@samp{"}) instead of apostrophes. -In this case, an apostrophe within the constant represents -a single apostrophe, while a double quote is represented in -the source text of the constant by two consecutive double -quotes with no intervening spaces. - -@cindex zero-length CHARACTER -@cindex null CHARACTER strings -@cindex empty CHARACTER strings -@cindex strings, empty -@cindex CHARACTER, null -A character constant may be empty (have a length of zero). - -A character constant may include a substring specification, -The value of such a constant is the value of the substring---for -example, the value of @samp{'hello'(3:5)} is the same -as the value of @samp{'llo'}. - -@node Expressions -@section Expressions - -(The following information augments or overrides the information in -Chapter 6 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 6 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* %LOC():: -@end menu - -@node %LOC() -@subsection The @code{%LOC()} Construct -@cindex %LOC() construct - -@example -%LOC(@var{arg}) -@end example - -The @code{%LOC()} construct is an expression -that yields the value of the location of its argument, -@var{arg}, in memory. -The size of the type of the expression depends on the system---typically, -it is equivalent to either @code{INTEGER(KIND=1)} or @code{INTEGER(KIND=2)}, -though it is actually type @code{INTEGER(KIND=7)}. - -The argument to @code{%LOC()} must be suitable as the -left-hand side of an assignment statement. -That is, it may not be a general expression involving -operators such as addition, subtraction, and so on, -nor may it be a constant. - -Use of @code{%LOC()} is recommended only for code that -is accessing facilities outside of GNU Fortran, such as -operating system or windowing facilities. -It is best to constrain such uses to isolated portions of -a program---portions that deal specifically and exclusively -with low-level, system-dependent facilities. -Such portions might well provide a portable interface for -use by the program as a whole, but are themselves not -portable, and should be thoroughly tested each time they -are rebuilt using a new compiler or version of a compiler. - -Do not depend on @code{%LOC()} returning a pointer that -can be safely used to @emph{define} (change) the argument. -While this might work in some circumstances, it is hard -to predict whether it will continue to work when a program -(that works using this unsafe behavior) -is recompiled using different command-line options or -a different version of @code{g77}. - -Generally, @code{%LOC()} is safe when used as an argument -to a procedure that makes use of the value of the corresponding -dummy argument only during its activation, and only when -such use is restricted to referencing (reading) the value -of the argument to @code{%LOC()}. - -@emph{Implementation Note:} Currently, @code{g77} passes -arguments (those not passed using a construct such as @code{%VAL()}) -by reference or descriptor, depending on the type of -the actual argument. -Thus, given @samp{INTEGER I}, @samp{CALL FOO(I)} would -seem to mean the same thing as @samp{CALL FOO(%VAL(%LOC(I)))}, and -in fact might compile to identical code. - -However, @samp{CALL FOO(%VAL(%LOC(I)))} emphatically means -``pass, by value, the address of @samp{I} in memory''. -While @samp{CALL FOO(I)} might use that same approach in a -particular version of @code{g77}, another version or compiler -might choose a different implementation, such as copy-in/copy-out, -to effect the desired behavior---and which will therefore not -necessarily compile to the same code as would -@samp{CALL FOO(%VAL(%LOC(I)))} -using the same version or compiler. - -@xref{Debugging and Interfacing}, for detailed information on -how this particular version of @code{g77} implements various -constructs. - -@node Specification Statements -@section Specification Statements - -(The following information augments or overrides the information in -Chapter 8 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 8 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* NAMELIST:: -* DOUBLE COMPLEX:: -@end menu - -@node NAMELIST -@subsection @code{NAMELIST} Statement -@cindex NAMELIST statement -@cindex statements, NAMELIST - -The @code{NAMELIST} statement, and related I/O constructs, are -supported by the GNU Fortran language in essentially the same -way as they are by @code{f2c}. - -This follows Fortran 90 with the restriction that on @code{NAMELIST} -input, subscripts must have the form -@smallexample -@var{subscript} [ @code{:} @var{subscript} [ @code{:} @var{stride}]] -@end smallexample -i.e.@: -@smallexample -&xx x(1:3,8:10:2)=1,2,3,4,5,6/ -@end smallexample -is allowed, but not, say, -@smallexample -&xx x(:3,8::2)=1,2,3,4,5,6/ -@end smallexample - -As an extension of the Fortran 90 form, @code{$} and @code{$END} may be -used in place of @code{&} and @code{/} in @code{NAMELIST} input, so that -@smallexample -$&xx x(1:3,8:10:2)=1,2,3,4,5,6 $end -@end smallexample -could be used instead of the example above. - -@node DOUBLE COMPLEX -@subsection @code{DOUBLE COMPLEX} Statement -@cindex DOUBLE COMPLEX - -@code{DOUBLE COMPLEX} is a type-statement (and type) that -specifies the type @code{COMPLEX(KIND=2)} in GNU Fortran. - -@node Control Statements -@section Control Statements - -(The following information augments or overrides the information in -Chapter 11 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 11 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* DO WHILE:: -* END DO:: -* Construct Names:: -* CYCLE and EXIT:: -@end menu - -@node DO WHILE -@subsection DO WHILE -@cindex DO WHILE -@cindex DO -@cindex MIL-STD 1753 - -The @code{DO WHILE} statement, a feature of both the MIL-STD 1753 and -Fortran 90 standards, is provided by the GNU Fortran language. -The Fortran 90 ``do forever'' statement comprising just @code{DO} is -also supported. - -@node END DO -@subsection END DO -@cindex END DO -@cindex MIL-STD 1753 - -The @code{END DO} statement is provided by the GNU Fortran language. - -This statement is used in one of two ways: - -@itemize @bullet -@item -The Fortran 90 meaning, in which it specifies the termination -point of a single @code{DO} loop started with a @code{DO} statement -that specifies no termination label. - -@item -The MIL-STD 1753 meaning, in which it specifies the termination -point of one or more @code{DO} loops, all of which start with a -@code{DO} statement that specify the label defined for the -@code{END DO} statement. - -This kind of @code{END DO} statement is merely a synonym for -@code{CONTINUE}, except it is permitted only when the statement -is labeled and a target of one or more labeled @code{DO} loops. - -It is expected that this use of @code{END DO} will be removed from -the GNU Fortran language in the future, though it is likely that -it will long be supported by @code{g77} as a dialect form. -@end itemize - -@node Construct Names -@subsection Construct Names -@cindex construct names - -The GNU Fortran language supports construct names as defined -by the Fortran 90 standard. -These names are local to the program unit and are defined -as follows: - -@smallexample -@var{construct-name}: @var{block-statement} -@end smallexample - -@noindent -Here, @var{construct-name} is the construct name itself; -its definition is connoted by the single colon (@samp{:}); and -@var{block-statement} is an @code{IF}, @code{DO}, -or @code{SELECT CASE} statement that begins a block. - -A block that is given a construct name must also specify the -same construct name in its termination statement: - -@example -END @var{block} @var{construct-name} -@end example - -@noindent -Here, @var{block} must be @code{IF}, @code{DO}, or @code{SELECT}, -as appropriate. - -@node CYCLE and EXIT -@subsection The @code{CYCLE} and @code{EXIT} Statements - -@cindex CYCLE statement -@cindex EXIT statement -@cindex statements, CYCLE -@cindex statements, EXIT -The @code{CYCLE} and @code{EXIT} statements specify that -the remaining statements in the current iteration of a -particular active (enclosing) @code{DO} loop are to be skipped. - -@code{CYCLE} specifies that these statements are skipped, -but the @code{END DO} statement that marks the end of the -@code{DO} loop be executed---that is, the next iteration, -if any, is to be started. -If the statement marking the end of the @code{DO} loop is -not @code{END DO}---in other words, if the loop is not -a block @code{DO}---the @code{CYCLE} statement does not -execute that statement, but does start the next iteration (if any). - -@code{EXIT} specifies that the loop specified by the -@code{DO} construct is terminated. - -The @code{DO} loop affected by @code{CYCLE} and @code{EXIT} -is the innermost enclosing @code{DO} loop when the following -forms are used: - -@example -CYCLE -EXIT -@end example - -Otherwise, the following forms specify the construct name -of the pertinent @code{DO} loop: - -@example -CYCLE @var{construct-name} -EXIT @var{construct-name} -@end example - -@code{CYCLE} and @code{EXIT} can be viewed as glorified @code{GO TO} -statements. -However, they cannot be easily thought of as @code{GO TO} statements -in obscure cases involving FORTRAN 77 loops. -For example: - -@smallexample - DO 10 I = 1, 5 - DO 10 J = 1, 5 - IF (J .EQ. 5) EXIT - DO 10 K = 1, 5 - IF (K .EQ. 3) CYCLE -10 PRINT *, 'I=', I, ' J=', J, ' K=', K -20 CONTINUE -@end smallexample - -@noindent -In particular, neither the @code{EXIT} nor @code{CYCLE} statements -above are equivalent to a @code{GO TO} statement to either label -@samp{10} or @samp{20}. - -To understand the effect of @code{CYCLE} and @code{EXIT} in the -above fragment, it is helpful to first translate it to its equivalent -using only block @code{DO} loops: - -@smallexample - DO I = 1, 5 - DO J = 1, 5 - IF (J .EQ. 5) EXIT - DO K = 1, 5 - IF (K .EQ. 3) CYCLE -10 PRINT *, 'I=', I, ' J=', J, ' K=', K - END DO - END DO - END DO -20 CONTINUE -@end smallexample - -Adding new labels allows translation of @code{CYCLE} and @code{EXIT} -to @code{GO TO} so they may be more easily understood by programmers -accustomed to FORTRAN coding: - -@smallexample - DO I = 1, 5 - DO J = 1, 5 - IF (J .EQ. 5) GOTO 18 - DO K = 1, 5 - IF (K .EQ. 3) GO TO 12 -10 PRINT *, 'I=', I, ' J=', J, ' K=', K -12 END DO - END DO -18 END DO -20 CONTINUE -@end smallexample - -@noindent -Thus, the @code{CYCLE} statement in the innermost loop skips over -the @code{PRINT} statement as it begins the next iteration of the -loop, while the @code{EXIT} statement in the middle loop ends that -loop but @emph{not} the outermost loop. - -@node Functions and Subroutines -@section Functions and Subroutines - -(The following information augments or overrides the information in -Chapter 15 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 15 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* %VAL():: -* %REF():: -* %DESCR():: -* Generics and Specifics:: -* REAL() and AIMAG() of Complex:: -* CMPLX() of DOUBLE PRECISION:: -* MIL-STD 1753:: -* f77/f2c Intrinsics:: -* Table of Intrinsic Functions:: -@end menu - -@node %VAL() -@subsection The @code{%VAL()} Construct -@cindex %VAL() construct - -@example -%VAL(@var{arg}) -@end example - -The @code{%VAL()} construct specifies that an argument, -@var{arg}, is to be passed by value, instead of by reference -or descriptor. - -@code{%VAL()} is restricted to actual arguments in -invocations of external procedures. - -Use of @code{%VAL()} is recommended only for code that -is accessing facilities outside of GNU Fortran, such as -operating system or windowing facilities. -It is best to constrain such uses to isolated portions of -a program---portions the deal specifically and exclusively -with low-level, system-dependent facilities. -Such portions might well provide a portable interface for -use by the program as a whole, but are themselves not -portable, and should be thoroughly tested each time they -are rebuilt using a new compiler or version of a compiler. - -@emph{Implementation Note:} Currently, @code{g77} passes -all arguments either by reference or by descriptor. - -Thus, use of @code{%VAL()} tends to be restricted to cases -where the called procedure is written in a language other -than Fortran that supports call-by-value semantics. -(C is an example of such a language.) - -@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, -for detailed information on -how this particular version of @code{g77} passes arguments -to procedures. - -@node %REF() -@subsection The @code{%REF()} Construct -@cindex %REF() construct - -@example -%REF(@var{arg}) -@end example - -The @code{%REF()} construct specifies that an argument, -@var{arg}, is to be passed by reference, instead of by -value or descriptor. - -@code{%REF()} is restricted to actual arguments in -invocations of external procedures. - -Use of @code{%REF()} is recommended only for code that -is accessing facilities outside of GNU Fortran, such as -operating system or windowing facilities. -It is best to constrain such uses to isolated portions of -a program---portions the deal specifically and exclusively -with low-level, system-dependent facilities. -Such portions might well provide a portable interface for -use by the program as a whole, but are themselves not -portable, and should be thoroughly tested each time they -are rebuilt using a new compiler or version of a compiler. - -Do not depend on @code{%REF()} supplying a pointer to the -procedure being invoked. -While that is a likely implementation choice, other -implementation choices are available that preserve Fortran -pass-by-reference semantics without passing a pointer to -the argument, @var{arg}. -(For example, a copy-in/copy-out implementation.) - -@emph{Implementation Note:} Currently, @code{g77} passes -all arguments -(other than variables and arrays of type @code{CHARACTER}) -by reference. -Future versions of, or dialects supported by, @code{g77} might -not pass @code{CHARACTER} functions by reference. - -Thus, use of @code{%REF()} tends to be restricted to cases -where @var{arg} is type @code{CHARACTER} but the called -procedure accesses it via a means other than the method -used for Fortran @code{CHARACTER} arguments. - -@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, for detailed information on -how this particular version of @code{g77} passes arguments -to procedures. - -@node %DESCR() -@subsection The @code{%DESCR()} Construct -@cindex %DESCR() construct - -@example -%DESCR(@var{arg}) -@end example - -The @code{%DESCR()} construct specifies that an argument, -@var{arg}, is to be passed by descriptor, instead of by -value or reference. - -@code{%DESCR()} is restricted to actual arguments in -invocations of external procedures. - -Use of @code{%DESCR()} is recommended only for code that -is accessing facilities outside of GNU Fortran, such as -operating system or windowing facilities. -It is best to constrain such uses to isolated portions of -a program---portions the deal specifically and exclusively -with low-level, system-dependent facilities. -Such portions might well provide a portable interface for -use by the program as a whole, but are themselves not -portable, and should be thoroughly tested each time they -are rebuilt using a new compiler or version of a compiler. - -Do not depend on @code{%DESCR()} supplying a pointer -and/or a length passed by value -to the procedure being invoked. -While that is a likely implementation choice, other -implementation choices are available that preserve the -pass-by-reference semantics without passing a pointer to -the argument, @var{arg}. -(For example, a copy-in/copy-out implementation.) -And, future versions of @code{g77} might change the -way descriptors are implemented, such as passing a -single argument pointing to a record containing the -pointer/length information instead of passing that same -information via two arguments as it currently does. - -@emph{Implementation Note:} Currently, @code{g77} passes -all variables and arrays of type @code{CHARACTER} -by descriptor. -Future versions of, or dialects supported by, @code{g77} might -pass @code{CHARACTER} functions by descriptor as well. - -Thus, use of @code{%DESCR()} tends to be restricted to cases -where @var{arg} is not type @code{CHARACTER} but the called -procedure accesses it via a means similar to the method -used for Fortran @code{CHARACTER} arguments. - -@xref{Procedures,,Procedures (SUBROUTINE and FUNCTION)}, for detailed information on -how this particular version of @code{g77} passes arguments -to procedures. - -@node Generics and Specifics -@subsection Generics and Specifics -@cindex generic intrinsics -@cindex intrinsics, generic - -The ANSI FORTRAN 77 language defines generic and specific -intrinsics. -In short, the distinctions are: - -@itemize @bullet -@item -@emph{Specific} intrinsics have -specific types for their arguments and a specific return -type. - -@item -@emph{Generic} intrinsics are treated, -on a case-by-case basis in the program's source code, -as one of several possible specific intrinsics. - -Typically, a generic intrinsic has a return type that -is determined by the type of one or more of its arguments. -@end itemize - -The GNU Fortran language generalizes these concepts somewhat, -especially by providing intrinsic subroutines and generic -intrinsics that are treated as either a specific intrinsic subroutine -or a specific intrinsic function (e.g. @code{SECOND}). - -However, GNU Fortran avoids generalizing this concept to -the point where existing code would be accepted as meaning -something possibly different than what was intended. - -For example, @code{ABS} is a generic intrinsic, so all working -code written using @code{ABS} of an @code{INTEGER} argument -expects an @code{INTEGER} return value. -Similarly, all such code expects that @code{ABS} of an @code{INTEGER*2} -argument returns an @code{INTEGER*2} return value. - -Yet, @code{IABS} is a @emph{specific} intrinsic that accepts only -an @code{INTEGER(KIND=1)} argument. -Code that passes something other than an @code{INTEGER(KIND=1)} -argument to @code{IABS} is not valid GNU Fortran code, because -it is not clear what the author intended. - -For example, if @samp{J} is @code{INTEGER(KIND=6)}, @samp{IABS(J)} -is not defined by the GNU Fortran language, because the programmer -might have used that construct to mean any of the following, subtly -different, things: - -@itemize @bullet -@item -Convert @samp{J} to @code{INTEGER(KIND=1)} first -(as if @samp{IABS(INT(J))} had been written). - -@item -Convert the result of the intrinsic to @code{INTEGER(KIND=1)} -(as if @samp{INT(ABS(J))} had been written). - -@item -No conversion (as if @samp{ABS(J)} had been written). -@end itemize - -The distinctions matter especially when types and values wider than -@code{INTEGER(KIND=1)} (such as @code{INTEGER(KIND=2)}), or when -operations performing more ``arithmetic'' than absolute-value, are involved. - -The following sample program is not a valid GNU Fortran program, but -might be accepted by other compilers. -If so, the output is likely to be revealing in terms of how a given -compiler treats intrinsics (that normally are specific) when they -are given arguments that do not conform to their stated requirements: - -@cindex JCB002 program -@smallexample - PROGRAM JCB002 -C Version 1: -C Modified 1997-05-21 (Burley) to accommodate compilers that implement -C INT(I1-I2) as INT(I1)-INT(I2) given INTEGER*2 I1,I2. -C -C Version 0: -C Written by James Craig Burley 1997-02-20. -C Contact via Internet email: burley@@gnu.org -C -C Purpose: -C Determine how compilers handle non-standard IDIM -C on INTEGER*2 operands, which presumably can be -C extrapolated into understanding how the compiler -C generally treats specific intrinsics that are passed -C arguments not of the correct types. -C -C If your compiler implements INTEGER*2 and INTEGER -C as the same type, change all INTEGER*2 below to -C INTEGER*1. -C - INTEGER*2 I0, I4 - INTEGER I1, I2, I3 - INTEGER*2 ISMALL, ILARGE - INTEGER*2 ITOOLG, ITWO - INTEGER*2 ITMP - LOGICAL L2, L3, L4 -C -C Find smallest INTEGER*2 number. -C - ISMALL=0 - 10 I0 = ISMALL-1 - IF ((I0 .GE. ISMALL) .OR. (I0+1 .NE. ISMALL)) GOTO 20 - ISMALL = I0 - GOTO 10 - 20 CONTINUE -C -C Find largest INTEGER*2 number. -C - ILARGE=0 - 30 I0 = ILARGE+1 - IF ((I0 .LE. ILARGE) .OR. (I0-1 .NE. ILARGE)) GOTO 40 - ILARGE = I0 - GOTO 30 - 40 CONTINUE -C -C Multiplying by two adds stress to the situation. -C - ITWO = 2 -C -C Need a number that, added to -2, is too wide to fit in I*2. -C - ITOOLG = ISMALL -C -C Use IDIM the straightforward way. -C - I1 = IDIM (ILARGE, ISMALL) * ITWO + ITOOLG -C -C Calculate result for first interpretation. -C - I2 = (INT (ILARGE) - INT (ISMALL)) * ITWO + ITOOLG -C -C Calculate result for second interpretation. -C - ITMP = ILARGE - ISMALL - I3 = (INT (ITMP)) * ITWO + ITOOLG -C -C Calculate result for third interpretation. -C - I4 = (ILARGE - ISMALL) * ITWO + ITOOLG -C -C Print results. -C - PRINT *, 'ILARGE=', ILARGE - PRINT *, 'ITWO=', ITWO - PRINT *, 'ITOOLG=', ITOOLG - PRINT *, 'ISMALL=', ISMALL - PRINT *, 'I1=', I1 - PRINT *, 'I2=', I2 - PRINT *, 'I3=', I3 - PRINT *, 'I4=', I4 - PRINT * - L2 = (I1 .EQ. I2) - L3 = (I1 .EQ. I3) - L4 = (I1 .EQ. I4) - IF (L2 .AND. .NOT.L3 .AND. .NOT.L4) THEN - PRINT *, 'Interp 1: IDIM(I*2,I*2) => IDIM(INT(I*2),INT(I*2))' - STOP - END IF - IF (L3 .AND. .NOT.L2 .AND. .NOT.L4) THEN - PRINT *, 'Interp 2: IDIM(I*2,I*2) => INT(DIM(I*2,I*2))' - STOP - END IF - IF (L4 .AND. .NOT.L2 .AND. .NOT.L3) THEN - PRINT *, 'Interp 3: IDIM(I*2,I*2) => DIM(I*2,I*2)' - STOP - END IF - PRINT *, 'Results need careful analysis.' - END -@end smallexample - -No future version of the GNU Fortran language -will likely permit specific intrinsic invocations with wrong-typed -arguments (such as @code{IDIM} in the above example), since -it has been determined that disagreements exist among -many production compilers on the interpretation of -such invocations. -These disagreements strongly suggest that Fortran programmers, -and certainly existing Fortran programs, disagree about the -meaning of such invocations. - -The first version of @samp{JCB002} didn't accommodate some compilers' -treatment of @samp{INT(I1-I2)} where @samp{I1} and @samp{I2} are -@code{INTEGER*2}. -In such a case, these compilers apparently convert both -operands to @code{INTEGER*4} and then do an @code{INTEGER*4} subtraction, -instead of doing an @code{INTEGER*2} subtraction on the -original values in @samp{I1} and @samp{I2}. - -However, the results of the careful analyses done on the outputs -of programs compiled by these various compilers show that they -all implement either @samp{Interp 1} or @samp{Interp 2} above. - -Specifically, it is believed that the new version of @samp{JCB002} -above will confirm that: - -@itemize @bullet -@item -Digital Semiconductor (``DEC'') Alpha OSF/1, HP-UX 10.0.1, AIX 3.2.5 -@code{f77} compilers all implement @samp{Interp 1}. - -@item -IRIX 5.3 @code{f77} compiler implements @samp{Interp 2}. - -@item -Solaris 2.5, SunOS 4.1.3, DECstation ULTRIX 4.3, -and IRIX 6.1 @code{f77} compilers all implement @samp{Interp 3}. -@end itemize - -If you get different results than the above for the stated -compilers, or have results for other compilers that might be -worth adding to the above list, please let us know the details -(compiler product, version, machine, results, and so on). - -@node REAL() and AIMAG() of Complex -@subsection @code{REAL()} and @code{AIMAG()} of Complex -@cindex REAL intrinsic -@cindex intrinsics, REAL -@cindex AIMAG intrinsic -@cindex intrinsics, AIMAG - -The GNU Fortran language disallows @code{REAL(@var{expr})} -and @code{AIMAG(@var{expr})}, -where @var{expr} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}, -except when they are used in the following way: - -@example -REAL(REAL(@var{expr})) -REAL(AIMAG(@var{expr})) -@end example - -@noindent -The above forms explicitly specify that the desired effect -is to convert the real or imaginary part of @var{expr}, which might -be some @code{REAL} type other than @code{REAL(KIND=1)}, -to type @code{REAL(KIND=1)}, -and have that serve as the value of the expression. - -The GNU Fortran language offers clearly named intrinsics to extract the -real and imaginary parts of a complex entity without any -conversion: - -@example -REALPART(@var{expr}) -IMAGPART(@var{expr}) -@end example - -To express the above using typical extended FORTRAN 77, -use the following constructs -(when @var{expr} is @code{COMPLEX(KIND=2)}): - -@example -DBLE(@var{expr}) -DIMAG(@var{expr}) -@end example - -The FORTRAN 77 language offers no way -to explicitly specify the real and imaginary parts of a complex expression of -arbitrary type, apparently as a result of requiring support for -only one @code{COMPLEX} type (@code{COMPLEX(KIND=1)}). -The concepts of converting an expression to type @code{REAL(KIND=1)} and -of extracting the real part of a complex expression were -thus ``smooshed'' by FORTRAN 77 into a single intrinsic, since -they happened to have the exact same effect in that language -(due to having only one @code{COMPLEX} type). - -@emph{Note:} When @samp{-ff90} is in effect, -@code{g77} treats @samp{REAL(@var{expr})}, where @var{expr} is of -type @code{COMPLEX}, as @samp{REALPART(@var{expr})}, -whereas with @samp{-fugly-complex -fno-f90} in effect, it is -treated as @samp{REAL(REALPART(@var{expr}))}. - -@xref{Ugly Complex Part Extraction}, for more information. - -@node CMPLX() of DOUBLE PRECISION -@subsection @code{CMPLX()} of @code{DOUBLE PRECISION} -@cindex CMPLX intrinsic -@cindex intrinsics, CMPLX - -In accordance with Fortran 90 and at least some (perhaps all) -other compilers, the GNU Fortran language defines @code{CMPLX()} -as always returning a result that is type @code{COMPLEX(KIND=1)}. - -This means @samp{CMPLX(D1,D2)}, where @samp{D1} and @samp{D2} -are @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}), is treated as: - -@example -CMPLX(SNGL(D1), SNGL(D2)) -@end example - -(It was necessary for Fortran 90 to specify this behavior -for @code{DOUBLE PRECISION} arguments, since that is -the behavior mandated by FORTRAN 77.) - -The GNU Fortran language also provides the @code{DCMPLX()} intrinsic, -which is provided by some FORTRAN 77 compilers to construct -a @code{DOUBLE COMPLEX} entity from of @code{DOUBLE PRECISION} -operands. -However, this solution does not scale well when more @code{COMPLEX} types -(having various precisions and ranges) are offered by Fortran implementations. - -Fortran 90 extends the @code{CMPLX()} intrinsic by adding -an extra argument used to specify the desired kind of complex -result. -However, this solution is somewhat awkward to use, and -@code{g77} currently does not support it. - -The GNU Fortran language provides a simple way to build a complex -value out of two numbers, with the precise type of the value -determined by the types of the two numbers (via the usual -type-promotion mechanism): - -@example -COMPLEX(@var{real}, @var{imag}) -@end example - -When @var{real} and @var{imag} are the same @code{REAL} types, @code{COMPLEX()} -performs no conversion other than to put them together to form a -complex result of the same (complex version of real) type. - -@xref{Complex Intrinsic}, for more information. - -@node MIL-STD 1753 -@subsection MIL-STD 1753 Support -@cindex MIL-STD 1753 - -The GNU Fortran language includes the MIL-STD 1753 intrinsics -@code{BTEST}, @code{IAND}, @code{IBCLR}, @code{IBITS}, -@code{IBSET}, @code{IEOR}, @code{IOR}, @code{ISHFT}, -@code{ISHFTC}, @code{MVBITS}, and @code{NOT}. - -@node f77/f2c Intrinsics -@subsection @code{f77}/@code{f2c} Intrinsics - -The bit-manipulation intrinsics supported by traditional -@code{f77} and by @code{f2c} are available in the GNU Fortran language. -These include @code{AND}, @code{LSHIFT}, @code{OR}, @code{RSHIFT}, -and @code{XOR}. - -Also supported are the intrinsics @code{CDABS}, -@code{CDCOS}, @code{CDEXP}, @code{CDLOG}, @code{CDSIN}, -@code{CDSQRT}, @code{DCMPLX}, @code{DCONJG}, @code{DFLOAT}, -@code{DIMAG}, @code{DREAL}, and @code{IMAG}, -@code{ZABS}, @code{ZCOS}, @code{ZEXP}, @code{ZLOG}, @code{ZSIN}, -and @code{ZSQRT}. - -@node Table of Intrinsic Functions -@subsection Table of Intrinsic Functions -@cindex intrinsics, table of -@cindex table of intrinsics - -(Corresponds to Section 15.10 of ANSI X3.9-1978 FORTRAN 77.) - -The GNU Fortran language adds various functions, subroutines, types, -and arguments to the set of intrinsic functions in ANSI FORTRAN 77. -The complete set of intrinsics supported by the GNU Fortran language -is described below. - -Note that a name is not treated as that of an intrinsic if it is -specified in an @code{EXTERNAL} statement in the same program unit; -if a command-line option is used to disable the groups to which -the intrinsic belongs; or if the intrinsic is not named in an -@code{INTRINSIC} statement and a command-line option is used to -hide the groups to which the intrinsic belongs. - -So, it is recommended that any reference in a program unit to -an intrinsic procedure that is not a standard FORTRAN 77 -intrinsic be accompanied by an appropriate @code{INTRINSIC} -statement in that program unit. -This sort of defensive programming makes it more -likely that an implementation will issue a diagnostic rather -than generate incorrect code for such a reference. - -The terminology used below is based on that of the Fortran 90 -standard, so that the text may be more concise and accurate: - -@itemize @bullet -@item -@code{OPTIONAL} means the argument may be omitted. - -@item -@samp{A-1, A-2, @dots{}, A-n} means more than one argument -(generally named @samp{A}) may be specified. - -@item -@samp{scalar} means the argument must not be an array (must -be a variable or array element, or perhaps a constant if expressions -are permitted). - -@item -@samp{DIMENSION(4)} means the argument must be an array having 4 elements. - -@item -@code{INTENT(IN)} means the argument must be an expression -(such as a constant or a variable that is defined upon invocation -of the intrinsic). - -@item -@code{INTENT(OUT)} means the argument must be definable by the -invocation of the intrinsic (that is, must not be a constant nor -an expression involving operators other than array reference and -substring reference). - -@item -@code{INTENT(INOUT)} means the argument must be defined prior to, -and definable by, invocation of the intrinsic (a combination of -the requirements of @code{INTENT(IN)} and @code{INTENT(OUT)}. - -@item -@xref{Kind Notation}, for an explanation of @code{KIND}. -@end itemize - -@ifinfo -(Note that the empty lines appearing in the menu below -are not intentional---they result from a bug in the -GNU @code{makeinfo} program@dots{}a program that, if it -did not exist, would leave this document in far worse shape!) -@end ifinfo - -@c The actual documentation for intrinsics comes from -@c intdoc.texi, which in turn is automatically generated -@c from the internal g77 tables in intrin.def _and_ the -@c largely hand-written text in intdoc.h. So, if you want -@c to change or add to existing documentation on intrinsics, -@c you probably want to edit intdoc.h. -@c -@set familyF77 -@set familyGNU -@set familyASC -@set familyMIL -@set familyF90 -@clear familyVXT -@clear familyFVZ -@set familyF2C -@set familyF2U -@clear familyBADU77 -@include intdoc.texi - -@node Scope and Classes of Names -@section Scope and Classes of Symbolic Names -@cindex symbolic names -@cindex scope - -(The following information augments or overrides the information in -Chapter 18 of ANSI X3.9-1978 FORTRAN 77 in specifying the GNU Fortran -language. -Chapter 18 of that document otherwise serves as the basis -for the relevant aspects of GNU Fortran.) - -@menu -* Underscores in Symbol Names:: -@end menu - -@node Underscores in Symbol Names -@subsection Underscores in Symbol Names -@cindex underscores - -Underscores (@samp{_}) are accepted in symbol names after the first -character (which must be a letter). - -@node I/O -@section I/O - -@cindex dollar sign -A dollar sign at the end of an output format specification suppresses -the newline at the end of the output. - -@cindex <> edit descriptor -@cindex edit descriptor, <> -Edit descriptors in @code{FORMAT} statements may contain compile-time -@code{INTEGER} constant expressions in angle brackets, such as -@smallexample -10 FORMAT (I<WIDTH>) -@end smallexample - -The @code{OPEN} specifier @code{NAME=} is equivalent to @code{FILE=}. - -These Fortran 90 features are supported: -@itemize @bullet -@item -@cindex Z edit descriptor -@cindex edit descriptor, Z -The @code{Z} edit descriptor is supported. -@item -The @code{FILE=} specifier may be omitted in an @code{OPEN} statement if -@code{STATUS='SCRATCH'} is supplied. The @code{STATUS='REPLACE'} -specifier is supported. -@end itemize - -@node Fortran 90 Features -@section Fortran 90 Features -@cindex Fortran 90 - -For convenience this section collects a list (probably incomplete) of -the Fortran 90 features supported by the GNU Fortran language, even if -they are documented elsewhere. -@c makeinfo 1.68 objects to the nested parens -@ifnotinfo -@xref{Characters Lines Sequence,,{Characters, Lines, and Execution Sequence}}, -@end ifnotinfo -@ifinfo -@xref{Characters Lines Sequence}, -@end ifinfo -for information on additional fixed source form lexical issues. In -addition, the free source form is supported through the -@cindex @samp{-ffree-form} -@samp{-ffree-form} option. Other Fortran 90 features can be turned on -by the -@cindex @samp{-ff90} -@samp{-ff90} option, @ref{Fortran 90}. For information on the Fortran -90 intrinsics available @ref{Table of Intrinsic Functions}. - -@table @asis -@item Automatic arrays in procedures -@item Character assignments -@cindex character assignments -In character assignments, the variable being assigned may occur on the -right hand side of the assignment. -@item Character strings -@cindex double quoted character constants -Strings may have zero length and substrings of character constants are -permitted. Character constants may be enclosed in double quotes -(@code{"}) as well as single quotes. @xref{Character Type}. -@item Construct names -(Symbolic tags on blocks.) @xref{Construct Names }. -@item @code{CYCLE} and @code{EXIT} -@xref{CYCLE and EXIT,,The @code{CYCLE} and @code{EXIT} Statements}. -@item @code{DOUBLE COMPLEX} -@xref{DOUBLE COMPLEX,,@code{DOUBLE COMPLEX} Statement -}. -@item @code{DO WHILE} -@xref{DO WHILE}. -@item @code{END} decoration -@xref{Statements}. -@item @code{END DO} -@xref{END DO}. -@item @code{KIND} -@item @code{IMPLICIT NONE} -@item @code{INCLUDE} statements -@xref{INCLUDE}. -@item List directed and namelist i/o on internal files -@item Binary, octal and hexadecimal constants -These are supported more generally than required by Fortran 90. -@xref{Integer Type}. -@item @code{NAMELIST} -@xref{NAMELIST}. -@item @code{OPEN} specifiers -@code{STATUS='REPLACE'} is supported. -@item Relational operators -The operators @code{<}, @code{<=}, @code{==}, @code{/=}, @code{>} and -@code{>=} may be used instead of @code{.LT.}, @code{.LE.}, @code{.EQ.}, -@code{.NE.}, @code{.GT.} and @code{.GE.} respectively. -@item @code{SELECT CASE} -Not fully implemented. @xref{SELECT CASE on CHARACTER Type,, -@code{SELECT CASE} on @code{CHARACTER} Type}. -@item Specification statements -A limited subset of the Fortran 90 syntax and semantics for variable -declarations is supported, including @code{KIND}. @xref{Kind Notation}. -(@code{KIND} is of limited usefulness in the absence of the -@code{KIND}-related intrinsics, since these intrinsics permit writing -more widely portable code.) An example of supported @code{KIND} usage -is: -@smallexample -INTEGER (KIND=1) :: FOO=1, BAR=2 -CHARACTER (LEN=3) FOO -@end smallexample -@code{PARAMETER} and @code{DIMENSION} attributes aren't supported. -@end table - -@node Other Dialects -@chapter Other Dialects - -GNU Fortran supports a variety of features that are not -considered part of the GNU Fortran language itself, but -are representative of various dialects of Fortran that -@code{g77} supports in whole or in part. - -Any of the features listed below might be disallowed by -@code{g77} unless some command-line option is specified. -Currently, some of the features are accepted using the -default invocation of @code{g77}, but that might change -in the future. - -@emph{Note: This portion of the documentation definitely needs a lot -of work!} - -@menu -* Source Form:: Details of fixed-form and free-form source. -* Trailing Comment:: Use of @samp{/*} to start a comment. -* Debug Line:: Use of @samp{D} in column 1. -* Dollar Signs:: Use of @samp{$} in symbolic names. -* Case Sensitivity:: Uppercase and lowercase in source files. -* VXT Fortran:: @dots{}versus the GNU Fortran language. -* Fortran 90:: @dots{}versus the GNU Fortran language. -* Pedantic Compilation:: Enforcing the standard. -* Distensions:: Misfeatures supported by GNU Fortran. -@end menu - -@node Source Form -@section Source Form -@cindex source file format -@cindex source form -@cindex files, source -@cindex source code -@cindex code, source -@cindex fixed form -@cindex free form - -GNU Fortran accepts programs written in either fixed form or -free form. - -Fixed form -corresponds to ANSI FORTRAN 77 (plus popular extensions, such as -allowing tabs) and Fortran 90's fixed form. - -Free form corresponds to -Fortran 90's free form (though possibly not entirely up-to-date, and -without complaining about some things that for which Fortran 90 requires -diagnostics, such as the spaces in the constant in @samp{R = 3 . 1}). - -The way a Fortran compiler views source files depends entirely on the -implementation choices made for the compiler, since those choices -are explicitly left to the implementation by the published Fortran -standards. -GNU Fortran currently tries to be somewhat like a few popular compilers -(@code{f2c}, Digital (``DEC'') Fortran, and so on), though a cleaner default -definition along with more -flexibility offered by command-line options is likely to be offered -in version 0.6. - -This section describes how @code{g77} interprets source lines. - -@menu -* Carriage Returns:: Carriage returns ignored. -* Tabs:: Tabs converted to spaces. -* Short Lines:: Short lines padded with spaces (fixed-form only). -* Long Lines:: Long lines truncated. -* Ampersands:: Special Continuation Lines. -@end menu - -@node Carriage Returns -@subsection Carriage Returns -@cindex carriage returns - -Carriage returns (@samp{\r}) in source lines are ignored. -This is somewhat different from @code{f2c}, which seems to treat them as -spaces outside character/Hollerith constants, and encodes them as @samp{\r} -inside such constants. - -@node Tabs -@subsection Tabs -@cindex tab characters - -A source line with a @key{TAB} character anywhere in it is treated as -entirely significant---however long it is---instead of ending in -column 72 (for fixed-form source) or 132 (for free-form source). -This also is different from @code{f2c}, which encodes tabs as -@samp{\t} (the ASCII @key{TAB} character) inside character -and Hollerith constants, but nevertheless seems to treat the column -position as if it had been affected by the canonical tab positioning. - -@code{g77} effectively -translates tabs to the appropriate number of spaces (a la the default -for the UNIX @code{expand} command) before doing any other processing, other -than (currently) noting whether a tab was found on a line and using this -information to decide how to interpret the length of the line and continued -constants. - -Note that this default behavior probably will change for version 0.6, -when it will presumably be available via a command-line option. -The default as of version 0.6 is planned to be a ``pure visual'' -model, where tabs are immediately -converted to spaces and otherwise have no effect, so the way a typical -user sees source lines produces a consistent result no matter how the -spacing in those source lines is actually implemented via tabs, spaces, -and trailing tabs/spaces before newline. -Command-line options are likely to be added to specify whether all or -just-tabbed lines are to be extended to 132 or full input-line length, -and perhaps even an option will be added to specify the truncated-line -behavior to which some Digital compilers default (and which affects -the way continued character/Hollerith constants are interpreted). - -@node Short Lines -@subsection Short Lines -@cindex short source lines -@cindex space-padding -@cindex spaces -@cindex source lines, short -@cindex lines, short - -Source lines shorter than the applicable fixed-form length are treated as -if they were padded with spaces to that length. -(None of this is relevant to source files written in free form.) - -This affects only -continued character and Hollerith constants, and is a different -interpretation than provided by some other popular compilers -(although a bit more consistent with the traditional punched-card -basis of Fortran and the way the Fortran standard expressed fixed -source form). - -@code{g77} might someday offer an option to warn about cases where differences -might be seen as a result of this treatment, and perhaps an option to -specify the alternate behavior as well. - -Note that this padding cannot apply to lines that are effectively of -infinite length---such lines are specified using command-line options -like @samp{-ffixed-line-length-none}, for example. - -@node Long Lines -@subsection Long Lines -@cindex long source lines -@cindex truncation -@cindex lines, long -@cindex source lines, long - -Source lines longer than the applicable length are truncated to that -length. -Currently, @code{g77} does not warn if the truncated characters are -not spaces, to accommodate existing code written for systems that -treated truncated text as commentary (especially in columns 73 through 80). - -@xref{Fortran Dialect Options,,Options Controlling Fortran Dialect}, -for information on the @samp{-ffixed-line-length-@var{n}} option, -which can be used to set the line length applicable to fixed-form -source files. - -@node Ampersands -@subsection Ampersand Continuation Line -@cindex ampersand continuation line -@cindex continuation line, ampersand - -A @samp{&} in column 1 of fixed-form source denotes an arbitrary-length -continuation line, imitating the behavior of @code{f2c}. - -@node Trailing Comment -@section Trailing Comment - -@cindex trailing comment -@cindex comment, trailing -@cindex /* -@code{g77} supports use of @samp{/*} to start a trailing -comment. -In the GNU Fortran language, @samp{!} is used for this purpose. - -@samp{/*} is not in the GNU Fortran language -because the use of @samp{/*} in a program might -suggest to some readers that a block, not trailing, comment is -started (and thus ended by @samp{*/}, not end of line), -since that is the meaning of @samp{/*} in C. - -Also, such readers might think they can use @samp{//} to start -a trailing comment as an alternative to @samp{/*}, but -@samp{//} already denotes concatenation, and such a ``comment'' -might actually result in a program that compiles without -error (though it would likely behave incorrectly). - -@node Debug Line -@section Debug Line -@cindex debug line -@cindex comment line, debug - -Use of @samp{D} or @samp{d} as the first character (column 1) of -a source line denotes a debug line. - -In turn, a debug line is treated as either a comment line -or a normal line, depending on whether debug lines are enabled. - -When treated as a comment line, a line beginning with @samp{D} or -@samp{d} is treated as if it the first character was @samp{C} or @samp{c}, respectively. -When treated as a normal line, such a line is treated as if -the first character was @key{SPC} (space). - -(Currently, @code{g77} provides no means for treating debug -lines as normal lines.) - -@node Dollar Signs -@section Dollar Signs in Symbol Names -@cindex dollar sign -@cindex $ - -Dollar signs (@samp{$}) are allowed in symbol names (after the first character) -when the @samp{-fdollar-ok} option is specified. - -@node Case Sensitivity -@section Case Sensitivity -@cindex case sensitivity -@cindex source file format -@cindex code, source -@cindex source code -@cindex uppercase letters -@cindex lowercase letters -@cindex letters, uppercase -@cindex letters, lowercase - -GNU Fortran offers the programmer way too much flexibility in deciding -how source files are to be treated vis-a-vis uppercase and lowercase -characters. -There are 66 useful settings that affect case sensitivity, plus 10 -settings that are nearly useless, with the remaining 116 settings -being either redundant or useless. - -None of these settings have any effect on the contents of comments -(the text after a @samp{c} or @samp{C} in Column 1, for example) -or of character or Hollerith constants. -Note that things like the @samp{E} in the statement -@samp{CALL FOO(3.2E10)} and the @samp{TO} in @samp{ASSIGN 10 TO LAB} -are considered built-in keywords, and so are affected by -these settings. - -Low-level switches are identified in this section as follows: - -@itemize @w{} -@item A -Source Case Conversion: - -@itemize @w{} -@item 0 -Preserve (see Note 1) -@item 1 -Convert to Upper Case -@item 2 -Convert to Lower Case -@end itemize - -@item B -Built-in Keyword Matching: - -@itemize @w{} -@item 0 -Match Any Case (per-character basis) -@item 1 -Match Upper Case Only -@item 2 -Match Lower Case Only -@item 3 -Match InitialCaps Only (see tables for spellings) -@end itemize - -@item C -Built-in Intrinsic Matching: - -@itemize @w{} -@item 0 -Match Any Case (per-character basis) -@item 1 -Match Upper Case Only -@item 2 -Match Lower Case Only -@item 3 -Match InitialCaps Only (see tables for spellings) -@end itemize - -@item D -User-defined Symbol Possibilities (warnings only): - -@itemize @w{} -@item 0 -Allow Any Case (per-character basis) -@item 1 -Allow Upper Case Only -@item 2 -Allow Lower Case Only -@item 3 -Allow InitialCaps Only (see Note 2) -@end itemize -@end itemize - -Note 1: @code{g77} eventually will support @code{NAMELIST} in a manner that is -consistent with these source switches---in the sense that input will be -expected to meet the same requirements as source code in terms -of matching symbol names and keywords (for the exponent letters). - -Currently, however, @code{NAMELIST} is supported by @code{libg2c}, -which uppercases @code{NAMELIST} input and symbol names for matching. -This means not only that @code{NAMELIST} output currently shows symbol -(and keyword) names in uppercase even if lower-case source -conversion (option A2) is selected, but that @code{NAMELIST} cannot be -adequately supported when source case preservation (option A0) -is selected. - -If A0 is selected, a warning message will be -output for each @code{NAMELIST} statement to this effect. -The behavior -of the program is undefined at run time if two or more symbol names -appear in a given @code{NAMELIST} such that the names are identical -when converted to upper case (e.g. @samp{NAMELIST /X/ VAR, Var, var}). -For complete and total elegance, perhaps there should be a warning -when option A2 is selected, since the output of NAMELIST is currently -in uppercase but will someday be lowercase (when a @code{libg77} is written), -but that seems to be overkill for a product in beta test. - -Note 2: Rules for InitialCaps names are: - -@itemize -- -@item -Must be a single uppercase letter, @strong{or} -@item -Must start with an uppercase letter and contain at least one -lowercase letter. -@end itemize - -So @samp{A}, @samp{Ab}, @samp{ABc}, @samp{AbC}, and @samp{Abc} are -valid InitialCaps names, but @samp{AB}, @samp{A2}, and @samp{ABC} are -not. -Note that most, but not all, built-in names meet these -requirements---the exceptions are some of the two-letter format -specifiers, such as @samp{BN} and @samp{BZ}. - -Here are the names of the corresponding command-line options: - -@smallexample -A0: -fsource-case-preserve -A1: -fsource-case-upper -A2: -fsource-case-lower - -B0: -fmatch-case-any -B1: -fmatch-case-upper -B2: -fmatch-case-lower -B3: -fmatch-case-initcap - -C0: -fintrin-case-any -C1: -fintrin-case-upper -C2: -fintrin-case-lower -C3: -fintrin-case-initcap - -D0: -fsymbol-case-any -D1: -fsymbol-case-upper -D2: -fsymbol-case-lower -D3: -fsymbol-case-initcap -@end smallexample - -Useful combinations of the above settings, along with abbreviated -option names that set some of these combinations all at once: - -@smallexample - 1: A0-- B0--- C0--- D0--- -fcase-preserve - 2: A0-- B0--- C0--- D-1-- - 3: A0-- B0--- C0--- D--2- - 4: A0-- B0--- C0--- D---3 - 5: A0-- B0--- C-1-- D0--- - 6: A0-- B0--- C-1-- D-1-- - 7: A0-- B0--- C-1-- D--2- - 8: A0-- B0--- C-1-- D---3 - 9: A0-- B0--- C--2- D0--- -10: A0-- B0--- C--2- D-1-- -11: A0-- B0--- C--2- D--2- -12: A0-- B0--- C--2- D---3 -13: A0-- B0--- C---3 D0--- -14: A0-- B0--- C---3 D-1-- -15: A0-- B0--- C---3 D--2- -16: A0-- B0--- C---3 D---3 -17: A0-- B-1-- C0--- D0--- -18: A0-- B-1-- C0--- D-1-- -19: A0-- B-1-- C0--- D--2- -20: A0-- B-1-- C0--- D---3 -21: A0-- B-1-- C-1-- D0--- -22: A0-- B-1-- C-1-- D-1-- -fcase-strict-upper -23: A0-- B-1-- C-1-- D--2- -24: A0-- B-1-- C-1-- D---3 -25: A0-- B-1-- C--2- D0--- -26: A0-- B-1-- C--2- D-1-- -27: A0-- B-1-- C--2- D--2- -28: A0-- B-1-- C--2- D---3 -29: A0-- B-1-- C---3 D0--- -30: A0-- B-1-- C---3 D-1-- -31: A0-- B-1-- C---3 D--2- -32: A0-- B-1-- C---3 D---3 -33: A0-- B--2- C0--- D0--- -34: A0-- B--2- C0--- D-1-- -35: A0-- B--2- C0--- D--2- -36: A0-- B--2- C0--- D---3 -37: A0-- B--2- C-1-- D0--- -38: A0-- B--2- C-1-- D-1-- -39: A0-- B--2- C-1-- D--2- -40: A0-- B--2- C-1-- D---3 -41: A0-- B--2- C--2- D0--- -42: A0-- B--2- C--2- D-1-- -43: A0-- B--2- C--2- D--2- -fcase-strict-lower -44: A0-- B--2- C--2- D---3 -45: A0-- B--2- C---3 D0--- -46: A0-- B--2- C---3 D-1-- -47: A0-- B--2- C---3 D--2- -48: A0-- B--2- C---3 D---3 -49: A0-- B---3 C0--- D0--- -50: A0-- B---3 C0--- D-1-- -51: A0-- B---3 C0--- D--2- -52: A0-- B---3 C0--- D---3 -53: A0-- B---3 C-1-- D0--- -54: A0-- B---3 C-1-- D-1-- -55: A0-- B---3 C-1-- D--2- -56: A0-- B---3 C-1-- D---3 -57: A0-- B---3 C--2- D0--- -58: A0-- B---3 C--2- D-1-- -59: A0-- B---3 C--2- D--2- -60: A0-- B---3 C--2- D---3 -61: A0-- B---3 C---3 D0--- -62: A0-- B---3 C---3 D-1-- -63: A0-- B---3 C---3 D--2- -64: A0-- B---3 C---3 D---3 -fcase-initcap -65: A-1- B01-- C01-- D01-- -fcase-upper -66: A--2 B0-2- C0-2- D0-2- -fcase-lower -@end smallexample - -Number 22 is the ``strict'' ANSI FORTRAN 77 model wherein all input -(except comments, character constants, and Hollerith strings) must -be entered in uppercase. -Use @samp{-fcase-strict-upper} to specify this -combination. - -Number 43 is like Number 22 except all input must be lowercase. Use -@samp{-fcase-strict-lower} to specify this combination. - -Number 65 is the ``classic'' ANSI FORTRAN 77 model as implemented on many -non-UNIX machines whereby all the source is translated to uppercase. -Use @samp{-fcase-upper} to specify this combination. - -Number 66 is the ``canonical'' UNIX model whereby all the source is -translated to lowercase. -Use @samp{-fcase-lower} to specify this combination. - -There are a few nearly useless combinations: - -@smallexample -67: A-1- B01-- C01-- D--2- -68: A-1- B01-- C01-- D---3 -69: A-1- B01-- C--23 D01-- -70: A-1- B01-- C--23 D--2- -71: A-1- B01-- C--23 D---3 -72: A--2 B01-- C0-2- D-1-- -73: A--2 B01-- C0-2- D---3 -74: A--2 B01-- C-1-3 D0-2- -75: A--2 B01-- C-1-3 D-1-- -76: A--2 B01-- C-1-3 D---3 -@end smallexample - -The above allow some programs to be compiled but with restrictions that -make most useful programs impossible: Numbers 67 and 72 warn about -@emph{any} user-defined symbol names (such as @samp{SUBROUTINE FOO}); -Numbers -68 and 73 warn about any user-defined symbol names longer than one -character that don't have at least one non-alphabetic character after -the first; -Numbers 69 and 74 disallow any references to intrinsics; -and Numbers 70, 71, 75, and 76 are combinations of the restrictions in -67+69, 68+69, 72+74, and 73+74, respectively. - -All redundant combinations are shown in the above tables anyplace -where more than one setting is shown for a low-level switch. -For example, @samp{B0-2-} means either setting 0 or 2 is valid for switch B. -The ``proper'' setting in such a case is the one that copies the setting -of switch A---any other setting might slightly reduce the speed of -the compiler, though possibly to an unmeasurable extent. - -All remaining combinations are useless in that they prevent successful -compilation of non-null source files (source files with something other -than comments). - -@node VXT Fortran -@section VXT Fortran - -@cindex VXT extensions -@cindex extensions, VXT -@code{g77} supports certain constructs that -have different meanings in VXT Fortran than they -do in the GNU Fortran language. - -Generally, this manual uses the invented term VXT Fortran to refer -VAX FORTRAN (circa v4). -That compiler offered many popular features, though not necessarily -those that are specific to the VAX processor architecture, -the VMS operating system, -or Digital Equipment Corporation's Fortran product line. -(VAX and VMS probably are trademarks of Digital Equipment -Corporation.) - -An extension offered by a Digital Fortran product that also is -offered by several other Fortran products for different kinds of -systems is probably going to be considered for inclusion in @code{g77} -someday, and is considered a VXT Fortran feature. - -The @samp{-fvxt} option generally specifies that, where -the meaning of a construct is ambiguous (means one thing -in GNU Fortran and another in VXT Fortran), the VXT Fortran -meaning is to be assumed. - -@menu -* Double Quote Meaning:: @samp{"2000} as octal constant. -* Exclamation Point:: @samp{!} in column 6. -@end menu - -@node Double Quote Meaning -@subsection Meaning of Double Quote -@cindex double quotes -@cindex character constants -@cindex constants, character -@cindex octal constants -@cindex constants, octal - -@code{g77} treats double-quote (@samp{"}) -as beginning an octal constant of @code{INTEGER(KIND=1)} type -when the @code{-fvxt} option is specified. -The form of this octal constant is - -@example -"@var{octal-digits} -@end example - -@noindent -where @var{octal-digits} is a nonempty string of characters in -the set @samp{01234567}. - -For example, the @code{-fvxt} option permits this: - -@example -PRINT *, "20 -END -@end example - -@noindent -The above program would print the value @samp{16}. - -@xref{Integer Type}, for information on the preferred construct -for integer constants specified using GNU Fortran's octal notation. - -(In the GNU Fortran language, the double-quote character (@samp{"}) -delimits a character constant just as does apostrophe (@samp{'}). -There is no way to allow -both constructs in the general case, since statements like -@samp{PRINT *,"2000 !comment?"} would be ambiguous.) - -@node Exclamation Point -@subsection Meaning of Exclamation Point in Column 6 -@cindex exclamation points -@cindex continuation character -@cindex characters, continuation -@cindex comment character -@cindex characters, comment - -@code{g77} treats an exclamation point (@samp{!}) in column 6 of -a fixed-form source file -as a continuation character rather than -as the beginning of a comment -(as it does in any other column) -when the @code{-fvxt} option is specified. - -The following program, when run, prints a message indicating -whether it is interpreted according to GNU Fortran (and Fortran 90) -rules or VXT Fortran rules: - -@smallexample -C234567 (This line begins in column 1.) - I = 0 - !1 - IF (I.EQ.0) PRINT *, ' I am a VXT Fortran program' - IF (I.EQ.1) PRINT *, ' I am a Fortran 90 program' - IF (I.LT.0 .OR. I.GT.1) PRINT *, ' I am a HAL 9000 computer' - END -@end smallexample - -(In the GNU Fortran and Fortran 90 languages, exclamation point is -a valid character and, unlike space (@key{SPC}) or zero (@samp{0}), -marks a line as a continuation line when it appears in column 6.) - -@node Fortran 90 -@section Fortran 90 -@cindex compatibility, Fortran 90 -@cindex Fortran 90 compatibility - -The GNU Fortran language includes a number of features that are -part of Fortran 90, even when the @samp{-ff90} option is not specified. -The features enabled by @samp{-ff90} are intended to be those that, -when @samp{-ff90} is not specified, would have another -meaning to @code{g77}---usually meaning something invalid in the -GNU Fortran language. - -So, the purpose of @samp{-ff90} is not to specify whether @code{g77} is -to gratuitously reject Fortran 90 constructs. -The @samp{-pedantic} option specified with @samp{-fno-f90} is intended -to do that, although its implementation is certainly incomplete at -this point. - -When @samp{-ff90} is specified: - -@itemize @bullet -@item -The type of @samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})}, -where @var{expr} is @code{COMPLEX} type, -is the same type as the real part of @var{expr}. - -For example, assuming @samp{Z} is type @code{COMPLEX(KIND=2)}, -@samp{REAL(Z)} would return a value of type @code{REAL(KIND=2)}, -not of type @code{REAL(KIND=1)}, since @samp{-ff90} is specified. -@end itemize - -@node Pedantic Compilation -@section Pedantic Compilation -@cindex pedantic compilation -@cindex compilation, pedantic - -The @samp{-fpedantic} command-line option specifies that @code{g77} -is to warn about code that is not standard-conforming. -This is useful for finding -some extensions @code{g77} accepts that other compilers might not accept. -(Note that the @samp{-pedantic} and @samp{-pedantic-errors} options -always imply @samp{-fpedantic}.) - -With @samp{-fno-f90} in force, ANSI FORTRAN 77 is used as the standard -for conforming code. -With @samp{-ff90} in force, Fortran 90 is used. - -The constructs for which @code{g77} issues diagnostics when @samp{-fpedantic} -and @samp{-fno-f90} are in force are: - -@itemize @bullet -@item -Automatic arrays, as in - -@example -SUBROUTINE X(N) -REAL A(N) -@dots{} -@end example - -@noindent -where @samp{A} is not listed in any @code{ENTRY} statement, -and thus is not a dummy argument. - -@item -The commas in @samp{READ (5), I} and @samp{WRITE (10), J}. - -These commas are disallowed by FORTRAN 77, but, while strictly -superfluous, are syntactically elegant, -especially given that commas are required in statements such -as @samp{READ 99, I} and @samp{PRINT *, J}. -Many compilers permit the superfluous commas for this reason. - -@item -@code{DOUBLE COMPLEX}, either explicitly or implicitly. - -An explicit use of this type is via a @code{DOUBLE COMPLEX} or -@code{IMPLICIT DOUBLE COMPLEX} statement, for examples. - -An example of an implicit use is the expression @samp{C*D}, -where @samp{C} is @code{COMPLEX(KIND=1)} -and @samp{D} is @code{DOUBLE PRECISION}. -This expression is prohibited by ANSI FORTRAN 77 -because the rules of promotion would suggest that it -produce a @code{DOUBLE COMPLEX} result---a type not -provided for by that standard. - -@item -Automatic conversion of numeric -expressions to @code{INTEGER(KIND=1)} in contexts such as: - -@itemize -- -@item -Array-reference indexes. -@item -Alternate-return values. -@item -Computed @code{GOTO}. -@item -@code{FORMAT} run-time expressions (not yet supported). -@item -Dimension lists in specification statements. -@item -Numbers for I/O statements (such as @samp{READ (UNIT=3.2), I}) -@item -Sizes of @code{CHARACTER} entities in specification statements. -@item -Kind types in specification entities (a Fortran 90 feature). -@item -Initial, terminal, and incrementation parameters for implied-@code{DO} -constructs in @code{DATA} statements. -@end itemize - -@item -Automatic conversion of @code{LOGICAL} expressions to @code{INTEGER} -in contexts such as arithmetic @code{IF} (where @code{COMPLEX} -expressions are disallowed anyway). - -@item -Zero-size array dimensions, as in: - -@example -INTEGER I(10,20,4:2) -@end example - -@item -Zero-length @code{CHARACTER} entities, as in: - -@example -PRINT *, '' -@end example - -@item -Substring operators applied to character constants and named -constants, as in: - -@example -PRINT *, 'hello'(3:5) -@end example - -@item -Null arguments passed to statement function, as in: - -@example -PRINT *, FOO(,3) -@end example - -@item -Disagreement among program units regarding whether a given @code{COMMON} -area is @code{SAVE}d (for targets where program units in a single source -file are ``glued'' together as they typically are for UNIX development -environments). - -@item -Disagreement among program units regarding the size of a -named @code{COMMON} block. - -@item -Specification statements following first @code{DATA} statement. - -(In the GNU Fortran language, @samp{DATA I/1/} may be followed by @samp{INTEGER J}, -but not @samp{INTEGER I}. -The @samp{-fpedantic} option disallows both of these.) - -@item -Semicolon as statement separator, as in: - -@example -CALL FOO; CALL BAR -@end example -@c -@c @item -@c Comma before list of I/O items in @code{WRITE} -@c @c, @code{ENCODE}, @code{DECODE}, and @code{REWRITE} -@c statements, as with @code{READ} (as explained above). - -@item -Use of @samp{&} in column 1 of fixed-form source (to indicate continuation). - -@item -Use of @code{CHARACTER} constants to initialize numeric entities, and vice -versa. - -@item -Expressions having two arithmetic operators in a row, such -as @samp{X*-Y}. -@end itemize - -If @samp{-fpedantic} is specified along with @samp{-ff90}, the -following constructs result in diagnostics: - -@itemize @bullet -@item -Use of semicolon as a statement separator on a line -that has an @code{INCLUDE} directive. -@end itemize - -@node Distensions -@section Distensions -@cindex distensions -@cindex ugly features -@cindex features, ugly - -The @samp{-fugly-*} command-line options determine whether certain -features supported by VAX FORTRAN and other such compilers, but considered -too ugly to be in code that can be changed to use safer and/or more -portable constructs, are accepted. -These are humorously referred to as ``distensions'', -extensions that just plain look ugly in the harsh light of day. - -@emph{Note:} The @samp{-fugly} option, which currently serves -as shorthand to enable all of the distensions below, is likely to -be removed in a future version of @code{g77}. -That's because it's likely new distensions will be added that -conflict with existing ones in terms of assigning meaning to -a given chunk of code. -(Also, it's pretty clear that users should not use @samp{-fugly} -as shorthand when the next release of @code{g77} might add a -distension to that that causes their existing code, when recompiled, -to behave differently---perhaps even fail to compile or run -correctly.) - -@menu -* Ugly Implicit Argument Conversion:: Disabled via @samp{-fno-ugly-args}. -* Ugly Assumed-Size Arrays:: Enabled via @samp{-fugly-assumed}. -* Ugly Null Arguments:: Enabled via @samp{-fugly-comma}. -* Ugly Complex Part Extraction:: Enabled via @samp{-fugly-complex}. -* Ugly Conversion of Initializers:: Disabled via @samp{-fno-ugly-init}. -* Ugly Integer Conversions:: Enabled via @samp{-fugly-logint}. -* Ugly Assigned Labels:: Enabled via @samp{-fugly-assign}. -@end menu - -@node Ugly Implicit Argument Conversion -@subsection Implicit Argument Conversion -@cindex Hollerith constants -@cindex constants, Hollerith - -The @samp{-fno-ugly-args} option disables -passing typeless and Hollerith constants as actual arguments -in procedure invocations. -For example: - -@example -CALL FOO(4HABCD) -CALL BAR('123'O) -@end example - -@noindent -These constructs can be too easily used to create non-portable -code, but are not considered as ``ugly'' as others. -Further, they are widely used in existing Fortran source code -in ways that often are quite portable. -Therefore, they are enabled by default. - -@node Ugly Assumed-Size Arrays -@subsection Ugly Assumed-Size Arrays -@cindex arrays, assumed-size -@cindex assumed-size arrays -@cindex DIMENSION X(1) - -The @samp{-fugly-assumed} option enables -the treatment of any array with a final dimension specified as @samp{1} -as an assumed-size array, as if @samp{*} had been specified -instead. - -For example, @samp{DIMENSION X(1)} is treated as if it -had read @samp{DIMENSION X(*)} if @samp{X} is listed as -a dummy argument in a preceding @code{SUBROUTINE}, @code{FUNCTION}, -or @code{ENTRY} statement in the same program unit. - -Use an explicit lower bound to avoid this interpretation. -For example, @samp{DIMENSION X(1:1)} is never treated as if -it had read @samp{DIMENSION X(*)} or @samp{DIMENSION X(1:*)}. -Nor is @samp{DIMENSION X(2-1)} affected by this option, -since that kind of expression is unlikely to have been -intended to designate an assumed-size array. - -This option is used to prevent warnings being issued about apparent -out-of-bounds reference such as @samp{X(2) = 99}. - -It also prevents the array from being used in contexts that -disallow assumed-size arrays, such as @samp{PRINT *,X}. -In such cases, a diagnostic is generated and the source file is -not compiled. - -The construct affected by this option is used only in old code -that pre-exists the widespread acceptance of adjustable and assumed-size -arrays in the Fortran community. - -@emph{Note:} This option does not affect how @samp{DIMENSION X(1)} is -treated if @samp{X} is listed as a dummy argument only -@emph{after} the @code{DIMENSION} statement (presumably in -an @code{ENTRY} statement). -For example, @samp{-fugly-assumed} has no effect on the -following program unit: - -@example -SUBROUTINE X -REAL A(1) -RETURN -ENTRY Y(A) -PRINT *, A -END -@end example - -@node Ugly Complex Part Extraction -@subsection Ugly Complex Part Extraction -@cindex complex values -@cindex real part -@cindex imaginary part - -The @samp{-fugly-complex} option enables -use of the @code{REAL()} and @code{AIMAG()} -intrinsics with arguments that are -@code{COMPLEX} types other than @code{COMPLEX(KIND=1)}. - -With @samp{-ff90} in effect, these intrinsics return -the unconverted real and imaginary parts (respectively) -of their argument. - -With @samp{-fno-f90} in effect, these intrinsics convert -the real and imaginary parts to @code{REAL(KIND=1)}, and return -the result of that conversion. - -Due to this ambiguity, the GNU Fortran language defines -these constructs as invalid, except in the specific -case where they are entirely and solely passed as an -argument to an invocation of the @code{REAL()} intrinsic. -For example, - -@example -REAL(REAL(Z)) -@end example - -@noindent -is permitted even when @samp{Z} is @code{COMPLEX(KIND=2)} -and @samp{-fno-ugly-complex} is in effect, because the -meaning is clear. - -@code{g77} enforces this restriction, unless @samp{-fugly-complex} -is specified, in which case the appropriate interpretation is -chosen and no diagnostic is issued. - -@xref{CMPAMBIG}, for information on how to cope with existing -code with unclear expectations of @code{REAL()} and @code{AIMAG()} -with @code{COMPLEX(KIND=2)} arguments. - -@xref{RealPart Intrinsic}, for information on the @code{REALPART()} -intrinsic, used to extract the real part of a complex expression -without conversion. -@xref{ImagPart Intrinsic}, for information on the @code{IMAGPART()} -intrinsic, used to extract the imaginary part of a complex expression -without conversion. - -@node Ugly Null Arguments -@subsection Ugly Null Arguments -@cindex trailing commas -@cindex commas, trailing -@cindex null arguments -@cindex arguments, null - -The @samp{-fugly-comma} option enables use of a single trailing comma -to mean ``pass an extra trailing null argument'' -in a list of actual arguments to an external procedure, -and use of an empty list of arguments to such a procedure -to mean ``pass a single null argument''. - -@cindex omitting arguments -@cindex arguments, omitting -(Null arguments often are used in some procedure-calling -schemes to indicate omitted arguments.) - -For example, @samp{CALL FOO(,)} means ``pass -two null arguments'', rather than ``pass one null argument''. -Also, @samp{CALL BAR()} means ``pass one null argument''. - -This construct is considered ``ugly'' because it does not -provide an elegant way to pass a single null argument -that is syntactically distinct from passing no arguments. -That is, this construct changes the meaning of code that -makes no use of the construct. - -So, with @samp{-fugly-comma} in force, @samp{CALL FOO()} -and @samp{I = JFUNC()} pass a single null argument, instead -of passing no arguments as required by the Fortran 77 and -90 standards. - -@emph{Note:} Many systems gracefully allow the case -where a procedure call passes one extra argument that the -called procedure does not expect. - -So, in practice, there might be no difference in -the behavior of a program that does @samp{CALL FOO()} -or @samp{I = JFUNC()} and is compiled with @samp{-fugly-comma} -in force as compared to its behavior when compiled -with the default, @samp{-fno-ugly-comma}, in force, -assuming @samp{FOO} and @samp{JFUNC} do not expect any -arguments to be passed. - -@node Ugly Conversion of Initializers -@subsection Ugly Conversion of Initializers - -The constructs disabled by @samp{-fno-ugly-init} are: - -@itemize @bullet -@cindex Hollerith constants -@cindex constants, Hollerith -@item -Use of Hollerith and typeless constants in contexts where they set -initial (compile-time) values for variables, arrays, and named -constants---that is, @code{DATA} and @code{PARAMETER} statements, plus -type-declaration statements specifying initial values. - -Here are some sample initializations that are disabled by the -@samp{-fno-ugly-init} option: - -@example -PARAMETER (VAL='9A304FFE'X) -REAL*8 STRING/8HOUTPUT00/ -DATA VAR/4HABCD/ -@end example - -@cindex character constants -@cindex constants, character -@item -In the same contexts as above, use of character constants to initialize -numeric items and vice versa (one constant per item). - -Here are more sample initializations that are disabled by the -@samp{-fno-ugly-init} option: - -@example -INTEGER IA -CHARACTER BELL -PARAMETER (IA = 'A') -PARAMETER (BELL = 7) -@end example - -@item -Use of Hollerith and typeless constants on the right-hand side -of assignment statements to numeric types, and in other -contexts (such as passing arguments in invocations of -intrinsic procedures and statement functions) that -are treated as assignments to known types (the dummy -arguments, in these cases). - -Here are sample statements that are disabled by the -@samp{-fno-ugly-init} option: - -@example -IVAR = 4HABCD -PRINT *, IMAX0(2HAB, 2HBA) -@end example -@end itemize - -The above constructs, when used, -can tend to result in non-portable code. -But, they are widely used in existing Fortran code in ways -that often are quite portable. -Therefore, they are enabled by default. - -@node Ugly Integer Conversions -@subsection Ugly Integer Conversions - -The constructs enabled via @samp{-fugly-logint} are: - -@itemize @bullet -@item -Automatic conversion between @code{INTEGER} and @code{LOGICAL} as -dictated by -context (typically implies nonportable dependencies on how a -particular implementation encodes @code{.TRUE.} and @code{.FALSE.}). - -@item -Use of a @code{LOGICAL} variable in @code{ASSIGN} and assigned-@code{GOTO} -statements. -@end itemize - -The above constructs are disabled by default because use -of them tends to lead to non-portable code. -Even existing Fortran code that uses that often turns out -to be non-portable, if not outright buggy. - -Some of this is due to differences among implementations as -far as how @code{.TRUE.} and @code{.FALSE.} are encoded as -@code{INTEGER} values---Fortran code that assumes a particular -coding is likely to use one of the above constructs, and is -also likely to not work correctly on implementations using -different encodings. - -@xref{Equivalence Versus Equality}, for more information. - -@node Ugly Assigned Labels -@subsection Ugly Assigned Labels -@cindex ASSIGN statement -@cindex statements, ASSIGN -@cindex assigned labels -@cindex pointers - -The @samp{-fugly-assign} option forces @code{g77} to use the -same storage for assigned labels as it would for a normal -assignment to the same variable. - -For example, consider the following code fragment: - -@example -I = 3 -ASSIGN 10 TO I -@end example - -@noindent -Normally, for portability and improved diagnostics, @code{g77} -reserves distinct storage for a ``sibling'' of @samp{I}, used -only for @code{ASSIGN} statements to that variable (along with -the corresponding assigned-@code{GOTO} and assigned-@samp{FORMAT}-I/O -statements that reference the variable). - -However, some code (that violates the ANSI FORTRAN 77 standard) -attempts to copy assigned labels among variables involved with -@code{ASSIGN} statements, as in: - -@example -ASSIGN 10 TO I -ISTATE(5) = I -@dots{} -J = ISTATE(ICUR) -GOTO J -@end example - -@noindent -Such code doesn't work under @code{g77} unless @samp{-fugly-assign} -is specified on the command-line, ensuring that the value of @code{I} -referenced in the second line is whatever value @code{g77} uses -to designate statement label @samp{10}, so the value may be -copied into the @samp{ISTATE} array, later retrieved into a -variable of the appropriate type (@samp{J}), and used as the target of -an assigned-@code{GOTO} statement. - -@emph{Note:} To avoid subtle program bugs, -when @samp{-fugly-assign} is specified, -@code{g77} requires the type of variables -specified in assigned-label contexts -@emph{must} be the same type returned by @code{%LOC()}. -On many systems, this type is effectively the same -as @code{INTEGER(KIND=1)}, while, on others, it is -effectively the same as @code{INTEGER(KIND=2)}. - -Do @emph{not} depend on @code{g77} actually writing valid pointers -to these variables, however. -While @code{g77} currently chooses that implementation, it might -be changed in the future. - -@xref{Assigned Statement Labels,,Assigned Statement Labels (ASSIGN and GOTO)}, -for implementation details on assigned-statement labels. - -@node Compiler -@chapter The GNU Fortran Compiler - -The GNU Fortran compiler, @code{g77}, supports programs written -in the GNU Fortran language and in some other dialects of Fortran. - -Some aspects of how @code{g77} works are universal regardless -of dialect, and yet are not properly part of the GNU Fortran -language itself. -These are described below. - -@emph{Note: This portion of the documentation definitely needs a lot -of work!} - -@menu -* Compiler Limits:: -* Compiler Types:: -* Compiler Constants:: -* Compiler Intrinsics:: -@end menu - -@node Compiler Limits -@section Compiler Limits -@cindex limits, compiler -@cindex compiler limits - -@code{g77}, as with GNU tools in general, imposes few arbitrary restrictions -on lengths of identifiers, number of continuation lines, number of external -symbols in a program, and so on. - -@cindex options, -Nl -@cindex -Nl option -@cindex options, -Nx -@cindex -Nx option -For example, some other Fortran compiler have an option -(such as @samp{-Nl@var{x}}) to increase the limit on the -number of continuation lines. -Also, some Fortran compilation systems have an option -(such as @samp{-Nx@var{x}}) to increase the limit on the -number of external symbols. - -@code{g77}, @code{gcc}, and GNU @code{ld} (the GNU linker) have -no equivalent options, since they do not impose arbitrary -limits in these areas. - -@cindex rank, maximum -@cindex maximum rank -@cindex number of dimensions, maximum -@cindex maximum number of dimensions -@code{g77} does currently limit the number of dimensions in an array -to the same degree as do the Fortran standards---seven (7). -This restriction might well be lifted in a future version. - -@node Compiler Types -@section Compiler Types -@cindex types, of data -@cindex data types - -Fortran implementations have a fair amount of freedom given them by the -standard as far as how much storage space is used and how much precision -and range is offered by the various types such as @code{LOGICAL(KIND=1)}, -@code{INTEGER(KIND=1)}, @code{REAL(KIND=1)}, @code{REAL(KIND=2)}, -@code{COMPLEX(KIND=1)}, and @code{CHARACTER}. -Further, many compilers offer so-called @samp{*@var{n}} notation, but -the interpretation of @var{n} varies across compilers and target architectures. - -The standard requires that @code{LOGICAL(KIND=1)}, @code{INTEGER(KIND=1)}, -and @code{REAL(KIND=1)} -occupy the same amount of storage space, and that @code{COMPLEX(KIND=1)} -and @code{REAL(KIND=2)} take twice as much storage space as @code{REAL(KIND=1)}. -Further, it requires that @code{COMPLEX(KIND=1)} -entities be ordered such that when a @code{COMPLEX(KIND=1)} variable is -storage-associated (such as via @code{EQUIVALENCE}) -with a two-element @code{REAL(KIND=1)} array named @samp{R}, @samp{R(1)} -corresponds to the real element and @samp{R(2)} to the imaginary -element of the @code{COMPLEX(KIND=1)} variable. - -(Few requirements as to precision or ranges of any of these are -placed on the implementation, nor is the relationship of storage sizes of -these types to the @code{CHARACTER} type specified, by the standard.) - -@code{g77} follows the above requirements, warning when compiling -a program requires placement of items in memory that contradict the -requirements of the target architecture. -(For example, a program can require placement of a @code{REAL(KIND=2)} -on a boundary that is not an even multiple of its size, but still an -even multiple of the size of a @code{REAL(KIND=1)} variable. -On some target architectures, using the canonical -mapping of Fortran types to underlying architectural types, such -placement is prohibited by the machine definition or -the Application Binary Interface (ABI) in force for -the configuration defined for building @code{gcc} and @code{g77}. -@code{g77} warns about such -situations when it encounters them.) - -@code{g77} follows consistent rules for configuring the mapping between Fortran -types, including the @samp{*@var{n}} notation, and the underlying architectural -types as accessed by a similarly-configured applicable version of the -@code{gcc} compiler. -These rules offer a widely portable, consistent Fortran/C -environment, although they might well conflict with the expectations of -users of Fortran compilers designed and written for particular -architectures. - -These rules are based on the configuration that is in force for the -version of @code{gcc} built in the same release as @code{g77} (and -which was therefore used to build both the @code{g77} compiler -components and the @code{libg2c} run-time library): - -@table @code -@cindex REAL(KIND=1) type -@cindex types, REAL(KIND=1) -@item REAL(KIND=1) -Same as @code{float} type. - -@cindex REAL(KIND=2) type -@cindex types, REAL(KIND=2) -@item REAL(KIND=2) -Same as whatever floating-point type that is twice the size -of a @code{float}---usually, this is a @code{double}. - -@cindex INTEGER(KIND=1) type -@cindex types, INTEGER(KIND=1) -@item INTEGER(KIND=1) -Same as an integral type that is occupies the same amount -of memory storage as @code{float}---usually, this is either -an @code{int} or a @code{long int}. - -@cindex LOGICAL(KIND=1) type -@cindex types, LOGICAL(KIND=1) -@item LOGICAL(KIND=1) -Same @code{gcc} type as @code{INTEGER(KIND=1)}. - -@cindex INTEGER(KIND=2) type -@cindex types, INTEGER(KIND=2) -@item INTEGER(KIND=2) -Twice the size, and usually nearly twice the range, -as @code{INTEGER(KIND=1)}---usually, this is either -a @code{long int} or a @code{long long int}. - -@cindex LOGICAL(KIND=2) type -@cindex types, LOGICAL(KIND=2) -@item LOGICAL(KIND=2) -Same @code{gcc} type as @code{INTEGER(KIND=2)}. - -@cindex INTEGER(KIND=3) type -@cindex types, INTEGER(KIND=3) -@item INTEGER(KIND=3) -Same @code{gcc} type as signed @code{char}. - -@cindex LOGICAL(KIND=3) type -@cindex types, LOGICAL(KIND=3) -@item LOGICAL(KIND=3) -Same @code{gcc} type as @code{INTEGER(KIND=3)}. - -@cindex INTEGER(KIND=6) type -@cindex types, INTEGER(KIND=6) -@item INTEGER(KIND=6) -Twice the size, and usually nearly twice the range, -as @code{INTEGER(KIND=3)}---usually, this is -a @code{short}. - -@cindex LOGICAL(KIND=6) type -@cindex types, LOGICAL(KIND=6) -@item LOGICAL(KIND=6) -Same @code{gcc} type as @code{INTEGER(KIND=6)}. - -@cindex COMPLEX(KIND=1) type -@cindex types, COMPLEX(KIND=1) -@item COMPLEX(KIND=1) -Two @code{REAL(KIND=1)} scalars (one for the real part followed by -one for the imaginary part). - -@cindex COMPLEX(KIND=2) type -@cindex types, COMPLEX(KIND=2) -@item COMPLEX(KIND=2) -Two @code{REAL(KIND=2)} scalars. - -@cindex *@var{n} notation -@item @var{numeric-type}*@var{n} -(Where @var{numeric-type} is any type other than @code{CHARACTER}.) -Same as whatever @code{gcc} type occupies @var{n} times the storage -space of a @code{gcc} @code{char} item. - -@cindex DOUBLE PRECISION type -@cindex types, DOUBLE PRECISION -@item DOUBLE PRECISION -Same as @code{REAL(KIND=2)}. - -@cindex DOUBLE COMPLEX type -@cindex types, DOUBLE COMPLEX -@item DOUBLE COMPLEX -Same as @code{COMPLEX(KIND=2)}. -@end table - -Note that the above are proposed correspondences and might change -in future versions of @code{g77}---avoid writing code depending -on them. - -Other types supported by @code{g77} -are derived from gcc types such as @code{char}, @code{short}, -@code{int}, @code{long int}, @code{long long int}, @code{long double}, -and so on. -That is, whatever types @code{gcc} already supports, @code{g77} supports -now or probably will support in a future version. -The rules for the @samp{@var{numeric-type}*@var{n}} notation -apply to these types, -and new values for @samp{@var{numeric-type}(KIND=@var{n})} will be -assigned in a way that encourages clarity, consistency, and portability. - -@node Compiler Constants -@section Compiler Constants -@cindex constants -@cindex types, constants - -@code{g77} strictly assigns types to @emph{all} constants not -documented as ``typeless'' (typeless constants including @samp{'1'Z}, -for example). -Many other Fortran compilers attempt to assign types to typed constants -based on their context. -This results in hard-to-find bugs, nonportable -code, and is not in the spirit (though it strictly follows the letter) -of the 77 and 90 standards. - -@code{g77} might offer, in a future release, explicit constructs by -which a wider variety of typeless constants may be specified, and/or -user-requested warnings indicating places where @code{g77} might differ -from how other compilers assign types to constants. - -@xref{Context-Sensitive Constants}, for more information on this issue. - -@node Compiler Intrinsics -@section Compiler Intrinsics - -@code{g77} offers an ever-widening set of intrinsics. -Currently these all are procedures (functions and subroutines). - -Some of these intrinsics are unimplemented, but their names reserved -to reduce future problems with existing code as they are implemented. -Others are implemented as part of the GNU Fortran language, while -yet others are provided for compatibility with other dialects of -Fortran but are not part of the GNU Fortran language. - -To manage these distinctions, @code{g77} provides intrinsic @emph{groups}, -a facility that is simply an extension of the intrinsic groups provided -by the GNU Fortran language. - -@menu -* Intrinsic Groups:: How intrinsics are grouped for easy management. -* Other Intrinsics:: Intrinsics other than those in the GNU - Fortran language. -@end menu - -@node Intrinsic Groups -@subsection Intrinsic Groups -@cindex groups of intrinsics -@cindex intrinsics, groups - -A given specific intrinsic belongs in one or more groups. -Each group is deleted, disabled, hidden, or enabled -by default or a command-line option. -The meaning of each term follows. - -@table @b -@cindex deleted intrinsics -@cindex intrinsics, deleted -@item Deleted -No intrinsics are recognized as belonging to that group. - -@cindex disabled intrinsics -@cindex intrinsics, disabled -@item Disabled -Intrinsics are recognized as belonging to the group, but -references to them (other than via the @code{INTRINSIC} statement) -are disallowed through that group. - -@cindex hidden intrinsics -@cindex intrinsics, hidden -@item Hidden -Intrinsics in that group are recognized and enabled (if implemented) -@emph{only} if the first mention of the actual name of an intrinsic -in a program unit is in an @code{INTRINSIC} statement. - -@cindex enabled intrinsics -@cindex intrinsics, enabled -@item Enabled -Intrinsics in that group are recognized and enabled (if implemented). -@end table - -The distinction between deleting and disabling a group is illustrated -by the following example. -Assume intrinsic @samp{FOO} belongs only to group @samp{FGR}. -If group @samp{FGR} is deleted, the following program unit will -successfully compile, because @samp{FOO()} will be seen as a -reference to an external function named @samp{FOO}: - -@example -PRINT *, FOO() -END -@end example - -@noindent -If group @samp{FGR} is disabled, compiling the above program will produce -diagnostics, either because the @samp{FOO} intrinsic is improperly invoked -or, if properly invoked, it is not enabled. -To change the above program so it references an external function @samp{FOO} -instead of the disabled @samp{FOO} intrinsic, -add the following line to the top: - -@example -EXTERNAL FOO -@end example - -@noindent -So, deleting a group tells @code{g77} to pretend as though the intrinsics in -that group do not exist at all, whereas disabling it tells @code{g77} to -recognize them as (disabled) intrinsics in intrinsic-like contexts. - -Hiding a group is like enabling it, but the intrinsic must be first -named in an @code{INTRINSIC} statement to be considered a reference to the -intrinsic rather than to an external procedure. -This might be the ``safest'' way to treat a new group of intrinsics -when compiling old -code, because it allows the old code to be generally written as if -those new intrinsics never existed, but to be changed to use them -by inserting @code{INTRINSIC} statements in the appropriate places. -However, it should be the goal of development to use @code{EXTERNAL} -for all names of external procedures that might be intrinsic names. - -If an intrinsic is in more than one group, it is enabled if any of its -containing groups are enabled; if not so enabled, it is hidden if -any of its containing groups are hidden; if not so hidden, it is disabled -if any of its containing groups are disabled; if not so disabled, it is -deleted. -This extra complication is necessary because some intrinsics, -such as @code{IBITS}, belong to more than one group, and hence should be -enabled if any of the groups to which they belong are enabled, and so -on. - -The groups are: - -@cindex intrinsics, groups of -@cindex groups of intrinsics -@table @code -@cindex @code{badu77} intrinsics group -@item badu77 -UNIX intrinsics having inappropriate forms (usually functions that -have intended side effects). - -@cindex @code{gnu} intrinsics group -@item gnu -Intrinsics the GNU Fortran language supports that are extensions to -the Fortran standards (77 and 90). - -@cindex @code{f2c} intrinsics group -@item f2c -Intrinsics supported by AT&T's @code{f2c} converter and/or @code{libf2c}. - -@cindex @code{f90} intrinsics group -@item f90 -Fortran 90 intrinsics. - -@cindex @code{mil} intrinsics group -@item mil -MIL-STD 1753 intrinsics (@code{MVBITS}, @code{IAND}, @code{BTEST}, and so on). - -@cindex @code{mil} intrinsics group -@item unix -UNIX intrinsics (@code{IARGC}, @code{EXIT}, @code{ERF}, and so on). - -@cindex @code{mil} intrinsics group -@item vxt -VAX/VMS FORTRAN (current as of v4) intrinsics. -@end table - -@node Other Intrinsics -@subsection Other Intrinsics -@cindex intrinsics, others -@cindex other intrinsics - -@code{g77} supports intrinsics other than those in the GNU Fortran -language proper. -This set of intrinsics is described below. - -@ifinfo -(Note that the empty lines appearing in the menu below -are not intentional---they result from a bug in the -@code{makeinfo} program.) -@end ifinfo - -@c The actual documentation for intrinsics comes from -@c intdoc.texi, which in turn is automatically generated -@c from the internal g77 tables in intrin.def _and_ the -@c largely hand-written text in intdoc.h. So, if you want -@c to change or add to existing documentation on intrinsics, -@c you probably want to edit intdoc.h. -@c -@clear familyF77 -@clear familyGNU -@clear familyASC -@clear familyMIL -@clear familyF90 -@set familyVXT -@set familyFVZ -@clear familyF2C -@clear familyF2U -@set familyBADU77 -@include intdoc.texi - -@node Other Compilers -@chapter Other Compilers - -An individual Fortran source file can be compiled to -an object (@file{*.o}) file instead of to the final -program executable. -This allows several portions of a program to be compiled -at different times and linked together whenever a new -version of the program is needed. -However, it introduces the issue of @dfn{object compatibility} -across the various object files (and libraries, or @file{*.a} -files) that are linked together to produce any particular -executable file. - -Object compatibility is an issue when combining, in one -program, Fortran code compiled by more than one compiler -(or more than one configuration of a compiler). -If the compilers -disagree on how to transform the names of procedures, there -will normally be errors when linking such programs. -Worse, if the compilers agree on naming, but disagree on issues -like how to pass parameters, return arguments, and lay out -@code{COMMON} areas, the earliest detected errors might be the -incorrect results produced by the program (and that assumes -these errors are detected, which is not always the case). - -Normally, @code{g77} generates code that is -object-compatible with code generated by a version of -@code{f2c} configured (with, for example, @file{f2c.h} definitions) -to be generally compatible with @code{g77} as built by @code{gcc}. -(Normally, @code{f2c} will, by default, conform to the appropriate -configuration, but it is possible that older or perhaps even newer -versions of @code{f2c}, or versions having certain configuration changes -to @code{f2c} internals, will produce object files that are -incompatible with @code{g77}.) - -For example, a Fortran string subroutine -argument will become two arguments on the C side: a @code{char *} -and an @code{int} length. - -Much of this compatibility results from the fact that -@code{g77} uses the same run-time library, -@code{libf2c}, used by @code{f2c}, -though @code{g77} gives its version the name @code{libg2c} -so as to avoid conflicts when linking, -installing them in the same directories, -and so on. - -Other compilers might or might not generate code that -is object-compatible with @code{libg2c} and current @code{g77}, -and some might offer such compatibility only when explicitly -selected via a command-line option to the compiler. - -@emph{Note: This portion of the documentation definitely needs a lot -of work!} - -@menu -* Dropping f2c Compatibility:: When speed is more important. -* Compilers Other Than f2c:: Interoperation with code from other compilers. -@end menu - -@node Dropping f2c Compatibility -@section Dropping @code{f2c} Compatibility - -Specifying @samp{-fno-f2c} allows @code{g77} to generate, in -some cases, faster code, by not needing to allow to the possibility -of linking with code compiled by @code{f2c}. - -For example, this affects how @code{REAL(KIND=1)}, -@code{COMPLEX(KIND=1)}, and @code{COMPLEX(KIND=2)} functions are called. -With @samp{-fno-f2c}, they are -compiled as returning the appropriate @code{gcc} type -(@code{float}, @code{__complex__ float}, @code{__complex__ double}, -in many configurations). - -With @samp{-ff2c} in force, they -are compiled differently (with perhaps slower run-time performance) -to accommodate the restrictions inherent in @code{f2c}'s use of K&R -C as an intermediate language---@code{REAL(KIND=1)} functions -return C's @code{double} type, while @code{COMPLEX} functions return -@code{void} and use an extra argument pointing to a place for the functions to -return their values. - -It is possible that, in some cases, leaving @samp{-ff2c} in force -might produce faster code than using @samp{-fno-f2c}. -Feel free to experiment, but remember to experiment with changing the way -@emph{entire programs and their Fortran libraries are compiled} at -a time, since this sort of experimentation affects the interface -of code generated for a Fortran source file---that is, it affects -object compatibility. - -Note that @code{f2c} compatibility is a fairly static target to achieve, -though not necessarily perfectly so, since, like @code{g77}, it is -still being improved. -However, specifying @samp{-fno-f2c} causes @code{g77} -to generate code that will probably be incompatible with code -generated by future versions of @code{g77} when the same option -is in force. -You should make sure you are always able to recompile complete -programs from source code when upgrading to new versions of @code{g77} -or @code{f2c}, especially when using options such as @samp{-fno-f2c}. - -Therefore, if you are using @code{g77} to compile libraries and other -object files for possible future use and you don't want to require -recompilation for future use with subsequent versions of @code{g77}, -you might want to stick with @code{f2c} compatibility for now, and -carefully watch for any announcements about changes to the -@code{f2c}/@code{libf2c} interface that might affect existing programs -(thus requiring recompilation). - -It is probable that a future version of @code{g77} will not, -by default, generate object files compatible with @code{f2c}, -and that version probably would no longer use @code{libf2c}. -If you expect to depend on this compatibility in the -long term, use the options @samp{-ff2c -ff2c-library} when compiling -all of the applicable code. -This should cause future versions of @code{g77} either to produce -compatible code (at the expense of the availability of some features and -performance), or at the very least, to produce diagnostics. - -(The library @code{g77} produces will no longer be named @file{libg2c} -when it is no longer generally compatible with @file{libf2c}. -It will likely be referred to, and, if installed as a distinct -library, named @code{libg77}, or some other as-yet-unused name.) - -@node Compilers Other Than f2c -@section Compilers Other Than @code{f2c} - -On systems with Fortran compilers other than @code{f2c} and @code{g77}, -code compiled by @code{g77} is not expected to work -well with code compiled by the native compiler. -(This is true for @code{f2c}-compiled objects as well.) -Libraries compiled with the native compiler probably will have -to be recompiled with @code{g77} to be used with @code{g77}-compiled code. - -Reasons for such incompatibilities include: - -@itemize @bullet -@item -There might be differences in the way names of Fortran procedures -are translated for use in the system's object-file format. -For example, the statement @samp{CALL FOO} might be compiled -by @code{g77} to call a procedure the linker @code{ld} sees -given the name @samp{_foo_}, while the apparently corresponding -statement @samp{SUBROUTINE FOO} might be compiled by the -native compiler to define the linker-visible name @samp{_foo}, -or @samp{_FOO_}, and so on. - -@item -There might be subtle type mismatches which cause subroutine arguments -and function return values to get corrupted. - -This is why simply getting @code{g77} to -transform procedure names the same way a native -compiler does is not usually a good idea---unless -some effort has been made to ensure that, aside -from the way the two compilers transform procedure -names, everything else about the way they generate -code for procedure interfaces is identical. - -@item -Native compilers -use libraries of private I/O routines which will not be available -at link time unless you have the native compiler---and you would -have to explicitly ask for them. - -For example, on the Sun you -would have to add @samp{-L/usr/lang/SCx.x -lF77 -lV77} to the link -command. -@end itemize - -@node Other Languages -@chapter Other Languages - -@emph{Note: This portion of the documentation definitely needs a lot -of work!} - -@menu -* Interoperating with C and C++:: -@end menu - -@node Interoperating with C and C++ -@section Tools and advice for interoperating with C and C++ - -@cindex C, linking with -@cindex C++, linking with -@cindex linking with C -The following discussion assumes that you are running @code{g77} in @code{f2c} -compatibility mode, i.e.@: not using @samp{-fno-f2c}. -It provides some -advice about quick and simple techniques for linking Fortran and C (or -C++), the most common requirement. -For the full story consult the -description of code generation. -@xref{Debugging and Interfacing}. - -When linking Fortran and C, it's usually best to use @code{g77} to do -the linking so that the correct libraries are included (including the -maths one). -If you're linking with C++ you will want to add -@samp{-lstdc++}, @samp{-lg++} or whatever. -If you need to use another -driver program (or @code{ld} directly), -you can find out what linkage -options @code{g77} passes by running @samp{g77 -v}. - -@menu -* C Interfacing Tools:: -* C Access to Type Information:: -* f2c Skeletons and Prototypes:: -* C++ Considerations:: -* Startup Code:: -@end menu - -@node C Interfacing Tools -@subsection C Interfacing Tools -@pindex f2c -@cindex cfortran.h -@cindex Netlib -Even if you don't actually use it as a compiler, @samp{f2c} from -@uref{ftp://ftp.netlib.org/f2c/src}, can be a useful tool when you're -interfacing (linking) Fortran and C@. -@xref{f2c Skeletons and Prototypes,,Generating Skeletons and Prototypes with @code{f2c}}. - -To use @code{f2c} for this purpose you only need retrieve and -build the @file{src} directory from the distribution, consult the -@file{README} instructions there for machine-specifics, and install the -@code{f2c} program on your path. - -Something else that might be useful is @samp{cfortran.h} from -@uref{ftp://zebra/desy.de/cfortran}. -This is a fairly general tool which -can be used to generate interfaces for calling in both directions -between Fortran and C@. -It can be used in @code{f2c} mode with -@code{g77}---consult its documentation for details. - -@node C Access to Type Information -@subsection Accessing Type Information in C - -@cindex types, Fortran/C -Generally, C code written to link with -@code{g77} code---calling and/or being -called from Fortran---should @samp{#include <g2c.h>} to define the C -versions of the Fortran types. -Don't assume Fortran @code{INTEGER} types -correspond to C @samp{int}s, for instance; instead, declare them as -@code{integer}, a type defined by @file{g2c.h}. -@file{g2c.h} is installed where @code{gcc} will find it by -default, assuming you use a copy of @code{gcc} compatible with -@code{g77}, probably built at the same time as @code{g77}. - -@node f2c Skeletons and Prototypes -@subsection Generating Skeletons and Prototypes with @code{f2c} - -@pindex f2c -@cindex -fno-second-underscore -A simple and foolproof way to write @code{g77}-callable C routines---e.g.@: to -interface with an existing library---is to write a file (named, for -example, @file{fred.f}) of dummy Fortran -skeletons comprising just the declaration of the routine(s) and dummy -arguments plus @samp{END} statements. -Then run @code{f2c} on file @file{fred.f} to produce @file{fred.c} -into which you can edit -useful code, confident the calling sequence is correct, at least. -(There are some errors otherwise commonly made in generating C -interfaces with @code{f2c} conventions, -such as not using @code{doublereal} -as the return type of a @code{REAL} @code{FUNCTION}.) - -@pindex ftnchek -@code{f2c} also can help with calling Fortran from C, using its -@samp{-P} option to generate C prototypes appropriate for calling the -Fortran.@footnote{The files generated like this can also be used for -inter-unit consistency checking of dummy and actual arguments, although -the @samp{ftnchek} tool from @uref{ftp://ftp.netlib.org/fortran} -or @uref{ftp://ftp.dsm.fordham.edu} is -probably better for this purpose.} -If the Fortran code containing any -routines to be called from C is in file @file{joe.f}, use the command -@kbd{f2c -P joe.f} to generate the file @file{joe.P} containing -prototype information. -@code{#include} this in the C which has to call -the Fortran routines to make sure you get it right. - -@xref{Arrays,,Arrays (DIMENSION)}, for information on the differences -between the way Fortran (including compilers like @code{g77}) and -C handle arrays. - -@node C++ Considerations -@subsection C++ Considerations - -@cindex C++ -@code{f2c} can be used to generate suitable code for compilation with a -C++ system using the @samp{-C++} option. -The important thing about linking @code{g77}-compiled -code with C++ is that the prototypes for the @code{g77} -routines must specify C linkage to avoid name mangling. -So, use an @samp{extern "C"} declaration. -@code{f2c}'s @samp{-C++} option will take care -of this when generating skeletons or prototype files as above, and also -avoid clashes with C++ reserved words in addition to those in C@. - -@node Startup Code -@subsection Startup Code - -@cindex startup code -@cindex runtime initialization -@cindex initialization, runtime -Unlike with some runtime systems, -it shouldn't be necessary -(unless there are bugs) -to use a Fortran main program unit to ensure the -runtime---specifically the I/O system---is initialized. - -However, to use the @code{g77} intrinsics @code{GETARG} and @code{IARGC}, -either the @code{main} routine from the @file{libg2c} library must be used, -or the @code{f_setarg} routine -(new as of @code{egcs} version 1.1 and @code{g77} version 0.5.23) -must be called with the appropriate @code{argc} and @code{argv} arguments -prior to the program calling @code{GETARG} or @code{IARGC}. - -To provide more flexibility for mixed-language programming -involving @code{g77} while allowing for shared libraries, -as of @code{egcs} version 1.1 and @code{g77} version 0.5.23, -@code{g77}'s @code{main} routine in @code{libg2c} -does the following, in order: - -@enumerate -@item -Calls @code{f_setarg} -with the incoming @code{argc} and @code{argv} arguments, -in the same order as for @code{main} itself. - -This sets up the command-line environment -for @code{GETARG} and @code{IARGC}. - -@item -Calls @code{f_setsig} (with no arguments). - -This sets up the signaling and exception environment. - -@item -Calls @code{f_init} (with no arguments). - -This initializes the I/O environment, -though that should not be necessary, -as all I/O functions in @code{libf2c} -are believed to call @code{f_init} automatically, -if necessary. - -(A future version of @code{g77} might skip this explicit step, -to speed up normal exit of a program.) - -@item -Arranges for @code{f_exit} to be called (with no arguments) -when the program exits. - -This ensures that the I/O environment is properly shut down -before the program exits normally. -Otherwise, output buffers might not be fully flushed, -scratch files might not be deleted, and so on. - -The simple way @code{main} does this is -to call @code{f_exit} itself after calling -@code{MAIN__} (in the next step). - -However, this does not catch the cases where the program -might call @code{exit} directly, -instead of using the @code{EXIT} intrinsic -(implemented as @code{exit_} in @code{libf2c}). - -So, @code{main} attempts to use -the operating environment's @code{onexit} or @code{atexit} -facility, if available, -to cause @code{f_exit} to be called automatically -upon any invocation of @code{exit}. - -@item -Calls @code{MAIN__} (with no arguments). - -This starts executing the Fortran main program unit for -the application. -(Both @code{g77} and @code{f2c} currently compile a main -program unit so that its global name is @code{MAIN__}.) - -@item -If no @code{onexit} or @code{atexit} is provided by the system, -calls @code{f_exit}. - -@item -Calls @code{exit} with a zero argument, -to signal a successful program termination. - -@item -Returns a zero value to the caller, -to signal a successful program termination, -in case @code{exit} doesn't exit on the system. -@end enumerate - -All of the above names are C @code{extern} names, -i.e.@: not mangled. - -When using the @code{main} procedure provided by @code{g77} -without a Fortran main program unit, -you need to provide @code{MAIN__} -as the entry point for your C code. -(Make sure you link the object file that defines that -entry point with the rest of your program.) - -To provide your own @code{main} procedure -in place of @code{g77}'s, -make sure you specify the object file defining that procedure -@emph{before} @samp{-lg2c} on the @code{g77} command line. -Since the @samp{-lg2c} option is implicitly provided, -this is usually straightforward. -(Use the @samp{--verbose} option to see how and where -@code{g77} implicitly adds @samp{-lg2c} in a command line -that will link the program. -Feel free to specify @samp{-lg2c} explicitly, -as appropriate.) - -However, when providing your own @code{main}, -make sure you perform the appropriate tasks in the -appropriate order. -For example, if your @code{main} does not call @code{f_setarg}, -make sure the rest of your application does not call -@code{GETARG} or @code{IARGC}. - -And, if your @code{main} fails to ensure that @code{f_exit} -is called upon program exit, -some files might end up incompletely written, -some scratch files might be left lying around, -and some existing files being written might be left -with old data not properly truncated at the end. - -Note that, generally, the @code{g77} operating environment -does not depend on a procedure named @code{MAIN__} actually -being called prior to any other @code{g77}-compiled code. -That is, @code{MAIN__} does not, itself, -set up any important operating-environment characteristics -upon which other code might depend. -This might change in future versions of @code{g77}, -with appropriate notification in the release notes. - -For more information, consult the source code for the above routines. -These are in @file{@value{path-libf2c}/libF77/}, named @file{main.c}, -@file{setarg.c}, @file{setsig.c}, @file{getarg_.c}, and @file{iargc_.c}. - -Also, the file @file{@value{path-g77}/com.c} contains the code @code{g77} -uses to open-code (inline) references to @code{IARGC}. - -@include g77install.texi - -@node Debugging and Interfacing -@chapter Debugging and Interfacing -@cindex debugging -@cindex interfacing -@cindex calling C routines -@cindex C routines calling Fortran -@cindex f2c compatibility - -GNU Fortran currently generates code that is object-compatible with -the @code{f2c} converter. -Also, it avoids limitations in the current GBE, such as the -inability to generate a procedure with -multiple entry points, by generating code that is structured -differently (in terms of procedure names, scopes, arguments, and -so on) than might be expected. - -As a result, writing code in other languages that calls on, is -called by, or shares in-memory data with @code{g77}-compiled code generally -requires some understanding of the way @code{g77} compiles code for -various constructs. - -Similarly, using a debugger to debug @code{g77}-compiled -code, even if that debugger supports native Fortran debugging, generally -requires this sort of information. - -This section describes some of the basic information on how -@code{g77} compiles code for constructs involving interfaces to other -languages and to debuggers. - -@emph{Caution:} Much or all of this information pertains to only the current -release of @code{g77}, sometimes even to using certain compiler options -with @code{g77} (such as @samp{-fno-f2c}). -Do not write code that depends on this -information without clearly marking said code as nonportable and -subject to review for every new release of @code{g77}. -This information -is provided primarily to make debugging of code generated by this -particular release of @code{g77} easier for the user, and partly to make -writing (generally nonportable) interface code easier. -Both of these -activities require tracking changes in new version of @code{g77} as they -are installed, because new versions can change the behaviors -described in this section. - -@menu -* Main Program Unit:: How @code{g77} compiles a main program unit. -* Procedures:: How @code{g77} constructs parameter lists - for procedures. -* Functions:: Functions returning floating-point or character data. -* Names:: Naming of user-defined variables, procedures, etc. -* Common Blocks:: Accessing common variables while debugging. -* Local Equivalence Areas:: Accessing @code{EQUIVALENCE} while debugging. -* Complex Variables:: How @code{g77} performs complex arithmetic. -* Arrays:: Dealing with (possibly multi-dimensional) arrays. -* Adjustable Arrays:: Special consideration for adjustable arrays. -* Alternate Entry Points:: How @code{g77} implements alternate @code{ENTRY}. -* Alternate Returns:: How @code{g77} handles alternate returns. -* Assigned Statement Labels:: How @code{g77} handles @code{ASSIGN}. -* Run-time Library Errors:: Meanings of some @code{IOSTAT=} values. -@end menu - -@node Main Program Unit -@section Main Program Unit (PROGRAM) -@cindex PROGRAM statement -@cindex statements, PROGRAM - -When @code{g77} compiles a main program unit, it gives it the public -procedure name @samp{MAIN__}. -The @code{libg2c} library has the actual @code{main()} procedure -as is typical of C-based environments, and -it is this procedure that performs some initial start-up -activity and then calls @samp{MAIN__}. - -Generally, @code{g77} and @code{libg2c} are designed so that you need not -include a main program unit written in Fortran in your program---it -can be written in C or some other language. -Especially for I/O handling, this is the case, although @code{g77} version 0.5.16 -includes a bug fix for @code{libg2c} that solved a problem with using the -@code{OPEN} statement as the first Fortran I/O activity in a program -without a Fortran main program unit. - -However, if you don't intend to use @code{g77} (or @code{f2c}) to compile -your main program unit---that is, if you intend to compile a @code{main()} -procedure using some other language---you should carefully -examine the code for @code{main()} in @code{libg2c}, found in the source -file @file{@value{path-libf2c}/libF77/main.c}, to see what kinds of things -might need to be done by your @code{main()} in order to provide the -Fortran environment your Fortran code is expecting. - -@cindex IARGC() intrinsic -@cindex intrinsics, IARGC() -@cindex GETARG() intrinsic -@cindex intrinsics, GETARG() -For example, @code{libg2c}'s @code{main()} sets up the information used by -the @code{IARGC} and @code{GETARG} intrinsics. -Bypassing @code{libg2c}'s @code{main()} -without providing a substitute for this activity would mean -that invoking @code{IARGC} and @code{GETARG} would produce undefined -results. - -@cindex debugging -@cindex main program unit, debugging -@cindex main() -@cindex MAIN__() -@cindex .gdbinit -When debugging, one implication of the fact that @code{main()}, which -is the place where the debugged program ``starts'' from the -debugger's point of view, is in @code{libg2c} is that you won't be -starting your Fortran program at a point you recognize as your -Fortran code. - -The standard way to get around this problem is to set a break -point (a one-time, or temporary, break point will do) at -the entrance to @samp{MAIN__}, and then run the program. -A convenient way to do so is to add the @code{gdb} command - -@example -tbreak MAIN__ -@end example - -@noindent -to the file @file{.gdbinit} in the directory in which you're debugging -(using @code{gdb}). - -After doing this, the debugger will see the current execution -point of the program as at the beginning of the main program -unit of your program. - -Of course, if you really want to set a break point at some -other place in your program and just start the program -running, without first breaking at @samp{MAIN__}, -that should work fine. - -@node Procedures -@section Procedures (SUBROUTINE and FUNCTION) -@cindex procedures -@cindex SUBROUTINE statement -@cindex statements, SUBROUTINE -@cindex FUNCTION statement -@cindex statements, FUNCTION -@cindex signature of procedures - -Currently, @code{g77} passes arguments via reference---specifically, -by passing a pointer to the location in memory of a variable, array, -array element, a temporary location that holds the result of evaluating an -expression, or a temporary or permanent location that holds the value -of a constant. - -Procedures that accept @code{CHARACTER} arguments are implemented by -@code{g77} so that each @code{CHARACTER} argument has two actual arguments. - -The first argument occupies the expected position in the -argument list and has the user-specified name. -This argument -is a pointer to an array of characters, passed by the caller. - -The second argument is appended to the end of the user-specified -calling sequence and is named @samp{__g77_length_@var{x}}, where @var{x} -is the user-specified name. -This argument is of the C type @code{ftnlen} -(see @file{@value{path-libf2c}/g2c.h.in} for information on that type) and -is the number of characters the caller has allocated in the -array pointed to by the first argument. - -A procedure will ignore the length argument if @samp{X} is not declared -@code{CHARACTER*(*)}, because for other declarations, it knows the -length. -Not all callers necessarily ``know'' this, however, which -is why they all pass the extra argument. - -The contents of the @code{CHARACTER} argument are specified by the -address passed in the first argument (named after it). -The procedure can read or write these contents as appropriate. - -When more than one @code{CHARACTER} argument is present in the argument -list, the length arguments are appended in the order -the original arguments appear. -So @samp{CALL FOO('HI','THERE')} is implemented in -C as @samp{foo("hi","there",2,5);}, ignoring the fact that @code{g77} -does not provide the trailing null bytes on the constant -strings (@code{f2c} does provide them, but they are unnecessary in -a Fortran environment, and you should not expect them to be -there). - -Note that the above information applies to @code{CHARACTER} variables and -arrays @strong{only}. -It does @strong{not} apply to external @code{CHARACTER} -functions or to intrinsic @code{CHARACTER} functions. -That is, no second length argument is passed to @samp{FOO} in this case: - -@example -CHARACTER X -EXTERNAL X -CALL FOO(X) -@end example - -@noindent -Nor does @samp{FOO} expect such an argument in this case: - -@example -SUBROUTINE FOO(X) -CHARACTER X -EXTERNAL X -@end example - -Because of this implementation detail, if a program has a bug -such that there is disagreement as to whether an argument is -a procedure, and the type of the argument is @code{CHARACTER}, subtle -symptoms might appear. - -@node Functions -@section Functions (FUNCTION and RETURN) -@cindex functions -@cindex FUNCTION statement -@cindex statements, FUNCTION -@cindex RETURN statement -@cindex statements, RETURN -@cindex return type of functions - -@code{g77} handles in a special way functions that return the following -types: - -@itemize @bullet -@item -@code{CHARACTER} -@item -@code{COMPLEX} -@item -@code{REAL(KIND=1)} -@end itemize - -For @code{CHARACTER}, @code{g77} implements a subroutine (a C function -returning @code{void}) -with two arguments prepended: @samp{__g77_result}, which the caller passes -as a pointer to a @code{char} array expected to hold the return value, -and @samp{__g77_length}, which the caller passes as an @code{ftnlen} value -specifying the length of the return value as declared in the calling -program. -For @code{CHARACTER*(*)}, the called function uses @samp{__g77_length} -to determine the size of the array that @samp{__g77_result} points to; -otherwise, it ignores that argument. - -For @code{COMPLEX}, when @samp{-ff2c} is in -force, @code{g77} implements -a subroutine with one argument prepended: @samp{__g77_result}, which the -caller passes as a pointer to a variable of the type of the function. -The called function writes the return value into this variable instead -of returning it as a function value. -When @samp{-fno-f2c} is in force, -@code{g77} implements a @code{COMPLEX} function as @code{gcc}'s -@samp{__complex__ float} or @samp{__complex__ double} function -(or an emulation thereof, when @samp{-femulate-complex} is in effect), -returning the result of the function in the same way as @code{gcc} would. - -For @code{REAL(KIND=1)}, when @samp{-ff2c} is in force, @code{g77} implements -a function that actually returns @code{REAL(KIND=2)} (typically -C's @code{double} type). -When @samp{-fno-f2c} is in force, @code{REAL(KIND=1)} -functions return @code{float}. - -@node Names -@section Names -@cindex symbol names -@cindex transformation of symbol names - -Fortran permits each implementation to decide how to represent -names as far as how they're seen in other contexts, such as debuggers -and when interfacing to other languages, and especially as far -as how casing is handled. - -External names---names of entities that are public, or ``accessible'', -to all modules in a program---normally have an underscore (@samp{_}) -appended by @code{g77}, -to generate code that is compatible with @code{f2c}. -External names include names of Fortran things like common blocks, -external procedures (subroutines and functions, but not including -statement functions, which are internal procedures), and entry point -names. - -However, use of the @samp{-fno-underscoring} option -disables this kind of transformation of external names (though inhibiting -the transformation certainly improves the chances of colliding with -incompatible externals written in other languages---but that -might be intentional. - -@cindex -fno-underscoring option -@cindex options, -fno-underscoring -@cindex -fno-second-underscore option -@cindex options, -fno-underscoring -When @samp{-funderscoring} is in force, any name (external or local) -that already has at least one underscore in it is -implemented by @code{g77} by appending two underscores. -(This second underscore can be disabled via the -@samp{-fno-second-underscore} option.) -External names are changed this way for @code{f2c} compatibility. -Local names are changed this way to avoid collisions with external names -that are different in the source code---@code{f2c} does the same thing, but -there's no compatibility issue there except for user expectations while -debugging. - -For example: - -@example -Max_Cost = 0 -@end example - -@cindex debugging -@noindent -Here, a user would, in the debugger, refer to this variable using the -name @samp{max_cost__} (or @samp{MAX_COST__} or @samp{Max_Cost__}, -as described below). -(We hope to improve @code{g77} in this regard in the future---don't -write scripts depending on this behavior! -Also, consider experimenting with the @samp{-fno-underscoring} -option to try out debugging without having to massage names by -hand like this.) - -@code{g77} provides a number of command-line options that allow the user -to control how case mapping is handled for source files. -The default is the traditional UNIX model for Fortran compilers---names -are mapped to lower case. -Other command-line options can be specified to map names to upper -case, or to leave them exactly as written in the source file. - -For example: - -@example -Foo = 9.436 -@end example - -@noindent -Here, it is normally the case that the variable assigned will be named -@samp{foo}. -This would be the name to enter when using a debugger to -access the variable. - -However, depending on the command-line options specified, the -name implemented by @code{g77} might instead be @samp{FOO} or even -@samp{Foo}, thus affecting how debugging is done. - -Also: - -@example -Call Foo -@end example - -@noindent -This would normally call a procedure that, if it were in a separate C program, -be defined starting with the line: - -@example -void foo_() -@end example - -@noindent -However, @code{g77} command-line options could be used to change the casing -of names, resulting in the name @samp{FOO_} or @samp{Foo_} being given to the -procedure instead of @samp{foo_}, and the @samp{-fno-underscoring} option -could be used to inhibit the appending of the underscore to the name. - -@node Common Blocks -@section Common Blocks (COMMON) -@cindex common blocks -@cindex COMMON statement -@cindex statements, COMMON - -@code{g77} names and lays out @code{COMMON} areas -the same way @code{f2c} does, -for compatibility with @code{f2c}. - -Currently, @code{g77} does not emit ``true'' debugging information for -members of a @code{COMMON} area, due to an apparent bug in the GBE. - -(As of Version 0.5.19, @code{g77} emits debugging information for such -members in the form of a constant string specifying the base name of -the aggregate area and the offset of the member in bytes from the start -of the area. -Use the @samp{-fdebug-kludge} option to enable this behavior. -In @code{gdb}, use @samp{set language c} before printing the value -of the member, then @samp{set language fortran} to restore the default -language, since @code{gdb} doesn't provide a way to print a readable -version of a character string in Fortran language mode. - -This kludge will be removed in a future version of @code{g77} that, -in conjunction with a contemporary version of @code{gdb}, -properly supports Fortran-language debugging, including access -to members of @code{COMMON} areas.) - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -Moreover, @code{g77} currently implements a @code{COMMON} area such that its -type is an array of the C @code{char} data type. - -So, when debugging, you must know the offset into a @code{COMMON} area -for a particular item in that area, and you have to take into -account the appropriate multiplier for the respective sizes -of the types (as declared in your code) for the items preceding -the item in question as compared to the size of the @code{char} type. - -For example, using default implicit typing, the statement - -@example -COMMON I(15), R(20), T -@end example - -@noindent -results in a public 144-byte @code{char} array named @samp{_BLNK__} -with @samp{I} placed at @samp{_BLNK__[0]}, @samp{R} at @samp{_BLNK__[60]}, -and @samp{T} at @samp{_BLNK__[140]}. -(This is assuming that the target machine for -the compilation has 4-byte @code{INTEGER(KIND=1)} and @code{REAL(KIND=1)} -types.) - -@node Local Equivalence Areas -@section Local Equivalence Areas (EQUIVALENCE) -@cindex equivalence areas -@cindex local equivalence areas -@cindex EQUIVALENCE statement -@cindex statements, EQUIVALENCE - -@code{g77} treats storage-associated areas involving a @code{COMMON} -block as explained in the section on common blocks. - -A local @code{EQUIVALENCE} area is a collection of variables and arrays -connected to each other in any way via @code{EQUIVALENCE}, none of which are -listed in a @code{COMMON} statement. - -Currently, @code{g77} does not emit ``true'' debugging information for -members in a local @code{EQUIVALENCE} area, due to an apparent bug in the GBE. - -(As of Version 0.5.19, @code{g77} does emit debugging information for such -members in the form of a constant string specifying the base name of -the aggregate area and the offset of the member in bytes from the start -of the area. -Use the @samp{-fdebug-kludge} option to enable this behavior. -In @code{gdb}, use @samp{set language c} before printing the value -of the member, then @samp{set language fortran} to restore the default -language, since @code{gdb} doesn't provide a way to print a readable -version of a character string in Fortran language mode. - -This kludge will be removed in a future version of @code{g77} that, -in conjunction with a contemporary version of @code{gdb}, -properly supports Fortran-language debugging, including access -to members of @code{EQUIVALENCE} areas.) - -@xref{Code Gen Options,,Options for Code Generation Conventions}, -for information on the @samp{-fdebug-kludge} option. - -Moreover, @code{g77} implements a local @code{EQUIVALENCE} area such that its -type is an array of the C @code{char} data type. - -The name @code{g77} gives this array of @code{char} type is @samp{__g77_equiv_@var{x}}, -where @var{x} is the name of the item that is placed at the beginning (offset 0) -of this array. -If more than one such item is placed at the beginning, @var{x} is -the name that sorts to the top in an alphabetical sort of the list of -such items. - -When debugging, you must therefore access members of @code{EQUIVALENCE} -areas by specifying the appropriate @samp{__g77_equiv_@var{x}} -array section with the appropriate offset. -See the explanation of debugging @code{COMMON} blocks -for info applicable to debugging local @code{EQUIVALENCE} areas. - -(@emph{Note:} @code{g77} version 0.5.18 and earlier chose the name -for @var{x} using a different method when more than one name was -in the list of names of entities placed at the beginning of the -array. -Though the documentation specified that the first name listed in -the @code{EQUIVALENCE} statements was chosen for @var{x}, @code{g77} -in fact chose the name using a method that was so complicated, -it seemed easier to change it to an alphabetical sort than to describe the -previous method in the documentation.) - -@node Complex Variables -@section Complex Variables (COMPLEX) -@cindex complex variables -@cindex imaginary part of complex -@cindex COMPLEX statement -@cindex statements, COMPLEX - -As of 0.5.20, @code{g77} defaults to handling @code{COMPLEX} types -(and related intrinsics, constants, functions, and so on) -in a manner that -makes direct debugging involving these types in Fortran -language mode difficult. - -Essentially, @code{g77} implements these types using an -internal construct similar to C's @code{struct}, at least -as seen by the @code{gcc} back end. - -Currently, the back end, when outputting debugging info with -the compiled code for the assembler to digest, does not detect -these @code{struct} types as being substitutes for Fortran -complex. -As a result, the Fortran language modes of debuggers such as -@code{gdb} see these types as C @code{struct} types, which -they might or might not support. - -Until this is fixed, switch to C language mode to work with -entities of @code{COMPLEX} type and then switch back to Fortran language -mode afterward. -(In @code{gdb}, this is accomplished via @samp{set lang c} and -either @samp{set lang fortran} or @samp{set lang auto}.) - -@emph{Note:} Compiling with the @samp{-fno-emulate-complex} option -avoids the debugging problem, but is known to cause other problems -like compiler crashes and generation of incorrect code, so it is -not recommended. - -@node Arrays -@section Arrays (DIMENSION) -@cindex DIMENSION statement -@cindex statements, DIMENSION -@cindex array ordering -@cindex ordering, array -@cindex column-major ordering -@cindex row-major ordering -@cindex arrays - -Fortran uses ``column-major ordering'' in its arrays. -This differs from other languages, such as C, which use ``row-major ordering''. -The difference is that, with Fortran, array elements adjacent to -each other in memory differ in the @emph{first} subscript instead of -the last; @samp{A(5,10,20)} immediately follows @samp{A(4,10,20)}, -whereas with row-major ordering it would follow @samp{A(5,10,19)}. - -This consideration -affects not only interfacing with and debugging Fortran code, -it can greatly affect how code is designed and written, especially -when code speed and size is a concern. - -Fortran also differs from C, a popular language for interfacing and -to support directly in debuggers, in the way arrays are treated. -In C, arrays are single-dimensional and have interesting relationships -to pointers, neither of which is true for Fortran. -As a result, dealing with Fortran arrays from within -an environment limited to C concepts can be challenging. - -For example, accessing the array element @samp{A(5,10,20)} is easy enough -in Fortran (use @samp{A(5,10,20)}), but in C some difficult machinations -are needed. -First, C would treat the A array as a single-dimension array. -Second, C does not understand low bounds for arrays as does Fortran. -Third, C assumes a low bound of zero (0), while Fortran defaults to a -low bound of one (1) and can supports an arbitrary low bound. -Therefore, calculations must be done -to determine what the C equivalent of @samp{A(5,10,20)} would be, and these -calculations require knowing the dimensions of @samp{A}. - -For @samp{DIMENSION A(2:11,21,0:29)}, the calculation of the offset of -@samp{A(5,10,20)} would be: - -@example - (5-2) -+ (10-1)*(11-2+1) -+ (20-0)*(11-2+1)*(21-1+1) -= 4293 -@end example - -@noindent -So the C equivalent in this case would be @samp{a[4293]}. - -When using a debugger directly on Fortran code, the C equivalent -might not work, because some debuggers cannot understand the notion -of low bounds other than zero. However, unlike @code{f2c}, @code{g77} -does inform the GBE that a multi-dimensional array (like @samp{A} -in the above example) is really multi-dimensional, rather than a -single-dimensional array, so at least the dimensionality of the array -is preserved. - -Debuggers that understand Fortran should have no trouble with -non-zero low bounds, but for non-Fortran debuggers, especially -C debuggers, the above example might have a C equivalent of -@samp{a[4305]}. -This calculation is arrived at by eliminating the subtraction -of the lower bound in the first parenthesized expression on each -line---that is, for @samp{(5-2)} substitute @samp{(5)}, for @samp{(10-1)} -substitute @samp{(10)}, and for @samp{(20-0)} substitute @samp{(20)}. -Actually, the implication of -this can be that the expression @samp{*(&a[2][1][0] + 4293)} works fine, -but that @samp{a[20][10][5]} produces the equivalent of -@samp{*(&a[0][0][0] + 4305)} because of the missing lower bounds. - -Come to think of it, perhaps -the behavior is due to the debugger internally compensating for -the lower bounds by offsetting the base address of @samp{a}, leaving -@samp{&a} set lower, in this case, than @samp{&a[2][1][0]} (the address of -its first element as identified by subscripts equal to the -corresponding lower bounds). - -You know, maybe nobody really needs to use arrays. - -@node Adjustable Arrays -@section Adjustable Arrays (DIMENSION) -@cindex arrays, adjustable -@cindex adjustable arrays -@cindex arrays, automatic -@cindex automatic arrays -@cindex DIMENSION statement -@cindex statements, DIMENSION -@cindex dimensioning arrays -@cindex arrays, dimensioning - -Adjustable and automatic arrays in Fortran require the implementation -(in this -case, the @code{g77} compiler) to ``memorize'' the expressions that -dimension the arrays each time the procedure is invoked. -This is so that subsequent changes to variables used in those -expressions, made during execution of the procedure, do not -have any effect on the dimensions of those arrays. - -For example: - -@example -REAL ARRAY(5) -DATA ARRAY/5*2/ -CALL X(ARRAY, 5) -END -SUBROUTINE X(A, N) -DIMENSION A(N) -N = 20 -PRINT *, N, A -END -@end example - -@noindent -Here, the implementation should, when running the program, print something -like: - -@example -20 2. 2. 2. 2. 2. -@end example - -@noindent -Note that this shows that while the value of @samp{N} was successfully -changed, the size of the @samp{A} array remained at 5 elements. - -To support this, @code{g77} generates code that executes before any user -code (and before the internally generated computed @code{GOTO} to handle -alternate entry points, as described below) that evaluates each -(nonconstant) expression in the list of subscripts for an -array, and saves the result of each such evaluation to be used when -determining the size of the array (instead of re-evaluating the -expressions). - -So, in the above example, when @samp{X} is first invoked, code is -executed that copies the value of @samp{N} to a temporary. -And that same temporary serves as the actual high bound for the single -dimension of the @samp{A} array (the low bound being the constant 1). -Since the user program cannot (legitimately) change the value -of the temporary during execution of the procedure, the size -of the array remains constant during each invocation. - -For alternate entry points, the code @code{g77} generates takes into -account the possibility that a dummy adjustable array is not actually -passed to the actual entry point being invoked at that time. -In that case, the public procedure implementing the entry point -passes to the master private procedure implementing all the -code for the entry points a @code{NULL} pointer where a pointer to that -adjustable array would be expected. -The @code{g77}-generated code -doesn't attempt to evaluate any of the expressions in the subscripts -for an array if the pointer to that array is @code{NULL} at run time in -such cases. -(Don't depend on this particular implementation -by writing code that purposely passes @code{NULL} pointers where the -callee expects adjustable arrays, even if you know the callee -won't reference the arrays---nor should you pass @code{NULL} pointers -for any dummy arguments used in calculating the bounds of such -arrays or leave undefined any values used for that purpose in -COMMON---because the way @code{g77} implements these things might -change in the future!) - -@node Alternate Entry Points -@section Alternate Entry Points (ENTRY) -@cindex alternate entry points -@cindex entry points -@cindex ENTRY statement -@cindex statements, ENTRY - -The GBE does not understand the general concept of -alternate entry points as Fortran provides via the ENTRY statement. -@code{g77} gets around this by using an approach to compiling procedures -having at least one @code{ENTRY} statement that is almost identical to the -approach used by @code{f2c}. -(An alternate approach could be used that -would probably generate faster, but larger, code that would also -be a bit easier to debug.) - -Information on how @code{g77} implements @code{ENTRY} is provided for those -trying to debug such code. -The choice of implementation seems -unlikely to affect code (compiled in other languages) that interfaces -to such code. - -@code{g77} compiles exactly one public procedure for the primary entry -point of a procedure plus each @code{ENTRY} point it specifies, as usual. -That is, in terms of the public interface, there is no difference -between - -@example -SUBROUTINE X -END -SUBROUTINE Y -END -@end example - -@noindent -and: - -@example -SUBROUTINE X -ENTRY Y -END -@end example - -The difference between the above two cases lies in the code compiled -for the @samp{X} and @samp{Y} procedures themselves, plus the fact that, -for the second case, an extra internal procedure is compiled. - -For every Fortran procedure with at least one @code{ENTRY} -statement, @code{g77} compiles an extra procedure -named @samp{__g77_masterfun_@var{x}}, where @var{x} is -the name of the primary entry point (which, in the above case, -using the standard compiler options, would be @samp{x_} in C). - -This extra procedure is compiled as a private procedure---that is, -a procedure not accessible by name to separately compiled modules. -It contains all the code in the program unit, including the code -for the primary entry point plus for every entry point. -(The code for each public procedure is quite short, and explained later.) - -The extra procedure has some other interesting characteristics. - -The argument list for this procedure is invented by @code{g77}. -It contains -a single integer argument named @samp{__g77_which_entrypoint}, -passed by value (as in Fortran's @samp{%VAL()} intrinsic), specifying the -entry point index---0 for the primary entry point, 1 for the -first entry point (the first @code{ENTRY} statement encountered), 2 for -the second entry point, and so on. - -It also contains, for functions returning @code{CHARACTER} and -(when @samp{-ff2c} is in effect) @code{COMPLEX} functions, -and for functions returning different types among the -@code{ENTRY} statements (e.g. @samp{REAL FUNCTION R()} -containing @samp{ENTRY I()}), an argument named @samp{__g77_result} that -is expected at run time to contain a pointer to where to store -the result of the entry point. -For @code{CHARACTER} functions, this -storage area is an array of the appropriate number of characters; -for @code{COMPLEX} functions, it is the appropriate area for the return -type; for multiple-return-type functions, it is a union of all the supported return -types (which cannot include @code{CHARACTER}, since combining @code{CHARACTER} -and non-@code{CHARACTER} return types via @code{ENTRY} in a single function -is not supported by @code{g77}). - -For @code{CHARACTER} functions, the @samp{__g77_result} argument is followed -by yet another argument named @samp{__g77_length} that, at run time, -specifies the caller's expected length of the returned value. -Note that only @code{CHARACTER*(*)} functions and entry points actually -make use of this argument, even though it is always passed by -all callers of public @code{CHARACTER} functions (since the caller does not -generally know whether such a function is @code{CHARACTER*(*)} or whether -there are any other callers that don't have that information). - -The rest of the argument list is the union of all the arguments -specified for all the entry points (in their usual forms, e.g. -@code{CHARACTER} arguments have extra length arguments, all appended at -the end of this list). -This is considered the ``master list'' of -arguments. - -The code for this procedure has, before the code for the first -executable statement, code much like that for the following Fortran -statement: - -@smallexample - GOTO (100000,100001,100002), __g77_which_entrypoint -100000 @dots{}code for primary entry point@dots{} -100001 @dots{}code immediately following first ENTRY statement@dots{} -100002 @dots{}code immediately following second ENTRY statement@dots{} -@end smallexample - -@noindent -(Note that invalid Fortran statement labels and variable names -are used in the above example to highlight the fact that it -represents code generated by the @code{g77} internals, not code to be -written by the user.) - -It is this code that, when the procedure is called, picks which -entry point to start executing. - -Getting back to the public procedures (@samp{x} and @samp{Y} in the original -example), those procedures are fairly simple. -Their interfaces -are just like they would be if they were self-contained procedures -(without @code{ENTRY}), of course, since that is what the callers -expect. -Their code consists of simply calling the private -procedure, described above, with the appropriate extra arguments -(the entry point index, and perhaps a pointer to a multiple-type- -return variable, local to the public procedure, that contains -all the supported returnable non-character types). -For arguments -that are not listed for a given entry point that are listed for -other entry points, and therefore that are in the ``master list'' -for the private procedure, null pointers (in C, the @code{NULL} macro) -are passed. -Also, for entry points that are part of a multiple-type- -returning function, code is compiled after the call of the private -procedure to extract from the multi-type union the appropriate result, -depending on the type of the entry point in question, returning -that result to the original caller. - -When debugging a procedure containing alternate entry points, you -can either set a break point on the public procedure itself (e.g. -a break point on @samp{X} or @samp{Y}) or on the private procedure that -contains most of the pertinent code (e.g. @samp{__g77_masterfun_@var{x}}). -If you do the former, you should use the debugger's command to -``step into'' the called procedure to get to the actual code; with -the latter approach, the break point leaves you right at the -actual code, skipping over the public entry point and its call -to the private procedure (unless you have set a break point there -as well, of course). - -Further, the list of dummy arguments that is visible when the -private procedure is active is going to be the expanded version -of the list for whichever particular entry point is active, -as explained above, and the way in which return values are -handled might well be different from how they would be handled -for an equivalent single-entry function. - -@node Alternate Returns -@section Alternate Returns (SUBROUTINE and RETURN) -@cindex subroutines -@cindex alternate returns -@cindex SUBROUTINE statement -@cindex statements, SUBROUTINE -@cindex RETURN statement -@cindex statements, RETURN - -Subroutines with alternate returns (e.g. @samp{SUBROUTINE X(*)} and -@samp{CALL X(*50)}) are implemented by @code{g77} as functions returning -the C @code{int} type. -The actual alternate-return arguments are omitted from the calling sequence. -Instead, the caller uses -the return value to do a rough equivalent of the Fortran -computed-@code{GOTO} statement, as in @samp{GOTO (50), X()} in the -example above (where @samp{X} is quietly declared as an @code{INTEGER(KIND=1)} -function), and the callee just returns whatever integer -is specified in the @code{RETURN} statement for the subroutine -For example, @samp{RETURN 1} is implemented as @samp{X = 1} followed -by @samp{RETURN} -in C, and @samp{RETURN} by itself is @samp{X = 0} and @samp{RETURN}). - -@node Assigned Statement Labels -@section Assigned Statement Labels (ASSIGN and GOTO) -@cindex assigned statement labels -@cindex statement labels, assigned -@cindex ASSIGN statement -@cindex statements, ASSIGN -@cindex GOTO statement -@cindex statements, GOTO - -For portability to machines where a pointer (such as to a label, -which is how @code{g77} implements @code{ASSIGN} and its relatives, -the assigned-@code{GOTO} and assigned-@code{FORMAT}-I/O statements) -is wider (bitwise) than an @code{INTEGER(KIND=1)}, @code{g77} -uses a different memory location to hold the @code{ASSIGN}ed value of a variable -than it does the numerical value in that variable, unless the -variable is wide enough (can hold enough bits). - -In particular, while @code{g77} implements - -@example -I = 10 -@end example - -@noindent -as, in C notation, @samp{i = 10;}, it implements - -@example -ASSIGN 10 TO I -@end example - -@noindent -as, in GNU's extended C notation (for the label syntax), -@samp{__g77_ASSIGN_I = &&L10;} (where @samp{L10} is just a massaging -of the Fortran label @samp{10} to make the syntax C-like; @code{g77} doesn't -actually generate the name @samp{L10} or any other name like that, -since debuggers cannot access labels anyway). - -While this currently means that an @code{ASSIGN} statement does not -overwrite the numeric contents of its target variable, @emph{do not} -write any code depending on this feature. -@code{g77} has already changed this implementation across -versions and might do so in the future. -This information is provided only to make debugging Fortran programs -compiled with the current version of @code{g77} somewhat easier. -If there's no debugger-visible variable named @samp{__g77_ASSIGN_I} -in a program unit that does @samp{ASSIGN 10 TO I}, that probably -means @code{g77} has decided it can store the pointer to the label directly -into @samp{I} itself. - -@xref{Ugly Assigned Labels}, for information on a command-line option -to force @code{g77} to use the same storage for both normal and -assigned-label uses of a variable. - -@node Run-time Library Errors -@section Run-time Library Errors -@cindex IOSTAT= -@cindex error values -@cindex error messages -@cindex messages, run-time -@cindex I/O, errors - -The @code{libg2c} library currently has the following table to relate -error code numbers, returned in @code{IOSTAT=} variables, to messages. -This information should, in future versions of this document, be -expanded upon to include detailed descriptions of each message. - -In line with good coding practices, any of the numbers in the -list below should @emph{not} be directly written into Fortran -code you write. -Instead, make a separate @code{INCLUDE} file that defines -@code{PARAMETER} names for them, and use those in your code, -so you can more easily change the actual numbers in the future. - -The information below is culled from the definition -of @samp{F_err} in @file{f/runtime/libI77/err.c} in the -@code{g77} source tree. - -@smallexample -100: "error in format" -101: "illegal unit number" -102: "formatted io not allowed" -103: "unformatted io not allowed" -104: "direct io not allowed" -105: "sequential io not allowed" -106: "can't backspace file" -107: "null file name" -108: "can't stat file" -109: "unit not connected" -110: "off end of record" -111: "truncation failed in endfile" -112: "incomprehensible list input" -113: "out of free space" -114: "unit not connected" -115: "read unexpected character" -116: "bad logical input field" -117: "bad variable type" -118: "bad namelist name" -119: "variable not in namelist" -120: "no end record" -121: "variable count incorrect" -122: "subscript for scalar variable" -123: "invalid array section" -124: "substring out of bounds" -125: "subscript out of bounds" -126: "can't read file" -127: "can't write file" -128: "'new' file exists" -129: "can't append to file" -130: "non-positive record number" -131: "I/O started while already doing I/O" -@end smallexample - -@node Collected Fortran Wisdom -@chapter Collected Fortran Wisdom -@cindex wisdom -@cindex legacy code -@cindex code, legacy -@cindex writing code -@cindex code, writing - -Most users of @code{g77} can be divided into two camps: - -@itemize @bullet -@item -Those writing new Fortran code to be compiled by @code{g77}. - -@item -Those using @code{g77} to compile existing, ``legacy'' code. -@end itemize - -Users writing new code generally understand most of the necessary -aspects of Fortran to write ``mainstream'' code, but often need -help deciding how to handle problems, such as the construction -of libraries containing @code{BLOCK DATA}. - -Users dealing with ``legacy'' code sometimes don't have much -experience with Fortran, but believe that the code they're compiling -already works when compiled by other compilers (and might -not understand why, as is sometimes the case, it doesn't work -when compiled by @code{g77}). - -The following information is designed to help users do a better job -coping with existing, ``legacy'' Fortran code, and with writing -new code as well. - -@menu -* Advantages Over f2c:: If @code{f2c} is so great, why @code{g77}? -* Block Data and Libraries:: How @code{g77} solves a common problem. -* Loops:: Fortran @code{DO} loops surprise many people. -* Working Programs:: Getting programs to work should be done first. -* Overly Convenient Options:: Temptations to avoid, habits to not form. -* Faster Programs:: Everybody wants these, but at what cost? -@end menu - -@node Advantages Over f2c -@section Advantages Over f2c - -Without @code{f2c}, @code{g77} would have taken much longer to -do and probably not been as good for quite a while. -Sometimes people who notice how much @code{g77} depends on, and -documents encouragement to use, @code{f2c} ask why @code{g77} -was created if @code{f2c} already existed. - -This section gives some basic answers to these questions, though it -is not intended to be comprehensive. - -@menu -* Language Extensions:: Features used by Fortran code. -* Compiler Options:: Features helpful during development. -* Compiler Speed:: Speed of the compilation process. -* Program Speed:: Speed of the generated, optimized code. -* Ease of Debugging:: Debugging ease-of-use at the source level. -* Character and Hollerith Constants:: A byte saved is a byte earned. -@end menu - -@node Language Extensions -@subsection Language Extensions - -@code{g77} offers several extensions to the Fortran language that @code{f2c} -doesn't. - -However, @code{f2c} offers a few that @code{g77} doesn't, like -fairly complete support for @code{INTEGER*2}. -It is expected that @code{g77} will offer some or all of these missing -features at some time in the future. -(Version 0.5.18 of @code{g77} offers some rudimentary support for some -of these features.) - -@node Compiler Options -@subsection Compiler Options - -@code{g77} offers a whole bunch of compiler options that @code{f2c} doesn't. - -However, @code{f2c} offers a few that @code{g77} doesn't, like an -option to generate code to check array subscripts at run time. -It is expected that @code{g77} will offer some or all of these -missing options at some time in the future. - -@node Compiler Speed -@subsection Compiler Speed - -Saving the steps of writing and then rereading C code is a big reason -why @code{g77} should be able to compile code much faster than using -@code{f2c} in conjunction with the equivalent invocation of @code{gcc}. - -However, due to @code{g77}'s youth, lots of self-checking is still being -performed. -As a result, this improvement is as yet unrealized -(though the potential seems to be there for quite a big speedup -in the future). -It is possible that, as of version 0.5.18, @code{g77} -is noticeably faster compiling many Fortran source files than using -@code{f2c} in conjunction with @code{gcc}. - -@node Program Speed -@subsection Program Speed - -@code{g77} has the potential to better optimize code than @code{f2c}, -even when @code{gcc} is used to compile the output of @code{f2c}, -because @code{f2c} must necessarily -translate Fortran into a somewhat lower-level language (C) that cannot -preserve all the information that is potentially useful for optimization, -while @code{g77} can gather, preserve, and transmit that information directly -to the GBE. - -For example, @code{g77} implements @code{ASSIGN} and assigned -@code{GOTO} using direct assignment of pointers to labels and direct -jumps to labels, whereas @code{f2c} maps the assigned labels to -integer values and then uses a C @code{switch} statement to encode -the assigned @code{GOTO} statements. - -However, as is typical, theory and reality don't quite match, at least -not in all cases, so it is still the case that @code{f2c} plus @code{gcc} -can generate code that is faster than @code{g77}. - -Version 0.5.18 of @code{g77} offered default -settings and options, via patches to the @code{gcc} -back end, that allow for better program speed, though -some of these improvements also affected the performance -of programs translated by @code{f2c} and then compiled -by @code{g77}'s version of @code{gcc}. - -Version 0.5.20 of @code{g77} offers further performance -improvements, at least one of which (alias analysis) is -not generally applicable to @code{f2c} (though @code{f2c} -could presumably be changed to also take advantage of -this new capability of the @code{gcc} back end, assuming -this is made available in an upcoming release of @code{gcc}). - -@node Ease of Debugging -@subsection Ease of Debugging - -Because @code{g77} compiles directly to assembler code like @code{gcc}, -instead of translating to an intermediate language (C) as does @code{f2c}, -support for debugging can be better for @code{g77} than @code{f2c}. - -However, although @code{g77} might be somewhat more ``native'' in terms of -debugging support than @code{f2c} plus @code{gcc}, there still are a lot -of things ``not quite right''. -Many of the important ones should be resolved in the near future. - -For example, @code{g77} doesn't have to worry about reserved names -like @code{f2c} does. -Given @samp{FOR = WHILE}, @code{f2c} must necessarily -translate this to something @emph{other} than -@samp{for = while;}, because C reserves those words. - -However, @code{g77} does still uses things like an extra level of indirection -for @code{ENTRY}-laden procedures---in this case, because the back end doesn't -yet support multiple entry points. - -Another example is that, given - -@smallexample -COMMON A, B -EQUIVALENCE (B, C) -@end smallexample - -@noindent -the @code{g77} user should be able to access the variables directly, by name, -without having to traverse C-like structures and unions, while @code{f2c} -is unlikely to ever offer this ability (due to limitations in the -C language). - -However, due to apparent bugs in the back end, @code{g77} currently doesn't -take advantage of this facility at all---it doesn't emit any debugging -information for @code{COMMON} and @code{EQUIVALENCE} areas, -other than information -on the array of @code{char} it creates (and, in the case -of local @code{EQUIVALENCE}, names) for each such area. - -Yet another example is arrays. -@code{g77} represents them to the debugger -using the same ``dimensionality'' as in the source code, while @code{f2c} -must necessarily convert them all to one-dimensional arrays to fit -into the confines of the C language. -However, the level of support -offered by debuggers for interactive Fortran-style access to arrays -as compiled by @code{g77} can vary widely. -In some cases, it can actually -be an advantage that @code{f2c} converts everything to widely supported -C semantics. - -In fairness, @code{g77} could do many of the things @code{f2c} does -to get things working at least as well as @code{f2c}---for now, -the developers prefer making @code{g77} work the -way they think it is supposed to, and finding help improving the -other products (the back end of @code{gcc}; @code{gdb}; and so on) -to get things working properly. - -@node Character and Hollerith Constants -@subsection Character and Hollerith Constants -@cindex character constants -@cindex constants, character -@cindex Hollerith constants -@cindex constants, Hollerith -@cindex trailing null byte -@cindex null byte, trailing -@cindex zero byte, trailing - -To avoid the extensive hassle that would be needed to avoid this, -@code{f2c} uses C character constants to encode character and Hollerith -constants. -That means a constant like @samp{'HELLO'} is translated to -@samp{"hello"} in C, which further means that an extra null byte is -present at the end of the constant. -This null byte is superfluous. - -@code{g77} does not generate such null bytes. -This represents significant -savings of resources, such as on systems where @file{/dev/null} or -@file{/dev/zero} represent bottlenecks in the systems' performance, -because @code{g77} simply asks for fewer zeros from the operating -system than @code{f2c}. -(Avoiding spurious use of zero bytes, each byte typically have -eight zero bits, also reduces the liabilities in case -Microsoft's rumored patent on the digits 0 and 1 is upheld.) - -@node Block Data and Libraries -@section Block Data and Libraries -@cindex block data and libraries -@cindex BLOCK DATA statement -@cindex statements, BLOCK DATA -@cindex libraries, containing BLOCK DATA -@cindex @code{f2c} compatibility -@cindex compatibility, @code{f2c} - -To ensure that block data program units are linked, especially a concern -when they are put into libraries, give each one a name (as in -@samp{BLOCK DATA FOO}) and make sure there is an @samp{EXTERNAL FOO} -statement in every program unit that uses any common block -initialized by the corresponding @code{BLOCK DATA}. -@code{g77} currently compiles a @code{BLOCK DATA} as if it were a -@code{SUBROUTINE}, -that is, it generates an actual procedure having the appropriate name. -The procedure does nothing but return immediately if it happens to be -called. -For @samp{EXTERNAL FOO}, where @samp{FOO} is not otherwise referenced in the -same program unit, @code{g77} assumes there exists a @samp{BLOCK DATA FOO} -in the program and ensures that by generating a -reference to it so the linker will make sure it is present. -(Specifically, @code{g77} outputs in the data section a static pointer to the -external name @samp{FOO}.) - -The implementation @code{g77} currently uses to make this work is -one of the few things not compatible with @code{f2c} as currently -shipped. -@code{f2c} currently does nothing with @samp{EXTERNAL FOO} except -issue a warning that @samp{FOO} is not otherwise referenced, -and, for @samp{BLOCK DATA FOO}, -@code{f2c} doesn't generate a dummy procedure with the name @samp{FOO}. -The upshot is that you shouldn't mix @code{f2c} and @code{g77} in -this particular case. -If you use @code{f2c} to compile @samp{BLOCK DATA FOO}, -then any @code{g77}-compiled program unit that says @samp{EXTERNAL FOO} -will result in an unresolved reference when linked. -If you do the -opposite, then @samp{FOO} might not be linked in under various -circumstances (such as when @samp{FOO} is in a library, or you're -using a ``clever'' linker---so clever, it produces a broken program -with little or no warning by omitting initializations of global data -because they are contained in unreferenced procedures). - -The changes you make to your code to make @code{g77} handle this situation, -however, appear to be a widely portable way to handle it. -That is, many systems permit it (as they should, since the -FORTRAN 77 standard permits @samp{EXTERNAL FOO} when @samp{FOO} -is a block data program unit), and of the ones -that might not link @samp{BLOCK DATA FOO} under some circumstances, most of -them appear to do so once @samp{EXTERNAL FOO} is present in the appropriate -program units. - -Here is the recommended approach to modifying a program containing -a program unit such as the following: - -@smallexample -BLOCK DATA FOO -COMMON /VARS/ X, Y, Z -DATA X, Y, Z / 3., 4., 5. / -END -@end smallexample - -@noindent -If the above program unit might be placed in a library module, then -ensure that every program unit in every program that references that -particular @code{COMMON} area uses the @code{EXTERNAL} statement -to force the area to be initialized. - -For example, change a program unit that starts with - -@smallexample -INTEGER FUNCTION CURX() -COMMON /VARS/ X, Y, Z -CURX = X -END -@end smallexample - -@noindent -so that it uses the @code{EXTERNAL} statement, as in: - -@smallexample -INTEGER FUNCTION CURX() -COMMON /VARS/ X, Y, Z -EXTERNAL FOO -CURX = X -END -@end smallexample - -@noindent -That way, @samp{CURX} is compiled by @code{g77} (and many other -compilers) so that the linker knows it must include @samp{FOO}, -the @code{BLOCK DATA} program unit that sets the initial values -for the variables in @samp{VAR}, in the executable program. - -@node Loops -@section Loops -@cindex DO statement -@cindex statements, DO -@cindex trips, number of -@cindex number of trips - -The meaning of a @code{DO} loop in Fortran is precisely specified -in the Fortran standard@dots{}and is quite different from what -many programmers might expect. - -In particular, Fortran indexed @code{DO} loops are implemented as if -the number of trips through the loop is calculated @emph{before} -the loop is entered. - -The number of trips for a loop is calculated from the @var{start}, -@var{end}, and @var{increment} values specified in a statement such as: - -@smallexample -DO @var{iter} = @var{start}, @var{end}, @var{increment} -@end smallexample - -@noindent -The trip count is evaluated using a fairly simple formula -based on the three values following the @samp{=} in the -statement, and it is that trip count that is effectively -decremented during each iteration of the loop. -If, at the beginning of an iteration of the loop, the -trip count is zero or negative, the loop terminates. -The per-loop-iteration modifications to @var{iter} are not -related to determining whether to terminate the loop. - -There are two important things to remember about the trip -count: - -@itemize @bullet -@item -It can be @emph{negative}, in which case it is -treated as if it was zero---meaning the loop is -not executed at all. - -@item -The type used to @emph{calculate} the trip count -is the same type as @var{iter}, but the final -calculation, and thus the type of the trip -count itself, always is @code{INTEGER(KIND=1)}. -@end itemize - -These two items mean that there are loops that cannot -be written in straightforward fashion using the Fortran @code{DO}. - -For example, on a system with the canonical 32-bit two's-complement -implementation of @code{INTEGER(KIND=1)}, the following loop will not work: - -@smallexample -DO I = -2000000000, 2000000000 -@end smallexample - -@noindent -Although the @var{start} and @var{end} values are well within -the range of @code{INTEGER(KIND=1)}, the @emph{trip count} is not. -The expected trip count is 40000000001, which is outside -the range of @code{INTEGER(KIND=1)} on many systems. - -Instead, the above loop should be constructed this way: - -@smallexample -I = -2000000000 -DO - IF (I .GT. 2000000000) EXIT - @dots{} - I = I + 1 -END DO -@end smallexample - -@noindent -The simple @code{DO} construct and the @code{EXIT} statement -(used to leave the innermost loop) -are F90 features that @code{g77} supports. - -Some Fortran compilers have buggy implementations of @code{DO}, -in that they don't follow the standard. -They implement @code{DO} as a straightforward translation -to what, in C, would be a @code{for} statement. -Instead of creating a temporary variable to hold the trip count -as calculated at run time, these compilers -use the iteration variable @var{iter} to control -whether the loop continues at each iteration. - -The bug in such an implementation shows up when the -trip count is within the range of the type of @var{iter}, -but the magnitude of @samp{ABS(@var{end}) + ABS(@var{incr})} -exceeds that range. For example: - -@smallexample -DO I = 2147483600, 2147483647 -@end smallexample - -@noindent -A loop started by the above statement will work as implemented -by @code{g77}, but the use, by some compilers, of a -more C-like implementation akin to - -@smallexample -for (i = 2147483600; i <= 2147483647; ++i) -@end smallexample - -@noindent -produces a loop that does not terminate, because @samp{i} -can never be greater than 2147483647, since incrementing it -beyond that value overflows @samp{i}, setting it to -2147483648. -This is a large, negative number that still is less than 2147483647. - -Another example of unexpected behavior of @code{DO} involves -using a nonintegral iteration variable @var{iter}, that is, -a @code{REAL} variable. -Consider the following program: - -@smallexample - DATA BEGIN, END, STEP /.1, .31, .007/ - DO 10 R = BEGIN, END, STEP - IF (R .GT. END) PRINT *, R, ' .GT. ', END, '!!' - PRINT *,R -10 CONTINUE - PRINT *,'LAST = ',R - IF (R .LE. END) PRINT *, R, ' .LE. ', END, '!!' - END -@end smallexample - -@noindent -A C-like view of @code{DO} would hold that the two ``exclamatory'' -@code{PRINT} statements are never executed. -However, this is the output of running the above program -as compiled by @code{g77} on a GNU/Linux ix86 system: - -@smallexample - .100000001 - .107000001 - .114 - .120999999 - @dots{} - .289000005 - .296000004 - .303000003 -LAST = .310000002 - .310000002 .LE. .310000002!! -@end smallexample - -Note that one of the two checks in the program turned up -an apparent violation of the programmer's expectation---yet, -the loop is correctly implemented by @code{g77}, in that -it has 30 iterations. -This trip count of 30 is correct when evaluated using -the floating-point representations for the @var{begin}, -@var{end}, and @var{incr} values (.1, .31, .007) on GNU/Linux -ix86 are used. -On other systems, an apparently more accurate trip count -of 31 might result, but, nevertheless, @code{g77} is -faithfully following the Fortran standard, and the result -is not what the author of the sample program above -apparently expected. -(Such other systems might, for different values in the @code{DATA} -statement, violate the other programmer's expectation, -for example.) - -Due to this combination of imprecise representation -of floating-point values and the often-misunderstood -interpretation of @code{DO} by standard-conforming -compilers such as @code{g77}, use of @code{DO} loops -with @code{REAL} iteration -variables is not recommended. -Such use can be caught by specifying @samp{-Wsurprising}. -@xref{Warning Options}, for more information on this -option. - -@node Working Programs -@section Working Programs - -Getting Fortran programs to work in the first place can be -quite a challenge---even when the programs already work on -other systems, or when using other compilers. - -@code{g77} offers some facilities that might be useful for -tracking down bugs in such programs. - -@menu -* Not My Type:: -* Variables Assumed To Be Zero:: -* Variables Assumed To Be Saved:: -* Unwanted Variables:: -* Unused Arguments:: -* Surprising Interpretations of Code:: -* Aliasing Assumed To Work:: -* Output Assumed To Flush:: -* Large File Unit Numbers:: -* Floating point precision:: -* Inconsistent Calling Sequences:: -@end menu - -@node Not My Type -@subsection Not My Type -@cindex mistyped variables -@cindex variables, mistyped -@cindex mistyped functions -@cindex functions, mistyped -@cindex implicit typing - -A fruitful source of bugs in Fortran source code is use, or -mis-use, of Fortran's implicit-typing feature, whereby the -type of a variable, array, or function is determined by the -first character of its name. - -Simple cases of this include statements like @samp{LOGX=9.227}, -without a statement such as @samp{REAL LOGX}. -In this case, @samp{LOGX} is implicitly given @code{INTEGER(KIND=1)} -type, with the result of the assignment being that it is given -the value @samp{9}. - -More involved cases include a function that is defined starting -with a statement like @samp{DOUBLE PRECISION FUNCTION IPS(@dots{})}. -Any caller of this function that does not also declare @samp{IPS} -as type @code{DOUBLE PRECISION} (or, in GNU Fortran, @code{REAL(KIND=2)}) -is likely to assume it returns -@code{INTEGER}, or some other type, leading to invalid results -or even program crashes. - -The @samp{-Wimplicit} option might catch failures to -properly specify the types of -variables, arrays, and functions in the code. - -However, in code that makes heavy use of Fortran's -implicit-typing facility, this option might produce so -many warnings about cases that are working, it would be -hard to find the one or two that represent bugs. -This is why so many experienced Fortran programmers strongly -recommend widespread use of the @code{IMPLICIT NONE} statement, -despite it not being standard FORTRAN 77, to completely turn -off implicit typing. -(@code{g77} supports @code{IMPLICIT NONE}, as do almost all -FORTRAN 77 compilers.) - -Note that @samp{-Wimplicit} catches only implicit typing of -@emph{names}. -It does not catch implicit typing of expressions such -as @samp{X**(2/3)}. -Such expressions can be buggy as well---in fact, @samp{X**(2/3)} -is equivalent to @samp{X**0}, due to the way Fortran expressions -are given types and then evaluated. -(In this particular case, the programmer probably wanted -@samp{X**(2./3.)}.) - -@node Variables Assumed To Be Zero -@subsection Variables Assumed To Be Zero -@cindex zero-initialized variables -@cindex variables assumed to be zero -@cindex uninitialized variables - -Many Fortran programs were developed on systems that provided -automatic initialization of all, or some, variables and arrays -to zero. -As a result, many of these programs depend, sometimes -inadvertently, on this behavior, though to do so violates -the Fortran standards. - -You can ask @code{g77} for this behavior by specifying the -@samp{-finit-local-zero} option when compiling Fortran code. -(You might want to specify @samp{-fno-automatic} as well, -to avoid code-size inflation for non-optimized compilations.) - -Note that a program that works better when compiled with the -@samp{-finit-local-zero} option -is almost certainly depending on a particular system's, -or compiler's, tendency to initialize some variables to zero. -It might be worthwhile finding such cases and fixing them, -using techniques such as compiling with the @samp{-O -Wuninitialized} -options using @code{g77}. - -@node Variables Assumed To Be Saved -@subsection Variables Assumed To Be Saved -@cindex variables retaining values across calls -@cindex saved variables -@cindex static variables - -Many Fortran programs were developed on systems that -saved the values of all, or some, variables and arrays -across procedure calls. -As a result, many of these programs depend, sometimes -inadvertently, on being able to assign a value to a -variable, perform a @code{RETURN} to a calling procedure, -and, upon subsequent invocation, reference the previously -assigned variable to obtain the value. - -They expect this despite not using the @code{SAVE} statement -to specify that the value in a variable is expected to survive -procedure returns and calls. -Depending on variables and arrays to retain values across -procedure calls without using @code{SAVE} to require it violates -the Fortran standards. - -You can ask @code{g77} to assume @code{SAVE} is specified for all -relevant (local) variables and arrays by using the -@samp{-fno-automatic} option. - -Note that a program that works better when compiled with the -@samp{-fno-automatic} option -is almost certainly depending on not having to use -the @code{SAVE} statement as required by the Fortran standard. -It might be worthwhile finding such cases and fixing them, -using techniques such as compiling with the @samp{-O -Wuninitialized} -options using @code{g77}. - -@node Unwanted Variables -@subsection Unwanted Variables - -The @samp{-Wunused} option can find bugs involving -implicit typing, sometimes -more easily than using @samp{-Wimplicit} in code that makes -heavy use of implicit typing. -An unused variable or array might indicate that the -spelling for its declaration is different from that of -its intended uses. - -Other than cases involving typos, unused variables rarely -indicate actual bugs in a program. -However, investigating such cases thoroughly has, on occasion, -led to the discovery of code that had not been completely -written---where the programmer wrote declarations as needed -for the whole algorithm, wrote some or even most of the code -for that algorithm, then got distracted and forgot that the -job was not complete. - -@node Unused Arguments -@subsection Unused Arguments -@cindex unused arguments -@cindex arguments, unused - -As with unused variables, It is possible that unused arguments -to a procedure might indicate a bug. -Compile with @samp{-W -Wunused} option to catch cases of -unused arguments. - -Note that @samp{-W} also enables warnings regarding overflow -of floating-point constants under certain circumstances. - -@node Surprising Interpretations of Code -@subsection Surprising Interpretations of Code - -The @samp{-Wsurprising} option can help find bugs involving -expression evaluation or in -the way @code{DO} loops with non-integral iteration variables -are handled. -Cases found by this option might indicate a difference of -interpretation between the author of the code involved, and -a standard-conforming compiler such as @code{g77}. -Such a difference might produce actual bugs. - -In any case, changing the code to explicitly do what the -programmer might have expected it to do, so @code{g77} and -other compilers are more likely to follow the programmer's -expectations, might be worthwhile, especially if such changes -make the program work better. - -@node Aliasing Assumed To Work -@subsection Aliasing Assumed To Work -@cindex -falias-check option -@cindex options, -falias-check -@cindex -fargument-alias option -@cindex options, -fargument-alias -@cindex -fargument-noalias option -@cindex options, -fargument-noalias -@cindex -fno-argument-noalias-global option -@cindex options, -fno-argument-noalias-global -@cindex aliasing -@cindex anti-aliasing -@cindex overlapping arguments -@cindex overlays -@cindex association, storage -@cindex storage association -@cindex scheduling of reads and writes -@cindex reads and writes, scheduling - -The @samp{-falias-check}, @samp{-fargument-alias}, -@samp{-fargument-noalias}, -and @samp{-fno-argument-noalias-global} options, -introduced in version 0.5.20 and -@code{g77}'s version 2.7.2.2.f.2 of @code{gcc}, -were withdrawn as of @code{g77} version 0.5.23 -due to their not being supported by @code{gcc} version 2.8. - -These options, which control the assumptions regarding aliasing -(overlapping) of writes and reads to main memory (core) made -by the @code{gcc} back end, -might well be added back (in some form) in a future version -of @code{gcc}. - -However, these options @emph{are} supported by @code{egcs}. - -The information below still is useful, but applies to -only those versions of @code{g77} that support the -alias analysis implied by support for these options. - -These options are effective only when compiling with @samp{-O} -(specifying any level other than @samp{-O0}) -or with @samp{-falias-check}. - -The default for Fortran code is @samp{-fargument-noalias-global}. -(The default for C code and code written in other C-based languages -is @samp{-fargument-alias}. -These defaults apply regardless of whether you use @code{g77} or -@code{gcc} to compile your code.) - -Note that, on some systems, compiling with @samp{-fforce-addr} in -effect can produce more optimal code when the default aliasing -options are in effect (and when optimization is enabled). - -If your program is not working when compiled with optimization, -it is possible it is violating the Fortran standards (77 and 90) -by relying on the ability to ``safely'' modify variables and -arrays that are aliased, via procedure calls, to other variables -and arrays, without using @code{EQUIVALENCE} to explicitly -set up this kind of aliasing. - -(The FORTRAN 77 standard's prohibition of this sort of -overlap, generally referred to therein as ``storage -assocation'', appears in Sections 15.9.3.6. -This prohibition allows implementations, such as @code{g77}, -to, for example, implement the passing of procedures and -even values in @code{COMMON} via copy operations into local, -perhaps more efficiently accessed temporaries at entry to a -procedure, and, where appropriate, via copy operations back -out to their original locations in memory at exit from that -procedure, without having to take into consideration the -order in which the local copies are updated by the code, -among other things.) - -To test this hypothesis, try compiling your program with -the @samp{-fargument-alias} option, which causes the -compiler to revert to assumptions essentially the same as -made by versions of @code{g77} prior to 0.5.20. - -If the program works using this option, that strongly suggests -that the bug is in your program. -Finding and fixing the bug(s) should result in a program that -is more standard-conforming and that can be compiled by @code{g77} -in a way that results in a faster executable. - -(You might want to try compiling with @samp{-fargument-noalias}, -a kind of half-way point, to see if the problem is limited to -aliasing between dummy arguments and @code{COMMON} variables---this -option assumes that such aliasing is not done, while still allowing -aliasing among dummy arguments.) - -An example of aliasing that is invalid according to the standards -is shown in the following program, which might @emph{not} produce -the expected results when executed: - -@smallexample -I = 1 -CALL FOO(I, I) -PRINT *, I -END - -SUBROUTINE FOO(J, K) -J = J + K -K = J * K -PRINT *, J, K -END -@end smallexample - -The above program attempts to use the temporary aliasing of the -@samp{J} and @samp{K} arguments in @samp{FOO} to effect a -pathological behavior---the simultaneous changing of the values -of @emph{both} @samp{J} and @samp{K} when either one of them -is written. - -The programmer likely expects the program to print these values: - -@example -2 4 -4 -@end example - -However, since the program is not standard-conforming, an -implementation's behavior when running it is undefined, because -subroutine @samp{FOO} modifies at least one of the arguments, -and they are aliased with each other. -(Even if one of the assignment statements was deleted, the -program would still violate these rules. -This kind of on-the-fly aliasing is permitted by the standard -only when none of the aliased items are defined, or written, -while the aliasing is in effect.) - -As a practical example, an optimizing compiler might schedule -the @samp{J =} part of the second line of @samp{FOO} @emph{after} -the reading of @samp{J} and @samp{K} for the @samp{J * K} expression, -resulting in the following output: - -@example -2 2 -2 -@end example - -Essentially, compilers are promised (by the standard and, therefore, -by programmers who write code they claim to be standard-conforming) -that if they cannot detect aliasing via static analysis of a single -program unit's @code{EQUIVALENCE} and @code{COMMON} statements, no -such aliasing exists. -In such cases, compilers are free to assume that an assignment to -one variable will not change the value of another variable, allowing -it to avoid generating code to re-read the value of the other -variable, to re-schedule reads and writes, and so on, to produce -a faster executable. - -The same promise holds true for arrays (as seen by the called -procedure)---an element of one dummy array cannot be aliased -with, or overlap, any element of another dummy array or be -in a @code{COMMON} area known to the procedure. - -(These restrictions apply only when the procedure defines, or -writes to, one of the aliased variables or arrays.) - -Unfortunately, there is no way to find @emph{all} possible cases of -violations of the prohibitions against aliasing in Fortran code. -Static analysis is certainly imperfect, as is run-time analysis, -since neither can catch all violations. -(Static analysis can catch all likely violations, and some that -might never actually happen, while run-time analysis can catch -only those violations that actually happen during a particular run. -Neither approach can cope with programs mixing Fortran code with -routines written in other languages, however.) - -Currently, @code{g77} provides neither static nor run-time facilities -to detect any cases of this problem, although other products might. -Run-time facilities are more likely to be offered by future -versions of @code{g77}, though patches improving @code{g77} so that -it provides either form of detection are welcome. - -@node Output Assumed To Flush -@subsection Output Assumed To Flush -@cindex ALWAYS_FLUSH -@cindex synchronous write errors -@cindex disk full -@cindex flushing output -@cindex fflush() -@cindex I/O, flushing -@cindex output, flushing -@cindex writes, flushing -@cindex NFS -@cindex network file system - -For several versions prior to 0.5.20, @code{g77} configured its -version of the @code{libf2c} run-time library so that one of -its configuration macros, @samp{ALWAYS_FLUSH}, was defined. - -This was done as a result of a belief that many programs expected -output to be flushed to the operating system (under UNIX, via -the @code{fflush()} library call) with the result that errors, -such as disk full, would be immediately flagged via the -relevant @code{ERR=} and @code{IOSTAT=} mechanism. - -Because of the adverse effects this approach had on the performance -of many programs, @code{g77} no longer configures @code{libf2c} -(now named @code{libg2c} in its @code{g77} incarnation) -to always flush output. - -If your program depends on this behavior, either insert the -appropriate @samp{CALL FLUSH} statements, or modify the sources -to the @code{libg2c}, rebuild and reinstall @code{g77}, and -relink your programs with the modified library. - -(Ideally, @code{libg2c} would offer the choice at run-time, so -that a compile-time option to @code{g77} or @code{f2c} could -result in generating the appropriate calls to flushing or -non-flushing library routines.) - -@xref{Always Flush Output}, for information on how to modify -the @code{g77} source tree so that a version of @code{libg2c} -can be built and installed with the @samp{ALWAYS_FLUSH} macro defined. - -@node Large File Unit Numbers -@subsection Large File Unit Numbers -@cindex MXUNIT -@cindex unit numbers -@cindex maximum unit number -@cindex illegal unit number -@cindex increasing maximum unit number - -If your program crashes at run time with a message including -the text @samp{illegal unit number}, that probably is -a message from the run-time library, @code{libg2c}. - -The message means that your program has attempted to use a -file unit number that is out of the range accepted by -@code{libg2c}. -Normally, this range is 0 through 99, and the high end -of the range is controlled by a @code{libg2c} source-file -macro named @samp{MXUNIT}. - -If you can easily change your program to use unit numbers -in the range 0 through 99, you should do so. - -Otherwise, see @ref{Larger File Unit Numbers}, for information on how -to change @samp{MXUNIT} in @code{libg2c} so you can build and -install a new version of @code{libg2c} that supports the larger -unit numbers you need. - -@emph{Note:} While @code{libg2c} places a limit on the range -of Fortran file-unit numbers, the underlying library and operating -system might impose different kinds of limits. -For example, some systems limit the number of files simultaneously -open by a running program. -Information on how to increase these limits should be found -in your system's documentation. - -@node Floating point precision -@subsection Floating point precision - -@cindex IEEE 754 -@cindex IEEE conformance -@cindex conformance, IEEE -@cindex floating point precision -If your program depends on exact IEEE 754 floating point handling it may -help on some systems---specifically x86 or m68k hardware---to use -the @code{-ffloat-store} option or to reset the precision flag on the -floating point unit @xref{Optimize Options}. - -However, it might be better simply to put the FPU into double precision -mode and not take the performance hit of @code{-ffloat-store}. On x86 -and m68k GNU systems you can do this with a technique similar to that -for turning on floating point exceptions @xref{Floating-point Exception -Handling}. The control word could be set to double precision by -replacing the @code{__setfpucw} call with one like this: -@smallexample - __setfpucw ((_FPU_DEFAULT & ~_FPU_EXTENDED) | _FPU_DOUBLE); -@end smallexample -(It is not clear whether this has any effect on the operation of the GNU -maths library, but we have no evidence of it causing trouble.) - -Some targets (such as the Alpha) may need special options for full IEEE -conformance @xref{Submodel Options,,Hardware Models and -Configurations,gcc,Using and Porting GNU CC}. - -@node Inconsistent Calling Sequences -@subsection Inconsistent Calling Sequences - -@pindex ftnchek -@cindex floating point errors -@cindex x86 FPU stack -Code containing inconsistent calling sequences in the same file is -normally rejected @xref{GLOBALS}. (Use, say, @code{ftnchek} to ensure -consistency across source files -@c makeinfo 1.68 objects to the nested parens -@ifinfo -@xref{f2c Skeletons and Prototypes}.) -@end ifinfo -@ifnotinfo -@xref{f2c Skeletons and Prototypes,, -{Generating Skeletons and Prototypes with @code{f2c}}}.) -@end ifnotinfo - -Mysterious errors, which may appear to be code generation problems, can -appear specifically on the x86 architecture with some such -inconsistencies. On x86 hardware, floating point return values of -functions are placed on the floating point unit's register stack, not -the normal stack. Thus calling a @code{REAL} or @code{DOUBLE PRECISION} -@code{FUNCTION} as some other sort of procedure, or vice versa, -scrambles the floating point stack. This may break unrelated code -executed later. Similarly if, say, external C routines are written -incorrectly. - -@node Overly Convenient Options -@section Overly Convenient Command-line Options -@cindex overly convenient options -@cindex options, overly convenient - -These options should be used only as a quick-and-dirty way to determine -how well your program will run under different compilation models -without having to change the source. -Some are more problematic -than others, depending on how portable and maintainable you want the -program to be (and, of course, whether you are allowed to change it -at all is crucial). - -You should not continue to use these command-line options to compile -a given program, but rather should make changes to the source code: - -@table @code -@cindex -finit-local-zero option -@cindex options, -finit-local-zero -@item -finit-local-zero -(This option specifies that any uninitialized local variables -and arrays have default initialization to binary zeros.) - -Many other compilers do this automatically, which means lots of -Fortran code developed with those compilers depends on it. - -It is safer (and probably -would produce a faster program) to find the variables and arrays that -need such initialization and provide it explicitly via @code{DATA}, so that -@samp{-finit-local-zero} is not needed. - -Consider using @samp{-Wuninitialized} (which requires @samp{-O}) to -find likely candidates, but -do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, -or this technique won't work. - -@cindex -fno-automatic option -@cindex options, -fno-automatic -@item -fno-automatic -(This option specifies that all local variables and arrays -are to be treated as if they were named in @code{SAVE} statements.) - -Many other compilers do this automatically, which means lots of -Fortran code developed with those compilers depends on it. - -The effect of this is that all non-automatic variables and arrays -are made static, that is, not placed on the stack or in heap storage. -This might cause a buggy program to appear to work better. -If so, rather than relying on this command-line option (and hoping all -compilers provide the equivalent one), add @code{SAVE} -statements to some or all program unit sources, as appropriate. -Consider using @samp{-Wuninitialized} (which requires @samp{-O}) -to find likely candidates, but -do not specify @samp{-finit-local-zero} or @samp{-fno-automatic}, -or this technique won't work. - -The default is @samp{-fautomatic}, which tells @code{g77} to try -and put variables and arrays on the stack (or in fast registers) -where possible and reasonable. -This tends to make programs faster. - -@cindex automatic arrays -@cindex arrays, automatic -@emph{Note:} Automatic variables and arrays are not affected -by this option. -These are variables and arrays that are @emph{necessarily} automatic, -either due to explicit statements, or due to the way they are -declared. -Examples include local variables and arrays not given the -@code{SAVE} attribute in procedures declared @code{RECURSIVE}, -and local arrays declared with non-constant bounds (automatic -arrays). -Currently, @code{g77} supports only automatic arrays, not -@code{RECURSIVE} procedures or other means of explicitly -specifying that variables or arrays are automatic. - -@cindex -fugly option -@cindex options, -fugly -@item -fugly -Fix the source code so that @samp{-fno-ugly} will work. -Note that, for many programs, it is difficult to practically -avoid using the features enabled via @samp{-fugly-init}, and these -features pose the lowest risk of writing nonportable code, among the -various ``ugly'' features. - -@cindex -f@var{group}-intrinsics-hide option -@cindex options, -f@var{group}-intrinsics-hide -@item -f@var{group}-intrinsics-hide -Change the source code to use @code{EXTERNAL} for any external procedure -that might be the name of an intrinsic. -It is easy to find these using @samp{-f@var{group}-intrinsics-disable}. -@end table - -@node Faster Programs -@section Faster Programs -@cindex speeding up programs -@cindex programs, speeding up - -Aside from the usual @code{gcc} options, such as @samp{-O}, -@samp{-ffast-math}, and so on, consider trying some of the -following approaches to speed up your program (once you get -it working). - -@menu -* Aligned Data:: -* Prefer Automatic Uninitialized Variables:: -* Avoid f2c Compatibility:: -* Use Submodel Options:: -@end menu - -@node Aligned Data -@subsection Aligned Data -@cindex data, aligned -@cindex stack, aligned -@cindex aligned data -@cindex aligned stack -@cindex Pentium optimizations -@cindex optimizations, Pentium - -On some systems, such as those with Pentium Pro CPUs, programs -that make heavy use of @code{REAL(KIND=2)} (@code{DOUBLE PRECISION}) -might run much slower -than possible due to the compiler not aligning these 64-bit -values to 64-bit boundaries in memory. -(The effect also is present, though -to a lesser extent, on the 586 (Pentium) architecture.) - -The Intel x86 architecture generally ensures that these programs will -work on all its implementations, -but particular implementations (such as Pentium Pro) -perform better with more strict alignment. -(Such behavior isn't unique to the Intel x86 architecture.) -Other architectures might @emph{demand} 64-bit alignment -of 64-bit data. - -There are a variety of approaches to use to address this problem: - -@itemize @bullet -@item -@cindex COMMON, layout -@cindex layout of common blocks -Order your @code{COMMON} and @code{EQUIVALENCE} areas such -that the variables and arrays with the widest alignment -guidelines come first. - -For example, on most systems, this would mean placing -@code{COMPLEX(KIND=2)}, @code{REAL(KIND=2)}, and -@code{INTEGER(KIND=2)} entities first, followed by @code{REAL(KIND=1)}, -@code{INTEGER(KIND=1)}, and @code{LOGICAL(KIND=1)} entities, then -@code{INTEGER(KIND=6)} entities, and finally @code{CHARACTER} -and @code{INTEGER(KIND=3)} entities. - -The reason to use such placement is it makes it more likely -that your data will be aligned properly, without requiring -you to do detailed analysis of each aggregate (@code{COMMON} -and @code{EQUIVALENCE}) area. - -Specifically, on systems where the above guidelines are -appropriate, placing @code{CHARACTER} entities before -@code{REAL(KIND=2)} entities can work just as well, -but only if the number of bytes occupied by the @code{CHARACTER} -entities is divisible by the recommended alignment for -@code{REAL(KIND=2)}. - -By ordering the placement of entities in aggregate -areas according to the simple guidelines above, you -avoid having to carefully count the number of bytes -occupied by each entity to determine whether the -actual alignment of each subsequent entity meets the -alignment guidelines for the type of that entity. - -If you don't ensure correct alignment of @code{COMMON} elements, the -compiler may be forced by some systems to violate the Fortran semantics by -adding padding to get @code{DOUBLE PRECISION} data properly aligned. -If the unfortunate practice is employed of overlaying different types of -data in the @code{COMMON} block, the different variants -of this block may become misaligned with respect to each other. -Even if your platform doesn't require strict alignment, -@code{COMMON} should be laid out as above for portability. -(Unfortunately the FORTRAN 77 standard didn't anticipate this -possible requirement, which is compiler-independent on a given platform.) - -@item -@cindex -malign-double option -@cindex options, -malign-double -Use the (x86-specific) @samp{-malign-double} option when compiling -programs for the Pentium and Pentium Pro architectures (called 586 -and 686 in the @code{gcc} configuration subsystem). -The warning about this in the @code{gcc} manual isn't -generally relevant to Fortran, -but using it will force @code{COMMON} to be padded if necessary to align -@code{DOUBLE PRECISION} data. - -When @code{DOUBLE PRECISION} data is forcibly aligned -in @code{COMMON} by @code{g77} due to specifying @samp{-malign-double}, -@code{g77} issues a warning about the need to -insert padding. - -In this case, each and every program unit that uses -the same @code{COMMON} area -must specify the same layout of variables and their types -for that area -and be compiled with @samp{-malign-double} as well. -@code{g77} will issue warnings in each case, -but as long as every program unit using that area -is compiled with the same warnings, -the resulting object files should work when linked together -unless the program makes additional assumptions about -@code{COMMON} area layouts that are outside the scope -of the FORTRAN 77 standard, -or uses @code{EQUIVALENCE} or different layouts -in ways that assume no padding is ever inserted by the compiler. - -@emph{Note:} @samp{-malign-double} applies only to -statically-allocated data. -Double-precision data on the stack can still -cause problems due to misalignment. -@xref{Aligned Data}. - -@item -Ensure that @file{crt0.o} or @file{crt1.o} -on your system guarantees a 64-bit -aligned stack for @code{main()}. -The recent one from GNU (@code{glibc2}) will do this on x86 systems, -but we don't know of any other x86 setups where it will be right. -Read your system's documentation to determine if -it is appropriate to upgrade to a more recent version -to obtain the optimal alignment. -@end itemize - -Progress is being made on making this work -``out of the box'' on future versions of @code{g77}, -@code{gcc}, and some of the relevant operating systems -(such as GNU/Linux). - -@node Prefer Automatic Uninitialized Variables -@subsection Prefer Automatic Uninitialized Variables - -If you're using @samp{-fno-automatic} already, you probably -should change your code to allow compilation with @samp{-fautomatic} -(the default), to allow the program to run faster. - -Similarly, you should be able to use @samp{-fno-init-local-zero} -(the default) instead of @samp{-finit-local-zero}. -This is because it is rare that every variable affected by these -options in a given program actually needs to -be so affected. - -For example, @samp{-fno-automatic}, which effectively @code{SAVE}s -every local non-automatic variable and array, affects even things like -@code{DO} iteration -variables, which rarely need to be @code{SAVE}d, and this often reduces -run-time performances. -Similarly, @samp{-fno-init-local-zero} forces such -variables to be initialized to zero---when @code{SAVE}d (such as when -@samp{-fno-automatic}), this by itself generally affects only -startup time for a program, but when not @code{SAVE}d, -it can slow down the procedure every time it is called. - -@xref{Overly Convenient Options,,Overly Convenient Command-Line Options}, -for information on the @samp{-fno-automatic} and -@samp{-finit-local-zero} options and how to convert -their use into selective changes in your own code. - -@node Avoid f2c Compatibility -@subsection Avoid f2c Compatibility -@cindex -fno-f2c option -@cindex options, -fno-f2c -@cindex @code{f2c} compatibility -@cindex compatibility, @code{f2c} - -If you aren't linking with any code compiled using -@code{f2c}, try using the @samp{-fno-f2c} option when -compiling @emph{all} the code in your program. -(Note that @code{libf2c} is @emph{not} an example of code -that is compiled using @code{f2c}---it is compiled by a C -compiler, typically @code{gcc}.) - -@node Use Submodel Options -@subsection Use Submodel Options -@cindex Pentium optimizations -@cindex optimizations, Pentium -@cindex 586/686 CPUs -@cindex submodels - -Using an appropriate @samp{-m} option to generate specific code for your -CPU may be worthwhile, though it may mean the executable won't run on -other versions of the CPU that don't support the same instruction set. -@xref{Submodel Options,,Hardware Models and Configurations,gcc,Using and -Porting GNU CC}. - -For recent CPUs that don't have explicit support in -the released version of @code{gcc}, it may still be possible to get -improvements. -For instance, the flags recommended for 586/686 -(Pentium(Pro)) chips for building the Linux kernel are: - -@smallexample --m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 --fomit-frame-pointer -@end smallexample - -@noindent @samp{-fomit-frame-pointer} will, however, inhibit debugging -on x86 systems. - -@node Trouble -@chapter Known Causes of Trouble with GNU Fortran -@cindex bugs, known -@cindex installation trouble -@cindex known causes of trouble - -This section describes known problems that affect users of GNU Fortran. -Most of these are not GNU Fortran bugs per se---if they were, we would -fix them. -But the result for a user might be like the result of a bug. - -Some of these problems are due to bugs in other software, some are -missing features that are too much work to add, and some are places -where people's opinions differ as to what is best. - -Information on bugs that show up when configuring, porting, building, -or installing @code{g77} is not provided here. -@xref{Problems Installing}. - -To find out about major bugs discovered in the current release and -possible workarounds for them, retrieve -@uref{ftp://alpha.gnu.org/g77.plan}. - -(Note that some of this portion of the manual is lifted -directly from the @code{gcc} manual, with minor modifications -to tailor it to users of @code{g77}. -Anytime a bug seems to have more to do with the @code{gcc} -portion of @code{g77}, -@xref{Trouble,,Known Causes of Trouble with GNU CC, -gcc,Using and Porting GNU CC}.) - -@menu -* But-bugs:: Bugs really in other programs or elsewhere. -* Actual Bugs:: Bugs and misfeatures we will fix later. -* Missing Features:: Features we already know we want to add later. -* Disappointments:: Regrettable things we can't change. -* Non-bugs:: Things we think are right, but some others disagree. -* Warnings and Errors:: Which problems in your code get warnings, - and which get errors. -@end menu - -@node But-bugs -@section Bugs Not In GNU Fortran -@cindex but-bugs - -These are bugs to which the maintainers often have to reply, -``but that isn't a bug in @code{g77}@dots{}''. -Some of these already are fixed in new versions of other -software; some still need to be fixed; some are problems -with how @code{g77} is installed or is being used; -some are the result of bad hardware that causes software -to misbehave in sometimes bizarre ways; -some just cannot be addressed at this time until more -is known about the problem. - -Please don't re-report these bugs to the @code{g77} maintainers---if -you must remind someone how important it is to you that the problem -be fixed, talk to the people responsible for the other products -identified below, but preferably only after you've tried the -latest versions of those products. -The @code{g77} maintainers have their hands full working on -just fixing and improving @code{g77}, without serving as a -clearinghouse for all bugs that happen to affect @code{g77} -users. - -@xref{Collected Fortran Wisdom}, for information on behavior -of Fortran programs, and the programs that compile them, that -might be @emph{thought} to indicate bugs. - -@menu -* Signal 11 and Friends:: Strange behavior by any software. -* Cannot Link Fortran Programs:: Unresolved references. -* Large Common Blocks:: Problems on older GNU/Linux systems. -* Debugger Problems:: When the debugger crashes. -* NeXTStep Problems:: Misbehaving executables. -* Stack Overflow:: More misbehaving executables. -* Nothing Happens:: Less behaving executables. -* Strange Behavior at Run Time:: Executables misbehaving due to - bugs in your program. -* Floating-point Errors:: The results look wrong, but@dots{}. -@end menu - -@node Signal 11 and Friends -@subsection Signal 11 and Friends -@cindex signal 11 -@cindex hardware errors - -A whole variety of strange behaviors can occur when the -software, or the way you are using the software, -stresses the hardware in a way that triggers hardware bugs. -This might seem hard to believe, but it happens frequently -enough that there exist documents explaining in detail -what the various causes of the problems are, what -typical symptoms look like, and so on. - -Generally these problems are referred to in this document -as ``signal 11'' crashes, because the Linux kernel, running -on the most popular hardware (the Intel x86 line), often -stresses the hardware more than other popular operating -systems. -When hardware problems do occur under GNU/Linux on x86 -systems, these often manifest themselves as ``signal 11'' -problems, as illustrated by the following diagnostic: - -@smallexample -sh# @kbd{g77 myprog.f} -gcc: Internal compiler error: program f771 got fatal signal 11 -sh# -@end smallexample - -It is @emph{very} important to remember that the above -message is @emph{not} the only one that indicates a -hardware problem, nor does it always indicate a hardware -problem. - -In particular, on systems other than those running the Linux -kernel, the message might appear somewhat or very different, -as it will if the error manifests itself while running a -program other than the @code{g77} compiler. -For example, -it will appear somewhat different when running your program, -when running Emacs, and so on. - -How to cope with such problems is well beyond the scope -of this manual. - -However, users of Linux-based systems (such as GNU/Linux) -should review @uref{http://www.bitwizard.nl/sig11}, a source -of detailed information on diagnosing hardware problems, -by recognizing their common symptoms. - -Users of other operating systems and hardware might -find this reference useful as well. -If you know of similar material for another hardware/software -combination, please let us know so we can consider including -a reference to it in future versions of this manual. - -@node Cannot Link Fortran Programs -@subsection Cannot Link Fortran Programs -@cindex unresolved reference (various) -@cindex linking error for user code -@cindex code, user -@cindex ld error for user code -@cindex ld can't find strange names -On some systems, perhaps just those with out-of-date (shared?) -libraries, unresolved-reference errors happen when linking @code{g77}-compiled -programs (which should be done using @code{g77}). - -If this happens to you, try appending @samp{-lc} to the command you -use to link the program, e.g. @samp{g77 foo.f -lc}. -@code{g77} already specifies @samp{-lg2c -lm} when it calls the linker, -but it cannot also specify @samp{-lc} because not all systems have a -file named @file{libc.a}. - -It is unclear at this point whether there are legitimately installed -systems where @samp{-lg2c -lm} is insufficient to resolve code produced -by @code{g77}. - -@cindex undefined reference (_main) -@cindex linking error for user code -@cindex ld error for user code -@cindex code, user -@cindex ld can't find _main -If your program doesn't link due to unresolved references to names -like @samp{_main}, make sure you're using the @code{g77} command to do the -link, since this command ensures that the necessary libraries are -loaded by specifying @samp{-lg2c -lm} when it invokes the @code{gcc} -command to do the actual link. -(Use the @samp{-v} option to discover -more about what actually happens when you use the @code{g77} and @code{gcc} -commands.) - -Also, try specifying @samp{-lc} as the last item on the @code{g77} -command line, in case that helps. - -@node Large Common Blocks -@subsection Large Common Blocks -@cindex common blocks, large -@cindex large common blocks -@cindex linker errors -@cindex ld errors -@cindex errors, linker -On some older GNU/Linux systems, programs with common blocks larger -than 16MB cannot be linked without some kind of error -message being produced. - -This is a bug in older versions of @code{ld}, fixed in -more recent versions of @code{binutils}, such as version 2.6. - -@node Debugger Problems -@subsection Debugger Problems -@cindex @code{gdb} support -@cindex support, @code{gdb} -There are some known problems when using @code{gdb} on code -compiled by @code{g77}. -Inadequate investigation as of the release of 0.5.16 results in not -knowing which products are the culprit, but @file{gdb-4.14} definitely -crashes when, for example, an attempt is made to print the contents -of a @code{COMPLEX(KIND=2)} dummy array, on at least some GNU/Linux -machines, plus some others. -Attempts to access assumed-size arrays are -also known to crash recent versions of @code{gdb}. -(@code{gdb}'s Fortran support was done for a different compiler -and isn't properly compatible with @code{g77}.) - -@node NeXTStep Problems -@subsection NeXTStep Problems -@cindex NeXTStep problems -@cindex bus error -@cindex segmentation violation -Developers of Fortran code on NeXTStep (all architectures) have to -watch out for the following problem when writing programs with -large, statically allocated (i.e. non-stack based) data structures -(common blocks, saved arrays). - -Due to the way the native loader (@file{/bin/ld}) lays out -data structures in virtual memory, it is very easy to create an -executable wherein the @samp{__DATA} segment overlaps (has addresses in -common) with the @samp{UNIX STACK} segment. - -This leads to all sorts of trouble, from the executable simply not -executing, to bus errors. -The NeXTStep command line tool @code{ebadexec} points to -the problem as follows: - -@smallexample -% @kbd{/bin/ebadexec a.out} -/bin/ebadexec: __LINKEDIT segment (truncated address = 0x3de000 -rounded size = 0x2a000) of executable file: a.out overlaps with UNIX -STACK segment (truncated address = 0x400000 rounded size = -0x3c00000) of executable file: a.out -@end smallexample - -(In the above case, it is the @samp{__LINKEDIT} segment that overlaps the -stack segment.) - -This can be cured by assigning the @samp{__DATA} segment -(virtual) addresses beyond the stack segment. -A conservative -estimate for this is from address 6000000 (hexadecimal) onwards---this -has always worked for me [Toon Moene]: - -@smallexample -% @kbd{g77 -segaddr __DATA 6000000 test.f} -% @kbd{ebadexec a.out} -ebadexec: file: a.out appears to be executable -% -@end smallexample - -Browsing through @file{@value{path-g77}/Makefile.in}, -you will find that the @code{f771} program itself also has to be -linked with these flags---it has large statically allocated -data structures. -(Version 0.5.18 reduces this somewhat, but probably -not enough.) - -(The above item was contributed by Toon Moene -(@email{toon@@moene.indiv.nluug.nl}).) - -@node Stack Overflow -@subsection Stack Overflow -@cindex stack overflow -@cindex segmentation violation -@code{g77} code might fail at runtime (probably with a ``segmentation -violation'') due to overflowing the stack. -This happens most often on systems with an environment -that provides substantially more heap space (for use -when arbitrarily allocating and freeing memory) than stack -space. - -Often this can be cured by -increasing or removing your shell's limit on stack usage, typically -using @kbd{limit stacksize} (in @code{csh} and derivatives) or -@kbd{ulimit -s} (in @code{sh} and derivatives). - -Increasing the allowed stack size might, however, require -changing some operating system or system configuration parameters. - -You might be able to work around the problem by compiling with the -@samp{-fno-automatic} option to reduce stack usage, probably at the -expense of speed. - -@xref{Maximum Stackable Size}, for information on patching -@code{g77} to use different criteria for placing local -non-automatic variables and arrays on the stack. - -@cindex automatic arrays -@cindex arrays, automatic -However, if your program uses large automatic arrays -(for example, has declarations like @samp{REAL A(N)} where -@samp{A} is a local array and @samp{N} is a dummy or -@code{COMMON} variable that can have a large value), -neither use of @samp{-fno-automatic}, -nor changing the cut-off point for @code{g77} for using the stack, -will solve the problem by changing the placement of these -large arrays, as they are @emph{necessarily} automatic. - -@code{g77} currently provides no means to specify that -automatic arrays are to be allocated on the heap instead -of the stack. -So, other than increasing the stack size, your best bet is to -change your source code to avoid large automatic arrays. -Methods for doing this currently are outside the scope of -this document. - -(@emph{Note:} If your system puts stack and heap space in the -same memory area, such that they are effectively combined, then -a stack overflow probably indicates a program that is either -simply too large for the system, or buggy.) - -@node Nothing Happens -@subsection Nothing Happens -@cindex nothing happens -@cindex naming programs @samp{test} -@cindex @samp{test} programs -@cindex programs named @samp{test} -It is occasionally reported that a ``simple'' program, -such as a ``Hello, World!'' program, does nothing when -it is run, even though the compiler reported no errors, -despite the program containing nothing other than a -simple @code{PRINT} statement. - -This most often happens because the program has been -compiled and linked on a UNIX system and named @samp{test}, -though other names can lead to similarly unexpected -run-time behavior on various systems. - -Essentially this problem boils down to giving -your program a name that is already known to -the shell you are using to identify some other program, -which the shell continues to execute instead of your -program when you invoke it via, for example: - -@smallexample -sh# @kbd{test} -sh# -@end smallexample - -Under UNIX and many other system, a simple command name -invokes a searching mechanism that might well not choose -the program located in the current working directory if -there is another alternative (such as the @code{test} -command commonly installed on UNIX systems). - -The reliable way to invoke a program you just linked in -the current directory under UNIX is to specify it using -an explicit pathname, as in: - -@smallexample -sh# @kbd{./test} - Hello, World! -sh# -@end smallexample - -Users who encounter this problem should take the time to -read up on how their shell searches for commands, how to -set their search path, and so on. -The relevant UNIX commands to learn about include -@code{man}, @code{info} (on GNU systems), @code{setenv} (or -@code{set} and @code{env}), @code{which}, and @code{find}. - -@node Strange Behavior at Run Time -@subsection Strange Behavior at Run Time -@cindex segmentation violation -@cindex bus error -@cindex overwritten data -@cindex data, overwritten -@code{g77} code might fail at runtime with ``segmentation violation'', -``bus error'', or even something as subtle as a procedure call -overwriting a variable or array element that it is not supposed -to touch. - -These can be symptoms of a wide variety of actual bugs that -occurred earlier during the program's run, but manifested -themselves as @emph{visible} problems some time later. - -Overflowing the bounds of an array---usually by writing beyond -the end of it---is one of two kinds of bug that often occurs -in Fortran code. - -The other kind of bug is a mismatch between the actual arguments -passed to a procedure and the dummy arguments as declared by that -procedure. - -Both of these kinds of bugs, and some others as well, can be -difficult to track down, because the bug can change its behavior, -or even appear to not occur, when using a debugger. - -That is, these bugs can be quite sensitive to data, including -data representing the placement of other data in memory (that is, -pointers, such as the placement of stack frames in memory). - -Plans call for improving @code{g77} so that it can offer the -ability to catch and report some of these problems at compile, link, or -run time, such as by generating code to detect references to -beyond the bounds of an array, or checking for agreement between -calling and called procedures. - -In the meantime, finding and fixing the programming -bugs that lead to these behaviors is, ultimately, the user's -responsibility, as difficult as that task can sometimes be. - -@cindex ``infinite spaces'' printed -@cindex spaces, endless printing of -@cindex libc, non-ANSI or non-default -@cindex C library -@cindex linking against non-standard library -@cindex Solaris -One runtime problem that has been observed might have a simple solution. -If a formatted @code{WRITE} produces an endless stream of spaces, check -that your program is linked against the correct version of the C library. -The configuration process takes care to account for your -system's normal @file{libc} not being ANSI-standard, which will -otherwise cause this behaviour. -If your system's default library is -ANSI-standard and you subsequently link against a non-ANSI one, there -might be problems such as this one. - -Specifically, on Solaris2 systems, -avoid picking up the @code{BSD} library from @file{/usr/ucblib}. - -@node Floating-point Errors -@subsection Floating-point Errors -@cindex floating-point errors -@cindex rounding errors -@cindex inconsistent floating-point results -@cindex results, inconsistent -Some programs appear to produce inconsistent floating-point -results compiled by @code{g77} versus by other compilers. - -Often the reason for this behavior is the fact that floating-point -values are represented on almost all Fortran systems by -@emph{approximations}, and these approximations are inexact -even for apparently simple values like 0.1, 0.2, 0.3, 0.4, 0.6, -0.7, 0.8, 0.9, 1.1, and so on. -Most Fortran systems, including all current ports of @code{g77}, -use binary arithmetic to represent these approximations. - -Therefore, the exact value of any floating-point approximation -as manipulated by @code{g77}-compiled code is representable by -adding some combination of the values 1.0, 0.5, 0.25, 0.125, and -so on (just keep dividing by two) through the precision of the -fraction (typically around 23 bits for @code{REAL(KIND=1)}, 52 for -@code{REAL(KIND=2)}), then multiplying the sum by a integral -power of two (in Fortran, by @samp{2**N}) that typically is between --127 and +128 for @code{REAL(KIND=1)} and -1023 and +1024 for -@code{REAL(KIND=2)}, then multiplying by -1 if the number -is negative. - -So, a value like 0.2 is exactly represented in decimal---since -it is a fraction, @samp{2/10}, with a denominator that is compatible -with the base of the number system (base 10). -However, @samp{2/10} cannot be represented by any finite number -of sums of any of 1.0, 0.5, 0.25, and so on, so 0.2 cannot -be exactly represented in binary notation. - -(On the other hand, decimal notation can represent any binary -number in a finite number of digits. -Decimal notation cannot do so with ternary, or base-3, -notation, which would represent floating-point numbers as -sums of any of @samp{1/1}, @samp{1/3}, @samp{1/9}, and so on. -After all, no finite number of decimal digits can exactly -represent @samp{1/3}. -Fortunately, few systems use ternary notation.) - -Moreover, differences in the way run-time I/O libraries convert -between these approximations and the decimal representation often -used by programmers and the programs they write can result in -apparent differences between results that do not actually exist, -or exist to such a small degree that they usually are not worth -worrying about. - -For example, consider the following program: - -@smallexample -PRINT *, 0.2 -END -@end smallexample - -When compiled by @code{g77}, the above program might output -@samp{0.20000003}, while another compiler might produce a -executable that outputs @samp{0.2}. - -This particular difference is due to the fact that, currently, -conversion of floating-point values by the @code{libg2c} library, -used by @code{g77}, handles only double-precision values. - -Since @samp{0.2} in the program is a single-precision value, it -is converted to double precision (still in binary notation) -before being converted back to decimal. -The conversion to binary appends _binary_ zero digits to the -original value---which, again, is an inexact approximation of -0.2---resulting in an approximation that is much less exact -than is connoted by the use of double precision. - -(The appending of binary zero digits has essentially the same -effect as taking a particular decimal approximation of -@samp{1/3}, such as @samp{0.3333333}, and appending decimal -zeros to it, producing @samp{0.33333330000000000}. -Treating the resulting decimal approximation as if it really -had 18 or so digits of valid precision would make it seem -a very poor approximation of @samp{1/3}.) - -As a result of converting the single-precision approximation -to double precision by appending binary zeros, the conversion -of the resulting double-precision -value to decimal produces what looks like an incorrect -result, when in fact the result is @emph{inexact}, and -is probably no less inaccurate or imprecise an approximation -of 0.2 than is produced by other compilers that happen to output -the converted value as ``exactly'' @samp{0.2}. -(Some compilers behave in a way that can make them appear -to retain more accuracy across a conversion of a single-precision -constant to double precision. -@xref{Context-Sensitive Constants}, to see why -this practice is illusory and even dangerous.) - -Note that a more exact approximation of the constant is -computed when the program is changed to specify a -double-precision constant: - -@smallexample -PRINT *, 0.2D0 -END -@end smallexample - -Future versions of @code{g77} and/or @code{libg2c} might convert -single-precision values directly to decimal, -instead of converting them to double precision first. -This would tend to result in output that is more consistent -with that produced by some other Fortran implementations. - -A useful source of information on floating point computation is David -Goldberg, `What Every Computer Scientist Should Know About -Floating-Point Arithmetic', Computing Surveys, 23, March 1991, pp.@: -5--48. At the time of writing this is available online under -@uref{http://docs.sun.com} and there is a supplemented version at -@uref{http://www.validgh.com/}. Information related to the IEEE 754 -floating point standard by a leading light can be found at -@uref{http://http.cs.berkeley.edu/%7Ewkahan/ieee754status }; see also -slides from the short course referenced from -@uref{http://http.cs.berkeley.edu/%7Efateman/}. -@uref{http://www.suburbia.net/%7Ebillm/floating-point/} has a brief -guide to IEEE 754, a somewhat x86 GNU/Linux-specific FAQ and library -code for GNU/Linux x86 systems. -@c xref would be different between editions: -The GNU C library provides routines for controlling the FPU, and other -documentation about this. - -@xref{Floating point precision}, regarding IEEE 754 conformance. - -@include bugs.texi - -@node Missing Features -@section Missing Features - -This section lists features we know are missing from @code{g77}, -and which we want to add someday. -(There is no priority implied in the ordering below.) - -@menu -GNU Fortran language: -* Better Source Model:: -* Fortran 90 Support:: -* Intrinsics in PARAMETER Statements:: -* SELECT CASE on CHARACTER Type:: -* RECURSIVE Keyword:: -* Popular Non-standard Types:: -* Full Support for Compiler Types:: -* Array Bounds Expressions:: -* POINTER Statements:: -* Sensible Non-standard Constructs:: -* FLUSH Statement:: -* Expressions in FORMAT Statements:: -* Explicit Assembler Code:: -* Q Edit Descriptor:: - -GNU Fortran dialects: -* Old-style PARAMETER Statements:: -* TYPE and ACCEPT I/O Statements:: -* STRUCTURE UNION RECORD MAP:: -* OPEN CLOSE and INQUIRE Keywords:: -* ENCODE and DECODE:: -* Suppressing Space Padding:: -* Fortran Preprocessor:: -* Bit Operations on Floating-point Data:: - -New facilities: -* POSIX Standard:: -* Floating-point Exception Handling:: -* Nonportable Conversions:: -* Large Automatic Arrays:: -* Support for Threads:: -* Increasing Precision/Range:: - -Better diagnostics: -* Gracefully Handle Sensible Bad Code:: -* Non-standard Conversions:: -* Non-standard Intrinsics:: -* Modifying DO Variable:: -* Better Pedantic Compilation:: -* Warn About Implicit Conversions:: -* Invalid Use of Hollerith Constant:: -* Dummy Array Without Dimensioning Dummy:: -* Invalid FORMAT Specifiers:: -* Ambiguous Dialects:: -* Unused Labels:: -* Informational Messages:: - -Run-time facilities: -* Uninitialized Variables at Run Time:: -* Bounds Checking at Run Time:: -* Portable Unformatted Files:: - -Debugging: -* Labels Visible to Debugger:: -@end menu - -@node Better Source Model -@subsection Better Source Model - -@code{g77} needs to provide, as the default source-line model, -a ``pure visual'' mode, where -the interpretation of a source program in this mode can be accurately -determined by a user looking at a traditionally displayed rendition -of the program (assuming the user knows whether the program is fixed -or free form). - -The design should assume the user cannot tell tabs from spaces -and cannot see trailing spaces on lines, but has canonical tab stops -and, for fixed-form source, has the ability to always know exactly -where column 72 is (since the Fortran standard itself requires -this for fixed-form source). - -This would change the default treatment of fixed-form source -to not treat lines with tabs as if they were infinitely long---instead, -they would end at column 72 just as if the tabs were replaced -by spaces in the canonical way. - -As part of this, provide common alternate models (Digital, @code{f2c}, -and so on) via command-line options. -This includes allowing arbitrarily long -lines for free-form source as well as fixed-form source and providing -various limits and diagnostics as appropriate. - -@cindex sequence numbers -@cindex columns 73 through 80 -Also, @code{g77} should offer, perhaps even default to, warnings -when characters beyond the last valid column are anything other -than spaces. -This would mean code with ``sequence numbers'' in columns 73 through 80 -would be rejected, and there's a lot of that kind of code around, -but one of the most frequent bugs encountered by new users is -accidentally writing fixed-form source code into and beyond -column 73. -So, maybe the users of old code would be able to more easily handle -having to specify, say, a @code{-Wno-col73to80} option. - -@node Fortran 90 Support -@subsection Fortran 90 Support -@cindex Fortran 90 support -@cindex support, Fortran 90 - -@code{g77} does not support many of the features that -distinguish Fortran 90 (and, now, Fortran 95) from -ANSI FORTRAN 77. - -Some Fortran 90 features are supported, because they -make sense to offer even to die-hard users of F77. -For example, many of them codify various ways F77 has -been extended to meet users' needs during its tenure, -so @code{g77} might as well offer them as the primary -way to meet those same needs, even if it offers compatibility -with one or more of the ways those needs were met -by other F77 compilers in the industry. - -Still, many important F90 features are not supported, -because no attempt has been made to research each and -every feature and assess its viability in @code{g77}. -In the meantime, users who need those features must -use Fortran 90 compilers anyway, and the best approach -to adding some F90 features to GNU Fortran might well be -to fund a comprehensive project to create GNU Fortran 95. - -@node Intrinsics in PARAMETER Statements -@subsection Intrinsics in @code{PARAMETER} Statements -@cindex PARAMETER statement -@cindex statements, PARAMETER - -@code{g77} doesn't allow intrinsics in @code{PARAMETER} statements. -This feature is considered to be absolutely vital, even though it -is not standard-conforming, and is scheduled for version 0.6. - -Related to this, @code{g77} doesn't allow non-integral -exponentiation in @code{PARAMETER} statements, such as -@samp{PARAMETER (R=2**.25)}. -It is unlikely @code{g77} will ever support this feature, -as doing it properly requires complete emulation of -a target computer's floating-point facilities when -building @code{g77} as a cross-compiler. -But, if the @code{gcc} back end is enhanced to provide -such a facility, @code{g77} will likely use that facility -in implementing this feature soon afterwards. - -@node SELECT CASE on CHARACTER Type -@subsection @code{SELECT CASE} on @code{CHARACTER} Type - -Character-type selector/cases for @code{SELECT CASE} currently -are not supported. - -@node RECURSIVE Keyword -@subsection @code{RECURSIVE} Keyword -@cindex RECURSIVE keyword -@cindex keywords, RECURSIVE -@cindex recursion, lack of -@cindex lack of recursion - -@code{g77} doesn't support the @code{RECURSIVE} keyword that -F90 compilers do. -Nor does it provide any means for compiling procedures -designed to do recursion. - -All recursive code can be rewritten to not use recursion, -but the result is not pretty. - -@node Increasing Precision/Range -@subsection Increasing Precision/Range -@cindex -r8 -@cindex -qrealsize=8 -@cindex -i8 -@cindex f2c -@cindex increasing precision -@cindex precision, increasing -@cindex increasing range -@cindex range, increasing -@cindex Toolpack -@cindex Netlib - -Some compilers, such as @code{f2c}, have an option (@samp{-r8}, -@samp{-qrealsize=8} or -similar) that provides automatic treatment of @code{REAL} -entities such that they have twice the storage size, and -a corresponding increase in the range and precision, of what -would normally be the @code{REAL(KIND=1)} (default @code{REAL}) type. -(This affects @code{COMPLEX} the same way.) - -They also typically offer another option (@samp{-i8}) to increase -@code{INTEGER} entities so they are twice as large -(with roughly twice as much range). - -(There are potential pitfalls in using these options.) - -@code{g77} does not yet offer any option that performs these -kinds of transformations. -Part of the problem is the lack of detailed specifications regarding -exactly how these options affect the interpretation of constants, -intrinsics, and so on. - -Until @code{g77} addresses this need, programmers could improve -the portability of their code by modifying it to not require -compile-time options to produce correct results. -Some free tools are available which may help, specifically -in Toolpack (which one would expect to be sound) and the @file{fortran} -section of the Netlib repository. - -Use of preprocessors can provide a fairly portable means -to work around the lack of widely portable methods in the Fortran -language itself (though increasing acceptance of Fortran 90 would -alleviate this problem). - -@node Popular Non-standard Types -@subsection Popular Non-standard Types -@cindex INTEGER*2 support -@cindex LOGICAL*1 support - -@code{g77} doesn't fully support @code{INTEGER*2}, @code{LOGICAL*1}, -and similar. -Version 0.6 will provide full support for this very -popular set of features. -In the meantime, version 0.5.18 provides rudimentary support -for them. - -@node Full Support for Compiler Types -@subsection Full Support for Compiler Types - -@cindex REAL*16 support -@code{g77} doesn't support @code{INTEGER}, @code{REAL}, and @code{COMPLEX} equivalents -for @emph{all} applicable back-end-supported types (@code{char}, @code{short int}, -@code{int}, @code{long int}, @code{long long int}, and @code{long double}). -This means providing intrinsic support, and maybe constant -support (using F90 syntax) as well, and, for most -machines will result in automatic support of @code{INTEGER*1}, -@code{INTEGER*2}, @code{INTEGER*8}, maybe even @code{REAL*16}, -and so on. -This is scheduled for version 0.6. - -@node Array Bounds Expressions -@subsection Array Bounds Expressions -@cindex array elements, in adjustable array bounds -@cindex function references, in adjustable array bounds -@cindex array bounds, adjustable -@cindex DIMENSION statement -@cindex statements, DIMENSION - -@code{g77} doesn't support more general expressions to dimension -arrays, such as array element references, function -references, etc. - -For example, @code{g77} currently does not accept the following: - -@smallexample -SUBROUTINE X(M, N) -INTEGER N(10), M(N(2), N(1)) -@end smallexample - -@node POINTER Statements -@subsection POINTER Statements -@cindex POINTER statement -@cindex statements, POINTER -@cindex Cray pointers - -@code{g77} doesn't support pointers or allocatable objects -(other than automatic arrays). -This set of features is -probably considered just behind intrinsics -in @code{PARAMETER} statements on the list of large, -important things to add to @code{g77}. - -In the meantime, consider using the @code{INTEGER(KIND=7)} -declaration to specify that a variable must be -able to hold a pointer. -This construct is not portable to other non-GNU compilers, -but it is portable to all machines GNU Fortran supports -when @code{g77} is used. - -@xref{Functions and Subroutines}, for information on -@code{%VAL()}, @code{%REF()}, and @code{%DESCR()} -constructs, which are useful for passing pointers to -procedures written in languages other than Fortran. - -@node Sensible Non-standard Constructs -@subsection Sensible Non-standard Constructs - -@code{g77} rejects things other compilers accept, -like @samp{INTRINSIC SQRT,SQRT}. -As time permits in the future, some of these things that are easy for -humans to read and write and unlikely to be intended to mean something -else will be accepted by @code{g77} (though @samp{-fpedantic} should -trigger warnings about such non-standard constructs). - -Until @code{g77} no longer gratuitously rejects sensible code, -you might as well fix your code -to be more standard-conforming and portable. - -The kind of case that is important to except from the -recommendation to change your code is one where following -good coding rules would force you to write non-standard -code that nevertheless has a clear meaning. - -For example, when writing an @code{INCLUDE} file that -defines a common block, it might be appropriate to -include a @code{SAVE} statement for the common block -(such as @samp{SAVE /CBLOCK/}), so that variables -defined in the common block retain their values even -when all procedures declaring the common block become -inactive (return to their callers). - -However, putting @code{SAVE} statements in an @code{INCLUDE} -file would prevent otherwise standard-conforming code -from also specifying the @code{SAVE} statement, by itself, -to indicate that all local variables and arrays are to -have the @code{SAVE} attribute. - -For this reason, @code{g77} already has been changed to -allow this combination, because although the general -problem of gratuitously rejecting unambiguous and -``safe'' constructs still exists in @code{g77}, this -particular construct was deemed useful enough that -it was worth fixing @code{g77} for just this case. - -So, while there is no need to change your code -to avoid using this particular construct, there -might be other, equally appropriate but non-standard -constructs, that you shouldn't have to stop using -just because @code{g77} (or any other compiler) -gratuitously rejects it. - -Until the general problem is solved, if you have -any such construct you believe is worthwhile -using (e.g. not just an arbitrary, redundant -specification of an attribute), please submit a -bug report with an explanation, so we can consider -fixing @code{g77} just for cases like yours. - -@node FLUSH Statement -@subsection @code{FLUSH} Statement - -@code{g77} could perhaps use a @code{FLUSH} statement that -does what @samp{CALL FLUSH} does, -but that supports @samp{*} as the unit designator (same unit as for -@code{PRINT}) and accepts @code{ERR=} and/or @code{IOSTAT=} -specifiers. - -@node Expressions in FORMAT Statements -@subsection Expressions in @code{FORMAT} Statements -@cindex FORMAT statement -@cindex statements, FORMAT - -@code{g77} doesn't support @samp{FORMAT(I<J>)} and the like. -Supporting this requires a significant redesign or replacement -of @code{libg2c}. - -However, @code{g77} does support -this construct when the expression is constant -(as of version 0.5.22). -For example: - -@smallexample - PARAMETER (IWIDTH = 12) -10 FORMAT (I<IWIDTH>) -@end smallexample - -Otherwise, at least for output (@code{PRINT} and -@code{WRITE}), Fortran code making use of this feature can -be rewritten to avoid it by constructing the @code{FORMAT} -string in a @code{CHARACTER} variable or array, then -using that variable or array in place of the @code{FORMAT} -statement label to do the original @code{PRINT} or @code{WRITE}. - -Many uses of this feature on input can be rewritten this way -as well, but not all can. -For example, this can be rewritten: - -@smallexample - READ 20, I -20 FORMAT (I<J>) -@end smallexample - -However, this cannot, in general, be rewritten, especially -when @code{ERR=} and @code{END=} constructs are employed: - -@smallexample - READ 30, J, I -30 FORMAT (I<J>) -@end smallexample - -@node Explicit Assembler Code -@subsection Explicit Assembler Code - -@code{g77} needs to provide some way, a la @code{gcc}, for @code{g77} -code to specify explicit assembler code. - -@node Q Edit Descriptor -@subsection Q Edit Descriptor -@cindex FORMAT statement -@cindex Q edit descriptor -@cindex edit descriptor, Q - -The @code{Q} edit descriptor in @code{FORMAT}s isn't supported. -(This is meant to get the number of characters remaining in an input record.) -Supporting this requires a significant redesign or replacement -of @code{libg2c}. - -A workaround might be using internal I/O or the stream-based intrinsics. -@xref{FGetC Intrinsic (subroutine)}. - -@node Old-style PARAMETER Statements -@subsection Old-style PARAMETER Statements -@cindex PARAMETER statement -@cindex statements, PARAMETER - -@code{g77} doesn't accept @samp{PARAMETER I=1}. -Supporting this obsolete form of -the @code{PARAMETER} statement would not be particularly hard, as most of the -parsing code is already in place and working. - -Until time/money is -spent implementing it, you might as well fix your code to use the -standard form, @samp{PARAMETER (I=1)} (possibly needing -@samp{INTEGER I} preceding the @code{PARAMETER} statement as well, -otherwise, in the obsolete form of @code{PARAMETER}, the -type of the variable is set from the type of the constant being -assigned to it). - -@node TYPE and ACCEPT I/O Statements -@subsection @code{TYPE} and @code{ACCEPT} I/O Statements -@cindex TYPE statement -@cindex statements, TYPE -@cindex ACCEPT statement -@cindex statements, ACCEPT - -@code{g77} doesn't support the I/O statements @code{TYPE} and -@code{ACCEPT}. -These are common extensions that should be easy to support, -but also are fairly easy to work around in user code. - -Generally, any @samp{TYPE fmt,list} I/O statement can be replaced -by @samp{PRINT fmt,list}. -And, any @samp{ACCEPT fmt,list} statement can be -replaced by @samp{READ fmt,list}. - -@node STRUCTURE UNION RECORD MAP -@subsection @code{STRUCTURE}, @code{UNION}, @code{RECORD}, @code{MAP} -@cindex STRUCTURE statement -@cindex statements, STRUCTURE -@cindex UNION statement -@cindex statements, UNION -@cindex RECORD statement -@cindex statements, RECORD -@cindex MAP statement -@cindex statements, MAP - -@code{g77} doesn't support @code{STRUCTURE}, @code{UNION}, @code{RECORD}, -@code{MAP}. -This set of extensions is quite a bit -lower on the list of large, important things to add to @code{g77}, partly -because it requires a great deal of work either upgrading or -replacing @code{libg2c}. - -@node OPEN CLOSE and INQUIRE Keywords -@subsection @code{OPEN}, @code{CLOSE}, and @code{INQUIRE} Keywords -@cindex disposition of files -@cindex OPEN statement -@cindex statements, OPEN -@cindex CLOSE statement -@cindex statements, CLOSE -@cindex INQUIRE statement -@cindex statements, INQUIRE - -@code{g77} doesn't have support for keywords such as @code{DISP='DELETE'} in -the @code{OPEN}, @code{CLOSE}, and @code{INQUIRE} statements. -These extensions are easy to add to @code{g77} itself, but -require much more work on @code{libg2c}. - -@cindex FORM='PRINT' -@cindex ANS carriage control -@cindex carraige control -@pindex asa -@pindex fpr -@code{g77} doesn't support @code{FORM='PRINT'} or an equivalent to -translate the traditional `carriage control' characters in column 1 of -output to use backspaces, carriage returns and the like. However -programs exist to translate them in output files (or standard output). -These are typically called either @code{fpr} or @code{asa}. You can get -a version of @code{asa} from -@uref{ftp://sunsite.unc.edu/pub/Linux/devel/lang/fortran} for GNU -systems which will probably build easily on other systems. -Alternatively, @code{fpr} is in BSD distributions in various archive -sites. - -@c (Can both programs can be used in a pipeline, -@c with a named input file, -@c and/or with a named output file???) - -@node ENCODE and DECODE -@subsection @code{ENCODE} and @code{DECODE} -@cindex ENCODE statement -@cindex statements, ENCODE -@cindex DECODE statement -@cindex statements, DECODE - -@code{g77} doesn't support @code{ENCODE} or @code{DECODE}. - -These statements are best replaced by READ and WRITE statements -involving internal files (CHARACTER variables and arrays). - -For example, replace a code fragment like - -@smallexample - INTEGER*1 LINE(80) -@dots{} - DECODE (80, 9000, LINE) A, B, C -@dots{} -9000 FORMAT (1X, 3(F10.5)) -@end smallexample - -@noindent -with: - -@smallexample - CHARACTER*80 LINE -@dots{} - READ (UNIT=LINE, FMT=9000) A, B, C -@dots{} -9000 FORMAT (1X, 3(F10.5)) -@end smallexample - -Similarly, replace a code fragment like - -@smallexample - INTEGER*1 LINE(80) -@dots{} - ENCODE (80, 9000, LINE) A, B, C -@dots{} -9000 FORMAT (1X, 'OUTPUT IS ', 3(F10.5)) -@end smallexample - -@noindent -with: - -@smallexample - CHARACTER*80 LINE -@dots{} - WRITE (UNIT=LINE, FMT=9000) A, B, C -@dots{} -9000 FORMAT (1X, 'OUTPUT IS ', 3(F10.5)) -@end smallexample - -It is entirely possible that @code{ENCODE} and @code{DECODE} will -be supported by a future version of @code{g77}. - -@node Suppressing Space Padding -@subsection Suppressing Space Padding of Source Lines - -@code{g77} should offer VXT-Fortran-style suppression of virtual -spaces at the end of a source line -if an appropriate command-line option is specified. - -This affects cases where -a character constant is continued onto the next line in a fixed-form -source file, as in the following example: - -@smallexample -10 PRINT *,'HOW MANY - 1 SPACES?' -@end smallexample - -@noindent -@code{g77}, and many other compilers, virtually extend -the continued line through column 72 with spaces that become part -of the character constant, but Digital Fortran normally didn't, -leaving only one space between @samp{MANY} and @samp{SPACES?} -in the output of the above statement. - -Fairly recently, at least one version of Digital Fortran -was enhanced to provide the other behavior when a -command-line option is specified, apparently due to demand -from readers of the USENET group @file{comp.lang.fortran} -to offer conformance to this widespread practice in the -industry. -@code{g77} should return the favor by offering conformance -to Digital's approach to handling the above example. - -@node Fortran Preprocessor -@subsection Fortran Preprocessor - -@code{g77} should offer a preprocessor designed specifically -for Fortran to replace @samp{cpp -traditional}. -There are several out there worth evaluating, at least. - -Such a preprocessor would recognize Hollerith constants, -properly parse comments and character constants, and so on. -It might also recognize, process, and thus preprocess -files included via the @code{INCLUDE} directive. - -@node Bit Operations on Floating-point Data -@subsection Bit Operations on Floating-point Data -@cindex AND intrinsic -@cindex intrinsics, AND -@cindex OR intrinsic -@cindex intrinsics, OR -@cindex SHIFT intrinsic -@cindex intrinsics, SHIFT - -@code{g77} does not allow @code{REAL} and other non-integral types for -arguments to intrinsics like @code{AND}, @code{OR}, and @code{SHIFT}. - -For example, this program is rejected by @code{g77}, because -the intrinsic @code{IAND} does not accept @code{REAL} arguments: - -@smallexample -DATA A/7.54/, B/9.112/ -PRINT *, IAND(A, B) -END -@end smallexample - -@node POSIX Standard -@subsection @code{POSIX} Standard - -@code{g77} should support the POSIX standard for Fortran. - -@node Floating-point Exception Handling -@subsection Floating-point Exception Handling -@cindex floating point exceptions -@cindex exceptions, floating point -@cindex FPE handling -@cindex NaN values - -The @code{gcc} backend and, consequently, @code{g77}, currently provides no -general control over whether or not floating-point exceptions are trapped or -ignored. -(Ignoring them typically results in NaN values being -propagated in systems that conform to IEEE 754.) -The behaviour is normally inherited from the system-dependent startup -code, though some targets, such as the Alpha, have code generation -options which change the behaviour. - -Most systems provide some C-callable mechanism to change this; this can -be invoked at startup using @code{gcc}'s @code{constructor} attribute. -For example, just compiling and linking the following C code with your -program will turn on exception trapping for the ``common'' exceptions -on an x86-based GNU system: - -@smallexample -#include <fpu_control.h> -static void __attribute__ ((constructor)) -trapfpe () -@{ - __setfpucw (_FPU_DEFAULT & - ~(_FPU_MASK_IM | _FPU_MASK_ZM | _FPU_MASK_OM)); -@} -@end smallexample - -A convenient trick is to compile this something like: -@smallexample -gcc -o libtrapfpe.a trapfpe.c -@end smallexample -and then use it by adding @code{-trapfpe} to the @code{g77} command line -when linking. - -@node Nonportable Conversions -@subsection Nonportable Conversions -@cindex nonportable conversions -@cindex conversions, nonportable - -@code{g77} doesn't accept some particularly nonportable, -silent data-type conversions such as @code{LOGICAL} -to @code{REAL} (as in @samp{A=.FALSE.}, where @samp{A} -is type @code{REAL}), that other compilers might -quietly accept. - -Some of these conversions are accepted by @code{g77} -when the @samp{-fugly} option is specified. -Perhaps it should accept more or all of them. - -@node Large Automatic Arrays -@subsection Large Automatic Arrays -@cindex automatic arrays -@cindex arrays, automatic - -Currently, automatic arrays always are allocated on the stack. -For situations where the stack cannot be made large enough, -@code{g77} should offer a compiler option that specifies -allocation of automatic arrays in heap storage. - -@node Support for Threads -@subsection Support for Threads -@cindex threads -@cindex parallel processing - -Neither the code produced by @code{g77} nor the @code{libg2c} library -are thread-safe, nor does @code{g77} have support for parallel processing -(other than the instruction-level parallelism available on some -processors). -A package such as PVM might help here. - -@node Gracefully Handle Sensible Bad Code -@subsection Gracefully Handle Sensible Bad Code - -@code{g77} generally should continue processing for -warnings and recoverable (user) errors whenever possible---that -is, it shouldn't gratuitously make bad or useless code. - -For example: - -@smallexample -INTRINSIC ZABS -CALL FOO(ZABS) -END -@end smallexample - -@noindent -When compiling the above with @samp{-ff2c-intrinsics-disable}, -@code{g77} should indeed complain about passing @code{ZABS}, -but it still should compile, instead of rejecting -the entire @code{CALL} statement. -(Some of this is related to improving -the compiler internals to improve how statements are analyzed.) - -@node Non-standard Conversions -@subsection Non-standard Conversions - -@samp{-Wconversion} and related should flag places where non-standard -conversions are found. -Perhaps much of this would be part of @samp{-Wugly*}. - -@node Non-standard Intrinsics -@subsection Non-standard Intrinsics - -@code{g77} needs a new option, like @samp{-Wintrinsics}, to warn about use of -non-standard intrinsics without explicit @code{INTRINSIC} statements for them. -This would help find code that might fail silently when ported to another -compiler. - -@node Modifying DO Variable -@subsection Modifying @code{DO} Variable - -@code{g77} should warn about modifying @code{DO} variables -via @code{EQUIVALENCE}. -(The internal information gathered to produce this warning -might also be useful in setting the -internal ``doiter'' flag for a variable or even array -reference within a loop, since that might produce faster code someday.) - -For example, this code is invalid, so @code{g77} should warn about -the invalid assignment to @samp{NOTHER}: - -@smallexample -EQUIVALENCE (I, NOTHER) -DO I = 1, 100 - IF (I.EQ. 10) NOTHER = 20 -END DO -@end smallexample - -@node Better Pedantic Compilation -@subsection Better Pedantic Compilation - -@code{g77} needs to support @samp{-fpedantic} more thoroughly, -and use it only to generate -warnings instead of rejecting constructs outright. -Have it warn: -if a variable that dimensions an array is not a dummy or placed -explicitly in @code{COMMON} (F77 does not allow it to be -placed in @code{COMMON} via @code{EQUIVALENCE}); if specification statements -follow statement-function-definition statements; about all sorts of -syntactic extensions. - -@node Warn About Implicit Conversions -@subsection Warn About Implicit Conversions - -@code{g77} needs a @samp{-Wpromotions} option to warn if source code appears -to expect automatic, silent, and -somewhat dangerous compiler-assisted conversion of @code{REAL(KIND=1)} -constants to @code{REAL(KIND=2)} based on context. - -For example, it would warn about cases like this: - -@smallexample -DOUBLE PRECISION FOO -PARAMETER (TZPHI = 9.435784839284958) -FOO = TZPHI * 3D0 -@end smallexample - -@node Invalid Use of Hollerith Constant -@subsection Invalid Use of Hollerith Constant - -@code{g77} should disallow statements like @samp{RETURN 2HAB}, -which are invalid in both source forms -(unlike @samp{RETURN (2HAB)}, -which probably still makes no sense but at least can -be reliably parsed). -Fixed-form processing rejects it, but not free-form, except -in a way that is a bit difficult to understand. - -@node Dummy Array Without Dimensioning Dummy -@subsection Dummy Array Without Dimensioning Dummy - -@code{g77} should complain when a list of dummy arguments containing an -adjustable dummy array does -not also contain every variable listed in the dimension list of the -adjustable array. - -Currently, @code{g77} does complain about a variable that -dimensions an array but doesn't appear in any dummy list or @code{COMMON} -area, but this needs to be extended to catch cases where it doesn't appear in -every dummy list that also lists any arrays it dimensions. - -For example, @code{g77} should warn about the entry point @samp{ALT} -below, since it includes @samp{ARRAY} but not @samp{ISIZE} in its -list of arguments: - -@smallexample -SUBROUTINE PRIMARY(ARRAY, ISIZE) -REAL ARRAY(ISIZE) -ENTRY ALT(ARRAY) -@end smallexample - -@node Invalid FORMAT Specifiers -@subsection Invalid FORMAT Specifiers - -@code{g77} should check @code{FORMAT} specifiers for validity -as it does @code{FORMAT} statements. - -For example, a diagnostic would be produced for: - -@smallexample -PRINT 'HI THERE!' !User meant PRINT *, 'HI THERE!' -@end smallexample - -@node Ambiguous Dialects -@subsection Ambiguous Dialects - -@code{g77} needs a set of options such as @samp{-Wugly*}, @samp{-Wautomatic}, -@samp{-Wvxt}, @samp{-Wf90}, and so on. -These would warn about places in the user's source where ambiguities -are found, helpful in resolving ambiguities in the program's -dialect or dialects. - -@node Unused Labels -@subsection Unused Labels - -@code{g77} should warn about unused labels when @samp{-Wunused} is in effect. - -@node Informational Messages -@subsection Informational Messages - -@code{g77} needs an option to suppress information messages (notes). -@samp{-w} does this but also suppresses warnings. -The default should be to suppress info messages. - -Perhaps info messages should simply be eliminated. - -@node Uninitialized Variables at Run Time -@subsection Uninitialized Variables at Run Time - -@code{g77} needs an option to initialize everything (not otherwise -explicitly initialized) to ``weird'' -(machine-dependent) values, e.g. NaNs, bad (non-@code{NULL}) pointers, and -largest-magnitude integers, would help track down references to -some kinds of uninitialized variables at run time. - -Note that use of the options @samp{-O -Wuninitialized} can catch -many such bugs at compile time. - -@node Bounds Checking at Run Time -@subsection Bounds Checking at Run Time - -@code{g77} should offer run-time bounds-checking of array/subscript references -in a fashion similar to @code{f2c}. - -Note that @code{g77} already warns about references to out-of-bounds -elements of arrays when it detects these at compile time. - -@node Portable Unformatted Files -@subsection Portable Unformatted Files - -@cindex unformatted files -@cindex file formats -@cindex binary data -@cindex byte ordering -@code{g77} has no facility for exchanging unformatted files with systems -using different number formats---even differing only in endianness (byte -order)---or written by other compilers. Some compilers provide -facilities at least for doing byte-swapping during unformatted I/O. - -It is unrealistic to expect to cope with exchanging unformatted files -with arbitrary other compiler runtimes, but the @code{g77} runtime -should at least be able to read files written by @code{g77} on systems -with different number formats, particularly if they differ only in byte -order. - -In case you do need to write a program to translate to or from -@code{g77} (@code{libf2c}) unformatted files, they are written as -follows: -@table @asis -@item Sequential -Unformatted sequential records consist of -@enumerate -@item -A number giving the length of the record contents; -@item -the length of record contents again (for backspace). -@end enumerate - -The record length is of C type -@code{long}; this means that it is 8 bytes on 64-bit systems such as -Alpha GNU/Linux and 4 bytes on other systems, such as x86 GNU/Linux. -Consequently such files cannot be exchanged between 64-bit and 32-bit -systems, even with the same basic number format. -@item Direct access -Unformatted direct access files form a byte stream of length -@var{records}*@var{recl} bytes, where @var{records} is the maximum -record number (@code{REC=@var{records}}) written and @var{recl} is the -record length in bytes specified in the @code{OPEN} statement -(@code{RECL=@var{recl}}). Data appear in the records as determined by -the relevant @code{WRITE} statement. Dummy records with arbitrary -contents appear in the file in place of records which haven't been -written. -@end table - -Thus for exchanging a sequential or direct access unformatted file -between big- and little-endian 32-bit systems using IEEE 754 floating -point it would be sufficient to reverse the bytes in consecutive words -in the file @emph{iff} only @code{REAL*4}, @code{COMPLEX}, -@code{INTEGER*4} and/or @code{LOGICAL*4} data have been written to it by -@code{g77}. - -If necessary, it is possible to do byte-oriented i/o with @code{g77}'s -@code{FGETC} and @code{FPUTC} intrinsics. Byte-swapping can be done in -Fortran by equivalencing larger sized variables to an @code{INTEGER*1} -array or a set of scalars. - -@cindex HDF -@cindex PDB -If you need to exchange binary data between arbitrary system and -compiler variations, we recommend using a portable binary format with -Fortran bindings, such as NCSA's HDF (@uref{http://hdf.ncsa.uiuc.edu/}) -or PACT's PDB@footnote{No, not @emph{that} one.} -(@uref{http://www.llnl.gov/def_sci/pact/pact_homepage.html}). (Unlike, -say, CDF or XDR, HDF-like systems write in the native number formats and -only incur overhead when they are read on a system with a different -format.) A future @code{g77} runtime library should use such -techniques. - -@node Labels Visible to Debugger -@subsection Labels Visible to Debugger - -@code{g77} should output debugging information for statements labels, -for use by debuggers that know how to support them. -Same with weirder things like construct names. -It is not yet known if any debug formats or debuggers support these. - -@node Disappointments -@section Disappointments and Misunderstandings - -These problems are perhaps regrettable, but we don't know any practical -way around them for now. - -@menu -* Mangling of Names:: @samp{SUBROUTINE FOO} is given - external name @samp{foo_}. -* Multiple Definitions of External Names:: No doing both @samp{COMMON /FOO/} - and @samp{SUBROUTINE FOO}. -* Limitation on Implicit Declarations:: No @samp{IMPLICIT CHARACTER*(*)}. -@end menu - -@node Mangling of Names -@subsection Mangling of Names in Source Code -@cindex naming issues -@cindex external names -@cindex common blocks -@cindex name space -@cindex underscores - -The current external-interface design, which includes naming of -external procedures, COMMON blocks, and the library interface, -has various usability problems, including things like adding -underscores where not really necessary (and preventing easier -inter-language operability) and yet not providing complete -namespace freedom for user C code linked with Fortran apps (due -to the naming of functions in the library, among other things). - -Project GNU should at least get all this ``right'' for systems -it fully controls, such as the Hurd, and provide defaults and -options for compatibility with existing systems and interoperability -with popular existing compilers. - -@node Multiple Definitions of External Names -@subsection Multiple Definitions of External Names -@cindex block data -@cindex BLOCK DATA statement -@cindex statements, BLOCK DATA -@cindex COMMON statement -@cindex statements, COMMON -@cindex naming conflicts - -@code{g77} doesn't allow a common block and an external procedure or -@code{BLOCK DATA} to have the same name. -Some systems allow this, but @code{g77} does not, -to be compatible with @code{f2c}. - -@code{g77} could special-case the way it handles -@code{BLOCK DATA}, since it is not compatible with @code{f2c} in this -particular area (necessarily, since @code{g77} offers an -important feature here), but -it is likely that such special-casing would be very annoying to people -with programs that use @samp{EXTERNAL FOO}, with no other mention of -@samp{FOO} in the same program unit, to refer to external procedures, since -the result would be that @code{g77} would treat these references as requests to -force-load BLOCK DATA program units. - -In that case, if @code{g77} modified -names of @code{BLOCK DATA} so they could have the same names as -@code{COMMON}, users -would find that their programs wouldn't link because the @samp{FOO} procedure -didn't have its name translated the same way. - -(Strictly speaking, -@code{g77} could emit a null-but-externally-satisfying definition of -@samp{FOO} with its name transformed as if it had been a -@code{BLOCK DATA}, but that probably invites more trouble than it's -worth.) - -@node Limitation on Implicit Declarations -@subsection Limitation on Implicit Declarations -@cindex IMPLICIT CHARACTER*(*) statement -@cindex statements, IMPLICIT CHARACTER*(*) - -@code{g77} disallows @code{IMPLICIT CHARACTER*(*)}. -This is not standard-conforming. - -@node Non-bugs -@section Certain Changes We Don't Want to Make - -This section lists changes that people frequently request, but which -we do not make because we think GNU Fortran is better without them. - -@menu -* Backslash in Constants:: Why @samp{'\\'} is a constant that - is one, not two, characters long. -* Initializing Before Specifying:: Why @samp{DATA VAR/1/} can't precede - @samp{COMMON VAR}. -* Context-Sensitive Intrinsicness:: Why @samp{CALL SQRT} won't work. -* Context-Sensitive Constants:: Why @samp{9.435784839284958} is a - single-precision constant, - and might be interpreted as - @samp{9.435785} or similar. -* Equivalence Versus Equality:: Why @samp{.TRUE. .EQ. .TRUE.} won't work. -* Order of Side Effects:: Why @samp{J = IFUNC() - IFUNC()} might - not behave as expected. -@end menu - -@node Backslash in Constants -@subsection Backslash in Constants -@cindex backslash -@cindex f77 support -@cindex support, f77 - -In the opinion of many experienced Fortran users, -@samp{-fno-backslash} should be the default, not @samp{-fbackslash}, -as currently set by @code{g77}. - -First of all, you can always specify -@samp{-fno-backslash} to turn off this processing. - -Despite not being within the spirit (though apparently within the -letter) of the ANSI FORTRAN 77 standard, @code{g77} defaults to -@samp{-fbackslash} because that is what most UNIX @code{f77} commands -default to, and apparently lots of code depends on this feature. - -This is a particularly troubling issue. -The use of a C construct in the midst of Fortran code -is bad enough, worse when it makes existing Fortran -programs stop working (as happens when programs written -for non-UNIX systems are ported to UNIX systems with -compilers that provide the @samp{-fbackslash} feature -as the default---sometimes with no option to turn it off). - -The author of GNU Fortran wished, for reasons of linguistic -purity, to make @samp{-fno-backslash} the default for GNU -Fortran and thus require users of UNIX @code{f77} and @code{f2c} -to specify @samp{-fbackslash} to get the UNIX behavior. - -However, the realization that @code{g77} is intended as -a replacement for @emph{UNIX} @code{f77}, caused the author -to choose to make @code{g77} as compatible with -@code{f77} as feasible, which meant making @samp{-fbackslash} -the default. - -The primary focus on compatibility is at the source-code -level, and the question became ``What will users expect -a replacement for @code{f77} to do, by default?'' -Although at least one UNIX @code{f77} does not provide -@samp{-fbackslash} as a default, it appears that -the majority of them do, which suggests that -the majority of code that is compiled by UNIX @code{f77} -compilers expects @samp{-fbackslash} to be the default. - -It is probably the case that more code exists -that would @emph{not} work with @samp{-fbackslash} -in force than code that requires it be in force. - -However, most of @emph{that} code is not being compiled -with @code{f77}, -and when it is, new build procedures (shell scripts, -makefiles, and so on) must be set up anyway so that -they work under UNIX. -That makes a much more natural and safe opportunity for -non-UNIX users to adapt their build procedures for -@code{g77}'s default of @samp{-fbackslash} than would -exist for the majority of UNIX @code{f77} users who -would have to modify existing, working build procedures -to explicitly specify @samp{-fbackslash} if that was -not the default. - -One suggestion has been to configure the default for -@samp{-fbackslash} (and perhaps other options as well) -based on the configuration of @code{g77}. - -This is technically quite straightforward, but will be avoided -even in cases where not configuring defaults to be -dependent on a particular configuration greatly inconveniences -some users of legacy code. - -Many users appreciate the GNU compilers because they provide an -environment that is uniform across machines. -These users would be -inconvenienced if the compiler treated things like the -format of the source code differently on certain machines. - -Occasionally users write programs intended only for a particular machine -type. -On these occasions, the users would benefit if the GNU Fortran compiler -were to support by default the same dialect as the other compilers on -that machine. -But such applications are rare. -And users writing a -program to run on more than one type of machine cannot possibly benefit -from this kind of compatibility. -(This is consistent with the design goals for @code{gcc}. -To change them for @code{g77}, you must first change them -for @code{gcc}. -Do not ask the maintainers of @code{g77} to do this for you, -or to disassociate @code{g77} from the widely understood, if -not widely agreed-upon, goals for GNU compilers in general.) - -This is why GNU Fortran does and will treat backslashes in the same -fashion on all types of machines (by default). -@xref{Direction of Language Development}, for more information on -this overall philosophy guiding the development of the GNU Fortran -language. - -Of course, users strongly concerned about portability should indicate -explicitly in their build procedures which options are expected -by their source code, or write source code that has as few such -expectations as possible. - -For example, avoid writing code that depends on backslash (@samp{\}) -being interpreted either way in particular, such as by -starting a program unit with: - -@smallexample -CHARACTER BACKSL -PARAMETER (BACKSL = '\\') -@end smallexample - -@noindent -Then, use concatenation of @samp{BACKSL} anyplace a backslash -is desired. -In this way, users can write programs which have the same meaning -in many Fortran dialects. - -(However, this technique does not work for Hollerith constants---which -is just as well, since the only generally portable uses for Hollerith -constants are in places where character constants can and should -be used instead, for readability.) - -@node Initializing Before Specifying -@subsection Initializing Before Specifying -@cindex initialization, statement placement -@cindex placing initialization statements - -@code{g77} does not allow @samp{DATA VAR/1/} to appear in the -source code before @samp{COMMON VAR}, -@samp{DIMENSION VAR(10)}, @samp{INTEGER VAR}, and so on. -In general, @code{g77} requires initialization of a variable -or array to be specified @emph{after} all other specifications -of attributes (type, size, placement, and so on) of that variable -or array are specified (though @emph{confirmation} of data type is -permitted). - -It is @emph{possible} @code{g77} will someday allow all of this, -even though it is not allowed by the FORTRAN 77 standard. - -Then again, maybe it is better to have -@code{g77} always require placement of @code{DATA} -so that it can possibly immediately write constants -to the output file, thus saving time and space. - -That is, @samp{DATA A/1000000*1/} should perhaps always -be immediately writable to canonical assembler, unless it's already known -to be in a @code{COMMON} area following as-yet-uninitialized stuff, -and to do this it cannot be followed by @samp{COMMON A}. - -@node Context-Sensitive Intrinsicness -@subsection Context-Sensitive Intrinsicness -@cindex intrinsics, context-sensitive -@cindex context-sensitive intrinsics - -@code{g77} treats procedure references to @emph{possible} intrinsic -names as always enabling their intrinsic nature, regardless of -whether the @emph{form} of the reference is valid for that -intrinsic. - -For example, @samp{CALL SQRT} is interpreted by @code{g77} as -an invalid reference to the @code{SQRT} intrinsic function, -because the reference is a subroutine invocation. - -First, @code{g77} recognizes the statement @samp{CALL SQRT} -as a reference to a @emph{procedure} named @samp{SQRT}, not -to a @emph{variable} with that name (as it would for a statement -such as @samp{V = SQRT}). - -Next, @code{g77} establishes that, in the program unit being compiled, -@code{SQRT} is an intrinsic---not a subroutine that -happens to have the same name as an intrinsic (as would be -the case if, for example, @samp{EXTERNAL SQRT} was present). - -Finally, @code{g77} recognizes that the @emph{form} of the -reference is invalid for that particular intrinsic. -That is, it recognizes that it is invalid for an intrinsic -@emph{function}, such as @code{SQRT}, to be invoked as -a @emph{subroutine}. - -At that point, @code{g77} issues a diagnostic. - -Some users claim that it is ``obvious'' that @samp{CALL SQRT} -references an external subroutine of their own, not an -intrinsic function. - -However, @code{g77} knows about intrinsic -subroutines, not just functions, and is able to support both having -the same names, for example. - -As a result of this, @code{g77} rejects calls -to intrinsics that are not subroutines, and function invocations -of intrinsics that are not functions, just as it (and most compilers) -rejects invocations of intrinsics with the wrong number (or types) -of arguments. - -So, use the @samp{EXTERNAL SQRT} statement in a program unit that calls -a user-written subroutine named @samp{SQRT}. - -@node Context-Sensitive Constants -@subsection Context-Sensitive Constants -@cindex constants, context-sensitive -@cindex context-sensitive constants - -@code{g77} does not use context to determine the types of -constants or named constants (@code{PARAMETER}), except -for (non-standard) typeless constants such as @samp{'123'O}. - -For example, consider the following statement: - -@smallexample -PRINT *, 9.435784839284958 * 2D0 -@end smallexample - -@noindent -@code{g77} will interpret the (truncated) constant -@samp{9.435784839284958} as a @code{REAL(KIND=1)}, not @code{REAL(KIND=2)}, -constant, because the suffix @code{D0} is not specified. - -As a result, the output of the above statement when -compiled by @code{g77} will appear to have ``less precision'' -than when compiled by other compilers. - -In these and other cases, some compilers detect the -fact that a single-precision constant is used in -a double-precision context and therefore interpret the -single-precision constant as if it was @emph{explicitly} -specified as a double-precision constant. -(This has the effect of appending @emph{decimal}, not -@emph{binary}, zeros to the fractional part of the -number---producing different computational results.) - -The reason this misfeature is dangerous is that a slight, -apparently innocuous change to the source code can change -the computational results. -Consider: - -@smallexample -REAL ALMOST, CLOSE -DOUBLE PRECISION FIVE -PARAMETER (ALMOST = 5.000000000001) -FIVE = 5 -CLOSE = 5.000000000001 -PRINT *, 5.000000000001 - FIVE -PRINT *, ALMOST - FIVE -PRINT *, CLOSE - FIVE -END -@end smallexample - -@noindent -Running the above program should -result in the same value being -printed three times. -With @code{g77} as the compiler, -it does. - -However, compiled by many other compilers, -running the above program would print -two or three distinct values, because -in two or three of the statements, the -constant @samp{5.000000000001}, which -on most systems is exactly equal to @samp{5.} -when interpreted as a single-precision constant, -is instead interpreted as a double-precision -constant, preserving the represented -precision. -However, this ``clever'' promotion of -type does not extend to variables or, -in some compilers, to named constants. - -Since programmers often are encouraged to replace manifest -constants or permanently-assigned variables with named -constants (@code{PARAMETER} in Fortran), and might need -to replace some constants with variables having the same -values for pertinent portions of code, -it is important that compilers treat code so modified in the -same way so that the results of such programs are the same. -@code{g77} helps in this regard by treating constants just -the same as variables in terms of determining their types -in a context-independent way. - -Still, there is a lot of existing Fortran code that has -been written to depend on the way other compilers freely -interpret constants' types based on context, so anything -@code{g77} can do to help flag cases of this in such code -could be very helpful. - -@node Equivalence Versus Equality -@subsection Equivalence Versus Equality -@cindex .EQV., with integer operands -@cindex comparing logical expressions -@cindex logical expressions, comparing - -Use of @code{.EQ.} and @code{.NE.} on @code{LOGICAL} operands -is not supported, except via @samp{-fugly}, which is not -recommended except for legacy code (where the behavior expected -by the @emph{code} is assumed). - -Legacy code should be changed, as resources permit, to use @code{.EQV.} -and @code{.NEQV.} instead, as these are permitted by the various -Fortran standards. - -New code should never be written expecting @code{.EQ.} or @code{.NE.} -to work if either of its operands is @code{LOGICAL}. - -The problem with supporting this ``feature'' is that there is -unlikely to be consensus on how it works, as illustrated by the -following sample program: - -@smallexample -LOGICAL L,M,N -DATA L,M,N /3*.FALSE./ -IF (L.AND.M.EQ.N) PRINT *,'L.AND.M.EQ.N' -END -@end smallexample - -The issue raised by the above sample program is: what is the -precedence of @code{.EQ.} (and @code{.NE.}) when applied to -@code{LOGICAL} operands? - -Some programmers will argue that it is the same as the precedence -for @code{.EQ.} when applied to numeric (such as @code{INTEGER}) -operands. -By this interpretation, the subexpression @samp{M.EQ.N} must be -evaluated first in the above program, resulting in a program that, -when run, does not execute the @code{PRINT} statement. - -Other programmers will argue that the precedence is the same as -the precedence for @code{.EQV.}, which is restricted by the standards -to @code{LOGICAL} operands. -By this interpretation, the subexpression @samp{L.AND.M} must be -evaluated first, resulting in a program that @emph{does} execute -the @code{PRINT} statement. - -Assigning arbitrary semantic interpretations to syntactic expressions -that might legitimately have more than one ``obvious'' interpretation -is generally unwise. - -The creators of the various Fortran standards have done a good job -in this case, requiring a distinct set of operators (which have their -own distinct precedence) to compare @code{LOGICAL} operands. -This requirement results in expression syntax with more certain -precedence (without requiring substantial context), making it easier -for programmers to read existing code. -@code{g77} will avoid muddying up elements of the Fortran language -that were well-designed in the first place. - -(Ask C programmers about the precedence of expressions such as -@samp{(a) & (b)} and @samp{(a) - (b)}---they cannot even tell -you, without knowing more context, whether the @samp{&} and @samp{-} -operators are infix (binary) or unary!) - -@node Order of Side Effects -@subsection Order of Side Effects -@cindex side effects, order of evaluation -@cindex order of evaluation, side effects - -@code{g77} does not necessarily produce code that, when run, performs -side effects (such as those performed by function invocations) -in the same order as in some other compiler---or even in the same -order as another version, port, or invocation (using different -command-line options) of @code{g77}. - -It is never safe to depend on the order of evaluation of side effects. -For example, an expression like this may very well behave differently -from one compiler to another: - -@smallexample -J = IFUNC() - IFUNC() -@end smallexample - -@noindent -There is no guarantee that @samp{IFUNC} will be evaluated in any particular -order. -Either invocation might happen first. -If @samp{IFUNC} returns 5 the first time it is invoked, and -returns 12 the second time, @samp{J} might end up with the -value @samp{7}, or it might end up with @samp{-7}. - -Generally, in Fortran, procedures with side-effects intended to -be visible to the caller are best designed as @emph{subroutines}, -not functions. -Examples of such side-effects include: - -@itemize @bullet -@item -The generation of random numbers -that are intended to influence return values. - -@item -Performing I/O -(other than internal I/O to local variables). - -@item -Updating information in common blocks. -@end itemize - -An example of a side-effect that is not intended to be visible -to the caller is a function that maintains a cache of recently -calculated results, intended solely to speed repeated invocations -of the function with identical arguments. -Such a function can be safely used in expressions, because -if the compiler optimizes away one or more calls to the -function, operation of the program is unaffected (aside -from being speeded up). - -@node Warnings and Errors -@section Warning Messages and Error Messages - -@cindex error messages -@cindex warnings vs errors -@cindex messages, warning and error -The GNU compiler can produce two kinds of diagnostics: errors and -warnings. -Each kind has a different purpose: - -@itemize @w{} -@item -@emph{Errors} report problems that make it impossible to compile your -program. -GNU Fortran reports errors with the source file name, line -number, and column within the line where the problem is apparent. - -@item -@emph{Warnings} report other unusual conditions in your code that -@emph{might} indicate a problem, although compilation can (and does) -proceed. -Warning messages also report the source file name, line number, -and column information, -but include the text @samp{warning:} to distinguish them -from error messages. -@end itemize - -Warnings might indicate danger points where you should check to make sure -that your program really does what you intend; or the use of obsolete -features; or the use of nonstandard features of GNU Fortran. -Many warnings are issued only if you ask for them, with one of the -@samp{-W} options (for instance, @samp{-Wall} requests a variety of -useful warnings). - -@emph{Note:} Currently, the text of the line and a pointer to the column -is printed in most @code{g77} diagnostics. -Probably, as of version 0.6, @code{g77} will -no longer print the text of the source line, instead printing -the column number following the file name and line number in -a form that GNU Emacs recognizes. -This change is expected to speed up and reduce the memory usage -of the @code{g77} compiler. -@c -@c Say this when it is true -- hopefully 0.6, maybe 0.7 or later. --burley -@c -@c GNU Fortran always tries to compile your program if possible; it never -@c gratuitously rejects a program whose meaning is clear merely because -@c (for instance) it fails to conform to a standard. In some cases, -@c however, the Fortran standard specifies that certain extensions are -@c forbidden, and a diagnostic @emph{must} be issued by a conforming -@c compiler. The @samp{-pedantic} option tells GNU Fortran to issue warnings -@c in such cases; @samp{-pedantic-errors} says to make them errors instead. -@c This does not mean that @emph{all} non-ANSI constructs get warnings -@c or errors. - -@xref{Warning Options,,Options to Request or Suppress Warnings}, for -more detail on these and related command-line options. - -@node Open Questions -@chapter Open Questions - -Please consider offering useful answers to these questions! - -@itemize @bullet -@item -@code{LOC()} and other intrinsics are probably somewhat misclassified. -Is the a need for more precise classification of intrinsics, and if so, -what are the appropriate groupings? -Is there a need to individually -enable/disable/delete/hide intrinsics from the command line? -@end itemize - -@node Bugs -@chapter Reporting Bugs -@cindex bugs -@cindex reporting bugs - -Your bug reports play an essential role in making GNU Fortran reliable. - -When you encounter a problem, the first thing to do is to see if it is -already known. -@xref{Trouble}. -If it isn't known, then you should report the problem. - -Reporting a bug might help you by bringing a solution to your problem, or -it might not. -(If it does not, look in the service directory; see -@ref{Service}.) -In any case, the principal function of a bug report is -to help the entire community by making the next version of GNU Fortran work -better. -Bug reports are your contribution to the maintenance of GNU Fortran. - -Since the maintainers are very overloaded, we cannot respond to every -bug report. -However, if the bug has not been fixed, we are likely to -send you a patch and ask you to tell us whether it works. - -In order for a bug report to serve its purpose, you must include the -information that makes for fixing the bug. - -@menu -* Criteria: Bug Criteria. Have you really found a bug? -* Where: Bug Lists. Where to send your bug report. -* Reporting: Bug Reporting. How to report a bug effectively. -* Patches: Sending Patches. How to send a patch for GNU Fortran. -@end menu - -@xref{Trouble,,Known Causes of Trouble with GNU Fortran}, -for information on problems we already know about. - -@xref{Service,,How To Get Help with GNU Fortran}, -for information on where to ask for help. - -@node Bug Criteria -@section Have You Found a Bug? -@cindex bug criteria - -If you are not sure whether you have found a bug, here are some guidelines: - -@itemize @bullet -@cindex fatal signal -@cindex core dump -@item -If the compiler gets a fatal signal, for any input whatever, that is a -compiler bug. -Reliable compilers never crash---they just remain obsolete. - -@cindex invalid assembly code -@cindex assembly code, invalid -@item -If the compiler produces invalid assembly code, for any input whatever, -@c (except an @code{asm} statement), -that is a compiler bug, unless the -compiler reports errors (not just warnings) which would ordinarily -prevent the assembler from being run. - -@cindex undefined behavior -@cindex undefined function value -@item -If the compiler produces valid assembly code that does not correctly -execute the input source code, that is a compiler bug. - -However, you must double-check to make sure, because you might have run -into an incompatibility between GNU Fortran and traditional Fortran. -@c (@pxref{Incompatibilities}). -These incompatibilities might be considered -bugs, but they are inescapable consequences of valuable features. - -Or you might have a program whose behavior is undefined, which happened -by chance to give the desired results with another Fortran compiler. -It is best to check the relevant Fortran standard thoroughly if -it is possible that the program indeed does something undefined. - -After you have localized the error to a single source line, it should -be easy to check for these things. -If your program is correct and well defined, you have found -a compiler bug. - -It might help if, in your submission, you identified the specific -language in the relevant Fortran standard that specifies the -desired behavior, if it isn't likely to be obvious and agreed-upon -by all Fortran users. - -@item -If the compiler produces an error message for valid input, that is a -compiler bug. - -@cindex invalid input -@item -If the compiler does not produce an error message for invalid input, -that is a compiler bug. -However, you should note that your idea of -``invalid input'' might be someone else's idea -of ``an extension'' or ``support for traditional practice''. - -@item -If you are an experienced user of Fortran compilers, your suggestions -for improvement of GNU Fortran are welcome in any case. -@end itemize - -Many, perhaps most, bug reports against @code{g77} turn out to -be bugs in the user's code. -While we find such bug reports educational, they sometimes take -a considerable amount of time to track down or at least respond -to---time we could be spending making @code{g77}, not some user's -code, better. - -Some steps you can take to verify that the bug is not certainly -in the code you're compiling with @code{g77}: - -@itemize @bullet -@item -Compile your code using the @code{g77} options @samp{-W -Wall -O}. -These options enable many useful warning; the @samp{-O} option -enables flow analysis that enables the uninitialized-variable -warning. - -If you investigate the warnings and find evidence of possible bugs -in your code, fix them first and retry @code{g77}. - -@item -Compile your code using the @code{g77} options @samp{-finit-local-zero}, -@samp{-fno-automatic}, @samp{-ffloat-store}, and various -combinations thereof. - -If your code works with any of these combinations, that is not -proof that the bug isn't in @code{g77}---a @code{g77} bug exposed -by your code might simply be avoided, or have a different, more subtle -effect, when different options are used---but it can be a -strong indicator that your code is making unwarranted assumptions -about the Fortran dialect and/or underlying machine it is -being compiled and run on. - -@xref{Overly Convenient Options,,Overly Convenient Command-Line Options}, -for information on the @samp{-fno-automatic} and -@samp{-finit-local-zero} options and how to convert -their use into selective changes in your own code. - -@item -@pindex ftnchek -Validate your code with @code{ftnchek} or a similar code-checking -tool. -@code{ftnchek} can be found at @uref{ftp://ftp.netlib.org/fortran} -or @uref{ftp://ftp.dsm.fordham.edu}. - -@pindex make -@cindex Makefile example -Here are some sample @file{Makefile} rules using @code{ftnchek} -``project'' files to do cross-file checking and @code{sfmakedepend} -(from @uref{ftp://ahab.rutgers.edu/pub/perl/sfmakedepend}) -to maintain dependencies automatically. -These assume the use of GNU @code{make}. - -@smallexample -# Dummy suffix for ftnchek targets: -.SUFFIXES: .chek -.PHONY: chekall - -# How to compile .f files (for implicit rule): -FC = g77 -# Assume `include' directory: -FFLAGS = -Iinclude -g -O -Wall - -# Flags for ftnchek: -CHEK1 = -array=0 -include=includes -noarray -CHEK2 = -nonovice -usage=1 -notruncation -CHEKFLAGS = $(CHEK1) $(CHEK2) - -# Run ftnchek with all the .prj files except the one corresponding -# to the target's root: -%.chek : %.f ; \ - ftnchek $(filter-out $*.prj,$(PRJS)) $(CHEKFLAGS) \ - -noextern -library $< - -# Derive a project file from a source file: -%.prj : %.f ; \ - ftnchek $(CHEKFLAGS) -noextern -project -library $< - -# The list of objects is assumed to be in variable OBJS. -# Sources corresponding to the objects: -SRCS = $(OBJS:%.o=%.f) -# ftnchek project files: -PRJS = $(OBJS:%.o=%.prj) - -# Build the program -prog: $(OBJS) ; \ - $(FC) -o $@ $(OBJS) - -chekall: $(PRJS) ; \ - ftnchek $(CHEKFLAGS) $(PRJS) - -prjs: $(PRJS) - -# For Emacs M-x find-tag: -TAGS: $(SRCS) ; \ - etags $(SRCS) - -# Rebuild dependencies: -depend: ; \ - sfmakedepend -I $(PLTLIBDIR) -I includes -a prj $(SRCS1) -@end smallexample - -@item -Try your code out using other Fortran compilers, such as @code{f2c}. -If it does not work on at least one other compiler (assuming the -compiler supports the features the code needs), that is a strong -indicator of a bug in the code. - -However, even if your code works on many compilers @emph{except} -@code{g77}, that does @emph{not} mean the bug is in @code{g77}. -It might mean the bug is in your code, and that @code{g77} simply -exposes it more readily than other compilers. -@end itemize - -@node Bug Lists -@section Where to Report Bugs -@cindex bug report mailing lists -@kindex @value{email-bugs} -Send bug reports for GNU Fortran to @email{@value{email-bugs}}. - -Often people think of posting bug reports to a newsgroup instead of -mailing them. -This sometimes appears to work, but it has one problem which can be -crucial: a newsgroup posting does not contain a mail path back to the -sender. -Thus, if maintainers need more information, they might be unable -to reach you. For this reason, you should always send bug reports by -mail to the proper mailing list. - -As a last resort, send bug reports on paper to: - -@example -GNU Compiler Bugs -Free Software Foundation -59 Temple Place - Suite 330 -Boston, MA 02111-1307, USA -@end example - -@node Bug Reporting -@section How to Report Bugs -@cindex compiler bugs, reporting - -The fundamental principle of reporting bugs usefully is this: -@strong{report all the facts}. -If you are not sure whether to state a -fact or leave it out, state it! - -Often people omit facts because they think they know what causes the -problem and they conclude that some details don't matter. -Thus, you might -assume that the name of the variable you use in an example does not matter. -Well, probably it doesn't, but one cannot be sure. -Perhaps the bug is a -stray memory reference which happens to fetch from the location where that -name is stored in memory; perhaps, if the name were different, the contents -of that location would fool the compiler into doing the right thing despite -the bug. -Play it safe and give a specific, complete example. -That is the -easiest thing for you to do, and the most helpful. - -Keep in mind that the purpose of a bug report is to enable someone to -fix the bug if it is not known. -It isn't very important what happens if -the bug is already known. -Therefore, always write your bug reports on -the assumption that the bug is not known. - -Sometimes people give a few sketchy facts and ask, ``Does this ring a -bell?'' -This cannot help us fix a bug, so it is rarely helpful. -We respond by asking for enough details to enable us to investigate. -You might as well expedite matters by sending them to begin with. -(Besides, there are enough bells ringing around here as it is.) - -Try to make your bug report self-contained. -If we have to ask you for -more information, it is best if you include all the previous information -in your response, as well as the information that was missing. - -Please report each bug in a separate message. -This makes it easier for -us to track which bugs have been fixed and to forward your bugs reports -to the appropriate maintainer. - -Do not compress and encode any part of your bug report using programs -such as @file{uuencode}. -If you do so it will slow down the processing -of your bug. -If you must submit multiple large files, use @file{shar}, -which allows us to read your message without having to run any -decompression programs. - -(As a special exception for GNU Fortran bug-reporting, at least -for now, if you are sending more than a few lines of code, if -your program's source file format contains ``interesting'' things -like trailing spaces or strange characters, or if you need to -include binary data files, it is acceptable to put all the -files together in a @code{tar} archive, and, whether you need to -do that, it is acceptable to then compress the single file (@code{tar} -archive or source file) -using @code{gzip} and encode it via @code{uuencode}. -Do not use any MIME stuff---the current maintainer can't decode this. -Using @code{compress} instead of @code{gzip} is acceptable, assuming -you have licensed the use of the patented algorithm in -@code{compress} from Unisys.) - -To enable someone to investigate the bug, you should include all these -things: - -@itemize @bullet -@item -The version of GNU Fortran. -You can get this by running @code{g77} with the @samp{-v} option. -(Ignore any error messages that might be displayed -when the linker is run.) - -Without this, we won't know whether there is any point in looking for -the bug in the current version of GNU Fortran. - -@item -@cindex preprocessor -@cindex cpp program -@cindex programs, cpp -@pindex cpp -A complete input file that will reproduce the bug. -If the bug is in the compiler proper (@file{f771}) and -you are using the C preprocessor, run your -source file through the C preprocessor by doing @samp{g77 -E -@var{sourcefile} > @var{outfile}}, then include the contents of -@var{outfile} in the bug report. (When you do this, use the same -@samp{-I}, @samp{-D} or @samp{-U} options that you used in actual -compilation.) - -A single statement is not enough of an example. -In order to compile it, -it must be embedded in a complete file of compiler input; and the bug -might depend on the details of how this is done. - -Without a real example one can compile, all anyone can do about your bug -report is wish you luck. It would be futile to try to guess how to -provoke the bug. For example, bugs in register allocation and reloading -frequently depend on every little detail of the function they happen in. - -@item -@cindex included files -@cindex INCLUDE directive -@cindex directive, INCLUDE -@cindex #include directive -@cindex directive, #include -Note that you should include with your bug report any files -included by the source file -(via the @code{#include} or @code{INCLUDE} directive) -that you send, and any files they include, and so on. - -It is not necessary to replace -the @code{#include} and @code{INCLUDE} directives -with the actual files in the version of the source file that -you send, but it might make submitting the bug report easier -in the end. -However, be sure to @emph{reproduce} the bug using the @emph{exact} -version of the source material you submit, to avoid wild-goose -chases. - -@item -The command arguments you gave GNU Fortran to compile that example -and observe the bug. For example, did you use @samp{-O}? To guarantee -you won't omit something important, list all the options. - -If we were to try to guess the arguments, we would probably guess wrong -and then we would not encounter the bug. - -@item -The type of machine you are using, and the operating system name and -version number. -(Much of this information is printed by @samp{g77 -v}---if you -include that, send along any additional info you have that you -don't see clearly represented in that output.) - -@item -The operands you gave to the @code{configure} command when you installed -the compiler. - -@item -A complete list of any modifications you have made to the compiler -source. (We don't promise to investigate the bug unless it happens in -an unmodified compiler. But if you've made modifications and don't tell -us, then you are sending us on a wild-goose chase.) - -Be precise about these changes. A description in English is not -enough---send a context diff for them. - -Adding files of your own (such as a machine description for a machine we -don't support) is a modification of the compiler source. - -@item -Details of any other deviations from the standard procedure for installing -GNU Fortran. - -@item -A description of what behavior you observe that you believe is -incorrect. For example, ``The compiler gets a fatal signal,'' or, -``The assembler instruction at line 208 in the output is incorrect.'' - -Of course, if the bug is that the compiler gets a fatal signal, then one -can't miss it. But if the bug is incorrect output, the maintainer might -not notice unless it is glaringly wrong. None of us has time to study -all the assembler code from a 50-line Fortran program just on the chance that -one instruction might be wrong. We need @emph{you} to do this part! - -Even if the problem you experience is a fatal signal, you should still -say so explicitly. Suppose something strange is going on, such as, your -copy of the compiler is out of synch, or you have encountered a bug in -the C library on your system. (This has happened!) Your copy might -crash and the copy here would not. If you @i{said} to expect a crash, -then when the compiler here fails to crash, we would know that the bug -was not happening. If you don't say to expect a crash, then we would -not know whether the bug was happening. We would not be able to draw -any conclusion from our observations. - -If the problem is a diagnostic when building GNU Fortran with some other -compiler, say whether it is a warning or an error. - -Often the observed symptom is incorrect output when your program is run. -Sad to say, this is not enough information unless the program is short -and simple. None of us has time to study a large program to figure out -how it would work if compiled correctly, much less which line of it was -compiled wrong. So you will have to do that. Tell us which source line -it is, and what incorrect result happens when that line is executed. A -person who understands the program can find this as easily as finding a -bug in the program itself. - -@item -If you send examples of assembler code output from GNU Fortran, -please use @samp{-g} when you make them. The debugging information -includes source line numbers which are essential for correlating the -output with the input. - -@item -If you wish to mention something in the GNU Fortran source, refer to it by -context, not by line number. - -The line numbers in the development sources don't match those in your -sources. Your line numbers would convey no convenient information to the -maintainers. - -@item -Additional information from a debugger might enable someone to find a -problem on a machine which he does not have available. However, you -need to think when you collect this information if you want it to have -any chance of being useful. - -@cindex backtrace for bug reports -For example, many people send just a backtrace, but that is never -useful by itself. A simple backtrace with arguments conveys little -about GNU Fortran because the compiler is largely data-driven; the same -functions are called over and over for different RTL insns, doing -different things depending on the details of the insn. - -Most of the arguments listed in the backtrace are useless because they -are pointers to RTL list structure. The numeric values of the -pointers, which the debugger prints in the backtrace, have no -significance whatever; all that matters is the contents of the objects -they point to (and most of the contents are other such pointers). - -In addition, most compiler passes consist of one or more loops that -scan the RTL insn sequence. The most vital piece of information about -such a loop---which insn it has reached---is usually in a local variable, -not in an argument. - -@findex debug_rtx -What you need to provide in addition to a backtrace are the values of -the local variables for several stack frames up. When a local -variable or an argument is an RTX, first print its value and then use -the GDB command @code{pr} to print the RTL expression that it points -to. (If GDB doesn't run on your machine, use your debugger to call -the function @code{debug_rtx} with the RTX as an argument.) In -general, whenever a variable is a pointer, its value is no use -without the data it points to. -@end itemize - -Here are some things that are not necessary: - -@itemize @bullet -@item -A description of the envelope of the bug. - -Often people who encounter a bug spend a lot of time investigating -which changes to the input file will make the bug go away and which -changes will not affect it. - -This is often time consuming and not very useful, because the way we -will find the bug is by running a single example under the debugger with -breakpoints, not by pure deduction from a series of examples. You might -as well save your time for something else. - -Of course, if you can find a simpler example to report @emph{instead} of -the original one, that is a convenience. Errors in the output will be -easier to spot, running under the debugger will take less time, etc. -Most GNU Fortran bugs involve just one function, so the most straightforward -way to simplify an example is to delete all the function definitions -except the one where the bug occurs. Those earlier in the file may be -replaced by external declarations if the crucial function depends on -them. (Exception: inline functions might affect compilation of functions -defined later in the file.) - -However, simplification is not vital; if you don't want to do this, -report the bug anyway and send the entire test case you used. - -@item -In particular, some people insert conditionals @samp{#ifdef BUG} around -a statement which, if removed, makes the bug not happen. These are just -clutter; we won't pay any attention to them anyway. Besides, you should -send us preprocessor output, and that can't have conditionals. - -@item -A patch for the bug. - -A patch for the bug is useful if it is a good one. But don't omit the -necessary information, such as the test case, on the assumption that a -patch is all we need. We might see problems with your patch and decide -to fix the problem another way, or we might not understand it at all. - -Sometimes with a program as complicated as GNU Fortran it is very hard to -construct an example that will make the program follow a certain path -through the code. If you don't send the example, we won't be able to -construct one, so we won't be able to verify that the bug is fixed. - -And if we can't understand what bug you are trying to fix, or why your -patch should be an improvement, we won't install it. A test case will -help us to understand. - -@xref{Sending Patches}, for guidelines on how to make it easy for us to -understand and install your patches. - -@item -A guess about what the bug is or what it depends on. - -Such guesses are usually wrong. Even the maintainer can't guess right -about such things without first using the debugger to find the facts. - -@item -A core dump file. - -We have no way of examining a core dump for your type of machine -unless we have an identical system---and if we do have one, -we should be able to reproduce the crash ourselves. -@end itemize - -@node Sending Patches -@section Sending Patches for GNU Fortran - -If you would like to write bug fixes or improvements for the GNU Fortran -compiler, that is very helpful. -Send suggested fixes to the bug report -mailing list, @email{@value{email-bugs}}. - -Please follow these guidelines so we can study your patches efficiently. -If you don't follow these guidelines, your information might still be -useful, but using it will take extra work. Maintaining GNU Fortran is a lot -of work in the best of circumstances, and we can't keep up unless you do -your best to help. - -@itemize @bullet -@item -Send an explanation with your changes of what problem they fix or what -improvement they bring about. For a bug fix, just include a copy of the -bug report, and explain why the change fixes the bug. - -(Referring to a bug report is not as good as including it, because then -we will have to look it up, and we have probably already deleted it if -we've already fixed the bug.) - -@item -Always include a proper bug report for the problem you think you have -fixed. We need to convince ourselves that the change is right before -installing it. Even if it is right, we might have trouble judging it if -we don't have a way to reproduce the problem. - -@item -Include all the comments that are appropriate to help people reading the -source in the future understand why this change was needed. - -@item -Don't mix together changes made for different reasons. -Send them @emph{individually}. - -If you make two changes for separate reasons, then we might not want to -install them both. We might want to install just one. If you send them -all jumbled together in a single set of diffs, we have to do extra work -to disentangle them---to figure out which parts of the change serve -which purpose. If we don't have time for this, we might have to ignore -your changes entirely. - -If you send each change as soon as you have written it, with its own -explanation, then the two changes never get tangled up, and we can -consider each one properly without any extra work to disentangle them. - -Ideally, each change you send should be impossible to subdivide into -parts that we might want to consider separately, because each of its -parts gets its motivation from the other parts. - -@item -Send each change as soon as that change is finished. Sometimes people -think they are helping us by accumulating many changes to send them all -together. As explained above, this is absolutely the worst thing you -could do. - -Since you should send each change separately, you might as well send it -right away. That gives us the option of installing it immediately if it -is important. - -@item -Use @samp{diff -c} to make your diffs. Diffs without context are hard -for us to install reliably. More than that, they make it hard for us to -study the diffs to decide whether we want to install them. Unidiff -format is better than contextless diffs, but not as easy to read as -@samp{-c} format. - -If you have GNU @code{diff}, use @samp{diff -cp}, which shows the name of the -function that each change occurs in. -(The maintainer of GNU Fortran currently uses @samp{diff -rcp2N}.) - -@item -Write the change log entries for your changes. We get lots of changes, -and we don't have time to do all the change log writing ourselves. - -Read the @file{ChangeLog} file to see what sorts of information to put -in, and to learn the style that we use. The purpose of the change log -is to show people where to find what was changed. So you need to be -specific about what functions you changed; in large functions, it's -often helpful to indicate where within the function the change was. - -On the other hand, once you have shown people where to find the change, -you need not explain its purpose. Thus, if you add a new function, all -you need to say about it is that it is new. If you feel that the -purpose needs explaining, it probably does---but the explanation will be -much more useful if you put it in comments in the code. - -If you would like your name to appear in the header line for who made -the change, send us the header line. - -@item -When you write the fix, keep in mind that we can't install a change that -would break other systems. - -People often suggest fixing a problem by changing machine-independent -files such as @file{toplev.c} to do something special that a particular -system needs. Sometimes it is totally obvious that such changes would -break GNU Fortran for almost all users. We can't possibly make a change like -that. At best it might tell us how to write another patch that would -solve the problem acceptably. - -Sometimes people send fixes that @emph{might} be an improvement in -general---but it is hard to be sure of this. It's hard to install -such changes because we have to study them very carefully. Of course, -a good explanation of the reasoning by which you concluded the change -was correct can help convince us. - -The safest changes are changes to the configuration files for a -particular machine. These are safe because they can't create new bugs -on other machines. - -Please help us keep up with the workload by designing the patch in a -form that is good to install. -@end itemize - -@node Service -@chapter How To Get Help with GNU Fortran - -If you need help installing, using or changing GNU Fortran, there are two -ways to find it: - -@itemize @bullet -@item -Look in the service directory for someone who might help you for a fee. -The service directory is found in the file named @file{SERVICE} in the -GNU CC distribution. - -@item -Send a message to @email{@value{email-general}}. -@end itemize - -@end ifset -@ifset INTERNALS -@node Adding Options -@chapter Adding Options -@cindex options, adding -@cindex adding options - -To add a new command-line option to @code{g77}, first decide -what kind of option you wish to add. -Search the @code{g77} and @code{gcc} documentation for one -or more options that is most closely like the one you want to add -(in terms of what kind of effect it has, and so on) to -help clarify its nature. - -@itemize @bullet -@item -@emph{Fortran options} are options that apply only -when compiling Fortran programs. -They are accepted by @code{g77} and @code{gcc}, but -they apply only when compiling Fortran programs. - -@item -@emph{Compiler options} are options that apply -when compiling most any kind of program. -@end itemize - -@emph{Fortran options} are listed in the file -@file{@value{path-g77}/lang-options.h}, -which is used during the build of @code{gcc} to -build a list of all options that are accepted by -at least one language's compiler. -This list goes into the @samp{lang_options} array -in @file{gcc/toplev.c}, which uses this array to -determine whether a particular option should be -offered to the linked-in front end for processing -by calling @samp{lang_option_decode}, which, for -@code{g77}, is in @file{@value{path-g77}/com.c} and just -calls @samp{ffe_decode_option}. - -If the linked-in front end ``rejects'' a -particular option passed to it, @file{toplev.c} -just ignores the option, because @emph{some} -language's compiler is willing to accept it. - -This allows commands like @samp{gcc -fno-asm foo.c bar.f} -to work, even though Fortran compilation does -not currently support the @samp{-fno-asm} option; -even though the @code{f771} version of @samp{lang_decode_option} -rejects @samp{-fno-asm}, @file{toplev.c} doesn't -produce a diagnostic because some other language (C) -does accept it. - -This also means that commands like -@samp{g77 -fno-asm foo.f} yield no diagnostics, -despite the fact that no phase of the command was -able to recognize and process @samp{-fno-asm}---perhaps -a warning about this would be helpful if it were -possible. - -Code that processes Fortran options is found in -@file{@value{path-g77}/top.c}, function @samp{ffe_decode_option}. -This code needs to check positive and negative forms -of each option. - -The defaults for Fortran options are set in their -global definitions, also found in @file{@value{path-g77}/top.c}. -Many of these defaults are actually macros defined -in @file{@value{path-g77}/target.h}, since they might be -machine-specific. -However, since, in practice, GNU compilers -should behave the same way on all configurations -(especially when it comes to language constructs), -the practice of setting defaults in @file{target.h} -is likely to be deprecated and, ultimately, stopped -in future versions of @code{g77}. - -Accessor macros for Fortran options, used by code -in the @code{g77} FFE, are defined in @file{@value{path-g77}/top.h}. - -@emph{Compiler options} are listed in @file{gcc/toplev.c} -in the array @samp{f_options}. -An option not listed in @samp{lang_options} is -looked up in @samp{f_options} and handled from there. - -The defaults for compiler options are set in the -global definitions for the corresponding variables, -some of which are in @file{gcc/toplev.c}. - -You can set different defaults for @emph{Fortran-oriented} -or @emph{Fortran-reticent} compiler options by changing -the way @code{f771} handles the @samp{-fset-g77-defaults} -option, which is always provided as the first option when -called by @code{g77} or @code{gcc}. - -This code is in @samp{ffe_decode_options} in @file{@value{path-g77}/top.c}. -Have it change just the variables that you want to default -to a different setting for Fortran compiles compared to -compiles of other languages. - -The @samp{-fset-g77-defaults} option is passed to @code{f771} -automatically because of the specification information -kept in @file{@value{path-g77}/lang-specs.h}. -This file tells the @code{gcc} command how to recognize, -in this case, Fortran source files (those to be preprocessed, -and those that are not), and further, how to invoke the -appropriate programs (including @code{f771}) to process -those source files. - -It is in @file{@value{path-g77}/lang-specs.h} that @samp{-fset-g77-defaults}, -@samp{-fversion}, and other options are passed, as appropriate, -even when the user has not explicitly specified them. -Other ``internal'' options such as @samp{-quiet} also -are passed via this mechanism. - -@node Projects -@chapter Projects -@cindex projects - -If you want to contribute to @code{g77} by doing research, -design, specification, documentation, coding, or testing, -the following information should give you some ideas. -More relevant information might be available from -@uref{ftp://alpha.gnu.org/gnu/g77/projects/}. - -@menu -* Efficiency:: Make @code{g77} itself compile code faster. -* Better Optimization:: Teach @code{g77} to generate faster code. -* Simplify Porting:: Make @code{g77} easier to configure, build, - and install. -* More Extensions:: Features many users won't know to ask for. -* Machine Model:: @code{g77} should better leverage @code{gcc}. -* Internals Documentation:: Make maintenance easier. -* Internals Improvements:: Make internals more robust. -* Better Diagnostics:: Make using @code{g77} on new code easier. -@end menu - -@node Efficiency -@section Improve Efficiency -@cindex efficiency - -Don't bother doing any performance analysis until most of the -following items are taken care of, because there's no question -they represent serious space/time problems, although some of -them show up only given certain kinds of (popular) input. - -@itemize @bullet -@item -Improve @samp{malloc} package and its uses to specify more info about -memory pools and, where feasible, use obstacks to implement them. - -@item -Skip over uninitialized portions of aggregate areas (arrays, -@code{COMMON} areas, @code{EQUIVALENCE} areas) so zeros need not be output. -This would reduce memory usage for large initialized aggregate -areas, even ones with only one initialized element. - -As of version 0.5.18, a portion of this item has already been -accomplished. - -@item -Prescan the statement (in @file{sta.c}) so that the nature of the statement -is determined as much as possible by looking entirely at its form, -and not looking at any context (previous statements, including types -of symbols). -This would allow ripping out of the statement-confirmation, -symbol retraction/confirmation, and diagnostic inhibition -mechanisms. -Plus, it would result in much-improved diagnostics. -For example, @samp{CALL some-intrinsic(@dots{})}, where the intrinsic -is not a subroutine intrinsic, would result actual error instead of the -unimplemented-statement catch-all. - -@item -Throughout @code{g77}, don't pass line/column pairs where -a simple @samp{ffewhere} type, which points to the error as much as is -desired by the configuration, will do, and don't pass @samp{ffelexToken} types -where a simple @samp{ffewhere} type will do. -Then, allow new default -configuration of @samp{ffewhere} such that the source line text is not -preserved, and leave it to things like Emacs' next-error function -to point to them (now that @samp{next-error} supports column, -or, perhaps, character-offset, numbers). -The change in calling sequences should improve performance somewhat, -as should not having to save source lines. -(Whether this whole -item will improve performance is questionable, but it should -improve maintainability.) - -@item -Handle @samp{DATA (A(I),I=1,1000000)/1000000*2/} more efficiently, especially -as regards the assembly output. -Some of this might require improving -the back end, but lots of improvement in space/time required in @code{g77} -itself can be fairly easily obtained without touching the back end. -Maybe type-conversion, where necessary, can be speeded up as well in -cases like the one shown (converting the @samp{2} into @samp{2.}). - -@item -If analysis shows it to be worthwhile, optimize @file{lex.c}. - -@item -Consider redesigning @file{lex.c} to not need any feedback -during tokenization, by keeping track of enough parse state on its -own. -@end itemize - -@node Better Optimization -@section Better Optimization -@cindex optimization, better -@cindex code generation, improving - -Much of this work should be put off until after @code{g77} has -all the features necessary for its widespread acceptance as a -useful F77 compiler. -However, perhaps this work can be done in parallel during -the feature-adding work. - -@itemize @bullet -@item -Do the equivalent of the trick of putting @samp{extern inline} in front -of every function definition in @code{libg2c} and #include'ing the resulting -file in @code{f2c}+@code{gcc}---that is, inline all run-time-library functions -that are at all worth inlining. -(Some of this has already been done, such as for integral exponentiation.) - -@item -When doing @samp{CHAR_VAR = CHAR_FUNC(@dots{})}, -and it's clear that types line up -and @samp{CHAR_VAR} is addressable or not a @samp{VAR_DECL}, -make @samp{CHAR_VAR}, not a -temporary, be the receiver for @samp{CHAR_FUNC}. -(This is now done for @code{COMPLEX} variables.) - -@item -Design and implement Fortran-specific optimizations that don't -really belong in the back end, or where the front end needs to -give the back end more info than it currently does. - -@item -Design and implement a new run-time library interface, with the -code going into @code{libgcc} so no special linking is required to -link Fortran programs using standard language features. -This library -would speed up lots of things, from I/O (using precompiled formats, -doing just one, or, at most, very few, calls for arrays or array sections, -and so on) to general computing (array/section implementations of -various intrinsics, implementation of commonly performed loops that -aren't likely to be optimally compiled otherwise, etc.). - -Among the important things the library would do are: - -@itemize @bullet -@item -Be a one-stop-shop-type -library, hence shareable and usable by all, in that what are now -library-build-time options in @code{libg2c} would be moved at least to the -@code{g77} compile phase, if not to finer grains (such as choosing how -list-directed I/O formatting is done by default at @code{OPEN} time, for -preconnected units via options or even statements in the main program -unit, maybe even on a per-I/O basis with appropriate pragma-like -devices). -@end itemize - -@item -Probably requiring the new library design, change interface to -normally have @code{COMPLEX} functions return their values in the way -@code{gcc} would if they were declared @code{__complex__ float}, -rather than using -the mechanism currently used by @code{CHARACTER} functions (whereby the -functions are compiled as returning void and their first arg is -a pointer to where to store the result). -(Don't append underscores to -external names for @code{COMPLEX} functions in some cases once @code{g77} uses -@code{gcc} rather than @code{f2c} calling conventions.) - -@item -Do something useful with @samp{doiter} references where possible. -For example, @samp{CALL FOO(I)} cannot modify @samp{I} if within -a @code{DO} loop that uses @samp{I} as the -iteration variable, and the back end might find that info useful -in determining whether it needs to read @samp{I} back into a register after -the call. -(It normally has to do that, unless it knows @samp{FOO} never -modifies its passed-by-reference argument, which is rarely the case -for Fortran-77 code.) -@end itemize - -@node Simplify Porting -@section Simplify Porting -@cindex porting, simplify -@cindex simplify porting - -Making @code{g77} easier to configure, port, build, and install, either -as a single-system compiler or as a cross-compiler, would be -very useful. - -@itemize @bullet -@item -A new library (replacing @code{libg2c}) should improve portability as well as -produce more optimal code. -Further, @code{g77} and the new library should -conspire to simplify naming of externals, such as by removing unnecessarily -added underscores, and to reduce/eliminate the possibility of naming -conflicts, while making debugger more straightforward. - -Also, it should -make multi-language applications more feasible, such as by providing -Fortran intrinsics that get Fortran unit numbers given C @code{FILE *} -descriptors. - -@item -Possibly related to a new library, @code{g77} should produce the equivalent -of a @code{gcc} @samp{main(argc, argv)} function when it compiles a -main program unit, instead of compiling something that must be -called by a library -implementation of @code{main()}. - -This would do many useful things such as -provide more flexibility in terms of setting up exception handling, -not requiring programmers to start their debugging sessions with -@kbd{breakpoint MAIN__} followed by @kbd{run}, and so on. - -@item -The GBE needs to understand the difference between alignment -requirements and desires. -For example, on Intel x86 machines, @code{g77} currently imposes -overly strict alignment requirements, due to the back end, but it -would be useful for Fortran and C programmers to be able to override -these @emph{recommendations} as long as they don't violate the actual -processor @emph{requirements}. -@end itemize - -@node More Extensions -@section More Extensions -@cindex extensions, more - -These extensions are not the sort of things users ask for ``by name'', -but they might improve the usability of @code{g77}, and Fortran in -general, in the long run. -Some of these items really pertain to improving @code{g77} internals -so that some popular extensions can be more easily supported. - -@itemize @bullet -@item -Look through all the documentation on the GNU Fortran language, -dialects, compiler, missing features, bugs, and so on. -Many mentions of incomplete or missing features are -sprinkled throughout. -It is not worth repeating them here. - -@item -@cindex concatenation -@cindex CHARACTER*(*) -Support arbitrary operands for concatenation, even in contexts where -run-time allocation is required. - -@item -Consider adding a @code{NUMERIC} type to designate typeless numeric constants, -named and unnamed. -The idea is to provide a forward-looking, effective -replacement for things like the old-style @code{PARAMETER} statement -when people -really need typelessness in a maintainable, portable, clearly documented -way. -Maybe @code{TYPELESS} would include @code{CHARACTER}, @code{POINTER}, -and whatever else might come along. -(This is not really a call for polymorphism per se, just -an ability to express limited, syntactic polymorphism.) - -@item -Support @samp{OPEN(@dots{},KEY=(@dots{}),@dots{})}. - -@item -Support arbitrary file unit numbers, instead of limiting them -to 0 through @samp{MXUNIT-1}. -(This is a @code{libg2c} issue.) - -@item -@samp{OPEN(NOSPANBLOCKS,@dots{})} is treated as -@samp{OPEN(UNIT=NOSPANBLOCKS,@dots{})}, so a -later @code{UNIT=} in the first example is invalid. -Make sure this is what users of this feature would expect. - -@item -Currently @code{g77} disallows @samp{READ(1'10)} since -it is an obnoxious syntax, but -supporting it might be pretty easy if needed. -More details are needed, such -as whether general expressions separated by an apostrophe are supported, -or maybe the record number can be a general expression, and so on. - -@item -Support @code{STRUCTURE}, @code{UNION}, @code{MAP}, and @code{RECORD} -fully. -Currently there is no support at all -for @code{%FILL} in @code{STRUCTURE} and related syntax, -whereas the rest of the -stuff has at least some parsing support. -This requires either major -changes to @code{libg2c} or its replacement. - -@item -F90 and @code{g77} probably disagree about label scoping relative to -@code{INTERFACE} and @code{END INTERFACE}, and their contained -procedure interface bodies (blocks?). - -@item -@code{ENTRY} doesn't support F90 @code{RESULT()} yet, -since that was added after S8.112. - -@item -Empty-statement handling (10 ;;CONTINUE;;) probably isn't consistent -with the final form of the standard (it was vague at S8.112). - -@item -It seems to be an ``open'' question whether a file, immediately after being -@code{OPEN}ed,is positioned at the beginning, the end, or wherever---it -might be nice to offer an option of opening to ``undefined'' status, requiring -an explicit absolute-positioning operation to be performed before any -other (besides @code{CLOSE}) to assist in making applications port to systems -(some IBM?) that @code{OPEN} to the end of a file or some such thing. -@end itemize - -@node Machine Model -@section Machine Model - -This items pertain to generalizing @code{g77}'s view of -the machine model to more fully accept whatever the GBE -provides it via its configuration. - -@itemize @bullet -@item -Switch to using @samp{REAL_VALUE_TYPE} to represent floating-point constants -exclusively so the target float format need not be required. -This -means changing the way @code{g77} handles initialization of aggregate areas -having more than one type, such as @code{REAL} and @code{INTEGER}, -because currently -it initializes them as if they were arrays of @code{char} and uses the -bit patterns of the constants of the various types in them to determine -what to stuff in elements of the arrays. - -@item -Rely more and more on back-end info and capabilities, especially in the -area of constants (where having the @code{g77} front-end's IL just store -the appropriate tree nodes containing constants might be best). - -@item -Suite of C and Fortran programs that a user/administrator can run on a -machine to help determine the configuration for @code{g77} before building -and help determine if the compiler works (especially with whatever -libraries are installed) after building. -@end itemize - -@node Internals Documentation -@section Internals Documentation - -Better info on how @code{g77} works and how to port it is needed. -Much of this should be done only after the redesign planned for -0.6 is complete. - -@node Internals Improvements -@section Internals Improvements - -Some more items that would make @code{g77} more reliable -and easier to maintain: - -@itemize @bullet -@item -Generally make expression handling focus -more on critical syntax stuff, leaving semantics to callers. -For example, -anything a caller can check, semantically, let it do so, rather -than having @file{expr.c} do it. -(Exceptions might include things like -diagnosing @samp{FOO(I--K:)=BAR} where @samp{FOO} is a @code{PARAMETER}---if -it seems -important to preserve the left-to-right-in-source order of production -of diagnostics.) - -@item -Come up with better naming conventions for @samp{-D} to establish requirements -to achieve desired implementation dialect via @file{proj.h}. - -@item -Clean up used tokens and @samp{ffewhere}s in @samp{ffeglobal_terminate_1}. - -@item -Replace @file{sta.c} @samp{outpooldisp} mechanism with @samp{malloc_pool_use}. - -@item -Check for @samp{opANY} in more places in @file{com.c}, @file{std.c}, -and @file{ste.c}, and get rid of the @samp{opCONVERT(opANY)} kludge -(after determining if there is indeed no real need for it). - -@item -Utility to read and check @file{bad.def} messages and their references in the -code, to make sure calls are consistent with message templates. - -@item -Search and fix @samp{&ffe@dots{}} and similar so that -@samp{ffe@dots{}ptr@dots{}} macros are -available instead (a good argument for wishing this could have written all -this stuff in C++, perhaps). -On the other hand, it's questionable whether this sort of -improvement is really necessary, given the availability of -tools such as Emacs and Perl, which make finding any -address-taking of structure members easy enough? - -@item -Some modules truly export the member names of their structures (and the -structures themselves), maybe fix this, and fix other modules that just -appear to as well (by appending @samp{_}, though it'd be ugly and probably -not worth the time). - -@item -Implement C macros @samp{RETURNS(value)} and @samp{SETS(something,value)} -in @file{proj.h} -and use them throughout @code{g77} source code (especially in the definitions -of access macros in @samp{.h} files) so they can be tailored -to catch code writing into a @samp{RETURNS()} or reading from a @samp{SETS()}. - -@item -Decorate throughout with @code{const} and other such stuff. - -@item -All F90 notational derivations in the source code are still based -on the S8.112 version of the draft standard. -Probably should update -to the official standard, or put documentation of the rules as used -in the code@dots{}uh@dots{}in the code. - -@item -Some @samp{ffebld_new} calls (those outside of @file{ffeexpr.c} or -inside but invoked via paths not involving @samp{ffeexpr_lhs} or -@samp{ffeexpr_rhs}) might be creating things -in improper pools, leading to such things staying around too long or -(doubtful, but possible and dangerous) not long enough. - -@item -Some @samp{ffebld_list_new} (or whatever) calls might not be matched by -@samp{ffebld_list_bottom} (or whatever) calls, which might someday matter. -(It definitely is not a problem just yet.) - -@item -Probably not doing clean things when we fail to @code{EQUIVALENCE} something -due to alignment/mismatch or other problems---they end up without -@samp{ffestorag} objects, so maybe the backend (and other parts of the front -end) can notice that and handle like an @samp{opANY} (do what it wants, just -don't complain or crash). -Most of this seems to have been addressed -by now, but a code review wouldn't hurt. -@end itemize - -@node Better Diagnostics -@section Better Diagnostics - -These are things users might not ask about, or that need to -be looked into, before worrying about. -Also here are items that involve reducing unnecessary diagnostic -clutter. - -@itemize @bullet -@item -When @code{FUNCTION} and @code{ENTRY} point types disagree (@code{CHARACTER} -lengths, type classes, and so on), -@samp{ANY}-ize the offending @code{ENTRY} point and any @emph{new} dummies -it specifies. - -@item -Speed up and improve error handling for data when repeat-count is -specified. -For example, don't output 20 unnecessary messages after the -first necessary one for: - -@smallexample -INTEGER X(20) -CONTINUE -DATA (X(I), J= 1, 20) /20*5/ -END -@end smallexample - -@noindent -(The @code{CONTINUE} statement ensures the @code{DATA} statement -is processed in the context of executable, not specification, -statements.) -@end itemize -@end ifset - -@ifset USING -@node Diagnostics -@chapter Diagnostics -@cindex diagnostics - -Some diagnostics produced by @code{g77} require sufficient explanation -that the explanations are given below, and the diagnostics themselves -identify the appropriate explanation. - -Identification uses the GNU Info format---specifically, the @code{info} -command that displays the explanation is given within square -brackets in the diagnostic. -For example: - -@smallexample -foo.f:5: Invalid statement [info -f g77 M FOOEY] -@end smallexample - -More details about the above diagnostic is found in the @code{g77} Info -documentation, menu item @samp{M}, submenu item @samp{FOOEY}, -which is displayed by typing the UNIX command -@samp{info -f g77 M FOOEY}. - -Other Info readers, such as EMACS, may be just as easily used to display -the pertinent node. -In the above example, @samp{g77} is the Info document name, -@samp{M} is the top-level menu item to select, -and, in that node (named @samp{Diagnostics}, the name of -this chapter, which is the very text you're reading now), -@samp{FOOEY} is the menu item to select. - -@iftex -In this printed version of the @code{g77} manual, the above example -points to a section, below, entitled @samp{FOOEY}---though, of course, -as the above is just a sample, no such section exists. -@end iftex - -@menu -* CMPAMBIG:: Ambiguous use of intrinsic. -* EXPIMP:: Intrinsic used explicitly and implicitly. -* INTGLOB:: Intrinsic also used as name of global. -* LEX:: Various lexer messages -* GLOBALS:: Disagreements about globals. -* LINKFAIL:: When linking @samp{f771} fails. -@end menu - -@node CMPAMBIG -@section @code{CMPAMBIG} - -@noindent -@smallexample -Ambiguous use of intrinsic @var{intrinsic} @dots{} -@end smallexample - -The type of the argument to the invocation of the @var{intrinsic} -intrinsic is a @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}. -Typically, it is @code{COMPLEX(KIND=2)}, also known as -@code{DOUBLE COMPLEX}. - -The interpretation of this invocation depends on the particular -dialect of Fortran for which the code was written. -Some dialects convert the real part of the argument to -@code{REAL(KIND=1)}, thus losing precision; other dialects, -and Fortran 90, do no such conversion. - -So, GNU Fortran rejects such invocations except under certain -circumstances, to avoid making an incorrect assumption that results -in generating the wrong code. - -To determine the dialect of the program unit, perhaps even whether -that particular invocation is properly coded, determine how the -result of the intrinsic is used. - -The result of @var{intrinsic} is expected (by the original programmer) -to be @code{REAL(KIND=1)} (the non-Fortran-90 interpretation) if: - -@itemize @bullet -@item -It is passed as an argument to a procedure that explicitly or -implicitly declares that argument @code{REAL(KIND=1)}. - -For example, -a procedure with no @code{DOUBLE PRECISION} or @code{IMPLICIT DOUBLE PRECISION} -statement specifying the dummy argument corresponding to an -actual argument of @samp{REAL(Z)}, where @samp{Z} is declared -@code{DOUBLE COMPLEX}, strongly suggests that the programmer -expected @samp{REAL(Z)} to return @code{REAL(KIND=1)} instead -of @code{REAL(KIND=2)}. - -@item -It is used in a context that would otherwise not include -any @code{REAL(KIND=2)} but where treating the @var{intrinsic} -invocation as @code{REAL(KIND=2)} would result in unnecessary -promotions and (typically) more expensive operations on the -wider type. - -For example: - -@smallexample -DOUBLE COMPLEX Z -@dots{} -R(1) = T * REAL(Z) -@end smallexample - -The above example suggests the programmer expected the real part -of @samp{Z} to be converted to @code{REAL(KIND=1)} before being -multiplied by @samp{T} (presumed, along with @samp{R} above, to -be type @code{REAL(KIND=1)}). - -Otherwise, the conversion would have to be delayed until after -the multiplication, requiring not only an extra conversion -(of @samp{T} to @code{REAL(KIND=2)}), but a (typically) more -expensive multiplication (a double-precision multiplication instead -of a single-precision one). -@end itemize - -The result of @var{intrinsic} is expected (by the original programmer) -to be @code{REAL(KIND=2)} (the Fortran 90 interpretation) if: - -@itemize @bullet -@item -It is passed as an argument to a procedure that explicitly or -implicitly declares that argument @code{REAL(KIND=2)}. - -For example, a procedure specifying a @code{DOUBLE PRECISION} -dummy argument corresponding to an -actual argument of @samp{REAL(Z)}, where @samp{Z} is declared -@code{DOUBLE COMPLEX}, strongly suggests that the programmer -expected @samp{REAL(Z)} to return @code{REAL(KIND=2)} instead -of @code{REAL(KIND=1)}. - -@item -It is used in an expression context that includes -other @code{REAL(KIND=2)} operands, -or is assigned to a @code{REAL(KIND=2)} variable or array element. - -For example: - -@smallexample -DOUBLE COMPLEX Z -DOUBLE PRECISION R, T -@dots{} -R(1) = T * REAL(Z) -@end smallexample - -The above example suggests the programmer expected the real part -of @samp{Z} to @emph{not} be converted to @code{REAL(KIND=1)} -by the @code{REAL()} intrinsic. - -Otherwise, the conversion would have to be immediately followed -by a conversion back to @code{REAL(KIND=2)}, losing -the original, full precision of the real part of @code{Z}, -before being multiplied by @samp{T}. -@end itemize - -Once you have determined whether a particular invocation of @var{intrinsic} -expects the Fortran 90 interpretation, you can: - -@itemize @bullet -@item -Change it to @samp{DBLE(@var{expr})} (if @var{intrinsic} is -@samp{REAL}) or @samp{DIMAG(@var{expr})} (if @var{intrinsic} -is @samp{AIMAG}) -if it expected the Fortran 90 interpretation. - -This assumes @var{expr} is @code{COMPLEX(KIND=2)}---if it is -some other type, such as @code{COMPLEX*32}, you should use the -appropriate intrinsic, such as the one to convert to @code{REAL*16} -(perhaps @code{DBLEQ()} in place of @code{DBLE()}, and -@code{QIMAG()} in place of @code{DIMAG()}). - -@item -Change it to @samp{REAL(@var{intrinsic}(@var{expr}))}, -otherwise. -This converts to @code{REAL(KIND=1)} in all working -Fortran compilers. -@end itemize - -If you don't want to change the code, and you are certain that all -ambiguous invocations of @var{intrinsic} in the source file have -the same expectation regarding interpretation, you can: - -@itemize @bullet -@item -Compile with the @code{g77} option @samp{-ff90}, to enable the -Fortran 90 interpretation. - -@item -Compile with the @code{g77} options @samp{-fno-f90 -fugly-complex}, -to enable the non-Fortran-90 interpretations. -@end itemize - -@xref{REAL() and AIMAG() of Complex}, for more information on this -issue. - -Note: If the above suggestions don't produce enough evidence -as to whether a particular program expects the Fortran 90 -interpretation of this ambiguous invocation of @var{intrinsic}, -there is one more thing you can try. - -If you have access to most or all the compilers used on the -program to create successfully tested and deployed executables, -read the documentation for, and @emph{also} test out, each compiler -to determine how it treats the @var{intrinsic} intrinsic in -this case. -(If all the compilers don't agree on an interpretation, there -might be lurking bugs in the deployed versions of the program.) - -The following sample program might help: - -@cindex JCB003 program -@smallexample - PROGRAM JCB003 -C -C Written by James Craig Burley 1997-02-23. -C Contact via Internet email: burley@@gnu.org -C -C Determine how compilers handle non-standard REAL -C and AIMAG on DOUBLE COMPLEX operands. -C - DOUBLE COMPLEX Z - REAL R - Z = (3.3D0, 4.4D0) - R = Z - CALL DUMDUM(Z, R) - R = REAL(Z) - R - IF (R .NE. 0.) PRINT *, 'REAL() is Fortran 90' - IF (R .EQ. 0.) PRINT *, 'REAL() is not Fortran 90' - R = 4.4D0 - CALL DUMDUM(Z, R) - R = AIMAG(Z) - R - IF (R .NE. 0.) PRINT *, 'AIMAG() is Fortran 90' - IF (R .EQ. 0.) PRINT *, 'AIMAG() is not Fortran 90' - END -C -C Just to make sure compiler doesn't use naive flow -C analysis to optimize away careful work above, -C which might invalidate results.... -C - SUBROUTINE DUMDUM(Z, R) - DOUBLE COMPLEX Z - REAL R - END -@end smallexample - -If the above program prints contradictory results on a -particular compiler, run away! - -@node EXPIMP -@section @code{EXPIMP} - -@noindent -@smallexample -Intrinsic @var{intrinsic} referenced @dots{} -@end smallexample - -The @var{intrinsic} is explicitly declared in one program -unit in the source file and implicitly used as an intrinsic -in another program unit in the same source file. - -This diagnostic is designed to catch cases where a program -might depend on using the name @var{intrinsic} as an intrinsic -in one program unit and as a global name (such as the name -of a subroutine or function) in another, but @code{g77} recognizes -the name as an intrinsic in both cases. - -After verifying that the program unit making implicit use -of the intrinsic is indeed written expecting the intrinsic, -add an @samp{INTRINSIC @var{intrinsic}} statement to that -program unit to prevent this warning. - -This and related warnings are disabled by using -the @samp{-Wno-globals} option when compiling. - -Note that this warning is not issued for standard intrinsics. -Standard intrinsics include those described in the FORTRAN 77 -standard and, if @samp{-ff90} is specified, those described -in the Fortran 90 standard. -Such intrinsics are not as likely to be confused with user -procedures as intrinsics provided as extensions to the -standard by @code{g77}. - -@node INTGLOB -@section @code{INTGLOB} - -@noindent -@smallexample -Same name `@var{intrinsic}' given @dots{} -@end smallexample - -The name @var{intrinsic} is used for a global entity (a common -block or a program unit) in one program unit and implicitly -used as an intrinsic in another program unit. - -This diagnostic is designed to catch cases where a program -intends to use a name entirely as a global name, but @code{g77} -recognizes the name as an intrinsic in the program unit that -references the name, a situation that would likely produce -incorrect code. - -For example: - -@smallexample -INTEGER FUNCTION TIME() -@dots{} -END -@dots{} -PROGRAM SAMP -INTEGER TIME -PRINT *, 'Time is ', TIME() -END -@end smallexample - -The above example defines a program unit named @samp{TIME}, but -the reference to @samp{TIME} in the main program unit @samp{SAMP} -is normally treated by @code{g77} as a reference to the intrinsic -@code{TIME()} (unless a command-line option that prevents such -treatment has been specified). - -As a result, the program @samp{SAMP} will @emph{not} -invoke the @samp{TIME} function in the same source file. - -Since @code{g77} recognizes @code{libU77} procedures as -intrinsics, and since some existing code uses the same names -for its own procedures as used by some @code{libU77} -procedures, this situation is expected to arise often enough -to make this sort of warning worth issuing. - -After verifying that the program unit making implicit use -of the intrinsic is indeed written expecting the intrinsic, -add an @samp{INTRINSIC @var{intrinsic}} statement to that -program unit to prevent this warning. - -Or, if you believe the program unit is designed to invoke the -program-defined procedure instead of the intrinsic (as -recognized by @code{g77}), add an @samp{EXTERNAL @var{intrinsic}} -statement to the program unit that references the name to -prevent this warning. - -This and related warnings are disabled by using -the @samp{-Wno-globals} option when compiling. - -Note that this warning is not issued for standard intrinsics. -Standard intrinsics include those described in the FORTRAN 77 -standard and, if @samp{-ff90} is specified, those described -in the Fortran 90 standard. -Such intrinsics are not as likely to be confused with user -procedures as intrinsics provided as extensions to the -standard by @code{g77}. - -@node LEX -@section @code{LEX} - -@noindent -@smallexample -Unrecognized character @dots{} -Invalid first character @dots{} -Line too long @dots{} -Non-numeric character @dots{} -Continuation indicator @dots{} -Label at @dots{} invalid with continuation line indicator @dots{} -Character constant @dots{} -Continuation line @dots{} -Statement at @dots{} begins with invalid token -@end smallexample - -Although the diagnostics identify specific problems, they can -be produced when general problems such as the following occur: - -@itemize @bullet -@item -The source file contains something other than Fortran code. - -If the code in the file does not look like many of the examples -elsewhere in this document, it might not be Fortran code. -(Note that Fortran code often is written in lower case letters, -while the examples in this document use upper case letters, -for stylistic reasons.) - -For example, if the file contains lots of strange-looking -characters, it might be APL source code; if it contains lots -of parentheses, it might be Lisp source code; if it -contains lots of bugs, it might be C++ source code. - -@item -The source file contains free-form Fortran code, but @samp{-ffree-form} -was not specified on the command line to compile it. - -Free form is a newer form for Fortran code. -The older, classic form is called fixed form. - -Fixed-form code is visually fairly distinctive, because -numerical labels and comments are all that appear in -the first five columns of a line, the sixth column is -reserved to denote continuation lines, -and actual statements start at or beyond column 7. -Spaces generally are not significant, so if you -see statements such as @samp{REALX,Y} and @samp{DO10I=1,100}, -you are looking at fixed-form code. -Comment lines are indicated by the letter @samp{C} or the symbol -@samp{*} in column 1. -(Some code uses @samp{!} or @samp{/*} to begin in-line comments, -which many compilers support.) - -Free-form code is distinguished from fixed-form source -primarily by the fact that statements may start anywhere. -(If lots of statements start in columns 1 through 6, -that's a strong indicator of free-form source.) -Consecutive keywords must be separated by spaces, so -@samp{REALX,Y} is not valid, while @samp{REAL X,Y} is. -There are no comment lines per se, but @samp{!} starts a -comment anywhere in a line (other than within a character or -Hollerith constant). - -@xref{Source Form}, for more information. - -@item -The source file is in fixed form and has been edited without -sensitivity to the column requirements. - -Statements in fixed-form code must be entirely contained within -columns 7 through 72 on a given line. -Starting them ``early'' is more likely to result in diagnostics -than finishing them ``late'', though both kinds of errors are -often caught at compile time. - -For example, if the following code fragment is edited by following -the commented instructions literally, the result, shown afterward, -would produce a diagnostic when compiled: - -@smallexample -C On XYZZY systems, remove "C" on next line: -C CALL XYZZY_RESET -@end smallexample - -The result of editing the above line might be: - -@smallexample -C On XYZZY systems, remove "C" on next line: - CALL XYZZY_RESET -@end smallexample - -However, that leaves the first @samp{C} in the @samp{CALL} -statement in column 6, making it a comment line, which is -not really what the author intended, and which is likely -to result in one of the above-listed diagnostics. - -@emph{Replacing} the @samp{C} in column 1 with a space -is the proper change to make, to ensure the @samp{CALL} -keyword starts in or after column 7. - -Another common mistake like this is to forget that fixed-form -source lines are significant through only column 72, and that, -normally, any text beyond column 72 is ignored or is diagnosed -at compile time. - -@xref{Source Form}, for more information. - -@item -The source file requires preprocessing, and the preprocessing -is not being specified at compile time. - -A source file containing lines beginning with @code{#define}, -@code{#include}, @code{#if}, and so on is likely one that -requires preprocessing. - -If the file's suffix is @samp{.f} or @samp{.for}, the file -will normally be compiled @emph{without} preprocessing by @code{g77}. - -Change the file's suffix from @samp{.f} to @samp{.F} (or, on -systems with case-insensitive file names, to @samp{.fpp}) or -from @samp{.for} to @samp{.fpp}. -@code{g77} compiles files with such names @emph{with} -preprocessing. - -@pindex cpp -@cindex preprocessor -@cindex cpp program -@cindex programs, cpp -@cindex @samp{-x f77-cpp-input} option -@cindex options, @samp{-x f77-cpp-input} -Or, learn how to use @code{gcc}'s @samp{-x} option to specify -the language @samp{f77-cpp-input} for Fortran files that -require preprocessing. -@xref{Overall Options,,gcc,Using and Porting GNU CC}. - -@item -The source file is preprocessed, and the results of preprocessing -result in syntactic errors that are not necessarily obvious to -someone examining the source file itself. - -Examples of errors resulting from preprocessor macro expansion -include exceeding the line-length limit, improperly starting, -terminating, or incorporating the apostrophe or double-quote in -a character constant, improperly forming a Hollerith constant, -and so on. - -@xref{Overall Options,,Options Controlling the Kind of Output}, -for suggestions about how to use, and not use, preprocessing -for Fortran code. -@end itemize - -@node GLOBALS -@section @code{GLOBALS} - -@noindent -@smallexample -Global name @var{name} defined at @dots{} already defined@dots{} -Global name @var{name} at @dots{} has different type@dots{} -Too many arguments passed to @var{name} at @dots{} -Too few arguments passed to @var{name} at @dots{} -Argument #@var{n} of @var{name} is @dots{} -@end smallexample - -These messages all identify disagreements about the -global procedure named @var{name} among different program -units (usually including @var{name} itself). - -These disagreements, if not diagnosed, could result in a -compiler crash if the compiler attempted to inline a reference -to @var{name} within a calling program unit that disagreed -with the @var{name} program unit regarding whether the -procedure is a subroutine or function, the type of the -return value of the procedure (if it is a function), the -number of arguments the procedure accepts, or the type -of each argument. - -Such disagreements @emph{should} be fixed in the Fortran -code itself. -However, if that is not immediately practical, and the code -has been working for some time, it is possible it will work -when compiled by @code{g77} with the @samp{-fno-globals} option. - -The @samp{-fno-globals} option disables these diagnostics, and -also disables all inlining of references to global procedures -to avoid compiler crashes. -The diagnostics are actually produced, but as warnings, unless -the @samp{-Wno-globals} option also is specified. - -After using @samp{-fno-globals} to work around these problems, -it is wise to stop using that option and address them by fixing -the Fortran code, because such problems, while they might not -actually result in bugs on some systems, indicate that the code -is not as portable as it could be. -In particular, the code might appear to work on a particular -system, but have bugs that affect the reliability of the data -without exhibiting any other outward manifestations of the bugs. - -@node LINKFAIL -@section @code{LINKFAIL} - -@noindent -@smallexample -If the above command failed due to an unresolved reference -to strtoul, _strtoul, bsearch, _bsearch, or similar, see -[info -f g77 M LINKFAIL] (a node in the g77 documentation) -for information on what causes this, how to work around -the problem by editing $@{srcdir@}/proj.c, and what else to do. -@end smallexample - -@xref{Missing strtoul or bsearch}, for more information on -this problem, -which occurs only in releases of @code{g77} -based on @code{gcc}. -(It does not occur in @code{egcs}.) - -On AIX 4.1, @code{g77} might not build with the native (non-GNU) tools -due to a linker bug in coping with the @samp{-bbigtoc} option which -leads to a @samp{Relocation overflow} error. The GNU linker is not -recommended on current AIX versions, though; it was developed under a -now-unsupported version. This bug is said to be fixed by `update PTF -U455193 for APAR IX75823'. - -Compiling with @samp{-mminimal-toc} -might solve this problem, e.g.@: by adding -@smallexample -BOOT_CFLAGS='-mminimal-toc -O2 -g' -@end smallexample -to the @code{make bootstrap} command line. -@end ifset - -@node Index -@unnumbered Index - -@printindex cp -@summarycontents -@contents -@bye diff --git a/gcc/f/g77install.texi b/gcc/f/g77install.texi deleted file mode 100755 index 7041107..0000000 --- a/gcc/f/g77install.texi +++ /dev/null @@ -1,2170 +0,0 @@ -@c Copyright (C) 1995-1997 Free Software Foundation, Inc. -@c This is part of the G77 manual. -@c For copying conditions, see the file g77.texi. - -@c The text of this file appears in the file INSTALL -@c in the G77 distribution, as well as in the G77 manual. - -@c 1998-07-13 - -@set version-g77 0.5.24 -@set version-gcc 2.8.1 -@set version-autoconf 2.12 -@set version-bison 1.25 -@set version-gperf 2.5 -@set version-gzip 1.2.4 -@set version-make 3.76.1 -@set version-makeinfo 1.68 -@set version-patch 2.5 -@set version-sed 2.05 -@set version-tar 1.12 -@set version-texinfo 3.12 - -@ifclear INSTALLONLY -@node Installation -@chapter Installing GNU Fortran -@end ifclear -@cindex installing GNU Fortran - -The following information describes how to install @code{g77}. - -Note that, for @code{egcs} users, -much of this information is obsolete, -and is superceded by the -@code{egcs} installation procedures. -Such information is explicitly flagged as such. - -The information in this file generally pertains to dealing -with @emph{source} distributions of @code{g77} and @code{gcc}. -It is possible that some of this information will be applicable -to some @emph{binary} distributions of these products---however, -since these distributions are not made by the maintainers of -@code{g77}, responsibility for binary distributions rests with -whoever built and first distributed them. - -Nevertheless, efforts to make @code{g77} easier to both build -and install from source and package up as a binary distribution -are ongoing. - -@menu -* Prerequisites:: Make sure your system is ready for @code{g77}. -* Problems Installing:: Known trouble areas. -* Settings:: Changing @code{g77} internals before building. -* Quick Start:: The easier procedure for non-experts. -* Complete Installation:: For experts, or those who want to be: the details. -* Distributing Binaries:: If you plan on distributing your @code{g77}. -@end menu - -@node Prerequisites -@section Prerequisites -@cindex prerequisites - -@emph{Version info:} -For @code{egcs} users, the following information is -superceded by the @code{egcs} installation instructions. - -The procedures described to unpack, configure, build, and -install @code{g77} assume your system has certain programs -already installed. - -The following prerequisites should be met by your -system before you follow the @code{g77} installation instructions: - -@table @asis -@item @code{gzip} and @code{tar} -To unpack the @code{gcc} and @code{g77} distributions, -you'll need the @code{gunzip} utility in the @code{gzip} -distribution. -Most UNIX systems already have @code{gzip} installed. -If yours doesn't, you can get it from the FSF. - -Note that you'll need @code{tar} and other utilities -as well, but all UNIX systems have these. -There are GNU versions of all these available---in fact, -a complete GNU UNIX system can be put together on -most systems, if desired. - -The version of GNU @code{gzip} used to package this release -is @value{version-gzip}. -(The version of GNU @code{tar} used to package this release -is @value{version-tar}.) - -@item @file{gcc-@value{version-gcc}.tar.gz} -You need to have this, or some other applicable, version -of @code{gcc} on your system. -The version should be an exact copy of a distribution -from the FSF. -Its size is approximately 8.4MB. - -If you've already unpacked @file{gcc-@value{version-gcc}.tar.gz} into a -directory (named @file{gcc-@value{version-gcc}}) called the @dfn{source tree} -for @code{gcc}, you can delete the distribution -itself, but you'll need to remember to skip any instructions to unpack -this distribution. - -Without an applicable @code{gcc} source tree, you cannot -build @code{g77}. -You can obtain an FSF distribution of @code{gcc} from the FSF. - -@item @file{g77-@value{version-g77}.tar.gz} -You probably have already unpacked this package, -or you are reading an advance copy of these installation instructions, -which are contained in this distribution. -The size of this package is approximately 1.4MB. - -You can obtain an FSF distribution of @code{g77} from the FSF, -the same way you obtained @code{gcc}. - -@item Enough disk space -The amount of disk space needed to unpack, build, install, -and use @code{g77} depends on the type of system you're -using, how you build @code{g77}, and how much of it you -install (primarily, which languages you install). - -The sizes shown below assume all languages distributed in -@c As of `Version 2.249', texinfo.tex loses on a construction like -@c @code{...@value{...-...}...} since the hyphen is expanded as -@c -@discretionary{}{}{}, even though @value resets its catcode. -@c Fortunately this is currently the only instance. Kluge, kluge. -@iftex -@begingroup @let@codedash=@realdash -@end iftex -@code{gcc-@value{version-gcc}}, -@iftex -@endgroup -@end iftex -plus @code{g77}, will be built and installed. -These sizes are indicative of GNU/Linux systems on -Intel x86 running COFF and on Digital Alpha (AXP) systems -running ELF. -These should be fairly representative of 32-bit and 64-bit -systems, respectively. - -Note that all sizes are approximate and subject to change without -notice! -They are based on preliminary releases of g77 made shortly -before the public beta release. - -@itemize --- -@item -@code{gcc} and @code{g77} distributions occupy 10MB -packed, 40MB unpacked. -These consist of the source code and documentation, -plus some derived files (mostly documentation), for -@code{gcc} and @code{g77}. -Any deviations from these numbers for different -kinds of systems are likely to be very minor. - -@item -A ``bootstrap'' build requires an additional 91MB -for a total of 132MB on an ix86, and an additional -136MB for a total of 177MB on an Alpha. - -@item -Removing @file{gcc/stage1} after the build recovers -13MB for a total of 119MB on an ix86, and recovers -21MB for a total of 155MB on an Alpha. - -After doing this, the integrity of the build can -still be verified via @samp{make compare}, and the -@code{gcc} compiler modified and used to build itself for -testing fairly quickly, using the copy of the compiler -kept in @code{gcc/stage2}. - -@item -Removing @file{gcc/stage2} after the build further -recovers 39MB for a total of 80MB, and recovers -57MB for a total of 98MB on an Alpha. - -After doing this, the compiler can still be installed, -especially if GNU @code{make} is used to avoid -gratuitous rebuilds (or, the installation can be done -by hand). - -@item -Installing @code{gcc} and @code{g77} copies -23MB onto the @samp{--prefix} disk for a total of 103MB -on an ix86, and copies 31MB onto the @samp{--prefix} -disk for a total of 130MB on an Alpha. -@end itemize - -After installation, if no further modifications and -builds of @code{gcc} or @code{g77} are planned, the -source and build directory may be removed, leaving -the total impact on a system's disk storage as -that of the amount copied during installation. - -Systems with the appropriate version of @code{gcc} -installed don't require the complete -bootstrap build. -Doing a ``straight build'' requires about as much -space as does a bootstrap build followed by removing -both the @file{gcc/stage1} and @file{gcc/stage2} -directories. - -Installing @code{gcc} and @code{g77} over existing -versions might require less @emph{new} disk space, -but note that, unlike many products, @code{gcc} -installs itself in a way that avoids overwriting other -installed versions of itself, so that other versions may -easily be invoked (via @samp{gcc -V @var{version}}). - -So, the amount of space saved as a result of having -an existing version of @code{gcc} and @code{g77} -already installed is not much---typically only the -command drivers (@code{gcc}, @code{g77}, @code{g++}, -and so on, which are small) and the documentation -is overwritten by the new installation. -The rest of the new installation is done without -replacing existing installed versions (assuming -they have different version numbers). - -@item @code{make} -Your system must have @code{make}, and you will probably save -yourself a lot of trouble if it is GNU @code{make} (sometimes -referred to as @code{gmake}). -In particular, you probably need GNU @code{make} -to build outside the source directory -(with @code{configure}'s @samp{--srcdir} option.) - -The version of GNU @code{make} used to develop this release -is @value{version-make}. - -@item @code{cc} -Your system must have a working C compiler. -If it doesn't, you might be able to obtain -a prebuilt binary of some version of @code{gcc} -from the network or on CD-ROM, -perhaps from the FSF@. -The best source of information about binaries -is probably a system-specific Usenet news group, -initially via its FAQ. - -@xref{Installation,,Installing GNU CC,gcc,Using and Porting GNU CC}, -for more information on prerequisites for installing @code{gcc}. - -@item @code{sed} -All UNIX systems have @code{sed}, but some have a broken -version that cannot handle configuring, building, or -installing @code{gcc} or @code{g77}. - -The version of GNU @code{sed} used to develop this release -is @value{version-sed}. -(Note that GNU @code{sed} version 3.0 was withdrawn by the -FSF---if you happen to have this version installed, replace -it with version @value{version-sed} immediately. -See a GNU distribution site for further explanation.) - -@item @code{root} access or equivalent -To perform the complete installation procedures on a system, -you need to have @code{root} access to that system, or -equivalent access to the @samp{--prefix} directory tree -specified on the @code{configure} command line. - -Portions of the procedure (such as configuring and building -@code{g77}) can be performed by any user with enough disk -space and virtual memory. - -However, these instructions are oriented towards less-experienced -users who want to install @code{g77} on their own personal -systems. - -System administrators with more experience will want to -determine for themselves how they want to modify the -procedures described below to suit the needs of their -installation. - -@item @code{autoconf} -The version of GNU @code{autoconf} used to develop this release -is @value{version-autoconf}. - -@code{autoconf} is not needed in the typical case of -installing @code{gcc} and @code{g77}. -@xref{Missing tools?}, for information on when it -might be needed and how to work around not having it. - -@item @code{bison} -The version of GNU @code{bison} used to develop this release -is @value{version-bison}. - -@code{bison} is not needed in the typical case of -installing @code{gcc} and @code{g77}. -@xref{Missing tools?}, for information on when it -might be needed and how to work around not having it. - -@item @code{gperf} -The version of GNU @code{gperf} used to develop this release -is @value{version-gperf}. - -@code{gperf} is not needed in the typical case of -installing @code{gcc} and @code{g77}. -@xref{Missing tools?}, for information on when it -might be needed and how to work around not having it. - -@item @code{makeinfo} -The version of GNU @code{makeinfo} used to develop this release -is @value{version-makeinfo}. - -@code{makeinfo} is part of the GNU @code{texinfo} package; -@code{makeinfo} version @value{version-makeinfo} -is distributed as part of -GNU @code{texinfo} version @value{version-texinfo}. - -@code{makeinfo} is not needed in the typical case of -installing @code{gcc} and @code{g77}. -@xref{Missing tools?}, for information on when it -might be needed and how to work around not having it. - -An up-to-date version of GNU @code{makeinfo} is still convenient -when obtaining a new version of a GNU distribution such as -@code{gcc} or @code{g77}, -as it allows you to obtain the @file{.diff.gz} file -instead of the entire @file{.tar.gz} distribution -(assuming you have installed @code{patch}). - -@item @code{patch} -The version of GNU @code{patch} used to develop this release -is @value{version-patch}. - -Beginning with @code{g77} version 0.5.23, it is no longer -necessary to patch the @code{gcc} back end to build @code{g77}. - -An up-to-date version of GNU @code{patch} is still convenient -when obtaining a new version of a GNU distribution such as -@code{gcc} or @code{g77}, -as it allows you to obtain the @file{.diff.gz} file -instead of the entire @file{.tar.gz} distribution -(assuming you have installed the tools needed -to rebuild derived files, such as @code{makeinfo}). -@end table - -@node Problems Installing -@section Problems Installing -@cindex problems installing -@cindex installation problems - -This is a list of problems (and some apparent problems which don't -really mean anything is wrong) that show up when configuring, -building, installing, or porting GNU Fortran. - -@xref{Installation Problems,,,gcc,Using and Porting GNU CC}, -for more information on installation problems that can afflict -either @code{gcc} or @code{g77}. - -@menu -* General Problems:: Problems afflicting most or all systems. -* System-specific Problems:: Problems afflicting particular systems. -* Cross-compiler Problems:: Problems afflicting cross-compilation setups. -@end menu - -@node General Problems -@subsection General Problems - -These problems can occur on most or all systems. - -@menu -* GNU C Required:: Why even ANSI C is not enough. -* Patching GNU CC:: Why @code{gcc} needn't be patched. -* Building GNU CC Necessary:: Why you can't build @emph{just} Fortran. -* Missing strtoul or bsearch:: When linking @samp{f771} fails. -* Cleanup Kills Stage Directories:: For @code{g77} developers. -* LANGUAGES Macro Ignored:: Sometimes @samp{LANGUAGES} is ignored. -@end menu - -@node GNU C Required -@subsubsection GNU C Required -@cindex GNU C required -@cindex requirements, GNU C - -Compiling @code{g77} requires GNU C, not just ANSI C. -Fixing this wouldn't -be very hard (just tedious), but the code using GNU extensions to -the C language is expected to be rewritten for 0.6 anyway, -so there are no plans for an interim fix. - -This requirement does not mean you must already have @code{gcc} -installed to build @code{g77}. -As long as you have a working C compiler, you can use a -bootstrap build to automate the process of first building -@code{gcc} using the working C compiler you have, then building -@code{g77} and rebuilding @code{gcc} using that just-built @code{gcc}, -and so on. - -@node Patching GNU CC -@subsubsection Patching GNU CC -@cindex patch files -@cindex GBE - -@code{g77} no longer requires application of a patch file -to the @code{gcc} compiler tree. -In fact, no such patch file is distributed with @code{g77}. -This is as of version 0.5.23 -and @code{egcs} version 1.0. - -@node Building GNU CC Necessary -@subsubsection Building GNU CC Necessary -@cindex gcc, building -@cindex building gcc - -It should be possible to build the runtime without building @code{cc1} -and other non-Fortran items, but, for now, an easy way to do that -is not yet established. - -@node Missing strtoul or bsearch -@subsubsection Missing strtoul or bsearch -@cindex bsearch -@cindex _bsearch -@cindex strtoul -@cindex _strtoul -@cindex undefined reference (_bsearch) -@cindex undefined reference (_strtoul) -@cindex f771, linking error for -@cindex linking error for f771 -@cindex ld error for f771 -@cindex ld can't find _bsearch -@cindex ld can't find _strtoul -@cindex SunOS4 - -@emph{Version info:} -The following information does not apply to the -@code{egcs} version of @code{g77}. - -On SunOS4 systems, linking the @code{f771} program used to -produce an error message concerning an undefined symbol named -@samp{_strtoul}, because the @samp{strtoul} library function -is not provided on that system. - -Other systems have, in the past, been reported to not provide -their own @samp{strtoul} or @samp{bsearch} function. - -Some versions @code{g77} tried to default to providing bare-bones -versions of @code{bsearch} and @code{strtoul} automatically, -but every attempt at this has failed for at least one kind of system. - -To limit the failures to those few systems actually missing the -required routines, the bare-bones versions are still provided, -in @file{gcc/f/proj.c}, -if the appropriate macros are defined. -These are @code{NEED_BSEARCH} for @samp{bsearch} and -@code{NEED_STRTOUL} for @samp{NEED_STRTOUL}. - -Therefore, if you are sure your system is missing -@code{bsearch} or @code{strtoul} in its library, -define the relevant macro(s) before building @code{g77}. -This can be done by editing @file{gcc/f/proj.c} and inserting -either or both of the following @samp{#define} statements -before the comment shown: - -@smallexample -/* Insert #define statements here. */ - -#define NEED_BSEARCH -#define NEED_STRTOUL -@end smallexample - -Then, continue configuring and building @code{g77} as usual. - -Or, you can define these on the @code{make} command line. -To build with the bundled @code{cc} on SunOS4, for example, try: -@smallexample -make bootstrap BOOT_CFLAGS='-O2 -g -DNEED_STRTOUL' -@end smallexample - -If you then encounter problems compiling @file{gcc/f/proj.c}, -it might be due to a discrepancy between how @samp{bsearch} -or @samp{strtoul} are defined by that file and how they're -declared by your system's header files. - -In that case, you'll have to use some basic knowledge of C -to work around the problem, perhaps by editing @file{gcc/f/proj.c} -somewhat. - -@node Cleanup Kills Stage Directories -@subsubsection Cleanup Kills Stage Directories -@cindex stage directories -@cindex make clean - -It'd be helpful if @code{g77}'s @file{Makefile.in} or @file{Make-lang.in} -would create the various @file{stage@var{n}} directories and their -subdirectories, so developers and expert installers wouldn't have to -reconfigure after cleaning up. - -That help has arrived as of version 0.5.23 of @code{g77} -and version 1.1 of @code{egcs}. -Configuration itself no longer creates any particular directories -that are unique to @code{g77}. -The build procedures in @file{Make-lang.in} take care of -that, on demand. - -@node LANGUAGES Macro Ignored -@subsubsection LANGUAGES Macro Ignored -@cindex @samp{LANGUAGES} macro ignored -@cindex ignoring @samp{LANGUAGES} macro - -Prior to version 0.5.23 of @code{g77} -and version 1.1 of @code{egcs}, -@code{g77} would sometimes ignore -the absence of @samp{f77} and @samp{F77} in the -@samp{LANGUAGES} macro definition used for the -@code{make} command being processed. - -As of @code{g77} version 0.5.23 -and @code{egcs} version 1.1, -@code{g77} now obeys this macro -in all relevant situations. - -However, in versions of @code{gcc} through 2.8.1, -non-@code{g77} portions of @code{gcc}, -such as @code{g++}, -are known to go ahead and perform various -language-specific activities when their -respective language strings do not appear -in the @samp{LANGUAGES} macro in effect -during that invocation of @code{make}. - -It is expected that these remaining problems will -be fixed in a future version of @code{gcc}. - -@node System-specific Problems -@subsection System-specific Problems - -@cindex AIX -A linker bug on some versions of AIX 4.1 might prevent building -when @code{g77} is built within @code{gcc}. -It might also occur when building within @code{egcs}. -@xref{LINKFAIL}. - -@node Cross-compiler Problems -@subsection Cross-compiler Problems -@cindex cross-compiler, problems - -@code{g77} has been in alpha testing since September of -1992, and in public beta testing since February of 1995. -Alpha testing was done by a small number of people worldwide on a fairly -wide variety of machines, involving self-compilation in most or -all cases. -Beta testing has been done primarily via self-compilation, -but in more and more cases, cross-compilation (and ``criss-cross -compilation'', where a version of a compiler is built on one machine -to run on a second and generate code that runs on a third) has -been tried and has succeeded, to varying extents. - -Generally, @code{g77} can be ported to any configuration to which -@code{gcc}, @code{f2c}, and @code{libf2c} can be ported and made -to work together, aside from the known problems described in this -manual. -If you want to port @code{g77} to a particular configuration, -you should first make sure @code{gcc} and @code{libf2c} can be -ported to that configuration before focusing on @code{g77}, because -@code{g77} is so dependent on them. - -Even for cases where @code{gcc} and @code{libf2c} work, -you might run into problems with cross-compilation on certain machines, -for several reasons. - -@itemize @bullet -@item -There is one known bug -(a design bug to be fixed in 0.6) that prevents configuration of -@code{g77} as a cross-compiler in some cases, -though there are assumptions made during -configuration that probably make doing non-self-hosting builds -a hassle, requiring manual intervention. - -@item -@code{gcc} might still have some trouble being configured -for certain combinations of machines. -For example, it might not know how to handle floating-point -constants. - -@item -Improvements to the way @code{libg2c} is built could make -building @code{g77} as a cross-compiler easier---for example, -passing and using @samp{$(LD)} and @samp{$(AR)} in the appropriate -ways. -(This is improved in the @code{egcs} version of @code{g77}, -especially as of version 1.1.) - -@item -There are still some challenges putting together the right -run-time libraries (needed by @code{libg2c}) for a target -system, depending on the systems involved in the configuration. -(This is a general problem with cross-compilation, and with -@code{gcc} in particular.) -@end itemize - -@node Settings -@section Changing Settings Before Building - -Here are some internal @code{g77} settings that can be changed -by editing source files in @file{gcc/f/} before building. - -This information, and perhaps even these settings, represent -stop-gap solutions to problems people doing various ports -of @code{g77} have encountered. -As such, none of the following information is expected to -be pertinent in future versions of @code{g77}. - -@menu -* Larger File Unit Numbers:: Raising @samp{MXUNIT}. -* Always Flush Output:: Synchronizing write errors. -* Maximum Stackable Size:: Large arrays forced off the stack. -* Floating-point Bit Patterns:: Possible programs building @code{g77} - as a cross-compiler. -* Large Initialization:: Large arrays with @code{DATA} - initialization. -* Alpha Problems Fixed:: Problems with 64-bit systems like - Alphas now fixed? -@end menu - -@node Larger File Unit Numbers -@subsection Larger File Unit Numbers -@cindex MXUNIT -@cindex unit numbers -@cindex maximum unit number -@cindex illegal unit number -@cindex increasing maximum unit number - -As distributed, whether as part of @code{f2c} or @code{g77}, -@code{libf2c} accepts file unit numbers only in the range -0 through 99. -For example, a statement such as @samp{WRITE (UNIT=100)} causes -a run-time crash in @code{libf2c}, because the unit number, -100, is out of range. - -If you know that Fortran programs at your installation require -the use of unit numbers higher than 99, you can change the -value of the @samp{MXUNIT} macro, which represents the maximum unit -number, to an appropriately higher value. - -To do this, edit the file @file{f/runtime/libI77/fio.h} in your -@code{g77} source tree, changing the following line: - -@example -#define MXUNIT 100 -@end example - -Change the line so that the value of @samp{MXUNIT} is defined to be -at least one @emph{greater} than the maximum unit number used by -the Fortran programs on your system. - -(For example, a program that does @samp{WRITE (UNIT=255)} would require -@samp{MXUNIT} set to at least 256 to avoid crashing.) - -Then build or rebuild @code{g77} as appropriate. - -@emph{Note:} Changing this macro has @emph{no} effect on other limits -your system might place on the number of files open at the same time. -That is, the macro might allow a program to do @samp{WRITE (UNIT=100)}, -but the library and operating system underlying @code{libf2c} might -disallow it if many other files have already been opened (via @code{OPEN} or -implicitly via @code{READ}, @code{WRITE}, and so on). -Information on how to increase these other limits should be found -in your system's documentation. - -@node Always Flush Output -@subsection Always Flush Output -@cindex ALWAYS_FLUSH -@cindex synchronous write errors -@cindex disk full -@cindex flushing output -@cindex fflush() -@cindex I/O, flushing -@cindex output, flushing -@cindex writes, flushing -@cindex NFS -@cindex network file system - -Some Fortran programs require output -(writes) to be flushed to the operating system (under UNIX, -via the @code{fflush()} library call) so that errors, -such as disk full, are immediately flagged via the relevant -@code{ERR=} and @code{IOSTAT=} mechanism, instead of such -errors being flagged later as subsequent writes occur, forcing -the previously written data to disk, or when the file is -closed. - -Essentially, the difference can be viewed as synchronous error -reporting (immediate flagging of errors during writes) versus -asynchronous, or, more precisely, buffered error reporting -(detection of errors might be delayed). - -@code{libg2c} supports flagging write errors immediately when -it is built with the @samp{ALWAYS_FLUSH} macro defined. -This results in a @code{libg2c} that runs slower, sometimes -quite a bit slower, under certain circumstances---for example, -accessing files via the networked file system NFS---but the -effect can be more reliable, robust file I/O. - -If you know that Fortran programs requiring this level of precision -of error reporting are to be compiled using the -version of @code{g77} you are building, you might wish to -modify the @code{g77} source tree so that the version of -@code{libg2c} is built with the @samp{ALWAYS_FLUSH} macro -defined, enabling this behavior. - -To do this, find this line in @file{f/runtime/f2c.h} in -your @code{g77} source tree: - -@example -/* #define ALWAYS_FLUSH */ -@end example - -Remove the leading @samp{/*@w{ }}, -so the line begins with @samp{#define}, -and the trailing @samp{@w{ }*/}. - -Then build or rebuild @code{g77} as appropriate. - -@node Maximum Stackable Size -@subsection Maximum Stackable Size -@vindex FFECOM_sizeMAXSTACKITEM -@cindex code, stack variables -@cindex maximum stackable size -@cindex stack allocation -@cindex segmentation violation -@code{g77}, on most machines, puts many variables and arrays on the stack -where possible, and can be configured (by changing -@samp{FFECOM_sizeMAXSTACKITEM} in @file{gcc/f/com.c}) to force -smaller-sized entities into static storage (saving -on stack space) or permit larger-sized entities to be put on the -stack (which can improve run-time performance, as it presents -more opportunities for the GBE to optimize the generated code). - -@emph{Note:} Putting more variables and arrays on the stack -might cause problems due to system-dependent limits on stack size. -Also, the value of @samp{FFECOM_sizeMAXSTACKITEM} has no -effect on automatic variables and arrays. -@xref{But-bugs}, for more information. - -@node Floating-point Bit Patterns -@subsection Floating-point Bit Patterns - -@cindex cross-compiler, building -@cindex floating-point bit patterns -@cindex bit patterns -The @code{g77} build will crash if an attempt is made to build -it as a cross-compiler -for a target when @code{g77} cannot reliably determine the bit pattern of -floating-point constants for the target. -Planned improvements for version 0.6 of @code{g77} -will give it the capabilities it needs to not have to crash the build -but rather generate correct code for the target. -(Currently, @code{g77} -would generate bad code under such circumstances if it didn't crash -during the build, e.g. when compiling a source file that does -something like @samp{EQUIVALENCE (I,R)} and @samp{DATA R/9.43578/}.) - -@node Large Initialization -@subsection Initialization of Large Aggregate Areas - -@cindex speed, compiler -@cindex slow compiler -@cindex memory utilization -@cindex large initialization -@cindex aggregate initialization -A warning message is issued when @code{g77} sees code that provides -initial values (e.g. via @code{DATA}) to an aggregate area (@code{COMMON} -or @code{EQUIVALENCE}, or even a large enough array or @code{CHARACTER} -variable) -that is large enough to increase @code{g77}'s compile time by roughly -a factor of 10. - -This size currently is quite small, since @code{g77} -currently has a known bug requiring too much memory -and time to handle such cases. -In @file{gcc/f/data.c}, the macro -@samp{FFEDATA_sizeTOO_BIG_INIT_} is defined -to the minimum size for the warning to appear. -The size is specified in storage units, -which can be bytes, words, or whatever, on a case-by-case basis. - -After changing this macro definition, you must -(of course) rebuild and reinstall @code{g77} for -the change to take effect. - -Note that, as of version 0.5.18, improvements have -reduced the scope of the problem for @emph{sparse} -initialization of large arrays, especially those -with large, contiguous uninitialized areas. -However, the warning is issued at a point prior to -when @code{g77} knows whether the initialization is sparse, -and delaying the warning could mean it is produced -too late to be helpful. - -Therefore, the macro definition should not be adjusted to -reflect sparse cases. -Instead, adjust it to generate the warning when densely -initialized arrays begin to cause responses noticeably slower -than linear performance would suggest. - -@node Alpha Problems Fixed -@subsection Alpha Problems Fixed - -@cindex Alpha, support -@cindex 64-bit systems -@code{g77} used to warn when it was used to compile Fortran code -for a target configuration that is not basically a 32-bit -machine (such as an Alpha, which is a 64-bit machine, especially -if it has a 64-bit operating system running on it). -That was because @code{g77} was known to not work -properly on such configurations. - -As of version 0.5.20, @code{g77} is believed to work well -enough on such systems. -So, the warning is no longer needed or provided. - -However, support for 64-bit systems, especially in -areas such as cross-compilation and handling of -intrinsics, is still incomplete. -The symptoms -are believed to be compile-time diagnostics rather -than the generation of bad code. -It is hoped that version 0.6 will completely support 64-bit -systems. - -@node Quick Start -@section Quick Start -@cindex quick start - -@emph{Version info:} -For @code{egcs} users, the following information is -superceded by the @code{egcs} installation instructions. - -This procedure configures, builds, and installs @code{g77} -``out of the box'' and works on most UNIX systems. -Each command is identified by a unique number, -used in the explanatory text that follows. -For the most part, the output of each command is not shown, -though indications of the types of responses are given in a -few cases. - -To perform this procedure, the installer must be logged -in as user @code{root}. -Much of it can be done while not logged in as @code{root}, -and users experienced with UNIX administration should be -able to modify the procedure properly to do so. - -Following traditional UNIX conventions, it is assumed that -the source trees for @code{g77} and @code{gcc} will be -placed in @file{/usr/src}. -It also is assumed that the source distributions themselves -already reside in @file{/usr/FSF}, a naming convention -used by the author of @code{g77} on his own system: - -@example -/usr/FSF/gcc-@value{version-gcc}.tar.gz -/usr/FSF/g77-@value{version-g77}.tar.gz -@end example - -@c (You can use @file{gcc-2.7.2.1.tar.gz} instead, or -@c the equivalent of it obtained by applying the -@c patch distributed as @file{gcc-2.7.2-2.7.2.1.diff.gz} -@c to version 2.7.2 of @code{gcc}, -@c if you remember to make the appropriate adjustments in the -@c instructions below.) - -@c @cindex SunOS4 -@c Users of the following systems should not blindly follow -@c these quick-start instructions, because of problems their -@c systems have coping with straightforward installation of -@c @code{g77}: -@c -@c @itemize @bullet -@c @item -@c SunOS4 -@c @end itemize -@c -@c Instead, see @ref{Complete Installation}, for detailed information -@c on how to configure, build, and install @code{g77} for your -@c particular system. -@c Also, see @ref{Trouble,,Known Causes of Trouble with GNU Fortran}, -@c for information on bugs and other problems known to afflict the -@c installation process, and how to report newly discovered ones. -@c -@c If your system is @emph{not} on the above list, and @emph{is} -@c a UNIX system or one of its variants, you should be able to -@c follow the instructions below. - -If you vary @emph{any} of the steps below, you might run into -trouble, including possibly breaking existing programs for -other users of your system. -Before doing so, it is wise to review the explanations of some -of the steps. -These explanations follow this list of steps. - -@example -sh[ 1]# @kbd{cd /usr/src} -@set source-dir 1 -sh[ 2]# @kbd{gunzip -c < /usr/FSF/gcc-@value{version-gcc}.tar.gz | tar xf -} -[Might say "Broken pipe"...that is normal on some systems.] -@set unpack-gcc 2 -sh[ 3]# @kbd{gunzip -c < /usr/FSF/g77-@value{version-g77}.tar.gz | tar xf -} -["Broken pipe" again possible.] -@set unpack-g77 3 -sh[ 4]# @kbd{ln -s gcc-@value{version-gcc} gcc} -@set link-gcc 4 -sh[ 5]# @kbd{ln -s g77-@value{version-g77} g77} -@set link-g77 5 -sh[ 6]# @kbd{mv -i g77/* gcc} -[No questions should be asked by mv here; or, you made a mistake.] -@set merge-g77 6 -sh[ 7]# @kbd{cd gcc} -sh[ 8]# @kbd{./configure --prefix=/usr} -[Do not do the above if gcc is not installed in /usr/bin. -You might need a different @kbd{--prefix=@dots{}}, as -described below.] -@set configure-gcc 8 -sh[ 9]# @kbd{make bootstrap} -[This takes a long time, and is where most problems occur.] -@set build-gcc 9 -sh[10]# @kbd{make compare} -[This verifies that the compiler is `sane'. -If any files are printed, you have likely found a g77 bug.] -@set compare-gcc 10 -sh[11]# @kbd{rm -fr stage1} -@set rm-stage1 11 -sh[12]# @kbd{make -k install} -[The actual installation.] -@set install-g77 12 -sh[13]# @kbd{g77 -v} -[Verify that g77 is installed, obtain version info.] -@set show-version 13 -sh[14]# -@set end-procedure 14 -@end example - -@xref{Updating Documentation,,Updating Your Info Directory}, for -information on how to update your system's top-level @code{info} -directory to contain a reference to this manual, so that -users of @code{g77} can easily find documentation instead -of having to ask you for it. - -Elaborations of many of the above steps follows: - -@table @asis -@item Step @value{source-dir}: @kbd{cd /usr/src} -You can build @code{g77} pretty much anyplace. -By convention, this manual assumes @file{/usr/src}. -It might be helpful if other users on your system -knew where to look for the source code for the -installed version of @code{g77} and @code{gcc} in any case. - -@c @item Step @value{unpack-gcc}: @kbd{gunzip -d @dots{}} -@c Here, you might wish to use @file{gcc-2.7.2.1.tar.gz} -@c instead, or apply @file{gcc-2.7.2-2.7.2.1.diff.gz} to achieve -@c similar results. - -@item Step @value{unpack-g77}: @kbd{gunzip -d < /usr/FSF/g77-@value{version-g77}.tar.gz | tar xf -} -It is not always necessary to obtain the latest version of -@code{g77} as a complete @file{.tar.gz} file if you have -a complete, earlier distribution of @code{g77}. -If appropriate, you can unpack that earlier -version of @code{g77}, and then apply the appropriate patches -to achieve the same result---a source tree containing version -@value{version-g77} of @code{g77}. - -@item Step @value{link-gcc}: @kbd{ln -s gcc-@value{version-gcc} gcc} -@item Step @value{link-g77}: @kbd{ln -s g77-@value{version-g77} g77} -These commands mainly help reduce typing, -and help reduce visual clutter in examples -in this manual showing what to type to install @code{g77}. - -@c Of course, if appropriate, @kbd{ln -s gcc-2.7.2.1 gcc} or -@c similar. - -@xref{Unpacking}, for information on -using distributions of @code{g77} made by organizations -other than the FSF. - -@item Step @value{merge-g77}: @kbd{mv -i g77/* gcc} -After doing this, you can, if you like, type -@samp{rm g77} and @samp{rmdir g77-@value{version-g77}} to remove -the empty directory and the symbol link to it. -But, it might be helpful to leave them around as -quick reminders of which version(s) of @code{g77} are -installed on your system. - -@xref{Unpacking}, for information -on the contents of the @file{g77} directory (as merged -into the @file{gcc} directory). - -@item Step @value{configure-gcc}: @kbd{./configure --prefix=/usr} -This is where you specify that -the @file{g77} and @file{gcc} executables are to be -installed in @file{/usr/bin/}, -the @code{g77} and @code{gcc} documentation is -to be installed in @file{/usr/info/} and @file{/usr/man/}, -and so on. - -You should ensure that any existing installation of the @file{gcc} -executable is in @file{/usr/bin/}. - -However, if that existing version of @code{gcc} is not @value{version-gcc}, -or if you simply wish to avoid risking overwriting it with a -newly built copy of the same version, -you can specify @samp{--prefix=/usr/local} -(which is the default) -or some other path, -and invoke the newly installed version -directly from that path's @file{bin} directory. - -@xref{Where to Install,,Where in the World Does Fortran (and GNU CC) Go?}, -for more information on determining where to install @code{g77}. -@xref{Configuring gcc}, for more information on the -configuration process triggered by invoking the @file{./configure} -script. - -@item Step @value{build-gcc}: @kbd{make bootstrap} -@xref{Installation,,Installing GNU CC, -gcc,Using and Porting GNU CC}, for information -on the kinds of diagnostics you should expect during -this procedure. - -@xref{Building gcc}, for complete @code{g77}-specific -information on this step. - -@item Step @value{compare-gcc}: @kbd{make compare} -@xref{Bug Lists,,Where to Port Bugs}, for information -on where to report that you observed files -having different contents during this -phase. - -@xref{Bug Reporting,,How to Report Bugs}, for -information on @emph{how} to report bugs like this. - -@item Step @value{rm-stage1}: @kbd{rm -fr stage1} -You don't need to do this, but it frees up disk space. - -@item Step @value{install-g77}: @kbd{make -k install} -If this doesn't seem to work, try: - -@example -make -k install install-libf77 -@end example - -Or, make sure you're using GNU @code{make}. - -@xref{Installation of Binaries}, for more information. - -@xref{Updating Documentation,,Updating Your Info Directory}, -for information on entering this manual into your -system's list of texinfo manuals. - -@item Step @value{show-version}: @kbd{g77 -v} -If this command prints approximately 25 lines of output, -including the GNU Fortran Front End version number (which -should be the same as the version number for the version -of @code{g77} you just built and installed) and the -version numbers for the three parts of the @code{libf2c} -library (@code{libF77}, @code{libI77}, @code{libU77}), and -those version numbers are all in agreement, then there is -a high likelihood that the installation has been successfully -completed. - -You might consider doing further testing. -For example, log in as a non-privileged user, then create -a small Fortran program, such as: - -@example - PROGRAM SMTEST - DO 10 I=1, 10 - PRINT *, 'Hello World #', I -10 CONTINUE - END -@end example - -Compile, link, and run the above program, and, assuming you named -the source file @file{smtest.f}, the session should look like this: - -@example -sh# @kbd{g77 -o smtest smtest.f} -sh# @kbd{./smtest} - Hello World # 1 - Hello World # 2 - Hello World # 3 - Hello World # 4 - Hello World # 5 - Hello World # 6 - Hello World # 7 - Hello World # 8 - Hello World # 9 - Hello World # 10 -sh# -@end example - -If invoking @code{g77} doesn't seem to work, -the problem might be that you've installed it in -a location that is not in your shell's search path. -For example, if you specified @samp{--prefix=/gnu}, -and @file{/gnu/bin} is not in your @code{PATH} -environment variable, -you must explicitly specify the location of the compiler -via @kbd{/gnu/bin/g77 -o smtest smtest.f}. - -After proper installation, you don't -need to keep your gcc and g77 source and build directories -around anymore. -Removing them can free up a lot of disk space. -@end table - -@node Complete Installation -@section Complete Installation - -@emph{Version info:} -For @code{egcs} users, the following information is -mostly superceded by the @code{egcs} installation instructions. - -Here is the complete @code{g77}-specific information on how -to configure, build, and install @code{g77}. - -@menu -* Unpacking:: -* Merging Distributions:: -* Where to Install:: -* Configuring gcc:: -* Building gcc:: -* Pre-installation Checks:: -* Installation of Binaries:: -* Updating Documentation:: -* Missing tools?:: -@end menu - -@node Unpacking -@subsection Unpacking -@cindex unpacking distributions -@cindex distributions, unpacking -@cindex code, source -@cindex source code -@cindex source tree -@cindex packages - -The @code{gcc} source distribution is a stand-alone distribution. -It is designed to be unpacked (producing the @code{gcc} -source tree) and built as is, assuming certain -prerequisites are met (including the availability of compatible -UNIX programs such as @code{make}, @code{cc}, and so on). - -However, before building @code{gcc}, you will want to unpack -and merge the @code{g77} distribution in with it, so that you -build a Fortran-capable version of @code{gcc}, which includes -the @code{g77} command, the necessary run-time libraries, -and this manual. - -Unlike @code{gcc}, the @code{g77} source distribution -is @emph{not} a stand-alone distribution. -It is designed to be unpacked and, afterwards, immediately merged -into an applicable @code{gcc} source tree. -That is, the @code{g77} distribution @emph{augments} a -@code{gcc} distribution---without @code{gcc}, generally -only the documentation is immediately usable. - -A sequence of commands typically used to unpack @code{gcc} -and @code{g77} is: - -@example -sh# @kbd{cd /usr/src} -sh# @kbd{gunzip -c /usr/FSF/gcc-@value{version-gcc}.tar.gz | tar xf -} -sh# @kbd{gunzip -c /usr/FSF/g77-@value{version-g77}.tar.gz | tar xf -} -sh# @kbd{ln -s gcc-@value{version-gcc} gcc} -sh# @kbd{ln -s g77-@value{version-g77} g77} -sh# @kbd{mv -i g77/* gcc} -@end example - -@emph{Notes:} The commands beginning with @samp{gunzip@dots{}} might -print @samp{Broken pipe@dots{}} as they complete. -That is nothing to worry about, unless you actually -@emph{hear} a pipe breaking. -The @code{ln} commands are helpful in reducing typing -and clutter in installation examples in this manual. -Hereafter, the top level of @code{gcc} source tree is referred to -as @file{gcc}, and the top level of just the @code{g77} -source tree (prior to issuing the @code{mv} command, above) -is referred to as @file{g77}. - -There are three top-level names in a @code{g77} distribution: - -@example -g77/COPYING.g77 -g77/README.g77 -g77/f -@end example - -All three entries should be moved (or copied) into a @code{gcc} -source tree (typically named after its version number and -as it appears in the FSF distributions---e.g. @file{gcc-@value{version-gcc}}). - -@file{g77/f} is the subdirectory containing all of the -code, documentation, and other information that is specific -to @code{g77}. -The other two files exist to provide information on @code{g77} -to someone encountering a @code{gcc} source tree with @code{g77} -already present, who has not yet read these installation -instructions and thus needs help understanding that the -source tree they are looking at does not come from a single -FSF distribution. -They also help people encountering an unmerged @code{g77} source -tree for the first time. - -@cindex modifying @code{g77} -@cindex code, modifying -@cindex Pentium optimizations -@cindex optimizations, Pentium -@emph{Note:} Please use @strong{only} @code{gcc} and @code{g77} -source trees as distributed by the FSF. -Use of modified versions is likely to result in problems that appear to be -in the @code{g77} code but, in fact, are not. -Do not use such modified versions -unless you understand all the differences between them and the versions -the FSF distributes---in which case you should be able to modify the -@code{g77} (or @code{gcc}) source trees appropriately so @code{g77} -and @code{gcc} can coexist as they do in the stock FSF distributions. - -@node Merging Distributions -@subsection Merging Distributions -@cindex merging distributions -@cindex @code{gcc} versions supported by @code{g77} -@cindex versions of @code{gcc} -@cindex support for @code{gcc} versions - -After merging the @code{g77} source tree into the @code{gcc} source tree, -you have put together a complete @code{g77} source tree. - -@cindex gcc version numbering -@cindex version numbering -@cindex g77 version number -@cindex GNU version numbering -As of version 0.5.23, @code{g77} no longer modifies -the version number of @code{gcc}, -nor does it patch @code{gcc} itself. - -@code{g77} still depends on being merged with an -appropriate version of @code{gcc}. -For version @value{version-g77} of @code{g77}, -the specific version of @code{gcc} supported is @value{version-gcc}. - -However, other versions of @code{gcc} might be suitable -``hosts'' for this version of @code{g77}. - -GNU version numbers make it easy to figure out whether a -particular version of a distribution is newer or older than -some other version of that distribution. -The format is, -generally, @var{major}.@var{minor}.@var{patch}, with -each field being a decimal number. -(You can safely ignore -leading zeros; for example, 1.5.3 is the same as 1.5.03.) -The @var{major} field only increases with time. -The other two fields are reset to 0 when the field to -their left is incremented; otherwise, they, too, only -increase with time. -So, version 2.6.2 is newer than version 2.5.8, and -version 3.0 is newer than both. -(Trailing @samp{.0} fields often are omitted in -announcements and in names for distributions and -the directories they create.) - -If your version of @code{gcc} is older than the oldest version -supported by @code{g77} -(as casually determined by listing the contents of @file{gcc/f/INSTALL/}, -which contains these installation instructions in plain-text format), -you should obtain a newer, supported version of @code{gcc}. -(You could instead obtain an older version of @code{g77}, -or try and get your @code{g77} to work with the old -@code{gcc}, but neither approach is recommended, and -you shouldn't bother reporting any bugs you find if you -take either approach, because they're probably already -fixed in the newer versions you're not using.) - -If your version of @code{gcc} is newer than the newest version -supported by @code{g77}, it is possible that your @code{g77} -will work with it anyway. -If the version number for @code{gcc} differs only in the -@var{patch} field, you might as well try that version of @code{gcc}. -Since it has the same @var{major} and @var{minor} fields, -the resulting combination is likely to work. - -So, for example, if a particular version of @code{g77} has support for -@code{gcc} versions 2.8.0 and 2.8.1, -it is likely that @file{gcc-2.8.2} would work well with @code{g77}. - -However, @file{gcc-2.9.0} would almost certainly -not work with that version of @code{g77} -without appropriate modifications, -so a new version of @code{g77} would be needed (and you should -wait for it rather than bothering the maintainers---@pxref{Changes,, -User-Visible Changes}). - -@cindex distributions, why separate -@cindex separate distributions -@cindex why separate distributions -This complexity is the result of @code{gcc} and @code{g77} being -separate distributions. -By keeping them separate, each product is able to be independently -improved and distributed to its user base more frequently. - -However, the GBE interface defined by @code{gcc} typically -undergoes some incompatible changes at least every time the -@var{minor} field of the version number is incremented, -and such changes require corresponding changes to -the @code{g77} front end (FFE). - -@c @pindex config-lang.in -@c @emph{Note:} @code{g77}'s configuration file @file{gcc/f/config-lang.in} -@c sometimes ensures that the source code for the version of @code{gcc} -@c being configured has at least one indication of being an appropriate -@c version as required specifically by @code{g77}. -@c This configuration-time -@c checking should catch failures to use the proper version of @code{gcc} and, -@c if so caught, should abort the configuration with an explanation. -@c @emph{Please} do not try to disable this check, -@c otherwise @code{g77} might well appear to build -@c and install correctly, and even appear to compile correctly, -@c but could easily produce broken code. - -@node Where to Install -@subsection Where in the World Does Fortran (and GNU CC) Go? -@cindex language f77 not recognized -@cindex gcc will not compile Fortran programs - -Before configuring, you should make sure you know -where you want the @code{g77} and @code{gcc} -binaries to be installed after they're built, -because this information is given to the configuration -tool and used during the build itself. - -A @code{g77} installation normally includes installation of -a Fortran-aware version of @code{gcc}, so that the @code{gcc} -command recognizes Fortran source files and knows how to compile -them. - -For this to work, the version of @code{gcc} that you will be building -as part of @code{g77} @strong{must} be installed as the ``active'' -version of @code{gcc} on the system. - -Sometimes people make the mistake of installing @code{gcc} as -@file{/usr/local/bin/gcc}, -leaving an older, non-Fortran-aware version in @file{/usr/bin/gcc}. -(Or, the opposite happens.) -This can result in @code{gcc} being unable to compile Fortran -source files, -because when the older version of @code{gcc} is invoked, -it complains that it does not -recognize the language, or the file name suffix. - -So, determine whether @code{gcc} already is installed on your system, -and, if so, @emph{where} it is installed, and prepare to configure the -new version of @code{gcc} you'll be building so that it installs -over the existing version of @code{gcc}. - -You might want to back up your existing copy of @file{/usr/bin/gcc}, and -the entire @file{/usr/lib} directory, before -you perform the actual installation (as described in this manual). - -Existing @code{gcc} installations typically are -found in @file{/usr} or @file{/usr/local}. -(This means the commands are installed in @file{/usr/bin} or -@file{/usr/local/bin}, -the libraries in @file{/usr/lib} or @file{/usr/local/lib}, -and so on.) - -If you aren't certain where the currently -installed version of @code{gcc} and its -related programs reside, look at the output -of this command: - -@example -gcc -v -o /tmp/delete-me -xc /dev/null -xnone -@end example - -All sorts of interesting information on the locations of various -@code{gcc}-related programs and data files should be visible -in the output of the above command. -(The output also is likely to include a diagnostic from -the linker, since there's no @samp{main_()} function.) -However, you do have to sift through it yourself; @code{gcc} -currently provides no easy way to ask it where it is installed -and where it looks for the various programs and data files it -calls on to do its work. - -Just @emph{building} @code{g77} should not overwrite any installed -programs---but, usually, after you build @code{g77}, you will want -to install it, so backing up anything it might overwrite is -a good idea. -(This is true for any package, not just @code{g77}, -though in this case it is intentional that @code{g77} overwrites -@code{gcc} if it is already installed---it is unusual that -the installation process for one distribution intentionally -overwrites a program or file installed by another distribution, -although, in this case, @code{g77} is an augmentation of the -@code{gcc} distribution.) - -Another reason to back up the existing version first, -or make sure you can restore it easily, is that it might be -an older version on which other users have come to depend -for certain behaviors. -However, even the new version of @code{gcc} you install -will offer users the ability to specify an older version of -the actual compilation programs if desired, and these -older versions need not include any @code{g77} components. -@xref{Target Options,,Specifying Target Machine and Compiler Version, -gcc,Using and Porting GNU CC}, for information on the @samp{-V} -option of @code{gcc}. - -@node Configuring gcc -@subsection Configuring GNU CC - -@code{g77} is configured automatically when you configure -@code{gcc}. -There are two parts of @code{g77} that are configured in two -different ways---@code{g77}, which ``camps on'' to the -@code{gcc} configuration mechanism, and @code{libg2c}, which -uses a variation of the GNU @code{autoconf} configuration -system. - -Generally, you shouldn't have to be concerned with -either @code{g77} or @code{libg2c} configuration, unless -you're configuring @code{g77} as a cross-compiler. -In this case, the @code{libg2c} configuration, and possibly the -@code{g77} and @code{gcc} configurations as well, -might need special attention. -(This also might be the case if you're porting @code{gcc} to -a whole new system---even if it is just a new operating system -on an existing, supported CPU.) - -To configure the system, see -@ref{Installation,,Installing GNU CC,gcc,Using and Porting GNU CC}, -following the instructions for running @file{./configure}. -Pay special attention to the @samp{--prefix=} option, which -you almost certainly will need to specify. - -(Note that @code{gcc} installation information is provided -as a plain-text file in @file{gcc/INSTALL}.) - -The information printed by the invocation of @file{./configure} -should show that the @file{f} directory (the Fortran language) -has been configured. -If it does not, there is a problem. - -@emph{Note:} Configuring with the @samp{--srcdir} argument, -or by starting in an empty directory -and typing a command such as @kbd{../gcc/configure} to -build with separate build and source directories, -is known to work with GNU @code{make}, -but it is known to not work with other variants of @code{make}. -Irix5.2 and SunOS4.1 versions of @code{make} definitely -won't work outside the source directory at present. - -@code{g77}'s portion of the @file{configure} script -used to issue a warning message about this -when configuring for building binaries outside the source directory, -but no longer does this as of version 0.5.23. - -Instead, @code{g77} simply rejects most common attempts -to build it using a non-GNU @code{make} when the -build directory is not the same as the source directory, -issuing an explanatory diagnostic. - -@node Building gcc -@subsection Building GNU CC -@cindex building @code{gcc} -@cindex building @code{g77} - -@vindex LANGUAGES -Building @code{g77} requires building enough of @code{gcc} that -these instructions assume you're going to build all of -@code{gcc}, including @code{g++}, @code{protoize}, and so on. -You can save a little time and disk space by changes the -@samp{LANGUAGES} macro definition in @code{gcc/Makefile.in} -or @code{gcc/Makefile}, but if you do that, you're on your own. -One change is almost @emph{certainly} going to cause failures: -removing @samp{c} or @samp{f77} from the definition of the -@samp{LANGUAGES} macro. - -After configuring @code{gcc}, which configures @code{g77} and -@code{libg2c} automatically, you're ready to start the actual -build by invoking @code{make}. - -@pindex configure -@emph{Note:} You @strong{must} have run the @file{configure} -script in @code{gcc} before you run @code{make}, -even if you're using an already existing @code{gcc} development directory, -because @file{./configure} does the work to recognize that you've added -@code{g77} to the configuration. - -There are two general approaches to building GNU CC from -scratch: - -@table @dfn -@item bootstrap -This method uses minimal native system facilities to -build a barebones, unoptimized @code{gcc}, that is then -used to compile (``bootstrap'') the entire system. - -@item straight -This method assumes a more complete native system -exists, and uses that just once to build the entire -system. -@end table - -On all systems without a recent version of @code{gcc} -already installed, the @i{bootstrap} method must be -used. -In particular, @code{g77} uses extensions to the C -language offered, apparently, only by @code{gcc}. - -On most systems with a recent version of @code{gcc} -already installed, the @i{straight} method can be -used. -This is an advantage, because it takes less CPU time -and disk space for the build. -However, it does require that the system have fairly -recent versions of many GNU programs and other -programs, which are not enumerated here. - -@menu -* Bootstrap Build:: For all systems. -* Straight Build:: For systems with a recent version of @code{gcc}. -@end menu - -@node Bootstrap Build -@subsubsection Bootstrap Build -@cindex bootstrap build -@cindex build, bootstrap - -A complete bootstrap build is done by issuing a command -beginning with @samp{make bootstrap @dots{}}, as -described in @ref{Installation,,Installing GNU CC, -gcc,Using and Porting GNU CC}. -This is the most reliable form of build, but it does require -the most disk space and CPU time, since the complete system -is built twice (in Stages 2 and 3), after an initial build -(during Stage 1) of a minimal @code{gcc} compiler using -the native compiler and libraries. - -You might have to, or want to, control the way a bootstrap -build is done by entering the @code{make} commands to build -each stage one at a time, as described in the @code{gcc} -manual. -For example, to save time or disk space, you might want -to not bother doing the Stage 3 build, in which case you -are assuming that the @code{gcc} compiler you have built -is basically sound (because you are giving up the opportunity -to compare a large number of object files to ensure they're -identical). - -To save some disk space during installation, after Stage 2 -is built, you can type @samp{rm -fr stage1} to remove the -binaries built during Stage 1. - -Also, @xref{Installation,,Installing GNU CC,gcc,Using and Porting GNU CC}, -for important information on building @code{gcc} that is -not described in this @code{g77} manual. -For example, explanations of diagnostic messages -and whether they're expected, or indicate trouble, -are found there. - -@node Straight Build -@subsubsection Straight Build -@cindex straight build -@cindex build, straight - -If you have a recent version of @code{gcc} -already installed on your system, and if you're -reasonably certain it produces code that is -object-compatible with the version of @code{gcc} -you want to build as part of building @code{g77}, -you can save time and disk space by doing a straight -build. - -To build just the compilers along with the -necessary run-time libraries, issue the following -command: - -@example -make -k CC=gcc -@end example - -If you run into problems using this method, you have -two options: - -@itemize @bullet -@item -Abandon this approach and do a bootstrap build. - -@item -Try to make this approach work by diagnosing the -problems you're running into and retrying. -@end itemize - -Especially if you do the latter, you might consider -submitting any solutions as bug/fix reports. -@xref{Trouble,,Known Causes of Trouble with GNU Fortran}. - -However, understand that many problems preventing a -straight build from working are not @code{g77} problems, -and, in such cases, are not likely to be addressed in -future versions of @code{g77}. -Consider treating them as @code{gcc} bugs instead. - -@node Pre-installation Checks -@subsection Pre-installation Checks -@cindex pre-installation checks -@cindex installing, checking before - -Before installing the system, which includes installing -@code{gcc}, you might want to do some minimum checking -to ensure that some basic things work. - -Here are some commands you can try, and output typically -printed by them when they work: - -@example -sh# @kbd{cd /usr/src/gcc} -sh# @kbd{./g77 -B./ -v} -g77 version @value{version-g77} -Driving: ./g77 -B./ -v -c -xf77-version /dev/null -xnone -Reading specs from ./specs -gcc version @value{version-gcc} - cpp -lang-c -v -isystem ./include -undef -D__GNUC__=2 @dots{} -GNU CPP version @value{version-gcc} (Alpha GNU/Linux with ELF) -#include "..." search starts here: -#include <...> search starts here: - include - /usr/alpha-linux/include - /usr/lib/gcc-lib/alpha-linux/@value{version-gcc}/include - /usr/include -End of search list. - ./f771 -fnull-version -quiet -dumpbase g77-version.f -version @dots{} -GNU F77 version @value{version-gcc} (alpha-linux) compiled @dots{} -GNU Fortran Front End version @value{version-g77} - as -nocpp -o /tmp/cca14485.o /tmp/cca14485.s - ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 @dots{} - /tmp/cca14485 -__G77_LIBF77_VERSION__: @value{version-g77} -@@(#)LIBF77 VERSION 19970919 -__G77_LIBI77_VERSION__: @value{version-g77} -@@(#) LIBI77 VERSION pjw,dmg-mods 19980405 -__G77_LIBU77_VERSION__: @value{version-g77} -@@(#) LIBU77 VERSION 19970919 -sh# @kbd{./xgcc -B./ -v -o /tmp/delete-me -xc /dev/null -xnone} -Reading specs from ./specs -gcc version @value{version-gcc} - ./cpp -lang-c -v -isystem ./include -undef @dots{} -GNU CPP version @value{version-gcc} (Alpha GNU/Linux with ELF) -#include "..." search starts here: -#include <...> search starts here: - include - /usr/alpha-linux/include - /usr/lib/gcc-lib/alpha-linux/@value{version-gcc}/include - /usr/include -End of search list. - ./cc1 /tmp/cca18063.i -quiet -dumpbase null.c -version @dots{} -GNU C version @value{version-gcc} (alpha-linux) compiled @dots{} - as -nocpp -o /tmp/cca180631.o /tmp/cca18063.s - ld -m elf64alpha -G 8 -O1 -dynamic-linker /lib/ld-linux.so.2 @dots{} -/usr/lib/crt1.o: In function `_start': -../sysdeps/alpha/elf/start.S:77: undefined reference to `main' -../sysdeps/alpha/elf/start.S:77: undefined reference to `main' -sh# -@end example - -(Note that long lines have been truncated, and @samp{@dots{}} -used to indicate such truncations.) - -The above two commands test whether @code{g77} and @code{gcc}, -respectively, are able to compile empty (null) source files, -whether invocation of the C preprocessor works, whether libraries -can be linked, and so on. - -If the output you get from either of the above two commands -is noticeably different, especially if it is shorter or longer -in ways that do not look consistent with the above sample -output, you probably should not install @code{gcc} and @code{g77} -until you have investigated further. - -For example, you could try compiling actual applications and -seeing how that works. -(You might want to do that anyway, even if the above tests -work.) - -To compile using the not-yet-installed versions of @code{gcc} -and @code{g77}, use the following commands to invoke them. - -To invoke @code{g77}, type: - -@example -/usr/src/gcc/g77 -B/usr/src/gcc/ @dots{} -@end example - -To invoke @code{gcc}, type: - -@example -/usr/src/gcc/xgcc -B/usr/src/gcc/ @dots{} -@end example - -@node Installation of Binaries -@subsection Installation of Binaries -@cindex installation of binaries -@cindex @code{g77}, installation of -@cindex @code{gcc}, installation of - -After configuring, building, and testing @code{g77} and @code{gcc}, -when you are ready to install them on your system, type: - -@example -make -k CC=gcc install -@end example - -As described in @ref{Installation,,Installing GNU CC, -gcc,Using and Porting GNU CC}, the values for -the @samp{CC} and @samp{LANGUAGES} macros should -be the same as those you supplied for the build -itself. - -So, the details of the above command might vary -if you used a bootstrap build (where you might be -able to omit both definitions, or might have to -supply the same definitions you used when building -the final stage) or if you deviated from the -instructions for a straight build. - -If the above command does not install @file{libg2c.a} -as expected, try this: - -@example -make -k @dots{} install install-libf77 -@end example - -We don't know why some non-GNU versions of @code{make} sometimes -require this alternate command, but they do. -(Remember to supply the appropriate definition for @samp{CC} -where you see @samp{@dots{}} in the above command.) - -Note that using the @samp{-k} option tells @code{make} to -continue after some installation problems, like not having -@code{makeinfo} installed on your system. -It might not be necessary for your system. - -@emph{Note:} @code{g77} no longer installs -files not directly part of @code{g77}, -such as @file{/usr/bin/f77}, @file{/usr/lib/libf2c.a}, -and @file{/usr/include/f2c.h}, or their -@file{/usr/local} equivalents. - -@xref{Distributing Binaries}, for information on -how to accommodate systems with no existing non-@code{g77} -@code{f77} compiler and systems with @code{f2c} installed. - -@node Updating Documentation -@subsection Updating Your Info Directory -@cindex updating info directory -@cindex info, updating directory -@cindex directory, updating info -@pindex /usr/info/dir -@pindex g77.info -@cindex texinfo -@cindex documentation - -As part of installing @code{g77}, you should make sure users -of @code{info} can easily access this manual on-line. - -@code{g77} does this automatically by -invoking the @code{install-info} command -when you use @samp{make install} to install @code{g77}. - -If that fails, or if the @code{info} directory -it updates is not the one normally accessed by users, -consider invoking it yourself. -For example: - -@smallexample -install-info --info-dir=/usr/info /usr/info/g77.info -@end smallexample - -The above example assumes the @code{g77} documentation -already is installed in @file{/usr/info} -and that @file{/usr/info/dir} is the file -you wish to update. -Adjust the command accordingly, -if those assumptions are wrong. - -@node Missing tools? -@subsection Missing tools? -@cindex command missing -@cindex command not found -@cindex file not found -@cindex not found - -A build of @code{gcc} might fail due to one or more tools -being called upon by @code{make} -(during the build or install process), -when those tools are not installed on your system. - -This situation can result from any of the following actions -(performed by you or someone else): - -@itemize @bullet -@item -Changing the source code or documentation yourself -(as a developer or technical writer). - -@item -Applying a patch that changes the source code or documentation -(including, sometimes, the official patches distributed by -the FSF). - -@item -Deleting the files that are created by the (missing) tools. - -The @samp{make maintainer-clean} command is supposed -to delete these files, so invoking this command without -having all the appropriate tools installed is not recommended. - -@item -Creating the source directory using a method that -does not preserve the date-time-modified information -in the original distribution. - -For example, the UNIX @samp{cp -r} command copies a -directory tree without preserving the date-time-modified -information. -Use @samp{cp -pr} instead. -@end itemize - -The reason these activities cause @code{make} to try and -invoke tools that it probably wouldn't when building -from a perfectly ``clean'' source directory containing -@code{gcc} and @code{g77} is that some files in the -source directory (and the corresponding distribution) -aren't really source files, but @emph{derived} files -that are produced by running tools with the corresponding -source files as input. -These derived files @dfn{depend}, in @code{make} terminology, -on the corresponding source files. - -@code{make} determines that a file that depends on another -needs to be updated if the date-time-modified information for -the source file shows that it is newer than the corresponding -information for the derived file. - -If it makes that determination, @code{make} runs the appropriate -commands (specified in the ``Makefile'') to update the -derived file, and this process typically calls upon one or -more installed tools to do the work. - -The ``safest'' approach to dealing with this situation -is to recreate the @code{gcc} and @code{g77} source -directories from complete @code{gcc} and @code{g77} distributions -known to be provided by the FSF. - -Another fairly ``safe'' approach is to simply install -the tools you need to complete the build process. -This is especially appropriate if you've changed the -source code or applied a patch to do so. - -However, if you're certain that the problem is limited -entirely to incorrect date-time-modified information, -that there are no discrepancies between the contents of -source files and files derived from them in the source -directory, you can often update the date-time-modified -information for the derived files to work around the -problem of not having the appropriate tools installed. - -On UNIX systems, the simplest way to update the date-time-modified -information of a file is to use the use the @samp{touch} -command. - -How to use @samp{touch} to update the derived files -updated by each of the tools is described below. -@emph{Note:} New versions of @code{g77} might change the set of -files it generates by invoking each of these tools. -If you cannot figure -out for yourself how to handle such a situation, try an -older version of @code{g77} until you find someone who can -(or until you obtain and install the relevant tools). - -@menu -* autoconf: Missing autoconf?. -* bison: Missing bison?. -* gperf: Missing gperf?. -* makeinfo: Missing makeinfo?. -@end menu - -@node Missing autoconf? -@subsubsection Missing @code{autoconf}? -@cindex @code{autoconf} -@cindex missing @code{autoconf} - -If you cannot install @code{autoconf}, make sure you have started -with a @emph{fresh} distribution of @code{gcc} and @code{g77}, -do @emph{not} do @samp{make maintainer-clean}, and, to ensure that -@code{autoconf} is not invoked by @code{make} during the build, -type these commands: - -@example -sh# @kbd{cd gcc/f/runtime} -sh# @kbd{touch configure libU77/configure} -sh# @kbd{cd ../../..} -sh# -@end example - -@node Missing bison? -@subsubsection Missing @code{bison}? -@cindex @code{bison} -@cindex missing @code{bison} - -If you cannot install @code{bison}, make sure you have started -with a @emph{fresh} distribution of @code{gcc}, do @emph{not} -do @samp{make maintainer-clean}, and, to ensure that -@code{bison} is not invoked by @code{make} during the build, -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 cp/parse.c cp/parse.h objc-parse.c} -sh# @kbd{cd ..} -sh# -@end example - -@node Missing gperf? -@subsubsection Missing @code{gperf}? -@cindex @code{gperf} -@cindex missing @code{gperf} - -If you cannot install @code{gperf}, make sure you have started -with a @emph{fresh} distribution of @code{gcc}, do @emph{not} -do @samp{make maintainer-clean}, and, to ensure that -@code{gperf} is not invoked by @code{make} during the build, -type these commands: - -@example -sh# @kbd{cd gcc} -sh# @kbd{touch c-gperf.h} -sh# @kbd{cd ..} -sh# -@end example - -@node Missing makeinfo? -@subsubsection Missing @code{makeinfo}? -@cindex @code{makeinfo} -@cindex missing @code{makeinfo} -@cindex @code{libg2c.a} not found -@cindex missing @code{libg2c.a} - -If @code{makeinfo} is needed but unavailable -when installing (via @code{make install}), -some files, like @file{libg2c.a}, -might not be installed, -because once @code{make} determines that it cannot -invoke @code{makeinfo}, it cancels any further processing. - -If you cannot install @code{makeinfo}, an easy work-around is to -specify @samp{MAKEINFO=true} on the @code{make} command line, -or to specify the @samp{-k} option (@kbd{make -k install}). - -Another approach is to force the relevant files to be up-to-date -by typing these commands and then re-trying the installation step: - -@example -sh# @kbd{cd gcc} -sh# @kbd{touch f/g77.info f/BUGS f/INSTALL f/NEWS} -sh# @kbd{cd ..} -sh# -@end example - -@node Distributing Binaries -@section Distributing Binaries -@cindex binaries, distributing -@cindex code, distributing - -If you are building @code{g77} for distribution to others in binary form, -first make sure you are aware of your legal responsibilities (read -the file @file{gcc/COPYING} thoroughly). - -Then, consider your target audience and decide where @code{g77} should -be installed. - -For systems like GNU/Linux that have no native Fortran compiler (or -where @code{g77} could be considered the native compiler for Fortran and -@code{gcc} for C, etc.), you should definitely configure -@code{g77} for installation -in @file{/usr/bin} instead of @file{/usr/local/bin}. -Specify the -@samp{--prefix=/usr} option when running @file{./configure}. - -You might also want to set up the distribution -so the @file{f77} command is a link to @file{g77}, -although a script that accepts ``classic'' UNIX @code{f77} -options and translates the command-line to the -appropriate @code{g77} command line would be more appropriate. -If you do this, @emph{please} also provide a ``man page'' in -@file{man/man1/f77.1} describing the command. -(A link to @file{man/man1/g77.1} is appropriate -if @file{bin/f77} is a link to @file{bin/g77}.) - -For a system that might already have @code{f2c} installed, -consider whether inter-operation with @code{g77} will be -important to users of @code{f2c} on that system. -If you want to improve the likelihood -that users will be able to use both @code{f2c} and @code{g77} -to compile code for a single program -without encountering link-time or run-time incompatibilities, -make sure that, -whenever they intend to combine @code{f2c}-produced code -with @code{g77}-produced code in an executable, they: - -@itemize @bullet -@item -Use the @file{lib/gcc-lib/@dots{}/include/g2c.h} file -generated by the @code{g77} build -in place of the @file{f2c.h} file -that normally comes with @code{f2c} -(or versions of @code{g77} prior to 0.5.23) -when compiling @emph{all} of the @code{f2c}-produced C code - -@item -Link to the @code{lib/gcc-lib/@dots{}/libg2c.a} library -built by the @code{g77} build -instead of the @file{libf2c.a} library -that normally comes with @code{f2c} -(or versions of @code{g77} prior to 0.5.23) -@end itemize - -How you choose to effect the above depends on whether -the existing installation of @code{f2c} must be -maintained. - -In any case, it is important to try and ensure that -the installation keeps working properly even after -subsequent re-installation of @code{f2c}, -which probably involves overwriting -@file{/usr/local/lib/libf2c.a} and -@file{/usr/local/include/f2c.h}, -or similar. - -At least, copying @file{libg2c.a} and @file{g2c.h} into -the appropriate ``public'' directories -allows users to more easily select the version of -@code{libf2c} they wish to use for a particular -build. -The names are changed by @code{g77} to make this -coexistence easier to maintain; -even if @code{f2c} is installed later, -the @code{g77} files normally installed -by its installation process aren't disturbed. -Use of symbolic links from one set of files to -another might result in problems after a subsequent -reinstallation of either @code{f2c} or @code{g77}, -so be sure to alert users of your distribution -accordingly. - -(Make sure you clearly document, in the description of -your distribution, how installation of your distribution will -affect existing installations of @code{gcc}, @code{f2c}, -@code{f77}, @file{libf2c.a}, and so on. -Similarly, you should clearly document any requirements -you assume will be met by users of your distribution.) - -For other systems with native @code{f77} (and @code{cc}) compilers, -configure @code{g77} as you (or most of your audience) would -configure @code{gcc} for their installations. -Typically this is for installation in @file{/usr/local}, -and would not include a new version of @file{/usr/bin/f77} -or @file{/usr/local/bin/f77}, -so users could still use the native @code{f77}. - -In any case, for @code{g77} to work properly, you @strong{must} ensure -that the binaries you distribute include: - -@table @file -@item bin/g77 -This is the command most users use to compile Fortran. - -@item bin/gcc -This is the command some users use to compile Fortran, -typically when compiling programs written in other languages -at the same time. -The @file{bin/gcc} executable file must have been built -from a @code{gcc} source tree into which a @code{g77} source -tree was merged and configured, or it will not know how -to compile Fortran programs. - -@item info/g77.info* -This is the documentation for @code{g77}. -If it is not included, users will have trouble understanding -diagnostics messages and other such things, and will send -you a lot of email asking questions. - -Please edit this documentation (by editing @file{gcc/f/*.texi} -and doing @samp{make doc} from the @file{/usr/src/gcc} directory) -to reflect any changes you've made to @code{g77}, or at -least to encourage users of your binary distribution to -report bugs to you first. - -Also, whether you distribute binaries or install @code{g77} -on your own system, it might be helpful for everyone to -add a line listing this manual by name and topic to the -top-level @code{info} node in @file{/usr/info/dir}. -That way, users can find @code{g77} documentation more -easily. -@xref{Updating Documentation,,Updating Your Info Directory}. - -@item man/man1/g77.1 -This is the short man page for @code{g77}. -It is not always kept up-to-date, -but you might as well include it -for people who really like ``man'' pages. - -@cindex gcc-lib directory -@cindex directories, gcc-lib -@item lib/gcc-lib -This is the directory containing the ``private'' files -installed by and for @code{gcc}, @code{g77}, @code{g++}, -and other GNU compilers. - -@item lib/gcc-lib/@dots{}/f771 -This is the actual Fortran compiler. - -@item lib/gcc-lib/@dots{}/libg2c.a -This is the run-time library for @code{g77}-compiled programs. -@end table - -Whether you want to include the slightly updated (and possibly -improved) versions of @file{cc1}, @file{cc1plus}, and whatever other -binaries get rebuilt with the changes the GNU Fortran distribution -makes to the GNU back end, is up to you. -These changes are highly unlikely to break any compilers, -because they involve doing things like adding to the -list of acceptable compiler options -(so, for example, @file{cc1plus} accepts, and ignores, -options that only @file{f771} actually processes). - -Please assure users that unless -they have a specific need for their existing, -older versions of @file{gcc} command, -they are unlikely to experience any problems by overwriting -it with your version---though they could certainly protect -themselves by making backup copies first! - -Otherwise, users might try and install your binaries -in a ``safe'' place, find they cannot compile Fortran -programs with your distribution (because, perhaps, they're -invoking their old version of the @file{gcc} command, -which does not recognize Fortran programs), and assume -that your binaries (or, more generally, GNU Fortran -distributions in general) are broken, at least for their -system. - -Finally, @strong{please} ask for bug reports to go to you first, at least -until you're sure your distribution is widely used and has been -well tested. -This especially goes for those of you making any -changes to the @code{g77} sources to port @code{g77}, e.g. to OS/2. -@email{fortran@@gnu.org} has received a fair number of bug -reports that turned out to be problems with other peoples' ports -and distributions, about which nothing could be done for the -user. -Once you are quite certain a bug report does not involve -your efforts, you can forward it to us. diff --git a/gcc/f/g77spec.c b/gcc/f/g77spec.c deleted file mode 100755 index 3cc2ac7..0000000 --- a/gcc/f/g77spec.c +++ /dev/null @@ -1,577 +0,0 @@ -/* Specific flags and argument handling of the Fortran front-end. - Copyright (C) 1997 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file contains a filter for the main `gcc' driver, which is - replicated for the `g77' driver by adding this filter. The purpose - of this filter is to be basically identical to gcc (in that - it faithfully passes all of the original arguments to gcc) but, - unless explicitly overridden by the user in certain ways, ensure - that the needs of the language supported by this wrapper are met. - - For GNU Fortran (g77), we do the following to the argument list - before passing it to `gcc': - - 1. Make sure `-lg2c -lm' is at the end of the list. - - 2. Make sure each time `-lg2c' or `-lm' is seen, it forms - part of the series `-lg2c -lm'. - - #1 and #2 are not done if `-nostdlib' or any option that disables - the linking phase is present, or if `-xfoo' is in effect. Note that - a lack of source files or -l options disables linking. - - This program was originally made out of gcc/cp/g++spec.c, but the - way it builds the new argument list was rewritten so it is much - easier to maintain, improve the way it decides to add or not add - extra arguments, etc. And several improvements were made in the - handling of arguments, primarily to make it more consistent with - `gcc' itself. */ - -#include "config.h" -#include "system.h" -#include <f/version.h> - -#ifndef MATH_LIBRARY -#define MATH_LIBRARY "-lm" -#endif - -#ifndef FORTRAN_LIBRARY -#define FORTRAN_LIBRARY "-lg2c" -#endif - -/* Options this driver needs to recognize, not just know how to - skip over. */ -typedef enum -{ - OPTION_b, /* Aka --prefix. */ - OPTION_B, /* Aka --target. */ - OPTION_c, /* Aka --compile. */ - OPTION_driver, /* Wrapper-specific option. */ - OPTION_E, /* Aka --preprocess. */ - OPTION_help, /* --help. */ - OPTION_i, /* -imacros, -include, -include-*. */ - OPTION_l, - OPTION_L, /* Aka --library-directory. */ - OPTION_M, /* Aka --dependencies. */ - OPTION_MM, /* Aka --user-dependencies. */ - OPTION_nostdlib, /* Aka --no-standard-libraries, or - -nodefaultlibs. */ - OPTION_o, /* Aka --output. */ - OPTION_S, /* Aka --assemble. */ - OPTION_syntax_only, /* -fsyntax-only. */ - OPTION_v, /* Aka --verbose. */ - OPTION_version, /* --version. */ - OPTION_V, /* Aka --use-version. */ - OPTION_x, /* Aka --language. */ - OPTION_ /* Unrecognized or unimportant. */ -} Option; - -/* The original argument list and related info is copied here. */ -static int g77_xargc; -static char **g77_xargv; -static void (*g77_fn)(); - -/* The new argument list will be built here. */ -static int g77_newargc; -static char **g77_newargv; - -extern char *version_string; - -/* --- This comes from gcc.c (2.8.1) verbatim: */ - -/* This defines which switch letters take arguments. */ - -#define DEFAULT_SWITCH_TAKES_ARG(CHAR) \ - ((CHAR) == 'D' || (CHAR) == 'U' || (CHAR) == 'o' \ - || (CHAR) == 'e' || (CHAR) == 'T' || (CHAR) == 'u' \ - || (CHAR) == 'I' || (CHAR) == 'm' || (CHAR) == 'x' \ - || (CHAR) == 'L' || (CHAR) == 'A') - -#ifndef SWITCH_TAKES_ARG -#define SWITCH_TAKES_ARG(CHAR) DEFAULT_SWITCH_TAKES_ARG(CHAR) -#endif - -/* This defines which multi-letter switches take arguments. */ - -#define DEFAULT_WORD_SWITCH_TAKES_ARG(STR) \ - (!strcmp (STR, "Tdata") || !strcmp (STR, "Ttext") \ - || !strcmp (STR, "Tbss") || !strcmp (STR, "include") \ - || !strcmp (STR, "imacros") || !strcmp (STR, "aux-info") \ - || !strcmp (STR, "idirafter") || !strcmp (STR, "iprefix") \ - || !strcmp (STR, "iwithprefix") || !strcmp (STR, "iwithprefixbefore") \ - || !strcmp (STR, "isystem") || !strcmp (STR, "specs")) - -#ifndef WORD_SWITCH_TAKES_ARG -#define WORD_SWITCH_TAKES_ARG(STR) DEFAULT_WORD_SWITCH_TAKES_ARG (STR) -#endif - -/* --- End of verbatim. */ - -/* Assumes text[0] == '-'. Returns number of argv items that belong to - (and follow) this one, an option id for options important to the - caller, and a pointer to the first char of the arg, if embedded (else - returns NULL, meaning no arg or it's the next argv). - - Note that this also assumes gcc.c's pass converting long options - to short ones, where available, has already been run. */ - -static void -lookup_option (xopt, xskip, xarg, text) - Option *xopt; - int *xskip; - char **xarg; - char *text; -{ - Option opt = OPTION_; - int skip; - char *arg = NULL; - - if ((skip = SWITCH_TAKES_ARG (text[1]))) - skip -= (text[2] != '\0'); /* See gcc.c. */ - - if (text[1] == 'B') - opt = OPTION_B, skip = (text[2] == '\0'), arg = text + 2; - else if (text[1] == 'b') - opt = OPTION_b, skip = (text[2] == '\0'), arg = text + 2; - else if ((text[1] == 'c') && (text[2] == '\0')) - opt = OPTION_c, skip = 0; - else if ((text[1] == 'E') && (text[2] == '\0')) - opt = OPTION_E, skip = 0; - else if (text[1] == 'i') - opt = OPTION_i, skip = 0; - else if (text[1] == 'l') - opt = OPTION_l; - else if (text[1] == 'L') - opt = OPTION_L, arg = text + 2; - else if (text[1] == 'o') - opt = OPTION_o; - else if ((text[1] == 'S') && (text[2] == '\0')) - opt = OPTION_S, skip = 0; - else if (text[1] == 'V') - opt = OPTION_V, skip = (text[2] == '\0'); - else if ((text[1] == 'v') && (text[2] == '\0')) - opt = OPTION_v, skip = 0; - else if (text[1] == 'x') - opt = OPTION_x, arg = text + 2; - else - { - if ((skip = WORD_SWITCH_TAKES_ARG (text + 1)) != 0) /* See gcc.c. */ - ; - else if (! strncmp (text, "-fdriver", 8)) /* Really --driver!! */ - opt = OPTION_driver; /* Never mind arg, this is unsupported. */ - else if (! strcmp (text, "-fhelp")) /* Really --help!! */ - opt = OPTION_help; - else if (! strcmp (text, "-M")) - opt = OPTION_M; - else if (! strcmp (text, "-MM")) - opt = OPTION_MM; - else if (! strcmp (text, "-nostdlib") - || ! strcmp (text, "-nodefaultlibs")) - opt = OPTION_nostdlib; - else if (! strcmp (text, "-fsyntax-only")) - opt = OPTION_syntax_only; - else if (! strcmp (text, "-dumpversion")) - opt = OPTION_version; - else if (! strcmp (text, "-Xlinker") - || ! strcmp (text, "-specs")) - skip = 1; - else - skip = 0; - } - - if (xopt != NULL) - *xopt = opt; - if (xskip != NULL) - *xskip = skip; - if (xarg != NULL) - { - if ((arg != NULL) - && (arg[0] == '\0')) - *xarg = NULL; - else - *xarg = arg; - } -} - -/* Append another argument to the list being built. As long as it is - identical to the corresponding arg in the original list, just increment - the new arg count. Otherwise allocate a new list, etc. */ - -static void -append_arg (arg) - char *arg; -{ - static int newargsize; - -#if 0 - fprintf (stderr, "`%s'\n", arg); -#endif - - if (g77_newargv == g77_xargv - && g77_newargc < g77_xargc - && (arg == g77_xargv[g77_newargc] - || ! strcmp (arg, g77_xargv[g77_newargc]))) - { - ++g77_newargc; - return; /* Nothing new here. */ - } - - if (g77_newargv == g77_xargv) - { /* Make new arglist. */ - int i; - - newargsize = (g77_xargc << 2) + 20; /* This should handle all. */ - g77_newargv = (char **) xmalloc (newargsize * sizeof (char *)); - - /* Copy what has been done so far. */ - for (i = 0; i < g77_newargc; ++i) - g77_newargv[i] = g77_xargv[i]; - } - - if (g77_newargc == newargsize) - (*g77_fn) ("overflowed output arg list for `%s'", arg); - - g77_newargv[g77_newargc++] = arg; -} - -void -lang_specific_driver (fn, in_argc, in_argv, in_added_libraries) - void (*fn)(); - int *in_argc; - char ***in_argv; - int *in_added_libraries; -{ - int argc = *in_argc; - char **argv = *in_argv; - int i; - int verbose = 0; - Option opt; - int skip; - char *arg; - - /* This will be NULL if we encounter a situation where we should not - link in libf2c. */ - char *library = FORTRAN_LIBRARY; - - /* This will become 0 if anything other than -v and kin (like -V) - is seen, meaning the user is trying to accomplish something. - If it remains nonzero, and the user wants version info, add stuff to - the command line to make gcc invoke all the appropriate phases - to get all the version info. */ - int add_version_magic = 1; - - /* 0 => -xnone in effect. - 1 => -xfoo in effect. */ - int saw_speclang = 0; - - /* 0 => initial/reset state - 1 => last arg was -l<library> - 2 => last two args were -l<library> -lm. */ - int saw_library = 0; - - /* The number of input and output files in the incoming arg list. */ - int n_infiles = 0; - int n_outfiles = 0; - -#if 0 - fprintf (stderr, "Incoming:"); - for (i = 0; i < argc; i++) - fprintf (stderr, " %s", argv[i]); - fprintf (stderr, "\n"); -#endif - - g77_xargc = argc; - g77_xargv = argv; - g77_newargc = 0; - g77_newargv = argv; - g77_fn = fn; - - /* First pass through arglist. - - If -nostdlib or a "turn-off-linking" option is anywhere in the - command line, don't do any library-option processing (except - relating to -x). Also, if -v is specified, but no other options - that do anything special (allowing -V version, etc.), remember - to add special stuff to make gcc command actually invoke all - the different phases of the compilation process so all the version - numbers can be seen. - - Also, here is where all problems with missing arguments to options - are caught. If this loop is exited normally, it means all options - have the appropriate number of arguments as far as the rest of this - program is concerned. */ - - for (i = 1; i < argc; ++i) - { - if ((argv[i][0] == '+') && (argv[i][1] == 'e')) - { - add_version_magic = 0; - continue; - } - - if ((argv[i][0] != '-') || (argv[i][1] == '\0')) - { - ++n_infiles; - add_version_magic = 0; - continue; - } - - lookup_option (&opt, &skip, NULL, argv[i]); - - switch (opt) - { - case OPTION_nostdlib: - case OPTION_c: - case OPTION_S: - case OPTION_syntax_only: - case OPTION_E: - case OPTION_M: - case OPTION_MM: - /* These options disable linking entirely or linking of the - standard libraries. */ - library = 0; - add_version_magic = 0; - break; - - case OPTION_l: - ++n_infiles; - add_version_magic = 0; - break; - - case OPTION_o: - ++n_outfiles; - add_version_magic = 0; - break; - - case OPTION_v: - if (! verbose) - fprintf (stderr, "g77 version %s (from FSF-g77 version %s)\n", - version_string, ffe_version_string); - verbose = 1; - break; - - case OPTION_b: - case OPTION_B: - case OPTION_L: - case OPTION_i: - case OPTION_V: - /* These options are useful in conjunction with -v to get - appropriate version info. */ - break; - - case OPTION_version: - printf ("\ -GNU Fortran %s\n\ -Copyright (C) 1997 Free Software Foundation, Inc.\n\ -For more version information on components of the GNU Fortran\n\ -compilation system, especially useful when reporting bugs,\n\ -type the command `g77 --verbose'.\n\ -\n\ -GNU Fortran comes with NO WARRANTY, to the extent permitted by law.\n\ -You may redistribute copies of GNU Fortran\n\ -under the terms of the GNU General Public License.\n\ -For more information about these matters, see the file named COPYING\n\ -or type the command `info -f g77 Copying'.\n\ -", ffe_version_string); - exit (0); - break; - - case OPTION_help: - /* Let gcc.c handle this, as the egcs version has a really - cool facility for handling --help and --verbose --help. */ - return; - -#if 0 - printf ("\ -Usage: g77 [OPTION]... FORTRAN-SOURCE...\n\ -\n\ -Compile and link Fortran source code to produce an executable program,\n\ -which by default is named `a.out', and can be invoked with the UNIX\n\ -command `./a.out'.\n\ -\n\ -Options:\n\ ---debug include debugging information in executable.\n\ ---help display this help and exit.\n\ ---optimize[=LEVEL] take extra time and memory to make generated\n\ - executable run faster. LEVEL is 0 for no\n\ - optimization, 1 for normal optimization, and\n\ - increases through 3 for more optimization.\n\ ---output=PROGRAM name the executable PROGRAM instead of a.out;\n\ - invoke with the command `./PROGRAM'.\n\ ---version display version information and exit.\n\ -\n\ -Many other options exist to tailor the compilation process, specify\n\ -the dialect of the Fortran source code, specify details of the\n\ -code-generation methodology, and so on.\n\ -\n\ -For more information on g77 and gcc, type the commands `info -f g77'\n\ -and `info -f gcc' to read the Info documentation.\n\ -\n\ -Report bugs to <egcs-bugs@cygnus.org>.\n"); - exit (0); - break; -#endif - - case OPTION_driver: - (*fn) ("--driver no longer supported", argv[i]); - break; - - default: - add_version_magic = 0; - break; - } - - /* This is the one place we check for missing arguments in the - program. */ - - if (i + skip < argc) - i += skip; - else - (*fn) ("argument to `%s' missing", argv[i]); - } - - if ((n_outfiles != 0) && (n_infiles == 0)) - (*fn) ("No input files; unwilling to write output files"); - - /* Second pass through arglist, transforming arguments as appropriate. */ - - append_arg (argv[0]); /* Start with command name, of course. */ - - for (i = 1; i < argc; ++i) - { - if (argv[i][0] == '\0') - { - append_arg (argv[i]); /* Interesting. Just append as is. */ - continue; - } - - if ((argv[i][0] == '-') && (argv[i][1] != 'l')) - { - /* Not a filename or library. */ - - if (saw_library == 1) /* -l<library>. */ - append_arg (MATH_LIBRARY); - - saw_library = 0; - - lookup_option (&opt, &skip, &arg, argv[i]); - - if (argv[i][1] == '\0') - { - append_arg (argv[i]); /* "-" == Standard input. */ - continue; - } - - if (opt == OPTION_x) - { - /* Track input language. */ - char *lang; - - if (arg == NULL) - lang = argv[i+1]; - else - lang = arg; - - saw_speclang = (strcmp (lang, "none") != 0); - } - - append_arg (argv[i]); - - for (; skip != 0; --skip) - append_arg (argv[++i]); - - continue; - } - - /* A filename/library, not an option. */ - - if (saw_speclang) - saw_library = 0; /* -xfoo currently active. */ - else - { /* -lfoo or filename. */ - if (strcmp (argv[i], MATH_LIBRARY) == 0 -#ifdef ALT_LIBM - || strcmp (argv[i], ALT_LIBM) == 0 -#endif - ) - { - if (saw_library == 1) - saw_library = 2; /* -l<library> -lm. */ - else - append_arg (FORTRAN_LIBRARY); - } - else if (strcmp (argv[i], FORTRAN_LIBRARY) == 0) - saw_library = 1; /* -l<library>. */ - else - { /* Other library, or filename. */ - if (saw_library == 1) - append_arg (MATH_LIBRARY); - saw_library = 0; - } - } - append_arg (argv[i]); - } - - /* Append `-lg2c -lm' as necessary. */ - - if (! add_version_magic && library) - { /* Doing a link and no -nostdlib. */ - if (saw_speclang) - append_arg ("-xnone"); - - switch (saw_library) - { - case 0: - append_arg (library); - case 1: - append_arg (MATH_LIBRARY); - default: - break; - } - } - else if (add_version_magic && verbose) - { - append_arg ("-c"); - append_arg ("-xf77-version"); - append_arg ("/dev/null"); - append_arg ("-xnone"); - } - - if (verbose - && g77_newargv != g77_xargv) - { - fprintf (stderr, "Driving:"); - for (i = 0; i < g77_newargc; i++) - fprintf (stderr, " %s", g77_newargv[i]); - fprintf (stderr, "\n"); - } - - *in_argc = g77_newargc; - *in_argv = g77_newargv; -} - -/* Called before linking. Returns 0 on success and -1 on failure. */ -int lang_specific_pre_link () /* Not used for F77. */ -{ - return 0; -} - -/* Number of extra output files that lang_specific_pre_link may generate. */ -int lang_specific_extra_outfiles = 0; /* Not used for F77. */ diff --git a/gcc/f/glimits.j b/gcc/f/glimits.j deleted file mode 100755 index 5d5406c..0000000 --- a/gcc/f/glimits.j +++ /dev/null @@ -1,28 +0,0 @@ -/* glimits.j -- Wrapper for GCC's glimits.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#if !USE_HOST_LIMITS -#include "glimits.h" -#else -#include <limits.h> -#endif -#endif diff --git a/gcc/f/global.c b/gcc/f/global.c deleted file mode 100755 index 8be7d0c..0000000 --- a/gcc/f/global.c +++ /dev/null @@ -1,1536 +0,0 @@ -/* global.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - - Description: - Manages information kept across individual program units within a single - source file. This includes reporting errors when a name is defined - multiple times (for example, two program units named FOO) and when a - COMMON block is given initial data in more than one program unit. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "global.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" -#include "name.h" -#include "symbol.h" -#include "top.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -#if FFEGLOBAL_ENABLED -static ffenameSpace ffeglobal_filewide_ = NULL; -static char *ffeglobal_type_string_[] = -{ - [FFEGLOBAL_typeNONE] "??", - [FFEGLOBAL_typeMAIN] "main program", - [FFEGLOBAL_typeEXT] "external", - [FFEGLOBAL_typeSUBR] "subroutine", - [FFEGLOBAL_typeFUNC] "function", - [FFEGLOBAL_typeBDATA] "block data", - [FFEGLOBAL_typeCOMMON] "common block", - [FFEGLOBAL_typeANY] "?any?" -}; -#endif - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* Call given fn with all globals - - ffeglobal (*fn)(ffeglobal g); - ffeglobal_drive(fn); */ - -#if FFEGLOBAL_ENABLED -void -ffeglobal_drive (ffeglobal (*fn) ()) -{ - if (ffeglobal_filewide_ != NULL) - ffename_space_drive_global (ffeglobal_filewide_, fn); -} - -#endif -/* ffeglobal_new_ -- Make new global - - ffename n; - ffeglobal g; - g = ffeglobal_new_(n); */ - -#if FFEGLOBAL_ENABLED -static ffeglobal -ffeglobal_new_ (ffename n) -{ - ffeglobal g; - - assert (n != NULL); - - g = (ffeglobal) malloc_new_ks (malloc_pool_image (), "FFEGLOBAL", - sizeof (*g)); - g->n = n; -#ifdef FFECOM_globalHOOK - g->hook = FFECOM_globalNULL; -#endif - g->tick = 0; - - ffename_set_global (n, g); - - return g; -} - -#endif -/* ffeglobal_init_1 -- Initialize per file - - ffeglobal_init_1(); */ - -void -ffeglobal_init_1 () -{ -#if FFEGLOBAL_ENABLED - if (ffeglobal_filewide_ != NULL) - ffename_space_kill (ffeglobal_filewide_); - ffeglobal_filewide_ = ffename_space_new (malloc_pool_image ()); -#endif -} - -/* ffeglobal_init_common -- Initial value specified for common block - - ffesymbol s; // the ffesymbol for the common block - ffelexToken t; // the token with the point of initialization - ffeglobal_init_common(s,t); - - For back ends where file-wide global symbols are not maintained, does - nothing. Otherwise, makes sure this common block hasn't already been - initialized in a previous program unit, and flag that it's been - initialized in this one. */ - -void -ffeglobal_init_common (ffesymbol s, ffelexToken t) -{ -#if FFEGLOBAL_ENABLED - ffeglobal g; - - g = ffesymbol_global (s); - - if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON)) - return; - if (g->type == FFEGLOBAL_typeANY) - return; - - if (g->tick == ffe_count_2) - return; - - if (g->tick != 0) - { - if (g->u.common.initt != NULL) - { - ffebad_start (FFEBAD_COMMON_ALREADY_INIT); - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->u.common.initt), - ffelex_token_where_column (g->u.common.initt)); - ffebad_finish (); - } - - /* Complain about just one attempt to reinit per program unit, but - continue referring back to the first such successful attempt. */ - } - else - { - if (g->u.common.blank) - { - ffebad_start (FFEBAD_COMMON_BLANK_INIT); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - - g->u.common.initt = ffelex_token_use (t); - } - - g->tick = ffe_count_2; -#endif -} - -/* ffeglobal_new_common -- New common block - - ffesymbol s; // the ffesymbol for the new common block - ffelexToken t; // the token with the name of the common block - bool blank; // TRUE if blank common - ffeglobal_new_common(s,t,blank); - - For back ends where file-wide global symbols are not maintained, does - nothing. Otherwise, makes sure this symbol hasn't been seen before or - is known as a common block. */ - -void -ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank) -{ -#if FFEGLOBAL_ENABLED - ffename n; - ffeglobal g; - - if (ffesymbol_global (s) == NULL) - { - n = ffename_find (ffeglobal_filewide_, t); - g = ffename_global (n); - } - else - { - g = ffesymbol_global (s); - n = NULL; - } - - if ((g != NULL) && (g->type == FFEGLOBAL_typeANY)) - return; - - if ((g != NULL) && (g->type != FFEGLOBAL_typeNONE)) - { - if (g->type == FFEGLOBAL_typeCOMMON) - { - assert (g->u.common.blank == blank); - } - else - { - if (ffe_is_globals () || ffe_is_warn_globals ()) - { - ffebad_start (ffe_is_globals () - ? FFEBAD_FILEWIDE_ALREADY_SEEN - : FFEBAD_FILEWIDE_ALREADY_SEEN_W); - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->type = FFEGLOBAL_typeANY; - } - } - else - { - if (g == NULL) - { - g = ffeglobal_new_ (n); - g->intrinsic = FALSE; - } - else if (g->intrinsic - && !g->explicit_intrinsic - && ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_INTRINSIC_GLOBAL); - ffebad_string (ffelex_token_text (t)); - ffebad_string ("common block"); - ffebad_string ("intrinsic"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->t = ffelex_token_use (t); - g->type = FFEGLOBAL_typeCOMMON; - g->u.common.have_pad = FALSE; - g->u.common.have_save = FALSE; - g->u.common.have_size = FALSE; - g->u.common.blank = blank; - } - - ffesymbol_set_global (s, g); -#endif -} - -/* ffeglobal_new_progunit_ -- New program unit - - ffesymbol s; // the ffesymbol for the new unit - ffelexToken t; // the token with the name of the unit - ffeglobalType type; // the type of the new unit - ffeglobal_new_progunit_(s,t,type); - - For back ends where file-wide global symbols are not maintained, does - nothing. Otherwise, makes sure this symbol hasn't been seen before. */ - -void -ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type) -{ -#if FFEGLOBAL_ENABLED - ffename n; - ffeglobal g; - - n = ffename_find (ffeglobal_filewide_, t); - g = ffename_global (n); - if ((g != NULL) && (g->type == FFEGLOBAL_typeANY)) - return; - - if ((g != NULL) - && ((g->type == FFEGLOBAL_typeMAIN) - || (g->type == FFEGLOBAL_typeSUBR) - || (g->type == FFEGLOBAL_typeFUNC) - || (g->type == FFEGLOBAL_typeBDATA)) - && g->u.proc.defined) - { - if (ffe_is_globals () || ffe_is_warn_globals ()) - { - ffebad_start (ffe_is_globals () - ? FFEBAD_FILEWIDE_ALREADY_SEEN - : FFEBAD_FILEWIDE_ALREADY_SEEN_W); - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->type = FFEGLOBAL_typeANY; - } - else if ((g != NULL) - && (g->type != FFEGLOBAL_typeNONE) - && (g->type != FFEGLOBAL_typeEXT) - && (g->type != type)) - { - if (ffe_is_globals () || ffe_is_warn_globals ()) - { - ffebad_start (ffe_is_globals () - ? FFEBAD_FILEWIDE_DISAGREEMENT - : FFEBAD_FILEWIDE_DISAGREEMENT_W); - ffebad_string (ffelex_token_text (t)); - ffebad_string (ffeglobal_type_string_[type]); - ffebad_string (ffeglobal_type_string_[g->type]); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->type = FFEGLOBAL_typeANY; - } - else - { - if (g == NULL) - { - g = ffeglobal_new_ (n); - g->intrinsic = FALSE; - g->u.proc.n_args = -1; - g->u.proc.other_t = NULL; - } - else if ((ffesymbol_basictype (s) != FFEINFO_basictypeNONE) - && ((ffesymbol_basictype (s) != g->u.proc.bt) - || (ffesymbol_kindtype (s) != g->u.proc.kt) - || ((ffesymbol_size (s) != FFETARGET_charactersizeNONE) - && (ffesymbol_size (s) != g->u.proc.sz)))) - { - if (ffe_is_globals () || ffe_is_warn_globals ()) - { - ffebad_start (ffe_is_globals () - ? FFEBAD_FILEWIDE_TYPE_MISMATCH - : FFEBAD_FILEWIDE_TYPE_MISMATCH_W); - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->type = FFEGLOBAL_typeANY; - return; - } - if (g->intrinsic - && !g->explicit_intrinsic - && ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_INTRINSIC_GLOBAL); - ffebad_string (ffelex_token_text (t)); - ffebad_string ("global"); - ffebad_string ("intrinsic"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->t = ffelex_token_use (t); - if ((g->tick == 0) - || (g->u.proc.bt == FFEINFO_basictypeNONE) - || (g->u.proc.kt == FFEINFO_kindtypeNONE)) - { - g->u.proc.bt = ffesymbol_basictype (s); - g->u.proc.kt = ffesymbol_kindtype (s); - g->u.proc.sz = ffesymbol_size (s); - } - g->tick = ffe_count_2; - if ((g->tick != 0) - && (g->type != type)) - g->u.proc.n_args = -1; - g->type = type; - g->u.proc.defined = TRUE; - } - - ffesymbol_set_global (s, g); -#endif -} - -/* ffeglobal_pad_common -- Check initial padding of common area - - ffesymbol s; // the common area - ffetargetAlign pad; // the initial padding - ffeglobal_pad_common(s,pad,ffesymbol_where_line(s), - ffesymbol_where_column(s)); - - In global-enabled mode, make sure the padding agrees with any existing - padding established for the common area, otherwise complain. - In global-disabled mode, warn about nonzero padding. */ - -void -ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl, - ffewhereColumn wc) -{ -#if FFEGLOBAL_ENABLED - ffeglobal g; - - g = ffesymbol_global (s); - if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON)) - return; /* Let someone else catch this! */ - if (g->type == FFEGLOBAL_typeANY) - return; - - if (!g->u.common.have_pad) - { - g->u.common.have_pad = TRUE; - g->u.common.pad = pad; - g->u.common.pad_where_line = ffewhere_line_use (wl); - g->u.common.pad_where_col = ffewhere_column_use (wc); - - if (pad != 0) - { - char padding[20]; - - sprintf (&padding[0], "%" ffetargetAlign_f "u", pad); - ffebad_start (FFEBAD_COMMON_INIT_PAD); - ffebad_string (ffesymbol_text (s)); - ffebad_string (padding); - ffebad_string ((pad == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_here (0, wl, wc); - ffebad_finish (); - } - } - else - { - if (g->u.common.pad != pad) - { - char padding_1[20]; - char padding_2[20]; - - sprintf (&padding_1[0], "%" ffetargetAlign_f "u", pad); - sprintf (&padding_2[0], "%" ffetargetAlign_f "u", g->u.common.pad); - ffebad_start (FFEBAD_COMMON_DIFF_PAD); - ffebad_string (ffesymbol_text (s)); - ffebad_string (padding_1); - ffebad_here (0, wl, wc); - ffebad_string (padding_2); - ffebad_string ((pad == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_string ((g->u.common.pad == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_here (1, g->u.common.pad_where_line, g->u.common.pad_where_col); - ffebad_finish (); - } - - if (g->u.common.pad < pad) - { - g->u.common.pad = pad; - g->u.common.pad_where_line = ffewhere_line_use (wl); - g->u.common.pad_where_col = ffewhere_column_use (wc); - } - } -#endif -} - -/* Collect info for a global's argument. */ - -void -ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary as, - ffeinfoBasictype bt, ffeinfoKindtype kt, - bool array) -{ - ffeglobal g = ffesymbol_global (s); - ffeglobalArgInfo_ ai; - - assert (g != NULL); - - if (g->type == FFEGLOBAL_typeANY) - return; - - assert (g->u.proc.n_args >= 0); - - if (argno >= g->u.proc.n_args) - return; /* Already complained about this discrepancy. */ - - ai = &g->u.proc.arg_info[argno]; - - /* Maybe warn about previous references. */ - - if ((ai->t != NULL) - && ffe_is_warn_globals ()) - { - char *refwhy = NULL; - char *defwhy = NULL; - bool warn = FALSE; - - switch (as) - { - case FFEGLOBAL_argsummaryREF: - if ((ai->as != FFEGLOBAL_argsummaryREF) - && (ai->as != FFEGLOBAL_argsummaryNONE) - && ((ai->as != FFEGLOBAL_argsummaryDESCR) /* Choose better message. */ - || (ai->bt != FFEINFO_basictypeCHARACTER) - || (ai->bt == bt))) - { - warn = TRUE; - refwhy = "passed by reference"; - } - break; - - case FFEGLOBAL_argsummaryDESCR: - if ((ai->as != FFEGLOBAL_argsummaryDESCR) - && (ai->as != FFEGLOBAL_argsummaryNONE) - && ((ai->as != FFEGLOBAL_argsummaryREF) /* Choose better message. */ - || (bt != FFEINFO_basictypeCHARACTER) - || (ai->bt == bt))) - { - warn = TRUE; - refwhy = "passed by descriptor"; - } - break; - - case FFEGLOBAL_argsummaryPROC: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummarySUBR) - && (ai->as != FFEGLOBAL_argsummaryFUNC) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - warn = TRUE; - refwhy = "a procedure"; - } - break; - - case FFEGLOBAL_argsummarySUBR: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummarySUBR) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - warn = TRUE; - refwhy = "a subroutine"; - } - break; - - case FFEGLOBAL_argsummaryFUNC: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummaryFUNC) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - warn = TRUE; - refwhy = "a function"; - } - break; - - case FFEGLOBAL_argsummaryALTRTN: - if ((ai->as != FFEGLOBAL_argsummaryALTRTN) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - warn = TRUE; - refwhy = "an alternate-return label"; - } - break; - - default: - break; - } - - if ((refwhy != NULL) && (defwhy == NULL)) - { - /* Fill in the def info. */ - - switch (ai->as) - { - case FFEGLOBAL_argsummaryNONE: - defwhy = "omitted"; - break; - - case FFEGLOBAL_argsummaryVAL: - defwhy = "passed by value"; - break; - - case FFEGLOBAL_argsummaryREF: - defwhy = "passed by reference"; - break; - - case FFEGLOBAL_argsummaryDESCR: - defwhy = "passed by descriptor"; - break; - - case FFEGLOBAL_argsummaryPROC: - defwhy = "a procedure"; - break; - - case FFEGLOBAL_argsummarySUBR: - defwhy = "a subroutine"; - break; - - case FFEGLOBAL_argsummaryFUNC: - defwhy = "a function"; - break; - - case FFEGLOBAL_argsummaryALTRTN: - defwhy = "an alternate-return label"; - break; - -#if 0 - case FFEGLOBAL_argsummaryPTR: - defwhy = "a pointer"; - break; -#endif - - default: - defwhy = "???"; - break; - } - } - - if (!warn - && (bt != FFEINFO_basictypeHOLLERITH) - && (bt != FFEINFO_basictypeTYPELESS) - && (bt != FFEINFO_basictypeNONE) - && (ai->bt != FFEINFO_basictypeHOLLERITH) - && (ai->bt != FFEINFO_basictypeTYPELESS) - && (ai->bt != FFEINFO_basictypeNONE)) - { - /* Check types. */ - - if ((bt != ai->bt) - && ((bt != FFEINFO_basictypeREAL) - || (ai->bt != FFEINFO_basictypeCOMPLEX)) - && ((bt != FFEINFO_basictypeCOMPLEX) - || (ai->bt != FFEINFO_basictypeREAL))) - { - warn = TRUE; /* We can cope with these differences. */ - refwhy = "one type"; - defwhy = "some other type"; - } - - if (!warn && (kt != ai->kt)) - { - warn = TRUE; - refwhy = "one precision"; - defwhy = "some other precision"; - } - } - - if (warn) - { - char num[60]; - - if (name == NULL) - sprintf (&num[0], "%d", argno + 1); - else - { - if (strlen (name) < 30) - sprintf (&num[0], "%d (named `%s')", argno + 1, name); - else - sprintf (&num[0], "%d (named `%.*s...')", argno + 1, 30, name); - } - ffebad_start (FFEBAD_FILEWIDE_ARG_W); - ffebad_string (ffesymbol_text (s)); - ffebad_string (num); - ffebad_string (refwhy); - ffebad_string (defwhy); - ffebad_here (0, ffelex_token_where_line (g->t), ffelex_token_where_column (g->t)); - ffebad_here (1, ffelex_token_where_line (ai->t), ffelex_token_where_column (ai->t)); - ffebad_finish (); - } - } - - /* Define this argument. */ - - if (ai->t != NULL) - ffelex_token_kill (ai->t); - if ((as != FFEGLOBAL_argsummaryPROC) - || (ai->t == NULL)) - ai->as = as; /* Otherwise leave SUBR/FUNC info intact. */ - ai->t = ffelex_token_use (g->t); - if (name == NULL) - ai->name = NULL; - else - { - ai->name = malloc_new_ks (malloc_pool_image (), - "ffeglobalArgInfo_ name", - strlen (name) + 1); - strcpy (ai->name, name); - } - ai->bt = bt; - ai->kt = kt; - ai->array = array; -} - -/* Collect info on #args a global accepts. */ - -void -ffeglobal_proc_def_nargs (ffesymbol s, int n_args) -{ - ffeglobal g = ffesymbol_global (s); - - assert (g != NULL); - - if (g->type == FFEGLOBAL_typeANY) - return; - - if (g->u.proc.n_args >= 0) - { - if (g->u.proc.n_args == n_args) - return; - - if (ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_NARGS_W); - ffebad_string (ffesymbol_text (s)); - if (g->u.proc.n_args > n_args) - ffebad_string ("few"); - else - ffebad_string ("many"); - ffebad_here (0, ffelex_token_where_line (g->u.proc.other_t), - ffelex_token_where_column (g->u.proc.other_t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - } - - /* This is new info we can use in cross-checking future references - and a possible future definition. */ - - g->u.proc.n_args = n_args; - g->u.proc.other_t = NULL; /* No other reference yet. */ - - if (n_args == 0) - { - g->u.proc.arg_info = NULL; - return; - } - - g->u.proc.arg_info - = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (), - "ffeglobalArgInfo_", - n_args * sizeof (g->u.proc.arg_info[0])); - while (n_args-- > 0) - g->u.proc.arg_info[n_args].t = NULL; -} - -/* Verify that the info for a global's argument is valid. */ - -bool -ffeglobal_proc_ref_arg (ffesymbol s, int argno, ffeglobalArgSummary as, - ffeinfoBasictype bt, ffeinfoKindtype kt, - bool array, ffelexToken t) -{ - ffeglobal g = ffesymbol_global (s); - ffeglobalArgInfo_ ai; - - assert (g != NULL); - - if (g->type == FFEGLOBAL_typeANY) - return FALSE; - - assert (g->u.proc.n_args >= 0); - - if (argno >= g->u.proc.n_args) - return TRUE; /* Already complained about this discrepancy. */ - - ai = &g->u.proc.arg_info[argno]; - - /* Warn about previous references. */ - - if (ai->t != NULL) - { - char *refwhy = NULL; - char *defwhy = NULL; - bool fail = FALSE; - bool warn = FALSE; - - switch (as) - { - case FFEGLOBAL_argsummaryNONE: - if (g->u.proc.defined) - { - fail = TRUE; - refwhy = "omitted"; - defwhy = "not optional"; - } - break; - - case FFEGLOBAL_argsummaryVAL: - if (ai->as != FFEGLOBAL_argsummaryVAL) - { - fail = TRUE; - refwhy = "passed by value"; - } - break; - - case FFEGLOBAL_argsummaryREF: - if ((ai->as != FFEGLOBAL_argsummaryREF) - && (ai->as != FFEGLOBAL_argsummaryNONE) - && ((ai->as != FFEGLOBAL_argsummaryDESCR) /* Choose better message. */ - || (ai->bt != FFEINFO_basictypeCHARACTER) - || (ai->bt == bt))) - { - fail = TRUE; - refwhy = "passed by reference"; - } - break; - - case FFEGLOBAL_argsummaryDESCR: - if ((ai->as != FFEGLOBAL_argsummaryDESCR) - && (ai->as != FFEGLOBAL_argsummaryNONE) - && ((ai->as != FFEGLOBAL_argsummaryREF) /* Choose better message. */ - || (bt != FFEINFO_basictypeCHARACTER) - || (ai->bt == bt))) - { - fail = TRUE; - refwhy = "passed by descriptor"; - } - break; - - case FFEGLOBAL_argsummaryPROC: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummarySUBR) - && (ai->as != FFEGLOBAL_argsummaryFUNC) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - fail = TRUE; - refwhy = "a procedure"; - } - break; - - case FFEGLOBAL_argsummarySUBR: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummarySUBR) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - fail = TRUE; - refwhy = "a subroutine"; - } - break; - - case FFEGLOBAL_argsummaryFUNC: - if ((ai->as != FFEGLOBAL_argsummaryPROC) - && (ai->as != FFEGLOBAL_argsummaryFUNC) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - fail = TRUE; - refwhy = "a function"; - } - break; - - case FFEGLOBAL_argsummaryALTRTN: - if ((ai->as != FFEGLOBAL_argsummaryALTRTN) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - fail = TRUE; - refwhy = "an alternate-return label"; - } - break; - -#if 0 - case FFEGLOBAL_argsummaryPTR: - if ((ai->as != FFEGLOBAL_argsummaryPTR) - && (ai->as != FFEGLOBAL_argsummaryNONE)) - { - fail = TRUE; - refwhy = "a pointer"; - } - break; -#endif - - default: - break; - } - - if ((refwhy != NULL) && (defwhy == NULL)) - { - /* Fill in the def info. */ - - switch (ai->as) - { - case FFEGLOBAL_argsummaryNONE: - defwhy = "omitted"; - break; - - case FFEGLOBAL_argsummaryVAL: - defwhy = "passed by value"; - break; - - case FFEGLOBAL_argsummaryREF: - defwhy = "passed by reference"; - break; - - case FFEGLOBAL_argsummaryDESCR: - defwhy = "passed by descriptor"; - break; - - case FFEGLOBAL_argsummaryPROC: - defwhy = "a procedure"; - break; - - case FFEGLOBAL_argsummarySUBR: - defwhy = "a subroutine"; - break; - - case FFEGLOBAL_argsummaryFUNC: - defwhy = "a function"; - break; - - case FFEGLOBAL_argsummaryALTRTN: - defwhy = "an alternate-return label"; - break; - -#if 0 - case FFEGLOBAL_argsummaryPTR: - defwhy = "a pointer"; - break; -#endif - - default: - defwhy = "???"; - break; - } - } - - if (!fail && !warn - && (bt != FFEINFO_basictypeHOLLERITH) - && (bt != FFEINFO_basictypeTYPELESS) - && (bt != FFEINFO_basictypeNONE) - && (ai->bt != FFEINFO_basictypeHOLLERITH) - && (ai->bt != FFEINFO_basictypeNONE) - && (ai->bt != FFEINFO_basictypeTYPELESS)) - { - /* Check types. */ - - if ((bt != ai->bt) - && ((bt != FFEINFO_basictypeREAL) - || (ai->bt != FFEINFO_basictypeCOMPLEX)) - && ((bt != FFEINFO_basictypeCOMPLEX) - || (ai->bt != FFEINFO_basictypeREAL))) - { - if (((bt == FFEINFO_basictypeINTEGER) - && (ai->bt == FFEINFO_basictypeLOGICAL)) - || ((bt == FFEINFO_basictypeLOGICAL) - && (ai->bt == FFEINFO_basictypeINTEGER))) - warn = TRUE; /* We can cope with these differences. */ - else - fail = TRUE; - refwhy = "one type"; - defwhy = "some other type"; - } - - if (!fail && !warn && (kt != ai->kt)) - { - fail = TRUE; - refwhy = "one precision"; - defwhy = "some other precision"; - } - } - - if (fail && ! g->u.proc.defined) - { - /* No point failing if we're worried only about invocations. */ - fail = FALSE; - warn = TRUE; - } - - if (fail && ! ffe_is_globals ()) - { - warn = TRUE; - fail = FALSE; - } - - if (fail || (warn && ffe_is_warn_globals ())) - { - char num[60]; - - if (ai->name == NULL) - sprintf (&num[0], "%d", argno + 1); - else - { - if (strlen (ai->name) < 30) - sprintf (&num[0], "%d (named `%s')", argno + 1, ai->name); - else - sprintf (&num[0], "%d (named `%.*s...')", argno + 1, 30, ai->name); - } - ffebad_start (fail ? FFEBAD_FILEWIDE_ARG : FFEBAD_FILEWIDE_ARG_W); - ffebad_string (ffesymbol_text (s)); - ffebad_string (num); - ffebad_string (refwhy); - ffebad_string (defwhy); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (ai->t), ffelex_token_where_column (ai->t)); - ffebad_finish (); - return (fail ? FALSE : TRUE); - } - - if (warn) - return TRUE; - } - - /* Define this argument. */ - - if (ai->t != NULL) - ffelex_token_kill (ai->t); - if ((as != FFEGLOBAL_argsummaryPROC) - || (ai->t == NULL)) - ai->as = as; - ai->t = ffelex_token_use (g->t); - ai->name = NULL; - ai->bt = bt; - ai->kt = kt; - ai->array = array; - return TRUE; -} - -bool -ffeglobal_proc_ref_nargs (ffesymbol s, int n_args, ffelexToken t) -{ - ffeglobal g = ffesymbol_global (s); - - assert (g != NULL); - - if (g->type == FFEGLOBAL_typeANY) - return FALSE; - - if (g->u.proc.n_args >= 0) - { - if (g->u.proc.n_args == n_args) - return TRUE; - - if (g->u.proc.defined && ffe_is_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_NARGS); - ffebad_string (ffesymbol_text (s)); - if (g->u.proc.n_args > n_args) - ffebad_string ("few"); - else - ffebad_string ("many"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - return FALSE; - } - - if (ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_NARGS_W); - ffebad_string (ffesymbol_text (s)); - if (g->u.proc.n_args > n_args) - ffebad_string ("few"); - else - ffebad_string ("many"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - - return TRUE; /* Don't replace the info we already have. */ - } - - /* This is new info we can use in cross-checking future references - and a possible future definition. */ - - g->u.proc.n_args = n_args; - g->u.proc.other_t = ffelex_token_use (t); - - /* Make this "the" place we found the global, since it has the most info. */ - - if (g->t != NULL) - ffelex_token_kill (g->t); - g->t = ffelex_token_use (t); - - if (n_args == 0) - { - g->u.proc.arg_info = NULL; - return TRUE; - } - - g->u.proc.arg_info - = (ffeglobalArgInfo_) malloc_new_ks (malloc_pool_image (), - "ffeglobalArgInfo_", - n_args * sizeof (g->u.proc.arg_info[0])); - while (n_args-- > 0) - g->u.proc.arg_info[n_args].t = NULL; - - return TRUE; -} - -/* Return a global for a promoted symbol (one that has heretofore - been assumed to be local, but since discovered to be global). */ - -ffeglobal -ffeglobal_promoted (ffesymbol s) -{ -#if FFEGLOBAL_ENABLED - ffename n; - ffeglobal g; - - assert (ffesymbol_global (s) == NULL); - - n = ffename_find (ffeglobal_filewide_, ffename_token (ffesymbol_name (s))); - g = ffename_global (n); - - return g; -#else - return NULL; -#endif -} - -/* Register a reference to an intrinsic. Such a reference is always - valid, though a warning might be in order if the same name has - already been used for a global. */ - -void -ffeglobal_ref_intrinsic (ffesymbol s, ffelexToken t, bool explicit) -{ -#if FFEGLOBAL_ENABLED - ffename n; - ffeglobal g; - - if (ffesymbol_global (s) == NULL) - { - n = ffename_find (ffeglobal_filewide_, t); - g = ffename_global (n); - } - else - { - g = ffesymbol_global (s); - n = NULL; - } - - if ((g != NULL) && (g->type == FFEGLOBAL_typeANY)) - return; - - if ((g != NULL) && (g->type != FFEGLOBAL_typeNONE)) - { - if (! explicit - && ! g->intrinsic - && ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_INTRINSIC_GLOBAL); - ffebad_string (ffelex_token_text (t)); - ffebad_string ("intrinsic"); - ffebad_string ("global"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - } - else - { - if (g == NULL) - { - g = ffeglobal_new_ (n); - g->tick = ffe_count_2; - g->type = FFEGLOBAL_typeNONE; - g->intrinsic = TRUE; - g->explicit_intrinsic = explicit; - g->t = ffelex_token_use (t); - } - else if (g->intrinsic - && (explicit != g->explicit_intrinsic) - && (g->tick != ffe_count_2) - && ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_INTRINSIC_EXPIMP); - ffebad_string (ffelex_token_text (t)); - ffebad_string (explicit ? "explicit" : "implicit"); - ffebad_string (explicit ? "implicit" : "explicit"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - } - - g->intrinsic = TRUE; - if (explicit) - g->explicit_intrinsic = TRUE; - - ffesymbol_set_global (s, g); -#endif -} - -/* Register a reference to a global. Returns TRUE if the reference - is valid. */ - -bool -ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type) -{ -#if FFEGLOBAL_ENABLED - ffename n = NULL; - ffeglobal g; - - /* It is never really _known_ that an EXTERNAL statement - names a BLOCK DATA by just looking at the program unit, - so override a different notion here. */ - if (type == FFEGLOBAL_typeBDATA) - type = FFEGLOBAL_typeEXT; - - g = ffesymbol_global (s); - if (g == NULL) - { - n = ffename_find (ffeglobal_filewide_, t); - g = ffename_global (n); - if (g != NULL) - ffesymbol_set_global (s, g); - } - - if ((g != NULL) && (g->type == FFEGLOBAL_typeANY)) - return TRUE; - - if ((g != NULL) - && (g->type != FFEGLOBAL_typeNONE) - && (g->type != type) - && (g->type != FFEGLOBAL_typeEXT) - && (type != FFEGLOBAL_typeEXT)) - { - if ((((type == FFEGLOBAL_typeBDATA) - && (g->type != FFEGLOBAL_typeCOMMON)) - || ((g->type == FFEGLOBAL_typeBDATA) - && (type != FFEGLOBAL_typeCOMMON) - && ! g->u.proc.defined))) - { -#if 0 /* This is likely to just annoy people. */ - if (ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_TIFF); - ffebad_string (ffelex_token_text (t)); - ffebad_string (ffeglobal_type_string_[type]); - ffebad_string (ffeglobal_type_string_[g->type]); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } -#endif - } - else if (ffe_is_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT); - ffebad_string (ffelex_token_text (t)); - ffebad_string (ffeglobal_type_string_[type]); - ffebad_string (ffeglobal_type_string_[g->type]); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - g->type = FFEGLOBAL_typeANY; - return FALSE; - } - else if (ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_DISAGREEMENT_W); - ffebad_string (ffelex_token_text (t)); - ffebad_string (ffeglobal_type_string_[type]); - ffebad_string (ffeglobal_type_string_[g->type]); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - g->type = FFEGLOBAL_typeANY; - return TRUE; - } - } - - if ((g != NULL) - && (type == FFEGLOBAL_typeFUNC)) - { - /* If just filling in this function's type, do so. */ - if ((g->tick == ffe_count_2) - && (ffesymbol_basictype (s) != FFEINFO_basictypeNONE) - && (ffesymbol_kindtype (s) != FFEINFO_kindtypeNONE)) - { - g->u.proc.bt = ffesymbol_basictype (s); - g->u.proc.kt = ffesymbol_kindtype (s); - g->u.proc.sz = ffesymbol_size (s); - } - /* Else, make sure there is type agreement. */ - else if ((g->u.proc.bt != FFEINFO_basictypeNONE) - && (ffesymbol_basictype (s) != FFEINFO_basictypeNONE) - && ((ffesymbol_basictype (s) != g->u.proc.bt) - || (ffesymbol_kindtype (s) != g->u.proc.kt) - || ((ffesymbol_size (s) != g->u.proc.sz) - && g->u.proc.defined - && (g->u.proc.sz != FFETARGET_charactersizeNONE)))) - { - if (ffe_is_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH); - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - g->type = FFEGLOBAL_typeANY; - return FALSE; - } - if (ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_FILEWIDE_TYPE_MISMATCH_W); - ffebad_string (ffelex_token_text (t)); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - g->type = FFEGLOBAL_typeANY; - return TRUE; - } - } - - if (g == NULL) - { - g = ffeglobal_new_ (n); - g->t = ffelex_token_use (t); - g->tick = ffe_count_2; - g->intrinsic = FALSE; - g->type = type; - g->u.proc.defined = FALSE; - g->u.proc.bt = ffesymbol_basictype (s); - g->u.proc.kt = ffesymbol_kindtype (s); - g->u.proc.sz = ffesymbol_size (s); - g->u.proc.n_args = -1; - ffesymbol_set_global (s, g); - } - else if (g->intrinsic - && !g->explicit_intrinsic - && (g->tick != ffe_count_2) - && ffe_is_warn_globals ()) - { - ffebad_start (FFEBAD_INTRINSIC_GLOBAL); - ffebad_string (ffelex_token_text (t)); - ffebad_string ("global"); - ffebad_string ("intrinsic"); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_here (1, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_finish (); - } - - if ((g->type != type) - && (type != FFEGLOBAL_typeEXT)) - { - /* We've learned more, so point to where we learned it. */ - g->t = ffelex_token_use (t); - g->type = type; -#ifdef FFECOM_globalHOOK - g->hook = FFECOM_globalNULL; /* Discard previous _DECL. */ -#endif - g->u.proc.n_args = -1; - } - - return TRUE; -#endif -} - -/* ffeglobal_save_common -- Check SAVE status of common area - - ffesymbol s; // the common area - bool save; // TRUE if SAVEd, FALSE otherwise - ffeglobal_save_common(s,save,ffesymbol_where_line(s), - ffesymbol_where_column(s)); - - In global-enabled mode, make sure the save info agrees with any existing - info established for the common area, otherwise complain. - In global-disabled mode, do nothing. */ - -void -ffeglobal_save_common (ffesymbol s, bool save, ffewhereLine wl, - ffewhereColumn wc) -{ -#if FFEGLOBAL_ENABLED - ffeglobal g; - - g = ffesymbol_global (s); - if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON)) - return; /* Let someone else catch this! */ - if (g->type == FFEGLOBAL_typeANY) - return; - - if (!g->u.common.have_save) - { - g->u.common.have_save = TRUE; - g->u.common.save = save; - g->u.common.save_where_line = ffewhere_line_use (wl); - g->u.common.save_where_col = ffewhere_column_use (wc); - } - else - { - if ((g->u.common.save != save) && ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_COMMON_DIFF_SAVE); - ffebad_string (ffesymbol_text (s)); - ffebad_here (save ? 0 : 1, wl, wc); - ffebad_here (save ? 1 : 0, g->u.common.pad_where_line, g->u.common.pad_where_col); - ffebad_finish (); - } - } -#endif -} - -/* ffeglobal_size_common -- Establish size of COMMON area - - ffesymbol s; // the common area - ffetargetOffset size; // size in units - if (ffeglobal_size_common(s,size)) // new size is largest seen - - In global-enabled mode, set the size if it current size isn't known or is - smaller than new size, and for non-blank common, complain if old size - is different from new. Return TRUE if the new size is the largest seen - for this COMMON area (or if no size was known for it previously). - In global-disabled mode, do nothing. */ - -#if FFEGLOBAL_ENABLED -bool -ffeglobal_size_common (ffesymbol s, ffetargetOffset size) -{ - ffeglobal g; - - g = ffesymbol_global (s); - if ((g == NULL) || (g->type != FFEGLOBAL_typeCOMMON)) - return FALSE; - if (g->type == FFEGLOBAL_typeANY) - return FALSE; - - if (!g->u.common.have_size) - { - g->u.common.have_size = TRUE; - g->u.common.size = size; - return TRUE; - } - - if ((g->tick > 0) && (g->tick < ffe_count_2) - && (g->u.common.size < size)) - { - char oldsize[40]; - char newsize[40]; - - /* Common block initialized in a previous program unit, which - effectively freezes its size, but now the program is trying - to enlarge it. */ - - sprintf (&oldsize[0], "%" ffetargetOffset_f "d", g->u.common.size); - sprintf (&newsize[0], "%" ffetargetOffset_f "d", size); - - ffebad_start (FFEBAD_COMMON_ENLARGED); - ffebad_string (ffesymbol_text (s)); - ffebad_string (oldsize); - ffebad_string (newsize); - ffebad_string ((g->u.common.size == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_string ((size == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_here (0, ffelex_token_where_line (g->u.common.initt), - ffelex_token_where_column (g->u.common.initt)); - ffebad_here (1, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_finish (); - } - else if ((g->u.common.size != size) && !g->u.common.blank) - { - char oldsize[40]; - char newsize[40]; - - /* Warn about this even if not -pedantic, because putting all - program units in a single source file is the only way to - detect this. Apparently UNIX-model linkers neither handle - nor report when they make a common unit smaller than - requested, such as when the smaller-declared version is - initialized and the larger-declared version is not. So - if people complain about strange overwriting, we can tell - them to put all their code in a single file and compile - that way. Warnings about differing sizes must therefore - always be issued. */ - - sprintf (&oldsize[0], "%" ffetargetOffset_f "d", g->u.common.size); - sprintf (&newsize[0], "%" ffetargetOffset_f "d", size); - - ffebad_start (FFEBAD_COMMON_DIFF_SIZE); - ffebad_string (ffesymbol_text (s)); - ffebad_string (oldsize); - ffebad_string (newsize); - ffebad_string ((g->u.common.size == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_string ((size == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_here (0, ffelex_token_where_line (g->t), - ffelex_token_where_column (g->t)); - ffebad_here (1, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_finish (); - } - - if (size > g->u.common.size) - { - g->u.common.size = size; - return TRUE; - } - - return FALSE; -} - -#endif -void -ffeglobal_terminate_1 () -{ -} diff --git a/gcc/f/global.h b/gcc/f/global.h deleted file mode 100755 index 38cf8d5..0000000 --- a/gcc/f/global.h +++ /dev/null @@ -1,200 +0,0 @@ -/* global.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - global.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_global -#define _H_f_global - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFEGLOBAL_typeNONE, - FFEGLOBAL_typeMAIN, - FFEGLOBAL_typeEXT, /* EXTERNAL is all we know. */ - FFEGLOBAL_typeSUBR, - FFEGLOBAL_typeFUNC, - FFEGLOBAL_typeBDATA, - FFEGLOBAL_typeCOMMON, - FFEGLOBAL_typeANY, /* Confusion reigns, so just ignore. */ - FFEGLOBAL_type - } ffeglobalType; - -typedef enum - { - FFEGLOBAL_argsummaryNONE, /* No arg present. */ - FFEGLOBAL_argsummaryVAL, /* Pass-by-value. */ - FFEGLOBAL_argsummaryREF, /* Pass-by-reference. */ - FFEGLOBAL_argsummaryDESCR, /* Pass-by-descriptor. */ - FFEGLOBAL_argsummaryPROC, /* Procedure (intrinsic, external). */ - FFEGLOBAL_argsummarySUBR, /* Subroutine (intrinsic, external). */ - FFEGLOBAL_argsummaryFUNC, /* Function (intrinsic, external). */ - FFEGLOBAL_argsummaryALTRTN, /* Alternate-return (label). */ - FFEGLOBAL_argsummaryANY, - FFEGLOBAL_argsummary - } ffeglobalArgSummary; - -/* Typedefs. */ - -typedef struct _ffeglobal_arginfo_ *ffeglobalArgInfo_; -typedef struct _ffeglobal_ *ffeglobal; - -/* Include files needed by this one. */ - -#include "info.h" -#include "lex.h" -#include "name.h" -#include "symbol.h" -#include "target.h" -#include "top.h" - -/* Structure definitions. */ - -struct _ffeglobal_arginfo_ -{ - ffelexToken t; /* Different from master token when difference is important. */ - char *name; /* Name of dummy arg, or NULL if not yet known. */ - ffeglobalArgSummary as; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - bool array; -}; - -struct _ffeglobal_ -{ - ffelexToken t; - ffename n; -#ifdef FFECOM_globalHOOK - ffecomGlobal hook; -#endif - ffeCounter tick; /* Recent transition in this progunit. */ - ffeglobalType type; - bool intrinsic; /* Known as intrinsic? */ - bool explicit_intrinsic; /* Explicit intrinsic? */ - union { - struct { - ffelexToken initt; /* First initial value. */ - bool have_pad; /* Padding info avail for COMMON? */ - ffetargetAlign pad; /* Initial padding for COMMON. */ - ffewhereLine pad_where_line; - ffewhereColumn pad_where_col; - bool have_save; /* Save info avail for COMMON? */ - bool save; /* Save info for COMMON. */ - ffewhereLine save_where_line; - ffewhereColumn save_where_col; - bool have_size; /* Size info avail for COMMON? */ - ffetargetOffset size; /* Size info for COMMON. */ - bool blank; /* TRUE if blank COMMON. */ - } common; - struct { - bool defined; /* Seen actual code yet? */ - ffeinfoBasictype bt; /* NONE for non-function. */ - ffeinfoKindtype kt; /* NONE for non-function. */ - ffetargetCharacterSize sz; - int n_args; /* 0 for main/blockdata. */ - ffelexToken other_t; /* Location of reference. */ - ffeglobalArgInfo_ arg_info; /* Info on each argument. */ - } proc; - } u; -}; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffeglobal_drive (ffeglobal (*fn) ()); -void ffeglobal_init_1 (void); -void ffeglobal_init_common (ffesymbol s, ffelexToken t); -void ffeglobal_new_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type); -void ffeglobal_new_common (ffesymbol s, ffelexToken t, bool blank); -void ffeglobal_pad_common (ffesymbol s, ffetargetAlign pad, ffewhereLine wl, - ffewhereColumn wc); -void ffeglobal_proc_def_arg (ffesymbol s, int argno, char *name, ffeglobalArgSummary as, - ffeinfoBasictype bt, ffeinfoKindtype kt, - bool array); -void ffeglobal_proc_def_nargs (ffesymbol s, int n_args); -bool ffeglobal_proc_ref_arg (ffesymbol s, int argno, ffeglobalArgSummary as, - ffeinfoBasictype bt, ffeinfoKindtype kt, - bool array, ffelexToken t); -bool ffeglobal_proc_ref_nargs (ffesymbol s, int n_args, ffelexToken t); -ffeglobal ffeglobal_promoted (ffesymbol s); -void ffeglobal_ref_intrinsic (ffesymbol s, ffelexToken t, bool explicit); -bool ffeglobal_ref_progunit_ (ffesymbol s, ffelexToken t, ffeglobalType type); -void ffeglobal_save_common (ffesymbol s, bool save, ffewhereLine wl, - ffewhereColumn wc); -bool ffeglobal_size_common (ffesymbol s, ffetargetOffset size); -void ffeglobal_terminate_1 (void); - -/* Define macros. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -#define FFEGLOBAL_ENABLED 0 -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#define FFEGLOBAL_ENABLED 1 -#else -#error -#endif - -#define ffeglobal_common_init(g) ((g)->tick != 0) -#define ffeglobal_common_have_pad(g) ((g)->u.common.have_pad) -#define ffeglobal_common_have_size(g) ((g)->u.common.have_size) -#define ffeglobal_common_pad(g) ((g)->u.common.pad) -#define ffeglobal_common_size(g) ((g)->u.common.size) -#define ffeglobal_hook(g) ((g)->hook) -#define ffeglobal_init_0() -#define ffeglobal_init_2() -#define ffeglobal_init_3() -#define ffeglobal_init_4() -#define ffeglobal_new_blockdata(s,t) \ - ffeglobal_new_progunit_(s,t,FFEGLOBAL_typeBDATA) -#define ffeglobal_new_function(s,t) \ - ffeglobal_new_progunit_(s,t,FFEGLOBAL_typeFUNC) -#define ffeglobal_new_program(s,t) \ - ffeglobal_new_progunit_(s,t,FFEGLOBAL_typeMAIN) -#define ffeglobal_new_subroutine(s,t) \ - ffeglobal_new_progunit_(s,t,FFEGLOBAL_typeSUBR) -#define ffeglobal_ref_blockdata(s,t) \ - ffeglobal_ref_progunit_(s,t,FFEGLOBAL_typeBDATA) -#define ffeglobal_ref_external(s,t) \ - ffeglobal_ref_progunit_(s,t,FFEGLOBAL_typeEXT) -#define ffeglobal_ref_function(s,t) \ - ffeglobal_ref_progunit_(s,t,FFEGLOBAL_typeFUNC) -#define ffeglobal_ref_subroutine(s,t) \ - ffeglobal_ref_progunit_(s,t,FFEGLOBAL_typeSUBR) -#define ffeglobal_set_hook(g,h) ((g)->hook = (h)) -#define ffeglobal_terminate_0() -#define ffeglobal_terminate_2() -#define ffeglobal_terminate_3() -#define ffeglobal_terminate_4() -#define ffeglobal_text(g) ffename_text((g)->n) -#define ffeglobal_type(g) ((g)->type) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/hconfig.j b/gcc/f/hconfig.j deleted file mode 100755 index a2fc0d1..0000000 --- a/gcc/f/hconfig.j +++ /dev/null @@ -1,27 +0,0 @@ -/* hconfig.j -- Wrapper for GCC's hconfig.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_hconfig -#define _J_f_hconfig -#include "hconfig.h" -#endif -#endif diff --git a/gcc/f/implic.c b/gcc/f/implic.c deleted file mode 100755 index b0271e8..0000000 --- a/gcc/f/implic.c +++ /dev/null @@ -1,382 +0,0 @@ -/* implic.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None. - - Description: - The GNU Fortran Front End. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "implic.h" -#include "info.h" -#include "src.h" -#include "symbol.h" -#include "target.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFEIMPLIC_stateINITIAL_, - FFEIMPLIC_stateASSUMED_, - FFEIMPLIC_stateESTABLISHED_, - FFEIMPLIC_state - } ffeimplicState_; - -/* Internal typedefs. */ - -typedef struct _ffeimplic_ *ffeimplic_; - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffeimplic_ - { - ffeimplicState_ state; - ffeinfo info; - }; - -/* Static objects accessed by functions in this module. */ - -/* NOTE: This is definitely ASCII-specific!! */ - -static struct _ffeimplic_ ffeimplic_table_['z' - 'A' + 1]; - -/* Static functions (internal). */ - -static ffeimplic_ ffeimplic_lookup_ (unsigned char c); - -/* Internal macros. */ - - -/* ffeimplic_lookup_ -- Look up implicit descriptor for initial character - - ffeimplic_ imp; - if ((imp = ffeimplic_lookup_('A')) == NULL) - // error - - Returns a pointer to an implicit descriptor block based on the character - passed, or NULL if it is not a valid initial character for an implicit - data type. */ - -static ffeimplic_ -ffeimplic_lookup_ (unsigned char c) -{ - /* NOTE: This is definitely ASCII-specific!! */ - if (ISALPHA (c) || (c == '_')) - return &ffeimplic_table_[c - 'A']; - return NULL; -} - -/* ffeimplic_establish_initial -- Establish type of implicit initial letter - - ffesymbol s; - if (!ffeimplic_establish_initial(s)) - // error - - Assigns implicit type information to the symbol based on the first - character of the symbol's name. */ - -bool -ffeimplic_establish_initial (char c, ffeinfoBasictype basic_type, - ffeinfoKindtype kind_type, ffetargetCharacterSize size) -{ - ffeimplic_ imp; - - imp = ffeimplic_lookup_ (c); - if (imp == NULL) - return FALSE; /* Character not A-Z or some such thing. */ - if (ffeinfo_basictype (imp->info) == FFEINFO_basictypeNONE) - return FALSE; /* IMPLICIT NONE in effect here. */ - - switch (imp->state) - { - case FFEIMPLIC_stateINITIAL_: - imp->info = ffeinfo_new (basic_type, - kind_type, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - size); - imp->state = FFEIMPLIC_stateESTABLISHED_; - return TRUE; - - case FFEIMPLIC_stateASSUMED_: - if ((ffeinfo_basictype (imp->info) != basic_type) - || (ffeinfo_kindtype (imp->info) != kind_type) - || (ffeinfo_size (imp->info) != size)) - return FALSE; - imp->state = FFEIMPLIC_stateESTABLISHED_; - return TRUE; - - case FFEIMPLIC_stateESTABLISHED_: - return FALSE; - - default: - assert ("Weird state for implicit object" == NULL); - return FALSE; - } -} - -/* ffeimplic_establish_symbol -- Establish implicit type of a symbol - - ffesymbol s; - if (!ffeimplic_establish_symbol(s)) - // error - - Assigns implicit type information to the symbol based on the first - character of the symbol's name. - - If symbol already has a type, return TRUE. - Get first character of symbol's name. - Get ffeimplic_ object for it (return FALSE if NULL returned). - Return FALSE if object has no assigned type (IMPLICIT NONE). - Copy the type information from the object to the symbol. - If the object is state "INITIAL", set to state "ASSUMED" so no - subsequent IMPLICIT statement may change the state. - Return TRUE. */ - -bool -ffeimplic_establish_symbol (ffesymbol s) -{ - char c; - ffeimplic_ imp; - - if (ffesymbol_basictype (s) != FFEINFO_basictypeNONE) - return TRUE; - - c = *(ffesymbol_text (s)); - imp = ffeimplic_lookup_ (c); - if (imp == NULL) - return FALSE; /* First character not A-Z or some such - thing. */ - if (ffeinfo_basictype (imp->info) == FFEINFO_basictypeNONE) - return FALSE; /* IMPLICIT NONE in effect here. */ - - ffesymbol_signal_change (s); /* Gonna change, save existing? */ - - /* Establish basictype, kindtype, size; preserve rank, kind, where. */ - - ffesymbol_set_info (s, - ffeinfo_new (ffeinfo_basictype (imp->info), - ffeinfo_kindtype (imp->info), - ffesymbol_rank (s), - ffesymbol_kind (s), - ffesymbol_where (s), - ffeinfo_size (imp->info))); - - if (imp->state == FFEIMPLIC_stateINITIAL_) - imp->state = FFEIMPLIC_stateASSUMED_; - - if (ffe_is_warn_implicit ()) - { - ffebad_start_msg ("Implicit declaration of `%A' at %0", - FFEBAD_severityWARNING); - ffebad_here (0, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_string (ffesymbol_text (s)); - ffebad_finish (); - } - - return TRUE; -} - -/* ffeimplic_init_2 -- Initialize table - - ffeimplic_init_2(); - - Assigns initial type information to all initial letters. - - Allows for holes in the sequence of letters (i.e. EBCDIC). */ - -void -ffeimplic_init_2 () -{ - ffeimplic_ imp; - char c; - - for (c = 'A'; c <= 'z'; ++c) - { - imp = &ffeimplic_table_[c - 'A']; - imp->state = FFEIMPLIC_stateINITIAL_; - switch (c) - { - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'F': - case 'G': - case 'H': - 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 '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'f': - case 'g': - case 'h': - case 'o': - case 'p': - case 'q': - case 'r': - case 's': - case 't': - case 'u': - case 'v': - case 'w': - case 'x': - case 'y': - case 'z': - imp->info = ffeinfo_new (FFEINFO_basictypeREAL, - FFEINFO_kindtypeREALDEFAULT, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE); - break; - - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'N': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'n': - imp->info = ffeinfo_new (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, FFEINFO_kindNONE, FFEINFO_whereNONE, - FFETARGET_charactersizeNONE); - break; - - default: - imp->info = ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, - FFEINFO_kindNONE, FFEINFO_whereNONE, FFETARGET_charactersizeNONE); - break; - } - } -} - -/* ffeimplic_none -- Implement IMPLICIT NONE statement - - ffeimplic_none(); - - Assigns null type information to all initial letters. */ - -void -ffeimplic_none () -{ - ffeimplic_ imp; - - for (imp = &ffeimplic_table_[0]; - imp != &ffeimplic_table_[ARRAY_SIZE (ffeimplic_table_)]; - imp++) - { - imp->info = ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE); - } -} - -/* ffeimplic_peek_symbol_type -- Determine implicit type of a symbol - - ffesymbol s; - char *name; // name for s in case it is NULL, or NULL if s never NULL - if (ffeimplic_peek_symbol_type(s,name) == FFEINFO_basictypeCHARACTER) - // is or will be a CHARACTER-typed name - - Like establish_symbol, but doesn't change anything. - - If symbol is non-NULL and already has a type, return it. - Get first character of symbol's name or from name arg if symbol is NULL. - Get ffeimplic_ object for it (return FALSE if NULL returned). - Return NONE if object has no assigned type (IMPLICIT NONE). - Return the data type indicated in the object. - - 24-Oct-91 JCB 2.0 - Take a char * instead of ffelexToken, since the latter isn't always - needed anyway (as when ffecom calls it). */ - -ffeinfoBasictype -ffeimplic_peek_symbol_type (ffesymbol s, char *name) -{ - char c; - ffeimplic_ imp; - - if (s == NULL) - c = *name; - else - { - if (ffesymbol_basictype (s) != FFEINFO_basictypeNONE) - return ffesymbol_basictype (s); - - c = *(ffesymbol_text (s)); - } - - imp = ffeimplic_lookup_ (c); - if (imp == NULL) - return FFEINFO_basictypeNONE; /* First character not A-Z or - something. */ - return ffeinfo_basictype (imp->info); -} - -/* ffeimplic_terminate_2 -- Terminate table - - ffeimplic_terminate_2(); - - Kills info object for each entry in table. */ - -void -ffeimplic_terminate_2 () -{ -} diff --git a/gcc/f/implic.h b/gcc/f/implic.h deleted file mode 100755 index 7550e0d..0000000 --- a/gcc/f/implic.h +++ /dev/null @@ -1,74 +0,0 @@ -/* implic.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - implic.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_implic -#define _H_f_implic - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "info.h" -#include "symbol.h" -#include "target.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -bool ffeimplic_establish_initial (char c, ffeinfoBasictype basic_type, - ffeinfoKindtype kind_type, ffetargetCharacterSize size); -bool ffeimplic_establish_symbol (ffesymbol s); -void ffeimplic_init_2 (void); -void ffeimplic_none (void); -ffeinfoBasictype ffeimplic_peek_symbol_type (ffesymbol s, char *name); -void ffeimplic_terminate_2 (void); - -/* Define macros. */ - -#define ffeimplic_init_0() -#define ffeimplic_init_1() -#define ffeimplic_init_3() -#define ffeimplic_init_4() -#define ffeimplic_terminate_0() -#define ffeimplic_terminate_1() -#define ffeimplic_terminate_3() -#define ffeimplic_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/info-b.def b/gcc/f/info-b.def deleted file mode 100755 index 30df25e..0000000 --- a/gcc/f/info-b.def +++ /dev/null @@ -1,36 +0,0 @@ -/* info-b.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - info.c - - Modifications: -*/ - -FFEINFO_BASICTYPE (FFEINFO_basictypeNONE, "None", "") -FFEINFO_BASICTYPE (FFEINFO_basictypeINTEGER, "INTEGER", "i") -FFEINFO_BASICTYPE (FFEINFO_basictypeLOGICAL, "LOGICAL", "l") -FFEINFO_BASICTYPE (FFEINFO_basictypeREAL, "REAL", "r") -FFEINFO_BASICTYPE (FFEINFO_basictypeCOMPLEX, "COMPLEX", "c") -FFEINFO_BASICTYPE (FFEINFO_basictypeCHARACTER, "CHARACTER", "a") -FFEINFO_BASICTYPE (FFEINFO_basictypeHOLLERITH, "Hollerith", "h") -FFEINFO_BASICTYPE (FFEINFO_basictypeTYPELESS, "Typeless", "t") -FFEINFO_BASICTYPE (FFEINFO_basictypeANY, "Any", "~") diff --git a/gcc/f/info-k.def b/gcc/f/info-k.def deleted file mode 100755 index a1441c9..0000000 --- a/gcc/f/info-k.def +++ /dev/null @@ -1,37 +0,0 @@ -/* info-k.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - info.c - - Modifications: -*/ - -FFEINFO_KIND (FFEINFO_kindNONE, "an unknown kind", "") -FFEINFO_KIND (FFEINFO_kindENTITY, "an entity", "e") -FFEINFO_KIND (FFEINFO_kindFUNCTION, "a function", "f") -FFEINFO_KIND (FFEINFO_kindSUBROUTINE, "a subroutine", "u") -FFEINFO_KIND (FFEINFO_kindPROGRAM, "a program", "p") -FFEINFO_KIND (FFEINFO_kindBLOCKDATA, "a block-data unit", "b") -FFEINFO_KIND (FFEINFO_kindCOMMON, "a common block", "c") -FFEINFO_KIND (FFEINFO_kindCONSTRUCT, "a construct", ":") -FFEINFO_KIND (FFEINFO_kindNAMELIST, "a namelist", "n") -FFEINFO_KIND (FFEINFO_kindANY, "anything", "~") diff --git a/gcc/f/info-w.def b/gcc/f/info-w.def deleted file mode 100755 index 54a1b36..0000000 --- a/gcc/f/info-w.def +++ /dev/null @@ -1,41 +0,0 @@ -/* info-w.def -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - info.c - - Modifications: -*/ - -FFEINFO_WHERE (FFEINFO_whereNONE, "None", "") -FFEINFO_WHERE (FFEINFO_whereLOCAL, "Local", "l") /* Defined locally. */ -FFEINFO_WHERE (FFEINFO_whereCOMMON, "Common", "c") /* In a common area. */ -FFEINFO_WHERE (FFEINFO_whereDUMMY, "Dummy", "d") /* A dummy argument. */ -FFEINFO_WHERE (FFEINFO_whereGLOBAL, "Global", "g") /* Reference to external global like FUNCTION, SUBR. */ -FFEINFO_WHERE (FFEINFO_whereRESULT, "Result", "r") /* Result of this function. */ -FFEINFO_WHERE (FFEINFO_whereFLEETING, "Fleeting", "f") /* Result of "X*Y", "FUNCREF(5,1.3)", "ARRAY(X)", etc. */ -FFEINFO_WHERE (FFEINFO_whereFLEETING_CADDR, "Fleet-Const", "fp") /* "A(3)", "CHARS(4:5)". */ -FFEINFO_WHERE (FFEINFO_whereFLEETING_IADDR, "Fleet-Immed", "fi") /* A(IX) in "DATA (A(IX),IX=1,100)/.../". */ -FFEINFO_WHERE (FFEINFO_whereIMMEDIATE, "Immediate", "i") /* IX in "DATA (A(IX),IX=1,100)/.../". */ -FFEINFO_WHERE (FFEINFO_whereINTRINSIC, "Intrinsic", "b") -FFEINFO_WHERE (FFEINFO_whereCONSTANT, "Constant", "p") /* For kindFUNCTION, means statement function! */ -FFEINFO_WHERE (FFEINFO_whereCONSTANT_SUBOBJECT, "Const-subobj", "q") /* As in "'FOO'(I:J)". */ -FFEINFO_WHERE (FFEINFO_whereANY, "Any", "~") diff --git a/gcc/f/info.c b/gcc/f/info.c deleted file mode 100755 index 05a6e26..0000000 --- a/gcc/f/info.c +++ /dev/null @@ -1,304 +0,0 @@ -/* info.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - An abstraction for information maintained on a per-operator and per- - operand basis in expression trees. - - Modifications: - 30-Aug-90 JCB 2.0 - Extensive rewrite for new cleaner approach. -*/ - -/* Include files. */ - -#include "proj.h" -#include "info.h" -#include "target.h" -#include "type.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -static char *ffeinfo_basictype_string_[] -= -{ -#define FFEINFO_BASICTYPE(KWD,LNAM,SNAM) SNAM, -#include "info-b.def" -#undef FFEINFO_BASICTYPE -}; -static char *ffeinfo_kind_message_[] -= -{ -#define FFEINFO_KIND(KWD,LNAM,SNAM) LNAM, -#include "info-k.def" -#undef FFEINFO_KIND -}; -static char *ffeinfo_kind_string_[] -= -{ -#define FFEINFO_KIND(KWD,LNAM,SNAM) SNAM, -#include "info-k.def" -#undef FFEINFO_KIND -}; -static ffeinfoBasictype ffeinfo_combine_[FFEINFO_basictype][FFEINFO_basictype]; -static char *ffeinfo_kindtype_string_[] -= -{ - "", - "1", - "2", - "3", - "4", - "5", - "6", - "7", - "8", - "*", -}; -static char *ffeinfo_where_string_[] -= -{ -#define FFEINFO_WHERE(KWD,LNAM,SNAM) SNAM, -#include "info-w.def" -#undef FFEINFO_WHERE -}; -static ffetype ffeinfo_types_[FFEINFO_basictype][FFEINFO_kindtype] - = { { NULL } }; - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffeinfo_basictype_combine -- Combine two basictypes into highest rank type - - ffeinfoBasictype i, j, k; - k = ffeinfo_basictype_combine(i,j); - - Returns a type based on "standard" operation between two given types. */ - -ffeinfoBasictype -ffeinfo_basictype_combine (ffeinfoBasictype l, ffeinfoBasictype r) -{ - assert (l < FFEINFO_basictype); - assert (r < FFEINFO_basictype); - return ffeinfo_combine_[l][r]; -} - -/* ffeinfo_basictype_string -- Return tiny string showing the basictype - - ffeinfoBasictype i; - printf("%s",ffeinfo_basictype_string(dt)); - - Returns the string based on the basic type. */ - -char * -ffeinfo_basictype_string (ffeinfoBasictype basictype) -{ - if (basictype >= ARRAY_SIZE (ffeinfo_basictype_string_)) - return "?\?\?"; - return ffeinfo_basictype_string_[basictype]; -} - -/* ffeinfo_init_0 -- Initialize - - ffeinfo_init_0(); */ - -void -ffeinfo_init_0 () -{ - ffeinfoBasictype i; - ffeinfoBasictype j; - - assert (FFEINFO_basictype == ARRAY_SIZE (ffeinfo_basictype_string_)); - assert (FFEINFO_kind == ARRAY_SIZE (ffeinfo_kind_message_)); - assert (FFEINFO_kind == ARRAY_SIZE (ffeinfo_kind_string_)); - assert (FFEINFO_kindtype == ARRAY_SIZE (ffeinfo_kindtype_string_)); - assert (FFEINFO_where == ARRAY_SIZE (ffeinfo_where_string_)); - - /* Make array that, given two basic types, produces resulting basic type. */ - - for (i = 0; i < FFEINFO_basictype; ++i) - for (j = 0; j < FFEINFO_basictype; ++j) - if ((i == FFEINFO_basictypeANY) || (j == FFEINFO_basictypeANY)) - ffeinfo_combine_[i][j] = FFEINFO_basictypeANY; - else - ffeinfo_combine_[i][j] = FFEINFO_basictypeNONE; - -#define same(bt) ffeinfo_combine_[bt][bt] = bt -#define use2(bt1,bt2) ffeinfo_combine_[bt1][bt2] \ - = ffeinfo_combine_[bt2][bt1] = bt2 - - same (FFEINFO_basictypeINTEGER); - same (FFEINFO_basictypeLOGICAL); - same (FFEINFO_basictypeREAL); - same (FFEINFO_basictypeCOMPLEX); - same (FFEINFO_basictypeCHARACTER); - use2 (FFEINFO_basictypeINTEGER, FFEINFO_basictypeREAL); - use2 (FFEINFO_basictypeINTEGER, FFEINFO_basictypeCOMPLEX); - use2 (FFEINFO_basictypeREAL, FFEINFO_basictypeCOMPLEX); - -#undef same -#undef use2 -} - -/* ffeinfo_kind_message -- Return helpful string showing the kind - - ffeinfoKind kind; - printf("%s",ffeinfo_kind_message(kind)); - - Returns the string based on the kind. */ - -char * -ffeinfo_kind_message (ffeinfoKind kind) -{ - if (kind >= ARRAY_SIZE (ffeinfo_kind_message_)) - return "?\?\?"; - return ffeinfo_kind_message_[kind]; -} - -/* ffeinfo_kind_string -- Return tiny string showing the kind - - ffeinfoKind kind; - printf("%s",ffeinfo_kind_string(kind)); - - Returns the string based on the kind. */ - -char * -ffeinfo_kind_string (ffeinfoKind kind) -{ - if (kind >= ARRAY_SIZE (ffeinfo_kind_string_)) - return "?\?\?"; - return ffeinfo_kind_string_[kind]; -} - -ffeinfoKindtype -ffeinfo_kindtype_max(ffeinfoBasictype bt, - ffeinfoKindtype k1, - ffeinfoKindtype k2) -{ - if ((bt == FFEINFO_basictypeANY) - || (k1 == FFEINFO_kindtypeANY) - || (k2 == FFEINFO_kindtypeANY)) - return FFEINFO_kindtypeANY; - - if (ffetype_size (ffeinfo_types_[bt][k1]) - > ffetype_size (ffeinfo_types_[bt][k2])) - return k1; - return k2; -} - -/* ffeinfo_kindtype_string -- Return tiny string showing the kind type - - ffeinfoKindtype kind_type; - printf("%s",ffeinfo_kindtype_string(kind)); - - Returns the string based on the kind type. */ - -char * -ffeinfo_kindtype_string (ffeinfoKindtype kind_type) -{ - if (kind_type >= ARRAY_SIZE (ffeinfo_kindtype_string_)) - return "?\?\?"; - return ffeinfo_kindtype_string_[kind_type]; -} - -void -ffeinfo_set_type (ffeinfoBasictype basictype, ffeinfoKindtype kindtype, - ffetype type) -{ - assert (basictype < FFEINFO_basictype); - assert (kindtype < FFEINFO_kindtype); - assert (ffeinfo_types_[basictype][kindtype] == NULL); - - ffeinfo_types_[basictype][kindtype] = type; -} - -ffetype -ffeinfo_type (ffeinfoBasictype basictype, ffeinfoKindtype kindtype) -{ - assert (basictype < FFEINFO_basictype); - assert (kindtype < FFEINFO_kindtype); - - return ffeinfo_types_[basictype][kindtype]; -} - -/* ffeinfo_where_string -- Return tiny string showing the where - - ffeinfoWhere where; - printf("%s",ffeinfo_where_string(where)); - - Returns the string based on the where. */ - -char * -ffeinfo_where_string (ffeinfoWhere where) -{ - if (where >= ARRAY_SIZE (ffeinfo_where_string_)) - return "?\?\?"; - return ffeinfo_where_string_[where]; -} - -/* ffeinfo_new -- Return object representing datatype, kind, and where info - - ffeinfo i; - i = ffeinfo_new(FFEINFO_datatypeINTEGER,FFEINFO_kindSCALAR, - FFEINFO_whereLOCAL); - - Returns the string based on the data type. */ - -#ifndef __GNUC__ -ffeinfo -ffeinfo_new (ffeinfoBasictype basictype, ffeinfoKindtype kindtype, - ffeinfoRank rank, ffeinfoKind kind, ffeinfoWhere where, - ffetargetCharacterSize size) -{ - ffeinfo i; - - i.basictype = basictype; - i.kindtype = kindtype; - i.rank = rank; - i.size = size; - i.kind = kind; - i.where = where; - i.size = size; - - return i; -} -#endif diff --git a/gcc/f/info.h b/gcc/f/info.h deleted file mode 100755 index 8eaaa5d..0000000 --- a/gcc/f/info.h +++ /dev/null @@ -1,186 +0,0 @@ -/* info.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - info.c - - Modifications: - 30-Aug-90 JCB 2.0 - Extensive rewrite for new cleaner approach. -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_info -#define _H_f_info - -/* Simple definitions and enumerations. */ - -typedef enum - { -#define FFEINFO_BASICTYPE(KWD,LNAM,SNAM) KWD, -#include "info-b.def" -#undef FFEINFO_BASICTYPE - FFEINFO_basictype - } ffeinfoBasictype; - -typedef enum - { /* If these kindtypes aren't in size order, - change _kindtype_max. */ - FFEINFO_kindtypeNONE, - FFEINFO_kindtypeINTEGER1, - FFEINFO_kindtypeINTEGER2, - FFEINFO_kindtypeINTEGER3, - FFEINFO_kindtypeINTEGER4, - FFEINFO_kindtypeINTEGER5, - FFEINFO_kindtypeINTEGER6, - FFEINFO_kindtypeINTEGER7, - FFEINFO_kindtypeINTEGER8, - FFEINFO_kindtypeLOGICAL1 = 1, /* Ok to omit, but ok to overlap. */ - FFEINFO_kindtypeLOGICAL2, - FFEINFO_kindtypeLOGICAL3, - FFEINFO_kindtypeLOGICAL4, - FFEINFO_kindtypeLOGICAL5, - FFEINFO_kindtypeLOGICAL6, - FFEINFO_kindtypeLOGICAL7, - FFEINFO_kindtypeLOGICAL8, - FFEINFO_kindtypeREAL1 = 1, /* Ok to omit, but ok to overlap. */ - FFEINFO_kindtypeREAL2, - FFEINFO_kindtypeREAL3, - FFEINFO_kindtypeREAL4, - FFEINFO_kindtypeREAL5, - FFEINFO_kindtypeREAL6, - FFEINFO_kindtypeREAL7, - FFEINFO_kindtypeREAL8, - FFEINFO_kindtypeCHARACTER1 = 1, /* Ok to omit, but ok to overlap. */ - FFEINFO_kindtypeCHARACTER2, - FFEINFO_kindtypeCHARACTER3, - FFEINFO_kindtypeCHARACTER4, - FFEINFO_kindtypeCHARACTER5, - FFEINFO_kindtypeCHARACTER6, - FFEINFO_kindtypeCHARACTER7, - FFEINFO_kindtypeCHARACTER8, - FFEINFO_kindtypeANY, - FFEINFO_kindtype - } ffeinfoKindtype; - -typedef enum - { -#define FFEINFO_KIND(KWD,LNAM,SNAM) KWD, -#include "info-k.def" -#undef FFEINFO_KIND - FFEINFO_kind - } ffeinfoKind; - -typedef enum - { -#define FFEINFO_WHERE(KWD,LNAM,SNAM) KWD, -#include "info-w.def" -#undef FFEINFO_WHERE - FFEINFO_where - } ffeinfoWhere; - -/* Typedefs. */ - -typedef struct _ffeinfo_ ffeinfo; -typedef char ffeinfoRank; - -/* Include files needed by this one. */ - -#include "target.h" -#include "type.h" - -/* Structure definitions. */ - -struct _ffeinfo_ - { - ffeinfoBasictype basictype; - ffeinfoKindtype kindtype; - ffeinfoRank rank; - ffeinfoKind kind; - ffeinfoWhere where; - ffetargetCharacterSize size; - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -ffeinfoBasictype ffeinfo_basictype_combine (ffeinfoBasictype l, - ffeinfoBasictype r); -char *ffeinfo_basictype_string (ffeinfoBasictype basictype); -void ffeinfo_init_0 (void); -char *ffeinfo_kind_message (ffeinfoKind kind); -char *ffeinfo_kind_string (ffeinfoKind kind); -ffeinfoKindtype ffeinfo_kindtype_max(ffeinfoBasictype bt, - ffeinfoKindtype k1, - ffeinfoKindtype k2); -char *ffeinfo_kindtype_string (ffeinfoKindtype kind_type); -char *ffeinfo_where_string (ffeinfoWhere where); -ffeinfo ffeinfo_new (ffeinfoBasictype basictype, ffeinfoKindtype kindtype, - ffeinfoRank rank, ffeinfoKind kind, ffeinfoWhere where, - ffetargetCharacterSize size); -void ffeinfo_set_type (ffeinfoBasictype basictype, ffeinfoKindtype kindtype, - ffetype type); -ffetype ffeinfo_type (ffeinfoBasictype basictype, ffeinfoKindtype kindtype); - -/* Define macros. */ - -#define ffeinfo_basictype(i) (i.basictype) -#define ffeinfo_init_1() -#define ffeinfo_init_2() -#define ffeinfo_init_3() -#define ffeinfo_init_4() -#define ffeinfo_kind(i) (i.kind) -#define ffeinfo_kindtype(i) (i.kindtype) -#ifdef __GNUC__ -#define ffeinfo_new(bt,kt,r,k,w,sz) \ - ((ffeinfo) {(bt), (kt), (r), (k), (w), (sz)}) -#endif -#define ffeinfo_new_any() \ - ffeinfo_new (FFEINFO_basictypeANY, FFEINFO_kindtypeANY, 0, \ - FFEINFO_kindANY, FFEINFO_whereANY, \ - FFETARGET_charactersizeNONE) -#define ffeinfo_new_null() \ - ffeinfo_new (FFEINFO_basictypeNONE, FFEINFO_kindtypeNONE, 0, \ - FFEINFO_kindNONE, FFEINFO_whereNONE, \ - FFETARGET_charactersizeNONE) -#define ffeinfo_rank(i) (i.rank) -#define ffeinfo_size(i) (i.size) -#define ffeinfo_terminate_0() -#define ffeinfo_terminate_1() -#define ffeinfo_terminate_2() -#define ffeinfo_terminate_3() -#define ffeinfo_terminate_4() -#define ffeinfo_use(i) i -#define ffeinfo_where(i) (i.where) - -#define FFEINFO_kindtypeINTEGERDEFAULT FFEINFO_kindtypeINTEGER1 -#define FFEINFO_kindtypeLOGICALDEFAULT FFEINFO_kindtypeLOGICAL1 -#define FFEINFO_kindtypeREALDEFAULT FFEINFO_kindtypeREAL1 -#define FFEINFO_kindtypeREALDOUBLE FFEINFO_kindtypeREAL2 -#define FFEINFO_kindtypeREALQUAD FFEINFO_kindtypeREAL3 -#define FFEINFO_kindtypeCHARACTERDEFAULT FFEINFO_kindtypeCHARACTER1 - -/* End of #include file. */ - -#endif diff --git a/gcc/f/input.j b/gcc/f/input.j deleted file mode 100755 index 1444de2..0000000 --- a/gcc/f/input.j +++ /dev/null @@ -1,27 +0,0 @@ -/* input.j -- Wrapper for GCC's input.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_input -#define _J_f_input -#include "input.h" -#endif -#endif diff --git a/gcc/f/install0.texi b/gcc/f/install0.texi deleted file mode 100755 index bbc8ab5..0000000 --- a/gcc/f/install0.texi +++ /dev/null @@ -1,14 +0,0 @@ -@setfilename INSTALL -@set INSTALLONLY - -@c The immediately following lines apply to the INSTALL file -@c which is generated using this file. -This file contains installation information for the GNU Fortran compiler. -Copyright (C) 1995, 1996 Free Software Foundation, Inc. -You may copy, distribute, and modify it freely as long as you preserve -this copyright notice and permission notice. - -@node Top,,, (dir) -@chapter Installing GNU Fortran -@include g77install.texi -@bye diff --git a/gcc/f/intdoc.c b/gcc/f/intdoc.c deleted file mode 100755 index 0ac39ff..0000000 --- a/gcc/f/intdoc.c +++ /dev/null @@ -1,1336 +0,0 @@ -/* intdoc.c - Copyright (C) 1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -/* From f/proj.h, which uses #error -- not all C compilers - support that, and we want *this* program to be compilable - by pretty much any C compiler. */ -#include "hconfig.j" -#include "system.j" -#include "assert.j" -#if HAVE_STDDEF_H -#include <stddef.h> -#endif - -typedef enum - { -#if !defined(false) || !defined(true) - false = 0, true = 1, -#endif -#if !defined(FALSE) || !defined(TRUE) - FALSE = 0, TRUE = 1, -#endif - Doggone_Trailing_Comma_Dont_Work = 1 - } bool; - -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -/* Pull in the intrinsics info, but only the doc parts. */ -#define FFEINTRIN_DOC 1 -#include "intrin.h" - -char *family_name (ffeintrinFamily family); -static void dumpif (ffeintrinFamily fam); -static void dumpendif (void); -static void dumpclearif (void); -static void dumpem (void); -static void dumpgen (int menu, char *name, char *name_uc, - ffeintrinGen gen); -static void dumpspec (int menu, char *name, char *name_uc, - ffeintrinSpec spec); -static void dumpimp (int menu, char *name, char *name_uc, size_t genno, ffeintrinFamily family, - ffeintrinImp imp, ffeintrinSpec spec); -static char *argument_info_ptr (ffeintrinImp imp, int argno); -static char *argument_info_string (ffeintrinImp imp, int argno); -static char *argument_name_ptr (ffeintrinImp imp, int argno); -static char *argument_name_string (ffeintrinImp imp, int argno); -#if 0 -static char *elaborate_if_complex (ffeintrinImp imp, int argno); -static char *elaborate_if_maybe_complex (ffeintrinImp imp, int argno); -static char *elaborate_if_real (ffeintrinImp imp, int argno); -#endif -static void print_type_string (char *c); - -int -main (int argc, char **argv) -{ - if (argc != 1) - { - fprintf (stderr, "\ -Usage: intdoc > intdoc.texi\n\ - Collects and dumps documentation on g77 intrinsics\n\ - to the file named intdoc.texi.\n"); - exit (1); - } - - dumpem (); - return 0; -} - -struct _ffeintrin_name_ - { - char *name_uc; - char *name_lc; - char *name_ic; - ffeintrinGen generic; - ffeintrinSpec specific; - }; - -struct _ffeintrin_gen_ - { - char *name; /* Name as seen in program. */ - ffeintrinSpec specs[2]; - }; - -struct _ffeintrin_spec_ - { - char *name; /* Uppercase name as seen in source code, - lowercase if no source name, "none" if no - name at all (NONE case). */ - bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */ - ffeintrinFamily family; - ffeintrinImp implementation; - }; - -struct _ffeintrin_imp_ - { - char *name; /* Name of implementation. */ -#if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - ffecomGfrt gfrt; /* gfrt index in library. */ -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - char *control; - }; - -static struct _ffeintrin_name_ names[] = { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \ - { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC }, -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_gen_ gens[] = { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) \ - { NAME, { SPEC1, SPEC2, }, }, -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_imp_ imps[] = { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#if 0 /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \ - { NAME, FFECOM_gfrt ## GFRT, CONTROL }, -#elif 1 /* FFECOM_targetCURRENT == FFECOM_targetFFE */ -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \ - { NAME, CONTROL }, -#else -#error -#endif -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_spec_ specs[] = { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \ - { NAME, CALLABLE, FAMILY, IMP, }, -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -struct cc_pair { ffeintrinImp imp; char *text; }; - -static char *descriptions[FFEINTRIN_imp] = { 0 }; -static struct cc_pair cc_descriptions[] = { -#define DEFDOC(IMP,SUMMARY,DESCRIPTION) { FFEINTRIN_imp ## IMP, DESCRIPTION }, -#include "intdoc.h0" -#undef DEFDOC -}; - -static char *summaries[FFEINTRIN_imp] = { 0 }; -static struct cc_pair cc_summaries[] = { -#define DEFDOC(IMP,SUMMARY,DESCRIPTION) { FFEINTRIN_imp ## IMP, SUMMARY }, -#include "intdoc.h0" -#undef DEFDOC -}; - -char * -family_name (ffeintrinFamily family) -{ - switch (family) - { - case FFEINTRIN_familyF77: - return "familyF77"; - - case FFEINTRIN_familyASC: - return "familyASC"; - - case FFEINTRIN_familyMIL: - return "familyMIL"; - - case FFEINTRIN_familyGNU: - return "familyGNU"; - - case FFEINTRIN_familyF90: - return "familyF90"; - - case FFEINTRIN_familyVXT: - return "familyVXT"; - - case FFEINTRIN_familyFVZ: - return "familyFVZ"; - - case FFEINTRIN_familyF2C: - return "familyF2C"; - - case FFEINTRIN_familyF2U: - return "familyF2U"; - - case FFEINTRIN_familyBADU77: - return "familyBADU77"; - - default: - assert ("bad family" == NULL); - return "??"; - } -} - -static int in_ifset = 0; -static ffeintrinFamily latest_family = FFEINTRIN_familyNONE; - -static void -dumpif (ffeintrinFamily fam) -{ - assert (fam != FFEINTRIN_familyNONE); - if ((in_ifset != 2) - || (fam != latest_family)) - { - if (in_ifset == 2) - printf ("@end ifset\n"); - latest_family = fam; - printf ("@ifset %s\n", family_name (fam)); - } - in_ifset = 1; -} - -static void -dumpendif () -{ - in_ifset = 2; -} - -static void -dumpclearif () -{ - if ((in_ifset == 2) - || (latest_family != FFEINTRIN_familyNONE)) - printf ("@end ifset\n"); - latest_family = FFEINTRIN_familyNONE; - in_ifset = 0; -} - -static void -dumpem () -{ - int i; - - for (i = 0; ((size_t) i) < ARRAY_SIZE (cc_descriptions); ++i) - { - assert (descriptions[cc_descriptions[i].imp] == NULL); - descriptions[cc_descriptions[i].imp] = cc_descriptions[i].text; - } - - for (i = 0; ((size_t) i) < ARRAY_SIZE (cc_summaries); ++i) - { - assert (summaries[cc_summaries[i].imp] == NULL); - summaries[cc_summaries[i].imp] = cc_summaries[i].text; - } - - printf ("@c This file is automatically derived from intdoc.c, intdoc.in,\n"); - printf ("@c ansify.c, intrin.def, and intrin.h. Edit those files instead.\n"); - printf ("@menu\n"); - for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i) - { - if (names[i].generic != FFEINTRIN_genNONE) - dumpgen (1, names[i].name_ic, names[i].name_uc, - names[i].generic); - if (names[i].specific != FFEINTRIN_specNONE) - dumpspec (1, names[i].name_ic, names[i].name_uc, - names[i].specific); - } - dumpclearif (); - - printf ("@end menu\n\n"); - - for (i = 0; ((size_t) i) < ARRAY_SIZE (names); ++i) - { - if (names[i].generic != FFEINTRIN_genNONE) - dumpgen (0, names[i].name_ic, names[i].name_uc, - names[i].generic); - if (names[i].specific != FFEINTRIN_specNONE) - dumpspec (0, names[i].name_ic, names[i].name_uc, - names[i].specific); - } - dumpclearif (); -} - -static void -dumpgen (int menu, char *name, char *name_uc, ffeintrinGen gen) -{ - size_t i; - int total = 0; - - if (!menu) - { - for (i = 0; i < ARRAY_SIZE (gens[gen].specs); ++i) - { - if (gens[gen].specs[i] != FFEINTRIN_specNONE) - ++total; - } - } - - for (i = 0; i < ARRAY_SIZE (gens[gen].specs); ++i) - { - ffeintrinSpec spec; - size_t j; - - if ((spec = gens[gen].specs[i]) == FFEINTRIN_specNONE) - continue; - - dumpif (specs[spec].family); - dumpimp (menu, name, name_uc, i, specs[spec].family, specs[spec].implementation, - spec); - if (!menu && (total > 0)) - { - if (total == 1) - { - printf ("\ -For information on another intrinsic with the same name:\n"); - } - else - { - printf ("\ -For information on other intrinsics with the same name:\n"); - } - for (j = 0; j < ARRAY_SIZE (gens[gen].specs); ++j) - { - if (j == i) - continue; - if ((spec = gens[gen].specs[j]) == FFEINTRIN_specNONE) - continue; - printf ("@xref{%s Intrinsic (%s)}.\n", - name, specs[spec].name); - } - printf ("\n"); - } - dumpendif (); - } -} - -static void -dumpspec (int menu, char *name, char *name_uc, ffeintrinSpec spec) -{ - dumpif (specs[spec].family); - dumpimp (menu, name, name_uc, 0, specs[spec].family, specs[spec].implementation, - FFEINTRIN_specNONE); - dumpendif (); -} - -static void -dumpimp (int menu, char *name, char *name_uc, size_t genno, ffeintrinFamily family, ffeintrinImp imp, - ffeintrinSpec spec) -{ - char *c; - bool subr; - char *argc; - char *argi; - int colon; - int argno; - - assert ((imp != FFEINTRIN_impNONE) || !genno); - - if (menu) - { - printf ("* %s Intrinsic", - name); - if (spec != FFEINTRIN_specNONE) - printf (" (%s)", specs[spec].name); /* See XYZZY1 below */ - printf ("::"); -#define INDENT_SUMMARY 24 - if ((imp == FFEINTRIN_impNONE) - || (summaries[imp] != NULL)) - { - int spaces = INDENT_SUMMARY - 14 - strlen (name); - char *c; - - if (spec != FFEINTRIN_specNONE) - spaces -= (3 + strlen (specs[spec].name)); /* See XYZZY1 above */ - if (spaces < 1) - spaces = 1; - while (spaces--) - fputc (' ', stdout); - - if (imp == FFEINTRIN_impNONE) - { - printf ("(Reserved for future use.)\n"); - return; - } - - for (c = summaries[imp]; c[0] != '\0'; ++c) - { - if ((c[0] == '@') - && (c[1] >= '0') - && (c[1] <= '9')) - { - int argno = c[1] - '0'; - - c += 2; - while ((c[0] >= '0') - && (c[0] <= '9')) - { - argno = 10 * argno + (c[0] - '0'); - ++c; - } - assert (c[0] == '@'); - if (argno == 0) - printf ("%s", name); - else if (argno == 99) - { /* Yeah, this is a major kludge. */ - printf ("\n"); - spaces = INDENT_SUMMARY + 1; - while (spaces--) - fputc (' ', stdout); - } - else - printf ("%s", argument_name_string (imp, argno - 1)); - } - else - fputc (c[0], stdout); - } - } - printf ("\n"); - return; - } - - printf ("@node %s Intrinsic", name); - if (spec != FFEINTRIN_specNONE) - printf (" (%s)", specs[spec].name); - printf ("\n@subsubsection %s Intrinsic", name); - if (spec != FFEINTRIN_specNONE) - printf (" (%s)", specs[spec].name); - printf ("\n@cindex %s intrinsic\n@cindex intrinsics, %s\n", - name, name); - - if (imp == FFEINTRIN_impNONE) - { - printf ("\n\ -This intrinsic is not yet implemented.\n\ -The name is, however, reserved as an intrinsic.\n\ -Use @samp{EXTERNAL %s} to use this name for an\n\ -external procedure.\n\ -\n\ -", - name); - return; - } - - c = imps[imp].control; - subr = (c[0] == '-'); - colon = (c[2] == ':') ? 2 : 3; - - printf ("\n\ -@noindent\n\ -@example\n\ -%s%s(", - (subr ? "CALL " : ""), name); - - fflush (stdout); - - for (argno = 0; ; ++argno) - { - argc = argument_name_ptr (imp, argno); - if (argc == NULL) - break; - if (argno > 0) - printf (", "); - printf ("@var{%s}", argc); - argi = argument_info_string (imp, argno); - if ((argi[0] == '*') - || (argi[0] == 'n') - || (argi[0] == '+') - || (argi[0] == 'p')) - printf ("-1, @var{%s}-2, @dots{}, @var{%s}-n", - argc, argc); - } - - printf (")\n\ -@end example\n\ -\n\ -"); - - if (!subr) - { - int other_arg; - char *arg_string; - char *arg_info; - - if ((c[colon + 1] >= '0') - && (c[colon + 1] <= '9')) - { - other_arg = c[colon + 1] - '0'; - arg_string = argument_name_string (imp, other_arg); - arg_info = argument_info_string (imp, other_arg); - } - else - { - other_arg = -1; - arg_string = NULL; - arg_info = NULL; - } - - printf ("\ -@noindent\n\ -%s: ", name); - print_type_string (c); - printf (" function"); - - if ((c[0] == 'R') - && (c[1] == 'C')) - { - assert (other_arg >= 0); - - if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+') - || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p')) - ++arg_info; - if ((arg_info[0] == 'F') || (arg_info[0] == 'N')) - printf (".\n\ -The exact type is @samp{REAL(KIND=1)} when argument @var{%s} is\n\ -any type other than @code{COMPLEX}, or when it is @code{COMPLEX(KIND=1)}.\n\ -When @var{%s} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)},\n\ -this intrinsic is valid only when used as the argument to\n\ -@code{REAL()}, as explained below.\n\n", - arg_string, - arg_string); - else - printf (".\n\ -This intrinsic is valid when argument @var{%s} is\n\ -@code{COMPLEX(KIND=1)}.\n\ -When @var{%s} is any other @code{COMPLEX} type,\n\ -this intrinsic is valid only when used as the argument to\n\ -@code{REAL()}, as explained below.\n\n", - arg_string, - arg_string); - } -#if 0 - else if ((c[0] == 'I') - && (c[1] == '7')) - printf (", the exact type being wide enough to hold a pointer\n\ -on the target system (typically @code{INTEGER(KIND=1)} or @code{INTEGER(KIND=4)}).\n\n"); -#endif - else if ((c[1] == '=') - && (c[colon + 1] >= '0') - && (c[colon + 1] <= '9')) - { - assert (other_arg >= 0); - - if ((arg_info[0] == '?') || (arg_info[0] == '!') || (arg_info[0] == '+') - || (arg_info[0] == '*') || (arg_info[0] == 'n') || (arg_info[0] == 'p')) - ++arg_info; - - if (((c[0] == arg_info[0]) - && ((c[0] == 'A') || (c[0] == 'C') || (c[0] == 'I') - || (c[0] == 'L') || (c[0] == 'R'))) - || ((c[0] == 'R') - && (arg_info[0] == 'C')) - || ((c[0] == 'C') - && (arg_info[0] == 'R'))) - printf (", the @samp{KIND=} value of the type being that of argument @var{%s}.\n\n", - arg_string); - else if ((c[0] == 'S') - && ((arg_info[0] == 'C') - || (arg_info[0] == 'F') - || (arg_info[0] == 'N'))) - printf (".\n\ -The exact type depends on that of argument @var{%s}---if @var{%s} is\n\ -@code{COMPLEX}, this function's type is @code{REAL}\n\ -with the same @samp{KIND=} value as the type of @var{%s}.\n\ -Otherwise, this function's type is the same as that of @var{%s}.\n\n", - arg_string, arg_string, arg_string, arg_string); - else - printf (", the exact type being that of argument @var{%s}.\n\n", - arg_string); - } - else if ((c[1] == '=') - && (c[colon + 1] == '*')) - printf (", the exact type being the result of cross-promoting the\n\ -types of all the arguments.\n\n"); - else if (c[1] == '=') - assert ("?0:?:" == NULL); - else - printf (".\n\n"); - } - - for (argno = 0, argc = &c[colon + 3]; *argc != '\0'; ++argno) - { - char optionality = '\0'; - char extra = '\0'; - char basic; - char kind; - int length; - int elements; - - printf ("\ -@noindent\n\ -@var{"); - for (; ; ++argc) - { - if (argc[0] == '=') - break; - printf ("%c", *argc); - } - printf ("}: "); - - ++argc; - if ((*argc == '?') - || (*argc == '!') - || (*argc == '*') - || (*argc == '+') - || (*argc == 'n') - || (*argc == 'p')) - optionality = *(argc++); - basic = *(argc++); - kind = *(argc++); - if (*argc == '[') - { - length = *++argc - '0'; - if (*++argc != ']') - length = 10 * length + (*(argc++) - '0'); - ++argc; - } - else - length = -1; - if (*argc == '(') - { - elements = *++argc - '0'; - if (*++argc != ')') - elements = 10 * elements + (*(argc++) - '0'); - ++argc; - } - else if (*argc == '&') - { - elements = -1; - ++argc; - } - else - elements = 0; - if ((*argc == '&') - || (*argc == 'i') - || (*argc == 'w') - || (*argc == 'x')) - extra = *(argc++); - if (*argc == ',') - ++argc; - - switch (basic) - { - case '-': - switch (kind) - { - case '*': - printf ("Any type"); - break; - - default: - assert ("kind arg" == NULL); - break; - } - break; - - case 'A': - assert ((kind == '1') || (kind == '*')); - printf ("@code{CHARACTER"); - if (length != -1) - printf ("*%d", length); - printf ("}"); - break; - - case 'C': - switch (kind) - { - case '*': - printf ("@code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{COMPLEX(KIND=%d)}", (kind - '0')); - break; - - case 'A': - printf ("Same @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Ca" == NULL); - break; - } - break; - - case 'I': - switch (kind) - { - case '*': - printf ("@code{INTEGER}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)}", (kind - '0')); - break; - - case 'A': - printf ("@code{INTEGER} with same @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Ia" == NULL); - break; - } - break; - - case 'L': - switch (kind) - { - case '*': - printf ("@code{LOGICAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{LOGICAL(KIND=%d)}", (kind - '0')); - break; - - case 'A': - printf ("@code{LOGICAL} with same @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("La" == NULL); - break; - } - break; - - case 'R': - switch (kind) - { - case '*': - printf ("@code{REAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{REAL(KIND=%d)}", (kind - '0')); - break; - - case 'A': - printf ("@code{REAL} with same @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Ra" == NULL); - break; - } - break; - - case 'B': - switch (kind) - { - case '*': - printf ("@code{INTEGER} or @code{LOGICAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - case 'A': - printf ("Same type and @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Ba" == NULL); - break; - } - break; - - case 'F': - switch (kind) - { - case '*': - printf ("@code{REAL} or @code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - case 'A': - printf ("Same type as @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Fa" == NULL); - break; - } - break; - - case 'N': - switch (kind) - { - case '*': - printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}", - (kind - '0'), (kind - '0'), (kind - '0')); - break; - - default: - assert ("N1" == NULL); - break; - } - break; - - case 'S': - switch (kind) - { - case '*': - printf ("@code{INTEGER} or @code{REAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - case 'A': - printf ("@code{INTEGER} or @code{REAL} with same @samp{KIND=} value as for @var{%s}", - argument_name_string (imp, 0)); - break; - - default: - assert ("Sa" == NULL); - break; - } - break; - - case 'g': - printf ("@samp{*@var{label}}, where @var{label} is the label\n\ -of an executable statement"); - break; - - case 's': - printf ("Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE})\n\ -or dummy/global @code{INTEGER(KIND=1)} scalar"); - break; - - default: - assert ("arg type?" == NULL); - break; - } - - switch (optionality) - { - case '\0': - break; - - case '!': - printf ("; OPTIONAL (must be omitted if @var{%s} is @code{COMPLEX})", - argument_name_string (imp, argno-1)); - break; - - case '?': - printf ("; OPTIONAL"); - break; - - case '*': - printf ("; OPTIONAL"); - break; - - case 'n': - case '+': - break; - - case 'p': - printf ("; at least two such arguments must be provided"); - break; - - default: - assert ("optionality!" == NULL); - break; - } - - switch (elements) - { - case -1: - break; - - case 0: - if ((basic != 'g') - && (basic != 's')) - printf ("; scalar"); - break; - - default: - assert (extra != '\0'); - printf ("; DIMENSION(%d)", elements); - break; - } - - switch (extra) - { - case '\0': - if ((basic != 'g') - && (basic != 's')) - printf ("; INTENT(IN)"); - break; - - case 'i': - break; - - case '&': - printf ("; cannot be a constant or expression"); - break; - - case 'w': - printf ("; INTENT(OUT)"); - break; - - case 'x': - printf ("; INTENT(INOUT)"); - break; - } - - printf (".\n\n"); - } - - printf ("\ -@noindent\n\ -Intrinsic groups: "); - switch (family) - { - case FFEINTRIN_familyF77: - printf ("(standard FORTRAN 77)."); - break; - - case FFEINTRIN_familyGNU: - printf ("@code{gnu}."); - break; - - case FFEINTRIN_familyASC: - printf ("@code{f2c}, @code{f90}."); - break; - - case FFEINTRIN_familyMIL: - printf ("@code{mil}, @code{f90}, @code{vxt}."); - break; - - case FFEINTRIN_familyF90: - printf ("@code{f90}."); - break; - - case FFEINTRIN_familyVXT: - printf ("@code{vxt}."); - break; - - case FFEINTRIN_familyFVZ: - printf ("@code{f2c}, @code{vxt}."); - break; - - case FFEINTRIN_familyF2C: - printf ("@code{f2c}."); - break; - - case FFEINTRIN_familyF2U: - printf ("@code{unix}."); - break; - - case FFEINTRIN_familyBADU77: - printf ("@code{badu77}."); - break; - - default: - assert ("bad family" == NULL); - printf ("@code{???}."); - break; - } - printf ("\n\n"); - - if (descriptions[imp] != NULL) - { - char *c = descriptions[imp]; - - printf ("\ -@noindent\n\ -Description:\n\ -\n"); - - while (c[0] != '\0') - { - if ((c[0] == '@') - && (c[1] >= '0') - && (c[1] <= '9')) - { - int argno = c[1] - '0'; - - c += 2; - while ((c[0] >= '0') - && (c[0] <= '9')) - { - argno = 10 * argno + (c[0] - '0'); - ++c; - } - assert (c[0] == '@'); - if (argno == 0) - printf ("%s", name_uc); - else - printf ("%s", argument_name_string (imp, argno - 1)); - } - else - fputc (c[0], stdout); - ++c; - } - - printf ("\n"); - } -} - -static char * -argument_info_ptr (ffeintrinImp imp, int argno) -{ - char *c = imps[imp].control; - static char arginfos[8][32]; - static int argx = 0; - int i; - - if (c[2] == ':') - c += 5; - else - c += 6; - - while (argno--) - { - while ((c[0] != ',') && (c[0] != '\0')) - ++c; - if (c[0] != ',') - break; - ++c; - } - - if (c[0] == '\0') - return NULL; - - for (; (c[0] != '=') && (c[0] != '\0'); ++c) - ; - - assert (c[0] == '='); - - for (i = 0, ++c; (c[0] != ',') && (c[0] != '\0'); ++c, ++i) - arginfos[argx][i] = c[0]; - - arginfos[argx][i] = '\0'; - - c = &arginfos[argx][0]; - ++argx; - if (((size_t) argx) >= ARRAY_SIZE (arginfos)) - argx = 0; - - return c; -} - -static char * -argument_info_string (ffeintrinImp imp, int argno) -{ - char *p; - - p = argument_info_ptr (imp, argno); - assert (p != NULL); - return p; -} - -static char * -argument_name_ptr (ffeintrinImp imp, int argno) -{ - char *c = imps[imp].control; - static char argnames[8][32]; - static int argx = 0; - int i; - - if (c[2] == ':') - c += 5; - else - c += 6; - - while (argno--) - { - while ((c[0] != ',') && (c[0] != '\0')) - ++c; - if (c[0] != ',') - break; - ++c; - } - - if (c[0] == '\0') - return NULL; - - for (i = 0; (c[0] != '=') && (c[0] != '\0'); ++c, ++i) - argnames[argx][i] = c[0]; - - assert (c[0] == '='); - argnames[argx][i] = '\0'; - - c = &argnames[argx][0]; - ++argx; - if (((size_t) argx) >= ARRAY_SIZE (argnames)) - argx = 0; - - return c; -} - -static char * -argument_name_string (ffeintrinImp imp, int argno) -{ - char *p; - - p = argument_name_ptr (imp, argno); - assert (p != NULL); - return p; -} - -static void -print_type_string (char *c) -{ - char basic = c[0]; - char kind = c[1]; - - switch (basic) - { - case 'A': - assert ((kind == '1') || (kind == '=')); - if (c[2] == ':') - printf ("@code{CHARACTER*1}"); - else - { - assert (c[2] == '*'); - printf ("@code{CHARACTER*(*)}"); - } - break; - - case 'C': - switch (kind) - { - case '=': - printf ("@code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{COMPLEX(KIND=%d)}", (kind - '0')); - break; - - default: - assert ("Ca" == NULL); - break; - } - break; - - case 'I': - switch (kind) - { - case '=': - printf ("@code{INTEGER}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)}", (kind - '0')); - break; - - default: - assert ("Ia" == NULL); - break; - } - break; - - case 'L': - switch (kind) - { - case '=': - printf ("@code{LOGICAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{LOGICAL(KIND=%d)}", (kind - '0')); - break; - - default: - assert ("La" == NULL); - break; - } - break; - - case 'R': - switch (kind) - { - case '=': - printf ("@code{REAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{REAL(KIND=%d)}", (kind - '0')); - break; - - case 'C': - printf ("@code{REAL}"); - break; - - default: - assert ("Ra" == NULL); - break; - } - break; - - case 'B': - switch (kind) - { - case '=': - printf ("@code{INTEGER} or @code{LOGICAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)} or @code{LOGICAL(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - default: - assert ("Ba" == NULL); - break; - } - break; - - case 'F': - switch (kind) - { - case '=': - printf ("@code{REAL} or @code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{REAL(KIND=%d)} or @code{COMPLEX(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - default: - assert ("Fa" == NULL); - break; - } - break; - - case 'N': - switch (kind) - { - case '=': - printf ("@code{INTEGER}, @code{REAL}, or @code{COMPLEX}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)}, @code{REAL(KIND=%d)}, or @code{COMPLEX(KIND=%d)}", - (kind - '0'), (kind - '0'), (kind - '0')); - break; - - default: - assert ("N1" == NULL); - break; - } - break; - - case 'S': - switch (kind) - { - case '=': - printf ("@code{INTEGER} or @code{REAL}"); - break; - - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - printf ("@code{INTEGER(KIND=%d)} or @code{REAL(KIND=%d)}", - (kind - '0'), (kind - '0')); - break; - - default: - assert ("Sa" == NULL); - break; - } - break; - - default: - assert ("type?" == NULL); - break; - } -} diff --git a/gcc/f/intdoc.in b/gcc/f/intdoc.in deleted file mode 100755 index a4af532..0000000 --- a/gcc/f/intdoc.in +++ /dev/null @@ -1,2498 +0,0 @@ -/* Copyright (C) 1997 Free Software Foundation, Inc. - * This is part of the G77 manual. - * For copying conditions, see the file g77.texi. */ - -/* This is the file containing the verbage for the - intrinsics. It consists of a data base built up - via DEFDOC macros of the form: - - DEFDOC (IMP, SUMMARY, DESCRIPTION) - - IMP is the implementation keyword used in the intrin module. - SUMMARY is the short summary to go in the "* Menu:" section - of the Info document. DESCRIPTION is the longer description - to go in the documentation itself. - - Note that IMP is leveraged across multiple intrinsic names. - - To make for more accurate and consistent documentation, - the translation made by intdoc.c of the text in SUMMARY - and DESCRIPTION includes the special sequence - - @ARGNO@ - - where ARGNO is a series of digits forming a number that - is substituted by intdoc.c as follows: - - 0 The initial-caps form of the intrinsic name (e.g. Float). - 1-98 The initial-caps form of the ARGNO'th argument. - 99 (SUMMARY only) a newline plus the appropriate # of spaces. - - Hope this info is enough to encourage people to feel free to - add documentation to this file! - -*/ - -#define ARCHAIC(upper,mixed) \ - "Archaic form of @code{" #upper "()} that is specific\n\ -to one type for @var{@1@}.\n\ -@xref{" #mixed " Intrinsic}.\n" - -#define ARCHAIC_2nd(upper,mixed) \ - "Archaic form of @code{" #upper "()} that is specific\n\ -to one type for @var{@2@}.\n\ -@xref{" #mixed " Intrinsic}.\n" - -#define ARCHAIC_2(upper,mixed) \ - "Archaic form of @code{" #upper "()} that is specific\n\ -to one type for @var{@1@} and @var{@2@}.\n\ -@xref{" #mixed " Intrinsic}.\n" - -DEFDOC (ABS, "Absolute value.", "\ -Returns the absolute value of @var{@1@}. - -If @var{@1@} is type @code{COMPLEX}, the absolute -value is computed as: - -@example -SQRT(REALPART(@var{@1@})**2, IMAGPART(@var{@1@})**2) -@end example - -@noindent -Otherwise, it is computed by negating the @var{@1@} if -it is negative, or returning @var{@1@}. - -@xref{Sign Intrinsic}, for how to explicitly -compute the positive or negative form of the absolute -value of an expression. -") - -DEFDOC (CABS, "Absolute value (archaic).", ARCHAIC (ABS, Abs)) - -DEFDOC (DABS, "Absolute value (archaic).", ARCHAIC (ABS, Abs)) - -DEFDOC (IABS, "Absolute value (archaic).", ARCHAIC (ABS, Abs)) - -DEFDOC (CDABS, "Absolute value (archaic).", ARCHAIC (ABS, Abs)) - -DEFDOC (ACHAR, "ASCII character from code.", "\ -Returns the ASCII character corresponding to the -code specified by @var{@1@}. - -@xref{IAChar Intrinsic}, for the inverse of this function. - -@xref{Char Intrinsic}, for the function corresponding -to the system's native character set. -") - -DEFDOC (IACHAR, "ASCII code for character.", "\ -Returns the code for the ASCII character in the -first character position of @var{@1@}. - -@xref{AChar Intrinsic}, for the inverse of this function. - -@xref{IChar Intrinsic}, for the function corresponding -to the system's native character set. -") - -DEFDOC (CHAR, "Character from code.", "\ -Returns the character corresponding to the -code specified by @var{@1@}, using the system's -native character set. - -Because the system's native character set is used, -the correspondence between character and their codes -is not necessarily the same between GNU Fortran -implementations. - -Note that no intrinsic exists to convert a numerical -value to a printable character string. -For example, there is no intrinsic that, given -an @code{INTEGER} or @code{REAL} argument with the -value @samp{154}, returns the @code{CHARACTER} -result @samp{'154'}. - -Instead, you can use internal-file I/O to do this kind -of conversion. -For example: - -@smallexample -INTEGER VALUE -CHARACTER*10 STRING -VALUE = 154 -WRITE (STRING, '(I10)'), VALUE -PRINT *, STRING -END -@end smallexample - -The above program, when run, prints: - -@smallexample - 154 -@end smallexample - -@xref{IChar Intrinsic}, for the inverse of the @code{@0@} function. - -@xref{AChar Intrinsic}, for the function corresponding -to the ASCII character set. -") - -DEFDOC (ICHAR, "Code for character.", "\ -Returns the code for the character in the -first character position of @var{@1@}. - -Because the system's native character set is used, -the correspondence between character and their codes -is not necessarily the same between GNU Fortran -implementations. - -Note that no intrinsic exists to convert a printable -character string to a numerical value. -For example, there is no intrinsic that, given -the @code{CHARACTER} value @samp{'154'}, returns an -@code{INTEGER} or @code{REAL} value with the value @samp{154}. - -Instead, you can use internal-file I/O to do this kind -of conversion. -For example: - -@smallexample -INTEGER VALUE -CHARACTER*10 STRING -STRING = '154' -READ (STRING, '(I10)'), VALUE -PRINT *, VALUE -END -@end smallexample - -The above program, when run, prints: - -@smallexample - 154 -@end smallexample - -@xref{Char Intrinsic}, for the inverse of the @code{@0@} function. - -@xref{IAChar Intrinsic}, for the function corresponding -to the ASCII character set. -") - -DEFDOC (ACOS, "Arc cosine.", "\ -Returns the arc-cosine (inverse cosine) of @var{@1@} -in radians. - -@xref{Cos Intrinsic}, for the inverse of this function. -") - -DEFDOC (DACOS, "Arc cosine (archaic).", ARCHAIC (ACOS, ACos)) - -DEFDOC (AIMAG, "Convert/extract imaginary part of complex.", "\ -Returns the (possibly converted) imaginary part of @var{@1@}. - -Use of @code{@0@()} with an argument of a type -other than @code{COMPLEX(KIND=1)} is restricted to the following case: - -@example -REAL(AIMAG(@1@)) -@end example - -@noindent -This expression converts the imaginary part of @1@ to -@code{REAL(KIND=1)}. - -@xref{REAL() and AIMAG() of Complex}, for more information. -") - -DEFDOC (DIMAG, "Convert/extract imaginary part of complex (archaic).", ARCHAIC (AIMAG, AImag)) - -DEFDOC (AINT, "Truncate to whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude truncated and its sign preserved. -(Also called ``truncation towards zero''.) - -@xref{ANInt Intrinsic}, for how to round to nearest -whole number. - -@xref{Int Intrinsic}, for how to truncate and then convert -number to @code{INTEGER}. -") - -DEFDOC (DINT, "Truncate to whole number (archaic).", ARCHAIC (AINT, AInt)) - -DEFDOC (INT, "Convert to @code{INTEGER} value truncated@99@to whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=1)}. - -If @var{@1@} is type @code{COMPLEX}, its real part is -truncated and converted, and its imaginary part is disregarded. - -@xref{NInt Intrinsic}, for how to convert, rounded to nearest -whole number. - -@xref{AInt Intrinsic}, for how to truncate to whole number -without converting. -") - -DEFDOC (IDINT, "Convert to @code{INTEGER} value truncated@99@to whole number (archaic).", ARCHAIC (INT, Int)) - -DEFDOC (ANINT, "Round to nearest whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude eliminated by rounding to the nearest whole -number and with its sign preserved. - -A fractional portion exactly equal to -@samp{.5} is rounded to the whole number that -is larger in magnitude. -(Also called ``Fortran round''.) - -@xref{AInt Intrinsic}, for how to truncate to -whole number. - -@xref{NInt Intrinsic}, for how to round and then convert -number to @code{INTEGER}. -") - -DEFDOC (DNINT, "Round to nearest whole number (archaic).", ARCHAIC (ANINT, ANInt)) - -DEFDOC (NINT, "Convert to @code{INTEGER} value rounded@99@to nearest whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude eliminated by rounding to the nearest whole -number and with its sign preserved, converted -to type @code{INTEGER(KIND=1)}. - -If @var{@1@} is type @code{COMPLEX}, its real part is -rounded and converted. - -A fractional portion exactly equal to -@samp{.5} is rounded to the whole number that -is larger in magnitude. -(Also called ``Fortran round''.) - -@xref{Int Intrinsic}, for how to convert, truncate to -whole number. - -@xref{ANInt Intrinsic}, for how to round to nearest whole number -without converting. -") - -DEFDOC (IDNINT, "Convert to @code{INTEGER} value rounded@99@to nearest whole number (archaic).", ARCHAIC (NINT, NInt)) - -DEFDOC (LOG, "Natural logarithm.", "\ -Returns the natural logarithm of @var{@1@}, which must -be greater than zero or, if type @code{COMPLEX}, must not -be zero. - -@xref{Exp Intrinsic}, for the inverse of this function. - -@xref{Log10 Intrinsic}, for the base-10 logarithm function. -") - -DEFDOC (ALOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log)) - -DEFDOC (CLOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log)) - -DEFDOC (DLOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log)) - -DEFDOC (CDLOG, "Natural logarithm (archaic).", ARCHAIC (LOG, Log)) - -DEFDOC (LOG10, "Natural logarithm.", "\ -Returns the natural logarithm of @var{@1@}, which must -be greater than zero or, if type @code{COMPLEX}, must not -be zero. - -The inverse of this function is @samp{10. ** LOG10(@var{@1@})}. - -@xref{Log Intrinsic}, for the natural logarithm function. -") - -DEFDOC (ALOG10, "Natural logarithm (archaic).", ARCHAIC (LOG10, Log10)) - -DEFDOC (DLOG10, "Natural logarithm (archaic).", ARCHAIC (LOG10, Log10)) - -DEFDOC (MAX, "Maximum value.", "\ -Returns the argument with the largest value. - -@xref{Min Intrinsic}, for the opposite function. -") - -DEFDOC (AMAX0, "Maximum value (archaic).", "\ -Archaic form of @code{MAX()} that is specific -to one type for @var{@1@} and a different return type. -@xref{Max Intrinsic}. -") - -DEFDOC (AMAX1, "Maximum value (archaic).", ARCHAIC (MAX, Max)) - -DEFDOC (DMAX1, "Maximum value (archaic).", ARCHAIC (MAX, Max)) - -DEFDOC (MAX0, "Maximum value (archaic).", ARCHAIC (MAX, Max)) - -DEFDOC (MAX1, "Maximum value (archaic).", "\ -Archaic form of @code{MAX()} that is specific -to one type for @var{@1@} and a different return type. -@xref{Max Intrinsic}. -") - -DEFDOC (MIN, "Minimum value.", "\ -Returns the argument with the smallest value. - -@xref{Max Intrinsic}, for the opposite function. -") - -DEFDOC (AMIN0, "Minimum value (archaic).", "\ -Archaic form of @code{MIN()} that is specific -to one type for @var{@1@} and a different return type. -@xref{Min Intrinsic}. -") - -DEFDOC (AMIN1, "Minimum value (archaic).", ARCHAIC (MIN, Min)) - -DEFDOC (DMIN1, "Minimum value (archaic).", ARCHAIC (MIN, Min)) - -DEFDOC (MIN0, "Minimum value (archaic).", ARCHAIC (MIN, Min)) - -DEFDOC (MIN1, "Minimum value (archaic).", "\ -Archaic form of @code{MIN()} that is specific -to one type for @var{@1@} and a different return type. -@xref{Min Intrinsic}. -") - -DEFDOC (MOD, "Remainder.", "\ -Returns remainder calculated as: - -@smallexample -@var{@1@} - (INT(@var{@1@} / @var{@2@}) * @var{@2@}) -@end smallexample - -@var{@2@} must not be zero. -") - -DEFDOC (AMOD, "Remainder (archaic).", ARCHAIC (MOD, Mod)) - -DEFDOC (DMOD, "Remainder (archaic).", ARCHAIC (MOD, Mod)) - -DEFDOC (AND, "Boolean AND.", "\ -Returns value resulting from boolean AND of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (IAND, "Boolean AND.", "\ -Returns value resulting from boolean AND of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (OR, "Boolean OR.", "\ -Returns value resulting from boolean OR of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (IOR, "Boolean OR.", "\ -Returns value resulting from boolean OR of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (XOR, "Boolean XOR.", "\ -Returns value resulting from boolean exclusive-OR of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (IEOR, "Boolean XOR.", "\ -Returns value resulting from boolean exclusive-OR of -pair of bits in each of @var{@1@} and @var{@2@}. -") - -DEFDOC (NOT, "Boolean NOT.", "\ -Returns value resulting from boolean NOT of each bit -in @var{@1@}. -") - -DEFDOC (ASIN, "Arc sine.", "\ -Returns the arc-sine (inverse sine) of @var{@1@} -in radians. - -@xref{Sin Intrinsic}, for the inverse of this function. -") - -DEFDOC (DASIN, "Arc sine (archaic).", ARCHAIC (ASIN, ASin)) - -DEFDOC (ATAN, "Arc tangent.", "\ -Returns the arc-tangent (inverse tangent) of @var{@1@} -in radians. - -@xref{Tan Intrinsic}, for the inverse of this function. -") - -DEFDOC (DATAN, "Arc tangent (archaic).", ARCHAIC (ATAN, ATan)) - -DEFDOC (ATAN2, "Arc tangent.", "\ -Returns the arc-tangent (inverse tangent) of the complex -number (@var{@1@}, @var{@2@}) in radians. - -@xref{Tan Intrinsic}, for the inverse of this function. -") - -DEFDOC (DATAN2, "Arc tangent (archaic).", ARCHAIC_2 (ATAN2, ATan2)) - -DEFDOC (BIT_SIZE, "Number of bits in argument's type.", "\ -Returns the number of bits (integer precision plus sign bit) -represented by the type for @var{@1@}. - -@xref{BTest Intrinsic}, for how to test the value of a -bit in a variable or array. - -@xref{IBSet Intrinsic}, for how to set a bit in a variable to 1. - -@xref{IBClr Intrinsic}, for how to set a bit in a variable to 0. - -") - -DEFDOC (BTEST, "Test bit.", "\ -Returns @code{.TRUE.} if bit @var{@2@} in @var{@1@} is -1, @code{.FALSE.} otherwise. - -(Bit 0 is the low-order (rightmost) bit, adding the value -@ifinfo -2**0, -@end ifinfo -@iftex -@tex -$2^0$, -@end tex -@end iftex -or 1, -to the number if set to 1; -bit 1 is the next-higher-order bit, adding -@ifinfo -2**1, -@end ifinfo -@iftex -@tex -$2^1$, -@end tex -@end iftex -or 2; -bit 2 adds -@ifinfo -2**2, -@end ifinfo -@iftex -@tex -$2^2$, -@end tex -@end iftex -or 4; and so on.) - -@xref{Bit_Size Intrinsic}, for how to obtain the number of bits -in a type. -The leftmost bit of @var{@1@} is @samp{BIT_SIZE(@var{@1@}-1)}. -") - -DEFDOC (CMPLX, "Construct @code{COMPLEX(KIND=1)} value.", "\ -If @var{@1@} is not type @code{COMPLEX}, -constructs a value of type @code{COMPLEX(KIND=1)} from the -real and imaginary values specified by @var{@1@} and -@var{@2@}, respectively. -If @var{@2@} is omitted, @samp{0.} is assumed. - -If @var{@1@} is type @code{COMPLEX}, -converts it to type @code{COMPLEX(KIND=1)}. - -@xref{Complex Intrinsic}, for information on easily constructing -a @code{COMPLEX} value of arbitrary precision from @code{REAL} -arguments. -") - -DEFDOC (DCMPLX, "Construct @code{COMPLEX(KIND=2)} value.", "\ -If @var{@1@} is not type @code{COMPLEX}, -constructs a value of type @code{COMPLEX(KIND=2)} from the -real and imaginary values specified by @var{@1@} and -@var{@2@}, respectively. -If @var{@2@} is omitted, @samp{0D0} is assumed. - -If @var{@1@} is type @code{COMPLEX}, -converts it to type @code{COMPLEX(KIND=2)}. - -Although this intrinsic is not standard Fortran, -it is a popular extension offered by many compilers -that support @code{DOUBLE COMPLEX}, since it offers -the easiest way to convert to @code{DOUBLE COMPLEX} -without using Fortran 90 features (such as the @samp{KIND=} -argument to the @code{CMPLX()} intrinsic). - -(@samp{CMPLX(0D0, 0D0)} returns a single-precision -@code{COMPLEX} result, as required by standard FORTRAN 77. -That's why so many compilers provide @code{DCMPLX()}, since -@samp{DCMPLX(0D0, 0D0)} returns a @code{DOUBLE COMPLEX} -result. -Still, @code{DCMPLX()} converts even @code{REAL*16} arguments -to their @code{REAL*8} equivalents in most dialects of -Fortran, so neither it nor @code{CMPLX()} allow easy -construction of arbitrary-precision values without -potentially forcing a conversion involving extending or -reducing precision. -GNU Fortran provides such an intrinsic, called @code{COMPLEX()}.) - -@xref{Complex Intrinsic}, for information on easily constructing -a @code{COMPLEX} value of arbitrary precision from @code{REAL} -arguments. -") - -DEFDOC (CONJG, "Complex conjugate.", "\ -Returns the complex conjugate: - -@example -COMPLEX(REALPART(@var{@1@}), -IMAGPART(@var{@1@})) -@end example -") - -DEFDOC (DCONJG, "Complex conjugate (archaic).", ARCHAIC (CONJG, Conjg)) - -DEFDOC (COS, "Cosine.", "\ -Returns the cosine of @var{@1@}, an angle measured -in radians. - -@xref{ACos Intrinsic}, for the inverse of this function. -") - -DEFDOC (CCOS, "Cosine (archaic).", ARCHAIC (COS, Cos)) - -DEFDOC (DCOS, "Cosine (archaic).", ARCHAIC (COS, Cos)) - -DEFDOC (CDCOS, "Cosine (archaic).", ARCHAIC (COS, Cos)) - -DEFDOC (COSH, "Hyperbolic cosine.", "\ -Returns the hyperbolic cosine of @var{@1@}. -") - -DEFDOC (DCOSH, "Hyperbolic cosine (archaic).", ARCHAIC (COSH, CosH)) - -DEFDOC (SQRT, "Square root.", "\ -Returns the square root of @var{@1@}, which must -not be negative. - -To calculate and represent the square root of a negative -number, complex arithmetic must be used. -For example, @samp{SQRT(COMPLEX(@var{@1@}))}. - -The inverse of this function is @samp{SQRT(@var{@1@}) * SQRT(@var{@1@})}. -") - -DEFDOC (CSQRT, "Square root (archaic).", ARCHAIC (SQRT, SqRt)) - -DEFDOC (DSQRT, "Square root (archaic).", ARCHAIC (SQRT, SqRt)) - -DEFDOC (CDSQRT, "Square root (archaic).", ARCHAIC (SQRT, SqRt)) - -DEFDOC (DBLE, "Convert to double precision.", "\ -Returns @var{@1@} converted to double precision -(@code{REAL(KIND=2)}). -If @var{@1@} is @code{COMPLEX}, the real part of -@var{@1@} is used for the conversion -and the imaginary part disregarded. - -@xref{Sngl Intrinsic}, for the function that converts -to single precision. - -@xref{Int Intrinsic}, for the function that converts -to @code{INTEGER}. - -@xref{Complex Intrinsic}, for the function that converts -to @code{COMPLEX}. -") - -DEFDOC (DIM, "Difference magnitude (non-negative subtract).", "\ -Returns @samp{@var{@1@}-@var{@2@}} if @var{@1@} is greater than -@var{@2@}; otherwise returns zero. -") - -DEFDOC (DDIM, "Difference magnitude (archaic).", ARCHAIC_2 (DIM, DiM)) -DEFDOC (IDIM, "Difference magnitude (archaic).", ARCHAIC_2 (DIM, DiM)) - -DEFDOC (DPROD, "Double-precision product.", "\ -Returns @samp{DBLE(@var{@1@})*DBLE(@var{@2@})}. -") - -DEFDOC (EXP, "Exponential.", "\ -Returns @samp{@var{e}**@var{@1@}}, where -@var{e} is approximately 2.7182818. - -@xref{Log Intrinsic}, for the inverse of this function. -") - -DEFDOC (CEXP, "Exponential (archaic).", ARCHAIC (EXP, Exp)) - -DEFDOC (DEXP, "Exponential (archaic).", ARCHAIC (EXP, Exp)) - -DEFDOC (CDEXP, "Exponential (archaic).", ARCHAIC (EXP, Exp)) - -DEFDOC (FLOAT, "Conversion (archaic).", ARCHAIC (REAL, Real)) -DEFDOC (DFLOAT, "Conversion (archaic).", ARCHAIC (REAL, Real)) - -DEFDOC (IFIX, "Conversion (archaic).", ARCHAIC (INT, Int)) - -DEFDOC (LONG, "Conversion to @code{INTEGER(KIND=1)} (archaic).", "\ -Archaic form of @code{INT()} that is specific -to one type for @var{@1@}. -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. -") - -DEFDOC (SHORT, "Convert to @code{INTEGER(KIND=6)} value@99@truncated to whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=6)}. - -If @var{@1@} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. -") - -DEFDOC (INT2, "Convert to @code{INTEGER(KIND=6)} value@99@truncated to whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=6)}. - -If @var{@1@} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. -") - -DEFDOC (INT8, "Convert to @code{INTEGER(KIND=2)} value@99@truncated to whole number.", "\ -Returns @var{@1@} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=2)}. - -If @var{@1@} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. -") - -DEFDOC (LEN, "Length of character entity.", "\ -Returns the length of @var{@1@}. - -If @var{@1@} is an array, the length of an element -of @var{@1@} is returned. - -Note that @var{@1@} need not be defined when this -intrinsic is invoked, since only the length, not -the content, of @var{@1@} is needed. - -@xref{Bit_Size Intrinsic}, for the function that determines -the size of its argument in bits. -") - -DEFDOC (TAN, "Tangent.", "\ -Returns the tangent of @var{@1@}, an angle measured -in radians. - -@xref{ATan Intrinsic}, for the inverse of this function. -") - -DEFDOC (DTAN, "Tangent (archaic).", ARCHAIC (TAN, Tan)) - -DEFDOC (TANH, "Hyperbolic tangent.", "\ -Returns the hyperbolic tangent of @var{@1@}. -") - -DEFDOC (DTANH, "Hyperbolic tangent (archaic).", ARCHAIC (TANH, TanH)) - -DEFDOC (SNGL, "Convert (archaic).", ARCHAIC (REAL, Real)) - -DEFDOC (SIN, "Sine.", "\ -Returns the sine of @var{@1@}, an angle measured -in radians. - -@xref{ASin Intrinsic}, for the inverse of this function. -") - -DEFDOC (CSIN, "Sine (archaic).", ARCHAIC (SIN, Sin)) - -DEFDOC (DSIN, "Sine (archaic).", ARCHAIC (SIN, Sin)) - -DEFDOC (CDSIN, "Sine (archaic).", ARCHAIC (SIN, Sin)) - -DEFDOC (SINH, "Hyperbolic sine.", "\ -Returns the hyperbolic sine of @var{@1@}. -") - -DEFDOC (DSINH, "Hyperbolic sine (archaic).", ARCHAIC (SINH, SinH)) - -DEFDOC (LSHIFT, "Left-shift bits.", "\ -Returns @var{@1@} shifted to the left -@var{@2@} bits. - -Although similar to the expression -@samp{@var{@1@}*(2**@var{@2@})}, there -are important differences. -For example, the sign of the result is -not necessarily the same as the sign of -@var{@1@}. - -Currently this intrinsic is defined assuming -the underlying representation of @var{@1@} -is as a two's-complement integer. -It is unclear at this point whether that -definition will apply when a different -representation is involved. - -@xref{LShift Intrinsic}, for the inverse of this function. - -@xref{IShft Intrinsic}, for information -on a more widely available left-shifting -intrinsic that is also more precisely defined. -") - -DEFDOC (RSHIFT, "Right-shift bits.", "\ -Returns @var{@1@} shifted to the right -@var{@2@} bits. - -Although similar to the expression -@samp{@var{@1@}/(2**@var{@2@})}, there -are important differences. -For example, the sign of the result is -undefined. - -Currently this intrinsic is defined assuming -the underlying representation of @var{@1@} -is as a two's-complement integer. -It is unclear at this point whether that -definition will apply when a different -representation is involved. - -@xref{RShift Intrinsic}, for the inverse of this function. - -@xref{IShft Intrinsic}, for information -on a more widely available right-shifting -intrinsic that is also more precisely defined. -") - -DEFDOC (LGE, "Lexically greater than or equal.", "\ -Returns @samp{.TRUE.} if @samp{@var{@1@}.GE.@var{@2@}}, -@samp{.FALSE.} otherwise. -@var{@1@} and @var{@2@} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{@1@} and @var{@2@} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -The lexical comparison intrinsics @code{LGe}, @code{LGt}, -@code{LLe}, and @code{LLt} differ from the corresponding -intrinsic operators @code{.GE.}, @code{.GT.}, -@code{.LE.}, @code{.LT.}. -Because the ASCII collating sequence is assumed, -the following expressions always return @samp{.TRUE.}: - -@smallexample -LGE ('0', ' ') -LGE ('A', '0') -LGE ('a', 'A') -@end smallexample - -The following related expressions do @emph{not} always -return @samp{.TRUE.}, as they are not necessarily evaluated -assuming the arguments use ASCII encoding: - -@smallexample -'0' .GE. ' ' -'A' .GE. '0' -'a' .GE. 'A' -@end smallexample - -The same difference exists -between @code{LGt} and @code{.GT.}; -between @code{LLe} and @code{.LE.}; and -between @code{LLt} and @code{.LT.}. -") - -DEFDOC (LGT, "Lexically greater than.", "\ -Returns @samp{.TRUE.} if @samp{@var{@1@}.GT.@var{@2@}}, -@samp{.FALSE.} otherwise. -@var{@1@} and @var{@2@} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{@1@} and @var{@2@} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{@0@} intrinsic and the @code{.GT.} -operator. -") - -DEFDOC (LLE, "Lexically less than or equal.", "\ -Returns @samp{.TRUE.} if @samp{@var{@1@}.LE.@var{@2@}}, -@samp{.FALSE.} otherwise. -@var{@1@} and @var{@2@} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{@1@} and @var{@2@} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{@0@} intrinsic and the @code{.LE.} -operator. -") - -DEFDOC (LLT, "Lexically less than.", "\ -Returns @samp{.TRUE.} if @samp{@var{@1@}.LT.@var{@2@}}, -@samp{.FALSE.} otherwise. -@var{@1@} and @var{@2@} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{@1@} and @var{@2@} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{@0@} intrinsic and the @code{.LT.} -operator. -") - -DEFDOC (SIGN, "Apply sign to magnitude.", "\ -Returns @samp{ABS(@var{@1@})*@var{s}}, where -@var{s} is +1 if @samp{@var{@2@}.GE.0}, --1 otherwise. - -@xref{Abs Intrinsic}, for the function that returns -the magnitude of a value. -") - -DEFDOC (DSIGN, "Apply sign to magnitude (archaic).", ARCHAIC_2 (SIGN, Sign)) -DEFDOC (ISIGN, "Apply sign to magnitude (archaic).", ARCHAIC_2 (SIGN, Sign)) - -DEFDOC (REAL, "Convert value to type @code{REAL(KIND=1)}.", "\ -Converts @var{@1@} to @code{REAL(KIND=1)}. - -Use of @code{@0@()} with a @code{COMPLEX} argument -(other than @code{COMPLEX(KIND=1)}) is restricted to the following case: - -@example -REAL(REAL(@1@)) -@end example - -@noindent -This expression converts the real part of @1@ to -@code{REAL(KIND=1)}. - -@xref{RealPart Intrinsic}, for information on a GNU Fortran -intrinsic that extracts the real part of an arbitrary -@code{COMPLEX} value. - -@xref{REAL() and AIMAG() of Complex}, for more information. -") - -DEFDOC (DREAL, "Convert value to type @code{REAL(KIND=2)}.", "\ -Converts @var{@1@} to @code{REAL(KIND=2)}. - -If @var{@1@} is type @code{COMPLEX}, its real part -is converted (if necessary) to @code{REAL(KIND=2)}, -and its imaginary part is disregarded. - -Although this intrinsic is not standard Fortran, -it is a popular extension offered by many compilers -that support @code{DOUBLE COMPLEX}, since it offers -the easiest way to extract the real part of a @code{DOUBLE COMPLEX} -value without using the Fortran 90 @code{REAL()} intrinsic -in a way that produces a return value inconsistent with -the way many FORTRAN 77 compilers handle @code{REAL()} of -a @code{DOUBLE COMPLEX} value. - -@xref{RealPart Intrinsic}, for information on a GNU Fortran -intrinsic that avoids these areas of confusion. - -@xref{Dble Intrinsic}, for information on the standard FORTRAN 77 -replacement for @code{DREAL()}. - -@xref{REAL() and AIMAG() of Complex}, for more information on -this issue. -") - -DEFDOC (IMAGPART, "Extract imaginary part of complex.", "\ -The imaginary part of @var{@1@} is returned, without conversion. - -@emph{Note:} The way to do this in standard Fortran 90 -is @samp{AIMAG(@var{@1@})}. -However, when, for example, @var{@1@} is @code{DOUBLE COMPLEX}, -@samp{AIMAG(@var{@1@})} means something different for some compilers -that are not true Fortran 90 compilers but offer some -extensions standardized by Fortran 90 (such as the -@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). - -The advantage of @code{@0@()} is that, while not necessarily -more or less portable than @code{AIMAG()}, it is more likely to -cause a compiler that doesn't support it to produce a diagnostic -than generate incorrect code. - -@xref{REAL() and AIMAG() of Complex}, for more information. -") - -DEFDOC (COMPLEX, "Build complex value from real and@99@imaginary parts.", "\ -Returns a @code{COMPLEX} value that has @samp{@1@} and @samp{@2@} as its -real and imaginary parts, respectively. - -If @var{@1@} and @var{@2@} are the same type, and that type is not -@code{INTEGER}, no data conversion is performed, and the type of -the resulting value has the same kind value as the types -of @var{@1@} and @var{@2@}. - -If @var{@1@} and @var{@2@} are not the same type, the usual type-promotion -rules are applied to both, converting either or both to the -appropriate @code{REAL} type. -The type of the resulting value has the same kind value as the -type to which both @var{@1@} and @var{@2@} were converted, in this case. - -If @var{@1@} and @var{@2@} are both @code{INTEGER}, they are both converted -to @code{REAL(KIND=1)}, and the result of the @code{@0@()} -invocation is type @code{COMPLEX(KIND=1)}. - -@emph{Note:} The way to do this in standard Fortran 90 -is too hairy to describe here, but it is important to -note that @samp{CMPLX(D1,D2)} returns a @code{COMPLEX(KIND=1)} -result even if @samp{D1} and @samp{D2} are type @code{REAL(KIND=2)}. -Hence the availability of @code{COMPLEX()} in GNU Fortran. -") - -DEFDOC (LOC, "Address of entity in core.", "\ -The @code{LOC()} intrinsic works the -same way as the @code{%LOC()} construct. -@xref{%LOC(),,The @code{%LOC()} Construct}, for -more information. -") - -DEFDOC (REALPART, "Extract real part of complex.", "\ -The real part of @var{@1@} is returned, without conversion. - -@emph{Note:} The way to do this in standard Fortran 90 -is @samp{REAL(@var{@1@})}. -However, when, for example, @var{@1@} is @code{COMPLEX(KIND=2)}, -@samp{REAL(@var{@1@})} means something different for some compilers -that are not true Fortran 90 compilers but offer some -extensions standardized by Fortran 90 (such as the -@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). - -The advantage of @code{@0@()} is that, while not necessarily -more or less portable than @code{REAL()}, it is more likely to -cause a compiler that doesn't support it to produce a diagnostic -than generate incorrect code. - -@xref{REAL() and AIMAG() of Complex}, for more information. -") - -DEFDOC (GETARG, "Obtain command-line argument.", "\ -Sets @var{@2@} to the @var{@1@}-th command-line argument (or to all -blanks if there are fewer than @var{@2@} command-line arguments); -@code{CALL @0@(0, @var{value})} sets @var{value} to the name of the -program (on systems that support this feature). - -@xref{IArgC Intrinsic}, for information on how to get the number -of arguments. -") - -DEFDOC (ABORT, "Abort the program.", "\ -Prints a message and potentially causes a core dump via @code{abort(3)}. -") - -DEFDOC (EXIT, "Terminate the program.", "\ -Exit the program with status @var{@1@} after closing open Fortran -I/O units and otherwise behaving as @code{exit(2)}. -If @var{@1@} is omitted the canonical `success' value -will be returned to the system. -") - -DEFDOC (IARGC, "Obtain count of command-line arguments.", "\ -Returns the number of command-line arguments. - -This count does not include the specification of the program -name itself. -") - -DEFDOC (CTIME_func, "Convert time to Day Mon dd hh:mm:ss yyyy.", "\ -Converts @var{@1@}, a system time value, such as returned by -@code{TIME8()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}, -and returns that string as the function value. - -@xref{Time8 Intrinsic}. -") - -DEFDOC (CTIME_subr, "Convert time to Day Mon dd hh:mm:ss yyyy.", "\ -Converts @var{@2@}, a system time value, such as returned by -@code{TIME8()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}, -and returns that string in @var{@1@}. - -@xref{Time8 Intrinsic}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (DATE, "Get current date as dd-Mon-yy.", "\ -Returns @var{@1@} in the form @samp{@var{dd}-@var{mmm}-@var{yy}}, -representing the numeric day of the month @var{dd}, a three-character -abbreviation of the month name @var{mmm} and the last two digits of -the year @var{yy}, e.g.@: @samp{25-Nov-96}. - -This intrinsic is not recommended, due to the year 2000 approaching. -@xref{CTime Intrinsic (subroutine)}, for information on obtaining more digits -for the current (or any) date. -") - -DEFDOC (DTIME_func, "Get elapsed time since last time.", "\ -Initially, return the number of seconds of runtime -since the start of the process's execution -as the function value, -and the user and system components of this in @samp{@var{@1@}(1)} -and @samp{@var{@1@}(2)} respectively. -The functions' value is equal to @samp{@var{@1@}(1) + @var{@1@}(2)}. - -Subsequent invocations of @samp{@0@()} return values accumulated since the -previous invocation. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (DTIME_subr, "Get elapsed time since last time.", "\ -Initially, return the number of seconds of runtime -since the start of the process's execution -in @var{@1@}, -and the user and system components of this in @samp{@var{@2@}(1)} -and @samp{@var{@2@}(2)} respectively. -The value of @var{@1@} is equal to @samp{@var{@2@}(1) + @var{@2@}(2)}. - -Subsequent invocations of @samp{@0@()} set values based on accumulations -since the previous invocation. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (ETIME_func, "Get elapsed time for process.", "\ -Return the number of seconds of runtime -since the start of the process's execution -as the function value, -and the user and system components of this in @samp{@var{@1@}(1)} -and @samp{@var{@1@}(2)} respectively. -The functions' value is equal to @samp{@var{@1@}(1) + @var{@1@}(2)}. -") - -DEFDOC (ETIME_subr, "Get elapsed time for process.", "\ -Return the number of seconds of runtime -since the start of the process's execution -in @var{@1@}, -and the user and system components of this in @samp{@var{@2@}(1)} -and @samp{@var{@2@}(2)} respectively. -The value of @var{@1@} is equal to @samp{@var{@2@}(1) + @var{@2@}(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (FDATE_func, "Get current time as Day Mon dd hh:mm:ss yyyy.", "\ -Returns the current date (using the same format as @code{CTIME()}). - -Equivalent to: - -@example -CTIME(TIME8()) -@end example - -@xref{CTime Intrinsic (function)}. -") - -DEFDOC (FDATE_subr, "Get current time as Day Mon dd hh:mm:ss yyyy.", "\ -Returns the current date (using the same format as @code{CTIME()}) -in @var{@1@}. - -Equivalent to: - -@example -CALL CTIME(@var{@1@}, TIME8()) -@end example - -@xref{CTime Intrinsic (subroutine)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (GMTIME, "Convert time to GMT time info.", "\ -Given a system time value @var{@1@}, fills @var{@2@} with values -extracted from it appropriate to the GMT time zone using -@code{gmtime(3)}. - -The array elements are as follows: - -@enumerate -@item -Seconds after the minute, range 0--59 or 0--61 to allow for leap -seconds - -@item -Minutes after the hour, range 0--59 - -@item -Hours past midnight, range 0--23 - -@item -Day of month, range 0--31 - -@item -Number of months since January, range 0--12 - -@item -Years since 1900 - -@item -Number of days since Sunday, range 0--6 - -@item -Days since January 1 - -@item -Daylight savings indicator: positive if daylight savings is in effect, -zero if not, and negative if the information isn't available. -@end enumerate -") - -DEFDOC (LTIME, "Convert time to local time info.", "\ -Given a system time value @var{@1@}, fills @var{@2@} with values -extracted from it appropriate to the GMT time zone using -@code{localtime(3)}. - -The array elements are as follows: - -@enumerate -@item -Seconds after the minute, range 0--59 or 0--61 to allow for leap -seconds - -@item -Minutes after the hour, range 0--59 - -@item -Hours past midnight, range 0--23 - -@item -Day of month, range 0--31 - -@item -Number of months since January, range 0--12 - -@item -Years since 1900 - -@item -Number of days since Sunday, range 0--6 - -@item -Days since January 1 - -@item -Daylight savings indicator: positive if daylight savings is in effect, -zero if not, and negative if the information isn't available. -@end enumerate -") - -DEFDOC (IDATE_unix, "Get local time info.", "\ -Fills @var{@1@} with the numerical values at the current local time -of day, month (in the range 1--12), and year in elements 1, 2, and 3, -respectively. -The year has four significant digits. -") - -DEFDOC (IDATE_vxt, "Get local time info (VAX/VMS).", "\ -Returns the numerical values of the current local time. -The month (in the range 1--12) is returned in @var{@1@}, -the day (in the range 1--7) in @var{@2@}, -and the year in @var{@3@} (in the range 0--99). - -This intrinsic is not recommended, due to the year 2000 approaching. -") - -DEFDOC (ITIME, "Get local time of day.", "\ -Returns the current local time hour, minutes, and seconds in elements -1, 2, and 3 of @var{@1@}, respectively. -") - -DEFDOC (MCLOCK, "Get number of clock ticks for process.", "\ -Returns the number of clock ticks since the start of the process. -Supported on systems with @code{clock(3)} (q.v.). - -This intrinsic is not fully portable, such as to systems -with 32-bit @code{INTEGER} types but supporting times -wider than 32 bits. -@xref{MClock8 Intrinsic}, for information on a -similar intrinsic that might be portable to more -GNU Fortran implementations, though to fewer -Fortran compilers. - -If the system does not support @code{clock(3)}, --1 is returned. -") - -DEFDOC (MCLOCK8, "Get number of clock ticks for process.", "\ -Returns the number of clock ticks since the start of the process. -Supported on systems with @code{clock(3)} (q.v.). - -No Fortran implementations other than GNU Fortran are -known to support this intrinsic at the time of this -writing. -@xref{MClock Intrinsic}, for information on a -similar intrinsic that might be portable to more Fortran -compilers, though to fewer GNU Fortran implementations. - -If the system does not support @code{clock(3)}, --1 is returned. -") - -DEFDOC (SECNDS, "Get local time offset since midnight.", "\ -Returns the local time in seconds since midnight minus the value -@var{@1@}. -") - -DEFDOC (SECOND_func, "Get CPU time for process in seconds.", "\ -Returns the process's runtime in seconds---the same value as the -UNIX function @code{etime} returns. -") - -DEFDOC (SECOND_subr, "Get CPU time for process@99@in seconds.", "\ -Returns the process's runtime in seconds in @var{@1@}---the same value -as the UNIX function @code{etime} returns. - -This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic}, -for a standard equivalent. -") - -DEFDOC (SYSTEM_CLOCK, "Get current system clock value.", "\ -Returns in @var{@1@} the current value of the system clock; this is -the value returned by the UNIX function @code{times(2)} -in this implementation, but -isn't in general. -@var{@2@} is the number of clock ticks per second and -@var{@3@} is the maximum value this can take, which isn't very useful -in this implementation since it's just the maximum C @code{unsigned -int} value. -") - -DEFDOC (CPU_TIME, "Get current CPU time.", "\ -Returns in @var{@1@} the current value of the system time. -This implementation of the Fortran 95 intrinsic is just an alias for -@code{second} @xref{Second Intrinsic (subroutine)}. -") - -DEFDOC (TIME8, "Get current time as time value.", "\ -Returns the current time encoded as a long integer -(in the manner of the UNIX function @code{time(3)}). -This value is suitable for passing to @code{CTIME}, -@code{GMTIME}, and @code{LTIME}. - -No Fortran implementations other than GNU Fortran are -known to support this intrinsic at the time of this -writing. -@xref{Time Intrinsic (UNIX)}, for information on a -similar intrinsic that might be portable to more Fortran -compilers, though to fewer GNU Fortran implementations. -") - -DEFDOC (TIME_unix, "Get current time as time value.", "\ -Returns the current time encoded as an integer -(in the manner of the UNIX function @code{time(3)}). -This value is suitable for passing to @code{CTIME}, -@code{GMTIME}, and @code{LTIME}. - -This intrinsic is not fully portable, such as to systems -with 32-bit @code{INTEGER} types but supporting times -wider than 32 bits. -@xref{Time8 Intrinsic}, for information on a -similar intrinsic that might be portable to more -GNU Fortran implementations, though to fewer -Fortran compilers. -") - -#define BES(num,n,val) "\ -Calculates the Bessel function of the " #num " kind of \ -order " #n " of @var{@" #val "@}.\n\ -See @code{bessel(3m)}, on whose implementation the \ -function depends.\ -" - -DEFDOC (BESJ0, "Bessel function.", BES (first, 0, 1)) -DEFDOC (BESJ1, "Bessel function.", BES (first, 1, 1)) -DEFDOC (BESJN, "Bessel function.", BES (first, @var{N}, 2)) -DEFDOC (BESY0, "Bessel function.", BES (second, 0, 1)) -DEFDOC (BESY1, "Bessel function.", BES (second, 1, 1)) -DEFDOC (BESYN, "Bessel function.", BES (second, @var{N}, 2)) -DEFDOC (DBESJ0, "Bessel function (archaic).", ARCHAIC (BESJ0, BesJ0)) -DEFDOC (DBESJ1, "Bessel function (archaic).", ARCHAIC (BESJ1, BesJ1)) -DEFDOC (DBESJN, "Bessel function (archaic).", ARCHAIC_2nd (BESJN, BesJN)) -DEFDOC (DBESY0, "Bessel function (archaic).", ARCHAIC (BESY0, BesY0)) -DEFDOC (DBESY1, "Bessel function (archaic).", ARCHAIC (BESY1, BesY1)) -DEFDOC (DBESYN, "Bessel function (archaic).", ARCHAIC_2nd (BESYN, BesYN)) - -DEFDOC (ERF, "Error function.", "\ -Returns the error function of @var{@1@}. -See @code{erf(3m)}, which provides the implementation. -") - -DEFDOC (ERFC, "Complementary error function.", "\ -Returns the complementary error function of @var{@1@}: -@samp{ERFC(R) = 1 - ERF(R)} (except that the result might be more -accurate than explicitly evaluating that formulae would give). -See @code{erfc(3m)}, which provides the implementation. -") - -DEFDOC (DERF, "Error function (archaic).", ARCHAIC (ERF, ErF)) -DEFDOC (DERFC, "Complementary error function (archaic).", ARCHAIC (ERFC, ErFC)) - -DEFDOC (IRAND, "Random number.", "\ -Returns a uniform quasi-random number up to a system-dependent limit. -If @var{@1@} is 0, the next number in sequence is returned; if -@var{@1@} is 1, the generator is restarted by calling the UNIX function -@samp{srand(0)}; if @var{@1@} has any other value, -it is used as a new seed with @code{srand()}. - -@xref{SRand Intrinsic}. - -@emph{Note:} As typically implemented (by the routine of the same -name in the C library), this random number generator is a very poor -one, though the BSD and GNU libraries provide a much better -implementation than the `traditional' one. -On a different system you almost certainly want to use something better. -") - -DEFDOC (RAND, "Random number.", "\ -Returns a uniform quasi-random number between 0 and 1. -If @var{@1@} is 0, the next number in sequence is returned; if -@var{@1@} is 1, the generator is restarted by calling @samp{srand(0)}; -if @var{@1@} has any other value, it is used as a new seed with -@code{srand}. - -@xref{SRand Intrinsic}. - -@emph{Note:} As typically implemented (by the routine of the same -name in the C library), this random number generator is a very poor -one, though the BSD and GNU libraries provide a much better -implementation than the `traditional' one. -On a different system you -almost certainly want to use something better. -") - -DEFDOC (SRAND, "Random seed.", "\ -Reinitialises the generator with the seed in @var{@1@}. -@xref{IRand Intrinsic}. -@xref{Rand Intrinsic}. -") - -DEFDOC (ACCESS, "Check file accessibility.", "\ -Checks file @var{@1@} for accessibility in the mode specified by @var{@2@} and -returns 0 if the file is accessible in that mode, otherwise an error -code if the file is inaccessible or @var{@2@} is invalid. -See @code{access(2)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -@var{@2@} may be a concatenation of any of the following characters: - -@table @samp -@item r -Read permission - -@item w -Write permission - -@item x -Execute permission - -@item @kbd{SPC} -Existence -@end table -") - -DEFDOC (CHDIR_subr, "Change directory.", "\ -Sets the current working directory to be @var{@1@}. -If the @var{@2@} argument is supplied, it contains 0 -on success or a non-zero error code otherwise upon return. -See @code{chdir(3)}. - -@emph{Caution:} Using this routine during I/O to a unit connected with a -non-absolute file name can cause subsequent I/O on such a unit to fail -because the I/O library might reopen files by name. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@2@} argument. -") - -DEFDOC (CHDIR_func, "Change directory.", "\ -Sets the current working directory to be @var{@1@}. -Returns 0 on success or a non-zero error code. -See @code{chdir(3)}. - -@emph{Caution:} Using this routine during I/O to a unit connected with a -non-absolute file name can cause subsequent I/O on such a unit to fail -because the I/O library might reopen files by name. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (CHMOD_func, "Change file modes.", "\ -Changes the access mode of file @var{@1@} according to the -specification @var{@2@}, which is given in the format of -@code{chmod(1)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -Currently, @var{@1@} must not contain the single quote -character. - -Returns 0 on success or a non-zero error code otherwise. - -Note that this currently works -by actually invoking @code{/bin/chmod} (or the @code{chmod} found when -the library was configured) and so might fail in some circumstances and -will, anyway, be slow. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (CHMOD_subr, "Change file modes.", "\ -Changes the access mode of file @var{@1@} according to the -specification @var{@2@}, which is given in the format of -@code{chmod(1)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -Currently, @var{@1@} must not contain the single quote -character. - -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Note that this currently works -by actually invoking @code{/bin/chmod} (or the @code{chmod} found when -the library was configured) and so might fail in some circumstances and -will, anyway, be slow. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (GETCWD_func, "Get current working directory.", "\ -Places the current working directory in @var{@1@}. -Returns 0 on -success, otherwise a non-zero error code -(@code{ENOSYS} if the system does not provide @code{getcwd(3)} -or @code{getwd(3)}). -") - -DEFDOC (GETCWD_subr, "Get current working directory.", "\ -Places the current working directory in @var{@1@}. -If the @var{@2@} argument is supplied, it contains 0 -success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{getcwd(3)} -or @code{getwd(3)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@2@} argument. -") - -DEFDOC (FSTAT_func, "Get file information.", "\ -Obtains data about the file open on Fortran I/O unit @var{@1@} and -places them in the array @var{@2@}. -The values in this array are -extracted from the @code{stat} structure as returned by -@code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code. -") - -DEFDOC (FSTAT_subr, "Get file information.", "\ -Obtains data about the file open on Fortran I/O unit @var{@1@} and -places them in the array @var{@2@}. -The values in this array are -extracted from the @code{stat} structure as returned by -@code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (LSTAT_func, "Get file information.", "\ -Obtains data about the given file @var{@1@} and places them in the array -@var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -If @var{@1@} is a symbolic link it returns data on the -link itself, so the routine is available only on systems that support -symbolic links. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{lstat(2)}). -") - -DEFDOC (LSTAT_subr, "Get file information.", "\ -Obtains data about the given file @var{@1@} and places them in the array -@var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -If @var{@1@} is a symbolic link it returns data on the -link itself, so the routine is available only on systems that support -symbolic links. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{lstat(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (STAT_func, "Get file information.", "\ -Obtains data about the given file @var{@1@} and places them in the array -@var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code. -") - -DEFDOC (STAT_subr, "Get file information.", "\ -Obtains data about the given file @var{@1@} and places them in the array -@var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (LINK_subr, "Make hard link in file system.", "\ -Makes a (hard) link from file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{link(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (LINK_func, "Make hard link in file system.", "\ -Makes a (hard) link from file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -Returns 0 on success or a non-zero error code. -See @code{link(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (SYMLNK_subr, "Make symbolic link in file system.", "\ -Makes a symbolic link from file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{symlink(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (SYMLNK_func, "Make symbolic link in file system.", "\ -Makes a symbolic link from file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -Returns 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{symlink(2)}). - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (RENAME_subr, "Rename file.", "\ -Renames the file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -See @code{rename(2)}. -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (RENAME_func, "Rename file.", "\ -Renames the file @var{@1@} to @var{@2@}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{@1@} and @var{@2@}---otherwise, -trailing blanks in @var{@1@} and @var{@2@} are ignored. -See @code{rename(2)}. -Returns 0 on success or a non-zero error code. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (UMASK_subr, "Set file creation permissions mask.", "\ -Sets the file creation mask to @var{@1@} and returns the old value in -argument @var{@2@} if it is supplied. -See @code{umask(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (UMASK_func, "Set file creation permissions mask.", "\ -Sets the file creation mask to @var{@1@} and returns the old value. -See @code{umask(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (UNLINK_subr, "Unlink file.", "\ -Unlink the file @var{@1@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -If the @var{@2@} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{unlink(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@2@} argument. -") - -DEFDOC (UNLINK_func, "Unlink file.", "\ -Unlink the file @var{@1@}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -Returns 0 on success or a non-zero error code. -See @code{unlink(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (GERROR, "Get error message for last error.", "\ -Returns the system error message corresponding to the last system -error (C @code{errno}). -") - -DEFDOC (IERRNO, "Get error number for last error.", "\ -Returns the last system error number (corresponding to the C -@code{errno}). -") - -DEFDOC (PERROR, "Print error message for last error.", "\ -Prints (on the C @code{stderr} stream) a newline-terminated error -message corresponding to the last system error. -This is prefixed by @var{@1@}, a colon and a space. -See @code{perror(3)}. -") - -DEFDOC (GETGID, "Get process group id.", "\ -Returns the group id for the current process. -") - -DEFDOC (GETUID, "Get process user id.", "\ -Returns the user id for the current process. -") - -DEFDOC (GETPID, "Get process id.", "\ -Returns the process id for the current process. -") - -DEFDOC (GETENV, "Get environment variable.", "\ -Sets @var{@2@} to the value of environment variable given by the -value of @var{@1@} (@code{$name} in shell terms) or to blanks if -@code{$name} has not been set. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{@1@}---otherwise, -trailing blanks in @var{@1@} are ignored. -") - -DEFDOC (GETLOG, "Get login name.", "\ -Returns the login name for the process in @var{@1@}. - -@emph{Caution:} On some systems, the @code{getlogin(3)} -function, which this intrinsic calls at run time, -is either not implemented or returns a null pointer. -In the latter case, this intrinsic returns blanks -in @var{@1@}. -") - -DEFDOC (HOSTNM_func, "Get host name.", "\ -Fills @var{@1@} with the system's host name returned by -@code{gethostname(2)}, returning 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{gethostname(2)}). - -On some systems (specifically SCO) it might be necessary to link the -``socket'' library if you call this routine. -Typically this means adding @samp{-lg2c -lsocket -lm} -to the @code{g77} command line when linking the program. -") - -DEFDOC (HOSTNM_subr, "Get host name.", "\ -Fills @var{@1@} with the system's host name returned by -@code{gethostname(2)}. -If the @var{@2@} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{gethostname(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@2@} argument. - -On some systems (specifically SCO) it might be necessary to link the -``socket'' library if you call this routine. -Typically this means adding @samp{-lg2c -lsocket -lm} -to the @code{g77} command line when linking the program. -") - -DEFDOC (FLUSH, "Flush buffered output.", "\ -Flushes Fortran unit(s) currently open for output. -Without the optional argument, all such units are flushed, -otherwise just the unit specified by @var{@1@}. - -Some non-GNU implementations of Fortran provide this intrinsic -as a library procedure that might or might not support the -(optional) @var{@1@} argument. -") - -DEFDOC (FNUM, "Get file descriptor from Fortran unit number.", "\ -Returns the Unix file descriptor number corresponding to the open -Fortran I/O unit @var{@1@}. -This could be passed to an interface to C I/O routines. -") - -#define IOWARN " -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. -" - -DEFDOC (FGET_func, "Read a character from unit 5 stream-wise.", "\ -Reads a single character into @var{@1@} in stream mode from unit 5 -(by-passing normal formatted input) using @code{getc(3)}. -Returns 0 on -success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FGET_subr, "Read a character from unit 5 stream-wise.", "\ -Reads a single character into @var{@1@} in stream mode from unit 5 -(by-passing normal formatted output) using @code{getc(3)}. -Returns in -@var{@2@} 0 on success, @minus{}1 on end-of-file, and the error code -from @code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FGETC_func, "Read a character stream-wise.", "\ -Reads a single character into @var{@2@} in stream mode from unit @var{@1@} -(by-passing normal formatted output) using @code{getc(3)}. -Returns 0 on -success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FGETC_subr, "Read a character stream-wise.", "\ -Reads a single character into @var{@2@} in stream mode from unit @var{@1@} -(by-passing normal formatted output) using @code{getc(3)}. -Returns in -@var{@3@} 0 on success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FPUT_func, "Write a character to unit 6 stream-wise.", "\ -Writes the single character @var{@1@} in stream mode to unit 6 -(by-passing normal formatted output) using @code{getc(3)}. -Returns 0 on -success, the error code from @code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FPUT_subr, "Write a character to unit 6 stream-wise.", "\ -Writes the single character @var{@1@} in stream mode to unit 6 -(by-passing normal formatted output) using @code{putc(3)}. -Returns in -@var{@2@} 0 on success, the error code from @code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FPUTC_func, "Write a character stream-wise.", "\ -Writes the single character @var{@2@} in stream mode to unit @var{@1@} -(by-passing normal formatted output) using @code{putc(3)}. -Returns 0 on -success, the error code from @code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FPUTC_subr, "Write a character stream-wise.", "\ -Writes the single character @var{@1@} in stream mode to unit 6 -(by-passing normal formatted output) using @code{putc(3)}. -Returns in -@var{@2@} 0 on success, the error code from @code{ferror(3)} otherwise. -" IOWARN) - -DEFDOC (FSEEK, "Position file (low-level).", "\ -Attempts to move Fortran unit @var{@1@} to the specified -@var{@2@}: absolute offset if @var{@3@}=0; relative to the -current offset if @var{@3@}=1; relative to the end of the file if -@var{@3@}=2. -It branches to label @var{@4@} if @var{@1@} is -not open or if the call otherwise fails. -") - -DEFDOC (FTELL_func, "Get file position (low-level).", "\ -Returns the current offset of Fortran unit @var{@1@} -(or @minus{}1 if @var{@1@} is not open). -") - -DEFDOC (FTELL_subr, "Get file position (low-level).", "\ -Sets @var{@2@} to the current offset of Fortran unit @var{@1@} -(or to @minus{}1 if @var{@1@} is not open). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (ISATTY, "Is unit connected to a terminal?", "\ -Returns @code{.TRUE.} if and only if the Fortran I/O unit -specified by @var{@1@} is connected -to a terminal device. -See @code{isatty(3)}. -") - -DEFDOC (TTYNAM_func, "Get name of terminal device for unit.", "\ -Returns the name of the terminal device open on logical unit -@var{@1@} or a blank string if @var{@1@} is not connected to a -terminal. -") - -DEFDOC (TTYNAM_subr, "Get name of terminal device for unit.", "\ -Sets @var{@1@} to the name of the terminal device open on logical unit -@var{@2@} or a blank string if @var{@2@} is not connected to a -terminal. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. -") - -DEFDOC (SIGNAL_subr, "Muck with signal handling.", "\ -If @var{@2@} is a an @code{EXTERNAL} routine, arranges for it to be -invoked with a single integer argument (of system-dependent length) -when signal @var{@1@} occurs. -If @var{@2@} is an integer, it can be -used to turn off handling of signal @var{@1@} or revert to its default -action. -See @code{signal(2)}. - -Note that @var{@2@} will be called using C conventions, -so the value of its argument in Fortran terms -Fortran terms is obtained by applying @code{%LOC()} (or @var{LOC()}) to it. - -The value returned by @code{signal(2)} is written to @var{@3@}, if -that argument is supplied. -Otherwise the return value is ignored. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. - -@emph{Warning:} Use of the @code{libf2c} run-time library function -@samp{signal_} directly -(such as via @samp{EXTERNAL SIGNAL}) -requires use of the @code{%VAL()} construct -to pass an @code{INTEGER} value -(such as @samp{SIG_IGN} or @samp{SIG_DFL}) -for the @var{@2@} argument. - -However, while @samp{CALL SIGNAL(@var{signum}, %VAL(SIG_IGN))} -works when @samp{SIGNAL} is treated as an external procedure -(and resolves, at link time, to @code{libf2c}'s @samp{signal_} routine), -this construct is not valid when @samp{SIGNAL} is recognized -as the intrinsic of that name. - -Therefore, for maximum portability and reliability, -code such references to the @samp{SIGNAL} facility as follows: - -@smallexample -INTRINSIC SIGNAL -@dots{} -CALL SIGNAL(@var{signum}, SIG_IGN) -@end smallexample - -@code{g77} will compile such a call correctly, -while other compilers will generally either do so as well -or reject the @samp{INTRINSIC SIGNAL} statement via a diagnostic, -allowing you to take appropriate action. -") - -DEFDOC (SIGNAL_func, "Muck with signal handling.", "\ -If @var{@2@} is a an @code{EXTERNAL} routine, arranges for it to be -invoked with a single integer argument (of system-dependent length) -when signal @var{@1@} occurs. -If @var{@2@} is an integer, it can be -used to turn off handling of signal @var{@1@} or revert to its default -action. -See @code{signal(2)}. - -Note that @var{@2@} will be called using C conventions, -so the value of its argument in Fortran terms -is obtained by applying @code{%LOC()} (or @var{LOC()}) to it. - -The value returned by @code{signal(2)} is returned. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -@emph{Warning:} If the returned value is stored in -an @code{INTEGER(KIND=1)} (default @code{INTEGER}) argument, -truncation of the original return value occurs on some systems -(such as Alphas, which have 64-bit pointers but 32-bit default integers), -with no warning issued by @code{g77} under normal circumstances. - -Therefore, the following code fragment might silently fail on -some systems: - -@smallexample -INTEGER RTN -EXTERNAL MYHNDL -RTN = SIGNAL(@var{signum}, MYHNDL) -@dots{} -! Restore original handler: -RTN = SIGNAL(@var{signum}, RTN) -@end smallexample - -The reason for the failure is that @samp{RTN} might not hold -all the information on the original handler for the signal, -thus restoring an invalid handler. -This bug could manifest itself as a spurious run-time failure -at an arbitrary point later during the program's execution, -for example. - -@emph{Warning:} Use of the @code{libf2c} run-time library function -@samp{signal_} directly -(such as via @samp{EXTERNAL SIGNAL}) -requires use of the @code{%VAL()} construct -to pass an @code{INTEGER} value -(such as @samp{SIG_IGN} or @samp{SIG_DFL}) -for the @var{@2@} argument. - -However, while @samp{RTN = SIGNAL(@var{signum}, %VAL(SIG_IGN))} -works when @samp{SIGNAL} is treated as an external procedure -(and resolves, at link time, to @code{libf2c}'s @samp{signal_} routine), -this construct is not valid when @samp{SIGNAL} is recognized -as the intrinsic of that name. - -Therefore, for maximum portability and reliability, -code such references to the @samp{SIGNAL} facility as follows: - -@smallexample -INTRINSIC SIGNAL -@dots{} -RTN = SIGNAL(@var{signum}, SIG_IGN) -@end smallexample - -@code{g77} will compile such a call correctly, -while other compilers will generally either do so as well -or reject the @samp{INTRINSIC SIGNAL} statement via a diagnostic, -allowing you to take appropriate action. -") - -DEFDOC (KILL_func, "Signal a process.", "\ -Sends the signal specified by @var{@2@} to the process @var{@1@}. -Returns 0 on success or a non-zero error code. -See @code{kill(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -") - -DEFDOC (KILL_subr, "Signal a process.", "\ -Sends the signal specified by @var{@2@} to the process @var{@1@}. -If the @var{@3@} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{kill(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@3@} argument. -") - -DEFDOC (LNBLNK, "Get last non-blank character in string.", "\ -Returns the index of the last non-blank character in @var{@1@}. -@code{LNBLNK} and @code{LEN_TRIM} are equivalent. -") - -DEFDOC (SLEEP, "Sleep for a specified time.", "\ -Causes the process to pause for @var{@1@} seconds. -See @code{sleep(2)}. -") - -DEFDOC (SYSTEM_subr, "Invoke shell (system) command.", "\ -Passes the command @var{@1@} to a shell (see @code{system(3)}). -If argument @var{@2@} is present, it contains the value returned by -@code{system(3)}, presumably 0 if the shell command succeeded. -Note that which shell is used to invoke the command is system-dependent -and environment-dependent. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{@2@} argument. -") - -DEFDOC (SYSTEM_func, "Invoke shell (system) command.", "\ -Passes the command @var{@1@} to a shell (see @code{system(3)}). -Returns the value returned by -@code{system(3)}, presumably 0 if the shell command succeeded. -Note that which shell is used to invoke the command is system-dependent -and environment-dependent. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -However, the function form can be valid in cases where the -actual side effects performed by the call are unimportant to -the application. - -For example, on a UNIX system, @samp{SAME = SYSTEM('cmp a b')} -does not perform any side effects likely to be important to the -program, so the programmer would not care if the actual system -call (and invocation of @code{cmp}) was optimized away in a situation -where the return value could be determined otherwise, or was not -actually needed (@samp{SAME} not actually referenced after the -sample assignment statement). -") - -DEFDOC (TIME_vxt, "Get the time as a character value.", "\ -Returns in @var{@1@} a character representation of the current time as -obtained from @code{ctime(3)}. - -@xref{Fdate Intrinsic (subroutine)} for an equivalent routine. -") - -DEFDOC (IBCLR, "Clear a bit.", "\ -Returns the value of @var{@1@} with bit @var{@2@} cleared (set to -zero). -@xref{BTest Intrinsic} for information on bit positions. -") - -DEFDOC (IBSET, "Set a bit.", "\ -Returns the value of @var{@1@} with bit @var{@2@} set (to one). -@xref{BTest Intrinsic} for information on bit positions. -") - -DEFDOC (IBITS, "Extract a bit subfield of a variable.", "\ -Extracts a subfield of length @var{@3@} from @var{@1@}, starting from -bit position @var{@2@} and extending left for @var{@3@} bits. -The result is right-justified and the remaining bits are zeroed. -The value -of @samp{@var{@2@}+@var{@3@}} must be less than or equal to the value -@samp{BIT_SIZE(@var{@1@})}. -@xref{Bit_Size Intrinsic}. -") - -DEFDOC (ISHFT, "Logical bit shift.", "\ -All bits representing @var{@1@} are shifted @var{@2@} places. -@samp{@var{@2@}.GT.0} indicates a left shift, @samp{@var{@2@}.EQ.0} -indicates no shift and @samp{@var{@2@}.LT.0} indicates a right shift. -If the absolute value of the shift count is greater than -@samp{BIT_SIZE(@var{@1@})}, the result is undefined. -Bits shifted out from the left end or the right end are lost. -Zeros are shifted in from the opposite end. - -@xref{IShftC Intrinsic}, for the circular-shift equivalent. -") - -DEFDOC (ISHFTC, "Circular bit shift.", "\ -The rightmost @var{@3@} bits of the argument @var{@1@} -are shifted circularly @var{@2@} -places, i.e.@: the bits shifted out of one end are shifted into -the opposite end. -No bits are lost. -The unshifted bits of the result are the same as -the unshifted bits of @var{@1@}. -The absolute value of the argument @var{@2@} -must be less than or equal to @var{@3@}. -The value of @var{@3@} must be greater than or equal to one and less than -or equal to @samp{BIT_SIZE(@var{@1@})}. - -@xref{IShft Intrinsic}, for the logical shift equivalent. -") - -DEFDOC (MVBITS, "Moving a bit field.", "\ -Moves @var{@3@} bits from positions @var{@2@} through -@samp{@var{@2@}+@var{@3@}-1} of @var{@1@} to positions @var{@5@} through -@samp{@var{@2@}+@var{@3@}-1} of @var{@4@}. The portion of argument -@var{@4@} not affected by the movement of bits is unchanged. Arguments -@var{@1@} and @var{@4@} are permitted to be the same numeric storage -unit. The values of @samp{@var{@2@}+@var{@3@}} and -@samp{@var{@5@}+@var{@3@}} must be less than or equal to -@samp{BIT_SIZE(@var{@1@})}. -") - -DEFDOC (INDEX, "Locate a CHARACTER substring.", "\ -Returns the position of the start of the first occurrence of string -@var{@2@} as a substring in @var{@1@}, counting from one. -If @var{@2@} doesn't occur in @var{@1@}, zero is returned. -") - -DEFDOC (ALARM, "Execute a routine after a given delay.", "\ -Causes external subroutine @var{@2@} to be executed after a delay of -@var{@1@} seconds by using @code{alarm(1)} to set up a signal and -@code{signal(2)} to catch it. -If @var{@3@} is supplied, it will be -returned with the number of seconds remaining until any previously -scheduled alarm was due to be delivered, or zero if there was no -previously scheduled alarm. -@xref{Signal Intrinsic (subroutine)}. -") - -DEFDOC (DATE_AND_TIME, "Get the current date and time.", "\ -Returns: -@table @var -@item @1@ -The date in the form @var{ccyymmdd}: century, year, month and day; -@item @2@ -The time in the form @samp{@var{hhmmss.ss}}: hours, minutes, seconds -and milliseconds; -@item @3@ -The difference between local time and UTC (GMT) in the form @var{Shhmm}: -sign, hours and minutes, e.g.@: @samp{-0500} (winter in New York); -@item @4@ -The year, month of the year, day of the month, time difference in -minutes from UTC, hour of the day, minutes of the hour and milliseconds -of the second in successive values of the array. -@end table - -On systems where a millisecond timer isn't available, the millisecond -value is returned as zero. -") diff --git a/gcc/f/intdoc.texi b/gcc/f/intdoc.texi deleted file mode 100755 index ab50fac..0000000 --- a/gcc/f/intdoc.texi +++ /dev/null @@ -1,10724 +0,0 @@ -@c This file is automatically derived from intdoc.c, intdoc.in, -@c ansify.c, intrin.def, and intrin.h. Edit those files instead. -@menu -@ifset familyF2U -* Abort Intrinsic:: Abort the program. -@end ifset -@ifset familyF77 -* Abs Intrinsic:: Absolute value. -@end ifset -@ifset familyF2U -* Access Intrinsic:: Check file accessibility. -@end ifset -@ifset familyASC -* AChar Intrinsic:: ASCII character from code. -@end ifset -@ifset familyF77 -* ACos Intrinsic:: Arc cosine. -@end ifset -@ifset familyVXT -* ACosD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* AdjustL Intrinsic:: (Reserved for future use.) -* AdjustR Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* AImag Intrinsic:: Convert/extract imaginary part of complex. -@end ifset -@ifset familyVXT -* AIMax0 Intrinsic:: (Reserved for future use.) -* AIMin0 Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* AInt Intrinsic:: Truncate to whole number. -@end ifset -@ifset familyVXT -* AJMax0 Intrinsic:: (Reserved for future use.) -* AJMin0 Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Alarm Intrinsic:: Execute a routine after a given delay. -@end ifset -@ifset familyF90 -* All Intrinsic:: (Reserved for future use.) -* Allocated Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* ALog Intrinsic:: Natural logarithm (archaic). -* ALog10 Intrinsic:: Natural logarithm (archaic). -* AMax0 Intrinsic:: Maximum value (archaic). -* AMax1 Intrinsic:: Maximum value (archaic). -* AMin0 Intrinsic:: Minimum value (archaic). -* AMin1 Intrinsic:: Minimum value (archaic). -* AMod Intrinsic:: Remainder (archaic). -@end ifset -@ifset familyF2C -* And Intrinsic:: Boolean AND. -@end ifset -@ifset familyF77 -* ANInt Intrinsic:: Round to nearest whole number. -@end ifset -@ifset familyF90 -* Any Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* ASin Intrinsic:: Arc sine. -@end ifset -@ifset familyVXT -* ASinD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Associated Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* ATan Intrinsic:: Arc tangent. -* ATan2 Intrinsic:: Arc tangent. -@end ifset -@ifset familyVXT -* ATan2D Intrinsic:: (Reserved for future use.) -* ATanD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* BesJ0 Intrinsic:: Bessel function. -* BesJ1 Intrinsic:: Bessel function. -* BesJN Intrinsic:: Bessel function. -* BesY0 Intrinsic:: Bessel function. -* BesY1 Intrinsic:: Bessel function. -* BesYN Intrinsic:: Bessel function. -@end ifset -@ifset familyVXT -* BITest Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Bit_Size Intrinsic:: Number of bits in argument's type. -@end ifset -@ifset familyVXT -* BJTest Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyMIL -* BTest Intrinsic:: Test bit. -@end ifset -@ifset familyF77 -* CAbs Intrinsic:: Absolute value (archaic). -* CCos Intrinsic:: Cosine (archaic). -@end ifset -@ifset familyFVZ -* CDAbs Intrinsic:: Absolute value (archaic). -* CDCos Intrinsic:: Cosine (archaic). -* CDExp Intrinsic:: Exponential (archaic). -* CDLog Intrinsic:: Natural logarithm (archaic). -* CDSin Intrinsic:: Sine (archaic). -* CDSqRt Intrinsic:: Square root (archaic). -@end ifset -@ifset familyF90 -* Ceiling Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* CExp Intrinsic:: Exponential (archaic). -* Char Intrinsic:: Character from code. -@end ifset -@ifset familyF2U -* ChDir Intrinsic (subroutine):: Change directory. -@end ifset -@ifset familyBADU77 -* ChDir Intrinsic (function):: Change directory. -@end ifset -@ifset familyF2U -* ChMod Intrinsic (subroutine):: Change file modes. -@end ifset -@ifset familyBADU77 -* ChMod Intrinsic (function):: Change file modes. -@end ifset -@ifset familyF77 -* CLog Intrinsic:: Natural logarithm (archaic). -* Cmplx Intrinsic:: Construct @code{COMPLEX(KIND=1)} value. -@end ifset -@ifset familyGNU -* Complex Intrinsic:: Build complex value from real and - imaginary parts. -@end ifset -@ifset familyF77 -* Conjg Intrinsic:: Complex conjugate. -* Cos Intrinsic:: Cosine. -@end ifset -@ifset familyVXT -* CosD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* CosH Intrinsic:: Hyperbolic cosine. -@end ifset -@ifset familyF90 -* Count Intrinsic:: (Reserved for future use.) -* CPU_Time Intrinsic:: Get current CPU time. -* CShift Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* CSin Intrinsic:: Sine (archaic). -* CSqRt Intrinsic:: Square root (archaic). -@end ifset -@ifset familyF2U -* CTime Intrinsic (subroutine):: Convert time to Day Mon dd hh:mm:ss yyyy. -* CTime Intrinsic (function):: Convert time to Day Mon dd hh:mm:ss yyyy. -@end ifset -@ifset familyF77 -* DAbs Intrinsic:: Absolute value (archaic). -* DACos Intrinsic:: Arc cosine (archaic). -@end ifset -@ifset familyVXT -* DACosD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DASin Intrinsic:: Arc sine (archaic). -@end ifset -@ifset familyVXT -* DASinD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DATan Intrinsic:: Arc tangent (archaic). -* DATan2 Intrinsic:: Arc tangent (archaic). -@end ifset -@ifset familyVXT -* DATan2D Intrinsic:: (Reserved for future use.) -* DATanD Intrinsic:: (Reserved for future use.) -* Date Intrinsic:: Get current date as dd-Mon-yy. -@end ifset -@ifset familyF90 -* Date_and_Time Intrinsic:: Get the current date and time. -@end ifset -@ifset familyF2U -* DbesJ0 Intrinsic:: Bessel function (archaic). -* DbesJ1 Intrinsic:: Bessel function (archaic). -* DbesJN Intrinsic:: Bessel function (archaic). -* DbesY0 Intrinsic:: Bessel function (archaic). -* DbesY1 Intrinsic:: Bessel function (archaic). -* DbesYN Intrinsic:: Bessel function (archaic). -@end ifset -@ifset familyF77 -* Dble Intrinsic:: Convert to double precision. -@end ifset -@ifset familyVXT -* DbleQ Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyFVZ -* DCmplx Intrinsic:: Construct @code{COMPLEX(KIND=2)} value. -* DConjg Intrinsic:: Complex conjugate (archaic). -@end ifset -@ifset familyF77 -* DCos Intrinsic:: Cosine (archaic). -@end ifset -@ifset familyVXT -* DCosD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DCosH Intrinsic:: Hyperbolic cosine (archaic). -* DDiM Intrinsic:: Difference magnitude (archaic). -@end ifset -@ifset familyF2U -* DErF Intrinsic:: Error function (archaic). -* DErFC Intrinsic:: Complementary error function (archaic). -@end ifset -@ifset familyF77 -* DExp Intrinsic:: Exponential (archaic). -@end ifset -@ifset familyFVZ -* DFloat Intrinsic:: Conversion (archaic). -@end ifset -@ifset familyVXT -* DFlotI Intrinsic:: (Reserved for future use.) -* DFlotJ Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Digits Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DiM Intrinsic:: Difference magnitude (non-negative subtract). -@end ifset -@ifset familyFVZ -* DImag Intrinsic:: Convert/extract imaginary part of complex (archaic). -@end ifset -@ifset familyF77 -* DInt Intrinsic:: Truncate to whole number (archaic). -* DLog Intrinsic:: Natural logarithm (archaic). -* DLog10 Intrinsic:: Natural logarithm (archaic). -* DMax1 Intrinsic:: Maximum value (archaic). -* DMin1 Intrinsic:: Minimum value (archaic). -* DMod Intrinsic:: Remainder (archaic). -* DNInt Intrinsic:: Round to nearest whole number (archaic). -@end ifset -@ifset familyF90 -* Dot_Product Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DProd Intrinsic:: Double-precision product. -@end ifset -@ifset familyVXT -* DReal Intrinsic:: Convert value to type @code{REAL(KIND=2)}. -@end ifset -@ifset familyF77 -* DSign Intrinsic:: Apply sign to magnitude (archaic). -* DSin Intrinsic:: Sine (archaic). -@end ifset -@ifset familyVXT -* DSinD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DSinH Intrinsic:: Hyperbolic sine (archaic). -* DSqRt Intrinsic:: Square root (archaic). -* DTan Intrinsic:: Tangent (archaic). -@end ifset -@ifset familyVXT -* DTanD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* DTanH Intrinsic:: Hyperbolic tangent (archaic). -@end ifset -@ifset familyF2U -* Dtime Intrinsic (subroutine):: Get elapsed time since last time. -@end ifset -@ifset familyBADU77 -* Dtime Intrinsic (function):: Get elapsed time since last time. -@end ifset -@ifset familyF90 -* EOShift Intrinsic:: (Reserved for future use.) -* Epsilon Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* ErF Intrinsic:: Error function. -* ErFC Intrinsic:: Complementary error function. -* ETime Intrinsic (subroutine):: Get elapsed time for process. -* ETime Intrinsic (function):: Get elapsed time for process. -* Exit Intrinsic:: Terminate the program. -@end ifset -@ifset familyF77 -* Exp Intrinsic:: Exponential. -@end ifset -@ifset familyF90 -* Exponent Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Fdate Intrinsic (subroutine):: Get current time as Day Mon dd hh:mm:ss yyyy. -* Fdate Intrinsic (function):: Get current time as Day Mon dd hh:mm:ss yyyy. -* FGet Intrinsic (subroutine):: Read a character from unit 5 stream-wise. -@end ifset -@ifset familyBADU77 -* FGet Intrinsic (function):: Read a character from unit 5 stream-wise. -@end ifset -@ifset familyF2U -* FGetC Intrinsic (subroutine):: Read a character stream-wise. -@end ifset -@ifset familyBADU77 -* FGetC Intrinsic (function):: Read a character stream-wise. -@end ifset -@ifset familyF77 -* Float Intrinsic:: Conversion (archaic). -@end ifset -@ifset familyVXT -* FloatI Intrinsic:: (Reserved for future use.) -* FloatJ Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Floor Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Flush Intrinsic:: Flush buffered output. -* FNum Intrinsic:: Get file descriptor from Fortran unit number. -* FPut Intrinsic (subroutine):: Write a character to unit 6 stream-wise. -@end ifset -@ifset familyBADU77 -* FPut Intrinsic (function):: Write a character to unit 6 stream-wise. -@end ifset -@ifset familyF2U -* FPutC Intrinsic (subroutine):: Write a character stream-wise. -@end ifset -@ifset familyBADU77 -* FPutC Intrinsic (function):: Write a character stream-wise. -@end ifset -@ifset familyF90 -* Fraction Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* FSeek Intrinsic:: Position file (low-level). -* FStat Intrinsic (subroutine):: Get file information. -* FStat Intrinsic (function):: Get file information. -* FTell Intrinsic (subroutine):: Get file position (low-level). -* FTell Intrinsic (function):: Get file position (low-level). -* GError Intrinsic:: Get error message for last error. -* GetArg Intrinsic:: Obtain command-line argument. -* GetCWD Intrinsic (subroutine):: Get current working directory. -* GetCWD Intrinsic (function):: Get current working directory. -* GetEnv Intrinsic:: Get environment variable. -* GetGId Intrinsic:: Get process group id. -* GetLog Intrinsic:: Get login name. -* GetPId Intrinsic:: Get process id. -* GetUId Intrinsic:: Get process user id. -* GMTime Intrinsic:: Convert time to GMT time info. -* HostNm Intrinsic (subroutine):: Get host name. -* HostNm Intrinsic (function):: Get host name. -@end ifset -@ifset familyF90 -* Huge Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* IAbs Intrinsic:: Absolute value (archaic). -@end ifset -@ifset familyASC -* IAChar Intrinsic:: ASCII code for character. -@end ifset -@ifset familyMIL -* IAnd Intrinsic:: Boolean AND. -@end ifset -@ifset familyF2U -* IArgC Intrinsic:: Obtain count of command-line arguments. -@end ifset -@ifset familyMIL -* IBClr Intrinsic:: Clear a bit. -* IBits Intrinsic:: Extract a bit subfield of a variable. -* IBSet Intrinsic:: Set a bit. -@end ifset -@ifset familyF77 -* IChar Intrinsic:: Code for character. -@end ifset -@ifset familyF2U -* IDate Intrinsic (UNIX):: Get local time info. -@end ifset -@ifset familyVXT -* IDate Intrinsic (VXT):: Get local time info (VAX/VMS). -@end ifset -@ifset familyF77 -* IDiM Intrinsic:: Difference magnitude (archaic). -* IDInt Intrinsic:: Convert to @code{INTEGER} value truncated - to whole number (archaic). -* IDNInt Intrinsic:: Convert to @code{INTEGER} value rounded - to nearest whole number (archaic). -@end ifset -@ifset familyMIL -* IEOr Intrinsic:: Boolean XOR. -@end ifset -@ifset familyF2U -* IErrNo Intrinsic:: Get error number for last error. -@end ifset -@ifset familyF77 -* IFix Intrinsic:: Conversion (archaic). -@end ifset -@ifset familyVXT -* IIAbs Intrinsic:: (Reserved for future use.) -* IIAnd Intrinsic:: (Reserved for future use.) -* IIBClr Intrinsic:: (Reserved for future use.) -* IIBits Intrinsic:: (Reserved for future use.) -* IIBSet Intrinsic:: (Reserved for future use.) -* IIDiM Intrinsic:: (Reserved for future use.) -* IIDInt Intrinsic:: (Reserved for future use.) -* IIDNnt Intrinsic:: (Reserved for future use.) -* IIEOr Intrinsic:: (Reserved for future use.) -* IIFix Intrinsic:: (Reserved for future use.) -* IInt Intrinsic:: (Reserved for future use.) -* IIOr Intrinsic:: (Reserved for future use.) -* IIQint Intrinsic:: (Reserved for future use.) -* IIQNnt Intrinsic:: (Reserved for future use.) -* IIShftC Intrinsic:: (Reserved for future use.) -* IISign Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2C -* Imag Intrinsic:: Extract imaginary part of complex. -@end ifset -@ifset familyGNU -* ImagPart Intrinsic:: Extract imaginary part of complex. -@end ifset -@ifset familyVXT -* IMax0 Intrinsic:: (Reserved for future use.) -* IMax1 Intrinsic:: (Reserved for future use.) -* IMin0 Intrinsic:: (Reserved for future use.) -* IMin1 Intrinsic:: (Reserved for future use.) -* IMod Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Index Intrinsic:: Locate a CHARACTER substring. -@end ifset -@ifset familyVXT -* INInt Intrinsic:: (Reserved for future use.) -* INot Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Int Intrinsic:: Convert to @code{INTEGER} value truncated - to whole number. -@end ifset -@ifset familyGNU -* Int2 Intrinsic:: Convert to @code{INTEGER(KIND=6)} value - truncated to whole number. -* Int8 Intrinsic:: Convert to @code{INTEGER(KIND=2)} value - truncated to whole number. -@end ifset -@ifset familyMIL -* IOr Intrinsic:: Boolean OR. -@end ifset -@ifset familyF2U -* IRand Intrinsic:: Random number. -* IsaTty Intrinsic:: Is unit connected to a terminal? -@end ifset -@ifset familyMIL -* IShft Intrinsic:: Logical bit shift. -* IShftC Intrinsic:: Circular bit shift. -@end ifset -@ifset familyF77 -* ISign Intrinsic:: Apply sign to magnitude (archaic). -@end ifset -@ifset familyF2U -* ITime Intrinsic:: Get local time of day. -@end ifset -@ifset familyVXT -* IZExt Intrinsic:: (Reserved for future use.) -* JIAbs Intrinsic:: (Reserved for future use.) -* JIAnd Intrinsic:: (Reserved for future use.) -* JIBClr Intrinsic:: (Reserved for future use.) -* JIBits Intrinsic:: (Reserved for future use.) -* JIBSet Intrinsic:: (Reserved for future use.) -* JIDiM Intrinsic:: (Reserved for future use.) -* JIDInt Intrinsic:: (Reserved for future use.) -* JIDNnt Intrinsic:: (Reserved for future use.) -* JIEOr Intrinsic:: (Reserved for future use.) -* JIFix Intrinsic:: (Reserved for future use.) -* JInt Intrinsic:: (Reserved for future use.) -* JIOr Intrinsic:: (Reserved for future use.) -* JIQint Intrinsic:: (Reserved for future use.) -* JIQNnt Intrinsic:: (Reserved for future use.) -* JIShft Intrinsic:: (Reserved for future use.) -* JIShftC Intrinsic:: (Reserved for future use.) -* JISign Intrinsic:: (Reserved for future use.) -* JMax0 Intrinsic:: (Reserved for future use.) -* JMax1 Intrinsic:: (Reserved for future use.) -* JMin0 Intrinsic:: (Reserved for future use.) -* JMin1 Intrinsic:: (Reserved for future use.) -* JMod Intrinsic:: (Reserved for future use.) -* JNInt Intrinsic:: (Reserved for future use.) -* JNot Intrinsic:: (Reserved for future use.) -* JZExt Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Kill Intrinsic (subroutine):: Signal a process. -@end ifset -@ifset familyBADU77 -* Kill Intrinsic (function):: Signal a process. -@end ifset -@ifset familyF90 -* Kind Intrinsic:: (Reserved for future use.) -* LBound Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Len Intrinsic:: Length of character entity. -@end ifset -@ifset familyF90 -* Len_Trim Intrinsic:: Get last non-blank character in string. -@end ifset -@ifset familyF77 -* LGe Intrinsic:: Lexically greater than or equal. -* LGt Intrinsic:: Lexically greater than. -@end ifset -@ifset familyF2U -* Link Intrinsic (subroutine):: Make hard link in file system. -@end ifset -@ifset familyBADU77 -* Link Intrinsic (function):: Make hard link in file system. -@end ifset -@ifset familyF77 -* LLe Intrinsic:: Lexically less than or equal. -* LLt Intrinsic:: Lexically less than. -@end ifset -@ifset familyF2U -* LnBlnk Intrinsic:: Get last non-blank character in string. -* Loc Intrinsic:: Address of entity in core. -@end ifset -@ifset familyF77 -* Log Intrinsic:: Natural logarithm. -* Log10 Intrinsic:: Natural logarithm. -@end ifset -@ifset familyF90 -* Logical Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Long Intrinsic:: Conversion to @code{INTEGER(KIND=1)} (archaic). -@end ifset -@ifset familyF2C -* LShift Intrinsic:: Left-shift bits. -@end ifset -@ifset familyF2U -* LStat Intrinsic (subroutine):: Get file information. -* LStat Intrinsic (function):: Get file information. -* LTime Intrinsic:: Convert time to local time info. -@end ifset -@ifset familyF90 -* MatMul Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Max Intrinsic:: Maximum value. -* Max0 Intrinsic:: Maximum value (archaic). -* Max1 Intrinsic:: Maximum value (archaic). -@end ifset -@ifset familyF90 -* MaxExponent Intrinsic:: (Reserved for future use.) -* MaxLoc Intrinsic:: (Reserved for future use.) -* MaxVal Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* MClock Intrinsic:: Get number of clock ticks for process. -* MClock8 Intrinsic:: Get number of clock ticks for process. -@end ifset -@ifset familyF90 -* Merge Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Min Intrinsic:: Minimum value. -* Min0 Intrinsic:: Minimum value (archaic). -* Min1 Intrinsic:: Minimum value (archaic). -@end ifset -@ifset familyF90 -* MinExponent Intrinsic:: (Reserved for future use.) -* MinLoc Intrinsic:: (Reserved for future use.) -* MinVal Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Mod Intrinsic:: Remainder. -@end ifset -@ifset familyF90 -* Modulo Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyMIL -* MvBits Intrinsic:: Moving a bit field. -@end ifset -@ifset familyF90 -* Nearest Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* NInt Intrinsic:: Convert to @code{INTEGER} value rounded - to nearest whole number. -@end ifset -@ifset familyMIL -* Not Intrinsic:: Boolean NOT. -@end ifset -@ifset familyF2C -* Or Intrinsic:: Boolean OR. -@end ifset -@ifset familyF90 -* Pack Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* PError Intrinsic:: Print error message for last error. -@end ifset -@ifset familyF90 -* Precision Intrinsic:: (Reserved for future use.) -* Present Intrinsic:: (Reserved for future use.) -* Product Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyVXT -* QAbs Intrinsic:: (Reserved for future use.) -* QACos Intrinsic:: (Reserved for future use.) -* QACosD Intrinsic:: (Reserved for future use.) -* QASin Intrinsic:: (Reserved for future use.) -* QASinD Intrinsic:: (Reserved for future use.) -* QATan Intrinsic:: (Reserved for future use.) -* QATan2 Intrinsic:: (Reserved for future use.) -* QATan2D Intrinsic:: (Reserved for future use.) -* QATanD Intrinsic:: (Reserved for future use.) -* QCos Intrinsic:: (Reserved for future use.) -* QCosD Intrinsic:: (Reserved for future use.) -* QCosH Intrinsic:: (Reserved for future use.) -* QDiM Intrinsic:: (Reserved for future use.) -* QExp Intrinsic:: (Reserved for future use.) -* QExt Intrinsic:: (Reserved for future use.) -* QExtD Intrinsic:: (Reserved for future use.) -* QFloat Intrinsic:: (Reserved for future use.) -* QInt Intrinsic:: (Reserved for future use.) -* QLog Intrinsic:: (Reserved for future use.) -* QLog10 Intrinsic:: (Reserved for future use.) -* QMax1 Intrinsic:: (Reserved for future use.) -* QMin1 Intrinsic:: (Reserved for future use.) -* QMod Intrinsic:: (Reserved for future use.) -* QNInt Intrinsic:: (Reserved for future use.) -* QSin Intrinsic:: (Reserved for future use.) -* QSinD Intrinsic:: (Reserved for future use.) -* QSinH Intrinsic:: (Reserved for future use.) -* QSqRt Intrinsic:: (Reserved for future use.) -* QTan Intrinsic:: (Reserved for future use.) -* QTanD Intrinsic:: (Reserved for future use.) -* QTanH Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Radix Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Rand Intrinsic:: Random number. -@end ifset -@ifset familyF90 -* Random_Number Intrinsic:: (Reserved for future use.) -* Random_Seed Intrinsic:: (Reserved for future use.) -* Range Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* Real Intrinsic:: Convert value to type @code{REAL(KIND=1)}. -@end ifset -@ifset familyGNU -* RealPart Intrinsic:: Extract real part of complex. -@end ifset -@ifset familyF2U -* Rename Intrinsic (subroutine):: Rename file. -@end ifset -@ifset familyBADU77 -* Rename Intrinsic (function):: Rename file. -@end ifset -@ifset familyF90 -* Repeat Intrinsic:: (Reserved for future use.) -* Reshape Intrinsic:: (Reserved for future use.) -* RRSpacing Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2C -* RShift Intrinsic:: Right-shift bits. -@end ifset -@ifset familyF90 -* Scale Intrinsic:: (Reserved for future use.) -* Scan Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyVXT -* Secnds Intrinsic:: Get local time offset since midnight. -@end ifset -@ifset familyF2U -* Second Intrinsic (function):: Get CPU time for process in seconds. -* Second Intrinsic (subroutine):: Get CPU time for process - in seconds. -@end ifset -@ifset familyF90 -* Selected_Int_Kind Intrinsic:: (Reserved for future use.) -* Selected_Real_Kind Intrinsic:: (Reserved for future use.) -* Set_Exponent Intrinsic:: (Reserved for future use.) -* Shape Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* Short Intrinsic:: Convert to @code{INTEGER(KIND=6)} value - truncated to whole number. -@end ifset -@ifset familyF77 -* Sign Intrinsic:: Apply sign to magnitude. -@end ifset -@ifset familyF2U -* Signal Intrinsic (subroutine):: Muck with signal handling. -@end ifset -@ifset familyBADU77 -* Signal Intrinsic (function):: Muck with signal handling. -@end ifset -@ifset familyF77 -* Sin Intrinsic:: Sine. -@end ifset -@ifset familyVXT -* SinD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* SinH Intrinsic:: Hyperbolic sine. -@end ifset -@ifset familyF2U -* Sleep Intrinsic:: Sleep for a specified time. -@end ifset -@ifset familyF77 -* Sngl Intrinsic:: Convert (archaic). -@end ifset -@ifset familyVXT -* SnglQ Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF90 -* Spacing Intrinsic:: (Reserved for future use.) -* Spread Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* SqRt Intrinsic:: Square root. -@end ifset -@ifset familyF2U -* SRand Intrinsic:: Random seed. -* Stat Intrinsic (subroutine):: Get file information. -* Stat Intrinsic (function):: Get file information. -@end ifset -@ifset familyF90 -* Sum Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* SymLnk Intrinsic (subroutine):: Make symbolic link in file system. -@end ifset -@ifset familyBADU77 -* SymLnk Intrinsic (function):: Make symbolic link in file system. -@end ifset -@ifset familyF2U -* System Intrinsic (subroutine):: Invoke shell (system) command. -@end ifset -@ifset familyBADU77 -* System Intrinsic (function):: Invoke shell (system) command. -@end ifset -@ifset familyF90 -* System_Clock Intrinsic:: Get current system clock value. -@end ifset -@ifset familyF77 -* Tan Intrinsic:: Tangent. -@end ifset -@ifset familyVXT -* TanD Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF77 -* TanH Intrinsic:: Hyperbolic tangent. -@end ifset -@ifset familyF2U -* Time Intrinsic (UNIX):: Get current time as time value. -@end ifset -@ifset familyVXT -* Time Intrinsic (VXT):: Get the time as a character value. -@end ifset -@ifset familyF2U -* Time8 Intrinsic:: Get current time as time value. -@end ifset -@ifset familyF90 -* Tiny Intrinsic:: (Reserved for future use.) -* Transfer Intrinsic:: (Reserved for future use.) -* Transpose Intrinsic:: (Reserved for future use.) -* Trim Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* TtyNam Intrinsic (subroutine):: Get name of terminal device for unit. -* TtyNam Intrinsic (function):: Get name of terminal device for unit. -@end ifset -@ifset familyF90 -* UBound Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2U -* UMask Intrinsic (subroutine):: Set file creation permissions mask. -@end ifset -@ifset familyBADU77 -* UMask Intrinsic (function):: Set file creation permissions mask. -@end ifset -@ifset familyF2U -* Unlink Intrinsic (subroutine):: Unlink file. -@end ifset -@ifset familyBADU77 -* Unlink Intrinsic (function):: Unlink file. -@end ifset -@ifset familyF90 -* Unpack Intrinsic:: (Reserved for future use.) -* Verify Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2C -* XOr Intrinsic:: Boolean XOR. -* ZAbs Intrinsic:: Absolute value (archaic). -* ZCos Intrinsic:: Cosine (archaic). -* ZExp Intrinsic:: Exponential (archaic). -@end ifset -@ifset familyVXT -* ZExt Intrinsic:: (Reserved for future use.) -@end ifset -@ifset familyF2C -* ZLog Intrinsic:: Natural logarithm (archaic). -* ZSin Intrinsic:: Sine (archaic). -* ZSqRt Intrinsic:: Square root (archaic). -@end ifset -@end menu - -@ifset familyF2U -@node Abort Intrinsic -@subsubsection Abort Intrinsic -@cindex Abort intrinsic -@cindex intrinsics, Abort - -@noindent -@example -CALL Abort() -@end example - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Prints a message and potentially causes a core dump via @code{abort(3)}. - -@end ifset -@ifset familyF77 -@node Abs Intrinsic -@subsubsection Abs Intrinsic -@cindex Abs intrinsic -@cindex intrinsics, Abs - -@noindent -@example -Abs(@var{A}) -@end example - -@noindent -Abs: @code{INTEGER} or @code{REAL} function. -The exact type depends on that of argument @var{A}---if @var{A} is -@code{COMPLEX}, this function's type is @code{REAL} -with the same @samp{KIND=} value as the type of @var{A}. -Otherwise, this function's type is the same as that of @var{A}. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the absolute value of @var{A}. - -If @var{A} is type @code{COMPLEX}, the absolute -value is computed as: - -@example -SQRT(REALPART(@var{A})**2, IMAGPART(@var{A})**2) -@end example - -@noindent -Otherwise, it is computed by negating the @var{A} if -it is negative, or returning @var{A}. - -@xref{Sign Intrinsic}, for how to explicitly -compute the positive or negative form of the absolute -value of an expression. - -@end ifset -@ifset familyF2U -@node Access Intrinsic -@subsubsection Access Intrinsic -@cindex Access intrinsic -@cindex intrinsics, Access - -@noindent -@example -Access(@var{Name}, @var{Mode}) -@end example - -@noindent -Access: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Mode}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Checks file @var{Name} for accessibility in the mode specified by @var{Mode} and -returns 0 if the file is accessible in that mode, otherwise an error -code if the file is inaccessible or @var{Mode} is invalid. -See @code{access(2)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{Name}---otherwise, -trailing blanks in @var{Name} are ignored. -@var{Mode} may be a concatenation of any of the following characters: - -@table @samp -@item r -Read permission - -@item w -Write permission - -@item x -Execute permission - -@item @kbd{SPC} -Existence -@end table - -@end ifset -@ifset familyASC -@node AChar Intrinsic -@subsubsection AChar Intrinsic -@cindex AChar intrinsic -@cindex intrinsics, AChar - -@noindent -@example -AChar(@var{I}) -@end example - -@noindent -AChar: @code{CHARACTER*1} function. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{f90}. - -@noindent -Description: - -Returns the ASCII character corresponding to the -code specified by @var{I}. - -@xref{IAChar Intrinsic}, for the inverse of this function. - -@xref{Char Intrinsic}, for the function corresponding -to the system's native character set. - -@end ifset -@ifset familyF77 -@node ACos Intrinsic -@subsubsection ACos Intrinsic -@cindex ACos intrinsic -@cindex intrinsics, ACos - -@noindent -@example -ACos(@var{X}) -@end example - -@noindent -ACos: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the arc-cosine (inverse cosine) of @var{X} -in radians. - -@xref{Cos Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node ACosD Intrinsic -@subsubsection ACosD Intrinsic -@cindex ACosD intrinsic -@cindex intrinsics, ACosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL ACosD} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node AdjustL Intrinsic -@subsubsection AdjustL Intrinsic -@cindex AdjustL intrinsic -@cindex intrinsics, AdjustL - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AdjustL} to use this name for an -external procedure. - -@node AdjustR Intrinsic -@subsubsection AdjustR Intrinsic -@cindex AdjustR intrinsic -@cindex intrinsics, AdjustR - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AdjustR} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node AImag Intrinsic -@subsubsection AImag Intrinsic -@cindex AImag intrinsic -@cindex intrinsics, AImag - -@noindent -@example -AImag(@var{Z}) -@end example - -@noindent -AImag: @code{REAL} function. -This intrinsic is valid when argument @var{Z} is -@code{COMPLEX(KIND=1)}. -When @var{Z} is any other @code{COMPLEX} type, -this intrinsic is valid only when used as the argument to -@code{REAL()}, as explained below. - -@noindent -@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the (possibly converted) imaginary part of @var{Z}. - -Use of @code{AIMAG()} with an argument of a type -other than @code{COMPLEX(KIND=1)} is restricted to the following case: - -@example -REAL(AIMAG(Z)) -@end example - -@noindent -This expression converts the imaginary part of Z to -@code{REAL(KIND=1)}. - -@xref{REAL() and AIMAG() of Complex}, for more information. - -@end ifset -@ifset familyVXT -@node AIMax0 Intrinsic -@subsubsection AIMax0 Intrinsic -@cindex AIMax0 intrinsic -@cindex intrinsics, AIMax0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AIMax0} to use this name for an -external procedure. - -@node AIMin0 Intrinsic -@subsubsection AIMin0 Intrinsic -@cindex AIMin0 intrinsic -@cindex intrinsics, AIMin0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AIMin0} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node AInt Intrinsic -@subsubsection AInt Intrinsic -@cindex AInt intrinsic -@cindex intrinsics, AInt - -@noindent -@example -AInt(@var{A}) -@end example - -@noindent -AInt: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{A}. - -@noindent -@var{A}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude truncated and its sign preserved. -(Also called ``truncation towards zero''.) - -@xref{ANInt Intrinsic}, for how to round to nearest -whole number. - -@xref{Int Intrinsic}, for how to truncate and then convert -number to @code{INTEGER}. - -@end ifset -@ifset familyVXT -@node AJMax0 Intrinsic -@subsubsection AJMax0 Intrinsic -@cindex AJMax0 intrinsic -@cindex intrinsics, AJMax0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AJMax0} to use this name for an -external procedure. - -@node AJMin0 Intrinsic -@subsubsection AJMin0 Intrinsic -@cindex AJMin0 intrinsic -@cindex intrinsics, AJMin0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL AJMin0} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Alarm Intrinsic -@subsubsection Alarm Intrinsic -@cindex Alarm intrinsic -@cindex intrinsics, Alarm - -@noindent -@example -CALL Alarm(@var{Seconds}, @var{Handler}, @var{Status}) -@end example - -@noindent -@var{Seconds}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Handler}: Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE}) -or dummy/global @code{INTEGER(KIND=1)} scalar. - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Causes external subroutine @var{Handler} to be executed after a delay of -@var{Seconds} seconds by using @code{alarm(1)} to set up a signal and -@code{signal(2)} to catch it. -If @var{Status} is supplied, it will be -returned with the number of seconds remaining until any previously -scheduled alarm was due to be delivered, or zero if there was no -previously scheduled alarm. -@xref{Signal Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node All Intrinsic -@subsubsection All Intrinsic -@cindex All intrinsic -@cindex intrinsics, All - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL All} to use this name for an -external procedure. - -@node Allocated Intrinsic -@subsubsection Allocated Intrinsic -@cindex Allocated intrinsic -@cindex intrinsics, Allocated - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Allocated} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node ALog Intrinsic -@subsubsection ALog Intrinsic -@cindex ALog intrinsic -@cindex intrinsics, ALog - -@noindent -@example -ALog(@var{X}) -@end example - -@noindent -ALog: @code{REAL(KIND=1)} function. - -@noindent -@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{LOG()} that is specific -to one type for @var{X}. -@xref{Log Intrinsic}. - -@node ALog10 Intrinsic -@subsubsection ALog10 Intrinsic -@cindex ALog10 intrinsic -@cindex intrinsics, ALog10 - -@noindent -@example -ALog10(@var{X}) -@end example - -@noindent -ALog10: @code{REAL(KIND=1)} function. - -@noindent -@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{LOG10()} that is specific -to one type for @var{X}. -@xref{Log10 Intrinsic}. - -@node AMax0 Intrinsic -@subsubsection AMax0 Intrinsic -@cindex AMax0 intrinsic -@cindex intrinsics, AMax0 - -@noindent -@example -AMax0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -AMax0: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MAX()} that is specific -to one type for @var{A} and a different return type. -@xref{Max Intrinsic}. - -@node AMax1 Intrinsic -@subsubsection AMax1 Intrinsic -@cindex AMax1 intrinsic -@cindex intrinsics, AMax1 - -@noindent -@example -AMax1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -AMax1: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MAX()} that is specific -to one type for @var{A}. -@xref{Max Intrinsic}. - -@node AMin0 Intrinsic -@subsubsection AMin0 Intrinsic -@cindex AMin0 intrinsic -@cindex intrinsics, AMin0 - -@noindent -@example -AMin0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -AMin0: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MIN()} that is specific -to one type for @var{A} and a different return type. -@xref{Min Intrinsic}. - -@node AMin1 Intrinsic -@subsubsection AMin1 Intrinsic -@cindex AMin1 intrinsic -@cindex intrinsics, AMin1 - -@noindent -@example -AMin1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -AMin1: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MIN()} that is specific -to one type for @var{A}. -@xref{Min Intrinsic}. - -@node AMod Intrinsic -@subsubsection AMod Intrinsic -@cindex AMod intrinsic -@cindex intrinsics, AMod - -@noindent -@example -AMod(@var{A}, @var{P}) -@end example - -@noindent -AMod: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{P}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MOD()} that is specific -to one type for @var{A}. -@xref{Mod Intrinsic}. - -@end ifset -@ifset familyF2C -@node And Intrinsic -@subsubsection And Intrinsic -@cindex And intrinsic -@cindex intrinsics, And - -@noindent -@example -And(@var{I}, @var{J}) -@end example - -@noindent -And: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Returns value resulting from boolean AND of -pair of bits in each of @var{I} and @var{J}. - -@end ifset -@ifset familyF77 -@node ANInt Intrinsic -@subsubsection ANInt Intrinsic -@cindex ANInt intrinsic -@cindex intrinsics, ANInt - -@noindent -@example -ANInt(@var{A}) -@end example - -@noindent -ANInt: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{A}. - -@noindent -@var{A}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude eliminated by rounding to the nearest whole -number and with its sign preserved. - -A fractional portion exactly equal to -@samp{.5} is rounded to the whole number that -is larger in magnitude. -(Also called ``Fortran round''.) - -@xref{AInt Intrinsic}, for how to truncate to -whole number. - -@xref{NInt Intrinsic}, for how to round and then convert -number to @code{INTEGER}. - -@end ifset -@ifset familyF90 -@node Any Intrinsic -@subsubsection Any Intrinsic -@cindex Any intrinsic -@cindex intrinsics, Any - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Any} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node ASin Intrinsic -@subsubsection ASin Intrinsic -@cindex ASin intrinsic -@cindex intrinsics, ASin - -@noindent -@example -ASin(@var{X}) -@end example - -@noindent -ASin: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the arc-sine (inverse sine) of @var{X} -in radians. - -@xref{Sin Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node ASinD Intrinsic -@subsubsection ASinD Intrinsic -@cindex ASinD intrinsic -@cindex intrinsics, ASinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL ASinD} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Associated Intrinsic -@subsubsection Associated Intrinsic -@cindex Associated intrinsic -@cindex intrinsics, Associated - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Associated} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node ATan Intrinsic -@subsubsection ATan Intrinsic -@cindex ATan intrinsic -@cindex intrinsics, ATan - -@noindent -@example -ATan(@var{X}) -@end example - -@noindent -ATan: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the arc-tangent (inverse tangent) of @var{X} -in radians. - -@xref{Tan Intrinsic}, for the inverse of this function. - -@node ATan2 Intrinsic -@subsubsection ATan2 Intrinsic -@cindex ATan2 intrinsic -@cindex intrinsics, ATan2 - -@noindent -@example -ATan2(@var{Y}, @var{X}) -@end example - -@noindent -ATan2: @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{Y}: @code{REAL}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the arc-tangent (inverse tangent) of the complex -number (@var{Y}, @var{X}) in radians. - -@xref{Tan Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node ATan2D Intrinsic -@subsubsection ATan2D Intrinsic -@cindex ATan2D intrinsic -@cindex intrinsics, ATan2D - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL ATan2D} to use this name for an -external procedure. - -@node ATanD Intrinsic -@subsubsection ATanD Intrinsic -@cindex ATanD intrinsic -@cindex intrinsics, ATanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL ATanD} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node BesJ0 Intrinsic -@subsubsection BesJ0 Intrinsic -@cindex BesJ0 intrinsic -@cindex intrinsics, BesJ0 - -@noindent -@example -BesJ0(@var{X}) -@end example - -@noindent -BesJ0: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the first kind of order 0 of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@node BesJ1 Intrinsic -@subsubsection BesJ1 Intrinsic -@cindex BesJ1 intrinsic -@cindex intrinsics, BesJ1 - -@noindent -@example -BesJ1(@var{X}) -@end example - -@noindent -BesJ1: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the first kind of order 1 of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@node BesJN Intrinsic -@subsubsection BesJN Intrinsic -@cindex BesJN intrinsic -@cindex intrinsics, BesJN - -@noindent -@example -BesJN(@var{N}, @var{X}) -@end example - -@noindent -BesJN: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{N}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the first kind of order @var{N} of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@node BesY0 Intrinsic -@subsubsection BesY0 Intrinsic -@cindex BesY0 intrinsic -@cindex intrinsics, BesY0 - -@noindent -@example -BesY0(@var{X}) -@end example - -@noindent -BesY0: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the second kind of order 0 of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@node BesY1 Intrinsic -@subsubsection BesY1 Intrinsic -@cindex BesY1 intrinsic -@cindex intrinsics, BesY1 - -@noindent -@example -BesY1(@var{X}) -@end example - -@noindent -BesY1: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the second kind of order 1 of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@node BesYN Intrinsic -@subsubsection BesYN Intrinsic -@cindex BesYN intrinsic -@cindex intrinsics, BesYN - -@noindent -@example -BesYN(@var{N}, @var{X}) -@end example - -@noindent -BesYN: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{N}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Calculates the Bessel function of the second kind of order @var{N} of @var{X}. -See @code{bessel(3m)}, on whose implementation the function depends. -@end ifset -@ifset familyVXT -@node BITest Intrinsic -@subsubsection BITest Intrinsic -@cindex BITest intrinsic -@cindex intrinsics, BITest - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL BITest} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Bit_Size Intrinsic -@subsubsection Bit_Size Intrinsic -@cindex Bit_Size intrinsic -@cindex intrinsics, Bit_Size - -@noindent -@example -Bit_Size(@var{I}) -@end example - -@noindent -Bit_Size: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar. - -@noindent -Intrinsic groups: @code{f90}. - -@noindent -Description: - -Returns the number of bits (integer precision plus sign bit) -represented by the type for @var{I}. - -@xref{BTest Intrinsic}, for how to test the value of a -bit in a variable or array. - -@xref{IBSet Intrinsic}, for how to set a bit in a variable to 1. - -@xref{IBClr Intrinsic}, for how to set a bit in a variable to 0. - - -@end ifset -@ifset familyVXT -@node BJTest Intrinsic -@subsubsection BJTest Intrinsic -@cindex BJTest intrinsic -@cindex intrinsics, BJTest - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL BJTest} to use this name for an -external procedure. - -@end ifset -@ifset familyMIL -@node BTest Intrinsic -@subsubsection BTest Intrinsic -@cindex BTest intrinsic -@cindex intrinsics, BTest - -@noindent -@example -BTest(@var{I}, @var{Pos}) -@end example - -@noindent -BTest: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns @code{.TRUE.} if bit @var{Pos} in @var{I} is -1, @code{.FALSE.} otherwise. - -(Bit 0 is the low-order (rightmost) bit, adding the value -@ifinfo -2**0, -@end ifinfo -@iftex -@tex -$2^0$, -@end tex -@end iftex -or 1, -to the number if set to 1; -bit 1 is the next-higher-order bit, adding -@ifinfo -2**1, -@end ifinfo -@iftex -@tex -$2^1$, -@end tex -@end iftex -or 2; -bit 2 adds -@ifinfo -2**2, -@end ifinfo -@iftex -@tex -$2^2$, -@end tex -@end iftex -or 4; and so on.) - -@xref{Bit_Size Intrinsic}, for how to obtain the number of bits -in a type. -The leftmost bit of @var{I} is @samp{BIT_SIZE(@var{I}-1)}. - -@end ifset -@ifset familyF77 -@node CAbs Intrinsic -@subsubsection CAbs Intrinsic -@cindex CAbs intrinsic -@cindex intrinsics, CAbs - -@noindent -@example -CAbs(@var{A}) -@end example - -@noindent -CAbs: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ABS()} that is specific -to one type for @var{A}. -@xref{Abs Intrinsic}. - -@node CCos Intrinsic -@subsubsection CCos Intrinsic -@cindex CCos intrinsic -@cindex intrinsics, CCos - -@noindent -@example -CCos(@var{X}) -@end example - -@noindent -CCos: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{COS()} that is specific -to one type for @var{X}. -@xref{Cos Intrinsic}. - -@end ifset -@ifset familyFVZ -@node CDAbs Intrinsic -@subsubsection CDAbs Intrinsic -@cindex CDAbs intrinsic -@cindex intrinsics, CDAbs - -@noindent -@example -CDAbs(@var{A}) -@end example - -@noindent -CDAbs: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{ABS()} that is specific -to one type for @var{A}. -@xref{Abs Intrinsic}. - -@node CDCos Intrinsic -@subsubsection CDCos Intrinsic -@cindex CDCos intrinsic -@cindex intrinsics, CDCos - -@noindent -@example -CDCos(@var{X}) -@end example - -@noindent -CDCos: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{COS()} that is specific -to one type for @var{X}. -@xref{Cos Intrinsic}. - -@node CDExp Intrinsic -@subsubsection CDExp Intrinsic -@cindex CDExp intrinsic -@cindex intrinsics, CDExp - -@noindent -@example -CDExp(@var{X}) -@end example - -@noindent -CDExp: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{EXP()} that is specific -to one type for @var{X}. -@xref{Exp Intrinsic}. - -@node CDLog Intrinsic -@subsubsection CDLog Intrinsic -@cindex CDLog intrinsic -@cindex intrinsics, CDLog - -@noindent -@example -CDLog(@var{X}) -@end example - -@noindent -CDLog: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{LOG()} that is specific -to one type for @var{X}. -@xref{Log Intrinsic}. - -@node CDSin Intrinsic -@subsubsection CDSin Intrinsic -@cindex CDSin intrinsic -@cindex intrinsics, CDSin - -@noindent -@example -CDSin(@var{X}) -@end example - -@noindent -CDSin: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{SIN()} that is specific -to one type for @var{X}. -@xref{Sin Intrinsic}. - -@node CDSqRt Intrinsic -@subsubsection CDSqRt Intrinsic -@cindex CDSqRt intrinsic -@cindex intrinsics, CDSqRt - -@noindent -@example -CDSqRt(@var{X}) -@end example - -@noindent -CDSqRt: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{SQRT()} that is specific -to one type for @var{X}. -@xref{SqRt Intrinsic}. - -@end ifset -@ifset familyF90 -@node Ceiling Intrinsic -@subsubsection Ceiling Intrinsic -@cindex Ceiling intrinsic -@cindex intrinsics, Ceiling - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Ceiling} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node CExp Intrinsic -@subsubsection CExp Intrinsic -@cindex CExp intrinsic -@cindex intrinsics, CExp - -@noindent -@example -CExp(@var{X}) -@end example - -@noindent -CExp: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{EXP()} that is specific -to one type for @var{X}. -@xref{Exp Intrinsic}. - -@node Char Intrinsic -@subsubsection Char Intrinsic -@cindex Char intrinsic -@cindex intrinsics, Char - -@noindent -@example -Char(@var{I}) -@end example - -@noindent -Char: @code{CHARACTER*1} function. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the character corresponding to the -code specified by @var{I}, using the system's -native character set. - -Because the system's native character set is used, -the correspondence between character and their codes -is not necessarily the same between GNU Fortran -implementations. - -Note that no intrinsic exists to convert a numerical -value to a printable character string. -For example, there is no intrinsic that, given -an @code{INTEGER} or @code{REAL} argument with the -value @samp{154}, returns the @code{CHARACTER} -result @samp{'154'}. - -Instead, you can use internal-file I/O to do this kind -of conversion. -For example: - -@smallexample -INTEGER VALUE -CHARACTER*10 STRING -VALUE = 154 -WRITE (STRING, '(I10)'), VALUE -PRINT *, STRING -END -@end smallexample - -The above program, when run, prints: - -@smallexample - 154 -@end smallexample - -@xref{IChar Intrinsic}, for the inverse of the @code{CHAR} function. - -@xref{AChar Intrinsic}, for the function corresponding -to the ASCII character set. - -@end ifset -@ifset familyF2U -@node ChDir Intrinsic (subroutine) -@subsubsection ChDir Intrinsic (subroutine) -@cindex ChDir intrinsic -@cindex intrinsics, ChDir - -@noindent -@example -CALL ChDir(@var{Dir}, @var{Status}) -@end example - -@noindent -@var{Dir}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets the current working directory to be @var{Dir}. -If the @var{Status} argument is supplied, it contains 0 -on success or a non-zero error code otherwise upon return. -See @code{chdir(3)}. - -@emph{Caution:} Using this routine during I/O to a unit connected with a -non-absolute file name can cause subsequent I/O on such a unit to fail -because the I/O library might reopen files by name. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{ChDir Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node ChDir Intrinsic (function) -@subsubsection ChDir Intrinsic (function) -@cindex ChDir intrinsic -@cindex intrinsics, ChDir - -@noindent -@example -ChDir(@var{Dir}) -@end example - -@noindent -ChDir: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Dir}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Sets the current working directory to be @var{Dir}. -Returns 0 on success or a non-zero error code. -See @code{chdir(3)}. - -@emph{Caution:} Using this routine during I/O to a unit connected with a -non-absolute file name can cause subsequent I/O on such a unit to fail -because the I/O library might reopen files by name. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{ChDir Intrinsic (subroutine)}. - -@end ifset -@ifset familyF2U -@node ChMod Intrinsic (subroutine) -@subsubsection ChMod Intrinsic (subroutine) -@cindex ChMod intrinsic -@cindex intrinsics, ChMod - -@noindent -@example -CALL ChMod(@var{Name}, @var{Mode}, @var{Status}) -@end example - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Mode}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Changes the access mode of file @var{Name} according to the -specification @var{Mode}, which is given in the format of -@code{chmod(1)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{Name}---otherwise, -trailing blanks in @var{Name} are ignored. -Currently, @var{Name} must not contain the single quote -character. - -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Note that this currently works -by actually invoking @code{/bin/chmod} (or the @code{chmod} found when -the library was configured) and so might fail in some circumstances and -will, anyway, be slow. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{ChMod Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node ChMod Intrinsic (function) -@subsubsection ChMod Intrinsic (function) -@cindex ChMod intrinsic -@cindex intrinsics, ChMod - -@noindent -@example -ChMod(@var{Name}, @var{Mode}) -@end example - -@noindent -ChMod: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Mode}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Changes the access mode of file @var{Name} according to the -specification @var{Mode}, which is given in the format of -@code{chmod(1)}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{Name}---otherwise, -trailing blanks in @var{Name} are ignored. -Currently, @var{Name} must not contain the single quote -character. - -Returns 0 on success or a non-zero error code otherwise. - -Note that this currently works -by actually invoking @code{/bin/chmod} (or the @code{chmod} found when -the library was configured) and so might fail in some circumstances and -will, anyway, be slow. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{ChMod Intrinsic (subroutine)}. - -@end ifset -@ifset familyF77 -@node CLog Intrinsic -@subsubsection CLog Intrinsic -@cindex CLog intrinsic -@cindex intrinsics, CLog - -@noindent -@example -CLog(@var{X}) -@end example - -@noindent -CLog: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{LOG()} that is specific -to one type for @var{X}. -@xref{Log Intrinsic}. - -@node Cmplx Intrinsic -@subsubsection Cmplx Intrinsic -@cindex Cmplx intrinsic -@cindex intrinsics, Cmplx - -@noindent -@example -Cmplx(@var{X}, @var{Y}) -@end example - -@noindent -Cmplx: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{INTEGER} or @code{REAL}; OPTIONAL (must be omitted if @var{X} is @code{COMPLEX}); scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -If @var{X} is not type @code{COMPLEX}, -constructs a value of type @code{COMPLEX(KIND=1)} from the -real and imaginary values specified by @var{X} and -@var{Y}, respectively. -If @var{Y} is omitted, @samp{0.} is assumed. - -If @var{X} is type @code{COMPLEX}, -converts it to type @code{COMPLEX(KIND=1)}. - -@xref{Complex Intrinsic}, for information on easily constructing -a @code{COMPLEX} value of arbitrary precision from @code{REAL} -arguments. - -@end ifset -@ifset familyGNU -@node Complex Intrinsic -@subsubsection Complex Intrinsic -@cindex Complex intrinsic -@cindex intrinsics, Complex - -@noindent -@example -Complex(@var{Real}, @var{Imag}) -@end example - -@noindent -Complex: @code{COMPLEX} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{Real}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -@var{Imag}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{gnu}. - -@noindent -Description: - -Returns a @code{COMPLEX} value that has @samp{Real} and @samp{Imag} as its -real and imaginary parts, respectively. - -If @var{Real} and @var{Imag} are the same type, and that type is not -@code{INTEGER}, no data conversion is performed, and the type of -the resulting value has the same kind value as the types -of @var{Real} and @var{Imag}. - -If @var{Real} and @var{Imag} are not the same type, the usual type-promotion -rules are applied to both, converting either or both to the -appropriate @code{REAL} type. -The type of the resulting value has the same kind value as the -type to which both @var{Real} and @var{Imag} were converted, in this case. - -If @var{Real} and @var{Imag} are both @code{INTEGER}, they are both converted -to @code{REAL(KIND=1)}, and the result of the @code{COMPLEX()} -invocation is type @code{COMPLEX(KIND=1)}. - -@emph{Note:} The way to do this in standard Fortran 90 -is too hairy to describe here, but it is important to -note that @samp{CMPLX(D1,D2)} returns a @code{COMPLEX(KIND=1)} -result even if @samp{D1} and @samp{D2} are type @code{REAL(KIND=2)}. -Hence the availability of @code{COMPLEX()} in GNU Fortran. - -@end ifset -@ifset familyF77 -@node Conjg Intrinsic -@subsubsection Conjg Intrinsic -@cindex Conjg intrinsic -@cindex intrinsics, Conjg - -@noindent -@example -Conjg(@var{Z}) -@end example - -@noindent -Conjg: @code{COMPLEX} function, the @samp{KIND=} value of the type being that of argument @var{Z}. - -@noindent -@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the complex conjugate: - -@example -COMPLEX(REALPART(@var{Z}), -IMAGPART(@var{Z})) -@end example - -@node Cos Intrinsic -@subsubsection Cos Intrinsic -@cindex Cos intrinsic -@cindex intrinsics, Cos - -@noindent -@example -Cos(@var{X}) -@end example - -@noindent -Cos: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the cosine of @var{X}, an angle measured -in radians. - -@xref{ACos Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node CosD Intrinsic -@subsubsection CosD Intrinsic -@cindex CosD intrinsic -@cindex intrinsics, CosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL CosD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node CosH Intrinsic -@subsubsection CosH Intrinsic -@cindex CosH intrinsic -@cindex intrinsics, CosH - -@noindent -@example -CosH(@var{X}) -@end example - -@noindent -CosH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the hyperbolic cosine of @var{X}. - -@end ifset -@ifset familyF90 -@node Count Intrinsic -@subsubsection Count Intrinsic -@cindex Count intrinsic -@cindex intrinsics, Count - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Count} to use this name for an -external procedure. - -@node CPU_Time Intrinsic -@subsubsection CPU_Time Intrinsic -@cindex CPU_Time intrinsic -@cindex intrinsics, CPU_Time - -@noindent -@example -CALL CPU_Time(@var{Seconds}) -@end example - -@noindent -@var{Seconds}: @code{REAL}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{f90}. - -@noindent -Description: - -Returns in @var{Seconds} the current value of the system time. -This implementation of the Fortran 95 intrinsic is just an alias for -@code{second} @xref{Second Intrinsic (subroutine)}. - -@node CShift Intrinsic -@subsubsection CShift Intrinsic -@cindex CShift intrinsic -@cindex intrinsics, CShift - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL CShift} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node CSin Intrinsic -@subsubsection CSin Intrinsic -@cindex CSin intrinsic -@cindex intrinsics, CSin - -@noindent -@example -CSin(@var{X}) -@end example - -@noindent -CSin: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SIN()} that is specific -to one type for @var{X}. -@xref{Sin Intrinsic}. - -@node CSqRt Intrinsic -@subsubsection CSqRt Intrinsic -@cindex CSqRt intrinsic -@cindex intrinsics, CSqRt - -@noindent -@example -CSqRt(@var{X}) -@end example - -@noindent -CSqRt: @code{COMPLEX(KIND=1)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SQRT()} that is specific -to one type for @var{X}. -@xref{SqRt Intrinsic}. - -@end ifset -@ifset familyF2U -@node CTime Intrinsic (subroutine) -@subsubsection CTime Intrinsic (subroutine) -@cindex CTime intrinsic -@cindex intrinsics, CTime - -@noindent -@example -CALL CTime(@var{Result}, @var{STime}) -@end example - -@noindent -@var{Result}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{STime}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Converts @var{STime}, a system time value, such as returned by -@code{TIME8()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}, -and returns that string in @var{Result}. - -@xref{Time8 Intrinsic}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{CTime Intrinsic (function)}. - -@node CTime Intrinsic (function) -@subsubsection CTime Intrinsic (function) -@cindex CTime intrinsic -@cindex intrinsics, CTime - -@noindent -@example -CTime(@var{STime}) -@end example - -@noindent -CTime: @code{CHARACTER*(*)} function. - -@noindent -@var{STime}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Converts @var{STime}, a system time value, such as returned by -@code{TIME8()}, to a string of the form @samp{Sat Aug 19 18:13:14 1995}, -and returns that string as the function value. - -@xref{Time8 Intrinsic}. - -For information on other intrinsics with the same name: -@xref{CTime Intrinsic (subroutine)}. - -@end ifset -@ifset familyF77 -@node DAbs Intrinsic -@subsubsection DAbs Intrinsic -@cindex DAbs intrinsic -@cindex intrinsics, DAbs - -@noindent -@example -DAbs(@var{A}) -@end example - -@noindent -DAbs: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ABS()} that is specific -to one type for @var{A}. -@xref{Abs Intrinsic}. - -@node DACos Intrinsic -@subsubsection DACos Intrinsic -@cindex DACos intrinsic -@cindex intrinsics, DACos - -@noindent -@example -DACos(@var{X}) -@end example - -@noindent -DACos: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ACOS()} that is specific -to one type for @var{X}. -@xref{ACos Intrinsic}. - -@end ifset -@ifset familyVXT -@node DACosD Intrinsic -@subsubsection DACosD Intrinsic -@cindex DACosD intrinsic -@cindex intrinsics, DACosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DACosD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DASin Intrinsic -@subsubsection DASin Intrinsic -@cindex DASin intrinsic -@cindex intrinsics, DASin - -@noindent -@example -DASin(@var{X}) -@end example - -@noindent -DASin: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ASIN()} that is specific -to one type for @var{X}. -@xref{ASin Intrinsic}. - -@end ifset -@ifset familyVXT -@node DASinD Intrinsic -@subsubsection DASinD Intrinsic -@cindex DASinD intrinsic -@cindex intrinsics, DASinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DASinD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DATan Intrinsic -@subsubsection DATan Intrinsic -@cindex DATan intrinsic -@cindex intrinsics, DATan - -@noindent -@example -DATan(@var{X}) -@end example - -@noindent -DATan: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ATAN()} that is specific -to one type for @var{X}. -@xref{ATan Intrinsic}. - -@node DATan2 Intrinsic -@subsubsection DATan2 Intrinsic -@cindex DATan2 intrinsic -@cindex intrinsics, DATan2 - -@noindent -@example -DATan2(@var{Y}, @var{X}) -@end example - -@noindent -DATan2: @code{REAL(KIND=2)} function. - -@noindent -@var{Y}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ATAN2()} that is specific -to one type for @var{Y} and @var{X}. -@xref{ATan2 Intrinsic}. - -@end ifset -@ifset familyVXT -@node DATan2D Intrinsic -@subsubsection DATan2D Intrinsic -@cindex DATan2D intrinsic -@cindex intrinsics, DATan2D - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DATan2D} to use this name for an -external procedure. - -@node DATanD Intrinsic -@subsubsection DATanD Intrinsic -@cindex DATanD intrinsic -@cindex intrinsics, DATanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DATanD} to use this name for an -external procedure. - -@node Date Intrinsic -@subsubsection Date Intrinsic -@cindex Date intrinsic -@cindex intrinsics, Date - -@noindent -@example -CALL Date(@var{Date}) -@end example - -@noindent -@var{Date}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{vxt}. - -@noindent -Description: - -Returns @var{Date} in the form @samp{@var{dd}-@var{mmm}-@var{yy}}, -representing the numeric day of the month @var{dd}, a three-character -abbreviation of the month name @var{mmm} and the last two digits of -the year @var{yy}, e.g.@: @samp{25-Nov-96}. - -This intrinsic is not recommended, due to the year 2000 approaching. -@xref{CTime Intrinsic (subroutine)}, for information on obtaining more digits -for the current (or any) date. - -@end ifset -@ifset familyF90 -@node Date_and_Time Intrinsic -@subsubsection Date_and_Time Intrinsic -@cindex Date_and_Time intrinsic -@cindex intrinsics, Date_and_Time - -@noindent -@example -CALL Date_and_Time(@var{Date}, @var{Time}, @var{Zone}, @var{Values}) -@end example - -@noindent -@var{Date}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Time}: @code{CHARACTER}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -@var{Zone}: @code{CHARACTER}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -@var{Values}: @code{INTEGER(KIND=1)}; OPTIONAL; DIMENSION(8); INTENT(OUT). - -@noindent -Intrinsic groups: @code{f90}. - -@noindent -Description: - -Returns: -@table @var -@item Date -The date in the form @var{ccyymmdd}: century, year, month and day; -@item Time -The time in the form @samp{@var{hhmmss.ss}}: hours, minutes, seconds -and milliseconds; -@item Zone -The difference between local time and UTC (GMT) in the form @var{Shhmm}: -sign, hours and minutes, e.g.@: @samp{-0500} (winter in New York); -@item Values -The year, month of the year, day of the month, time difference in -minutes from UTC, hour of the day, minutes of the hour and milliseconds -of the second in successive values of the array. -@end table - -On systems where a millisecond timer isn't available, the millisecond -value is returned as zero. - -@end ifset -@ifset familyF2U -@node DbesJ0 Intrinsic -@subsubsection DbesJ0 Intrinsic -@cindex DbesJ0 intrinsic -@cindex intrinsics, DbesJ0 - -@noindent -@example -DbesJ0(@var{X}) -@end example - -@noindent -DbesJ0: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESJ0()} that is specific -to one type for @var{X}. -@xref{BesJ0 Intrinsic}. - -@node DbesJ1 Intrinsic -@subsubsection DbesJ1 Intrinsic -@cindex DbesJ1 intrinsic -@cindex intrinsics, DbesJ1 - -@noindent -@example -DbesJ1(@var{X}) -@end example - -@noindent -DbesJ1: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESJ1()} that is specific -to one type for @var{X}. -@xref{BesJ1 Intrinsic}. - -@node DbesJN Intrinsic -@subsubsection DbesJN Intrinsic -@cindex DbesJN intrinsic -@cindex intrinsics, DbesJN - -@noindent -@example -DbesJN(@var{N}, @var{X}) -@end example - -@noindent -DbesJN: @code{REAL(KIND=2)} function. - -@noindent -@var{N}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESJN()} that is specific -to one type for @var{X}. -@xref{BesJN Intrinsic}. - -@node DbesY0 Intrinsic -@subsubsection DbesY0 Intrinsic -@cindex DbesY0 intrinsic -@cindex intrinsics, DbesY0 - -@noindent -@example -DbesY0(@var{X}) -@end example - -@noindent -DbesY0: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESY0()} that is specific -to one type for @var{X}. -@xref{BesY0 Intrinsic}. - -@node DbesY1 Intrinsic -@subsubsection DbesY1 Intrinsic -@cindex DbesY1 intrinsic -@cindex intrinsics, DbesY1 - -@noindent -@example -DbesY1(@var{X}) -@end example - -@noindent -DbesY1: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESY1()} that is specific -to one type for @var{X}. -@xref{BesY1 Intrinsic}. - -@node DbesYN Intrinsic -@subsubsection DbesYN Intrinsic -@cindex DbesYN intrinsic -@cindex intrinsics, DbesYN - -@noindent -@example -DbesYN(@var{N}, @var{X}) -@end example - -@noindent -DbesYN: @code{REAL(KIND=2)} function. - -@noindent -@var{N}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{BESYN()} that is specific -to one type for @var{X}. -@xref{BesYN Intrinsic}. - -@end ifset -@ifset familyF77 -@node Dble Intrinsic -@subsubsection Dble Intrinsic -@cindex Dble intrinsic -@cindex intrinsics, Dble - -@noindent -@example -Dble(@var{A}) -@end example - -@noindent -Dble: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @var{A} converted to double precision -(@code{REAL(KIND=2)}). -If @var{A} is @code{COMPLEX}, the real part of -@var{A} is used for the conversion -and the imaginary part disregarded. - -@xref{Sngl Intrinsic}, for the function that converts -to single precision. - -@xref{Int Intrinsic}, for the function that converts -to @code{INTEGER}. - -@xref{Complex Intrinsic}, for the function that converts -to @code{COMPLEX}. - -@end ifset -@ifset familyVXT -@node DbleQ Intrinsic -@subsubsection DbleQ Intrinsic -@cindex DbleQ intrinsic -@cindex intrinsics, DbleQ - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DbleQ} to use this name for an -external procedure. - -@end ifset -@ifset familyFVZ -@node DCmplx Intrinsic -@subsubsection DCmplx Intrinsic -@cindex DCmplx intrinsic -@cindex intrinsics, DCmplx - -@noindent -@example -DCmplx(@var{X}, @var{Y}) -@end example - -@noindent -DCmplx: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{INTEGER} or @code{REAL}; OPTIONAL (must be omitted if @var{X} is @code{COMPLEX}); scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -If @var{X} is not type @code{COMPLEX}, -constructs a value of type @code{COMPLEX(KIND=2)} from the -real and imaginary values specified by @var{X} and -@var{Y}, respectively. -If @var{Y} is omitted, @samp{0D0} is assumed. - -If @var{X} is type @code{COMPLEX}, -converts it to type @code{COMPLEX(KIND=2)}. - -Although this intrinsic is not standard Fortran, -it is a popular extension offered by many compilers -that support @code{DOUBLE COMPLEX}, since it offers -the easiest way to convert to @code{DOUBLE COMPLEX} -without using Fortran 90 features (such as the @samp{KIND=} -argument to the @code{CMPLX()} intrinsic). - -(@samp{CMPLX(0D0, 0D0)} returns a single-precision -@code{COMPLEX} result, as required by standard FORTRAN 77. -That's why so many compilers provide @code{DCMPLX()}, since -@samp{DCMPLX(0D0, 0D0)} returns a @code{DOUBLE COMPLEX} -result. -Still, @code{DCMPLX()} converts even @code{REAL*16} arguments -to their @code{REAL*8} equivalents in most dialects of -Fortran, so neither it nor @code{CMPLX()} allow easy -construction of arbitrary-precision values without -potentially forcing a conversion involving extending or -reducing precision. -GNU Fortran provides such an intrinsic, called @code{COMPLEX()}.) - -@xref{Complex Intrinsic}, for information on easily constructing -a @code{COMPLEX} value of arbitrary precision from @code{REAL} -arguments. - -@node DConjg Intrinsic -@subsubsection DConjg Intrinsic -@cindex DConjg intrinsic -@cindex intrinsics, DConjg - -@noindent -@example -DConjg(@var{Z}) -@end example - -@noindent -DConjg: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{Z}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{CONJG()} that is specific -to one type for @var{Z}. -@xref{Conjg Intrinsic}. - -@end ifset -@ifset familyF77 -@node DCos Intrinsic -@subsubsection DCos Intrinsic -@cindex DCos intrinsic -@cindex intrinsics, DCos - -@noindent -@example -DCos(@var{X}) -@end example - -@noindent -DCos: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{COS()} that is specific -to one type for @var{X}. -@xref{Cos Intrinsic}. - -@end ifset -@ifset familyVXT -@node DCosD Intrinsic -@subsubsection DCosD Intrinsic -@cindex DCosD intrinsic -@cindex intrinsics, DCosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DCosD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DCosH Intrinsic -@subsubsection DCosH Intrinsic -@cindex DCosH intrinsic -@cindex intrinsics, DCosH - -@noindent -@example -DCosH(@var{X}) -@end example - -@noindent -DCosH: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{COSH()} that is specific -to one type for @var{X}. -@xref{CosH Intrinsic}. - -@node DDiM Intrinsic -@subsubsection DDiM Intrinsic -@cindex DDiM intrinsic -@cindex intrinsics, DDiM - -@noindent -@example -DDiM(@var{X}, @var{Y}) -@end example - -@noindent -DDiM: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{DIM()} that is specific -to one type for @var{X} and @var{Y}. -@xref{DiM Intrinsic}. - -@end ifset -@ifset familyF2U -@node DErF Intrinsic -@subsubsection DErF Intrinsic -@cindex DErF intrinsic -@cindex intrinsics, DErF - -@noindent -@example -DErF(@var{X}) -@end example - -@noindent -DErF: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{ERF()} that is specific -to one type for @var{X}. -@xref{ErF Intrinsic}. - -@node DErFC Intrinsic -@subsubsection DErFC Intrinsic -@cindex DErFC intrinsic -@cindex intrinsics, DErFC - -@noindent -@example -DErFC(@var{X}) -@end example - -@noindent -DErFC: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{ERFC()} that is specific -to one type for @var{X}. -@xref{ErFC Intrinsic}. - -@end ifset -@ifset familyF77 -@node DExp Intrinsic -@subsubsection DExp Intrinsic -@cindex DExp intrinsic -@cindex intrinsics, DExp - -@noindent -@example -DExp(@var{X}) -@end example - -@noindent -DExp: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{EXP()} that is specific -to one type for @var{X}. -@xref{Exp Intrinsic}. - -@end ifset -@ifset familyFVZ -@node DFloat Intrinsic -@subsubsection DFloat Intrinsic -@cindex DFloat intrinsic -@cindex intrinsics, DFloat - -@noindent -@example -DFloat(@var{A}) -@end example - -@noindent -DFloat: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{REAL()} that is specific -to one type for @var{A}. -@xref{Real Intrinsic}. - -@end ifset -@ifset familyVXT -@node DFlotI Intrinsic -@subsubsection DFlotI Intrinsic -@cindex DFlotI intrinsic -@cindex intrinsics, DFlotI - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DFlotI} to use this name for an -external procedure. - -@node DFlotJ Intrinsic -@subsubsection DFlotJ Intrinsic -@cindex DFlotJ intrinsic -@cindex intrinsics, DFlotJ - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DFlotJ} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Digits Intrinsic -@subsubsection Digits Intrinsic -@cindex Digits intrinsic -@cindex intrinsics, Digits - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Digits} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DiM Intrinsic -@subsubsection DiM Intrinsic -@cindex DiM intrinsic -@cindex intrinsics, DiM - -@noindent -@example -DiM(@var{X}, @var{Y}) -@end example - -@noindent -DiM: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{X}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{@var{X}-@var{Y}} if @var{X} is greater than -@var{Y}; otherwise returns zero. - -@end ifset -@ifset familyFVZ -@node DImag Intrinsic -@subsubsection DImag Intrinsic -@cindex DImag intrinsic -@cindex intrinsics, DImag - -@noindent -@example -DImag(@var{Z}) -@end example - -@noindent -DImag: @code{REAL(KIND=2)} function. - -@noindent -@var{Z}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{vxt}. - -@noindent -Description: - -Archaic form of @code{AIMAG()} that is specific -to one type for @var{Z}. -@xref{AImag Intrinsic}. - -@end ifset -@ifset familyF77 -@node DInt Intrinsic -@subsubsection DInt Intrinsic -@cindex DInt intrinsic -@cindex intrinsics, DInt - -@noindent -@example -DInt(@var{A}) -@end example - -@noindent -DInt: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{AINT()} that is specific -to one type for @var{A}. -@xref{AInt Intrinsic}. - -@node DLog Intrinsic -@subsubsection DLog Intrinsic -@cindex DLog intrinsic -@cindex intrinsics, DLog - -@noindent -@example -DLog(@var{X}) -@end example - -@noindent -DLog: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{LOG()} that is specific -to one type for @var{X}. -@xref{Log Intrinsic}. - -@node DLog10 Intrinsic -@subsubsection DLog10 Intrinsic -@cindex DLog10 intrinsic -@cindex intrinsics, DLog10 - -@noindent -@example -DLog10(@var{X}) -@end example - -@noindent -DLog10: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{LOG10()} that is specific -to one type for @var{X}. -@xref{Log10 Intrinsic}. - -@node DMax1 Intrinsic -@subsubsection DMax1 Intrinsic -@cindex DMax1 intrinsic -@cindex intrinsics, DMax1 - -@noindent -@example -DMax1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -DMax1: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MAX()} that is specific -to one type for @var{A}. -@xref{Max Intrinsic}. - -@node DMin1 Intrinsic -@subsubsection DMin1 Intrinsic -@cindex DMin1 intrinsic -@cindex intrinsics, DMin1 - -@noindent -@example -DMin1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -DMin1: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MIN()} that is specific -to one type for @var{A}. -@xref{Min Intrinsic}. - -@node DMod Intrinsic -@subsubsection DMod Intrinsic -@cindex DMod intrinsic -@cindex intrinsics, DMod - -@noindent -@example -DMod(@var{A}, @var{P}) -@end example - -@noindent -DMod: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -@var{P}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MOD()} that is specific -to one type for @var{A}. -@xref{Mod Intrinsic}. - -@node DNInt Intrinsic -@subsubsection DNInt Intrinsic -@cindex DNInt intrinsic -@cindex intrinsics, DNInt - -@noindent -@example -DNInt(@var{A}) -@end example - -@noindent -DNInt: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ANINT()} that is specific -to one type for @var{A}. -@xref{ANInt Intrinsic}. - -@end ifset -@ifset familyF90 -@node Dot_Product Intrinsic -@subsubsection Dot_Product Intrinsic -@cindex Dot_Product intrinsic -@cindex intrinsics, Dot_Product - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Dot_Product} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DProd Intrinsic -@subsubsection DProd Intrinsic -@cindex DProd intrinsic -@cindex intrinsics, DProd - -@noindent -@example -DProd(@var{X}, @var{Y}) -@end example - -@noindent -DProd: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{DBLE(@var{X})*DBLE(@var{Y})}. - -@end ifset -@ifset familyVXT -@node DReal Intrinsic -@subsubsection DReal Intrinsic -@cindex DReal intrinsic -@cindex intrinsics, DReal - -@noindent -@example -DReal(@var{A}) -@end example - -@noindent -DReal: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{vxt}. - -@noindent -Description: - -Converts @var{A} to @code{REAL(KIND=2)}. - -If @var{A} is type @code{COMPLEX}, its real part -is converted (if necessary) to @code{REAL(KIND=2)}, -and its imaginary part is disregarded. - -Although this intrinsic is not standard Fortran, -it is a popular extension offered by many compilers -that support @code{DOUBLE COMPLEX}, since it offers -the easiest way to extract the real part of a @code{DOUBLE COMPLEX} -value without using the Fortran 90 @code{REAL()} intrinsic -in a way that produces a return value inconsistent with -the way many FORTRAN 77 compilers handle @code{REAL()} of -a @code{DOUBLE COMPLEX} value. - -@xref{RealPart Intrinsic}, for information on a GNU Fortran -intrinsic that avoids these areas of confusion. - -@xref{Dble Intrinsic}, for information on the standard FORTRAN 77 -replacement for @code{DREAL()}. - -@xref{REAL() and AIMAG() of Complex}, for more information on -this issue. - -@end ifset -@ifset familyF77 -@node DSign Intrinsic -@subsubsection DSign Intrinsic -@cindex DSign intrinsic -@cindex intrinsics, DSign - -@noindent -@example -DSign(@var{A}, @var{B}) -@end example - -@noindent -DSign: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -@var{B}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SIGN()} that is specific -to one type for @var{A} and @var{B}. -@xref{Sign Intrinsic}. - -@node DSin Intrinsic -@subsubsection DSin Intrinsic -@cindex DSin intrinsic -@cindex intrinsics, DSin - -@noindent -@example -DSin(@var{X}) -@end example - -@noindent -DSin: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SIN()} that is specific -to one type for @var{X}. -@xref{Sin Intrinsic}. - -@end ifset -@ifset familyVXT -@node DSinD Intrinsic -@subsubsection DSinD Intrinsic -@cindex DSinD intrinsic -@cindex intrinsics, DSinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DSinD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DSinH Intrinsic -@subsubsection DSinH Intrinsic -@cindex DSinH intrinsic -@cindex intrinsics, DSinH - -@noindent -@example -DSinH(@var{X}) -@end example - -@noindent -DSinH: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SINH()} that is specific -to one type for @var{X}. -@xref{SinH Intrinsic}. - -@node DSqRt Intrinsic -@subsubsection DSqRt Intrinsic -@cindex DSqRt intrinsic -@cindex intrinsics, DSqRt - -@noindent -@example -DSqRt(@var{X}) -@end example - -@noindent -DSqRt: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SQRT()} that is specific -to one type for @var{X}. -@xref{SqRt Intrinsic}. - -@node DTan Intrinsic -@subsubsection DTan Intrinsic -@cindex DTan intrinsic -@cindex intrinsics, DTan - -@noindent -@example -DTan(@var{X}) -@end example - -@noindent -DTan: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{TAN()} that is specific -to one type for @var{X}. -@xref{Tan Intrinsic}. - -@end ifset -@ifset familyVXT -@node DTanD Intrinsic -@subsubsection DTanD Intrinsic -@cindex DTanD intrinsic -@cindex intrinsics, DTanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL DTanD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node DTanH Intrinsic -@subsubsection DTanH Intrinsic -@cindex DTanH intrinsic -@cindex intrinsics, DTanH - -@noindent -@example -DTanH(@var{X}) -@end example - -@noindent -DTanH: @code{REAL(KIND=2)} function. - -@noindent -@var{X}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{TANH()} that is specific -to one type for @var{X}. -@xref{TanH Intrinsic}. - -@end ifset -@ifset familyF2U -@node Dtime Intrinsic (subroutine) -@subsubsection Dtime Intrinsic (subroutine) -@cindex Dtime intrinsic -@cindex intrinsics, Dtime - -@noindent -@example -CALL Dtime(@var{Result}, @var{TArray}) -@end example - -@noindent -@var{Result}: @code{REAL(KIND=1)}; scalar; INTENT(OUT). - -@noindent -@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Initially, return the number of seconds of runtime -since the start of the process's execution -in @var{Result}, -and the user and system components of this in @samp{@var{TArray}(1)} -and @samp{@var{TArray}(2)} respectively. -The value of @var{Result} is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}. - -Subsequent invocations of @samp{DTIME()} set values based on accumulations -since the previous invocation. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{Dtime Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Dtime Intrinsic (function) -@subsubsection Dtime Intrinsic (function) -@cindex Dtime intrinsic -@cindex intrinsics, Dtime - -@noindent -@example -Dtime(@var{TArray}) -@end example - -@noindent -Dtime: @code{REAL(KIND=1)} function. - -@noindent -@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Initially, return the number of seconds of runtime -since the start of the process's execution -as the function value, -and the user and system components of this in @samp{@var{TArray}(1)} -and @samp{@var{TArray}(2)} respectively. -The functions' value is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}. - -Subsequent invocations of @samp{DTIME()} return values accumulated since the -previous invocation. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{Dtime Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node EOShift Intrinsic -@subsubsection EOShift Intrinsic -@cindex EOShift intrinsic -@cindex intrinsics, EOShift - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL EOShift} to use this name for an -external procedure. - -@node Epsilon Intrinsic -@subsubsection Epsilon Intrinsic -@cindex Epsilon intrinsic -@cindex intrinsics, Epsilon - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Epsilon} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node ErF Intrinsic -@subsubsection ErF Intrinsic -@cindex ErF intrinsic -@cindex intrinsics, ErF - -@noindent -@example -ErF(@var{X}) -@end example - -@noindent -ErF: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the error function of @var{X}. -See @code{erf(3m)}, which provides the implementation. - -@node ErFC Intrinsic -@subsubsection ErFC Intrinsic -@cindex ErFC intrinsic -@cindex intrinsics, ErFC - -@noindent -@example -ErFC(@var{X}) -@end example - -@noindent -ErFC: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the complementary error function of @var{X}: -@samp{ERFC(R) = 1 - ERF(R)} (except that the result might be more -accurate than explicitly evaluating that formulae would give). -See @code{erfc(3m)}, which provides the implementation. - -@node ETime Intrinsic (subroutine) -@subsubsection ETime Intrinsic (subroutine) -@cindex ETime intrinsic -@cindex intrinsics, ETime - -@noindent -@example -CALL ETime(@var{Result}, @var{TArray}) -@end example - -@noindent -@var{Result}: @code{REAL(KIND=1)}; scalar; INTENT(OUT). - -@noindent -@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Return the number of seconds of runtime -since the start of the process's execution -in @var{Result}, -and the user and system components of this in @samp{@var{TArray}(1)} -and @samp{@var{TArray}(2)} respectively. -The value of @var{Result} is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{ETime Intrinsic (function)}. - -@node ETime Intrinsic (function) -@subsubsection ETime Intrinsic (function) -@cindex ETime intrinsic -@cindex intrinsics, ETime - -@noindent -@example -ETime(@var{TArray}) -@end example - -@noindent -ETime: @code{REAL(KIND=1)} function. - -@noindent -@var{TArray}: @code{REAL(KIND=1)}; DIMENSION(2); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Return the number of seconds of runtime -since the start of the process's execution -as the function value, -and the user and system components of this in @samp{@var{TArray}(1)} -and @samp{@var{TArray}(2)} respectively. -The functions' value is equal to @samp{@var{TArray}(1) + @var{TArray}(2)}. - -For information on other intrinsics with the same name: -@xref{ETime Intrinsic (subroutine)}. - -@node Exit Intrinsic -@subsubsection Exit Intrinsic -@cindex Exit intrinsic -@cindex intrinsics, Exit - -@noindent -@example -CALL Exit(@var{Status}) -@end example - -@noindent -@var{Status}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Exit the program with status @var{Status} after closing open Fortran -I/O units and otherwise behaving as @code{exit(2)}. -If @var{Status} is omitted the canonical `success' value -will be returned to the system. - -@end ifset -@ifset familyF77 -@node Exp Intrinsic -@subsubsection Exp Intrinsic -@cindex Exp intrinsic -@cindex intrinsics, Exp - -@noindent -@example -Exp(@var{X}) -@end example - -@noindent -Exp: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{@var{e}**@var{X}}, where -@var{e} is approximately 2.7182818. - -@xref{Log Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyF90 -@node Exponent Intrinsic -@subsubsection Exponent Intrinsic -@cindex Exponent intrinsic -@cindex intrinsics, Exponent - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Exponent} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Fdate Intrinsic (subroutine) -@subsubsection Fdate Intrinsic (subroutine) -@cindex Fdate intrinsic -@cindex intrinsics, Fdate - -@noindent -@example -CALL Fdate(@var{Date}) -@end example - -@noindent -@var{Date}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current date (using the same format as @code{CTIME()}) -in @var{Date}. - -Equivalent to: - -@example -CALL CTIME(@var{Date}, TIME8()) -@end example - -@xref{CTime Intrinsic (subroutine)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{Fdate Intrinsic (function)}. - -@node Fdate Intrinsic (function) -@subsubsection Fdate Intrinsic (function) -@cindex Fdate intrinsic -@cindex intrinsics, Fdate - -@noindent -@example -Fdate() -@end example - -@noindent -Fdate: @code{CHARACTER*(*)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current date (using the same format as @code{CTIME()}). - -Equivalent to: - -@example -CTIME(TIME8()) -@end example - -@xref{CTime Intrinsic (function)}. - -For information on other intrinsics with the same name: -@xref{Fdate Intrinsic (subroutine)}. - -@node FGet Intrinsic (subroutine) -@subsubsection FGet Intrinsic (subroutine) -@cindex FGet intrinsic -@cindex intrinsics, FGet - -@noindent -@example -CALL FGet(@var{C}, @var{Status}) -@end example - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Reads a single character into @var{C} in stream mode from unit 5 -(by-passing normal formatted output) using @code{getc(3)}. -Returns in -@var{Status} 0 on success, @minus{}1 on end-of-file, and the error code -from @code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FGet Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node FGet Intrinsic (function) -@subsubsection FGet Intrinsic (function) -@cindex FGet intrinsic -@cindex intrinsics, FGet - -@noindent -@example -FGet(@var{C}) -@end example - -@noindent -FGet: @code{INTEGER(KIND=1)} function. - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Reads a single character into @var{C} in stream mode from unit 5 -(by-passing normal formatted input) using @code{getc(3)}. -Returns 0 on -success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FGet Intrinsic (subroutine)}. - -@end ifset -@ifset familyF2U -@node FGetC Intrinsic (subroutine) -@subsubsection FGetC Intrinsic (subroutine) -@cindex FGetC intrinsic -@cindex intrinsics, FGetC - -@noindent -@example -CALL FGetC(@var{Unit}, @var{C}, @var{Status}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Reads a single character into @var{C} in stream mode from unit @var{Unit} -(by-passing normal formatted output) using @code{getc(3)}. -Returns in -@var{Status} 0 on success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FGetC Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node FGetC Intrinsic (function) -@subsubsection FGetC Intrinsic (function) -@cindex FGetC intrinsic -@cindex intrinsics, FGetC - -@noindent -@example -FGetC(@var{Unit}, @var{C}) -@end example - -@noindent -FGetC: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Reads a single character into @var{C} in stream mode from unit @var{Unit} -(by-passing normal formatted output) using @code{getc(3)}. -Returns 0 on -success, @minus{}1 on end-of-file, and the error code from -@code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FGetC Intrinsic (subroutine)}. - -@end ifset -@ifset familyF77 -@node Float Intrinsic -@subsubsection Float Intrinsic -@cindex Float intrinsic -@cindex intrinsics, Float - -@noindent -@example -Float(@var{A}) -@end example - -@noindent -Float: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{REAL()} that is specific -to one type for @var{A}. -@xref{Real Intrinsic}. - -@end ifset -@ifset familyVXT -@node FloatI Intrinsic -@subsubsection FloatI Intrinsic -@cindex FloatI intrinsic -@cindex intrinsics, FloatI - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL FloatI} to use this name for an -external procedure. - -@node FloatJ Intrinsic -@subsubsection FloatJ Intrinsic -@cindex FloatJ intrinsic -@cindex intrinsics, FloatJ - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL FloatJ} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Floor Intrinsic -@subsubsection Floor Intrinsic -@cindex Floor intrinsic -@cindex intrinsics, Floor - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Floor} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Flush Intrinsic -@subsubsection Flush Intrinsic -@cindex Flush intrinsic -@cindex intrinsics, Flush - -@noindent -@example -CALL Flush(@var{Unit}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Flushes Fortran unit(s) currently open for output. -Without the optional argument, all such units are flushed, -otherwise just the unit specified by @var{Unit}. - -Some non-GNU implementations of Fortran provide this intrinsic -as a library procedure that might or might not support the -(optional) @var{Unit} argument. - -@node FNum Intrinsic -@subsubsection FNum Intrinsic -@cindex FNum intrinsic -@cindex intrinsics, FNum - -@noindent -@example -FNum(@var{Unit}) -@end example - -@noindent -FNum: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the Unix file descriptor number corresponding to the open -Fortran I/O unit @var{Unit}. -This could be passed to an interface to C I/O routines. - -@node FPut Intrinsic (subroutine) -@subsubsection FPut Intrinsic (subroutine) -@cindex FPut intrinsic -@cindex intrinsics, FPut - -@noindent -@example -CALL FPut(@var{C}, @var{Status}) -@end example - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Writes the single character @var{C} in stream mode to unit 6 -(by-passing normal formatted output) using @code{putc(3)}. -Returns in -@var{Status} 0 on success, the error code from @code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FPut Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node FPut Intrinsic (function) -@subsubsection FPut Intrinsic (function) -@cindex FPut intrinsic -@cindex intrinsics, FPut - -@noindent -@example -FPut(@var{C}) -@end example - -@noindent -FPut: @code{INTEGER(KIND=1)} function. - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Writes the single character @var{C} in stream mode to unit 6 -(by-passing normal formatted output) using @code{getc(3)}. -Returns 0 on -success, the error code from @code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FPut Intrinsic (subroutine)}. - -@end ifset -@ifset familyF2U -@node FPutC Intrinsic (subroutine) -@subsubsection FPutC Intrinsic (subroutine) -@cindex FPutC intrinsic -@cindex intrinsics, FPutC - -@noindent -@example -CALL FPutC(@var{Unit}, @var{C}, @var{Status}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Writes the single character @var{Unit} in stream mode to unit 6 -(by-passing normal formatted output) using @code{putc(3)}. -Returns in -@var{C} 0 on success, the error code from @code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FPutC Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node FPutC Intrinsic (function) -@subsubsection FPutC Intrinsic (function) -@cindex FPutC intrinsic -@cindex intrinsics, FPutC - -@noindent -@example -FPutC(@var{Unit}, @var{C}) -@end example - -@noindent -FPutC: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Writes the single character @var{C} in stream mode to unit @var{Unit} -(by-passing normal formatted output) using @code{putc(3)}. -Returns 0 on -success, the error code from @code{ferror(3)} otherwise. - -Stream I/O should not be mixed with normal record-oriented (formatted or -unformatted) I/O on the same unit; the results are unpredictable. - -For information on other intrinsics with the same name: -@xref{FPutC Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Fraction Intrinsic -@subsubsection Fraction Intrinsic -@cindex Fraction intrinsic -@cindex intrinsics, Fraction - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Fraction} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node FSeek Intrinsic -@subsubsection FSeek Intrinsic -@cindex FSeek intrinsic -@cindex intrinsics, FSeek - -@noindent -@example -CALL FSeek(@var{Unit}, @var{Offset}, @var{Whence}, @var{ErrLab}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Offset}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Whence}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{ErrLab}: @samp{*@var{label}}, where @var{label} is the label -of an executable statement; OPTIONAL. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Attempts to move Fortran unit @var{Unit} to the specified -@var{Offset}: absolute offset if @var{Whence}=0; relative to the -current offset if @var{Whence}=1; relative to the end of the file if -@var{Whence}=2. -It branches to label @var{ErrLab} if @var{Unit} is -not open or if the call otherwise fails. - -@node FStat Intrinsic (subroutine) -@subsubsection FStat Intrinsic (subroutine) -@cindex FStat intrinsic -@cindex intrinsics, FStat - -@noindent -@example -CALL FStat(@var{Unit}, @var{SArray}, @var{Status}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the file open on Fortran I/O unit @var{Unit} and -places them in the array @var{SArray}. -The values in this array are -extracted from the @code{stat} structure as returned by -@code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{FStat Intrinsic (function)}. - -@node FStat Intrinsic (function) -@subsubsection FStat Intrinsic (function) -@cindex FStat intrinsic -@cindex intrinsics, FStat - -@noindent -@example -FStat(@var{Unit}, @var{SArray}) -@end example - -@noindent -FStat: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the file open on Fortran I/O unit @var{Unit} and -places them in the array @var{SArray}. -The values in this array are -extracted from the @code{stat} structure as returned by -@code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code. - -For information on other intrinsics with the same name: -@xref{FStat Intrinsic (subroutine)}. - -@node FTell Intrinsic (subroutine) -@subsubsection FTell Intrinsic (subroutine) -@cindex FTell intrinsic -@cindex intrinsics, FTell - -@noindent -@example -CALL FTell(@var{Unit}, @var{Offset}) -@end example - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Offset}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets @var{Offset} to the current offset of Fortran unit @var{Unit} -(or to @minus{}1 if @var{Unit} is not open). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{FTell Intrinsic (function)}. - -@node FTell Intrinsic (function) -@subsubsection FTell Intrinsic (function) -@cindex FTell intrinsic -@cindex intrinsics, FTell - -@noindent -@example -FTell(@var{Unit}) -@end example - -@noindent -FTell: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current offset of Fortran unit @var{Unit} -(or @minus{}1 if @var{Unit} is not open). - -For information on other intrinsics with the same name: -@xref{FTell Intrinsic (subroutine)}. - -@node GError Intrinsic -@subsubsection GError Intrinsic -@cindex GError intrinsic -@cindex intrinsics, GError - -@noindent -@example -CALL GError(@var{Message}) -@end example - -@noindent -@var{Message}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the system error message corresponding to the last system -error (C @code{errno}). - -@node GetArg Intrinsic -@subsubsection GetArg Intrinsic -@cindex GetArg intrinsic -@cindex intrinsics, GetArg - -@noindent -@example -CALL GetArg(@var{Pos}, @var{Value}) -@end example - -@noindent -@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Value}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets @var{Value} to the @var{Pos}-th command-line argument (or to all -blanks if there are fewer than @var{Value} command-line arguments); -@code{CALL GETARG(0, @var{value})} sets @var{value} to the name of the -program (on systems that support this feature). - -@xref{IArgC Intrinsic}, for information on how to get the number -of arguments. - -@node GetCWD Intrinsic (subroutine) -@subsubsection GetCWD Intrinsic (subroutine) -@cindex GetCWD intrinsic -@cindex intrinsics, GetCWD - -@noindent -@example -CALL GetCWD(@var{Name}, @var{Status}) -@end example - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Places the current working directory in @var{Name}. -If the @var{Status} argument is supplied, it contains 0 -success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{getcwd(3)} -or @code{getwd(3)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{GetCWD Intrinsic (function)}. - -@node GetCWD Intrinsic (function) -@subsubsection GetCWD Intrinsic (function) -@cindex GetCWD intrinsic -@cindex intrinsics, GetCWD - -@noindent -@example -GetCWD(@var{Name}) -@end example - -@noindent -GetCWD: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Places the current working directory in @var{Name}. -Returns 0 on -success, otherwise a non-zero error code -(@code{ENOSYS} if the system does not provide @code{getcwd(3)} -or @code{getwd(3)}). - -For information on other intrinsics with the same name: -@xref{GetCWD Intrinsic (subroutine)}. - -@node GetEnv Intrinsic -@subsubsection GetEnv Intrinsic -@cindex GetEnv intrinsic -@cindex intrinsics, GetEnv - -@noindent -@example -CALL GetEnv(@var{Name}, @var{Value}) -@end example - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Value}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets @var{Value} to the value of environment variable given by the -value of @var{Name} (@code{$name} in shell terms) or to blanks if -@code{$name} has not been set. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{Name}---otherwise, -trailing blanks in @var{Name} are ignored. - -@node GetGId Intrinsic -@subsubsection GetGId Intrinsic -@cindex GetGId intrinsic -@cindex intrinsics, GetGId - -@noindent -@example -GetGId() -@end example - -@noindent -GetGId: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the group id for the current process. - -@node GetLog Intrinsic -@subsubsection GetLog Intrinsic -@cindex GetLog intrinsic -@cindex intrinsics, GetLog - -@noindent -@example -CALL GetLog(@var{Login}) -@end example - -@noindent -@var{Login}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the login name for the process in @var{Login}. - -@emph{Caution:} On some systems, the @code{getlogin(3)} -function, which this intrinsic calls at run time, -is either not implemented or returns a null pointer. -In the latter case, this intrinsic returns blanks -in @var{Login}. - -@node GetPId Intrinsic -@subsubsection GetPId Intrinsic -@cindex GetPId intrinsic -@cindex intrinsics, GetPId - -@noindent -@example -GetPId() -@end example - -@noindent -GetPId: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the process id for the current process. - -@node GetUId Intrinsic -@subsubsection GetUId Intrinsic -@cindex GetUId intrinsic -@cindex intrinsics, GetUId - -@noindent -@example -GetUId() -@end example - -@noindent -GetUId: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the user id for the current process. - -@node GMTime Intrinsic -@subsubsection GMTime Intrinsic -@cindex GMTime intrinsic -@cindex intrinsics, GMTime - -@noindent -@example -CALL GMTime(@var{STime}, @var{TArray}) -@end example - -@noindent -@var{STime}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(9); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Given a system time value @var{STime}, fills @var{TArray} with values -extracted from it appropriate to the GMT time zone using -@code{gmtime(3)}. - -The array elements are as follows: - -@enumerate -@item -Seconds after the minute, range 0--59 or 0--61 to allow for leap -seconds - -@item -Minutes after the hour, range 0--59 - -@item -Hours past midnight, range 0--23 - -@item -Day of month, range 0--31 - -@item -Number of months since January, range 0--12 - -@item -Years since 1900 - -@item -Number of days since Sunday, range 0--6 - -@item -Days since January 1 - -@item -Daylight savings indicator: positive if daylight savings is in effect, -zero if not, and negative if the information isn't available. -@end enumerate - -@node HostNm Intrinsic (subroutine) -@subsubsection HostNm Intrinsic (subroutine) -@cindex HostNm intrinsic -@cindex intrinsics, HostNm - -@noindent -@example -CALL HostNm(@var{Name}, @var{Status}) -@end example - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Fills @var{Name} with the system's host name returned by -@code{gethostname(2)}. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{gethostname(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -On some systems (specifically SCO) it might be necessary to link the -``socket'' library if you call this routine. -Typically this means adding @samp{-lg2c -lsocket -lm} -to the @code{g77} command line when linking the program. - -For information on other intrinsics with the same name: -@xref{HostNm Intrinsic (function)}. - -@node HostNm Intrinsic (function) -@subsubsection HostNm Intrinsic (function) -@cindex HostNm intrinsic -@cindex intrinsics, HostNm - -@noindent -@example -HostNm(@var{Name}) -@end example - -@noindent -HostNm: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Fills @var{Name} with the system's host name returned by -@code{gethostname(2)}, returning 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{gethostname(2)}). - -On some systems (specifically SCO) it might be necessary to link the -``socket'' library if you call this routine. -Typically this means adding @samp{-lg2c -lsocket -lm} -to the @code{g77} command line when linking the program. - -For information on other intrinsics with the same name: -@xref{HostNm Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Huge Intrinsic -@subsubsection Huge Intrinsic -@cindex Huge intrinsic -@cindex intrinsics, Huge - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Huge} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node IAbs Intrinsic -@subsubsection IAbs Intrinsic -@cindex IAbs intrinsic -@cindex intrinsics, IAbs - -@noindent -@example -IAbs(@var{A}) -@end example - -@noindent -IAbs: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{ABS()} that is specific -to one type for @var{A}. -@xref{Abs Intrinsic}. - -@end ifset -@ifset familyASC -@node IAChar Intrinsic -@subsubsection IAChar Intrinsic -@cindex IAChar intrinsic -@cindex intrinsics, IAChar - -@noindent -@example -IAChar(@var{C}) -@end example - -@noindent -IAChar: @code{INTEGER(KIND=1)} function. - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}, @code{f90}. - -@noindent -Description: - -Returns the code for the ASCII character in the -first character position of @var{C}. - -@xref{AChar Intrinsic}, for the inverse of this function. - -@xref{IChar Intrinsic}, for the function corresponding -to the system's native character set. - -@end ifset -@ifset familyMIL -@node IAnd Intrinsic -@subsubsection IAnd Intrinsic -@cindex IAnd intrinsic -@cindex intrinsics, IAnd - -@noindent -@example -IAnd(@var{I}, @var{J}) -@end example - -@noindent -IAnd: @code{INTEGER} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns value resulting from boolean AND of -pair of bits in each of @var{I} and @var{J}. - -@end ifset -@ifset familyF2U -@node IArgC Intrinsic -@subsubsection IArgC Intrinsic -@cindex IArgC intrinsic -@cindex intrinsics, IArgC - -@noindent -@example -IArgC() -@end example - -@noindent -IArgC: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the number of command-line arguments. - -This count does not include the specification of the program -name itself. - -@end ifset -@ifset familyMIL -@node IBClr Intrinsic -@subsubsection IBClr Intrinsic -@cindex IBClr intrinsic -@cindex intrinsics, IBClr - -@noindent -@example -IBClr(@var{I}, @var{Pos}) -@end example - -@noindent -IBClr: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns the value of @var{I} with bit @var{Pos} cleared (set to -zero). -@xref{BTest Intrinsic} for information on bit positions. - -@node IBits Intrinsic -@subsubsection IBits Intrinsic -@cindex IBits intrinsic -@cindex intrinsics, IBits - -@noindent -@example -IBits(@var{I}, @var{Pos}, @var{Len}) -@end example - -@noindent -IBits: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Len}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Extracts a subfield of length @var{Len} from @var{I}, starting from -bit position @var{Pos} and extending left for @var{Len} bits. -The result is right-justified and the remaining bits are zeroed. -The value -of @samp{@var{Pos}+@var{Len}} must be less than or equal to the value -@samp{BIT_SIZE(@var{I})}. -@xref{Bit_Size Intrinsic}. - -@node IBSet Intrinsic -@subsubsection IBSet Intrinsic -@cindex IBSet intrinsic -@cindex intrinsics, IBSet - -@noindent -@example -IBSet(@var{I}, @var{Pos}) -@end example - -@noindent -IBSet: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Pos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns the value of @var{I} with bit @var{Pos} set (to one). -@xref{BTest Intrinsic} for information on bit positions. - -@end ifset -@ifset familyF77 -@node IChar Intrinsic -@subsubsection IChar Intrinsic -@cindex IChar intrinsic -@cindex intrinsics, IChar - -@noindent -@example -IChar(@var{C}) -@end example - -@noindent -IChar: @code{INTEGER(KIND=1)} function. - -@noindent -@var{C}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the code for the character in the -first character position of @var{C}. - -Because the system's native character set is used, -the correspondence between character and their codes -is not necessarily the same between GNU Fortran -implementations. - -Note that no intrinsic exists to convert a printable -character string to a numerical value. -For example, there is no intrinsic that, given -the @code{CHARACTER} value @samp{'154'}, returns an -@code{INTEGER} or @code{REAL} value with the value @samp{154}. - -Instead, you can use internal-file I/O to do this kind -of conversion. -For example: - -@smallexample -INTEGER VALUE -CHARACTER*10 STRING -STRING = '154' -READ (STRING, '(I10)'), VALUE -PRINT *, VALUE -END -@end smallexample - -The above program, when run, prints: - -@smallexample - 154 -@end smallexample - -@xref{Char Intrinsic}, for the inverse of the @code{ICHAR} function. - -@xref{IAChar Intrinsic}, for the function corresponding -to the ASCII character set. - -@end ifset -@ifset familyF2U -@node IDate Intrinsic (UNIX) -@subsubsection IDate Intrinsic (UNIX) -@cindex IDate intrinsic -@cindex intrinsics, IDate - -@noindent -@example -CALL IDate(@var{TArray}) -@end example - -@noindent -@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(3); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Fills @var{TArray} with the numerical values at the current local time -of day, month (in the range 1--12), and year in elements 1, 2, and 3, -respectively. -The year has four significant digits. - -For information on other intrinsics with the same name: -@xref{IDate Intrinsic (VXT)}. - -@end ifset -@ifset familyVXT -@node IDate Intrinsic (VXT) -@subsubsection IDate Intrinsic (VXT) -@cindex IDate intrinsic -@cindex intrinsics, IDate - -@noindent -@example -CALL IDate(@var{M}, @var{D}, @var{Y}) -@end example - -@noindent -@var{M}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). - -@noindent -@var{D}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). - -@noindent -@var{Y}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{vxt}. - -@noindent -Description: - -Returns the numerical values of the current local time. -The month (in the range 1--12) is returned in @var{M}, -the day (in the range 1--7) in @var{D}, -and the year in @var{Y} (in the range 0--99). - -This intrinsic is not recommended, due to the year 2000 approaching. - -For information on other intrinsics with the same name: -@xref{IDate Intrinsic (UNIX)}. - -@end ifset -@ifset familyF77 -@node IDiM Intrinsic -@subsubsection IDiM Intrinsic -@cindex IDiM intrinsic -@cindex intrinsics, IDiM - -@noindent -@example -IDiM(@var{X}, @var{Y}) -@end example - -@noindent -IDiM: @code{INTEGER(KIND=1)} function. - -@noindent -@var{X}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{Y}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{DIM()} that is specific -to one type for @var{X} and @var{Y}. -@xref{DiM Intrinsic}. - -@node IDInt Intrinsic -@subsubsection IDInt Intrinsic -@cindex IDInt intrinsic -@cindex intrinsics, IDInt - -@noindent -@example -IDInt(@var{A}) -@end example - -@noindent -IDInt: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{INT()} that is specific -to one type for @var{A}. -@xref{Int Intrinsic}. - -@node IDNInt Intrinsic -@subsubsection IDNInt Intrinsic -@cindex IDNInt intrinsic -@cindex intrinsics, IDNInt - -@noindent -@example -IDNInt(@var{A}) -@end example - -@noindent -IDNInt: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{NINT()} that is specific -to one type for @var{A}. -@xref{NInt Intrinsic}. - -@end ifset -@ifset familyMIL -@node IEOr Intrinsic -@subsubsection IEOr Intrinsic -@cindex IEOr intrinsic -@cindex intrinsics, IEOr - -@noindent -@example -IEOr(@var{I}, @var{J}) -@end example - -@noindent -IEOr: @code{INTEGER} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns value resulting from boolean exclusive-OR of -pair of bits in each of @var{I} and @var{J}. - -@end ifset -@ifset familyF2U -@node IErrNo Intrinsic -@subsubsection IErrNo Intrinsic -@cindex IErrNo intrinsic -@cindex intrinsics, IErrNo - -@noindent -@example -IErrNo() -@end example - -@noindent -IErrNo: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the last system error number (corresponding to the C -@code{errno}). - -@end ifset -@ifset familyF77 -@node IFix Intrinsic -@subsubsection IFix Intrinsic -@cindex IFix intrinsic -@cindex intrinsics, IFix - -@noindent -@example -IFix(@var{A}) -@end example - -@noindent -IFix: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{INT()} that is specific -to one type for @var{A}. -@xref{Int Intrinsic}. - -@end ifset -@ifset familyVXT -@node IIAbs Intrinsic -@subsubsection IIAbs Intrinsic -@cindex IIAbs intrinsic -@cindex intrinsics, IIAbs - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIAbs} to use this name for an -external procedure. - -@node IIAnd Intrinsic -@subsubsection IIAnd Intrinsic -@cindex IIAnd intrinsic -@cindex intrinsics, IIAnd - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIAnd} to use this name for an -external procedure. - -@node IIBClr Intrinsic -@subsubsection IIBClr Intrinsic -@cindex IIBClr intrinsic -@cindex intrinsics, IIBClr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIBClr} to use this name for an -external procedure. - -@node IIBits Intrinsic -@subsubsection IIBits Intrinsic -@cindex IIBits intrinsic -@cindex intrinsics, IIBits - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIBits} to use this name for an -external procedure. - -@node IIBSet Intrinsic -@subsubsection IIBSet Intrinsic -@cindex IIBSet intrinsic -@cindex intrinsics, IIBSet - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIBSet} to use this name for an -external procedure. - -@node IIDiM Intrinsic -@subsubsection IIDiM Intrinsic -@cindex IIDiM intrinsic -@cindex intrinsics, IIDiM - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIDiM} to use this name for an -external procedure. - -@node IIDInt Intrinsic -@subsubsection IIDInt Intrinsic -@cindex IIDInt intrinsic -@cindex intrinsics, IIDInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIDInt} to use this name for an -external procedure. - -@node IIDNnt Intrinsic -@subsubsection IIDNnt Intrinsic -@cindex IIDNnt intrinsic -@cindex intrinsics, IIDNnt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIDNnt} to use this name for an -external procedure. - -@node IIEOr Intrinsic -@subsubsection IIEOr Intrinsic -@cindex IIEOr intrinsic -@cindex intrinsics, IIEOr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIEOr} to use this name for an -external procedure. - -@node IIFix Intrinsic -@subsubsection IIFix Intrinsic -@cindex IIFix intrinsic -@cindex intrinsics, IIFix - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIFix} to use this name for an -external procedure. - -@node IInt Intrinsic -@subsubsection IInt Intrinsic -@cindex IInt intrinsic -@cindex intrinsics, IInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IInt} to use this name for an -external procedure. - -@node IIOr Intrinsic -@subsubsection IIOr Intrinsic -@cindex IIOr intrinsic -@cindex intrinsics, IIOr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIOr} to use this name for an -external procedure. - -@node IIQint Intrinsic -@subsubsection IIQint Intrinsic -@cindex IIQint intrinsic -@cindex intrinsics, IIQint - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIQint} to use this name for an -external procedure. - -@node IIQNnt Intrinsic -@subsubsection IIQNnt Intrinsic -@cindex IIQNnt intrinsic -@cindex intrinsics, IIQNnt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIQNnt} to use this name for an -external procedure. - -@node IIShftC Intrinsic -@subsubsection IIShftC Intrinsic -@cindex IIShftC intrinsic -@cindex intrinsics, IIShftC - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IIShftC} to use this name for an -external procedure. - -@node IISign Intrinsic -@subsubsection IISign Intrinsic -@cindex IISign intrinsic -@cindex intrinsics, IISign - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IISign} to use this name for an -external procedure. - -@end ifset -@ifset familyF2C -@node Imag Intrinsic -@subsubsection Imag Intrinsic -@cindex Imag intrinsic -@cindex intrinsics, Imag - -@noindent -@example -Imag(@var{Z}) -@end example - -@noindent -Imag: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. - -@noindent -@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -The imaginary part of @var{Z} is returned, without conversion. - -@emph{Note:} The way to do this in standard Fortran 90 -is @samp{AIMAG(@var{Z})}. -However, when, for example, @var{Z} is @code{DOUBLE COMPLEX}, -@samp{AIMAG(@var{Z})} means something different for some compilers -that are not true Fortran 90 compilers but offer some -extensions standardized by Fortran 90 (such as the -@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). - -The advantage of @code{IMAG()} is that, while not necessarily -more or less portable than @code{AIMAG()}, it is more likely to -cause a compiler that doesn't support it to produce a diagnostic -than generate incorrect code. - -@xref{REAL() and AIMAG() of Complex}, for more information. - -@end ifset -@ifset familyGNU -@node ImagPart Intrinsic -@subsubsection ImagPart Intrinsic -@cindex ImagPart intrinsic -@cindex intrinsics, ImagPart - -@noindent -@example -ImagPart(@var{Z}) -@end example - -@noindent -ImagPart: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. - -@noindent -@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{gnu}. - -@noindent -Description: - -The imaginary part of @var{Z} is returned, without conversion. - -@emph{Note:} The way to do this in standard Fortran 90 -is @samp{AIMAG(@var{Z})}. -However, when, for example, @var{Z} is @code{DOUBLE COMPLEX}, -@samp{AIMAG(@var{Z})} means something different for some compilers -that are not true Fortran 90 compilers but offer some -extensions standardized by Fortran 90 (such as the -@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). - -The advantage of @code{IMAGPART()} is that, while not necessarily -more or less portable than @code{AIMAG()}, it is more likely to -cause a compiler that doesn't support it to produce a diagnostic -than generate incorrect code. - -@xref{REAL() and AIMAG() of Complex}, for more information. - -@end ifset -@ifset familyVXT -@node IMax0 Intrinsic -@subsubsection IMax0 Intrinsic -@cindex IMax0 intrinsic -@cindex intrinsics, IMax0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IMax0} to use this name for an -external procedure. - -@node IMax1 Intrinsic -@subsubsection IMax1 Intrinsic -@cindex IMax1 intrinsic -@cindex intrinsics, IMax1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IMax1} to use this name for an -external procedure. - -@node IMin0 Intrinsic -@subsubsection IMin0 Intrinsic -@cindex IMin0 intrinsic -@cindex intrinsics, IMin0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IMin0} to use this name for an -external procedure. - -@node IMin1 Intrinsic -@subsubsection IMin1 Intrinsic -@cindex IMin1 intrinsic -@cindex intrinsics, IMin1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IMin1} to use this name for an -external procedure. - -@node IMod Intrinsic -@subsubsection IMod Intrinsic -@cindex IMod intrinsic -@cindex intrinsics, IMod - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IMod} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Index Intrinsic -@subsubsection Index Intrinsic -@cindex Index intrinsic -@cindex intrinsics, Index - -@noindent -@example -Index(@var{String}, @var{Substring}) -@end example - -@noindent -Index: @code{INTEGER(KIND=1)} function. - -@noindent -@var{String}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Substring}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the position of the start of the first occurrence of string -@var{Substring} as a substring in @var{String}, counting from one. -If @var{Substring} doesn't occur in @var{String}, zero is returned. - -@end ifset -@ifset familyVXT -@node INInt Intrinsic -@subsubsection INInt Intrinsic -@cindex INInt intrinsic -@cindex intrinsics, INInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL INInt} to use this name for an -external procedure. - -@node INot Intrinsic -@subsubsection INot Intrinsic -@cindex INot intrinsic -@cindex intrinsics, INot - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL INot} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Int Intrinsic -@subsubsection Int Intrinsic -@cindex Int intrinsic -@cindex intrinsics, Int - -@noindent -@example -Int(@var{A}) -@end example - -@noindent -Int: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=1)}. - -If @var{A} is type @code{COMPLEX}, its real part is -truncated and converted, and its imaginary part is disregarded. - -@xref{NInt Intrinsic}, for how to convert, rounded to nearest -whole number. - -@xref{AInt Intrinsic}, for how to truncate to whole number -without converting. - -@end ifset -@ifset familyGNU -@node Int2 Intrinsic -@subsubsection Int2 Intrinsic -@cindex Int2 intrinsic -@cindex intrinsics, Int2 - -@noindent -@example -Int2(@var{A}) -@end example - -@noindent -Int2: @code{INTEGER(KIND=6)} function. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{gnu}. - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=6)}. - -If @var{A} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. - -@node Int8 Intrinsic -@subsubsection Int8 Intrinsic -@cindex Int8 intrinsic -@cindex intrinsics, Int8 - -@noindent -@example -Int8(@var{A}) -@end example - -@noindent -Int8: @code{INTEGER(KIND=2)} function. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{gnu}. - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=2)}. - -If @var{A} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. - -@end ifset -@ifset familyMIL -@node IOr Intrinsic -@subsubsection IOr Intrinsic -@cindex IOr intrinsic -@cindex intrinsics, IOr - -@noindent -@example -IOr(@var{I}, @var{J}) -@end example - -@noindent -IOr: @code{INTEGER} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns value resulting from boolean OR of -pair of bits in each of @var{I} and @var{J}. - -@end ifset -@ifset familyF2U -@node IRand Intrinsic -@subsubsection IRand Intrinsic -@cindex IRand intrinsic -@cindex intrinsics, IRand - -@noindent -@example -IRand(@var{Flag}) -@end example - -@noindent -IRand: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Flag}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns a uniform quasi-random number up to a system-dependent limit. -If @var{Flag} is 0, the next number in sequence is returned; if -@var{Flag} is 1, the generator is restarted by calling the UNIX function -@samp{srand(0)}; if @var{Flag} has any other value, -it is used as a new seed with @code{srand()}. - -@xref{SRand Intrinsic}. - -@emph{Note:} As typically implemented (by the routine of the same -name in the C library), this random number generator is a very poor -one, though the BSD and GNU libraries provide a much better -implementation than the `traditional' one. -On a different system you almost certainly want to use something better. - -@node IsaTty Intrinsic -@subsubsection IsaTty Intrinsic -@cindex IsaTty intrinsic -@cindex intrinsics, IsaTty - -@noindent -@example -IsaTty(@var{Unit}) -@end example - -@noindent -IsaTty: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns @code{.TRUE.} if and only if the Fortran I/O unit -specified by @var{Unit} is connected -to a terminal device. -See @code{isatty(3)}. - -@end ifset -@ifset familyMIL -@node IShft Intrinsic -@subsubsection IShft Intrinsic -@cindex IShft intrinsic -@cindex intrinsics, IShft - -@noindent -@example -IShft(@var{I}, @var{Shift}) -@end example - -@noindent -IShft: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -All bits representing @var{I} are shifted @var{Shift} places. -@samp{@var{Shift}.GT.0} indicates a left shift, @samp{@var{Shift}.EQ.0} -indicates no shift and @samp{@var{Shift}.LT.0} indicates a right shift. -If the absolute value of the shift count is greater than -@samp{BIT_SIZE(@var{I})}, the result is undefined. -Bits shifted out from the left end or the right end are lost. -Zeros are shifted in from the opposite end. - -@xref{IShftC Intrinsic}, for the circular-shift equivalent. - -@node IShftC Intrinsic -@subsubsection IShftC Intrinsic -@cindex IShftC intrinsic -@cindex intrinsics, IShftC - -@noindent -@example -IShftC(@var{I}, @var{Shift}, @var{Size}) -@end example - -@noindent -IShftC: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Size}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -The rightmost @var{Size} bits of the argument @var{I} -are shifted circularly @var{Shift} -places, i.e.@: the bits shifted out of one end are shifted into -the opposite end. -No bits are lost. -The unshifted bits of the result are the same as -the unshifted bits of @var{I}. -The absolute value of the argument @var{Shift} -must be less than or equal to @var{Size}. -The value of @var{Size} must be greater than or equal to one and less than -or equal to @samp{BIT_SIZE(@var{I})}. - -@xref{IShft Intrinsic}, for the logical shift equivalent. - -@end ifset -@ifset familyF77 -@node ISign Intrinsic -@subsubsection ISign Intrinsic -@cindex ISign intrinsic -@cindex intrinsics, ISign - -@noindent -@example -ISign(@var{A}, @var{B}) -@end example - -@noindent -ISign: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{B}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{SIGN()} that is specific -to one type for @var{A} and @var{B}. -@xref{Sign Intrinsic}. - -@end ifset -@ifset familyF2U -@node ITime Intrinsic -@subsubsection ITime Intrinsic -@cindex ITime intrinsic -@cindex intrinsics, ITime - -@noindent -@example -CALL ITime(@var{TArray}) -@end example - -@noindent -@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(3); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current local time hour, minutes, and seconds in elements -1, 2, and 3 of @var{TArray}, respectively. - -@end ifset -@ifset familyVXT -@node IZExt Intrinsic -@subsubsection IZExt Intrinsic -@cindex IZExt intrinsic -@cindex intrinsics, IZExt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL IZExt} to use this name for an -external procedure. - -@node JIAbs Intrinsic -@subsubsection JIAbs Intrinsic -@cindex JIAbs intrinsic -@cindex intrinsics, JIAbs - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIAbs} to use this name for an -external procedure. - -@node JIAnd Intrinsic -@subsubsection JIAnd Intrinsic -@cindex JIAnd intrinsic -@cindex intrinsics, JIAnd - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIAnd} to use this name for an -external procedure. - -@node JIBClr Intrinsic -@subsubsection JIBClr Intrinsic -@cindex JIBClr intrinsic -@cindex intrinsics, JIBClr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIBClr} to use this name for an -external procedure. - -@node JIBits Intrinsic -@subsubsection JIBits Intrinsic -@cindex JIBits intrinsic -@cindex intrinsics, JIBits - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIBits} to use this name for an -external procedure. - -@node JIBSet Intrinsic -@subsubsection JIBSet Intrinsic -@cindex JIBSet intrinsic -@cindex intrinsics, JIBSet - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIBSet} to use this name for an -external procedure. - -@node JIDiM Intrinsic -@subsubsection JIDiM Intrinsic -@cindex JIDiM intrinsic -@cindex intrinsics, JIDiM - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIDiM} to use this name for an -external procedure. - -@node JIDInt Intrinsic -@subsubsection JIDInt Intrinsic -@cindex JIDInt intrinsic -@cindex intrinsics, JIDInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIDInt} to use this name for an -external procedure. - -@node JIDNnt Intrinsic -@subsubsection JIDNnt Intrinsic -@cindex JIDNnt intrinsic -@cindex intrinsics, JIDNnt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIDNnt} to use this name for an -external procedure. - -@node JIEOr Intrinsic -@subsubsection JIEOr Intrinsic -@cindex JIEOr intrinsic -@cindex intrinsics, JIEOr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIEOr} to use this name for an -external procedure. - -@node JIFix Intrinsic -@subsubsection JIFix Intrinsic -@cindex JIFix intrinsic -@cindex intrinsics, JIFix - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIFix} to use this name for an -external procedure. - -@node JInt Intrinsic -@subsubsection JInt Intrinsic -@cindex JInt intrinsic -@cindex intrinsics, JInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JInt} to use this name for an -external procedure. - -@node JIOr Intrinsic -@subsubsection JIOr Intrinsic -@cindex JIOr intrinsic -@cindex intrinsics, JIOr - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIOr} to use this name for an -external procedure. - -@node JIQint Intrinsic -@subsubsection JIQint Intrinsic -@cindex JIQint intrinsic -@cindex intrinsics, JIQint - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIQint} to use this name for an -external procedure. - -@node JIQNnt Intrinsic -@subsubsection JIQNnt Intrinsic -@cindex JIQNnt intrinsic -@cindex intrinsics, JIQNnt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIQNnt} to use this name for an -external procedure. - -@node JIShft Intrinsic -@subsubsection JIShft Intrinsic -@cindex JIShft intrinsic -@cindex intrinsics, JIShft - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIShft} to use this name for an -external procedure. - -@node JIShftC Intrinsic -@subsubsection JIShftC Intrinsic -@cindex JIShftC intrinsic -@cindex intrinsics, JIShftC - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JIShftC} to use this name for an -external procedure. - -@node JISign Intrinsic -@subsubsection JISign Intrinsic -@cindex JISign intrinsic -@cindex intrinsics, JISign - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JISign} to use this name for an -external procedure. - -@node JMax0 Intrinsic -@subsubsection JMax0 Intrinsic -@cindex JMax0 intrinsic -@cindex intrinsics, JMax0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JMax0} to use this name for an -external procedure. - -@node JMax1 Intrinsic -@subsubsection JMax1 Intrinsic -@cindex JMax1 intrinsic -@cindex intrinsics, JMax1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JMax1} to use this name for an -external procedure. - -@node JMin0 Intrinsic -@subsubsection JMin0 Intrinsic -@cindex JMin0 intrinsic -@cindex intrinsics, JMin0 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JMin0} to use this name for an -external procedure. - -@node JMin1 Intrinsic -@subsubsection JMin1 Intrinsic -@cindex JMin1 intrinsic -@cindex intrinsics, JMin1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JMin1} to use this name for an -external procedure. - -@node JMod Intrinsic -@subsubsection JMod Intrinsic -@cindex JMod intrinsic -@cindex intrinsics, JMod - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JMod} to use this name for an -external procedure. - -@node JNInt Intrinsic -@subsubsection JNInt Intrinsic -@cindex JNInt intrinsic -@cindex intrinsics, JNInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JNInt} to use this name for an -external procedure. - -@node JNot Intrinsic -@subsubsection JNot Intrinsic -@cindex JNot intrinsic -@cindex intrinsics, JNot - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JNot} to use this name for an -external procedure. - -@node JZExt Intrinsic -@subsubsection JZExt Intrinsic -@cindex JZExt intrinsic -@cindex intrinsics, JZExt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL JZExt} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Kill Intrinsic (subroutine) -@subsubsection Kill Intrinsic (subroutine) -@cindex Kill intrinsic -@cindex intrinsics, Kill - -@noindent -@example -CALL Kill(@var{Pid}, @var{Signal}, @var{Status}) -@end example - -@noindent -@var{Pid}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Signal}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sends the signal specified by @var{Signal} to the process @var{Pid}. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{kill(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{Kill Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Kill Intrinsic (function) -@subsubsection Kill Intrinsic (function) -@cindex Kill intrinsic -@cindex intrinsics, Kill - -@noindent -@example -Kill(@var{Pid}, @var{Signal}) -@end example - -@noindent -Kill: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Pid}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Signal}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Sends the signal specified by @var{Signal} to the process @var{Pid}. -Returns 0 on success or a non-zero error code. -See @code{kill(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{Kill Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Kind Intrinsic -@subsubsection Kind Intrinsic -@cindex Kind intrinsic -@cindex intrinsics, Kind - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Kind} to use this name for an -external procedure. - -@node LBound Intrinsic -@subsubsection LBound Intrinsic -@cindex LBound intrinsic -@cindex intrinsics, LBound - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL LBound} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Len Intrinsic -@subsubsection Len Intrinsic -@cindex Len intrinsic -@cindex intrinsics, Len - -@noindent -@example -Len(@var{String}) -@end example - -@noindent -Len: @code{INTEGER(KIND=1)} function. - -@noindent -@var{String}: @code{CHARACTER}; scalar. - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the length of @var{String}. - -If @var{String} is an array, the length of an element -of @var{String} is returned. - -Note that @var{String} need not be defined when this -intrinsic is invoked, since only the length, not -the content, of @var{String} is needed. - -@xref{Bit_Size Intrinsic}, for the function that determines -the size of its argument in bits. - -@end ifset -@ifset familyF90 -@node Len_Trim Intrinsic -@subsubsection Len_Trim Intrinsic -@cindex Len_Trim intrinsic -@cindex intrinsics, Len_Trim - -@noindent -@example -Len_Trim(@var{String}) -@end example - -@noindent -Len_Trim: @code{INTEGER(KIND=1)} function. - -@noindent -@var{String}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f90}. - -@noindent -Description: - -Returns the index of the last non-blank character in @var{String}. -@code{LNBLNK} and @code{LEN_TRIM} are equivalent. - -@end ifset -@ifset familyF77 -@node LGe Intrinsic -@subsubsection LGe Intrinsic -@cindex LGe intrinsic -@cindex intrinsics, LGe - -@noindent -@example -LGe(@var{String_A}, @var{String_B}) -@end example - -@noindent -LGe: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{.TRUE.} if @samp{@var{String_A}.GE.@var{String_B}}, -@samp{.FALSE.} otherwise. -@var{String_A} and @var{String_B} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{String_A} and @var{String_B} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -The lexical comparison intrinsics @code{LGe}, @code{LGt}, -@code{LLe}, and @code{LLt} differ from the corresponding -intrinsic operators @code{.GE.}, @code{.GT.}, -@code{.LE.}, @code{.LT.}. -Because the ASCII collating sequence is assumed, -the following expressions always return @samp{.TRUE.}: - -@smallexample -LGE ('0', ' ') -LGE ('A', '0') -LGE ('a', 'A') -@end smallexample - -The following related expressions do @emph{not} always -return @samp{.TRUE.}, as they are not necessarily evaluated -assuming the arguments use ASCII encoding: - -@smallexample -'0' .GE. ' ' -'A' .GE. '0' -'a' .GE. 'A' -@end smallexample - -The same difference exists -between @code{LGt} and @code{.GT.}; -between @code{LLe} and @code{.LE.}; and -between @code{LLt} and @code{.LT.}. - -@node LGt Intrinsic -@subsubsection LGt Intrinsic -@cindex LGt intrinsic -@cindex intrinsics, LGt - -@noindent -@example -LGt(@var{String_A}, @var{String_B}) -@end example - -@noindent -LGt: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{.TRUE.} if @samp{@var{String_A}.GT.@var{String_B}}, -@samp{.FALSE.} otherwise. -@var{String_A} and @var{String_B} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{String_A} and @var{String_B} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{LGT} intrinsic and the @code{.GT.} -operator. - -@end ifset -@ifset familyF2U -@node Link Intrinsic (subroutine) -@subsubsection Link Intrinsic (subroutine) -@cindex Link intrinsic -@cindex intrinsics, Link - -@noindent -@example -CALL Link(@var{Path1}, @var{Path2}, @var{Status}) -@end example - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Makes a (hard) link from file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{link(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{Link Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Link Intrinsic (function) -@subsubsection Link Intrinsic (function) -@cindex Link intrinsic -@cindex intrinsics, Link - -@noindent -@example -Link(@var{Path1}, @var{Path2}) -@end example - -@noindent -Link: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Makes a (hard) link from file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -Returns 0 on success or a non-zero error code. -See @code{link(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{Link Intrinsic (subroutine)}. - -@end ifset -@ifset familyF77 -@node LLe Intrinsic -@subsubsection LLe Intrinsic -@cindex LLe intrinsic -@cindex intrinsics, LLe - -@noindent -@example -LLe(@var{String_A}, @var{String_B}) -@end example - -@noindent -LLe: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{.TRUE.} if @samp{@var{String_A}.LE.@var{String_B}}, -@samp{.FALSE.} otherwise. -@var{String_A} and @var{String_B} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{String_A} and @var{String_B} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{LLE} intrinsic and the @code{.LE.} -operator. - -@node LLt Intrinsic -@subsubsection LLt Intrinsic -@cindex LLt intrinsic -@cindex intrinsics, LLt - -@noindent -@example -LLt(@var{String_A}, @var{String_B}) -@end example - -@noindent -LLt: @code{LOGICAL(KIND=1)} function. - -@noindent -@var{String_A}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{String_B}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{.TRUE.} if @samp{@var{String_A}.LT.@var{String_B}}, -@samp{.FALSE.} otherwise. -@var{String_A} and @var{String_B} are interpreted as containing -ASCII character codes. -If either value contains a character not in the ASCII -character set, the result is processor dependent. - -If the @var{String_A} and @var{String_B} are not the same length, -the shorter is compared as if spaces were appended to -it to form a value that has the same length as the longer. - -@xref{LGe Intrinsic}, for information on the distinction -between the @code{LLT} intrinsic and the @code{.LT.} -operator. - -@end ifset -@ifset familyF2U -@node LnBlnk Intrinsic -@subsubsection LnBlnk Intrinsic -@cindex LnBlnk intrinsic -@cindex intrinsics, LnBlnk - -@noindent -@example -LnBlnk(@var{String}) -@end example - -@noindent -LnBlnk: @code{INTEGER(KIND=1)} function. - -@noindent -@var{String}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the index of the last non-blank character in @var{String}. -@code{LNBLNK} and @code{LEN_TRIM} are equivalent. - -@node Loc Intrinsic -@subsubsection Loc Intrinsic -@cindex Loc intrinsic -@cindex intrinsics, Loc - -@noindent -@example -Loc(@var{Entity}) -@end example - -@noindent -Loc: @code{INTEGER(KIND=7)} function. - -@noindent -@var{Entity}: Any type; cannot be a constant or expression. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -The @code{LOC()} intrinsic works the -same way as the @code{%LOC()} construct. -@xref{%LOC(),,The @code{%LOC()} Construct}, for -more information. - -@end ifset -@ifset familyF77 -@node Log Intrinsic -@subsubsection Log Intrinsic -@cindex Log intrinsic -@cindex intrinsics, Log - -@noindent -@example -Log(@var{X}) -@end example - -@noindent -Log: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the natural logarithm of @var{X}, which must -be greater than zero or, if type @code{COMPLEX}, must not -be zero. - -@xref{Exp Intrinsic}, for the inverse of this function. - -@xref{Log10 Intrinsic}, for the base-10 logarithm function. - -@node Log10 Intrinsic -@subsubsection Log10 Intrinsic -@cindex Log10 intrinsic -@cindex intrinsics, Log10 - -@noindent -@example -Log10(@var{X}) -@end example - -@noindent -Log10: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the natural logarithm of @var{X}, which must -be greater than zero or, if type @code{COMPLEX}, must not -be zero. - -The inverse of this function is @samp{10. ** LOG10(@var{X})}. - -@xref{Log Intrinsic}, for the natural logarithm function. - -@end ifset -@ifset familyF90 -@node Logical Intrinsic -@subsubsection Logical Intrinsic -@cindex Logical intrinsic -@cindex intrinsics, Logical - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Logical} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Long Intrinsic -@subsubsection Long Intrinsic -@cindex Long intrinsic -@cindex intrinsics, Long - -@noindent -@example -Long(@var{A}) -@end example - -@noindent -Long: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=6)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Archaic form of @code{INT()} that is specific -to one type for @var{A}. -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. - -@end ifset -@ifset familyF2C -@node LShift Intrinsic -@subsubsection LShift Intrinsic -@cindex LShift intrinsic -@cindex intrinsics, LShift - -@noindent -@example -LShift(@var{I}, @var{Shift}) -@end example - -@noindent -LShift: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Returns @var{I} shifted to the left -@var{Shift} bits. - -Although similar to the expression -@samp{@var{I}*(2**@var{Shift})}, there -are important differences. -For example, the sign of the result is -not necessarily the same as the sign of -@var{I}. - -Currently this intrinsic is defined assuming -the underlying representation of @var{I} -is as a two's-complement integer. -It is unclear at this point whether that -definition will apply when a different -representation is involved. - -@xref{LShift Intrinsic}, for the inverse of this function. - -@xref{IShft Intrinsic}, for information -on a more widely available left-shifting -intrinsic that is also more precisely defined. - -@end ifset -@ifset familyF2U -@node LStat Intrinsic (subroutine) -@subsubsection LStat Intrinsic (subroutine) -@cindex LStat intrinsic -@cindex intrinsics, LStat - -@noindent -@example -CALL LStat(@var{File}, @var{SArray}, @var{Status}) -@end example - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the given file @var{File} and places them in the array -@var{SArray}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -If @var{File} is a symbolic link it returns data on the -link itself, so the routine is available only on systems that support -symbolic links. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{lstat(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{LStat Intrinsic (function)}. - -@node LStat Intrinsic (function) -@subsubsection LStat Intrinsic (function) -@cindex LStat intrinsic -@cindex intrinsics, LStat - -@noindent -@example -LStat(@var{File}, @var{SArray}) -@end example - -@noindent -LStat: @code{INTEGER(KIND=1)} function. - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the given file @var{File} and places them in the array -@var{SArray}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -If @var{File} is a symbolic link it returns data on the -link itself, so the routine is available only on systems that support -symbolic links. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{lstat(2)}). - -For information on other intrinsics with the same name: -@xref{LStat Intrinsic (subroutine)}. - -@node LTime Intrinsic -@subsubsection LTime Intrinsic -@cindex LTime intrinsic -@cindex intrinsics, LTime - -@noindent -@example -CALL LTime(@var{STime}, @var{TArray}) -@end example - -@noindent -@var{STime}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -@var{TArray}: @code{INTEGER(KIND=1)}; DIMENSION(9); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Given a system time value @var{STime}, fills @var{TArray} with values -extracted from it appropriate to the GMT time zone using -@code{localtime(3)}. - -The array elements are as follows: - -@enumerate -@item -Seconds after the minute, range 0--59 or 0--61 to allow for leap -seconds - -@item -Minutes after the hour, range 0--59 - -@item -Hours past midnight, range 0--23 - -@item -Day of month, range 0--31 - -@item -Number of months since January, range 0--12 - -@item -Years since 1900 - -@item -Number of days since Sunday, range 0--6 - -@item -Days since January 1 - -@item -Daylight savings indicator: positive if daylight savings is in effect, -zero if not, and negative if the information isn't available. -@end enumerate - -@end ifset -@ifset familyF90 -@node MatMul Intrinsic -@subsubsection MatMul Intrinsic -@cindex MatMul intrinsic -@cindex intrinsics, MatMul - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MatMul} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Max Intrinsic -@subsubsection Max Intrinsic -@cindex Max intrinsic -@cindex intrinsics, Max - -@noindent -@example -Max(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Max: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{A}: @code{INTEGER} or @code{REAL}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the argument with the largest value. - -@xref{Min Intrinsic}, for the opposite function. - -@node Max0 Intrinsic -@subsubsection Max0 Intrinsic -@cindex Max0 intrinsic -@cindex intrinsics, Max0 - -@noindent -@example -Max0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Max0: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MAX()} that is specific -to one type for @var{A}. -@xref{Max Intrinsic}. - -@node Max1 Intrinsic -@subsubsection Max1 Intrinsic -@cindex Max1 intrinsic -@cindex intrinsics, Max1 - -@noindent -@example -Max1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Max1: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MAX()} that is specific -to one type for @var{A} and a different return type. -@xref{Max Intrinsic}. - -@end ifset -@ifset familyF90 -@node MaxExponent Intrinsic -@subsubsection MaxExponent Intrinsic -@cindex MaxExponent intrinsic -@cindex intrinsics, MaxExponent - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MaxExponent} to use this name for an -external procedure. - -@node MaxLoc Intrinsic -@subsubsection MaxLoc Intrinsic -@cindex MaxLoc intrinsic -@cindex intrinsics, MaxLoc - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MaxLoc} to use this name for an -external procedure. - -@node MaxVal Intrinsic -@subsubsection MaxVal Intrinsic -@cindex MaxVal intrinsic -@cindex intrinsics, MaxVal - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MaxVal} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node MClock Intrinsic -@subsubsection MClock Intrinsic -@cindex MClock intrinsic -@cindex intrinsics, MClock - -@noindent -@example -MClock() -@end example - -@noindent -MClock: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the number of clock ticks since the start of the process. -Supported on systems with @code{clock(3)} (q.v.). - -This intrinsic is not fully portable, such as to systems -with 32-bit @code{INTEGER} types but supporting times -wider than 32 bits. -@xref{MClock8 Intrinsic}, for information on a -similar intrinsic that might be portable to more -GNU Fortran implementations, though to fewer -Fortran compilers. - -If the system does not support @code{clock(3)}, --1 is returned. - -@node MClock8 Intrinsic -@subsubsection MClock8 Intrinsic -@cindex MClock8 intrinsic -@cindex intrinsics, MClock8 - -@noindent -@example -MClock8() -@end example - -@noindent -MClock8: @code{INTEGER(KIND=2)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the number of clock ticks since the start of the process. -Supported on systems with @code{clock(3)} (q.v.). - -No Fortran implementations other than GNU Fortran are -known to support this intrinsic at the time of this -writing. -@xref{MClock Intrinsic}, for information on a -similar intrinsic that might be portable to more Fortran -compilers, though to fewer GNU Fortran implementations. - -If the system does not support @code{clock(3)}, --1 is returned. - -@end ifset -@ifset familyF90 -@node Merge Intrinsic -@subsubsection Merge Intrinsic -@cindex Merge intrinsic -@cindex intrinsics, Merge - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Merge} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Min Intrinsic -@subsubsection Min Intrinsic -@cindex Min intrinsic -@cindex intrinsics, Min - -@noindent -@example -Min(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Min: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{A}: @code{INTEGER} or @code{REAL}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the argument with the smallest value. - -@xref{Max Intrinsic}, for the opposite function. - -@node Min0 Intrinsic -@subsubsection Min0 Intrinsic -@cindex Min0 intrinsic -@cindex intrinsics, Min0 - -@noindent -@example -Min0(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Min0: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{INTEGER(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MIN()} that is specific -to one type for @var{A}. -@xref{Min Intrinsic}. - -@node Min1 Intrinsic -@subsubsection Min1 Intrinsic -@cindex Min1 intrinsic -@cindex intrinsics, Min1 - -@noindent -@example -Min1(@var{A}-1, @var{A}-2, @dots{}, @var{A}-n) -@end example - -@noindent -Min1: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=1)}; at least two such arguments must be provided; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{MIN()} that is specific -to one type for @var{A} and a different return type. -@xref{Min Intrinsic}. - -@end ifset -@ifset familyF90 -@node MinExponent Intrinsic -@subsubsection MinExponent Intrinsic -@cindex MinExponent intrinsic -@cindex intrinsics, MinExponent - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MinExponent} to use this name for an -external procedure. - -@node MinLoc Intrinsic -@subsubsection MinLoc Intrinsic -@cindex MinLoc intrinsic -@cindex intrinsics, MinLoc - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MinLoc} to use this name for an -external procedure. - -@node MinVal Intrinsic -@subsubsection MinVal Intrinsic -@cindex MinVal intrinsic -@cindex intrinsics, MinVal - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL MinVal} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Mod Intrinsic -@subsubsection Mod Intrinsic -@cindex Mod intrinsic -@cindex intrinsics, Mod - -@noindent -@example -Mod(@var{A}, @var{P}) -@end example - -@noindent -Mod: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{A}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -@var{P}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns remainder calculated as: - -@smallexample -@var{A} - (INT(@var{A} / @var{P}) * @var{P}) -@end smallexample - -@var{P} must not be zero. - -@end ifset -@ifset familyF90 -@node Modulo Intrinsic -@subsubsection Modulo Intrinsic -@cindex Modulo intrinsic -@cindex intrinsics, Modulo - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Modulo} to use this name for an -external procedure. - -@end ifset -@ifset familyMIL -@node MvBits Intrinsic -@subsubsection MvBits Intrinsic -@cindex MvBits intrinsic -@cindex intrinsics, MvBits - -@noindent -@example -CALL MvBits(@var{From}, @var{FromPos}, @var{Len}, @var{TO}, @var{ToPos}) -@end example - -@noindent -@var{From}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{FromPos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Len}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{TO}: @code{INTEGER} with same @samp{KIND=} value as for @var{From}; scalar; INTENT(INOUT). - -@noindent -@var{ToPos}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Moves @var{Len} bits from positions @var{FromPos} through -@samp{@var{FromPos}+@var{Len}-1} of @var{From} to positions @var{ToPos} through -@samp{@var{FromPos}+@var{Len}-1} of @var{TO}. The portion of argument -@var{TO} not affected by the movement of bits is unchanged. Arguments -@var{From} and @var{TO} are permitted to be the same numeric storage -unit. The values of @samp{@var{FromPos}+@var{Len}} and -@samp{@var{ToPos}+@var{Len}} must be less than or equal to -@samp{BIT_SIZE(@var{From})}. - -@end ifset -@ifset familyF90 -@node Nearest Intrinsic -@subsubsection Nearest Intrinsic -@cindex Nearest intrinsic -@cindex intrinsics, Nearest - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Nearest} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node NInt Intrinsic -@subsubsection NInt Intrinsic -@cindex NInt intrinsic -@cindex intrinsics, NInt - -@noindent -@example -NInt(@var{A}) -@end example - -@noindent -NInt: @code{INTEGER(KIND=1)} function. - -@noindent -@var{A}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude eliminated by rounding to the nearest whole -number and with its sign preserved, converted -to type @code{INTEGER(KIND=1)}. - -If @var{A} is type @code{COMPLEX}, its real part is -rounded and converted. - -A fractional portion exactly equal to -@samp{.5} is rounded to the whole number that -is larger in magnitude. -(Also called ``Fortran round''.) - -@xref{Int Intrinsic}, for how to convert, truncate to -whole number. - -@xref{ANInt Intrinsic}, for how to round to nearest whole number -without converting. - -@end ifset -@ifset familyMIL -@node Not Intrinsic -@subsubsection Not Intrinsic -@cindex Not intrinsic -@cindex intrinsics, Not - -@noindent -@example -Not(@var{I}) -@end example - -@noindent -Not: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{mil}, @code{f90}, @code{vxt}. - -@noindent -Description: - -Returns value resulting from boolean NOT of each bit -in @var{I}. - -@end ifset -@ifset familyF2C -@node Or Intrinsic -@subsubsection Or Intrinsic -@cindex Or intrinsic -@cindex intrinsics, Or - -@noindent -@example -Or(@var{I}, @var{J}) -@end example - -@noindent -Or: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Returns value resulting from boolean OR of -pair of bits in each of @var{I} and @var{J}. - -@end ifset -@ifset familyF90 -@node Pack Intrinsic -@subsubsection Pack Intrinsic -@cindex Pack intrinsic -@cindex intrinsics, Pack - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Pack} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node PError Intrinsic -@subsubsection PError Intrinsic -@cindex PError intrinsic -@cindex intrinsics, PError - -@noindent -@example -CALL PError(@var{String}) -@end example - -@noindent -@var{String}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Prints (on the C @code{stderr} stream) a newline-terminated error -message corresponding to the last system error. -This is prefixed by @var{String}, a colon and a space. -See @code{perror(3)}. - -@end ifset -@ifset familyF90 -@node Precision Intrinsic -@subsubsection Precision Intrinsic -@cindex Precision intrinsic -@cindex intrinsics, Precision - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Precision} to use this name for an -external procedure. - -@node Present Intrinsic -@subsubsection Present Intrinsic -@cindex Present intrinsic -@cindex intrinsics, Present - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Present} to use this name for an -external procedure. - -@node Product Intrinsic -@subsubsection Product Intrinsic -@cindex Product intrinsic -@cindex intrinsics, Product - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Product} to use this name for an -external procedure. - -@end ifset -@ifset familyVXT -@node QAbs Intrinsic -@subsubsection QAbs Intrinsic -@cindex QAbs intrinsic -@cindex intrinsics, QAbs - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QAbs} to use this name for an -external procedure. - -@node QACos Intrinsic -@subsubsection QACos Intrinsic -@cindex QACos intrinsic -@cindex intrinsics, QACos - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QACos} to use this name for an -external procedure. - -@node QACosD Intrinsic -@subsubsection QACosD Intrinsic -@cindex QACosD intrinsic -@cindex intrinsics, QACosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QACosD} to use this name for an -external procedure. - -@node QASin Intrinsic -@subsubsection QASin Intrinsic -@cindex QASin intrinsic -@cindex intrinsics, QASin - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QASin} to use this name for an -external procedure. - -@node QASinD Intrinsic -@subsubsection QASinD Intrinsic -@cindex QASinD intrinsic -@cindex intrinsics, QASinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QASinD} to use this name for an -external procedure. - -@node QATan Intrinsic -@subsubsection QATan Intrinsic -@cindex QATan intrinsic -@cindex intrinsics, QATan - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QATan} to use this name for an -external procedure. - -@node QATan2 Intrinsic -@subsubsection QATan2 Intrinsic -@cindex QATan2 intrinsic -@cindex intrinsics, QATan2 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QATan2} to use this name for an -external procedure. - -@node QATan2D Intrinsic -@subsubsection QATan2D Intrinsic -@cindex QATan2D intrinsic -@cindex intrinsics, QATan2D - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QATan2D} to use this name for an -external procedure. - -@node QATanD Intrinsic -@subsubsection QATanD Intrinsic -@cindex QATanD intrinsic -@cindex intrinsics, QATanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QATanD} to use this name for an -external procedure. - -@node QCos Intrinsic -@subsubsection QCos Intrinsic -@cindex QCos intrinsic -@cindex intrinsics, QCos - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QCos} to use this name for an -external procedure. - -@node QCosD Intrinsic -@subsubsection QCosD Intrinsic -@cindex QCosD intrinsic -@cindex intrinsics, QCosD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QCosD} to use this name for an -external procedure. - -@node QCosH Intrinsic -@subsubsection QCosH Intrinsic -@cindex QCosH intrinsic -@cindex intrinsics, QCosH - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QCosH} to use this name for an -external procedure. - -@node QDiM Intrinsic -@subsubsection QDiM Intrinsic -@cindex QDiM intrinsic -@cindex intrinsics, QDiM - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QDiM} to use this name for an -external procedure. - -@node QExp Intrinsic -@subsubsection QExp Intrinsic -@cindex QExp intrinsic -@cindex intrinsics, QExp - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QExp} to use this name for an -external procedure. - -@node QExt Intrinsic -@subsubsection QExt Intrinsic -@cindex QExt intrinsic -@cindex intrinsics, QExt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QExt} to use this name for an -external procedure. - -@node QExtD Intrinsic -@subsubsection QExtD Intrinsic -@cindex QExtD intrinsic -@cindex intrinsics, QExtD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QExtD} to use this name for an -external procedure. - -@node QFloat Intrinsic -@subsubsection QFloat Intrinsic -@cindex QFloat intrinsic -@cindex intrinsics, QFloat - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QFloat} to use this name for an -external procedure. - -@node QInt Intrinsic -@subsubsection QInt Intrinsic -@cindex QInt intrinsic -@cindex intrinsics, QInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QInt} to use this name for an -external procedure. - -@node QLog Intrinsic -@subsubsection QLog Intrinsic -@cindex QLog intrinsic -@cindex intrinsics, QLog - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QLog} to use this name for an -external procedure. - -@node QLog10 Intrinsic -@subsubsection QLog10 Intrinsic -@cindex QLog10 intrinsic -@cindex intrinsics, QLog10 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QLog10} to use this name for an -external procedure. - -@node QMax1 Intrinsic -@subsubsection QMax1 Intrinsic -@cindex QMax1 intrinsic -@cindex intrinsics, QMax1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QMax1} to use this name for an -external procedure. - -@node QMin1 Intrinsic -@subsubsection QMin1 Intrinsic -@cindex QMin1 intrinsic -@cindex intrinsics, QMin1 - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QMin1} to use this name for an -external procedure. - -@node QMod Intrinsic -@subsubsection QMod Intrinsic -@cindex QMod intrinsic -@cindex intrinsics, QMod - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QMod} to use this name for an -external procedure. - -@node QNInt Intrinsic -@subsubsection QNInt Intrinsic -@cindex QNInt intrinsic -@cindex intrinsics, QNInt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QNInt} to use this name for an -external procedure. - -@node QSin Intrinsic -@subsubsection QSin Intrinsic -@cindex QSin intrinsic -@cindex intrinsics, QSin - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QSin} to use this name for an -external procedure. - -@node QSinD Intrinsic -@subsubsection QSinD Intrinsic -@cindex QSinD intrinsic -@cindex intrinsics, QSinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QSinD} to use this name for an -external procedure. - -@node QSinH Intrinsic -@subsubsection QSinH Intrinsic -@cindex QSinH intrinsic -@cindex intrinsics, QSinH - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QSinH} to use this name for an -external procedure. - -@node QSqRt Intrinsic -@subsubsection QSqRt Intrinsic -@cindex QSqRt intrinsic -@cindex intrinsics, QSqRt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QSqRt} to use this name for an -external procedure. - -@node QTan Intrinsic -@subsubsection QTan Intrinsic -@cindex QTan intrinsic -@cindex intrinsics, QTan - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QTan} to use this name for an -external procedure. - -@node QTanD Intrinsic -@subsubsection QTanD Intrinsic -@cindex QTanD intrinsic -@cindex intrinsics, QTanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QTanD} to use this name for an -external procedure. - -@node QTanH Intrinsic -@subsubsection QTanH Intrinsic -@cindex QTanH intrinsic -@cindex intrinsics, QTanH - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL QTanH} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Radix Intrinsic -@subsubsection Radix Intrinsic -@cindex Radix intrinsic -@cindex intrinsics, Radix - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Radix} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Rand Intrinsic -@subsubsection Rand Intrinsic -@cindex Rand intrinsic -@cindex intrinsics, Rand - -@noindent -@example -Rand(@var{Flag}) -@end example - -@noindent -Rand: @code{REAL(KIND=1)} function. - -@noindent -@var{Flag}: @code{INTEGER}; OPTIONAL; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns a uniform quasi-random number between 0 and 1. -If @var{Flag} is 0, the next number in sequence is returned; if -@var{Flag} is 1, the generator is restarted by calling @samp{srand(0)}; -if @var{Flag} has any other value, it is used as a new seed with -@code{srand}. - -@xref{SRand Intrinsic}. - -@emph{Note:} As typically implemented (by the routine of the same -name in the C library), this random number generator is a very poor -one, though the BSD and GNU libraries provide a much better -implementation than the `traditional' one. -On a different system you -almost certainly want to use something better. - -@end ifset -@ifset familyF90 -@node Random_Number Intrinsic -@subsubsection Random_Number Intrinsic -@cindex Random_Number intrinsic -@cindex intrinsics, Random_Number - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Random_Number} to use this name for an -external procedure. - -@node Random_Seed Intrinsic -@subsubsection Random_Seed Intrinsic -@cindex Random_Seed intrinsic -@cindex intrinsics, Random_Seed - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Random_Seed} to use this name for an -external procedure. - -@node Range Intrinsic -@subsubsection Range Intrinsic -@cindex Range intrinsic -@cindex intrinsics, Range - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Range} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node Real Intrinsic -@subsubsection Real Intrinsic -@cindex Real intrinsic -@cindex intrinsics, Real - -@noindent -@example -Real(@var{A}) -@end example - -@noindent -Real: @code{REAL} function. -The exact type is @samp{REAL(KIND=1)} when argument @var{A} is -any type other than @code{COMPLEX}, or when it is @code{COMPLEX(KIND=1)}. -When @var{A} is any @code{COMPLEX} type other than @code{COMPLEX(KIND=1)}, -this intrinsic is valid only when used as the argument to -@code{REAL()}, as explained below. - -@noindent -@var{A}: @code{INTEGER}, @code{REAL}, or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Converts @var{A} to @code{REAL(KIND=1)}. - -Use of @code{REAL()} with a @code{COMPLEX} argument -(other than @code{COMPLEX(KIND=1)}) is restricted to the following case: - -@example -REAL(REAL(A)) -@end example - -@noindent -This expression converts the real part of A to -@code{REAL(KIND=1)}. - -@xref{RealPart Intrinsic}, for information on a GNU Fortran -intrinsic that extracts the real part of an arbitrary -@code{COMPLEX} value. - -@xref{REAL() and AIMAG() of Complex}, for more information. - -@end ifset -@ifset familyGNU -@node RealPart Intrinsic -@subsubsection RealPart Intrinsic -@cindex RealPart intrinsic -@cindex intrinsics, RealPart - -@noindent -@example -RealPart(@var{Z}) -@end example - -@noindent -RealPart: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{Z}. - -@noindent -@var{Z}: @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{gnu}. - -@noindent -Description: - -The real part of @var{Z} is returned, without conversion. - -@emph{Note:} The way to do this in standard Fortran 90 -is @samp{REAL(@var{Z})}. -However, when, for example, @var{Z} is @code{COMPLEX(KIND=2)}, -@samp{REAL(@var{Z})} means something different for some compilers -that are not true Fortran 90 compilers but offer some -extensions standardized by Fortran 90 (such as the -@code{DOUBLE COMPLEX} type, also known as @code{COMPLEX(KIND=2)}). - -The advantage of @code{REALPART()} is that, while not necessarily -more or less portable than @code{REAL()}, it is more likely to -cause a compiler that doesn't support it to produce a diagnostic -than generate incorrect code. - -@xref{REAL() and AIMAG() of Complex}, for more information. - -@end ifset -@ifset familyF2U -@node Rename Intrinsic (subroutine) -@subsubsection Rename Intrinsic (subroutine) -@cindex Rename intrinsic -@cindex intrinsics, Rename - -@noindent -@example -CALL Rename(@var{Path1}, @var{Path2}, @var{Status}) -@end example - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Renames the file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -See @code{rename(2)}. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{Rename Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Rename Intrinsic (function) -@subsubsection Rename Intrinsic (function) -@cindex Rename intrinsic -@cindex intrinsics, Rename - -@noindent -@example -Rename(@var{Path1}, @var{Path2}) -@end example - -@noindent -Rename: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Renames the file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -See @code{rename(2)}. -Returns 0 on success or a non-zero error code. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{Rename Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Repeat Intrinsic -@subsubsection Repeat Intrinsic -@cindex Repeat intrinsic -@cindex intrinsics, Repeat - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Repeat} to use this name for an -external procedure. - -@node Reshape Intrinsic -@subsubsection Reshape Intrinsic -@cindex Reshape intrinsic -@cindex intrinsics, Reshape - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Reshape} to use this name for an -external procedure. - -@node RRSpacing Intrinsic -@subsubsection RRSpacing Intrinsic -@cindex RRSpacing intrinsic -@cindex intrinsics, RRSpacing - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL RRSpacing} to use this name for an -external procedure. - -@end ifset -@ifset familyF2C -@node RShift Intrinsic -@subsubsection RShift Intrinsic -@cindex RShift intrinsic -@cindex intrinsics, RShift - -@noindent -@example -RShift(@var{I}, @var{Shift}) -@end example - -@noindent -RShift: @code{INTEGER} function, the @samp{KIND=} value of the type being that of argument @var{I}. - -@noindent -@var{I}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Shift}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Returns @var{I} shifted to the right -@var{Shift} bits. - -Although similar to the expression -@samp{@var{I}/(2**@var{Shift})}, there -are important differences. -For example, the sign of the result is -undefined. - -Currently this intrinsic is defined assuming -the underlying representation of @var{I} -is as a two's-complement integer. -It is unclear at this point whether that -definition will apply when a different -representation is involved. - -@xref{RShift Intrinsic}, for the inverse of this function. - -@xref{IShft Intrinsic}, for information -on a more widely available right-shifting -intrinsic that is also more precisely defined. - -@end ifset -@ifset familyF90 -@node Scale Intrinsic -@subsubsection Scale Intrinsic -@cindex Scale intrinsic -@cindex intrinsics, Scale - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Scale} to use this name for an -external procedure. - -@node Scan Intrinsic -@subsubsection Scan Intrinsic -@cindex Scan intrinsic -@cindex intrinsics, Scan - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Scan} to use this name for an -external procedure. - -@end ifset -@ifset familyVXT -@node Secnds Intrinsic -@subsubsection Secnds Intrinsic -@cindex Secnds intrinsic -@cindex intrinsics, Secnds - -@noindent -@example -Secnds(@var{T}) -@end example - -@noindent -Secnds: @code{REAL(KIND=1)} function. - -@noindent -@var{T}: @code{REAL(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{vxt}. - -@noindent -Description: - -Returns the local time in seconds since midnight minus the value -@var{T}. - -@end ifset -@ifset familyF2U -@node Second Intrinsic (function) -@subsubsection Second Intrinsic (function) -@cindex Second intrinsic -@cindex intrinsics, Second - -@noindent -@example -Second() -@end example - -@noindent -Second: @code{REAL(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the process's runtime in seconds---the same value as the -UNIX function @code{etime} returns. - -For information on other intrinsics with the same name: -@xref{Second Intrinsic (subroutine)}. - -@node Second Intrinsic (subroutine) -@subsubsection Second Intrinsic (subroutine) -@cindex Second intrinsic -@cindex intrinsics, Second - -@noindent -@example -CALL Second(@var{Seconds}) -@end example - -@noindent -@var{Seconds}: @code{REAL}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the process's runtime in seconds in @var{Seconds}---the same value -as the UNIX function @code{etime} returns. - -This routine is known from Cray Fortran. @xref{CPU_Time Intrinsic}, -for a standard equivalent. - -For information on other intrinsics with the same name: -@xref{Second Intrinsic (function)}. - -@end ifset -@ifset familyF90 -@node Selected_Int_Kind Intrinsic -@subsubsection Selected_Int_Kind Intrinsic -@cindex Selected_Int_Kind intrinsic -@cindex intrinsics, Selected_Int_Kind - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Selected_Int_Kind} to use this name for an -external procedure. - -@node Selected_Real_Kind Intrinsic -@subsubsection Selected_Real_Kind Intrinsic -@cindex Selected_Real_Kind intrinsic -@cindex intrinsics, Selected_Real_Kind - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Selected_Real_Kind} to use this name for an -external procedure. - -@node Set_Exponent Intrinsic -@subsubsection Set_Exponent Intrinsic -@cindex Set_Exponent intrinsic -@cindex intrinsics, Set_Exponent - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Set_Exponent} to use this name for an -external procedure. - -@node Shape Intrinsic -@subsubsection Shape Intrinsic -@cindex Shape intrinsic -@cindex intrinsics, Shape - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Shape} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node Short Intrinsic -@subsubsection Short Intrinsic -@cindex Short intrinsic -@cindex intrinsics, Short - -@noindent -@example -Short(@var{A}) -@end example - -@noindent -Short: @code{INTEGER(KIND=6)} function. - -@noindent -@var{A}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns @var{A} with the fractional portion of its -magnitude truncated and its sign preserved, converted -to type @code{INTEGER(KIND=6)}. - -If @var{A} is type @code{COMPLEX}, its real part -is truncated and converted, and its imaginary part is disgregarded. - -@xref{Int Intrinsic}. - -The precise meaning of this intrinsic might change -in a future version of the GNU Fortran language, -as more is learned about how it is used. - -@end ifset -@ifset familyF77 -@node Sign Intrinsic -@subsubsection Sign Intrinsic -@cindex Sign intrinsic -@cindex intrinsics, Sign - -@noindent -@example -Sign(@var{A}, @var{B}) -@end example - -@noindent -Sign: @code{INTEGER} or @code{REAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{A}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -@var{B}: @code{INTEGER} or @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns @samp{ABS(@var{A})*@var{s}}, where -@var{s} is +1 if @samp{@var{B}.GE.0}, --1 otherwise. - -@xref{Abs Intrinsic}, for the function that returns -the magnitude of a value. - -@end ifset -@ifset familyF2U -@node Signal Intrinsic (subroutine) -@subsubsection Signal Intrinsic (subroutine) -@cindex Signal intrinsic -@cindex intrinsics, Signal - -@noindent -@example -CALL Signal(@var{Number}, @var{Handler}, @var{Status}) -@end example - -@noindent -@var{Number}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Handler}: Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE}) -or dummy/global @code{INTEGER(KIND=1)} scalar. - -@noindent -@var{Status}: @code{INTEGER(KIND=7)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -If @var{Handler} is a an @code{EXTERNAL} routine, arranges for it to be -invoked with a single integer argument (of system-dependent length) -when signal @var{Number} occurs. -If @var{Handler} is an integer, it can be -used to turn off handling of signal @var{Number} or revert to its default -action. -See @code{signal(2)}. - -Note that @var{Handler} will be called using C conventions, -so the value of its argument in Fortran terms -Fortran terms is obtained by applying @code{%LOC()} (or @var{LOC()}) to it. - -The value returned by @code{signal(2)} is written to @var{Status}, if -that argument is supplied. -Otherwise the return value is ignored. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -@emph{Warning:} Use of the @code{libf2c} run-time library function -@samp{signal_} directly -(such as via @samp{EXTERNAL SIGNAL}) -requires use of the @code{%VAL()} construct -to pass an @code{INTEGER} value -(such as @samp{SIG_IGN} or @samp{SIG_DFL}) -for the @var{Handler} argument. - -However, while @samp{CALL SIGNAL(@var{signum}, %VAL(SIG_IGN))} -works when @samp{SIGNAL} is treated as an external procedure -(and resolves, at link time, to @code{libf2c}'s @samp{signal_} routine), -this construct is not valid when @samp{SIGNAL} is recognized -as the intrinsic of that name. - -Therefore, for maximum portability and reliability, -code such references to the @samp{SIGNAL} facility as follows: - -@smallexample -INTRINSIC SIGNAL -@dots{} -CALL SIGNAL(@var{signum}, SIG_IGN) -@end smallexample - -@code{g77} will compile such a call correctly, -while other compilers will generally either do so as well -or reject the @samp{INTRINSIC SIGNAL} statement via a diagnostic, -allowing you to take appropriate action. - -For information on other intrinsics with the same name: -@xref{Signal Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Signal Intrinsic (function) -@subsubsection Signal Intrinsic (function) -@cindex Signal intrinsic -@cindex intrinsics, Signal - -@noindent -@example -Signal(@var{Number}, @var{Handler}) -@end example - -@noindent -Signal: @code{INTEGER(KIND=7)} function. - -@noindent -@var{Number}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Handler}: Signal handler (@code{INTEGER FUNCTION} or @code{SUBROUTINE}) -or dummy/global @code{INTEGER(KIND=1)} scalar. - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -If @var{Handler} is a an @code{EXTERNAL} routine, arranges for it to be -invoked with a single integer argument (of system-dependent length) -when signal @var{Number} occurs. -If @var{Handler} is an integer, it can be -used to turn off handling of signal @var{Number} or revert to its default -action. -See @code{signal(2)}. - -Note that @var{Handler} will be called using C conventions, -so the value of its argument in Fortran terms -is obtained by applying @code{%LOC()} (or @var{LOC()}) to it. - -The value returned by @code{signal(2)} is returned. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -@emph{Warning:} If the returned value is stored in -an @code{INTEGER(KIND=1)} (default @code{INTEGER}) argument, -truncation of the original return value occurs on some systems -(such as Alphas, which have 64-bit pointers but 32-bit default integers), -with no warning issued by @code{g77} under normal circumstances. - -Therefore, the following code fragment might silently fail on -some systems: - -@smallexample -INTEGER RTN -EXTERNAL MYHNDL -RTN = SIGNAL(@var{signum}, MYHNDL) -@dots{} -! Restore original handler: -RTN = SIGNAL(@var{signum}, RTN) -@end smallexample - -The reason for the failure is that @samp{RTN} might not hold -all the information on the original handler for the signal, -thus restoring an invalid handler. -This bug could manifest itself as a spurious run-time failure -at an arbitrary point later during the program's execution, -for example. - -@emph{Warning:} Use of the @code{libf2c} run-time library function -@samp{signal_} directly -(such as via @samp{EXTERNAL SIGNAL}) -requires use of the @code{%VAL()} construct -to pass an @code{INTEGER} value -(such as @samp{SIG_IGN} or @samp{SIG_DFL}) -for the @var{Handler} argument. - -However, while @samp{RTN = SIGNAL(@var{signum}, %VAL(SIG_IGN))} -works when @samp{SIGNAL} is treated as an external procedure -(and resolves, at link time, to @code{libf2c}'s @samp{signal_} routine), -this construct is not valid when @samp{SIGNAL} is recognized -as the intrinsic of that name. - -Therefore, for maximum portability and reliability, -code such references to the @samp{SIGNAL} facility as follows: - -@smallexample -INTRINSIC SIGNAL -@dots{} -RTN = SIGNAL(@var{signum}, SIG_IGN) -@end smallexample - -@code{g77} will compile such a call correctly, -while other compilers will generally either do so as well -or reject the @samp{INTRINSIC SIGNAL} statement via a diagnostic, -allowing you to take appropriate action. - -For information on other intrinsics with the same name: -@xref{Signal Intrinsic (subroutine)}. - -@end ifset -@ifset familyF77 -@node Sin Intrinsic -@subsubsection Sin Intrinsic -@cindex Sin intrinsic -@cindex intrinsics, Sin - -@noindent -@example -Sin(@var{X}) -@end example - -@noindent -Sin: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the sine of @var{X}, an angle measured -in radians. - -@xref{ASin Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node SinD Intrinsic -@subsubsection SinD Intrinsic -@cindex SinD intrinsic -@cindex intrinsics, SinD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL SinD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node SinH Intrinsic -@subsubsection SinH Intrinsic -@cindex SinH intrinsic -@cindex intrinsics, SinH - -@noindent -@example -SinH(@var{X}) -@end example - -@noindent -SinH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the hyperbolic sine of @var{X}. - -@end ifset -@ifset familyF2U -@node Sleep Intrinsic -@subsubsection Sleep Intrinsic -@cindex Sleep intrinsic -@cindex intrinsics, Sleep - -@noindent -@example -CALL Sleep(@var{Seconds}) -@end example - -@noindent -@var{Seconds}: @code{INTEGER(KIND=1)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Causes the process to pause for @var{Seconds} seconds. -See @code{sleep(2)}. - -@end ifset -@ifset familyF77 -@node Sngl Intrinsic -@subsubsection Sngl Intrinsic -@cindex Sngl intrinsic -@cindex intrinsics, Sngl - -@noindent -@example -Sngl(@var{A}) -@end example - -@noindent -Sngl: @code{REAL(KIND=1)} function. - -@noindent -@var{A}: @code{REAL(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Archaic form of @code{REAL()} that is specific -to one type for @var{A}. -@xref{Real Intrinsic}. - -@end ifset -@ifset familyVXT -@node SnglQ Intrinsic -@subsubsection SnglQ Intrinsic -@cindex SnglQ intrinsic -@cindex intrinsics, SnglQ - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL SnglQ} to use this name for an -external procedure. - -@end ifset -@ifset familyF90 -@node Spacing Intrinsic -@subsubsection Spacing Intrinsic -@cindex Spacing intrinsic -@cindex intrinsics, Spacing - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Spacing} to use this name for an -external procedure. - -@node Spread Intrinsic -@subsubsection Spread Intrinsic -@cindex Spread intrinsic -@cindex intrinsics, Spread - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Spread} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node SqRt Intrinsic -@subsubsection SqRt Intrinsic -@cindex SqRt intrinsic -@cindex intrinsics, SqRt - -@noindent -@example -SqRt(@var{X}) -@end example - -@noindent -SqRt: @code{REAL} or @code{COMPLEX} function, the exact type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL} or @code{COMPLEX}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the square root of @var{X}, which must -not be negative. - -To calculate and represent the square root of a negative -number, complex arithmetic must be used. -For example, @samp{SQRT(COMPLEX(@var{X}))}. - -The inverse of this function is @samp{SQRT(@var{X}) * SQRT(@var{X})}. - -@end ifset -@ifset familyF2U -@node SRand Intrinsic -@subsubsection SRand Intrinsic -@cindex SRand intrinsic -@cindex intrinsics, SRand - -@noindent -@example -CALL SRand(@var{Seed}) -@end example - -@noindent -@var{Seed}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Reinitialises the generator with the seed in @var{Seed}. -@xref{IRand Intrinsic}. -@xref{Rand Intrinsic}. - -@node Stat Intrinsic (subroutine) -@subsubsection Stat Intrinsic (subroutine) -@cindex Stat intrinsic -@cindex intrinsics, Stat - -@noindent -@example -CALL Stat(@var{File}, @var{SArray}, @var{Status}) -@end example - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the given file @var{File} and places them in the array -@var{SArray}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{Stat Intrinsic (function)}. - -@node Stat Intrinsic (function) -@subsubsection Stat Intrinsic (function) -@cindex Stat intrinsic -@cindex intrinsics, Stat - -@noindent -@example -Stat(@var{File}, @var{SArray}) -@end example - -@noindent -Stat: @code{INTEGER(KIND=1)} function. - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{SArray}: @code{INTEGER(KIND=1)}; DIMENSION(13); INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Obtains data about the given file @var{File} and places them in the array -@var{SArray}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -The values in this array are extracted from the -@code{stat} structure as returned by @code{fstat(2)} q.v., as follows: - -@enumerate -@item -File mode - -@item -Inode number - -@item -ID of device containing directory entry for file - -@item -Device id (if relevant) - -@item -Number of links - -@item -Owner's uid - -@item -Owner's gid - -@item -File size (bytes) - -@item -Last access time - -@item -Last modification time - -@item -Last file status change time - -@item -Preferred I/O block size - -@item -Number of blocks allocated -@end enumerate - -Not all these elements are relevant on all systems. -If an element is not relevant, it is returned as 0. - -Returns 0 on success or a non-zero error code. - -For information on other intrinsics with the same name: -@xref{Stat Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Sum Intrinsic -@subsubsection Sum Intrinsic -@cindex Sum intrinsic -@cindex intrinsics, Sum - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Sum} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node SymLnk Intrinsic (subroutine) -@subsubsection SymLnk Intrinsic (subroutine) -@cindex SymLnk intrinsic -@cindex intrinsics, SymLnk - -@noindent -@example -CALL SymLnk(@var{Path1}, @var{Path2}, @var{Status}) -@end example - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Makes a symbolic link from file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return -(@code{ENOSYS} if the system does not provide @code{symlink(2)}). - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{SymLnk Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node SymLnk Intrinsic (function) -@subsubsection SymLnk Intrinsic (function) -@cindex SymLnk intrinsic -@cindex intrinsics, SymLnk - -@noindent -@example -SymLnk(@var{Path1}, @var{Path2}) -@end example - -@noindent -SymLnk: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Path1}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Path2}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Makes a symbolic link from file @var{Path1} to @var{Path2}. -A null character (@samp{CHAR(0)}) marks the end of -the names in @var{Path1} and @var{Path2}---otherwise, -trailing blanks in @var{Path1} and @var{Path2} are ignored. -Returns 0 on success or a non-zero error code -(@code{ENOSYS} if the system does not provide @code{symlink(2)}). - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{SymLnk Intrinsic (subroutine)}. - -@end ifset -@ifset familyF2U -@node System Intrinsic (subroutine) -@subsubsection System Intrinsic (subroutine) -@cindex System intrinsic -@cindex intrinsics, System - -@noindent -@example -CALL System(@var{Command}, @var{Status}) -@end example - -@noindent -@var{Command}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Passes the command @var{Command} to a shell (see @code{system(3)}). -If argument @var{Status} is present, it contains the value returned by -@code{system(3)}, presumably 0 if the shell command succeeded. -Note that which shell is used to invoke the command is system-dependent -and environment-dependent. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{System Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node System Intrinsic (function) -@subsubsection System Intrinsic (function) -@cindex System intrinsic -@cindex intrinsics, System - -@noindent -@example -System(@var{Command}) -@end example - -@noindent -System: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Command}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Passes the command @var{Command} to a shell (see @code{system(3)}). -Returns the value returned by -@code{system(3)}, presumably 0 if the shell command succeeded. -Note that which shell is used to invoke the command is system-dependent -and environment-dependent. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. -However, the function form can be valid in cases where the -actual side effects performed by the call are unimportant to -the application. - -For example, on a UNIX system, @samp{SAME = SYSTEM('cmp a b')} -does not perform any side effects likely to be important to the -program, so the programmer would not care if the actual system -call (and invocation of @code{cmp}) was optimized away in a situation -where the return value could be determined otherwise, or was not -actually needed (@samp{SAME} not actually referenced after the -sample assignment statement). - -For information on other intrinsics with the same name: -@xref{System Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node System_Clock Intrinsic -@subsubsection System_Clock Intrinsic -@cindex System_Clock intrinsic -@cindex intrinsics, System_Clock - -@noindent -@example -CALL System_Clock(@var{Count}, @var{Rate}, @var{Max}) -@end example - -@noindent -@var{Count}: @code{INTEGER(KIND=1)}; scalar; INTENT(OUT). - -@noindent -@var{Rate}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -@var{Max}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{f90}. - -@noindent -Description: - -Returns in @var{Count} the current value of the system clock; this is -the value returned by the UNIX function @code{times(2)} -in this implementation, but -isn't in general. -@var{Rate} is the number of clock ticks per second and -@var{Max} is the maximum value this can take, which isn't very useful -in this implementation since it's just the maximum C @code{unsigned -int} value. - -@end ifset -@ifset familyF77 -@node Tan Intrinsic -@subsubsection Tan Intrinsic -@cindex Tan intrinsic -@cindex intrinsics, Tan - -@noindent -@example -Tan(@var{X}) -@end example - -@noindent -Tan: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the tangent of @var{X}, an angle measured -in radians. - -@xref{ATan Intrinsic}, for the inverse of this function. - -@end ifset -@ifset familyVXT -@node TanD Intrinsic -@subsubsection TanD Intrinsic -@cindex TanD intrinsic -@cindex intrinsics, TanD - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL TanD} to use this name for an -external procedure. - -@end ifset -@ifset familyF77 -@node TanH Intrinsic -@subsubsection TanH Intrinsic -@cindex TanH intrinsic -@cindex intrinsics, TanH - -@noindent -@example -TanH(@var{X}) -@end example - -@noindent -TanH: @code{REAL} function, the @samp{KIND=} value of the type being that of argument @var{X}. - -@noindent -@var{X}: @code{REAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: (standard FORTRAN 77). - -@noindent -Description: - -Returns the hyperbolic tangent of @var{X}. - -@end ifset -@ifset familyF2U -@node Time Intrinsic (UNIX) -@subsubsection Time Intrinsic (UNIX) -@cindex Time intrinsic -@cindex intrinsics, Time - -@noindent -@example -Time() -@end example - -@noindent -Time: @code{INTEGER(KIND=1)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current time encoded as an integer -(in the manner of the UNIX function @code{time(3)}). -This value is suitable for passing to @code{CTIME}, -@code{GMTIME}, and @code{LTIME}. - -This intrinsic is not fully portable, such as to systems -with 32-bit @code{INTEGER} types but supporting times -wider than 32 bits. -@xref{Time8 Intrinsic}, for information on a -similar intrinsic that might be portable to more -GNU Fortran implementations, though to fewer -Fortran compilers. - -For information on other intrinsics with the same name: -@xref{Time Intrinsic (VXT)}. - -@end ifset -@ifset familyVXT -@node Time Intrinsic (VXT) -@subsubsection Time Intrinsic (VXT) -@cindex Time intrinsic -@cindex intrinsics, Time - -@noindent -@example -CALL Time(@var{Time}) -@end example - -@noindent -@var{Time}: @code{CHARACTER*8}; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{vxt}. - -@noindent -Description: - -Returns in @var{Time} a character representation of the current time as -obtained from @code{ctime(3)}. - -@xref{Fdate Intrinsic (subroutine)} for an equivalent routine. - -For information on other intrinsics with the same name: -@xref{Time Intrinsic (UNIX)}. - -@end ifset -@ifset familyF2U -@node Time8 Intrinsic -@subsubsection Time8 Intrinsic -@cindex Time8 intrinsic -@cindex intrinsics, Time8 - -@noindent -@example -Time8() -@end example - -@noindent -Time8: @code{INTEGER(KIND=2)} function. - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the current time encoded as a long integer -(in the manner of the UNIX function @code{time(3)}). -This value is suitable for passing to @code{CTIME}, -@code{GMTIME}, and @code{LTIME}. - -No Fortran implementations other than GNU Fortran are -known to support this intrinsic at the time of this -writing. -@xref{Time Intrinsic (UNIX)}, for information on a -similar intrinsic that might be portable to more Fortran -compilers, though to fewer GNU Fortran implementations. - -@end ifset -@ifset familyF90 -@node Tiny Intrinsic -@subsubsection Tiny Intrinsic -@cindex Tiny intrinsic -@cindex intrinsics, Tiny - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Tiny} to use this name for an -external procedure. - -@node Transfer Intrinsic -@subsubsection Transfer Intrinsic -@cindex Transfer intrinsic -@cindex intrinsics, Transfer - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Transfer} to use this name for an -external procedure. - -@node Transpose Intrinsic -@subsubsection Transpose Intrinsic -@cindex Transpose intrinsic -@cindex intrinsics, Transpose - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Transpose} to use this name for an -external procedure. - -@node Trim Intrinsic -@subsubsection Trim Intrinsic -@cindex Trim intrinsic -@cindex intrinsics, Trim - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Trim} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node TtyNam Intrinsic (subroutine) -@subsubsection TtyNam Intrinsic (subroutine) -@cindex TtyNam intrinsic -@cindex intrinsics, TtyNam - -@noindent -@example -CALL TtyNam(@var{Name}, @var{Unit}) -@end example - -@noindent -@var{Name}: @code{CHARACTER}; scalar; INTENT(OUT). - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets @var{Name} to the name of the terminal device open on logical unit -@var{Unit} or a blank string if @var{Unit} is not connected to a -terminal. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{TtyNam Intrinsic (function)}. - -@node TtyNam Intrinsic (function) -@subsubsection TtyNam Intrinsic (function) -@cindex TtyNam intrinsic -@cindex intrinsics, TtyNam - -@noindent -@example -TtyNam(@var{Unit}) -@end example - -@noindent -TtyNam: @code{CHARACTER*(*)} function. - -@noindent -@var{Unit}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Returns the name of the terminal device open on logical unit -@var{Unit} or a blank string if @var{Unit} is not connected to a -terminal. - -For information on other intrinsics with the same name: -@xref{TtyNam Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node UBound Intrinsic -@subsubsection UBound Intrinsic -@cindex UBound intrinsic -@cindex intrinsics, UBound - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL UBound} to use this name for an -external procedure. - -@end ifset -@ifset familyF2U -@node UMask Intrinsic (subroutine) -@subsubsection UMask Intrinsic (subroutine) -@cindex UMask intrinsic -@cindex intrinsics, UMask - -@noindent -@example -CALL UMask(@var{Mask}, @var{Old}) -@end example - -@noindent -@var{Mask}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -@var{Old}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Sets the file creation mask to @var{Mask} and returns the old value in -argument @var{Old} if it is supplied. -See @code{umask(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine. - -For information on other intrinsics with the same name: -@xref{UMask Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node UMask Intrinsic (function) -@subsubsection UMask Intrinsic (function) -@cindex UMask intrinsic -@cindex intrinsics, UMask - -@noindent -@example -UMask(@var{Mask}) -@end example - -@noindent -UMask: @code{INTEGER(KIND=1)} function. - -@noindent -@var{Mask}: @code{INTEGER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Sets the file creation mask to @var{Mask} and returns the old value. -See @code{umask(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{UMask Intrinsic (subroutine)}. - -@end ifset -@ifset familyF2U -@node Unlink Intrinsic (subroutine) -@subsubsection Unlink Intrinsic (subroutine) -@cindex Unlink intrinsic -@cindex intrinsics, Unlink - -@noindent -@example -CALL Unlink(@var{File}, @var{Status}) -@end example - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -@var{Status}: @code{INTEGER(KIND=1)}; OPTIONAL; scalar; INTENT(OUT). - -@noindent -Intrinsic groups: @code{unix}. - -@noindent -Description: - -Unlink the file @var{File}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -If the @var{Status} argument is supplied, it contains -0 on success or a non-zero error code upon return. -See @code{unlink(2)}. - -Some non-GNU implementations of Fortran provide this intrinsic as -only a function, not as a subroutine, or do not support the -(optional) @var{Status} argument. - -For information on other intrinsics with the same name: -@xref{Unlink Intrinsic (function)}. - -@end ifset -@ifset familyBADU77 -@node Unlink Intrinsic (function) -@subsubsection Unlink Intrinsic (function) -@cindex Unlink intrinsic -@cindex intrinsics, Unlink - -@noindent -@example -Unlink(@var{File}) -@end example - -@noindent -Unlink: @code{INTEGER(KIND=1)} function. - -@noindent -@var{File}: @code{CHARACTER}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{badu77}. - -@noindent -Description: - -Unlink the file @var{File}. -A null character (@samp{CHAR(0)}) marks the end of -the name in @var{File}---otherwise, -trailing blanks in @var{File} are ignored. -Returns 0 on success or a non-zero error code. -See @code{unlink(2)}. - -Due to the side effects performed by this intrinsic, the function -form is not recommended. - -For information on other intrinsics with the same name: -@xref{Unlink Intrinsic (subroutine)}. - -@end ifset -@ifset familyF90 -@node Unpack Intrinsic -@subsubsection Unpack Intrinsic -@cindex Unpack intrinsic -@cindex intrinsics, Unpack - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Unpack} to use this name for an -external procedure. - -@node Verify Intrinsic -@subsubsection Verify Intrinsic -@cindex Verify intrinsic -@cindex intrinsics, Verify - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL Verify} to use this name for an -external procedure. - -@end ifset -@ifset familyF2C -@node XOr Intrinsic -@subsubsection XOr Intrinsic -@cindex XOr intrinsic -@cindex intrinsics, XOr - -@noindent -@example -XOr(@var{I}, @var{J}) -@end example - -@noindent -XOr: @code{INTEGER} or @code{LOGICAL} function, the exact type being the result of cross-promoting the -types of all the arguments. - -@noindent -@var{I}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -@var{J}: @code{INTEGER} or @code{LOGICAL}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Returns value resulting from boolean exclusive-OR of -pair of bits in each of @var{I} and @var{J}. - -@node ZAbs Intrinsic -@subsubsection ZAbs Intrinsic -@cindex ZAbs intrinsic -@cindex intrinsics, ZAbs - -@noindent -@example -ZAbs(@var{A}) -@end example - -@noindent -ZAbs: @code{REAL(KIND=2)} function. - -@noindent -@var{A}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{ABS()} that is specific -to one type for @var{A}. -@xref{Abs Intrinsic}. - -@node ZCos Intrinsic -@subsubsection ZCos Intrinsic -@cindex ZCos intrinsic -@cindex intrinsics, ZCos - -@noindent -@example -ZCos(@var{X}) -@end example - -@noindent -ZCos: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{COS()} that is specific -to one type for @var{X}. -@xref{Cos Intrinsic}. - -@node ZExp Intrinsic -@subsubsection ZExp Intrinsic -@cindex ZExp intrinsic -@cindex intrinsics, ZExp - -@noindent -@example -ZExp(@var{X}) -@end example - -@noindent -ZExp: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{EXP()} that is specific -to one type for @var{X}. -@xref{Exp Intrinsic}. - -@end ifset -@ifset familyVXT -@node ZExt Intrinsic -@subsubsection ZExt Intrinsic -@cindex ZExt intrinsic -@cindex intrinsics, ZExt - -This intrinsic is not yet implemented. -The name is, however, reserved as an intrinsic. -Use @samp{EXTERNAL ZExt} to use this name for an -external procedure. - -@end ifset -@ifset familyF2C -@node ZLog Intrinsic -@subsubsection ZLog Intrinsic -@cindex ZLog intrinsic -@cindex intrinsics, ZLog - -@noindent -@example -ZLog(@var{X}) -@end example - -@noindent -ZLog: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{LOG()} that is specific -to one type for @var{X}. -@xref{Log Intrinsic}. - -@node ZSin Intrinsic -@subsubsection ZSin Intrinsic -@cindex ZSin intrinsic -@cindex intrinsics, ZSin - -@noindent -@example -ZSin(@var{X}) -@end example - -@noindent -ZSin: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{SIN()} that is specific -to one type for @var{X}. -@xref{Sin Intrinsic}. - -@node ZSqRt Intrinsic -@subsubsection ZSqRt Intrinsic -@cindex ZSqRt intrinsic -@cindex intrinsics, ZSqRt - -@noindent -@example -ZSqRt(@var{X}) -@end example - -@noindent -ZSqRt: @code{COMPLEX(KIND=2)} function. - -@noindent -@var{X}: @code{COMPLEX(KIND=2)}; scalar; INTENT(IN). - -@noindent -Intrinsic groups: @code{f2c}. - -@noindent -Description: - -Archaic form of @code{SQRT()} that is specific -to one type for @var{X}. -@xref{SqRt Intrinsic}. - -@end ifset diff --git a/gcc/f/intrin.c b/gcc/f/intrin.c deleted file mode 100755 index dbfbdaf..0000000 --- a/gcc/f/intrin.c +++ /dev/null @@ -1,2056 +0,0 @@ -/* intrin.c -- Recognize references to intrinsics - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -#include "proj.h" -#include "intrin.h" -#include "expr.h" -#include "info.h" -#include "src.h" -#include "symbol.h" -#include "target.h" -#include "top.h" - -struct _ffeintrin_name_ - { - char *name_uc; - char *name_lc; - char *name_ic; - ffeintrinGen generic; - ffeintrinSpec specific; - }; - -struct _ffeintrin_gen_ - { - char *name; /* Name as seen in program. */ - ffeintrinSpec specs[2]; - }; - -struct _ffeintrin_spec_ - { - char *name; /* Uppercase name as seen in source code, - lowercase if no source name, "none" if no - name at all (NONE case). */ - bool is_actualarg; /* Ok to pass as actual arg if -pedantic. */ - ffeintrinFamily family; - ffeintrinImp implementation; - }; - -struct _ffeintrin_imp_ - { - char *name; /* Name of implementation. */ -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffecomGfrt gfrt_direct; /* library routine, direct-callable form. */ - ffecomGfrt gfrt_f2c; /* library routine, f2c-callable form. */ - ffecomGfrt gfrt_gnu; /* library routine, gnu-callable form. */ -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - char *control; - }; - -static ffebad ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, - ffebld args, ffeinfoBasictype *xbt, - ffeinfoKindtype *xkt, - ffetargetCharacterSize *xsz, - bool *check_intrin, - ffelexToken t, - bool commit); -static bool ffeintrin_check_any_ (ffebld arglist); -static int ffeintrin_cmp_name_ (const void *name, const void *intrinsic); - -static struct _ffeintrin_name_ ffeintrin_names_[] -= -{ /* Alpha order. */ -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) \ - { UPPER, LOWER, MIXED, FFEINTRIN_ ## GEN, FFEINTRIN_ ## SPEC }, -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_gen_ ffeintrin_gens_[] -= -{ -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) \ - { NAME, { SPEC1, SPEC2, }, }, -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_imp_ ffeintrin_imps_[] -= -{ -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \ - { NAME, FFECOM_gfrt ## GFRTDIRECT, FFECOM_gfrt ## GFRTF2C, \ - FFECOM_gfrt ## GFRTGNU, CONTROL }, -#elif FFECOM_targetCURRENT == FFECOM_targetFFE -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \ - { NAME, CONTROL }, -#else -#error -#endif -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - -static struct _ffeintrin_spec_ ffeintrin_specs_[] -= -{ -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) \ - { NAME, CALLABLE, FAMILY, IMP, }, -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP -}; - - -static ffebad -ffeintrin_check_ (ffeintrinImp imp, ffebldOp op, - ffebld args, ffeinfoBasictype *xbt, - ffeinfoKindtype *xkt, - ffetargetCharacterSize *xsz, - bool *check_intrin, - ffelexToken t, - bool commit) -{ - char *c = ffeintrin_imps_[imp].control; - bool subr = (c[0] == '-'); - char *argc; - ffebld arg; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - ffetargetCharacterSize sz = FFETARGET_charactersizeNONE; - ffeinfoKindtype firstarg_kt; - bool need_col; - ffeinfoBasictype col_bt = FFEINFO_basictypeNONE; - ffeinfoKindtype col_kt = FFEINFO_kindtypeNONE; - int colon = (c[2] == ':') ? 2 : 3; - int argno; - - /* Check procedure type (function vs. subroutine) against - invocation. */ - - if (op == FFEBLD_opSUBRREF) - { - if (!subr) - return FFEBAD_INTRINSIC_IS_FUNC; - } - else if (op == FFEBLD_opFUNCREF) - { - if (subr) - return FFEBAD_INTRINSIC_IS_SUBR; - } - else - return FFEBAD_INTRINSIC_REF; - - /* Check the arglist for validity. */ - - if ((args != NULL) - && (ffebld_head (args) != NULL)) - firstarg_kt = ffeinfo_kindtype (ffebld_info (ffebld_head (args))); - else - firstarg_kt = FFEINFO_kindtype; - - for (argc = &c[colon + 3], - arg = args; - *argc != '\0'; - ) - { - char optional = '\0'; - char required = '\0'; - char extra = '\0'; - char basic; - char kind; - int length; - int elements; - bool lastarg_complex = FALSE; - - /* We don't do anything with keywords yet. */ - do - { - } while (*(++argc) != '='); - - ++argc; - if ((*argc == '?') - || (*argc == '!') - || (*argc == '*')) - optional = *(argc++); - if ((*argc == '+') - || (*argc == 'n') - || (*argc == 'p')) - required = *(argc++); - basic = *(argc++); - kind = *(argc++); - if (*argc == '[') - { - length = *++argc - '0'; - if (*++argc != ']') - length = 10 * length + (*(argc++) - '0'); - ++argc; - } - else - length = -1; - if (*argc == '(') - { - elements = *++argc - '0'; - if (*++argc != ')') - elements = 10 * elements + (*(argc++) - '0'); - ++argc; - } - else if (*argc == '&') - { - elements = -1; - ++argc; - } - else - elements = 0; - if ((*argc == '&') - || (*argc == 'i') - || (*argc == 'w') - || (*argc == 'x')) - extra = *(argc++); - if (*argc == ',') - ++argc; - - /* Break out of this loop only when current arg spec completely - processed. */ - - do - { - bool okay; - ffebld a; - ffeinfo i; - bool anynum; - ffeinfoBasictype abt = FFEINFO_basictypeNONE; - ffeinfoKindtype akt = FFEINFO_kindtypeNONE; - - if ((arg == NULL) - || (ffebld_head (arg) == NULL)) - { - if (required != '\0') - return FFEBAD_INTRINSIC_TOOFEW; - if (optional == '\0') - return FFEBAD_INTRINSIC_TOOFEW; - if (arg != NULL) - arg = ffebld_trail (arg); - break; /* Try next argspec. */ - } - - a = ffebld_head (arg); - i = ffebld_info (a); - anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH) - || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS); - - /* See how well the arg matches up to the spec. */ - - switch (basic) - { - case 'A': - okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER) - && ((length == -1) - || (ffeinfo_size (i) == (ffetargetCharacterSize) length)); - break; - - case 'C': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX); - abt = FFEINFO_basictypeCOMPLEX; - break; - - case 'I': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER); - abt = FFEINFO_basictypeINTEGER; - break; - - case 'L': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL); - abt = FFEINFO_basictypeLOGICAL; - break; - - case 'R': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - abt = FFEINFO_basictypeREAL; - break; - - case 'B': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL); - break; - - case 'F': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'N': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX) - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'S': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'g': - okay = ((ffebld_op (a) == FFEBLD_opLABTER) - || (ffebld_op (a) == FFEBLD_opLABTOK)); - elements = -1; - extra = '-'; - break; - - case 's': - okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE) - && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE) - && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE)) - || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT) - && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION)) - || (ffeinfo_kind (i) == FFEINFO_kindNONE)) - && ((ffeinfo_where (i) == FFEINFO_whereDUMMY) - || (ffeinfo_where (i) == FFEINFO_whereGLOBAL))) - || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - && (ffeinfo_kind (i) == FFEINFO_kindENTITY))); - elements = -1; - extra = '-'; - break; - - case '-': - default: - okay = TRUE; - break; - } - - switch (kind) - { - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - akt = (kind - '0'); - if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL)) - { - switch (akt) - { /* Translate to internal kinds for now! */ - default: - break; - - case 2: - akt = 4; - break; - - case 3: - akt = 2; - break; - - case 4: - akt = 5; - break; - - case 6: - akt = 3; - break; - - case 7: - akt = ffecom_pointer_kind (); - break; - } - } - okay &= anynum || (ffeinfo_kindtype (i) == akt); - break; - - case 'A': - okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt); - akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE - : firstarg_kt; - break; - - case '*': - default: - break; - } - - switch (elements) - { - ffebld b; - - case -1: - break; - - case 0: - if (ffeinfo_rank (i) != 0) - okay = FALSE; - break; - - default: - if ((ffeinfo_rank (i) != 1) - || (ffebld_op (a) != FFEBLD_opSYMTER) - || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL) - || (ffebld_op (b) != FFEBLD_opCONTER) - || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT) - || (ffebld_constant_integer1 (ffebld_conter (b)) != elements)) - okay = FALSE; - break; - } - - switch (extra) - { - case '&': - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || ((ffebld_op (a) != FFEBLD_opSYMTER) - && (ffebld_op (a) != FFEBLD_opSUBSTR) - && (ffebld_op (a) != FFEBLD_opARRAYREF))) - okay = FALSE; - break; - - case 'w': - case 'x': - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || ((ffebld_op (a) != FFEBLD_opSYMTER) - && (ffebld_op (a) != FFEBLD_opARRAYREF) - && (ffebld_op (a) != FFEBLD_opSUBSTR))) - okay = FALSE; - break; - - case '-': - case 'i': - break; - - default: - if (ffeinfo_kind (i) != FFEINFO_kindENTITY) - okay = FALSE; - break; - } - - if ((optional == '!') - && lastarg_complex) - okay = FALSE; - - if (!okay) - { - /* If it wasn't optional, it's an error, - else maybe it could match a later argspec. */ - if (optional == '\0') - return FFEBAD_INTRINSIC_REF; - break; /* Try next argspec. */ - } - - lastarg_complex - = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX); - - if (anynum) - { - /* If we know dummy arg type, convert to that now. */ - - if ((abt != FFEINFO_basictypeNONE) - && (akt != FFEINFO_kindtypeNONE) - && commit) - { - /* We have a known type, convert hollerith/typeless - to it. */ - - a = ffeexpr_convert (a, t, NULL, - abt, akt, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - ffebld_set_head (arg, a); - } - } - - arg = ffebld_trail (arg); /* Arg accepted, now move on. */ - - if (optional == '*') - continue; /* Go ahead and try another arg. */ - if (required == '\0') - break; - if ((required == 'n') - || (required == '+')) - { - optional = '*'; - required = '\0'; - } - else if (required == 'p') - required = 'n'; - } while (TRUE); - } - - if (arg != NULL) - return FFEBAD_INTRINSIC_TOOMANY; - - /* Set up the initial type for the return value of the function. */ - - need_col = FALSE; - switch (c[0]) - { - case 'A': - bt = FFEINFO_basictypeCHARACTER; - sz = (c[2] == '*') ? FFETARGET_charactersizeNONE : 1; - break; - - case 'C': - bt = FFEINFO_basictypeCOMPLEX; - break; - - case 'I': - bt = FFEINFO_basictypeINTEGER; - break; - - case 'L': - bt = FFEINFO_basictypeLOGICAL; - break; - - case 'R': - bt = FFEINFO_basictypeREAL; - break; - - case 'B': - case 'F': - case 'N': - case 'S': - need_col = TRUE; - /* Fall through. */ - case '-': - default: - bt = FFEINFO_basictypeNONE; - break; - } - - switch (c[1]) - { - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - kt = (c[1] - '0'); - if ((bt == FFEINFO_basictypeINTEGER) - || (bt == FFEINFO_basictypeLOGICAL)) - { - switch (kt) - { /* Translate to internal kinds for now! */ - default: - break; - - case 2: - kt = 4; - break; - - case 3: - kt = 2; - break; - - case 4: - kt = 5; - break; - - case 6: - kt = 3; - break; - - case 7: - kt = ffecom_pointer_kind (); - break; - } - } - break; - - case 'C': - if (ffe_is_90 ()) - need_col = TRUE; - kt = 1; - break; - - case '=': - need_col = TRUE; - /* Fall through. */ - case '-': - default: - kt = FFEINFO_kindtypeNONE; - break; - } - - /* Determine collective type of COL, if there is one. */ - - if (need_col || c[colon + 1] != '-') - { - bool okay = TRUE; - bool have_anynum = FALSE; - - for (arg = args; - arg != NULL; - arg = (c[colon + 1] == '*') ? ffebld_trail (arg) : NULL) - { - ffebld a = ffebld_head (arg); - ffeinfo i; - bool anynum; - - if (a == NULL) - continue; - i = ffebld_info (a); - - anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH) - || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS); - if (anynum) - { - have_anynum = TRUE; - continue; - } - - if ((col_bt == FFEINFO_basictypeNONE) - && (col_kt == FFEINFO_kindtypeNONE)) - { - col_bt = ffeinfo_basictype (i); - col_kt = ffeinfo_kindtype (i); - } - else - { - ffeexpr_type_combine (&col_bt, &col_kt, - col_bt, col_kt, - ffeinfo_basictype (i), - ffeinfo_kindtype (i), - NULL); - if ((col_bt == FFEINFO_basictypeNONE) - || (col_kt == FFEINFO_kindtypeNONE)) - return FFEBAD_INTRINSIC_REF; - } - } - - if (have_anynum - && ((col_bt == FFEINFO_basictypeNONE) - || (col_kt == FFEINFO_kindtypeNONE))) - { - /* No type, but have hollerith/typeless. Use type of return - value to determine type of COL. */ - - switch (c[0]) - { - case 'A': - return FFEBAD_INTRINSIC_REF; - - case 'B': - case 'I': - case 'L': - if ((col_bt != FFEINFO_basictypeNONE) - && (col_bt != FFEINFO_basictypeINTEGER)) - return FFEBAD_INTRINSIC_REF; - /* Fall through. */ - case 'N': - case 'S': - case '-': - default: - col_bt = FFEINFO_basictypeINTEGER; - col_kt = FFEINFO_kindtypeINTEGER1; - break; - - case 'C': - if ((col_bt != FFEINFO_basictypeNONE) - && (col_bt != FFEINFO_basictypeCOMPLEX)) - return FFEBAD_INTRINSIC_REF; - col_bt = FFEINFO_basictypeCOMPLEX; - col_kt = FFEINFO_kindtypeREAL1; - break; - - case 'R': - if ((col_bt != FFEINFO_basictypeNONE) - && (col_bt != FFEINFO_basictypeREAL)) - return FFEBAD_INTRINSIC_REF; - /* Fall through. */ - case 'F': - col_bt = FFEINFO_basictypeREAL; - col_kt = FFEINFO_kindtypeREAL1; - break; - } - } - - switch (c[0]) - { - case 'B': - okay = (col_bt == FFEINFO_basictypeINTEGER) - || (col_bt == FFEINFO_basictypeLOGICAL); - if (need_col) - bt = col_bt; - break; - - case 'F': - okay = (col_bt == FFEINFO_basictypeCOMPLEX) - || (col_bt == FFEINFO_basictypeREAL); - if (need_col) - bt = col_bt; - break; - - case 'N': - okay = (col_bt == FFEINFO_basictypeCOMPLEX) - || (col_bt == FFEINFO_basictypeINTEGER) - || (col_bt == FFEINFO_basictypeREAL); - if (need_col) - bt = col_bt; - break; - - case 'S': - okay = (col_bt == FFEINFO_basictypeINTEGER) - || (col_bt == FFEINFO_basictypeREAL) - || (col_bt == FFEINFO_basictypeCOMPLEX); - if (need_col) - bt = ((col_bt != FFEINFO_basictypeCOMPLEX) ? col_bt - : FFEINFO_basictypeREAL); - break; - } - - switch (c[1]) - { - case '=': - if (need_col) - kt = col_kt; - break; - - case 'C': - if (col_bt == FFEINFO_basictypeCOMPLEX) - { - if (col_kt != FFEINFO_kindtypeREALDEFAULT) - *check_intrin = TRUE; - if (need_col) - kt = col_kt; - } - break; - } - - if (!okay) - return FFEBAD_INTRINSIC_REF; - } - - /* Now, convert args in the arglist to the final type of the COL. */ - - for (argno = 0, argc = &c[colon + 3], - arg = args; - *argc != '\0'; - ++argno) - { - char optional = '\0'; - char required = '\0'; - char extra = '\0'; - char basic; - char kind; - int length; - int elements; - bool lastarg_complex = FALSE; - - /* We don't do anything with keywords yet. */ - do - { - } while (*(++argc) != '='); - - ++argc; - if ((*argc == '?') - || (*argc == '!') - || (*argc == '*')) - optional = *(argc++); - if ((*argc == '+') - || (*argc == 'n') - || (*argc == 'p')) - required = *(argc++); - basic = *(argc++); - kind = *(argc++); - if (*argc == '[') - { - length = *++argc - '0'; - if (*++argc != ']') - length = 10 * length + (*(argc++) - '0'); - ++argc; - } - else - length = -1; - if (*argc == '(') - { - elements = *++argc - '0'; - if (*++argc != ')') - elements = 10 * elements + (*(argc++) - '0'); - ++argc; - } - else if (*argc == '&') - { - elements = -1; - ++argc; - } - else - elements = 0; - if ((*argc == '&') - || (*argc == 'i') - || (*argc == 'w') - || (*argc == 'x')) - extra = *(argc++); - if (*argc == ',') - ++argc; - - /* Break out of this loop only when current arg spec completely - processed. */ - - do - { - bool okay; - ffebld a; - ffeinfo i; - bool anynum; - ffeinfoBasictype abt = FFEINFO_basictypeNONE; - ffeinfoKindtype akt = FFEINFO_kindtypeNONE; - - if ((arg == NULL) - || (ffebld_head (arg) == NULL)) - { - if (arg != NULL) - arg = ffebld_trail (arg); - break; /* Try next argspec. */ - } - - a = ffebld_head (arg); - i = ffebld_info (a); - anynum = (ffeinfo_basictype (i) == FFEINFO_basictypeHOLLERITH) - || (ffeinfo_basictype (i) == FFEINFO_basictypeTYPELESS); - - /* Determine what the default type for anynum would be. */ - - if (anynum) - { - switch (c[colon + 1]) - { - case '-': - break; - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (argno != (c[colon + 1] - '0')) - break; - case '*': - abt = col_bt; - akt = col_kt; - break; - } - } - - /* Again, match arg up to the spec. We go through all of - this again to properly follow the contour of optional - arguments. Probably this level of flexibility is not - needed, perhaps it's even downright naughty. */ - - switch (basic) - { - case 'A': - okay = (ffeinfo_basictype (i) == FFEINFO_basictypeCHARACTER) - && ((length == -1) - || (ffeinfo_size (i) == (ffetargetCharacterSize) length)); - break; - - case 'C': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX); - abt = FFEINFO_basictypeCOMPLEX; - break; - - case 'I': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER); - abt = FFEINFO_basictypeINTEGER; - break; - - case 'L': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL); - abt = FFEINFO_basictypeLOGICAL; - break; - - case 'R': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - abt = FFEINFO_basictypeREAL; - break; - - case 'B': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL); - break; - - case 'F': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'N': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX) - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'S': - okay = anynum - || (ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeREAL); - break; - - case 'g': - okay = ((ffebld_op (a) == FFEBLD_opLABTER) - || (ffebld_op (a) == FFEBLD_opLABTOK)); - elements = -1; - extra = '-'; - break; - - case 's': - okay = (((((ffeinfo_basictype (i) == FFEINFO_basictypeNONE) - && (ffeinfo_kindtype (i) == FFEINFO_kindtypeNONE) - && (ffeinfo_kind (i) == FFEINFO_kindSUBROUTINE)) - || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - && (ffeinfo_kindtype (i) == FFEINFO_kindtypeINTEGERDEFAULT) - && (ffeinfo_kind (i) == FFEINFO_kindFUNCTION)) - || (ffeinfo_kind (i) == FFEINFO_kindNONE)) - && ((ffeinfo_where (i) == FFEINFO_whereDUMMY) - || (ffeinfo_where (i) == FFEINFO_whereGLOBAL))) - || ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - && (ffeinfo_kind (i) == FFEINFO_kindENTITY))); - elements = -1; - extra = '-'; - break; - - case '-': - default: - okay = TRUE; - break; - } - - switch (kind) - { - case '1': case '2': case '3': case '4': case '5': - case '6': case '7': case '8': case '9': - akt = (kind - '0'); - if ((ffeinfo_basictype (i) == FFEINFO_basictypeINTEGER) - || (ffeinfo_basictype (i) == FFEINFO_basictypeLOGICAL)) - { - switch (akt) - { /* Translate to internal kinds for now! */ - default: - break; - - case 2: - akt = 4; - break; - - case 3: - akt = 2; - break; - - case 4: - akt = 5; - break; - - case 6: - akt = 3; - break; - - case 7: - akt = ffecom_pointer_kind (); - break; - } - } - okay &= anynum || (ffeinfo_kindtype (i) == akt); - break; - - case 'A': - okay &= anynum || (ffeinfo_kindtype (i) == firstarg_kt); - akt = (firstarg_kt == FFEINFO_kindtype) ? FFEINFO_kindtypeNONE - : firstarg_kt; - break; - - case '*': - default: - break; - } - - switch (elements) - { - ffebld b; - - case -1: - break; - - case 0: - if (ffeinfo_rank (i) != 0) - okay = FALSE; - break; - - default: - if ((ffeinfo_rank (i) != 1) - || (ffebld_op (a) != FFEBLD_opSYMTER) - || ((b = ffesymbol_arraysize (ffebld_symter (a))) == NULL) - || (ffebld_op (b) != FFEBLD_opCONTER) - || (ffeinfo_basictype (ffebld_info (b)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (b)) != FFEINFO_kindtypeINTEGERDEFAULT) - || (ffebld_constant_integer1 (ffebld_conter (b)) != elements)) - okay = FALSE; - break; - } - - switch (extra) - { - case '&': - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || ((ffebld_op (a) != FFEBLD_opSYMTER) - && (ffebld_op (a) != FFEBLD_opSUBSTR) - && (ffebld_op (a) != FFEBLD_opARRAYREF))) - okay = FALSE; - break; - - case 'w': - case 'x': - if ((ffeinfo_kind (i) != FFEINFO_kindENTITY) - || ((ffebld_op (a) != FFEBLD_opSYMTER) - && (ffebld_op (a) != FFEBLD_opARRAYREF) - && (ffebld_op (a) != FFEBLD_opSUBSTR))) - okay = FALSE; - break; - - case '-': - case 'i': - break; - - default: - if (ffeinfo_kind (i) != FFEINFO_kindENTITY) - okay = FALSE; - break; - } - - if ((optional == '!') - && lastarg_complex) - okay = FALSE; - - if (!okay) - { - /* If it wasn't optional, it's an error, - else maybe it could match a later argspec. */ - if (optional == '\0') - return FFEBAD_INTRINSIC_REF; - break; /* Try next argspec. */ - } - - lastarg_complex - = (ffeinfo_basictype (i) == FFEINFO_basictypeCOMPLEX); - - if (anynum && commit) - { - /* If we know dummy arg type, convert to that now. */ - - if (abt == FFEINFO_basictypeNONE) - abt = FFEINFO_basictypeINTEGER; - if (akt == FFEINFO_kindtypeNONE) - akt = FFEINFO_kindtypeINTEGER1; - - /* We have a known type, convert hollerith/typeless to it. */ - - a = ffeexpr_convert (a, t, NULL, - abt, akt, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - ffebld_set_head (arg, a); - } - else if ((c[colon + 1] == '*') && commit) - { - /* This is where we promote types to the consensus - type for the COL. Maybe this is where -fpedantic - should issue a warning as well. */ - - a = ffeexpr_convert (a, t, NULL, - col_bt, col_kt, 0, - ffeinfo_size (i), - FFEEXPR_contextLET); - ffebld_set_head (arg, a); - } - - arg = ffebld_trail (arg); /* Arg accepted, now move on. */ - - if (optional == '*') - continue; /* Go ahead and try another arg. */ - if (required == '\0') - break; - if ((required == 'n') - || (required == '+')) - { - optional = '*'; - required = '\0'; - } - else if (required == 'p') - required = 'n'; - } while (TRUE); - } - - *xbt = bt; - *xkt = kt; - *xsz = sz; - return FFEBAD; -} - -static bool -ffeintrin_check_any_ (ffebld arglist) -{ - ffebld item; - - for (; arglist != NULL; arglist = ffebld_trail (arglist)) - { - item = ffebld_head (arglist); - if ((item != NULL) - && (ffebld_op (item) == FFEBLD_opANY)) - return TRUE; - } - - return FALSE; -} - -/* Compare name to intrinsic's name. Uses strcmp on arguments' names. */ - -static int -ffeintrin_cmp_name_ (const void *name, const void *intrinsic) -{ - char *uc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_uc; - char *lc = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_lc; - char *ic = (char *) ((struct _ffeintrin_name_ *) intrinsic)->name_ic; - - return ffesrc_strcmp_2c (ffe_case_intrin (), name, uc, lc, ic); -} - -/* Return basic type of intrinsic implementation, based on its - run-time implementation *only*. (This is used only when - the type of an intrinsic name is needed without having a - list of arguments, i.e. an interface signature, such as when - passing the intrinsic itself, or really the run-time-library - function, as an argument.) - - If there's no eligible intrinsic implementation, there must be - a bug somewhere else; no such reference should have been permitted - to go this far. (Well, this might be wrong.) */ - -ffeinfoBasictype -ffeintrin_basictype (ffeintrinSpec spec) -{ - ffeintrinImp imp; - ffecomGfrt gfrt; - - assert (spec < FFEINTRIN_spec); - imp = ffeintrin_specs_[spec].implementation; - assert (imp < FFEINTRIN_imp); - - if (ffe_is_f2c ()) - gfrt = ffeintrin_imps_[imp].gfrt_f2c; - else - gfrt = ffeintrin_imps_[imp].gfrt_gnu; - - assert (gfrt != FFECOM_gfrt); - - return ffecom_gfrt_basictype (gfrt); -} - -/* Return family to which specific intrinsic belongs. */ - -ffeintrinFamily -ffeintrin_family (ffeintrinSpec spec) -{ - if (spec >= FFEINTRIN_spec) - return FALSE; - return ffeintrin_specs_[spec].family; -} - -/* Check and fill in info on func/subr ref node. - - ffebld expr; // FUNCREF or SUBRREF with no info (caller - // gets it from the modified info structure). - ffeinfo info; // Already filled in, will be overwritten. - ffelexToken token; // Used for error message. - ffeintrin_fulfill_generic (&expr, &info, token); - - Based on the generic id, figure out which specific procedure is meant and - pick that one. Else return an error, a la _specific. */ - -void -ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t) -{ - ffebld symter; - ffebldOp op; - ffeintrinGen gen; - ffeintrinSpec spec = FFEINTRIN_specNONE; - ffeinfoBasictype bt = FFEINFO_basictypeNONE; - ffeinfoKindtype kt = FFEINFO_kindtypeNONE; - ffetargetCharacterSize sz = FFETARGET_charactersizeNONE; - ffeintrinImp imp; - ffeintrinSpec tspec; - ffeintrinImp nimp = FFEINTRIN_impNONE; - ffebad error; - bool any = FALSE; - bool highly_specific = FALSE; - int i; - - op = ffebld_op (*expr); - assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF)); - assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER); - - gen = ffebld_symter_generic (ffebld_left (*expr)); - assert (gen != FFEINTRIN_genNONE); - - imp = FFEINTRIN_impNONE; - error = FFEBAD; - - any = ffeintrin_check_any_ (ffebld_right (*expr)); - - for (i = 0; - (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs)) - && ((tspec = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE) - && !any; - ++i) - { - ffeintrinImp timp = ffeintrin_specs_[tspec].implementation; - ffeinfoBasictype tbt; - ffeinfoKindtype tkt; - ffetargetCharacterSize tsz; - ffeIntrinsicState state - = ffeintrin_state_family (ffeintrin_specs_[tspec].family); - ffebad terror; - - if (state == FFE_intrinsicstateDELETED) - continue; - - if (timp != FFEINTRIN_impNONE) - { - if (!(ffeintrin_imps_[timp].control[0] == '-') - != !(ffebld_op (*expr) == FFEBLD_opSUBRREF)) - continue; /* Form of reference must match form of specific. */ - } - - if (state == FFE_intrinsicstateDISABLED) - terror = FFEBAD_INTRINSIC_DISABLED; - else if (timp == FFEINTRIN_impNONE) - terror = FFEBAD_INTRINSIC_UNIMPL; - else - { - terror = ffeintrin_check_ (timp, ffebld_op (*expr), - ffebld_right (*expr), - &tbt, &tkt, &tsz, NULL, t, FALSE); - if (terror == FFEBAD) - { - if (imp != FFEINTRIN_impNONE) - { - ffebad_start (FFEBAD_INTRINSIC_AMBIG); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (ffeintrin_gens_[gen].name); - ffebad_string (ffeintrin_specs_[spec].name); - ffebad_string (ffeintrin_specs_[tspec].name); - ffebad_finish (); - } - else - { - if (ffebld_symter_specific (ffebld_left (*expr)) - == tspec) - highly_specific = TRUE; - imp = timp; - spec = tspec; - bt = tbt; - kt = tkt; - sz = tkt; - error = terror; - } - } - else if (terror != FFEBAD) - { /* This error has precedence over others. */ - if ((error == FFEBAD_INTRINSIC_DISABLED) - || (error == FFEBAD_INTRINSIC_UNIMPL)) - error = FFEBAD; - } - } - - if (error == FFEBAD) - error = terror; - } - - if (any || (imp == FFEINTRIN_impNONE)) - { - if (!any) - { - if (error == FFEBAD) - error = FFEBAD_INTRINSIC_REF; - ffebad_start (error); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (ffeintrin_gens_[gen].name); - ffebad_finish (); - } - - *expr = ffebld_new_any (); - *info = ffeinfo_new_any (); - } - else - { - if (!highly_specific && (nimp != FFEINTRIN_impNONE)) - { - fprintf (stderr, "lineno=%ld, gen=%s, imp=%s, timp=%s\n", - (long) lineno, - ffeintrin_gens_[gen].name, - ffeintrin_imps_[imp].name, - ffeintrin_imps_[nimp].name); - assert ("Ambiguous generic reference" == NULL); - abort (); - } - error = ffeintrin_check_ (imp, ffebld_op (*expr), - ffebld_right (*expr), - &bt, &kt, &sz, NULL, t, TRUE); - assert (error == FFEBAD); - *info = ffeinfo_new (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereFLEETING, - sz); - symter = ffebld_left (*expr); - ffebld_symter_set_specific (symter, spec); - ffebld_symter_set_implementation (symter, imp); - ffebld_set_info (symter, - ffeinfo_new (bt, - kt, - 0, - (bt == FFEINFO_basictypeNONE) - ? FFEINFO_kindSUBROUTINE - : FFEINFO_kindFUNCTION, - FFEINFO_whereINTRINSIC, - sz)); - - if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE) - && (((bt != ffesymbol_basictype (ffebld_symter (symter))) - || (kt != ffesymbol_kindtype (ffebld_symter (symter))) - || ((sz != FFETARGET_charactersizeNONE) - && (sz != ffesymbol_size (ffebld_symter (symter))))))) - { - ffebad_start (FFEBAD_INTRINSIC_TYPE); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (ffeintrin_gens_[gen].name); - ffebad_finish (); - } - } -} - -/* Check and fill in info on func/subr ref node. - - ffebld expr; // FUNCREF or SUBRREF with no info (caller - // gets it from the modified info structure). - ffeinfo info; // Already filled in, will be overwritten. - bool check_intrin; // May be omitted, else set TRUE if intrinsic needs checking. - ffelexToken token; // Used for error message. - ffeintrin_fulfill_specific (&expr, &info, &check_intrin, token); - - Based on the specific id, determine whether the arg list is valid - (number, type, rank, and kind of args) and fill in the info structure - accordingly. Currently don't rewrite the expression, but perhaps - someday do so for constant collapsing, except when an error occurs, - in which case it is overwritten with ANY and info is also overwritten - accordingly. */ - -void -ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, - bool *check_intrin, ffelexToken t) -{ - ffebld symter; - ffebldOp op; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - ffeinfoBasictype bt = FFEINFO_basictypeNONE; - ffeinfoKindtype kt = FFEINFO_kindtypeNONE; - ffetargetCharacterSize sz = FFETARGET_charactersizeNONE; - ffeIntrinsicState state; - ffebad error; - bool any = FALSE; - char *name; - - op = ffebld_op (*expr); - assert ((op == FFEBLD_opFUNCREF) || (op == FFEBLD_opSUBRREF)); - assert (ffebld_op (ffebld_left (*expr)) == FFEBLD_opSYMTER); - - gen = ffebld_symter_generic (ffebld_left (*expr)); - spec = ffebld_symter_specific (ffebld_left (*expr)); - assert (spec != FFEINTRIN_specNONE); - - if (gen != FFEINTRIN_genNONE) - name = ffeintrin_gens_[gen].name; - else - name = ffeintrin_specs_[spec].name; - - state = ffeintrin_state_family (ffeintrin_specs_[spec].family); - - imp = ffeintrin_specs_[spec].implementation; - if (check_intrin != NULL) - *check_intrin = FALSE; - - any = ffeintrin_check_any_ (ffebld_right (*expr)); - - if (state == FFE_intrinsicstateDISABLED) - error = FFEBAD_INTRINSIC_DISABLED; - else if (imp == FFEINTRIN_impNONE) - error = FFEBAD_INTRINSIC_UNIMPL; - else if (!any) - { - error = ffeintrin_check_ (imp, ffebld_op (*expr), - ffebld_right (*expr), - &bt, &kt, &sz, check_intrin, t, TRUE); - } - else - error = FFEBAD; /* Not really needed, but quiet -Wuninitialized. */ - - if (any || (error != FFEBAD)) - { - if (!any) - { - - ffebad_start (error); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (name); - ffebad_finish (); - } - - *expr = ffebld_new_any (); - *info = ffeinfo_new_any (); - } - else - { - *info = ffeinfo_new (bt, - kt, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereFLEETING, - sz); - symter = ffebld_left (*expr); - ffebld_set_info (symter, - ffeinfo_new (bt, - kt, - 0, - (bt == FFEINFO_basictypeNONE) - ? FFEINFO_kindSUBROUTINE - : FFEINFO_kindFUNCTION, - FFEINFO_whereINTRINSIC, - sz)); - - if ((ffesymbol_attrs (ffebld_symter (symter)) & FFESYMBOL_attrsTYPE) - && (((bt != ffesymbol_basictype (ffebld_symter (symter))) - || (kt != ffesymbol_kindtype (ffebld_symter (symter))) - || (sz != ffesymbol_size (ffebld_symter (symter)))))) - { - ffebad_start (FFEBAD_INTRINSIC_TYPE); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (name); - ffebad_finish (); - } - } -} - -/* Return run-time index of intrinsic implementation as direct call. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -ffecomGfrt -ffeintrin_gfrt_direct (ffeintrinImp imp) -{ - assert (imp < FFEINTRIN_imp); - - return ffeintrin_imps_[imp].gfrt_direct; -} -#endif - -/* Return run-time index of intrinsic implementation as actual argument. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -ffecomGfrt -ffeintrin_gfrt_indirect (ffeintrinImp imp) -{ - assert (imp < FFEINTRIN_imp); - - if (! ffe_is_f2c ()) - return ffeintrin_imps_[imp].gfrt_gnu; - return ffeintrin_imps_[imp].gfrt_f2c; -} -#endif - -void -ffeintrin_init_0 () -{ - int i; - char *p1; - char *p2; - char *p3; - int colon; - - if (!ffe_is_do_internal_checks ()) - return; - - assert (FFEINTRIN_gen == ARRAY_SIZE (ffeintrin_gens_)); - assert (FFEINTRIN_imp == ARRAY_SIZE (ffeintrin_imps_)); - assert (FFEINTRIN_spec == ARRAY_SIZE (ffeintrin_specs_)); - - for (i = 1; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i) - { /* Make sure binary-searched list is in alpha - order. */ - if (strcmp (ffeintrin_names_[i - 1].name_uc, - ffeintrin_names_[i].name_uc) >= 0) - assert ("name list out of order" == NULL); - } - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_names_); ++i) - { - assert ((ffeintrin_names_[i].generic == FFEINTRIN_genNONE) - || (ffeintrin_names_[i].specific == FFEINTRIN_specNONE)); - - p1 = ffeintrin_names_[i].name_uc; - p2 = ffeintrin_names_[i].name_lc; - p3 = ffeintrin_names_[i].name_ic; - for (; *p1 != '\0' && *p2 != '\0' && *p3 != '\0'; ++p1, ++p2, ++p3) - { - if (! IN_CTYPE_DOMAIN (*p1) - || ! IN_CTYPE_DOMAIN (*p2) - || ! IN_CTYPE_DOMAIN (*p3)) - break; - if ((ISDIGIT (*p1) || (*p1 == '_')) && (*p1 == *p2) && (*p1 == *p3)) - continue; - if (! ISUPPER ((unsigned char)*p1) || ! ISLOWER ((unsigned char)*p2) - || (*p1 != toupper ((unsigned char)*p2)) - || ((*p3 != *p1) && (*p3 != *p2))) - break; - } - assert ((*p1 == *p2) && (*p1 == *p3) && (*p1 == '\0')); - } - - for (i = 0; ((size_t) i) < ARRAY_SIZE (ffeintrin_imps_); ++i) - { - char *c = ffeintrin_imps_[i].control; - - if (c[0] == '\0') - continue; - - if ((c[0] != '-') - && (c[0] != 'A') - && (c[0] != 'C') - && (c[0] != 'I') - && (c[0] != 'L') - && (c[0] != 'R') - && (c[0] != 'B') - && (c[0] != 'F') - && (c[0] != 'N') - && (c[0] != 'S')) - { - fprintf (stderr, "%s: bad return-base-type\n", - ffeintrin_imps_[i].name); - continue; - } - if ((c[1] != '-') - && (c[1] != '=') - && ((c[1] < '1') - || (c[1] > '9')) - && (c[1] != 'C')) - { - fprintf (stderr, "%s: bad return-kind-type\n", - ffeintrin_imps_[i].name); - continue; - } - if (c[2] == ':') - colon = 2; - else - { - if (c[2] != '*') - { - fprintf (stderr, "%s: bad return-modifier\n", - ffeintrin_imps_[i].name); - continue; - } - colon = 3; - } - if ((c[colon] != ':') || (c[colon + 2] != ':')) - { - fprintf (stderr, "%s: bad control\n", - ffeintrin_imps_[i].name); - continue; - } - if ((c[colon + 1] != '-') - && (c[colon + 1] != '*') - && ((c[colon + 1] < '0') - || (c[colon + 1] > '9'))) - { - fprintf (stderr, "%s: bad COL-spec\n", - ffeintrin_imps_[i].name); - continue; - } - c += (colon + 3); - while (c[0] != '\0') - { - while ((c[0] != '=') - && (c[0] != ',') - && (c[0] != '\0')) - ++c; - if (c[0] != '=') - { - fprintf (stderr, "%s: bad keyword\n", - ffeintrin_imps_[i].name); - break; - } - if ((c[1] == '?') - || (c[1] == '!') - || (c[1] == '+') - || (c[1] == '*') - || (c[1] == 'n') - || (c[1] == 'p')) - ++c; - if ((c[1] != '-') - && (c[1] != 'A') - && (c[1] != 'C') - && (c[1] != 'I') - && (c[1] != 'L') - && (c[1] != 'R') - && (c[1] != 'B') - && (c[1] != 'F') - && (c[1] != 'N') - && (c[1] != 'S') - && (c[1] != 'g') - && (c[1] != 's')) - { - fprintf (stderr, "%s: bad arg-base-type\n", - ffeintrin_imps_[i].name); - break; - } - if ((c[2] != '*') - && ((c[2] < '1') - || (c[2] > '9')) - && (c[2] != 'A')) - { - fprintf (stderr, "%s: bad arg-kind-type\n", - ffeintrin_imps_[i].name); - break; - } - if (c[3] == '[') - { - if (((c[4] < '0') || (c[4] > '9')) - || ((c[5] != ']') - && (++c, (c[4] < '0') || (c[4] > '9') - || (c[5] != ']')))) - { - fprintf (stderr, "%s: bad arg-len\n", - ffeintrin_imps_[i].name); - break; - } - c += 3; - } - if (c[3] == '(') - { - if (((c[4] < '0') || (c[4] > '9')) - || ((c[5] != ')') - && (++c, (c[4] < '0') || (c[4] > '9') - || (c[5] != ')')))) - { - fprintf (stderr, "%s: bad arg-rank\n", - ffeintrin_imps_[i].name); - break; - } - c += 3; - } - else if ((c[3] == '&') - && (c[4] == '&')) - ++c; - if ((c[3] == '&') - || (c[3] == 'i') - || (c[3] == 'w') - || (c[3] == 'x')) - ++c; - if (c[3] == ',') - { - c += 4; - continue; - } - if (c[3] != '\0') - { - fprintf (stderr, "%s: bad arg-list\n", - ffeintrin_imps_[i].name); - } - break; - } - } -} - -/* Determine whether intrinsic is okay as an actual argument. */ - -bool -ffeintrin_is_actualarg (ffeintrinSpec spec) -{ - ffeIntrinsicState state; - - if (spec >= FFEINTRIN_spec) - return FALSE; - - state = ffeintrin_state_family (ffeintrin_specs_[spec].family); - - return (!ffe_is_pedantic () || ffeintrin_specs_[spec].is_actualarg) -#if FFECOM_targetCURRENT == FFECOM_targetGCC - && (ffe_is_f2c () - ? (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_f2c - != FFECOM_gfrt) - : (ffeintrin_imps_[ffeintrin_specs_[spec].implementation].gfrt_gnu - != FFECOM_gfrt)) -#endif - && ((state == FFE_intrinsicstateENABLED) - || (state == FFE_intrinsicstateHIDDEN)); -} - -/* Determine if name is intrinsic, return info. - - char *name; // C-string name of possible intrinsic. - ffelexToken t; // NULL if no diagnostic to be given. - bool explicit; // TRUE if INTRINSIC name. - ffeintrinGen gen; // (TRUE only) Generic id of intrinsic. - ffeintrinSpec spec; // (TRUE only) Specific id of intrinsic. - ffeintrinImp imp; // (TRUE only) Implementation id of intrinsic. - if (ffeintrin_is_intrinsic (name, t, explicit, - &gen, &spec, &imp)) - // is an intrinsic, use gen, spec, imp, and - // kind accordingly. */ - -bool -ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, - ffeintrinGen *xgen, ffeintrinSpec *xspec, - ffeintrinImp *ximp) -{ - struct _ffeintrin_name_ *intrinsic; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - ffeIntrinsicState state; - bool disabled = FALSE; - bool unimpl = FALSE; - - intrinsic = bsearch (name, &ffeintrin_names_[0], - ARRAY_SIZE (ffeintrin_names_), - sizeof (struct _ffeintrin_name_), - (void *) ffeintrin_cmp_name_); - - if (intrinsic == NULL) - return FALSE; - - gen = intrinsic->generic; - spec = intrinsic->specific; - imp = ffeintrin_specs_[spec].implementation; - - /* Generic is okay only if at least one of its specifics is okay. */ - - if (gen != FFEINTRIN_genNONE) - { - int i; - ffeintrinSpec tspec; - bool ok = FALSE; - - name = ffeintrin_gens_[gen].name; - - for (i = 0; - (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs)) - && ((tspec - = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE); - ++i) - { - state = ffeintrin_state_family (ffeintrin_specs_[tspec].family); - - if (state == FFE_intrinsicstateDELETED) - continue; - - if (state == FFE_intrinsicstateDISABLED) - { - disabled = TRUE; - continue; - } - - if (ffeintrin_specs_[tspec].implementation == FFEINTRIN_impNONE) - { - unimpl = TRUE; - continue; - } - - if ((state == FFE_intrinsicstateENABLED) - || (explicit - && (state == FFE_intrinsicstateHIDDEN))) - { - ok = TRUE; - break; - } - } - if (!ok) - gen = FFEINTRIN_genNONE; - } - - /* Specific is okay only if not: unimplemented, disabled, deleted, or - hidden and not explicit. */ - - if (spec != FFEINTRIN_specNONE) - { - if (gen != FFEINTRIN_genNONE) - name = ffeintrin_gens_[gen].name; - else - name = ffeintrin_specs_[spec].name; - - if (((state = ffeintrin_state_family (ffeintrin_specs_[spec].family)) - == FFE_intrinsicstateDELETED) - || (!explicit - && (state == FFE_intrinsicstateHIDDEN))) - spec = FFEINTRIN_specNONE; - else if (state == FFE_intrinsicstateDISABLED) - { - disabled = TRUE; - spec = FFEINTRIN_specNONE; - } - else if (imp == FFEINTRIN_impNONE) - { - unimpl = TRUE; - spec = FFEINTRIN_specNONE; - } - } - - /* If neither is okay, not an intrinsic. */ - - if ((gen == FFEINTRIN_genNONE) && (spec == FFEINTRIN_specNONE)) - { - /* Here is where we produce a diagnostic about a reference to a - disabled or unimplemented intrinsic, if the diagnostic is desired. */ - - if ((disabled || unimpl) - && (t != NULL)) - { - ffebad_start (disabled - ? FFEBAD_INTRINSIC_DISABLED - : FFEBAD_INTRINSIC_UNIMPLW); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (name); - ffebad_finish (); - } - - return FALSE; - } - - /* Determine whether intrinsic is function or subroutine. If no specific - id, scan list of possible specifics for generic to get consensus. If - not unanimous, or clear from the context, return NONE. */ - - if (spec == FFEINTRIN_specNONE) - { - int i; - ffeintrinSpec tspec; - ffeintrinImp timp; - bool at_least_one_ok = FALSE; - - for (i = 0; - (((size_t) i) < ARRAY_SIZE (ffeintrin_gens_[gen].specs)) - && ((tspec - = ffeintrin_gens_[gen].specs[i]) != FFEINTRIN_specNONE); - ++i) - { - if (((state = ffeintrin_state_family (ffeintrin_specs_[tspec].family)) - == FFE_intrinsicstateDELETED) - || (state == FFE_intrinsicstateDISABLED)) - continue; - - if ((timp = ffeintrin_specs_[tspec].implementation) - == FFEINTRIN_impNONE) - continue; - - at_least_one_ok = TRUE; - break; - } - - if (!at_least_one_ok) - { - *xgen = FFEINTRIN_genNONE; - *xspec = FFEINTRIN_specNONE; - *ximp = FFEINTRIN_impNONE; - return FALSE; - } - } - - *xgen = gen; - *xspec = spec; - *ximp = imp; - return TRUE; -} - -/* Return TRUE if intrinsic is standard F77 (or, if -ff90, F90). */ - -bool -ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec) -{ - if (spec == FFEINTRIN_specNONE) - { - if (gen == FFEINTRIN_genNONE) - return FALSE; - - spec = ffeintrin_gens_[gen].specs[0]; - if (spec == FFEINTRIN_specNONE) - return FALSE; - } - - if ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF77) - || (ffe_is_90 () - && ((ffeintrin_specs_[spec].family == FFEINTRIN_familyF90) - || (ffeintrin_specs_[spec].family == FFEINTRIN_familyMIL) - || (ffeintrin_specs_[spec].family == FFEINTRIN_familyASC)))) - return TRUE; - return FALSE; -} - -/* Return kind type of intrinsic implementation. See ffeintrin_basictype, - its sibling. */ - -ffeinfoKindtype -ffeintrin_kindtype (ffeintrinSpec spec) -{ - ffeintrinImp imp; - ffecomGfrt gfrt; - - assert (spec < FFEINTRIN_spec); - imp = ffeintrin_specs_[spec].implementation; - assert (imp < FFEINTRIN_imp); - - if (ffe_is_f2c ()) - gfrt = ffeintrin_imps_[imp].gfrt_f2c; - else - gfrt = ffeintrin_imps_[imp].gfrt_gnu; - - assert (gfrt != FFECOM_gfrt); - - return ffecom_gfrt_kindtype (gfrt); -} - -/* Return name of generic intrinsic. */ - -char * -ffeintrin_name_generic (ffeintrinGen gen) -{ - assert (gen < FFEINTRIN_gen); - return ffeintrin_gens_[gen].name; -} - -/* Return name of intrinsic implementation. */ - -char * -ffeintrin_name_implementation (ffeintrinImp imp) -{ - assert (imp < FFEINTRIN_imp); - return ffeintrin_imps_[imp].name; -} - -/* Return external/internal name of specific intrinsic. */ - -char * -ffeintrin_name_specific (ffeintrinSpec spec) -{ - assert (spec < FFEINTRIN_spec); - return ffeintrin_specs_[spec].name; -} - -/* Return state of family. */ - -ffeIntrinsicState -ffeintrin_state_family (ffeintrinFamily family) -{ - ffeIntrinsicState state; - - switch (family) - { - case FFEINTRIN_familyNONE: - return FFE_intrinsicstateDELETED; - - case FFEINTRIN_familyF77: - return FFE_intrinsicstateENABLED; - - case FFEINTRIN_familyASC: - state = ffe_intrinsic_state_f2c (); - state = ffe_state_max (state, ffe_intrinsic_state_f90 ()); - return state; - - case FFEINTRIN_familyMIL: - state = ffe_intrinsic_state_vxt (); - state = ffe_state_max (state, ffe_intrinsic_state_f90 ()); - state = ffe_state_max (state, ffe_intrinsic_state_mil ()); - return state; - - case FFEINTRIN_familyGNU: - state = ffe_intrinsic_state_gnu (); - return state; - - case FFEINTRIN_familyF90: - state = ffe_intrinsic_state_f90 (); - return state; - - case FFEINTRIN_familyVXT: - state = ffe_intrinsic_state_vxt (); - return state; - - case FFEINTRIN_familyFVZ: - state = ffe_intrinsic_state_f2c (); - state = ffe_state_max (state, ffe_intrinsic_state_vxt ()); - return state; - - case FFEINTRIN_familyF2C: - state = ffe_intrinsic_state_f2c (); - return state; - - case FFEINTRIN_familyF2U: - state = ffe_intrinsic_state_unix (); - return state; - - case FFEINTRIN_familyBADU77: - state = ffe_intrinsic_state_badu77 (); - return state; - - default: - assert ("bad family" == NULL); - return FFE_intrinsicstateDELETED; - } -} diff --git a/gcc/f/intrin.def b/gcc/f/intrin.def deleted file mode 100755 index 0c00dcc..0000000 --- a/gcc/f/intrin.def +++ /dev/null @@ -1,3351 +0,0 @@ -/* intrin.def -- Public #include File (module.h template V1.0) - The Free Software Foundation has released this file into the - public domain. - - Owning Modules: - intrin.c - - Modifications: -*/ - -/* Intrinsic names listed in alphabetical order, sorted by uppercase name. - This list is keyed to the names of intrinsics as seen in source code. */ - -DEFNAME ("ABORT", "abort", "Abort", genNONE, specABORT) /* UNIX */ -DEFNAME ("ABS", "abs", "Abs", genNONE, specABS) -DEFNAME ("ACCESS", "access", "Access", genNONE, specACCESS) /* UNIX */ -DEFNAME ("ACHAR", "achar", "AChar", genNONE, specACHAR) /* F90, F2C */ -DEFNAME ("ACOS", "acos", "ACos", genNONE, specACOS) -DEFNAME ("ACOSD", "acosd", "ACosD", genNONE, specACOSD) /* VXT */ -DEFNAME ("ADJUSTL", "adjustl", "AdjustL", genNONE, specADJUSTL) /* F90 */ -DEFNAME ("ADJUSTR", "adjustr", "AdjustR", genNONE, specADJUSTR) /* F90 */ -DEFNAME ("AIMAG", "aimag", "AImag", genNONE, specAIMAG) -DEFNAME ("AIMAX0", "aimax0", "AIMax0", genNONE, specAIMAX0) /* VXT */ -DEFNAME ("AIMIN0", "aimin0", "AIMin0", genNONE, specAIMIN0) /* VXT */ -DEFNAME ("AINT", "aint", "AInt", genNONE, specAINT) -DEFNAME ("AJMAX0", "ajmax0", "AJMax0", genNONE, specAJMAX0) /* VXT */ -DEFNAME ("AJMIN0", "ajmin0", "AJMin0", genNONE, specAJMIN0) /* VXT */ -DEFNAME ("ALARM", "alarm", "Alarm", genNONE, specALARM) /* UNIX */ -DEFNAME ("ALL", "all", "All", genNONE, specALL) /* F90 */ -DEFNAME ("ALLOCATED", "allocated", "Allocated", genNONE, specALLOCATED) /* F90 */ -DEFNAME ("ALOG", "alog", "ALog", genNONE, specALOG) -DEFNAME ("ALOG10", "alog10", "ALog10", genNONE, specALOG10) -DEFNAME ("AMAX0", "amax0", "AMax0", genNONE, specAMAX0) -DEFNAME ("AMAX1", "amax1", "AMax1", genNONE, specAMAX1) -DEFNAME ("AMIN0", "amin0", "AMin0", genNONE, specAMIN0) -DEFNAME ("AMIN1", "amin1", "AMin1", genNONE, specAMIN1) -DEFNAME ("AMOD", "amod", "AMod", genNONE, specAMOD) -DEFNAME ("AND", "and", "And", genNONE, specAND) /* F2C */ -DEFNAME ("ANINT", "anint", "ANInt", genNONE, specANINT) -DEFNAME ("ANY", "any", "Any", genNONE, specANY) /* F90 */ -DEFNAME ("ASIN", "asin", "ASin", genNONE, specASIN) -DEFNAME ("ASIND", "asind", "ASinD", genNONE, specASIND) /* VXT */ -DEFNAME ("ASSOCIATED", "associated", "Associated", genNONE, specASSOCIATED) /* F90 */ -DEFNAME ("ATAN", "atan", "ATan", genNONE, specATAN) -DEFNAME ("ATAN2", "atan2", "ATan2", genNONE, specATAN2) -DEFNAME ("ATAN2D", "atan2d", "ATan2D", genNONE, specATAN2D) /* VXT */ -DEFNAME ("ATAND", "atand", "ATanD", genNONE, specATAND) /* VXT */ -DEFNAME ("BESJ0", "besj0", "BesJ0", genNONE, specBESJ0) /* UNIX */ -DEFNAME ("BESJ1", "besj1", "BesJ1", genNONE, specBESJ1) /* UNIX */ -DEFNAME ("BESJN", "besjn", "BesJN", genNONE, specBESJN) /* UNIX */ -DEFNAME ("BESY0", "besy0", "BesY0", genNONE, specBESY0) /* UNIX */ -DEFNAME ("BESY1", "besy1", "BesY1", genNONE, specBESY1) /* UNIX */ -DEFNAME ("BESYN", "besyn", "BesYN", genNONE, specBESYN) /* UNIX */ -DEFNAME ("BITEST", "bitest", "BITest", genNONE, specBITEST) /* VXT */ -DEFNAME ("BIT_SIZE", "bit_size", "Bit_Size", genNONE, specBIT_SIZE) /* F90 */ -DEFNAME ("BJTEST", "bjtest", "BJTest", genNONE, specBJTEST) /* VXT */ -DEFNAME ("BTEST", "btest", "BTest", genNONE, specBTEST) /* F90, VXT */ -DEFNAME ("CABS", "cabs", "CAbs", genNONE, specCABS) -DEFNAME ("CCOS", "ccos", "CCos", genNONE, specCCOS) -DEFNAME ("CDABS", "cdabs", "CDAbs", genNONE, specCDABS) /* VXT */ -DEFNAME ("CDCOS", "cdcos", "CDCos", genNONE, specCDCOS) /* VXT */ -DEFNAME ("CDEXP", "cdexp", "CDExp", genNONE, specCDEXP) /* VXT */ -DEFNAME ("CDLOG", "cdlog", "CDLog", genNONE, specCDLOG) /* VXT */ -DEFNAME ("CDSIN", "cdsin", "CDSin", genNONE, specCDSIN) /* VXT */ -DEFNAME ("CDSQRT", "cdsqrt", "CDSqRt", genNONE, specCDSQRT) /* VXT */ -DEFNAME ("CEILING", "ceiling", "Ceiling", genNONE, specCEILING) /* F90 */ -DEFNAME ("CEXP", "cexp", "CExp", genNONE, specCEXP) -DEFNAME ("CHAR", "char", "Char", genNONE, specCHAR) -DEFNAME ("CHDIR", "chdir", "ChDir", genCHDIR, specNONE) /* UNIX */ -DEFNAME ("CHMOD", "chmod", "ChMod", genCHMOD, specNONE) /* UNIX */ -DEFNAME ("CLOG", "clog", "CLog", genNONE, specCLOG) -DEFNAME ("CMPLX", "cmplx", "Cmplx", genNONE, specCMPLX) -DEFNAME ("COMPLEX", "complex", "Complex", genNONE, specCOMPLEX) -DEFNAME ("CONJG", "conjg", "Conjg", genNONE, specCONJG) -DEFNAME ("COS", "cos", "Cos", genNONE, specCOS) -DEFNAME ("COSD", "cosd", "CosD", genNONE, specCOSD) /* VXT */ -DEFNAME ("COSH", "cosh", "CosH", genNONE, specCOSH) -DEFNAME ("COUNT", "count", "Count", genNONE, specCOUNT) /* F90 */ -DEFNAME ("CPU_TIME", "cpu_time", "CPU_Time", genNONE, specCPU_TIME) /* F95 */ -DEFNAME ("CSHIFT", "cshift", "CShift", genNONE, specCSHIFT) /* F90 */ -DEFNAME ("CSIN", "csin", "CSin", genNONE, specCSIN) -DEFNAME ("CSQRT", "csqrt", "CSqRt", genNONE, specCSQRT) -DEFNAME ("CTIME", "ctime", "CTime", genCTIME, specNONE) /* UNIX */ -DEFNAME ("DABS", "dabs", "DAbs", genNONE, specDABS) -DEFNAME ("DACOS", "dacos", "DACos", genNONE, specDACOS) -DEFNAME ("DACOSD", "dacosd", "DACosD", genNONE, specDACOSD) /* VXT */ -DEFNAME ("DASIN", "dasin", "DASin", genNONE, specDASIN) -DEFNAME ("DASIND", "dasind", "DASinD", genNONE, specDASIND) /* VXT */ -DEFNAME ("DATAN", "datan", "DATan", genNONE, specDATAN) -DEFNAME ("DATAN2", "datan2", "DATan2", genNONE, specDATAN2) -DEFNAME ("DATAN2D", "datan2d", "DATan2D", genNONE, specDATAN2D) /* VXT */ -DEFNAME ("DATAND", "datand", "DATanD", genNONE, specDATAND) /* VXT */ -DEFNAME ("DATE", "date", "Date", genNONE, specDATE) /* VXT */ -DEFNAME ("DATE_AND_TIME", "date_and_time", "Date_and_Time", genNONE, specDATE_AND_TIME) /* F90 */ -DEFNAME ("DBESJ0", "dbesj0", "DbesJ0", genNONE, specDBESJ0) /* UNIX */ -DEFNAME ("DBESJ1", "dbesj1", "DbesJ1", genNONE, specDBESJ1) /* UNIX */ -DEFNAME ("DBESJN", "dbesjn", "DbesJN", genNONE, specDBESJN) /* UNIX */ -DEFNAME ("DBESY0", "dbesy0", "DbesY0", genNONE, specDBESY0) /* UNIX */ -DEFNAME ("DBESY1", "dbesy1", "DbesY1", genNONE, specDBESY1) /* UNIX */ -DEFNAME ("DBESYN", "dbesyn", "DbesYN", genNONE, specDBESYN) /* UNIX */ -DEFNAME ("DBLE", "dble", "Dble", genNONE, specDBLE) -DEFNAME ("DBLEQ", "dbleq", "DbleQ", genNONE, specDBLEQ) /* VXT */ -DEFNAME ("DCMPLX", "dcmplx", "DCmplx", genNONE, specDCMPLX) /* F2C, VXT */ -DEFNAME ("DCONJG", "dconjg", "DConjg", genNONE, specDCONJG) /* F2C, VXT */ -DEFNAME ("DCOS", "dcos", "DCos", genNONE, specDCOS) -DEFNAME ("DCOSD", "dcosd", "DCosD", genNONE, specDCOSD) /* VXT */ -DEFNAME ("DCOSH", "dcosh", "DCosH", genNONE, specDCOSH) -DEFNAME ("DDIM", "ddim", "DDiM", genNONE, specDDIM) -DEFNAME ("DERF", "derf", "DErF", genNONE, specDERF) /* UNIX */ -DEFNAME ("DERFC", "derfc", "DErFC", genNONE, specDERFC) /* UNIX */ -DEFNAME ("DEXP", "dexp", "DExp", genNONE, specDEXP) -DEFNAME ("DFLOAT", "dfloat", "DFloat", genNONE, specDFLOAT) /* F2C, VXT */ -DEFNAME ("DFLOTI", "dfloti", "DFlotI", genNONE, specDFLOTI) /* VXT */ -DEFNAME ("DFLOTJ", "dflotj", "DFlotJ", genNONE, specDFLOTJ) /* VXT */ -DEFNAME ("DIGITS", "digits", "Digits", genNONE, specDIGITS) /* F90 */ -DEFNAME ("DIM", "dim", "DiM", genNONE, specDIM) -DEFNAME ("DIMAG", "dimag", "DImag", genNONE, specDIMAG) /* F2C, VXT */ -DEFNAME ("DINT", "dint", "DInt", genNONE, specDINT) -DEFNAME ("DLOG", "dlog", "DLog", genNONE, specDLOG) -DEFNAME ("DLOG10", "dlog10", "DLog10", genNONE, specDLOG10) -DEFNAME ("DMAX1", "dmax1", "DMax1", genNONE, specDMAX1) -DEFNAME ("DMIN1", "dmin1", "DMin1", genNONE, specDMIN1) -DEFNAME ("DMOD", "dmod", "DMod", genNONE, specDMOD) -DEFNAME ("DNINT", "dnint", "DNInt", genNONE, specDNINT) -DEFNAME ("DOT_PRODUCT", "dot_product", "Dot_Product", genNONE, specDOT_PRODUCT) /* F90 */ -DEFNAME ("DPROD", "dprod", "DProd", genNONE, specDPROD) -DEFNAME ("DREAL", "dreal", "DReal", genNONE, specDREAL) /* VXT */ -DEFNAME ("DSIGN", "dsign", "DSign", genNONE, specDSIGN) -DEFNAME ("DSIN", "dsin", "DSin", genNONE, specDSIN) -DEFNAME ("DSIND", "dsind", "DSinD", genNONE, specDSIND) /* VXT */ -DEFNAME ("DSINH", "dsinh", "DSinH", genNONE, specDSINH) -DEFNAME ("DSQRT", "dsqrt", "DSqRt", genNONE, specDSQRT) -DEFNAME ("DTAN", "dtan", "DTan", genNONE, specDTAN) -DEFNAME ("DTAND", "dtand", "DTanD", genNONE, specDTAND) /* VXT */ -DEFNAME ("DTANH", "dtanh", "DTanH", genNONE, specDTANH) -DEFNAME ("DTIME", "dtime", "Dtime", genDTIME, specNONE) /* UNIX */ -DEFNAME ("EOSHIFT", "eoshift", "EOShift", genNONE, specEOSHIFT) /* F90 */ -DEFNAME ("EPSILON", "epsilon", "Epsilon", genNONE, specEPSILON) /* F90 */ -DEFNAME ("ERF", "erf", "ErF", genNONE, specERF) /* UNIX */ -DEFNAME ("ERFC", "erfc", "ErFC", genNONE, specERFC) /* UNIX */ -DEFNAME ("ETIME", "etime", "ETime", genETIME, specNONE) /* UNIX */ -DEFNAME ("EXIT", "exit", "Exit", genNONE, specEXIT) /* UNIX */ -DEFNAME ("EXP", "exp", "Exp", genNONE, specEXP) -DEFNAME ("EXPONENT", "exponent", "Exponent", genNONE, specEXPONENT) /* F90 */ -DEFNAME ("FDATE", "fdate", "Fdate", genFDATE, specNONE) /* UNIX */ -DEFNAME ("FGET", "fget", "FGet", genFGET, specNONE) /* UNIX */ -DEFNAME ("FGETC", "fgetc", "FGetC", genFGETC, specNONE) /* UNIX */ -DEFNAME ("FLOAT", "float", "Float", genNONE, specFLOAT) -DEFNAME ("FLOATI", "floati", "FloatI", genNONE, specFLOATI) /* VXT */ -DEFNAME ("FLOATJ", "floatj", "FloatJ", genNONE, specFLOATJ) /* VXT */ -DEFNAME ("FLOOR", "floor", "Floor", genNONE, specFLOOR) /* F90 */ -DEFNAME ("FLUSH", "flush", "Flush", genNONE, specFLUSH) /* UNIX */ -DEFNAME ("FNUM", "fnum", "FNum", genNONE, specFNUM) /* UNIX */ -DEFNAME ("FPABSP", "fpabsp", "FPAbsP", genFPABSP, specNONE) /* F2C */ -DEFNAME ("FPEXPN", "fpexpn", "FPExpn", genFPEXPN, specNONE) /* F2C */ -DEFNAME ("FPFRAC", "fpfrac", "FPFrac", genFPFRAC, specNONE) /* F2C */ -DEFNAME ("FPMAKE", "fpmake", "FPMake", genFPMAKE, specNONE) /* F2C */ -DEFNAME ("FPRRSP", "fprrsp", "FPRRSp", genFPRRSP, specNONE) /* F2C */ -DEFNAME ("FPSCAL", "fpscal", "FPScal", genFPSCAL, specNONE) /* F2C */ -DEFNAME ("FPUT", "fput", "FPut", genFPUT, specNONE) /* UNIX */ -DEFNAME ("FPUTC", "fputc", "FPutC", genFPUTC, specNONE) /* UNIX */ -DEFNAME ("FRACTION", "fraction", "Fraction", genNONE, specFRACTION) /* F90 */ -DEFNAME ("FSEEK", "fseek", "FSeek", genNONE, specFSEEK) /* UNIX */ -DEFNAME ("FSTAT", "fstat", "FStat", genFSTAT, specNONE) /* UNIX */ -DEFNAME ("FTELL", "ftell", "FTell", genFTELL, specNONE) /* UNIX */ -DEFNAME ("GERROR", "gerror", "GError", genNONE, specGERROR) /* UNIX */ -DEFNAME ("GETARG", "getarg", "GetArg", genNONE, specGETARG) /* UNIX */ -DEFNAME ("GETCWD", "getcwd", "GetCWD", genGETCWD, specNONE) /* UNIX */ -DEFNAME ("GETENV", "getenv", "GetEnv", genNONE, specGETENV) /* UNIX */ -DEFNAME ("GETGID", "getgid", "GetGId", genNONE, specGETGID) /* UNIX */ -DEFNAME ("GETLOG", "getlog", "GetLog", genNONE, specGETLOG) /* UNIX */ -DEFNAME ("GETPID", "getpid", "GetPId", genNONE, specGETPID) /* UNIX */ -DEFNAME ("GETUID", "getuid", "GetUId", genNONE, specGETUID) /* UNIX */ -DEFNAME ("GMTIME", "gmtime", "GMTime", genNONE, specGMTIME) /* UNIX */ -DEFNAME ("HOSTNM", "hostnm", "HostNm", genHOSTNM, specNONE) /* UNIX */ -DEFNAME ("HUGE", "huge", "Huge", genNONE, specHUGE) /* F90 */ -DEFNAME ("IABS", "iabs", "IAbs", genNONE, specIABS) -DEFNAME ("IACHAR", "iachar", "IAChar", genNONE, specIACHAR) /* F90, F2C */ -DEFNAME ("IAND", "iand", "IAnd", genNONE, specIAND) /* F90, VXT */ -DEFNAME ("IARGC", "iargc", "IArgC", genNONE, specIARGC) /* UNIX */ -DEFNAME ("IBCLR", "ibclr", "IBClr", genNONE, specIBCLR) /* F90, VXT */ -DEFNAME ("IBITS", "ibits", "IBits", genNONE, specIBITS) /* F90, VXT */ -DEFNAME ("IBSET", "ibset", "IBSet", genNONE, specIBSET) /* F90, VXT */ -DEFNAME ("ICHAR", "ichar", "IChar", genNONE, specICHAR) -DEFNAME ("IDATE", "idate", "IDate", genIDATE, specNONE) /* UNIX, VXT */ -DEFNAME ("IDIM", "idim", "IDiM", genNONE, specIDIM) -DEFNAME ("IDINT", "idint", "IDInt", genNONE, specIDINT) -DEFNAME ("IDNINT", "idnint", "IDNInt", genNONE, specIDNINT) -DEFNAME ("IEOR", "ieor", "IEOr", genNONE, specIEOR) /* F90, VXT */ -DEFNAME ("IERRNO", "ierrno", "IErrNo", genNONE, specIERRNO) /* UNIX */ -DEFNAME ("IFIX", "ifix", "IFix", genNONE, specIFIX) -DEFNAME ("IIABS", "iiabs", "IIAbs", genNONE, specIIABS) /* VXT */ -DEFNAME ("IIAND", "iiand", "IIAnd", genNONE, specIIAND) /* VXT */ -DEFNAME ("IIBCLR", "iibclr", "IIBClr", genNONE, specIIBCLR) /* VXT */ -DEFNAME ("IIBITS", "iibits", "IIBits", genNONE, specIIBITS) /* VXT */ -DEFNAME ("IIBSET", "iibset", "IIBSet", genNONE, specIIBSET) /* VXT */ -DEFNAME ("IIDIM", "iidim", "IIDiM", genNONE, specIIDIM) /* VXT */ -DEFNAME ("IIDINT", "iidint", "IIDInt", genNONE, specIIDINT) /* VXT */ -DEFNAME ("IIDNNT", "iidnnt", "IIDNnt", genNONE, specIIDNNT) /* VXT */ -DEFNAME ("IIEOR", "iieor", "IIEOr", genNONE, specIIEOR) /* VXT */ -DEFNAME ("IIFIX", "iifix", "IIFix", genNONE, specIIFIX) /* VXT */ -DEFNAME ("IINT", "iint", "IInt", genNONE, specIINT) /* VXT */ -DEFNAME ("IIOR", "iior", "IIOr", genNONE, specIIOR) /* VXT */ -DEFNAME ("IIQINT", "iiqint", "IIQint", genNONE, specIIQINT) /* VXT */ -DEFNAME ("IIQNNT", "iiqnnt", "IIQNnt", genNONE, specIIQNNT) /* VXT */ -DEFNAME ("IISHFT", "iishft", "IIShft", genNONE, specNONE) /* VXT */ -DEFNAME ("IISHFTC", "iishftc", "IIShftC", genNONE, specIISHFTC) /* VXT */ -DEFNAME ("IISIGN", "iisign", "IISign", genNONE, specIISIGN) /* VXT */ -DEFNAME ("IMAG", "imag", "Imag", genNONE, specIMAG) /* F2C */ -DEFNAME ("IMAGPART", "imagpart", "ImagPart", genNONE, specIMAGPART) /* GNU */ -DEFNAME ("IMAX0", "imax0", "IMax0", genNONE, specIMAX0) /* VXT */ -DEFNAME ("IMAX1", "imax1", "IMax1", genNONE, specIMAX1) /* VXT */ -DEFNAME ("IMIN0", "imin0", "IMin0", genNONE, specIMIN0) /* VXT */ -DEFNAME ("IMIN1", "imin1", "IMin1", genNONE, specIMIN1) /* VXT */ -DEFNAME ("IMOD", "imod", "IMod", genNONE, specIMOD) /* VXT */ -DEFNAME ("INDEX", "index", "Index", genNONE, specINDEX) -DEFNAME ("ININT", "inint", "INInt", genNONE, specININT) /* VXT */ -DEFNAME ("INOT", "inot", "INot", genNONE, specINOT) /* VXT */ -DEFNAME ("INT", "int", "Int", genNONE, specINT) -DEFNAME ("INT2", "int2", "Int2", genNONE, specINT2) /* MS */ -DEFNAME ("INT8", "int8", "Int8", genNONE, specINT8) /* GNU */ -DEFNAME ("IOR", "ior", "IOr", genNONE, specIOR) /* F90, VXT */ -DEFNAME ("IRAND", "irand", "IRand", genNONE, specIRAND) /* UNIX */ -DEFNAME ("ISATTY", "isatty", "IsaTty", genNONE, specISATTY) /* UNIX */ -DEFNAME ("ISHFT", "ishft", "IShft", genNONE, specISHFT) /* F90 */ -DEFNAME ("ISHFTC", "ishftc", "IShftC", genNONE, specISHFTC) /* F90, VXT */ -DEFNAME ("ISIGN", "isign", "ISign", genNONE, specISIGN) -DEFNAME ("ITIME", "itime", "ITime", genNONE, specITIME) /* UNIX */ -DEFNAME ("IZEXT", "izext", "IZExt", genNONE, specIZEXT) /* VXT */ -DEFNAME ("JIABS", "jiabs", "JIAbs", genNONE, specJIABS) /* VXT */ -DEFNAME ("JIAND", "jiand", "JIAnd", genNONE, specJIAND) /* VXT */ -DEFNAME ("JIBCLR", "jibclr", "JIBClr", genNONE, specJIBCLR) /* VXT */ -DEFNAME ("JIBITS", "jibits", "JIBits", genNONE, specJIBITS) /* VXT */ -DEFNAME ("JIBSET", "jibset", "JIBSet", genNONE, specJIBSET) /* VXT */ -DEFNAME ("JIDIM", "jidim", "JIDiM", genNONE, specJIDIM) /* VXT */ -DEFNAME ("JIDINT", "jidint", "JIDInt", genNONE, specJIDINT) /* VXT */ -DEFNAME ("JIDNNT", "jidnnt", "JIDNnt", genNONE, specJIDNNT) /* VXT */ -DEFNAME ("JIEOR", "jieor", "JIEOr", genNONE, specJIEOR) /* VXT */ -DEFNAME ("JIFIX", "jifix", "JIFix", genNONE, specJIFIX) /* VXT */ -DEFNAME ("JINT", "jint", "JInt", genNONE, specJINT) /* VXT */ -DEFNAME ("JIOR", "jior", "JIOr", genNONE, specJIOR) /* VXT */ -DEFNAME ("JIQINT", "jiqint", "JIQint", genNONE, specJIQINT) /* VXT */ -DEFNAME ("JIQNNT", "jiqnnt", "JIQNnt", genNONE, specJIQNNT) /* VXT */ -DEFNAME ("JISHFT", "jishft", "JIShft", genNONE, specJISHFT) /* VXT */ -DEFNAME ("JISHFTC", "jishftc", "JIShftC", genNONE, specJISHFTC) /* VXT */ -DEFNAME ("JISIGN", "jisign", "JISign", genNONE, specJISIGN) /* VXT */ -DEFNAME ("JMAX0", "jmax0", "JMax0", genNONE, specJMAX0) /* VXT */ -DEFNAME ("JMAX1", "jmax1", "JMax1", genNONE, specJMAX1) /* VXT */ -DEFNAME ("JMIN0", "jmin0", "JMin0", genNONE, specJMIN0) /* VXT */ -DEFNAME ("JMIN1", "jmin1", "JMin1", genNONE, specJMIN1) /* VXT */ -DEFNAME ("JMOD", "jmod", "JMod", genNONE, specJMOD) /* VXT */ -DEFNAME ("JNINT", "jnint", "JNInt", genNONE, specJNINT) /* VXT */ -DEFNAME ("JNOT", "jnot", "JNot", genNONE, specJNOT) /* VXT */ -DEFNAME ("JZEXT", "jzext", "JZExt", genNONE, specJZEXT) /* VXT */ -DEFNAME ("KILL", "kill", "Kill", genKILL, specNONE) /* UNIX */ -DEFNAME ("KIND", "kind", "Kind", genNONE, specKIND) /* F90 */ -DEFNAME ("LBOUND", "lbound", "LBound", genNONE, specLBOUND) /* F90 */ -DEFNAME ("LEN", "len", "Len", genNONE, specLEN) -DEFNAME ("LEN_TRIM", "len_trim", "Len_Trim", genNONE, specLEN_TRIM) /* F90 */ -DEFNAME ("LGE", "lge", "LGe", genNONE, specLGE) -DEFNAME ("LGT", "lgt", "LGt", genNONE, specLGT) -DEFNAME ("LINK", "link", "Link", genLINK, specNONE) /* UNIX */ -DEFNAME ("LLE", "lle", "LLe", genNONE, specLLE) -DEFNAME ("LLT", "llt", "LLt", genNONE, specLLT) -DEFNAME ("LNBLNK", "lnblnk", "LnBlnk", genNONE, specLNBLNK) /* UNIX */ -DEFNAME ("LOC", "loc", "Loc", genNONE, specLOC) /* VXT */ -DEFNAME ("LOG", "log", "Log", genNONE, specLOG) -DEFNAME ("LOG10", "log10", "Log10", genNONE, specLOG10) -DEFNAME ("LOGICAL", "logical", "Logical", genNONE, specLOGICAL) /* F90 */ -DEFNAME ("LONG", "long", "Long", genNONE, specLONG) /* UNIX */ -DEFNAME ("LSHIFT", "lshift", "LShift", genNONE, specLSHIFT) /* F2C */ -DEFNAME ("LSTAT", "lstat", "LStat", genLSTAT, specNONE) /* UNIX */ -DEFNAME ("LTIME", "ltime", "LTime", genNONE, specLTIME) /* UNIX */ -DEFNAME ("MATMUL", "matmul", "MatMul", genNONE, specMATMUL) /* F90 */ -DEFNAME ("MAX", "max", "Max", genNONE, specMAX) -DEFNAME ("MAX0", "max0", "Max0", genNONE, specMAX0) -DEFNAME ("MAX1", "max1", "Max1", genNONE, specMAX1) -DEFNAME ("MAXEXPONENT", "maxexponent", "MaxExponent", genNONE, specMAXEXPONENT) /* F90 */ -DEFNAME ("MAXLOC", "maxloc", "MaxLoc", genNONE, specMAXLOC) /* F90 */ -DEFNAME ("MAXVAL", "maxval", "MaxVal", genNONE, specMAXVAL) /* F90 */ -DEFNAME ("MCLOCK", "mclock", "MClock", genNONE, specMCLOCK) /* UNIX */ -DEFNAME ("MCLOCK8", "mclock8", "MClock8", genNONE, specMCLOCK8) /* UNIX */ -DEFNAME ("MERGE", "merge", "Merge", genNONE, specMERGE) /* F90 */ -DEFNAME ("MIN", "min", "Min", genNONE, specMIN) -DEFNAME ("MIN0", "min0", "Min0", genNONE, specMIN0) -DEFNAME ("MIN1", "min1", "Min1", genNONE, specMIN1) -DEFNAME ("MINEXPONENT", "minexponent", "MinExponent", genNONE, specMINEXPONENT) /* F90 */ -DEFNAME ("MINLOC", "minloc", "MinLoc", genNONE, specMINLOC) /* F90 */ -DEFNAME ("MINVAL", "minval", "MinVal", genNONE, specMINVAL) /* F90 */ -DEFNAME ("MOD", "mod", "Mod", genNONE, specMOD) -DEFNAME ("MODULO", "modulo", "Modulo", genNONE, specMODULO) /* F90 */ -DEFNAME ("MVBITS", "mvbits", "MvBits", genNONE, specMVBITS) /* F90 */ -DEFNAME ("NEAREST", "nearest", "Nearest", genNONE, specNEAREST) /* F90 */ -DEFNAME ("NINT", "nint", "NInt", genNONE, specNINT) -DEFNAME ("NOT", "not", "Not", genNONE, specNOT) /* F2C, F90, VXT */ -DEFNAME ("OR", "or", "Or", genNONE, specOR) /* F2C */ -DEFNAME ("PACK", "pack", "Pack", genNONE, specPACK) /* F90 */ -DEFNAME ("PERROR", "perror", "PError", genNONE, specPERROR) /* UNIX */ -DEFNAME ("PRECISION", "precision", "Precision", genNONE, specPRECISION) /* F90 */ -DEFNAME ("PRESENT", "present", "Present", genNONE, specPRESENT) /* F90 */ -DEFNAME ("PRODUCT", "product", "Product", genNONE, specPRODUCT) /* F90 */ -DEFNAME ("QABS", "qabs", "QAbs", genNONE, specQABS) /* VXT */ -DEFNAME ("QACOS", "qacos", "QACos", genNONE, specQACOS) /* VXT */ -DEFNAME ("QACOSD", "qacosd", "QACosD", genNONE, specQACOSD) /* VXT */ -DEFNAME ("QASIN", "qasin", "QASin", genNONE, specQASIN) /* VXT */ -DEFNAME ("QASIND", "qasind", "QASinD", genNONE, specQASIND) /* VXT */ -DEFNAME ("QATAN", "qatan", "QATan", genNONE, specQATAN) /* VXT */ -DEFNAME ("QATAN2", "qatan2", "QATan2", genNONE, specQATAN2) /* VXT */ -DEFNAME ("QATAN2D", "qatan2d", "QATan2D", genNONE, specQATAN2D) /* VXT */ -DEFNAME ("QATAND", "qatand", "QATanD", genNONE, specQATAND) /* VXT */ -DEFNAME ("QCOS", "qcos", "QCos", genNONE, specQCOS) /* VXT */ -DEFNAME ("QCOSD", "qcosd", "QCosD", genNONE, specQCOSD) /* VXT */ -DEFNAME ("QCOSH", "qcosh", "QCosH", genNONE, specQCOSH) /* VXT */ -DEFNAME ("QDIM", "qdim", "QDiM", genNONE, specQDIM) /* VXT */ -DEFNAME ("QEXP", "qexp", "QExp", genNONE, specQEXP) /* VXT */ -DEFNAME ("QEXT", "qext", "QExt", genNONE, specQEXT) /* VXT */ -DEFNAME ("QEXTD", "qextd", "QExtD", genNONE, specQEXTD) /* VXT */ -DEFNAME ("QFLOAT", "qfloat", "QFloat", genNONE, specQFLOAT) /* VXT */ -DEFNAME ("QINT", "qint", "QInt", genNONE, specQINT) /* VXT */ -DEFNAME ("QLOG", "qlog", "QLog", genNONE, specQLOG) /* VXT */ -DEFNAME ("QLOG10", "qlog10", "QLog10", genNONE, specQLOG10) /* VXT */ -DEFNAME ("QMAX1", "qmax1", "QMax1", genNONE, specQMAX1) /* VXT */ -DEFNAME ("QMIN1", "qmin1", "QMin1", genNONE, specQMIN1) /* VXT */ -DEFNAME ("QMOD", "qmod", "QMod", genNONE, specQMOD) /* VXT */ -DEFNAME ("QNINT", "qnint", "QNInt", genNONE, specQNINT) /* VXT */ -DEFNAME ("QSIN", "qsin", "QSin", genNONE, specQSIN) /* VXT */ -DEFNAME ("QSIND", "qsind", "QSinD", genNONE, specQSIND) /* VXT */ -DEFNAME ("QSINH", "qsinh", "QSinH", genNONE, specQSINH) /* VXT */ -DEFNAME ("QSQRT", "qsqrt", "QSqRt", genNONE, specQSQRT) /* VXT */ -DEFNAME ("QTAN", "qtan", "QTan", genNONE, specQTAN) /* VXT */ -DEFNAME ("QTAND", "qtand", "QTanD", genNONE, specQTAND) /* VXT */ -DEFNAME ("QTANH", "qtanh", "QTanH", genNONE, specQTANH) /* VXT */ -DEFNAME ("RADIX", "radix", "Radix", genNONE, specRADIX) /* F90 */ -DEFNAME ("RAND", "rand", "Rand", genNONE, specRAND) /* UNIX */ -DEFNAME ("RANDOM_NUMBER", "random_number", "Random_Number", genNONE, specRANDOM_NUMBER) /* F90 */ -DEFNAME ("RANDOM_SEED", "random_seed", "Random_Seed", genNONE, specRANDOM_SEED) /* F90 */ -DEFNAME ("RANGE", "range", "Range", genNONE, specRANGE) /* F90 */ -DEFNAME ("REAL", "real", "Real", genNONE, specREAL) -DEFNAME ("REALPART", "realpart", "RealPart", genNONE, specREALPART) /* GNU */ -DEFNAME ("RENAME", "rename", "Rename", genRENAME, specNONE) /* UNIX */ -DEFNAME ("REPEAT", "repeat", "Repeat", genNONE, specREPEAT) /* F90 */ -DEFNAME ("RESHAPE", "reshape", "Reshape", genNONE, specRESHAPE) /* F90 */ -DEFNAME ("RRSPACING", "rrspacing", "RRSpacing", genNONE, specRRSPACING) /* F90 */ -DEFNAME ("RSHIFT", "rshift", "RShift", genNONE, specRSHIFT) /* F2C */ -DEFNAME ("SCALE", "scale", "Scale", genNONE, specSCALE) /* F90 */ -DEFNAME ("SCAN", "scan", "Scan", genNONE, specSCAN) /* F90 */ -DEFNAME ("SECNDS", "secnds", "Secnds", genNONE, specSECNDS) /* VXT */ -DEFNAME ("SECOND", "second", "Second", genSECOND, specNONE) /* UNIX */ -DEFNAME ("SELECTED_INT_KIND", "selected_int_kind", "Selected_Int_Kind", genNONE, specSEL_INT_KIND) /* F90 */ -DEFNAME ("SELECTED_REAL_KIND", "selected_real_kind", "Selected_Real_Kind", genNONE, specSEL_REAL_KIND) /* F90 */ -DEFNAME ("SET_EXPONENT", "set_exponent", "Set_Exponent", genNONE, specSET_EXPONENT) /* F90 */ -DEFNAME ("SHAPE", "shape", "Shape", genNONE, specSHAPE) /* F90 */ -DEFNAME ("SHORT", "short", "Short", genNONE, specSHORT) /* UNIX */ -DEFNAME ("SIGN", "sign", "Sign", genNONE, specSIGN) -DEFNAME ("SIGNAL", "signal", "Signal", genSIGNAL, specNONE) /* UNIX */ -DEFNAME ("SIN", "sin", "Sin", genNONE, specSIN) -DEFNAME ("SIND", "sind", "SinD", genNONE, specSIND) /* VXT */ -DEFNAME ("SINH", "sinh", "SinH", genNONE, specSINH) -DEFNAME ("SLEEP", "sleep", "Sleep", genNONE, specSLEEP) /* UNIX */ -DEFNAME ("SNGL", "sngl", "Sngl", genNONE, specSNGL) -DEFNAME ("SNGLQ", "snglq", "SnglQ", genNONE, specSNGLQ) /* VXT */ -DEFNAME ("SPACING", "spacing", "Spacing", genNONE, specSPACING) /* F90 */ -DEFNAME ("SPREAD", "spread", "Spread", genNONE, specSPREAD) /* F90 */ -DEFNAME ("SQRT", "sqrt", "SqRt", genNONE, specSQRT) -DEFNAME ("SRAND", "srand", "SRand", genNONE, specSRAND) /* UNIX */ -DEFNAME ("STAT", "stat", "Stat", genSTAT, specNONE) /* UNIX */ -DEFNAME ("SUM", "sum", "Sum", genNONE, specSUM) /* F90 */ -DEFNAME ("SYMLNK", "symlnk", "SymLnk", genSYMLNK, specNONE) /* UNIX */ -DEFNAME ("SYSTEM", "system", "System", genSYSTEM, specNONE) /* UNIX */ -DEFNAME ("SYSTEM_CLOCK", "system_clock", "System_Clock", genNONE, specSYSTEM_CLOCK) /* F90 */ -DEFNAME ("TAN", "tan", "Tan", genNONE, specTAN) -DEFNAME ("TAND", "tand", "TanD", genNONE, specTAND) /* VXT */ -DEFNAME ("TANH", "tanh", "TanH", genNONE, specTANH) -DEFNAME ("TIME", "time", "Time", genTIME, specNONE) /* UNIX, VXT */ -DEFNAME ("TIME8", "time8", "Time8", genNONE, specTIME8) /* UNIX */ -DEFNAME ("TINY", "tiny", "Tiny", genNONE, specTINY) /* F90 */ -DEFNAME ("TRANSFER", "transfer", "Transfer", genNONE, specTRANSFER) /* F90 */ -DEFNAME ("TRANSPOSE", "transpose", "Transpose", genNONE, specTRANSPOSE) /* F90 */ -DEFNAME ("TRIM", "trim", "Trim", genNONE, specTRIM) /* F90 */ -DEFNAME ("TTYNAM", "ttynam", "TtyNam", genTTYNAM, specNONE) /* UNIX */ -DEFNAME ("UBOUND", "ubound", "UBound", genNONE, specUBOUND) /* F90 */ -DEFNAME ("UMASK", "umask", "UMask", genUMASK, specNONE) /* UNIX */ -DEFNAME ("UNLINK", "unlink", "Unlink", genUNLINK, specNONE) /* UNIX */ -DEFNAME ("UNPACK", "unpack", "Unpack", genNONE, specUNPACK) /* F90 */ -DEFNAME ("VERIFY", "verify", "Verify", genNONE, specVERIFY) /* F90 */ -DEFNAME ("XOR", "xor", "XOr", genNONE, specXOR) /* F2C */ -DEFNAME ("ZABS", "zabs", "ZAbs", genNONE, specZABS) /* F2C */ -DEFNAME ("ZCOS", "zcos", "ZCos", genNONE, specZCOS) /* F2C */ -DEFNAME ("ZEXP", "zexp", "ZExp", genNONE, specZEXP) /* F2C */ -DEFNAME ("ZEXT", "zext", "ZExt", genNONE, specZEXT) /* VXT */ -DEFNAME ("ZLOG", "zlog", "ZLog", genNONE, specZLOG) /* F2C */ -DEFNAME ("ZSIN", "zsin", "ZSin", genNONE, specZSIN) /* F2C */ -DEFNAME ("ZSQRT", "zsqrt", "ZSqRt", genNONE, specZSQRT) /* F2C */ - -/* Internally generic intrinsics. - - Should properly be called "mapped" intrinsics. These are intrinsics - that map to one or more generally different implementations -- e.g. - that have differing interpretations depending on the Fortran dialect - being used. Also, this includes the placeholder intrinsics that - have no specific versions, but we want to reserve the names for now. */ - -DEFGEN (CTIME, "CTIME", /* UNIX */ - FFEINTRIN_specCTIME_subr, - FFEINTRIN_specCTIME_func - ) -DEFGEN (CHDIR, "CHDIR", /* UNIX */ - FFEINTRIN_specCHDIR_subr, - FFEINTRIN_specCHDIR_func - ) -DEFGEN (CHMOD, "CHMOD", /* UNIX */ - FFEINTRIN_specCHMOD_subr, - FFEINTRIN_specCHMOD_func - ) -DEFGEN (DTIME, "DTIME", /* UNIX */ - FFEINTRIN_specDTIME_subr, - FFEINTRIN_specDTIME_func - ) -DEFGEN (ETIME, "ETIME", /* UNIX */ - FFEINTRIN_specETIME_subr, - FFEINTRIN_specETIME_func - ) -DEFGEN (FDATE, "FDATE", /* UNIX */ - FFEINTRIN_specFDATE_subr, - FFEINTRIN_specFDATE_func - ) -DEFGEN (FGET, "FGET", /* UNIX */ - FFEINTRIN_specFGET_subr, - FFEINTRIN_specFGET_func - ) -DEFGEN (FGETC, "FGETC", /* UNIX */ - FFEINTRIN_specFGETC_subr, - FFEINTRIN_specFGETC_func - ) -DEFGEN (FPABSP, "FPABSP", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPEXPN, "FPEXPN", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPFRAC, "FPFRAC", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPMAKE, "FPMAKE", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPRRSP, "FPRRSP", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPSCAL, "FPSCAL", /* F2C */ - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) -DEFGEN (FPUT, "FPUT", /* UNIX */ - FFEINTRIN_specFPUT_subr, - FFEINTRIN_specFPUT_func - ) -DEFGEN (FPUTC, "FPUTC", /* UNIX */ - FFEINTRIN_specFPUTC_subr, - FFEINTRIN_specFPUTC_func - ) -DEFGEN (FSTAT, "FSTAT", /* UNIX */ - FFEINTRIN_specFSTAT_subr, - FFEINTRIN_specFSTAT_func - ) -DEFGEN (FTELL, "FTELL", /* UNIX */ - FFEINTRIN_specFTELL_subr, - FFEINTRIN_specFTELL_func - ) -DEFGEN (GETCWD, "GETCWD", /* UNIX */ - FFEINTRIN_specGETCWD_subr, - FFEINTRIN_specGETCWD_func - ) -DEFGEN (HOSTNM, "HOSTNM", /* UNIX */ - FFEINTRIN_specHOSTNM_subr, - FFEINTRIN_specHOSTNM_func - ) -DEFGEN (IDATE, "IDATE", /* UNIX/VXT */ - FFEINTRIN_specIDATE_unix, - FFEINTRIN_specIDATE_vxt - ) -DEFGEN (KILL, "KILL", /* UNIX */ - FFEINTRIN_specKILL_subr, - FFEINTRIN_specKILL_func - ) -DEFGEN (LINK, "LINK", /* UNIX */ - FFEINTRIN_specLINK_subr, - FFEINTRIN_specLINK_func - ) -DEFGEN (LSTAT, "LSTAT", /* UNIX */ - FFEINTRIN_specLSTAT_subr, - FFEINTRIN_specLSTAT_func - ) -DEFGEN (RENAME, "RENAME", /* UNIX */ - FFEINTRIN_specRENAME_subr, - FFEINTRIN_specRENAME_func - ) -DEFGEN (SECOND, "SECOND", /* UNIX/CRAY */ - FFEINTRIN_specSECOND_func, - FFEINTRIN_specSECOND_subr - ) -DEFGEN (SIGNAL, "SIGNAL", /* UNIX */ - FFEINTRIN_specSIGNAL_subr, - FFEINTRIN_specSIGNAL_func - ) -DEFGEN (STAT, "STAT", /* UNIX */ - FFEINTRIN_specSTAT_subr, - FFEINTRIN_specSTAT_func - ) -DEFGEN (SYMLNK, "SYMLNK", /* UNIX */ - FFEINTRIN_specSYMLNK_subr, - FFEINTRIN_specSYMLNK_func - ) -DEFGEN (SYSTEM, "SYSTEM", /* UNIX */ - FFEINTRIN_specSYSTEM_subr, - FFEINTRIN_specSYSTEM_func - ) -DEFGEN (TIME, "TIME", /* UNIX/VXT */ - FFEINTRIN_specTIME_unix, - FFEINTRIN_specTIME_vxt - ) -DEFGEN (TTYNAM, "TTYNAM", /* UNIX/VXT */ - FFEINTRIN_specTTYNAM_subr, - FFEINTRIN_specTTYNAM_func - ) -DEFGEN (UMASK, "UMASK", /* UNIX */ - FFEINTRIN_specUMASK_subr, - FFEINTRIN_specUMASK_func - ) -DEFGEN (UNLINK, "UNLINK", /* UNIX */ - FFEINTRIN_specUNLINK_subr, - FFEINTRIN_specUNLINK_func - ) -DEFGEN (NONE, "none", - FFEINTRIN_specNONE, - FFEINTRIN_specNONE - ) - -/* Specific intrinsic information. - - Currently this list starts with the list of F77-standard intrinsics - in alphabetical order, then continues with the list of all other - intrinsics. - - The second boolean argument specifies whether the intrinsic is - allowed by the standard to be passed as an actual argument. */ - -DEFSPEC (ABS, - "ABS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impABS - ) -DEFSPEC (ACOS, - "ACOS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impACOS - ) -DEFSPEC (AIMAG, - "AIMAG", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impAIMAG - ) -DEFSPEC (AINT, - "AINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impAINT - ) -DEFSPEC (ALOG, - "ALOG", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impALOG - ) -DEFSPEC (ALOG10, - "ALOG10", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impALOG10 - ) -DEFSPEC (AMAX0, - "AMAX0", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impAMAX0 - ) -DEFSPEC (AMAX1, - "AMAX1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impAMAX1 - ) -DEFSPEC (AMIN0, - "AMIN0", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impAMIN0 - ) -DEFSPEC (AMIN1, - "AMIN1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impAMIN1 - ) -DEFSPEC (AMOD, - "AMOD", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impAMOD - ) -DEFSPEC (ANINT, - "ANINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impANINT - ) -DEFSPEC (ASIN, - "ASIN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impASIN - ) -DEFSPEC (ATAN, - "ATAN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impATAN - ) -DEFSPEC (ATAN2, - "ATAN2", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impATAN2 - ) -DEFSPEC (CABS, - "CABS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCABS - ) -DEFSPEC (CCOS, - "CCOS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCCOS - ) -DEFSPEC (CEXP, - "CEXP", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCEXP - ) -DEFSPEC (CHAR, - "CHAR", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impCHAR - ) -DEFSPEC (CLOG, - "CLOG", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCLOG - ) -DEFSPEC (CMPLX, - "CMPLX", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impCMPLX - ) -DEFSPEC (CONJG, - "CONJG", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCONJG - ) -DEFSPEC (COS, - "COS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCOS - ) -DEFSPEC (COSH, - "COSH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCOSH - ) -DEFSPEC (CSIN, - "CSIN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCSIN - ) -DEFSPEC (CSQRT, - "CSQRT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impCSQRT - ) -DEFSPEC (DABS, - "DABS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDABS - ) -DEFSPEC (DACOS, - "DACOS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDACOS - ) -DEFSPEC (DASIN, - "DASIN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDASIN - ) -DEFSPEC (DATAN, - "DATAN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDATAN - ) -DEFSPEC (DATAN2, - "DATAN2", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDATAN2 - ) -DEFSPEC (DBLE, - "DBLE", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impDBLE - ) -DEFSPEC (DCOS, - "DCOS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDCOS - ) -DEFSPEC (DCOSH, - "DCOSH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDCOSH - ) -DEFSPEC (DDIM, - "DDIM", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDDIM - ) -DEFSPEC (DEXP, - "DEXP", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDEXP - ) -DEFSPEC (DIM, - "DIM", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDIM - ) -DEFSPEC (DINT, - "DINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDINT - ) -DEFSPEC (DLOG, - "DLOG", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDLOG - ) -DEFSPEC (DLOG10, - "DLOG10", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDLOG10 - ) -DEFSPEC (DMAX1, - "DMAX1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impDMAX1 - ) -DEFSPEC (DMIN1, - "DMIN1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impDMIN1 - ) -DEFSPEC (DMOD, - "DMOD", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDMOD - ) -DEFSPEC (DNINT, - "DNINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDNINT - ) -DEFSPEC (DPROD, - "DPROD", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDPROD - ) -DEFSPEC (DSIGN, - "DSIGN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDSIGN - ) -DEFSPEC (DSIN, - "DSIN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDSIN - ) -DEFSPEC (DSINH, - "DSINH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDSINH - ) -DEFSPEC (DSQRT, - "DSQRT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDSQRT - ) -DEFSPEC (DTAN, - "DTAN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDTAN - ) -DEFSPEC (DTANH, - "DTANH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impDTANH - ) -DEFSPEC (EXP, - "EXP", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impEXP - ) -DEFSPEC (FLOAT, - "FLOAT", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impFLOAT - ) -DEFSPEC (IABS, - "IABS", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impIABS - ) -DEFSPEC (ICHAR, - "ICHAR", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impICHAR - ) -DEFSPEC (IDIM, - "IDIM", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impIDIM - ) -DEFSPEC (IDINT, - "IDINT", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impIDINT - ) -DEFSPEC (IDNINT, - "IDNINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impIDNINT - ) -DEFSPEC (IFIX, - "IFIX", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impIFIX - ) -DEFSPEC (INDEX, - "INDEX", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impINDEX - ) -DEFSPEC (INT, - "INT", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impINT - ) -DEFSPEC (ISIGN, - "ISIGN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impISIGN - ) -DEFSPEC (LEN, - "LEN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impLEN - ) -DEFSPEC (LGE, - "LGE", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLGE - ) -DEFSPEC (LGT, - "LGT", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLGT - ) -DEFSPEC (LLE, - "LLE", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLLE - ) -DEFSPEC (LLT, - "LLT", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLLT - ) -DEFSPEC (LOG, - "LOG", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLOG - ) -DEFSPEC (LOG10, - "LOG10", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impLOG10 - ) -DEFSPEC (MAX, - "MAX", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMAX - ) -DEFSPEC (MAX0, - "MAX0", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMAX0 - ) -DEFSPEC (MAX1, - "MAX1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMAX1 - ) -DEFSPEC (MIN, - "MIN", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMIN - ) -DEFSPEC (MIN0, - "MIN0", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMIN0 - ) -DEFSPEC (MIN1, - "MIN1", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impMIN1 - ) -DEFSPEC (MOD, - "MOD", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impMOD - ) -DEFSPEC (NINT, - "NINT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impNINT - ) -DEFSPEC (REAL, - "REAL", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impREAL - ) -DEFSPEC (SIGN, - "SIGN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impSIGN - ) -DEFSPEC (SIN, - "SIN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impSIN - ) -DEFSPEC (SINH, - "SINH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impSINH - ) -DEFSPEC (SNGL, - "SNGL", - FALSE, - FFEINTRIN_familyF77, - FFEINTRIN_impSNGL - ) -DEFSPEC (SQRT, - "SQRT", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impSQRT - ) -DEFSPEC (TAN, - "TAN", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impTAN - ) -DEFSPEC (TANH, - "TANH", - TRUE, - FFEINTRIN_familyF77, - FFEINTRIN_impTANH - ) - -DEFSPEC (ABORT, - "ABORT", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impABORT - ) -DEFSPEC (ACCESS, - "ACCESS", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impACCESS -) -DEFSPEC (ACHAR, - "ACHAR", - FALSE, - FFEINTRIN_familyASC, - FFEINTRIN_impACHAR - ) -DEFSPEC (ACOSD, - "ACOSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ADJUSTL, - "ADJUSTL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (ADJUSTR, - "ADJUSTR", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (AIMAX0, - "AIMAX0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (AIMIN0, - "AIMIN0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (AJMAX0, - "AJMAX0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (AJMIN0, - "AJMIN0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ALARM, - "ALARM", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impALARM - ) -DEFSPEC (ALL, - "ALL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (ALLOCATED, - "ALLOCATED", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (AND, - "AND", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impAND - ) -DEFSPEC (ANY, - "ANY", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (ASIND, - "ASIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ASSOCIATED, - "ASSOCIATED", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (ATAN2D, - "ATAN2D", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ATAND, - "ATAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (BESJ0, - "BESJ0", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESJ0 -) -DEFSPEC (BESJ1, - "BESJ1", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESJ1 -) -DEFSPEC (BESJN, - "BESJN", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESJN -) -DEFSPEC (BESY0, - "BESY0", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESY0 -) -DEFSPEC (BESY1, - "BESY1", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESY1 -) -DEFSPEC (BESYN, - "BESYN", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impBESYN -) -DEFSPEC (BIT_SIZE, - "BIT_SIZE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impBIT_SIZE - ) -DEFSPEC (BITEST, - "BITEST", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (BJTEST, - "BJTEST", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (BTEST, - "BTEST", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impBTEST - ) -DEFSPEC (CDABS, - "CDABS", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDABS - ) -DEFSPEC (CDCOS, - "CDCOS", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDCOS - ) -DEFSPEC (CDEXP, - "CDEXP", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDEXP - ) -DEFSPEC (CDLOG, - "CDLOG", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDLOG - ) -DEFSPEC (CDSIN, - "CDSIN", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDSIN - ) -DEFSPEC (CDSQRT, - "CDSQRT", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impCDSQRT - ) -DEFSPEC (CEILING, - "CEILING", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (CHDIR_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impCHDIR_func -) -DEFSPEC (CHDIR_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impCHDIR_subr -) -DEFSPEC (CHMOD_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impCHMOD_func -) -DEFSPEC (CHMOD_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impCHMOD_subr -) -DEFSPEC (COMPLEX, - "COMPLEX", - FALSE, - FFEINTRIN_familyGNU, - FFEINTRIN_impCOMPLEX - ) -DEFSPEC (COSD, - "COSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (COUNT, - "COUNT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (CSHIFT, - "CSHIFT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (CPU_TIME, - "CPU_TIME", - FALSE, - FFEINTRIN_familyF95, - FFEINTRIN_impCPU_TIME -) -DEFSPEC (CTIME_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impCTIME_func -) -DEFSPEC (CTIME_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impCTIME_subr -) -DEFSPEC (DACOSD, - "DACOSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DASIND, - "DASIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DATAN2D, - "DATAN2D", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DATAND, - "DATAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DATE, - "DATE", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impDATE -) -DEFSPEC (DATE_AND_TIME, - "DATE_AND_TIME", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impDATE_AND_TIME - ) -DEFSPEC (DBESJ0, - "DBESJ0", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESJ0 -) -DEFSPEC (DBESJ1, - "DBESJ1", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESJ1 -) -DEFSPEC (DBESJN, - "DBESJN", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESJN -) -DEFSPEC (DBESY0, - "DBESY0", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESY0 -) -DEFSPEC (DBESY1, - "DBESY1", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESY1 -) -DEFSPEC (DBESYN, - "DBESYN", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDBESYN -) -DEFSPEC (DBLEQ, - "DBLEQ", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DCMPLX, - "DCMPLX", - FALSE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impDCMPLX - ) -DEFSPEC (DCONJG, - "DCONJG", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impDCONJG - ) -DEFSPEC (DCOSD, - "DCOSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DERF, - "DERF", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDERF - ) -DEFSPEC (DERFC, - "DERFC", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDERFC - ) -DEFSPEC (DFLOAT, - "DFLOAT", - FALSE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impDFLOAT - ) -DEFSPEC (DFLOTI, - "DFLOTI", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DFLOTJ, - "DFLOTJ", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DIGITS, - "DIGITS", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (DIMAG, - "DIMAG", - TRUE, - FFEINTRIN_familyFVZ, - FFEINTRIN_impDIMAG - ) -DEFSPEC (DOT_PRODUCT, - "DOT_PRODUCT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (DREAL, - "DREAL", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impDREAL - ) -DEFSPEC (DSIND, - "DSIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DTAND, - "DTAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (DTIME_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impDTIME_func -) -DEFSPEC (DTIME_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impDTIME_subr -) -DEFSPEC (EOSHIFT, - "EOSHIFT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (EPSILON, - "EPSILON", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (ERF, - "ERF", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impERF - ) -DEFSPEC (ERFC, - "ERFC", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impERFC - ) -DEFSPEC (ETIME_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impETIME_func -) -DEFSPEC (ETIME_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impETIME_subr -) -DEFSPEC (EXIT, - "EXIT", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impEXIT - ) -DEFSPEC (EXPONENT, - "EXPONENT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (FDATE_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFDATE_func -) -DEFSPEC (FDATE_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFDATE_subr -) -DEFSPEC (FGET_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impFGET_func -) -DEFSPEC (FGET_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFGET_subr -) -DEFSPEC (FGETC_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impFGETC_func -) -DEFSPEC (FGETC_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFGETC_subr -) -DEFSPEC (FLOATI, - "FLOATI", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (FLOATJ, - "FLOATJ", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (FLOOR, - "FLOOR", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (FLUSH, - "FLUSH", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFLUSH - ) -DEFSPEC (FNUM, - "FNUM", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFNUM -) -DEFSPEC (FPUT_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impFPUT_func -) -DEFSPEC (FPUT_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFPUT_subr -) -DEFSPEC (FPUTC_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impFPUTC_func -) -DEFSPEC (FPUTC_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFPUTC_subr -) -DEFSPEC (FRACTION, - "FRACTION", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (FSEEK, - "FSEEK", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFSEEK - ) -DEFSPEC (FSTAT_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFSTAT_func -) -DEFSPEC (FSTAT_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFSTAT_subr -) -DEFSPEC (FTELL_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFTELL_func - ) -DEFSPEC (FTELL_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impFTELL_subr - ) -DEFSPEC (GERROR, - "GERROR", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGERROR -) -DEFSPEC (GETARG, - "GETARG", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETARG - ) -DEFSPEC (GETCWD_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETCWD_func -) -DEFSPEC (GETCWD_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETCWD_subr -) -DEFSPEC (GETENV, - "GETENV", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETENV - ) -DEFSPEC (GETGID, - "GETGID", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETGID -) -DEFSPEC (GETLOG, - "GETLOG", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETLOG -) -DEFSPEC (GETPID, - "GETPID", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETPID -) -DEFSPEC (GETUID, - "GETUID", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGETUID -) -DEFSPEC (GMTIME, - "GMTIME", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impGMTIME -) -DEFSPEC (HOSTNM_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impHOSTNM_func -) -DEFSPEC (HOSTNM_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impHOSTNM_subr -) -DEFSPEC (HUGE, - "HUGE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (IACHAR, - "IACHAR", - FALSE, - FFEINTRIN_familyASC, - FFEINTRIN_impIACHAR - ) -DEFSPEC (IAND, - "IAND", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIAND - ) -DEFSPEC (IARGC, - "IARGC", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impIARGC - ) -DEFSPEC (IBCLR, - "IBCLR", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIBCLR - ) -DEFSPEC (IBITS, - "IBITS", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIBITS - ) -DEFSPEC (IBSET, - "IBSET", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIBSET - ) -DEFSPEC (IDATE_unix, - "UNIX", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impIDATE_unix -) -DEFSPEC (IDATE_vxt, - "VXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impIDATE_vxt -) -DEFSPEC (IEOR, - "IEOR", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIEOR - ) -DEFSPEC (IERRNO, - "IERRNO", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impIERRNO -) -DEFSPEC (IIABS, - "IIABS", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIAND, - "IIAND", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIBCLR, - "IIBCLR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIBITS, - "IIBITS", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIBSET, - "IIBSET", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIDIM, - "IIDIM", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIDINT, - "IIDINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIDNNT, - "IIDNNT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIEOR, - "IIEOR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIFIX, - "IIFIX", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IINT, - "IINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIOR, - "IIOR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIQINT, - "IIQINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IIQNNT, - "IIQNNT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IISHFT, - "IISHFT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IISHFTC, - "IISHFTC", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IISIGN, - "IISIGN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IMAG, - "IMAG", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impIMAGPART - ) -DEFSPEC (IMAGPART, - "IMAGPART", - FALSE, - FFEINTRIN_familyGNU, - FFEINTRIN_impIMAGPART - ) -DEFSPEC (IMAX0, - "IMAX0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IMAX1, - "IMAX1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IMIN0, - "IMIN0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IMIN1, - "IMIN1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (IMOD, - "IMOD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ININT, - "ININT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (INOT, - "INOT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (INT2, - "INT2", - FALSE, - FFEINTRIN_familyGNU, - FFEINTRIN_impINT2 - ) -DEFSPEC (INT8, - "INT8", - FALSE, - FFEINTRIN_familyGNU, - FFEINTRIN_impINT8 - ) -DEFSPEC (IOR, - "IOR", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impIOR - ) -DEFSPEC (IRAND, - "IRAND", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impIRAND -) -DEFSPEC (ISATTY, - "ISATTY", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impISATTY -) -DEFSPEC (ISHFT, - "ISHFT", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impISHFT - ) -DEFSPEC (ISHFTC, - "ISHFTC", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impISHFTC - ) -DEFSPEC (ITIME, - "ITIME", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impITIME -) -DEFSPEC (IZEXT, - "IZEXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIABS, - "JIABS", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIAND, - "JIAND", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIBCLR, - "JIBCLR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIBITS, - "JIBITS", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIBSET, - "JIBSET", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIDIM, - "JIDIM", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIDINT, - "JIDINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIDNNT, - "JIDNNT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIEOR, - "JIEOR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIFIX, - "JIFIX", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JINT, - "JINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIOR, - "JIOR", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIQINT, - "JIQINT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JIQNNT, - "JIQNNT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JISHFT, - "JISHFT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JISHFTC, - "JISHFTC", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JISIGN, - "JISIGN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JMAX0, - "JMAX0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JMAX1, - "JMAX1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JMIN0, - "JMIN0", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JMIN1, - "JMIN1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JMOD, - "JMOD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JNINT, - "JNINT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JNOT, - "JNOT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (JZEXT, - "JZEXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (KILL_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impKILL_func -) -DEFSPEC (KILL_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impKILL_subr -) -DEFSPEC (KIND, - "KIND", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (LBOUND, - "LBOUND", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (LINK_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impLINK_func -) -DEFSPEC (LINK_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLINK_subr -) -DEFSPEC (LEN_TRIM, - "LEN_TRIM", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impLNBLNK - ) -DEFSPEC (LNBLNK, - "LNBLNK", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLNBLNK -) -DEFSPEC (LOC, - "LOC", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLOC - ) -DEFSPEC (LOGICAL, - "LOGICAL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (LONG, - "LONG", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLONG - ) -DEFSPEC (LSHIFT, - "LSHIFT", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impLSHIFT - ) -DEFSPEC (LSTAT_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLSTAT_func -) -DEFSPEC (LSTAT_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLSTAT_subr -) -DEFSPEC (LTIME, - "LTIME", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impLTIME -) -DEFSPEC (MATMUL, - "MATMUL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MAXEXPONENT, - "MAXEXPONENT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MAXLOC, - "MAXLOC", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MAXVAL, - "MAXVAL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MCLOCK, - "MCLOCK", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impMCLOCK -) -DEFSPEC (MCLOCK8, - "MCLOCK8", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impMCLOCK8 -) -DEFSPEC (MERGE, - "MERGE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MINEXPONENT, - "MINEXPONENT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MINLOC, - "MINLOC", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MINVAL, - "MINVAL", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MODULO, - "MODULO", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (MVBITS, - "MVBITS", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impMVBITS - ) -DEFSPEC (NEAREST, - "NEAREST", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (NOT, - "NOT", - FALSE, - FFEINTRIN_familyMIL, - FFEINTRIN_impNOT - ) -DEFSPEC (OR, - "OR", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impOR - ) -DEFSPEC (PACK, - "PACK", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (PERROR, - "PERROR", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impPERROR -) -DEFSPEC (PRECISION, - "PRECISION", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (PRESENT, - "PRESENT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (PRODUCT, - "PRODUCT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (QABS, - "QABS", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QACOS, - "QACOS", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QACOSD, - "QACOSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QASIN, - "QASIN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QASIND, - "QASIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QATAN, - "QATAN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QATAN2, - "QATAN2", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QATAN2D, - "QATAN2D", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QATAND, - "QATAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QCOS, - "QCOS", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QCOSD, - "QCOSD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QCOSH, - "QCOSH", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QDIM, - "QDIM", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QEXP, - "QEXP", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QEXT, - "QEXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QEXTD, - "QEXTD", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QFLOAT, - "QFLOAT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QINT, - "QINT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QLOG, - "QLOG", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QLOG10, - "QLOG10", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QMAX1, - "QMAX1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QMIN1, - "QMIN1", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QMOD, - "QMOD", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QNINT, - "QNINT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QSIGN, - "QSIGN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QSIN, - "QSIN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QSIND, - "QSIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QSINH, - "QSINH", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QSQRT, - "QSQRT", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QTAN, - "QTAN", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QTAND, - "QTAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (QTANH, - "QTANH", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (RADIX, - "RADIX", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RAND, - "RAND", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impRAND -) -DEFSPEC (RANDOM_NUMBER, - "RANDOM_NUMBER", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RANDOM_SEED, - "RANDOM_SEED", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RANGE, - "RANGE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (REALPART, - "REALPART", - FALSE, - FFEINTRIN_familyGNU, - FFEINTRIN_impREALPART - ) -DEFSPEC (RENAME_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impRENAME_func -) -DEFSPEC (RENAME_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impRENAME_subr -) -DEFSPEC (REPEAT, - "REPEAT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RESHAPE, - "RESHAPE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RRSPACING, - "RRSPACING", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (RSHIFT, - "RSHIFT", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impRSHIFT - ) -DEFSPEC (SCALE, - "SCALE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SCAN, - "SCAN", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SECNDS, - "SECNDS", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impSECNDS -) -DEFSPEC (SECOND_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSECOND_func -) -DEFSPEC (SECOND_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSECOND_subr -) -DEFSPEC (SEL_INT_KIND, - "SEL_INT_KIND", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SEL_REAL_KIND, - "SEL_REAL_KIND", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SET_EXPONENT, - "SET_EXPONENT", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SHAPE, - "SHAPE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SHORT, - "SHORT", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSHORT - ) -DEFSPEC (SIGNAL_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impSIGNAL_func - ) -DEFSPEC (SIGNAL_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSIGNAL_subr - ) -DEFSPEC (SIND, - "SIND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (SLEEP, - "SLEEP", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSLEEP -) -DEFSPEC (SNGLQ, - "SNGLQ", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (SPACING, - "SPACING", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SPREAD, - "SPREAD", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SRAND, - "SRAND", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSRAND -) -DEFSPEC (STAT_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSTAT_func -) -DEFSPEC (STAT_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSTAT_subr -) -DEFSPEC (SUM, - "SUM", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (SYMLNK_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impSYMLNK_func -) -DEFSPEC (SYMLNK_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSYMLNK_subr -) -DEFSPEC (SYSTEM_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impSYSTEM_func - ) -DEFSPEC (SYSTEM_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impSYSTEM_subr - ) -DEFSPEC (SYSTEM_CLOCK, - "SYSTEM_CLOCK", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impSYSTEM_CLOCK - ) -DEFSPEC (TAND, - "TAND", - TRUE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (TIME8, - "UNIX", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impTIME8 -) -DEFSPEC (TIME_unix, - "UNIX", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impTIME_unix -) -DEFSPEC (TIME_vxt, - "VXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impTIME_vxt -) -DEFSPEC (TINY, - "TINY", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (TRANSFER, - "TRANSFER", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (TRANSPOSE, - "TRANSPOSE", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (TRIM, - "TRIM", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (TTYNAM_func, - "function", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impTTYNAM_func -) -DEFSPEC (TTYNAM_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impTTYNAM_subr -) -DEFSPEC (UBOUND, - "UBOUND", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (UMASK_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impUMASK_func -) -DEFSPEC (UMASK_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impUMASK_subr -) -DEFSPEC (UNLINK_func, - "function", - FALSE, - FFEINTRIN_familyBADU77, - FFEINTRIN_impUNLINK_func -) -DEFSPEC (UNLINK_subr, - "subroutine", - FALSE, - FFEINTRIN_familyF2U, - FFEINTRIN_impUNLINK_subr -) -DEFSPEC (UNPACK, - "UNPACK", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (VERIFY, - "VERIFY", - FALSE, - FFEINTRIN_familyF90, - FFEINTRIN_impNONE - ) -DEFSPEC (XOR, - "XOR", - FALSE, - FFEINTRIN_familyF2C, - FFEINTRIN_impXOR - ) -DEFSPEC (ZABS, - "ZABS", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDABS - ) -DEFSPEC (ZCOS, - "ZCOS", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDCOS - ) -DEFSPEC (ZEXP, - "ZEXP", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDEXP - ) -DEFSPEC (ZEXT, - "ZEXT", - FALSE, - FFEINTRIN_familyVXT, - FFEINTRIN_impNONE - ) -DEFSPEC (ZLOG, - "ZLOG", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDLOG - ) -DEFSPEC (ZSIN, - "ZSIN", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDSIN - ) -DEFSPEC (ZSQRT, - "ZSQRT", - TRUE, - FFEINTRIN_familyF2C, - FFEINTRIN_impCDSQRT - ) -DEFSPEC (NONE, - "none", - FALSE, - FFEINTRIN_familyNONE, - FFEINTRIN_impNONE - ) - -/* Intrinsic implementations ordered in two sections: - F77, then extensions; secondarily, alphabetical - ordering. */ - -/* The DEFIMP macro specifies the following fields for an intrinsic: - - CODE -- The internal name for this intrinsic; `FFEINTRIN_imp' - prepends this to form the `enum' name. - - NAME -- The textual name to use when printing information on - this intrinsic. - - GFRTDIRECT -- The run-time library routine that is suitable for - a call to implement a *direct* invocation of the - intrinsic (e.g. `ABS(10)'). - - GFRTF2C -- The run-time library routine that is suitable for - passing as an argument to a procedure that will - invoke the argument as an EXTERNAL procedure, when - f2c calling conventions will be used (e.g. - `CALL FOO(ABS)', when FOO compiled with -ff2c). - - GFRTGNU -- The run-time library routine that is suitable for - passing as an argument to a procedure that will - invoke the argument as an EXTERNAL procedure, when - GNU calling conventions will be used (e.g. - `CALL FOO(ABS)', when FOO compiled with -fno-f2c). - - CONTROL -- A control string, described below. - -*/ - -/* The control string has the following format: - - <return-type>:<arglist-info>:[<argitem-info>,...] - - <return-type> is: - - <return-base-type><return-kind-type>[<return-modifier>] - - <return-base-type> is: - - - Subroutine - A Character - C Complex - I Integer - L Logical - R Real - B Boolean (I or L), decided by co-operand list (COL) - F Floating-point (C or R), decided by COL - N Numeric (C, I, or R), decided by co-operand list (COL) - S Scalar numeric (I or R), decided by COL, which may be COMPLEX - - <return-kind-type> is: - - - Subroutine - = Decided by COL - 1 (Default) - 2 (Twice the size of 1) - 3 (Same size as CHARACTER*1) - 4 (Twice the size of 2) - 6 (Twice the size as 3) - 7 (Same size as `char *') - C Like 1 (F77), except (F90), if COL is COMPLEX, uses kind type of COL - - <return-modifier> is: - - * Valid for <return-base-type> of `A' only, means program may - declare any length for return value, default being (*) - - <arglist-info> is: - - <COL-spec> - - <COL-spec> is: - - - No COL (return-base-type and return-kind-type must be definitive) - * All arguments form COL (must have more than one argument) - n Argument n (0 for first arg, 1 for second, etc.) forms COL - - <argitem-info> is: - - <name>=[<optionality>]<arg-base-type><arg-kind-type>[<arg-len>][<arg-rank>][<arg-extra>] - - <name> is the standard keyword name for the argument. - - <optionality> is: - - ? Argument is optional - ! Like ?, but argument must be omitted if previous arg was COMPLEX - + One or more of these arguments must be specified - * Zero or more of these arguments must be specified - n Numbered names for arguments, one or more must be specified - p Like n, but two or more must be specified - - <arg-base-type> is: - - - Any is valid (arg-kind-type is 0) - A Character*(*) - C Complex - I Integer - L Logical - R Real - B Boolean (I or L) - F Floating-point (C or R) - N Numeric (C, I, or R) - S Scalar numeric (I or R) - g GOTO label (alternate-return form of CALL) (arg-kind-type is 0) - s Signal handler (INTEGER FUNCTION, SUBROUTINE or dummy/global - default INTEGER variable) (arg-kind-type is 0) - - <arg-kind-type> is: - - * Any is valid - 1 (Default) - 2 (Twice the size of 1) - 3 (Same size as CHARACTER*1) - 4 (Twice the size of 2) - 6 (Twice the size as 3) - A Same as first argument - - <arg-len> is: - - (Default) CHARACTER*(*) - [n] CHARACTER*n - - <arg-rank> is: - - (default) Rank-0 (variable or array element) - (n) Rank-1 array n elements long - & Any (arg-extra is &) - - <arg-extra> is: - - (default) Arg is INTENT(IN) - i Arg's attributes are all that matter (inquiry function) - w Arg is INTENT(OUT) - x Arg is INTENT(INOUT) - & Arg can have its address taken (LOC(), for example) - -*/ - -DEFIMP (ABS, "ABS", ,ABS,, "S=:0:A=N*") -DEFIMP (ACOS, "ACOS", L_ACOS,ACOS,, "R=:0:X=R*") -DEFIMP (AIMAG, "AIMAG", ,AIMAG,, "RC:0:Z=C*") -DEFIMP (AINT, "AINT", ,AINT,, "R=:0:A=R*") -DEFIMP (ALOG, "ALOG", L_LOG,ALOG,, "R1:-:X=R1") -DEFIMP (ALOG10, "ALOG10", ,ALOG10,, "R1:-:X=R1") -DEFIMP (AMAX0, "AMAX0", ,,, "R1:*:A=pI1") -DEFIMP (AMAX1, "AMAX1", ,,, "R1:*:A=pR1") -DEFIMP (AMIN0, "AMIN0", ,,, "R1:*:A=pI1") -DEFIMP (AMIN1, "AMIN1", ,,, "R1:*:A=pR1") -DEFIMP (AMOD, "AMOD", ,AMOD,, "R1:*:A=R1,P=R1") -DEFIMP (ANINT, "ANINT", ,ANINT,, "R=:0:A=R*") -DEFIMP (ASIN, "ASIN", L_ASIN,ASIN,, "R=:0:X=R*") -DEFIMP (ATAN, "ATAN", L_ATAN,ATAN,, "R=:0:X=R*") -DEFIMP (ATAN2, "ATAN2", L_ATAN2,ATAN2,, "R=:*:Y=R*,X=R*") -DEFIMP (CABS, "CABS", ,CABS,, "R1:-:A=C1") -DEFIMP (CCOS, "CCOS", ,CCOS,, "C1:-:X=C1") -DEFIMP (CEXP, "CEXP", ,CEXP,, "C1:-:X=C1") -DEFIMP (CHAR, "CHAR", ,,, "A1:-:I=I*") -DEFIMP (CLOG, "CLOG", ,CLOG,, "C1:-:X=C1") -DEFIMP (CMPLX, "CMPLX", ,,, "C1:*:X=N*,Y=!S*") -DEFIMP (CONJG, "CONJG", ,CONJG,, "C=:0:Z=C*") -DEFIMP (COS, "COS", L_COS,COS,, "F=:0:X=F*") -DEFIMP (COSH, "COSH", L_COSH,COSH,, "R=:0:X=R*") -DEFIMP (CSIN, "CSIN", ,CSIN,, "C1:-:X=C1") -DEFIMP (CSQRT, "CSQRT", ,CSQRT,, "C1:-:X=C1") -DEFIMP (DABS, "DABS", ,DABS,, "R2:-:A=R2") -DEFIMP (DACOS, "DACOS", L_ACOS,DACOS,, "R2:-:X=R2") -DEFIMP (DASIN, "DASIN", L_ASIN,DASIN,, "R2:-:X=R2") -DEFIMP (DATAN, "DATAN", L_ATAN,DATAN,, "R2:-:X=R2") -DEFIMP (DATAN2, "DATAN2", L_ATAN2,DATAN2,,"R2:*:Y=R2,X=R2") -DEFIMP (DBLE, "DBLE", ,,, "R2:-:A=N*") -DEFIMP (DCMPLX, "DCMPLX", ,,, "C2:*:X=N*,Y=!S*") -DEFIMP (DCOS, "DCOS", L_COS,DCOS,, "R2:-:X=R2") -DEFIMP (DCOSH, "DCOSH", L_COSH,DCOSH,, "R2:-:X=R2") -DEFIMP (DDIM, "DDIM", ,DDIM,, "R2:*:X=R2,Y=R2") -DEFIMP (DEXP, "DEXP", L_EXP,DEXP,, "R2:-:X=R2") -DEFIMP (DIM, "DIM", ,DIM,, "S=:*:X=S*,Y=S*") -DEFIMP (DINT, "DINT", ,DINT,, "R2:-:A=R2") -DEFIMP (DLOG, "DLOG", L_LOG,DLOG,, "R2:-:X=R2") -DEFIMP (DLOG10, "DLOG10", ,DLOG10,, "R2:-:X=R2") -DEFIMP (DMAX1, "DMAX1", ,,, "R2:*:A=pR2") -DEFIMP (DMIN1, "DMIN1", ,,, "R2:*:A=pR2") -DEFIMP (DMOD, "DMOD", ,DMOD,, "R2:*:A=R2,P=R2") -DEFIMP (DNINT, "DNINT", ,DNINT,, "R2:-:A=R2") -DEFIMP (DPROD, "DPROD", ,DPROD,, "R2:*:X=R1,Y=R1") -DEFIMP (DSIGN, "DSIGN", ,DSIGN,, "R2:*:A=R2,B=R2") -DEFIMP (DSIN, "DSIN", L_SIN,DSIN,, "R2:-:X=R2") -DEFIMP (DSINH, "DSINH", L_SINH,DSINH,, "R2:-:X=R2") -DEFIMP (DSQRT, "DSQRT", L_SQRT,DSQRT,, "R2:-:X=R2") -DEFIMP (DTAN, "DTAN", L_TAN,DTAN,, "R2:-:X=R2") -DEFIMP (DTANH, "DTANH", L_TANH,DTANH,, "R2:-:X=R2") -DEFIMP (EXP, "EXP", L_EXP,EXP,, "F=:0:X=F*") -DEFIMP (FLOAT, "FLOAT", ,,, "R1:-:A=I*") -DEFIMP (IABS, "IABS", ,IABS,IABS, "I1:-:A=I1") -DEFIMP (ICHAR, "ICHAR", ,,, "I1:-:C=A*") -DEFIMP (IDIM, "IDIM", ,IDIM,IDIM, "I1:*:X=I1,Y=I1") -DEFIMP (IDINT, "IDINT", ,,, "I1:-:A=R2") -DEFIMP (IDNINT, "IDNINT", ,IDNINT,IDNINT, "I1:-:A=R2") -DEFIMP (IFIX, "IFIX", ,,, "I1:-:A=R1") -DEFIMP (INDEX, "INDEX", ,INDEX,INDEX, "I1:*:String=A*,Substring=A*") -DEFIMP (INT, "INT", ,,, "I1:-:A=N*") -DEFIMP (ISIGN, "ISIGN", ,ISIGN,ISIGN, "I1:*:A=I1,B=I1") -DEFIMP (LEN, "LEN", ,LEN,LEN, "I1:-:String=A*i") -DEFIMP (LGE, "LGE", ,LGE,LGE, "L1:*:String_A=A1,String_B=A1") -DEFIMP (LGT, "LGT", ,LGT,LGT, "L1:*:String_A=A1,String_B=A1") -DEFIMP (LLE, "LLE", ,LLE,LLE, "L1:*:String_A=A1,String_B=A1") -DEFIMP (LLT, "LLT", ,LLT,LLT, "L1:*:String_A=A1,String_B=A1") -DEFIMP (LOG, "LOG", L_LOG,ALOG,, "F=:0:X=F*") -DEFIMP (LOG10, "LOG10", ,,, "R=:0:X=R*") -DEFIMP (MAX, "MAX", ,,, "S=:*:A=pS*") -DEFIMP (MIN, "MIN", ,,, "S=:*:A=pS*") -DEFIMP (MAX0, "MAX0", ,,, "I1:*:A=pI1") -DEFIMP (MAX1, "MAX1", ,,, "I1:*:A=pR1") -DEFIMP (MIN0, "MIN0", ,,, "I1:*:A=pI1") -DEFIMP (MIN1, "MIN1", ,,, "I1:*:A=pR1") -DEFIMP (MOD, "MOD", ,MOD,MOD, "S=:*:A=S*,P=S*") -DEFIMP (NINT, "NINT", ,NINT,NINT, "I1:-:A=R*") -DEFIMP (REAL, "REAL", ,,, "RC:0:A=N*") -DEFIMP (SIGN, "SIGN", ,SIGN,, "S=:*:A=S*,B=S*") -DEFIMP (SIN, "SIN", L_SIN,SIN,, "F=:0:X=F*") -DEFIMP (SINH, "SINH", L_SINH,SINH,, "R=:0:X=R*") -DEFIMP (SNGL, "SNGL", ,,, "R1:-:A=R2") -DEFIMP (SQRT, "SQRT", L_SQRT,SQRT,, "F=:0:X=F*") -DEFIMP (TAN, "TAN", L_TAN,TAN,, "R=:0:X=R*") -DEFIMP (TANH, "TANH", L_TANH,TANH,, "R=:0:X=R*") - -DEFIMP (ABORT, "ABORT", ABORT,,, "--:-:") -DEFIMP (ACCESS, "ACCESS", ACCESS,,, "I1:-:Name=A1,Mode=A1") -DEFIMP (ACHAR, "ACHAR", ,,, "A1:-:I=I*") -DEFIMP (ALARM, "ALARM", ALARM,,, "--:-:Seconds=I*,Handler=s*,Status=?I1w") -DEFIMP (AND, "AND", ,,, "B=:*:I=B*,J=B*") -DEFIMP (BESJ0, "BESJ0", L_BESJ0,,, "R=:0:X=R*") -DEFIMP (BESJ1, "BESJ1", L_BESJ1,,, "R=:0:X=R*") -DEFIMP (BESJN, "BESJN", L_BESJN,,, "R=:1:N=I*,X=R*") -DEFIMP (BESY0, "BESY0", L_BESY0,,, "R=:0:X=R*") -DEFIMP (BESY1, "BESY1", L_BESY1,,, "R=:0:X=R*") -DEFIMP (BESYN, "BESYN", L_BESYN,,, "R=:1:N=I*,X=R*") -DEFIMP (BIT_SIZE, "BIT_SIZE", ,,, "I=:0:I=I*i") -DEFIMP (BTEST, "BTEST", ,,, "L1:*:I=I*,Pos=I*") -DEFIMP (CDABS, "CDABS", ,CDABS,, "R2:-:A=C2") -DEFIMP (CDCOS, "CDCOS", ,CDCOS,, "C2:-:X=C2") -DEFIMP (CDEXP, "CDEXP", ,CDEXP,, "C2:-:X=C2") -DEFIMP (CDLOG, "CDLOG", ,CDLOG,, "C2:-:X=C2") -DEFIMP (CDSIN, "CDSIN", ,CDSIN,, "C2:-:X=C2") -DEFIMP (CDSQRT, "CDSQRT", ,CDSQRT,, "C2:-:X=C2") -DEFIMP (CHDIR_func, "CHDIR_func", CHDIR,,, "I1:-:Dir=A1") -DEFIMP (CHDIR_subr, "CHDIR_subr", CHDIR,,, "--:-:Dir=A1,Status=?I1w") -DEFIMP (CHMOD_func, "CHMOD_func", CHMOD,,, "I1:-:Name=A1,Mode=A1") -DEFIMP (CHMOD_subr, "CHMOD_subr", CHMOD,,, "--:-:Name=A1,Mode=A1,Status=?I1w") -DEFIMP (COMPLEX, "COMPLEX", ,,, "C=:*:Real=S*,Imag=S*") -DEFIMP (CPU_TIME, "CPU_TIME", SECOND,,, "--:-:Seconds=R*w") -DEFIMP (CTIME_func, "CTIME_func", CTIME,,, "A1*:-:STime=I*") -DEFIMP (CTIME_subr, "CTIME_subr", CTIME,,, "--:-:Result=A1w,STime=I*") -DEFIMP (DATE, "DATE", DATE,,, "--:-:Date=A1w") -DEFIMP (DATE_AND_TIME, "DATE_AND_TIME", DATE_AND_TIME,,, "--:-:Date=A1w,Time=?A1w,Zone=?A1w,Values=?I1(8)w") -DEFIMP (DBESJ0, "DBESJ0", L_BESJ0,,, "R2:-:X=R2") -DEFIMP (DBESJ1, "DBESJ1", L_BESJ1,,, "R2:-:X=R2") -DEFIMP (DBESJN, "DBESJN", L_BESJN,,, "R2:-:N=I*,X=R2") -DEFIMP (DBESY0, "DBESY0", L_BESY0,,, "R2:-:X=R2") -DEFIMP (DBESY1, "DBESY1", L_BESY1,,, "R2:-:X=R2") -DEFIMP (DBESYN, "DBESYN", L_BESYN,,, "R2:-:N=I*,X=R2") -DEFIMP (DCONJG, "DCONJG", ,DCONJG,, "C2:-:Z=C2") -DEFIMP (DERF, "DERF", L_ERF,DERF,, "R2:-:X=R2") -DEFIMP (DERFC, "DERFC", L_ERFC,DERFC,, "R2:-:X=R2") -DEFIMP (DFLOAT, "DFLOAT", ,,, "R2:-:A=I*") -DEFIMP (DIMAG, "DIMAG", ,DIMAG,, "R2:-:Z=C2") -DEFIMP (DREAL, "DREAL", ,,, "R2:-:A=N*") -DEFIMP (DTIME_func, "DTIME_func", DTIME,,, "R1:-:TArray=R1(2)w") -DEFIMP (DTIME_subr, "DTIME_subr", DTIME,,, "--:-:Result=R1w,TArray=R1(2)w") -DEFIMP (ERF, "ERF", L_ERF,ERF,, "R=:0:X=R*") -DEFIMP (ERFC, "ERFC", L_ERFC,ERFC,, "R=:0:X=R*") -DEFIMP (ETIME_func, "ETIME_func", ETIME,,, "R1:-:TArray=R1(2)w") -DEFIMP (ETIME_subr, "ETIME_subr", ETIME,,, "--:-:Result=R1w,TArray=R1(2)w") -DEFIMP (EXIT, "EXIT", EXIT,,, "--:-:Status=?I*") -DEFIMP (FDATE_func, "FDATE_func", FDATE,,, "A1*:-:") -DEFIMP (FDATE_subr, "FDATE_subr", FDATE,,, "--:-:Date=A1w") -DEFIMP (FGET_func, "FGET_func", FGET,,, "I1:-:C=A1w") -DEFIMP (FGET_subr, "FGET_subr", FGET,,, "--:-:C=A1w,Status=?I1w") -DEFIMP (FGETC_func, "FGETC_func", FGETC,,, "I1:-:Unit=I*,C=A1w") -DEFIMP (FGETC_subr, "FGETC_subr", FGETC,,, "--:-:Unit=I*,C=A1w,Status=?I1w") -DEFIMP (FLUSH, "FLUSH", ,,, "--:-:Unit=?I*") -DEFIMP (FNUM, "FNUM", FNUM,,, "I1:-:Unit=I*") -DEFIMP (FPUT_func, "FPUT_func", FPUT,,, "I1:-:C=A1") -DEFIMP (FPUT_subr, "FPUT_subr", FPUT,,, "--:-:C=A1,Status=?I1w") -DEFIMP (FPUTC_func, "FPUTC_func", FPUTC,,, "I1:-:Unit=I*,C=A1") -DEFIMP (FPUTC_subr, "FPUTC_subr", FPUTC,,, "--:-:Unit=I*,C=A1,Status=?I1w") -DEFIMP (FSEEK, "FSEEK", FSEEK,,, "--:-:Unit=I*,Offset=I*,Whence=I*,ErrLab=?g*") -DEFIMP (FSTAT_func, "FSTAT_func", FSTAT,,, "I1:-:Unit=I*,SArray=I1(13)w") -DEFIMP (FSTAT_subr, "FSTAT_subr", FSTAT,,, "--:-:Unit=I*,SArray=I1(13)w,Status=?I1w") -DEFIMP (FTELL_func, "FTELL_func", FTELL,,, "I1:-:Unit=I*") -DEFIMP (FTELL_subr, "FTELL_subr", FTELL,,, "--:-:Unit=I*,Offset=I1w") -DEFIMP (GERROR, "GERROR", GERROR,,, "--:-:Message=A1w") -DEFIMP (GETARG, "GETARG", GETARG,,, "--:-:Pos=I*,Value=A1w") -DEFIMP (GETCWD_func, "GETCWD_func", GETCWD,,, "I1:-:Name=A1w") -DEFIMP (GETCWD_subr, "GETCWD_subr", GETCWD,,, "--:-:Name=A1w,Status=?I1w") -DEFIMP (GETGID, "GETGID", GETGID,,, "I1:-:") -DEFIMP (GETLOG, "GETLOG", GETLOG,,, "--:-:Login=A1w") -DEFIMP (GETPID, "GETPID", GETPID,,, "I1:-:") -DEFIMP (GETUID, "GETUID", GETUID,,, "I1:-:") -DEFIMP (GETENV, "GETENV", GETENV,,, "--:-:Name=A1,Value=A1w") -DEFIMP (GMTIME, "GMTIME", GMTIME,,, "--:-:STime=I1,TArray=I1(9)w") -DEFIMP (HOSTNM_func, "HOSTNM_func", HOSTNM,,, "I1:-:Name=A1w") -DEFIMP (HOSTNM_subr, "HOSTNM_subr", HOSTNM,,, "--:-:Name=A1w,Status=?I1w") -DEFIMP (IACHAR, "IACHAR", ,,, "I1:-:C=A*") -DEFIMP (IAND, "IAND", ,,, "I=:*:I=I*,J=I*") -DEFIMP (IARGC, "IARGC", IARGC,,, "I1:-:") -DEFIMP (IBCLR, "IBCLR", ,,, "I=:0:I=I*,Pos=I*") -DEFIMP (IBITS, "IBITS", ,,, "I=:0:I=I*,Pos=I*,Len=I*") -DEFIMP (IBSET, "IBSET", ,,, "I=:0:I=I*,Pos=I*") -DEFIMP (IDATE_unix, "IDATE_unix", IDATE,,, "--:-:TArray=I1(3)w") -DEFIMP (IDATE_vxt, "IDATE_vxt", VXTIDATE,,, "--:-:M=I1w,D=I1w,Y=I1w") -DEFIMP (IEOR, "IEOR", ,,, "I=:*:I=I*,J=I*") -DEFIMP (IOR, "IOR", ,,, "I=:*:I=I*,J=I*") -DEFIMP (IERRNO, "IERRNO", IERRNO,,, "I1:-:") -DEFIMP (IMAGPART, "IMAGPART", ,,, "R=:0:Z=C*") -DEFIMP (INT2, "INT2", ,,, "I6:-:A=N*") -DEFIMP (INT8, "INT8", ,,, "I2:-:A=N*") -DEFIMP (IRAND, "IRAND", IRAND,,, "I1:-:Flag=?I*") -DEFIMP (ISATTY, "ISATTY", ISATTY,,, "L1:-:Unit=I*") -DEFIMP (ISHFT, "ISHFT", ,,, "I=:0:I=I*,Shift=I*") -DEFIMP (ISHFTC, "ISHFTC", ,,, "I=:0:I=I*,Shift=I*,Size=I*") -DEFIMP (ITIME, "ITIME", ITIME,,, "--:-:TArray=I1(3)w") -DEFIMP (KILL_func, "KILL_func", KILL,,, "I1:-:Pid=I*,Signal=I*") -DEFIMP (KILL_subr, "KILL_subr", KILL,,, "--:-:Pid=I*,Signal=I*,Status=?I1w") -DEFIMP (LINK_func, "LINK_func", LINK,,, "I1:-:Path1=A1,Path2=A1") -DEFIMP (LINK_subr, "LINK_subr", LINK,,, "--:-:Path1=A1,Path2=A1,Status=?I1w") -DEFIMP (LNBLNK, "LNBLNK", LNBLNK,,, "I1:-:String=A1") -DEFIMP (LONG, "LONG", ,,, "I1:-:A=I6") -DEFIMP (LSTAT_func, "LSTAT_func", LSTAT,,, "I1:-:File=A1,SArray=I1(13)w") -DEFIMP (LSTAT_subr, "LSTAT_subr", LSTAT,,, "--:-:File=A1,SArray=I1(13)w,Status=?I1w") -DEFIMP (LTIME, "LTIME", LTIME,,, "--:-:STime=I1,TArray=I1(9)w") -DEFIMP (LOC, "LOC", ,,, "I7:-:Entity=-*&&") -DEFIMP (LSHIFT, "LSHIFT", ,,, "I=:0:I=I*,Shift=I*") -DEFIMP (MCLOCK, "MCLOCK", MCLOCK,,, "I1:-:") -DEFIMP (MCLOCK8, "MCLOCK8", MCLOCK,,, "I2:-:") -DEFIMP (MVBITS, "MVBITS", ,,, "--:-:From=I*,FromPos=I*,Len=I*,TO=IAx,ToPos=I*") -DEFIMP (NOT, "NOT", ,,, "I=:0:I=I*") -DEFIMP (OR, "OR", ,,, "B=:*:I=B*,J=B*") -DEFIMP (PERROR, "PERROR", PERROR,,, "--:-:String=A1") -DEFIMP (RAND, "RAND", RAND,,, "R1:-:Flag=?I*") -DEFIMP (REALPART, "REALPART", ,,, "R=:0:Z=C*") -DEFIMP (RENAME_func, "RENAME_func", RENAME,,, "I1:-:Path1=A1,Path2=A1") -DEFIMP (RENAME_subr, "RENAME_subr", RENAME,,, "--:-:Path1=A1,Path2=A1,Status=?I1w") -DEFIMP (RSHIFT, "RSHIFT", ,,, "I=:0:I=I*,Shift=I*") -DEFIMP (SECNDS, "SECNDS", SECNDS,,, "R1:-:T=R1") -DEFIMP (SECOND_func, "SECOND_func", SECOND,SECOND,, "R1:-:") -DEFIMP (SECOND_subr, "SECOND_subr", SECOND,,, "--:-:Seconds=R*w") -DEFIMP (SHORT, "SHORT", ,,, "I6:-:A=I*") -DEFIMP (SIGNAL_func, "SIGNAL_func", L_SIGNAL,,, "I7:-:Number=I*,Handler=s*") -DEFIMP (SIGNAL_subr, "SIGNAL_subr", L_SIGNAL,,, "--:-:Number=I*,Handler=s*,Status=?I7w") -DEFIMP (SLEEP, "SLEEP", SLEEP,,, "--:-:Seconds=I1") -DEFIMP (SRAND, "SRAND", SRAND,,, "--:-:Seed=I*") -DEFIMP (STAT_func, "STAT_func", STAT,,, "I1:-:File=A1,SArray=I1(13)w") -DEFIMP (STAT_subr, "STAT_subr", STAT,,, "--:-:File=A1,SArray=I1(13)w,Status=?I1w") -DEFIMP (SYMLNK_func, "SYMLNK_func", SYMLNK,,, "I1:-:Path1=A1,Path2=A1") -DEFIMP (SYMLNK_subr, "SYMLNK_subr", SYMLNK,,, "--:-:Path1=A1,Path2=A1,Status=?I1w") -DEFIMP (SYSTEM_func, "SYSTEM_func", SYSTEM,SYSTEM,SYSTEM,"I1:-:Command=A1") -DEFIMP (SYSTEM_subr, "SYSTEM_subr", SYSTEM,,, "--:-:Command=A1,Status=?I1w") -DEFIMP (SYSTEM_CLOCK, "SYSTEM_CLOCK", SYSTEM_CLOCK,,, "--:-:Count=I1w,Rate=?I1w,Max=?I1w") -DEFIMP (TIME8, "TIME8", TIME,,, "I2:-:") -DEFIMP (TIME_unix, "TIME_unix", TIME,,, "I1:-:") -DEFIMP (TIME_vxt, "TIME_vxt", VXTTIME,,, "--:-:Time=A1[8]w") -DEFIMP (TTYNAM_func, "TTYNAM_func", TTYNAM,,, "A1*:-:Unit=I*") -DEFIMP (TTYNAM_subr, "TTYNAM_subr", TTYNAM,,, "--:-:Name=A1w,Unit=I*") -DEFIMP (UMASK_func, "UMASK_func", UMASK,,, "I1:-:Mask=I*") -DEFIMP (UMASK_subr, "UMASK_subr", UMASK,,, "--:-:Mask=I*,Old=?I1w") -DEFIMP (UNLINK_func, "UNLINK_func", UNLINK,,, "I1:-:File=A1") -DEFIMP (UNLINK_subr, "UNLINK_subr", UNLINK,,, "--:-:File=A1,Status=?I1w") -DEFIMP (XOR, "XOR", ,,, "B=:*:I=B*,J=B*") -DEFIMP (NONE, "none", ,,, "") diff --git a/gcc/f/intrin.h b/gcc/f/intrin.h deleted file mode 100755 index 0006c8a..0000000 --- a/gcc/f/intrin.h +++ /dev/null @@ -1,130 +0,0 @@ -/* intrin.h -- Public interface for intrin.c - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -#ifndef _H_f_intrin -#define _H_f_intrin - -#ifndef FFEINTRIN_DOC -#define FFEINTRIN_DOC 0 /* 1 means intrinsic documentation only (intdoc.c). */ -#endif - -typedef enum - { - FFEINTRIN_familyNONE, /* Not in any family. */ - FFEINTRIN_familyF77, /* ANSI FORTRAN 77. */ - FFEINTRIN_familyGNU, /* GNU Fortran intrinsics. */ - FFEINTRIN_familyF2C, /* f2c intrinsics. */ - FFEINTRIN_familyF90, /* Fortran 90. */ - FFEINTRIN_familyF95 = FFEINTRIN_familyF90, - FFEINTRIN_familyVXT, /* VAX/VMS FORTRAN. */ - FFEINTRIN_familyMIL, /* MIL STD 1753 (MVBITS, etc), in mil, vxt, and f90. */ - FFEINTRIN_familyASC, /* ASCII-related (ACHAR, IACHAR), both f2c and f90. */ - FFEINTRIN_familyFVZ, /* in both f2c and VAX/VMS FORTRAN. */ - FFEINTRIN_familyF2U, /* libf2c/libU77 UNIX system intrinsics. */ - FFEINTRIN_familyBADU77, /* libU77 UNIX system intrinsics with bad form. */ - FFEINTRIN_family - } ffeintrinFamily; - -typedef enum - { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) FFEINTRIN_gen ## CODE, -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP - FFEINTRIN_gen - } ffeintrinGen; - -typedef enum - { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) FFEINTRIN_spec ## CODE, -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP - FFEINTRIN_spec - } ffeintrinSpec; - -typedef enum - { -#define DEFNAME(UPPER,LOWER,MIXED,GEN,SPEC) -#define DEFGEN(CODE,NAME,SPEC1,SPEC2) -#define DEFSPEC(CODE,NAME,CALLABLE,FAMILY,IMP) -#define DEFIMP(CODE,NAME,GFRTDIRECT,GFRTF2C,GFRTGNU,CONTROL) \ - FFEINTRIN_imp ## CODE, -#include "intrin.def" -#undef DEFNAME -#undef DEFGEN -#undef DEFSPEC -#undef DEFIMP - FFEINTRIN_imp - } ffeintrinImp; - -#if !FFEINTRIN_DOC - -#include "bld.h" -#include "info.h" - -ffeinfoBasictype ffeintrin_basictype (ffeintrinSpec spec); -ffeintrinFamily ffeintrin_family (ffeintrinSpec spec); -void ffeintrin_fulfill_generic (ffebld *expr, ffeinfo *info, ffelexToken t); -void ffeintrin_fulfill_specific (ffebld *expr, ffeinfo *info, - bool *check_intrin, ffelexToken t); -#if FFECOM_targetCURRENT == FFECOM_targetGCC -ffecomGfrt ffeintrin_gfrt_direct (ffeintrinImp imp); -ffecomGfrt ffeintrin_gfrt_indirect (ffeintrinImp imp); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ -void ffeintrin_init_0 (void); -#define ffeintrin_init_1() -#define ffeintrin_init_2() -#define ffeintrin_init_3() -#define ffeintrin_init_4() -bool ffeintrin_is_actualarg (ffeintrinSpec spec); -bool ffeintrin_is_intrinsic (char *name, ffelexToken t, bool explicit, - ffeintrinGen *gen, ffeintrinSpec *spec, - ffeintrinImp *imp); -bool ffeintrin_is_standard (ffeintrinGen gen, ffeintrinSpec spec); -ffeinfoKindtype ffeintrin_kindtype (ffeintrinSpec spec); -char *ffeintrin_name_generic (ffeintrinGen gen); -char *ffeintrin_name_implementation (ffeintrinImp imp); -char *ffeintrin_name_specific (ffeintrinSpec spec); -ffeIntrinsicState ffeintrin_state_family (ffeintrinFamily family); -#define ffeintrin_terminate_0() -#define ffeintrin_terminate_1() -#define ffeintrin_terminate_2() -#define ffeintrin_terminate_3() -#define ffeintrin_terminate_4() - -#endif /* !FFEINTRIN_DOC */ - -/* End of #include file. */ - -#endif diff --git a/gcc/f/lab.c b/gcc/f/lab.c deleted file mode 100755 index e161097..0000000 --- a/gcc/f/lab.c +++ /dev/null @@ -1,159 +0,0 @@ -/* lab.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - - Description: - Complex data abstraction for Fortran labels. Maintains a single master - list for all labels; it is expected initialization and termination of - this list will occur on program-unit boundaries. - - Modifications: - 22-Aug-89 JCB 1.1 - Change ffelab_new for new ffewhere interface. -*/ - -/* Include files. */ - -#include "proj.h" -#include "lab.h" -#include "malloc.h" - -/* Externals defined here. */ - -ffelab ffelab_list_; -ffelabNumber ffelab_num_news_; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffelab_find -- Find the ffelab object having the desired label value - - ffelab l; - ffelabValue v; - l = ffelab_find(v); - - If the desired ffelab object doesn't exist, returns NULL. - - Straightforward search of list of ffelabs. */ - -ffelab -ffelab_find (ffelabValue v) -{ - ffelab l; - - for (l = ffelab_list_; (l != NULL) && (ffelab_value (l) != v); l = l->next) - ; - - return l; -} - -/* ffelab_finish -- Shut down label management - - ffelab_finish(); - - At the end of processing a program unit, call this routine to shut down - label management. - - Kill all the labels on the list. */ - -void -ffelab_finish () -{ - ffelab l; - ffelab pl; - - for (pl = NULL, l = ffelab_list_; l != NULL; pl = l, l = l->next) - if (pl != NULL) - malloc_kill_ks (ffe_pool_any_unit (), pl, sizeof (*pl)); - - if (pl != NULL) - malloc_kill_ks (ffe_pool_any_unit (), pl, sizeof (*pl)); -} - -/* ffelab_init_3 -- Initialize label management system - - ffelab_init_3(); - - Initialize the label management system. Do this before a new program - unit is going to be processed. */ - -void -ffelab_init_3 () -{ - ffelab_list_ = NULL; - ffelab_num_news_ = 0; -} - -/* ffelab_new -- Create an ffelab object. - - ffelab l; - ffelabValue v; - l = ffelab_new(v); - - Create a label having a given value. If the value isn't known, pass - FFELAB_valueNONE, and set it later with ffelab_set_value. - - Allocate, initialize, and stick at top of label list. - - 22-Aug-89 JCB 1.1 - Change for new ffewhere interface. */ - -ffelab -ffelab_new (ffelabValue v) -{ - ffelab l; - - ++ffelab_num_news_; - l = (ffelab) malloc_new_ks (ffe_pool_any_unit (), "FFELAB label", sizeof (*l)); - l->next = ffelab_list_; -#ifdef FFECOM_labelHOOK - l->hook = FFECOM_labelNULL; -#endif - l->value = v; - l->firstref_line = ffewhere_line_unknown (); - l->firstref_col = ffewhere_column_unknown (); - l->doref_line = ffewhere_line_unknown (); - l->doref_col = ffewhere_column_unknown (); - l->definition_line = ffewhere_line_unknown (); - l->definition_col = ffewhere_column_unknown (); - l->type = FFELAB_typeUNKNOWN; - ffelab_list_ = l; - return l; -} diff --git a/gcc/f/lab.h b/gcc/f/lab.h deleted file mode 100755 index d559860..0000000 --- a/gcc/f/lab.h +++ /dev/null @@ -1,154 +0,0 @@ -/* lab.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - lab.c - - Modifications: - 22-Aug-89 JCB 1.1 - Change for new ffewhere interface. -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_lab -#define _H_f_lab - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFELAB_typeUNKNOWN, /* No info yet on label. */ - FFELAB_typeANY, /* Label valid for anything, no msgs. */ - FFELAB_typeUSELESS, /* No valid way to reference this label. */ - FFELAB_typeASSIGNABLE, /* Target of ASSIGN: so FORMAT or BRANCH. */ - FFELAB_typeFORMAT, /* FORMAT label. */ - FFELAB_typeLOOPEND, /* Target of a labeled DO statement. */ - FFELAB_typeNOTLOOP, /* Branch target statement not valid DO - target. */ - FFELAB_typeENDIF, /* END IF label. */ - FFELAB_type - } ffelabType; - -#define FFELAB_valueNONE 0 -#define FFELAB_valueMAX 99999 - -/* Typedefs. */ - -typedef struct _ffelab_ *ffelab; -typedef ffelab ffelabHandle; -typedef unsigned long ffelabNumber; /* Count of new labels. */ -#define ffelabNumber_f "l" -typedef unsigned long ffelabValue; -#define ffelabValue_f "l" - -/* Include files needed by this one. */ - -#include "com.h" -#include "where.h" - -/* Structure definitions. */ - -struct _ffelab_ - { - ffelab next; -#ifdef FFECOM_labelHOOK - ffecomLabel hook; -#endif - ffelabValue value; /* 1 through 99999, or 100000+ for temp - labels. */ - unsigned long blocknum; /* Managed entirely by user of module. */ - ffewhereLine firstref_line; - ffewhereColumn firstref_col; - ffewhereLine doref_line; - ffewhereColumn doref_col; - ffewhereLine definition_line; /* ffewhere_line_unknown() if not - defined. */ - ffewhereColumn definition_col; - ffelabType type; - }; - -/* Global objects accessed by users of this module. */ - -extern ffelab ffelab_list_; -extern ffelabNumber ffelab_num_news_; - -/* Declare functions with prototypes. */ - -ffelab ffelab_find (ffelabValue v); -void ffelab_finish (void); -void ffelab_init_3 (void); -ffelab ffelab_new (ffelabValue v); - -/* Define macros. */ - -#define ffelab_blocknum(l) ((l)->blocknum) -#define ffelab_definition_column(l) ((l)->definition_col) -#define ffelab_definition_filename(l) \ - ffewhere_line_filename((l)->definition_line) -#define ffelab_definition_filelinenum(l) \ - ffewhere_line_filelinenum((l)->definition_line) -#define ffelab_definition_line(l) ((l)->definition_line) -#define ffelab_definition_line_number(l) \ - ffewhere_line_number((l)->definition_line) -#define ffelab_doref_column(l) ((l)->doref_col) -#define ffelab_doref_filename(l) ffewhere_line_filename((l)->doref_line) -#define ffelab_doref_filelinenum(l) ffewhere_line_filelinenum((l)->doref_line) -#define ffelab_doref_line(l) ((l)->doref_line) -#define ffelab_doref_line_number(l) ffewhere_line_number((l)->doref_line) -#define ffelab_firstref_column(l) ((l)->firstref_col) -#define ffelab_firstref_filename(l) ffewhere_line_filename((l)->firstref_line) -#define ffelab_firstref_filelinenum(l) \ - ffewhere_line_filelinenum((l)->firstref_line) -#define ffelab_firstref_line(l) ((l)->firstref_line) -#define ffelab_firstref_line_number(l) ffewhere_line_number((l)->firstref_line) -#define ffelab_handle_done(h) -#define ffelab_handle_first() ((ffelabHandle) ffelab_list_) -#define ffelab_handle_next(h) ((ffelabHandle) (((ffelab) h)->next)) -#define ffelab_handle_target(h) ((ffelab) h) -#define ffelab_hook(l) ((l)->hook) -#define ffelab_init_0() -#define ffelab_init_1() -#define ffelab_init_2() -#define ffelab_init_4() -#define ffelab_kill(l) ffelab_set_value(l,FFELAB_valueNONE); -#define ffelab_new_generated() (ffelab_new(ffelab_generated_++)) -#define ffelab_number() (ffelab_num_news_) -#define ffelab_set_blocknum(l,b) ((l)->blocknum = (b)) -#define ffelab_set_definition_column(l,cn) ((l)->definition_col = (cn)) -#define ffelab_set_definition_line(l,ln) ((l)->definition_line = (ln)) -#define ffelab_set_doref_column(l,cn) ((l)->doref_col = (cn)) -#define ffelab_set_doref_line(l,ln) ((l)->doref_line = (ln)) -#define ffelab_set_firstref_column(l,cn) ((l)->firstref_col = (cn)) -#define ffelab_set_firstref_line(l,ln) ((l)->firstref_line = (ln)) -#define ffelab_set_hook(l,h) ((l)->hook = (h)) -#define ffelab_set_type(l,t) ((l)->type = (t)) -#define ffelab_terminate_0() -#define ffelab_terminate_1() -#define ffelab_terminate_2() -#define ffelab_terminate_3() -#define ffelab_terminate_4() -#define ffelab_type(l) ((l)->type) -#define ffelab_value(l) ((l)->value) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/lang-options.h b/gcc/f/lang-options.h deleted file mode 100755 index 0fa927a..0000000 --- a/gcc/f/lang-options.h +++ /dev/null @@ -1,164 +0,0 @@ -/* lang-options.h file for Fortran - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -/* This is the contribution to the `lang_options' array in gcc.c for - g77. */ - -#ifdef __STDC__ /* To be consistent with lang-specs.h. Maybe avoid - overflowing some old compiler's tables, etc. */ - -DEFINE_LANG_NAME ("Fortran") - -/* Use of FTNOPT makes tracking changes between FSF-g77 and egcs-g77 - easier, since FSF-gcc doesn't support doc strings. */ -#define FTNOPT(opt,doc) { opt, doc }, - -FTNOPT( "-fversion", "Print g77-specific compiler version info, run internal tests" ) -FTNOPT( "-fnull-version", "" ) -/*"-fident",*/ -/*"-fno-ident",*/ -FTNOPT( "-ff66", "Program is written in typical FORTRAN 66 dialect" ) -FTNOPT( "-fno-f66", "" ) -FTNOPT( "-ff77", "Program is written in typical Unix f77 dialect" ) -FTNOPT( "-fno-f77", "Program does not use Unix-f77 dialectal features" ) -FTNOPT( "-ff90", "Program is written in Fortran-90-ish dialect" ) -FTNOPT( "-fno-f90", "" ) -FTNOPT( "-fautomatic", "" ) -FTNOPT( "-fno-automatic", "Treat local vars and COMMON blocks as if they were named in SAVE statements" ) -FTNOPT( "-fdollar-ok", "Allow $ in symbol names" ) -FTNOPT( "-fno-dollar-ok", "" ) -FTNOPT( "-ff2c", "" ) -FTNOPT( "-fno-f2c", "f2c-compatible code need not be generated" ) -FTNOPT( "-ff2c-library", "" ) -FTNOPT( "-fno-f2c-library", "Unsupported; do not generate libf2c-calling code" ) -FTNOPT( "-ffree-form", "Program is written in Fortran-90-ish free form" ) -FTNOPT( "-fno-free-form", "" ) -FTNOPT( "-ffixed-form", "" ) -FTNOPT( "-fno-fixed-form", "" ) -FTNOPT( "-fpedantic", "Warn about use of (only a few for now) Fortran extensions" ) -FTNOPT( "-fno-pedantic", "" ) -FTNOPT( "-fvxt", "Program is written in VXT (Digital-like) FORTRAN" ) -FTNOPT( "-fno-vxt", "" ) -FTNOPT( "-fugly", "Obsolete; allow certain ugly features" ) -FTNOPT( "-fno-ugly", "" ) -FTNOPT( "-fugly-args", "" ) -FTNOPT( "-fno-ugly-args", "Hollerith and typeless constants not passed as arguments" ) -FTNOPT( "-fugly-assign", "Allow ordinary copying of ASSIGN'ed vars" ) -FTNOPT( "-fno-ugly-assign", "" ) -FTNOPT( "-fugly-assumed", "Dummy array dimensioned to (1) is assumed-size" ) -FTNOPT( "-fno-ugly-assumed", "" ) -FTNOPT( "-fugly-comma", "Trailing comma in procedure call denotes null argument" ) -FTNOPT( "-fno-ugly-comma", "" ) -FTNOPT( "-fugly-complex", "Allow REAL(Z) and AIMAG(Z) given DOUBLE COMPLEX Z" ) -FTNOPT( "-fno-ugly-complex", "" ) -FTNOPT( "-fugly-init", "" ) -FTNOPT( "-fno-ugly-init", "Initialization via DATA and PARAMETER is type-compatible" ) -FTNOPT( "-fugly-logint", "Allow INTEGER and LOGICAL interchangeability" ) -FTNOPT( "-fno-ugly-logint", "" ) -FTNOPT( "-fxyzzy", "Print internal debugging-related info" ) -FTNOPT( "-fno-xyzzy", "" ) -FTNOPT( "-finit-local-zero", "Initialize local vars and arrays to zero" ) -FTNOPT( "-fno-init-local-zero", "" ) -FTNOPT( "-fbackslash", "" ) -FTNOPT( "-fno-backslash", "Backslashes in character/hollerith constants not special (C-style)" ) -FTNOPT( "-femulate-complex", "" ) -FTNOPT( "-fno-emulate-complex", "Have compiler back end cope with COMPLEX arithmetic" ) -FTNOPT( "-funderscoring", "" ) -FTNOPT( "-fno-underscoring", "Disable the appending of underscores to externals" ) -FTNOPT( "-fsecond-underscore", "" ) -FTNOPT( "-fno-second-underscore", "Never append a second underscore to externals" ) -FTNOPT( "-fintrin-case-initcap", "Intrinsics spelled as e.g. SqRt" ) -FTNOPT( "-fintrin-case-upper", "Intrinsics in uppercase" ) -FTNOPT( "-fintrin-case-lower", "" ) -FTNOPT( "-fintrin-case-any", "Intrinsics letters in arbitrary cases" ) -FTNOPT( "-fmatch-case-initcap", "Language keywords spelled as e.g. IOStat" ) -FTNOPT( "-fmatch-case-upper", "Language keywords in uppercase" ) -FTNOPT( "-fmatch-case-lower", "" ) -FTNOPT( "-fmatch-case-any", "Language keyword letters in arbitrary cases" ) -FTNOPT( "-fsource-case-upper", "Internally convert most source to uppercase" ) -FTNOPT( "-fsource-case-lower", "" ) -FTNOPT( "-fsource-case-preserve", "Internally preserve source case" ) -FTNOPT( "-fsymbol-case-initcap", "Symbol names spelled in mixed case" ) -FTNOPT( "-fsymbol-case-upper", "Symbol names in uppercase" ) -FTNOPT( "-fsymbol-case-lower", "Symbol names in lowercase" ) -FTNOPT( "-fsymbol-case-any", "" ) -FTNOPT( "-fcase-strict-upper", "Program written in uppercase" ) -FTNOPT( "-fcase-strict-lower", "Program written in lowercase" ) -FTNOPT( "-fcase-initcap", "Program written in strict mixed-case" ) -FTNOPT( "-fcase-upper", "Compile as if program written in uppercase" ) -FTNOPT( "-fcase-lower", "Compile as if program written in lowercase" ) -FTNOPT( "-fcase-preserve", "Preserve all spelling (case) used in program" ) -FTNOPT( "-fbadu77-intrinsics-delete", "Delete libU77 intrinsics with bad interfaces" ) -FTNOPT( "-fbadu77-intrinsics-disable", "Disable libU77 intrinsics with bad interfaces" ) -FTNOPT( "-fbadu77-intrinsics-enable", "" ) -FTNOPT( "-fbadu77-intrinsics-hide", "Hide libU77 intrinsics with bad interfaces" ) -FTNOPT( "-ff2c-intrinsics-delete", "Delete non-FORTRAN-77 intrinsics f2c supports" ) -FTNOPT( "-ff2c-intrinsics-disable", "Disable non-FORTRAN-77 intrinsics f2c supports" ) -FTNOPT( "-ff2c-intrinsics-enable", "" ) -FTNOPT( "-ff2c-intrinsics-hide", "Hide non-FORTRAN-77 intrinsics f2c supports" ) -FTNOPT( "-ff90-intrinsics-delete", "Delete non-FORTRAN-77 intrinsics F90 supports" ) -FTNOPT( "-ff90-intrinsics-disable", "Disable non-FORTRAN-77 intrinsics F90 supports" ) -FTNOPT( "-ff90-intrinsics-enable", "" ) -FTNOPT( "-ff90-intrinsics-hide", "Hide non-FORTRAN-77 intrinsics F90 supports" ) -FTNOPT( "-fgnu-intrinsics-delete", "Delete non-FORTRAN-77 intrinsics g77 supports" ) -FTNOPT( "-fgnu-intrinsics-disable", "Disable non-FORTRAN 77 intrinsics F90 supports" ) -FTNOPT( "-fgnu-intrinsics-enable", "" ) -FTNOPT( "-fgnu-intrinsics-hide", "Hide non-FORTRAN 77 intrinsics F90 supports" ) -FTNOPT( "-fmil-intrinsics-delete", "Delete MIL-STD 1753 intrinsics" ) -FTNOPT( "-fmil-intrinsics-disable", "Disable MIL-STD 1753 intrinsics" ) -FTNOPT( "-fmil-intrinsics-enable", "" ) -FTNOPT( "-fmil-intrinsics-hide", "Hide MIL-STD 1753 intrinsics" ) -FTNOPT( "-funix-intrinsics-delete", "Delete libU77 intrinsics" ) -FTNOPT( "-funix-intrinsics-disable", "Disable libU77 intrinsics" ) -FTNOPT( "-funix-intrinsics-enable", "" ) -FTNOPT( "-funix-intrinsics-hide", "Hide libU77 intrinsics" ) -FTNOPT( "-fvxt-intrinsics-delete", "Delete non-FORTRAN-77 intrinsics VXT FORTRAN supports" ) -FTNOPT( "-fvxt-intrinsics-disable", "Disable non-FORTRAN-77 intrinsics VXT FORTRAN supports" ) -FTNOPT( "-fvxt-intrinsics-enable", "" ) -FTNOPT( "-fvxt-intrinsics-hide", "Hide non-FORTRAN-77 intrinsics VXT FORTRAN supports" ) -FTNOPT( "-fzeros", "Treat initial values of 0 like non-zero values" ) -FTNOPT( "-fno-zeros", "" ) -FTNOPT( "-fdebug-kludge", "Emit special debugging information for COMMON and EQUIVALENCE" ) -FTNOPT( "-fno-debug-kludge", "" ) -FTNOPT( "-fonetrip", "Take at least one trip through each iterative DO loop" ) -FTNOPT( "-fno-onetrip", "" ) -FTNOPT( "-fsilent", "" ) -FTNOPT( "-fno-silent", "Print names of program units as they are compiled" ) -FTNOPT( "-fglobals", "" ) -FTNOPT( "-fno-globals", "Disable fatal diagnostics about inter-procedural problems" ) -FTNOPT( "-ftypeless-boz", "Make prefix-radix non-decimal constants be typeless" ) -FTNOPT( "-fno-typeless-boz", "" ) -FTNOPT( "-Wglobals", "" ) -FTNOPT( "-Wno-globals", "Disable warnings about inter-procedural problems" ) -/*"-Wimplicit",*/ -/*"-Wno-implicit",*/ -FTNOPT( "-Wsurprising", "Warn about constructs with surprising meanings" ) -FTNOPT( "-Wno-surprising", "" ) -/*"-Wall",*/ -/* Prefix options. */ -FTNOPT( "-I", "Add a directory for INCLUDE searching" ) -FTNOPT( "-ffixed-line-length-", "Set the maximum line length" ) - -#undef FTNOPT - -#endif diff --git a/gcc/f/lang-specs.h b/gcc/f/lang-specs.h deleted file mode 100755 index bf8786f..0000000 --- a/gcc/f/lang-specs.h +++ /dev/null @@ -1,106 +0,0 @@ -/* lang-specs.h file for Fortran - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -/* This is the contribution to the `default_compilers' array in gcc.c for - g77. */ - - {".F", {"@f77-cpp-input"}}, - {".fpp", {"@f77-cpp-input"}}, - {"@f77-cpp-input", - /* For f77 we want -traditional to avoid errors with, for - instance, mismatched '. Also, we avoid unpleasant surprises - with substitution of names not prefixed by `_' by using %P - rather than %p (although this isn't consistent with SGI and - Sun f77, at least) so you test `__unix' rather than `unix'. - -D_LANGUAGE_FORTRAN is used by some compilers like SGI and - might as well be in there. */ - {"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -$ -D__STRICT_ANSI__}\ - %{!undef:%P} -D_LANGUAGE_FORTRAN %{trigraphs} \ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} -traditional\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.i}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:f771 %{!pipe:%g.i} %(f771) \ - %{!Q:-quiet} -dumpbase %b.F %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} \ - %{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, - {".r", {"@ratfor"}}, - {"@ratfor", - {"ratfor %{C} %{v}\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{!E:%{!pipe:-o %g.f}}%{E:%W{o*}} %i |\n", - "%{!E:f771 %{!pipe:%g.f} %(f771) \ - %{!Q:-quiet} -dumpbase %b.r %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} \ - %{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}"}}, - {".f", {"@f77"}}, - {".for", {"@f77"}}, - {"@f77", - {"%{!M:%{!MM:%{!E:f771 %i %(f771) \ - %{!Q:-quiet} -dumpbase %b.f %{d*} %{m*} %{a}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*}\ - %{v:-version -fversion} %{pg:-p} %{p} %{f*} %{I*}\ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, - {"@f77-version", - {"cpp -lang-c %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I \ - %{C:%{!E:%eGNU C does not support -C without using -E}} \ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG} \ - -undef -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 \ - %{ansi:-trigraphs -$ -D__STRICT_ANSI__} \ - %{!undef:%P} -D_LANGUAGE_FORTRAN %{trigraphs} \ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}} -traditional \ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z \ - /dev/null /dev/null \n\ - f771 -fnull-version %(f771) \ - %{!Q:-quiet} -dumpbase g77-version.f %{d*} %{m*} %{a} \ - %{g*} %{O*} %{W*} %{w} %{pedantic*} \ - -version -fversion %{f*} %{I*} -o %g.s /dev/null \n\ - as %a %Y -o %g%O %g.s %A \n\ - ld %l %X -o %g %g%O %{A} %{d} %{e*} %{m} %{N} %{n} \ - %{r} %{s} %{t} %{u*} %{x} %{z} %{Z} \ - %{!A:%{!nostdlib:%{!nostartfiles:%S}}} \ - %{static:} %{L*} %D -lg2c -lm \ - %{!nostdlib:%{!nodefaultlibs:%G %L %G}} \ - %{!A:%{!nostdlib:%{!nostartfiles:%E}}} \ - %{T*} \n\ - %g \n"}}, diff --git a/gcc/f/lex.c b/gcc/f/lex.c deleted file mode 100755 index 57b0e45..0000000 --- a/gcc/f/lex.c +++ /dev/null @@ -1,4759 +0,0 @@ -/* Implementation of Fortran lexer - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#include "proj.h" -#include "top.h" -#include "bad.h" -#include "com.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#include "flags.j" -#include "input.j" -#include "toplev.j" -#include "tree.j" -#include "output.j" /* Must follow tree.j so TREE_CODE is defined! */ -#endif - -#ifdef DWARF_DEBUGGING_INFO -void dwarfout_resume_previous_source_file (register unsigned); -void dwarfout_start_new_source_file (register char *); -void dwarfout_define (register unsigned, register char *); -void dwarfout_undef (register unsigned, register char *); -#endif DWARF_DEBUGGING_INFO - -static void ffelex_append_to_token_ (char c); -static int ffelex_backslash_ (int c, ffewhereColumnNumber col); -static void ffelex_bad_1_ (ffebad errnum, ffewhereLineNumber ln0, - ffewhereColumnNumber cn0); -static void ffelex_bad_2_ (ffebad errnum, ffewhereLineNumber ln0, - ffewhereColumnNumber cn0, ffewhereLineNumber ln1, - ffewhereColumnNumber cn1); -static void ffelex_bad_here_ (int num, ffewhereLineNumber ln0, - ffewhereColumnNumber cn0); -static void ffelex_finish_statement_ (void); -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int ffelex_get_directive_line_ (char **text, FILE *finput); -static int ffelex_hash_ (FILE *f); -#endif -static ffewhereColumnNumber ffelex_image_char_ (int c, - ffewhereColumnNumber col); -static void ffelex_include_ (void); -static bool ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col); -static bool ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col); -static void ffelex_next_line_ (void); -static void ffelex_prepare_eos_ (void); -static void ffelex_send_token_ (void); -static ffelexHandler ffelex_swallow_tokens_ (ffelexToken t); -static ffelexToken ffelex_token_new_ (void); - -/* Pertaining to the geometry of the input file. */ - -/* Initial size for card image to be allocated. */ -#define FFELEX_columnINITIAL_SIZE_ 255 - -/* The card image itself, which grows as source lines get longer. It - has room for ffelex_card_size_ + 8 characters, and the length of the - current image is ffelex_card_length_. (The + 8 characters are made - available for easy handling of tabs and such.) */ -static char *ffelex_card_image_; -static ffewhereColumnNumber ffelex_card_size_; -static ffewhereColumnNumber ffelex_card_length_; - -/* Max width for free-form lines (ISO F90). */ -#define FFELEX_FREE_MAX_COLUMNS_ 132 - -/* True if we saw a tab on the current line, as this (currently) means - the line is therefore treated as though final_nontab_column_ were - infinite. */ -static bool ffelex_saw_tab_; - -/* TRUE if current line is known to be erroneous, so don't bother - expanding room for it just to display it. */ -static bool ffelex_bad_line_ = FALSE; - -/* Last column for vanilla, i.e. non-tabbed, line. Usually 72 or 132. */ -static ffewhereColumnNumber ffelex_final_nontab_column_; - -/* Array for quickly deciding what kind of line the current card has, - based on its first character. */ -static ffelexType ffelex_first_char_[256]; - -/* Pertaining to file management. */ - -/* The wf argument of the most recent active ffelex_file_(fixed,free) - function. */ -static ffewhereFile ffelex_current_wf_; - -/* TRUE if an INCLUDE statement can be processed (ffelex_set_include - can be called). */ -static bool ffelex_permit_include_; - -/* TRUE if an INCLUDE statement is pending (ffelex_set_include has been - called). */ -static bool ffelex_set_include_; - -/* Information on the pending INCLUDE file. */ -static FILE *ffelex_include_file_; -static bool ffelex_include_free_form_; -static ffewhereFile ffelex_include_wherefile_; - -/* Current master line count. */ -static ffewhereLineNumber ffelex_linecount_current_; -/* Next master line count. */ -static ffewhereLineNumber ffelex_linecount_next_; - -/* ffewhere info on the latest (currently active) line read from the - active source file. */ -static ffewhereLine ffelex_current_wl_; -static ffewhereColumn ffelex_current_wc_; - -/* Pertaining to tokens in general. */ - -/* Initial capacity for text in a CHARACTER/HOLLERITH/NAME/NAMES/NUMBER - token. */ -#define FFELEX_columnTOKEN_SIZE_ 63 -#if FFELEX_columnTOKEN_SIZE_ < FFEWHERE_indexMAX -#error "token size too small!" -#endif - -/* Current token being lexed. */ -static ffelexToken ffelex_token_; - -/* Handler for current token. */ -static ffelexHandler ffelex_handler_; - -/* TRUE if fixed-form lexer is to generate NAMES instead of NAME tokens. */ -static bool ffelex_names_; - -/* TRUE if both lexers are to generate NAMES instead of NAME tokens. */ -static bool ffelex_names_pure_; - -/* TRUE if 0-9 starts a NAME token instead of NUMBER, for parsing hex - numbers. */ -static bool ffelex_hexnum_; - -/* For ffelex_swallow_tokens(). */ -static ffelexHandler ffelex_eos_handler_; - -/* Number of tokens sent since last EOS or beginning of input file - (include INCLUDEd files). */ -static unsigned long int ffelex_number_of_tokens_; - -/* Number of labels sent (as NUMBER tokens) since last reset of - ffelex_number_of_tokens_ to 0, should be 0 or 1 in most cases. - (Fixed-form source only.) */ -static unsigned long int ffelex_label_tokens_; - -/* Metering for token management, to catch token-memory leaks. */ -static long int ffelex_total_tokens_ = 0; -static long int ffelex_old_total_tokens_ = 1; -static long int ffelex_token_nextid_ = 0; - -/* Pertaining to lexing CHARACTER and HOLLERITH tokens. */ - -/* >0 if a Hollerith constant of that length might be in mid-lex, used - when the next character seen is 'H' or 'h' to enter HOLLERITH lexing - mode (see ffelex_raw_mode_). */ -static long int ffelex_expecting_hollerith_; - -/* -3: Backslash (escape) sequence being lexed in CHARACTER. - -2: Possible closing apostrophe/quote seen in CHARACTER. - -1: Lexing CHARACTER. - 0: Not lexing CHARACTER or HOLLERITH. - >0: Lexing HOLLERITH, value is # chars remaining to expect. */ -static long int ffelex_raw_mode_; - -/* When lexing CHARACTER, open quote/apostrophe (either ' or "). */ -static char ffelex_raw_char_; - -/* TRUE when backslash processing had to use most recent character - to finish its state engine, but that character is not part of - the backslash sequence, so must be reconsidered as a "normal" - character in CHARACTER/HOLLERITH lexing. */ -static bool ffelex_backslash_reconsider_ = FALSE; - -/* Characters preread before lexing happened (might include EOF). */ -static int *ffelex_kludge_chars_ = NULL; - -/* Doing the kludge processing, so not initialized yet. */ -static bool ffelex_kludge_flag_ = FALSE; - -/* The beginning of a (possible) CHARACTER/HOLLERITH token. */ -static ffewhereLine ffelex_raw_where_line_; -static ffewhereColumn ffelex_raw_where_col_; - - -/* Call this to append another character to the current token. If it isn't - currently big enough for it, it will be enlarged. The current token - must be a CHARACTER, HOLLERITH, NAME, NAMES, or NUMBER. */ - -static void -ffelex_append_to_token_ (char c) -{ - if (ffelex_token_->text == NULL) - { - ffelex_token_->text - = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - FFELEX_columnTOKEN_SIZE_ + 1); - ffelex_token_->size = FFELEX_columnTOKEN_SIZE_; - ffelex_token_->length = 0; - } - else if (ffelex_token_->length >= ffelex_token_->size) - { - ffelex_token_->text - = malloc_resize_ksr (malloc_pool_image (), - ffelex_token_->text, - (ffelex_token_->size << 1) + 1, - ffelex_token_->size + 1); - ffelex_token_->size <<= 1; - assert (ffelex_token_->length < ffelex_token_->size); - } -#ifdef MAP_CHARACTER -Sorry, MAP_CHARACTER is not going to work as expected in GNU Fortran, -please contact fortran@gnu.org if you wish to fund work to -port g77 to non-ASCII machines. -#endif - ffelex_token_->text[ffelex_token_->length++] = c; -} - -/* Do backslash (escape) processing for a CHARACTER/HOLLERITH token - being lexed. */ - -static int -ffelex_backslash_ (int c, ffewhereColumnNumber col) -{ - static int state = 0; - static unsigned int count; - static int code; - static unsigned int firstdig = 0; - static int nonnull; - static ffewhereLineNumber line; - static ffewhereColumnNumber column; - - /* See gcc/c-lex.c readescape() for a straightforward version - of this state engine for handling backslashes in character/ - hollerith constants. */ - -#define wide_flag 0 -#define warn_traditional 0 -#define flag_traditional 0 - - switch (state) - { - case 0: - if ((c == '\\') - && (ffelex_raw_mode_ != 0) - && ffe_is_backslash ()) - { - state = 1; - column = col + 1; - line = ffelex_linecount_current_; - return EOF; - } - return c; - - case 1: - state = 0; /* Assume simple case. */ - switch (c) - { - case 'x': - if (warn_traditional) - { - ffebad_start_msg_lex ("The meaning of `\\x' (at %0) varies with -traditional", - FFEBAD_severityWARNING); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - - if (flag_traditional) - return c; - - code = 0; - count = 0; - nonnull = 0; - state = 2; - return EOF; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = c - '0'; - count = 1; - state = 3; - return EOF; - - case '\\': case '\'': case '"': - return c; - -#if 0 /* Inappropriate for Fortran. */ - case '\n': - ffelex_next_line_ (); - *ignore_ptr = 1; - return 0; -#endif - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - if (warn_traditional) - { - ffebad_start_msg_lex ("The meaning of `\\a' (at %0) varies with -traditional", - FFEBAD_severityWARNING); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': -#if 0 /* Vertical tab is present in common usage compilers. */ - if (flag_traditional) - return c; -#endif - return TARGET_VT; - - case 'e': - case 'E': - case '(': - case '{': - case '[': - case '%': - if (pedantic) - { - char m[2]; - - m[0] = c; - m[1] = '\0'; - ffebad_start_msg_lex ("Non-ANSI-C-standard escape sequence `\\%A' at %0", - FFEBAD_severityPEDANTIC); - ffelex_bad_here_ (0, line, column); - ffebad_string (m); - ffebad_finish (); - } - return (c == 'E' || c == 'e') ? 033 : c; - - case '?': - return c; - - default: - if (c >= 040 && c < 0177) - { - char m[2]; - - m[0] = c; - m[1] = '\0'; - ffebad_start_msg_lex ("Unknown escape sequence `\\%A' at %0", - FFEBAD_severityPEDANTIC); - ffelex_bad_here_ (0, line, column); - ffebad_string (m); - ffebad_finish (); - } - else if (c == EOF) - { - ffebad_start_msg_lex ("Unterminated escape sequence `\\' at %0", - FFEBAD_severityPEDANTIC); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - else - { - char m[20]; - - sprintf (&m[0], "%x", c); - ffebad_start_msg_lex ("Unknown escape sequence `\\' followed by char code 0x%A at %0", - FFEBAD_severityPEDANTIC); - ffelex_bad_here_ (0, line, column); - ffebad_string (m); - ffebad_finish (); - } - } - return c; - - case 2: - if ((c >= 'a' && c <= 'f') - || (c >= 'A' && c <= 'F') - || (c >= '0' && c <= '9')) - { - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - return EOF; - } - - state = 0; - - if (! nonnull) - { - ffebad_start_msg_lex ("\\x used at %0 with no following hex digits", - FFEBAD_severityFATAL); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && ((1 << (TYPE_PRECISION (integer_type_node) - (count - 1) * 4)) - <= (int) firstdig))) - { - ffebad_start_msg_lex ("Hex escape at %0 out of range", - FFEBAD_severityPEDANTIC); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - break; - - case 3: - if ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - return EOF; - } - state = 0; - break; - - default: - assert ("bad backslash state" == NULL); - abort (); - } - - /* Come here when code has a built character, and c is the next - character that might (or might not) be the next one in the constant. */ - - /* Don't bother doing this check for each character going into - CHARACTER or HOLLERITH constants, just the escaped-value ones. - gcc apparently checks every single character, which seems - like it'd be kinda slow and not worth doing anyway. */ - - if (!wide_flag - && TYPE_PRECISION (char_type_node) < HOST_BITS_PER_INT - && code >= (1 << TYPE_PRECISION (char_type_node))) - { - ffebad_start_msg_lex ("Escape sequence at %0 out of range for character", - FFEBAD_severityFATAL); - ffelex_bad_here_ (0, line, column); - ffebad_finish (); - } - - if (c == EOF) - { - /* Known end of constant, just append this character. */ - ffelex_append_to_token_ (code); - if (ffelex_raw_mode_ > 0) - --ffelex_raw_mode_; - return EOF; - } - - /* Have two characters to handle. Do the first, then leave it to the - caller to detect anything special about the second. */ - - ffelex_append_to_token_ (code); - if (ffelex_raw_mode_ > 0) - --ffelex_raw_mode_; - ffelex_backslash_reconsider_ = TRUE; - return c; -} - -/* ffelex_bad_1_ -- Issue diagnostic with one source point - - ffelex_bad_1_(FFEBAD_SOME_ERROR,ffelex_linecount_current_,column + 1); - - Creates ffewhere line and column objects for the source point, sends them - along with the error code to ffebad, then kills the line and column - objects before returning. */ - -static void -ffelex_bad_1_ (ffebad errnum, ffewhereLineNumber ln0, ffewhereColumnNumber cn0) -{ - ffewhereLine wl0; - ffewhereColumn wc0; - - wl0 = ffewhere_line_new (ln0); - wc0 = ffewhere_column_new (cn0); - ffebad_start_lex (errnum); - ffebad_here (0, wl0, wc0); - ffebad_finish (); - ffewhere_line_kill (wl0); - ffewhere_column_kill (wc0); -} - -/* ffelex_bad_2_ -- Issue diagnostic with two source points - - ffelex_bad_2_(FFEBAD_SOME_ERROR,ffelex_linecount_current_,column + 1, - otherline,othercolumn); - - Creates ffewhere line and column objects for the source points, sends them - along with the error code to ffebad, then kills the line and column - objects before returning. */ - -static void -ffelex_bad_2_ (ffebad errnum, ffewhereLineNumber ln0, ffewhereColumnNumber cn0, - ffewhereLineNumber ln1, ffewhereColumnNumber cn1) -{ - ffewhereLine wl0, wl1; - ffewhereColumn wc0, wc1; - - wl0 = ffewhere_line_new (ln0); - wc0 = ffewhere_column_new (cn0); - wl1 = ffewhere_line_new (ln1); - wc1 = ffewhere_column_new (cn1); - ffebad_start_lex (errnum); - ffebad_here (0, wl0, wc0); - ffebad_here (1, wl1, wc1); - ffebad_finish (); - ffewhere_line_kill (wl0); - ffewhere_column_kill (wc0); - ffewhere_line_kill (wl1); - ffewhere_column_kill (wc1); -} - -static void -ffelex_bad_here_ (int n, ffewhereLineNumber ln0, - ffewhereColumnNumber cn0) -{ - ffewhereLine wl0; - ffewhereColumn wc0; - - wl0 = ffewhere_line_new (ln0); - wc0 = ffewhere_column_new (cn0); - ffebad_here (n, wl0, wc0); - ffewhere_line_kill (wl0); - ffewhere_column_kill (wc0); -} - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int -ffelex_getc_ (FILE *finput) -{ - int c; - - if (ffelex_kludge_chars_ == NULL) - return getc (finput); - - c = *ffelex_kludge_chars_++; - if (c != 0) - return c; - - ffelex_kludge_chars_ = NULL; - return getc (finput); -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int -ffelex_cfebackslash_ (int *use_d, int *d, FILE *finput) -{ - register int c = getc (finput); - register int code; - register unsigned count; - unsigned firstdig = 0; - int nonnull; - - *use_d = 0; - - switch (c) - { - case 'x': - if (warn_traditional) - warning ("the meaning of `\\x' varies with -traditional"); - - if (flag_traditional) - return c; - - code = 0; - count = 0; - nonnull = 0; - while (1) - { - c = getc (finput); - if (!(c >= 'a' && c <= 'f') - && !(c >= 'A' && c <= 'F') - && !(c >= '0' && c <= '9')) - { - *use_d = 1; - *d = c; - break; - } - code *= 16; - if (c >= 'a' && c <= 'f') - code += c - 'a' + 10; - if (c >= 'A' && c <= 'F') - code += c - 'A' + 10; - if (c >= '0' && c <= '9') - code += c - '0'; - if (code != 0 || count != 0) - { - if (count == 0) - firstdig = code; - count++; - } - nonnull = 1; - } - if (! nonnull) - error ("\\x used with no following hex digits"); - else if (count == 0) - /* Digits are all 0's. Ok. */ - ; - else if ((count - 1) * 4 >= TYPE_PRECISION (integer_type_node) - || (count > 1 - && (((unsigned) 1 - << (TYPE_PRECISION (integer_type_node) - (count - 1) - * 4)) - <= firstdig))) - pedwarn ("hex escape out of range"); - return code; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': - code = 0; - count = 0; - while ((c <= '7') && (c >= '0') && (count++ < 3)) - { - code = (code * 8) + (c - '0'); - c = getc (finput); - } - *use_d = 1; - *d = c; - return code; - - case '\\': case '\'': case '"': - return c; - - case '\n': - ffelex_next_line_ (); - *use_d = 2; - return 0; - - case EOF: - *use_d = 1; - *d = EOF; - return EOF; - - case 'n': - return TARGET_NEWLINE; - - case 't': - return TARGET_TAB; - - case 'r': - return TARGET_CR; - - case 'f': - return TARGET_FF; - - case 'b': - return TARGET_BS; - - case 'a': - if (warn_traditional) - warning ("the meaning of `\\a' varies with -traditional"); - - if (flag_traditional) - return c; - return TARGET_BELL; - - case 'v': -#if 0 /* Vertical tab is present in common usage compilers. */ - if (flag_traditional) - return c; -#endif - return TARGET_VT; - - case 'e': - case 'E': - if (pedantic) - pedwarn ("non-ANSI-standard escape sequence, `\\%c'", c); - return 033; - - case '?': - return c; - - /* `\(', etc, are used at beginning of line to avoid confusing Emacs. */ - case '(': - case '{': - case '[': - /* `\%' is used to prevent SCCS from getting confused. */ - case '%': - if (pedantic) - pedwarn ("non-ANSI escape sequence `\\%c'", c); - return c; - } - if (c >= 040 && c < 0177) - pedwarn ("unknown escape sequence `\\%c'", c); - else - pedwarn ("unknown escape sequence: `\\' followed by char code 0x%x", c); - return c; -} - -#endif -/* A miniature version of the C front-end lexer. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int -ffelex_cfelex_ (ffelexToken *xtoken, FILE *finput, int c) -{ - ffelexToken token; - char buff[129]; - char *p; - char *q; - char *r; - register unsigned buffer_length; - - if ((*xtoken != NULL) && !ffelex_kludge_flag_) - ffelex_token_kill (*xtoken); - - switch (c) - { - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - buffer_length = ARRAY_SIZE (buff); - p = &buff[0]; - q = p; - r = &buff[buffer_length]; - for (;;) - { - *p++ = c; - if (p >= r) - { - register unsigned bytes_used = (p - q); - - buffer_length *= 2; - q = (char *)xrealloc (q, buffer_length); - p = &q[bytes_used]; - r = &q[buffer_length]; - } - c = ffelex_getc_ (finput); - if (! ISDIGIT (c)) - break; - } - *p = '\0'; - token = ffelex_token_new_number (q, ffewhere_line_unknown (), - ffewhere_column_unknown ()); - - if (q != &buff[0]) - free (q); - - break; - - case '\"': - buffer_length = ARRAY_SIZE (buff); - p = &buff[0]; - q = p; - r = &buff[buffer_length]; - c = ffelex_getc_ (finput); - for (;;) - { - bool done = FALSE; - int use_d = 0; - int d; - - switch (c) - { - case '\"': - c = getc (finput); - done = TRUE; - break; - - case '\\': /* ~~~~~ */ - c = ffelex_cfebackslash_ (&use_d, &d, finput); - break; - - case EOF: - case '\n': - fatal ("Badly formed directive -- no closing quote"); - done = TRUE; - break; - - default: - break; - } - if (done) - break; - - if (use_d != 2) /* 0=>c, 1=>cd, 2=>nil. */ - { - *p++ = c; - if (p >= r) - { - register unsigned bytes_used = (p - q); - - buffer_length = bytes_used * 2; - q = (char *)xrealloc (q, buffer_length); - p = &q[bytes_used]; - r = &q[buffer_length]; - } - } - if (use_d == 1) - c = d; - else - c = getc (finput); - } - *p = '\0'; - token = ffelex_token_new_character (q, ffewhere_line_unknown (), - ffewhere_column_unknown ()); - - if (q != &buff[0]) - free (q); - - break; - - default: - token = NULL; - break; - } - - *xtoken = token; - return c; -} -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffelex_file_pop_ (char *input_filename) -{ - if (input_file_stack->next) - { - struct file_stack *p = input_file_stack; - input_file_stack = p->next; - free (p); - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_resume_previous_source_file (input_file_stack->line); -#endif /* DWARF_DEBUGGING_INFO */ - } - else - error ("#-lines for entering and leaving files don't match"); - - /* Now that we've pushed or popped the input stack, - update the name in the top element. */ - if (input_file_stack) - input_file_stack->name = input_filename; -} - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffelex_file_push_ (int old_lineno, char *input_filename) -{ - struct file_stack *p - = (struct file_stack *) xmalloc (sizeof (struct file_stack)); - - input_file_stack->line = old_lineno; - p->next = input_file_stack; - p->name = input_filename; - input_file_stack = p; - input_file_stack_tick++; -#ifdef DWARF_DEBUGGING_INFO - if (debug_info_level == DINFO_LEVEL_VERBOSE - && write_symbols == DWARF_DEBUG) - dwarfout_start_new_source_file (input_filename); -#endif /* DWARF_DEBUGGING_INFO */ - - /* Now that we've pushed or popped the input stack, - update the name in the top element. */ - if (input_file_stack) - input_file_stack->name = input_filename; -} -#endif - -/* Prepare to finish a statement-in-progress by sending the current - token, if any, then setting up EOS as the current token with the - appropriate current pointer. The caller can then move the current - pointer before actually sending EOS, if desired, as it is in - typical fixed-form cases. */ - -static void -ffelex_prepare_eos_ () -{ - if (ffelex_token_->type != FFELEX_typeNONE) - { - ffelex_backslash_ (EOF, 0); - - switch (ffelex_raw_mode_) - { - case -2: - break; - - case -1: - ffebad_start_lex ((ffelex_raw_char_ == '\'') ? FFEBAD_NO_CLOSING_APOSTROPHE - : FFEBAD_NO_CLOSING_QUOTE); - ffebad_here (0, ffelex_token_->where_line, ffelex_token_->where_col); - ffebad_here (1, ffelex_current_wl_, ffelex_current_wc_); - ffebad_finish (); - break; - - case 0: - break; - - default: - { - char num[20]; - - ffebad_start_lex (FFEBAD_NOT_ENOUGH_HOLLERITH_CHARS); - ffebad_here (0, ffelex_token_->where_line, ffelex_token_->where_col); - ffebad_here (1, ffelex_current_wl_, ffelex_current_wc_); - sprintf (num, "%lu", (unsigned long) ffelex_raw_mode_); - ffebad_string (num); - ffebad_finish (); - /* Make sure the token has some text, might as well fill up with spaces. */ - do - { - ffelex_append_to_token_ (' '); - } while (--ffelex_raw_mode_ > 0); - break; - } - } - ffelex_raw_mode_ = 0; - ffelex_send_token_ (); - } - ffelex_token_->type = FFELEX_typeEOS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_use (ffelex_current_wc_); -} - -static void -ffelex_finish_statement_ () -{ - if ((ffelex_number_of_tokens_ == 0) - && (ffelex_token_->type == FFELEX_typeNONE)) - return; /* Don't have a statement pending. */ - - if (ffelex_token_->type != FFELEX_typeEOS) - ffelex_prepare_eos_ (); - - ffelex_permit_include_ = TRUE; - ffelex_send_token_ (); - ffelex_permit_include_ = FALSE; - ffelex_number_of_tokens_ = 0; - ffelex_label_tokens_ = 0; - ffelex_names_ = TRUE; - ffelex_names_pure_ = FALSE; /* Probably not necessary. */ - ffelex_hexnum_ = FALSE; - - if (!ffe_is_ffedebug ()) - return; - - /* For debugging purposes only. */ - - if (ffelex_total_tokens_ != ffelex_old_total_tokens_) - { - fprintf (dmpout, "; token_track had %ld tokens, now have %ld.\n", - ffelex_old_total_tokens_, ffelex_total_tokens_); - ffelex_old_total_tokens_ = ffelex_total_tokens_; - } -} - -/* Copied from gcc/c-common.c get_directive_line. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int -ffelex_get_directive_line_ (char **text, FILE *finput) -{ - static char *directive_buffer = NULL; - static unsigned buffer_length = 0; - register char *p; - register char *buffer_limit; - register int looking_for = 0; - register int char_escaped = 0; - - if (buffer_length == 0) - { - directive_buffer = (char *)xmalloc (128); - buffer_length = 128; - } - - buffer_limit = &directive_buffer[buffer_length]; - - for (p = directive_buffer; ; ) - { - int c; - - /* Make buffer bigger if it is full. */ - if (p >= buffer_limit) - { - register unsigned bytes_used = (p - directive_buffer); - - buffer_length *= 2; - directive_buffer - = (char *)xrealloc (directive_buffer, buffer_length); - p = &directive_buffer[bytes_used]; - buffer_limit = &directive_buffer[buffer_length]; - } - - c = getc (finput); - - /* Discard initial whitespace. */ - if ((c == ' ' || c == '\t') && p == directive_buffer) - continue; - - /* Detect the end of the directive. */ - if ((c == '\n' && looking_for == 0) - || c == EOF) - { - if (looking_for != 0) - fatal ("Bad directive -- missing close-quote"); - - *p++ = '\0'; - *text = directive_buffer; - return c; - } - - *p++ = c; - if (c == '\n') - ffelex_next_line_ (); - - /* Handle string and character constant syntax. */ - if (looking_for) - { - if (looking_for == c && !char_escaped) - looking_for = 0; /* Found terminator... stop looking. */ - } - else - if (c == '\'' || c == '"') - looking_for = c; /* Don't stop buffering until we see another - one of these (or an EOF). */ - - /* Handle backslash. */ - char_escaped = (c == '\\' && ! char_escaped); - } -} -#endif - -/* Handle # directives that make it through (or are generated by) the - preprocessor. As much as reasonably possible, emulate the behavior - of the gcc compiler phase cc1, though interactions between #include - and INCLUDE might possibly produce bizarre results in terms of - error reporting and the generation of debugging info vis-a-vis the - locations of some things. - - Returns the next character unhandled, which is always newline or EOF. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - -#if defined HANDLE_PRAGMA -/* Local versions of these macros, that can be passed as function pointers. */ -static int -pragma_getc () -{ - return getc (finput); -} - -static void -pragma_ungetc (arg) - int arg; -{ - ungetc (arg, finput); -} -#endif /* HANDLE_PRAGMA */ - -static int -ffelex_hash_ (FILE *finput) -{ - register int c; - ffelexToken token = NULL; - - /* Read first nonwhite char after the `#'. */ - - c = ffelex_getc_ (finput); - while (c == ' ' || c == '\t') - c = ffelex_getc_ (finput); - - /* If a letter follows, then if the word here is `line', skip - it and ignore it; otherwise, ignore the line, with an error - if the word isn't `pragma', `ident', `define', or `undef'. */ - - if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) - { - if (c == 'p') - { - if (getc (finput) == 'r' - && getc (finput) == 'a' - && getc (finput) == 'g' - && getc (finput) == 'm' - && getc (finput) == 'a' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n' - || c == EOF)) - { -#if 0 /* g77 doesn't handle pragmas, so ignores them FOR NOW. */ - static char buffer [128]; - char * buff = buffer; - - /* Read the pragma name into a buffer. */ - while (isspace (c = getc (finput))) - continue; - - do - { - * buff ++ = c; - c = getc (finput); - } - while (c != EOF && ! isspace (c) && c != '\n' - && buff < buffer + 128); - - pragma_ungetc (c); - - * -- buff = 0; -#ifdef HANDLE_PRAGMA - if (HANDLE_PRAGMA (pragma_getc, pragma_ungetc, buffer)) - goto skipline; -#endif /* HANDLE_PRAGMA */ -#ifdef HANDLE_GENERIC_PRAGMAS - if (handle_generic_pragma (buffer)) - goto skipline; -#endif /* !HANDLE_GENERIC_PRAGMAS */ - - /* Issue a warning message if we have been asked to do so. - Ignoring unknown pragmas in system header file unless - an explcit -Wunknown-pragmas has been given. */ - if (warn_unknown_pragmas > 1 - || (warn_unknown_pragmas && ! in_system_header)) - warning ("ignoring pragma: %s", token_buffer); -#endif /* 0 */ - goto skipline; - } - } - - else if (c == 'd') - { - if (getc (finput) == 'e' - && getc (finput) == 'f' - && getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n' - || c == EOF)) - { - char *text; - - c = ffelex_get_directive_line_ (&text, finput); - -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_define (lineno, text); -#endif /* DWARF_DEBUGGING_INFO */ - - goto skipline; - } - } - else if (c == 'u') - { - if (getc (finput) == 'n' - && getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'f' - && ((c = getc (finput)) == ' ' || c == '\t' || c == '\n' - || c == EOF)) - { - char *text; - - c = ffelex_get_directive_line_ (&text, finput); - -#ifdef DWARF_DEBUGGING_INFO - if ((debug_info_level == DINFO_LEVEL_VERBOSE) - && (write_symbols == DWARF_DEBUG)) - dwarfout_undef (lineno, text); -#endif /* DWARF_DEBUGGING_INFO */ - - goto skipline; - } - } - else if (c == 'l') - { - if (getc (finput) == 'i' - && getc (finput) == 'n' - && getc (finput) == 'e' - && ((c = getc (finput)) == ' ' || c == '\t')) - goto linenum; - } - else if (c == 'i') - { - if (getc (finput) == 'd' - && getc (finput) == 'e' - && getc (finput) == 'n' - && getc (finput) == 't' - && ((c = getc (finput)) == ' ' || c == '\t')) - { - /* #ident. The pedantic warning is now in cccp.c. */ - - /* Here we have just seen `#ident '. - A string constant should follow. */ - - while (c == ' ' || c == '\t') - c = getc (finput); - - /* If no argument, ignore the line. */ - if (c == '\n' || c == EOF) - return c; - - c = ffelex_cfelex_ (&token, finput, c); - - if ((token == NULL) - || (ffelex_token_type (token) != FFELEX_typeCHARACTER)) - { - error ("invalid #ident"); - goto skipline; - } - - if (ffe_is_ident ()) - { -#ifdef ASM_OUTPUT_IDENT - ASM_OUTPUT_IDENT (asm_out_file, - ffelex_token_text (token)); -#endif - } - - /* Skip the rest of this line. */ - goto skipline; - } - } - - error ("undefined or invalid # directive"); - goto skipline; - } - - linenum: - /* Here we have either `#line' or `# <nonletter>'. - In either case, it should be a line number; a digit should follow. */ - - while (c == ' ' || c == '\t') - c = ffelex_getc_ (finput); - - /* If the # is the only nonwhite char on the line, - just ignore it. Check the new newline. */ - if (c == '\n' || c == EOF) - return c; - - /* Something follows the #; read a token. */ - - c = ffelex_cfelex_ (&token, finput, c); - - if ((token != NULL) - && (ffelex_token_type (token) == FFELEX_typeNUMBER)) - { - int old_lineno = lineno; - char *old_input_filename = input_filename; - ffewhereFile wf; - - /* subtract one, because it is the following line that - gets the specified number */ - int l = atoi (ffelex_token_text (token)) - 1; - - /* Is this the last nonwhite stuff on the line? */ - while (c == ' ' || c == '\t') - c = ffelex_getc_ (finput); - if (c == '\n' || c == EOF) - { - /* No more: store the line number and check following line. */ - lineno = l; - if (!ffelex_kludge_flag_) - { - ffewhere_file_set (NULL, TRUE, (ffewhereLineNumber) l); - - if (token != NULL) - ffelex_token_kill (token); - } - return c; - } - - /* More follows: it must be a string constant (filename). */ - - /* Read the string constant. */ - c = ffelex_cfelex_ (&token, finput, c); - - if ((token == NULL) - || (ffelex_token_type (token) != FFELEX_typeCHARACTER)) - { - error ("invalid #line"); - goto skipline; - } - - lineno = l; - - if (ffelex_kludge_flag_) - input_filename = ffelex_token_text (token); - else - { - wf = ffewhere_file_new (ffelex_token_text (token), - ffelex_token_length (token)); - input_filename = ffewhere_file_name (wf); - ffewhere_file_set (wf, TRUE, (ffewhereLineNumber) l); - } - -#if 0 /* Not sure what g77 should do with this yet. */ - /* Each change of file name - reinitializes whether we are now in a system header. */ - in_system_header = 0; -#endif - - if (main_input_filename == 0) - main_input_filename = input_filename; - - /* Is this the last nonwhite stuff on the line? */ - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n' || c == EOF) - { - if (!ffelex_kludge_flag_) - { - /* Update the name in the top element of input_file_stack. */ - if (input_file_stack) - input_file_stack->name = input_filename; - - if (token != NULL) - ffelex_token_kill (token); - } - return c; - } - - c = ffelex_cfelex_ (&token, finput, c); - - /* `1' after file name means entering new file. - `2' after file name means just left a file. */ - - if ((token != NULL) - && (ffelex_token_type (token) == FFELEX_typeNUMBER)) - { - int num = atoi (ffelex_token_text (token)); - - if (ffelex_kludge_flag_) - { - lineno = 1; - input_filename = old_input_filename; - fatal ("Use `#line ...' instead of `# ...' in first line"); - } - - if (num == 1) - { - /* Pushing to a new file. */ - ffelex_file_push_ (old_lineno, input_filename); - } - else if (num == 2) - { - /* Popping out of a file. */ - ffelex_file_pop_ (input_filename); - } - - /* Is this the last nonwhite stuff on the line? */ - while (c == ' ' || c == '\t') - c = getc (finput); - if (c == '\n' || c == EOF) - { - if (token != NULL) - ffelex_token_kill (token); - return c; - } - - c = ffelex_cfelex_ (&token, finput, c); - } - - /* `3' after file name means this is a system header file. */ - -#if 0 /* Not sure what g77 should do with this yet. */ - if ((token != NULL) - && (ffelex_token_type (token) == FFELEX_typeNUMBER) - && (atoi (ffelex_token_text (token)) == 3)) - in_system_header = 1; -#endif - - while (c == ' ' || c == '\t') - c = getc (finput); - if (((token != NULL) - || (c != '\n' && c != EOF)) - && ffelex_kludge_flag_) - { - lineno = 1; - input_filename = old_input_filename; - fatal ("Use `#line ...' instead of `# ...' in first line"); - } - } - else - error ("invalid #-line"); - - /* skip the rest of this line. */ - skipline: - if ((token != NULL) && !ffelex_kludge_flag_) - ffelex_token_kill (token); - while ((c = getc (finput)) != EOF && c != '\n') - ; - return c; -} -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - -/* "Image" a character onto the card image, return incremented column number. - - Normally invoking this function as in - column = ffelex_image_char_ (c, column); - is the same as doing: - ffelex_card_image_[column++] = c; - - However, tabs and carriage returns are handled specially, to preserve - the visual "image" of the input line (in most editors) in the card - image. - - Carriage returns are ignored, as they are assumed to be followed - by newlines. - - A tab is handled by first doing: - ffelex_card_image_[column++] = ' '; - That is, it translates to at least one space. Then, as many spaces - are imaged as necessary to bring the column number to the next tab - position, where tab positions start in the ninth column and each - eighth column afterwards. ALSO, a static var named ffelex_saw_tab_ - is set to TRUE to notify the lexer that a tab was seen. - - Columns are numbered and tab stops set as illustrated below: - - 012345670123456701234567... - x y z - xx yy zz - ... - xxxxxxx yyyyyyy zzzzzzz - xxxxxxxx yyyyyyyy... */ - -static ffewhereColumnNumber -ffelex_image_char_ (int c, ffewhereColumnNumber column) -{ - ffewhereColumnNumber old_column = column; - - if (column >= ffelex_card_size_) - { - ffewhereColumnNumber newmax = ffelex_card_size_ << 1; - - if (ffelex_bad_line_) - return column; - - if ((newmax >> 1) != ffelex_card_size_) - { /* Overflowed column number. */ - overflow: /* :::::::::::::::::::: */ - - ffelex_bad_line_ = TRUE; - strcpy (&ffelex_card_image_[column - 3], "..."); - ffelex_card_length_ = column; - ffelex_bad_1_ (FFEBAD_LINE_TOO_LONG, - ffelex_linecount_current_, column + 1); - return column; - } - - ffelex_card_image_ - = malloc_resize_ksr (malloc_pool_image (), - ffelex_card_image_, - newmax + 9, - ffelex_card_size_ + 9); - ffelex_card_size_ = newmax; - } - - switch (c) - { - case '\r': - break; - - case '\t': - ffelex_saw_tab_ = TRUE; - ffelex_card_image_[column++] = ' '; - while ((column & 7) != 0) - ffelex_card_image_[column++] = ' '; - break; - - case '\0': - if (!ffelex_bad_line_) - { - ffelex_bad_line_ = TRUE; - strcpy (&ffelex_card_image_[column], "[\\0]"); - ffelex_card_length_ = column + 4; - ffebad_start_msg_lex ("Null character at %0 -- line ignored", - FFEBAD_severityFATAL); - ffelex_bad_here_ (0, ffelex_linecount_current_, column + 1); - ffebad_finish (); - column += 4; - } - break; - - default: - ffelex_card_image_[column++] = c; - break; - } - - if (column < old_column) - { - column = old_column; - goto overflow; /* :::::::::::::::::::: */ - } - - return column; -} - -static void -ffelex_include_ () -{ - ffewhereFile include_wherefile = ffelex_include_wherefile_; - FILE *include_file = ffelex_include_file_; - /* The rest of this is to push, and after the INCLUDE file is processed, - pop, the static lexer state info that pertains to each particular - input file. */ - char *card_image; - ffewhereColumnNumber card_size = ffelex_card_size_; - ffewhereColumnNumber card_length = ffelex_card_length_; - ffewhereLine current_wl = ffelex_current_wl_; - ffewhereColumn current_wc = ffelex_current_wc_; - bool saw_tab = ffelex_saw_tab_; - ffewhereColumnNumber final_nontab_column = ffelex_final_nontab_column_; - ffewhereFile current_wf = ffelex_current_wf_; - ffewhereLineNumber linecount_current = ffelex_linecount_current_; - ffewhereLineNumber linecount_offset - = ffewhere_line_filelinenum (current_wl); -#if FFECOM_targetCURRENT == FFECOM_targetGCC - int old_lineno = lineno; - char *old_input_filename = input_filename; -#endif - - if (card_length != 0) - { - card_image = malloc_new_ks (malloc_pool_image (), - "FFELEX saved card image", - card_length); - memcpy (card_image, ffelex_card_image_, card_length); - } - else - card_image = NULL; - - ffelex_set_include_ = FALSE; - - ffelex_next_line_ (); - - ffewhere_file_set (include_wherefile, TRUE, 0); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffelex_file_push_ (old_lineno, ffewhere_file_name (include_wherefile)); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - - if (ffelex_include_free_form_) - ffelex_file_free (include_wherefile, include_file); - else - ffelex_file_fixed (include_wherefile, include_file); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffelex_file_pop_ (ffewhere_file_name (current_wf)); -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC */ - - ffewhere_file_set (current_wf, TRUE, linecount_offset); - - ffecom_close_include (include_file); - - if (card_length != 0) - { -#ifdef REDUCE_CARD_SIZE_AFTER_BIGGY /* Define if occasional large lines. */ -#error "need to handle possible reduction of card size here!!" -#endif - assert (ffelex_card_size_ >= card_length); /* It shrunk?? */ - memcpy (ffelex_card_image_, card_image, card_length); - } - ffelex_card_image_[card_length] = '\0'; - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - input_filename = old_input_filename; - lineno = old_lineno; -#endif - ffelex_linecount_current_ = linecount_current; - ffelex_current_wf_ = current_wf; - ffelex_final_nontab_column_ = final_nontab_column; - ffelex_saw_tab_ = saw_tab; - ffelex_current_wc_ = current_wc; - ffelex_current_wl_ = current_wl; - ffelex_card_length_ = card_length; - ffelex_card_size_ = card_size; -} - -/* ffelex_is_free_char_ctx_contin_ -- Character Context Continuation? - - ffewhereColumnNumber col; - int c; // Char at col. - if ((c == '&') && ffelex_is_free_char_ctx_contin_(col + 1)) - // We have a continuation indicator. - - If there are <n> spaces starting at ffelex_card_image_[col] up through - the null character, where <n> is 0 or greater, returns TRUE. */ - -static bool -ffelex_is_free_char_ctx_contin_ (ffewhereColumnNumber col) -{ - while (ffelex_card_image_[col] != '\0') - { - if (ffelex_card_image_[col++] != ' ') - return FALSE; - } - return TRUE; -} - -/* ffelex_is_free_nonc_ctx_contin_ -- Noncharacter Context Continuation? - - ffewhereColumnNumber col; - int c; // Char at col. - if ((c == '&') && ffelex_is_free_nonc_ctx_contin_(col + 1)) - // We have a continuation indicator. - - If there are <n> spaces starting at ffelex_card_image_[col] up through - the null character or '!', where <n> is 0 or greater, returns TRUE. */ - -static bool -ffelex_is_free_nonc_ctx_contin_ (ffewhereColumnNumber col) -{ - while ((ffelex_card_image_[col] != '\0') && (ffelex_card_image_[col] != '!')) - { - if (ffelex_card_image_[col++] != ' ') - return FALSE; - } - return TRUE; -} - -static void -ffelex_next_line_ () -{ - ffelex_linecount_current_ = ffelex_linecount_next_; - ++ffelex_linecount_next_; -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ++lineno; -#endif -} - -static void -ffelex_send_token_ () -{ - ++ffelex_number_of_tokens_; - - ffelex_backslash_ (EOF, 0); - - if (ffelex_token_->text == NULL) - { - if (ffelex_token_->type == FFELEX_typeCHARACTER) - { - ffelex_append_to_token_ ('\0'); - ffelex_token_->length = 0; - } - } - else - ffelex_token_->text[ffelex_token_->length] = '\0'; - - assert (ffelex_raw_mode_ == 0); - - if (ffelex_token_->type == FFELEX_typeNAMES) - { - ffewhere_line_kill (ffelex_token_->currentnames_line); - ffewhere_column_kill (ffelex_token_->currentnames_col); - } - - assert (ffelex_handler_ != NULL); - ffelex_handler_ = (ffelexHandler) (*ffelex_handler_) (ffelex_token_); - assert (ffelex_handler_ != NULL); - - ffelex_token_kill (ffelex_token_); - - ffelex_token_ = ffelex_token_new_ (); - ffelex_token_->uses = 1; - ffelex_token_->text = NULL; - if (ffelex_raw_mode_ < 0) - { - ffelex_token_->type = FFELEX_typeCHARACTER; - ffelex_token_->where_line = ffelex_raw_where_line_; - ffelex_token_->where_col = ffelex_raw_where_col_; - ffelex_raw_where_line_ = ffewhere_line_unknown (); - ffelex_raw_where_col_ = ffewhere_column_unknown (); - } - else - { - ffelex_token_->type = FFELEX_typeNONE; - ffelex_token_->where_line = ffewhere_line_unknown (); - ffelex_token_->where_col = ffewhere_column_unknown (); - } - - if (ffelex_set_include_) - ffelex_include_ (); -} - -/* ffelex_swallow_tokens_ -- Eat all tokens delivered to me - - return ffelex_swallow_tokens_; - - Return this handler when you don't want to look at any more tokens in the - statement because you've encountered an unrecoverable error in the - statement. */ - -static ffelexHandler -ffelex_swallow_tokens_ (ffelexToken t) -{ - assert (ffelex_eos_handler_ != NULL); - - if ((ffelex_token_type (t) == FFELEX_typeEOS) - || (ffelex_token_type (t) == FFELEX_typeSEMICOLON)) - return (ffelexHandler) (*ffelex_eos_handler_) (t); - - return (ffelexHandler) ffelex_swallow_tokens_; -} - -static ffelexToken -ffelex_token_new_ () -{ - ffelexToken t; - - ++ffelex_total_tokens_; - - t = (ffelexToken) malloc_new_ks (malloc_pool_image (), - "FFELEX token", sizeof (*t)); - t->id_ = ffelex_token_nextid_++; - return t; -} - -static char * -ffelex_type_string_ (ffelexType type) -{ - static char *types[] = { - "FFELEX_typeNONE", - "FFELEX_typeCOMMENT", - "FFELEX_typeEOS", - "FFELEX_typeEOF", - "FFELEX_typeERROR", - "FFELEX_typeRAW", - "FFELEX_typeQUOTE", - "FFELEX_typeDOLLAR", - "FFELEX_typeHASH", - "FFELEX_typePERCENT", - "FFELEX_typeAMPERSAND", - "FFELEX_typeAPOSTROPHE", - "FFELEX_typeOPEN_PAREN", - "FFELEX_typeCLOSE_PAREN", - "FFELEX_typeASTERISK", - "FFELEX_typePLUS", - "FFELEX_typeMINUS", - "FFELEX_typePERIOD", - "FFELEX_typeSLASH", - "FFELEX_typeNUMBER", - "FFELEX_typeOPEN_ANGLE", - "FFELEX_typeEQUALS", - "FFELEX_typeCLOSE_ANGLE", - "FFELEX_typeNAME", - "FFELEX_typeCOMMA", - "FFELEX_typePOWER", - "FFELEX_typeCONCAT", - "FFELEX_typeDEBUG", - "FFELEX_typeNAMES", - "FFELEX_typeHOLLERITH", - "FFELEX_typeCHARACTER", - "FFELEX_typeCOLON", - "FFELEX_typeSEMICOLON", - "FFELEX_typeUNDERSCORE", - "FFELEX_typeQUESTION", - "FFELEX_typeOPEN_ARRAY", - "FFELEX_typeCLOSE_ARRAY", - "FFELEX_typeCOLONCOLON", - "FFELEX_typeREL_LE", - "FFELEX_typeREL_NE", - "FFELEX_typeREL_EQ", - "FFELEX_typePOINTS", - "FFELEX_typeREL_GE" - }; - - if (type >= ARRAY_SIZE (types)) - return "???"; - return types[type]; -} - -void -ffelex_display_token (ffelexToken t) -{ - if (t == NULL) - t = ffelex_token_; - - fprintf (dmpout, "; Token #%lu is %s (line %" ffewhereLineNumber_f "u, col %" - ffewhereColumnNumber_f "u)", - t->id_, - ffelex_type_string_ (t->type), - ffewhere_line_number (t->where_line), - ffewhere_column_number (t->where_col)); - - if (t->text != NULL) - fprintf (dmpout, ": \"%.*s\"\n", - (int) t->length, - t->text); - else - fprintf (dmpout, ".\n"); -} - -/* ffelex_expecting_character -- Tells if next token expected to be CHARACTER - - if (ffelex_expecting_character()) - // next token delivered by lexer will be CHARACTER. - - If the most recent call to ffelex_set_expecting_hollerith since the last - token was delivered by the lexer passed a length of -1, then we return - TRUE, because the next token we deliver will be typeCHARACTER, else we - return FALSE. */ - -bool -ffelex_expecting_character () -{ - return (ffelex_raw_mode_ != 0); -} - -/* ffelex_file_fixed -- Lex a given file in fixed source form - - ffewhere wf; - FILE *f; - ffelex_file_fixed(wf,f); - - Lexes the file according to Fortran 90 ANSI + VXT specifications. */ - -ffelexHandler -ffelex_file_fixed (ffewhereFile wf, FILE *f) -{ - register int c = 0; /* Character currently under consideration. */ - register ffewhereColumnNumber column = 0; /* Not really; 0 means column 1... */ - bool disallow_continuation_line; - bool ignore_disallowed_continuation = FALSE; - int latest_char_in_file = 0; /* For getting back into comment-skipping - code. */ - ffelexType lextype; - ffewhereColumnNumber first_label_char; /* First char of label -- - column number. */ - char label_string[6]; /* Text of label. */ - int labi; /* Length of label text. */ - bool finish_statement; /* Previous statement finished? */ - bool have_content; /* This line have content? */ - bool just_do_label; /* Nothing but label (and continuation?) on - line. */ - - /* Lex is called for a particular file, not for a particular program unit. - Yet the two events do share common characteristics. The first line in a - file or in a program unit cannot be a continuation line. No token can - be in mid-formation. No current label for the statement exists, since - there is no current statement. */ - - assert (ffelex_handler_ != NULL); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - lineno = 0; - input_filename = ffewhere_file_name (wf); -#endif - ffelex_current_wf_ = wf; - disallow_continuation_line = TRUE; - ignore_disallowed_continuation = FALSE; - ffelex_token_->type = FFELEX_typeNONE; - ffelex_number_of_tokens_ = 0; - ffelex_label_tokens_ = 0; - ffelex_current_wl_ = ffewhere_line_unknown (); - ffelex_current_wc_ = ffewhere_column_unknown (); - latest_char_in_file = '\n'; - - if (ffe_is_null_version ()) - { - /* Just substitute a "program" directly here. */ - - char line[] = " call g77__fvers;call g77__ivers;call g77__uvers;end"; - char *p; - - column = 0; - for (p = &line[0]; *p != '\0'; ++p) - column = ffelex_image_char_ (*p, column); - - c = EOF; - - goto have_line; /* :::::::::::::::::::: */ - } - - goto first_line; /* :::::::::::::::::::: */ - - /* Come here to get a new line. */ - - beginning_of_line: /* :::::::::::::::::::: */ - - disallow_continuation_line = FALSE; - - /* Come here directly when last line didn't clarify the continuation issue. */ - - beginning_of_line_again: /* :::::::::::::::::::: */ - -#ifdef REDUCE_CARD_SIZE_AFTER_BIGGY /* Define if occasional large lines. */ - if (ffelex_card_size_ != FFELEX_columnINITIAL_SIZE_) - { - ffelex_card_image_ - = malloc_resize_ks (malloc_pool_image (), - ffelex_card_image_, - FFELEX_columnINITIAL_SIZE_ + 9, - ffelex_card_size_ + 9); - ffelex_card_size_ = FFELEX_columnINITIAL_SIZE_; - } -#endif - - first_line: /* :::::::::::::::::::: */ - - c = latest_char_in_file; - if ((c == EOF) || ((c = ffelex_getc_ (f)) == EOF)) - { - - end_of_file: /* :::::::::::::::::::: */ - - /* Line ending in EOF instead of \n still counts as a whole line. */ - - ffelex_finish_statement_ (); - ffewhere_line_kill (ffelex_current_wl_); - ffewhere_column_kill (ffelex_current_wc_); - return (ffelexHandler) ffelex_handler_; - } - - ffelex_next_line_ (); - - ffelex_bad_line_ = FALSE; - - /* Skip over comment (and otherwise ignored) lines as quickly as possible! */ - - while (((lextype = ffelex_first_char_[c]) == FFELEX_typeCOMMENT) - || (lextype == FFELEX_typeERROR) - || (lextype == FFELEX_typeSLASH) - || (lextype == FFELEX_typeHASH)) - { - /* Test most frequent type of line first, etc. */ - if ((lextype == FFELEX_typeCOMMENT) - || ((lextype == FFELEX_typeSLASH) - && ((c = getc (f)) == '*'))) /* NOTE SIDE-EFFECT. */ - { - /* Typical case (straight comment), just ignore rest of line. */ - comment_line: /* :::::::::::::::::::: */ - - while ((c != '\n') && (c != EOF)) - c = getc (f); - } -#if FFECOM_targetCURRENT == FFECOM_targetGCC - else if (lextype == FFELEX_typeHASH) - c = ffelex_hash_ (f); -#endif - else if (lextype == FFELEX_typeSLASH) - { - /* SIDE-EFFECT ABOVE HAS HAPPENED. */ - ffelex_card_image_[0] = '/'; - ffelex_card_image_[1] = c; - column = 2; - goto bad_first_character; /* :::::::::::::::::::: */ - } - else - /* typeERROR or unsupported typeHASH. */ - { /* Bad first character, get line and display - it with message. */ - column = ffelex_image_char_ (c, 0); - - bad_first_character: /* :::::::::::::::::::: */ - - ffelex_bad_line_ = TRUE; - while (((c = getc (f)) != '\n') && (c != EOF)) - column = ffelex_image_char_ (c, column); - ffelex_card_image_[column] = '\0'; - ffelex_card_length_ = column; - ffelex_bad_1_ (FFEBAD_FIRST_CHAR_INVALID, - ffelex_linecount_current_, 1); - } - - /* Read past last char in line. */ - - if (c == EOF) - { - ffelex_next_line_ (); - goto end_of_file; /* :::::::::::::::::::: */ - } - - c = getc (f); - - ffelex_next_line_ (); - - if (c == EOF) - goto end_of_file; /* :::::::::::::::::::: */ - - ffelex_bad_line_ = FALSE; - } /* while [c, first char, means comment] */ - - ffelex_saw_tab_ - = (c == '&') - || (ffelex_final_nontab_column_ == 0); - - if (lextype == FFELEX_typeDEBUG) - c = ' '; /* A 'D' or 'd' in column 1 with the - debug-lines option on. */ - - column = ffelex_image_char_ (c, 0); - - /* Read the entire line in as is (with whitespace processing). */ - - while (((c = getc (f)) != '\n') && (c != EOF)) - column = ffelex_image_char_ (c, column); - - if (ffelex_bad_line_) - { - ffelex_card_image_[column] = '\0'; - ffelex_card_length_ = column; - goto comment_line; /* :::::::::::::::::::: */ - } - - /* If no tab, cut off line after column 72/132. */ - - if (!ffelex_saw_tab_ && (column > ffelex_final_nontab_column_)) - { - /* Technically, we should now fill ffelex_card_image_ up thru column - 72/132 with spaces, since character/hollerith constants must count - them in that manner. To save CPU time in several ways (avoid a loop - here that would be used only when we actually end a line in - character-constant mode; avoid writing memory unnecessarily; avoid a - loop later checking spaces when not scanning for character-constant - characters), we don't do this, and we do the appropriate thing when - we encounter end-of-line while actually processing a character - constant. */ - - column = ffelex_final_nontab_column_; - } - - have_line: /* :::::::::::::::::::: */ - - ffelex_card_image_[column] = '\0'; - ffelex_card_length_ = column; - - /* Save next char in file so we can use register-based c while analyzing - line we just read. */ - - latest_char_in_file = c; /* Should be either '\n' or EOF. */ - - have_content = FALSE; - - /* Handle label, if any. */ - - labi = 0; - first_label_char = FFEWHERE_columnUNKNOWN; - for (column = 0; column < 5; ++column) - { - switch (c = ffelex_card_image_[column]) - { - case '\0': - case '!': - goto stop_looking; /* :::::::::::::::::::: */ - - case ' ': - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - label_string[labi++] = c; - if (first_label_char == FFEWHERE_columnUNKNOWN) - first_label_char = column + 1; - break; - - case '&': - if (column != 0) - { - ffelex_bad_1_ (FFEBAD_LABEL_FIELD_NOT_NUMERIC, - ffelex_linecount_current_, - column + 1); - goto beginning_of_line_again; /* :::::::::::::::::::: */ - } - if (ffe_is_pedantic ()) - ffelex_bad_1_ (FFEBAD_AMPERSAND, - ffelex_linecount_current_, 1); - finish_statement = FALSE; - just_do_label = FALSE; - goto got_a_continuation; /* :::::::::::::::::::: */ - - case '/': - if (ffelex_card_image_[column + 1] == '*') - goto stop_looking; /* :::::::::::::::::::: */ - /* Fall through. */ - default: - ffelex_bad_1_ (FFEBAD_LABEL_FIELD_NOT_NUMERIC, - ffelex_linecount_current_, column + 1); - goto beginning_of_line_again; /* :::::::::::::::::::: */ - } - } - - stop_looking: /* :::::::::::::::::::: */ - - label_string[labi] = '\0'; - - /* Find first nonblank char starting with continuation column. */ - - if (column == 5) /* In which case we didn't see end of line in - label field. */ - while ((c = ffelex_card_image_[column]) == ' ') - ++column; - - /* Now we're trying to figure out whether this is a continuation line and - whether there's anything else of substance on the line. The cases are - as follows: - - 1. If a line has an explicit continuation character (other than the digit - zero), then if it also has a label, the label is ignored and an error - message is printed. Any remaining text on the line is passed to the - parser tasks, thus even an all-blank line (possibly with an ignored - label) aside from a positive continuation character might have meaning - in the midst of a character or hollerith constant. - - 2. If a line has no explicit continuation character (that is, it has a - space in column 6 and the first non-space character past column 6 is - not a digit 0-9), then there are two possibilities: - - A. A label is present and/or a non-space (and non-comment) character - appears somewhere after column 6. Terminate processing of the previous - statement, if any, send the new label for the next statement, if any, - and start processing a new statement with this non-blank character, if - any. - - B. The line is essentially blank, except for a possible comment character. - Don't terminate processing of the previous statement and don't pass any - characters to the parser tasks, since the line is not flagged as a - continuation line. We treat it just like a completely blank line. - - 3. If a line has a continuation character of zero (0), then we terminate - processing of the previous statement, if any, send the new label for the - next statement, if any, and start processing a new statement, if any - non-blank characters are present. - - If, when checking to see if we should terminate the previous statement, it - is found that there is no previous statement but that there is an - outstanding label, substitute CONTINUE as the statement for the label - and display an error message. */ - - finish_statement = FALSE; - just_do_label = FALSE; - - switch (c) - { - case '!': /* ANSI Fortran 90 says ! in column 6 is - continuation. */ - /* VXT Fortran says ! anywhere is comment, even column 6. */ - if (ffe_is_vxt () || (column != 5)) - goto no_tokens_on_line; /* :::::::::::::::::::: */ - goto got_a_continuation; /* :::::::::::::::::::: */ - - case '/': - if (ffelex_card_image_[column + 1] != '*') - goto some_other_character; /* :::::::::::::::::::: */ - /* Fall through. */ - if (column == 5) - { - /* This seems right to do. But it is close to call, since / * starting - in column 6 will thus be interpreted as a continuation line - beginning with '*'. */ - - goto got_a_continuation;/* :::::::::::::::::::: */ - } - /* Fall through. */ - case '\0': - /* End of line. Therefore may be continued-through line, so handle - pending label as possible to-be-continued and drive end-of-statement - for any previous statement, else treat as blank line. */ - - no_tokens_on_line: /* :::::::::::::::::::: */ - - if (ffe_is_pedantic () && (c == '/')) - ffelex_bad_1_ (FFEBAD_NON_ANSI_COMMENT, - ffelex_linecount_current_, column + 1); - if (first_label_char != FFEWHERE_columnUNKNOWN) - { /* Can't be a continued-through line if it - has a label. */ - finish_statement = TRUE; - have_content = TRUE; - just_do_label = TRUE; - break; - } - goto beginning_of_line_again; /* :::::::::::::::::::: */ - - case '0': - if (ffe_is_pedantic () && (column != 5)) - ffelex_bad_1_ (FFEBAD_NON_ANSI_CONTINUATION_COLUMN, - ffelex_linecount_current_, column + 1); - finish_statement = TRUE; - goto check_for_content; /* :::::::::::::::::::: */ - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - - /* NOTE: This label can be reached directly from the code - that lexes the label field in columns 1-5. */ - got_a_continuation: /* :::::::::::::::::::: */ - - if (first_label_char != FFEWHERE_columnUNKNOWN) - { - ffelex_bad_2_ (FFEBAD_LABEL_ON_CONTINUATION, - ffelex_linecount_current_, - first_label_char, - ffelex_linecount_current_, - column + 1); - first_label_char = FFEWHERE_columnUNKNOWN; - } - if (disallow_continuation_line) - { - if (!ignore_disallowed_continuation) - ffelex_bad_1_ (FFEBAD_INVALID_CONTINUATION, - ffelex_linecount_current_, column + 1); - goto beginning_of_line_again; /* :::::::::::::::::::: */ - } - if (ffe_is_pedantic () && (column != 5)) - ffelex_bad_1_ (FFEBAD_NON_ANSI_CONTINUATION_COLUMN, - ffelex_linecount_current_, column + 1); - if ((ffelex_raw_mode_ != 0) - && (((c = ffelex_card_image_[column + 1]) != '\0') - || !ffelex_saw_tab_)) - { - ++column; - have_content = TRUE; - break; - } - - check_for_content: /* :::::::::::::::::::: */ - - while ((c = ffelex_card_image_[++column]) == ' ') - ; - if ((c == '\0') - || (c == '!') - || ((c == '/') - && (ffelex_card_image_[column + 1] == '*'))) - { - if (ffe_is_pedantic () && (c == '/')) - ffelex_bad_1_ (FFEBAD_NON_ANSI_COMMENT, - ffelex_linecount_current_, column + 1); - just_do_label = TRUE; - } - else - have_content = TRUE; - break; - - default: - - some_other_character: /* :::::::::::::::::::: */ - - if (column == 5) - goto got_a_continuation;/* :::::::::::::::::::: */ - - /* Here is the very normal case of a regular character starting in - column 7 or beyond with a blank in column 6. */ - - finish_statement = TRUE; - have_content = TRUE; - break; - } - - if (have_content - || (first_label_char != FFEWHERE_columnUNKNOWN)) - { - /* The line has content of some kind, install new end-statement - point for error messages. Note that "content" includes cases - where there's little apparent content but enough to finish - a statement. That's because finishing a statement can trigger - an impending INCLUDE, and that requires accurate line info being - maintained by the lexer. */ - - if (finish_statement) - ffelex_prepare_eos_ (); /* Prepare EOS before we move current pointer. */ - - ffewhere_line_kill (ffelex_current_wl_); - ffewhere_column_kill (ffelex_current_wc_); - ffelex_current_wl_ = ffewhere_line_new (ffelex_linecount_current_); - ffelex_current_wc_ = ffewhere_column_new (ffelex_card_length_ + 1); - } - - /* We delay this for a combination of reasons. Mainly, it can start - INCLUDE processing, and we want to delay that until the lexer's - info on the line is coherent. And we want to delay that until we're - sure there's a reason to make that info coherent, to avoid saving - lots of useless lines. */ - - if (finish_statement) - ffelex_finish_statement_ (); - - /* If label is present, enclose it in a NUMBER token and send it along. */ - - if (first_label_char != FFEWHERE_columnUNKNOWN) - { - assert (ffelex_token_->type == FFELEX_typeNONE); - ffelex_token_->type = FFELEX_typeNUMBER; - ffelex_append_to_token_ ('\0'); /* Make room for label text. */ - strcpy (ffelex_token_->text, label_string); - ffelex_token_->where_line - = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (first_label_char); - ffelex_token_->length = labi; - ffelex_send_token_ (); - ++ffelex_label_tokens_; - } - - if (just_do_label) - goto beginning_of_line; /* :::::::::::::::::::: */ - - /* Here is the main engine for parsing. c holds the character at column. - It is already known that c is not a blank, end of line, or shriek, - unless ffelex_raw_mode_ is not 0 (indicating we are in a - character/hollerith constant). A partially filled token may already - exist in ffelex_token_. One special case: if, when the end of the line - is reached, continuation_line is FALSE and the only token on the line is - END, then it is indeed the last statement. We don't look for - continuation lines during this program unit in that case. This is - according to ANSI. */ - - if (ffelex_raw_mode_ != 0) - { - - parse_raw_character: /* :::::::::::::::::::: */ - - if (c == '\0') - { - ffewhereColumnNumber i; - - if (ffelex_saw_tab_ || (column >= ffelex_final_nontab_column_)) - goto beginning_of_line; /* :::::::::::::::::::: */ - - /* Pad out line with "virtual" spaces. */ - - for (i = column; i < ffelex_final_nontab_column_; ++i) - ffelex_card_image_[i] = ' '; - ffelex_card_image_[i] = '\0'; - ffelex_card_length_ = i; - c = ' '; - } - - switch (ffelex_raw_mode_) - { - case -3: - c = ffelex_backslash_ (c, column); - if (c == EOF) - break; - - if (!ffelex_backslash_reconsider_) - ffelex_append_to_token_ (c); - ffelex_raw_mode_ = -1; - break; - - case -2: - if (c == ffelex_raw_char_) - { - ffelex_raw_mode_ = -1; - ffelex_append_to_token_ (c); - } - else - { - ffelex_raw_mode_ = 0; - ffelex_backslash_reconsider_ = TRUE; - } - break; - - case -1: - if (c == ffelex_raw_char_) - ffelex_raw_mode_ = -2; - else - { - c = ffelex_backslash_ (c, column); - if (c == EOF) - { - ffelex_raw_mode_ = -3; - break; - } - - ffelex_append_to_token_ (c); - } - break; - - default: - c = ffelex_backslash_ (c, column); - if (c == EOF) - break; - - if (!ffelex_backslash_reconsider_) - { - ffelex_append_to_token_ (c); - --ffelex_raw_mode_; - } - break; - } - - if (ffelex_backslash_reconsider_) - ffelex_backslash_reconsider_ = FALSE; - else - c = ffelex_card_image_[++column]; - - if (ffelex_raw_mode_ == 0) - { - ffelex_send_token_ (); - assert (ffelex_raw_mode_ == 0); - while (c == ' ') - c = ffelex_card_image_[++column]; - if ((c == '\0') - || (c == '!') - || ((c == '/') - && (ffelex_card_image_[column + 1] == '*'))) - goto beginning_of_line; /* :::::::::::::::::::: */ - goto parse_nonraw_character; /* :::::::::::::::::::: */ - } - goto parse_raw_character; /* :::::::::::::::::::: */ - } - - parse_nonraw_character: /* :::::::::::::::::::: */ - - switch (ffelex_token_->type) - { - case FFELEX_typeNONE: - switch (c) - { - case '\"': - ffelex_token_->type = FFELEX_typeQUOTE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '$': - ffelex_token_->type = FFELEX_typeDOLLAR; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '%': - ffelex_token_->type = FFELEX_typePERCENT; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '&': - ffelex_token_->type = FFELEX_typeAMPERSAND; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '\'': - ffelex_token_->type = FFELEX_typeAPOSTROPHE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '(': - ffelex_token_->type = FFELEX_typeOPEN_PAREN; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case ')': - ffelex_token_->type = FFELEX_typeCLOSE_PAREN; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '*': - ffelex_token_->type = FFELEX_typeASTERISK; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '+': - ffelex_token_->type = FFELEX_typePLUS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case ',': - ffelex_token_->type = FFELEX_typeCOMMA; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '-': - ffelex_token_->type = FFELEX_typeMINUS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '.': - ffelex_token_->type = FFELEX_typePERIOD; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '/': - ffelex_token_->type = FFELEX_typeSLASH; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ffelex_token_->type - = ffelex_hexnum_ ? FFELEX_typeNAME : FFELEX_typeNUMBER; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_append_to_token_ (c); - break; - - case ':': - ffelex_token_->type = FFELEX_typeCOLON; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case ';': - ffelex_token_->type = FFELEX_typeSEMICOLON; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_permit_include_ = TRUE; - ffelex_send_token_ (); - ffelex_permit_include_ = FALSE; - break; - - case '<': - ffelex_token_->type = FFELEX_typeOPEN_ANGLE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '=': - ffelex_token_->type = FFELEX_typeEQUALS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '>': - ffelex_token_->type = FFELEX_typeCLOSE_ANGLE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '?': - ffelex_token_->type = FFELEX_typeQUESTION; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '_': - if (1 || ffe_is_90 ()) - { - ffelex_token_->type = FFELEX_typeUNDERSCORE; - ffelex_token_->where_line - = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col - = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - } - /* Fall through. */ - 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': - c = ffesrc_char_source (c); - - if (ffesrc_char_match_init (c, 'H', 'h') - && ffelex_expecting_hollerith_ != 0) - { - ffelex_raw_mode_ = ffelex_expecting_hollerith_; - ffelex_token_->type = FFELEX_typeHOLLERITH; - ffelex_token_->where_line = ffelex_raw_where_line_; - ffelex_token_->where_col = ffelex_raw_where_col_; - ffelex_raw_where_line_ = ffewhere_line_unknown (); - ffelex_raw_where_col_ = ffewhere_column_unknown (); - c = ffelex_card_image_[++column]; - goto parse_raw_character; /* :::::::::::::::::::: */ - } - - if (ffelex_names_) - { - ffelex_token_->where_line - = ffewhere_line_use (ffelex_token_->currentnames_line - = ffewhere_line_use (ffelex_current_wl_)); - ffelex_token_->where_col - = ffewhere_column_use (ffelex_token_->currentnames_col - = ffewhere_column_new (column + 1)); - ffelex_token_->type = FFELEX_typeNAMES; - } - else - { - ffelex_token_->where_line - = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_token_->type = FFELEX_typeNAME; - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_bad_1_ (FFEBAD_UNRECOGNIZED_CHARACTER, - ffelex_linecount_current_, column + 1); - ffelex_finish_statement_ (); - disallow_continuation_line = TRUE; - ignore_disallowed_continuation = TRUE; - goto beginning_of_line_again; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNAME: - switch (c) - { - 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': - c = ffesrc_char_source (c); - /* Fall through. */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '_': - case '$': - if ((c == '$') - && !ffe_is_dollar_ok ()) - { - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNAMES: - switch (c) - { - 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': - c = ffesrc_char_source (c); - /* Fall through. */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '_': - case '$': - if ((c == '$') - && !ffe_is_dollar_ok ()) - { - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - if (ffelex_token_->length < FFEWHERE_indexMAX) - { - ffewhere_track (&ffelex_token_->currentnames_line, - &ffelex_token_->currentnames_col, - ffelex_token_->wheretrack, - ffelex_token_->length, - ffelex_linecount_current_, - column + 1); - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNUMBER: - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeASTERISK: - switch (c) - { - case '*': /* ** */ - ffelex_token_->type = FFELEX_typePOWER; - ffelex_send_token_ (); - break; - - default: /* * not followed by another *. */ - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeCOLON: - switch (c) - { - case ':': /* :: */ - ffelex_token_->type = FFELEX_typeCOLONCOLON; - ffelex_send_token_ (); - break; - - default: /* : not followed by another :. */ - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeSLASH: - switch (c) - { - case '/': /* // */ - ffelex_token_->type = FFELEX_typeCONCAT; - ffelex_send_token_ (); - break; - - case ')': /* /) */ - ffelex_token_->type = FFELEX_typeCLOSE_ARRAY; - ffelex_send_token_ (); - break; - - case '=': /* /= */ - ffelex_token_->type = FFELEX_typeREL_NE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeOPEN_PAREN: - switch (c) - { - case '/': /* (/ */ - ffelex_token_->type = FFELEX_typeOPEN_ARRAY; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeOPEN_ANGLE: - switch (c) - { - case '=': /* <= */ - ffelex_token_->type = FFELEX_typeREL_LE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeEQUALS: - switch (c) - { - case '=': /* == */ - ffelex_token_->type = FFELEX_typeREL_EQ; - ffelex_send_token_ (); - break; - - case '>': /* => */ - ffelex_token_->type = FFELEX_typePOINTS; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeCLOSE_ANGLE: - switch (c) - { - case '=': /* >= */ - ffelex_token_->type = FFELEX_typeREL_GE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - default: - assert ("Serious error!!" == NULL); - abort (); - break; - } - - c = ffelex_card_image_[++column]; - - parse_next_character: /* :::::::::::::::::::: */ - - if (ffelex_raw_mode_ != 0) - goto parse_raw_character; /* :::::::::::::::::::: */ - - while (c == ' ') - c = ffelex_card_image_[++column]; - - if ((c == '\0') - || (c == '!') - || ((c == '/') - && (ffelex_card_image_[column + 1] == '*'))) - { - if ((ffelex_number_of_tokens_ == ffelex_label_tokens_) - && (ffelex_token_->type == FFELEX_typeNAMES) - && (ffelex_token_->length == 3) - && (ffesrc_strncmp_2c (ffe_case_match (), - ffelex_token_->text, - "END", "end", "End", - 3) - == 0)) - { - ffelex_finish_statement_ (); - disallow_continuation_line = TRUE; - ignore_disallowed_continuation = FALSE; - goto beginning_of_line_again; /* :::::::::::::::::::: */ - } - goto beginning_of_line; /* :::::::::::::::::::: */ - } - goto parse_nonraw_character; /* :::::::::::::::::::: */ -} - -/* ffelex_file_free -- Lex a given file in free source form - - ffewhere wf; - FILE *f; - ffelex_file_free(wf,f); - - Lexes the file according to Fortran 90 ANSI + VXT specifications. */ - -ffelexHandler -ffelex_file_free (ffewhereFile wf, FILE *f) -{ - register int c = 0; /* Character currently under consideration. */ - register ffewhereColumnNumber column = 0; /* Not really; 0 means column 1... */ - bool continuation_line = FALSE; - ffewhereColumnNumber continuation_column; - int latest_char_in_file = 0; /* For getting back into comment-skipping - code. */ - - /* Lex is called for a particular file, not for a particular program unit. - Yet the two events do share common characteristics. The first line in a - file or in a program unit cannot be a continuation line. No token can - be in mid-formation. No current label for the statement exists, since - there is no current statement. */ - - assert (ffelex_handler_ != NULL); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - lineno = 0; - input_filename = ffewhere_file_name (wf); -#endif - ffelex_current_wf_ = wf; - continuation_line = FALSE; - ffelex_token_->type = FFELEX_typeNONE; - ffelex_number_of_tokens_ = 0; - ffelex_current_wl_ = ffewhere_line_unknown (); - ffelex_current_wc_ = ffewhere_column_unknown (); - latest_char_in_file = '\n'; - - /* Come here to get a new line. */ - - beginning_of_line: /* :::::::::::::::::::: */ - - c = latest_char_in_file; - if ((c == EOF) || ((c = ffelex_getc_ (f)) == EOF)) - { - - end_of_file: /* :::::::::::::::::::: */ - - /* Line ending in EOF instead of \n still counts as a whole line. */ - - ffelex_finish_statement_ (); - ffewhere_line_kill (ffelex_current_wl_); - ffewhere_column_kill (ffelex_current_wc_); - return (ffelexHandler) ffelex_handler_; - } - - ffelex_next_line_ (); - - ffelex_bad_line_ = FALSE; - - /* Skip over initial-comment and empty lines as quickly as possible! */ - - while ((c == '\n') - || (c == '!') - || (c == '#')) - { - if (c == '#') - { -#if FFECOM_targetCURRENT == FFECOM_targetGCC - c = ffelex_hash_ (f); -#else - /* Don't skip over # line after all. */ - break; -#endif - } - - comment_line: /* :::::::::::::::::::: */ - - while ((c != '\n') && (c != EOF)) - c = getc (f); - - if (c == EOF) - { - ffelex_next_line_ (); - goto end_of_file; /* :::::::::::::::::::: */ - } - - c = getc (f); - - ffelex_next_line_ (); - - if (c == EOF) - goto end_of_file; /* :::::::::::::::::::: */ - } - - ffelex_saw_tab_ = FALSE; - - column = ffelex_image_char_ (c, 0); - - /* Read the entire line in as is (with whitespace processing). */ - - while (((c = getc (f)) != '\n') && (c != EOF)) - column = ffelex_image_char_ (c, column); - - if (ffelex_bad_line_) - { - ffelex_card_image_[column] = '\0'; - ffelex_card_length_ = column; - goto comment_line; /* :::::::::::::::::::: */ - } - - /* If no tab, cut off line after column 132. */ - - if (!ffelex_saw_tab_ && (column > FFELEX_FREE_MAX_COLUMNS_)) - column = FFELEX_FREE_MAX_COLUMNS_; - - ffelex_card_image_[column] = '\0'; - ffelex_card_length_ = column; - - /* Save next char in file so we can use register-based c while analyzing - line we just read. */ - - latest_char_in_file = c; /* Should be either '\n' or EOF. */ - - column = 0; - continuation_column = 0; - - /* Skip over initial spaces to see if the first nonblank character - is exclamation point, newline, or EOF (line is therefore a comment) or - ampersand (line is therefore a continuation line). */ - - while ((c = ffelex_card_image_[column]) == ' ') - ++column; - - switch (c) - { - case '!': - case '\0': - goto beginning_of_line; /* :::::::::::::::::::: */ - - case '&': - continuation_column = column + 1; - break; - - default: - break; - } - - /* The line definitely has content of some kind, install new end-statement - point for error messages. */ - - ffewhere_line_kill (ffelex_current_wl_); - ffewhere_column_kill (ffelex_current_wc_); - ffelex_current_wl_ = ffewhere_line_new (ffelex_linecount_current_); - ffelex_current_wc_ = ffewhere_column_new (ffelex_card_length_ + 1); - - /* Figure out which column to start parsing at. */ - - if (continuation_line) - { - if (continuation_column == 0) - { - if (ffelex_raw_mode_ != 0) - { - ffelex_bad_1_ (FFEBAD_BAD_CHAR_CONTINUE, - ffelex_linecount_current_, column + 1); - } - else if (ffelex_token_->type != FFELEX_typeNONE) - { - ffelex_bad_1_ (FFEBAD_BAD_LEXTOK_CONTINUE, - ffelex_linecount_current_, column + 1); - } - } - else if (ffelex_is_free_char_ctx_contin_ (continuation_column)) - { /* Line contains only a single "&" as only - nonblank character. */ - ffelex_bad_1_ (FFEBAD_BAD_FREE_CONTINUE, - ffelex_linecount_current_, continuation_column); - goto beginning_of_line; /* :::::::::::::::::::: */ - } - column = continuation_column; - } - else - column = 0; - - c = ffelex_card_image_[column]; - continuation_line = FALSE; - - /* Here is the main engine for parsing. c holds the character at column. - It is already known that c is not a blank, end of line, or shriek, - unless ffelex_raw_mode_ is not 0 (indicating we are in a - character/hollerith constant). A partially filled token may already - exist in ffelex_token_. */ - - if (ffelex_raw_mode_ != 0) - { - - parse_raw_character: /* :::::::::::::::::::: */ - - switch (c) - { - case '&': - if (ffelex_is_free_char_ctx_contin_ (column + 1)) - { - continuation_line = TRUE; - goto beginning_of_line; /* :::::::::::::::::::: */ - } - break; - - case '\0': - ffelex_finish_statement_ (); - goto beginning_of_line; /* :::::::::::::::::::: */ - - default: - break; - } - - switch (ffelex_raw_mode_) - { - case -3: - c = ffelex_backslash_ (c, column); - if (c == EOF) - break; - - if (!ffelex_backslash_reconsider_) - ffelex_append_to_token_ (c); - ffelex_raw_mode_ = -1; - break; - - case -2: - if (c == ffelex_raw_char_) - { - ffelex_raw_mode_ = -1; - ffelex_append_to_token_ (c); - } - else - { - ffelex_raw_mode_ = 0; - ffelex_backslash_reconsider_ = TRUE; - } - break; - - case -1: - if (c == ffelex_raw_char_) - ffelex_raw_mode_ = -2; - else - { - c = ffelex_backslash_ (c, column); - if (c == EOF) - { - ffelex_raw_mode_ = -3; - break; - } - - ffelex_append_to_token_ (c); - } - break; - - default: - c = ffelex_backslash_ (c, column); - if (c == EOF) - break; - - if (!ffelex_backslash_reconsider_) - { - ffelex_append_to_token_ (c); - --ffelex_raw_mode_; - } - break; - } - - if (ffelex_backslash_reconsider_) - ffelex_backslash_reconsider_ = FALSE; - else - c = ffelex_card_image_[++column]; - - if (ffelex_raw_mode_ == 0) - { - ffelex_send_token_ (); - assert (ffelex_raw_mode_ == 0); - while (c == ' ') - c = ffelex_card_image_[++column]; - if ((c == '\0') || (c == '!')) - { - ffelex_finish_statement_ (); - goto beginning_of_line; /* :::::::::::::::::::: */ - } - if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1)) - { - continuation_line = TRUE; - goto beginning_of_line; /* :::::::::::::::::::: */ - } - goto parse_nonraw_character_noncontin; /* :::::::::::::::::::: */ - } - goto parse_raw_character; /* :::::::::::::::::::: */ - } - - parse_nonraw_character: /* :::::::::::::::::::: */ - - if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1)) - { - continuation_line = TRUE; - goto beginning_of_line; /* :::::::::::::::::::: */ - } - - parse_nonraw_character_noncontin: /* :::::::::::::::::::: */ - - switch (ffelex_token_->type) - { - case FFELEX_typeNONE: - if (c == ' ') - { /* Otherwise - finish-statement/continue-statement - already checked. */ - while (c == ' ') - c = ffelex_card_image_[++column]; - if ((c == '\0') || (c == '!')) - { - ffelex_finish_statement_ (); - goto beginning_of_line; /* :::::::::::::::::::: */ - } - if ((c == '&') && ffelex_is_free_nonc_ctx_contin_ (column + 1)) - { - continuation_line = TRUE; - goto beginning_of_line; /* :::::::::::::::::::: */ - } - } - - switch (c) - { - case '\"': - ffelex_token_->type = FFELEX_typeQUOTE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '$': - ffelex_token_->type = FFELEX_typeDOLLAR; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '%': - ffelex_token_->type = FFELEX_typePERCENT; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '&': - ffelex_token_->type = FFELEX_typeAMPERSAND; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '\'': - ffelex_token_->type = FFELEX_typeAPOSTROPHE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '(': - ffelex_token_->type = FFELEX_typeOPEN_PAREN; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case ')': - ffelex_token_->type = FFELEX_typeCLOSE_PAREN; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '*': - ffelex_token_->type = FFELEX_typeASTERISK; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '+': - ffelex_token_->type = FFELEX_typePLUS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case ',': - ffelex_token_->type = FFELEX_typeCOMMA; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '-': - ffelex_token_->type = FFELEX_typeMINUS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '.': - ffelex_token_->type = FFELEX_typePERIOD; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '/': - ffelex_token_->type = FFELEX_typeSLASH; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ffelex_token_->type - = ffelex_hexnum_ ? FFELEX_typeNAME : FFELEX_typeNUMBER; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_append_to_token_ (c); - break; - - case ':': - ffelex_token_->type = FFELEX_typeCOLON; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case ';': - ffelex_token_->type = FFELEX_typeSEMICOLON; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_permit_include_ = TRUE; - ffelex_send_token_ (); - ffelex_permit_include_ = FALSE; - break; - - case '<': - ffelex_token_->type = FFELEX_typeOPEN_ANGLE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '=': - ffelex_token_->type = FFELEX_typeEQUALS; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '>': - ffelex_token_->type = FFELEX_typeCLOSE_ANGLE; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - break; - - case '?': - ffelex_token_->type = FFELEX_typeQUESTION; - ffelex_token_->where_line = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - - case '_': - if (1 || ffe_is_90 ()) - { - ffelex_token_->type = FFELEX_typeUNDERSCORE; - ffelex_token_->where_line - = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col - = ffewhere_column_new (column + 1); - ffelex_send_token_ (); - break; - } - /* Fall through. */ - 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': - c = ffesrc_char_source (c); - - if (ffesrc_char_match_init (c, 'H', 'h') - && ffelex_expecting_hollerith_ != 0) - { - ffelex_raw_mode_ = ffelex_expecting_hollerith_; - ffelex_token_->type = FFELEX_typeHOLLERITH; - ffelex_token_->where_line = ffelex_raw_where_line_; - ffelex_token_->where_col = ffelex_raw_where_col_; - ffelex_raw_where_line_ = ffewhere_line_unknown (); - ffelex_raw_where_col_ = ffewhere_column_unknown (); - c = ffelex_card_image_[++column]; - goto parse_raw_character; /* :::::::::::::::::::: */ - } - - if (ffelex_names_pure_) - { - ffelex_token_->where_line - = ffewhere_line_use (ffelex_token_->currentnames_line - = ffewhere_line_use (ffelex_current_wl_)); - ffelex_token_->where_col - = ffewhere_column_use (ffelex_token_->currentnames_col - = ffewhere_column_new (column + 1)); - ffelex_token_->type = FFELEX_typeNAMES; - } - else - { - ffelex_token_->where_line - = ffewhere_line_use (ffelex_current_wl_); - ffelex_token_->where_col = ffewhere_column_new (column + 1); - ffelex_token_->type = FFELEX_typeNAME; - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_bad_1_ (FFEBAD_UNRECOGNIZED_CHARACTER, - ffelex_linecount_current_, column + 1); - ffelex_finish_statement_ (); - goto beginning_of_line; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNAME: - switch (c) - { - 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': - c = ffesrc_char_source (c); - /* Fall through. */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '_': - case '$': - if ((c == '$') - && !ffe_is_dollar_ok ()) - { - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNAMES: - switch (c) - { - 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': - c = ffesrc_char_source (c); - /* Fall through. */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case '_': - case '$': - if ((c == '$') - && !ffe_is_dollar_ok ()) - { - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - if (ffelex_token_->length < FFEWHERE_indexMAX) - { - ffewhere_track (&ffelex_token_->currentnames_line, - &ffelex_token_->currentnames_col, - ffelex_token_->wheretrack, - ffelex_token_->length, - ffelex_linecount_current_, - column + 1); - } - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeNUMBER: - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - ffelex_append_to_token_ (c); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeASTERISK: - switch (c) - { - case '*': /* ** */ - ffelex_token_->type = FFELEX_typePOWER; - ffelex_send_token_ (); - break; - - default: /* * not followed by another *. */ - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeCOLON: - switch (c) - { - case ':': /* :: */ - ffelex_token_->type = FFELEX_typeCOLONCOLON; - ffelex_send_token_ (); - break; - - default: /* : not followed by another :. */ - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeSLASH: - switch (c) - { - case '/': /* // */ - ffelex_token_->type = FFELEX_typeCONCAT; - ffelex_send_token_ (); - break; - - case ')': /* /) */ - ffelex_token_->type = FFELEX_typeCLOSE_ARRAY; - ffelex_send_token_ (); - break; - - case '=': /* /= */ - ffelex_token_->type = FFELEX_typeREL_NE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeOPEN_PAREN: - switch (c) - { - case '/': /* (/ */ - ffelex_token_->type = FFELEX_typeOPEN_ARRAY; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeOPEN_ANGLE: - switch (c) - { - case '=': /* <= */ - ffelex_token_->type = FFELEX_typeREL_LE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeEQUALS: - switch (c) - { - case '=': /* == */ - ffelex_token_->type = FFELEX_typeREL_EQ; - ffelex_send_token_ (); - break; - - case '>': /* => */ - ffelex_token_->type = FFELEX_typePOINTS; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - case FFELEX_typeCLOSE_ANGLE: - switch (c) - { - case '=': /* >= */ - ffelex_token_->type = FFELEX_typeREL_GE; - ffelex_send_token_ (); - break; - - default: - ffelex_send_token_ (); - goto parse_next_character; /* :::::::::::::::::::: */ - } - break; - - default: - assert ("Serious error!" == NULL); - abort (); - break; - } - - c = ffelex_card_image_[++column]; - - parse_next_character: /* :::::::::::::::::::: */ - - if (ffelex_raw_mode_ != 0) - goto parse_raw_character; /* :::::::::::::::::::: */ - - if ((c == '\0') || (c == '!')) - { - ffelex_finish_statement_ (); - goto beginning_of_line; /* :::::::::::::::::::: */ - } - goto parse_nonraw_character; /* :::::::::::::::::::: */ -} - -/* See the code in com.c that calls this to understand why. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -void -ffelex_hash_kludge (FILE *finput) -{ - /* If you change this constant string, you have to change whatever - code might thus be affected by it in terms of having to use - ffelex_getc_() instead of getc() in the lexers and _hash_. */ - static char match[] = "# 1 \""; - static int kludge[ARRAY_SIZE (match) + 1]; - int c; - char *p; - int *q; - - /* Read chars as long as they match the target string. - Copy them into an array that will serve as a record - of what we read (essentially a multi-char ungetc(), - for code that uses ffelex_getc_ instead of getc() elsewhere - in the lexer. */ - for (p = &match[0], q = &kludge[0], c = getc (finput); - (c == *p) && (*p != '\0') && (c != EOF); - ++p, ++q, c = getc (finput)) - *q = c; - - *q = c; /* Might be EOF, which requires int. */ - *++q = 0; - - ffelex_kludge_chars_ = &kludge[0]; - - if (*p == 0) - { - ffelex_kludge_flag_ = TRUE; - ++ffelex_kludge_chars_; - ffelex_hash_ (finput); /* Handle it NOW rather than later. */ - ffelex_kludge_flag_ = FALSE; - } -} - -#endif -void -ffelex_init_1 () -{ - unsigned int i; - - ffelex_final_nontab_column_ = ffe_fixed_line_length (); - ffelex_card_size_ = FFELEX_columnINITIAL_SIZE_; - ffelex_card_image_ = malloc_new_ksr (malloc_pool_image (), - "FFELEX card image", - FFELEX_columnINITIAL_SIZE_ + 9); - ffelex_card_image_[0] = '\0'; - - for (i = 0; i < 256; ++i) - ffelex_first_char_[i] = FFELEX_typeERROR; - - ffelex_first_char_['\t'] = FFELEX_typeRAW; - ffelex_first_char_['\n'] = FFELEX_typeCOMMENT; - ffelex_first_char_['\v'] = FFELEX_typeCOMMENT; - ffelex_first_char_['\f'] = FFELEX_typeCOMMENT; - ffelex_first_char_['\r'] = FFELEX_typeRAW; - ffelex_first_char_[' '] = FFELEX_typeRAW; - ffelex_first_char_['!'] = FFELEX_typeCOMMENT; - ffelex_first_char_['*'] = FFELEX_typeCOMMENT; - ffelex_first_char_['/'] = FFELEX_typeSLASH; - ffelex_first_char_['&'] = FFELEX_typeRAW; - ffelex_first_char_['#'] = FFELEX_typeHASH; - - for (i = '0'; i <= '9'; ++i) - ffelex_first_char_[i] = FFELEX_typeRAW; - - if ((ffe_case_match () == FFE_caseNONE) - || ((ffe_case_match () == FFE_caseUPPER) - && (ffe_case_source () != FFE_caseLOWER)) /* Idiot! :-) */ - || ((ffe_case_match () == FFE_caseLOWER) - && (ffe_case_source () == FFE_caseLOWER))) - { - ffelex_first_char_['C'] = FFELEX_typeCOMMENT; - ffelex_first_char_['D'] = FFELEX_typeCOMMENT; - } - if ((ffe_case_match () == FFE_caseNONE) - || ((ffe_case_match () == FFE_caseLOWER) - && (ffe_case_source () != FFE_caseUPPER)) /* Idiot! :-) */ - || ((ffe_case_match () == FFE_caseUPPER) - && (ffe_case_source () == FFE_caseUPPER))) - { - ffelex_first_char_['c'] = FFELEX_typeCOMMENT; - ffelex_first_char_['d'] = FFELEX_typeCOMMENT; - } - - ffelex_linecount_current_ = 0; - ffelex_linecount_next_ = 1; - ffelex_raw_mode_ = 0; - ffelex_set_include_ = FALSE; - ffelex_permit_include_ = FALSE; - ffelex_names_ = TRUE; /* First token in program is a names. */ - ffelex_names_pure_ = FALSE; /* Free-form lexer does NAMES only for - FORMAT. */ - ffelex_hexnum_ = FALSE; - ffelex_expecting_hollerith_ = 0; - ffelex_raw_where_line_ = ffewhere_line_unknown (); - ffelex_raw_where_col_ = ffewhere_column_unknown (); - - ffelex_token_ = ffelex_token_new_ (); - ffelex_token_->type = FFELEX_typeNONE; - ffelex_token_->uses = 1; - ffelex_token_->where_line = ffewhere_line_unknown (); - ffelex_token_->where_col = ffewhere_column_unknown (); - ffelex_token_->text = NULL; - - ffelex_handler_ = NULL; -} - -/* ffelex_is_names_expected -- Is the current parser expecting NAMES vs. NAME? - - if (ffelex_is_names_expected()) - // Deliver NAMES token - else - // Deliver NAME token - - Must be called while lexer is active, obviously. */ - -bool -ffelex_is_names_expected () -{ - return ffelex_names_; -} - -/* Current card image, which has the master linecount number - ffelex_linecount_current_. */ - -char * -ffelex_line () -{ - return ffelex_card_image_; -} - -/* ffelex_line_length -- Return length of current lexer line - - printf("Length is %lu\n",ffelex_line_length()); - - Must be called while lexer is active, obviously. */ - -ffewhereColumnNumber -ffelex_line_length () -{ - return ffelex_card_length_; -} - -/* Master line count of current card image, or 0 if no card image - is current. */ - -ffewhereLineNumber -ffelex_line_number () -{ - return ffelex_linecount_current_; -} - -/* ffelex_set_expecting_hollerith -- Set hollerith expectation status - - ffelex_set_expecting_hollerith(0); - - Lex initially assumes no hollerith constant is about to show up. If - syntactic analysis expects one, it should call this function with the - number of characters expected in the constant immediately after recognizing - the decimal number preceding the "H" and the constant itself. Then, if - the next character is indeed H, the lexer will interpret it as beginning - a hollerith constant and ship the token formed by reading the specified - number of characters (interpreting blanks and otherwise-comments too) - from the input file. It is up to syntactic analysis to call this routine - again with 0 to turn hollerith detection off immediately upon receiving - the token that might or might not be HOLLERITH. - - Also call this after seeing an APOSTROPHE or QUOTE token that begins a - character constant. Pass the expected termination character (apostrophe - or quote). - - Pass for length either the length of the hollerith (must be > 0), -1 - meaning expecting a character constant, or 0 to cancel expectation of - a hollerith only after calling it with a length of > 0 and receiving the - next token (which may or may not have been a HOLLERITH token). - - Pass for which either an apostrophe or quote when passing length of -1. - Else which is a don't-care. - - Pass for line and column the line/column info for the token beginning the - character or hollerith constant, for use in error messages, when passing - a length of -1 -- this function will invoke ffewhere_line/column_use to - make its own copies. Else line and column are don't-cares (when length - is 0) and the outstanding copies of the previous line/column info, if - still around, are killed. - - 21-Feb-90 JCB 3.1 - When called with length of 0, also zero ffelex_raw_mode_. This is - so ffest_save_ can undo the effects of replaying tokens like - APOSTROPHE and QUOTE. - 25-Jan-90 JCB 3.0 - New line, column arguments allow error messages to point to the true - beginning of a character/hollerith constant, rather than the beginning - of the content part, which makes them more consistent and helpful. - 05-Nov-89 JCB 2.0 - New "which" argument allows caller to specify termination character, - which should be apostrophe or double-quote, to support Fortran 90. */ - -void -ffelex_set_expecting_hollerith (long length, char which, - ffewhereLine line, ffewhereColumn column) -{ - - /* First kill the pending line/col info, if any (should only be pending - when this call has length==0, the previous call had length>0, and a - non-HOLLERITH token was sent in between the calls, but play it safe). */ - - ffewhere_line_kill (ffelex_raw_where_line_); - ffewhere_column_kill (ffelex_raw_where_col_); - - /* Now handle the length function. */ - switch (length) - { - case 0: - ffelex_expecting_hollerith_ = 0; - ffelex_raw_mode_ = 0; - ffelex_raw_where_line_ = ffewhere_line_unknown (); - ffelex_raw_where_col_ = ffewhere_column_unknown (); - return; /* Don't set new line/column info from args. */ - - case -1: - ffelex_raw_mode_ = -1; - ffelex_raw_char_ = which; - break; - - default: /* length > 0 */ - ffelex_expecting_hollerith_ = length; - break; - } - - /* Now set new line/column information from passed args. */ - - ffelex_raw_where_line_ = ffewhere_line_use (line); - ffelex_raw_where_col_ = ffewhere_column_use (column); -} - -/* ffelex_set_handler -- Set handler for tokens before calling _fixed or _free - - ffelex_set_handler((ffelexHandler) my_first_handler); - - Must be called before calling ffelex_file_fixed or ffelex_file_free or - after they return, but not while they are active. */ - -void -ffelex_set_handler (ffelexHandler first) -{ - ffelex_handler_ = first; -} - -/* ffelex_set_hexnum -- Set hexnum flag - - ffelex_set_hexnum(TRUE); - - Lex normally interprets a token starting with [0-9] as a NUMBER token, - so if it sees a [A-Za-z] in it, it stops parsing the NUMBER and leaves - the character as the first of the next token. But when parsing a - hexadecimal number, by calling this function with TRUE before starting - the parse of the token itself, lex will interpret [0-9] as the start - of a NAME token. */ - -void -ffelex_set_hexnum (bool f) -{ - ffelex_hexnum_ = f; -} - -/* ffelex_set_include -- Set INCLUDE file to be processed next - - ffewhereFile wf; // The ffewhereFile object for the file. - bool free_form; // TRUE means read free-form file, FALSE fixed-form. - FILE *fi; // The file to INCLUDE. - ffelex_set_include(wf,free_form,fi); - - Must be called only after receiving the EOS token following a valid - INCLUDE statement specifying a file that has already been successfully - opened. */ - -void -ffelex_set_include (ffewhereFile wf, bool free_form, FILE *fi) -{ - assert (ffelex_permit_include_); - assert (!ffelex_set_include_); - ffelex_set_include_ = TRUE; - ffelex_include_free_form_ = free_form; - ffelex_include_file_ = fi; - ffelex_include_wherefile_ = wf; -} - -/* ffelex_set_names -- Set names/name flag, names = TRUE - - ffelex_set_names(FALSE); - - Lex initially assumes multiple names should be formed. If this function is - called with FALSE, then single names are formed instead. The differences - are a difference in the token type (FFELEX_typeNAMES vs. FFELEX_typeNAME) - and in whether full source-location tracking is performed (it is for - multiple names, not for single names), which is more expensive in terms of - CPU time. */ - -void -ffelex_set_names (bool f) -{ - ffelex_names_ = f; - if (!f) - ffelex_names_pure_ = FALSE; -} - -/* ffelex_set_names_pure -- Set names/name (pure) flag, names = TRUE - - ffelex_set_names_pure(FALSE); - - Like ffelex_set_names, except affects both lexers. Normally, the - free-form lexer need not generate NAMES tokens because adjacent NAME - tokens must be separated by spaces which causes the lexer to generate - separate tokens for analysis (whereas in fixed-form the spaces are - ignored resulting in one long token). But in FORMAT statements, for - some reason, the Fortran 90 standard specifies that spaces can occur - anywhere within a format-item-list with no effect on the format spec - (except of course within character string edit descriptors), which means - that "1PE14.2" and "1 P E 1 4 . 2" are equivalent. For the FORMAT - statement handling, the existence of spaces makes it hard to deal with, - because each token is seen distinctly (i.e. seven tokens in the latter - example). But when no spaces are provided, as in the former example, - then only four tokens are generated, NUMBER("1"), NAME("PE14"), PERIOD, - NUMBER ("2"). By generating a NAMES instead of NAME, three things happen: - One, ffest_kw_format_ does a substring rather than full-string match, - and thus matches "PE14" to "PE"; two, ffelex_token_xyz_from_names functions - may be used to pull NAME/NAMES and NUMBER tokens out of the NAMES token; - and three, error reporting can point to the actual character rather than - at or prior to it. The first two things could be resolved by providing - alternate functions fairly easy, thus allowing FORMAT handling to expect - both lexers to generate NAME tokens instead of NAMES (with otherwise minor - changes to FORMAT parsing), but the third, error reporting, would suffer, - and when one makes mistakes in a FORMAT, believe me, one wants a pointer - to exactly where the compilers thinks the problem is, to even begin to get - a handle on it. So there. */ - -void -ffelex_set_names_pure (bool f) -{ - ffelex_names_pure_ = f; - ffelex_names_ = f; -} - -/* ffelex_splice_tokens -- Splice off and send tokens from a NAMES - - return (ffelexHandler) ffelex_splice_tokens(first_handler,master_token, - start_char_index); - - Returns first_handler if start_char_index chars into master_token (which - must be a NAMES token) is '\0'. Else, creates a subtoken from that - char, either NUMBER (if it is a digit), a NAME (if a valid firstnamechar), - an UNDERSCORE (if an underscore), or DOLLAR (if a dollar sign) - and sends it to first_handler. If anything other than NAME is sent, the - character at the end of it in the master token is examined to see if it - begins a NAME, NUMBER, UNDERSCORE, or DOLLAR, and, if so, - the handler returned by first_handler is invoked with that token, and - this process is repeated until the end of the master token or a NAME - token is reached. */ - -ffelexHandler -ffelex_splice_tokens (ffelexHandler first, ffelexToken master, - ffeTokenLength start) -{ - unsigned char *p; - ffeTokenLength i; - ffelexToken t; - - p = ffelex_token_text (master) + (i = start); - - while (*p != '\0') - { - if (ISDIGIT (*p)) - { - t = ffelex_token_number_from_names (master, i); - p += ffelex_token_length (t); - i += ffelex_token_length (t); - } - else if (ffesrc_is_name_init (*p)) - { - t = ffelex_token_name_from_names (master, i, 0); - p += ffelex_token_length (t); - i += ffelex_token_length (t); - } - else if (*p == '$') - { - t = ffelex_token_dollar_from_names (master, i); - ++p; - ++i; - } - else if (*p == '_') - { - t = ffelex_token_uscore_from_names (master, i); - ++p; - ++i; - } - else - { - assert ("not a valid NAMES character" == NULL); - t = NULL; - } - assert (first != NULL); - first = (ffelexHandler) (*first) (t); - ffelex_token_kill (t); - } - - return first; -} - -/* ffelex_swallow_tokens -- Eat all tokens delivered to me - - return ffelex_swallow_tokens; - - Return this handler when you don't want to look at any more tokens in the - statement because you've encountered an unrecoverable error in the - statement. */ - -ffelexHandler -ffelex_swallow_tokens (ffelexToken t, ffelexHandler handler) -{ - assert (handler != NULL); - - if ((t != NULL) && ((ffelex_token_type (t) == FFELEX_typeEOS) - || (ffelex_token_type (t) == FFELEX_typeSEMICOLON))) - return (ffelexHandler) (*handler) (t); - - ffelex_eos_handler_ = handler; - return (ffelexHandler) ffelex_swallow_tokens_; -} - -/* ffelex_token_dollar_from_names -- Return a dollar from within a names token - - ffelexToken t; - t = ffelex_token_dollar_from_names(t,6); - - It's as if you made a new token of dollar type having the dollar - at, in the example above, the sixth character of the NAMES token. */ - -ffelexToken -ffelex_token_dollar_from_names (ffelexToken t, ffeTokenLength start) -{ - ffelexToken nt; - - assert (t != NULL); - assert (ffelex_token_type (t) == FFELEX_typeNAMES); - assert (start < t->length); - assert (t->text[start] == '$'); - - /* Now make the token. */ - - nt = ffelex_token_new_ (); - nt->type = FFELEX_typeDOLLAR; - nt->length = 0; - nt->uses = 1; - ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line, - t->where_col, t->wheretrack, start); - nt->text = NULL; - return nt; -} - -/* ffelex_token_kill -- Decrement use count for token, kill if no uses left - - ffelexToken t; - ffelex_token_kill(t); - - Complements a call to ffelex_token_use or ffelex_token_new_.... */ - -void -ffelex_token_kill (ffelexToken t) -{ - assert (t != NULL); - - assert (t->uses > 0); - - if (--t->uses != 0) - return; - - --ffelex_total_tokens_; - - if (t->type == FFELEX_typeNAMES) - ffewhere_track_kill (t->where_line, t->where_col, - t->wheretrack, t->length); - ffewhere_line_kill (t->where_line); - ffewhere_column_kill (t->where_col); - if (t->text != NULL) - malloc_kill_ksr (malloc_pool_image (), t->text, t->size + 1); - malloc_kill_ks (malloc_pool_image (), t, sizeof (*t)); -} - -/* Make a new NAME token that is a substring of a NAMES token. */ - -ffelexToken -ffelex_token_name_from_names (ffelexToken t, ffeTokenLength start, - ffeTokenLength len) -{ - ffelexToken nt; - - assert (t != NULL); - assert (ffelex_token_type (t) == FFELEX_typeNAMES); - assert (start < t->length); - if (len == 0) - len = t->length - start; - else - { - assert (len > 0); - assert ((start + len) <= t->length); - } - assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start]))); - - nt = ffelex_token_new_ (); - nt->type = FFELEX_typeNAME; - nt->size = len; /* Assume nobody's gonna fiddle with token - text. */ - nt->length = len; - nt->uses = 1; - ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line, - t->where_col, t->wheretrack, start); - nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - len + 1); - strncpy (nt->text, t->text + start, len); - nt->text[len] = '\0'; - return nt; -} - -/* Make a new NAMES token that is a substring of another NAMES token. */ - -ffelexToken -ffelex_token_names_from_names (ffelexToken t, ffeTokenLength start, - ffeTokenLength len) -{ - ffelexToken nt; - - assert (t != NULL); - assert (ffelex_token_type (t) == FFELEX_typeNAMES); - assert (start < t->length); - if (len == 0) - len = t->length - start; - else - { - assert (len > 0); - assert ((start + len) <= t->length); - } - assert (ffelex_is_firstnamechar ((unsigned char)(t->text[start]))); - - nt = ffelex_token_new_ (); - nt->type = FFELEX_typeNAMES; - nt->size = len; /* Assume nobody's gonna fiddle with token - text. */ - nt->length = len; - nt->uses = 1; - ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line, - t->where_col, t->wheretrack, start); - ffewhere_track_copy (nt->wheretrack, t->wheretrack, start, len); - nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - len + 1); - strncpy (nt->text, t->text + start, len); - nt->text[len] = '\0'; - return nt; -} - -/* Make a new CHARACTER token. */ - -ffelexToken -ffelex_token_new_character (char *s, ffewhereLine l, ffewhereColumn c) -{ - ffelexToken t; - - t = ffelex_token_new_ (); - t->type = FFELEX_typeCHARACTER; - t->length = t->size = strlen (s); /* Assume it won't get bigger. */ - t->uses = 1; - t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - t->size + 1); - strcpy (t->text, s); - t->where_line = ffewhere_line_use (l); - t->where_col = ffewhere_column_new (c); - return t; -} - -/* Make a new EOF token right after end of file. */ - -ffelexToken -ffelex_token_new_eof () -{ - ffelexToken t; - - t = ffelex_token_new_ (); - t->type = FFELEX_typeEOF; - t->uses = 1; - t->text = NULL; - t->where_line = ffewhere_line_new (ffelex_linecount_current_); - t->where_col = ffewhere_column_new (1); - return t; -} - -/* Make a new NAME token. */ - -ffelexToken -ffelex_token_new_name (char *s, ffewhereLine l, ffewhereColumn c) -{ - ffelexToken t; - - assert (ffelex_is_firstnamechar ((unsigned char)*s)); - - t = ffelex_token_new_ (); - t->type = FFELEX_typeNAME; - t->length = t->size = strlen (s); /* Assume it won't get bigger. */ - t->uses = 1; - t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - t->size + 1); - strcpy (t->text, s); - t->where_line = ffewhere_line_use (l); - t->where_col = ffewhere_column_new (c); - return t; -} - -/* Make a new NAMES token. */ - -ffelexToken -ffelex_token_new_names (char *s, ffewhereLine l, ffewhereColumn c) -{ - ffelexToken t; - - assert (ffelex_is_firstnamechar ((unsigned char)*s)); - - t = ffelex_token_new_ (); - t->type = FFELEX_typeNAMES; - t->length = t->size = strlen (s); /* Assume it won't get bigger. */ - t->uses = 1; - t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - t->size + 1); - strcpy (t->text, s); - t->where_line = ffewhere_line_use (l); - t->where_col = ffewhere_column_new (c); - ffewhere_track_clear (t->wheretrack, t->length); /* Assume contiguous - names. */ - return t; -} - -/* Make a new NUMBER token. - - The first character of the string must be a digit, and only the digits - are copied into the new number. So this may be used to easily extract - a NUMBER token from within any text string. Then the length of the - resulting token may be used to calculate where the digits stopped - in the original string. */ - -ffelexToken -ffelex_token_new_number (char *s, ffewhereLine l, ffewhereColumn c) -{ - ffelexToken t; - ffeTokenLength len; - - /* How long is the string of decimal digits at s? */ - - len = strspn (s, "0123456789"); - - /* Make sure there is at least one digit. */ - - assert (len != 0); - - /* Now make the token. */ - - t = ffelex_token_new_ (); - t->type = FFELEX_typeNUMBER; - t->length = t->size = len; /* Assume it won't get bigger. */ - t->uses = 1; - t->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - len + 1); - strncpy (t->text, s, len); - t->text[len] = '\0'; - t->where_line = ffewhere_line_use (l); - t->where_col = ffewhere_column_new (c); - return t; -} - -/* Make a new token of any type that doesn't contain text. A private - function that is used by public macros in the interface file. */ - -ffelexToken -ffelex_token_new_simple_ (ffelexType type, ffewhereLine l, ffewhereColumn c) -{ - ffelexToken t; - - t = ffelex_token_new_ (); - t->type = type; - t->uses = 1; - t->text = NULL; - t->where_line = ffewhere_line_use (l); - t->where_col = ffewhere_column_new (c); - return t; -} - -/* Make a new NUMBER token from an existing NAMES token. - - Like ffelex_token_new_number, this function calculates the length - of the digit string itself. */ - -ffelexToken -ffelex_token_number_from_names (ffelexToken t, ffeTokenLength start) -{ - ffelexToken nt; - ffeTokenLength len; - - assert (t != NULL); - assert (ffelex_token_type (t) == FFELEX_typeNAMES); - assert (start < t->length); - - /* How long is the string of decimal digits at s? */ - - len = strspn (t->text + start, "0123456789"); - - /* Make sure there is at least one digit. */ - - assert (len != 0); - - /* Now make the token. */ - - nt = ffelex_token_new_ (); - nt->type = FFELEX_typeNUMBER; - nt->size = len; /* Assume nobody's gonna fiddle with token - text. */ - nt->length = len; - nt->uses = 1; - ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line, - t->where_col, t->wheretrack, start); - nt->text = malloc_new_ksr (malloc_pool_image (), "FFELEX token text", - len + 1); - strncpy (nt->text, t->text + start, len); - nt->text[len] = '\0'; - return nt; -} - -/* Make a new UNDERSCORE token from a NAMES token. */ - -ffelexToken -ffelex_token_uscore_from_names (ffelexToken t, ffeTokenLength start) -{ - ffelexToken nt; - - assert (t != NULL); - assert (ffelex_token_type (t) == FFELEX_typeNAMES); - assert (start < t->length); - assert (t->text[start] == '_'); - - /* Now make the token. */ - - nt = ffelex_token_new_ (); - nt->type = FFELEX_typeUNDERSCORE; - nt->uses = 1; - ffewhere_set_from_track (&nt->where_line, &nt->where_col, t->where_line, - t->where_col, t->wheretrack, start); - nt->text = NULL; - return nt; -} - -/* ffelex_token_use -- Return another instance of a token - - ffelexToken t; - t = ffelex_token_use(t); - - In a sense, the new token is a copy of the old, though it might be the - same with just a new use count. - - We use the use count method (easy). */ - -ffelexToken -ffelex_token_use (ffelexToken t) -{ - if (t == NULL) - assert ("_token_use: null token" == NULL); - t->uses++; - return t; -} diff --git a/gcc/f/lex.h b/gcc/f/lex.h deleted file mode 100755 index c9a9dd5..0000000 --- a/gcc/f/lex.h +++ /dev/null @@ -1,201 +0,0 @@ -/* lex.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - lex.c - - Modifications: - 22-Aug-89 JCB 1.1 - Change for new ffewhere interface. -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_lex -#define _H_f_lex - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFELEX_typeNONE, - FFELEX_typeCOMMENT, - FFELEX_typeEOS, - FFELEX_typeEOF, - FFELEX_typeERROR, - FFELEX_typeRAW, - FFELEX_typeQUOTE, - FFELEX_typeDOLLAR, - FFELEX_typeHASH, - FFELEX_typePERCENT, - FFELEX_typeAMPERSAND, - FFELEX_typeAPOSTROPHE, - FFELEX_typeOPEN_PAREN, - FFELEX_typeCLOSE_PAREN, - FFELEX_typeASTERISK, - FFELEX_typePLUS, - FFELEX_typeMINUS, - FFELEX_typePERIOD, - FFELEX_typeSLASH, - FFELEX_typeNUMBER, /* Grep: [0-9][0-9]*. */ - FFELEX_typeOPEN_ANGLE, - FFELEX_typeEQUALS, - FFELEX_typeCLOSE_ANGLE, - FFELEX_typeNAME, /* Grep: [A-Za-z][A-Za-z0-9_]*. */ - FFELEX_typeCOMMA, - FFELEX_typePOWER, /* "**". */ - FFELEX_typeCONCAT, /* "//". */ - FFELEX_typeDEBUG, - FFELEX_typeNAMES, /* Same as FFELEX_typeNAME in initial - context. */ - FFELEX_typeHOLLERITH, /* <text> part of <nn>H<text>. */ - FFELEX_typeCHARACTER, /* <text> part of '<text>' or "<text>". */ - FFELEX_typeCOLON, - FFELEX_typeSEMICOLON, - FFELEX_typeUNDERSCORE, - FFELEX_typeQUESTION, - FFELEX_typeOPEN_ARRAY, /* "(/". */ - FFELEX_typeCLOSE_ARRAY, /* "/)". */ - FFELEX_typeCOLONCOLON, /* "::". */ - FFELEX_typeREL_LE, /* "<=". */ - FFELEX_typeREL_NE, /* "<>". */ - FFELEX_typeREL_EQ, /* "==". */ - FFELEX_typePOINTS, /* "=>". */ - FFELEX_typeREL_GE, /* ">=". */ - FFELEX_type - } ffelexType; - -/* Typedefs. */ - -typedef struct _lextoken_ *ffelexToken; -typedef void *lex_sigh_; -typedef lex_sigh_ (*lex_sigh__) (ffelexToken); -typedef lex_sigh__ (*ffelexHandler) (ffelexToken); - -/* Include files needed by this one. */ - -#include "top.h" -#include "where.h" - -/* Structure definitions. */ - -struct _lextoken_ - { - long int id_; /* DEBUG ONLY. */ - ffeTokenLength size; - ffeTokenLength length; - unsigned short uses; - char *text; - ffelexType type; - ffewhereLine where_line; - ffewhereColumn where_col; - ffewhereLine currentnames_line; /* For tracking NAMES tokens. */ - ffewhereColumn currentnames_col; /* For tracking NAMES tokens. */ - ffewhereTrack wheretrack; /* For tracking NAMES tokens. */ - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffelex_display_token (ffelexToken t); -bool ffelex_expecting_character (void); -ffelexHandler ffelex_file_fixed (ffewhereFile wf, FILE *f); -ffelexHandler ffelex_file_free (ffewhereFile wf, FILE *f); -void ffelex_hash_kludge (FILE *f); -void ffelex_init_1 (void); -bool ffelex_is_names_expected (void); -char *ffelex_line (void); -ffewhereColumnNumber ffelex_line_length (void); -ffewhereLineNumber ffelex_line_number (void); -void ffelex_set_expecting_hollerith (long length, char which, - ffewhereLine line, - ffewhereColumn column); -void ffelex_set_handler (ffelexHandler first); -void ffelex_set_hexnum (bool on); -void ffelex_set_include (ffewhereFile wf, bool free_form, FILE *fi); -void ffelex_set_names (bool on); -void ffelex_set_names_pure (bool on); -ffelexHandler ffelex_splice_tokens (ffelexHandler first, ffelexToken master, - ffeTokenLength start); -ffelexHandler ffelex_swallow_tokens (ffelexToken t, ffelexHandler handler); -ffelexToken ffelex_token_dollar_from_names (ffelexToken t, - ffeTokenLength start); -void ffelex_token_kill (ffelexToken t); -ffelexToken ffelex_token_name_from_names (ffelexToken t, - ffeTokenLength start, - ffeTokenLength len); -ffelexToken ffelex_token_names_from_names (ffelexToken t, - ffeTokenLength start, - ffeTokenLength len); -ffelexToken ffelex_token_new (void); -ffelexToken ffelex_token_new_character (char *s, ffewhereLine l, - ffewhereColumn c); -ffelexToken ffelex_token_new_eof (void); -ffelexToken ffelex_token_new_name (char *s, ffewhereLine l, - ffewhereColumn c); -ffelexToken ffelex_token_new_names (char *s, ffewhereLine l, - ffewhereColumn c); -ffelexToken ffelex_token_new_number (char *s, ffewhereLine l, - ffewhereColumn c); -ffelexToken ffelex_token_new_simple_ (ffelexType type, ffewhereLine l, - ffewhereColumn c); -ffelexToken ffelex_token_number_from_names (ffelexToken t, - ffeTokenLength start); -ffelexToken ffelex_token_uscore_from_names (ffelexToken t, - ffeTokenLength start); -ffelexToken ffelex_token_use (ffelexToken t); - -/* Define macros. */ - -#define ffelex_init_0() -#define ffelex_init_2() -#define ffelex_init_3() -#define ffelex_init_4() -#define ffelex_is_firstnamechar(c) \ - (ISALPHA ((c)) || ((c) == '_')) -#define ffelex_terminate_0() -#define ffelex_terminate_1() -#define ffelex_terminate_2() -#define ffelex_terminate_3() -#define ffelex_terminate_4() -#define ffelex_token_length(t) ((t)->length) -#define ffelex_token_new_eos(l,c) \ - ffelex_token_new_simple_ (FFELEX_typeEOS, (l), (c)) -#define ffelex_token_new_period(l,c) \ - ffelex_token_new_simple_ (FFELEX_typePERIOD, (l), (c)) -#define ffelex_token_strcmp(t1,t2) strcmp ((t1)->text, (t2)->text) -#define ffelex_token_text(t) ((t)->text) -#define ffelex_token_type(t) ((t)->type) -#define ffelex_token_where_column(t) ((t)->where_col) -#define ffelex_token_where_filename(t) \ - ffewhere_line_filename ((t)->where_line) -#define ffelex_token_where_filelinenum(t) \ - ffewhere_line_filelinenum((t)->where_line) -#define ffelex_token_where_line(t) ((t)->where_line) -#define ffelex_token_where_line_number(t) \ - ffewhere_line_number ((t)->where_line) -#define ffelex_token_wheretrack(t) ((t)->wheretrack) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/malloc.c b/gcc/f/malloc.c deleted file mode 100755 index d7041c3..0000000 --- a/gcc/f/malloc.c +++ /dev/null @@ -1,552 +0,0 @@ -/* malloc.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Fast pool-based memory allocation. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "malloc.h" - -/* Externals defined here. */ - -struct _malloc_root_ malloc_root_ -= -{ - { - &malloc_root_.malloc_pool_image_, - &malloc_root_.malloc_pool_image_, - (mallocPool) &malloc_root_.malloc_pool_image_.eldest, - (mallocPool) &malloc_root_.malloc_pool_image_.eldest, - (mallocArea_) &malloc_root_.malloc_pool_image_.first, - (mallocArea_) &malloc_root_.malloc_pool_image_.first, - 0, -#if MALLOC_DEBUG - 0, 0, 0, 0, 0, 0, 0, { '/' } -#else - { 0 } -#endif - }, -}; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -static void *malloc_reserve_ = NULL; /* For crashes. */ -#if MALLOC_DEBUG -static char *malloc_types_[] = -{"KS", "KSR", "NF", "NFR", "US", "USR"}; -#endif - -/* Static functions (internal). */ - -static void malloc_kill_area_ (mallocPool pool, mallocArea_ a); -#if MALLOC_DEBUG -static void malloc_verify_area_ (mallocPool pool, mallocArea_ a); -#endif - -/* Internal macros. */ - -#if MALLOC_DEBUG -#define malloc_kill_(ptr,s) do {memset((ptr),127,(s));free((ptr));} while(0) -#else -#define malloc_kill_(ptr,s) free((ptr)) -#endif - -/* malloc_kill_area_ -- Kill storage area and its object - - malloc_kill_area_(mallocPool pool,mallocArea_ area); - - Does the actual killing of a storage area. */ - -static void -malloc_kill_area_ (mallocPool pool UNUSED, mallocArea_ a) -{ -#if MALLOC_DEBUG - assert (strcmp (a->name, ((char *) (a->where)) + a->size) == 0); -#endif - malloc_kill_ (a->where, a->size); - a->next->previous = a->previous; - a->previous->next = a->next; -#if MALLOC_DEBUG - pool->freed += a->size; - pool->frees++; -#endif - malloc_kill_ (a, - offsetof (struct _malloc_area_, name) - + strlen (a->name) + 1); -} - -/* malloc_verify_area_ -- Verify storage area and its object - - malloc_verify_area_(mallocPool pool,mallocArea_ area); - - Does the actual verifying of a storage area. */ - -#if MALLOC_DEBUG -static void -malloc_verify_area_ (mallocPool pool UNUSED, mallocArea_ a UNUSED) -{ - mallocSize s = a->size; - - assert (strcmp (a->name, ((char *) (a->where)) + s) == 0); -} -#endif - -/* malloc_init -- Initialize malloc cluster - - malloc_init(); - - Call malloc_init before you do anything else. */ - -void -malloc_init () -{ - if (malloc_reserve_ != NULL) - return; - malloc_reserve_ = malloc (20 * 1024); /* In case of crash, free this first. */ - assert (malloc_reserve_ != NULL); -} - -/* malloc_pool_display -- Display a pool - - mallocPool p; - malloc_pool_display(p); - - Displays information associated with the pool and its subpools. */ - -void -malloc_pool_display (mallocPool p UNUSED) -{ -#if MALLOC_DEBUG - mallocPool q; - mallocArea_ a; - - fprintf (dmpout, "Pool \"%s\": bytes allocated=%lu, freed=%lu, old sizes=%lu, new sizes\ -=%lu,\n allocations=%lu, frees=%lu, resizes=%lu, uses=%lu\n Subpools:\n", - p->name, p->allocated, p->freed, p->old_sizes, p->new_sizes, p->allocations, - p->frees, p->resizes, p->uses); - - for (q = p->eldest; q != (mallocPool) & p->eldest; q = q->next) - fprintf (dmpout, " \"%s\"\n", q->name); - - fprintf (dmpout, " Storage areas:\n"); - - for (a = p->first; a != (mallocArea_) & p->first; a = a->next) - { - fprintf (dmpout, " "); - malloc_display_ (a); - } -#endif -} - -/* malloc_pool_kill -- Destroy a pool - - mallocPool p; - malloc_pool_kill(p); - - Releases all storage associated with the pool and its subpools. */ - -void -malloc_pool_kill (mallocPool p) -{ - mallocPool q; - mallocArea_ a; - - if (--p->uses != 0) - return; - -#if 0 - malloc_pool_display (p); -#endif - - assert (p->next->previous == p); - assert (p->previous->next == p); - - /* Kill off all the subpools. */ - - while ((q = p->eldest) != (mallocPool) &p->eldest) - { - q->uses = 1; /* Force the kill. */ - malloc_pool_kill (q); - } - - /* Now free all the storage areas. */ - - while ((a = p->first) != (mallocArea_) & p->first) - { - malloc_kill_area_ (p, a); - } - - /* Now remove from list of sibling pools. */ - - p->next->previous = p->previous; - p->previous->next = p->next; - - /* Finally, free the pool itself. */ - - malloc_kill_ (p, - offsetof (struct _malloc_pool_, name) - + strlen (p->name) + 1); -} - -/* malloc_pool_new -- Make a new pool - - mallocPool p; - p = malloc_pool_new("My new pool",malloc_pool_image(),1024); - - Makes a new pool with the given name and default new-chunk allocation. */ - -mallocPool -malloc_pool_new (char *name, mallocPool parent, - unsigned long chunks UNUSED) -{ - mallocPool p; - - if (parent == NULL) - parent = malloc_pool_image (); - - p = malloc_new_ (offsetof (struct _malloc_pool_, name) - + (MALLOC_DEBUG ? strlen (name) + 1 : 0)); - p->next = (mallocPool) &(parent->eldest); - p->previous = parent->youngest; - parent->youngest->next = p; - parent->youngest = p; - p->eldest = (mallocPool) &(p->eldest); - p->youngest = (mallocPool) &(p->eldest); - p->first = (mallocArea_) &(p->first); - p->last = (mallocArea_) &(p->first); - p->uses = 1; -#if MALLOC_DEBUG - p->allocated = p->freed = p->old_sizes = p->new_sizes = p->allocations - = p->frees = p->resizes = 0; - strcpy (p->name, name); -#endif - return p; -} - -/* malloc_pool_use -- Use an existing pool - - mallocPool p; - p = malloc_pool_new(pool); - - Increments use count for pool; means a matching malloc_pool_kill must - be performed before a subsequent one will actually kill the pool. */ - -mallocPool -malloc_pool_use (mallocPool pool) -{ - ++pool->uses; - return pool; -} - -/* malloc_display_ -- Display info on a mallocArea_ - - mallocArea_ a; - malloc_display_(a); - - Simple. */ - -void -malloc_display_ (mallocArea_ a UNUSED) -{ -#if MALLOC_DEBUG - fprintf (dmpout, "At %08lX, size=%" mallocSize_f "u, type=%s, \"%s\"\n", - (unsigned long) a->where, a->size, malloc_types_[a->type], a->name); -#endif -} - -/* malloc_find_inpool_ -- Find mallocArea_ for object in pool - - mallocPool pool; - void *ptr; - mallocArea_ a; - a = malloc_find_inpool_(pool,ptr); - - Search for object in list of mallocArea_s, die if not found. */ - -mallocArea_ -malloc_find_inpool_ (mallocPool pool, void *ptr) -{ - mallocArea_ a; - mallocArea_ b = (mallocArea_) &pool->first; - int n = 0; - - for (a = pool->first; a != (mallocArea_) &pool->first; a = a->next) - { - assert (("Infinite loop detected" != NULL) && (a != b)); - if (a->where == ptr) - return a; - ++n; - if (n & 1) - b = b->next; - } - assert ("Couldn't find object in pool!" == NULL); - return NULL; -} - -/* malloc_kill_inpool_ -- Kill object - - malloc_kill_inpool_(NULL,MALLOC_typeUS_,ptr,size_in_bytes); - - Find the mallocArea_ for the pointer, make sure the type is proper, and - kill both of them. */ - -void -malloc_kill_inpool_ (mallocPool pool, mallocType_ type UNUSED, - void *ptr, mallocSize s UNUSED) -{ - mallocArea_ a; - - if (pool == NULL) - pool = malloc_pool_image (); - -#if MALLOC_DEBUG - assert ((pool == malloc_pool_image ()) - || malloc_pool_find_ (pool, malloc_pool_image ())); -#endif - - a = malloc_find_inpool_ (pool, ptr); -#if MALLOC_DEBUG - assert (a->type == type); - if ((type != MALLOC_typeUS_) && (type != MALLOC_typeUSR_)) - assert (a->size == s); -#endif - malloc_kill_area_ (pool, a); -} - -/* malloc_new_ -- Allocate new object, die if unable - - ptr = malloc_new_(size_in_bytes); - - Call malloc, bomb if it returns NULL. */ - -void * -malloc_new_ (mallocSize s) -{ - void *ptr; - unsigned ss = s; - -#if MALLOC_DEBUG && 0 - assert (s == (mallocSize) ss);/* Else alloc is too big for this - library/sys. */ -#endif - - ptr = xmalloc (ss); -#if MALLOC_DEBUG - memset (ptr, 126, ss); /* Catch some kinds of errors more - quickly/reliably. */ -#endif - return ptr; -} - -/* malloc_new_inpool_ -- Allocate new object, die if unable - - ptr = malloc_new_inpool_(NULL,MALLOC_typeUS_,"object",size_in_bytes); - - Allocate the structure and allocate a mallocArea_ to describe it, then - add it to the list of mallocArea_s for the pool. */ - -void * -malloc_new_inpool_ (mallocPool pool, mallocType_ type, char *name, mallocSize s) -{ - void *ptr; - mallocArea_ a; - unsigned short i; - - if (pool == NULL) - pool = malloc_pool_image (); - -#if MALLOC_DEBUG - assert ((pool == malloc_pool_image ()) - || malloc_pool_find_ (pool, malloc_pool_image ())); -#endif - - ptr = malloc_new_ (s + (i = (MALLOC_DEBUG ? strlen (name) + 1 : 0))); -#if MALLOC_DEBUG - strcpy (((char *) (ptr)) + s, name); -#endif - a = malloc_new_ (offsetof (struct _malloc_area_, name) + i); - switch (type) - { /* A little optimization to speed up killing - of non-permanent stuff. */ - case MALLOC_typeKP_: - case MALLOC_typeKPR_: - a->next = (mallocArea_) &pool->first; - break; - - default: - a->next = pool->first; - break; - } - a->previous = a->next->previous; - a->next->previous = a; - a->previous->next = a; - a->where = ptr; -#if MALLOC_DEBUG - a->size = s; - a->type = type; - strcpy (a->name, name); - pool->allocated += s; - pool->allocations++; -#endif - return ptr; -} - -/* malloc_new_zinpool_ -- Allocate new zeroed object, die if unable - - ptr = malloc_new_zinpool_(NULL,MALLOC_typeUS_,"object",size_in_bytes,0); - - Like malloc_new_inpool_, but zeros out all the bytes in the area (assuming - you pass it a 0). */ - -void * -malloc_new_zinpool_ (mallocPool pool, mallocType_ type, char *name, mallocSize s, - int z) -{ - void *ptr; - - ptr = malloc_new_inpool_ (pool, type, name, s); - memset (ptr, z, s); - return ptr; -} - -/* malloc_pool_find_ -- See if pool is a descendant of another pool - - if (malloc_pool_find_(target_pool,parent_pool)) ...; - - Recursive descent on each of the children of the parent pool, after - first checking the children themselves. */ - -char -malloc_pool_find_ (mallocPool pool, mallocPool parent) -{ - mallocPool p; - - for (p = parent->eldest; p != (mallocPool) & parent->eldest; p = p->next) - { - if ((p == pool) || malloc_pool_find_ (pool, p)) - return 1; - } - return 0; -} - -/* malloc_resize_inpool_ -- Resize existing object in pool - - ptr = malloc_resize_inpool_(NULL,MALLOC_typeUSR_,ptr,new_size,old_size); - - Find the object's mallocArea_, check it out, then do the resizing. */ - -void * -malloc_resize_inpool_ (mallocPool pool, mallocType_ type UNUSED, - void *ptr, mallocSize ns, mallocSize os UNUSED) -{ - mallocArea_ a; - - if (pool == NULL) - pool = malloc_pool_image (); - -#if MALLOC_DEBUG - assert ((pool == malloc_pool_image ()) - || malloc_pool_find_ (pool, malloc_pool_image ())); -#endif - - a = malloc_find_inpool_ (pool, ptr); -#if MALLOC_DEBUG - assert (a->type == type); - if ((type == MALLOC_typeKSR_) || (type == MALLOC_typeKPR_)) - assert (a->size == os); - assert (strcmp (a->name, ((char *) (ptr)) + os) == 0); -#endif - ptr = malloc_resize_ (ptr, ns + (MALLOC_DEBUG ? strlen (a->name) + 1: 0)); - a->where = ptr; -#if MALLOC_DEBUG - a->size = ns; - strcpy (((char *) (ptr)) + ns, a->name); - pool->old_sizes += os; - pool->new_sizes += ns; - pool->resizes++; -#endif - return ptr; -} - -/* malloc_resize_ -- Reallocate object, die if unable - - ptr = malloc_resize_(ptr,size_in_bytes); - - Call realloc, bomb if it returns NULL. */ - -void * -malloc_resize_ (void *ptr, mallocSize s) -{ - int ss = s; - -#if MALLOC_DEBUG && 0 - assert (s == (mallocSize) ss);/* Too big if failure here. */ -#endif - - ptr = xrealloc (ptr, ss); - return ptr; -} - -/* malloc_verify_inpool_ -- Verify object - - Find the mallocArea_ for the pointer, make sure the type is proper, and - verify both of them. */ - -void -malloc_verify_inpool_ (mallocPool pool UNUSED, mallocType_ type UNUSED, - void *ptr UNUSED, mallocSize s UNUSED) -{ -#if MALLOC_DEBUG - mallocArea_ a; - - if (pool == NULL) - pool = malloc_pool_image (); - - assert ((pool == malloc_pool_image ()) - || malloc_pool_find_ (pool, malloc_pool_image ())); - - a = malloc_find_inpool_ (pool, ptr); - assert (a->type == type); - if ((type != MALLOC_typeUS_) && (type != MALLOC_typeUSR_)) - assert (a->size == s); - malloc_verify_area_ (pool, a); -#endif -} diff --git a/gcc/f/malloc.h b/gcc/f/malloc.h deleted file mode 100755 index ea43276..0000000 --- a/gcc/f/malloc.h +++ /dev/null @@ -1,183 +0,0 @@ -/* malloc.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - malloc.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_malloc -#define _H_f_malloc - -#ifndef MALLOC_DEBUG -#define MALLOC_DEBUG 0 /* 1 means check caller's use of this module. */ -#endif - -/* Simple definitions and enumerations. */ - -typedef enum - { - MALLOC_typeKS_, - MALLOC_typeKSR_, - MALLOC_typeKP_, - MALLOC_typeKPR_, - MALLOC_typeUS_, - MALLOC_typeUSR_, - MALLOC_type_ - } mallocType_; - -/* Typedefs. */ - -typedef struct _malloc_area_ *mallocArea_; -typedef struct _malloc_pool_ *mallocPool; -typedef unsigned long int mallocSize; -#define mallocSize_f "l" - -/* Include files needed by this one. */ - - -/* Structure definitions. */ - -struct _malloc_area_ - { - mallocArea_ next; - mallocArea_ previous; - void *where; -#if MALLOC_DEBUG - mallocSize size; - mallocType_ type; -#endif - char name[1]; - }; - -struct _malloc_pool_ - { - mallocPool next; - mallocPool previous; - mallocPool eldest; - mallocPool youngest; - mallocArea_ first; - mallocArea_ last; - unsigned long uses; -#if MALLOC_DEBUG - mallocSize allocated; - mallocSize freed; - mallocSize old_sizes; - mallocSize new_sizes; - unsigned long allocations; - unsigned long frees; - unsigned long resizes; -#endif - char name[1]; - }; - -struct _malloc_root_ - { - struct _malloc_pool_ malloc_pool_image_; - }; - -/* Global objects accessed by users of this module. */ - -extern struct _malloc_root_ malloc_root_; - -/* Declare functions with prototypes. */ - -void malloc_display_ (mallocArea_ a); -mallocArea_ malloc_find_inpool_ (mallocPool pool, void *ptr); -void malloc_init (void); -void malloc_kill_inpool_ (mallocPool pool, mallocType_ type, void *ptr, - mallocSize size); -void *malloc_new_ (mallocSize size); -void *malloc_new_inpool_ (mallocPool pool, mallocType_ type, char *name, - mallocSize size); -void *malloc_new_zinpool_ (mallocPool pool, mallocType_ type, char *name, - mallocSize size, int z); -void malloc_pool_display (mallocPool p); -char malloc_pool_find_ (mallocPool p, mallocPool parent); -void malloc_pool_kill (mallocPool p); -mallocPool malloc_pool_new (char *name, mallocPool parent, unsigned long chunks); -mallocPool malloc_pool_use (mallocPool p); -void *malloc_resize_ (void *ptr, mallocSize new_size); -void *malloc_resize_inpool_ (mallocPool pool, mallocType_ type, void *ptr, - mallocSize new_size, mallocSize old_size); -void malloc_verify_inpool_ (mallocPool pool, mallocType_ type, void *ptr, - mallocSize size); - -/* Define macros. */ - -#define malloc_new_ks(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeKS_,name,size) -#define malloc_new_ksr(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeKSR_,name,size) -#define malloc_new_kp(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeKP_,name,size) -#define malloc_new_kpr(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeKPR_,name,size) -#define malloc_new_us(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeUS_,name,size) -#define malloc_new_usr(pool,name,size) \ - malloc_new_inpool_ (pool,MALLOC_typeUSR_,name,size) -#define malloc_new_zks(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeKS_,name,size,z) -#define malloc_new_zksr(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeKSR_,name,size,z) -#define malloc_new_zkp(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeKP_,name,size,z) -#define malloc_new_zkpr(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeKPR_,name,size,z) -#define malloc_new_zus(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeUS_,name,size,z) -#define malloc_new_zusr(pool,name,size,z) \ - malloc_new_zinpool_ (pool,MALLOC_typeUSR_,name,size,z) -#define malloc_kill_ks(pool,ptr,size) \ - malloc_kill_inpool_ (pool,MALLOC_typeKS_,ptr,size) -#define malloc_kill_ksr(pool,ptr,size) \ - malloc_kill_inpool_ (pool,MALLOC_typeKSR_,ptr,size) -#define malloc_kill_us(pool,ptr) \ - malloc_kill_inpool_ (pool,MALLOC_typeUS_,ptr,0) -#define malloc_kill_usr(pool,ptr) \ - malloc_kill_inpool_ (pool,MALLOC_typeUSR_,ptr,0) -#define malloc_pool_image() (&malloc_root_.malloc_pool_image_) -#define malloc_resize_ksr(pool,ptr,new_size,old_size) \ - malloc_resize_inpool_ (pool,MALLOC_typeKSR_,ptr,new_size,old_size) -#define malloc_resize_kpr(pool,ptr,new_size,old_size) \ - malloc_resize_inpool_ (pool,MALLOC_typeKPR_,ptr,new_size,old_size) -#define malloc_resize_usr(pool,ptr,new_size) \ - malloc_resize_inpool_ (pool,MALLOC_typeUSR_,ptr,new_size,0) -#define malloc_verify_kp(pool,name,size) \ - malloc_verify_inpool_ (pool,MALLOC_typeKP_,name,size) -#define malloc_verify_kpr(pool,name,size) \ - malloc_verify_inpool_ (pool,MALLOC_typeKPR_,name,size) -#define malloc_verify_ks(pool,ptr,size) \ - malloc_verify_inpool_ (pool,MALLOC_typeKS_,ptr,size) -#define malloc_verify_ksr(pool,ptr,size) \ - malloc_verify_inpool_ (pool,MALLOC_typeKSR_,ptr,size) -#define malloc_verify_us(pool,ptr) \ - malloc_verify_inpool_ (pool,MALLOC_typeUS_,ptr,0) -#define malloc_verify_usr(pool,ptr) \ - malloc_verify_inpool_ (pool,MALLOC_typeUSR_,ptr,0) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/name.c b/gcc/f/name.c deleted file mode 100755 index 560f642..0000000 --- a/gcc/f/name.c +++ /dev/null @@ -1,242 +0,0 @@ -/* name.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None. - - Description: - Name and name space abstraction. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "bad.h" -#include "name.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#include "where.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - -static ffename ffename_lookup_ (ffenameSpace ns, ffelexToken t, bool *found); - -/* Internal macros. */ - - -/* Searches for and returns the matching ffename object, or returns a - pointer to the name before which the new name should go. */ - -static ffename -ffename_lookup_ (ffenameSpace ns, ffelexToken t, bool *found) -{ - ffename n; - - for (n = ns->first; n != (ffename) &ns->first; n = n->next) - { - if (ffelex_token_strcmp (t, n->t) == 0) - { - *found = TRUE; - return n; - } - } - - *found = FALSE; - return n; /* (n == (ffename) &ns->first) */ -} - -/* Searches for and returns the matching ffename object, or creates a new - one (with a NULL ffesymbol) and returns that. If last arg is TRUE, - check whether token meets character-content requirements (such as - "all characters must be uppercase", as determined by - ffesrc_bad_char_symbol (), issue diagnostic if it doesn't. */ - -ffename -ffename_find (ffenameSpace ns, ffelexToken t) -{ - ffename n; - ffename newn; - bool found; - - assert (ns != NULL); - assert ((t != NULL) && ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES))); - - n = ffename_lookup_ (ns, t, &found); - if (found) - return n; - - newn = (ffename) malloc_new_ks (ns->pool, "FFENAME name", sizeof (*n)); - newn->next = n; - newn->previous = n->previous; - n->previous = newn; - newn->previous->next = newn; - newn->t = ffelex_token_use (t); - newn->u.s = NULL; - - return newn; -} - -/* ffename_kill -- Kill name from name space - - ffenameSpace ns; - ffename s; - ffename_kill(ns,s); - - Removes the name from the name space. */ - -void -ffename_kill (ffenameSpace ns, ffename n) -{ - assert (ns != NULL); - assert (n != NULL); - - ffelex_token_kill (n->t); - n->next->previous = n->previous; - n->previous->next = n->next; - malloc_kill_ks (ns->pool, n, sizeof (*n)); -} - -/* ffename_lookup -- Look up name in name space - - ffenameSpace ns; - ffelexToken t; - ffename s; - n = ffename_lookup(ns,t); - - Searches for and returns the matching ffename object, or returns NULL. */ - -ffename -ffename_lookup (ffenameSpace ns, ffelexToken t) -{ - ffename n; - bool found; - - assert (ns != NULL); - assert ((t != NULL) && ((ffelex_token_type (t) == FFELEX_typeNAME) - || (ffelex_token_type (t) == FFELEX_typeNAMES))); - - n = ffename_lookup_ (ns, t, &found); - - return found ? n : NULL; -} - -/* ffename_space_drive_global -- Call given fn for each global in name space - - ffenameSpace ns; - ffeglobal (*fn)(); - ffename_space_drive_global(ns,fn); */ - -void -ffename_space_drive_global (ffenameSpace ns, ffeglobal (*fn) ()) -{ - ffename n; - - if (ns == NULL) - return; - - for (n = ns->first; n != (ffename) &ns->first; n = n->next) - { - if (n->u.g != NULL) - n->u.g = (*fn) (n->u.g); - } -} - -/* ffename_space_drive_symbol -- Call given fn for each symbol in name space - - ffenameSpace ns; - ffesymbol (*fn)(); - ffename_space_drive_symbol(ns,fn); */ - -void -ffename_space_drive_symbol (ffenameSpace ns, ffesymbol (*fn) ()) -{ - ffename n; - - if (ns == NULL) - return; - - for (n = ns->first; n != (ffename) &ns->first; n = n->next) - { - if (n->u.s != NULL) - n->u.s = (*fn) (n->u.s); - } -} - -/* ffename_space_kill -- Kill name space - - ffenameSpace ns; - ffename_space_kill(ns); - - Removes the names from the name space; kills the name space. */ - -void -ffename_space_kill (ffenameSpace ns) -{ - assert (ns != NULL); - - while (ns->first != (ffename) &ns->first) - ffename_kill (ns, ns->first); - - malloc_kill_ks (ns->pool, ns, sizeof (*ns)); -} - -/* ffename_space_new -- Create name space - - ffenameSpace ns; - ns = ffename_space_new(malloc_pool_image()); - - Create new name space. */ - -ffenameSpace -ffename_space_new (mallocPool pool) -{ - ffenameSpace ns; - - ns = (ffenameSpace) malloc_new_ks (pool, "FFENAME space", - sizeof (*ns)); - ns->first = (ffename) &ns->first; - ns->last = (ffename) &ns->first; - ns->pool = pool; - - return ns; -} diff --git a/gcc/f/name.h b/gcc/f/name.h deleted file mode 100755 index 8359ed6..0000000 --- a/gcc/f/name.h +++ /dev/null @@ -1,109 +0,0 @@ -/* name.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - name.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_name -#define _H_f_name - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffename_ *ffename; -typedef struct _ffename_space_ *ffenameSpace; - -/* Include files needed by this one. */ - -#include "global.h" -#include "lex.h" -#include "malloc.h" -#include "symbol.h" - -/* Structure definitions. */ - -struct _ffename_ - { - ffename next; - ffename previous; - ffelexToken t; - union - { - ffesymbol s; - ffeglobal g; - } - u; - }; - -struct _ffename_space_ - { - ffename first; - ffename last; - mallocPool pool; - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -ffename ffename_find (ffenameSpace ns, ffelexToken t); -void ffename_kill (ffenameSpace ns, ffename n); -ffename ffename_lookup (ffenameSpace ns, ffelexToken t); -void ffename_space_drive_global (ffenameSpace ns, ffeglobal (*fn) ()); -void ffename_space_drive_symbol (ffenameSpace ns, ffesymbol (*fn) ()); -void ffename_space_kill (ffenameSpace ns); -ffenameSpace ffename_space_new (mallocPool pool); - -/* Define macros. */ - -#define ffename_first_token(n) ((n)->t) -#define ffename_global(n) ((n)->u.g) -#define ffename_init_0() -#define ffename_init_1() -#define ffename_init_2() -#define ffename_init_3() -#define ffename_init_4() -#define ffename_set_global(n,glob) ((n)->u.g = (glob)) -#define ffename_set_symbol(n,sym) ((n)->u.s = (sym)) -#define ffename_symbol(n) ((n)->u.s) -#define ffename_terminate_0() -#define ffename_terminate_1() -#define ffename_terminate_2() -#define ffename_terminate_3() -#define ffename_terminate_4() -#define ffename_text(n) ffelex_token_text((n)->t) -#define ffename_token(n) ((n)->t) -#define ffename_where_filename(n) ffelex_token_where_filename((n)->t) -#define ffename_where_filelinenum(n) ffelex_token_where_filelinenum((n)->t) -#define ffename_where_line(n) ffelex_token_where_line((n)->t) -#define ffename_where_column(n) ffelex_token_where_column((n)->t) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/news.texi b/gcc/f/news.texi deleted file mode 100755 index 6ff1330..0000000 --- a/gcc/f/news.texi +++ /dev/null @@ -1,2284 +0,0 @@ -@c Copyright (C) 1995-1997 Free Software Foundation, Inc. -@c This is part of the G77 manual. -@c For copying conditions, see the file g77.texi. - -@c The text of this file appears in the file BUGS -@c in the G77 distribution, as well as in the G77 manual. - -@c 1998-11-03 - -@ifclear NEWSONLY -@node News -@chapter News About GNU Fortran -@end ifclear -@cindex versions, recent -@cindex recent versions - -Changes made to recent versions of GNU Fortran are listed -below, with the most recent version first. - -The changes are generally listed in order: - -@enumerate -@item -Code-generation and run-time-library bug-fixes - -@item -Compiler and run-time-library crashes involving valid code -that have been fixed - -@item -New features - -@item -Fixes and enhancements to existing features - -@item -New diagnostics - -@item -Internal improvements - -@item -Miscellany -@end enumerate - -This order is not strict---for example, some items -involve a combination of these elements. - -Note that two variants of @code{g77} are tracked below. -The @code{egcs} variant is described vis-a-vis -previous versions of @code{egcs} and/or -an official FSF version, -as appropriate. - -Therefore, @code{egcs} versions sometimes have multiple listings -to help clarify how they differ from other versions, -though this can make getting a complete picture -of what a particular @code{egcs} version contains -somewhat more difficult. - -@heading In 0.5.24 and @code{egcs} 1.1.1 (versus 0.5.23 and 1.1): -@itemize @bullet -@item -Fix @code{libg2c} so it performs an implicit @code{ENDFILE} operation -(as appropriate) -whenever a @code{REWIND} is done. - -(This bug was introduced in 0.5.23 and @code{egcs} 1.1 in -@code{g77}'s version of @code{libf2c}.) - -@item -Fix @code{libg2c} so it no longer crashes with a spurious diagnostic -upon doing any I/O following a direct formatted write. - -(This bug was introduced in 0.5.23 and @code{egcs} 1.1 in -@code{g77}'s version of @code{libf2c}.) - -@item -Fix @code{g77} so it no longer crashes compiling references -to the @samp{Rand} intrinsic on some systems. - -@item -Fix @code{g77} portion of installation process so it works -better on some systems -(those with shells requiring @samp{else true} clauses -on @samp{if} constructs -for the completion code to be set properly). -@end itemize - -@heading In @code{egcs} 1.1 (versus 0.5.24): -@itemize @bullet -@item -Fix @code{g77} crash compiling code -containing the construct @samp{CMPLX(0.)} or similar. - -@item -Fix @code{g77} crash -(or apparently infinite run-time) -when compiling certain complicated expressions -involving @code{COMPLEX} arithmetic -(especially multiplication). - -@cindex DNRM2 -@cindex stack, 387 coprocessor -@cindex Intel x86 -@cindex -O2 -@item -Fix a code-generation bug that afflicted -Intel x86 targets when @samp{-O2} was specified -compiling, for example, an old version of -the @samp{DNRM2} routine. - -The x87 coprocessor stack was being -mismanaged in cases involving assigned @code{GOTO} -and @code{ASSIGN}. - -@cindex alignment -@cindex double-precision performance -@cindex -malign-double -@item -Align static double-precision variables and arrays -on Intel x86 targets -regardless of whether @samp{-malign-double} is specified. - -Generally, this affects only local variables and arrays -having the @code{SAVE} attribute -or given initial values via @code{DATA}. -@end itemize - -@c 1998-09-01: egcs-1.1 released. -@heading In @code{egcs} 1.1 (versus @code{egcs} 1.0.3): -@itemize @bullet -@item -Fix bugs in the @code{libU77} intrinsic @samp{HostNm} -that wrote one byte beyond the end of its @samp{CHARACTER} -argument, -and in the @code{libU77} intrinsics -@samp{GMTime} and @samp{LTime} -that overwrote their arguments. - -@item -Assumed arrays with negative bounds -(such as @samp{REAL A(-1:*)}) -no longer elicit spurious diagnostics from @code{g77}, -even on systems with pointers having -different sizes than integers. - -This bug is not known to have existed in any -recent version of @code{gcc}. -It was introduced in an early release of @code{egcs}. - -@item -Valid combinations of @code{EXTERNAL}, -passing that external as a dummy argument -without explicitly giving it a type, -and, in a subsequent program unit, -referencing that external as -an external function with a different type -no longer crash @code{g77}. - -@item -@code{CASE DEFAULT} no longer crashes @code{g77}. - -@item -The @samp{-Wunused} option no longer issues a spurious -warning about the ``master'' procedure generated by -@code{g77} for procedures containing @code{ENTRY} statements. - -@item -Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a -compile-time constant @code{INTEGER} expression. - -@item -Fix @code{g77} @samp{-g} option so procedures that -use @samp{ENTRY} can be stepped through, line by line, -in @code{gdb}. - -@item -Allow any @code{REAL} argument to intrinsics -@code{Second} and @code{CPU_Time}. - -@item -Use @code{tempnam}, if available, to open scratch files -(as in @samp{OPEN(STATUS='SCRATCH')}) -so that the @code{TMPDIR} environment variable, -if present, is used. - -@item -@code{g77}'s version of @code{libf2c} separates out -the setting of global state -(such as command-line arguments and signal handling) -from @file{main.o} into distinct, new library -archive members. - -This should make it easier to write portable applications -that have their own (non-Fortran) @code{main()} routine -properly set up the @code{libf2c} environment, even -when @code{libf2c} (now @code{libg2c}) is a shared library. - -@item -@code{g77} no longer installs the @file{f77} command -and @file{f77.1} man page -in the @file{/usr} or @file{/usr/local} heirarchy, -even if the @file{f77-install-ok} file exists -in the source or build directory. -See the installation documentation for more information. - -@item -@code{g77} no longer installs the @file{libf2c.a} library -and @file{f2c.h} include file -in the @file{/usr} or @file{/usr/local} heirarchy, -even if the @file{f2c-install-ok} or @file{f2c-exists-ok} files exist -in the source or build directory. -See the installation documentation for more information. - -@item -The @file{libf2c.a} library produced by @code{g77} has been -renamed to @file{libg2c.a}. -It is installed only in the @code{gcc} ``private'' -directory heirarchy, @file{gcc-lib}. -This allows system administrators and users to choose which -version of the @code{libf2c} library from @code{netlib} they -wish to use on a case-by-case basis. -See the installation documentation for more information. - -@item -The @file{f2c.h} include (header) file produced by @code{g77} -has been renamed to @file{g2c.h}. -It is installed only in the @code{gcc} ``private'' -directory heirarchy, @file{gcc-lib}. -This allows system administrators and users to choose which -version of the include file from @code{netlib} they -wish to use on a case-by-case basis. -See the installation documentation for more information. - -@item -The @code{g77} command now expects the run-time library -to be named @code{libg2c.a} instead of @code{libf2c.a}, -to ensure that a version other than the one built and -installed as part of the same @code{g77} version is picked up. - -@item -During the configuration and build process, -@code{g77} creates subdirectories it needs only as it -needs them. -Other cleaning up of the configuration and build process -has been performed as well. - -@item -@code{install-info} now used to update the directory of -Info documentation to contain an entry for @code{g77} -(during installation). - -@item -Some diagnostics have been changed from warnings to errors, -to prevent inadvertent use of the resulting, probably buggy, -programs. -These mostly include diagnostics about use of unsupported features -in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and -@code{WRITE} statements, -and about truncations of various sorts of constants. - -@item -Improve compilation of @code{FORMAT} expressions so that -a null byte is appended to the last operand if it -is a constant. -This provides a cleaner run-time diagnostic as provided -by @code{libf2c} for statements like @samp{PRINT '(I1', 42}. - -@item -Improve documentation and indexing. - -@item -The upgrade to @code{libf2c} as of 1998-06-18 -should fix a variety of problems, including -those involving some uses of the @samp{T} format -specifier, and perhaps some build (porting) problems -as well. -@end itemize - -@heading In 0.5.24 and @code{egcs} 1.1 (versus 0.5.23): -@itemize @bullet -@item -@code{g77} no longer produces incorrect code -and initial values -for @samp{EQUIVALENCE} and @samp{COMMON} -aggregates that, due to ``unnatural'' ordering of members -vis-a-vis their types, require initial padding. - -@item -@code{g77} no longer crashes when compiling code -containing specification statements such as -@samp{INTEGER(KIND=7) PTR}. - -@item -@code{g77} now treats @samp{%LOC(@var{expr})} and -@samp{LOC(@var{expr})} as ``ordinary'' expressions -when they are used as arguments in procedure calls. -This change applies only to global (filewide) analysis, -making it consistent with -how @code{g77} actually generates code -for these cases. - -Previously, @code{g77} treated these expressions -as denoting special ``pointer'' arguments -for the purposes of filewide analysis. - -@item -The @code{g77} driver now ensures that @samp{-lg2c} -is specified in the link phase prior to any -occurrence of @samp{-lm}. -This prevents accidentally linking to a routine -in the SunOS4 @samp{-lm} library -when the generated code wants to link to the one -in @code{libf2c} (@code{libg2c}). - -@item -@code{g77} emits more debugging information when -@samp{-g} is used. - -This new information allows, for example, -@kbd{which __g77_length_a} to be used in @code{gdb} -to determine the type of the phantom length argument -supplied with @samp{CHARACTER} variables. - -This information pertains to internally-generated -type, variable, and other information, -not to the longstanding deficiencies vis-a-vis -@samp{COMMON} and @samp{EQUIVALENCE}. - -@item -The F90 @samp{Date_and_Time} intrinsic now is -supported. - -@item -The F90 @samp{System_Clock} intrinsic allows -the optional arguments (except for the @samp{Count} -argument) to be omitted. - -@item -Upgrade to @code{libf2c} as of 1998-06-18. - -@item -Improve documentation and indexing. -@end itemize - -@c 1998-05-20: 0.5.23 released. -@heading In 0.5.23 (versus 0.5.22): -@itemize @bullet -@item -This release contains several regressions against -version 0.5.22 of @code{g77}, due to using the -``vanilla'' @code{gcc} back end instead of patching -it to fix a few bugs and improve performance in a -few cases. - -@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}, -available in plain-text format in @code{gcc/f/BUGS}, -for information on the known bugs in this version, -including the regressions. - -Features that have been dropped from this version -of @code{g77} due to their being implemented -via @code{g77}-specific patches to the @code{gcc} -back end in previous releases include: - -@itemize -- -@item -Support for @code{__restrict__} keyword, -the options @samp{-fargument-alias}, @samp{-fargument-noalias}, -and @samp{-fargument-noalias-global}, -and the corresponding alias-analysis code. - -(@code{egcs} has the alias-analysis -code, but not the @code{__restrict__} keyword. -@code{egcs} @code{g77} users benefit from the alias-analysis -code despite the lack of the @code{__restrict__} keyword, -which is a C-language construct.) - -@item -Support for the GNU compiler options -@samp{-fmove-all-movables}, -@samp{-freduce-all-givs}, -and @samp{-frerun-loop-opt}. - -(@code{egcs} supports these options. -@code{g77} users of @code{egcs} benefit from them even if -they are not explicitly specified, -because the defaults are optimized for @code{g77} users.) - -@item -Support for the @samp{-W} option warning about -integer division by zero. - -@item -The Intel x86-specific option @samp{-malign-double} -applying to stack-allocated data -as well as statically-allocate data. -@end itemize - -Note that the @file{gcc/f/gbe/} subdirectory has been removed -from this distribution as a result of @code{g77} no longer -including patches for the @code{gcc} back end. - -@item -Fix bugs in the @code{libU77} intrinsic @samp{HostNm} -that wrote one byte beyond the end of its @samp{CHARACTER} -argument, -and in the @code{libU77} intrinsics -@samp{GMTime} and @samp{LTime} -that overwrote their arguments. - -@item -Support @code{gcc} version 2.8, -and remove support for prior versions of @code{gcc}. - -@cindex -@w{}-driver option -@cindex g77 options, -@w{}-driver -@cindex options, -@w{}-driver -@item -Remove support for the @samp{--driver} option, -as @code{g77} now does all the driving, -just like @code{gcc}. - -@item -@code{CASE DEFAULT} no longer crashes @code{g77}. - -@item -Valid combinations of @code{EXTERNAL}, -passing that external as a dummy argument -without explicitly giving it a type, -and, in a subsequent program unit, -referencing that external as -an external function with a different type -no longer crash @code{g77}. - -@item -@code{g77} no longer installs the @file{f77} command -and @file{f77.1} man page -in the @file{/usr} or @file{/usr/local} heirarchy, -even if the @file{f77-install-ok} file exists -in the source or build directory. -See the installation documentation for more information. - -@item -@code{g77} no longer installs the @file{libf2c.a} library -and @file{f2c.h} include file -in the @file{/usr} or @file{/usr/local} heirarchy, -even if the @file{f2c-install-ok} or @file{f2c-exists-ok} files exist -in the source or build directory. -See the installation documentation for more information. - -@item -The @file{libf2c.a} library produced by @code{g77} has been -renamed to @file{libg2c.a}. -It is installed only in the @code{gcc} ``private'' -directory heirarchy, @file{gcc-lib}. -This allows system administrators and users to choose which -version of the @code{libf2c} library from @code{netlib} they -wish to use on a case-by-case basis. -See the installation documentation for more information. - -@item -The @file{f2c.h} include (header) file produced by @code{g77} -has been renamed to @file{g2c.h}. -It is installed only in the @code{gcc} ``private'' -directory heirarchy, @file{gcc-lib}. -This allows system administrators and users to choose which -version of the include file from @code{netlib} they -wish to use on a case-by-case basis. -See the installation documentation for more information. - -@item -The @code{g77} command now expects the run-time library -to be named @code{libg2c.a} instead of @code{libf2c.a}, -to ensure that a version other than the one built and -installed as part of the same @code{g77} version is picked up. - -@item -The @samp{-Wunused} option no longer issues a spurious -warning about the ``master'' procedure generated by -@code{g77} for procedures containing @code{ENTRY} statements. - -@item -@code{g77}'s version of @code{libf2c} separates out -the setting of global state -(such as command-line arguments and signal handling) -from @file{main.o} into distinct, new library -archive members. - -This should make it easier to write portable applications -that have their own (non-Fortran) @code{main()} routine -properly set up the @code{libf2c} environment, even -when @code{libf2c} (now @code{libg2c}) is a shared library. - -@item -During the configuration and build process, -@code{g77} creates subdirectories it needs only as it -needs them, thus avoiding unnecessary creation of, for example, -@file{stage1/f/runtime} when doing a non-bootstrap build. -Other cleaning up of the configuration and build process -has been performed as well. - -@item -@code{install-info} now used to update the directory of -Info documentation to contain an entry for @code{g77} -(during installation). - -@item -Some diagnostics have been changed from warnings to errors, -to prevent inadvertent use of the resulting, probably buggy, -programs. -These mostly include diagnostics about use of unsupported features -in the @code{OPEN}, @code{INQUIRE}, @code{READ}, and -@code{WRITE} statements, -and about truncations of various sorts of constants. - -@item -Improve documentation and indexing. - -@item -Upgrade to @code{libf2c} as of 1998-04-20. - -This should fix a variety of problems, including -those involving some uses of the @samp{T} format -specifier, and perhaps some build (porting) problems -as well. -@end itemize - -@c 1998-03-16: 0.5.22 released. -@heading In 0.5.22 (versus 0.5.21): -@itemize @bullet -@item -Fix code generation for iterative @code{DO} loops that -have one or more references to the iteration variable, -or to aliases of it, in their control expressions. -For example, @samp{DO 10 J=2,J} now is compiled correctly. - -@cindex DNRM2 -@cindex stack, 387 coprocessor -@cindex Intel x86 -@cindex -O2 -@item -Fix a code-generation bug that afflicted -Intel x86 targets when @samp{-O2} was specified -compiling, for example, an old version of -the @samp{DNRM2} routine. - -The x87 coprocessor stack was being -mismanaged in cases involving assigned @code{GOTO} -and @code{ASSIGN}. - -@item -Fix @code{DTime} intrinsic so as not to truncate -results to integer values (on some systems). - -@item -Fix @code{Signal} intrinsic so it offers portable -support for 64-bit systems (such as Digital Alphas -running GNU/Linux). - -@item -Fix run-time crash involving @code{NAMELIST} on 64-bit -machines such as Alphas. - -@item -Fix @code{g77} version of @code{libf2c} so it no longer -produces a spurious @samp{I/O recursion} diagnostic at run time -when an I/O operation (such as @samp{READ *,I}) is interrupted -in a manner that causes the program to be terminated -via the @samp{f_exit} routine (such as via @kbd{C-c}). - -@item -Fix @code{g77} crash triggered by @code{CASE} statement with -an omitted lower or upper bound. - -@item -Fix @code{g77} crash compiling references to @code{CPU_Time} -intrinsic. - -@item -Fix @code{g77} crash -(or apparently infinite run-time) -when compiling certain complicated expressions -involving @code{COMPLEX} arithmetic -(especially multiplication). - -@item -Fix @code{g77} crash on statements such as -@samp{PRINT *, (REAL(Z(I)),I=1,2)}, where -@samp{Z} is @code{DOUBLE COMPLEX}. - -@item -Fix a @code{g++} crash. - -@item -Support @samp{FORMAT(I<@var{expr}>)} when @var{expr} is a -compile-time constant @code{INTEGER} expression. - -@item -Fix @code{g77} @samp{-g} option so procedures that -use @samp{ENTRY} can be stepped through, line by line, -in @code{gdb}. - -@item -Fix a profiling-related bug in @code{gcc} back end for -Intel x86 architecture. - -@item -Allow any @code{REAL} argument to intrinsics -@code{Second} and @code{CPU_Time}. - -@item -Allow any numeric argument to intrinsics -@code{Int2} and @code{Int8}. - -@item -Use @code{tempnam}, if available, to open scratch files -(as in @samp{OPEN(STATUS='SCRATCH')}) -so that the @code{TMPDIR} environment variable, -if present, is used. - -@item -Rename the @code{gcc} keyword @code{restrict} to -@code{__restrict__}, to avoid rejecting valid, existing, -C programs. -Support for @code{restrict} is now more like support -for @code{complex}. - -@item -Fix @samp{-fpedantic} to not reject procedure invocations -such as @samp{I=J()} and @samp{CALL FOO()}. - -@item -Fix @samp{-fugly-comma} to affect invocations of -only external procedures. -Restore rejection of gratuitous trailing omitted -arguments to intrinsics, as in @samp{I=MAX(3,4,,)}. - -@item -Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and -@samp{-fbadu77-intrinsics-*} options. - -@item -Improve diagnostic messages from @code{libf2c} -so it is more likely that the printing of the -active format string is limited to the string, -with no trailing garbage being printed. - -(Unlike @code{f2c}, @code{g77} did not append -a null byte to its compiled form of every -format string specified via a @code{FORMAT} statement. -However, @code{f2c} would exhibit the problem -anyway for a statement like @samp{PRINT '(I)garbage', 1} -by printing @samp{(I)garbage} as the format string.) - -@item -Improve compilation of @code{FORMAT} expressions so that -a null byte is appended to the last operand if it -is a constant. -This provides a cleaner run-time diagnostic as provided -by @code{libf2c} for statements like @samp{PRINT '(I1', 42}. - -@item -Fix various crashes involving code with diagnosed errors. - -@item -Fix cross-compilation bug when configuring @code{libf2c}. - -@item -Improve diagnostics. - -@item -Improve documentation and indexing. - -@item -Upgrade to @code{libf2c} as of 1997-09-23. -This fixes a formatted-I/O bug that afflicted -64-bit systems with 32-bit integers -(such as Digital Alpha running GNU/Linux). -@end itemize - -@c 1998-03-15: egcs-1.0.2 released. -@heading In @code{egcs} 1.0.2 (versus @code{egcs} 1.0.1): -@itemize @bullet -@item -Fix @code{g77} crash triggered by @code{CASE} statement with -an omitted lower or upper bound. - -@item -Fix @code{g77} crash on statements such as -@samp{PRINT *, (REAL(Z(I)),I=1,2)}, where -@samp{Z} is @code{DOUBLE COMPLEX}. - -@cindex ELF support -@cindex support, ELF -@cindex -fPIC option -@cindex options, -fPIC -@item -Fix @samp{-fPIC} (such as compiling for ELF targets) -on the Intel x86 architecture target -so invalid assembler code is no longer produced. - -@item -Fix @samp{-fpedantic} to not reject procedure invocations -such as @samp{I=J()} and @samp{CALL FOO()}. - -@item -Fix @samp{-fugly-comma} to affect invocations of -only external procedures. -Restore rejection of gratuitous trailing omitted -arguments to intrinsics, as in @samp{I=MAX(3,4,,)}. - -@item -Fix compiler so it accepts @samp{-fgnu-intrinsics-*} and -@samp{-fbadu77-intrinsics-*} options. -@end itemize - -@c 1998-01-02: egcs-1.0.1 released. -@heading In @code{egcs} 1.0.1 (versus @code{egcs} 1.0): -@itemize @bullet -@item -Fix run-time crash involving @code{NAMELIST} on 64-bit -machines such as Alphas. -@end itemize - -@c 1997-12-03: egcs-1.0 released. -@heading In @code{egcs} 1.0 (versus 0.5.21): -@itemize @bullet -@item -Version 1.0 of @code{egcs} -contains several regressions against -version 0.5.21 of @code{g77}, -due to using the -``vanilla'' @code{gcc} back end instead of patching -it to fix a few bugs and improve performance in a -few cases. - -@xref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}, -available in plain-text format in @code{gcc/f/BUGS}, -for information on the known bugs in this version, -including the regressions. - -Features that have been dropped from this version -of @code{g77} due to their being implemented -via @code{g77}-specific patches to the @code{gcc} -back end in previous releases include: - -@itemize -- -@item -Support for the C-language @code{restrict} keyword. - -@item -Support for the @samp{-W} option warning about -integer division by zero. - -@item -The Intel x86-specific option @samp{-malign-double} -applying to stack-allocated data -as well as statically-allocate data. -@end itemize - -Note that the @file{gcc/f/gbe/} subdirectory has been removed -from this distribution as a result of @code{g77} -being fully integrated with -the @code{egcs} variant of the @code{gcc} back end. - -@item -Fix code generation for iterative @code{DO} loops that -have one or more references to the iteration variable, -or to aliases of it, in their control expressions. -For example, @samp{DO 10 J=2,J} now is compiled correctly. - -@item -Fix @code{DTime} intrinsic so as not to truncate -results to integer values (on some systems). - -@item -Remove support for non-@code{egcs} versions of @code{gcc}. - -@cindex -@w{}-driver option -@cindex g77 options, -@w{}-driver -@cindex options, -@w{}-driver -@item -Remove support for the @samp{--driver} option, -as @code{g77} now does all the driving, -just like @code{gcc}. - -@item -Allow any numeric argument to intrinsics -@code{Int2} and @code{Int8}. - -@item -Improve diagnostic messages from @code{libf2c} -so it is more likely that the printing of the -active format string is limited to the string, -with no trailing garbage being printed. - -(Unlike @code{f2c}, @code{g77} did not append -a null byte to its compiled form of every -format string specified via a @code{FORMAT} statement. -However, @code{f2c} would exhibit the problem -anyway for a statement like @samp{PRINT '(I)garbage', 1} -by printing @samp{(I)garbage} as the format string.) - -@item -Upgrade to @code{libf2c} as of 1997-09-23. -This fixes a formatted-I/O bug that afflicted -64-bit systems with 32-bit integers -(such as Digital Alpha running GNU/Linux). -@end itemize - -@c 1997-09-09: 0.5.21 released. -@heading In 0.5.21: -@itemize @bullet -@item -Fix a code-generation bug introduced by 0.5.20 -caused by loop unrolling (by specifying -@samp{-funroll-loops} or similar). -This bug afflicted all code compiled by -version 2.7.2.2.f.2 of @code{gcc} (C, C++, -Fortran, and so on). - -@item -Fix a code-generation bug manifested when -combining local @code{EQUIVALENCE} with a -@code{DATA} statement that follows -the first executable statement (or is -treated as an executable-context statement -as a result of using the @samp{-fpedantic} -option). - -@item -Fix a compiler crash that occured when an -integer division by a constant zero is detected. -Instead, when the @samp{-W} option is specified, -the @code{gcc} back end issues a warning about such a case. -This bug afflicted all code compiled by -version 2.7.2.2.f.2 of @code{gcc} (C, C++, -Fortran, and so on). - -@item -Fix a compiler crash that occurred in some cases -of procedure inlining. -(Such cases became more frequent in 0.5.20.) - -@item -Fix a compiler crash resulting from using @code{DATA} -or similar to initialize a @code{COMPLEX} variable or -array to zero. - -@item -Fix compiler crashes involving use of @code{AND}, @code{OR}, -or @code{XOR} intrinsics. - -@item -Fix compiler bug triggered when using a @code{COMMON} -or @code{EQUIVALENCE} variable -as the target of an @code{ASSIGN} -or assigned-@code{GOTO} statement. - -@item -Fix compiler crashes due to using the name of a some -non-standard intrinsics (such as @samp{FTELL} or -@samp{FPUTC}) as such and as the name of a procedure -or common block. -Such dual use of a name in a program is allowed by -the standard. - -@c @code{g77}'s version of @code{libf2c} has been modified -@c so that the external names of library's procedures do not -@c conflict with names used for Fortran procedures compiled -@c by @code{g77}. -@c An additional layer of jacket procedures has been added -@c to @code{libf2c} to map the old names to the new names, -@c for automatic use by programs that interface to the -@c library procedures via the external-procedure mechanism. -@c -@c For example, the intrinsic @code{FPUTC} previously was -@c implemented by @code{g77} as a call to the @code{libf2c} -@c routine @samp{fputc_}. -@c This would conflict with a Fortran procedure named @code{FPUTC} -@c (using default compiler options), and this conflict -@c would cause a crash under certain circumstances. -@c -@c Now, the intrinsic @code{FPUTC} calls @samp{G77_fputc_0}, -@c which does not conflict with the @samp{fputc_} external -@c that implements a Fortran procedure named @code{FPUTC}. -@c -@c Programs that refer to @code{FPUTC} as an external procedure -@c without supplying their own implementation will link to -@c the new @code{libf2c} routine @samp{fputc_}, which is -@c simply a jacket routine that calls @samp{G77_fputc_0}. - -@item -Place automatic arrays on the stack, even if -@code{SAVE} or the @samp{-fno-automatic} option -is in effect. -This avoids a compiler crash in some cases. - -@item -The @samp{-malign-double} option now reliably aligns -@code{DOUBLE PRECISION} optimally on Pentium and -Pentium Pro architectures (586 and 686 in @code{gcc}). - -@item -New option @samp{-Wno-globals} disables warnings -about ``suspicious'' use of a name both as a global -name and as the implicit name of an intrinsic, and -warnings about disagreements over the number or natures of -arguments passed to global procedures, or the -natures of the procedures themselves. - -The default is to issue such warnings, which are -new as of this version of @code{g77}. - -@item -New option @samp{-fno-globals} disables diagnostics -about potentially fatal disagreements -analysis problems, such as disagreements over the -number or natures of arguments passed to global -procedures, or the natures of those procedures themselves. - -The default is to issue such diagnostics and flag -the compilation as unsuccessful. -With this option, the diagnostics are issued as -warnings, or, if @samp{-Wno-globals} is specified, -are not issued at all. - -This option also disables inlining of global procedures, -to avoid compiler crashes resulting from coding errors -that these diagnostics normally would identify. - -@item -Diagnose cases where a reference to a procedure -disagrees with the type of that procedure, or -where disagreements about the number or nature -of arguments exist. -This avoids a compiler crash. - -@item -Fix parsing bug whereby @code{g77} rejected a -second initialization specification immediately -following the first's closing @samp{/} without -an intervening comma in a @code{DATA} statement, -and the second specification was an implied-DO list. - -@item -Improve performance of the @code{gcc} back end so -certain complicated expressions involving @code{COMPLEX} -arithmetic (especially multiplication) don't appear to -take forever to compile. - -@item -Fix a couple of profiling-related bugs in @code{gcc} -back end. - -@item -Integrate GNU Ada's (GNAT's) changes to the back end, -which consist almost entirely of bug fixes. -These fixes are circa version 3.10p of GNAT. - -@item -Include some other @code{gcc} fixes that seem useful in -@code{g77}'s version of @code{gcc}. -(See @file{gcc/ChangeLog} for details---compare it -to that file in the vanilla @code{gcc-2.7.2.3.tar.gz} -distribution.) - -@item -Fix @code{libU77} routines that accept file and other names -to strip trailing blanks from them, for consistency -with other implementations. -Blanks may be forcibly appended to such names by -appending a single null character (@samp{CHAR(0)}) -to the significant trailing blanks. - -@item -Fix @code{CHMOD} intrinsic to work with file names -that have embedded blanks, commas, and so on. - -@item -Fix @code{SIGNAL} intrinsic so it accepts an -optional third @samp{Status} argument. - -@item -Fix @code{IDATE()} intrinsic subroutine (VXT form) -so it accepts arguments in the correct order. -Documentation fixed accordingly, and for -@code{GMTIME()} and @code{LTIME()} as well. - -@item -Make many changes to @code{libU77} intrinsics to -support existing code more directly. - -Such changes include allowing both subroutine and -function forms of many routines, changing @code{MCLOCK()} -and @code{TIME()} to return @code{INTEGER(KIND=1)} values, -introducing @code{MCLOCK8()} and @code{TIME8()} to -return @code{INTEGER(KIND=2)} values, -and placing functions that are intended to perform -side effects in a new intrinsic group, @code{badu77}. - -@item -Improve @code{libU77} so it is more portable. - -@item -Add options @samp{-fbadu77-intrinsics-delete}, -@samp{-fbadu77-intrinsics-hide}, and so on. - -@item -Fix crashes involving diagnosed or invalid code. - -@item -@code{g77} and @code{gcc} now do a somewhat better -job detecting and diagnosing arrays that are too -large to handle before these cause diagnostics -during the assembler or linker phase, a compiler -crash, or generation of incorrect code. - -@item -Make some fixes to alias analysis code. - -@item -Add support for @code{restrict} keyword in @code{gcc} -front end. - -@item -Support @code{gcc} version 2.7.2.3 -(modified by @code{g77} into version 2.7.2.3.f.1), -and remove -support for prior versions of @code{gcc}. - -@item -Incorporate GNAT's patches to the @code{gcc} back -end into @code{g77}'s, so GNAT users do not need -to apply GNAT's patches to build both GNAT and @code{g77} -from the same source tree. - -@item -Modify @code{make} rules and related code so that -generation of Info documentation doesn't require -compilation using @code{gcc}. -Now, any ANSI C compiler should be adequate to -produce the @code{g77} documentation (in particular, -the tables of intrinsics) from scratch. - -@item -Add @code{INT2} and @code{INT8} intrinsics. - -@item -Add @code{CPU_TIME} intrinsic. - -@item -Add @code{ALARM} intrinsic. - -@item -@code{CTIME} intrinsic now accepts any @code{INTEGER} -argument, not just @code{INTEGER(KIND=2)}. - -@item -Warn when explicit type declaration disagrees with -the type of an intrinsic invocation. - -@item -Support @samp{*f771} entry in @code{gcc} @file{specs} file. - -@item -Fix typo in @code{make} rule @samp{g77-cross}, used only for -cross-compiling. - -@item -Fix @code{libf2c} build procedure to re-archive library -if previous attempt to archive was interrupted. - -@item -Change @code{gcc} to unroll loops only during the last -invocation (of as many as two invocations) of loop -optimization. - -@item -Improve handling of @samp{-fno-f2c} so that code that -attempts to pass an intrinsic as an actual argument, -such as @samp{CALL FOO(ABS)}, is rejected due to the fact -that the run-time-library routine is, effectively, -compiled with @samp{-ff2c} in effect. - -@item -Fix @code{g77} driver to recognize @samp{-fsyntax-only} -as an option that inhibits linking, just like @samp{-c} or -@samp{-S}, and to recognize and properly handle the -@samp{-nostdlib}, @samp{-M}, @samp{-MM}, @samp{-nodefaultlibs}, -and @samp{-Xlinker} options. - -@item -Upgrade to @code{libf2c} as of 1997-08-16. - -@item -Modify @code{libf2c} to consistently and clearly diagnose -recursive I/O (at run time). - -@item -@code{g77} driver now prints version information (such as produced -by @kbd{g77 -v}) to @code{stderr} instead of @code{stdout}. - -@item -The @samp{.r} suffix now designates a Ratfor source file, -to be preprocessed via the @code{ratfor} command, available -separately. - -@item -Fix some aspects of how @code{gcc} determines what kind of -system is being configured and what kinds are supported. -For example, GNU Linux/Alpha ELF systems now are directly -supported. - -@item -Improve diagnostics. - -@item -Improve documentation and indexing. - -@item -Include all pertinent files for @code{libf2c} that come -from @code{netlib.bell-labs.com}; give any such files -that aren't quite accurate in @code{g77}'s version of -@code{libf2c} the suffix @samp{.netlib}. - -@item -Reserve @code{INTEGER(KIND=0)} for future use. -@end itemize - -@c 1997-02-28: 0.5.20 released. -@heading In 0.5.20: -@itemize @bullet -@item -The @samp{-fno-typeless-boz} option is now the default. - -This option specifies that non-decimal-radix -constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @code{INTEGER} constants. -Specify @samp{-ftypeless-boz} to cause such -constants to be interpreted as typeless. - -(Version 0.5.19 introduced @samp{-fno-typeless-boz} and -its inverse.) - -@item -Options @samp{-ff90-intrinsics-enable} and -@samp{-fvxt-intrinsics-enable} now are the -defaults. - -Some programs might use names that clash with -intrinsic names defined (and now enabled) by these -options or by the new @code{libU77} intrinsics. -Users of such programs might need to compile them -differently (using, for example, @samp{-ff90-intrinsics-disable}) -or, better yet, insert appropriate @code{EXTERNAL} -statements specifying that these names are not intended -to be names of intrinsics. - -@item -The @samp{ALWAYS_FLUSH} macro is no longer defined when -building @code{libf2c}, which should result in improved -I/O performance, especially over NFS. - -@emph{Note:} If you have code that depends on the behavior -of @code{libf2c} when built with @samp{ALWAYS_FLUSH} defined, -you will have to modify @code{libf2c} accordingly before -building it from this and future versions of @code{g77}. - -@item -Dave Love's implementation of @code{libU77} has been -added to the version of @code{libf2c} distributed with -and built as part of @code{g77}. -@code{g77} now knows about the routines in this library -as intrinsics. - -@item -New option @samp{-fvxt} specifies that the -source file is written in VXT Fortran, instead of GNU Fortran. - -@item -The @samp{-fvxt-not-f90} option has been deleted, -along with its inverse, @samp{-ff90-not-vxt}. - -If you used one of these deleted options, you should -re-read the pertinent documentation to determine which -options, if any, are appropriate for compiling your -code with this version of @code{g77}. - -@item -The @samp{-fugly} option now issues a warning, as it -likely will be removed in a future version. - -(Enabling all the @samp{-fugly-*} options is unlikely -to be feasible, or sensible, in the future, -so users should learn to specify only those -@samp{-fugly-*} options they really need for a -particular source file.) - -@item -The @samp{-fugly-assumed} option, introduced in -version 0.5.19, has been changed to -better accommodate old and new code. - -@item -Make a number of fixes to the @code{g77} front end and -the @code{gcc} back end to better support Alpha (AXP) -machines. -This includes providing at least one bug-fix to the -@code{gcc} back end for Alphas. - -@item -Related to supporting Alpha (AXP) machines, the @code{LOC()} -intrinsic and @code{%LOC()} construct now return -values of integer type that is the same width (holds -the same number of bits) as the pointer type on the -machine. - -On most machines, this won't make a difference, whereas -on Alphas, the type these constructs return is -@code{INTEGER*8} instead of the more common @code{INTEGER*4}. - -@item -Emulate @code{COMPLEX} arithmetic in the @code{g77} front -end, to avoid bugs in @code{complex} support in the -@code{gcc} back end. -New option @samp{-fno-emulate-complex} -causes @code{g77} to revert the 0.5.19 behavior. - -@item -Fix bug whereby @samp{REAL A(1)}, for example, caused -a compiler crash if @samp{-fugly-assumed} was in effect -and @var{A} was a local (automatic) array. -That case is no longer affected by the new -handling of @samp{-fugly-assumed}. - -@item -Fix @code{g77} command driver so that @samp{g77 -o foo.f} -no longer deletes @file{foo.f} before issuing other -diagnostics, and so the @samp{-x} option is properly -handled. - -@item -Enable inlining of subroutines and functions by the @code{gcc} -back end. -This works as it does for @code{gcc} itself---program units -may be inlined for invocations that follow them in the same -program unit, as long as the appropriate compile-time -options are specified. - -@item -Dummy arguments are no longer assumed to potentially alias -(overlap) -other dummy arguments or @code{COMMON} areas when any of -these are defined (assigned to) by Fortran code. - -This can result in faster and/or smaller programs when -compiling with optimization enabled, though on some -systems this effect is observed only when @samp{-fforce-addr} -also is specified. - -New options @samp{-falias-check}, @samp{-fargument-alias}, -@samp{-fargument-noalias}, -and @samp{-fno-argument-noalias-global} control the -way @code{g77} handles potential aliasing. - -@item -The @code{CONJG()} and @code{DCONJG()} intrinsics now -are compiled in-line. - -@item -The bug-fix for 0.5.19.1 has been re-done. -The @code{g77} compiler has been changed back to -assume @code{libf2c} has no aliasing problems in -its implementations of the @code{COMPLEX} (and -@code{DOUBLE COMPLEX}) intrinsics. -The @code{libf2c} has been changed to have no such -problems. - -As a result, 0.5.20 is expected to offer improved performance -over 0.5.19.1, perhaps as good as 0.5.19 in most -or all cases, due to this change alone. - -@emph{Note:} This change requires version 0.5.20 of -@code{libf2c}, at least, when linking code produced -by any versions of @code{g77} other than 0.5.19.1. -Use @samp{g77 -v} to determine the version numbers -of the @code{libF77}, @code{libI77}, and @code{libU77} -components of the @code{libf2c} library. -(If these version numbers are not printed---in -particular, if the linker complains about unresolved -references to names like @samp{g77__fvers__}---that -strongly suggests your installation has an obsolete -version of @code{libf2c}.) - -@item -New option @samp{-fugly-assign} specifies that the -same memory locations are to be used to hold the -values assigned by both statements @samp{I = 3} and -@samp{ASSIGN 10 TO I}, for example. -(Normally, @code{g77} uses a separate memory location -to hold assigned statement labels.) - -@item -@code{FORMAT} and @code{ENTRY} statements now are allowed to -precede @code{IMPLICIT NONE} statements. - -@item -Produce diagnostic for unsupported @code{SELECT CASE} on -@code{CHARACTER} type, instead of crashing, at compile time. - -@item -Fix crashes involving diagnosed or invalid code. - -@item -Change approach to building @code{libf2c} archive -(@file{libf2c.a}) so that members are added to it -only when truly necessary, so the user that installs -an already-built @code{g77} doesn't need to have write -access to the build tree (whereas the user doing the -build might not have access to install new software -on the system). - -@item -Support @code{gcc} version 2.7.2.2 -(modified by @code{g77} into version 2.7.2.2.f.2), -and remove -support for prior versions of @code{gcc}. - -@item -Upgrade to @code{libf2c} as of 1997-02-08, and -fix up some of the build procedures. - -@item -Improve general build procedures for @code{g77}, -fixing minor bugs (such as deletion of any file -named @file{f771} in the parent directory of @code{gcc/}). - -@item -Enable full support of @code{INTEGER*8} available in -@code{libf2c} and @file{f2c.h} so that @code{f2c} users -may make full use of its features via the @code{g77} -version of @file{f2c.h} and the @code{INTEGER*8} -support routines in the @code{g77} version of @code{libf2c}. - -@item -Improve @code{g77} driver and @code{libf2c} so that @samp{g77 -v} -yields version information on the library. - -@item -The @code{SNGL} and @code{FLOAT} intrinsics now are -specific intrinsics, instead of synonyms for the -generic intrinsic @code{REAL}. - -@item -New intrinsics have been added. -These are @code{REALPART}, @code{IMAGPART}, -@code{COMPLEX}, -@code{LONG}, and @code{SHORT}. - -@item -A new group of intrinsics, @samp{gnu}, has been added -to contain the new @code{REALPART}, @code{IMAGPART}, -and @code{COMPLEX} intrinsics. -An old group, @samp{dcp}, has been removed. - -@item -Complain about industry-wide ambiguous references -@samp{REAL(@var{expr})} and @samp{AIMAG(@var{expr})}, -where @var{expr} is @code{DOUBLE COMPLEX} (or any -complex type other than @code{COMPLEX}), unless -@samp{-ff90} option specifies Fortran 90 interpretation -or new @samp{-fugly-complex} option, in conjunction with -@samp{-fnot-f90}, specifies @code{f2c} interpretation. - -@item -Make improvements to diagnostics. - -@item -Speed up compiler a bit. - -@item -Improvements to documentation and indexing, including -a new chapter containing information on one, later -more, diagnostics that users are directed to pull -up automatically via a message in the diagnostic itself. - -(Hence the menu item @samp{M} for the node -@samp{Diagnostics} in the top-level menu of -the Info documentation.) -@end itemize - -@c 1997-02-01: 0.5.19.1 released. -@heading In 0.5.19.1: -@itemize @bullet -@item -Code-generation bugs afflicting operations on complex -data have been fixed. - -These bugs occurred when assigning the result of an -operation to a complex variable (or array element) -that also served as an input to that operation. - -The operations affected by this bug were: @samp{CONJG()}, -@samp{DCONJG()}, @samp{CCOS()}, @samp{CDCOS()}, -@samp{CLOG()}, @samp{CDLOG()}, @samp{CSIN()}, @samp{CDSIN()}, -@samp{CSQRT()}, @samp{CDSQRT()}, complex division, and -raising a @code{DOUBLE COMPLEX} operand to an @code{INTEGER} -power. -(The related generic and @samp{Z}-prefixed intrinsics, -such as @samp{ZSIN()}, also were affected.) - -For example, @samp{C = CSQRT(C)}, @samp{Z = Z/C}, and @samp{Z = Z**I} -(where @samp{C} is @code{COMPLEX} and @samp{Z} is -@code{DOUBLE COMPLEX}) have been fixed. -@end itemize - -@c 1996-12-07: 0.5.19 released. -@heading In 0.5.19: -@itemize @bullet -@item -Fix @code{FORMAT} statement parsing so negative values for -specifiers such as @samp{P} (e.g. @samp{FORMAT(-1PF8.1)}) -are correctly processed as negative. - -@item -Fix @code{SIGNAL} intrinsic so it once again accepts a -procedure as its second argument. - -@item -A temporary kludge option provides bare-bones information on -@code{COMMON} and @code{EQUIVALENCE} members at debug time. - -@item -New @samp{-fonetrip} option specifies FORTRAN-66-style -one-trip @code{DO} loops. - -@item -New @samp{-fno-silent} option causes names of program units -to be printed as they are compiled, in a fashion similar to -UNIX @code{f77} and @code{f2c}. - -@item -New @samp{-fugly-assumed} option specifies that arrays -dimensioned via @samp{DIMENSION X(1)}, for example, are to be -treated as assumed-size. - -@item -New @samp{-fno-typeless-boz} option specifies that non-decimal-radix -constants using the prefixed-radix form (such as @samp{Z'1234'}) -are to be interpreted as @code{INTEGER} constants. - -@item -New @samp{-ff66} option is a ``shorthand'' option that specifies -behaviors considered appropriate for FORTRAN 66 programs. - -@item -New @samp{-ff77} option is a ``shorthand'' option that specifies -behaviors considered appropriate for UNIX @code{f77} programs. - -@item -New @samp{-fugly-comma} and @samp{-fugly-logint} options provided -to perform some of what @samp{-fugly} used to do. -@samp{-fugly} and @samp{-fno-ugly} are now ``shorthand'' options, -in that they do nothing more than enable (or disable) other -@samp{-fugly-*} options. - -@item -Fix parsing of assignment statements involving targets that -are substrings of elements of @code{CHARACTER} arrays having -names such as @samp{READ}, @samp{WRITE}, @samp{GOTO}, and -@samp{REALFUNCTIONFOO}. - -@item -Fix crashes involving diagnosed code. - -@item -Fix handling of local @code{EQUIVALENCE} areas so certain cases -of valid Fortran programs are not misdiagnosed as improperly -extending the area backwards. - -@item -Support @code{gcc} version 2.7.2.1. - -@item -Upgrade to @code{libf2c} as of 1996-09-26, and -fix up some of the build procedures. - -@item -Change code generation for list-directed I/O so it allows -for new versions of @code{libf2c} that might return non-zero -status codes for some operations previously assumed to always -return zero. - -This change not only affects how @code{IOSTAT=} variables -are set by list-directed I/O, it also affects whether -@code{END=} and @code{ERR=} labels are reached by these -operations. - -@item -Add intrinsic support for new @code{FTELL} and @code{FSEEK} -procedures in @code{libf2c}. - -@item -Modify @code{fseek_()} in @code{libf2c} to be more portable -(though, in practice, there might be no systems where this -matters) and to catch invalid @samp{whence} arguments. - -@item -Some useless warnings from the @samp{-Wunused} option have -been eliminated. - -@item -Fix a problem building the @file{f771} executable -on AIX systems by linking with the @samp{-bbigtoc} option. - -@item -Abort configuration if @code{gcc} has not been patched -using the patch file provided in the @samp{gcc/f/gbe/} -subdirectory. - -@item -Add options @samp{--help} and @samp{--version} to the -@code{g77} command, to conform to GNU coding guidelines. -Also add printing of @code{g77} version number when -the @samp{--verbose} (@samp{-v}) option is used. - -@item -Change internally generated name for local @code{EQUIVALENCE} -areas to one based on the alphabetically sorted first name -in the list of names for entities placed at the beginning -of the areas. - -@item -Improvements to documentation and indexing. -@end itemize - -@c 1996-04-01: 0.5.18 released. -@heading In 0.5.18: -@itemize @bullet -@item -Add some rudimentary support for @code{INTEGER*1}, -@code{INTEGER*2}, @code{INTEGER*8}, -and their @code{LOGICAL} equivalents. -(This support works on most, maybe all, @code{gcc} targets.) - -Thanks to Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) -for providing the patch for this! - -Among the missing elements from the support for these -features are full intrinsic support and constants. - -@item -Add some rudimentary support for the @code{BYTE} and -@code{WORD} type-declaration statements. -@code{BYTE} corresponds to @code{INTEGER*1}, -while @code{WORD} corresponds to @code{INTEGER*2}. - -Thanks to Scott Snyder (@email{snyder@@d0sgif.fnal.gov}) -for providing the patch for this! - -@item -The compiler code handling intrinsics has been largely -rewritten to accommodate the new types. -No new intrinsics or arguments for existing -intrinsics have been added, so there is, at this -point, no intrinsic to convert to @code{INTEGER*8}, -for example. - -@item -Support automatic arrays in procedures. - -@item -Reduce space/time requirements for handling large -@emph{sparsely} initialized aggregate arrays. -This improvement applies to only a subset of -the general problem to be addressed in 0.6. - -@item -Treat initial values of zero as if they weren't -specified (in DATA and type-declaration statements). -The initial values will be set to zero anyway, but the amount -of compile time processing them will be reduced, -in some cases significantly (though, again, this -is only a subset of the general problem to be -addressed in 0.6). - -A new option, @samp{-fzeros}, is introduced to -enable the traditional treatment of zeros as any -other value. - -@item -With @samp{-ff90} in force, @code{g77} incorrectly -interpreted @samp{REAL(Z)} as returning a @code{REAL} -result, instead of as a @code{DOUBLE PRECISION} -result. -(Here, @samp{Z} is @code{DOUBLE COMPLEX}.) - -With @samp{-fno-f90} in force, the interpretation remains -unchanged, since this appears to be how at least some -F77 code using the @code{DOUBLE COMPLEX} extension expected -it to work. - -Essentially, @samp{REAL(Z)} in F90 is the same as -@samp{DBLE(Z)}, while in extended F77, it appears to -be the same as @samp{REAL(REAL(Z))}. - -@item -An expression involving exponentiation, where both operands -were type @code{INTEGER} and the right-hand operand -was negative, was erroneously evaluated. - -@item -Fix bugs involving @code{DATA} implied-@code{DO} constructs -(these involved an errant diagnostic and a crash, both on good -code, one involving subsequent statement-function definition). - -@item -Close @code{INCLUDE} files after processing them, so compiling source -files with lots of @code{INCLUDE} statements does not result in -being unable to open @code{INCLUDE} files after all the available -file descriptors are used up. - -@item -Speed up compiling, especially of larger programs, and perhaps -slightly reduce memory utilization while compiling (this is -@emph{not} the improvement planned for 0.6 involving large aggregate -areas)---these improvements result from simply turning -off some low-level code to do self-checking that hasn't been -triggered in a long time. - -@item -Introduce three new options that -implement optimizations in the @code{gcc} back end (GBE). -These options are @samp{-fmove-all-movables}, @samp{-freduce-all-givs}, -and @samp{-frerun-loop-opt}, which are enabled, by default, -for Fortran compilations. -These optimizations are intended to help toon Fortran programs. - -@item -Patch the GBE to do a better job optimizing certain -kinds of references to array elements. - -@item -Due to patches to the GBE, the version number of @code{gcc} -also is patched to make it easier to manage installations, -especially useful if it turns out a @code{g77} change to the -GBE has a bug. - -The @code{g77}-modified version number is the @code{gcc} -version number with the string @samp{.f.@var{n}} appended, -where @samp{f} identifies the version as enhanced for -Fortran, and @var{n} is @samp{1} for the first Fortran -patch for that version of @code{gcc}, @samp{2} for the -second, and so on. - -So, this introduces version 2.7.2.f.1 of @code{gcc}. - -@item -Make several improvements and fixes to diagnostics, including -the removal of two that were inappropriate or inadequate. - -@item -Warning about two successive arithmetic operators, produced -by @samp{-Wsurprising}, now produced @emph{only} when both -operators are, indeed, arithmetic (not relational/boolean). - -@item -@samp{-Wsurprising} now warns about the remaining cases -of using non-integral variables for implied-@code{DO} -loops, instead of these being rejected unless @samp{-fpedantic} -or @samp{-fugly} specified. - -@item -Allow @code{SAVE} of a local variable or array, even after -it has been given an initial value via @code{DATA}, for example. - -@item -Introduce an Info version of @code{g77} documentation, which -supercedes @file{gcc/f/CREDITS}, @file{gcc/f/DOC}, and -@file{gcc/f/PROJECTS}. -These files will be removed in a future release. -The files @file{gcc/f/BUGS}, @file{gcc/f/INSTALL}, and -@file{gcc/f/NEWS} now are automatically built from -the texinfo source when distributions are made. - -This effort was inspired by a first pass at translating -@file{g77-0.5.16/f/DOC} that was contributed to Craig by -David Ronis (@email{ronis@@onsager.chem.mcgill.ca}). - -@item -New @samp{-fno-second-underscore} option to specify -that, when @samp{-funderscoring} is in effect, a second -underscore is not to be appended to Fortran names already -containing an underscore. - -@item -Change the way iterative @code{DO} loops work to follow -the F90 standard. -In particular, calculation of the iteration count is -still done by converting the start, end, and increment -parameters to the type of the @code{DO} variable, but -the result of the calculation is always converted to -the default @code{INTEGER} type. - -(This should have no effect on existing code compiled -by @code{g77}, but code written to assume that use -of a @emph{wider} type for the @code{DO} variable -will result in an iteration count being fully calculated -using that wider type (wider -than default @code{INTEGER}) must be rewritten.) - -@item -Support @code{gcc} version 2.7.2. - -@item -Upgrade to @code{libf2c} as of 1996-03-23, and -fix up some of the build procedures. - -Note that the email addresses related to @code{f2c} -have changed---the distribution site now is -named @code{netlib.bell-labs.com}, and the -maintainer's new address is @email{dmg@@bell-labs.com}. -@end itemize - -@c 1995-11-18: 0.5.17 released. -@heading In 0.5.17: -@itemize @bullet -@item -@strong{Fix serious bug} in @samp{g77 -v} command that can cause removal of a -system's @file{/dev/null} special file if run by user @samp{root}. - -@strong{All users} of version 0.5.16 should ensure that -they have not removed @file{/dev/null} or replaced it with an ordinary -file (e.g. by comparing the output of @samp{ls -l /dev/null} with -@samp{ls -l /dev/zero}. -If the output isn't basically the -same, contact your system -administrator about restoring @file{/dev/null} to its proper status). - -This bug is particularly insidious because removing @file{/dev/null} as -a special file can go undetected for quite a while, aside from -various applications and programs exhibiting sudden, strange -behaviors. - -I sincerely apologize for not realizing the -implications of the fact that when @samp{g77 -v} runs the @code{ld} command -with @samp{-o /dev/null} that @code{ld} tries to @emph{remove} the executable -it is supposed to build (especially if it reports unresolved -references, which it should in this case)! - -@item -Fix crash on @samp{CHARACTER*(*) FOO} in a main or block data program unit. - -@item -Fix crash that can occur when diagnostics given outside of any -program unit (such as when input file contains @samp{@@foo}). - -@item -Fix crashes, infinite loops (hangs), and such involving diagnosed code. - -@item -Fix @code{ASSIGN}'ed variables so they can be @code{SAVE}'d or dummy arguments, -and issue clearer error message in cases where target of @code{ASSIGN} -or @code{ASSIGN}ed @code{GOTO}/@code{FORMAT} is too small (which should -never happen). - -@item -Make @code{libf2c} build procedures work on more systems again by -eliminating unnecessary invocations of @samp{ld -r -x} and @samp{mv}. - -@item -Fix omission of @samp{-funix-intrinsics-@dots{}} options in list of permitted -options to compiler. - -@item -Fix failure to always diagnose missing type declaration for -@code{IMPLICIT NONE}. - -@item -Fix compile-time performance problem (which could sometimes -crash the compiler, cause a hang, or whatever, due to a bug -in the back end) involving exponentiation with a large @code{INTEGER} -constant for the right-hand operator (e.g. @samp{I**32767}). - -@item -Fix build procedures so cross-compiling @code{g77} (the @code{fini} -utility in particular) is properly built using the host compiler. - -@item -Add new @samp{-Wsurprising} option to warn about constructs that are -interpreted by the Fortran standard (and @code{g77}) in ways that -are surprising to many programmers. - -@item -Add @code{ERF()} and @code{ERFC()} as generic intrinsics mapping to existing -@code{ERF}/@code{DERF} and @code{ERFC}/@code{DERFC} specific intrinsics. - -@emph{Note:} You should -specify @samp{INTRINSIC ERF,ERFC} in any code where you might use -these as generic intrinsics, to improve likelihood of diagnostics -(instead of subtle run-time bugs) when using a compiler that -doesn't support these as intrinsics (e.g. @code{f2c}). - -@item -Remove from @samp{-fno-pedantic} the diagnostic about @code{DO} -with non-@code{INTEGER} index variable; issue that under -@samp{-Wsurprising} instead. - -@item -Clarify some diagnostics that say things like ``ignored'' when that's -misleading. - -@item -Clarify diagnostic on use of @code{.EQ.}/@code{.NE.} on @code{LOGICAL} -operands. - -@item -Minor improvements to code generation for various operations on -@code{LOGICAL} operands. - -@item -Minor improvement to code generation for some @code{DO} loops on some -machines. - -@item -Support @code{gcc} version 2.7.1. - -@item -Upgrade to @code{libf2c} as of 1995-11-15. -@end itemize - -@c 1995-08-30: 0.5.16 released. -@heading In 0.5.16: -@itemize @bullet -@item -Fix a code-generation bug involving complicated @code{EQUIVALENCE} statements -not involving @code{COMMON}. - -@item -Fix code-generation bugs involving invoking ``gratis'' library procedures -in @code{libf2c} from code compiled with @samp{-fno-f2c} by making these -procedures known to @code{g77} as intrinsics (not affected by -fno-f2c). -This is known to fix code invoking @code{ERF()}, @code{ERFC()}, -@code{DERF()}, and @code{DERFC()}. - -@item -Update @code{libf2c} to include netlib patches through 1995-08-16, and -@code{#define} @samp{WANT_LEAD_0} to 1 to make @code{g77}-compiled code more -consistent with other Fortran implementations by outputting -leading zeros in formatted and list-directed output. - -@item -Fix a code-generation bug involving adjustable dummy arrays with high -bounds whose primaries are changed during procedure execution, and -which might well improve code-generation performance for such arrays -compared to @code{f2c} plus @code{gcc} (but apparently only when using -@file{gcc-2.7.0} or later). - -@item -Fix a code-generation bug involving invocation of @code{COMPLEX} and -@code{DOUBLE COMPLEX} @code{FUNCTION}s and doing @code{COMPLEX} and -@code{DOUBLE COMPLEX} divides, when the result -of the invocation or divide is assigned directly to a variable -that overlaps one or more of the arguments to the invocation or divide. - -@item -Fix crash by not generating new optimal code for @samp{X**I} if @samp{I} is -nonconstant and the expression is used to dimension a dummy -array, since the @code{gcc} back end does not support the necessary -mechanics (and the @code{gcc} front end rejects the equivalent -construct, as it turns out). - -@item -Fix crash on expressions like @samp{COMPLEX**INTEGER}. - -@item -Fix crash on expressions like @samp{(1D0,2D0)**2}, i.e. raising a -@code{DOUBLE COMPLEX} constant to an @code{INTEGER} constant power. - -@item -Fix crashes and such involving diagnosed code. - -@item -Diagnose, instead of crashing on, statement function definitions -having duplicate dummy argument names. - -@item -Fix bug causing rejection of good code involving statement function -definitions. - -@item -Fix bug resulting in debugger not knowing size of local equivalence -area when any member of area has initial value (via @code{DATA}, -for example). - -@item -Fix installation bug that prevented installation of @code{g77} driver. -Provide for easy selection of whether to install copy of @code{g77} -as @code{f77} to replace the broken code. - -@item -Fix @code{gcc} driver (affects @code{g77} thereby) to not -gratuitously invoke the -@code{f771} program (e.g. when @samp{-E} is specified). - -@item -Fix diagnostic to point to correct source line when it immediately -follows an @code{INCLUDE} statement. - -@item -Support more compiler options in @code{gcc}/@code{g77} when -compiling Fortran files. -These options include @samp{-p}, @samp{-pg}, @samp{-aux-info}, @samp{-P}, -correct setting of version-number macros for preprocessing, full -recognition of @samp{-O0}, and -automatic insertion of configuration-specific linker specs. - -@item -Add new intrinsics that interface to existing routines in @code{libf2c}: -@code{ABORT}, @code{DERF}, @code{DERFC}, @code{ERF}, @code{ERFC}, @code{EXIT}, -@code{FLUSH}, @code{GETARG}, @code{GETENV}, @code{IARGC}, -@code{SIGNAL}, and @code{SYSTEM}. -Note that @code{ABORT}, @code{EXIT}, @code{FLUSH}, @code{SIGNAL}, and -@code{SYSTEM} are intrinsic subroutines, not functions (since they -have side effects), so to get the return values from @code{SIGNAL} -and @code{SYSTEM}, append a final argument specifying an @code{INTEGER} -variable or array element (e.g. @samp{CALL SYSTEM('rm foo',ISTAT)}). - -@item -Add new intrinsic group named @samp{unix} to contain the new intrinsics, -and by default enable this new group. - -@item -Move @code{LOC()} intrinsic out of the @samp{vxt} group to the new -@samp{unix} group. - -@item -Improve @code{g77} so that @samp{g77 -v} by itself (or with -certain other options, including @samp{-B}, @samp{-b}, @samp{-i}, -@samp{-nostdlib}, and @samp{-V}) reports lots more useful -version info, and so that long-form options @code{gcc} accepts are -understood by @code{g77} as well (even in truncated, unambiguous forms). - -@item -Add new @code{g77} option @samp{--driver=name} to specify driver when -default, @code{gcc}, isn't appropriate. - -@item -Add support for @samp{#} directives (as output by the preprocessor) in the -compiler, and enable generation of those directives by the -preprocessor (when compiling @samp{.F} files) so diagnostics and debugging -info are more useful to users of the preprocessor. - -@item -Produce better diagnostics, more like @code{gcc}, with info such as -@samp{In function `foo':} and @samp{In file included from...:}. - -@item -Support @code{gcc}'s @samp{-fident} and @samp{-fno-ident} options. - -@item -When @samp{-Wunused} in effect, don't warn about local variables used as -statement-function dummy arguments or @code{DATA} implied-@code{DO} iteration -variables, even though, strictly speaking, these are not uses -of the variables themselves. - -@item -When @samp{-W -Wunused} in effect, don't warn about unused dummy arguments -at all, since there's no way to turn this off for individual -cases (@code{g77} might someday start warning about these)---applies -to @code{gcc} versions 2.7.0 and later, since earlier versions didn't -warn about unused dummy arguments. - -@item -New option @samp{-fno-underscoring} that inhibits transformation of names -(by appending one or two underscores) so users may experiment -with implications of such an environment. - -@item -Minor improvement to @file{gcc/f/info} module to make it easier to build -@code{g77} using the native (non-@code{gcc}) compiler on certain machines -(but definitely not all machines nor all non-@code{gcc} compilers). -Please -do not report bugs showing problems compilers have with -macros defined in @file{gcc/f/target.h} and used in places like -@file{gcc/f/expr.c}. - -@item -Add warning to be printed for each invocation of the compiler -if the target machine @code{INTEGER}, @code{REAL}, or @code{LOGICAL} size -is not 32 bits, -since @code{g77} is known to not work well for such cases (to be -fixed in Version 0.6---@pxref{Actual Bugs,,Actual Bugs We Haven't Fixed Yet}). - -@item -Lots of new documentation (though work is still needed to put it into -canonical GNU format). - -@item -Build @code{libf2c} with @samp{-g0}, not @samp{-g2}, in effect -(by default), to produce -smaller library without lots of debugging clutter. -@end itemize - -@c 1995-05-19: 0.5.15 released. -@heading In 0.5.15: -@itemize @bullet -@item -Fix bad code generation involving @samp{X**I} and temporary, internal variables -generated by @code{g77} and the back end (such as for @code{DO} loops). - -@item -Fix crash given @samp{CHARACTER A;DATA A/.TRUE./}. - -@item -Replace crash with diagnostic given @samp{CHARACTER A;DATA A/1.0/}. - -@item -Fix crash or other erratic behavior when null character constant -(@samp{''}) is encountered. - -@item -Fix crash or other erratic behavior involving diagnosed code. - -@item -Fix code generation for external functions returning type @code{REAL} when -the @samp{-ff2c} option is in force (which it is by default) so that -@code{f2c} compatibility is indeed provided. - -@item -Disallow @samp{COMMON I(10)} if @samp{I} has previously been specified -with an array declarator. - -@item -New @samp{-ffixed-line-length-@var{n}} option, where @var{n} is the -maximum length -of a typical fixed-form line, defaulting to 72 columns, such -that characters beyond column @var{n} are ignored, or @var{n} is @samp{none}, -meaning no characters are ignored. -does not affect lines -with @samp{&} in column 1, which are always processed as if -@samp{-ffixed-line-length-none} was in effect. - -@item -No longer generate better code for some kinds of array references, -as @code{gcc} back end is to be fixed to do this even better, and it -turned out to slow down some code in some cases after all. - -@item -In @code{COMMON} and @code{EQUIVALENCE} areas with any members given initial -values (e.g. via @code{DATA}), uninitialized members now always -initialized to binary zeros (though this is not required by -the standard, and might not be done in future versions -of @code{g77}). -Previously, in some @code{COMMON}/@code{EQUIVALENCE} areas -(essentially those with members of more than one type), the -uninitialized members were initialized to spaces, to -cater to @code{CHARACTER} types, but it seems no existing code expects -that, while much existing code expects binary zeros. -@end itemize - -@heading In 0.5.14: -@itemize @bullet -@item -Don't emit bad code when low bound of adjustable array is nonconstant -and thus might vary as an expression at run time. - -@item -Emit correct code for calculation of number of trips in @code{DO} loops -for cases -where the loop should not execute at all. -(This bug affected cases -where the difference between the begin and end values was less -than the step count, though probably not for floating-point cases.) - -@item -Fix crash when extra parentheses surround item in -@code{DATA} implied-@code{DO} list. - -@item -Fix crash over minor internal inconsistencies in handling diagnostics, -just substitute dummy strings where necessary. - -@item -Fix crash on some systems when compiling call to @code{MVBITS()} intrinsic. - -@item -Fix crash on array assignment @samp{TYPE@var{ddd}(@dots{})=@dots{}}, where @var{ddd} -is a string of one or more digits. - -@item -Fix crash on @code{DCMPLX()} with a single @code{INTEGER} argument. - -@item -Fix various crashes involving code with diagnosed errors. - -@item -Support @samp{-I} option for @code{INCLUDE} statement, plus @code{gcc}'s -@file{header.gcc} facility for handling systems like MS-DOS. - -@item -Allow @code{INCLUDE} statement to be continued across multiple lines, -even allow it to coexist with other statements on the same line. - -@item -Incorporate Bellcore fixes to @code{libf2c} through 1995-03-15---this -fixes a bug involving infinite loops reading EOF with empty list-directed -I/O list. - -@item -Remove all the @code{g77}-specific auto-configuration scripts, code, -and so on, -except for temporary substitutes for bsearch() and strtoul(), as -too many configure/build problems were reported in these areas. -People will have to fix their systems' problems themselves, or at -least somewhere other than @code{g77}, which expects a working ANSI C -environment (and, for now, a GNU C compiler to compile @code{g77} itself). - -@item -Complain if initialized common redeclared as larger in subsequent program -unit. - -@item -Warn if blank common initialized, since its size can vary and hence -related warnings that might be helpful won't be seen. - -@item -New @samp{-fbackslash} option, on by default, that causes @samp{\} -within @code{CHARACTER} -and Hollerith constants to be interpreted a la GNU C. -Note that -this behavior is somewhat different from @code{f2c}'s, which supports only -a limited subset of backslash (escape) sequences. - -@item -Make @samp{-fugly-args} the default. - -@item -New @samp{-fugly-init} option, on by default, that allows typeless/Hollerith -to be specified as initial values for variables or named constants -(@code{PARAMETER}), and also allows character<->numeric conversion in -those contexts---turn off via @samp{-fno-ugly-init}. - -@item -New @samp{-finit-local-zero} option to initialize -local variables to binary zeros. -This does not affect whether they are @code{SAVE}d, i.e. made -automatic or static. - -@item -New @samp{-Wimplicit} option to warn about implicitly typed variables, arrays, -and functions. -(Basically causes all program units to default to @code{IMPLICIT NONE}.) - -@item -@samp{-Wall} now implies @samp{-Wuninitialized} as with @code{gcc} -(i.e. unless @samp{-O} not specified, since @samp{-Wuninitialized} -requires @samp{-O}), and implies @samp{-Wunused} as well. - -@item -@samp{-Wunused} no longer gives spurious messages for unused -@code{EXTERNAL} names (since they are assumed to refer to block data -program units, to make use of libraries more reliable). - -@item -Support @code{%LOC()} and @code{LOC()} of character arguments. - -@item -Support null (zero-length) character constants and expressions. - -@item -Support @code{f2c}'s @code{IMAG()} generic intrinsic. - -@item -Support @code{ICHAR()}, @code{IACHAR()}, and @code{LEN()} of -character expressions that are valid in assignments but -not normally as actual arguments. - -@item -Support @code{f2c}-style @samp{&} in column 1 to mean continuation line. - -@item -Allow @code{NAMELIST}, @code{EXTERNAL}, @code{INTRINSIC}, and @code{VOLATILE} -in @code{BLOCK DATA}, even though these are not allowed by the standard. - -@item -Allow @code{RETURN} in main program unit. - -@item -Changes to Hollerith-constant support to obey Appendix C of the -standard: - -@itemize -- -@item -Now padded on the right with zeros, not spaces. - -@item -Hollerith ``format specifications'' in the form of arrays of -non-character allowed. - -@item -Warnings issued when non-space truncation occurs when converting -to another type. - -@item -When specified as actual argument, now passed -by reference to @code{INTEGER} (padded on right with spaces if constant -too small, otherwise fully intact if constant wider the @code{INTEGER} -type) instead of by value. -@end itemize - -@strong{Warning:} @code{f2c} differs on the -interpretation of @samp{CALL FOO(1HX)}, which it treats exactly the -same as @samp{CALL FOO('X')}, but which the standard and @code{g77} treat -as @samp{CALL FOO(%REF('X '))} (padded with as many spaces as necessary -to widen to @code{INTEGER}), essentially. - -@item -Changes and fixes to typeless-constant support: - -@itemize -- -@item -Now treated as a typeless double-length @code{INTEGER} value. - -@item -Warnings issued when overflow occurs. - -@item -Padded on the left with zeros when converting -to a larger type. - -@item -Should be properly aligned and ordered on -the target machine for whatever type it is turned into. - -@item -When specified as actual argument, now passed as reference to -a default @code{INTEGER} constant. -@end itemize - -@item -@code{%DESCR()} of a non-@code{CHARACTER} expression now passes a pointer to -the expression plus a length for the expression just as if -it were a @code{CHARACTER} expression. -For example, @samp{CALL FOO(%DESCR(D))}, where -@samp{D} is @code{REAL*8}, is the same as @samp{CALL FOO(D,%VAL(8)))}. - -@item -Name of multi-entrypoint master function changed to incorporate -the name of the primary entry point instead of a decimal -value, so the name of the master function for @samp{SUBROUTINE X} -with alternate entry points is now @samp{__g77_masterfun_x}. - -@item -Remove redundant message about zero-step-count @code{DO} loops. - -@item -Clean up diagnostic messages, shortening many of them. - -@item -Fix typo in @code{g77} man page. - -@item -Clarify implications of constant-handling bugs in @file{f/BUGS}. - -@item -Generate better code for @samp{**} operator with a right-hand operand of -type @code{INTEGER}. - -@item -Generate better code for @code{SQRT()} and @code{DSQRT()}, -also when @samp{-ffast-math} -specified, enable better code generation for @code{SIN()} and @code{COS()}. - -@item -Generate better code for some kinds of array references. - -@item -Speed up lexing somewhat (this makes the compilation phase noticeably -faster). -@end itemize diff --git a/gcc/f/news0.texi b/gcc/f/news0.texi deleted file mode 100755 index 8fb85f4..0000000 --- a/gcc/f/news0.texi +++ /dev/null @@ -1,14 +0,0 @@ -@setfilename NEW -@set NEWSONLY - -@c The immediately following lines apply to the NEWS file -@c which is generated using this file. -This file lists recent changes to the GNU Fortran compiler. -Copyright (C) 1995, 1996 Free Software Foundation, Inc. -You may copy, distribute, and modify it freely as long as you preserve -this copyright notice and permission notice. - -@node Top,,, (dir) -@chapter News About GNU Fortran -@include news.texi -@bye diff --git a/gcc/f/output.j b/gcc/f/output.j deleted file mode 100755 index 2816b7e..0000000 --- a/gcc/f/output.j +++ /dev/null @@ -1,27 +0,0 @@ -/* output.j -- Wrapper for GCC's output.h - Copyright (C) 1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_output -#define _J_f_output -#include "output.h" -#endif -#endif diff --git a/gcc/f/parse.c b/gcc/f/parse.c deleted file mode 100755 index 6c92de9..0000000 --- a/gcc/f/parse.c +++ /dev/null @@ -1,95 +0,0 @@ -/* GNU Fortran - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#include "proj.h" -#include "top.h" -#include "com.h" -#include "where.h" -#include "version.h" -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#include "flags.j" -#endif - -#define NAME_OF_STDIN "<stdin>" - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -main (int argc, char *argv[]) -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -FILE *finput; - -int -yyparse () -#else -#error -#endif -{ - ffewhereFile wf; - - if (ffe_is_version ()) - fprintf (stderr, "GNU Fortran Front End version %s\n", ffe_version_string); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffe_init_0 (); - - { - int strings_processed; - for (--argc, ++argv; argc > 0; argc -= strings_processed, argv += strings_processed) - { - strings_processed = ffe_decode_option (argc, argv); - if (strings_processed == 0) - { - fprintf (stderr, "Unrecognized option: %s\n", argv[0]); - strings_processed = 1; - } - } - } -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - if (!ffe_is_pedantic ()) - ffe_set_is_pedantic (pedantic); -#else -#error -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - wf = ffewhere_file_new (NAME_OF_STDIN, strlen (NAME_OF_STDIN)); - ffecom_file (NAME_OF_STDIN); - ffe_file (wf, stdin); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - wf = ffewhere_file_new (main_input_filename, strlen (main_input_filename)); - ffecom_file (main_input_filename); - ffe_file (wf, finput); -#else -#error -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffecom_finish_compile (); - - return 0; -#elif FFECOM_targetCURRENT == FFECOM_targetFFE - ffe_terminate_0 (); - - exit (0); -#else -#error -#endif -} diff --git a/gcc/f/proj.c b/gcc/f/proj.c deleted file mode 100755 index 6af2df5..0000000 --- a/gcc/f/proj.c +++ /dev/null @@ -1,68 +0,0 @@ -/* proj.c file for GNU Fortran - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#include "proj.h" -#include "glimits.j" - -#ifndef HAVE_STRTOUL -unsigned long int -strtoul (const char *nptr, char **endptr, int base) -{ - unsigned long int number = 0; - unsigned long int old_number = 0; - - assert (base == 10); - assert (endptr == NULL); - - while (ISDIGIT (*nptr)) - { - number = old_number * 10 + (*(nptr++) - '0'); - if ((number <= old_number) && (old_number != 0)) - return ULONG_MAX; - old_number = number; - } - - return number; -} -#endif - -#ifndef HAVE_BSEARCH -void * -bsearch (const void *key, const void *base, size_t nmemb, size_t size, - int (*compar) (const void *, const void *)) -{ - size_t i; - int cmp; - - /* We do a dumb incremental search, not a binary search, for now. */ - - for (i = 0; i < nmemb; ++i) - { - if ((cmp = (*compar) (key, base)) == 0) - return base; - if (cmp < 0) - break; - base += size; - } - - return NULL; -} -#endif diff --git a/gcc/f/proj.h b/gcc/f/proj.h deleted file mode 100755 index 93b12b3..0000000 --- a/gcc/f/proj.h +++ /dev/null @@ -1,83 +0,0 @@ -/* proj.h file for Gnu Fortran - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -#ifndef _H_f_proj -#define _H_f_proj - -#ifdef USE_HCONFIG -#include "hconfig.j" -#else -#include "config.j" -#endif -#include "system.j" - -#if !defined (__GNUC__) || (__GNUC__ < 2) -#error "You have to use gcc 2.x to build g77 (might be fixed in g77-0.6)." -#endif - -#ifndef BUILT_WITH_270 -#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 7) -#define BUILT_WITH_270 1 -#else -#define BUILT_WITH_270 0 -#endif -#endif /* !defined (BUILT_WITH_270) */ - -/* Include files everyone gets. <assert.h> is needed for assert(). - <stddef.h> is needed for offsetof, but technically also NULL, - size_t, ptrdiff_t, and so on. */ - -#include "assert.j" - -#if HAVE_STDDEF_H -#include <stddef.h> -#endif - -/* Generally useful definitions. */ - -typedef enum - { -#if !defined(false) || !defined(true) - false = 0, true = 1, -#endif -#if !defined(FALSE) || !defined(TRUE) - FALSE = 0, TRUE = 1, -#endif - Doggone_Trailing_Comma_Dont_Work = 1 - } bool; - -#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) - -#ifndef UNUSED /* Compile with -DUNUSED= if cc doesn't support this. */ -#if BUILT_WITH_270 -#define UNUSED __attribute__ ((unused)) -#else /* !BUILT_WITH_270 */ -#define UNUSED -#endif /* !BUILT_WITH_270 */ -#endif /* !defined (UNUSED) */ - -#ifndef dmpout -#define dmpout stderr -#endif - -#endif diff --git a/gcc/f/rtl.j b/gcc/f/rtl.j deleted file mode 100755 index 99923f4..0000000 --- a/gcc/f/rtl.j +++ /dev/null @@ -1,28 +0,0 @@ -/* rtl.j -- Wrapper for GCC's rtl.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_rtl -#define _J_f_rtl -#include "config.j" -#include "rtl.h" -#endif -#endif diff --git a/gcc/f/src.c b/gcc/f/src.c deleted file mode 100755 index 3fd1755..0000000 --- a/gcc/f/src.c +++ /dev/null @@ -1,445 +0,0 @@ -/* src.c -- Implementation File - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - - Description: - Source-file functions to handle various combinations of case sensitivity - and insensitivity at run time. - - Modifications: -*/ - -#include "proj.h" -#include "src.h" -#include "top.h" - -/* This array does a toupper (), but any valid char type is valid as an - index and returns identity if not a lower-case character. */ - -char ffesrc_toupper_[256]; - -/* This array does a tolower (), but any valid char type is valid as an - index and returns identity if not an upper-case character. */ - -char ffesrc_tolower_[256]; - -/* This array is set up so that, given a source-mapped character, the result - of indexing into this array will match an upper-cased character depending - on the source-mapped character's case and the established ffe_case_match() - setting. So the uppercase cells contain identies (e.g. ['A'] == 'A') - as long as uppercase matching is permitted (!FFE_caseLOWER) and the - lowercase cells contain uppercased identities (e.g. ['a'] == 'A') as long - as lowercase matching is permitted (!FFE_caseUPPER). Else the case - cells contain -1. _init_ is for the first character of a keyword, - and _noninit_ is for other characters. */ - -char ffesrc_char_match_init_[256]; -char ffesrc_char_match_noninit_[256]; - -/* This array is used to map input source according to the established - ffe_case_source() setting: for FFE_caseNONE, the array is all - identities; for FFE_caseUPPER, the lowercase cells contain - uppercased identities; and vice versa for FFE_caseLOWER. */ - -char ffesrc_char_source_[256]; - -/* This array is used to map an internally generated character so that it - will be accepted as an initial character in a keyword. The assumption - is that the incoming character is uppercase. */ - -char ffesrc_char_internal_init_[256]; - -/* This array is used to determine if a particular character is valid in - a symbol name according to the established ffe_case_symbol() setting: - for FFE_caseNONE, the array is all FFEBAD; for FFE_caseUPPER, the - lowercase cells contain a non-FFEBAD error code (FFEBAD_SYMBOL_UPPER_CASE); - and vice versa for FFE_caseLOWER. _init_ and _noninit_ distinguish - between initial and subsequent characters for the caseINITCAP case, - and their error codes are different for appropriate messages -- - specifically, _noninit_ contains a non-FFEBAD error code for all - except lowercase characters for the caseINITCAP case. - - See ffesrc_check_symbol_, it must be TRUE if this array is not all - FFEBAD. */ - -ffebad ffesrc_bad_symbol_init_[256]; -ffebad ffesrc_bad_symbol_noninit_[256]; - -/* Set TRUE if any element in ffesrc_bad_symbol (with an index representing - a character that can also be in the text of a token passed to - ffename_find, strictly speaking) is not FFEBAD. I.e., TRUE if it is - necessary to check token characters against the ffesrc_bad_symbol_ - array. */ - -bool ffesrc_check_symbol_; - -/* These are set TRUE if the kind of character (upper/lower) is ok as a match - in the context (initial/noninitial character of keyword). */ - -bool ffesrc_ok_match_init_upper_; -bool ffesrc_ok_match_init_lower_; -bool ffesrc_ok_match_noninit_upper_; -bool ffesrc_ok_match_noninit_lower_; - -/* Initialize table of alphabetic matches. */ - -void -ffesrc_init_1 () -{ - int i; - - for (i = 0; i < 256; ++i) - { - ffesrc_char_match_init_[i] = i; - ffesrc_char_match_noninit_[i] = i; - ffesrc_char_source_[i] = i; - ffesrc_char_internal_init_[i] = i; - ffesrc_toupper_[i] = i; - ffesrc_tolower_[i] = i; - ffesrc_bad_symbol_init_[i] = FFEBAD; - ffesrc_bad_symbol_noninit_[i] = FFEBAD; - } - - for (i = 'A'; i <= 'Z'; ++i) - ffesrc_tolower_[i] = tolower (i); - - for (i = 'a'; i <= 'z'; ++i) - ffesrc_toupper_[i] = toupper (i); - - ffesrc_check_symbol_ = (ffe_case_symbol () != FFE_caseNONE); - - ffesrc_ok_match_init_upper_ = (ffe_case_match () != FFE_caseLOWER); - ffesrc_ok_match_init_lower_ = (ffe_case_match () != FFE_caseUPPER) - && (ffe_case_match () != FFE_caseINITCAP); - ffesrc_ok_match_noninit_upper_ = (ffe_case_match () != FFE_caseLOWER) - && (ffe_case_match () != FFE_caseINITCAP); - ffesrc_ok_match_noninit_lower_ = (ffe_case_match () != FFE_caseUPPER); - - /* Note that '-' is used to flag an invalid match character. '-' is - somewhat arbitrary, actually. -1 was used, but that's not wise on a - system with unsigned chars as default -- it'd turn into 255 or some such - large positive number, which would sort higher than the alphabetics and - thus possibly cause problems. So '-' is picked just because it's never - likely to be a symbol character in Fortran and because it's "less than" - any alphabetic character. EBCDIC might see things differently, I don't - remember it well enough, but that's just tough -- lots of other things - might have to change to support EBCDIC -- anyway, some other character - could easily be picked. */ - -#define FFESRC_INVALID_SYMBOL_CHAR_ '-' - - if (!ffesrc_ok_match_init_upper_) - for (i = 'A'; i <= 'Z'; ++i) - ffesrc_char_match_init_[i] = FFESRC_INVALID_SYMBOL_CHAR_; - - if (ffesrc_ok_match_init_lower_) - for (i = 'a'; i <= 'z'; ++i) - ffesrc_char_match_init_[i] = toupper (i); - else - for (i = 'a'; i <= 'z'; ++i) - ffesrc_char_match_init_[i] = FFESRC_INVALID_SYMBOL_CHAR_; - - if (!ffesrc_ok_match_noninit_upper_) - for (i = 'A'; i <= 'Z'; ++i) - ffesrc_char_match_noninit_[i] = FFESRC_INVALID_SYMBOL_CHAR_; - - if (ffesrc_ok_match_noninit_lower_) - for (i = 'a'; i <= 'z'; ++i) - ffesrc_char_match_noninit_[i] = toupper (i); - else - for (i = 'a'; i <= 'z'; ++i) - ffesrc_char_match_noninit_[i] = FFESRC_INVALID_SYMBOL_CHAR_; - - if (ffe_case_source () == FFE_caseLOWER) - for (i = 'A'; i <= 'Z'; ++i) - ffesrc_char_source_[i] = tolower (i); - else if (ffe_case_source () == FFE_caseUPPER) - for (i = 'a'; i <= 'z'; ++i) - ffesrc_char_source_[i] = toupper (i); - - if (ffe_case_match () == FFE_caseLOWER) - for (i = 'A'; i <= 'Z'; ++i) - ffesrc_char_internal_init_[i] = tolower (i); - - switch (ffe_case_symbol ()) - { - case FFE_caseLOWER: - for (i = 'A'; i <= 'Z'; ++i) - { - ffesrc_bad_symbol_init_[i] = FFEBAD_SYMBOL_UPPER_CASE; - ffesrc_bad_symbol_noninit_[i] = FFEBAD_SYMBOL_UPPER_CASE; - } - break; - - case FFE_caseUPPER: - for (i = 'a'; i <= 'z'; ++i) - { - ffesrc_bad_symbol_init_[i] = FFEBAD_SYMBOL_LOWER_CASE; - ffesrc_bad_symbol_noninit_[i] = FFEBAD_SYMBOL_LOWER_CASE; - } - break; - - case FFE_caseINITCAP: - for (i = 0; i < 256; ++i) - ffesrc_bad_symbol_noninit_[i] = FFEBAD_SYMBOL_NOLOWER_INITCAP; - for (i = 'a'; i <= 'z'; ++i) - { - ffesrc_bad_symbol_init_[i] = FFEBAD_SYMBOL_LOWER_INITCAP; - ffesrc_bad_symbol_noninit_[i] = FFEBAD; - } - break; - - default: - break; - } -} - -/* Compare two strings a la strcmp, the first being a source string with its - length passed, and the second being a constant string passed - in InitialCaps form. Also, the return value is always -1, 0, or 1. */ - -int -ffesrc_strcmp_1ns2i (ffeCase mcase, const char *var, int len, - const char *str_ic) -{ - char c; - char d; - - switch (mcase) - { - case FFE_caseNONE: - for (; len > 0; --len, ++var, ++str_ic) - { - c = ffesrc_char_source (*var); /* Transform source. */ - c = ffesrc_toupper (c); /* Upcase source. */ - d = ffesrc_toupper (*str_ic); /* Upcase InitialCaps char. */ - if (c != d) - { - if ((d != '\0') && (c < d)) - return -1; - else - return 1; - } - } - break; - - case FFE_caseUPPER: - for (; len > 0; --len, ++var, ++str_ic) - { - c = ffesrc_char_source (*var); /* Transform source. */ - d = ffesrc_toupper (*str_ic); /* Transform InitialCaps char. */ - if (c != d) - { - if ((d != '\0') && (c < d)) - return -1; - else - return 1; - } - } - break; - - case FFE_caseLOWER: - for (; len > 0; --len, ++var, ++str_ic) - { - c = ffesrc_char_source (*var); /* Transform source. */ - d = ffesrc_tolower (*str_ic); /* Transform InitialCaps char. */ - if (c != d) - { - if ((d != '\0') && (c < d)) - return -1; - else - return 1; - } - } - break; - - case FFE_caseINITCAP: - for (; len > 0; --len, ++var, ++str_ic) - { - c = ffesrc_char_source (*var); /* Transform source. */ - d = *str_ic; /* No transform of InitialCaps char. */ - if (c != d) - { - c = ffesrc_toupper (c); - d = ffesrc_toupper (d); - while ((len > 0) && (c == d)) - { /* Skip past equivalent (case-ins) chars. */ - --len, ++var, ++str_ic; - if (len > 0) - c = ffesrc_toupper (*var); - d = ffesrc_toupper (*str_ic); - } - if ((d != '\0') && (c < d)) - return -1; - else - return 1; - } - } - break; - - default: - assert ("bad case value" == NULL); - return -1; - } - - if (*str_ic == '\0') - return 0; - return -1; -} - -/* Compare two strings a la strcmp, the second being a constant string passed - in both uppercase and lowercase form. If not equal, the uppercase string - is used to determine the sign of the return value. Also, the return - value is always -1, 0, or 1. */ - -int -ffesrc_strcmp_2c (ffeCase mcase, const char *var, const char *str_uc, - const char *str_lc, const char *str_ic) -{ - int i; - char c; - - switch (mcase) - { - case FFE_caseNONE: - for (; *var != '\0'; ++var, ++str_uc) - { - c = ffesrc_toupper (*var); /* Upcase source. */ - if (c != *str_uc) - { - if ((*str_uc != '\0') && (c < *str_uc)) - return -1; - else - return 1; - } - } - if (*str_uc == '\0') - return 0; - return -1; - - case FFE_caseUPPER: - i = strcmp (var, str_uc); - break; - - case FFE_caseLOWER: - i = strcmp (var, str_lc); - break; - - case FFE_caseINITCAP: - for (; *var != '\0'; ++var, ++str_ic, ++str_uc) - { - if (*var != *str_ic) - { - c = ffesrc_toupper (*var); - while ((c != '\0') && (c == *str_uc)) - { /* Skip past equivalent (case-ins) chars. */ - ++var, ++str_uc; - c = ffesrc_toupper (*var); - } - if ((*str_uc != '\0') && (c < *str_uc)) - return -1; - else - return 1; - } - } - if (*str_ic == '\0') - return 0; - return -1; - - default: - assert ("bad case value" == NULL); - return -1; - } - - if (i == 0) - return 0; - else if (i < 0) - return -1; - return 1; -} - -/* Compare two strings a la strncmp, the second being a constant string passed - in uppercase, lowercase, and InitialCaps form. If not equal, the - uppercase string is used to determine the sign of the return value. */ - -int -ffesrc_strncmp_2c (ffeCase mcase, const char *var, const char *str_uc, - const char *str_lc, const char *str_ic, int len) -{ - int i; - char c; - - switch (mcase) - { - case FFE_caseNONE: - for (; len > 0; ++var, ++str_uc, --len) - { - c = ffesrc_toupper (*var); /* Upcase source. */ - if (c != *str_uc) - { - if (c < *str_uc) - return -1; - else - return 1; - } - } - return 0; - - case FFE_caseUPPER: - i = strncmp (var, str_uc, len); - break; - - case FFE_caseLOWER: - i = strncmp (var, str_lc, len); - break; - - case FFE_caseINITCAP: - for (; len > 0; ++var, ++str_ic, ++str_uc, --len) - { - if (*var != *str_ic) - { - c = ffesrc_toupper (*var); - while ((len > 0) && (c == *str_uc)) - { /* Skip past equivalent (case-ins) chars. */ - --len, ++var, ++str_uc; - if (len > 0) - c = ffesrc_toupper (*var); - } - if ((len > 0) && (c < *str_uc)) - return -1; - else - return 1; - } - } - return 0; - - default: - assert ("bad case value" == NULL); - return -1; - } - - if (i == 0) - return 0; - else if (i < 0) - return -1; - return 1; -} diff --git a/gcc/f/src.h b/gcc/f/src.h deleted file mode 100755 index 0216a7c..0000000 --- a/gcc/f/src.h +++ /dev/null @@ -1,144 +0,0 @@ -/* src.h -- Public #include File - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - src.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_src -#define _H_f_src - -#include "bad.h" -#include "top.h" - -extern char ffesrc_toupper_[256]; -extern char ffesrc_tolower_[256]; -extern char ffesrc_char_match_init_[256]; -extern char ffesrc_char_match_noninit_[256]; -extern char ffesrc_char_source_[256]; -extern char ffesrc_char_internal_init_[256]; -extern ffebad ffesrc_bad_symbol_init_[256]; -extern ffebad ffesrc_bad_symbol_noninit_[256]; -extern bool ffesrc_check_symbol_; -extern bool ffesrc_ok_match_init_upper_; -extern bool ffesrc_ok_match_init_lower_; -extern bool ffesrc_ok_match_noninit_upper_; -extern bool ffesrc_ok_match_noninit_lower_; - -/* These C-language-syntax modifiers could avoid the match arg if gcc's - extension allowing macros to generate dynamic labels was used. They - could use the no_match arg (and the "caller's" label defs) if there - was a way to say "goto default" in a switch statement. Oh well. - - NOTE: These macro assume "case FFESRC_CASE_MATCH_[NON]INIT(...):" is used - to invoke them, and thus assume the "above" case does not fall through to - this one. This syntax was chosen to keep indenting tools working. */ - -#define FFESRC_CASE_MATCH_INIT(upper, lower, match, no_match) \ - upper: if (!ffesrc_ok_match_init_upper_) goto no_match; \ - else goto match; \ - case lower: if (!ffesrc_ok_match_init_lower_) goto no_match; \ - match - -#define FFESRC_CASE_MATCH_NONINIT(upper, lower, match, no_match) \ - upper: if (!ffesrc_ok_match_noninit_upper_) goto no_match; \ - else goto match; \ - case lower: if (!ffesrc_ok_match_noninit_lower_) goto no_match; \ - match - -/* If character is ok in a symbol name (not including intrinsic names), - returns FFEBAD, else returns something else, type ffebad. */ - -#define ffesrc_bad_char_symbol_init(c) \ - (ffesrc_bad_symbol_init_[(unsigned int) (c)]) -#define ffesrc_bad_char_symbol_noninit(c) \ - (ffesrc_bad_symbol_noninit_[(unsigned int) (c)]) - -/* Returns TRUE if character is ok in a symbol name (including - intrinsic names). Doesn't care about case settings, this is - used just for parsing (before semantic complaints about symbol- - name casing and such). One specific usage is to decide whether - an underscore is valid as the first or subsequent character in - some symbol name -- if not, an underscore is a separate token - (while lexing, for example). Note that ffesrc_is_name_init - must return TRUE for a (not necessarily proper) subset of - characters for which ffelex_is_firstnamechar returns TRUE. */ - -#define ffesrc_is_name_init(c) \ - ((ISALPHA ((c))) || (! (1 || ffe_is_90 ()) && ((c) == '_'))) -#define ffesrc_is_name_noninit(c) \ - ((ISALNUM ((c))) || (! (1 || ffe_is_90 ()) && ((c) == '_'))) - -/* Test if source-translated character matches given alphabetic character - (passed in both uppercase and lowercase, to allow for custom speedup - of compilation in environments where compile-time options aren't needed - for casing). */ - -#define ffesrc_char_match_init(c, up, low) \ - (ffesrc_char_match_init_[(unsigned int) (c)] == up) - -#define ffesrc_char_match_noninit(c, up, low) \ - (ffesrc_char_match_noninit_[(unsigned int) (c)] == up) - -/* Translate character from input-file form to source form. */ - -#define ffesrc_char_source(c) (ffesrc_char_source_[(unsigned int) (c)]) - -/* Translate internal character (upper/lower) to source form in an - initial-character context (i.e. ffesrc_char_match_init of the result - will always succeed). */ - -#define ffesrc_char_internal_init(up, low) \ - (ffesrc_char_internal_init_[(unsigned int) (up)]) - -/* Returns TRUE if a name representing a symbol should be checked for - validity according to compile-time options. That is, if it is possible - that ffesrc_bad_char_symbol(c) can return something other than FFEBAD - for any valid character in an ffelex NAME(S) token. */ - -#define ffesrc_check_symbol() ffesrc_check_symbol_ - -#define ffesrc_init_0() -void ffesrc_init_1 (void); -#define ffesrc_init_2() -#define ffesrc_init_3() -#define ffesrc_init_4() -int ffesrc_strcmp_1ns2i (ffeCase mcase, const char *var, int len, - const char *str_ic); -int ffesrc_strcmp_2c (ffeCase mcase, const char *var, const char *str_uc, - const char *str_lc, const char *str_ic); -int ffesrc_strncmp_2c (ffeCase mcase, const char *var, const char *str_uc, - const char *str_lc, const char *str_ic, int len); -#define ffesrc_terminate_0() -#define ffesrc_terminate_1() -#define ffesrc_terminate_2() -#define ffesrc_terminate_3() -#define ffesrc_terminate_4() -#define ffesrc_toupper(c) (ffesrc_toupper_[(unsigned int) (c)]) -#define ffesrc_tolower(c) (ffesrc_tolower_[(unsigned int) (c)]) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/st.c b/gcc/f/st.c deleted file mode 100755 index 2abd099..0000000 --- a/gcc/f/st.c +++ /dev/null @@ -1,554 +0,0 @@ -/* st.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - The high-level input level to statement handling for the rest of the - FFE. ffest_first is the first state for the lexer to invoke to start - a statement. A statement normally starts with a NUMBER token (to indicate - a label def) followed by a NAME token (to indicate what kind of statement - it is), though of course the NUMBER token may be omitted. ffest_first - gathers the first NAME token and returns a state of ffest_second_, - where the trailing underscore means "internal to ffest" and thus outside - users should not depend on this. ffest_second_ then looks at the second - token in conjunction with the first, decides what possible statements are - meant, and tries each possible statement in turn, from most likely to - least likely. A successful attempt currently is recorded, and further - successful attempts by other possibilities raise an assertion error in - ffest_confirmed (this is to detect ambiguities). A failure in an - attempt is signaled by calling ffest_ffebad_start; this results in the - next token sent by ffest_save_ (the intermediary when more than one - possible statement exists) being EOS to shut down processing and the next - possibility tried. - - When all possibilities have been tried, the successful one is retried with - inhibition turned off (FALSE) as reported by ffest_is_inhibited(). If - there is no successful one, the first one is retried so the user gets to - see the error messages. - - In the future, after syntactic bugs have been reasonably shaken out and - ambiguities thus detected, the first successful possibility will be - enabled (inhibited goes FALSE) as soon as it confirms success by calling - ffest_confirmed, thus retrying the possibility will not be necessary. - - The only complication in all this is that expression handling is - happening while possibilities are inhibited. It is up to the expression - handler, conceptually, to not make any changes to its knowledge base for - variable names and so on when inhibited that cannot be undone if - the current possibility fails (shuts down via ffest_ffebad_start). In - fact, this business is handled not be ffeexpr, but by lower levels. - - ffesta functions serve only to provide information used in syntactic - processing of possible statements, and thus may not make changes to the - knowledge base for variables and such. - - ffestb functions perform the syntactic analysis for possible statements, - and thus again may not make changes to the knowledge base except under the - auspices of ffeexpr and its subordinates, changes which can be undone when - necessary. - - ffestc functions perform the semantic analysis for the chosen statement, - and thus may change the knowledge base as necessary since they are invoked - by ffestb functions only after a given statement is confirmed and - enabled. Note, however, that a few ffestc functions (identified by - their statement names rather than grammar numbers) indicate valid forms - that are, outside of any context, ambiguous, such as ELSE WHERE and - PRIVATE; these functions should make a quick decision as to what is - intended and dispatch to the appropriate specific ffestc function. - - ffestd functions actually implement statements. When called, the - statement is considered valid and is either an executable statement or - a nonexecutable statement with direct-output results. For example, CALL, - GOTO, and assignment statements pass through ffestd because they are - executable; DATA statements pass through because they map directly to the - output file (or at least might so map); ENTRY statements also pass through - because they essentially affect code generation in an immediate way; - whereas INTEGER, SAVE, and SUBROUTINE statements do not go through - ffestd functions because they merely update the knowledge base. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "st.h" -#include "bad.h" -#include "lex.h" -#include "sta.h" -#include "stb.h" -#include "stc.h" -#include "std.h" -#include "ste.h" -#include "stp.h" -#include "str.h" -#include "sts.h" -#include "stt.h" -#include "stu.h" -#include "stv.h" -#include "stw.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffest_confirmed -- Confirm current possibility as only one - - ffest_confirmed(); - - Sets the confirmation flag. During debugging for ambiguous constructs, - asserts that the confirmation flag for a previous possibility has not - yet been set. */ - -void -ffest_confirmed () -{ - ffesta_confirmed (); -} - -/* ffest_eof -- End of (non-INCLUDEd) source file - - ffest_eof(); - - Call after piping tokens through ffest_first, where the most recent - token sent through must be EOS. - - 20-Feb-91 JCB 1.1 - Put new EOF token in ffesta_tokens[0], not NULL, because too much - code expects something there for error reporting and the like. Also, - do basically the same things ffest_second and ffesta_zero do for - processing a statement (make and destroy pools, et cetera). */ - -void -ffest_eof () -{ - ffesta_eof (); -} - -/* ffest_ffebad_here_current_stmt -- ffebad_here with ptr to current stmt - - ffest_ffebad_here_current_stmt(0); - - Outsiders can call this fn if they have no more convenient place to - point to (via a token or pair of ffewhere objects) and they know a - current, useful statement is being evaluted by ffest (i.e. they are - being called from ffestb, ffestc, ffestd, ... functions). */ - -void -ffest_ffebad_here_current_stmt (ffebadIndex i) -{ - ffesta_ffebad_here_current_stmt (i); -} - -/* ffest_ffebad_here_doiter -- Calls ffebad_here with ptr to DO iter var - - ffesymbol s; - // call ffebad_start first, of course. - ffest_ffebad_here_doiter(0,s); - // call ffebad_finish afterwards, naturally. - - Searches the stack of blocks backwards for a DO loop that has s - as its iteration variable, then calls ffebad_here with pointers to - that particular reference to the variable. Crashes if the DO loop - can't be found. */ - -void -ffest_ffebad_here_doiter (ffebadIndex i, ffesymbol s) -{ - ffestc_ffebad_here_doiter (i, s); -} - -/* ffest_ffebad_start -- Start a possibly inhibited error report - - if (ffest_ffebad_start(FFEBAD_SOME_ERROR)) - { - ffebad_here, ffebad_string ...; - ffebad_finish(); - } - - Call if the error might indicate that ffest is evaluating the wrong - statement form, instead of calling ffebad_start directly. If ffest - is choosing between forms, it will return FALSE, send an EOS/SEMICOLON - token through as the next token (if the current one isn't already one - of those), and try another possible form. Otherwise, ffebad_start is - called with the argument and TRUE returned. */ - -bool -ffest_ffebad_start (ffebad errnum) -{ - return ffesta_ffebad_start (errnum); -} - -/* ffest_first -- Parse the first token in a statement - - return ffest_first; // to lexer. */ - -ffelexHandler -ffest_first (ffelexToken t) -{ - return ffesta_first (t); -} - -/* ffest_init_0 -- Initialize for entire image invocation - - ffest_init_0(); - - Call just once per invocation of the compiler (not once per invocation - of the front end). - - Gets memory for the list of possibles once and for all, since this - list never gets larger than a certain size (FFEST_maxPOSSIBLES_) - and is not particularly large. Initializes the array of pointers to - this list. Initializes the executable and nonexecutable lists. */ - -void -ffest_init_0 () -{ - ffesta_init_0 (); - ffestb_init_0 (); - ffestc_init_0 (); - ffestd_init_0 (); - ffeste_init_0 (); - ffestp_init_0 (); - ffestr_init_0 (); - ffests_init_0 (); - ffestt_init_0 (); - ffestu_init_0 (); - ffestv_init_0 (); - ffestw_init_0 (); -} - -/* ffest_init_1 -- Initialize for entire image invocation - - ffest_init_1(); - - Call just once per invocation of the compiler (not once per invocation - of the front end). - - Gets memory for the list of possibles once and for all, since this - list never gets larger than a certain size (FFEST_maxPOSSIBLES_) - and is not particularly large. Initializes the array of pointers to - this list. Initializes the executable and nonexecutable lists. */ - -void -ffest_init_1 () -{ - ffesta_init_1 (); - ffestb_init_1 (); - ffestc_init_1 (); - ffestd_init_1 (); - ffeste_init_1 (); - ffestp_init_1 (); - ffestr_init_1 (); - ffests_init_1 (); - ffestt_init_1 (); - ffestu_init_1 (); - ffestv_init_1 (); - ffestw_init_1 (); -} - -/* ffest_init_2 -- Initialize for entire image invocation - - ffest_init_2(); - - Call just once per invocation of the compiler (not once per invocation - of the front end). - - Gets memory for the list of possibles once and for all, since this - list never gets larger than a certain size (FFEST_maxPOSSIBLES_) - and is not particularly large. Initializes the array of pointers to - this list. Initializes the executable and nonexecutable lists. */ - -void -ffest_init_2 () -{ - ffesta_init_2 (); - ffestb_init_2 (); - ffestc_init_2 (); - ffestd_init_2 (); - ffeste_init_2 (); - ffestp_init_2 (); - ffestr_init_2 (); - ffests_init_2 (); - ffestt_init_2 (); - ffestu_init_2 (); - ffestv_init_2 (); - ffestw_init_2 (); -} - -/* ffest_init_3 -- Initialize for any program unit - - ffest_init_3(); */ - -void -ffest_init_3 () -{ - ffesta_init_3 (); - ffestb_init_3 (); - ffestc_init_3 (); - ffestd_init_3 (); - ffeste_init_3 (); - ffestp_init_3 (); - ffestr_init_3 (); - ffests_init_3 (); - ffestt_init_3 (); - ffestu_init_3 (); - ffestv_init_3 (); - ffestw_init_3 (); - - ffestw_display_state (); -} - -/* ffest_init_4 -- Initialize for statement functions - - ffest_init_4(); */ - -void -ffest_init_4 () -{ - ffesta_init_4 (); - ffestb_init_4 (); - ffestc_init_4 (); - ffestd_init_4 (); - ffeste_init_4 (); - ffestp_init_4 (); - ffestr_init_4 (); - ffests_init_4 (); - ffestt_init_4 (); - ffestu_init_4 (); - ffestv_init_4 (); - ffestw_init_4 (); -} - -/* Test whether ENTRY statement is valid. - - Returns TRUE if current program unit is known to be FUNCTION or SUBROUTINE. - Else returns FALSE. */ - -bool -ffest_is_entry_valid () -{ - return ffesta_is_entry_valid; -} - -/* ffest_is_inhibited -- Test whether the current possibility is inhibited - - if (!ffest_is_inhibited()) - // implement the statement. - - Just make sure the current possibility has been confirmed. If anyone - really needs to test whether the current possibility is inhibited prior - to confirming it, that indicates a need to begin statement processing - before it is certain that the given possibility is indeed the statement - to be processed. As of this writing, there does not appear to be such - a need. If there is, then when confirming a statement would normally - immediately disable the inhibition (whereas currently we leave the - confirmed statement disabled until we've tried the other possibilities, - to check for ambiguities), we must check to see if the possibility has - already tested for inhibition prior to confirmation and, if so, maintain - inhibition until the end of the statement (which may be forced right - away) and then rerun the entire statement from the beginning. Otherwise, - initial calls to ffestb functions won't have been made, but subsequent - calls (after confirmation) will, which is wrong. Of course, this all - applies only to those statements implemented via multiple calls to - ffestb, although if a statement requiring only a single ffestb call - tested for inhibition prior to confirmation, it would likely mean that - the ffestb call would be completely dropped without this mechanism. */ - -bool -ffest_is_inhibited () -{ - return ffesta_is_inhibited (); -} - -/* ffest_seen_first_exec -- Test whether first executable stmt has been seen - - if (ffest_seen_first_exec()) - // No more spec stmts can be seen. - - In a case where, say, the first statement is PARAMETER(A)=B, FALSE - will be returned while the PARAMETER statement is being run, and TRUE - will be returned if it doesn't confirm and the assignment statement - is being run. */ - -bool -ffest_seen_first_exec () -{ - return ffesta_seen_first_exec; -} - -/* Shut down current parsing possibility, but without bothering the - user with a diagnostic if we're not inhibited. */ - -void -ffest_shutdown () -{ - ffesta_shutdown (); -} - -/* ffest_sym_end_transition -- Update symbol info just before end of unit - - ffesymbol s; - ffest_sym_end_transition(s); */ - -ffesymbol -ffest_sym_end_transition (ffesymbol s) -{ - return ffestu_sym_end_transition (s); -} - -/* ffest_sym_exec_transition -- Update symbol just before first exec stmt - - ffesymbol s; - ffest_sym_exec_transition(s); */ - -ffesymbol -ffest_sym_exec_transition (ffesymbol s) -{ - return ffestu_sym_exec_transition (s); -} - -/* ffest_terminate_0 -- Terminate for entire image invocation - - ffest_terminate_0(); */ - -void -ffest_terminate_0 () -{ - ffesta_terminate_0 (); - ffestb_terminate_0 (); - ffestc_terminate_0 (); - ffestd_terminate_0 (); - ffeste_terminate_0 (); - ffestp_terminate_0 (); - ffestr_terminate_0 (); - ffests_terminate_0 (); - ffestt_terminate_0 (); - ffestu_terminate_0 (); - ffestv_terminate_0 (); - ffestw_terminate_0 (); -} - -/* ffest_terminate_1 -- Terminate for source file - - ffest_terminate_1(); */ - -void -ffest_terminate_1 () -{ - ffesta_terminate_1 (); - ffestb_terminate_1 (); - ffestc_terminate_1 (); - ffestd_terminate_1 (); - ffeste_terminate_1 (); - ffestp_terminate_1 (); - ffestr_terminate_1 (); - ffests_terminate_1 (); - ffestt_terminate_1 (); - ffestu_terminate_1 (); - ffestv_terminate_1 (); - ffestw_terminate_1 (); -} - -/* ffest_terminate_2 -- Terminate for outer program unit - - ffest_terminate_2(); */ - -void -ffest_terminate_2 () -{ - ffesta_terminate_2 (); - ffestb_terminate_2 (); - ffestc_terminate_2 (); - ffestd_terminate_2 (); - ffeste_terminate_2 (); - ffestp_terminate_2 (); - ffestr_terminate_2 (); - ffests_terminate_2 (); - ffestt_terminate_2 (); - ffestu_terminate_2 (); - ffestv_terminate_2 (); - ffestw_terminate_2 (); -} - -/* ffest_terminate_3 -- Terminate for any program unit - - ffest_terminate_3(); */ - -void -ffest_terminate_3 () -{ - ffesta_terminate_3 (); - ffestb_terminate_3 (); - ffestc_terminate_3 (); - ffestd_terminate_3 (); - ffeste_terminate_3 (); - ffestp_terminate_3 (); - ffestr_terminate_3 (); - ffests_terminate_3 (); - ffestt_terminate_3 (); - ffestu_terminate_3 (); - ffestv_terminate_3 (); - ffestw_terminate_3 (); -} - -/* ffest_terminate_4 -- Terminate for statement functions - - ffest_terminate_4(); */ - -void -ffest_terminate_4 () -{ - ffesta_terminate_4 (); - ffestb_terminate_4 (); - ffestc_terminate_4 (); - ffestd_terminate_4 (); - ffeste_terminate_4 (); - ffestp_terminate_4 (); - ffestr_terminate_4 (); - ffests_terminate_4 (); - ffestt_terminate_4 (); - ffestu_terminate_4 (); - ffestv_terminate_4 (); - ffestw_terminate_4 (); -} diff --git a/gcc/f/st.h b/gcc/f/st.h deleted file mode 100755 index 5036b27..0000000 --- a/gcc/f/st.h +++ /dev/null @@ -1,81 +0,0 @@ -/* st.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - st.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_st -#define _H_f_st - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bad.h" -#include "lex.h" -#include "symbol.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffest_confirmed (void); -void ffest_eof (void); -bool ffest_ffebad_start (ffebad errnum); -void ffest_ffebad_here_current_stmt (ffebadIndex i); -void ffest_ffebad_here_doiter (ffebadIndex i, ffesymbol s); -ffelexHandler ffest_first (ffelexToken t); -void ffest_init_0 (void); -void ffest_init_1 (void); -void ffest_init_2 (void); -void ffest_init_3 (void); -void ffest_init_4 (void); -bool ffest_is_entry_valid (void); -bool ffest_is_inhibited (void); -bool ffest_seen_first_exec (void); -void ffest_shutdown (void); -ffesymbol ffest_sym_end_transition (ffesymbol s); -ffesymbol ffest_sym_exec_transition (ffesymbol s); -void ffest_terminate_0 (void); -void ffest_terminate_1 (void); -void ffest_terminate_2 (void); -void ffest_terminate_3 (void); -void ffest_terminate_4 (void); - -/* Define macros. */ - - -/* End of #include file. */ - -#endif diff --git a/gcc/f/sta.c b/gcc/f/sta.c deleted file mode 100755 index 58156f5..0000000 --- a/gcc/f/sta.c +++ /dev/null @@ -1,2000 +0,0 @@ -/* sta.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Analyzes the first two tokens, figures out what statements are - possible, tries parsing the possible statements by calling on - the ffestb functions. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "sta.h" -#include "bad.h" -#include "implic.h" -#include "lex.h" -#include "malloc.h" -#include "stb.h" -#include "stc.h" -#include "std.h" -#include "str.h" -#include "storag.h" -#include "symbol.h" - -/* Externals defined here. */ - -ffelexToken ffesta_tokens[FFESTA_tokensMAX]; /* For use by a possible. */ -ffestrFirst ffesta_first_kw; /* First NAME(S) looked up. */ -ffestrSecond ffesta_second_kw; /* Second NAME(S) looked up. */ -mallocPool ffesta_output_pool; /* Pool for results of stmt handling. */ -mallocPool ffesta_scratch_pool; /* Pool for stmt scratch handling. */ -ffelexToken ffesta_construct_name; -ffelexToken ffesta_label_token; /* Pending label stuff. */ -bool ffesta_seen_first_exec; -bool ffesta_is_entry_valid = FALSE; /* TRUE only in SUBROUTINE/FUNCTION. */ -bool ffesta_line_has_semicolons = FALSE; - -/* Simple definitions and enumerations. */ - -#define FFESTA_ABORT_ON_CONFIRM_ 1 /* 0=slow, tested way; 1=faster way - that might not always work. Here's - the old description of what used - to not work with ==1: (try - "CONTINUE\10 - FORMAT('hi',I11)\END"). Problem - is that the "topology" of the - confirmed stmt's tokens with - regard to CHARACTER, HOLLERITH, - NAME/NAMES/NUMBER tokens (like hex - numbers), isn't traced if we abort - early, then other stmts might get - their grubby hands on those - unprocessed tokens and commit them - improperly. Ideal fix is to rerun - the confirmed stmt and forget the - rest. */ - -#define FFESTA_maxPOSSIBLES_ 8/* Never more than this # of possibles. */ - -/* Internal typedefs. */ - -typedef struct _ffesta_possible_ *ffestaPossible_; - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffesta_possible_ - { - ffestaPossible_ next; - ffestaPossible_ previous; - ffelexHandler handler; - bool named; - }; - -struct _ffesta_possible_root_ - { - ffestaPossible_ first; - ffestaPossible_ last; - ffelexHandler nil; - }; - -/* Static objects accessed by functions in this module. */ - -static bool ffesta_is_inhibited_ = FALSE; -static ffelexToken ffesta_token_0_; /* For use by ffest possibility - handling. */ -static ffestaPossible_ ffesta_possibles_[FFESTA_maxPOSSIBLES_]; -static int ffesta_num_possibles_ = 0; /* Number of possibilities. */ -static struct _ffesta_possible_root_ ffesta_possible_nonexecs_; -static struct _ffesta_possible_root_ ffesta_possible_execs_; -static ffestaPossible_ ffesta_current_possible_; -static ffelexHandler ffesta_current_handler_; -static bool ffesta_confirmed_current_ = FALSE; -static bool ffesta_confirmed_other_ = FALSE; -static ffestaPossible_ ffesta_confirmed_possible_; -static bool ffesta_current_shutdown_ = FALSE; -#if !FFESTA_ABORT_ON_CONFIRM_ -static bool ffesta_is_two_into_statement_ = FALSE; /* For IF, WHERE stmts. */ -static ffelexToken ffesta_twotokens_1_; /* For IF, WHERE stmts. */ -static ffelexToken ffesta_twotokens_2_; /* For IF, WHERE stmts. */ -#endif -static ffestaPooldisp ffesta_outpooldisp_; /* After statement dealt - with. */ -static bool ffesta_inhibit_confirmation_ = FALSE; - -/* Static functions (internal). */ - -static void ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named); -static bool ffesta_inhibited_exec_transition_ (void); -static void ffesta_reset_possibles_ (void); -static ffelexHandler ffesta_save_ (ffelexToken t); -static ffelexHandler ffesta_second_ (ffelexToken t); -#if !FFESTA_ABORT_ON_CONFIRM_ -static ffelexHandler ffesta_send_two_ (ffelexToken t); -#endif - -/* Internal macros. */ - -#define ffesta_add_possible_exec_(fn) (ffesta_add_possible_ (fn, TRUE, TRUE)) -#define ffesta_add_possible_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, TRUE)) -#define ffesta_add_possible_unnamed_exec_(fn) (ffesta_add_possible_ (fn, TRUE, FALSE)) -#define ffesta_add_possible_unnamed_nonexec_(fn) (ffesta_add_possible_ (fn, FALSE, FALSE)) - -/* Add possible statement to appropriate list. */ - -static void -ffesta_add_possible_ (ffelexHandler fn, bool exec, bool named) -{ - ffestaPossible_ p; - - assert (ffesta_num_possibles_ < FFESTA_maxPOSSIBLES_); - - p = ffesta_possibles_[ffesta_num_possibles_++]; - - if (exec) - { - p->next = (ffestaPossible_) &ffesta_possible_execs_.first; - p->previous = ffesta_possible_execs_.last; - } - else - { - p->next = (ffestaPossible_) &ffesta_possible_nonexecs_.first; - p->previous = ffesta_possible_nonexecs_.last; - } - p->next->previous = p; - p->previous->next = p; - - p->handler = fn; - p->named = named; -} - -/* ffesta_inhibited_exec_transition_ -- Do exec transition while inhibited - - if (!ffesta_inhibited_exec_transition_()) // couldn't transition... - - Invokes ffestc_exec_transition, but first enables ffebad and ffesta and - afterwards disables them again. Then returns the result of the - invocation of ffestc_exec_transition. */ - -static bool -ffesta_inhibited_exec_transition_ () -{ - bool result; - - assert (ffebad_inhibit ()); - assert (ffesta_is_inhibited_); - - ffebad_set_inhibit (FALSE); - ffesta_is_inhibited_ = FALSE; - - result = ffestc_exec_transition (); - - ffebad_set_inhibit (TRUE); - ffesta_is_inhibited_ = TRUE; - - return result; -} - -/* ffesta_reset_possibles_ -- Reset (clear) lists of possible statements - - ffesta_reset_possibles_(); - - Clears the lists of executable and nonexecutable statements. */ - -static void -ffesta_reset_possibles_ () -{ - ffesta_num_possibles_ = 0; - - ffesta_possible_execs_.first = ffesta_possible_execs_.last - = (ffestaPossible_) &ffesta_possible_execs_.first; - ffesta_possible_nonexecs_.first = ffesta_possible_nonexecs_.last - = (ffestaPossible_) &ffesta_possible_nonexecs_.first; -} - -/* ffesta_save_ -- Save token on list, pass thru to current handler - - return ffesta_save_; // to lexer. - - Receives a token from the lexer. Saves it in the list of tokens. Calls - the current handler with the token. - - If no shutdown error occurred (via - ffest_ffebad_start), then if the token was EOS or SEMICOLON, mark the - current possible as successful and confirmed but try the next possible - anyway until ambiguities in the form handling are ironed out. */ - -static ffelexHandler -ffesta_save_ (ffelexToken t) -{ - static ffelexToken *saved_tokens = NULL; /* A variable-sized array. */ - static unsigned int num_saved_tokens = 0; /* Number currently saved. */ - static unsigned int max_saved_tokens = 0; /* Maximum to be saved. */ - unsigned int toknum; /* Index into saved_tokens array. */ - ffelexToken eos; /* EOS created on-the-fly for shutdown - purposes. */ - ffelexToken t2; /* Another temporary token (no intersect with - eos, btw). */ - - /* Save the current token. */ - - if (saved_tokens == NULL) - { - saved_tokens - = (ffelexToken *) malloc_new_ksr (malloc_pool_image (), - "FFEST Saved Tokens", - (max_saved_tokens = 8) * sizeof (ffelexToken)); - /* Start off with 8. */ - } - else if (num_saved_tokens >= max_saved_tokens) - { - toknum = max_saved_tokens; - max_saved_tokens <<= 1; /* Multiply by two. */ - assert (max_saved_tokens > toknum); - saved_tokens - = (ffelexToken *) malloc_resize_ksr (malloc_pool_image (), - saved_tokens, - max_saved_tokens * sizeof (ffelexToken), - toknum * sizeof (ffelexToken)); - } - - *(saved_tokens + num_saved_tokens++) = ffelex_token_use (t); - - /* Transmit the current token to the current handler. */ - - ffesta_current_handler_ = (ffelexHandler) (*ffesta_current_handler_) (t); - - /* See if this possible has been shut down, or confirmed in which case we - might as well shut it down anyway to save time. */ - - if ((ffesta_current_shutdown_ || (FFESTA_ABORT_ON_CONFIRM_ - && ffesta_confirmed_current_)) - && !ffelex_expecting_character ()) - { - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - eos = ffelex_token_new_eos (ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffesta_inhibit_confirmation_ = ffesta_current_shutdown_; - (*ffesta_current_handler_) (eos); - ffesta_inhibit_confirmation_ = FALSE; - ffelex_token_kill (eos); - break; - } - } - else - { - - /* If this is an EOS or SEMICOLON token, switch to next handler, else - return self as next handler for lexer. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - return (ffelexHandler) ffesta_save_; - } - } - - next_handler: /* :::::::::::::::::::: */ - - /* Note that a shutdown also happens after seeing the first two tokens - after "IF (expr)" or "WHERE (expr)" where a statement follows, even - though there is no error. This causes the IF or WHERE form to be - implemented first before ffest_first is called for the first token in - the following statement. */ - - if (ffesta_current_shutdown_) - ffesta_current_shutdown_ = FALSE; /* Only after sending EOS! */ - else - assert (ffesta_confirmed_current_); - - if (ffesta_confirmed_current_) - { - ffesta_confirmed_current_ = FALSE; - ffesta_confirmed_other_ = TRUE; - } - - /* Pick next handler. */ - - ffesta_current_possible_ = ffesta_current_possible_->next; - ffesta_current_handler_ = ffesta_current_possible_->handler; - if (ffesta_current_handler_ == NULL) - { /* No handler in this list, try exec list if - not tried yet. */ - if (ffesta_current_possible_ - == (ffestaPossible_) &ffesta_possible_nonexecs_) - { - ffesta_current_possible_ = ffesta_possible_execs_.first; - ffesta_current_handler_ = ffesta_current_possible_->handler; - } - if ((ffesta_current_handler_ == NULL) - || (!ffesta_seen_first_exec - && ((ffesta_confirmed_possible_ != NULL) - || !ffesta_inhibited_exec_transition_ ()))) - /* Don't run execs if: (decoding the "if" ^^^ up here ^^^) - we - have no exec handler available, or - we haven't seen the first - executable statement yet, and - we've confirmed a nonexec - (otherwise even a nonexec would cause a transition), or - a - nonexec-to-exec transition can't be made at the statement context - level (as in an executable statement in the middle of a STRUCTURE - definition); if it can be made, ffestc_exec_transition makes the - corresponding transition at the statement state level so - specification statements are no longer accepted following an - unrecognized statement. (Note: it is valid for f_e_t_ to decide - to always return TRUE by "shrieking" away the statement state - stack until a transitionable state is reached. Or it can leave - the stack as is and return FALSE.) - - If we decide not to run execs, enter this block to rerun the - confirmed statement, if any. */ - { /* At end of both lists! Pick confirmed or - first possible. */ - ffebad_set_inhibit (FALSE); - ffesta_is_inhibited_ = FALSE; - ffesta_confirmed_other_ = FALSE; - ffesta_tokens[0] = ffesta_token_0_; - if (ffesta_confirmed_possible_ == NULL) - { /* No confirmed success, just use first - named possible, or first possible if - no named possibles. */ - ffestaPossible_ possible = ffesta_possible_nonexecs_.first; - ffestaPossible_ first = NULL; - ffestaPossible_ first_named = NULL; - ffestaPossible_ first_exec = NULL; - - for (;;) - { - if (possible->handler == NULL) - { - if (possible == (ffestaPossible_) &ffesta_possible_nonexecs_) - { - possible = first_exec = ffesta_possible_execs_.first; - continue; - } - else - break; - } - if (first == NULL) - first = possible; - if (possible->named - && (first_named == NULL)) - first_named = possible; - - possible = possible->next; - } - - if (first_named != NULL) - ffesta_current_possible_ = first_named; - else if (ffesta_seen_first_exec - && (first_exec != NULL)) - ffesta_current_possible_ = first_exec; - else - ffesta_current_possible_ = first; - - ffesta_current_handler_ = ffesta_current_possible_->handler; - assert (ffesta_current_handler_ != NULL); - } - else - { /* Confirmed success, use it. */ - ffesta_current_possible_ = ffesta_confirmed_possible_; - ffesta_current_handler_ = ffesta_confirmed_possible_->handler; - } - ffesta_reset_possibles_ (); - } - else - { /* Switching from [empty?] list of nonexecs - to nonempty list of execs at this point. */ - ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_); - ffesymbol_set_retractable (ffesta_scratch_pool); - } - } - else - { - ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_); - ffesymbol_set_retractable (ffesta_scratch_pool); - } - - /* Send saved tokens to current handler until either shut down or all - tokens sent. */ - - for (toknum = 0; toknum < num_saved_tokens; ++toknum) - { - t = *(saved_tokens + toknum); - switch (ffelex_token_type (t)) - { - case FFELEX_typeCHARACTER: - ffelex_set_expecting_hollerith (0, '\0', - ffewhere_line_unknown (), - ffewhere_column_unknown ()); - ffesta_current_handler_ - = (ffelexHandler) (*ffesta_current_handler_) (t); - break; - - case FFELEX_typeNAMES: - if (ffelex_is_names_expected ()) - ffesta_current_handler_ - = (ffelexHandler) (*ffesta_current_handler_) (t); - else - { - t2 = ffelex_token_name_from_names (t, 0, 0); - ffesta_current_handler_ - = (ffelexHandler) (*ffesta_current_handler_) (t2); - ffelex_token_kill (t2); - } - break; - - default: - ffesta_current_handler_ - = (ffelexHandler) (*ffesta_current_handler_) (t); - break; - } - - if (!ffesta_is_inhibited_) - ffelex_token_kill (t); /* Won't need this any more. */ - - /* See if this possible has been shut down. */ - - else if ((ffesta_current_shutdown_ || (FFESTA_ABORT_ON_CONFIRM_ - && ffesta_confirmed_current_)) - && !ffelex_expecting_character ()) - { - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - eos = ffelex_token_new_eos (ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffesta_inhibit_confirmation_ = ffesta_current_shutdown_; - (*ffesta_current_handler_) (eos); - ffesta_inhibit_confirmation_ = FALSE; - ffelex_token_kill (eos); - break; - } - goto next_handler; /* :::::::::::::::::::: */ - } - } - - /* Finished sending all the tokens so far. If still trying possibilities, - then if we've just sent an EOS or SEMICOLON token through, go to the - next handler. Otherwise, return self so we can gather and process more - tokens. */ - - if (ffesta_is_inhibited_) - { - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - goto next_handler; /* :::::::::::::::::::: */ - - default: -#if FFESTA_ABORT_ON_CONFIRM_ - assert (!ffesta_confirmed_other_); /* Catch ambiguities. */ -#endif - return (ffelexHandler) ffesta_save_; - } - } - - /* This was the one final possibility, uninhibited, so send the final - handler it sent. */ - - num_saved_tokens = 0; -#if !FFESTA_ABORT_ON_CONFIRM_ - if (ffesta_is_two_into_statement_) - { /* End of the line for the previous two - tokens, resurrect them. */ - ffelexHandler next; - - ffesta_is_two_into_statement_ = FALSE; - next = (ffelexHandler) ffesta_first (ffesta_twotokens_1_); - ffelex_token_kill (ffesta_twotokens_1_); - next = (ffelexHandler) (*next) (ffesta_twotokens_2_); - ffelex_token_kill (ffesta_twotokens_2_); - return (ffelexHandler) next; - } -#endif - - assert (ffesta_current_handler_ != NULL); - return (ffelexHandler) ffesta_current_handler_; -} - -/* ffesta_second_ -- Parse the token after a NAME/NAMES in a statement - - return ffesta_second_; // to lexer. - - The second token cannot be a NAMES, since the first token is a NAME or - NAMES. If the second token is a NAME, look up its name in the list of - second names for use by whoever needs it. - - Then make a list of all the possible statements this could be, based on - looking at the first two tokens. Two lists of possible statements are - created, one consisting of nonexecutable statements, the other consisting - of executable statements. - - If the total number of possibilities is one, just fire up that - possibility by calling its handler function, passing the first two - tokens through it and so on. - - Otherwise, start up a process whereby tokens are passed to the first - possibility on the list until EOS or SEMICOLON is reached or an error - is detected. But inhibit any actual reporting of errors; just record - their existence in the list. If EOS or SEMICOLON is reached with no - errors (other than non-form errors happening downstream, such as an - overflowing value for an integer or a GOTO statement identifying a label - on a FORMAT statement), then that is the only possible statement. Rerun - the statement with error-reporting turned on if any non-form errors were - generated, otherwise just use its results, then erase the list of tokens - memorized during the search process. If a form error occurs, immediately - cancel that possibility by sending EOS as the next token, remember the - error code for that possibility, and try the next possibility on the list, - first sending it the list of tokens memorized while handling the first - possibility, then continuing on as before. - - Ultimately, either the end of the list of possibilities will be reached - without any successful forms being detected, in which case we pick one - based on hueristics (usually the first possibility) and rerun it with - error reporting turned on using the list of memorized tokens so the user - sees the error, or one of the possibilities will effectively succeed. */ - -static ffelexHandler -ffesta_second_ (ffelexToken t) -{ - ffelexHandler next; - ffesymbol s; - - assert (ffelex_token_type (t) != FFELEX_typeNAMES); - - if (ffelex_token_type (t) == FFELEX_typeNAME) - ffesta_second_kw = ffestr_second (t); - - /* Here we use switch on the first keyword name and handle each possible - recognizable name by looking at the second token, and building the list - of possible names accordingly. For now, just put every possible - statement on the list for ambiguity checking. */ - - switch (ffesta_first_kw) - { -#if FFESTR_VXT - case FFESTR_firstACCEPT: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V019); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstALLOCATABLE: - ffestb_args.dimlist.len = FFESTR_firstlALLOCATABLE; - ffestb_args.dimlist.badname = "ALLOCATABLE"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstALLOCATE: - ffestb_args.heap.len = FFESTR_firstlALLOCATE; - ffestb_args.heap.badname = "ALLOCATE"; - ffestb_args.heap.ctx = FFEEXPR_contextALLOCATE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap); - break; -#endif - - case FFESTR_firstASSIGN: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R838); - break; - - case FFESTR_firstBACKSPACE: - ffestb_args.beru.len = FFESTR_firstlBACKSPACE; - ffestb_args.beru.badname = "BACKSPACE"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); - break; - - case FFESTR_firstBLOCK: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_block); - break; - - case FFESTR_firstBLOCKDATA: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_blockdata); - break; - - case FFESTR_firstBYTE: - ffestb_args.decl.len = FFESTR_firstlBYTE; - ffestb_args.decl.type = FFESTP_typeBYTE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - - case FFESTR_firstCALL: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1212); - break; - - case FFESTR_firstCASE: - case FFESTR_firstCASEDEFAULT: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R810); - break; - - case FFESTR_firstCHRCTR: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_chartype); - break; - - case FFESTR_firstCLOSE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R907); - break; - - case FFESTR_firstCOMMON: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R547); - break; - - case FFESTR_firstCMPLX: - ffestb_args.decl.len = FFESTR_firstlCMPLX; - ffestb_args.decl.type = FFESTP_typeCOMPLEX; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - -#if FFESTR_F90 - case FFESTR_firstCONTAINS: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1228); - break; -#endif - - case FFESTR_firstCONTINUE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R841); - break; - - case FFESTR_firstCYCLE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R834); - break; - - case FFESTR_firstDATA: - if (ffe_is_pedantic_not_90 ()) - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R528); - else - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R528); - break; - -#if FFESTR_F90 - case FFESTR_firstDEALLOCATE: - ffestb_args.heap.len = FFESTR_firstlDEALLOCATE; - ffestb_args.heap.badname = "DEALLOCATE"; - ffestb_args.heap.ctx = FFEEXPR_contextDEALLOCATE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_heap); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstDECODE: - ffestb_args.vxtcode.len = FFESTR_firstlDECODE; - ffestb_args.vxtcode.badname = "DECODE"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstDEFINEFILE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V025); - break; - - case FFESTR_firstDELETE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V021); - break; -#endif - case FFESTR_firstDIMENSION: - ffestb_args.R524.len = FFESTR_firstlDIMENSION; - ffestb_args.R524.badname = "DIMENSION"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524); - break; - - case FFESTR_firstDO: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_do); - break; - - case FFESTR_firstDBL: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_double); - break; - - case FFESTR_firstDBLCMPLX: - ffestb_args.decl.len = FFESTR_firstlDBLCMPLX; - ffestb_args.decl.type = FFESTP_typeDBLCMPLX; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype); - break; - - case FFESTR_firstDBLPRCSN: - ffestb_args.decl.len = FFESTR_firstlDBLPRCSN; - ffestb_args.decl.type = FFESTP_typeDBLPRCSN; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_dbltype); - break; - - case FFESTR_firstDOWHILE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_dowhile); - break; - - case FFESTR_firstELSE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_else); - break; - - case FFESTR_firstELSEIF: - ffestb_args.elsexyz.second = FFESTR_secondIF; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz); - break; - -#if FFESTR_F90 - case FFESTR_firstELSEWHERE: - ffestb_args.elsexyz.second = FFESTR_secondWHERE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_elsexyz); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstENCODE: - ffestb_args.vxtcode.len = FFESTR_firstlENCODE; - ffestb_args.vxtcode.badname = "ENCODE"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_vxtcode); - break; -#endif - - case FFESTR_firstEND: - if ((ffelex_token_type (ffesta_token_0_) == FFELEX_typeNAMES) - || (ffelex_token_type (t) != FFELEX_typeNAME)) - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end); - else - { - switch (ffesta_second_kw) - { - case FFESTR_secondBLOCK: - case FFESTR_secondBLOCKDATA: - case FFESTR_secondDO: - case FFESTR_secondFILE: - case FFESTR_secondFUNCTION: - case FFESTR_secondIF: -#if FFESTR_F90 - case FFESTR_secondMODULE: -#endif - case FFESTR_secondPROGRAM: - case FFESTR_secondSELECT: - case FFESTR_secondSUBROUTINE: -#if FFESTR_F90 - case FFESTR_secondWHERE: -#endif - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_end); - break; - - default: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_end); - break; - } - } - break; - - case FFESTR_firstENDBLOCK: - ffestb_args.endxyz.len = FFESTR_firstlENDBLOCK; - ffestb_args.endxyz.second = FFESTR_secondBLOCK; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - - case FFESTR_firstENDBLOCKDATA: - ffestb_args.endxyz.len = FFESTR_firstlENDBLOCKDATA; - ffestb_args.endxyz.second = FFESTR_secondBLOCKDATA; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - - case FFESTR_firstENDDO: - ffestb_args.endxyz.len = FFESTR_firstlENDDO; - ffestb_args.endxyz.second = FFESTR_secondDO; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - - case FFESTR_firstENDFILE: - ffestb_args.beru.len = FFESTR_firstlENDFILE; - ffestb_args.beru.badname = "ENDFILE"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); - break; - - case FFESTR_firstENDFUNCTION: - ffestb_args.endxyz.len = FFESTR_firstlENDFUNCTION; - ffestb_args.endxyz.second = FFESTR_secondFUNCTION; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - - case FFESTR_firstENDIF: - ffestb_args.endxyz.len = FFESTR_firstlENDIF; - ffestb_args.endxyz.second = FFESTR_secondIF; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - -#if FFESTR_F90 - case FFESTR_firstENDINTERFACE: - ffestb_args.endxyz.len = FFESTR_firstlENDINTERFACE; - ffestb_args.endxyz.second = FFESTR_secondINTERFACE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstENDMAP: - ffestb_args.endxyz.len = FFESTR_firstlENDMAP; - ffestb_args.endxyz.second = FFESTR_secondMAP; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstENDMODULE: - ffestb_args.endxyz.len = FFESTR_firstlENDMODULE; - ffestb_args.endxyz.second = FFESTR_secondMODULE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - - case FFESTR_firstENDPROGRAM: - ffestb_args.endxyz.len = FFESTR_firstlENDPROGRAM; - ffestb_args.endxyz.second = FFESTR_secondPROGRAM; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - - case FFESTR_firstENDSELECT: - ffestb_args.endxyz.len = FFESTR_firstlENDSELECT; - ffestb_args.endxyz.second = FFESTR_secondSELECT; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - -#if FFESTR_VXT - case FFESTR_firstENDSTRUCTURE: - ffestb_args.endxyz.len = FFESTR_firstlENDSTRUCTURE; - ffestb_args.endxyz.second = FFESTR_secondSTRUCTURE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - - case FFESTR_firstENDSUBROUTINE: - ffestb_args.endxyz.len = FFESTR_firstlENDSUBROUTINE; - ffestb_args.endxyz.second = FFESTR_secondSUBROUTINE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; - -#if FFESTR_F90 - case FFESTR_firstENDTYPE: - ffestb_args.endxyz.len = FFESTR_firstlENDTYPE; - ffestb_args.endxyz.second = FFESTR_secondTYPE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstENDUNION: - ffestb_args.endxyz.len = FFESTR_firstlENDUNION; - ffestb_args.endxyz.second = FFESTR_secondUNION; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstENDWHERE: - ffestb_args.endxyz.len = FFESTR_firstlENDWHERE; - ffestb_args.endxyz.second = FFESTR_secondWHERE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_endxyz); - break; -#endif - - case FFESTR_firstENTRY: - ffestb_args.dummy.len = FFESTR_firstlENTRY; - ffestb_args.dummy.badname = "ENTRY"; - ffestb_args.dummy.is_subr = ffestc_is_entry_in_subr (); - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy); - break; - - case FFESTR_firstEQUIVALENCE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R544); - break; - - case FFESTR_firstEXIT: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R835); - break; - - case FFESTR_firstEXTERNAL: - ffestb_args.varlist.len = FFESTR_firstlEXTERNAL; - ffestb_args.varlist.badname = "EXTERNAL"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; - -#if FFESTR_VXT - case FFESTR_firstFIND: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V026); - break; -#endif - - /* WARNING: don't put anything that might cause an item to precede - FORMAT in the list of possible statements (it's added below) without - making sure FORMAT still is first. It has to run with - ffelex_set_names_pure(TRUE), to make sure the lexer delivers NAMES - tokens. */ - - case FFESTR_firstFORMAT: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1001); - break; - - case FFESTR_firstFUNCTION: - ffestb_args.dummy.len = FFESTR_firstlFUNCTION; - ffestb_args.dummy.badname = "FUNCTION"; - ffestb_args.dummy.is_subr = FALSE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy); - break; - - case FFESTR_firstGOTO: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_goto); - break; - - case FFESTR_firstIF: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_if); - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R840); - break; - - case FFESTR_firstIMPLICIT: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_R539); - break; - - case FFESTR_firstINCLUDE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_S3P4); - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - case FFELEX_typeNAME: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - break; - - default: - break; - } - break; - - case FFESTR_firstINQUIRE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R923); - break; - - case FFESTR_firstINTGR: - ffestb_args.decl.len = FFESTR_firstlINTGR; - ffestb_args.decl.type = FFESTP_typeINTEGER; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffestb_args.varlist.len = FFESTR_firstlINTENT; - ffestb_args.varlist.badname = "INTENT"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstINTERFACE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1202); - break; -#endif - - case FFESTR_firstINTRINSIC: - ffestb_args.varlist.len = FFESTR_firstlINTRINSIC; - ffestb_args.varlist.badname = "INTRINSIC"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; - - case FFESTR_firstLGCL: - ffestb_args.decl.len = FFESTR_firstlLGCL; - ffestb_args.decl.type = FFESTP_typeLOGICAL; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - -#if FFESTR_VXT - case FFESTR_firstMAP: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V012); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstMODULE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_module); - break; -#endif - - case FFESTR_firstNAMELIST: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R542); - break; - -#if FFESTR_F90 - case FFESTR_firstNULLIFY: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R624); - break; -#endif - - case FFESTR_firstOPEN: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R904); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestb_args.varlist.len = FFESTR_firstlOPTIONAL; - ffestb_args.varlist.badname = "OPTIONAL"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; -#endif - - case FFESTR_firstPARAMETER: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R537); - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V027); - break; - - case FFESTR_firstPAUSE: - ffestb_args.halt.len = FFESTR_firstlPAUSE; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt); - break; - -#if FFESTR_F90 - case FFESTR_firstPOINTER: - ffestb_args.dimlist.len = FFESTR_firstlPOINTER; - ffestb_args.dimlist.badname = "POINTER"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist); - break; -#endif - - case FFESTR_firstPRINT: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R911); - break; - -#if HARD_F90 - case FFESTR_firstPRIVATE: - ffestb_args.varlist.len = FFESTR_firstlPRIVATE; - ffestb_args.varlist.badname = "ACCESS"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; -#endif - - case FFESTR_firstPROGRAM: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1102); - break; - -#if HARD_F90 - case FFESTR_firstPUBLIC: - ffestb_args.varlist.len = FFESTR_firstlPUBLIC; - ffestb_args.varlist.badname = "ACCESS"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_varlist); - break; -#endif - - case FFESTR_firstREAD: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R909); - break; - - case FFESTR_firstREAL: - ffestb_args.decl.len = FFESTR_firstlREAL; - ffestb_args.decl.type = FFESTP_typeREAL; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - -#if FFESTR_VXT - case FFESTR_firstRECORD: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V016); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstRECURSIVE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_recursive); - break; -#endif - - case FFESTR_firstRETURN: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R1227); - break; - - case FFESTR_firstREWIND: - ffestb_args.beru.len = FFESTR_firstlREWIND; - ffestb_args.beru.badname = "REWIND"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); - break; - -#if FFESTR_VXT - case FFESTR_firstREWRITE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V018); - break; -#endif - - case FFESTR_firstSAVE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R522); - break; - - case FFESTR_firstSELECT: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809); - break; - - case FFESTR_firstSELECTCASE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R809); - break; - -#if HARD_F90 - case FFESTR_firstSEQUENCE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R423B); - break; -#endif - - case FFESTR_firstSTOP: - ffestb_args.halt.len = FFESTR_firstlSTOP; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_halt); - break; - -#if FFESTR_VXT - case FFESTR_firstSTRUCTURE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V003); - break; -#endif - - case FFESTR_firstSUBROUTINE: - ffestb_args.dummy.len = FFESTR_firstlSUBROUTINE; - ffestb_args.dummy.badname = "SUBROUTINE"; - ffestb_args.dummy.is_subr = TRUE; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dummy); - break; - -#if FFESTR_F90 - case FFESTR_firstTARGET: - ffestb_args.dimlist.len = FFESTR_firstlTARGET; - ffestb_args.dimlist.badname = "TARGET"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_dimlist); - break; -#endif - - case FFESTR_firstTYPE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_V020); - break; - -#if FFESTR_F90 - case FFESTR_firstTYPE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_type); - break; -#endif - -#if HARD_F90 - case FFESTR_firstTYPE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_typetype); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstUNLOCK: - ffestb_args.beru.len = FFESTR_firstlUNLOCK; - ffestb_args.beru.badname = "UNLOCK"; - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_beru); - break; -#endif - -#if FFESTR_VXT - case FFESTR_firstUNION: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V009); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstUSE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R1107); - break; -#endif - - case FFESTR_firstVIRTUAL: - ffestb_args.R524.len = FFESTR_firstlVIRTUAL; - ffestb_args.R524.badname = "VIRTUAL"; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_R524); - break; - - case FFESTR_firstVOLATILE: - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_V014); - break; - -#if HARD_F90 - case FFESTR_firstWHERE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_where); - break; -#endif - - case FFESTR_firstWORD: - ffestb_args.decl.len = FFESTR_firstlWORD; - ffestb_args.decl.type = FFESTP_typeWORD; - ffesta_add_possible_nonexec_ ((ffelexHandler) ffestb_decl_gentype); - break; - - case FFESTR_firstWRITE: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_R910); - break; - - default: - break; - } - - /* Now check the default cases, which are always "live" (meaning that no - other possibility can override them). These are where the second token - is OPEN_PAREN, PERCENT, EQUALS, POINTS, or COLON. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - s = ffesymbol_lookup_local (ffesta_token_0_); - if (((s == NULL) || (ffesymbol_dims (s) == NULL)) - && !ffesta_seen_first_exec) - { /* Not known as array; may be stmt function. */ - ffesta_add_possible_unnamed_nonexec_ ((ffelexHandler) ffestb_R1229); - - /* If the symbol is (or will be due to implicit typing) of - CHARACTER type, then the statement might be an assignment - statement. If so, since it can't be a function invocation nor - an array element reference, the open paren following the symbol - name must be followed by an expression and a colon. Without the - colon (which cannot appear in a stmt function definition), the - let stmt rejects. So CHARACTER_NAME(...)=expr, unlike any other - type, is not ambiguous alone. */ - - if (ffeimplic_peek_symbol_type (s, - ffelex_token_text (ffesta_token_0_)) - == FFEINFO_basictypeCHARACTER) - ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); - } - else /* Not statement function if known as an - array. */ - ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); - break; - -#if FFESTR_F90 - case FFELEX_typePERCENT: -#endif - case FFELEX_typeEQUALS: -#if FFESTR_F90 - case FFELEX_typePOINTS: -#endif - ffesta_add_possible_unnamed_exec_ ((ffelexHandler) ffestb_let); - break; - - case FFELEX_typeCOLON: - ffesta_add_possible_exec_ ((ffelexHandler) ffestb_construct); - break; - - default: - ; - } - - /* Now see how many possibilities are on the list. */ - - switch (ffesta_num_possibles_) - { - case 0: /* None, so invalid statement. */ - no_stmts: /* :::::::::::::::::::: */ - ffesta_tokens[0] = ffesta_token_0_; - ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_token_0_, t); - next = (ffelexHandler) ffelex_swallow_tokens (NULL, - (ffelexHandler) ffesta_zero); - break; - - case 1: /* One, so just do it! */ - ffesta_tokens[0] = ffesta_token_0_; - next = ffesta_possible_execs_.first->handler; - if (next == NULL) - { /* Have a nonexec stmt. */ - next = ffesta_possible_nonexecs_.first->handler; - assert (next != NULL); - } - else if (ffesta_seen_first_exec) - ; /* Have an exec stmt after exec transition. */ - else if (!ffestc_exec_transition ()) - /* 1 exec stmt only, but not valid in context, so pretend as though - statement is unrecognized. */ - goto no_stmts; /* :::::::::::::::::::: */ - break; - - default: /* More than one, so try them in order. */ - ffesta_confirmed_possible_ = NULL; - ffesta_current_possible_ = ffesta_possible_nonexecs_.first; - ffesta_current_handler_ = ffesta_current_possible_->handler; - if (ffesta_current_handler_ == NULL) - { - ffesta_current_possible_ = ffesta_possible_execs_.first; - ffesta_current_handler_ = ffesta_current_possible_->handler; - assert (ffesta_current_handler_ != NULL); - if (!ffesta_seen_first_exec) - { /* Need to do exec transition now. */ - ffesta_tokens[0] = ffesta_token_0_; - if (!ffestc_exec_transition ()) - goto no_stmts; /* :::::::::::::::::::: */ - } - } - ffesta_tokens[0] = ffelex_token_use (ffesta_token_0_); - next = (ffelexHandler) ffesta_save_; - ffebad_set_inhibit (TRUE); - ffesta_is_inhibited_ = TRUE; - break; - } - - ffesta_output_pool - = malloc_pool_new ("Statement Output", ffe_pool_program_unit (), 1024); - ffesta_scratch_pool - = malloc_pool_new ("Statement Scratch", ffe_pool_program_unit (), 1024); - ffesta_outpooldisp_ = FFESTA_pooldispDISCARD; - - if (ffesta_is_inhibited_) - ffesymbol_set_retractable (ffesta_scratch_pool); - - ffelex_set_names (FALSE); /* Most handlers will want this. If not, - they have to set it TRUE again (its value - at the beginning of a statement). */ - - return (ffelexHandler) (*next) (t); -} - -/* ffesta_send_two_ -- Send the two tokens saved by ffesta_two after all - - return ffesta_send_two_; // to lexer. - - Currently, if this function gets called, it means that the two tokens - saved by ffesta_two did not have their handlers derailed by - ffesta_save_, which probably means they weren't sent by ffesta_save_ - but directly by the lexer, which probably means the original statement - (which should be IF (expr) or WHERE (expr)) somehow evaluated to only - one possibility in ffesta_second_ or somebody optimized FFEST to - immediately revert to one possibility upon confirmation but forgot to - change this function (and thus perhaps the entire resubmission - mechanism). */ - -#if !FFESTA_ABORT_ON_CONFIRM_ -static ffelexHandler -ffesta_send_two_ (ffelexToken t) -{ - assert ("what am I doing here?" == NULL); - return NULL; -} - -#endif -/* ffesta_confirmed -- Confirm current possibility as only one - - ffesta_confirmed(); - - Sets the confirmation flag. During debugging for ambiguous constructs, - asserts that the confirmation flag for a previous possibility has not - yet been set. */ - -void -ffesta_confirmed () -{ - if (ffesta_inhibit_confirmation_) - return; - ffesta_confirmed_current_ = TRUE; - assert (!ffesta_confirmed_other_ - || (ffesta_confirmed_possible_ == ffesta_current_possible_)); - ffesta_confirmed_possible_ = ffesta_current_possible_; -} - -/* ffesta_eof -- End of (non-INCLUDEd) source file - - ffesta_eof(); - - Call after piping tokens through ffest_first, where the most recent - token sent through must be EOS. - - 20-Feb-91 JCB 1.1 - Put new EOF token in ffesta_tokens[0], not NULL, because too much - code expects something there for error reporting and the like. Also, - do basically the same things ffest_second and ffesta_zero do for - processing a statement (make and destroy pools, et cetera). */ - -void -ffesta_eof () -{ - ffesta_tokens[0] = ffelex_token_new_eof (); - - ffesta_output_pool - = malloc_pool_new ("Statement Output", ffe_pool_program_unit (), 1024); - ffesta_scratch_pool - = malloc_pool_new ("Statement Scratch", ffe_pool_program_unit (), 1024); - ffesta_outpooldisp_ = FFESTA_pooldispDISCARD; - - ffestc_eof (); - - if (ffesta_tokens[0] != NULL) - ffelex_token_kill (ffesta_tokens[0]); - - if (ffesta_output_pool != NULL) - { - if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD) - malloc_pool_kill (ffesta_output_pool); - ffesta_output_pool = NULL; - } - - if (ffesta_scratch_pool != NULL) - { - malloc_pool_kill (ffesta_scratch_pool); - ffesta_scratch_pool = NULL; - } - - if (ffesta_label_token != NULL) - { - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; - } - - if (ffe_is_ffedebug ()) - { - ffestorag_report (); -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffesymbol_report_all (); -#endif - } -} - -/* ffesta_ffebad_here_current_stmt -- ffebad_here with ptr to current stmt - - ffesta_ffebad_here_current_stmt(0); - - Outsiders can call this fn if they have no more convenient place to - point to (via a token or pair of ffewhere objects) and they know a - current, useful statement is being evaluted by ffest (i.e. they are - being called from ffestb, ffestc, ffestd, ... functions). */ - -void -ffesta_ffebad_here_current_stmt (ffebadIndex i) -{ - assert (ffesta_tokens[0] != NULL); - ffebad_here (i, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); -} - -/* ffesta_ffebad_start -- Start a possibly inhibited error report - - if (ffesta_ffebad_start(FFEBAD_SOME_ERROR)) - { - ffebad_here, ffebad_string ...; - ffebad_finish(); - } - - Call if the error might indicate that ffest is evaluating the wrong - statement form, instead of calling ffebad_start directly. If ffest - is choosing between forms, it will return FALSE, send an EOS/SEMICOLON - token through as the next token (if the current one isn't already one - of those), and try another possible form. Otherwise, ffebad_start is - called with the argument and TRUE returned. */ - -bool -ffesta_ffebad_start (ffebad errnum) -{ - if (!ffesta_is_inhibited_) - { - ffebad_start (errnum); - return TRUE; - } - - if (!ffesta_confirmed_current_) - ffesta_current_shutdown_ = TRUE; - - return FALSE; -} - -/* ffesta_first -- Parse the first token in a statement - - return ffesta_first; // to lexer. */ - -ffelexHandler -ffesta_first (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSEMICOLON: - case FFELEX_typeEOS: - ffesta_tokens[0] = ffelex_token_use (t); - if (ffesta_label_token != NULL) - { - ffebad_start (FFEBAD_LABEL_WITHOUT_STMT); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_string (ffelex_token_text (ffesta_label_token)); - ffebad_here (1, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffesta_token_0_ = ffelex_token_use (t); - ffesta_first_kw = ffestr_first (t); - return (ffelexHandler) ffesta_second_; - - case FFELEX_typeNUMBER: - if (ffesta_line_has_semicolons - && !ffe_is_free_form () - && ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_LABEL_WRONG_PLACE); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffelex_token_text (t)); - ffebad_finish (); - } - if (ffesta_label_token == NULL) - { - ffesta_label_token = ffelex_token_use (t); - return (ffelexHandler) ffesta_first; - } - else - { - ffebad_start (FFEBAD_EXTRA_LABEL_DEF); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_string (ffelex_token_text (t)); - ffebad_here (1, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_string (ffelex_token_text (ffesta_label_token)); - ffebad_finish (); - - return (ffelexHandler) ffesta_first; - } - - default: /* Invalid first token. */ - ffesta_tokens[0] = ffelex_token_use (t); - ffebad_start (FFEBAD_STMT_BEGINS_BAD); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffesta_init_0 -- Initialize for entire image invocation - - ffesta_init_0(); - - Call just once per invocation of the compiler (not once per invocation - of the front end). - - Gets memory for the list of possibles once and for all, since this - list never gets larger than a certain size (FFESTA_maxPOSSIBLES_) - and is not particularly large. Initializes the array of pointers to - this list. Initializes the executable and nonexecutable lists. */ - -void -ffesta_init_0 () -{ - ffestaPossible_ ptr; - int i; - - ptr = (ffestaPossible_) malloc_new_kp (malloc_pool_image (), - "FFEST possibles", - FFESTA_maxPOSSIBLES_ - * sizeof (*ptr)); - - for (i = 0; i < FFESTA_maxPOSSIBLES_; ++i) - ffesta_possibles_[i] = ptr++; - - ffesta_possible_execs_.first = ffesta_possible_execs_.last - = (ffestaPossible_) &ffesta_possible_execs_.first; - ffesta_possible_nonexecs_.first = ffesta_possible_nonexecs_.last - = (ffestaPossible_) &ffesta_possible_nonexecs_.first; - ffesta_possible_execs_.nil = ffesta_possible_nonexecs_.nil = NULL; -} - -/* ffesta_init_3 -- Initialize for any program unit - - ffesta_init_3(); */ - -void -ffesta_init_3 () -{ - ffesta_output_pool = NULL; /* May be doing this just before reaching */ - ffesta_scratch_pool = NULL; /* ffesta_zero or ffesta_two. */ - /* NOTE: we let the ffe_terminate_2 action of killing the program_unit pool - handle the killing of the output and scratch pools for us, which is why - we don't have a terminate_3 action to do so. */ - ffesta_construct_name = NULL; - ffesta_label_token = NULL; - ffesta_seen_first_exec = FALSE; -} - -/* ffesta_is_inhibited -- Test whether the current possibility is inhibited - - if (!ffesta_is_inhibited()) - // implement the statement. - - Just make sure the current possibility has been confirmed. If anyone - really needs to test whether the current possibility is inhibited prior - to confirming it, that indicates a need to begin statement processing - before it is certain that the given possibility is indeed the statement - to be processed. As of this writing, there does not appear to be such - a need. If there is, then when confirming a statement would normally - immediately disable the inhibition (whereas currently we leave the - confirmed statement disabled until we've tried the other possibilities, - to check for ambiguities), we must check to see if the possibility has - already tested for inhibition prior to confirmation and, if so, maintain - inhibition until the end of the statement (which may be forced right - away) and then rerun the entire statement from the beginning. Otherwise, - initial calls to ffestb functions won't have been made, but subsequent - calls (after confirmation) will, which is wrong. Of course, this all - applies only to those statements implemented via multiple calls to - ffestb, although if a statement requiring only a single ffestb call - tested for inhibition prior to confirmation, it would likely mean that - the ffestb call would be completely dropped without this mechanism. */ - -bool -ffesta_is_inhibited () -{ - assert (ffesta_confirmed_current_ || ffesta_inhibit_confirmation_); - return ffesta_is_inhibited_; -} - -/* ffesta_ffebad_1p -- Issue diagnostic with one source character - - ffelexToken names_token; - ffeTokenLength index; - ffelexToken next_token; - ffesta_ffebad_1p(FFEBAD_SOME_ERROR,names_token,index,next_token); - - Equivalent to "if (ffest_ffebad_start(FFEBAD_SOME_ERROR))" followed by - sending one argument, the location of index with names_token, if TRUE is - returned. If index is equal to the length of names_token, meaning it - points to the end of the token, then uses the location in next_token - (which should be the token sent by the lexer after it sent names_token) - instead. */ - -void -ffesta_ffebad_1p (ffebad errnum, ffelexToken names_token, ffeTokenLength index, - ffelexToken next_token) -{ - ffewhereLine line; - ffewhereColumn col; - - assert (index <= ffelex_token_length (names_token)); - - if (ffesta_ffebad_start (errnum)) - { - if (index == ffelex_token_length (names_token)) - { - assert (next_token != NULL); - line = ffelex_token_where_line (next_token); - col = ffelex_token_where_column (next_token); - ffebad_here (0, line, col); - } - else - { - ffewhere_set_from_track (&line, &col, - ffelex_token_where_line (names_token), - ffelex_token_where_column (names_token), - ffelex_token_wheretrack (names_token), - index); - ffebad_here (0, line, col); - ffewhere_line_kill (line); - ffewhere_column_kill (col); - } - ffebad_finish (); - } -} - -void -ffesta_ffebad_1sp (ffebad errnum, char *s, ffelexToken names_token, - ffeTokenLength index, ffelexToken next_token) -{ - ffewhereLine line; - ffewhereColumn col; - - assert (index <= ffelex_token_length (names_token)); - - if (ffesta_ffebad_start (errnum)) - { - ffebad_string (s); - if (index == ffelex_token_length (names_token)) - { - assert (next_token != NULL); - line = ffelex_token_where_line (next_token); - col = ffelex_token_where_column (next_token); - ffebad_here (0, line, col); - } - else - { - ffewhere_set_from_track (&line, &col, - ffelex_token_where_line (names_token), - ffelex_token_where_column (names_token), - ffelex_token_wheretrack (names_token), - index); - ffebad_here (0, line, col); - ffewhere_line_kill (line); - ffewhere_column_kill (col); - } - ffebad_finish (); - } -} - -void -ffesta_ffebad_1st (ffebad errnum, char *s, ffelexToken t) -{ - if (ffesta_ffebad_start (errnum)) - { - ffebad_string (s); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } -} - -/* ffesta_ffebad_1t -- Issue diagnostic with one source token - - ffelexToken t; - ffesta_ffebad_1t(FFEBAD_SOME_ERROR,t); - - Equivalent to "if (ffesta_ffebad_start(FFEBAD_SOME_ERROR))" followed by - sending one argument, the location of the token t, if TRUE is returned. */ - -void -ffesta_ffebad_1t (ffebad errnum, ffelexToken t) -{ - if (ffesta_ffebad_start (errnum)) - { - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } -} - -void -ffesta_ffebad_2st (ffebad errnum, char *s, ffelexToken t1, ffelexToken t2) -{ - if (ffesta_ffebad_start (errnum)) - { - ffebad_string (s); - ffebad_here (0, ffelex_token_where_line (t1), ffelex_token_where_column (t1)); - ffebad_here (1, ffelex_token_where_line (t2), ffelex_token_where_column (t2)); - ffebad_finish (); - } -} - -/* ffesta_ffebad_2t -- Issue diagnostic with two source tokens - - ffelexToken t1, t2; - ffesta_ffebad_2t(FFEBAD_SOME_ERROR,t1,t2); - - Equivalent to "if (ffesta_ffebad_start(FFEBAD_SOME_ERROR))" followed by - sending two argument, the locations of the tokens t1 and t2, if TRUE is - returned. */ - -void -ffesta_ffebad_2t (ffebad errnum, ffelexToken t1, ffelexToken t2) -{ - if (ffesta_ffebad_start (errnum)) - { - ffebad_here (0, ffelex_token_where_line (t1), ffelex_token_where_column (t1)); - ffebad_here (1, ffelex_token_where_line (t2), ffelex_token_where_column (t2)); - ffebad_finish (); - } -} - -ffestaPooldisp -ffesta_outpooldisp () -{ - return ffesta_outpooldisp_; -} - -void -ffesta_set_outpooldisp (ffestaPooldisp d) -{ - ffesta_outpooldisp_ = d; -} - -/* Shut down current parsing possibility, but without bothering the - user with a diagnostic if we're not inhibited. */ - -void -ffesta_shutdown () -{ - if (ffesta_is_inhibited_) - ffesta_current_shutdown_ = TRUE; -} - -/* ffesta_two -- Deal with the first two tokens after a swallowed statement - - return ffesta_two(first_token,second_token); // to lexer. - - Like ffesta_zero, except instead of expecting an EOS or SEMICOLON, it - expects the first two tokens of a statement that is part of another - statement: the first two tokens of statement in "IF (expr) statement" or - "WHERE (expr) statement", in particular. The first token must be a NAME - or NAMES, the second can be basically anything. The statement type MUST - be confirmed by now. - - If we're not inhibited, just handle things as if we were ffesta_zero - and saw an EOS just before the two tokens. - - If we're inhibited, set ffesta_current_shutdown_ to shut down the current - statement and continue with other possibilities, then (presumably) come - back to this one for real when not inhibited. */ - -ffelexHandler -ffesta_two (ffelexToken first, ffelexToken second) -{ -#if FFESTA_ABORT_ON_CONFIRM_ - ffelexHandler next; -#endif - - assert ((ffelex_token_type (first) == FFELEX_typeNAME) - || (ffelex_token_type (first) == FFELEX_typeNAMES)); - assert (ffesta_tokens[0] != NULL); - - if (ffesta_is_inhibited_) /* Oh, not really done with statement. */ - { - ffesta_current_shutdown_ = TRUE; - /* To catch the EOS on shutdown. */ - return (ffelexHandler) ffelex_swallow_tokens (second, - (ffelexHandler) ffesta_zero); - } - - ffestw_display_state (); - - ffelex_token_kill (ffesta_tokens[0]); - - if (ffesta_output_pool != NULL) - { - if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD) - malloc_pool_kill (ffesta_output_pool); - ffesta_output_pool = NULL; - } - - if (ffesta_scratch_pool != NULL) - { - malloc_pool_kill (ffesta_scratch_pool); - ffesta_scratch_pool = NULL; - } - - ffesta_reset_possibles_ (); - ffesta_confirmed_current_ = FALSE; - - /* What happens here is somewhat interesting. We effectively derail the - line of handlers for these two tokens, the first two in a statement, by - setting a flag to TRUE. This flag tells ffesta_save_ (or, conceivably, - the lexer via ffesta_second_'s case 1:, where it has only one possible - kind of statement -- someday this will be more likely, i.e. after - confirmation causes an immediate switch to only the one context rather - than just setting a flag and running through the remaining possibles to - look for ambiguities) that the last two tokens it sent did not reach the - truly desired targets (ffest_first and ffesta_second_) since that would - otherwise attempt to recursively invoke ffesta_save_ in most cases, - while the existing ffesta_save_ was still alive and making use of static - (nonrecursive) variables. Instead, ffesta_save_, upon seeing this flag - set TRUE, sets it to FALSE and resubmits the two tokens copied here to - ffest_first and, presumably, ffesta_second_, kills them, and returns the - handler returned by the handler for the second token. Thus, even though - ffesta_save_ is still (likely to be) recursively invoked, the former - invocation is past the use of any static variables possibly changed - during the first-two-token invocation of the latter invocation. */ - -#if FFESTA_ABORT_ON_CONFIRM_ - /* Shouldn't be in ffesta_save_ at all here. */ - - next = (ffelexHandler) ffesta_first (first); - return (ffelexHandler) (*next) (second); -#else - ffesta_twotokens_1_ = ffelex_token_use (first); - ffesta_twotokens_2_ = ffelex_token_use (second); - - ffesta_is_two_into_statement_ = TRUE; - return (ffelexHandler) ffesta_send_two_; /* Shouldn't get called. */ -#endif -} - -/* ffesta_zero -- Deal with the end of a swallowed statement - - return ffesta_zero; // to lexer. - - NOTICE that this code is COPIED, largely, into a - similar function named ffesta_two that gets invoked in place of - _zero_ when the end of the statement happens before EOS or SEMICOLON and - to tokens into the next statement have been read (as is the case with the - logical-IF and WHERE-stmt statements). So any changes made here should - probably be made in _two_ at the same time. */ - -ffelexHandler -ffesta_zero (ffelexToken t) -{ - assert ((ffelex_token_type (t) == FFELEX_typeEOS) - || (ffelex_token_type (t) == FFELEX_typeSEMICOLON)); - assert (ffesta_tokens[0] != NULL); - - if (ffesta_is_inhibited_) - ffesymbol_retract (TRUE); - else - ffestw_display_state (); - - /* Do CONTINUE if nothing else. This is done specifically so that "IF - (...) BLAH" causes the same things to happen as if "IF (...) CONTINUE" - was done, so that tracking of labels and such works. (Try a small - program like "DO 10 ...", "IF (...) BLAH", "10 CONTINUE", "END".) - - But it turns out that just testing "!ffesta_confirmed_current_" - isn't enough, because then typing "GOTO" instead of "BLAH" above - doesn't work -- the statement is confirmed (we know the user - attempted a GOTO) but ffestc hasn't seen it. So, instead, just - always tell ffestc to do "any" statement it needs to reset. */ - - if (!ffesta_is_inhibited_ - && ffesta_seen_first_exec) - { - ffestc_any (); - } - - ffelex_token_kill (ffesta_tokens[0]); - - if (ffesta_is_inhibited_) /* Oh, not really done with statement. */ - return (ffelexHandler) ffesta_zero; /* Call me again when done! */ - - if (ffesta_output_pool != NULL) - { - if (ffesta_outpooldisp_ == FFESTA_pooldispDISCARD) - malloc_pool_kill (ffesta_output_pool); - ffesta_output_pool = NULL; - } - - if (ffesta_scratch_pool != NULL) - { - malloc_pool_kill (ffesta_scratch_pool); - ffesta_scratch_pool = NULL; - } - - ffesta_reset_possibles_ (); - ffesta_confirmed_current_ = FALSE; - - if (ffelex_token_type (t) == FFELEX_typeSEMICOLON) - { - ffesta_line_has_semicolons = TRUE; - if (ffe_is_pedantic_not_90 ()) - { - ffebad_start (FFEBAD_SEMICOLON); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - } - else - ffesta_line_has_semicolons = FALSE; - - if (ffesta_label_token != NULL) - { - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; - } - - if (ffe_is_ffedebug ()) - { - ffestorag_report (); -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffesymbol_report_all (); -#endif - } - - ffelex_set_names (TRUE); - return (ffelexHandler) ffesta_first; -} diff --git a/gcc/f/sta.h b/gcc/f/sta.h deleted file mode 100755 index 6bb9913..0000000 --- a/gcc/f/sta.h +++ /dev/null @@ -1,117 +0,0 @@ -/* sta.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - sta.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_sta -#define _H_f_sta - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFESTA_pooldispDISCARD, /* Default state. */ - FFESTA_pooldispPRESERVE, /* Preserve through end of program unit. */ - FFESTA_pooldisp - } ffestaPooldisp; - -#define FFESTA_tokensMAX 10 /* Max # tokens in fixed positions. */ - -/* Typedefs. */ - -/* Include files needed by this one. */ - -#include "bad.h" -#include "lex.h" -#include "malloc.h" -#include "str.h" -#include "symbol.h" - -typedef mallocPool ffestaPool; /* No need for use count yet. */ - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern ffelexToken ffesta_tokens[FFESTA_tokensMAX]; -extern ffestrFirst ffesta_first_kw; -extern ffestrSecond ffesta_second_kw; -extern mallocPool ffesta_output_pool; -extern mallocPool ffesta_scratch_pool; -extern ffelexToken ffesta_construct_name; -extern ffelexToken ffesta_label_token; -extern bool ffesta_seen_first_exec; -extern bool ffesta_is_entry_valid; -extern bool ffesta_line_has_semicolons; - -/* Declare functions with prototypes. */ - -void ffesta_confirmed (void); -void ffesta_eof (void); -bool ffesta_ffebad_start (ffebad errnum); -void ffesta_ffebad_here_current_stmt (ffebadIndex i); -ffelexHandler ffesta_first (ffelexToken t); -void ffesta_init_0 (void); -void ffesta_init_3 (void); -bool ffesta_is_inhibited (void); -void ffesta_terminate_0 (void); -void ffesta_terminate_1 (void); -void ffesta_terminate_2 (void); -void ffesta_terminate_3 (void); -void ffesta_terminate_4 (void); -void ffesta_ffebad_here_doiter (ffebadIndex i, ffesymbol s); -void ffesta_shutdown (void); -ffesymbol ffesta_sym_end_transition (ffesymbol s); -ffesymbol ffesta_sym_exec_transition (ffesymbol s); -void ffesta_ffebad_1p (ffebad msg, ffelexToken names_token, - ffeTokenLength index, ffelexToken next_token); -void ffesta_ffebad_1sp (ffebad msg, char *s, ffelexToken names_token, - ffeTokenLength index, ffelexToken next_token); -void ffesta_ffebad_1st (ffebad msg, char *s, ffelexToken t); -void ffesta_ffebad_1t (ffebad msg, ffelexToken t); -void ffesta_ffebad_2st (ffebad msg, char *s, ffelexToken t1, ffelexToken t2); -void ffesta_ffebad_2t (ffebad msg, ffelexToken t1, ffelexToken t2); -ffelexHandler ffesta_zero (ffelexToken t); -ffelexHandler ffesta_two (ffelexToken first, ffelexToken second); -ffestaPooldisp ffesta_outpooldisp (void); -void ffesta_set_outpooldisp (ffestaPooldisp d); - -/* Define macros. */ - -#define ffesta_init_1() -#define ffesta_init_2() -#define ffesta_init_4() -#define ffesta_terminate_0() -#define ffesta_terminate_1() -#define ffesta_terminate_2() -#define ffesta_terminate_3() -#define ffesta_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stb.c b/gcc/f/stb.c deleted file mode 100755 index c14ccf5..0000000 --- a/gcc/f/stb.c +++ /dev/null @@ -1,25199 +0,0 @@ -/* stb.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - st.c - - Description: - Parses the proper form for statements, builds up expression trees for - them, but does not actually implement them. Uses ffebad (primarily via - ffesta_ffebad_start) to indicate errors in form. In many cases, an invalid - statement form indicates another possible statement needs to be looked at - by ffest. In a few cases, a valid statement form might not completely - determine the nature of the statement, as in REALFUNCTIONA(B), which is - a valid form for either the first statement of a function named A taking - an argument named B or for the declaration of a real array named FUNCTIONA - with an adjustable size of B. A similar (though somewhat easier) choice - must be made for the statement-function-def vs. assignment forms, as in - the case of FOO(A) = A+2.0. - - A given parser consists of one or more state handlers, the first of which - is the initial state, and the last of which (for any given input) returns - control to a final state handler (ffesta_zero or ffesta_two, explained - below). The functions handling the states for a given parser usually have - the same names, differing only in the final number, as in ffestb_foo_ - (handles the initial state), ffestb_foo_1_, ffestb_foo_2_ (handle - subsequent states), although liberties sometimes are taken with the "foo" - part either when keywords are clarified into given statements or are - transferred into other possible areas. (For example, the type-name - states can hop over to _dummy_ functions when the FUNCTION or RECURSIVE - keywords are seen, though this kind of thing is kept to a minimum.) Only - the names without numbers are exported to the rest of ffest; the others - are local (static). - - Each initial state is provided with the first token in ffesta_tokens[0], - which will be killed upon return to the final state (ffesta_zero or - ffelex_swallow_tokens passed through to ffesta_zero), so while it may - be changed to another token, a valid token must be left there to be - killed. Also, a "convenient" array of tokens are left in - ffesta_tokens[1..FFESTA_tokensMAX]. The initial state of this set of - elements is undefined, thus, if tokens are stored here, they must be - killed before returning to the final state. Any parser may also use - cross-state local variables by sticking a structure containing storage - for those variables in the local union ffestb_local_ (unless the union - goes on strike). Furthermore, parsers that handle more than one first or - second tokens (like _varlist_, which handles EXTERNAL, INTENT, INTRINSIC, - OPTIONAL, - PUBLIC, or PRIVATE, and _endxyz_, which handles ENDBLOCK, ENDBLOCKDATA, - ENDDO, ENDIF, and so on) may expect arguments from ffest in the - ffest-wide union ffest_args_, the substructure specific to the parser. - - A parser's responsibility is: to call either ffesta_confirmed or - ffest_ffebad_start before returning to the final state; to be the only - parser that can possibly call ffesta_confirmed for a given statement; - to call ffest_ffebad_start immediately upon recognizing a bad token - (specifically one that another statement parser might confirm upon); - to call ffestc functions only after calling ffesta_confirmed and only - when ffesta_is_inhibited returns FALSE; and to call ffesta_is_inhibited - only after calling ffesta_confirmed. Confirm as early as reasonably - possible, even when only one ffestc function is called for the statement - later on, because early confirmation can enhance the error-reporting - capabilities if a subsequent error is detected and this parser isn't - the first possibility for the statement. - - To assist the parser, functions like ffesta_ffebad_1t and _1p_ have - been provided to make use of ffest_ffebad_start fairly easy. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stb.h" -#include "bad.h" -#include "expr.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#include "sta.h" -#include "stc.h" -#include "stp.h" -#include "str.h" - -/* Externals defined here. */ - -struct _ffestb_args_ ffestb_args; - -/* Simple definitions and enumerations. */ - -#define FFESTB_KILL_EASY_ 1 /* 1 for only one _subr_kill_xyz_ fn. */ - -/* Internal typedefs. */ - -union ffestb_subrargs_u_ - { - struct - { - ffesttTokenList labels; /* Input arg, must not be NULL. */ - ffelexHandler handler; /* Input arg, call me when done. */ - bool ok; /* Output arg, TRUE if list ended in - CLOSE_PAREN. */ - } - label_list; - struct - { - ffesttDimList dims; /* Input arg, must not be NULL. */ - ffelexHandler handler; /* Input arg, call me when done. */ - mallocPool pool; /* Pool to allocate into. */ - bool ok; /* Output arg, TRUE if list ended in - CLOSE_PAREN. */ - ffeexprContext ctx; /* DIMLIST or DIMLISTCOMMON. */ -#ifdef FFECOM_dimensionsMAX - int ndims; /* For backends that really can't have - infinite dims. */ -#endif - } - dim_list; - struct - { - ffesttTokenList args; /* Input arg, must not be NULL. */ - ffelexHandler handler; /* Input arg, call me when done. */ - ffelexToken close_paren;/* Output arg if ok, CLOSE_PAREN token. */ - bool is_subr; /* Input arg, TRUE if list in subr-def - context. */ - bool ok; /* Output arg, TRUE if list ended in - CLOSE_PAREN. */ - bool names; /* Do ffelex_set_names(TRUE) before return. */ - } - name_list; - }; - -union ffestb_local_u_ - { - struct - { - ffebld expr; - } - call_stmt; - struct - { - ffebld expr; - } - go_to; - struct - { - ffebld dest; - bool vxtparam; /* If assignment might really be VXT - PARAMETER stmt. */ - } - let; - struct - { - ffebld expr; - } - if_stmt; - struct - { - ffebld expr; - } - else_stmt; - struct - { - ffebld expr; - } - dowhile; - struct - { - ffebld var; - ffebld start; - ffebld end; - } - do_stmt; - struct - { - bool is_cblock; - } - R522; - struct - { - ffebld expr; - bool started; - } - parameter; - struct - { - ffesttExprList exprs; - bool started; - } - equivalence; - struct - { - ffebld expr; - bool started; - } - data; - struct - { - ffestrOther kw; - } - varlist; -#if FFESTR_F90 - struct - { - ffestrOther kw; - } - type; -#endif - struct - { - ffelexHandler next; - } - construct; - struct - { - ffesttFormatList f; - ffestpFormatType current; /* What we're currently working on. */ - ffelexToken t; /* Token of what we're currently working on. */ - ffesttFormatValue pre; - ffesttFormatValue post; - ffesttFormatValue dot; - ffesttFormatValue exp; - bool sign; /* _3_, pos/neg; elsewhere, signed/unsigned. */ - bool complained; /* If run-time expr seen in nonexec context. */ - } - format; -#if FFESTR_F90 - struct - { - bool started; - } - moduleprocedure; -#endif - struct - { - ffebld expr; - } - selectcase; - struct - { - ffesttCaseList cases; - } - case_stmt; -#if FFESTR_F90 - struct - { - ffesttExprList exprs; - ffebld expr; - } - heap; -#endif -#if FFESTR_F90 - struct - { - ffesttExprList exprs; - } - R624; -#endif -#if FFESTR_F90 - struct - { - ffestpDefinedOperator operator; - bool assignment; /* TRUE for INTERFACE ASSIGNMENT, FALSE for - ...OPERATOR. */ - bool slash; /* TRUE if OPEN_ARRAY, FALSE if OPEN_PAREN. */ - } - interface; -#endif - struct - { - bool is_cblock; - } - V014; -#if FFESTR_VXT - struct - { - bool started; - ffebld u; - ffebld m; - ffebld n; - ffebld asv; - } - V025; -#endif - struct - { - ffestpBeruIx ix; - bool label; - bool left; - ffeexprContext context; - } - beru; - struct - { - ffestpCloseIx ix; - bool label; - bool left; - ffeexprContext context; - } - close; - struct - { - ffestpDeleteIx ix; - bool label; - bool left; - ffeexprContext context; - } - delete; - struct - { - ffestpDeleteIx ix; - bool label; - bool left; - ffeexprContext context; - } - find; - struct - { - ffestpInquireIx ix; - bool label; - bool left; - ffeexprContext context; - bool may_be_iolength; - } - inquire; - struct - { - ffestpOpenIx ix; - bool label; - bool left; - ffeexprContext context; - } - open; - struct - { - ffestpReadIx ix; - bool label; - bool left; - ffeexprContext context; - } - read; - struct - { - ffestpRewriteIx ix; - bool label; - bool left; - ffeexprContext context; - } - rewrite; - struct - { - ffestpWriteIx ix; - bool label; - bool left; - ffeexprContext context; - } - vxtcode; - struct - { - ffestpWriteIx ix; - bool label; - bool left; - ffeexprContext context; - } - write; -#if FFESTR_F90 - struct - { - bool started; - } - structure; -#endif - struct - { - bool started; - } - common; - struct - { - bool started; - } - dimension; - struct - { - bool started; - } - dimlist; - struct - { - char *badname; - ffestrFirst first_kw; - bool is_subr; - } - dummy; - struct - { - ffebld kind; /* Kind type parameter, if any. */ - ffelexToken kindt; /* Kind type first token, if any. */ - ffebld len; /* Length type parameter, if any. */ - ffelexToken lent; /* Length type parameter, if any. */ - ffelexHandler handler; - ffelexToken recursive; - ffebld expr; - ffesttTokenList toklist;/* For ambiguity resolution. */ - ffesttImpList imps; /* List of IMPLICIT letters. */ - ffelexHandler imp_handler; /* Call if paren list wasn't letters. */ - char *badname; - ffestrOther kw; /* INTENT(IN/OUT/INOUT). */ - ffestpType type; - bool parameter; /* If PARAMETER attribute seen (governs =expr - context). */ - bool coloncolon; /* If COLONCOLON seen (allows =expr). */ - bool aster_after; /* "*" seen after, not before, - [RECURSIVE]FUNCTIONxyz. */ - bool empty; /* Ambig function dummy arg list empty so - far? */ - bool imp_started; /* Started IMPLICIT statement already. */ - bool imp_seen_comma; /* TRUE if next COMMA within parens means not - R541. */ - } - decl; - struct - { - bool started; - } - vxtparam; - }; /* Merge with the one in ffestb later. */ - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -static union ffestb_subrargs_u_ ffestb_subrargs_; -static union ffestb_local_u_ ffestb_local_; - -/* Static functions (internal). */ - -static void ffestb_subr_ambig_to_ents_ (void); -static ffelexHandler ffestb_subr_ambig_nope_ (ffelexToken t); -static ffelexHandler ffestb_subr_dimlist_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_subr_dimlist_1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_subr_dimlist_2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_subr_name_list_ (ffelexToken t); -static ffelexHandler ffestb_subr_name_list_1_ (ffelexToken t); -static void ffestb_subr_R1001_append_p_ (void); -static ffelexHandler ffestb_decl_kindparam_ (ffelexToken t); -static ffelexHandler ffestb_decl_kindparam_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_kindparam_2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_starkind_ (ffelexToken t); -static ffelexHandler ffestb_decl_starlen_ (ffelexToken t); -static ffelexHandler ffestb_decl_starlen_1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_typeparams_ (ffelexToken t); -static ffelexHandler ffestb_decl_typeparams_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_typeparams_2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_typeparams_3_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_decl_typetype1_ (ffelexToken t); -static ffelexHandler ffestb_decl_typetype2_ (ffelexToken t); -#endif -static ffelexHandler ffestb_subr_label_list_ (ffelexToken t); -static ffelexHandler ffestb_subr_label_list_1_ (ffelexToken t); -static ffelexHandler ffestb_do1_ (ffelexToken t); -static ffelexHandler ffestb_do2_ (ffelexToken t); -static ffelexHandler ffestb_do3_ (ffelexToken t); -static ffelexHandler ffestb_do4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_do5_ (ffelexToken t); -static ffelexHandler ffestb_do6_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_do7_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_do8_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_do9_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_else1_ (ffelexToken t); -static ffelexHandler ffestb_else2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_else3_ (ffelexToken t); -static ffelexHandler ffestb_else4_ (ffelexToken t); -static ffelexHandler ffestb_else5_ (ffelexToken t); -static ffelexHandler ffestb_end1_ (ffelexToken t); -static ffelexHandler ffestb_end2_ (ffelexToken t); -static ffelexHandler ffestb_end3_ (ffelexToken t); -static ffelexHandler ffestb_goto1_ (ffelexToken t); -static ffelexHandler ffestb_goto2_ (ffelexToken t); -static ffelexHandler ffestb_goto3_ (ffelexToken t); -static ffelexHandler ffestb_goto4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_goto5_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_goto6_ (ffelexToken t); -static ffelexHandler ffestb_goto7_ (ffelexToken t); -static ffelexHandler ffestb_halt1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_if1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_if2_ (ffelexToken t); -static ffelexHandler ffestb_if3_ (ffelexToken t); -static ffelexHandler ffestb_let1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_let2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_type1_ (ffelexToken t); -static ffelexHandler ffestb_type2_ (ffelexToken t); -static ffelexHandler ffestb_type3_ (ffelexToken t); -static ffelexHandler ffestb_type4_ (ffelexToken t); -#endif -#if FFESTR_F90 -static ffelexHandler ffestb_varlist1_ (ffelexToken t); -static ffelexHandler ffestb_varlist2_ (ffelexToken t); -static ffelexHandler ffestb_varlist3_ (ffelexToken t); -static ffelexHandler ffestb_varlist4_ (ffelexToken t); -#endif -static ffelexHandler ffestb_varlist5_ (ffelexToken t); -static ffelexHandler ffestb_varlist6_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_where1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_where2_ (ffelexToken t); -static ffelexHandler ffestb_where3_ (ffelexToken t); -#endif -static ffelexHandler ffestb_R5221_ (ffelexToken t); -static ffelexHandler ffestb_R5222_ (ffelexToken t); -static ffelexHandler ffestb_R5223_ (ffelexToken t); -static ffelexHandler ffestb_R5224_ (ffelexToken t); -static ffelexHandler ffestb_R5281_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5282_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5283_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5284_ (ffelexToken t); -static ffelexHandler ffestb_R5371_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5372_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5373_ (ffelexToken t); -static ffelexHandler ffestb_R5421_ (ffelexToken t); -static ffelexHandler ffestb_R5422_ (ffelexToken t); -static ffelexHandler ffestb_R5423_ (ffelexToken t); -static ffelexHandler ffestb_R5424_ (ffelexToken t); -static ffelexHandler ffestb_R5425_ (ffelexToken t); -static ffelexHandler ffestb_R5441_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5442_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R5443_ (ffelexToken t); -static ffelexHandler ffestb_R5444_ (ffelexToken t); -static ffelexHandler ffestb_R8341_ (ffelexToken t); -static ffelexHandler ffestb_R8351_ (ffelexToken t); -static ffelexHandler ffestb_R8381_ (ffelexToken t); -static ffelexHandler ffestb_R8382_ (ffelexToken t); -static ffelexHandler ffestb_R8383_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R8401_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R8402_ (ffelexToken t); -static ffelexHandler ffestb_R8403_ (ffelexToken t); -static ffelexHandler ffestb_R8404_ (ffelexToken t); -static ffelexHandler ffestb_R8405_ (ffelexToken t); -static ffelexHandler ffestb_R8406_ (ffelexToken t); -static ffelexHandler ffestb_R8407_ (ffelexToken t); -static ffelexHandler ffestb_R11021_ (ffelexToken t); -static ffelexHandler ffestb_R1111_1_ (ffelexToken t); -static ffelexHandler ffestb_R1111_2_ (ffelexToken t); -static ffelexHandler ffestb_R12121_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R12271_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_construct1_ (ffelexToken t); -static ffelexHandler ffestb_construct2_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_heap1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_heap2_ (ffelexToken t); -static ffelexHandler ffestb_heap3_ (ffelexToken t); -static ffelexHandler ffestb_heap4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_heap5_ (ffelexToken t); -#endif -#if FFESTR_F90 -static ffelexHandler ffestb_module1_ (ffelexToken t); -static ffelexHandler ffestb_module2_ (ffelexToken t); -static ffelexHandler ffestb_module3_ (ffelexToken t); -#endif -static ffelexHandler ffestb_R8091_ (ffelexToken t); -static ffelexHandler ffestb_R8092_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R8093_ (ffelexToken t); -static ffelexHandler ffestb_R8101_ (ffelexToken t); -static ffelexHandler ffestb_R8102_ (ffelexToken t); -static ffelexHandler ffestb_R8103_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R8104_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R10011_ (ffelexToken t); -static ffelexHandler ffestb_R10012_ (ffelexToken t); -static ffelexHandler ffestb_R10013_ (ffelexToken t); -static ffelexHandler ffestb_R10014_ (ffelexToken t); -static ffelexHandler ffestb_R10015_ (ffelexToken t); -static ffelexHandler ffestb_R10016_ (ffelexToken t); -static ffelexHandler ffestb_R10017_ (ffelexToken t); -static ffelexHandler ffestb_R10018_ (ffelexToken t); -static ffelexHandler ffestb_R10019_ (ffelexToken t); -static ffelexHandler ffestb_R100110_ (ffelexToken t); -static ffelexHandler ffestb_R100111_ (ffelexToken t); -static ffelexHandler ffestb_R100112_ (ffelexToken t); -static ffelexHandler ffestb_R100113_ (ffelexToken t); -static ffelexHandler ffestb_R100114_ (ffelexToken t); -static ffelexHandler ffestb_R100115_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R100116_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R100117_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R100118_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_R11071_ (ffelexToken t); -static ffelexHandler ffestb_R11072_ (ffelexToken t); -static ffelexHandler ffestb_R11073_ (ffelexToken t); -static ffelexHandler ffestb_R11074_ (ffelexToken t); -static ffelexHandler ffestb_R11075_ (ffelexToken t); -static ffelexHandler ffestb_R11076_ (ffelexToken t); -static ffelexHandler ffestb_R11077_ (ffelexToken t); -static ffelexHandler ffestb_R11078_ (ffelexToken t); -static ffelexHandler ffestb_R11079_ (ffelexToken t); -static ffelexHandler ffestb_R110710_ (ffelexToken t); -static ffelexHandler ffestb_R110711_ (ffelexToken t); -static ffelexHandler ffestb_R110712_ (ffelexToken t); -#endif -#if FFESTR_F90 -static ffelexHandler ffestb_R12021_ (ffelexToken t); -static ffelexHandler ffestb_R12022_ (ffelexToken t); -static ffelexHandler ffestb_R12023_ (ffelexToken t); -static ffelexHandler ffestb_R12024_ (ffelexToken t); -static ffelexHandler ffestb_R12025_ (ffelexToken t); -static ffelexHandler ffestb_R12026_ (ffelexToken t); -#endif -static ffelexHandler ffestb_S3P41_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0141_ (ffelexToken t); -static ffelexHandler ffestb_V0142_ (ffelexToken t); -static ffelexHandler ffestb_V0143_ (ffelexToken t); -static ffelexHandler ffestb_V0144_ (ffelexToken t); -#if FFESTR_VXT -static ffelexHandler ffestb_V0251_ (ffelexToken t); -static ffelexHandler ffestb_V0252_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0253_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0254_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0255_ (ffelexToken t); -static ffelexHandler ffestb_V0256_ (ffelexToken t); -static ffelexHandler ffestb_V0257_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0258_ (ffelexToken t); -#endif -#if FFESTB_KILL_EASY_ -static void ffestb_subr_kill_easy_ (ffestpInquireIx max); -#else -static void ffestb_subr_kill_accept_ (void); -static void ffestb_subr_kill_beru_ (void); -static void ffestb_subr_kill_close_ (void); -static void ffestb_subr_kill_delete_ (void); -static void ffestb_subr_kill_find_ (void); /* Not written yet. */ -static void ffestb_subr_kill_inquire_ (void); -static void ffestb_subr_kill_open_ (void); -static void ffestb_subr_kill_print_ (void); -static void ffestb_subr_kill_read_ (void); -static void ffestb_subr_kill_rewrite_ (void); -static void ffestb_subr_kill_type_ (void); -static void ffestb_subr_kill_vxtcode_ (void); /* Not written yet. */ -static void ffestb_subr_kill_write_ (void); -#endif -static ffelexHandler ffestb_beru1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_beru2_ (ffelexToken t); -static ffelexHandler ffestb_beru3_ (ffelexToken t); -static ffelexHandler ffestb_beru4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_beru5_ (ffelexToken t); -static ffelexHandler ffestb_beru6_ (ffelexToken t); -static ffelexHandler ffestb_beru7_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_beru8_ (ffelexToken t); -static ffelexHandler ffestb_beru9_ (ffelexToken t); -static ffelexHandler ffestb_beru10_ (ffelexToken t); -#if FFESTR_VXT -static ffelexHandler ffestb_vxtcode1_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_vxtcode2_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_vxtcode3_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_vxtcode4_ (ffelexToken t); -static ffelexHandler ffestb_vxtcode5_ (ffelexToken t); -static ffelexHandler ffestb_vxtcode6_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_vxtcode7_ (ffelexToken t); -static ffelexHandler ffestb_vxtcode8_ (ffelexToken t); -static ffelexHandler ffestb_vxtcode9_ (ffelexToken t); -static ffelexHandler ffestb_vxtcode10_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#endif -static ffelexHandler ffestb_R9041_ (ffelexToken t); -static ffelexHandler ffestb_R9042_ (ffelexToken t); -static ffelexHandler ffestb_R9043_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9044_ (ffelexToken t); -static ffelexHandler ffestb_R9045_ (ffelexToken t); -static ffelexHandler ffestb_R9046_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9047_ (ffelexToken t); -static ffelexHandler ffestb_R9048_ (ffelexToken t); -static ffelexHandler ffestb_R9049_ (ffelexToken t); -static ffelexHandler ffestb_R9071_ (ffelexToken t); -static ffelexHandler ffestb_R9072_ (ffelexToken t); -static ffelexHandler ffestb_R9073_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9074_ (ffelexToken t); -static ffelexHandler ffestb_R9075_ (ffelexToken t); -static ffelexHandler ffestb_R9076_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9077_ (ffelexToken t); -static ffelexHandler ffestb_R9078_ (ffelexToken t); -static ffelexHandler ffestb_R9079_ (ffelexToken t); -static ffelexHandler ffestb_R9091_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9092_ (ffelexToken t); -static ffelexHandler ffestb_R9093_ (ffelexToken t); -static ffelexHandler ffestb_R9094_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9095_ (ffelexToken t); -static ffelexHandler ffestb_R9096_ (ffelexToken t); -static ffelexHandler ffestb_R9097_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9098_ (ffelexToken t); -static ffelexHandler ffestb_R9099_ (ffelexToken t); -static ffelexHandler ffestb_R90910_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R90911_ (ffelexToken t); -static ffelexHandler ffestb_R90912_ (ffelexToken t); -static ffelexHandler ffestb_R90913_ (ffelexToken t); -static ffelexHandler ffestb_R90914_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R90915_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9101_ (ffelexToken t); -static ffelexHandler ffestb_R9102_ (ffelexToken t); -static ffelexHandler ffestb_R9103_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9104_ (ffelexToken t); -static ffelexHandler ffestb_R9105_ (ffelexToken t); -static ffelexHandler ffestb_R9106_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9107_ (ffelexToken t); -static ffelexHandler ffestb_R9108_ (ffelexToken t); -static ffelexHandler ffestb_R9109_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R91010_ (ffelexToken t); -static ffelexHandler ffestb_R91011_ (ffelexToken t); -static ffelexHandler ffestb_R91012_ (ffelexToken t); -static ffelexHandler ffestb_R91013_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R91014_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9111_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9112_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9231_ (ffelexToken t); -static ffelexHandler ffestb_R9232_ (ffelexToken t); -static ffelexHandler ffestb_R9233_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9234_ (ffelexToken t); -static ffelexHandler ffestb_R9235_ (ffelexToken t); -static ffelexHandler ffestb_R9236_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R9237_ (ffelexToken t); -static ffelexHandler ffestb_R9238_ (ffelexToken t); -static ffelexHandler ffestb_R9239_ (ffelexToken t); -static ffelexHandler ffestb_R92310_ (ffelexToken t); -static ffelexHandler ffestb_R92311_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#if FFESTR_VXT -static ffelexHandler ffestb_V0181_ (ffelexToken t); -static ffelexHandler ffestb_V0182_ (ffelexToken t); -static ffelexHandler ffestb_V0183_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0184_ (ffelexToken t); -static ffelexHandler ffestb_V0185_ (ffelexToken t); -static ffelexHandler ffestb_V0186_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0187_ (ffelexToken t); -static ffelexHandler ffestb_V0188_ (ffelexToken t); -static ffelexHandler ffestb_V0189_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V01810_ (ffelexToken t); -static ffelexHandler ffestb_V01811_ (ffelexToken t); -static ffelexHandler ffestb_V01812_ (ffelexToken t); -static ffelexHandler ffestb_V01813_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0191_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0192_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#endif -static ffelexHandler ffestb_V0201_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0202_ (ffelexToken ft, ffebld expr, - ffelexToken t); -#if FFESTR_VXT -static ffelexHandler ffestb_V0211_ (ffelexToken t); -static ffelexHandler ffestb_V0212_ (ffelexToken t); -static ffelexHandler ffestb_V0213_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0214_ (ffelexToken t); -static ffelexHandler ffestb_V0215_ (ffelexToken t); -static ffelexHandler ffestb_V0216_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0217_ (ffelexToken t); -static ffelexHandler ffestb_V0218_ (ffelexToken t); -static ffelexHandler ffestb_V0219_ (ffelexToken t); -static ffelexHandler ffestb_V0261_ (ffelexToken t); -static ffelexHandler ffestb_V0262_ (ffelexToken t); -static ffelexHandler ffestb_V0263_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0264_ (ffelexToken t); -static ffelexHandler ffestb_V0265_ (ffelexToken t); -static ffelexHandler ffestb_V0266_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0267_ (ffelexToken t); -static ffelexHandler ffestb_V0268_ (ffelexToken t); -static ffelexHandler ffestb_V0269_ (ffelexToken t); -#endif -#if FFESTR_F90 -static ffelexHandler ffestb_dimlist1_ (ffelexToken t); -static ffelexHandler ffestb_dimlist2_ (ffelexToken t); -static ffelexHandler ffestb_dimlist3_ (ffelexToken t); -static ffelexHandler ffestb_dimlist4_ (ffelexToken t); -#endif -static ffelexHandler ffestb_dummy1_ (ffelexToken t); -static ffelexHandler ffestb_dummy2_ (ffelexToken t); -static ffelexHandler ffestb_R5241_ (ffelexToken t); -static ffelexHandler ffestb_R5242_ (ffelexToken t); -static ffelexHandler ffestb_R5243_ (ffelexToken t); -static ffelexHandler ffestb_R5244_ (ffelexToken t); -static ffelexHandler ffestb_R5471_ (ffelexToken t); -static ffelexHandler ffestb_R5472_ (ffelexToken t); -static ffelexHandler ffestb_R5473_ (ffelexToken t); -static ffelexHandler ffestb_R5474_ (ffelexToken t); -static ffelexHandler ffestb_R5475_ (ffelexToken t); -static ffelexHandler ffestb_R5476_ (ffelexToken t); -static ffelexHandler ffestb_R5477_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_R6241_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_R6242_ (ffelexToken t); -#endif -static ffelexHandler ffestb_R12291_ (ffelexToken t); -static ffelexHandler ffestb_R12292_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_chartype1_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_decl_recursive1_ (ffelexToken t); -static ffelexHandler ffestb_decl_recursive2_ (ffelexToken t); -static ffelexHandler ffestb_decl_recursive3_ (ffelexToken t); -static ffelexHandler ffestb_decl_recursive4_ (ffelexToken t); -#endif -static ffelexHandler ffestb_decl_attrs_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrs_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrs_2_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_decl_attrs_3_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrs_4_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrs_5_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrs_6_ (ffelexToken t); -#endif -static ffelexHandler ffestb_decl_attrs_7_ (ffelexToken t); -static ffelexHandler ffestb_decl_attrsp_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_2_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_3_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_4_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_5_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_6_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_ents_7_ (ffelexToken t); -static ffelexHandler ffestb_decl_ents_8_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_ents_9_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_ents_10_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_ents_11_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_2_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_3_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_4_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_entsp_5_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_6_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_7_ (ffelexToken t); -static ffelexHandler ffestb_decl_entsp_8_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_decl_func_ (ffelexToken t); -#endif -static ffelexHandler ffestb_decl_funcname_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_2_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_3_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_decl_funcname_4_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_5_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_6_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_7_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_8_ (ffelexToken t); -static ffelexHandler ffestb_decl_funcname_9_ (ffelexToken t); -#if FFESTR_VXT -static ffelexHandler ffestb_V0031_ (ffelexToken t); -static ffelexHandler ffestb_V0032_ (ffelexToken t); -static ffelexHandler ffestb_V0033_ (ffelexToken t); -static ffelexHandler ffestb_V0034_ (ffelexToken t); -static ffelexHandler ffestb_V0035_ (ffelexToken t); -static ffelexHandler ffestb_V0036_ (ffelexToken t); -static ffelexHandler ffestb_V0161_ (ffelexToken t); -static ffelexHandler ffestb_V0162_ (ffelexToken t); -static ffelexHandler ffestb_V0163_ (ffelexToken t); -static ffelexHandler ffestb_V0164_ (ffelexToken t); -static ffelexHandler ffestb_V0165_ (ffelexToken t); -static ffelexHandler ffestb_V0166_ (ffelexToken t); -#endif -static ffelexHandler ffestb_V0271_ (ffelexToken t); -static ffelexHandler ffestb_V0272_ (ffelexToken ft, ffebld expr, - ffelexToken t); -static ffelexHandler ffestb_V0273_ (ffelexToken t); -static ffelexHandler ffestb_decl_R5391_ (ffelexToken t); -static ffelexHandler ffestb_decl_R5392_ (ffelexToken t); -#if FFESTR_F90 -static ffelexHandler ffestb_decl_R5393_ (ffelexToken t); -#endif -static ffelexHandler ffestb_decl_R5394_ (ffelexToken t); -static ffelexHandler ffestb_decl_R5395_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_2_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_3_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_4_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539letters_5_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_1_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_2_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_3_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_4_ (ffelexToken t); -static ffelexHandler ffestb_decl_R539maybe_5_ (ffelexToken t); - -/* Internal macros. */ - -#if FFESTB_KILL_EASY_ -#define ffestb_subr_kill_accept_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_acceptix) -#define ffestb_subr_kill_beru_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_beruix) -#define ffestb_subr_kill_close_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_closeix) -#define ffestb_subr_kill_delete_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_deleteix) -#define ffestb_subr_kill_find_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_findix) -#define ffestb_subr_kill_inquire_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_inquireix) -#define ffestb_subr_kill_open_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_openix) -#define ffestb_subr_kill_print_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_printix) -#define ffestb_subr_kill_read_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_readix) -#define ffestb_subr_kill_rewrite_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_rewriteix) -#define ffestb_subr_kill_type_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_typeix) -#define ffestb_subr_kill_vxtcode_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_vxtcodeix) -#define ffestb_subr_kill_write_() \ - ffestb_subr_kill_easy_((ffestpInquireIx) FFESTP_writeix) -#endif - -/* ffestb_subr_ambig_nope_ -- Cleans up and aborts ambig w/o confirming - - ffestb_subr_ambig_nope_(); - - Switch from ambiguity handling in _entsp_ functions to handling entities - in _ents_ (perform housekeeping tasks). */ - -static ffelexHandler -ffestb_subr_ambig_nope_ (ffelexToken t) -{ - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_subr_ambig_to_ents_ -- Switches from ambiguity to entity decl - - ffestb_subr_ambig_to_ents_(); - - Switch from ambiguity handling in _entsp_ functions to handling entities - in _ents_ (perform housekeeping tasks). */ - -static void -ffestb_subr_ambig_to_ents_ () -{ - ffelexToken nt; - - nt = ffelex_token_name_from_names (ffesta_tokens[1], 0, 0); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_tokens[1] = nt; - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (!ffestb_local_.decl.aster_after) - { - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - { - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent); - if (ffestb_local_.decl.kindt != NULL) - { - ffelex_token_kill (ffestb_local_.decl.kindt); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - } - if (ffestb_local_.decl.lent != NULL) - { - ffelex_token_kill (ffestb_local_.decl.lent); - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - } - } - else - { - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, NULL, - NULL); - if (ffestb_local_.decl.kindt != NULL) - { - ffelex_token_kill (ffestb_local_.decl.kindt); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - } - } - return; - } - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - { - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, NULL, NULL); - if (ffestb_local_.decl.kindt != NULL) - { - ffelex_token_kill (ffestb_local_.decl.kindt); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - } - } - else if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - /* NAME/NAMES token already in ffesta_tokens[1]. */ -} - -/* ffestb_subr_dimlist_ -- OPEN_PAREN expr - - (ffestb_subr_dimlist_) // to expression handler - - Deal with a dimension list. - - 19-Dec-90 JCB 1.1 - Detect too many dimensions if backend wants it. */ - -static ffelexHandler -ffestb_subr_dimlist_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; -#ifdef FFECOM_dimensionsMAX - if (ffestb_subrargs_.dim_list.ndims++ == FFECOM_dimensionsMAX) - { - ffesta_ffebad_1t (FFEBAD_TOO_MANY_DIMS, ft); - ffestb_subrargs_.dim_list.ok = TRUE; /* Not a parse error, really. */ - return (ffelexHandler) ffestb_subrargs_.dim_list.handler; - } -#endif - ffestt_dimlist_append (ffestb_subrargs_.dim_list.dims, NULL, expr, - ffelex_token_use (t)); - ffestb_subrargs_.dim_list.ok = TRUE; - return (ffelexHandler) ffestb_subrargs_.dim_list.handler; - - case FFELEX_typeCOMMA: - if ((expr != NULL) && (ffebld_op (expr) == FFEBLD_opSTAR)) - break; -#ifdef FFECOM_dimensionsMAX - if (ffestb_subrargs_.dim_list.ndims++ == FFECOM_dimensionsMAX) - { - ffesta_ffebad_1t (FFEBAD_TOO_MANY_DIMS, ft); - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_2_); - } -#endif - ffestt_dimlist_append (ffestb_subrargs_.dim_list.dims, NULL, expr, - ffelex_token_use (t)); - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOLON: - if ((expr != NULL) && (ffebld_op (expr) == FFEBLD_opSTAR)) - break; -#ifdef FFECOM_dimensionsMAX - if (ffestb_subrargs_.dim_list.ndims++ == FFECOM_dimensionsMAX) - { - ffesta_ffebad_1t (FFEBAD_TOO_MANY_DIMS, ft); - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_2_); - } -#endif - ffestt_dimlist_append (ffestb_subrargs_.dim_list.dims, expr, NULL, - ffelex_token_use (t)); /* NULL second expr for - now, just plug in. */ - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_1_); - - default: - break; - } - - ffestb_subrargs_.dim_list.ok = FALSE; - return (ffelexHandler) ffestb_subrargs_.dim_list.handler (t); -} - -/* ffestb_subr_dimlist_1_ -- OPEN_PAREN expr COLON expr - - (ffestb_subr_dimlist_1_) // to expression handler - - Get the upper bound. */ - -static ffelexHandler -ffestb_subr_dimlist_1_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_subrargs_.dim_list.dims->previous->upper = expr; - ffestb_subrargs_.dim_list.ok = TRUE; - return (ffelexHandler) ffestb_subrargs_.dim_list.handler; - - case FFELEX_typeCOMMA: - if ((expr != NULL) && (ffebld_op (expr) == FFEBLD_opSTAR)) - break; - ffestb_subrargs_.dim_list.dims->previous->upper = expr; - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, (ffeexprCallback) ffestb_subr_dimlist_); - - default: - break; - } - - ffestb_subrargs_.dim_list.ok = FALSE; - return (ffelexHandler) ffestb_subrargs_.dim_list.handler (t); -} - -/* ffestb_subr_dimlist_2_ -- OPEN_PAREN too-many-dim-exprs - - (ffestb_subr_dimlist_2_) // to expression handler - - Get the upper bound. */ - -static ffelexHandler -ffestb_subr_dimlist_2_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_subrargs_.dim_list.ok = TRUE; /* Not a parse error, really. */ - return (ffelexHandler) ffestb_subrargs_.dim_list.handler; - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLON: - if ((expr != NULL) && (ffebld_op (expr) == FFEBLD_opSTAR)) - break; - return (ffelexHandler) ffeexpr_rhs (ffestb_subrargs_.dim_list.pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_2_); - - default: - break; - } - - ffestb_subrargs_.dim_list.ok = FALSE; - return (ffelexHandler) ffestb_subrargs_.dim_list.handler (t); -} - -/* ffestb_subr_name_list_ -- Collect a list of name args and close-paren - - return ffestb_subr_name_list_; // to lexer after seeing OPEN_PAREN - - This implements R1224 in the Fortran 90 spec. The arg list may be - empty, or be a comma-separated list (an optional trailing comma currently - results in a warning but no other effect) of arguments. For functions, - however, "*" is invalid (we implement dummy-arg-name, rather than R1224 - dummy-arg, which itself is either dummy-arg-name or "*"). */ - -static ffelexHandler -ffestb_subr_name_list_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (ffestt_tokenlist_count (ffestb_subrargs_.name_list.args) != 0) - { /* Trailing comma, warn. */ - ffebad_start (FFEBAD_TRAILING_COMMA); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - ffestb_subrargs_.name_list.ok = TRUE; - ffestb_subrargs_.name_list.close_paren = ffelex_token_use (t); - if (ffestb_subrargs_.name_list.names) - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_subrargs_.name_list.handler; - - case FFELEX_typeASTERISK: - if (!ffestb_subrargs_.name_list.is_subr) - break; - - case FFELEX_typeNAME: - ffestt_tokenlist_append (ffestb_subrargs_.name_list.args, - ffelex_token_use (t)); - return (ffelexHandler) ffestb_subr_name_list_1_; - - default: - break; - } - - ffestb_subrargs_.name_list.ok = FALSE; - ffestb_subrargs_.name_list.close_paren = ffelex_token_use (t); - if (ffestb_subrargs_.name_list.names) - ffelex_set_names (TRUE); - return (ffelexHandler) (*ffestb_subrargs_.name_list.handler) (t); -} - -/* ffestb_subr_name_list_1_ -- NAME or ASTERISK - - return ffestb_subr_name_list_1_; // to lexer - - The next token must be COMMA or CLOSE_PAREN, either way go to original - state, but only after adding the appropriate name list item. */ - -static ffelexHandler -ffestb_subr_name_list_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_subr_name_list_; - - case FFELEX_typeCLOSE_PAREN: - ffestb_subrargs_.name_list.ok = TRUE; - ffestb_subrargs_.name_list.close_paren = ffelex_token_use (t); - if (ffestb_subrargs_.name_list.names) - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_subrargs_.name_list.handler; - - default: - ffestb_subrargs_.name_list.ok = FALSE; - ffestb_subrargs_.name_list.close_paren = ffelex_token_use (t); - if (ffestb_subrargs_.name_list.names) - ffelex_set_names (TRUE); - return (ffelexHandler) (*ffestb_subrargs_.name_list.handler) (t); - } -} - -static void -ffestb_subr_R1001_append_p_ (void) -{ - ffesttFormatList f; - - if (!ffestb_local_.format.pre.present) - { - ffesta_ffebad_1t (FFEBAD_FORMAT_BAD_P_SPEC, ffestb_local_.format.t); - ffelex_token_kill (ffestb_local_.format.t); - return; - } - - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeP; - f->t = ffestb_local_.format.t; - f->u.R1010.val = ffestb_local_.format.pre; -} - -/* ffestb_decl_kindparam_ -- "type" OPEN_PAREN - - return ffestb_decl_kindparam_; // to lexer - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_kindparam_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_kindparam_1_; - - default: - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, - (ffeexprCallback) ffestb_decl_kindparam_2_))) - (t); - } -} - -/* ffestb_decl_kindparam_1_ -- "type" OPEN_PAREN NAME - - return ffestb_decl_kindparam_1_; // to lexer - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_kindparam_1_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestr_other (ffesta_tokens[1]) != FFESTR_otherKIND) - break; - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, (ffeexprCallback) ffestb_decl_kindparam_2_); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, (ffeexprCallback) ffestb_decl_kindparam_2_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_kindparam_2_ -- "type" OPEN_PAREN ["KIND="] expr - - (ffestb_decl_kindparam_2_) // to expression handler - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_kindparam_2_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.decl.kind = expr; - ffestb_local_.decl.kindt = ffelex_token_use (ft); - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_starkind_ -- "type" ASTERISK - - return ffestb_decl_starkind_; // to lexer - - Handle NUMBER. */ - -static ffelexHandler -ffestb_decl_starkind_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestb_local_.decl.kindt = ffelex_token_use (t); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_starlen_ -- "CHARACTER" ASTERISK - - return ffestb_decl_starlen_; // to lexer - - Handle NUMBER. */ - -static ffelexHandler -ffestb_decl_starlen_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = ffelex_token_use (t); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_starlen_1_); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_starlen_1_ -- "CHARACTER" ASTERISK OPEN_PAREN expr - - (ffestb_decl_starlen_1_) // to expression handler - - Handle CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_starlen_1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typeparams_ -- "CHARACTER" OPEN_PAREN - - return ffestb_decl_typeparams_; // to lexer - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_typeparams_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_typeparams_1_; - - default: - if (ffestb_local_.decl.lent == NULL) - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_typeparams_2_))) - (t); - if (ffestb_local_.decl.kindt != NULL) - break; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, - (ffeexprCallback) ffestb_decl_typeparams_3_))) - (t); - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typeparams_1_ -- "CHARACTER" OPEN_PAREN NAME - - return ffestb_decl_typeparams_1_; // to lexer - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_typeparams_1_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - switch (ffestr_other (ffesta_tokens[1])) - { - case FFESTR_otherLEN: - if (ffestb_local_.decl.lent != NULL) - break; - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_typeparams_2_); - - case FFESTR_otherKIND: - if (ffestb_local_.decl.kindt != NULL) - break; - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, - (ffeexprCallback) ffestb_decl_typeparams_3_); - - default: - break; - } - break; - - default: - nt = ffesta_tokens[1]; - if (ffestb_local_.decl.lent == NULL) - next = (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_typeparams_2_))) - (nt); - else if (ffestb_local_.decl.kindt == NULL) - next = (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextKINDTYPE, - (ffeexprCallback) ffestb_decl_typeparams_3_))) - (nt); - else - { - ffesta_tokens[1] = nt; - break; - } - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typeparams_2_ -- "CHARACTER" OPEN_PAREN ["LEN="] expr - - (ffestb_decl_typeparams_2_) // to expression handler - - Handle "[LEN=]expr)". */ - -static ffelexHandler -ffestb_decl_typeparams_2_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - case FFELEX_typeCOMMA: - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - return (ffelexHandler) ffestb_decl_typeparams_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typeparams_3_ -- "CHARACTER" OPEN_PAREN ["KIND="] expr - - (ffestb_decl_typeparams_3_) // to expression handler - - Handle "[KIND=]expr)". */ - -static ffelexHandler -ffestb_decl_typeparams_3_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.decl.kind = expr; - ffestb_local_.decl.kindt = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - case FFELEX_typeCOMMA: - ffestb_local_.decl.kind = expr; - ffestb_local_.decl.kindt = ffelex_token_use (ft); - return (ffelexHandler) ffestb_decl_typeparams_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typetype1_ -- "TYPE" OPEN_PAREN - - return ffestb_decl_typetype1_; // to lexer - - Handle NAME. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_decl_typetype1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffestb_local_.decl.kindt = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_typetype2_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_typetype2_ -- "TYPE" OPEN_PAREN NAME - - return ffestb_decl_typetype2_; // to lexer - - Handle CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_typetype2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.decl.type = FFESTP_typeTYPE; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_local_.decl.handler; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffelex_token_kill (ffestb_local_.decl.kindt); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - ffestb_local_.decl.badname, - t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_subr_label_list_ -- Collect a tokenlist of labels and close-paren - - return ffestb_subr_label_list_; // to lexer after seeing OPEN_PAREN - - First token must be a NUMBER. Must be followed by zero or more COMMA - NUMBER pairs. Must then be followed by a CLOSE_PAREN. If all ok, put - the NUMBER tokens in a token list and return via the handler for the - token after CLOSE_PAREN. Else return via - same handler, but with the ok return value set FALSE. */ - -static ffelexHandler -ffestb_subr_label_list_ (ffelexToken t) -{ - if (ffelex_token_type (t) == FFELEX_typeNUMBER) - { - ffestt_tokenlist_append (ffestb_subrargs_.label_list.labels, - ffelex_token_use (t)); - return (ffelexHandler) ffestb_subr_label_list_1_; - } - - ffestb_subrargs_.label_list.ok = FALSE; - return (ffelexHandler) (*ffestb_subrargs_.label_list.handler) (t); -} - -/* ffestb_subr_label_list_1_ -- NUMBER - - return ffestb_subr_label_list_1_; // to lexer after seeing NUMBER - - The next token must be COMMA, in which case go back to - ffestb_subr_label_list_, or CLOSE_PAREN, in which case set ok to TRUE - and go to the handler. */ - -static ffelexHandler -ffestb_subr_label_list_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_subr_label_list_; - - case FFELEX_typeCLOSE_PAREN: - ffestb_subrargs_.label_list.ok = TRUE; - return (ffelexHandler) ffestb_subrargs_.label_list.handler; - - default: - ffestb_subrargs_.label_list.ok = FALSE; - return (ffelexHandler) (*ffestb_subrargs_.label_list.handler) (t); - } -} - -/* ffestb_do -- Parse the DO statement - - return ffestb_do; // to lexer - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_do (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexHandler next; - ffelexToken nt; - ffestrSecond kw; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstDO) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_do1_; - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_do2_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_do3_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_do1_ (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstDO) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlDO); - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: /* Must be "DO" label "WHILE". */ - if (! ISDIGIT (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_number_from_names (ffesta_tokens[0], - i); - p += ffelex_token_length (ffesta_tokens[1]); - i += ffelex_token_length (ffesta_tokens[1]); - if (((*p) != 'W') && ((*p) != 'w')) - goto bad_i1; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - kw = ffestr_second (nt); - ffelex_token_kill (nt); - if (kw != FFESTR_secondWHILE) - goto bad_i1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDOWHILE, (ffeexprCallback) ffestb_do4_); - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (*p == '\0') - { - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_do2_; - } - if (! ISDIGIT (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_number_from_names (ffesta_tokens[0], - i); - p += ffelex_token_length (ffesta_tokens[1]); - i += ffelex_token_length (ffesta_tokens[1]); - if (*p != '\0') - goto bad_i1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_do2_; - - case FFELEX_typeEQUALS: - if (ISDIGIT (*p)) - { - ffesta_tokens[1] - = ffelex_token_number_from_names (ffesta_tokens[0], i); - p += ffelex_token_length (ffesta_tokens[1]); - i += ffelex_token_length (ffesta_tokens[1]); - } - else - ffesta_tokens[1] = NULL; - if (!ffesrc_is_name_init (*p)) - goto bad_i1; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_lhs - (ffesta_output_pool, FFEEXPR_contextDO, - (ffeexprCallback) ffestb_do6_))) - (nt); - ffelex_token_kill (nt); /* Will get it back in _6_... */ - return (ffelexHandler) (*next) (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (ISDIGIT (*p)) - { - ffesta_tokens[1] - = ffelex_token_number_from_names (ffesta_tokens[0], i); - p += ffelex_token_length (ffesta_tokens[1]); - i += ffelex_token_length (ffesta_tokens[1]); - } - else - ffesta_tokens[1] = NULL; - if (*p != '\0') - goto bad_i1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_do1_ (t); - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i1: /* :::::::::::::::::::: */ - if (ffesta_tokens[1]) - ffelex_token_kill (ffesta_tokens[1]); - -bad_i: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "DO", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dowhile -- Parse the DOWHILE statement - - return ffestb_dowhile; // to lexer - - Make sure the statement has a valid form for the DOWHILE statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_dowhile (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstDOWHILE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlDOWHILE); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDOWHILE, (ffeexprCallback) ffestb_do4_); - - case FFELEX_typeEQUALS:/* Not really DOWHILE, but DOWHILExyz=.... */ - ffesta_tokens[1] = NULL; - nt = ffelex_token_name_from_names (ffesta_tokens[0], FFESTR_firstlDO, - 0); - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_lhs - (ffesta_output_pool, FFEEXPR_contextDO, - (ffeexprCallback) ffestb_do6_))) - (nt); - ffelex_token_kill (nt); /* Will get it back in _6_... */ - return (ffelexHandler) (*next) (t); - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "DO", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do1_ -- "DO" [label] - - return ffestb_do1_; // to lexer - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - return (ffelexHandler) ffestb_do2_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (ffesta_tokens[1] != NULL) - ffestc_R819B (ffesta_construct_name, ffesta_tokens[1], NULL, - NULL); - else - ffestc_R820B (ffesta_construct_name, NULL, NULL); - } - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - return (ffelexHandler) ffestb_do2_ (t); - - default: - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do2_ -- "DO" [label] [,] - - return ffestb_do2_; // to lexer - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_do3_; - - default: - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do3_ -- "DO" [label] [,] NAME - - return ffestb_do3_; // to lexer - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do3_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDO, (ffeexprCallback) ffestb_do6_))) - (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[2]); /* Will get it back in _6_... */ - return (ffelexHandler) (*next) (t); - - case FFELEX_typeOPEN_PAREN: - if (ffestr_second (ffesta_tokens[2]) != FFESTR_secondWHILE) - { - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid token. */ - } - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDOWHILE, (ffeexprCallback) ffestb_do4_); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do4_ -- "DO" [label] [,] "WHILE" OPEN_PAREN expr - - (ffestb_do4_) // to expression handler - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do4_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[2] = ffelex_token_use (ft); - ffestb_local_.dowhile.expr = expr; - return (ffelexHandler) ffestb_do5_; - - default: - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do5_ -- "DO" [label] [,] "WHILE" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_do5_; // to lexer - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (ffesta_tokens[1] != NULL) - ffestc_R819B (ffesta_construct_name, ffesta_tokens[1], - ffestb_local_.dowhile.expr, ffesta_tokens[2]); - else - ffestc_R820B (ffesta_construct_name, ffestb_local_.dowhile.expr, - ffesta_tokens[2]); - } - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do6_ -- "DO" [label] [,] var-expr - - (ffestb_do6_) // to expression handler - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do6_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - /* _3_ already ensured that this would be an EQUALS token. If not, it is a - bug in the FFE. */ - - assert (ffelex_token_type (t) == FFELEX_typeEQUALS); - - ffesta_tokens[2] = ffelex_token_use (ft); - ffestb_local_.do_stmt.var = expr; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDO, (ffeexprCallback) ffestb_do7_); -} - -/* ffestb_do7_ -- "DO" [label] [,] var-expr EQUALS expr - - (ffestb_do7_) // to expression handler - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do7_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (expr == NULL) - break; - ffesta_tokens[3] = ffelex_token_use (ft); - ffestb_local_.do_stmt.start = expr; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDO, (ffeexprCallback) ffestb_do8_); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do8_ -- "DO" [label] [,] var-expr EQUALS expr COMMA expr - - (ffestb_do8_) // to expression handler - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do8_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffesta_tokens[4] = ffelex_token_use (ft); - ffestb_local_.do_stmt.end = expr; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDO, (ffeexprCallback) ffestb_do9_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - ffesta_tokens[4] = ffelex_token_use (ft); - ffestb_local_.do_stmt.end = expr; - return (ffelexHandler) ffestb_do9_ (NULL, NULL, t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_do9_ -- "DO" [label] [,] var-expr EQUALS expr COMMA expr - [COMMA expr] - - (ffestb_do9_) // to expression handler - - Make sure the statement has a valid form for the DO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_do9_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if ((expr == NULL) && (ft != NULL)) - break; - if (!ffesta_is_inhibited ()) - { - if (ffesta_tokens[1] != NULL) - ffestc_R819A (ffesta_construct_name, ffesta_tokens[1], - ffestb_local_.do_stmt.var, ffesta_tokens[2], - ffestb_local_.do_stmt.start, ffesta_tokens[3], - ffestb_local_.do_stmt.end, ffesta_tokens[4], expr, ft); - else - ffestc_R820A (ffesta_construct_name, ffestb_local_.do_stmt.var, - ffesta_tokens[2], ffestb_local_.do_stmt.start, - ffesta_tokens[3], ffestb_local_.do_stmt.end, - ffesta_tokens[4], expr, ft); - } - ffelex_token_kill (ffesta_tokens[4]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[4]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_else -- Parse the ELSE statement - - return ffestb_else; // to lexer - - Make sure the statement has a valid form for the ELSE statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_else (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstELSE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - ffestb_args.elsexyz.second = FFESTR_secondNone; - return (ffelexHandler) ffestb_else1_ (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - - ffesta_confirmed (); - ffestb_args.elsexyz.second = ffesta_second_kw; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_else1_; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstELSE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlELSE) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlELSE); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - } - else - ffesta_tokens[1] = NULL; - ffestb_args.elsexyz.second = FFESTR_secondNone; - return (ffelexHandler) ffestb_else1_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "ELSE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_elsexyz -- Parse an ELSEIF/ELSEWHERE statement - - return ffestb_elsexyz; // to lexer - - Expects len and second to be set in ffestb_args.elsexyz to the length - of the ELSExyz keyword involved and the corresponding ffestrSecond value. */ - -ffelexHandler -ffestb_elsexyz (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (ffesta_first_kw == FFESTR_firstELSEIF) - goto bad_0; /* :::::::::::::::::::: */ - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_else1_ (t); - - case FFELEX_typeNAME: - ffesta_confirmed (); - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffesta_first_kw != FFESTR_firstELSEIF) - goto bad_0; /* :::::::::::::::::::: */ - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_else1_ (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffesta_first_kw != FFESTR_firstELSEIF) - goto bad_1; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlELSEIF) - { - i = FFESTR_firstlELSEIF; - goto bad_i; /* :::::::::::::::::::: */ - } - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_else1_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlELSE); - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); -#if FFESTR_F90 - if ((ffestb_args.elsexyz.second == FFESTR_secondWHERE) - && (ffelex_token_length (ffesta_tokens[1]) != FFESTR_secondlWHERE)) - ffestb_args.elsexyz.second = FFESTR_secondNone; -#endif - return (ffelexHandler) ffestb_else1_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "ELSE IF", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_else1_ -- "ELSE" (NAME) - - return ffestb_else1_; // to lexer - - If EOS/SEMICOLON, implement the appropriate statement (keep in mind that - "ELSE WHERE" is ambiguous at the syntactic level). If OPEN_PAREN, start - expression analysis with callback at _2_. */ - -static ffelexHandler -ffestb_else1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - if (ffestb_args.elsexyz.second == FFESTR_secondIF) - { - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIF, (ffeexprCallback) ffestb_else2_); - } - /* Fall through. */ - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE", t); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - } - - switch (ffestb_args.elsexyz.second) - { -#if FFESTR_F90 - case FFESTR_secondWHERE: - if (!ffesta_is_inhibited ()) - if ((ffesta_first_kw == FFESTR_firstELSEWHERE) - && (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME)) - ffestc_R744 (); - else - ffestc_elsewhere (ffesta_tokens[1]); /* R744 or R805. */ - break; -#endif - - default: - if (!ffesta_is_inhibited ()) - ffestc_R805 (ffesta_tokens[1]); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); -} - -/* ffestb_else2_ -- "ELSE" "IF" OPEN_PAREN expr - - (ffestb_else2_) // to expression handler - - Make sure the next token is CLOSE_PAREN. */ - -static ffelexHandler -ffestb_else2_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffestb_local_.else_stmt.expr = expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_else3_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE IF", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_else3_ -- "ELSE" "IF" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_else3_; // to lexer - - Make sure the next token is "THEN". */ - -static ffelexHandler -ffestb_else3_ (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_confirmed (); - if (ffestr_first (t) == FFESTR_firstTHEN) - return (ffelexHandler) ffestb_else4_; - break; - - case FFELEX_typeNAMES: - ffesta_confirmed (); - if (ffestr_first (t) != FFESTR_firstTHEN) - break; - if (ffelex_token_length (t) == FFESTR_firstlTHEN) - return (ffelexHandler) ffestb_else4_; - p = ffelex_token_text (t) + (i = FFESTR_firstlTHEN); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[2] = ffelex_token_name_from_names (t, i, 0); - return (ffelexHandler) ffestb_else5_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE IF", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "ELSE IF", t, i, NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_else4_ -- "ELSE" "IF" OPEN_PAREN expr CLOSE_PAREN "THEN" - - return ffestb_else4_; // to lexer - - Handle a NAME or EOS/SEMICOLON, then go to state _5_. */ - -static ffelexHandler -ffestb_else4_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_tokens[2] = NULL; - return (ffelexHandler) ffestb_else5_ (t); - - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_else5_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE IF", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_else5_ -- "ELSE" "IF" OPEN_PAREN expr CLOSE_PAREN "THEN" - - return ffestb_else5_; // to lexer - - Make sure the next token is EOS or SEMICOLON; implement R804. */ - -static ffelexHandler -ffestb_else5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R804 (ffestb_local_.else_stmt.expr, ffesta_tokens[1], - ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_tokens[2] != NULL) - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ELSE IF", t); - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_tokens[2] != NULL) - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_end -- Parse the END statement - - return ffestb_end; // to lexer - - Make sure the statement has a valid form for the END statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_end (ffelexToken t) -{ - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstEND) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_tokens[1] = NULL; - ffestb_args.endxyz.second = FFESTR_secondNone; - return (ffelexHandler) ffestb_end3_ (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - - ffesta_confirmed (); - ffestb_args.endxyz.second = ffesta_second_kw; - switch (ffesta_second_kw) - { - case FFESTR_secondFILE: - ffestb_args.beru.badname = "ENDFILE"; - return (ffelexHandler) ffestb_beru; - - case FFESTR_secondBLOCK: - return (ffelexHandler) ffestb_end1_; - -#if FFESTR_F90 - case FFESTR_secondINTERFACE: -#endif -#if FFESTR_VXT - case FFESTR_secondMAP: - case FFESTR_secondSTRUCTURE: - case FFESTR_secondUNION: -#endif -#if FFESTR_F90 - case FFESTR_secondWHERE: - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_end3_; -#endif - - case FFESTR_secondNone: - goto bad_1; /* :::::::::::::::::::: */ - - default: - return (ffelexHandler) ffestb_end2_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstEND) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlEND) - { - i = FFESTR_firstlEND; - goto bad_i; /* :::::::::::::::::::: */ - } - ffesta_tokens[1] = NULL; - ffestb_args.endxyz.second = FFESTR_secondNone; - return (ffelexHandler) ffestb_end3_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_endxyz -- Parse an ENDxyz statement - - return ffestb_endxyz; // to lexer - - Expects len and second to be set in ffestb_args.endxyz to the length - of the ENDxyz keyword involved and the corresponding ffestrSecond value. */ - -ffelexHandler -ffestb_endxyz (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_end3_ (t); - - case FFELEX_typeNAME: - ffesta_confirmed (); - switch (ffestb_args.endxyz.second) - { -#if FFESTR_F90 - case FFESTR_secondINTERFACE: -#endif -#if FFESTR_VXT - case FFESTR_secondMAP: - case FFESTR_secondSTRUCTURE: - case FFESTR_secondUNION: -#endif -#if FFESTR_F90 - case FFESTR_secondWHERE: - goto bad_1; /* :::::::::::::::::::: */ -#endif - - case FFESTR_secondBLOCK: - if (ffesta_second_kw != FFESTR_secondDATA) - goto bad_1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_end2_; - - default: - return (ffelexHandler) ffestb_end2_ (t); - } - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - if (ffestb_args.endxyz.second == FFESTR_secondBLOCK) - { - i = FFESTR_firstlEND; - goto bad_i; /* :::::::::::::::::::: */ - } - if (ffelex_token_length (ffesta_tokens[0]) != ffestb_args.endxyz.len) - { - p = ffelex_token_text (ffesta_tokens[0]) - + (i = ffestb_args.endxyz.len); - switch (ffestb_args.endxyz.second) - { -#if FFESTR_F90 - case FFESTR_secondINTERFACE: -#endif -#if FFESTR_VXT - case FFESTR_secondMAP: - case FFESTR_secondSTRUCTURE: - case FFESTR_secondUNION: -#endif -#if FFESTR_F90 - case FFESTR_secondWHERE: - goto bad_i; /* :::::::::::::::::::: */ -#endif - - default: - break; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_end3_ (t); - } - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_end3_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_end1_ -- "END" "BLOCK" - - return ffestb_end1_; // to lexer - - Make sure the next token is "DATA". */ - -static ffelexHandler -ffestb_end1_ (ffelexToken t) -{ - if ((ffelex_token_type (t) == FFELEX_typeNAME) - && (ffesrc_strcmp_2c (ffe_case_match (), ffelex_token_text (t), "DATA", - "data", "Data") - == 0)) - { - return (ffelexHandler) ffestb_end2_; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_end2_ -- "END" <unit-kind> - - return ffestb_end2_; // to lexer - - Make sure the next token is a NAME or EOS. */ - -static ffelexHandler -ffestb_end2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_end3_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_end3_ (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_end3_ -- "END" <unit-kind> (NAME) - - return ffestb_end3_; // to lexer - - Make sure the next token is an EOS, then implement the statement. */ - -static ffelexHandler -ffestb_end3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", t); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (ffestb_args.endxyz.second == FFESTR_secondNone) - { - if (!ffesta_is_inhibited ()) - ffestc_end (); - return (ffelexHandler) ffesta_zero (t); - } - break; - } - - switch (ffestb_args.endxyz.second) - { -#if FFESTR_F90 - case FFESTR_secondTYPE: - if (!ffesta_is_inhibited ()) - ffestc_R425 (ffesta_tokens[1]); - break; -#endif - -#if FFESTR_F90 - case FFESTR_secondWHERE: - if (!ffesta_is_inhibited ()) - ffestc_R745 (); - break; -#endif - - case FFESTR_secondIF: - if (!ffesta_is_inhibited ()) - ffestc_R806 (ffesta_tokens[1]); - break; - - case FFESTR_secondSELECT: - if (!ffesta_is_inhibited ()) - ffestc_R811 (ffesta_tokens[1]); - break; - - case FFESTR_secondDO: - if (!ffesta_is_inhibited ()) - ffestc_R825 (ffesta_tokens[1]); - break; - - case FFESTR_secondPROGRAM: - if (!ffesta_is_inhibited ()) - ffestc_R1103 (ffesta_tokens[1]); - break; - -#if FFESTR_F90 - case FFESTR_secondMODULE: - if (!ffesta_is_inhibited ()) - ffestc_R1106 (ffesta_tokens[1]); - break; -#endif - case FFESTR_secondBLOCK: - case FFESTR_secondBLOCKDATA: - if (!ffesta_is_inhibited ()) - ffestc_R1112 (ffesta_tokens[1]); - break; - -#if FFESTR_F90 - case FFESTR_secondINTERFACE: - if (!ffesta_is_inhibited ()) - ffestc_R1203 (); - break; -#endif - - case FFESTR_secondFUNCTION: - if (!ffesta_is_inhibited ()) - ffestc_R1221 (ffesta_tokens[1]); - break; - - case FFESTR_secondSUBROUTINE: - if (!ffesta_is_inhibited ()) - ffestc_R1225 (ffesta_tokens[1]); - break; - -#if FFESTR_VXT - case FFESTR_secondSTRUCTURE: - if (!ffesta_is_inhibited ()) - ffestc_V004 (); - break; -#endif - -#if FFESTR_VXT - case FFESTR_secondUNION: - if (!ffesta_is_inhibited ()) - ffestc_V010 (); - break; -#endif - -#if FFESTR_VXT - case FFESTR_secondMAP: - if (!ffesta_is_inhibited ()) - ffestc_V013 (); - break; -#endif - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "END", ffesta_tokens[0]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); -} - -/* ffestb_goto -- Parse the GOTO statement - - return ffestb_goto; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_goto (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffesta_first_kw) - { - case FFESTR_firstGO: - if ((ffelex_token_type (t) != FFELEX_typeNAME) - || (ffesta_second_kw != FFESTR_secondTO)) - goto bad_1; /* :::::::::::::::::::: */ - ffesta_confirmed (); - return (ffelexHandler) ffestb_goto1_; - - case FFESTR_firstGOTO: - return (ffelexHandler) ffestb_goto1_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstGOTO) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - case FFELEX_typePERCENT: /* Since GOTO I%J is apparently valid - in '90. */ - case FFELEX_typeCOMMA: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - } - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlGOTO) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlGOTO); - if (ISDIGIT (*p)) - { - nt = ffelex_token_number_from_names (ffesta_tokens[0], i); - p += ffelex_token_length (nt); - i += ffelex_token_length (nt); - if (*p != '\0') - { - ffelex_token_kill (nt); - goto bad_i; /* :::::::::::::::::::: */ - } - } - else if (ffesrc_is_name_init (*p)) - { - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - } - else - goto bad_i; /* :::::::::::::::::::: */ - next = (ffelexHandler) ffestb_goto1_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } - return (ffelexHandler) ffestb_goto1_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "GO TO", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "GO TO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "GO TO", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto1_ -- "GOTO" or "GO" "TO" - - return ffestb_goto1_; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - if (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME) - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_goto2_; - - case FFELEX_typeOPEN_PAREN: - ffesta_tokens[1] = ffelex_token_use (t); - ffestb_subrargs_.label_list.labels = ffestt_tokenlist_create (); - ffestb_subrargs_.label_list.handler = (ffelexHandler) ffestb_goto3_; - return (ffelexHandler) ffestb_subr_label_list_; - - case FFELEX_typeNAME: - if (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME) - ffesta_confirmed (); - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextAGOTO, - (ffeexprCallback) ffestb_goto4_))) - (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "GO TO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto2_ -- "GO/TO" NUMBER - - return ffestb_goto2_; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R836 (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "GO TO", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto3_ -- "GO/TO" OPEN_PAREN label-list CLOSE_PAREN - - return ffestb_goto3_; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto3_ (ffelexToken t) -{ - if (!ffestb_subrargs_.label_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextCGOTO, - (ffeexprCallback) ffestb_goto5_); - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - ffesta_confirmed (); - /* Fall through. */ - case FFELEX_typeOPEN_PAREN: /* Could still be assignment!! */ - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextCGOTO, - (ffeexprCallback) ffestb_goto5_))) - (t); - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "computed-GOTO", t); - ffelex_token_kill (ffesta_tokens[1]); - ffestt_tokenlist_kill (ffestb_subrargs_.label_list.labels); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto4_ -- "GO/TO" expr - - (ffestb_goto4_) // to expression handler - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto4_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffestb_local_.go_to.expr = expr; - return (ffelexHandler) ffestb_goto6_; - - case FFELEX_typeOPEN_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffestb_local_.go_to.expr = expr; - return (ffelexHandler) ffestb_goto6_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R839 (expr, ft, NULL); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assigned-GOTO", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto5_ -- "GO/TO" OPEN_PAREN label-list CLOSE_PAREN (COMMA) expr - - (ffestb_goto5_) // to expression handler - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto5_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R837 (ffestb_subrargs_.label_list.labels, expr, ft); - ffelex_token_kill (ffesta_tokens[1]); - ffestt_tokenlist_kill (ffestb_subrargs_.label_list.labels); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "computed-GOTO", t); - ffelex_token_kill (ffesta_tokens[1]); - ffestt_tokenlist_kill (ffestb_subrargs_.label_list.labels); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto6_ -- "GO/TO" expr (COMMA) - - return ffestb_goto6_; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto6_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffesta_tokens[2] = ffelex_token_use (t); - ffestb_subrargs_.label_list.labels = ffestt_tokenlist_create (); - ffestb_subrargs_.label_list.handler = (ffelexHandler) ffestb_goto7_; - return (ffelexHandler) ffestb_subr_label_list_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assigned-GOTO", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_goto7_ -- "GO/TO" expr (COMMA) OPEN_PAREN label-list CLOSE_PAREN - - return ffestb_goto7_; // to lexer - - Make sure the statement has a valid form for the GOTO statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_goto7_ (ffelexToken t) -{ - if (!ffestb_subrargs_.label_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R839 (ffestb_local_.go_to.expr, ffesta_tokens[1], - ffestb_subrargs_.label_list.labels); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffestt_tokenlist_kill (ffestb_subrargs_.label_list.labels); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assigned-GOTO", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffestt_tokenlist_kill (ffestb_subrargs_.label_list.labels); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_halt -- Parse the STOP/PAUSE statement - - return ffestb_halt; // to lexer - - Make sure the statement has a valid form for the STOP/PAUSE statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_halt (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - ffesta_confirmed (); - break; - } - - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextSTOP, - (ffeexprCallback) ffestb_halt1_))) - (t); - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - ffesta_confirmed (); - break; - } - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextSTOP, - (ffeexprCallback) ffestb_halt1_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - ffestb_args.halt.len); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - (ffesta_first_kw == FFESTR_firstSTOP) - ? "STOP" : "PAUSE", - ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - (ffesta_first_kw == FFESTR_firstSTOP) - ? "STOP" : "PAUSE", - t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_halt1_ -- "STOP/PAUSE" expr - - (ffestb_halt1_) // to expression handler - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_halt1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (ffesta_first_kw == FFESTR_firstSTOP) - ffestc_R842 (expr, ft); - else - ffestc_R843 (expr, ft); - } - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - (ffesta_first_kw == FFESTR_firstSTOP) - ? "STOP" : "PAUSE", - t); - break; - } - - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_if -- Parse an IF statement - - return ffestb_if; // to lexer - - Make sure the statement has a valid form for an IF statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_if (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstIF) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstIF) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlIF) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextIF, - (ffeexprCallback) ffestb_if1_); - -bad_0: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IF", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IF", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_if1_ -- "IF" OPEN_PAREN expr - - (ffestb_if1_) // to expression handler - - Make sure the next token is CLOSE_PAREN. */ - -static ffelexHandler -ffestb_if1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffestb_local_.if_stmt.expr = expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_if2_; - - default: - break; - } - - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IF", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_if2_ -- "IF" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_if2_; // to lexer - - Make sure the next token is NAME. */ - -static ffelexHandler -ffestb_if2_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffesta_confirmed (); - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_if3_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - if ((ffesta_construct_name == NULL) - || (ffelex_token_type (t) != FFELEX_typeNUMBER)) - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IF", t); - else - ffesta_ffebad_2st (FFEBAD_INVALID_STMT_FORM, "CONSTRUCT", - ffesta_construct_name, t); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_if3_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NAME - - return ffestb_if3_; // to lexer - - If the next token is EOS or SEMICOLON and the preceding NAME was "THEN", - implement R803. Else, implement R807 and send the preceding NAME followed - by the current token. */ - -static ffelexHandler -ffestb_if3_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (ffestr_first (ffesta_tokens[2]) == FFESTR_firstTHEN) - { - if (!ffesta_is_inhibited ()) - ffestc_R803 (ffesta_construct_name, ffestb_local_.if_stmt.expr, - ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - return (ffelexHandler) ffesta_zero (t); - } - break; - - default: - break; - } - - if (ffesta_construct_name != NULL) - { - if (!ffesta_is_inhibited ()) - ffesta_ffebad_2st (FFEBAD_INVALID_STMT_FORM, "CONSTRUCT", - ffesta_construct_name, ffesta_tokens[2]); - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - } - - if (!ffesta_is_inhibited ()) - ffestc_R807 (ffestb_local_.if_stmt.expr, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - { - ffelexToken my_2 = ffesta_tokens[2]; - - next = (ffelexHandler) ffesta_two (my_2, t); - ffelex_token_kill (my_2); - } - return (ffelexHandler) next; -} - -/* ffestb_where -- Parse a WHERE statement - - return ffestb_where; // to lexer - - Make sure the statement has a valid form for a WHERE statement. - If it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_where (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstWHERE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstWHERE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlWHERE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextWHERE, - (ffeexprCallback) ffestb_where1_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -#endif -/* ffestb_where1_ -- "WHERE" OPEN_PAREN expr - - (ffestb_where1_) // to expression handler - - Make sure the next token is CLOSE_PAREN. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_where1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffestb_local_.if_stmt.expr = expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_where2_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_where2_ -- "WHERE" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_where2_; // to lexer - - Make sure the next token is NAME. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_where2_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - ffesta_confirmed (); - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_where3_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R742 (ffestb_local_.if_stmt.expr, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WHERE", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_where3_ -- "WHERE" OPEN_PAREN expr CLOSE_PAREN NAME - - return ffestb_where3_; // to lexer - - Implement R742. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_where3_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken my_2 = ffesta_tokens[2]; - - if (!ffesta_is_inhibited ()) - ffestc_R740 (ffestb_local_.if_stmt.expr, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - next = (ffelexHandler) ffesta_two (my_2, t); - ffelex_token_kill (my_2); - return (ffelexHandler) next; -} - -#endif -/* ffestb_let -- Parse an assignment statement - - return ffestb_let; // to lexer - - Make sure the statement has a valid form for an assignment statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_let (ffelexToken t) -{ - ffelexHandler next; - bool vxtparam; /* TRUE if it might really be a VXT PARAMETER - stmt. */ - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - vxtparam = FALSE; - break; - - case FFELEX_typeNAMES: - vxtparam = TRUE; - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - case FFELEX_typePERCENT: - case FFELEX_typePOINTS: - ffestb_local_.let.vxtparam = FALSE; - break; - - case FFELEX_typeEQUALS: - if (!vxtparam || (ffesta_first_kw != FFESTR_firstPARAMETER)) - { - ffestb_local_.let.vxtparam = FALSE; - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + FFESTR_firstlPARAMETER; - ffestb_local_.let.vxtparam = ffesrc_is_name_init (*p); - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - next = (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextLET, - (ffeexprCallback) ffestb_let1_))) - (ffesta_tokens[0]); - return (ffelexHandler) (*next) (t); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assignment", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assignment", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_let1_ -- expr - - (ffestb_let1_) // to expression handler - - Make sure the next token is EQUALS or POINTS. */ - -static ffelexHandler -ffestb_let1_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - ffestb_local_.let.dest = expr; - - switch (ffelex_token_type (t)) - { -#if FFESTR_F90 - case FFELEX_typePOINTS: -#endif - case FFELEX_typeEQUALS: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextLET, (ffeexprCallback) ffestb_let2_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "assignment", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_let2_ -- expr EQUALS/POINTS expr - - (ffestb_end2_) // to expression handler - - Make sure the next token is EOS or SEMICOLON; implement the statement. */ - -static ffelexHandler -ffestb_let2_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (ffestb_local_.let.vxtparam && !ffestc_is_let_not_V027 ()) - break; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) -#if FFESTR_F90 - if (ffelex_token_type (ffesta_tokens[1]) == FFELEX_typeEQUALS) -#endif - ffestc_let (ffestb_local_.let.dest, expr, ft); -#if FFESTR_F90 - else - ffestc_R738 (ffestb_local_.let.dest, expr, ft); -#endif - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, - (ffelex_token_type (ffesta_tokens[1]) == FFELEX_typeEQUALS) - ? "assignment" : "pointer-assignment", - t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_type -- Parse the TYPE statement - - return ffestb_type; // to lexer - - Make sure the statement has a valid form for the TYPE statement. If - it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_type (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - return (ffelexHandler) ffestb_type1_; - - case FFELEX_typeNAME: /* No confirm here, because ambig w/V020 VXT - TYPE. */ - ffesta_tokens[1] = NULL; - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_type4_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlTYPE); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - ffesta_confirmed (); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_type1_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = NULL; - ffesta_tokens[2] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_type4_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "TYPE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_type1_ -- "TYPE" COMMA - - return ffestb_type1_; // to lexer - - Make sure the next token is a NAME. */ - -static ffelexHandler -ffestb_type1_ (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - ffestb_local_.type.kw = ffestr_other (t); - switch (ffestb_local_.varlist.kw) - { - case FFESTR_otherPUBLIC: - case FFESTR_otherPRIVATE: - return (ffelexHandler) ffestb_type2_; - - default: - ffelex_token_kill (ffesta_tokens[1]); - break; - } - break; - - case FFELEX_typeNAMES: - ffesta_tokens[1] = ffelex_token_use (t); - ffestb_local_.type.kw = ffestr_other (t); - switch (ffestb_local_.varlist.kw) - { - case FFESTR_otherPUBLIC: - p = ffelex_token_text (t) + (i = FFESTR_otherlPUBLIC); - if (*p == '\0') - return (ffelexHandler) ffestb_type2_; - if (!ffesrc_is_name_init (*p)) - goto bad_i1; /* :::::::::::::::::::: */ - ffesta_tokens[2] = ffelex_token_name_from_names (t, i, 0); - return (ffelexHandler) ffestb_type4_; - - case FFESTR_otherPRIVATE: - p = ffelex_token_text (t) + (i = FFESTR_otherlPRIVATE); - if (*p == '\0') - return (ffelexHandler) ffestb_type2_; - if (!ffesrc_is_name_init (*p)) - goto bad_i1; /* :::::::::::::::::::: */ - ffesta_tokens[2] = ffelex_token_name_from_names (t, i, 0); - return (ffelexHandler) ffestb_type4_; - - default: - ffelex_token_kill (ffesta_tokens[1]); - break; - } - break; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_i1: /* :::::::::::::::::::: */ - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "TYPE", t, i, NULL); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_type2_ -- "TYPE" COMMA NAME - - return ffestb_type2_; // to lexer - - Handle COLONCOLON or NAME. */ - -static ffelexHandler -ffestb_type2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - return (ffelexHandler) ffestb_type3_; - - case FFELEX_typeNAME: - return (ffelexHandler) ffestb_type3_ (t); - - default: - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_type3_ -- "TYPE" [COMMA NAME [COLONCOLON]] - - return ffestb_type3_; // to lexer - - Make sure the next token is a NAME. */ - -static ffelexHandler -ffestb_type3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_type4_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_type4_ -- "TYPE" [COMMA NAME [COLONCOLON]] NAME - - return ffestb_type4_; // to lexer - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_type4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R424 (ffesta_tokens[1], ffestb_local_.type.kw, - ffesta_tokens[2]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE", t); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_varlist -- Parse EXTERNAL/INTENT/INTRINSIC/OPTIONAL/PUBLIC/PRIVATE - statement - - return ffestb_varlist; // to lexer - - Make sure the statement has a valid form. If it - does, implement the statement. */ - -ffelexHandler -ffestb_varlist (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521A (); - return (ffelexHandler) ffesta_zero (t); - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_private (); /* Either R523A or R521B. */ - return (ffelexHandler) ffesta_zero (t); -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeCOMMA: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - if (!ffesta_is_inhibited ()) - ffestc_R520_start (); - break; - - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521Astart (); - break; - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_R521Bstart (); - break; -#endif - - default: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - } - return (ffelexHandler) ffestb_varlist5_; - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstINTENT: - return (ffelexHandler) ffestb_varlist1_; -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAME: - ffesta_confirmed (); - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - if (!ffesta_is_inhibited ()) - ffestc_R1207_start (); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - goto bad_1; /* :::::::::::::::::::: */ -#endif - - case FFESTR_firstINTRINSIC: - if (!ffesta_is_inhibited ()) - ffestc_R1208_start (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - if (!ffesta_is_inhibited ()) - ffestc_R520_start (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521Astart (); - break; - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_R521Bstart (); - break; -#endif - - default: - break; - } - return (ffelexHandler) ffestb_varlist5_ (t); - } - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.varlist.len); - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstINTENT: - goto bad_1; /* :::::::::::::::::::: */ -#endif - - default: - break; - } - if (*p != '\0') - break; - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521A (); - return (ffelexHandler) ffesta_zero (t); - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_private (); /* Either R423A or R521B. */ - return (ffelexHandler) ffesta_zero (t); -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeCOMMA: - ffesta_confirmed (); /* Error, but clearly intended. */ - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstINTENT: - goto bad_1; /* :::::::::::::::::::: */ -#endif - - default: - break; - } - if (*p != '\0') - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - if (!ffesta_is_inhibited ()) - ffestc_R520_start (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521Astart (); - break; - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_R521Bstart (); - break; -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - return (ffelexHandler) ffestb_varlist5_; - - case FFELEX_typeOPEN_PAREN: - switch (ffesta_first_kw) - { -#if FFESTR_F90 - case FFESTR_firstINTENT: - if (*p != '\0') - goto bad_1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_varlist1_; -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAME: - ffesta_confirmed (); - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - if (!ffesta_is_inhibited ()) - ffestc_R1207_start (); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - goto bad_1; /* :::::::::::::::::::: */ -#endif - - case FFESTR_firstINTRINSIC: - if (!ffesta_is_inhibited ()) - ffestc_R1208_start (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - if (!ffesta_is_inhibited ()) - ffestc_R520_start (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_R521Astart (); - break; - - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_R521Bstart (); - break; -#endif - - default: - break; - } - return (ffelexHandler) ffestb_varlist5_ (t); - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - /* Here, we have at least one char after the first keyword and t is - COMMA or EOS/SEMICOLON. Also we know that this form is valid for - only the statements reaching here (specifically, INTENT won't reach - here). */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - ffestc_R1207_start (); - break; - - case FFESTR_firstINTRINSIC: - ffestc_R1208_start (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestc_R520_start (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - ffestc_R521Astart (); - break; - - case FFESTR_firstPRIVATE: - ffestc_R521Bstart (); - break; -#endif - - default: - assert (FALSE); - } - } - next = (ffelexHandler) ffestb_varlist5_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_varlist1_ -- "INTENT" OPEN_PAREN - - return ffestb_varlist1_; // to lexer - - Handle NAME. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_varlist1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - ffestb_local_.varlist.kw = ffestr_other (t); - switch (ffestb_local_.varlist.kw) - { - case FFESTR_otherIN: - return (ffelexHandler) ffestb_varlist2_; - - case FFESTR_otherINOUT: - return (ffelexHandler) ffestb_varlist3_; - - case FFESTR_otherOUT: - return (ffelexHandler) ffestb_varlist3_; - - default: - ffelex_token_kill (ffesta_tokens[1]); - break; - } - break; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_varlist2_ -- "INTENT" OPEN_PAREN "IN" - - return ffestb_varlist2_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_varlist2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_other (t)) - { - case FFESTR_otherOUT: - ffestb_local_.varlist.kw = FFESTR_otherINOUT; - return (ffelexHandler) ffestb_varlist3_; - - default: - break; - } - break; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_varlist4_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_varlist3_ -- "INTENT" OPEN_PAREN NAME ["OUT"] - - return ffestb_varlist3_; // to lexer - - Handle CLOSE_PAREN. */ - -static ffelexHandler -ffestb_varlist3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_varlist4_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_varlist4_ -- "INTENT" OPEN_PAREN NAME ["OUT"] CLOSE_PAREN - - return ffestb_varlist4_; // to lexer - - Handle COLONCOLON or NAME. */ - -static ffelexHandler -ffestb_varlist4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R519_start (ffesta_tokens[1], ffestb_local_.varlist.kw); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_varlist5_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R519_start (ffesta_tokens[1], ffestb_local_.varlist.kw); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_varlist5_ (t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_varlist5_ -- Handles the list of variable names - - return ffestb_varlist5_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_varlist5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_varlist6_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - ffestc_R1207_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffestc_R519_finish (); - break; -#endif - - case FFESTR_firstINTRINSIC: - ffestc_R1208_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestc_R520_finish (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - ffestc_R521Afinish (); - break; - - case FFESTR_firstPRIVATE: - ffestc_R521Bfinish (); - break; -#endif - - default: - assert (FALSE); - } - } - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_varlist6_ -- (whatever) NAME - - return ffestb_varlist6_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_varlist6_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - ffestc_R1207_item (ffesta_tokens[1]); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffestc_R519_item (ffesta_tokens[1]); - break; -#endif - - case FFESTR_firstINTRINSIC: - ffestc_R1208_item (ffesta_tokens[1]); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestc_R520_item (ffesta_tokens[1]); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - ffestc_R521Aitem (ffesta_tokens[1]); - break; - - case FFESTR_firstPRIVATE: - ffestc_R521Bitem (ffesta_tokens[1]); - break; -#endif - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_varlist5_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - ffestc_R1207_item (ffesta_tokens[1]); - ffestc_R1207_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffestc_R519_item (ffesta_tokens[1]); - ffestc_R519_finish (); - break; -#endif - - case FFESTR_firstINTRINSIC: - ffestc_R1208_item (ffesta_tokens[1]); - ffestc_R1208_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestc_R520_item (ffesta_tokens[1]); - ffestc_R520_finish (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - ffestc_R521Aitem (ffesta_tokens[1]); - ffestc_R521Afinish (); - break; - - case FFESTR_firstPRIVATE: - ffestc_R521Bitem (ffesta_tokens[1]); - ffestc_R521Bfinish (); - break; -#endif - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.varlist.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstEXTERNAL: - ffestc_R1207_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffestc_R519_finish (); - break; -#endif - - case FFESTR_firstINTRINSIC: - ffestc_R1208_finish (); - break; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - ffestc_R520_finish (); - break; -#endif - -#if FFESTR_F90 - case FFESTR_firstPUBLIC: - ffestc_R521Afinish (); - break; - - case FFESTR_firstPRIVATE: - ffestc_R521Bfinish (); - break; -#endif - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R423B -- Parse the SEQUENCE statement - - return ffestb_R423B; // to lexer - - Make sure the statement has a valid form for the SEQUENCE statement. If - it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_R423B (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstSEQUENCE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstSEQUENCE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlSEQUENCE) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSEQUENCE); - goto bad_i; /* :::::::::::::::::::: */ - } - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R423B (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "SEQUENCE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_R522 -- Parse the SAVE statement - - return ffestb_R522; // to lexer - - Make sure the statement has a valid form for the SAVE statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R522 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstSAVE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R522 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R522start (); - return (ffelexHandler) ffestb_R5221_ (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R522start (); - return (ffelexHandler) ffestb_R5221_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstSAVE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSAVE); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (*p != '\0') - break; - if (!ffesta_is_inhibited ()) - ffestc_R522 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_R522start (); - return (ffelexHandler) ffestb_R5221_ (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_R522start (); - return (ffelexHandler) ffestb_R5221_; - } - - /* Here, we have at least one char after "SAVE" and t is COMMA or - EOS/SEMICOLON. */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (!ffesta_is_inhibited ()) - ffestc_R522start (); - next = (ffelexHandler) ffestb_R5221_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "SAVE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5221_ -- "SAVE" [COLONCOLON] - - return ffestb_R5221_; // to lexer - - Handle NAME or SLASH. */ - -static ffelexHandler -ffestb_R5221_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffestb_local_.R522.is_cblock = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R5224_; - - case FFELEX_typeSLASH: - ffestb_local_.R522.is_cblock = TRUE; - return (ffelexHandler) ffestb_R5222_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R522finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5222_ -- "SAVE" [COLONCOLON] SLASH - - return ffestb_R5222_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5222_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R5223_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R522finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5223_ -- "SAVE" [COLONCOLON] SLASH NAME - - return ffestb_R5223_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_R5223_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_R5224_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R522finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5224_ -- "SAVE" [COLONCOLON] R523 - - return ffestb_R5224_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R5224_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - { - if (ffestb_local_.R522.is_cblock) - ffestc_R522item_cblock (ffesta_tokens[1]); - else - ffestc_R522item_object (ffesta_tokens[1]); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5221_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - if (ffestb_local_.R522.is_cblock) - ffestc_R522item_cblock (ffesta_tokens[1]); - else - ffestc_R522item_object (ffesta_tokens[1]); - ffestc_R522finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SAVE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R522finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R528 -- Parse the DATA statement - - return ffestb_R528; // to lexer - - Make sure the statement has a valid form for the DATA statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R528 (ffelexToken t) -{ - unsigned char *p; - ffeTokenLength i; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstDATA) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeSLASH: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - break; - } - ffestb_local_.data.started = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5281_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstDATA) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlDATA); - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (*p == '\0') - { - ffestb_local_.data.started = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) - ffestb_R5281_))) - (t); - } - break; - - case FFELEX_typeCOMMA: - case FFELEX_typeSLASH: - ffesta_confirmed (); - break; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.data.started = FALSE; - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - next = (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5281_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "DATA", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5281_ -- "DATA" expr-list - - (ffestb_R5281_) // to expression handler - - Handle COMMA or SLASH. */ - -static ffelexHandler -ffestb_R5281_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.data.started) - { - ffestc_R528_start (); - ffestb_local_.data.started = TRUE; - } - ffestc_R528_item_object (expr, ft); - } - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5281_); - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.data.started) - { - ffestc_R528_start (); - ffestb_local_.data.started = TRUE; - } - ffestc_R528_item_object (expr, ft); - ffestc_R528_item_startvals (); - } - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5282_); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", t); - break; - } - - if (ffestb_local_.data.started && !ffesta_is_inhibited ()) - ffestc_R528_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5282_ -- "DATA" expr-list SLASH expr-list - - (ffestb_R5282_) // to expression handler - - Handle ASTERISK, COMMA, or SLASH. */ - -static ffelexHandler -ffestb_R5282_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R528_item_value (NULL, NULL, expr, ft); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5282_); - - case FFELEX_typeASTERISK: - if (expr == NULL) - break; - ffestb_local_.data.expr = expr; - ffesta_tokens[1] = ffelex_token_use (ft); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5283_); - - case FFELEX_typeSLASH: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R528_item_value (NULL, NULL, expr, ft); - ffestc_R528_item_endvals (t); - } - return (ffelexHandler) ffestb_R5284_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", t); - break; - } - - if (!ffesta_is_inhibited ()) - { - ffestc_R528_item_endvals (t); - ffestc_R528_finish (); - } - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5283_ -- "DATA" expr-list SLASH expr ASTERISK expr - - (ffestb_R5283_) // to expression handler - - Handle COMMA or SLASH. */ - -static ffelexHandler -ffestb_R5283_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R528_item_value (ffestb_local_.data.expr, ffesta_tokens[1], - expr, ft); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5282_); - - case FFELEX_typeSLASH: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R528_item_value (ffestb_local_.data.expr, ffesta_tokens[1], - expr, ft); - ffestc_R528_item_endvals (t); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5284_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", t); - break; - } - - if (!ffesta_is_inhibited ()) - { - ffestc_R528_item_endvals (t); - ffestc_R528_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5284_ -- "DATA" expr-list SLASH expr-list SLASH - - return ffestb_R5284_; // to lexer - - Handle [COMMA] NAME or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R5284_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5281_); - - case FFELEX_typeNAME: - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_R5281_))) - (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R528_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DATA", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R528_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R537 -- Parse a PARAMETER statement - - return ffestb_R537; // to lexer - - Make sure the statement has a valid form for an PARAMETER statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R537 (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstPARAMETER) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstPARAMETER) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlPARAMETER) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_local_.parameter.started = FALSE; - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextPARAMETER, - (ffeexprCallback) ffestb_R5371_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R5371_ -- "PARAMETER" OPEN_PAREN expr - - (ffestb_R5371_) // to expression handler - - Make sure the next token is EQUALS. */ - -static ffelexHandler -ffestb_R5371_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffestb_local_.parameter.expr = expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextPARAMETER, (ffeexprCallback) ffestb_R5372_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - if (ffestb_local_.parameter.started) - ffestc_R537_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5372_ -- "PARAMETER" OPEN_PAREN expr EQUALS expr - - (ffestb_R5372_) // to expression handler - - Make sure the next token is COMMA or CLOSE_PAREN. */ - -static ffelexHandler -ffestb_R5372_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.parameter.started) - { - ffestc_R537_start (); - ffestb_local_.parameter.started = TRUE; - } - ffestc_R537_item (ffestb_local_.parameter.expr, ffesta_tokens[1], - expr, ft); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextPARAMETER, - (ffeexprCallback) ffestb_R5371_); - - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.parameter.started) - { - ffestc_R537_start (); - ffestb_local_.parameter.started = TRUE; - } - ffestc_R537_item (ffestb_local_.parameter.expr, ffesta_tokens[1], - expr, ft); - ffestc_R537_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5373_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - if (ffestb_local_.parameter.started) - ffestc_R537_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5373_ -- "PARAMETER" OPEN_PAREN expr EQUALS expr CLOSE_PAREN - - return ffestb_R5373_; // to lexer - - Make sure the next token is EOS or SEMICOLON, or generate an error. All - cleanup has already been done, by the way. */ - -static ffelexHandler -ffestb_R5373_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R542 -- Parse the NAMELIST statement - - return ffestb_R542; // to lexer - - Make sure the statement has a valid form for the NAMELIST statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R542 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstNAMELIST) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstNAMELIST) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlNAMELIST); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeSLASH: - break; - } - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R542_start (); - return (ffelexHandler) ffestb_R5421_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "NAMELIST", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5421_ -- "NAMELIST" SLASH - - return ffestb_R5421_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5421_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_R542_item_nlist (t); - return (ffelexHandler) ffestb_R5422_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5422_ -- "NAMELIST" SLASH NAME - - return ffestb_R5422_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_R5422_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_R5423_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5423_ -- "NAMELIST" SLASH NAME SLASH - - return ffestb_R5423_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5423_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_R542_item_nitem (t); - return (ffelexHandler) ffestb_R5424_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5424_ -- "NAMELIST" SLASH NAME SLASH NAME - - return ffestb_R5424_; // to lexer - - Handle COMMA, EOS/SEMICOLON, or SLASH. */ - -static ffelexHandler -ffestb_R5424_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R5425_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_R5421_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5425_ -- "NAMELIST" SLASH NAME SLASH NAME COMMA - - return ffestb_R5425_; // to lexer - - Handle NAME or SLASH. */ - -static ffelexHandler -ffestb_R5425_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_R542_item_nitem (t); - return (ffelexHandler) ffestb_R5424_; - - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_R5421_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NAMELIST", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R542_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R544 -- Parse an EQUIVALENCE statement - - return ffestb_R544; // to lexer - - Make sure the statement has a valid form for an EQUIVALENCE statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R544 (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstEQUIVALENCE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstEQUIVALENCE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlEQUIVALENCE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_local_.equivalence.started = FALSE; - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextEQUIVALENCE, - (ffeexprCallback) ffestb_R5441_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R5441_ -- "EQUIVALENCE" OPEN_PAREN expr - - (ffestb_R5441_) // to expression handler - - Make sure the next token is COMMA. */ - -static ffelexHandler -ffestb_R5441_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffestb_local_.equivalence.exprs = ffestt_exprlist_create (); - ffestt_exprlist_append (ffestb_local_.equivalence.exprs, expr, - ffelex_token_use (ft)); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextEQUIVALENCE, - (ffeexprCallback) ffestb_R5442_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", t); - if (ffestb_local_.equivalence.started) - ffestc_R544_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5442_ -- "EQUIVALENCE" OPEN_PAREN expr COMMA expr - - (ffestb_R5442_) // to expression handler - - Make sure the next token is COMMA or CLOSE_PAREN. For COMMA, we just - append the expression to our list and continue; for CLOSE_PAREN, we - append the expression and move to _3_. */ - -static ffelexHandler -ffestb_R5442_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.equivalence.exprs, expr, - ffelex_token_use (ft)); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextEQUIVALENCE, - (ffeexprCallback) ffestb_R5442_); - - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.equivalence.exprs, expr, - ffelex_token_use (ft)); - return (ffelexHandler) ffestb_R5443_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", t); - if (ffestb_local_.equivalence.started) - ffestc_R544_finish (); - ffestt_exprlist_kill (ffestb_local_.equivalence.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5443_ -- "EQUIVALENCE" OPEN_PAREN expr COMMA expr CLOSE_PAREN - - return ffestb_R5443_; // to lexer - - Make sure the next token is COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R5443_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.equivalence.started) - { - ffestc_R544_start (); - ffestb_local_.equivalence.started = TRUE; - } - ffestc_R544_item (ffestb_local_.equivalence.exprs); - } - ffestt_exprlist_kill (ffestb_local_.equivalence.exprs); - return (ffelexHandler) ffestb_R5444_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.equivalence.started) - { - ffestc_R544_start (); - ffestb_local_.equivalence.started = TRUE; - } - ffestc_R544_item (ffestb_local_.equivalence.exprs); - ffestc_R544_finish (); - } - ffestt_exprlist_kill (ffestb_local_.equivalence.exprs); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", t); - if (ffestb_local_.equivalence.started) - ffestc_R544_finish (); - ffestt_exprlist_kill (ffestb_local_.equivalence.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5444_ -- "EQUIVALENCE" OPEN_PAREN expr COMMA expr CLOSE_PAREN COMMA - - return ffestb_R5444_; // to lexer - - Make sure the next token is OPEN_PAREN, or generate an error. */ - -static ffelexHandler -ffestb_R5444_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextEQUIVALENCE, - (ffeexprCallback) ffestb_R5441_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EQUIVALENCE", t); - if (ffestb_local_.equivalence.started) - ffestc_R544_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R834 -- Parse the CYCLE statement - - return ffestb_R834; // to lexer - - Make sure the statement has a valid form for the CYCLE statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_R834 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCYCLE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8341_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_R8341_ (t); - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCYCLE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCYCLE); - if (*p == '\0') - { - ffesta_tokens[1] = NULL; - } - else - { - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - } - return (ffelexHandler) ffestb_R8341_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CYCLE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CYCLE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CYCLE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8341_ -- "CYCLE" [NAME] - - return ffestb_R8341_; // to lexer - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R8341_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R834 (ffesta_tokens[1]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CYCLE", t); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R835 -- Parse the EXIT statement - - return ffestb_R835; // to lexer - - Make sure the statement has a valid form for the EXIT statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_R835 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstEXIT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8351_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_R8351_ (t); - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstEXIT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlEXIT); - if (*p == '\0') - { - ffesta_tokens[1] = NULL; - } - else - { - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - } - return (ffelexHandler) ffestb_R8351_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EXIT", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EXIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "EXIT", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8351_ -- "EXIT" [NAME] - - return ffestb_R8351_; // to lexer - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R8351_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R835 (ffesta_tokens[1]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "EXIT", t); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R838 -- Parse the ASSIGN statement - - return ffestb_R838; // to lexer - - Make sure the statement has a valid form for the ASSIGN statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R838 (ffelexToken t) -{ - unsigned char *p; - ffeTokenLength i; - ffelexHandler next; - ffelexToken et; /* First token in target. */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstASSIGN) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNUMBER: - break; - } - ffesta_tokens[1] = ffelex_token_use (t); - ffesta_confirmed (); - return (ffelexHandler) ffestb_R8381_; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstASSIGN) - goto bad_0; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - /* Fall through. */ - case FFELEX_typePERCENT: - case FFELEX_typeOPEN_PAREN: - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlASSIGN); - if (! ISDIGIT (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_number_from_names (ffesta_tokens[0], i); - p += ffelex_token_length (ffesta_tokens[1]); /* Skip to "TO". */ - i += ffelex_token_length (ffesta_tokens[1]); - if (!ffesrc_char_match_init (*p, 'T', 't') /* "TO". */ - || (++i, !ffesrc_char_match_noninit (*++p, 'O', 'o'))) - { - bad_i_1: /* :::::::::::::::::::: */ - ffelex_token_kill (ffesta_tokens[1]); - goto bad_i; /* :::::::::::::::::::: */ - } - ++p, ++i; - if (!ffesrc_is_name_init (*p)) - goto bad_i_1; /* :::::::::::::::::::: */ - et = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - next = (ffelexHandler) - (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextASSIGN, - (ffeexprCallback) - ffestb_R8383_))) - (et); - ffelex_token_kill (et); - return (ffelexHandler) (*next) (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ASSIGN", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ASSIGN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "ASSIGN", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8381_ -- "ASSIGN" NUMBER - - return ffestb_R8381_; // to lexer - - Make sure the next token is "TO". */ - -static ffelexHandler -ffestb_R8381_ (ffelexToken t) -{ - if ((ffelex_token_type (t) == FFELEX_typeNAME) - && (ffesrc_strcmp_2c (ffe_case_match (), ffelex_token_text (t), "TO", "to", - "To") == 0)) - { - return (ffelexHandler) ffestb_R8382_; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ASSIGN", t); - if (ffelex_token_type (t) == FFELEX_typeNAME) - return (ffelexHandler) ffestb_R8382_ (t); /* Maybe user forgot "TO". */ - - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8382_ -- "ASSIGN" NUMBER ("TO") - - return ffestb_R8382_; // to lexer - - Make sure the next token is a name, then pass it along to the expression - evaluator as an LHS expression. The callback function is _3_. */ - -static ffelexHandler -ffestb_R8382_ (ffelexToken t) -{ - if (ffelex_token_type (t) == FFELEX_typeNAME) - { - return (ffelexHandler) - (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, FFEEXPR_contextASSIGN, - (ffeexprCallback) ffestb_R8383_))) - (t); - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ASSIGN", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8383_ -- "ASSIGN" NUMBER ("TO") expression - - (ffestb_R8383_) // to expression handler - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R8383_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R838 (ffesta_tokens[1], expr, ft); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ASSIGN", t); - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R840 -- Parse an arithmetic-IF statement - - return ffestb_R840; // to lexer - - Make sure the statement has a valid form for an arithmetic-IF statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R840 (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlIF) - goto bad_0; /* :::::::::::::::::::: */ - if (ffesta_first_kw != FFESTR_firstIF) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstIF) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextARITHIF, - (ffeexprCallback) ffestb_R8401_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R8401_ -- "IF" OPEN_PAREN expr - - (ffestb_R8401_) // to expression handler - - Make sure the next token is CLOSE_PAREN. */ - -static ffelexHandler -ffestb_R8401_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - ffestb_local_.if_stmt.expr = expr; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffelex_set_names (TRUE); /* In case it's a logical IF instead. */ - return (ffelexHandler) ffestb_R8402_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8402_ -- "IF" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_R8402_; // to lexer - - Make sure the next token is NUMBER. */ - -static ffelexHandler -ffestb_R8402_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffesta_confirmed (); - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8403_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8403_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NUMBER - - return ffestb_R8403_; // to lexer - - Make sure the next token is COMMA. */ - -static ffelexHandler -ffestb_R8403_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R8404_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8404_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NUMBER COMMA - - return ffestb_R8404_; // to lexer - - Make sure the next token is NUMBER. */ - -static ffelexHandler -ffestb_R8404_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffesta_tokens[3] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8405_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8405_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NUMBER COMMA NUMBER - - return ffestb_R8405_; // to lexer - - Make sure the next token is COMMA. */ - -static ffelexHandler -ffestb_R8405_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R8406_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8406_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NUMBER COMMA NUMBER COMMA - - return ffestb_R8406_; // to lexer - - Make sure the next token is NUMBER. */ - -static ffelexHandler -ffestb_R8406_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffesta_tokens[4] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8407_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8407_ -- "IF" OPEN_PAREN expr CLOSE_PAREN NUMBER COMMA NUMBER COMMA - NUMBER - - return ffestb_R8407_; // to lexer - - Make sure the next token is EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R8407_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R840 (ffestb_local_.if_stmt.expr, ffesta_tokens[1], - ffesta_tokens[2], ffesta_tokens[3], ffesta_tokens[4]); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[4]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "arithmetic-IF", t); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[4]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R841 -- Parse the CONTINUE statement - - return ffestb_R841; // to lexer - - Make sure the statement has a valid form for the CONTINUE statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_R841 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCONTINUE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCONTINUE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlCONTINUE) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCONTINUE); - goto bad_i; /* :::::::::::::::::::: */ - } - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R841 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTINUE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTINUE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CONTINUE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1102 -- Parse the PROGRAM statement - - return ffestb_R1102; // to lexer - - Make sure the statement has a valid form for the PROGRAM statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R1102 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstPROGRAM) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R11021_; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstPROGRAM) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlPROGRAM); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_R11021_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PROGRAM", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PROGRAM", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "PROGRAM", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11021_ -- "PROGRAM" NAME - - return ffestb_R11021_; // to lexer - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R11021_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1102 (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PROGRAM", t); - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_block -- Parse the BLOCK DATA statement - - return ffestb_block; // to lexer - - Make sure the statement has a valid form for the BLOCK DATA statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_block (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstBLOCK) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - if (ffesta_second_kw != FFESTR_secondDATA) - goto bad_1; /* :::::::::::::::::::: */ - break; - } - - ffesta_confirmed (); - return (ffelexHandler) ffestb_R1111_1_; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_blockdata -- Parse the BLOCKDATA statement - - return ffestb_blockdata; // to lexer - - Make sure the statement has a valid form for the BLOCKDATA statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_blockdata (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstBLOCKDATA) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R1111_2_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_R1111_2_ (t); - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstBLOCKDATA) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlBLOCKDATA); - if (*p == '\0') - { - ffesta_tokens[1] = NULL; - } - else - { - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - } - return (ffelexHandler) ffestb_R1111_2_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1111_1_ -- "BLOCK" "DATA" - - return ffestb_R1111_1_; // to lexer - - Make sure the next token is a NAME, EOS, or SEMICOLON token. */ - -static ffelexHandler -ffestb_R1111_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R1111_2_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_R1111_2_ (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", t); - break; - } - - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1111_2_ -- "BLOCK/DATA" NAME - - return ffestb_R1111_2_; // to lexer - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R1111_2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1111 (ffesta_tokens[1]); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "BLOCK DATA", t); - break; - } - - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1212 -- Parse the CALL statement - - return ffestb_R1212; // to lexer - - Make sure the statement has a valid form for the CALL statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R1212 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCALL) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - ffesta_confirmed (); - return (ffelexHandler) - (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, FFEEXPR_contextSUBROUTINEREF, - (ffeexprCallback) ffestb_R12121_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCALL) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCALL); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - next = (ffelexHandler) - (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, FFEEXPR_contextSUBROUTINEREF, - (ffeexprCallback) ffestb_R12121_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CALL", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CALL", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CALL", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12121_ -- "CALL" expr - - (ffestb_R12121_) // to expression handler - - Make sure the statement has a valid form for the CALL statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R12121_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R1212 (expr, ft); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CALL", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1227 -- Parse the RETURN statement - - return ffestb_R1227; // to lexer - - Make sure the statement has a valid form for the RETURN statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R1227 (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstRETURN) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - default: - break; - } - - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextRETURN, - (ffeexprCallback) ffestb_R12271_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstRETURN) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - default: - break; - } - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextRETURN, (ffeexprCallback) ffestb_R12271_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - FFESTR_firstlRETURN); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RETURN", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RETURN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R12271_ -- "RETURN" expr - - (ffestb_R12271_) // to expression handler - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R12271_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1227 (expr, ft); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RETURN", t); - break; - } - - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1228 -- Parse the CONTAINS statement - - return ffestb_R1228; // to lexer - - Make sure the statement has a valid form for the CONTAINS statement. If - it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_R1228 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCONTAINS) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCONTAINS) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlCONTAINS) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCONTAINS); - goto bad_i; /* :::::::::::::::::::: */ - } - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1228 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTAINS", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CONTAINS", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CONTAINS", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_V009 -- Parse the UNION statement - - return ffestb_V009; // to lexer - - Make sure the statement has a valid form for the UNION statement. If - it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V009 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstUNION) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstUNION) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlUNION) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlUNION); - goto bad_i; /* :::::::::::::::::::: */ - } - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V009 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "UNION", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "UNION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "UNION", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_construct -- Parse a construct name - - return ffestb_construct; // to lexer - - Make sure the statement can have a construct name (if-then-stmt, do-stmt, - select-case-stmt). */ - -ffelexHandler -ffestb_construct (ffelexToken t UNUSED) -{ - /* This handler gets invoked only when token 0 is NAME/NAMES and token 1 is - COLON. */ - - ffesta_confirmed (); - ffelex_set_names (TRUE); - return (ffelexHandler) ffestb_construct1_; -} - -/* ffestb_construct1_ -- NAME COLON - - return ffestb_construct1_; // to lexer - - Make sure we've got a NAME that is DO, DOWHILE, IF, SELECT, or SELECTCASE. */ - -static ffelexHandler -ffestb_construct1_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_first_kw = ffestr_first (t); - switch (ffesta_first_kw) - { - case FFESTR_firstIF: - ffestb_local_.construct.next = (ffelexHandler) ffestb_if; - break; - - case FFESTR_firstDO: - ffestb_local_.construct.next = (ffelexHandler) ffestb_do; - break; - - case FFESTR_firstDOWHILE: - ffestb_local_.construct.next = (ffelexHandler) ffestb_dowhile; - break; - - case FFESTR_firstSELECT: - case FFESTR_firstSELECTCASE: - ffestb_local_.construct.next = (ffelexHandler) ffestb_R809; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - ffesta_construct_name = ffesta_tokens[0]; - ffesta_tokens[0] = ffelex_token_use (t); - return (ffelexHandler) ffestb_construct2_; - - case FFELEX_typeNAMES: - ffesta_first_kw = ffestr_first (t); - switch (ffesta_first_kw) - { - case FFESTR_firstIF: - if (ffelex_token_length (t) != FFESTR_firstlIF) - goto bad; /* :::::::::::::::::::: */ - ffestb_local_.construct.next = (ffelexHandler) ffestb_if; - break; - - case FFESTR_firstDO: - ffestb_local_.construct.next = (ffelexHandler) ffestb_do; - break; - - case FFESTR_firstDOWHILE: - if (ffelex_token_length (t) != FFESTR_firstlDOWHILE) - goto bad; /* :::::::::::::::::::: */ - ffestb_local_.construct.next = (ffelexHandler) ffestb_dowhile; - break; - - case FFESTR_firstSELECTCASE: - if (ffelex_token_length (t) != FFESTR_firstlSELECTCASE) - goto bad; /* :::::::::::::::::::: */ - ffestb_local_.construct.next = (ffelexHandler) ffestb_R809; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - ffesta_construct_name = ffesta_tokens[0]; - ffesta_tokens[0] = ffelex_token_use (t); - return (ffelexHandler) ffestb_construct2_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_2st (FFEBAD_INVALID_STMT_FORM, "CONSTRUCT", - ffesta_tokens[0], t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_construct2_ -- NAME COLON "DO/DOWHILE/IF/SELECT/SELECTCASE" - - return ffestb_construct2_; // to lexer - - This extra step is needed to set ffesta_second_kw if the second token - (here) is a NAME, so DO and SELECT can continue to expect it. */ - -static ffelexHandler -ffestb_construct2_ (ffelexToken t) -{ - if (ffelex_token_type (t) == FFELEX_typeNAME) - ffesta_second_kw = ffestr_second (t); - return (ffelexHandler) (*ffestb_local_.construct.next) (t); -} - -/* ffestb_heap -- Parse an ALLOCATE/DEALLOCATE statement - - return ffestb_heap; // to lexer - - Make sure the statement has a valid form for an ALLOCATE/DEALLOCATE - statement. If it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_heap (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - break; - - case FFELEX_typeNAMES: - if (ffelex_token_length (ffesta_tokens[0]) != ffestb_args.heap.len) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_local_.heap.exprs = ffestt_exprlist_create (); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_args.heap.ctx, - (ffeexprCallback) ffestb_heap1_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_heap1_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr - - (ffestb_heap1_) // to expression handler - - Make sure the next token is COMMA. */ - -static ffelexHandler -ffestb_heap1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.heap.exprs, expr, - ffelex_token_use (t)); - return (ffelexHandler) ffestb_heap2_; - - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.heap.exprs, expr, - ffelex_token_use (t)); - ffesta_tokens[1] = NULL; - ffestb_local_.heap.expr = NULL; - return (ffelexHandler) ffestb_heap5_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_heap2_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr COMMA - - return ffestb_heap2_; // to lexer - - Make sure the next token is NAME. */ - -static ffelexHandler -ffestb_heap2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_heap3_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_heap3_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN expr COMMA NAME - - return ffestb_heap3_; // to lexer - - If token is EQUALS, make sure NAME was "STAT" and handle STAT variable; - else pass NAME and token to expression handler. */ - -static ffelexHandler -ffestb_heap3_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestr_other (ffesta_tokens[1]) != FFESTR_otherSTAT) - break; - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextHEAPSTAT, - (ffeexprCallback) ffestb_heap4_); - - default: - next = (ffelexHandler) - (*((ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_args.heap.ctx, - (ffeexprCallback) ffestb_heap1_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_heap4_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN ... COMMA "STAT" EQUALS - expr - - (ffestb_heap4_) // to expression handler - - Make sure the next token is CLOSE_PAREN. */ - -static ffelexHandler -ffestb_heap4_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffestb_local_.heap.expr = expr; - return (ffelexHandler) ffestb_heap5_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_heap5_ -- "ALLOCATE/DEALLOCATE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_heap5_; // to lexer - - Make sure the next token is EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_heap5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - if (ffesta_first_kw == FFESTR_firstALLOCATE) - ffestc_R620 (ffestb_local_.heap.exprs, ffestb_local_.heap.expr, - ffesta_tokens[1]); - else - ffestc_R625 (ffestb_local_.heap.exprs, ffestb_local_.heap.expr, - ffesta_tokens[1]); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.heap.badname, t); - ffestt_exprlist_kill (ffestb_local_.heap.exprs); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_module -- Parse the MODULEPROCEDURE statement - - return ffestb_module; // to lexer - - Make sure the statement has a valid form for the MODULEPROCEDURE statement. - If it does, implement the statement. - - 31-May-90 JCB 1.1 - Confirm NAME==MODULE followed by standard four invalid tokens, so we - get decent message if somebody forgets that MODULE requires a name. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_module (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexToken nt; - ffelexToken mt; /* Name in MODULE PROCEDUREname, i.e. - includes "PROCEDURE". */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstMODULE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - break; - - case FFELEX_typeCOLONCOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - goto bad_1m; /* :::::::::::::::::::: */ - - default: - goto bad_1m; /* :::::::::::::::::::: */ - } - - ffesta_confirmed (); - if (ffesta_second_kw != FFESTR_secondPROCEDURE) - { - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_module3_; - } - ffestb_local_.moduleprocedure.started = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_module1_; - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) - + (i = FFESTR_firstlMODULEPROCEDURE); - if ((ffesta_first_kw == FFESTR_firstMODULE) - || ((ffesta_first_kw == FFESTR_firstMODULEPROCEDURE) - && !ffesrc_is_name_init (*p))) - { /* Definitely not "MODULE PROCEDURE name". */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1m; /* :::::::::::::::::::: */ - - default: - goto bad_1m; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlMODULE); - if (!ffesrc_is_name_init (*p)) - goto bad_im; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (!ffesta_is_inhibited ()) - ffestc_R1105 (nt); - ffelex_token_kill (nt); - return (ffelexHandler) ffesta_zero (t); - } - - /* Here we know that we're indeed looking at a MODULEPROCEDURE - statement rather than MODULE and that the character following - MODULEPROCEDURE in the NAMES token is a valid first character for a - NAME. This means that unless the second token is COMMA, we have an - ambiguous statement that can be read either as MODULE PROCEDURE name - or MODULE PROCEDUREname, the former being an R1205, the latter an - R1105. */ - - if (ffesta_first_kw != FFESTR_firstMODULEPROCEDURE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: /* Aha, clearly not MODULE PROCEDUREname. */ - ffesta_confirmed (); - ffestb_local_.moduleprocedure.started = FALSE; - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_module2_ (t); - - case FFELEX_typeEOS: /* MODULE PROCEDURE name or MODULE - PROCEDUREname. */ - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - } - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - mt = ffelex_token_name_from_names (ffesta_tokens[0], FFESTR_firstlMODULE, - 0); - if (!ffesta_is_inhibited ()) - ffestc_module (mt, nt); /* Implement ambiguous statement. */ - ffelex_token_kill (nt); - ffelex_token_kill (mt); - return (ffelexHandler) ffesta_zero (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_1m: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_im: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "MODULE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_module1_ -- "MODULEPROCEDURE" or "MODULE" "PROCEDURE" - - return ffestb_module1_; // to lexer - - Make sure the statement has a valid form for the MODULEPROCEDURE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_module1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffestb_local_.moduleprocedure.started - && (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME)) - { - ffesta_confirmed (); - ffelex_token_kill (ffesta_tokens[1]); - } - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_module2_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (ffestb_local_.moduleprocedure.started) - break; /* Error if we've already seen NAME COMMA. */ - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1105 (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - if (ffestb_local_.moduleprocedure.started && !ffesta_is_inhibited ()) - ffestc_R1205_finish (); - else if (!ffestb_local_.moduleprocedure.started) - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_module2_ -- "MODULE/PROCEDURE" NAME - - return ffestb_module2_; // to lexer - - Make sure the statement has a valid form for the MODULEPROCEDURE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_module2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffestb_local_.moduleprocedure.started) - { - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1205_start (); - } - if (!ffesta_is_inhibited ()) - { - ffestc_R1205_item (ffesta_tokens[1]); - ffestc_R1205_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - if (!ffestb_local_.moduleprocedure.started) - { - ffestb_local_.moduleprocedure.started = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1205_start (); - } - if (!ffesta_is_inhibited ()) - ffestc_R1205_item (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_module1_; - - default: - break; - } - - if (ffestb_local_.moduleprocedure.started && !ffesta_is_inhibited ()) - ffestc_R1205_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE PROCEDURE", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_module3_ -- "MODULE" NAME - - return ffestb_module3_; // to lexer - - Make sure the statement has a valid form for the MODULE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_module3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1105 (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MODULE", t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_R809 -- Parse the SELECTCASE statement - - return ffestb_R809; // to lexer - - Make sure the statement has a valid form for the SELECTCASE statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R809 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffesta_first_kw) - { - case FFESTR_firstSELECT: - if ((ffelex_token_type (t) != FFELEX_typeNAME) - || (ffesta_second_kw != FFESTR_secondCASE)) - goto bad_1; /* :::::::::::::::::::: */ - ffesta_confirmed (); - return (ffelexHandler) ffestb_R8091_; - - case FFESTR_firstSELECTCASE: - return (ffelexHandler) ffestb_R8091_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstSELECTCASE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSELECTCASE); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_R8091_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8091_ -- "SELECTCASE" or "SELECT" "CASE" - - return ffestb_R8091_; // to lexer - - Make sure the statement has a valid form for the SELECTCASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8091_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextSELECTCASE, (ffeexprCallback) ffestb_R8092_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8092_ -- "SELECT/CASE" OPEN_PAREN expr - - (ffestb_R8092_) // to expression handler - - Make sure the statement has a valid form for the SELECTCASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8092_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffesta_tokens[1] = ffelex_token_use (ft); - ffestb_local_.selectcase.expr = expr; - return (ffelexHandler) ffestb_R8093_; - - default: - break; - } - - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8093_ -- "SELECT/CASE" OPEN_PAREN expr CLOSE_PAREN - - return ffestb_R8093_; // to lexer - - Make sure the statement has a valid form for the SELECTCASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8093_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R809 (ffesta_construct_name, ffestb_local_.selectcase.expr, - ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - return ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - if (ffesta_construct_name != NULL) - { - ffelex_token_kill (ffesta_construct_name); - ffesta_construct_name = NULL; - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "SELECT CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R810 -- Parse the CASE statement - - return ffestb_R810; // to lexer - - Make sure the statement has a valid form for the CASE statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R810 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCASE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - if (ffesta_second_kw != FFESTR_secondDEFAULT) - goto bad_1; /* :::::::::::::::::::: */ - ffestb_local_.case_stmt.cases = NULL; - return (ffelexHandler) ffestb_R8101_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.case_stmt.cases = ffestt_caselist_create (); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCASE, (ffeexprCallback) ffestb_R8103_); - } - - case FFELEX_typeNAMES: - switch (ffesta_first_kw) - { - case FFESTR_firstCASEDEFAULT: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - } - ffestb_local_.case_stmt.cases = NULL; - p = ffelex_token_text (ffesta_tokens[0]) - + (i = FFESTR_firstlCASEDEFAULT); - if (*p == '\0') - return (ffelexHandler) ffestb_R8101_ (t); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_name_from_names (ffesta_tokens[0], i, - 0); - return (ffelexHandler) ffestb_R8102_ (t); - - case FFESTR_firstCASE: - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCASE); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.case_stmt.cases = ffestt_caselist_create (); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCASE, (ffeexprCallback) ffestb_R8103_); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "CASE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8101_ -- "CASE" case-selector - - return ffestb_R8101_; // to lexer - - Make sure the statement has a valid form for the CASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8101_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R8102_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_tokens[1] = NULL; - return (ffelexHandler) ffestb_R8102_ (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - if (ffestb_local_.case_stmt.cases != NULL) - ffestt_caselist_kill (ffestb_local_.case_stmt.cases); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8102_ -- "CASE" case-selector [NAME] - - return ffestb_R8102_; // to lexer - - Make sure the statement has a valid form for the CASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8102_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R810 (ffestb_local_.case_stmt.cases, ffesta_tokens[1]); - if (ffestb_local_.case_stmt.cases != NULL) - ffestt_caselist_kill (ffestb_local_.case_stmt.cases); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - if (ffestb_local_.case_stmt.cases != NULL) - ffestt_caselist_kill (ffestb_local_.case_stmt.cases); - if (ffesta_tokens[1] != NULL) - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8103_ -- "CASE" OPEN_PAREN expr - - (ffestb_R8103_) // to expression handler - - Make sure the statement has a valid form for the CASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8103_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestt_caselist_append (ffestb_local_.case_stmt.cases, FALSE, expr, NULL, - ffelex_token_use (ft)); - return (ffelexHandler) ffestb_R8101_; - - case FFELEX_typeCOMMA: - ffestt_caselist_append (ffestb_local_.case_stmt.cases, FALSE, expr, NULL, - ffelex_token_use (ft)); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCASE, (ffeexprCallback) ffestb_R8103_); - - case FFELEX_typeCOLON: - ffestt_caselist_append (ffestb_local_.case_stmt.cases, TRUE, expr, NULL, - ffelex_token_use (ft)); /* NULL second expr for - now, just plug in. */ - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCASE, (ffeexprCallback) ffestb_R8104_); - - default: - break; - } - - ffestt_caselist_kill (ffestb_local_.case_stmt.cases); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R8104_ -- "CASE" OPEN_PAREN expr COLON expr - - (ffestb_R8104_) // to expression handler - - Make sure the statement has a valid form for the CASE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R8104_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.case_stmt.cases->previous->expr2 = expr; - return (ffelexHandler) ffestb_R8101_; - - case FFELEX_typeCOMMA: - ffestb_local_.case_stmt.cases->previous->expr2 = expr; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCASE, (ffeexprCallback) ffestb_R8103_); - - default: - break; - } - - ffestt_caselist_kill (ffestb_local_.case_stmt.cases); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CASE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R1001 -- Parse a FORMAT statement - - return ffestb_R1001; // to lexer - - Make sure the statement has a valid form for an FORMAT statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R1001 (ffelexToken t) -{ - ffesttFormatList f; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstFORMAT) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstFORMAT) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlFORMAT) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_local_.format.complained = FALSE; - ffestb_local_.format.f = NULL; /* No parent yet. */ - ffestb_local_.format.f = ffestt_formatlist_create (NULL, - ffelex_token_use (t)); - ffelex_set_names_pure (TRUE); /* Have even free-form lexer give us - NAMES. */ - return (ffelexHandler) ffestb_R10011_; - - case FFELEX_typeOPEN_ARRAY:/* "(/". */ - ffesta_confirmed (); - ffestb_local_.format.complained = FALSE; - ffestb_local_.format.f = ffestt_formatlist_create (NULL, - ffelex_token_use (t)); - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - ffelex_set_names_pure (TRUE); /* Have even free-form lexer give us - NAMES. */ - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R10011_ -- "FORMAT" OPEN_PAREN expr - - return ffestb_R10011_; // to lexer - - For CLOSE_PAREN, wrap up the format list and if it is the top-level one, - exit. For anything else, pass it to _2_. */ - -static ffelexHandler -ffestb_R10011_ (ffelexToken t) -{ - ffesttFormatList f; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - break; - - default: - return (ffelexHandler) ffestb_R10012_ (t); - } - - /* If we have a format we're working on, continue working on it. */ - - f = ffestb_local_.format.f->u.root.parent; - - if (f != NULL) - { - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - } - - return (ffelexHandler) ffestb_R100114_; -} - -/* ffestb_R10012_ -- "FORMAT" OPEN_PAREN [format-item-list] - - return ffestb_R10012_; // to lexer - - The initial state for a format-item. Here, just handle the initial - number, sign for number, or run-time expression. Also handle spurious - comma, close-paren (indicating spurious comma), close-array (like - close-paren but preceded by slash), and quoted strings. */ - -static ffelexHandler -ffestb_R10012_ (ffelexToken t) -{ - unsigned long unsigned_val; - ffesttFormatList f; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_ANGLE: - ffesta_confirmed (); - ffestb_local_.format.pre.t = ffelex_token_use (t); - ffelex_set_names_pure (FALSE); - if (!ffesta_seen_first_exec && !ffestb_local_.format.complained) - { - ffestb_local_.format.complained = TRUE; - ffebad_start (FFEBAD_FORMAT_EXPR_SPEC); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFORMAT, (ffeexprCallback) ffestb_R100115_); - - case FFELEX_typeNUMBER: - ffestb_local_.format.sign = FALSE; /* No sign present. */ - ffestb_local_.format.pre.present = TRUE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = ffelex_token_use (t); - ffestb_local_.format.pre.u.unsigned_val = unsigned_val - = strtoul (ffelex_token_text (t), NULL, 10); - ffelex_set_expecting_hollerith (unsigned_val, '\0', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - return (ffelexHandler) ffestb_R10014_; - - case FFELEX_typePLUS: - ffestb_local_.format.sign = TRUE; /* Positive. */ - ffestb_local_.format.pre.t = ffelex_token_use (t); - return (ffelexHandler) ffestb_R10013_; - - case FFELEX_typeMINUS: - ffestb_local_.format.sign = FALSE; /* Negative. */ - ffestb_local_.format.pre.t = ffelex_token_use (t); - return (ffelexHandler) ffestb_R10013_; - - case FFELEX_typeCOLON: - case FFELEX_typeCOLONCOLON:/* "::". */ - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: /* "//". */ - case FFELEX_typeNAMES: - case FFELEX_typeDOLLAR: - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeOPEN_ARRAY:/* "(/". */ - ffestb_local_.format.sign = FALSE; /* No sign present. */ - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R10014_ (t); - - case FFELEX_typeCOMMA: - ffebad_start (FFEBAD_FORMAT_EXTRA_COMMA); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffestb_R10012_; - - case FFELEX_typeCLOSE_PAREN: - ffebad_start (FFEBAD_FORMAT_EXTRA_COMMA); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeCLOSE_ARRAY: /* "/)". */ - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_PAREN, t); - for (f = ffestb_local_.format.f; - f->u.root.parent != NULL; - f = f->u.root.parent->next) - ; - ffestb_local_.format.f = f; - return (ffelexHandler) ffestb_R100114_ (t); - - case FFELEX_typeQUOTE: - if (ffe_is_vxt ()) - break; /* Error, probably something like FORMAT("17) - = X. */ - ffelex_set_expecting_hollerith (-1, '\"', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); /* Don't have to unset - this one. */ - return (ffelexHandler) ffestb_R100113_; - - case FFELEX_typeAPOSTROPHE: -#if 0 /* No apparent need for this, and not killed - anywhere. */ - ffesta_tokens[1] = ffelex_token_use (t); -#endif - ffelex_set_expecting_hollerith (-1, '\'', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); /* Don't have to unset - this one. */ - return (ffelexHandler) ffestb_R100113_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R10013_ -- "FORMAT" OPEN_PAREN [format-item-list] PLUS/MINUS - - return ffestb_R10013_; // to lexer - - Expect a NUMBER or complain about and then ignore the PLUS/MINUS. */ - -static ffelexHandler -ffestb_R10013_ (ffelexToken t) -{ - unsigned long unsigned_val; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestb_local_.format.pre.present = TRUE; - ffestb_local_.format.pre.rtexpr = FALSE; - unsigned_val = strtoul (ffelex_token_text (t), NULL, 10); - ffestb_local_.format.pre.u.signed_val = ffestb_local_.format.sign - ? unsigned_val : -unsigned_val; - ffestb_local_.format.sign = TRUE; /* Sign present. */ - return (ffelexHandler) ffestb_R10014_; - - default: - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffelex_token_kill (ffestb_local_.format.pre.t); - return (ffelexHandler) ffestb_R10012_ (t); - } -} - -/* ffestb_R10014_ -- "FORMAT" OPEN_PAREN [format-item-list] [[+/-] NUMBER] - - return ffestb_R10014_; // to lexer - - Here is where we expect to see the actual NAMES, COLON, SLASH, OPEN_PAREN, - OPEN_ARRAY, COLONCOLON, CONCAT, DOLLAR, or HOLLERITH that identifies what - kind of format-item we're dealing with. But if we see a NUMBER instead, it - means free-form spaces number like "5 6 X", so scale the current number - accordingly and reenter this state. (I really wouldn't be surprised if - they change this spacing rule in the F90 spec so that you can't embed - spaces within numbers or within keywords like BN in a free-source-form - program.) */ - -static ffelexHandler -ffestb_R10014_ (ffelexToken t) -{ - ffesttFormatList f; - ffeTokenLength i; - char *p; - ffestrFormat kw; - - ffelex_set_expecting_hollerith (0, '\0', - ffewhere_line_unknown (), - ffewhere_column_unknown ()); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeHOLLERITH: - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeR1016; - f->t = ffelex_token_use (t); - ffelex_token_kill (ffestb_local_.format.pre.t); /* It WAS present! */ - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeNUMBER: - assert (ffestb_local_.format.pre.present); - ffesta_confirmed (); - if (ffestb_local_.format.pre.rtexpr) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffestb_R10014_; - } - if (ffestb_local_.format.sign) - { - for (i = ffelex_token_length (t) + 1; i > 0; --i) - ffestb_local_.format.pre.u.signed_val *= 10; - ffestb_local_.format.pre.u.signed_val += strtoul (ffelex_token_text (t), - NULL, 10); - } - else - { - for (i = ffelex_token_length (t) + 1; i > 0; --i) - ffestb_local_.format.pre.u.unsigned_val *= 10; - ffestb_local_.format.pre.u.unsigned_val += strtoul (ffelex_token_text (t), - NULL, 10); - ffelex_set_expecting_hollerith (ffestb_local_.format.pre.u.unsigned_val, - '\0', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); - } - return (ffelexHandler) ffestb_R10014_; - - case FFELEX_typeCOLONCOLON: /* "::". */ - if (ffestb_local_.format.pre.present) - { - ffesta_ffebad_1t (FFEBAD_FORMAT_BAD_COLON_SPEC, - ffestb_local_.format.pre.t); - ffelex_token_kill (ffestb_local_.format.pre.t); - ffestb_local_.format.pre.present = FALSE; - } - else - { - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeCOLON; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeCOLON; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeCOLON: - if (ffestb_local_.format.pre.present) - { - ffesta_ffebad_1t (FFEBAD_FORMAT_BAD_COLON_SPEC, - ffestb_local_.format.pre.t); - ffelex_token_kill (ffestb_local_.format.pre.t); - return (ffelexHandler) ffestb_R100112_; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeCOLON; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeCONCAT: /* "//". */ - if (ffestb_local_.format.sign) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffestb_local_.format.pre.u.unsigned_val - = (ffestb_local_.format.pre.u.signed_val < 0) - ? -ffestb_local_.format.pre.u.signed_val - : ffestb_local_.format.pre.u.signed_val; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val = ffestb_local_.format.pre; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val = ffestb_local_.format.pre; - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeSLASH: - if (ffestb_local_.format.sign) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffestb_local_.format.pre.u.unsigned_val - = (ffestb_local_.format.pre.u.signed_val < 0) - ? -ffestb_local_.format.pre.u.signed_val - : ffestb_local_.format.pre.u.signed_val; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val = ffestb_local_.format.pre; - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeOPEN_PAREN: - if (ffestb_local_.format.sign) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffestb_local_.format.pre.u.unsigned_val - = (ffestb_local_.format.pre.u.signed_val < 0) - ? -ffestb_local_.format.pre.u.signed_val - : ffestb_local_.format.pre.u.signed_val; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeFORMAT; - f->t = ffelex_token_use (t); - f->u.R1003D.R1004 = ffestb_local_.format.pre; - f->u.R1003D.format = ffestb_local_.format.f - = ffestt_formatlist_create (f, ffelex_token_use (t)); - return (ffelexHandler) ffestb_R10011_; - - case FFELEX_typeOPEN_ARRAY:/* "(/". */ - if (ffestb_local_.format.sign) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffestb_local_.format.pre.u.unsigned_val - = (ffestb_local_.format.pre.u.signed_val < 0) - ? -ffestb_local_.format.pre.u.signed_val - : ffestb_local_.format.pre.u.signed_val; - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeFORMAT; - f->t = ffelex_token_use (t); - f->u.R1003D.R1004 = ffestb_local_.format.pre; - f->u.R1003D.format = ffestb_local_.format.f - = ffestt_formatlist_create (f, ffelex_token_use (t)); - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R100112_; - - case FFELEX_typeCLOSE_ARRAY: /* "/)". */ - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val = ffestb_local_.format.pre; - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeQUOTE: - if (ffe_is_vxt ()) - break; /* A totally bad character in a VXT FORMAT. */ - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffelex_token_kill (ffestb_local_.format.pre.t); - ffesta_confirmed (); -#if 0 /* No apparent need for this, and not killed - anywhere. */ - ffesta_tokens[1] = ffelex_token_use (t); -#endif - ffelex_set_expecting_hollerith (-1, '\"', - ffelex_token_where_line (t), - ffelex_token_where_column (t)); /* Don't have to unset - this one. */ - return (ffelexHandler) ffestb_R100113_; - - case FFELEX_typeAPOSTROPHE: - ffesta_confirmed (); - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffelex_token_kill (ffestb_local_.format.pre.t); -#if 0 /* No apparent need for this, and not killed - anywhere. */ - ffesta_tokens[1] = ffelex_token_use (t); -#endif - ffelex_set_expecting_hollerith (-1, '\'', ffelex_token_where_line (t), - ffelex_token_where_column (t)); /* Don't have to unset - this one. */ - return (ffelexHandler) ffestb_R100113_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_PAREN, t); - for (f = ffestb_local_.format.f; - f->u.root.parent != NULL; - f = f->u.root.parent->next) - ; - ffestb_local_.format.f = f; - ffelex_token_kill (ffestb_local_.format.pre.t); - return (ffelexHandler) ffestb_R100114_ (t); - - case FFELEX_typeDOLLAR: - ffestb_local_.format.t = ffelex_token_use (t); - if (ffestb_local_.format.pre.present) - ffesta_confirmed (); /* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeDOLLAR; - return (ffelexHandler) ffestb_R10015_; - - case FFELEX_typeNAMES: - kw = ffestr_format (t); - ffestb_local_.format.t = ffelex_token_use (t); - switch (kw) - { - case FFESTR_formatI: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeI; - i = FFESTR_formatlI; - break; - - case FFESTR_formatB: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeB; - i = FFESTR_formatlB; - break; - - case FFESTR_formatO: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeO; - i = FFESTR_formatlO; - break; - - case FFESTR_formatZ: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeZ; - i = FFESTR_formatlZ; - break; - - case FFESTR_formatF: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeF; - i = FFESTR_formatlF; - break; - - case FFESTR_formatE: - ffestb_local_.format.current = FFESTP_formattypeE; - i = FFESTR_formatlE; - break; - - case FFESTR_formatEN: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeEN; - i = FFESTR_formatlEN; - break; - - case FFESTR_formatG: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeG; - i = FFESTR_formatlG; - break; - - case FFESTR_formatL: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeL; - i = FFESTR_formatlL; - break; - - case FFESTR_formatA: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeA; - i = FFESTR_formatlA; - break; - - case FFESTR_formatD: - ffestb_local_.format.current = FFESTP_formattypeD; - i = FFESTR_formatlD; - break; - - case FFESTR_formatQ: - ffestb_local_.format.current = FFESTP_formattypeQ; - i = FFESTR_formatlQ; - break; - - case FFESTR_formatDOLLAR: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeDOLLAR; - i = FFESTR_formatlDOLLAR; - break; - - case FFESTR_formatP: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeP; - i = FFESTR_formatlP; - break; - - case FFESTR_formatT: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeT; - i = FFESTR_formatlT; - break; - - case FFESTR_formatTL: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeTL; - i = FFESTR_formatlTL; - break; - - case FFESTR_formatTR: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeTR; - i = FFESTR_formatlTR; - break; - - case FFESTR_formatX: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeX; - i = FFESTR_formatlX; - break; - - case FFESTR_formatS: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeS; - i = FFESTR_formatlS; - break; - - case FFESTR_formatSP: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeSP; - i = FFESTR_formatlSP; - break; - - case FFESTR_formatSS: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeSS; - i = FFESTR_formatlSS; - break; - - case FFESTR_formatBN: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeBN; - i = FFESTR_formatlBN; - break; - - case FFESTR_formatBZ: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeBZ; - i = FFESTR_formatlBZ; - break; - - case FFESTR_formatH: /* Error, either "H" or "<expr>H". */ - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeH; - i = FFESTR_formatlH; - break; - - case FFESTR_formatPD: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_name_from_names (t, - FFESTR_formatlP, 1); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - ffestb_local_.format.current = FFESTP_formattypeD; - i = FFESTR_formatlPD; - break; - - case FFESTR_formatPE: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_name_from_names (t, - FFESTR_formatlP, 1); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - ffestb_local_.format.current = FFESTP_formattypeE; - i = FFESTR_formatlPE; - break; - - case FFESTR_formatPEN: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_name_from_names (t, - FFESTR_formatlP, 1); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - ffestb_local_.format.current = FFESTP_formattypeEN; - i = FFESTR_formatlPEN; - break; - - case FFESTR_formatPF: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_name_from_names (t, - FFESTR_formatlP, 1); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - ffestb_local_.format.current = FFESTP_formattypeF; - i = FFESTR_formatlPF; - break; - - case FFESTR_formatPG: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_name_from_names (t, - FFESTR_formatlP, 1); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - ffestb_local_.format.current = FFESTP_formattypeG; - i = FFESTR_formatlPG; - break; - - default: - if (ffestb_local_.format.pre.present) - ffesta_confirmed ();/* Number preceding this invalid elsewhere. */ - ffestb_local_.format.current = FFESTP_formattypeNone; - p = strpbrk (ffelex_token_text (t), "0123456789"); - if (p == NULL) - i = ffelex_token_length (t); - else - i = p - ffelex_token_text (t); - break; - } - p = ffelex_token_text (t) + i; - if (*p == '\0') - return (ffelexHandler) ffestb_R10015_; - if (! ISDIGIT (*p)) - { - if (ffestb_local_.format.current == FFESTP_formattypeH) - p = strpbrk (p, "0123456789"); - else - { - p = NULL; - ffestb_local_.format.current = FFESTP_formattypeNone; - } - if (p == NULL) - return (ffelexHandler) ffestb_R10015_; - i = p - ffelex_token_text (t); /* Collect digits. */ - } - ffestb_local_.format.post.present = TRUE; - ffestb_local_.format.post.rtexpr = FALSE; - ffestb_local_.format.post.t = ffelex_token_number_from_names (t, i); - ffestb_local_.format.post.u.unsigned_val - = strtoul (ffelex_token_text (ffestb_local_.format.post.t), NULL, 10); - p += ffelex_token_length (ffestb_local_.format.post.t); - i += ffelex_token_length (ffestb_local_.format.post.t); - if (*p == '\0') - return (ffelexHandler) ffestb_R10016_; - if ((kw != FFESTR_formatP) || - !ffelex_is_firstnamechar ((unsigned char)*p)) - { - if (ffestb_local_.format.current != FFESTP_formattypeH) - ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, i, NULL); - return (ffelexHandler) ffestb_R10016_; - } - - /* Here we have [number]P[number][text]. Treat as - [number]P,[number][text]. */ - - ffestb_subr_R1001_append_p_ (); - t = ffestb_local_.format.t = ffelex_token_names_from_names (t, i, 0); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre = ffestb_local_.format.post; - kw = ffestr_format (t); - switch (kw) - { /* Only a few possibilities here. */ - case FFESTR_formatD: - ffestb_local_.format.current = FFESTP_formattypeD; - i = FFESTR_formatlD; - break; - - case FFESTR_formatE: - ffestb_local_.format.current = FFESTP_formattypeE; - i = FFESTR_formatlE; - break; - - case FFESTR_formatEN: - ffestb_local_.format.current = FFESTP_formattypeEN; - i = FFESTR_formatlEN; - break; - - case FFESTR_formatF: - ffestb_local_.format.current = FFESTP_formattypeF; - i = FFESTR_formatlF; - break; - - case FFESTR_formatG: - ffestb_local_.format.current = FFESTP_formattypeG; - i = FFESTR_formatlG; - break; - - default: - ffebad_start (FFEBAD_FORMAT_P_NOCOMMA); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - ffestb_local_.format.current = FFESTP_formattypeNone; - p = strpbrk (ffelex_token_text (t), "0123456789"); - if (p == NULL) - i = ffelex_token_length (t); - else - i = p - ffelex_token_text (t); - } - p = ffelex_token_text (t) + i; - if (*p == '\0') - return (ffelexHandler) ffestb_R10015_; - if (! ISDIGIT (*p)) - { - ffestb_local_.format.current = FFESTP_formattypeNone; - p = strpbrk (p, "0123456789"); - if (p == NULL) - return (ffelexHandler) ffestb_R10015_; - i = p - ffelex_token_text (t); /* Collect digits anyway. */ - } - ffestb_local_.format.post.present = TRUE; - ffestb_local_.format.post.rtexpr = FALSE; - ffestb_local_.format.post.t = ffelex_token_number_from_names (t, i); - ffestb_local_.format.post.u.unsigned_val - = strtoul (ffelex_token_text (ffestb_local_.format.post.t), NULL, 10); - p += ffelex_token_length (ffestb_local_.format.post.t); - i += ffelex_token_length (ffestb_local_.format.post.t); - if (*p == '\0') - return (ffelexHandler) ffestb_R10016_; - ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, i, NULL); - return (ffelexHandler) ffestb_R10016_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); -} - -/* ffestb_R10015_ -- [[+/-] NUMBER] NAMES - - return ffestb_R10015_; // to lexer - - Here we've gotten at least the initial mnemonic for the edit descriptor. - We expect either a NUMBER, for the post-mnemonic value, a NAMES, for - further clarification (in free-form only, sigh) of the mnemonic, or - anything else. In all cases we go to _6_, with the difference that for - NUMBER and NAMES we send the next token rather than the current token. */ - -static ffelexHandler -ffestb_R10015_ (ffelexToken t) -{ - bool split_pea; /* New NAMES requires splitting kP from new - edit desc. */ - ffestrFormat kw; - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_ANGLE: - ffesta_confirmed (); - ffestb_local_.format.post.t = ffelex_token_use (t); - ffelex_set_names_pure (FALSE); - if (!ffesta_seen_first_exec && !ffestb_local_.format.complained) - { - ffestb_local_.format.complained = TRUE; - ffebad_start (FFEBAD_FORMAT_EXPR_SPEC); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFORMAT, (ffeexprCallback) ffestb_R100116_); - - case FFELEX_typeNUMBER: - ffestb_local_.format.post.present = TRUE; - ffestb_local_.format.post.rtexpr = FALSE; - ffestb_local_.format.post.t = ffelex_token_use (t); - ffestb_local_.format.post.u.unsigned_val - = strtoul (ffelex_token_text (t), NULL, 10); - return (ffelexHandler) ffestb_R10016_; - - case FFELEX_typeNAMES: - ffesta_confirmed (); /* NAMES " " NAMES invalid elsewhere in - free-form. */ - kw = ffestr_format (t); - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - split_pea = TRUE; - break; - - case FFESTP_formattypeH: /* An error, maintain this indicator. */ - kw = FFESTR_formatNone; - split_pea = FALSE; - break; - - default: - split_pea = FALSE; - break; - } - - switch (kw) - { - case FFESTR_formatF: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - ffestb_local_.format.current = FFESTP_formattypeF; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlF; - break; - - case FFESTR_formatE: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - ffestb_local_.format.current = FFESTP_formattypeE; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlE; - break; - - case FFESTR_formatEN: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - ffestb_local_.format.current = FFESTP_formattypeEN; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlEN; - break; - - case FFESTR_formatG: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - ffestb_local_.format.current = FFESTP_formattypeG; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlG; - break; - - case FFESTR_formatL: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeT: - ffestb_local_.format.current = FFESTP_formattypeTL; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlL; - break; - - case FFESTR_formatD: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeP: - ffestb_local_.format.current = FFESTP_formattypeD; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlD; - break; - - case FFESTR_formatS: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeS: - ffestb_local_.format.current = FFESTP_formattypeSS; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlS; - break; - - case FFESTR_formatP: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeS: - ffestb_local_.format.current = FFESTP_formattypeSP; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlP; - break; - - case FFESTR_formatR: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeT: - ffestb_local_.format.current = FFESTP_formattypeTR; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlR; - break; - - case FFESTR_formatZ: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeB: - ffestb_local_.format.current = FFESTP_formattypeBZ; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlZ; - break; - - case FFESTR_formatN: - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeE: - ffestb_local_.format.current = FFESTP_formattypeEN; - break; - - case FFESTP_formattypeB: - ffestb_local_.format.current = FFESTP_formattypeBN; - break; - - default: - ffestb_local_.format.current = FFESTP_formattypeNone; - break; - } - i = FFESTR_formatlN; - break; - - default: - if (ffestb_local_.format.current != FFESTP_formattypeH) - ffestb_local_.format.current = FFESTP_formattypeNone; - split_pea = FALSE; /* Go ahead and let the P be in the party. */ - p = strpbrk (ffelex_token_text (t), "0123456789"); - if (p == NULL) - i = ffelex_token_length (t); - else - i = p - ffelex_token_text (t); - } - - if (split_pea) - { - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.t = ffelex_token_use (t); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre.present = FALSE; - ffestb_local_.format.pre.rtexpr = FALSE; - ffestb_local_.format.pre.t = NULL; - ffestb_local_.format.pre.u.unsigned_val = 1; - } - - p = ffelex_token_text (t) + i; - if (*p == '\0') - return (ffelexHandler) ffestb_R10015_; - if (! ISDIGIT (*p)) - { - ffestb_local_.format.current = FFESTP_formattypeNone; - p = strpbrk (p, "0123456789"); - if (p == NULL) - return (ffelexHandler) ffestb_R10015_; - i = p - ffelex_token_text (t); /* Collect digits anyway. */ - } - ffestb_local_.format.post.present = TRUE; - ffestb_local_.format.post.rtexpr = FALSE; - ffestb_local_.format.post.t = ffelex_token_number_from_names (t, i); - ffestb_local_.format.post.u.unsigned_val - = strtoul (ffelex_token_text (ffestb_local_.format.post.t), NULL, 10); - p += ffelex_token_length (ffestb_local_.format.post.t); - i += ffelex_token_length (ffestb_local_.format.post.t); - if (*p == '\0') - return (ffelexHandler) ffestb_R10016_; - ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, i, NULL); - return (ffelexHandler) ffestb_R10016_; - - default: - ffestb_local_.format.post.present = FALSE; - ffestb_local_.format.post.rtexpr = FALSE; - ffestb_local_.format.post.t = NULL; - ffestb_local_.format.post.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R10016_ (t); - } -} - -/* ffestb_R10016_ -- [[+/-] NUMBER] NAMES NUMBER - - return ffestb_R10016_; // to lexer - - Expect a PERIOD here. Maybe find a NUMBER to append to the current - number, in which case return to this state. Maybe find a NAMES to switch - from a kP descriptor to a new descriptor (else the NAMES is spurious), - in which case generator the P item and go to state _4_. Anything - else, pass token on to state _8_. */ - -static ffelexHandler -ffestb_R10016_ (ffelexToken t) -{ - ffeTokenLength i; - - switch (ffelex_token_type (t)) - { - case FFELEX_typePERIOD: - return (ffelexHandler) ffestb_R10017_; - - case FFELEX_typeNUMBER: - assert (ffestb_local_.format.post.present); - ffesta_confirmed (); - if (ffestb_local_.format.post.rtexpr) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffestb_R10016_; - } - for (i = ffelex_token_length (t) + 1; i > 0; --i) - ffestb_local_.format.post.u.unsigned_val *= 10; - ffestb_local_.format.post.u.unsigned_val += strtoul (ffelex_token_text (t), - NULL, 10); - return (ffelexHandler) ffestb_R10016_; - - case FFELEX_typeNAMES: - ffesta_confirmed (); /* NUMBER " " NAMES invalid elsewhere. */ - if (ffestb_local_.format.current != FFESTP_formattypeP) - { - ffesta_ffebad_1t (FFEBAD_FORMAT_TEXT_IN_NUMBER, t); - return (ffelexHandler) ffestb_R10016_; - } - ffestb_subr_R1001_append_p_ (); - ffestb_local_.format.sign = FALSE; - ffestb_local_.format.pre = ffestb_local_.format.post; - return (ffelexHandler) ffestb_R10014_ (t); - - default: - ffestb_local_.format.dot.present = FALSE; - ffestb_local_.format.dot.rtexpr = FALSE; - ffestb_local_.format.dot.t = NULL; - ffestb_local_.format.dot.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R10018_ (t); - } -} - -/* ffestb_R10017_ -- [[+/-] NUMBER] NAMES NUMBER PERIOD - - return ffestb_R10017_; // to lexer - - Here we've gotten the period following the edit descriptor. - We expect either a NUMBER, for the dot value, or something else, which - probably means we're not even close to being in a real FORMAT statement. */ - -static ffelexHandler -ffestb_R10017_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_ANGLE: - ffestb_local_.format.dot.t = ffelex_token_use (t); - ffelex_set_names_pure (FALSE); - if (!ffesta_seen_first_exec && !ffestb_local_.format.complained) - { - ffestb_local_.format.complained = TRUE; - ffebad_start (FFEBAD_FORMAT_EXPR_SPEC); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFORMAT, (ffeexprCallback) ffestb_R100117_); - - case FFELEX_typeNUMBER: - ffestb_local_.format.dot.present = TRUE; - ffestb_local_.format.dot.rtexpr = FALSE; - ffestb_local_.format.dot.t = ffelex_token_use (t); - ffestb_local_.format.dot.u.unsigned_val - = strtoul (ffelex_token_text (t), NULL, 10); - return (ffelexHandler) ffestb_R10018_; - - default: - ffelex_token_kill (ffestb_local_.format.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - if (ffestb_local_.format.post.present) - ffelex_token_kill (ffestb_local_.format.post.t); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_DOT, t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R10018_ -- [[+/-] NUMBER] NAMES NUMBER PERIOD NUMBER - - return ffestb_R10018_; // to lexer - - Expect a NAMES here, which must begin with "E" to be valid. Maybe find a - NUMBER to append to the current number, in which case return to this state. - Anything else, pass token on to state _10_. */ - -static ffelexHandler -ffestb_R10018_ (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - assert (ffestb_local_.format.dot.present); - ffesta_confirmed (); - if (ffestb_local_.format.dot.rtexpr) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffestb_R10018_; - } - for (i = ffelex_token_length (t) + 1; i > 0; --i) - ffestb_local_.format.dot.u.unsigned_val *= 10; - ffestb_local_.format.dot.u.unsigned_val += strtoul (ffelex_token_text (t), - NULL, 10); - return (ffelexHandler) ffestb_R10018_; - - case FFELEX_typeNAMES: - if (!ffesrc_char_match_init (*(p = ffelex_token_text (t)), 'E', 'e')) - { - ffesta_ffebad_1t (FFEBAD_FORMAT_TEXT_IN_NUMBER, t); - return (ffelexHandler) ffestb_R10018_; - } - if (*++p == '\0') - return (ffelexHandler) ffestb_R10019_; /* Go get NUMBER. */ - i = 1; - if (! ISDIGIT (*p)) - { - ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, 1, NULL); - return (ffelexHandler) ffestb_R10018_; - } - ffestb_local_.format.exp.present = TRUE; - ffestb_local_.format.exp.rtexpr = FALSE; - ffestb_local_.format.exp.t = ffelex_token_number_from_names (t, i); - ffestb_local_.format.exp.u.unsigned_val - = strtoul (ffelex_token_text (ffestb_local_.format.exp.t), NULL, 10); - p += ffelex_token_length (ffestb_local_.format.exp.t); - i += ffelex_token_length (ffestb_local_.format.exp.t); - if (*p == '\0') - return (ffelexHandler) ffestb_R100110_; - ffesta_ffebad_1p (FFEBAD_FORMAT_TEXT_IN_NUMBER, t, i, NULL); - return (ffelexHandler) ffestb_R100110_; - - default: - ffestb_local_.format.exp.present = FALSE; - ffestb_local_.format.exp.rtexpr = FALSE; - ffestb_local_.format.exp.t = NULL; - ffestb_local_.format.exp.u.unsigned_val = 1; - return (ffelexHandler) ffestb_R100110_ (t); - } -} - -/* ffestb_R10019_ -- [[+/-] NUMBER] NAMES NUMBER PERIOD NUMBER "E" - - return ffestb_R10019_; // to lexer - - Here we've gotten the "E" following the edit descriptor. - We expect either a NUMBER, for the exponent value, or something else. */ - -static ffelexHandler -ffestb_R10019_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_ANGLE: - ffestb_local_.format.exp.t = ffelex_token_use (t); - ffelex_set_names_pure (FALSE); - if (!ffesta_seen_first_exec && !ffestb_local_.format.complained) - { - ffestb_local_.format.complained = TRUE; - ffebad_start (FFEBAD_FORMAT_EXPR_SPEC); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - } - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFORMAT, (ffeexprCallback) ffestb_R100118_); - - case FFELEX_typeNUMBER: - ffestb_local_.format.exp.present = TRUE; - ffestb_local_.format.exp.rtexpr = FALSE; - ffestb_local_.format.exp.t = ffelex_token_use (t); - ffestb_local_.format.exp.u.unsigned_val - = strtoul (ffelex_token_text (t), NULL, 10); - return (ffelexHandler) ffestb_R100110_; - - default: - ffelex_token_kill (ffestb_local_.format.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - if (ffestb_local_.format.post.present) - ffelex_token_kill (ffestb_local_.format.post.t); - if (ffestb_local_.format.dot.present) - ffelex_token_kill (ffestb_local_.format.dot.t); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_EXP, t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100110_ -- [[+/-] NUMBER] NAMES NUMBER [PERIOD NUMBER ["E" NUMBER]] - - return ffestb_R100110_; // to lexer - - Maybe find a NUMBER to append to the current number, in which case return - to this state. Anything else, handle current descriptor, then pass token - on to state _10_. */ - -static ffelexHandler -ffestb_R100110_ (ffelexToken t) -{ - ffeTokenLength i; - enum expect - { - required, - optional, - disallowed - }; - ffebad err; - enum expect pre; - enum expect post; - enum expect dot; - enum expect exp; - bool R1005; - ffesttFormatList f; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - assert (ffestb_local_.format.exp.present); - ffesta_confirmed (); - if (ffestb_local_.format.exp.rtexpr) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_NUMBER); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); - return (ffelexHandler) ffestb_R100110_; - } - for (i = ffelex_token_length (t) + 1; i > 0; --i) - ffestb_local_.format.exp.u.unsigned_val *= 10; - ffestb_local_.format.exp.u.unsigned_val += strtoul (ffelex_token_text (t), - NULL, 10); - return (ffelexHandler) ffestb_R100110_; - - default: - if (ffestb_local_.format.sign - && (ffestb_local_.format.current != FFESTP_formattypeP) - && (ffestb_local_.format.current != FFESTP_formattypeH)) - { - ffebad_start (FFEBAD_FORMAT_SPURIOUS_SIGN); - ffebad_here (0, ffelex_token_where_line (ffestb_local_.format.pre.t), - ffelex_token_where_column (ffestb_local_.format.pre.t)); - ffebad_finish (); - ffestb_local_.format.pre.u.unsigned_val - = (ffestb_local_.format.pre.u.signed_val < 0) - ? -ffestb_local_.format.pre.u.signed_val - : ffestb_local_.format.pre.u.signed_val; - } - switch (ffestb_local_.format.current) - { - case FFESTP_formattypeI: - err = FFEBAD_FORMAT_BAD_I_SPEC; - pre = optional; - post = required; - dot = optional; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeB: - err = FFEBAD_FORMAT_BAD_B_SPEC; - pre = optional; - post = required; - dot = optional; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeO: - err = FFEBAD_FORMAT_BAD_O_SPEC; - pre = optional; - post = required; - dot = optional; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeZ: - err = FFEBAD_FORMAT_BAD_Z_SPEC; - pre = optional; - post = required; - dot = optional; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeF: - err = FFEBAD_FORMAT_BAD_F_SPEC; - pre = optional; - post = required; - dot = required; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeE: - err = FFEBAD_FORMAT_BAD_E_SPEC; - pre = optional; - post = required; - dot = required; - exp = optional; - R1005 = TRUE; - break; - - case FFESTP_formattypeEN: - err = FFEBAD_FORMAT_BAD_EN_SPEC; - pre = optional; - post = required; - dot = required; - exp = optional; - R1005 = TRUE; - break; - - case FFESTP_formattypeG: - err = FFEBAD_FORMAT_BAD_G_SPEC; - pre = optional; - post = required; - dot = required; - exp = optional; - R1005 = TRUE; - break; - - case FFESTP_formattypeL: - err = FFEBAD_FORMAT_BAD_L_SPEC; - pre = optional; - post = required; - dot = disallowed; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeA: - err = FFEBAD_FORMAT_BAD_A_SPEC; - pre = optional; - post = optional; - dot = disallowed; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeD: - err = FFEBAD_FORMAT_BAD_D_SPEC; - pre = optional; - post = required; - dot = required; - exp = disallowed; - R1005 = TRUE; - break; - - case FFESTP_formattypeQ: - err = FFEBAD_FORMAT_BAD_Q_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeDOLLAR: - err = FFEBAD_FORMAT_BAD_DOLLAR_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeP: - err = FFEBAD_FORMAT_BAD_P_SPEC; - pre = required; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeT: - err = FFEBAD_FORMAT_BAD_T_SPEC; - pre = disallowed; - post = required; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeTL: - err = FFEBAD_FORMAT_BAD_TL_SPEC; - pre = disallowed; - post = required; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeTR: - err = FFEBAD_FORMAT_BAD_TR_SPEC; - pre = disallowed; - post = required; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeX: - err = FFEBAD_FORMAT_BAD_X_SPEC; - pre = required; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeS: - err = FFEBAD_FORMAT_BAD_S_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeSP: - err = FFEBAD_FORMAT_BAD_SP_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeSS: - err = FFEBAD_FORMAT_BAD_SS_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeBN: - err = FFEBAD_FORMAT_BAD_BN_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeBZ: - err = FFEBAD_FORMAT_BAD_BZ_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeH: /* Definitely an error, make sure of - it. */ - err = FFEBAD_FORMAT_BAD_H_SPEC; - pre = ffestb_local_.format.pre.present ? disallowed : required; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - - case FFESTP_formattypeNone: - ffesta_ffebad_1t (FFEBAD_FORMAT_BAD_SPEC, - ffestb_local_.format.t); - - clean_up_to_11_: /* :::::::::::::::::::: */ - - ffelex_token_kill (ffestb_local_.format.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - if (ffestb_local_.format.post.present) - ffelex_token_kill (ffestb_local_.format.post.t); - if (ffestb_local_.format.dot.present) - ffelex_token_kill (ffestb_local_.format.dot.t); - if (ffestb_local_.format.exp.present) - ffelex_token_kill (ffestb_local_.format.exp.t); - return (ffelexHandler) ffestb_R100111_ (t); - - default: - assert ("bad format item" == NULL); - err = FFEBAD_FORMAT_BAD_H_SPEC; - pre = disallowed; - post = disallowed; - dot = disallowed; - exp = disallowed; - R1005 = FALSE; - break; - } - if (((pre == disallowed) && ffestb_local_.format.pre.present) - || ((pre == required) && !ffestb_local_.format.pre.present)) - { - ffesta_ffebad_1t (err, (pre == required) - ? ffestb_local_.format.t : ffestb_local_.format.pre.t); - goto clean_up_to_11_; /* :::::::::::::::::::: */ - } - if (((post == disallowed) && ffestb_local_.format.post.present) - || ((post == required) && !ffestb_local_.format.post.present)) - { - ffesta_ffebad_1t (err, (post == required) - ? ffestb_local_.format.t : ffestb_local_.format.post.t); - goto clean_up_to_11_; /* :::::::::::::::::::: */ - } - if (((dot == disallowed) && ffestb_local_.format.dot.present) - || ((dot == required) && !ffestb_local_.format.dot.present)) - { - ffesta_ffebad_1t (err, (dot == required) - ? ffestb_local_.format.t : ffestb_local_.format.dot.t); - goto clean_up_to_11_; /* :::::::::::::::::::: */ - } - if (((exp == disallowed) && ffestb_local_.format.exp.present) - || ((exp == required) && !ffestb_local_.format.exp.present)) - { - ffesta_ffebad_1t (err, (exp == required) - ? ffestb_local_.format.t : ffestb_local_.format.exp.t); - goto clean_up_to_11_; /* :::::::::::::::::::: */ - } - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = ffestb_local_.format.current; - f->t = ffestb_local_.format.t; - if (R1005) - { - f->u.R1005.R1004 = ffestb_local_.format.pre; - f->u.R1005.R1006 = ffestb_local_.format.post; - f->u.R1005.R1007_or_R1008 = ffestb_local_.format.dot; - f->u.R1005.R1009 = ffestb_local_.format.exp; - } - else - /* Must be R1010. */ - { - if (pre == disallowed) - f->u.R1010.val = ffestb_local_.format.post; - else - f->u.R1010.val = ffestb_local_.format.pre; - } - return (ffelexHandler) ffestb_R100111_ (t); - } -} - -/* ffestb_R100111_ -- edit-descriptor - - return ffestb_R100111_; // to lexer - - Expect a COMMA, CLOSE_PAREN, CLOSE_ARRAY, COLON, COLONCOLON, SLASH, or - CONCAT, or complain about missing comma. */ - -static ffelexHandler -ffestb_R100111_ (ffelexToken t) -{ - ffesttFormatList f; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R10012_; - - case FFELEX_typeCOLON: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - return (ffelexHandler) ffestb_R10012_ (t); - - case FFELEX_typeCLOSE_PAREN: - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeCLOSE_ARRAY: /* "/)". */ - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeOPEN_ANGLE: - case FFELEX_typeDOLLAR: - case FFELEX_typeNUMBER: - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeOPEN_ARRAY: - case FFELEX_typeQUOTE: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeNAMES: - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_COMMA, t); - return (ffelexHandler) ffestb_R10012_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_PAREN, t); - for (f = ffestb_local_.format.f; - f->u.root.parent != NULL; - f = f->u.root.parent->next) - ; - ffestb_local_.format.f = f; - return (ffelexHandler) ffestb_R100114_ (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100112_ -- COLON, COLONCOLON, SLASH, OPEN_ARRAY, or CONCAT - - return ffestb_R100112_; // to lexer - - Like _11_ except the COMMA is optional. */ - -static ffelexHandler -ffestb_R100112_ (ffelexToken t) -{ - ffesttFormatList f; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R10012_; - - case FFELEX_typeCOLON: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - case FFELEX_typeOPEN_ANGLE: - case FFELEX_typeNAMES: - case FFELEX_typeDOLLAR: - case FFELEX_typeNUMBER: - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeOPEN_ARRAY: - case FFELEX_typeQUOTE: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typePLUS: - case FFELEX_typeMINUS: - return (ffelexHandler) ffestb_R10012_ (t); - - case FFELEX_typeCLOSE_PAREN: - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeCLOSE_ARRAY: /* "/)". */ - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeSLASH; - f->t = ffelex_token_use (t); - f->u.R1010.val.present = FALSE; - f->u.R1010.val.rtexpr = FALSE; - f->u.R1010.val.t = NULL; - f->u.R1010.val.u.unsigned_val = 1; - f = ffestb_local_.format.f->u.root.parent; - if (f == NULL) - return (ffelexHandler) ffestb_R100114_; - ffestb_local_.format.f = f->next; - return (ffelexHandler) ffestb_R100111_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffesta_ffebad_1t (FFEBAD_FORMAT_MISSING_PAREN, t); - for (f = ffestb_local_.format.f; - f->u.root.parent != NULL; - f = f->u.root.parent->next) - ; - ffestb_local_.format.f = f; - return (ffelexHandler) ffestb_R100114_ (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100113_ -- Handle CHARACTER token. - - return ffestb_R100113_; // to lexer - - Append the format item to the list, go to _11_. */ - -static ffelexHandler -ffestb_R100113_ (ffelexToken t) -{ - ffesttFormatList f; - - assert (ffelex_token_type (t) == FFELEX_typeCHARACTER); - - if (ffe_is_pedantic_not_90 () && (ffelex_token_length (t) == 0)) - { - ffebad_start (FFEBAD_NULL_CHAR_CONST); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_finish (); - } - - f = ffestt_formatlist_append (ffestb_local_.format.f); - f->type = FFESTP_formattypeR1016; - f->t = ffelex_token_use (t); - return (ffelexHandler) ffestb_R100111_; -} - -/* ffestb_R100114_ -- "FORMAT" OPEN_PAREN format-item-list CLOSE_PAREN - - return ffestb_R100114_; // to lexer - - Handle EOS/SEMICOLON or something else. */ - -static ffelexHandler -ffestb_R100114_ (ffelexToken t) -{ - ffelex_set_names_pure (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited () && !ffestb_local_.format.complained) - ffestc_R1001 (ffestb_local_.format.f); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100115_ -- OPEN_ANGLE expr - - (ffestb_R100115_) // to expression handler - - Handle expression prior to the edit descriptor. */ - -static ffelexHandler -ffestb_R100115_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_ANGLE: - ffestb_local_.format.pre.present = TRUE; - ffestb_local_.format.pre.rtexpr = TRUE; - ffestb_local_.format.pre.u.expr = expr; - ffelex_set_names_pure (TRUE); - return (ffelexHandler) ffestb_R10014_; - - default: - ffelex_token_kill (ffestb_local_.format.pre.t); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100116_ -- "[n]X" OPEN_ANGLE expr - - (ffestb_R100116_) // to expression handler - - Handle expression after the edit descriptor. */ - -static ffelexHandler -ffestb_R100116_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_ANGLE: - ffestb_local_.format.post.present = TRUE; - ffestb_local_.format.post.rtexpr = TRUE; - ffestb_local_.format.post.u.expr = expr; - ffelex_set_names_pure (TRUE); - return (ffelexHandler) ffestb_R10016_; - - default: - ffelex_token_kill (ffestb_local_.format.t); - ffelex_token_kill (ffestb_local_.format.post.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100117_ -- "[n]X[n]." OPEN_ANGLE expr - - (ffestb_R100117_) // to expression handler - - Handle expression after the PERIOD. */ - -static ffelexHandler -ffestb_R100117_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_ANGLE: - ffestb_local_.format.dot.present = TRUE; - ffestb_local_.format.dot.rtexpr = TRUE; - ffestb_local_.format.dot.u.expr = expr; - ffelex_set_names_pure (TRUE); - return (ffelexHandler) ffestb_R10018_; - - default: - ffelex_token_kill (ffestb_local_.format.t); - ffelex_token_kill (ffestb_local_.format.dot.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - if (ffestb_local_.format.post.present) - ffelex_token_kill (ffestb_local_.format.post.t); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R100118_ -- "[n]X[n].[n]E" OPEN_ANGLE expr - - (ffestb_R100118_) // to expression handler - - Handle expression after the "E". */ - -static ffelexHandler -ffestb_R100118_ (ffelexToken ft UNUSED, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_ANGLE: - ffestb_local_.format.exp.present = TRUE; - ffestb_local_.format.exp.rtexpr = TRUE; - ffestb_local_.format.exp.u.expr = expr; - ffelex_set_names_pure (TRUE); - return (ffelexHandler) ffestb_R100110_; - - default: - ffelex_token_kill (ffestb_local_.format.t); - ffelex_token_kill (ffestb_local_.format.exp.t); - if (ffestb_local_.format.pre.present) - ffelex_token_kill (ffestb_local_.format.pre.t); - if (ffestb_local_.format.post.present) - ffelex_token_kill (ffestb_local_.format.post.t); - if (ffestb_local_.format.dot.present) - ffelex_token_kill (ffestb_local_.format.dot.t); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FORMAT", t); - ffestt_formatlist_kill (ffestb_local_.format.f); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } -} - -/* ffestb_R1107 -- Parse the USE statement - - return ffestb_R1107; // to lexer - - Make sure the statement has a valid form for the USE statement. - If it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_R1107 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstUSE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R11071_; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstUSE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlUSE); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - } - ffesta_confirmed (); - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_R11071_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "USE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11071_ -- "USE" NAME - - return ffestb_R11071_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11071_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_R1107_start (ffesta_tokens[1], FALSE); - ffestc_R1107_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R11072_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11072_ -- "USE" NAME COMMA - - return ffestb_R11072_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11072_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R11073_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11073_ -- "USE" NAME COMMA NAME - - return ffestb_R11073_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11073_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLON: - if (ffestr_other (ffesta_tokens[2]) != FFESTR_otherONLY) - break; - if (!ffesta_is_inhibited ()) - ffestc_R1107_start (ffesta_tokens[1], TRUE); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffestb_R11074_; - - case FFELEX_typePOINTS: - if (!ffesta_is_inhibited ()) - ffestc_R1107_start (ffesta_tokens[1], FALSE); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = ffesta_tokens[2]; - return (ffelexHandler) ffestb_R110711_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11074_ -- "USE" NAME COMMA "ONLY" COLON - - return ffestb_R11074_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11074_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R11075_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1107_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11075_ -- "USE" NAME COMMA "ONLY" COLON NAME - - return ffestb_R11075_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11075_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_R1107_item (NULL, ffesta_tokens[1]); - ffestc_R1107_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_R1107_item (NULL, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R11078_; - - case FFELEX_typePOINTS: - return (ffelexHandler) ffestb_R11076_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11076_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS - - return ffestb_R11076_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11076_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_R1107_item (ffesta_tokens[1], t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R11077_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11077_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS NAME - - return ffestb_R11077_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11077_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1107_finish (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R11078_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11078_ -- "USE" NAME COMMA "ONLY" COLON NAME POINTS NAME COMMA - - return ffestb_R11078_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11078_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R11075_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R11079_ -- "USE" NAME COMMA - - return ffestb_R11079_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R11079_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R110710_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R110710_ -- "USE" NAME COMMA NAME - - return ffestb_R110710_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R110710_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typePOINTS: - return (ffelexHandler) ffestb_R110711_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R110711_ -- "USE" NAME COMMA NAME POINTS - - return ffestb_R110711_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R110711_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_R1107_item (ffesta_tokens[1], t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R110712_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R110712_ -- "USE" NAME COMMA NAME POINTS NAME - - return ffestb_R110712_; // to lexer - - Make sure the statement has a valid form for the USE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R110712_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1107_finish (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R11079_; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "USE", t); - ffestc_R1107_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_R1202 -- Parse the INTERFACE statement - - return ffestb_R1202; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. - If it does, implement the statement. - - 15-May-90 JCB 1.1 - Allow INTERFACE by itself; missed this - valid form when originally doing syntactic analysis code. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_R1202 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstINTERFACE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNone, NULL); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffesta_confirmed (); - switch (ffesta_second_kw) - { - case FFESTR_secondOPERATOR: - ffestb_local_.interface.operator = FFESTP_definedoperatorOPERATOR; - break; - - case FFESTR_secondASSIGNMENT: - ffestb_local_.interface.operator = FFESTP_definedoperatorASSIGNMENT; - break; - - default: - ffestb_local_.interface.operator = FFESTP_definedoperatorNone; - break; - } - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R12021_; - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlINTERFACE); - switch (ffesta_first_kw) - { - case FFESTR_firstINTERFACEOPERATOR: - if (*(ffelex_token_text (ffesta_tokens[0]) - + FFESTR_firstlINTERFACEOPERATOR) == '\0') - ffestb_local_.interface.operator - = FFESTP_definedoperatorOPERATOR; - break; - - case FFESTR_firstINTERFACEASSGNMNT: - if (*(ffelex_token_text (ffesta_tokens[0]) - + FFESTR_firstlINTERFACEASSGNMNT) == '\0') - ffestb_local_.interface.operator - = FFESTP_definedoperatorASSIGNMENT; - break; - - case FFESTR_firstINTERFACE: - ffestb_local_.interface.operator = FFESTP_definedoperatorNone; - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeOPEN_ARRAY: /* Sigh. */ - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (*p == '\0') - { - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNone, NULL); - return (ffelexHandler) ffesta_zero (t); - } - break; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_R12021_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "INTERFACE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12021_ -- "INTERFACE" NAME - - return ffestb_R12021_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12021_ (ffelexToken t) -{ - ffestb_local_.interface.slash = TRUE; /* Slash follows open paren. */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNone, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.interface.slash = FALSE; /* Slash doesn't follow. */ - /* Fall through. */ - case FFELEX_typeOPEN_ARRAY: - switch (ffestb_local_.interface.operator) - { - case FFESTP_definedoperatorNone: - break; - - case FFESTP_definedoperatorOPERATOR: - ffestb_local_.interface.assignment = FALSE; - return (ffelexHandler) ffestb_R12022_; - - case FFESTP_definedoperatorASSIGNMENT: - ffestb_local_.interface.assignment = TRUE; - return (ffelexHandler) ffestb_R12022_; - - default: - assert (FALSE); - } - break; - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12022_ -- "INTERFACE" "OPERATOR/ASSIGNMENT" OPEN_PAREN - - return ffestb_R12022_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12022_ (ffelexToken t) -{ - ffesta_tokens[2] = ffelex_token_use (t); - - switch (ffelex_token_type (t)) - { - case FFELEX_typePERIOD: - if (ffestb_local_.interface.slash) - break; - return (ffelexHandler) ffestb_R12023_; - - case FFELEX_typePOWER: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorPOWER; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeASTERISK: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorMULT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typePLUS: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorADD; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeCONCAT: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeSLASH: - if (ffestb_local_.interface.slash) - { - ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT; - return (ffelexHandler) ffestb_R12025_; - } - ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeMINUS: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorSUBTRACT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeREL_EQ: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorEQ; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeREL_NE: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorNE; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeOPEN_ANGLE: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorLT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeREL_LE: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorLE; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeCLOSE_ANGLE: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorGT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeREL_GE: - if (ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorGE; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeEQUALS: - if (ffestb_local_.interface.slash) - { - ffestb_local_.interface.operator = FFESTP_definedoperatorNE; - return (ffelexHandler) ffestb_R12025_; - } - ffestb_local_.interface.operator = FFESTP_definedoperatorASSIGNMENT; - return (ffelexHandler) ffestb_R12025_; - - case FFELEX_typeCLOSE_ARRAY: - if (!ffestb_local_.interface.slash) - { - ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE; - return (ffelexHandler) ffestb_R12026_; - } - ffestb_local_.interface.operator = FFESTP_definedoperatorCONCAT; - return (ffelexHandler) ffestb_R12026_; - - case FFELEX_typeCLOSE_PAREN: - if (!ffestb_local_.interface.slash) - break; - ffestb_local_.interface.operator = FFESTP_definedoperatorDIVIDE; - return (ffelexHandler) ffestb_R12026_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12023_ -- "INTERFACE" NAME OPEN_PAREN PERIOD - - return ffestb_R12023_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12023_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffelex_token_kill (ffesta_tokens[2]); - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R12024_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12024_ -- "INTERFACE" NAME OPEN_PAREN PERIOD NAME - - return ffestb_R12024_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12024_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typePERIOD: - return (ffelexHandler) ffestb_R12025_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12025_ -- "INTERFACE" NAME OPEN_PAREN operator - - return ffestb_R12025_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12025_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R12026_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12026_ -- "INTERFACE" NAME OPEN_PAREN operator CLOSE_PAREN - - return ffestb_R12026_; // to lexer - - Make sure the statement has a valid form for the INTERFACE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12026_ (ffelexToken t) -{ - char *p; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (ffestb_local_.interface.assignment - && (ffestb_local_.interface.operator - != FFESTP_definedoperatorASSIGNMENT)) - { - ffebad_start (FFEBAD_INTERFACE_ASSIGNMENT); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[1]), - ffelex_token_where_column (ffesta_tokens[1])); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[2]), - ffelex_token_where_column (ffesta_tokens[2])); - ffebad_finish (); - } - switch (ffelex_token_type (ffesta_tokens[2])) - { - case FFELEX_typeNAME: - switch (ffestr_other (ffesta_tokens[2])) - { - case FFESTR_otherNOT: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNOT, NULL); - break; - - case FFESTR_otherAND: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorAND, NULL); - break; - - case FFESTR_otherOR: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorOR, NULL); - break; - - case FFESTR_otherEQV: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorEQV, NULL); - break; - - case FFESTR_otherNEQV: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNEQV, NULL); - break; - - case FFESTR_otherEQ: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorEQ, NULL); - break; - - case FFESTR_otherNE: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorNE, NULL); - break; - - case FFESTR_otherLT: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorLT, NULL); - break; - - case FFESTR_otherLE: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorLE, NULL); - break; - - case FFESTR_otherGT: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorGT, NULL); - break; - - case FFESTR_otherGE: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorGE, NULL); - break; - - default: - for (p = ffelex_token_text (ffesta_tokens[2]); *p != '\0'; ++p) - { - if (! ISALPHA (*p)) - { - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1t (FFEBAD_INTERFACE_NONLETTER, - ffesta_tokens[2]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - } - } - if (!ffesta_is_inhibited ()) - ffestc_R1202 (FFESTP_definedoperatorOPERATOR, - ffesta_tokens[2]); - } - break; - - case FFELEX_typeEQUALS: - if (!ffestb_local_.interface.assignment - && (ffestb_local_.interface.operator - == FFESTP_definedoperatorASSIGNMENT)) - { - ffebad_start (FFEBAD_INTERFACE_OPERATOR); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[1]), - ffelex_token_where_column (ffesta_tokens[1])); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[2]), - ffelex_token_where_column (ffesta_tokens[2])); - ffebad_finish (); - } - if (!ffesta_is_inhibited ()) - ffestc_R1202 (ffestb_local_.interface.operator, NULL); - break; - - default: - if (!ffesta_is_inhibited ()) - ffestc_R1202 (ffestb_local_.interface.operator, NULL); - } - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INTERFACE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_S3P4 -- Parse the INCLUDE line - - return ffestb_S3P4; // to lexer - - Make sure the statement has a valid form for the INCLUDE line. If it - does, implement the statement. */ - -ffelexHandler -ffestb_S3P4 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexHandler next; - ffelexToken nt; - ffelexToken ut; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstINCLUDE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - ffesta_confirmed (); - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextINCLUDE, - (ffeexprCallback) ffestb_S3P41_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstINCLUDE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlINCLUDE); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeAPOSTROPHE: - case FFELEX_typeQUOTE: - break; - } - ffesta_confirmed (); - if (*p == '\0') - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, FFEEXPR_contextINCLUDE, - (ffeexprCallback) ffestb_S3P41_))) - (t); - if (! ISDIGIT (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_number_from_names (ffesta_tokens[0], i); - p += ffelex_token_length (nt); - i += ffelex_token_length (nt); - if ((*p != '_') || (++i, *++p != '\0')) - { - ffelex_token_kill (nt); - goto bad_i; /* :::::::::::::::::::: */ - } - ut = ffelex_token_uscore_from_names (ffesta_tokens[0], i - 1); - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextINCLUDE, - (ffeexprCallback) ffestb_S3P41_))) - (nt); - ffelex_token_kill (nt); - next = (ffelexHandler) (*next) (ut); - ffelex_token_kill (ut); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INCLUDE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INCLUDE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "INCLUDE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_S3P41_ -- "INCLUDE" [NUMBER "_"] expr - - (ffestb_S3P41_) // to expression handler - - Make sure the next token is an EOS, but not a SEMICOLON. */ - -static ffelexHandler -ffestb_S3P41_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (ffe_is_pedantic () - && ((ffelex_token_type (t) == FFELEX_typeSEMICOLON) - || ffesta_line_has_semicolons)) - { - ffebad_start_msg ("INCLUDE at %0 not the only statement on the source line", FFEBAD_severityWARNING); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - ffestc_S3P4 (expr, ft); - } - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INCLUDE", t); - break; - } - - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V012 -- Parse the MAP statement - - return ffestb_V012; // to lexer - - Make sure the statement has a valid form for the MAP statement. If - it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V012 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstMAP) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstMAP) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlMAP) - { - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlMAP); - goto bad_i; /* :::::::::::::::::::: */ - } - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V012 (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MAP", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid first token. */ - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "MAP", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "MAP", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_V014 -- Parse the VOLATILE statement - - return ffestb_V014; // to lexer - - Make sure the statement has a valid form for the VOLATILE statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_V014 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstVOLATILE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V014_start (); - return (ffelexHandler) ffestb_V0141_ (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V014_start (); - return (ffelexHandler) ffestb_V0141_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstVOLATILE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlVOLATILE); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_V014_start (); - return (ffelexHandler) ffestb_V0141_ (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_V014_start (); - return (ffelexHandler) ffestb_V0141_; - } - - /* Here, we have at least one char after "VOLATILE" and t is COMMA or - EOS/SEMICOLON. */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (!ffesta_is_inhibited ()) - ffestc_V014_start (); - next = (ffelexHandler) ffestb_V0141_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "VOLATILE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0141_ -- "VOLATILE" [COLONCOLON] - - return ffestb_V0141_; // to lexer - - Handle NAME or SLASH. */ - -static ffelexHandler -ffestb_V0141_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffestb_local_.V014.is_cblock = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0144_; - - case FFELEX_typeSLASH: - ffestb_local_.V014.is_cblock = TRUE; - return (ffelexHandler) ffestb_V0142_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V014_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0142_ -- "VOLATILE" [COLONCOLON] SLASH - - return ffestb_V0142_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0142_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0143_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V014_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0143_ -- "VOLATILE" [COLONCOLON] SLASH NAME - - return ffestb_V0143_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_V0143_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_V0144_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V014_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0144_ -- "VOLATILE" [COLONCOLON] R523 - - return ffestb_V0144_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0144_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - { - if (ffestb_local_.V014.is_cblock) - ffestc_V014_item_cblock (ffesta_tokens[1]); - else - ffestc_V014_item_object (ffesta_tokens[1]); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_V0141_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - if (ffestb_local_.V014.is_cblock) - ffestc_V014_item_cblock (ffesta_tokens[1]); - else - ffestc_V014_item_object (ffesta_tokens[1]); - ffestc_V014_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "VOLATILE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V014_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V025 -- Parse the DEFINEFILE statement - - return ffestb_V025; // to lexer - - Make sure the statement has a valid form for the DEFINEFILE statement. - If it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V025 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexToken nt; - ffelexHandler next; - - ffestb_local_.V025.started = FALSE; - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffesta_first_kw) - { - case FFESTR_firstDEFINE: - if ((ffelex_token_type (t) != FFELEX_typeNAME) - || (ffesta_second_kw != FFESTR_secondFILE)) - goto bad_1; /* :::::::::::::::::::: */ - ffesta_confirmed (); - return (ffelexHandler) ffestb_V0251_; - - case FFESTR_firstDEFINEFILE: - return (ffelexHandler) ffestb_V0251_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstDEFINEFILE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlDEFINEFILE); - if (ISDIGIT (*p)) - nt = ffelex_token_number_from_names (ffesta_tokens[0], i); - else if (ffesrc_is_name_init (*p)) - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - else - goto bad_i; /* :::::::::::::::::::: */ - next = (ffelexHandler) ffestb_V0251_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0251_ -- "DEFINEFILE" or "DEFINE" "FILE" - - return ffestb_V0251_; // to lexer - - Make sure the statement has a valid form for the DEFINEFILE statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_V0251_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - if (ffelex_token_type (ffesta_tokens[0]) == FFELEX_typeNAME) - ffesta_confirmed (); - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNIT_DF, (ffeexprCallback) ffestb_V0252_))) - (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - break; - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0252_ -- "DEFINEFILE" expr - - (ffestb_V0252_) // to expression handler - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0252_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_local_.V025.u = expr; - ffesta_tokens[1] = ffelex_token_use (ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0253_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0253_ -- "DEFINEFILE" expr OPEN_PAREN expr - - (ffestb_V0253_) // to expression handler - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0253_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffestb_local_.V025.m = expr; - ffesta_tokens[2] = ffelex_token_use (ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0254_); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0254_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr - - (ffestb_V0254_) // to expression handler - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0254_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffestb_local_.V025.n = expr; - ffesta_tokens[3] = ffelex_token_use (ft); - return (ffelexHandler) ffestb_V0255_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0255_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA - - return ffestb_V0255_; // to lexer - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0255_ (ffelexToken t) -{ - char *p; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - p = ffelex_token_text (t); - if (!ffesrc_char_match_init (*p, 'U', 'u') || (*++p != '\0')) - break; - return (ffelexHandler) ffestb_V0256_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0256_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U" - - return ffestb_V0256_; // to lexer - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0256_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextFILEASSOC, - (ffeexprCallback) ffestb_V0257_); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0257_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U" - COMMA expr - - (ffestb_V0257_) // to expression handler - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0257_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestb_local_.V025.asv = expr; - ffesta_tokens[4] = ffelex_token_use (ft); - return (ffelexHandler) ffestb_V0258_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0258_ -- "DEFINEFILE" expr OPEN_PAREN expr COMMA expr COMMA "U" - COMMA expr CLOSE_PAREN - - return ffestb_V0258_; // to lexer - - Make sure the statement has a valid form for the DEFINEFILE statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_V0258_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffestb_local_.V025.started) - { - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V025_start (); - ffestb_local_.V025.started = TRUE; - } - if (!ffesta_is_inhibited ()) - ffestc_V025_item (ffestb_local_.V025.u, ffesta_tokens[1], - ffestb_local_.V025.m, ffesta_tokens[2], - ffestb_local_.V025.n, ffesta_tokens[3], - ffestb_local_.V025.asv, ffesta_tokens[4]); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[4]); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNIT_DF, (ffeexprCallback) ffestb_V0252_); - if (!ffesta_is_inhibited ()) - ffestc_V025_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffesta_tokens[3]); - ffelex_token_kill (ffesta_tokens[4]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DEFINE FILE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_subr_kill_easy_ -- Kill I/O statement data structure - - ffestb_subr_kill_easy_(); - - Kills all tokens in the I/O data structure. Assumes that they are - overlaid with each other (union) in ffest_private.h and the typing - and structure references assume (though not necessarily dangerous if - FALSE) that INQUIRE has the most file elements. */ - -#if FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_easy_ (ffestpInquireIx max) -{ - ffestpInquireIx ix; - - for (ix = 0; ix < max; ++ix) - { - if (ffestp_file.inquire.inquire_spec[ix].kw_or_val_present) - { - if (ffestp_file.inquire.inquire_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.inquire.inquire_spec[ix].kw); - if (ffestp_file.inquire.inquire_spec[ix].value_present) - ffelex_token_kill (ffestp_file.inquire.inquire_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_accept_ -- Kill ACCEPT statement data structure - - ffestb_subr_kill_accept_(); - - Kills all tokens in the ACCEPT data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_accept_ () -{ - ffestpAcceptIx ix; - - for (ix = 0; ix < FFESTP_acceptix; ++ix) - { - if (ffestp_file.accept.accept_spec[ix].kw_or_val_present) - { - if (ffestp_file.accept.accept_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.accept.accept_spec[ix].kw); - if (ffestp_file.accept.accept_spec[ix].value_present) - ffelex_token_kill (ffestp_file.accept.accept_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_beru_ -- Kill BACKSPACE/ENDFILE/REWIND/UNLOCK statement - data structure - - ffestb_subr_kill_beru_(); - - Kills all tokens in the BACKSPACE/ENDFILE/REWIND/UNLOCK data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_beru_ () -{ - ffestpBeruIx ix; - - for (ix = 0; ix < FFESTP_beruix; ++ix) - { - if (ffestp_file.beru.beru_spec[ix].kw_or_val_present) - { - if (ffestp_file.beru.beru_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.beru.beru_spec[ix].kw); - if (ffestp_file.beru.beru_spec[ix].value_present) - ffelex_token_kill (ffestp_file.beru.beru_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_close_ -- Kill CLOSE statement data structure - - ffestb_subr_kill_close_(); - - Kills all tokens in the CLOSE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_close_ () -{ - ffestpCloseIx ix; - - for (ix = 0; ix < FFESTP_closeix; ++ix) - { - if (ffestp_file.close.close_spec[ix].kw_or_val_present) - { - if (ffestp_file.close.close_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.close.close_spec[ix].kw); - if (ffestp_file.close.close_spec[ix].value_present) - ffelex_token_kill (ffestp_file.close.close_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_delete_ -- Kill DELETE statement data structure - - ffestb_subr_kill_delete_(); - - Kills all tokens in the DELETE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_delete_ () -{ - ffestpDeleteIx ix; - - for (ix = 0; ix < FFESTP_deleteix; ++ix) - { - if (ffestp_file.delete.delete_spec[ix].kw_or_val_present) - { - if (ffestp_file.delete.delete_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.delete.delete_spec[ix].kw); - if (ffestp_file.delete.delete_spec[ix].value_present) - ffelex_token_kill (ffestp_file.delete.delete_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_inquire_ -- Kill INQUIRE statement data structure - - ffestb_subr_kill_inquire_(); - - Kills all tokens in the INQUIRE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_inquire_ () -{ - ffestpInquireIx ix; - - for (ix = 0; ix < FFESTP_inquireix; ++ix) - { - if (ffestp_file.inquire.inquire_spec[ix].kw_or_val_present) - { - if (ffestp_file.inquire.inquire_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.inquire.inquire_spec[ix].kw); - if (ffestp_file.inquire.inquire_spec[ix].value_present) - ffelex_token_kill (ffestp_file.inquire.inquire_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_open_ -- Kill OPEN statement data structure - - ffestb_subr_kill_open_(); - - Kills all tokens in the OPEN data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_open_ () -{ - ffestpOpenIx ix; - - for (ix = 0; ix < FFESTP_openix; ++ix) - { - if (ffestp_file.open.open_spec[ix].kw_or_val_present) - { - if (ffestp_file.open.open_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.open.open_spec[ix].kw); - if (ffestp_file.open.open_spec[ix].value_present) - ffelex_token_kill (ffestp_file.open.open_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_print_ -- Kill PRINT statement data structure - - ffestb_subr_kill_print_(); - - Kills all tokens in the PRINT data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_print_ () -{ - ffestpPrintIx ix; - - for (ix = 0; ix < FFESTP_printix; ++ix) - { - if (ffestp_file.print.print_spec[ix].kw_or_val_present) - { - if (ffestp_file.print.print_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.print.print_spec[ix].kw); - if (ffestp_file.print.print_spec[ix].value_present) - ffelex_token_kill (ffestp_file.print.print_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_read_ -- Kill READ statement data structure - - ffestb_subr_kill_read_(); - - Kills all tokens in the READ data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_read_ () -{ - ffestpReadIx ix; - - for (ix = 0; ix < FFESTP_readix; ++ix) - { - if (ffestp_file.read.read_spec[ix].kw_or_val_present) - { - if (ffestp_file.read.read_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.read.read_spec[ix].kw); - if (ffestp_file.read.read_spec[ix].value_present) - ffelex_token_kill (ffestp_file.read.read_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_rewrite_ -- Kill REWRITE statement data structure - - ffestb_subr_kill_rewrite_(); - - Kills all tokens in the REWRITE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_rewrite_ () -{ - ffestpRewriteIx ix; - - for (ix = 0; ix < FFESTP_rewriteix; ++ix) - { - if (ffestp_file.rewrite.rewrite_spec[ix].kw_or_val_present) - { - if (ffestp_file.rewrite.rewrite_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.rewrite.rewrite_spec[ix].kw); - if (ffestp_file.rewrite.rewrite_spec[ix].value_present) - ffelex_token_kill (ffestp_file.rewrite.rewrite_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_type_ -- Kill TYPE statement data structure - - ffestb_subr_kill_type_(); - - Kills all tokens in the TYPE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_type_ () -{ - ffestpTypeIx ix; - - for (ix = 0; ix < FFESTP_typeix; ++ix) - { - if (ffestp_file.type.type_spec[ix].kw_or_val_present) - { - if (ffestp_file.type.type_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.type.type_spec[ix].kw); - if (ffestp_file.type.type_spec[ix].value_present) - ffelex_token_kill (ffestp_file.type.type_spec[ix].value); - } - } -} - -#endif -/* ffestb_subr_kill_write_ -- Kill WRITE statement data structure - - ffestb_subr_kill_write_(); - - Kills all tokens in the WRITE data structure. */ - -#if !FFESTB_KILL_EASY_ -static void -ffestb_subr_kill_write_ () -{ - ffestpWriteIx ix; - - for (ix = 0; ix < FFESTP_writeix; ++ix) - { - if (ffestp_file.write.write_spec[ix].kw_or_val_present) - { - if (ffestp_file.write.write_spec[ix].kw_present) - ffelex_token_kill (ffestp_file.write.write_spec[ix].kw); - if (ffestp_file.write.write_spec[ix].value_present) - ffelex_token_kill (ffestp_file.write.write_spec[ix].value); - } - } -} - -#endif -/* ffestb_beru -- Parse the BACKSPACE/ENDFILE/REWIND/UNLOCK statement - - return ffestb_beru; // to lexer - - Make sure the statement has a valid form for the BACKSPACE/ENDFILE/REWIND/ - UNLOCK statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_beru (ffelexToken t) -{ - ffelexHandler next; - ffestpBeruIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - for (ix = 0; ix < FFESTP_beruix; ++ix) - ffestp_file.beru.beru_spec[ix].kw_or_val_present = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_beru2_; - - default: - break; - } - - for (ix = 0; ix < FFESTP_beruix; ++ix) - ffestp_file.beru.beru_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, - (ffeexprCallback) ffestb_beru1_))) - (t); - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) - != ffestb_args.beru.len) - break; - - for (ix = 0; ix < FFESTP_beruix; ++ix) - ffestp_file.beru.beru_spec[ix].kw_or_val_present = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_beru2_; - - default: - break; - } - for (ix = 0; ix < FFESTP_beruix; ++ix) - ffestp_file.beru.beru_spec[ix].kw_or_val_present = FALSE; - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_beru1_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - ffestb_args.beru.len); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_beru1_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" expr - - (ffestb_beru1_) // to expression handler - - Make sure the next token is an EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_beru1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - ffesta_confirmed (); - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].kw_or_val_present - = TRUE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].kw_present = FALSE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value_present = TRUE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value_is_label - = FALSE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value - = ffelex_token_use (ft); - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].u.expr = expr; - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstBACKSPACE: - ffestc_R919 (); - break; - - case FFESTR_firstENDFILE: - case FFESTR_firstEND: - ffestc_R920 (); - break; - - case FFESTR_firstREWIND: - ffestc_R921 (); - break; - -#if FFESTR_VXT - case FFESTR_firstUNLOCK: - ffestc_V022 (); - break; -#endif - - default: - assert (FALSE); - } - } - ffestb_subr_kill_beru_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru2_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN - - return ffestb_beru2_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_beru2_ (ffelexToken t) -{ - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_beru3_; - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUMAMBIG, (ffeexprCallback) ffestb_beru4_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_beru3_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN NAME - - return ffestb_beru3_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_beru3_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - ffelexToken ot; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffelex_token_kill (ffesta_tokens[1]); - nt = ffesta_tokens[2]; - next = (ffelexHandler) ffestb_beru5_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - ot = ffesta_tokens[2]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUMAMBIG, (ffeexprCallback) ffestb_beru4_))) - (nt); - ffelex_token_kill (nt); - next = (ffelexHandler) (*next) (ot); - ffelex_token_kill (ot); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_beru4_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN expr [CLOSE_PAREN] - - (ffestb_beru4_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. - - 15-Feb-91 JCB 1.2 - Now using new mechanism whereby expr comes back as opITEM if the - expr is considered part (or all) of an I/O control list (and should - be stripped of its outer opITEM node) or not if it is considered - a plain unit number that happens to have been enclosed in parens. - 26-Mar-90 JCB 1.1 - No longer expecting close-paren here because of constructs like - BACKSPACE (5)+2, so now expecting either COMMA because it was a - construct like BACKSPACE (5+2,... or EOS/SEMICOLON because it is like - the former construct. Ah, the vagaries of Fortran. */ - -static ffelexHandler -ffestb_beru4_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - bool inlist; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - if (ffebld_op (expr) == FFEBLD_opITEM) - { - inlist = TRUE; - expr = ffebld_head (expr); - } - else - inlist = FALSE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].kw_or_val_present - = TRUE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].kw_present = FALSE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value_present = TRUE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value_is_label - = FALSE; - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].value - = ffelex_token_use (ft); - ffestp_file.beru.beru_spec[FFESTP_beruixUNIT].u.expr = expr; - if (inlist) - return (ffelexHandler) ffestb_beru9_ (t); - return (ffelexHandler) ffestb_beru10_ (t); - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru5_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN [external-file-unit - COMMA] - - return ffestb_beru5_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_beru5_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.beru.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.beru.ix = FFESTP_beruixERR; - ffestb_local_.beru.label = TRUE; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.beru.ix = FFESTP_beruixIOSTAT; - ffestb_local_.beru.left = TRUE; - ffestb_local_.beru.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioUNIT: - ffestb_local_.beru.ix = FFESTP_beruixUNIT; - ffestb_local_.beru.left = FALSE; - ffestb_local_.beru.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.beru.beru_spec[ffestb_local_.beru.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix] - .kw_or_val_present = TRUE; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix] - .kw_present = TRUE; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix] - .value_present = FALSE; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].value_is_label - = ffestb_local_.beru.label; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_beru6_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru6_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN [external-file-unit - COMMA] NAME - - return ffestb_beru6_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_beru6_ (ffelexToken t) -{ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.beru.label) - return (ffelexHandler) ffestb_beru8_; - if (ffestb_local_.beru.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.beru.context, - (ffeexprCallback) ffestb_beru7_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.beru.context, - (ffeexprCallback) ffestb_beru7_); - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru7_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_beru7_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_beru7_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].value_present - = TRUE; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].value - = ffelex_token_use (ft); - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_beru5_; - return (ffelexHandler) ffestb_beru10_; - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru8_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN ... NAME EQUALS - - return ffestb_beru8_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_beru8_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].value_present - = TRUE; - ffestp_file.beru.beru_spec[ffestb_local_.beru.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_beru9_; - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru9_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN ... NAME EQUALS - NUMBER - - return ffestb_beru9_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_beru9_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_beru5_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_beru10_; - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_beru10_ -- "BACKSPACE/ENDFILE/REWIND/UNLOCK" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_beru10_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_beru10_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstBACKSPACE: - ffestc_R919 (); - break; - - case FFESTR_firstENDFILE: - case FFESTR_firstEND: - ffestc_R920 (); - break; - - case FFESTR_firstREWIND: - ffestc_R921 (); - break; - -#if FFESTR_VXT - case FFESTR_firstUNLOCK: - ffestc_V022 (); - break; -#endif - - default: - assert (FALSE); - } - } - ffestb_subr_kill_beru_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_beru_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.beru.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode -- Parse the VXT DECODE/ENCODE statement - - return ffestb_vxtcode; // to lexer - - Make sure the statement has a valid form for the VXT DECODE/ENCODE - statement. If it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_vxtcode (ffelexToken t) -{ - ffestpVxtcodeIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - for (ix = 0; ix < FFESTP_vxtcodeix; ++ix) - ffestp_file.vxtcode.vxtcode_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_vxtcode1_); - } - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) - != ffestb_args.vxtcode.len) - goto bad_0; /* :::::::::::::::::::: */ - - for (ix = 0; ix < FFESTP_vxtcodeix; ++ix) - ffestp_file.vxtcode.vxtcode_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_vxtcode1_); - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_vxtcode1_ -- "VXTCODE" OPEN_PAREN expr - - (ffestb_vxtcode1_) // to expression handler - - Handle COMMA here. */ - -static ffelexHandler -ffestb_vxtcode1_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].kw_or_val_present - = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].kw_present = FALSE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value_present = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value_is_label - = FALSE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].value - = ffelex_token_use (ft); - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixC].u.expr = expr; - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_vxtcode2_); - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode2_ -- "VXTCODE" OPEN_PAREN expr COMMA expr - - (ffestb_vxtcode2_) // to expression handler - - Handle COMMA here. */ - -static ffelexHandler -ffestb_vxtcode2_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].kw_or_val_present - = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].kw_present = FALSE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value_present = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value_is_label - = (expr == NULL); - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].value - = ffelex_token_use (ft); - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixF].u.expr = expr; - if (ffesta_first_kw == FFESTR_firstENCODE) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextFILEVXTCODE, - (ffeexprCallback) ffestb_vxtcode3_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEVXTCODE, - (ffeexprCallback) ffestb_vxtcode3_); - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode3_ -- "VXTCODE" OPEN_PAREN expr COMMA expr COMMA expr - - (ffestb_vxtcode3_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_vxtcode3_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].kw_or_val_present - = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].kw_present = FALSE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value_present = TRUE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value_is_label - = FALSE; - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].value - = ffelex_token_use (ft); - ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixB].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_vxtcode4_; - return (ffelexHandler) ffestb_vxtcode9_; - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode4_ -- "VXTCODE" OPEN_PAREN ... - - return ffestb_vxtcode4_; // to lexer - - Handle NAME=expr construct here. */ - -static ffelexHandler -ffestb_vxtcode4_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.vxtcode.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.vxtcode.ix = FFESTP_vxtcodeixERR; - ffestb_local_.vxtcode.label = TRUE; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.vxtcode.ix = FFESTP_vxtcodeixIOSTAT; - ffestb_local_.vxtcode.left = TRUE; - ffestb_local_.vxtcode.context = FFEEXPR_contextFILEINT; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix] - .kw_or_val_present = TRUE; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix] - .kw_present = TRUE; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix] - .value_present = FALSE; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_is_label - = ffestb_local_.vxtcode.label; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_vxtcode5_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode5_ -- "VXTCODE" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] NAME - - return ffestb_vxtcode5_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_vxtcode5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.vxtcode.label) - return (ffelexHandler) ffestb_vxtcode7_; - if (ffestb_local_.vxtcode.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.vxtcode.context, - (ffeexprCallback) ffestb_vxtcode6_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.vxtcode.context, - (ffeexprCallback) ffestb_vxtcode6_); - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode6_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_vxtcode6_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_vxtcode6_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_present - = TRUE; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value - = ffelex_token_use (ft); - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_vxtcode4_; - return (ffelexHandler) ffestb_vxtcode9_; - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode7_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS - - return ffestb_vxtcode7_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_vxtcode7_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value_present - = TRUE; - ffestp_file.vxtcode.vxtcode_spec[ffestb_local_.vxtcode.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_vxtcode8_; - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode8_ -- "VXTCODE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_vxtcode8_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_vxtcode8_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_vxtcode4_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_vxtcode9_; - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode9_ -- "VXTCODE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_vxtcode9_; // to lexer - - Handle EOS or SEMICOLON here. - - 07-Jun-90 JCB 1.1 - Context for ENCODE/DECODE expressions is now IOLISTDF instead of IOLIST - since they apply to internal files. */ - -static ffelexHandler -ffestb_vxtcode9_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (ffesta_first_kw == FFESTR_firstENCODE) - { - ffestc_V023_start (); - ffestc_V023_finish (); - } - else - { - ffestc_V024_start (); - ffestc_V024_finish (); - } - } - ffestb_subr_kill_vxtcode_ (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - if (ffesta_first_kw == FFESTR_firstENCODE) - ffestc_V023_start (); - else - ffestc_V024_start (); - ffestb_subr_kill_vxtcode_ (); - if (ffesta_first_kw == FFESTR_firstDECODE) - next = (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextIOLISTDF, - (ffeexprCallback) ffestb_vxtcode10_); - else - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLISTDF, - (ffeexprCallback) ffestb_vxtcode10_); - - /* EXTENSION: Allow an optional preceding COMMA here if not pedantic. - (f2c provides this extension, as do other compilers, supposedly.) */ - - if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA)) - return next; - - return (ffelexHandler) (*next) (t); - - default: - break; - } - - ffestb_subr_kill_vxtcode_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_vxtcode10_ -- "VXTCODE(...)" expr - - (ffestb_vxtcode10_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. - - 07-Jun-90 JCB 1.1 - Context for ENCODE/DECODE expressions is now IOLISTDF instead of IOLIST - since they apply to internal files. */ - -static ffelexHandler -ffestb_vxtcode10_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - if (ffesta_first_kw == FFESTR_firstENCODE) - ffestc_V023_item (expr, ft); - else - ffestc_V024_item (expr, ft); - if (ffesta_first_kw == FFESTR_firstDECODE) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextIOLISTDF, - (ffeexprCallback) ffestb_vxtcode10_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLISTDF, - (ffeexprCallback) ffestb_vxtcode10_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - if (ffesta_first_kw == FFESTR_firstENCODE) - { - ffestc_V023_item (expr, ft); - ffestc_V023_finish (); - } - else - { - ffestc_V024_item (expr, ft); - ffestc_V024_finish (); - } - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - if (ffesta_first_kw == FFESTR_firstENCODE) - ffestc_V023_finish (); - else - ffestc_V024_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.vxtcode.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_R904 -- Parse an OPEN statement - - return ffestb_R904; // to lexer - - Make sure the statement has a valid form for an OPEN statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R904 (ffelexToken t) -{ - ffestpOpenIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstOPEN) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstOPEN) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlOPEN) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - for (ix = 0; ix < FFESTP_openix; ++ix) - ffestp_file.open.open_spec[ix].kw_or_val_present = FALSE; - - return (ffelexHandler) ffestb_R9041_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9041_ -- "OPEN" OPEN_PAREN - - return ffestb_R9041_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9041_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9042_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9043_))) - (t); - } -} - -/* ffestb_R9042_ -- "OPEN" OPEN_PAREN NAME - - return ffestb_R9042_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9042_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9044_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9043_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9043_ -- "OPEN" OPEN_PAREN expr - - (ffestb_R9043_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9043_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.open.open_spec[FFESTP_openixUNIT].kw_or_val_present - = TRUE; - ffestp_file.open.open_spec[FFESTP_openixUNIT].kw_present = FALSE; - ffestp_file.open.open_spec[FFESTP_openixUNIT].value_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixUNIT].value_is_label - = FALSE; - ffestp_file.open.open_spec[FFESTP_openixUNIT].value - = ffelex_token_use (ft); - ffestp_file.open.open_spec[FFESTP_openixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9044_; - return (ffelexHandler) ffestb_R9049_; - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9044_ -- "OPEN" OPEN_PAREN [external-file-unit COMMA] - - return ffestb_R9044_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9044_ (ffelexToken t) -{ - ffestrOpen kw; - - ffestb_local_.open.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_open (t); - switch (kw) - { - case FFESTR_openACCESS: - ffestb_local_.open.ix = FFESTP_openixACCESS; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openACTION: - ffestb_local_.open.ix = FFESTP_openixACTION; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openASSOCIATEVARIABLE: - ffestb_local_.open.ix = FFESTP_openixASSOCIATEVARIABLE; - ffestb_local_.open.left = TRUE; - ffestb_local_.open.context = FFEEXPR_contextFILEASSOC; - break; - - case FFESTR_openBLANK: - ffestb_local_.open.ix = FFESTP_openixBLANK; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openBLOCKSIZE: - ffestb_local_.open.ix = FFESTP_openixBLOCKSIZE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openBUFFERCOUNT: - ffestb_local_.open.ix = FFESTP_openixBUFFERCOUNT; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openCARRIAGECONTROL: - ffestb_local_.open.ix = FFESTP_openixCARRIAGECONTROL; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openDEFAULTFILE: - ffestb_local_.open.ix = FFESTP_openixDEFAULTFILE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openDELIM: - ffestb_local_.open.ix = FFESTP_openixDELIM; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openDISP: - case FFESTR_openDISPOSE: - ffestb_local_.open.ix = FFESTP_openixDISPOSE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openERR: - ffestb_local_.open.ix = FFESTP_openixERR; - ffestb_local_.open.label = TRUE; - break; - - case FFESTR_openEXTENDSIZE: - ffestb_local_.open.ix = FFESTP_openixEXTENDSIZE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openFILE: - case FFESTR_openNAME: - ffestb_local_.open.ix = FFESTP_openixFILE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openFORM: - ffestb_local_.open.ix = FFESTP_openixFORM; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openINITIALSIZE: - ffestb_local_.open.ix = FFESTP_openixINITIALSIZE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openIOSTAT: - ffestb_local_.open.ix = FFESTP_openixIOSTAT; - ffestb_local_.open.left = TRUE; - ffestb_local_.open.context = FFEEXPR_contextFILEINT; - break; - -#if 0 /* Haven't added support for expression - context yet (though easy). */ - case FFESTR_openKEY: - ffestb_local_.open.ix = FFESTP_openixKEY; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEKEY; - break; -#endif - - case FFESTR_openMAXREC: - ffestb_local_.open.ix = FFESTP_openixMAXREC; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openNOSPANBLOCKS: - if (ffestp_file.open.open_spec[FFESTP_openixNOSPANBLOCKS] - .kw_or_val_present) - goto bad; /* :::::::::::::::::::: */ - ffestp_file.open.open_spec[FFESTP_openixNOSPANBLOCKS] - .kw_or_val_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixNOSPANBLOCKS] - .kw_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixNOSPANBLOCKS] - .value_present = FALSE; - ffestp_file.open.open_spec[FFESTP_openixNOSPANBLOCKS].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9048_; - - case FFESTR_openORGANIZATION: - ffestb_local_.open.ix = FFESTP_openixORGANIZATION; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openPAD: - ffestb_local_.open.ix = FFESTP_openixPAD; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openPOSITION: - ffestb_local_.open.ix = FFESTP_openixPOSITION; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openREADONLY: - if (ffestp_file.open.open_spec[FFESTP_openixREADONLY] - .kw_or_val_present) - goto bad; /* :::::::::::::::::::: */ - ffestp_file.open.open_spec[FFESTP_openixREADONLY] - .kw_or_val_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixREADONLY] - .kw_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixREADONLY] - .value_present = FALSE; - ffestp_file.open.open_spec[FFESTP_openixREADONLY].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9048_; - - case FFESTR_openRECL: - case FFESTR_openRECORDSIZE: - ffestb_local_.open.ix = FFESTP_openixRECL; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openRECORDTYPE: - ffestb_local_.open.ix = FFESTP_openixRECORDTYPE; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_openSHARED: - if (ffestp_file.open.open_spec[FFESTP_openixSHARED] - .kw_or_val_present) - goto bad; /* :::::::::::::::::::: */ - ffestp_file.open.open_spec[FFESTP_openixSHARED] - .kw_or_val_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixSHARED] - .kw_present = TRUE; - ffestp_file.open.open_spec[FFESTP_openixSHARED] - .value_present = FALSE; - ffestp_file.open.open_spec[FFESTP_openixSHARED].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9048_; - - case FFESTR_openSTATUS: - case FFESTR_openTYPE: - ffestb_local_.open.ix = FFESTP_openixSTATUS; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_openUNIT: - ffestb_local_.open.ix = FFESTP_openixUNIT; - ffestb_local_.open.left = FALSE; - ffestb_local_.open.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_openUSEROPEN: - ffestb_local_.open.ix = FFESTP_openixUSEROPEN; - ffestb_local_.open.left = TRUE; - ffestb_local_.open.context = FFEEXPR_contextFILEEXTFUNC; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.open.open_spec[ffestb_local_.open.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.open.open_spec[ffestb_local_.open.ix] - .kw_or_val_present = TRUE; - ffestp_file.open.open_spec[ffestb_local_.open.ix] - .kw_present = TRUE; - ffestp_file.open.open_spec[ffestb_local_.open.ix] - .value_present = FALSE; - ffestp_file.open.open_spec[ffestb_local_.open.ix].value_is_label - = ffestb_local_.open.label; - ffestp_file.open.open_spec[ffestb_local_.open.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9045_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9045_ -- "OPEN" OPEN_PAREN [external-file-unit COMMA] NAME - - return ffestb_R9045_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_R9045_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.open.label) - return (ffelexHandler) ffestb_R9047_; - if (ffestb_local_.open.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.open.context, - (ffeexprCallback) ffestb_R9046_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.open.context, - (ffeexprCallback) ffestb_R9046_); - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9046_ -- "OPEN" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_R9046_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9046_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.open.open_spec[ffestb_local_.open.ix].value_present - = TRUE; - ffestp_file.open.open_spec[ffestb_local_.open.ix].value - = ffelex_token_use (ft); - ffestp_file.open.open_spec[ffestb_local_.open.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9044_; - return (ffelexHandler) ffestb_R9049_; - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9047_ -- "OPEN" OPEN_PAREN ... NAME EQUALS - - return ffestb_R9047_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_R9047_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.open.open_spec[ffestb_local_.open.ix].value_present - = TRUE; - ffestp_file.open.open_spec[ffestb_local_.open.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9048_; - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9048_ -- "OPEN" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_R9048_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9048_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R9044_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R9049_; - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9049_ -- "OPEN" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_R9049_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_R9049_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R904 (); - ffestb_subr_kill_open_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_open_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "OPEN", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R907 -- Parse a CLOSE statement - - return ffestb_R907; // to lexer - - Make sure the statement has a valid form for a CLOSE statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R907 (ffelexToken t) -{ - ffestpCloseIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCLOSE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCLOSE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlCLOSE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - for (ix = 0; ix < FFESTP_closeix; ++ix) - ffestp_file.close.close_spec[ix].kw_or_val_present = FALSE; - - return (ffelexHandler) ffestb_R9071_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9071_ -- "CLOSE" OPEN_PAREN - - return ffestb_R9071_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9071_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9072_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9073_))) - (t); - } -} - -/* ffestb_R9072_ -- "CLOSE" OPEN_PAREN NAME - - return ffestb_R9072_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9072_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9074_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9073_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9073_ -- "CLOSE" OPEN_PAREN expr - - (ffestb_R9073_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9073_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.close.close_spec[FFESTP_closeixUNIT].kw_or_val_present - = TRUE; - ffestp_file.close.close_spec[FFESTP_closeixUNIT].kw_present = FALSE; - ffestp_file.close.close_spec[FFESTP_closeixUNIT].value_present = TRUE; - ffestp_file.close.close_spec[FFESTP_closeixUNIT].value_is_label - = FALSE; - ffestp_file.close.close_spec[FFESTP_closeixUNIT].value - = ffelex_token_use (ft); - ffestp_file.close.close_spec[FFESTP_closeixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9074_; - return (ffelexHandler) ffestb_R9079_; - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9074_ -- "CLOSE" OPEN_PAREN [external-file-unit COMMA] - - return ffestb_R9074_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9074_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.close.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.close.ix = FFESTP_closeixERR; - ffestb_local_.close.label = TRUE; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.close.ix = FFESTP_closeixIOSTAT; - ffestb_local_.close.left = TRUE; - ffestb_local_.close.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioSTATUS: - case FFESTR_genioDISP: - case FFESTR_genioDISPOSE: - ffestb_local_.close.ix = FFESTP_closeixSTATUS; - ffestb_local_.close.left = FALSE; - ffestb_local_.close.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_genioUNIT: - ffestb_local_.close.ix = FFESTP_closeixUNIT; - ffestb_local_.close.left = FALSE; - ffestb_local_.close.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.close.close_spec[ffestb_local_.close.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.close.close_spec[ffestb_local_.close.ix] - .kw_or_val_present = TRUE; - ffestp_file.close.close_spec[ffestb_local_.close.ix] - .kw_present = TRUE; - ffestp_file.close.close_spec[ffestb_local_.close.ix] - .value_present = FALSE; - ffestp_file.close.close_spec[ffestb_local_.close.ix].value_is_label - = ffestb_local_.close.label; - ffestp_file.close.close_spec[ffestb_local_.close.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9075_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9075_ -- "CLOSE" OPEN_PAREN [external-file-unit COMMA] NAME - - return ffestb_R9075_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_R9075_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.close.label) - return (ffelexHandler) ffestb_R9077_; - if (ffestb_local_.close.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.close.context, - (ffeexprCallback) ffestb_R9076_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.close.context, - (ffeexprCallback) ffestb_R9076_); - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9076_ -- "CLOSE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_R9076_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9076_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.close.close_spec[ffestb_local_.close.ix].value_present - = TRUE; - ffestp_file.close.close_spec[ffestb_local_.close.ix].value - = ffelex_token_use (ft); - ffestp_file.close.close_spec[ffestb_local_.close.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9074_; - return (ffelexHandler) ffestb_R9079_; - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9077_ -- "CLOSE" OPEN_PAREN ... NAME EQUALS - - return ffestb_R9077_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_R9077_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.close.close_spec[ffestb_local_.close.ix].value_present - = TRUE; - ffestp_file.close.close_spec[ffestb_local_.close.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9078_; - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9078_ -- "CLOSE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_R9078_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9078_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R9074_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R9079_; - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9079_ -- "CLOSE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_R9079_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_R9079_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R907 (); - ffestb_subr_kill_close_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_close_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "CLOSE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R909 -- Parse the READ statement - - return ffestb_R909; // to lexer - - Make sure the statement has a valid form for the READ - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_R909 (ffelexToken t) -{ - ffelexHandler next; - ffestpReadIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstREAD) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - for (ix = 0; ix < FFESTP_readix; ++ix) - ffestp_file.read.read_spec[ix].kw_or_val_present = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9092_; - - default: - break; - } - - for (ix = 0; ix < FFESTP_readix; ++ix) - ffestp_file.read.read_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9091_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstREAD) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlREAD) - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlREAD) - break; - - for (ix = 0; ix < FFESTP_readix; ++ix) - ffestp_file.read.read_spec[ix].kw_or_val_present = FALSE; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9092_; - - default: - break; - } - for (ix = 0; ix < FFESTP_readix; ++ix) - ffestp_file.read.read_spec[ix].kw_or_val_present = FALSE; - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9091_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - FFESTR_firstlREAD); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9091_ -- "READ" expr - - (ffestb_R9091_) // to expression handler - - Make sure the next token is a COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R9091_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_present = FALSE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_present = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].u.expr = expr; - if (!ffesta_is_inhibited ()) - ffestc_R909_start (TRUE); - ffestb_subr_kill_read_ (); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90915_); - if (!ffesta_is_inhibited ()) - ffestc_R909_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9092_ -- "READ" OPEN_PAREN - - return ffestb_R9092_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9092_ (ffelexToken t) -{ - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9093_; - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNITAMBIG, (ffeexprCallback) ffestb_R9094_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9093_ -- "READ" OPEN_PAREN NAME - - return ffestb_R9093_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9093_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - ffelexToken ot; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffelex_token_kill (ffesta_tokens[1]); - nt = ffesta_tokens[2]; - next = (ffelexHandler) ffestb_R9098_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - ot = ffesta_tokens[2]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNITAMBIG, (ffeexprCallback) ffestb_R9094_))) - (nt); - ffelex_token_kill (nt); - next = (ffelexHandler) (*next) (ot); - ffelex_token_kill (ot); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9094_ -- "READ" OPEN_PAREN expr [CLOSE_PAREN] - - (ffestb_R9094_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. - - 15-Feb-91 JCB 1.1 - Use new ffeexpr mechanism whereby the expr is encased in an opITEM if - ffeexpr decided it was an item in a control list (hence a unit - specifier), or a format specifier otherwise. */ - -static ffelexHandler -ffestb_R9094_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - if (expr == NULL) - goto bad; /* :::::::::::::::::::: */ - - if (ffebld_op (expr) != FFEBLD_opITEM) - { - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_present = FALSE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_present = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_is_label - = FALSE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].u.expr = expr; - if (!ffesta_is_inhibited ()) - ffestc_R909_start (TRUE); - ffestb_subr_kill_read_ (); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90915_); - if (!ffesta_is_inhibited ()) - ffestc_R909_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - goto bad; /* :::::::::::::::::::: */ - } - } - - expr = ffebld_head (expr); - - if (expr == NULL) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - ffestp_file.read.read_spec[FFESTP_readixUNIT].kw_or_val_present - = TRUE; - ffestp_file.read.read_spec[FFESTP_readixUNIT].kw_present = FALSE; - ffestp_file.read.read_spec[FFESTP_readixUNIT].value_present = TRUE; - ffestp_file.read.read_spec[FFESTP_readixUNIT].value_is_label - = FALSE; - ffestp_file.read.read_spec[FFESTP_readixUNIT].value - = ffelex_token_use (ft); - ffestp_file.read.read_spec[FFESTP_readixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9095_; - return (ffelexHandler) ffestb_R90913_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9095_ -- "READ" OPEN_PAREN expr COMMA - - return ffestb_R9095_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9095_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9096_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9097_))) - (t); - } -} - -/* ffestb_R9096_ -- "READ" OPEN_PAREN expr COMMA NAME - - return ffestb_R9096_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9096_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9098_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9097_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9097_ -- "READ" OPEN_PAREN expr COMMA expr - - (ffestb_R9097_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9097_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].kw_present = FALSE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_present = TRUE; - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.read.read_spec[FFESTP_readixFORMAT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9098_; - return (ffelexHandler) ffestb_R90913_; - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9098_ -- "READ" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] - - return ffestb_R9098_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9098_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.read.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioADVANCE: - ffestb_local_.read.ix = FFESTP_readixADVANCE; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_genioEOR: - ffestb_local_.read.ix = FFESTP_readixEOR; - ffestb_local_.read.label = TRUE; - break; - - case FFESTR_genioERR: - ffestb_local_.read.ix = FFESTP_readixERR; - ffestb_local_.read.label = TRUE; - break; - - case FFESTR_genioEND: - ffestb_local_.read.ix = FFESTP_readixEND; - ffestb_local_.read.label = TRUE; - break; - - case FFESTR_genioFMT: - ffestb_local_.read.ix = FFESTP_readixFORMAT; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILEFORMAT; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.read.ix = FFESTP_readixIOSTAT; - ffestb_local_.read.left = TRUE; - ffestb_local_.read.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioKEY: - case FFESTR_genioKEYEQ: - ffestb_local_.read.ix = FFESTP_readixKEYEQ; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILENUMCHAR; - break; - - case FFESTR_genioKEYGE: - ffestb_local_.read.ix = FFESTP_readixKEYGE; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILENUMCHAR; - break; - - case FFESTR_genioKEYGT: - ffestb_local_.read.ix = FFESTP_readixKEYGT; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILENUMCHAR; - break; - - case FFESTR_genioKEYID: - ffestb_local_.read.ix = FFESTP_readixKEYID; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_genioNML: - ffestb_local_.read.ix = FFESTP_readixFORMAT; - ffestb_local_.read.left = TRUE; - ffestb_local_.read.context = FFEEXPR_contextFILENAMELIST; - break; - - case FFESTR_genioNULLS: - ffestb_local_.read.ix = FFESTP_readixNULLS; - ffestb_local_.read.left = TRUE; - ffestb_local_.read.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioREC: - ffestb_local_.read.ix = FFESTP_readixREC; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_genioSIZE: - ffestb_local_.read.ix = FFESTP_readixSIZE; - ffestb_local_.read.left = TRUE; - ffestb_local_.read.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioUNIT: - ffestb_local_.read.ix = FFESTP_readixUNIT; - ffestb_local_.read.left = FALSE; - ffestb_local_.read.context = FFEEXPR_contextFILEUNIT; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[ffestb_local_.read.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.read.read_spec[ffestb_local_.read.ix] - .kw_or_val_present = TRUE; - ffestp_file.read.read_spec[ffestb_local_.read.ix] - .kw_present = TRUE; - ffestp_file.read.read_spec[ffestb_local_.read.ix] - .value_present = FALSE; - ffestp_file.read.read_spec[ffestb_local_.read.ix].value_is_label - = ffestb_local_.read.label; - ffestp_file.read.read_spec[ffestb_local_.read.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9099_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9099_ -- "READ" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] NAME - - return ffestb_R9099_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_R9099_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.read.label) - return (ffelexHandler) ffestb_R90911_; - if (ffestb_local_.read.left) - return (ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.read.context, - (ffeexprCallback) ffestb_R90910_); - return (ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.read.context, - (ffeexprCallback) ffestb_R90910_); - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R90910_ -- "READ" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_R90910_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R90910_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - { - if (ffestb_local_.read.context == FFEEXPR_contextFILEFORMAT) - ffestp_file.read.read_spec[ffestb_local_.read.ix] - .value_is_label = TRUE; - else - break; - } - ffestp_file.read.read_spec[ffestb_local_.read.ix].value_present - = TRUE; - ffestp_file.read.read_spec[ffestb_local_.read.ix].value - = ffelex_token_use (ft); - ffestp_file.read.read_spec[ffestb_local_.read.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9098_; - return (ffelexHandler) ffestb_R90913_; - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R90911_ -- "READ" OPEN_PAREN ... NAME EQUALS - - return ffestb_R90911_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_R90911_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.read.read_spec[ffestb_local_.read.ix].value_present - = TRUE; - ffestp_file.read.read_spec[ffestb_local_.read.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R90912_; - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R90912_ -- "READ" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_R90912_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R90912_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R9098_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R90913_; - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R90913_ -- "READ" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_R90913_; // to lexer - - Handle EOS or SEMICOLON here. - - 15-Feb-91 JCB 1.1 - Fix to allow implied-DO construct here (OPEN_PAREN) -- actually, - don't presume knowledge of what an initial token in an lhs context - is going to be, let ffeexpr_lhs handle that as much as possible. */ - -static ffelexHandler -ffestb_R90913_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - ffestc_R909_start (FALSE); - ffestc_R909_finish (); - } - ffestb_subr_kill_read_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_confirmed (); - /* Fall through. */ - case FFELEX_typeOPEN_PAREN: /* Could still be assignment!! */ - break; - } - - /* If token isn't NAME or OPEN_PAREN, ffeexpr_lhs will ultimately whine - about it, so leave it up to that code. */ - - /* EXTENSION: Allow an optional preceding COMMA here if not pedantic. (f2c - provides this extension, as do other compilers, supposedly.) */ - - if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA)) - return (ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90914_); - - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90914_))) - (t); -} - -/* ffestb_R90914_ -- "READ(...)" expr - - (ffestb_R90914_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R90914_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R909_start (FALSE); - ffestb_subr_kill_read_ (); - - if (!ffesta_is_inhibited ()) - ffestc_R909_item (expr, ft); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90915_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R909_start (FALSE); - ffestb_subr_kill_read_ (); - - if (!ffesta_is_inhibited ()) - { - ffestc_R909_item (expr, ft); - ffestc_R909_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_read_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R90915_ -- "READ(...)" expr COMMA expr - - (ffestb_R90915_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R90915_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R909_item (expr, ft); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestc_context_iolist (), - (ffeexprCallback) ffestb_R90915_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R909_item (expr, ft); - ffestc_R909_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R909_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "READ", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R910 -- Parse the WRITE statement - - return ffestb_R910; // to lexer - - Make sure the statement has a valid form for the WRITE - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_R910 (ffelexToken t) -{ - ffestpWriteIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstWRITE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - for (ix = 0; ix < FFESTP_writeix; ++ix) - ffestp_file.write.write_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffestb_R9101_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstWRITE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlWRITE) - goto bad_0; /* :::::::::::::::::::: */ - - for (ix = 0; ix < FFESTP_writeix; ++ix) - ffestp_file.write.write_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffestb_R9101_; - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9101_ -- "WRITE" OPEN_PAREN - - return ffestb_R9101_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9101_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9102_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNIT, (ffeexprCallback) ffestb_R9103_))) - (t); - } -} - -/* ffestb_R9102_ -- "WRITE" OPEN_PAREN NAME - - return ffestb_R9102_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9102_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9107_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEUNIT, (ffeexprCallback) ffestb_R9103_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9103_ -- "WRITE" OPEN_PAREN expr [CLOSE_PAREN] - - (ffestb_R9103_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R9103_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.write.write_spec[FFESTP_writeixUNIT].kw_or_val_present - = TRUE; - ffestp_file.write.write_spec[FFESTP_writeixUNIT].kw_present = FALSE; - ffestp_file.write.write_spec[FFESTP_writeixUNIT].value_present = TRUE; - ffestp_file.write.write_spec[FFESTP_writeixUNIT].value_is_label - = FALSE; - ffestp_file.write.write_spec[FFESTP_writeixUNIT].value - = ffelex_token_use (ft); - ffestp_file.write.write_spec[FFESTP_writeixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9104_; - return (ffelexHandler) ffestb_R91012_; - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9104_ -- "WRITE" OPEN_PAREN expr COMMA - - return ffestb_R9104_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9104_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9105_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9106_))) - (t); - } -} - -/* ffestb_R9105_ -- "WRITE" OPEN_PAREN expr COMMA NAME - - return ffestb_R9105_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9105_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9107_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9106_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9106_ -- "WRITE" OPEN_PAREN expr COMMA expr - - (ffestb_R9106_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9106_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].kw_present = FALSE; - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].value_present = TRUE; - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.write.write_spec[FFESTP_writeixFORMAT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9107_; - return (ffelexHandler) ffestb_R91012_; - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9107_ -- "WRITE" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] - - return ffestb_R9107_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9107_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.write.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioADVANCE: - ffestb_local_.write.ix = FFESTP_writeixADVANCE; - ffestb_local_.write.left = FALSE; - ffestb_local_.write.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_genioEOR: - ffestb_local_.write.ix = FFESTP_writeixEOR; - ffestb_local_.write.label = TRUE; - break; - - case FFESTR_genioERR: - ffestb_local_.write.ix = FFESTP_writeixERR; - ffestb_local_.write.label = TRUE; - break; - - case FFESTR_genioFMT: - ffestb_local_.write.ix = FFESTP_writeixFORMAT; - ffestb_local_.write.left = FALSE; - ffestb_local_.write.context = FFEEXPR_contextFILEFORMAT; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.write.ix = FFESTP_writeixIOSTAT; - ffestb_local_.write.left = TRUE; - ffestb_local_.write.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioNML: - ffestb_local_.write.ix = FFESTP_writeixFORMAT; - ffestb_local_.write.left = TRUE; - ffestb_local_.write.context = FFEEXPR_contextFILENAMELIST; - break; - - case FFESTR_genioREC: - ffestb_local_.write.ix = FFESTP_writeixREC; - ffestb_local_.write.left = FALSE; - ffestb_local_.write.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_genioUNIT: - ffestb_local_.write.ix = FFESTP_writeixUNIT; - ffestb_local_.write.left = FALSE; - ffestb_local_.write.context = FFEEXPR_contextFILEUNIT; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.write.write_spec[ffestb_local_.write.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.write.write_spec[ffestb_local_.write.ix] - .kw_or_val_present = TRUE; - ffestp_file.write.write_spec[ffestb_local_.write.ix] - .kw_present = TRUE; - ffestp_file.write.write_spec[ffestb_local_.write.ix] - .value_present = FALSE; - ffestp_file.write.write_spec[ffestb_local_.write.ix].value_is_label - = ffestb_local_.write.label; - ffestp_file.write.write_spec[ffestb_local_.write.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9108_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9108_ -- "WRITE" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] NAME - - return ffestb_R9108_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_R9108_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.write.label) - return (ffelexHandler) ffestb_R91010_; - if (ffestb_local_.write.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.write.context, - (ffeexprCallback) ffestb_R9109_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.write.context, - (ffeexprCallback) ffestb_R9109_); - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9109_ -- "WRITE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_R9109_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9109_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - { - if (ffestb_local_.write.context == FFEEXPR_contextFILEFORMAT) - ffestp_file.write.write_spec[ffestb_local_.write.ix] - .value_is_label = TRUE; - else - break; - } - ffestp_file.write.write_spec[ffestb_local_.write.ix].value_present - = TRUE; - ffestp_file.write.write_spec[ffestb_local_.write.ix].value - = ffelex_token_use (ft); - ffestp_file.write.write_spec[ffestb_local_.write.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9107_; - return (ffelexHandler) ffestb_R91012_; - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R91010_ -- "WRITE" OPEN_PAREN ... NAME EQUALS - - return ffestb_R91010_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_R91010_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.write.write_spec[ffestb_local_.write.ix].value_present - = TRUE; - ffestp_file.write.write_spec[ffestb_local_.write.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R91011_; - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R91011_ -- "WRITE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_R91011_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R91011_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R9107_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R91012_; - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R91012_ -- "WRITE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_R91012_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_R91012_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - ffestc_R910_start (); - ffestc_R910_finish (); - } - ffestb_subr_kill_write_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_confirmed (); - /* Fall through. */ - case FFELEX_typeOPEN_PAREN: /* Could still be assignment!! */ - - /* EXTENSION: Allow an optional preceding COMMA here if not pedantic. - (f2c provides this extension, as do other compilers, supposedly.) */ - - if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA)) - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestc_context_iolist (), (ffeexprCallback) ffestb_R91013_); - - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestc_context_iolist (), (ffeexprCallback) ffestb_R91013_))) - (t); - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R91013_ -- "WRITE(...)" expr - - (ffestb_R91013_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R91013_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R910_start (); - ffestb_subr_kill_write_ (); - - if (!ffesta_is_inhibited ()) - ffestc_R910_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestc_context_iolist (), (ffeexprCallback) ffestb_R91014_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R910_start (); - ffestb_subr_kill_write_ (); - - if (!ffesta_is_inhibited ()) - { - ffestc_R910_item (expr, ft); - ffestc_R910_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_write_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R91014_ -- "WRITE(...)" expr COMMA expr - - (ffestb_R91014_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R91014_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R910_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestc_context_iolist (), (ffeexprCallback) ffestb_R91014_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R910_item (expr, ft); - ffestc_R910_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R910_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "WRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R911 -- Parse the PRINT statement - - return ffestb_R911; // to lexer - - Make sure the statement has a valid form for the PRINT - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_R911 (ffelexToken t) -{ - ffelexHandler next; - ffestpPrintIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstPRINT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - default: - break; - } - - for (ix = 0; ix < FFESTP_printix; ++ix) - ffestp_file.print.print_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9111_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstPRINT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlPRINT) - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - default: - break; - } - for (ix = 0; ix < FFESTP_printix; ++ix) - ffestp_file.print.print_spec[ix].kw_or_val_present = FALSE; - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_R9111_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - FFESTR_firstlPRINT); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PRINT", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PRINT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9111_ -- "PRINT" expr - - (ffestb_R9111_) // to expression handler - - Make sure the next token is a COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R9111_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - ffestp_file.print.print_spec[FFESTP_printixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.print.print_spec[FFESTP_printixFORMAT].kw_present = FALSE; - ffestp_file.print.print_spec[FFESTP_printixFORMAT].value_present = TRUE; - ffestp_file.print.print_spec[FFESTP_printixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.print.print_spec[FFESTP_printixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.print.print_spec[FFESTP_printixFORMAT].u.expr = expr; - if (!ffesta_is_inhibited ()) - ffestc_R911_start (); - ffestb_subr_kill_print_ (); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_R9112_); - if (!ffesta_is_inhibited ()) - ffestc_R911_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_print_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PRINT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9112_ -- "PRINT" expr COMMA expr - - (ffestb_R9112_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R9112_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R911_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_R9112_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R911_item (expr, ft); - ffestc_R911_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R911_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PRINT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R923 -- Parse an INQUIRE statement - - return ffestb_R923; // to lexer - - Make sure the statement has a valid form for an INQUIRE statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_R923 (ffelexToken t) -{ - ffestpInquireIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstINQUIRE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstINQUIRE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlINQUIRE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - for (ix = 0; ix < FFESTP_inquireix; ++ix) - ffestp_file.inquire.inquire_spec[ix].kw_or_val_present = FALSE; - - ffestb_local_.inquire.may_be_iolength = TRUE; - return (ffelexHandler) ffestb_R9231_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R9231_ -- "INQUIRE" OPEN_PAREN - - return ffestb_R9231_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9231_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9232_; - - default: - ffestb_local_.inquire.may_be_iolength = FALSE; - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9233_))) - (t); - } -} - -/* ffestb_R9232_ -- "INQUIRE" OPEN_PAREN NAME - - return ffestb_R9232_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_R9232_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_R9234_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - ffestb_local_.inquire.may_be_iolength = FALSE; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_R9233_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_R9233_ -- "INQUIRE" OPEN_PAREN expr - - (ffestb_R9233_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9233_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_or_val_present - = TRUE; - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_present = FALSE; - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value_present = TRUE; - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value_is_label - = FALSE; - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value - = ffelex_token_use (ft); - ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9234_; - return (ffelexHandler) ffestb_R9239_; - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9234_ -- "INQUIRE" OPEN_PAREN [external-file-unit COMMA] - - return ffestb_R9234_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_R9234_ (ffelexToken t) -{ - ffestrInquire kw; - - ffestb_local_.inquire.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_inquire (t); - if (kw != FFESTR_inquireIOLENGTH) - ffestb_local_.inquire.may_be_iolength = FALSE; - switch (kw) - { - case FFESTR_inquireACCESS: - ffestb_local_.inquire.ix = FFESTP_inquireixACCESS; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireACTION: - ffestb_local_.inquire.ix = FFESTP_inquireixACTION; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireBLANK: - ffestb_local_.inquire.ix = FFESTP_inquireixBLANK; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireCARRIAGECONTROL: - ffestb_local_.inquire.ix = FFESTP_inquireixCARRIAGECONTROL; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireDEFAULTFILE: - ffestb_local_.inquire.ix = FFESTP_inquireixDEFAULTFILE; - ffestb_local_.inquire.left = FALSE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireDELIM: - ffestb_local_.inquire.ix = FFESTP_inquireixDELIM; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireDIRECT: - ffestb_local_.inquire.ix = FFESTP_inquireixDIRECT; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireERR: - ffestb_local_.inquire.ix = FFESTP_inquireixERR; - ffestb_local_.inquire.label = TRUE; - break; - - case FFESTR_inquireEXIST: - ffestb_local_.inquire.ix = FFESTP_inquireixEXIST; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILELOG; - break; - - case FFESTR_inquireFILE: - ffestb_local_.inquire.ix = FFESTP_inquireixFILE; - ffestb_local_.inquire.left = FALSE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireFORM: - ffestb_local_.inquire.ix = FFESTP_inquireixFORM; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireFORMATTED: - ffestb_local_.inquire.ix = FFESTP_inquireixFORMATTED; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireIOLENGTH: - if (!ffestb_local_.inquire.may_be_iolength) - goto bad; /* :::::::::::::::::::: */ - ffestb_local_.inquire.ix = FFESTP_inquireixIOLENGTH; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_inquireIOSTAT: - ffestb_local_.inquire.ix = FFESTP_inquireixIOSTAT; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_inquireKEYED: - ffestb_local_.inquire.ix = FFESTP_inquireixKEYED; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireNAME: - ffestb_local_.inquire.ix = FFESTP_inquireixNAME; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireNAMED: - ffestb_local_.inquire.ix = FFESTP_inquireixNAMED; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILELOG; - break; - - case FFESTR_inquireNEXTREC: - ffestb_local_.inquire.ix = FFESTP_inquireixNEXTREC; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFINT; - break; - - case FFESTR_inquireNUMBER: - ffestb_local_.inquire.ix = FFESTP_inquireixNUMBER; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_inquireOPENED: - ffestb_local_.inquire.ix = FFESTP_inquireixOPENED; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILELOG; - break; - - case FFESTR_inquireORGANIZATION: - ffestb_local_.inquire.ix = FFESTP_inquireixORGANIZATION; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquirePAD: - ffestb_local_.inquire.ix = FFESTP_inquireixPAD; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquirePOSITION: - ffestb_local_.inquire.ix = FFESTP_inquireixPOSITION; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireREAD: - ffestb_local_.inquire.ix = FFESTP_inquireixREAD; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireREADWRITE: - ffestb_local_.inquire.ix = FFESTP_inquireixREADWRITE; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireRECL: - ffestb_local_.inquire.ix = FFESTP_inquireixRECL; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_inquireRECORDTYPE: - ffestb_local_.inquire.ix = FFESTP_inquireixRECORDTYPE; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILECHAR; - break; - - case FFESTR_inquireSEQUENTIAL: - ffestb_local_.inquire.ix = FFESTP_inquireixSEQUENTIAL; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireUNFORMATTED: - ffestb_local_.inquire.ix = FFESTP_inquireixUNFORMATTED; - ffestb_local_.inquire.left = TRUE; - ffestb_local_.inquire.context = FFEEXPR_contextFILEDFCHAR; - break; - - case FFESTR_inquireUNIT: - ffestb_local_.inquire.ix = FFESTP_inquireixUNIT; - ffestb_local_.inquire.left = FALSE; - ffestb_local_.inquire.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix] - .kw_or_val_present = TRUE; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix] - .kw_present = TRUE; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix] - .value_present = FALSE; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].value_is_label - = ffestb_local_.inquire.label; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9235_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9235_ -- "INQUIRE" OPEN_PAREN [external-file-unit COMMA] NAME - - return ffestb_R9235_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_R9235_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.inquire.label) - return (ffelexHandler) ffestb_R9237_; - if (ffestb_local_.inquire.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.inquire.context, - (ffeexprCallback) ffestb_R9236_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.inquire.context, - (ffeexprCallback) ffestb_R9236_); - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9236_ -- "INQUIRE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_R9236_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9236_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (ffestb_local_.inquire.ix == FFESTP_inquireixIOLENGTH) - break; /* IOLENGTH=expr must be followed by - CLOSE_PAREN. */ - /* Fall through. */ - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].value_present - = TRUE; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].value - = ffelex_token_use (ft); - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_R9234_; - if (ffestb_local_.inquire.ix == FFESTP_inquireixIOLENGTH) - return (ffelexHandler) ffestb_R92310_; - return (ffelexHandler) ffestb_R9239_; - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9237_ -- "INQUIRE" OPEN_PAREN ... NAME EQUALS - - return ffestb_R9237_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_R9237_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].value_present - = TRUE; - ffestp_file.inquire.inquire_spec[ffestb_local_.inquire.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_R9238_; - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9238_ -- "INQUIRE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_R9238_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_R9238_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_R9234_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_R9239_; - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R9239_ -- "INQUIRE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_R9239_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_R9239_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R923A (); - ffestb_subr_kill_inquire_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R92310_ -- "INQUIRE(IOLENGTH=expr)" - - return ffestb_R92310_; // to lexer - - Make sure EOS or SEMICOLON not here; begin R923B processing and expect - output IO list. */ - -static ffelexHandler -ffestb_R92310_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - break; - - default: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R923B_start (); - ffestb_subr_kill_inquire_ (); - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_R92311_))) - (t); - } - - ffestb_subr_kill_inquire_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R92311_ -- "INQUIRE(IOLENGTH=expr)" expr - - (ffestb_R92311_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_R92311_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_R923B_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_R92311_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_R923B_item (expr, ft); - ffestc_R923B_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R923B_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "INQUIRE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V018 -- Parse the REWRITE statement - - return ffestb_V018; // to lexer - - Make sure the statement has a valid form for the REWRITE - statement. If it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V018 (ffelexToken t) -{ - ffestpRewriteIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstREWRITE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - for (ix = 0; ix < FFESTP_rewriteix; ++ix) - ffestp_file.rewrite.rewrite_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffestb_V0181_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstREWRITE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlREWRITE) - goto bad_0; /* :::::::::::::::::::: */ - - for (ix = 0; ix < FFESTP_rewriteix; ++ix) - ffestp_file.rewrite.rewrite_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) ffestb_V0181_; - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_V0181_ -- "REWRITE" OPEN_PAREN - - return ffestb_V0181_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0181_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0182_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0183_))) - (t); - } -} - -/* ffestb_V0182_ -- "REWRITE" OPEN_PAREN NAME - - return ffestb_V0182_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_V0182_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_V0187_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0183_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_V0183_ -- "REWRITE" OPEN_PAREN expr [CLOSE_PAREN] - - (ffestb_V0183_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_V0183_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].kw_or_val_present - = TRUE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].kw_present = FALSE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value_present = TRUE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value_is_label - = FALSE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].value - = ffelex_token_use (ft); - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0184_; - return (ffelexHandler) ffestb_V01812_; - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0184_ -- "REWRITE" OPEN_PAREN expr COMMA - - return ffestb_V0184_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0184_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0185_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_V0186_))) - (t); - } -} - -/* ffestb_V0185_ -- "REWRITE" OPEN_PAREN expr COMMA NAME - - return ffestb_V0185_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_V0185_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_V0187_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - nt = ffesta_tokens[1]; - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMAT, (ffeexprCallback) ffestb_V0186_))) - (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_V0186_ -- "REWRITE" OPEN_PAREN expr COMMA expr - - (ffestb_V0186_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0186_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_or_val_present - = TRUE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_present = FALSE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value_present = TRUE; - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value_is_label - = (expr == NULL); - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value - = ffelex_token_use (ft); - ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0187_; - return (ffelexHandler) ffestb_V01812_; - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0187_ -- "REWRITE" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] - - return ffestb_V0187_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0187_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.rewrite.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.rewrite.ix = FFESTP_rewriteixERR; - ffestb_local_.rewrite.label = TRUE; - break; - - case FFESTR_genioFMT: - ffestb_local_.rewrite.ix = FFESTP_rewriteixFMT; - ffestb_local_.rewrite.left = FALSE; - ffestb_local_.rewrite.context = FFEEXPR_contextFILEFORMAT; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.rewrite.ix = FFESTP_rewriteixIOSTAT; - ffestb_local_.rewrite.left = TRUE; - ffestb_local_.rewrite.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioUNIT: - ffestb_local_.rewrite.ix = FFESTP_rewriteixUNIT; - ffestb_local_.rewrite.left = FALSE; - ffestb_local_.rewrite.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix] - .kw_or_val_present = TRUE; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix] - .kw_present = TRUE; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix] - .value_present = FALSE; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_is_label - = ffestb_local_.rewrite.label; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0188_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0188_ -- "REWRITE" OPEN_PAREN [external-file-unit COMMA [format - COMMA]] NAME - - return ffestb_V0188_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_V0188_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.rewrite.label) - return (ffelexHandler) ffestb_V01810_; - if (ffestb_local_.rewrite.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.rewrite.context, - (ffeexprCallback) ffestb_V0189_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.rewrite.context, - (ffeexprCallback) ffestb_V0189_); - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0189_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_V0189_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0189_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - if (ffestb_local_.rewrite.context == FFEEXPR_contextFILEFORMAT) - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix] - .value_is_label = TRUE; - else - break; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_present - = TRUE; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value - = ffelex_token_use (ft); - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0187_; - return (ffelexHandler) ffestb_V01812_; - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V01810_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS - - return ffestb_V01810_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_V01810_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value_present - = TRUE; - ffestp_file.rewrite.rewrite_spec[ffestb_local_.rewrite.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V01811_; - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V01811_ -- "REWRITE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_V01811_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V01811_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_V0187_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_V01812_; - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V01812_ -- "REWRITE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_V01812_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_V01812_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - ffestc_V018_start (); - ffestc_V018_finish (); - } - ffestb_subr_kill_rewrite_ (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - case FFELEX_typeOPEN_PAREN: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V018_start (); - ffestb_subr_kill_rewrite_ (); - - /* EXTENSION: Allow an optional preceding COMMA here if not pedantic. - (f2c provides this extension, as do other compilers, supposedly.) */ - - if (!ffe_is_pedantic () && (ffelex_token_type (t) == FFELEX_typeCOMMA)) - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_); - - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_))) - (t); - - default: - break; - } - - ffestb_subr_kill_rewrite_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V01813_ -- "REWRITE(...)" expr - - (ffestb_V01813_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_V01813_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_V018_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V01813_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_V018_item (expr, ft); - ffestc_V018_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V018_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "REWRITE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V019 -- Parse the ACCEPT statement - - return ffestb_V019; // to lexer - - Make sure the statement has a valid form for the ACCEPT - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_V019 (ffelexToken t) -{ - ffelexHandler next; - ffestpAcceptIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstACCEPT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - default: - break; - } - - for (ix = 0; ix < FFESTP_acceptix; ++ix) - ffestp_file.accept.accept_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0191_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstACCEPT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlACCEPT) - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - default: - break; - } - for (ix = 0; ix < FFESTP_acceptix; ++ix) - ffestp_file.accept.accept_spec[ix].kw_or_val_present = FALSE; - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0191_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - FFESTR_firstlACCEPT); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_V0191_ -- "ACCEPT" expr - - (ffestb_V0191_) // to expression handler - - Make sure the next token is a COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0191_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].kw_present = FALSE; - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value_present = TRUE; - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT].u.expr = expr; - if (!ffesta_is_inhibited ()) - ffestc_V019_start (); - ffestb_subr_kill_accept_ (); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, - (ffeexprCallback) ffestb_V0192_); - if (!ffesta_is_inhibited ()) - ffestc_V019_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_accept_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0192_ -- "ACCEPT" expr COMMA expr - - (ffestb_V0192_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_V0192_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_V019_item (expr, ft); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, - (ffeexprCallback) ffestb_V0192_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_V019_item (expr, ft); - ffestc_V019_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V019_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "ACCEPT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_V020 -- Parse the TYPE statement - - return ffestb_V020; // to lexer - - Make sure the statement has a valid form for the TYPE - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_V020 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexHandler next; - ffestpTypeIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - case FFELEX_typeCOMMA: /* Because "TYPE,PUBLIC::A" is ambiguous with - '90. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNUMBER: - ffesta_confirmed (); - break; - - case FFELEX_typeNAME: /* Because TYPE A is ambiguous with '90. */ - default: - break; - } - - for (ix = 0; ix < FFESTP_typeix; ++ix) - ffestp_file.type.type_spec[ix].kw_or_val_present = FALSE; - return (ffelexHandler) (*((ffelexHandler) - ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0201_))) - (t); - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlTYPE) - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (ffelex_token_length (ffesta_tokens[0]) == FFESTR_firstlTYPE) - break; /* Else might be assignment/stmtfuncdef. */ - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typeCOLON: - goto bad_1; /* :::::::::::::::::::: */ - - default: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlTYPE); - if (ISDIGIT (*p)) - ffesta_confirmed (); /* Else might be '90 TYPE statement. */ - for (ix = 0; ix < FFESTP_typeix; ++ix) - ffestp_file.type.type_spec[ix].kw_or_val_present = FALSE; - next = (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILEFORMATNML, (ffeexprCallback) ffestb_V0201_); - next = (ffelexHandler) ffelex_splice_tokens (next, ffesta_tokens[0], - FFESTR_firstlTYPE); - if (next == NULL) - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE I/O", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE I/O", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_V0201_ -- "TYPE" expr - - (ffestb_V0201_) // to expression handler - - Make sure the next token is a COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0201_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - bool comma = TRUE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffe_is_vxt () && (expr != NULL) - && (ffebld_op (expr) == FFEBLD_opSYMTER)) - break; - comma = FALSE; - /* Fall through. */ - case FFELEX_typeCOMMA: - if (!ffe_is_vxt () && comma && (expr != NULL) - && (ffebld_op (expr) == FFEBLD_opPAREN) - && (ffebld_op (ffebld_left (expr)) == FFEBLD_opSYMTER)) - break; - ffesta_confirmed (); - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].kw_or_val_present - = TRUE; - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].kw_present = FALSE; - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].value_present = TRUE; - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].value_is_label - = (expr == NULL); - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].value - = ffelex_token_use (ft); - ffestp_file.type.type_spec[FFESTP_typeixFORMAT].u.expr = expr; - if (!ffesta_is_inhibited ()) - ffestc_V020_start (); - ffestb_subr_kill_type_ (); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V0202_); - if (!ffesta_is_inhibited ()) - ffestc_V020_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_type_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE I/O", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0202_ -- "TYPE" expr COMMA expr - - (ffestb_V0202_) // to expression handler - - Handle COMMA or EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_V0202_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_V020_item (expr, ft); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextIOLIST, (ffeexprCallback) ffestb_V0202_); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_V020_item (expr, ft); - ffestc_V020_finish (); - } - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V020_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "TYPE I/O", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V021 -- Parse a DELETE statement - - return ffestb_V021; // to lexer - - Make sure the statement has a valid form for a DELETE statement. - If it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V021 (ffelexToken t) -{ - ffestpDeleteIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstDELETE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstDELETE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlDELETE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - for (ix = 0; ix < FFESTP_deleteix; ++ix) - ffestp_file.delete.delete_spec[ix].kw_or_val_present = FALSE; - - return (ffelexHandler) ffestb_V0211_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_V0211_ -- "DELETE" OPEN_PAREN - - return ffestb_V0211_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0211_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0212_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0213_))) - (t); - } -} - -/* ffestb_V0212_ -- "DELETE" OPEN_PAREN NAME - - return ffestb_V0212_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_V0212_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_V0214_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0213_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_V0213_ -- "DELETE" OPEN_PAREN expr - - (ffestb_V0213_) // to expression handler - - Handle COMMA or DELETE_PAREN here. */ - -static ffelexHandler -ffestb_V0213_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].kw_or_val_present - = TRUE; - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].kw_present = FALSE; - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value_present = TRUE; - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value_is_label - = FALSE; - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].value - = ffelex_token_use (ft); - ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0214_; - return (ffelexHandler) ffestb_V0219_; - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0214_ -- "DELETE" OPEN_PAREN [external-file-unit COMMA] - - return ffestb_V0214_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0214_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.delete.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.delete.ix = FFESTP_deleteixERR; - ffestb_local_.delete.label = TRUE; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.delete.ix = FFESTP_deleteixIOSTAT; - ffestb_local_.delete.left = TRUE; - ffestb_local_.delete.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioREC: - ffestb_local_.delete.ix = FFESTP_deleteixREC; - ffestb_local_.delete.left = FALSE; - ffestb_local_.delete.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_genioUNIT: - ffestb_local_.delete.ix = FFESTP_deleteixUNIT; - ffestb_local_.delete.left = FALSE; - ffestb_local_.delete.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.delete.delete_spec[ffestb_local_.delete.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix] - .kw_or_val_present = TRUE; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix] - .kw_present = TRUE; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix] - .value_present = FALSE; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_is_label - = ffestb_local_.delete.label; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0215_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0215_ -- "DELETE" OPEN_PAREN [external-file-unit COMMA] NAME - - return ffestb_V0215_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_V0215_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.delete.label) - return (ffelexHandler) ffestb_V0217_; - if (ffestb_local_.delete.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.delete.context, - (ffeexprCallback) ffestb_V0216_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.delete.context, (ffeexprCallback) ffestb_V0216_); - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0216_ -- "DELETE" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_V0216_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0216_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_present - = TRUE; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value - = ffelex_token_use (ft); - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0214_; - return (ffelexHandler) ffestb_V0219_; - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0217_ -- "DELETE" OPEN_PAREN ... NAME EQUALS - - return ffestb_V0217_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_V0217_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value_present - = TRUE; - ffestp_file.delete.delete_spec[ffestb_local_.delete.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0218_; - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0218_ -- "DELETE" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_V0218_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0218_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_V0214_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_V0219_; - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0219_ -- "DELETE" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_V0219_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_V0219_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V021 (); - ffestb_subr_kill_delete_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_delete_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "DELETE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V026 -- Parse a FIND statement - - return ffestb_V026; // to lexer - - Make sure the statement has a valid form for a FIND statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_V026 (ffelexToken t) -{ - ffestpFindIx ix; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstFIND) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstFIND) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlFIND) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - for (ix = 0; ix < FFESTP_findix; ++ix) - ffestp_file.find.find_spec[ix].kw_or_val_present = FALSE; - - return (ffelexHandler) ffestb_V0261_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_V0261_ -- "FIND" OPEN_PAREN - - return ffestb_V0261_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0261_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0262_; - - default: - return (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0263_))) - (t); - } -} - -/* ffestb_V0262_ -- "FIND" OPEN_PAREN NAME - - return ffestb_V0262_; // to lexer - - If EQUALS here, go to states that handle it. Else, send NAME and this - token thru expression handler. */ - -static ffelexHandler -ffestb_V0262_ (ffelexToken t) -{ - ffelexHandler next; - ffelexToken nt; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - nt = ffesta_tokens[1]; - next = (ffelexHandler) ffestb_V0264_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - next = (ffelexHandler) (*((ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextFILENUM, (ffeexprCallback) ffestb_V0263_))) - (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) (*next) (t); - } -} - -/* ffestb_V0263_ -- "FIND" OPEN_PAREN expr - - (ffestb_V0263_) // to expression handler - - Handle COMMA or FIND_PAREN here. */ - -static ffelexHandler -ffestb_V0263_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.find.find_spec[FFESTP_findixUNIT].kw_or_val_present - = TRUE; - ffestp_file.find.find_spec[FFESTP_findixUNIT].kw_present = FALSE; - ffestp_file.find.find_spec[FFESTP_findixUNIT].value_present = TRUE; - ffestp_file.find.find_spec[FFESTP_findixUNIT].value_is_label - = FALSE; - ffestp_file.find.find_spec[FFESTP_findixUNIT].value - = ffelex_token_use (ft); - ffestp_file.find.find_spec[FFESTP_findixUNIT].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0264_; - return (ffelexHandler) ffestb_V0269_; - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0264_ -- "FIND" OPEN_PAREN [external-file-unit COMMA] - - return ffestb_V0264_; // to lexer - - Handle expr construct (not NAME=expr construct) here. */ - -static ffelexHandler -ffestb_V0264_ (ffelexToken t) -{ - ffestrGenio kw; - - ffestb_local_.find.label = FALSE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - kw = ffestr_genio (t); - switch (kw) - { - case FFESTR_genioERR: - ffestb_local_.find.ix = FFESTP_findixERR; - ffestb_local_.find.label = TRUE; - break; - - case FFESTR_genioIOSTAT: - ffestb_local_.find.ix = FFESTP_findixIOSTAT; - ffestb_local_.find.left = TRUE; - ffestb_local_.find.context = FFEEXPR_contextFILEINT; - break; - - case FFESTR_genioREC: - ffestb_local_.find.ix = FFESTP_findixREC; - ffestb_local_.find.left = FALSE; - ffestb_local_.find.context = FFEEXPR_contextFILENUM; - break; - - case FFESTR_genioUNIT: - ffestb_local_.find.ix = FFESTP_findixUNIT; - ffestb_local_.find.left = FALSE; - ffestb_local_.find.context = FFEEXPR_contextFILENUM; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - if (ffestp_file.find.find_spec[ffestb_local_.find.ix] - .kw_or_val_present) - break; /* Can't specify a keyword twice! */ - ffestp_file.find.find_spec[ffestb_local_.find.ix] - .kw_or_val_present = TRUE; - ffestp_file.find.find_spec[ffestb_local_.find.ix] - .kw_present = TRUE; - ffestp_file.find.find_spec[ffestb_local_.find.ix] - .value_present = FALSE; - ffestp_file.find.find_spec[ffestb_local_.find.ix].value_is_label - = ffestb_local_.find.label; - ffestp_file.find.find_spec[ffestb_local_.find.ix].kw - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0265_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0265_ -- "FIND" OPEN_PAREN [external-file-unit COMMA] NAME - - return ffestb_V0265_; // to lexer - - Make sure EQUALS here, send next token to expression handler. */ - -static ffelexHandler -ffestb_V0265_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (ffestb_local_.find.label) - return (ffelexHandler) ffestb_V0267_; - if (ffestb_local_.find.left) - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - ffestb_local_.find.context, - (ffeexprCallback) ffestb_V0266_); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.find.context, - (ffeexprCallback) ffestb_V0266_); - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0266_ -- "FIND" OPEN_PAREN ... NAME EQUALS expr - - (ffestb_V0266_) // to expression handler - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0266_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestp_file.find.find_spec[ffestb_local_.find.ix].value_present - = TRUE; - ffestp_file.find.find_spec[ffestb_local_.find.ix].value - = ffelex_token_use (ft); - ffestp_file.find.find_spec[ffestb_local_.find.ix].u.expr = expr; - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_V0264_; - return (ffelexHandler) ffestb_V0269_; - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0267_ -- "FIND" OPEN_PAREN ... NAME EQUALS - - return ffestb_V0267_; // to lexer - - Handle NUMBER for label here. */ - -static ffelexHandler -ffestb_V0267_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestp_file.find.find_spec[ffestb_local_.find.ix].value_present - = TRUE; - ffestp_file.find.find_spec[ffestb_local_.find.ix].value - = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0268_; - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0268_ -- "FIND" OPEN_PAREN ... NAME EQUALS NUMBER - - return ffestb_V0268_; // to lexer - - Handle COMMA or CLOSE_PAREN here. */ - -static ffelexHandler -ffestb_V0268_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_V0264_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_V0269_; - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0269_ -- "FIND" OPEN_PAREN ... CLOSE_PAREN - - return ffestb_V0269_; // to lexer - - Handle EOS or SEMICOLON here. */ - -static ffelexHandler -ffestb_V0269_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V026 (); - ffestb_subr_kill_find_ (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestb_subr_kill_find_ (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FIND", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_dimlist -- Parse the ALLOCATABLE/POINTER/TARGET statement - - return ffestb_dimlist; // to lexer - - Make sure the statement has a valid form for the ALLOCATABLE/POINTER/ - TARGET statement. If it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_dimlist (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - ffestb_local_.dimlist.started = TRUE; - return (ffelexHandler) ffestb_dimlist1_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - ffestb_local_.dimlist.started = TRUE; - return (ffelexHandler) ffestb_dimlist1_ (t); - } - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.dimlist.len); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - ffestb_local_.dimlist.started = TRUE; - next = (ffelexHandler) ffestb_dimlist1_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - ffestb_local_.dimlist.started = TRUE; - return (ffelexHandler) ffestb_dimlist1_; - - case FFELEX_typeOPEN_PAREN: - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - ffestb_local_.dimlist.started = FALSE; - next = (ffelexHandler) ffestb_dimlist1_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dimlist1_ -- "ALLOCATABLE/POINTER/TARGET" [COLONCOLON] - - return ffestb_dimlist1_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_dimlist1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_dimlist2_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dimlist2_ -- "ALLOCATABLE/POINTER/TARGET" ... NAME - - return ffestb_dimlist2_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_dimlist2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_dimlist3_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLIST; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDIMLIST, (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimlist.started) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - ffestb_local_.dimlist.started = TRUE; - } - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_item (ffesta_tokens[1], NULL); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_item (ffesta_tokens[1], NULL); - break; - - case FFESTR_firstTARGET: - ffestc_R527_item (ffesta_tokens[1], NULL); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_dimlist4_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimlist.started) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_item (ffesta_tokens[1], NULL); - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_item (ffesta_tokens[1], NULL); - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_item (ffesta_tokens[1], NULL); - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dimlist3_ -- "ALLOCATABLE/POINTER/TARGET" ... NAME OPEN_PAREN - dimlist CLOSE_PAREN - - return ffestb_dimlist3_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_dimlist3_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimlist.started) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - ffestb_local_.dimlist.started = TRUE; - } - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - break; - - case FFESTR_firstTARGET: - ffestc_R527_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_dimlist4_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimlist.started) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_start (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_start (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_start (); - break; - - default: - assert (FALSE); - } - } - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t); - if (ffestb_local_.dimlist.started && !ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dimlist4_ -- "ALLOCATABLE/POINTER/TARGET" ... COMMA - - return ffestb_dimlist4_; // to lexer - - Make sure we don't have EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_dimlist4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - switch (ffesta_first_kw) - { - case FFESTR_firstALLOCATABLE: - ffestc_R525_finish (); - break; - - case FFESTR_firstPOINTER: - ffestc_R526_finish (); - break; - - case FFESTR_firstTARGET: - ffestc_R527_finish (); - break; - - default: - assert (FALSE); - } - } - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dimlist.badname, t); - return (ffelexHandler) ffesta_zero (t); - - default: - return (ffelexHandler) ffestb_dimlist1_ (t); - } -} - -#endif -/* ffestb_dummy -- Parse an ENTRY/FUNCTION/SUBROUTINE statement - - return ffestb_dummy; // to lexer - - Make sure the statement has a valid form for an ENTRY/FUNCTION/SUBROUTINE - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_dummy (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - ffestb_local_.decl.recursive = NULL; - ffestb_local_.dummy.badname = ffestb_args.dummy.badname; - ffestb_local_.dummy.is_subr = ffestb_args.dummy.is_subr; - ffestb_local_.dummy.first_kw = ffesta_first_kw; - return (ffelexHandler) ffestb_dummy1_; - - case FFELEX_typeNAMES: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.dummy.len); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] - = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - ffestb_local_.decl.recursive = NULL; - ffestb_local_.dummy.badname = ffestb_args.dummy.badname; - ffestb_local_.dummy.is_subr = ffestb_args.dummy.is_subr; - ffestb_local_.dummy.first_kw = ffesta_first_kw; - return (ffelexHandler) ffestb_dummy1_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dummy.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.dummy.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, ffestb_args.dummy.badname, ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dummy1_ -- "ENTRY/FUNCTION/SUBROUTINE" NAME - - return ffestb_dummy1_; // to lexer - - Make sure the next token is an EOS, SEMICOLON, or OPEN_PAREN. In the - former case, just implement a null arg list, else get the arg list and - then implement. */ - -static ffelexHandler -ffestb_dummy1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (ffestb_local_.dummy.first_kw == FFESTR_firstFUNCTION) - { - ffesta_confirmed (); /* Later, not if typename w/o RECURSIVE. */ - break; /* Produce an error message, need that open - paren. */ - } - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { /* Pretend as though we got a truly NULL - list. */ - ffestb_subrargs_.name_list.args = NULL; - ffestb_subrargs_.name_list.ok = TRUE; - ffestb_subrargs_.name_list.close_paren = ffelex_token_use (t); - return (ffelexHandler) ffestb_dummy2_ (t); - } - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.name_list.args = ffestt_tokenlist_create (); - ffestb_subrargs_.name_list.handler = (ffelexHandler) ffestb_dummy2_; - ffestb_subrargs_.name_list.is_subr = ffestb_local_.dummy.is_subr; - ffestb_subrargs_.name_list.names = FALSE; - return (ffelexHandler) ffestb_subr_name_list_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_local_.dummy.badname, t); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_dummy2_ -- <dummy-keyword> NAME OPEN_PAREN arg-list CLOSE_PAREN - - return ffestb_dummy2_; // to lexer - - Make sure the statement has a valid form for a dummy-def statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_dummy2_ (ffelexToken t) -{ - if (!ffestb_subrargs_.name_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - switch (ffestb_local_.dummy.first_kw) - { - case FFESTR_firstFUNCTION: - ffestc_R1219 (ffesta_tokens[1], ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren, FFESTP_typeNone, - NULL, NULL, NULL, NULL, ffestb_local_.decl.recursive, NULL); - break; - - case FFESTR_firstSUBROUTINE: - ffestc_R1223 (ffesta_tokens[1], ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren, - ffestb_local_.decl.recursive); - break; - - case FFESTR_firstENTRY: - ffestc_R1226 (ffesta_tokens[1], ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren); - break; - - default: - assert (FALSE); - } - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - if (ffestb_subrargs_.name_list.args != NULL) - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - ffesta_confirmed (); - if ((ffestb_local_.dummy.first_kw != FFESTR_firstFUNCTION) - || (ffestr_other (t) != FFESTR_otherRESULT)) - break; - ffestb_local_.decl.type = FFESTP_typeNone; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_funcname_6_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_local_.dummy.badname, t); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - if (ffestb_subrargs_.name_list.args != NULL) - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R524 -- Parse the DIMENSION statement - - return ffestb_R524; // to lexer - - Make sure the statement has a valid form for the DIMENSION statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_R524 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R524_start (ffesta_first_kw == FFESTR_firstVIRTUAL); - ffestb_local_.dimension.started = TRUE; - return (ffelexHandler) ffestb_R5241_ (t); - } - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.R524.len); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - break; - } - - /* Here, we have at least one char after "DIMENSION" and t is - OPEN_PAREN. */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - ffestb_local_.dimension.started = FALSE; - next = (ffelexHandler) ffestb_R5241_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5241_ -- "DIMENSION" - - return ffestb_R5241_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5241_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R5242_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R524_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5242_ -- "DIMENSION" ... NAME - - return ffestb_R5242_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_R5242_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_R5243_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = ffesta_is_entry_valid - ? FFEEXPR_contextDIMLIST : FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R524_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5243_ -- "DIMENSION" ... NAME OPEN_PAREN dimlist CLOSE_PAREN - - return ffestb_R5243_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R5243_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimension.started) - { - ffestc_R524_start (ffesta_first_kw == FFESTR_firstVIRTUAL); - ffestb_local_.dimension.started = TRUE; - } - ffestc_R524_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_R5244_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.dimension.started) - { - ffestc_R524_start (ffesta_first_kw == FFESTR_firstVIRTUAL); - ffestb_local_.dimension.started = TRUE; - } - ffestc_R524_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_R524_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, t); - if (ffestb_local_.dimension.started && !ffesta_is_inhibited ()) - ffestc_R524_finish (); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5244_ -- "DIMENSION" ... COMMA - - return ffestb_R5244_; // to lexer - - Make sure we don't have EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R5244_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R524_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, ffestb_args.R524.badname, t); - return (ffelexHandler) ffesta_zero (t); - - default: - return (ffelexHandler) ffestb_R5241_ (t); - } -} - -/* ffestb_R547 -- Parse the COMMON statement - - return ffestb_R547; // to lexer - - Make sure the statement has a valid form for the COMMON statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_R547 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCOMMON) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R547_start (); - ffestb_local_.common.started = TRUE; - return (ffelexHandler) ffestb_R5471_ (t); - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCOMMON) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCOMMON); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - ffesta_confirmed (); - if (*p != '\0') - break; - if (!ffesta_is_inhibited ()) - ffestc_R547_start (); - ffestb_local_.common.started = TRUE; - return (ffelexHandler) ffestb_R5471_ (t); - - case FFELEX_typeOPEN_PAREN: - break; - } - - /* Here, we have at least one char after "COMMON" and t is COMMA, - EOS/SEMICOLON, OPEN_PAREN, SLASH, or CONCAT. */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (ffelex_token_type (t) == FFELEX_typeOPEN_PAREN) - ffestb_local_.common.started = FALSE; - else - { - if (!ffesta_is_inhibited ()) - ffestc_R547_start (); - ffestb_local_.common.started = TRUE; - } - next = (ffelexHandler) ffestb_R5471_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "COMMON", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5471_ -- "COMMON" - - return ffestb_R5471_; // to lexer - - Handle NAME, SLASH, or CONCAT. */ - -static ffelexHandler -ffestb_R5471_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - return (ffelexHandler) ffestb_R5474_ (t); - - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_R5472_; - - case FFELEX_typeCONCAT: - if (!ffesta_is_inhibited ()) - ffestc_R547_item_cblock (NULL); - return (ffelexHandler) ffestb_R5474_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5472_ -- "COMMON" SLASH - - return ffestb_R5472_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5472_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R5473_; - - case FFELEX_typeSLASH: - if (!ffesta_is_inhibited ()) - ffestc_R547_item_cblock (NULL); - return (ffelexHandler) ffestb_R5474_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5473_ -- "COMMON" SLASH NAME - - return ffestb_R5473_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_R5473_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - if (!ffesta_is_inhibited ()) - ffestc_R547_item_cblock (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5474_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5474_ -- "COMMON" [SLASH NAME SLASH] or "COMMON" CONCAT - - return ffestb_R5474_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_R5474_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_R5475_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5475_ -- "COMMON" ... NAME - - return ffestb_R5475_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_R5475_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_R5476_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDIMLISTCOMMON, (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_R547_item_object (ffesta_tokens[1], NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5477_; - - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - if (!ffesta_is_inhibited ()) - ffestc_R547_item_object (ffesta_tokens[1], NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_R5471_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_R547_item_object (ffesta_tokens[1], NULL); - ffestc_R547_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5476_ -- "COMMON" ... NAME OPEN_PAREN dimlist CLOSE_PAREN - - return ffestb_R5476_; // to lexer - - Handle COMMA, SLASH, CONCAT, EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_R5476_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.common.started) - { - ffestc_R547_start (); - ffestb_local_.common.started = TRUE; - } - ffestc_R547_item_object (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_R5477_; - - case FFELEX_typeSLASH: - case FFELEX_typeCONCAT: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.common.started) - { - ffestc_R547_start (); - ffestb_local_.common.started = TRUE; - } - ffestc_R547_item_object (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_R5471_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.common.started) - ffestc_R547_start (); - ffestc_R547_item_object (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_R547_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - if (ffestb_local_.common.started && !ffesta_is_inhibited ()) - ffestc_R547_finish (); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R5477_ -- "COMMON" ... COMMA - - return ffestb_R5477_; // to lexer - - Make sure we don't have EOS or SEMICOLON. */ - -static ffelexHandler -ffestb_R5477_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R547_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "COMMON", t); - return (ffelexHandler) ffesta_zero (t); - - default: - return (ffelexHandler) ffestb_R5471_ (t); - } -} - -/* ffestb_R624 -- Parse a NULLIFY statement - - return ffestb_R624; // to lexer - - Make sure the statement has a valid form for a NULLIFY - statement. If it does, implement the statement. - - 31-May-90 JCB 2.0 - Rewrite to produce a list of expressions rather than just names; this - eases semantic checking, putting it in expression handling where that - kind of thing gets done anyway, and makes it easier to support more - flexible extensions to Fortran 90 like NULLIFY(FOO%BAR). */ - -#if FFESTR_F90 -ffelexHandler -ffestb_R624 (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstNULLIFY) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstNULLIFY) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlNULLIFY) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeNAME: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_local_.R624.exprs = ffestt_exprlist_create (); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextNULLIFY, - (ffeexprCallback) ffestb_R6241_); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_R6241_ -- "NULLIFY" OPEN_PAREN expr - - return ffestb_R6241_; // to lexer - - Make sure the statement has a valid form for a NULLIFY statement. If it - does, implement the statement. - - 31-May-90 JCB 2.0 - Rewrite to produce a list of expressions rather than just names; this - eases semantic checking, putting it in expression handling where that - kind of thing gets done anyway, and makes it easier to support more - flexible extensions to Fortran 90 like NULLIFY(FOO%BAR). */ - -static ffelexHandler -ffestb_R6241_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.R624.exprs, expr, - ffelex_token_use (t)); - return (ffelexHandler) ffestb_R6242_; - - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - ffestt_exprlist_append (ffestb_local_.R624.exprs, expr, - ffelex_token_use (t)); - return (ffelexHandler) ffeexpr_lhs (ffesta_output_pool, - FFEEXPR_contextNULLIFY, - (ffeexprCallback) ffestb_R6241_); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t); - ffestt_exprlist_kill (ffestb_local_.R624.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R6242_ -- "NULLIFY" OPEN_PAREN expr-list CLOSE_PAREN - - return ffestb_R6242_; // to lexer - - Make sure the statement has a valid form for a NULLIFY statement. If it - does, implement the statement. */ - -static ffelexHandler -ffestb_R6242_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R624 (ffestb_local_.R624.exprs); - ffestt_exprlist_kill (ffestb_local_.R624.exprs); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "NULLIFY", t); - ffestt_exprlist_kill (ffestb_local_.R624.exprs); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_R1229 -- Parse a STMTFUNCTION statement - - return ffestb_R1229; // to lexer - - Make sure the statement has a valid form for a STMTFUNCTION - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_R1229 (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeNAME: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_subrargs_.name_list.args = ffestt_tokenlist_create (); - ffestb_subrargs_.name_list.handler = (ffelexHandler) ffestb_R12291_; - ffestb_subrargs_.name_list.is_subr = FALSE; /* No "*" items in list! */ - ffestb_subrargs_.name_list.names = TRUE; /* In case "IF(FOO)CALL - FOO...". */ - return (ffelexHandler) ffestb_subr_name_list_; - -bad_0: /* :::::::::::::::::::: */ -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_tokens[0], t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12291_ -- "STMTFUNCTION" OPEN_PAREN dummy-name-list CLOSE_PAREN - - return ffestb_R12291_; // to lexer - - Make sure the statement has a valid form for a STMTFUNCTION statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12291_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - if (!ffestb_subrargs_.name_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1229_start (ffesta_tokens[0], - ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextSFUNCDEF, (ffeexprCallback) ffestb_R12292_); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_2t (FFEBAD_UNREC_STMT, ffesta_tokens[0], t); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_R12292_ -- "STMTFUNCTION" OPEN_PAREN dummy-name-list CLOSE_PAREN - EQUALS expr - - (ffestb_R12292_) // to expression handler - - Make sure the statement has a valid form for a STMTFUNCTION statement. If - it does, implement the statement. */ - -static ffelexHandler -ffestb_R12292_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - if (expr == NULL) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1229_finish (expr, ft); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffestc_R1229_finish (NULL, NULL); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "statement-function-definition", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_chartype -- Parse the CHARACTER statement - - return ffestb_decl_chartype; // to lexer - - Make sure the statement has a valid form for the CHARACTER statement. If - it does, implement the statement. */ - -ffelexHandler -ffestb_decl_chartype (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - ffestb_local_.decl.recursive = NULL; - ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */ - ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstCHRCTR) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeASTERISK: - ffesta_confirmed (); - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_chartype1_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_starlen_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "_TYPEDECL"; - return (ffelexHandler) ffestb_decl_typeparams_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_entsp_ (t); - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstCHRCTR) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlCHRCTR); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (*p != '\0') - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeASTERISK: - ffesta_confirmed (); - if (*p != '\0') - break; - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_chartype1_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_starlen_; - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (*p != '\0') - break; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_typeparams_; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffesta_tokens[1] = ffelex_token_names_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_decl_entsp_2_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_chartype1_ -- "CHARACTER" ASTERISK char-length - - return ffestb_decl_chartype1_; // to lexer - - Handle COMMA, COLONCOLON, or anything else. */ - -static ffelexHandler -ffestb_decl_chartype1_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - /* Fall through. */ - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, ffestb_local_.decl.len, ffestb_local_.decl.lent); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffestb_decl_ents_; - - default: - return (ffelexHandler) ffestb_decl_entsp_ (t); - } -} - -/* ffestb_decl_dbltype -- Parse the DOUBLEPRECISION/DOUBLECOMPLEX statement - - return ffestb_decl_dbltype; // to lexer - - Make sure the statement has a valid form for the DOUBLEPRECISION/ - DOUBLECOMPLEX statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_decl_dbltype (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - ffestb_local_.decl.type = ffestb_args.decl.type; - ffestb_local_.decl.recursive = NULL; - ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */ - ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_entsp_ (t); - } - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.decl.len); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (*p != '\0') - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeOPEN_PAREN: - if (*p != '\0') - break; - goto bad_1; /* :::::::::::::::::::: */ - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffesta_tokens[1] = ffelex_token_names_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_decl_entsp_2_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_double -- Parse the DOUBLE PRECISION/DOUBLE COMPLEX statement - - return ffestb_decl_double; // to lexer - - Make sure the statement has a valid form for the DOUBLE PRECISION/ - DOUBLE COMPLEX statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_decl_double (ffelexToken t) -{ - ffestb_local_.decl.recursive = NULL; - ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */ - ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstDBL) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - switch (ffestr_second (t)) - { - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - break; - - case FFESTR_secondPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_attrsp_; - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_decl_gentype -- Parse the INTEGER/REAL/COMPLEX/LOGICAL statement - - return ffestb_decl_gentype; // to lexer - - Make sure the statement has a valid form for the INTEGER/REAL/COMPLEX/ - LOGICAL statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_decl_gentype (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - - ffestb_local_.decl.type = ffestb_args.decl.type; - ffestb_local_.decl.recursive = NULL; - ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */ - ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */ - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeASTERISK: - ffesta_confirmed (); - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_starkind_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_kindparam_; - - case FFELEX_typeNAME: - ffesta_confirmed (); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_entsp_ (t); - } - - case FFELEX_typeNAMES: - p = ffelex_token_text (ffesta_tokens[0]) + (i = ffestb_args.decl.len); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (*p != '\0') - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - break; - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeASTERISK: - ffesta_confirmed (); - if (*p != '\0') - break; - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_starkind_; - - case FFELEX_typeOPEN_PAREN: - if (*p != '\0') - break; - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "TYPEDECL"; - return (ffelexHandler) ffestb_decl_kindparam_; - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - ffesta_tokens[1] = ffelex_token_names_from_names (ffesta_tokens[0], i, 0); - return (ffelexHandler) ffestb_decl_entsp_2_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_recursive -- Parse the RECURSIVE FUNCTION statement - - return ffestb_decl_recursive; // to lexer - - Make sure the statement has a valid form for the RECURSIVE FUNCTION - statement. If it does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_decl_recursive (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexToken nt; - ffelexToken ot; - ffelexHandler next; - bool needfunc; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstRECURSIVE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - ffesta_confirmed (); - ffestb_local_.decl.recursive = ffelex_token_use (ffesta_tokens[0]); - switch (ffesta_second_kw) - { - case FFESTR_secondINTEGER: - ffestb_local_.decl.type = FFESTP_typeINTEGER; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondBYTE: - ffestb_local_.decl.type = FFESTP_typeBYTE; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondWORD: - ffestb_local_.decl.type = FFESTP_typeWORD; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondREAL: - ffestb_local_.decl.type = FFESTP_typeREAL; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeCOMPLEX; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondLOGICAL: - ffestb_local_.decl.type = FFESTP_typeLOGICAL; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondCHARACTER: - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - return (ffelexHandler) ffestb_decl_recursive1_; - - case FFESTR_secondDOUBLE: - return (ffelexHandler) ffestb_decl_recursive2_; - - case FFESTR_secondDOUBLEPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_func_; - - case FFESTR_secondDOUBLECOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_func_; - - case FFESTR_secondTYPE: - ffestb_local_.decl.type = FFESTP_typeTYPE; - return (ffelexHandler) ffestb_decl_recursive3_; - - case FFESTR_secondFUNCTION: - ffestb_local_.dummy.first_kw = FFESTR_firstFUNCTION; - ffestb_local_.dummy.badname = "FUNCTION"; - ffestb_local_.dummy.is_subr = FALSE; - return (ffelexHandler) ffestb_decl_recursive4_; - - case FFESTR_secondSUBROUTINE: - ffestb_local_.dummy.first_kw = FFESTR_firstSUBROUTINE; - ffestb_local_.dummy.badname = "SUBROUTINE"; - ffestb_local_.dummy.is_subr = TRUE; - return (ffelexHandler) ffestb_decl_recursive4_; - - default: - ffelex_token_kill (ffestb_local_.decl.recursive); - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstRECURSIVE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeASTERISK: - case FFELEX_typeSEMICOLON: - case FFELEX_typeEOS: - ffesta_confirmed (); - break; - - default: - break; - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlRECURSIVE); - if (!ffesrc_is_name_init (*p)) - goto bad_0; /* :::::::::::::::::::: */ - ffestb_local_.decl.recursive - = ffelex_token_name_from_names (ffesta_tokens[0], 0, - FFESTR_firstlRECURSIVE); - nt = ffelex_token_names_from_names (ffesta_tokens[0], - FFESTR_firstlRECURSIVE, 0); - switch (ffestr_first (nt)) - { - case FFESTR_firstINTGR: - p = ffelex_token_text (nt) + (i = FFESTR_firstlINTGR); - ffestb_local_.decl.type = FFESTP_typeINTEGER; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstBYTE: - p = ffelex_token_text (nt) + (i = FFESTR_firstlBYTE); - ffestb_local_.decl.type = FFESTP_typeBYTE; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstWORD: - p = ffelex_token_text (nt) + (i = FFESTR_firstlWORD); - ffestb_local_.decl.type = FFESTP_typeWORD; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstREAL: - p = ffelex_token_text (nt) + (i = FFESTR_firstlREAL); - ffestb_local_.decl.type = FFESTP_typeREAL; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstCMPLX: - p = ffelex_token_text (nt) + (i = FFESTR_firstlCMPLX); - ffestb_local_.decl.type = FFESTP_typeCOMPLEX; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstLGCL: - p = ffelex_token_text (nt) + (i = FFESTR_firstlLGCL); - ffestb_local_.decl.type = FFESTP_typeLOGICAL; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstCHRCTR: - p = ffelex_token_text (nt) + (i = FFESTR_firstlCHRCTR); - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - needfunc = FALSE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstDBLPRCSN: - p = ffelex_token_text (nt) + (i = FFESTR_firstlDBLPRCSN); - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - needfunc = TRUE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstDBLCMPLX: - p = ffelex_token_text (nt) + (i = FFESTR_firstlDBLCMPLX); - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - needfunc = TRUE; - goto typefunc; /* :::::::::::::::::::: */ - - case FFESTR_firstTYPE: - p = ffelex_token_text (nt) + (i = FFESTR_firstlTYPE); - ffestb_local_.decl.type = FFESTP_typeTYPE; - next = (ffelexHandler) ffestb_decl_recursive3_; - break; - - case FFESTR_firstFUNCTION: - p = ffelex_token_text (nt) + (i = FFESTR_firstlFUNCTION); - ffestb_local_.dummy.first_kw = FFESTR_firstFUNCTION; - ffestb_local_.dummy.badname = "FUNCTION"; - ffestb_local_.dummy.is_subr = FALSE; - next = (ffelexHandler) ffestb_decl_recursive4_; - break; - - case FFESTR_firstSUBROUTINE: - p = ffelex_token_text (nt) + (i = FFESTR_firstlSUBROUTINE); - ffestb_local_.dummy.first_kw = FFESTR_firstSUBROUTINE; - ffestb_local_.dummy.badname = "SUBROUTINE"; - ffestb_local_.dummy.is_subr = TRUE; - next = (ffelexHandler) ffestb_decl_recursive4_; - break; - - default: - ffelex_token_kill (ffestb_local_.decl.recursive); - ffelex_token_kill (nt); - goto bad_1; /* :::::::::::::::::::: */ - } - if (*p == '\0') - { - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ot = ffelex_token_name_from_names (nt, i, 0); - ffelex_token_kill (nt); - next = (ffelexHandler) (*next) (ot); - ffelex_token_kill (ot); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -typefunc: /* :::::::::::::::::::: */ - if (*p == '\0') - { - ffelex_token_kill (nt); - if (needfunc) /* DOUBLE PRECISION or DOUBLE COMPLEX? */ - { - ffelex_token_kill (ffestb_local_.decl.recursive); - goto bad_1; /* :::::::::::::::::::: */ - } - return (ffelexHandler) ffestb_decl_recursive1_ (t); - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ot = ffelex_token_names_from_names (nt, i, 0); - ffelex_token_kill (nt); - if (ffestr_first (ot) != FFESTR_firstFUNCTION) - goto bad_o; /* :::::::::::::::::::: */ - p = ffelex_token_text (ot) + (i = FFESTR_firstlFUNCTION); - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_name_from_names (ot, i, 0); - ffelex_token_kill (ot); - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_funcname_1_ (t); - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "type-declaration", nt, i, t); - ffelex_token_kill (nt); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_o: /* :::::::::::::::::::: */ - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", ot); - ffelex_token_kill (ot); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_recursive1_ -- "RECURSIVE" generic-type - - return ffestb_decl_recursive1_; // to lexer - - Handle ASTERISK, OPEN_PAREN, or NAME. */ - -static ffelexHandler -ffestb_decl_recursive1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeASTERISK: - ffesta_confirmed (); - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_; - ffestb_local_.decl.badname = "TYPEFUNC"; - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - return (ffelexHandler) ffestb_decl_starlen_; - return (ffelexHandler) ffestb_decl_starkind_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_; - ffestb_local_.decl.badname = "TYPEFUNC"; - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - { - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_typeparams_; - } - return (ffelexHandler) ffestb_decl_kindparam_; - - case FFELEX_typeNAME: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_func_ (t); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_recursive2_ -- "RECURSIVE" "DOUBLE" - - return ffestb_decl_recursive2_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_recursive2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_second (t)) - { - case FFESTR_secondPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - break; - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_func_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_recursive3_ -- "RECURSIVE" "TYPE" - - return ffestb_decl_recursive3_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_recursive3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_func_; - ffestb_local_.decl.badname = "TYPEFUNC"; - return (ffelexHandler) ffestb_decl_typetype1_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_recursive4_ -- "RECURSIVE" "FUNCTION/SUBROUTINE" - - return ffestb_decl_recursive4_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_recursive4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_dummy1_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_decl_typetype -- Parse the R426/R501/R1219 TYPE statement - - return ffestb_decl_typetype; // to lexer - - Make sure the statement has a valid form for the TYPE statement. If it - does, implement the statement. */ - -#if FFESTR_F90 -ffelexHandler -ffestb_decl_typetype (ffelexToken t) -{ - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstTYPE) - goto bad_0; /* :::::::::::::::::::: */ - if (ffelex_token_length (ffesta_tokens[0]) != FFESTR_firstlTYPE) - goto bad_0; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - break; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON:/* Not COMMA: R424 "TYPE,PUBLIC::A". */ - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - ffestb_local_.decl.recursive = NULL; - ffestb_local_.decl.parameter = FALSE; /* No PARAMETER attribute seen. */ - ffestb_local_.decl.coloncolon = FALSE; /* No COLONCOLON seen. */ - - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_attrsp_; - ffestb_local_.decl.badname = "type-declaration"; - return (ffelexHandler) ffestb_decl_typetype1_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -#endif -/* ffestb_decl_attrs_ -- "type" [type parameters] COMMA - - return ffestb_decl_attrs_; // to lexer - - Handle NAME of an attribute. */ - -static ffelexHandler -ffestb_decl_attrs_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_first (t)) - { -#if FFESTR_F90 - case FFESTR_firstALLOCATABLE: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribALLOCATABLE, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; -#endif - - case FFESTR_firstDIMENSION: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_attrs_1_; - - case FFESTR_firstEXTERNAL: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribEXTERNAL, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; - -#if FFESTR_F90 - case FFESTR_firstINTENT: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_attrs_3_; -#endif - - case FFESTR_firstINTRINSIC: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribINTRINSIC, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; - -#if FFESTR_F90 - case FFESTR_firstOPTIONAL: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribOPTIONAL, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; -#endif - - case FFESTR_firstPARAMETER: - ffestb_local_.decl.parameter = TRUE; - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribPARAMETER, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; - -#if FFESTR_F90 - case FFESTR_firstPOINTER: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribPOINTER, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; -#endif - -#if FFESTR_F90 - case FFESTR_firstPRIVATE: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribPRIVATE, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; - - case FFESTR_firstPUBLIC: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribPUBLIC, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; -#endif - - case FFESTR_firstSAVE: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribSAVE, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; - -#if FFESTR_F90 - case FFESTR_firstTARGET: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribTARGET, t, - FFESTR_otherNone, NULL); - return (ffelexHandler) ffestb_decl_attrs_7_; -#endif - - default: - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t); - return (ffelexHandler) ffestb_decl_attrs_7_; - } - break; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_1_ -- "type" [type parameters] ",DIMENSION" - - return ffestb_decl_attrs_1_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_attrs_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_decl_attrs_2_; - ffestb_subrargs_.dim_list.pool = ffesta_scratch_pool; - ffestb_subrargs_.dim_list.ctx = ffesta_is_entry_valid - ? FFEEXPR_contextDIMLIST : FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_scratch_pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_attrs_7_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_2_ -- "type" [type parameters] ",DIMENSION" OPEN_PAREN - dimlist CLOSE_PAREN - - return ffestb_decl_attrs_2_; // to lexer - - Handle COMMA or COLONCOLON. */ - -static ffelexHandler -ffestb_decl_attrs_2_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - if (!ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribDIMENSION, ffesta_tokens[1], - FFESTR_otherNone, ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_decl_attrs_7_ (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_3_ -- "type" [type parameters] ",INTENT" - - return ffestb_decl_attrs_3_; // to lexer - - Handle OPEN_PAREN. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_decl_attrs_3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffestb_decl_attrs_4_; - - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_attrs_7_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_4_ -- "type" [type parameters] ",INTENT" OPEN_PAREN - - return ffestb_decl_attrs_4_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_attrs_4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffestb_local_.decl.kw = ffestr_other (t); - switch (ffestb_local_.decl.kw) - { - case FFESTR_otherIN: - return (ffelexHandler) ffestb_decl_attrs_5_; - - case FFESTR_otherINOUT: - return (ffelexHandler) ffestb_decl_attrs_6_; - - case FFESTR_otherOUT: - return (ffelexHandler) ffestb_decl_attrs_6_; - - default: - ffestb_local_.decl.kw = FFESTR_otherNone; - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t); - return (ffelexHandler) ffestb_decl_attrs_5_; - } - break; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_5_ -- "type" [type parameters] ",INTENT" OPEN_PAREN "IN" - - return ffestb_decl_attrs_5_; // to lexer - - Handle NAME or CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_attrs_5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_other (t)) - { - case FFESTR_otherOUT: - if (ffestb_local_.decl.kw != FFESTR_otherNone) - ffestb_local_.decl.kw = FFESTR_otherINOUT; - return (ffelexHandler) ffestb_decl_attrs_6_; - - default: - if (ffestb_local_.decl.kw != FFESTR_otherNone) - { - ffestb_local_.decl.kw = FFESTR_otherNone; - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_ATTR, t); - } - return (ffelexHandler) ffestb_decl_attrs_5_; - } - break; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_decl_attrs_6_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrs_6_ -- "type" [type parameters] ",INTENT" OPEN_PAREN "IN" - ["OUT"] - - return ffestb_decl_attrs_6_; // to lexer - - Handle CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_attrs_6_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if ((ffestb_local_.decl.kw != FFESTR_otherNone) - && !ffesta_is_inhibited ()) - ffestc_decl_attrib (FFESTP_attribINTENT, ffesta_tokens[1], - ffestb_local_.decl.kw, NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_attrs_7_; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_decl_attrs_7_ -- "type" [type parameters] attribute - - return ffestb_decl_attrs_7_; // to lexer - - Handle COMMA (another attribute) or COLONCOLON (entities). */ - -static ffelexHandler -ffestb_decl_attrs_7_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - return (ffelexHandler) ffestb_decl_ents_; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_attrsp_ -- "type" [type parameters] - - return ffestb_decl_attrsp_; // to lexer - - Handle COMMA (meaning we have attributes), COLONCOLON (meaning we have - no attributes but entities), or go to entsp to see about functions or - entities. */ - -static ffelexHandler -ffestb_decl_attrsp_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffestb_decl_attrs_; - - case FFELEX_typeCOLONCOLON: - ffestb_local_.decl.coloncolon = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffestb_decl_ents_; - - default: - return (ffelexHandler) ffestb_decl_entsp_ (t); - } -} - -/* ffestb_decl_ents_ -- "type" [type parameters] [attributes "::"] - - return ffestb_decl_ents_; // to lexer - - Handle NAME of an entity. */ - -static ffelexHandler -ffestb_decl_ents_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_ents_1_; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_1_ -- "type" [type parameters] [attributes "::"] NAME - - return ffestb_decl_ents_1_; // to lexer - - Handle ASTERISK, OPEN_PAREN, EQUALS, SLASH, COMMA, or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_decl_item (ffesta_tokens[1], NULL, NULL, NULL, NULL, NULL, NULL, - NULL, FALSE); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], NULL, NULL, NULL, NULL, NULL, NULL, - NULL, FALSE); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeASTERISK: - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_ents_2_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_ents_3_ (t); - - case FFELEX_typeEQUALS: - case FFELEX_typeSLASH: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_subrargs_.dim_list.dims = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_ents_7_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_2_ -- "type" [type parameters] [attributes "::"] NAME - ASTERISK - - return ffestb_decl_ents_2_; // to lexer - - Handle NUMBER or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_ents_2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - if (ffestb_local_.decl.type != FFESTP_typeCHARACTER) - { - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_ents_3_; - } - /* Fall through. *//* (CHARACTER's *n is always a len spec. */ - case FFELEX_typeOPEN_PAREN:/* "*(" is after the (omitted) - "(array-spec)". */ - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_subrargs_.dim_list.dims = NULL; - return (ffelexHandler) ffestb_decl_ents_5_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_3_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] - - return ffestb_decl_ents_3_; // to lexer - - Handle ASTERISK, OPEN_PAREN, EQUALS, SLASH, COMMA, or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, NULL, NULL, NULL, NULL, NULL, FALSE); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, NULL, NULL, NULL, NULL, NULL, FALSE); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeASTERISK: - ffestb_subrargs_.dim_list.dims = NULL; - return (ffelexHandler) ffestb_decl_ents_5_; - - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_decl_ents_4_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = ffesta_is_entry_valid - ? FFEEXPR_contextDIMLIST : FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_subrargs_.dim_list.ctx, - (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeEQUALS: - case FFELEX_typeSLASH: - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_subrargs_.dim_list.dims = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_ents_7_ (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_4_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - - return ffestb_decl_ents_4_; // to lexer - - Handle ASTERISK, EQUALS, SLASH, COMMA, or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_4_ (ffelexToken t) -{ - ffelexToken nt; - - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - if (ffelex_token_type (ffesta_tokens[1]) == FFELEX_typeNAMES) - { - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeASTERISK: - case FFELEX_typeSLASH: /* But NOT FFELEX_typeEQUALS. */ - case FFELEX_typeCOLONCOLON: /* Actually an error. */ - break; /* Confirm and handle. */ - - default: /* Perhaps EQUALS, as in - INTEGERFUNCTIONX(A)=B. */ - goto bad; /* :::::::::::::::::::: */ - } - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - nt = ffelex_token_name_from_names (ffesta_tokens[1], 0, 0); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = nt; - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - NULL, NULL, NULL, NULL); - } - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, NULL, NULL, - FALSE); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, NULL, NULL, - FALSE); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeASTERISK: - if (ffestb_local_.decl.lent != NULL) - break; /* Can't specify "*length" twice. */ - return (ffelexHandler) ffestb_decl_ents_5_; - - case FFELEX_typeEQUALS: - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_decl_ents_7_ (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - if ((ffelex_token_type (ffesta_tokens[1]) != FFELEX_typeNAMES) - && !ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_5_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - ASTERISK - - return ffestb_decl_ents_5_; // to lexer - - Handle NUMBER or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_ents_5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_ents_7_; - - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, (ffeexprCallback) ffestb_decl_ents_6_); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_6_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - ASTERISK OPEN_PAREN expr - - (ffestb_decl_ents_6_) // to expression handler - - Handle CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_ents_6_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - return (ffelexHandler) ffestb_decl_ents_7_; - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_7_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - [ASTERISK charlength] - - return ffestb_decl_ents_7_; // to lexer - - Handle EQUALS, SLASH, COMMA, or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_7_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, NULL, NULL, - FALSE); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, NULL, NULL, - FALSE); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeEQUALS: - if (!ffestb_local_.decl.coloncolon) - ffesta_ffebad_1t (FFEBAD_INVALID_TYPEDECL_INIT, t); - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - ffestb_local_.decl.parameter ? FFEEXPR_contextPARAMETER - : FFEEXPR_contextINITVAL, (ffeexprCallback) ffestb_decl_ents_8_); - - case FFELEX_typeSLASH: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, NULL, NULL, - TRUE); - ffestc_decl_itemstartvals (); - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_decl_ents_9_); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_8_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - [ASTERISK charlength] EQUALS expr - - (ffestb_decl_ents_8_) // to expression handler - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_8_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, expr, ft, - FALSE); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_decl_item (ffesta_tokens[1], ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_subrargs_.dim_list.dims, - ffestb_local_.decl.len, ffestb_local_.decl.lent, expr, ft, - FALSE); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_subrargs_.dim_list.dims != NULL) - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_9_ -- "type" ... SLASH expr - - (ffestb_decl_ents_9_) // to expression handler - - Handle ASTERISK, COMMA, or SLASH. */ - -static ffelexHandler -ffestb_decl_ents_9_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_itemvalue (NULL, NULL, expr, ft); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_decl_ents_9_); - - case FFELEX_typeASTERISK: - if (expr == NULL) - break; - ffestb_local_.decl.expr = expr; - ffesta_tokens[1] = ffelex_token_use (ft); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_decl_ents_10_); - - case FFELEX_typeSLASH: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_decl_itemvalue (NULL, NULL, expr, ft); - ffestc_decl_itemendvals (t); - } - return (ffelexHandler) ffestb_decl_ents_11_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - break; - } - - if (!ffesta_is_inhibited ()) - { - ffestc_decl_itemendvals (t); - ffestc_decl_finish (); - } - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_10_ -- "type" ... SLASH expr ASTERISK expr - - (ffestb_decl_ents_10_) // to expression handler - - Handle COMMA or SLASH. */ - -static ffelexHandler -ffestb_decl_ents_10_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_decl_itemvalue (ffestb_local_.decl.expr, ffesta_tokens[1], - expr, ft); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffeexpr_rhs - (ffesta_output_pool, FFEEXPR_contextDATA, - (ffeexprCallback) ffestb_decl_ents_9_); - - case FFELEX_typeSLASH: - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_decl_itemvalue (ffestb_local_.decl.expr, ffesta_tokens[1], - expr, ft); - ffestc_decl_itemendvals (t); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_ents_11_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - break; - } - - if (!ffesta_is_inhibited ()) - { - ffestc_decl_itemendvals (t); - ffestc_decl_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_ents_11_ -- "type" [type parameters] [attributes "::"] NAME - [ASTERISK NUMBER] [OPEN_PAREN dimlist CLOSE_PAREN] - [ASTERISK charlength] SLASH initvals SLASH - - return ffestb_decl_ents_11_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_ents_11_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_decl_ents_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_decl_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_entsp_ -- "type" [type parameters] - - return ffestb_decl_entsp_; // to lexer - - Handle NAME or NAMES beginning either an entity (object) declaration or - a function definition.. */ - -static ffelexHandler -ffestb_decl_entsp_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_entsp_1_; - - case FFELEX_typeNAMES: - ffesta_confirmed (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_entsp_2_; - - default: - break; - } - - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "type-declaration", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_entsp_1_ -- "type" [type parameters] NAME - - return ffestb_decl_entsp_1_; // to lexer - - If we get another NAME token here, then the previous one must be - "RECURSIVE" or "FUNCTION" and we handle it accordingly. Otherwise, - we send the previous and current token through to _ents_. */ - -static ffelexHandler -ffestb_decl_entsp_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_first (ffesta_tokens[1])) - { -#if FFESTR_F90 - case FFESTR_firstRECURSIVE: - if (ffestr_first (t) != FFESTR_firstFUNCTION) - { - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - } - ffestb_local_.decl.recursive = ffesta_tokens[1]; - return (ffelexHandler) ffestb_decl_funcname_; -#endif - - case FFESTR_firstFUNCTION: - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_decl_funcname_ (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", ffesta_tokens[1]); - break; - } - break; - - default: - if ((ffelex_token_type (ffesta_tokens[1]) != FFELEX_typeNAMES) - && !ffesta_is_inhibited ()) - ffestc_decl_start (ffestb_local_.decl.type, ffesta_tokens[0], - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - /* NAME/NAMES token already in ffesta_tokens[1]. */ - return (ffelexHandler) ffestb_decl_ents_1_ (t); - } - - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_entsp_2_ -- "type" [type parameters] NAMES - - return ffestb_decl_entsp_2_; // to lexer - - If we get an ASTERISK or OPEN_PAREN here, then if the previous NAMES - begins with "FUNCTION" or "RECURSIVEFUNCTION" and is followed by a - first-name-char, we have a possible syntactically ambiguous situation. - Otherwise, we have a straightforward situation just as if we went - through _entsp_1_ instead of here. */ - -static ffelexHandler -ffestb_decl_entsp_2_ (ffelexToken t) -{ - ffelexToken nt; - bool asterisk_ok; - unsigned char *p; - ffeTokenLength i; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeASTERISK: - ffesta_confirmed (); - switch (ffestb_local_.decl.type) - { - case FFESTP_typeINTEGER: - case FFESTP_typeREAL: - case FFESTP_typeCOMPLEX: - case FFESTP_typeLOGICAL: - asterisk_ok = (ffestb_local_.decl.kindt == NULL); - break; - - case FFESTP_typeCHARACTER: - asterisk_ok = (ffestb_local_.decl.lent == NULL); - break; - - case FFESTP_typeBYTE: - case FFESTP_typeWORD: - default: - asterisk_ok = FALSE; - break; - } - switch (ffestr_first (ffesta_tokens[1])) - { -#if FFESTR_F90 - case FFESTR_firstRECURSIVEFNCTN: - if (!asterisk_ok) - break; /* For our own convenience, treat as non-FN - stmt. */ - p = ffelex_token_text (ffesta_tokens[1]) - + (i = FFESTR_firstlRECURSIVEFNCTN); - if (!ffesrc_is_name_init (*p)) - break; - ffestb_local_.decl.recursive - = ffelex_token_name_from_names (ffesta_tokens[1], 0, - FFESTR_firstlRECURSIVEFNCTN); - ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1], - FFESTR_firstlRECURSIVEFNCTN, 0); - return (ffelexHandler) ffestb_decl_entsp_3_; -#endif - - case FFESTR_firstFUNCTION: - if (!asterisk_ok) - break; /* For our own convenience, treat as non-FN - stmt. */ - p = ffelex_token_text (ffesta_tokens[1]) - + (i = FFESTR_firstlFUNCTION); - if (!ffesrc_is_name_init (*p)) - break; - ffestb_local_.decl.recursive = NULL; - ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1], - FFESTR_firstlFUNCTION, 0); - return (ffelexHandler) ffestb_decl_entsp_3_; - - default: - break; - } - break; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.aster_after = FALSE; - switch (ffestr_first (ffesta_tokens[1])) - { -#if FFESTR_F90 - case FFESTR_firstRECURSIVEFNCTN: - p = ffelex_token_text (ffesta_tokens[1]) - + (i = FFESTR_firstlRECURSIVEFNCTN); - if (!ffesrc_is_name_init (*p)) - break; - ffestb_local_.decl.recursive - = ffelex_token_name_from_names (ffesta_tokens[1], 0, - FFESTR_firstlRECURSIVEFNCTN); - ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1], - FFESTR_firstlRECURSIVEFNCTN, 0); - return (ffelexHandler) ffestb_decl_entsp_5_ (t); -#endif - - case FFESTR_firstFUNCTION: - p = ffelex_token_text (ffesta_tokens[1]) - + (i = FFESTR_firstlFUNCTION); - if (!ffesrc_is_name_init (*p)) - break; - ffestb_local_.decl.recursive = NULL; - ffesta_tokens[2] = ffelex_token_name_from_names (ffesta_tokens[1], - FFESTR_firstlFUNCTION, 0); - return (ffelexHandler) ffestb_decl_entsp_5_ (t); - - default: - break; - } - if ((ffestb_local_.decl.kindt != NULL) - || (ffestb_local_.decl.lent != NULL)) - break; /* Have kind/len type param, definitely not - assignment stmt. */ - return (ffelexHandler) ffestb_decl_entsp_1_ (t); - - default: - break; - } - - nt = ffelex_token_name_from_names (ffesta_tokens[1], 0, 0); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = nt; /* Change NAMES to NAME. */ - return (ffelexHandler) ffestb_decl_entsp_1_ (t); -} - -/* ffestb_decl_entsp_3_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME ASTERISK - - return ffestb_decl_entsp_3_; // to lexer - - Handle NUMBER or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_entsp_3_ (ffelexToken t) -{ - ffestb_local_.decl.aster_after = TRUE; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - switch (ffestb_local_.decl.type) - { - case FFESTP_typeINTEGER: - case FFESTP_typeREAL: - case FFESTP_typeCOMPLEX: - case FFESTP_typeLOGICAL: - ffestb_local_.decl.kindt = ffelex_token_use (t); - break; - - case FFESTP_typeCHARACTER: - ffestb_local_.decl.lent = ffelex_token_use (t); - break; - - case FFESTP_typeBYTE: - case FFESTP_typeWORD: - default: - assert (FALSE); - } - return (ffelexHandler) ffestb_decl_entsp_5_; - - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_entsp_4_); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_entsp_4_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME ASTERISK OPEN_PAREN expr - - (ffestb_decl_entsp_4_) // to expression handler - - Allow only CLOSE_PAREN; and deal with character-length expression. */ - -static ffelexHandler -ffestb_decl_entsp_4_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - switch (ffestb_local_.decl.type) - { - case FFESTP_typeCHARACTER: - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - break; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - } - return (ffelexHandler) ffestb_decl_entsp_5_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_entsp_5_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] - - return ffestb_decl_entsp_5_; // to lexer - - Make sure the next token is an OPEN_PAREN. Get the arg list or dimension - list. If it can't be an arg list, or if the CLOSE_PAREN is followed by - something other than EOS/SEMICOLON or NAME, then treat as dimension list - and handle statement as an R426/R501. If it can't be a dimension list, or - if the CLOSE_PAREN is followed by NAME, treat as an arg list and handle - statement as an R1219. If it can be either an arg list or a dimension - list and if the CLOSE_PAREN is followed by EOS/SEMICOLON, ask FFESTC - whether to treat the statement as an R426/R501 or an R1219 and act - accordingly. */ - -static ffelexHandler -ffestb_decl_entsp_5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - if (ffestb_local_.decl.aster_after && (ffestb_local_.decl.len != NULL)) - { /* "CHARACTER[RECURSIVE]FUNCTIONxyz*(len-expr) - (..." must be a function-stmt, since the - (len-expr) cannot precede (array-spec) in - an object declaration but can precede - (name-list) in a function stmt. */ - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = ffesta_tokens[2]; - return (ffelexHandler) ffestb_decl_funcname_4_ (t); - } - ffestb_local_.decl.toklist = ffestt_tokenlist_create (); - ffestb_local_.decl.empty = TRUE; - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_entsp_6_; - - default: - break; - } - - assert (ffestb_local_.decl.aster_after); - ffesta_confirmed (); /* We've seen an ASTERISK, so even EQUALS - confirmed. */ - ffestb_subr_ambig_to_ents_ (); - ffestb_subrargs_.dim_list.dims = NULL; - return (ffelexHandler) ffestb_decl_ents_7_ (t); -} - -/* ffestb_decl_entsp_6_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN - - return ffestb_decl_entsp_6_; // to lexer - - If CLOSE_PAREN, we definitely have an R1219 function-stmt, since - the notation "name()" is invalid for a declaration. */ - -static ffelexHandler -ffestb_decl_entsp_6_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (!ffestb_local_.decl.empty) - { /* Trailing comma, just a warning for - stmt func def, so allow ambiguity. */ - ffestt_tokenlist_append (ffestb_local_.decl.toklist, - ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_entsp_8_; - } - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = ffesta_tokens[2]; - next = (ffelexHandler) ffestt_tokenlist_handle - (ffestb_local_.decl.toklist, (ffelexHandler) ffestb_decl_funcname_4_); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); - - case FFELEX_typeNAME: - ffestb_local_.decl.empty = FALSE; - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_entsp_7_; - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typePERCENT: - case FFELEX_typePERIOD: - case FFELEX_typeOPEN_PAREN: - if ((ffestb_local_.decl.kindt != NULL) - || (ffestb_local_.decl.lent != NULL)) - break; /* type(params)name or type*val name, either - way confirmed. */ - return (ffelexHandler) ffestb_subr_ambig_nope_ (t); - - default: - break; - } - - ffesta_confirmed (); - ffestb_subr_ambig_to_ents_ (); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_decl_ents_3_); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_entsp_7_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN NAME - - return ffestb_decl_entsp_7_; // to lexer - - Expect COMMA or CLOSE_PAREN to remain ambiguous, else not an R1219 - function-stmt. */ - -static ffelexHandler -ffestb_decl_entsp_7_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_entsp_8_; - - case FFELEX_typeCOMMA: - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_entsp_6_; - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typePERCENT: - case FFELEX_typePERIOD: - case FFELEX_typeOPEN_PAREN: - if ((ffestb_local_.decl.kindt != NULL) - || (ffestb_local_.decl.lent != NULL)) - break; /* type(params)name or type*val name, either - way confirmed. */ - return (ffelexHandler) ffestb_subr_ambig_nope_ (t); - - default: - break; - } - - ffesta_confirmed (); - ffestb_subr_ambig_to_ents_ (); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_decl_ents_3_); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_entsp_8_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN name-list - CLOSE_PAREN - - return ffestb_decl_entsp_8_; // to lexer - - If EOS/SEMICOLON, situation remains ambiguous, ask FFESTC to resolve - it. If NAME (must be "RESULT", but that is checked later on), - definitely an R1219 function-stmt. Anything else, handle as entity decl. */ - -static ffelexHandler -ffestb_decl_entsp_8_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (ffestc_is_decl_not_R1219 ()) - break; - /* Fall through. */ - case FFELEX_typeNAME: - ffesta_confirmed (); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_tokens[1] = ffesta_tokens[2]; - next = (ffelexHandler) ffestt_tokenlist_handle - (ffestb_local_.decl.toklist, (ffelexHandler) ffestb_decl_funcname_4_); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); - - case FFELEX_typeEQUALS: - case FFELEX_typePOINTS: - case FFELEX_typePERCENT: - case FFELEX_typePERIOD: - case FFELEX_typeOPEN_PAREN: - if ((ffestb_local_.decl.kindt != NULL) - || (ffestb_local_.decl.lent != NULL)) - break; /* type(params)name or type*val name, either - way confirmed. */ - return (ffelexHandler) ffestb_subr_ambig_nope_ (t); - - default: - break; - } - - ffesta_confirmed (); - ffestb_subr_ambig_to_ents_ (); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_decl_ents_3_); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_func_ -- ["type" [type parameters]] RECURSIVE - - return ffestb_decl_func_; // to lexer - - Handle "FUNCTION". */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_decl_func_ (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (ffestr_first (t) != FFESTR_firstFUNCTION) - break; - return (ffelexHandler) ffestb_decl_funcname_; - - case FFELEX_typeNAMES: - ffesta_confirmed (); - if (ffestr_first (t) != FFESTR_firstFUNCTION) - break; - p = ffelex_token_text (t) + (i = FFESTR_firstlFUNCTION); - if (*p == '\0') - break; - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffesta_tokens[1] = ffelex_token_name_from_names (t, i, 0); - return (ffelexHandler) ffestb_decl_funcname_1_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_i: /* :::::::::::::::::::: */ - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t, i, NULL); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_decl_funcname_ -- "type" [type parameters] [RECURSIVE] FUNCTION - - return ffestb_decl_funcname_; // to lexer - - Handle NAME of a function. */ - -static ffelexHandler -ffestb_decl_funcname_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_funcname_1_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_1_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME - - return ffestb_decl_funcname_1_; // to lexer - - Handle ASTERISK or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_funcname_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeASTERISK: - return (ffelexHandler) ffestb_decl_funcname_2_; - - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffestb_decl_funcname_4_ (t); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_2_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME ASTERISK - - return ffestb_decl_funcname_2_; // to lexer - - Handle NUMBER or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_funcname_2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNUMBER: - switch (ffestb_local_.decl.type) - { - case FFESTP_typeINTEGER: - case FFESTP_typeREAL: - case FFESTP_typeCOMPLEX: - case FFESTP_typeLOGICAL: - if (ffestb_local_.decl.kindt == NULL) - ffestb_local_.decl.kindt = ffelex_token_use (t); - else - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - - case FFESTP_typeCHARACTER: - if (ffestb_local_.decl.lent == NULL) - ffestb_local_.decl.lent = ffelex_token_use (t); - else - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - - case FFESTP_typeBYTE: - case FFESTP_typeWORD: - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - } - return (ffelexHandler) ffestb_decl_funcname_4_; - - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextCHARACTERSIZE, - (ffeexprCallback) ffestb_decl_funcname_3_); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_3_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME ASTERISK OPEN_PAREN expr - - (ffestb_decl_funcname_3_) // to expression handler - - Allow only CLOSE_PAREN; and deal with character-length expression. */ - -static ffelexHandler -ffestb_decl_funcname_3_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - if (expr == NULL) - break; - switch (ffestb_local_.decl.type) - { - case FFESTP_typeCHARACTER: - if (ffestb_local_.decl.lent == NULL) - { - ffestb_local_.decl.len = expr; - ffestb_local_.decl.lent = ffelex_token_use (ft); - } - else - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - break; - } - return (ffelexHandler) ffestb_decl_funcname_4_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_4_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] - - return ffestb_decl_funcname_4_; // to lexer - - Make sure the next token is an OPEN_PAREN. Get the arg list and - then implement. */ - -static ffelexHandler -ffestb_decl_funcname_4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.name_list.args = ffestt_tokenlist_create (); - ffestb_subrargs_.name_list.handler - = (ffelexHandler) ffestb_decl_funcname_5_; - ffestb_subrargs_.name_list.is_subr = FALSE; - ffestb_subrargs_.name_list.names = FALSE; - return (ffelexHandler) ffestb_subr_name_list_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_5_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN arg-list - CLOSE_PAREN - - return ffestb_decl_funcname_5_; // to lexer - - Must have EOS/SEMICOLON or "RESULT" here. */ - -static ffelexHandler -ffestb_decl_funcname_5_ (ffelexToken t) -{ - if (!ffestb_subrargs_.name_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R1219 (ffesta_tokens[1], ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren, ffestb_local_.decl.type, - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent, - ffestb_local_.decl.recursive, NULL); - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeNAME: - if (ffestr_other (t) != FFESTR_otherRESULT) - break; - return (ffelexHandler) ffestb_decl_funcname_6_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_6_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN arglist - CLOSE_PAREN "RESULT" - - return ffestb_decl_funcname_6_; // to lexer - - Make sure the next token is an OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_funcname_6_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - return (ffelexHandler) ffestb_decl_funcname_7_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_7_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN arglist - CLOSE_PAREN "RESULT" OPEN_PAREN - - return ffestb_decl_funcname_7_; // to lexer - - Make sure the next token is a NAME. */ - -static ffelexHandler -ffestb_decl_funcname_7_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[2] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_funcname_8_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_8_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN arglist - CLOSE_PAREN "RESULT" OPEN_PAREN NAME - - return ffestb_decl_funcname_8_; // to lexer - - Make sure the next token is a CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_funcname_8_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_decl_funcname_9_; - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_funcname_9_ -- "type" [type parameters] [RECURSIVE] FUNCTION - NAME [type parameter] OPEN_PAREN arg-list - CLOSE_PAREN "RESULT" OPEN_PAREN NAME CLOSE_PAREN - - return ffestb_decl_funcname_9_; // to lexer - - Must have EOS/SEMICOLON here. */ - -static ffelexHandler -ffestb_decl_funcname_9_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_R1219 (ffesta_tokens[1], ffestb_subrargs_.name_list.args, - ffestb_subrargs_.name_list.close_paren, ffestb_local_.decl.type, - ffestb_local_.decl.kind, ffestb_local_.decl.kindt, - ffestb_local_.decl.len, ffestb_local_.decl.lent, - ffestb_local_.decl.recursive, ffesta_tokens[2]); - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - if (ffestb_local_.decl.recursive != NULL) - ffelex_token_kill (ffestb_local_.decl.recursive); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffelex_token_kill (ffesta_tokens[1]); - ffelex_token_kill (ffesta_tokens[2]); - ffelex_token_kill (ffestb_subrargs_.name_list.close_paren); - ffestt_tokenlist_kill (ffestb_subrargs_.name_list.args); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "FUNCTION", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V003 -- Parse the STRUCTURE statement - - return ffestb_V003; // to lexer - - Make sure the statement has a valid form for the STRUCTURE statement. - If it does, implement the statement. */ - -#if FFESTR_VXT -ffelexHandler -ffestb_V003 (ffelexToken t) -{ - ffeTokenLength i; - char *p; - ffelexToken nt; - ffelexHandler next; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstSTRUCTURE) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V003_start (NULL); - ffestb_local_.structure.started = TRUE; - return (ffelexHandler) ffestb_V0034_ (t); - - case FFELEX_typeSLASH: - ffesta_confirmed (); - return (ffelexHandler) ffestb_V0031_; - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstSTRUCTURE) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlSTRUCTURE); - switch (ffelex_token_type (t)) - { - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); - break; - - case FFELEX_typeSLASH: - ffesta_confirmed (); - if (*p != '\0') - goto bad_1; /* :::::::::::::::::::: */ - return (ffelexHandler) ffestb_V0031_; - - case FFELEX_typeOPEN_PAREN: - break; - } - - /* Here, we have at least one char after "STRUCTURE" and t is COMMA, - EOS/SEMICOLON, or OPEN_PAREN. */ - - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - nt = ffelex_token_name_from_names (ffesta_tokens[0], i, 0); - if (ffelex_token_type (t) == FFELEX_typeOPEN_PAREN) - ffestb_local_.structure.started = FALSE; - else - { - if (!ffesta_is_inhibited ()) - ffestc_V003_start (NULL); - ffestb_local_.structure.started = TRUE; - } - next = (ffelexHandler) ffestb_V0034_ (nt); - ffelex_token_kill (nt); - return (ffelexHandler) (*next) (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0031_ -- "STRUCTURE" SLASH - - return ffestb_V0031_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0031_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0032_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - break; - } - - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0032_ -- "STRUCTURE" SLASH NAME - - return ffestb_V0032_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_V0032_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - if (!ffesta_is_inhibited ()) - ffestc_V003_start (ffesta_tokens[1]); - ffestb_local_.structure.started = TRUE; - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_V0033_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0033_ -- "STRUCTURE" SLASH NAME SLASH - - return ffestb_V0033_; // to lexer - - Handle NAME or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0033_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - return (ffelexHandler) ffestb_V0034_ (t); - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - ffestc_V003_finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0034_ -- "STRUCTURE" [SLASH NAME SLASH] - - return ffestb_V0034_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0034_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0035_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V003_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0035_ -- "STRUCTURE" ... NAME - - return ffestb_V0035_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_V0035_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_V0036_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDIMLISTCOMMON, (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_V003_item (ffesta_tokens[1], NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_V0034_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_V003_item (ffesta_tokens[1], NULL); - ffestc_V003_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V003_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0036_ -- "STRUCTURE" ... NAME OPEN_PAREN dimlist CLOSE_PAREN - - return ffestb_V0036_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0036_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.structure.started) - { - ffestc_V003_start (NULL); - ffestb_local_.structure.started = TRUE; - } - ffestc_V003_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_V0034_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - { - if (!ffestb_local_.structure.started) - ffestc_V003_start (NULL); - ffestc_V003_item (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_V003_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "STRUCTURE", t); - if (ffestb_local_.structure.started && !ffesta_is_inhibited ()) - ffestc_V003_finish (); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V016 -- Parse the RECORD statement - - return ffestb_V016; // to lexer - - Make sure the statement has a valid form for the RECORD statement. If it - does, implement the statement. */ - -ffelexHandler -ffestb_V016 (ffelexToken t) -{ - char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstRECORD) - goto bad_0; /* :::::::::::::::::::: */ - break; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstRECORD) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlRECORD); - if (*p != '\0') - goto bad_i; /* :::::::::::::::::::: */ - break; - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeSLASH: - break; - } - - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V016_start (); - return (ffelexHandler) ffestb_V0161_; - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "RECORD", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0161_ -- "RECORD" SLASH - - return ffestb_V0161_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0161_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (!ffesta_is_inhibited ()) - ffestc_V016_item_structure (t); - return (ffelexHandler) ffestb_V0162_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V016_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0162_ -- "RECORD" SLASH NAME - - return ffestb_V0162_; // to lexer - - Handle SLASH. */ - -static ffelexHandler -ffestb_V0162_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_V0163_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V016_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0163_ -- "RECORD" SLASH NAME SLASH - - return ffestb_V0163_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0163_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0164_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V016_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0164_ -- "RECORD" ... NAME - - return ffestb_V0164_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_V0164_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_subrargs_.dim_list.dims = ffestt_dimlist_create (); - ffestb_subrargs_.dim_list.handler = (ffelexHandler) ffestb_V0165_; - ffestb_subrargs_.dim_list.pool = ffesta_output_pool; - ffestb_subrargs_.dim_list.ctx = FFEEXPR_contextDIMLISTCOMMON; -#ifdef FFECOM_dimensionsMAX - ffestb_subrargs_.dim_list.ndims = 0; -#endif - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextDIMLISTCOMMON, (ffeexprCallback) ffestb_subr_dimlist_); - - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_V016_item_object (ffesta_tokens[1], NULL); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_V0166_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_V016_item_object (ffesta_tokens[1], NULL); - ffestc_V016_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V016_finish (); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0165_ -- "RECORD" ... NAME OPEN_PAREN dimlist CLOSE_PAREN - - return ffestb_V0165_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0165_ (ffelexToken t) -{ - if (!ffestb_subrargs_.dim_list.ok) - goto bad; /* :::::::::::::::::::: */ - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (!ffesta_is_inhibited ()) - ffestc_V016_item_object (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffestb_V0166_; - - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffesta_is_inhibited ()) - { - ffestc_V016_item_object (ffesta_tokens[1], - ffestb_subrargs_.dim_list.dims); - ffestc_V016_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - if (ffestb_local_.structure.started && !ffesta_is_inhibited ()) - ffestc_V016_finish (); - ffestt_dimlist_kill (ffestb_subrargs_.dim_list.dims); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0166_ -- "RECORD" SLASH NAME SLASH NAME [OPEN_PAREN dimlist - CLOSE_PAREN] COMMA - - return ffestb_V0166_; // to lexer - - Handle NAME or SLASH. */ - -static ffelexHandler -ffestb_V0166_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0164_; - - case FFELEX_typeSLASH: - return (ffelexHandler) ffestb_V0161_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "RECORD", t); - break; - } - - if (!ffesta_is_inhibited ()) - ffestc_V016_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_V027 -- Parse the VXT PARAMETER statement - - return ffestb_V027; // to lexer - - Make sure the statement has a valid form for the VXT PARAMETER statement. - If it does, implement the statement. */ - -ffelexHandler -ffestb_V027 (ffelexToken t) -{ - unsigned char *p; - ffeTokenLength i; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstPARAMETER) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - ffesta_confirmed (); - ffestb_local_.vxtparam.started = TRUE; - if (!ffesta_is_inhibited ()) - ffestc_V027_start (); - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0271_; - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstPARAMETER) - goto bad_0; /* :::::::::::::::::::: */ - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlPARAMETER); - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - if (!ffesrc_is_name_init (*p)) - goto bad_i; /* :::::::::::::::::::: */ - ffestb_local_.vxtparam.started = FALSE; - ffesta_tokens[1] = ffelex_token_name_from_names (ffesta_tokens[0], i, - 0); - return (ffelexHandler) ffestb_V0271_ (t); - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ - -bad_i: /* :::::::::::::::::::: */ - ffesta_ffebad_1sp (FFEBAD_INVALID_STMT_FORM, "PARAMETER", ffesta_tokens[0], i, t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0271_ -- "PARAMETER" NAME - - return ffestb_V0271_; // to lexer - - Handle EQUALS. */ - -static ffelexHandler -ffestb_V0271_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEQUALS: - return (ffelexHandler) ffeexpr_rhs (ffesta_output_pool, - FFEEXPR_contextPARAMETER, (ffeexprCallback) ffestb_V0272_); - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.vxtparam.started && !ffesta_is_inhibited ()) - ffestc_V027_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0272_ -- "PARAMETER" NAME EQUALS expr - - (ffestb_V0272_) // to expression handler - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_V0272_ (ffelexToken ft, ffebld expr, ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffestb_local_.vxtparam.started) - { - if (ffestc_is_let_not_V027 ()) - break; /* Not a valid VXTPARAMETER stmt. */ - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_V027_start (); - ffestb_local_.vxtparam.started = TRUE; - } - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - { - ffestc_V027_item (ffesta_tokens[1], expr, ft); - ffestc_V027_finish (); - } - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeCOMMA: - ffesta_confirmed (); - if (!ffestb_local_.vxtparam.started) - { - if (!ffesta_is_inhibited ()) - ffestc_V027_start (); - ffestb_local_.vxtparam.started = TRUE; - } - if (expr == NULL) - break; - if (!ffesta_is_inhibited ()) - ffestc_V027_item (ffesta_tokens[1], expr, ft); - ffelex_token_kill (ffesta_tokens[1]); - return (ffelexHandler) ffestb_V0273_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - if (ffestb_local_.vxtparam.started && !ffesta_is_inhibited ()) - ffestc_V027_finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_V0273_ -- "PARAMETER" NAME EQUALS expr COMMA - - return ffestb_V0273_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_V0273_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_V0271_; - - default: - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "PARAMETER", t); - break; - } - - if (ffestb_local_.vxtparam.started && !ffesta_is_inhibited ()) - ffestc_V027_finish (); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539 -- Parse the IMPLICIT FUNCTION statement - - return ffestb_decl_R539; // to lexer - - Make sure the statement has a valid form for the IMPLICIT - statement. If it does, implement the statement. */ - -ffelexHandler -ffestb_decl_R539 (ffelexToken t) -{ - ffeTokenLength i; - unsigned char *p; - ffelexToken nt; - ffestrSecond kw; - - ffestb_local_.decl.recursive = NULL; - - switch (ffelex_token_type (ffesta_tokens[0])) - { - case FFELEX_typeNAME: - if (ffesta_first_kw != FFESTR_firstIMPLICIT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - ffesta_confirmed (); /* Error, but clearly intended. */ - goto bad_1; /* :::::::::::::::::::: */ - - default: - goto bad_1; /* :::::::::::::::::::: */ - - case FFELEX_typeNAME: - break; - } - ffesta_confirmed (); - ffestb_local_.decl.imp_started = FALSE; - switch (ffesta_second_kw) - { - case FFESTR_secondINTEGER: - ffestb_local_.decl.type = FFESTP_typeINTEGER; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondBYTE: - ffestb_local_.decl.type = FFESTP_typeBYTE; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondWORD: - ffestb_local_.decl.type = FFESTP_typeWORD; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondREAL: - ffestb_local_.decl.type = FFESTP_typeREAL; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeCOMPLEX; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondLOGICAL: - ffestb_local_.decl.type = FFESTP_typeLOGICAL; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondCHARACTER: - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondDOUBLE: - return (ffelexHandler) ffestb_decl_R5392_; - - case FFESTR_secondDOUBLEPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_; - - case FFESTR_secondDOUBLECOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_; - - case FFESTR_secondNONE: - return (ffelexHandler) ffestb_decl_R5394_; - -#if FFESTR_F90 - case FFESTR_secondTYPE: - ffestb_local_.decl.type = FFESTP_typeTYPE; - return (ffelexHandler) ffestb_decl_R5393_; -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - case FFELEX_typeNAMES: - if (ffesta_first_kw != FFESTR_firstIMPLICIT) - goto bad_0; /* :::::::::::::::::::: */ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeCOLONCOLON: - case FFELEX_typeASTERISK: - case FFELEX_typeSEMICOLON: - case FFELEX_typeEOS: - ffesta_confirmed (); - break; - - case FFELEX_typeOPEN_PAREN: - break; - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - p = ffelex_token_text (ffesta_tokens[0]) + (i = FFESTR_firstlIMPLICIT); - if (!ffesrc_is_name_init (*p)) - goto bad_0; /* :::::::::::::::::::: */ - ffestb_local_.decl.imp_started = FALSE; - nt = ffelex_token_name_from_names (ffesta_tokens[0], - FFESTR_firstlIMPLICIT, 0); - kw = ffestr_second (nt); - ffelex_token_kill (nt); - switch (kw) - { - case FFESTR_secondINTEGER: - ffestb_local_.decl.type = FFESTP_typeINTEGER; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondBYTE: - ffestb_local_.decl.type = FFESTP_typeBYTE; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondWORD: - ffestb_local_.decl.type = FFESTP_typeWORD; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondREAL: - ffestb_local_.decl.type = FFESTP_typeREAL; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeCOMPLEX; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondLOGICAL: - ffestb_local_.decl.type = FFESTP_typeLOGICAL; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondCHARACTER: - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - return (ffelexHandler) ffestb_decl_R5391_ (t); - - case FFESTR_secondDOUBLEPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_ (t); - - case FFESTR_secondDOUBLECOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_ (t); - - case FFESTR_secondNONE: - return (ffelexHandler) ffestb_decl_R5394_ (t); - -#if FFESTR_F90 - case FFESTR_secondTYPE: - ffestb_local_.decl.type = FFESTP_typeTYPE; - return (ffelexHandler) ffestb_decl_R5393_ (t); -#endif - - default: - goto bad_1; /* :::::::::::::::::::: */ - } - - default: - goto bad_0; /* :::::::::::::::::::: */ - } - -bad_0: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", ffesta_tokens[0]); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); - -bad_1: /* :::::::::::::::::::: */ - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, - (ffelexHandler) ffesta_zero); /* Invalid second token. */ -} - -/* ffestb_decl_R5391_ -- "IMPLICIT" generic-type - - return ffestb_decl_R5391_; // to lexer - - Handle ASTERISK or OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_R5391_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeASTERISK: - ffesta_confirmed (); - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_R539letters_; - ffestb_local_.decl.badname = "IMPLICIT"; - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - return (ffelexHandler) ffestb_decl_starlen_; - return (ffelexHandler) ffestb_decl_starkind_; - - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_R539letters_; - ffestb_local_.decl.badname = "IMPLICIT"; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - if (ffestb_local_.decl.type == FFESTP_typeCHARACTER) - ffestb_local_.decl.imp_handler - = (ffelexHandler) ffestb_decl_typeparams_; - else - ffestb_local_.decl.imp_handler - = (ffelexHandler) ffestb_decl_kindparam_; - return (ffelexHandler) ffestb_decl_R539maybe_ (t); - - default: - break; - } - - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R5392_ -- "IMPLICIT" "DOUBLE" - - return ffestb_decl_R5392_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_R5392_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_second (t)) - { - case FFESTR_secondPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - break; - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - break; - - default: - goto bad; /* :::::::::::::::::::: */ - } - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_; - - default: - break; - } - -bad: /* :::::::::::::::::::: */ - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R5393_ -- "IMPLICIT" "TYPE" - - return ffestb_decl_R5393_; // to lexer - - Handle OPEN_PAREN. */ - -#if FFESTR_F90 -static ffelexHandler -ffestb_decl_R5393_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.handler = (ffelexHandler) ffestb_decl_R539letters_; - ffestb_local_.decl.badname = "IMPLICIT"; - return (ffelexHandler) ffestb_decl_typetype1_; - - default: - break; - } - - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -#endif -/* ffestb_decl_R5394_ -- "IMPLICIT" "NONE" - - return ffestb_decl_R5394_; // to lexer - - Handle EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_R5394_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R539 (); /* IMPLICIT NONE. */ - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R5395_ -- "IMPLICIT" implicit-spec-list COMMA - - return ffestb_decl_R5395_; // to lexer - - Handle NAME for next type-spec. */ - -static ffelexHandler -ffestb_decl_R5395_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - switch (ffestr_second (t)) - { - case FFESTR_secondINTEGER: - ffestb_local_.decl.type = FFESTP_typeINTEGER; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondBYTE: - ffestb_local_.decl.type = FFESTP_typeBYTE; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondWORD: - ffestb_local_.decl.type = FFESTP_typeWORD; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondREAL: - ffestb_local_.decl.type = FFESTP_typeREAL; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondCOMPLEX: - ffestb_local_.decl.type = FFESTP_typeCOMPLEX; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondLOGICAL: - ffestb_local_.decl.type = FFESTP_typeLOGICAL; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondCHARACTER: - ffestb_local_.decl.type = FFESTP_typeCHARACTER; - return (ffelexHandler) ffestb_decl_R5391_; - - case FFESTR_secondDOUBLE: - return (ffelexHandler) ffestb_decl_R5392_; - - case FFESTR_secondDOUBLEPRECISION: - ffestb_local_.decl.type = FFESTP_typeDBLPRCSN; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_; - - case FFESTR_secondDOUBLECOMPLEX: - ffestb_local_.decl.type = FFESTP_typeDBLCMPLX; - ffestb_local_.decl.kind = NULL; - ffestb_local_.decl.kindt = NULL; - ffestb_local_.decl.len = NULL; - ffestb_local_.decl.lent = NULL; - return (ffelexHandler) ffestb_decl_R539letters_; - -#if FFESTR_F90 - case FFESTR_secondTYPE: - ffestb_local_.decl.type = FFESTP_typeTYPE; - return (ffelexHandler) ffestb_decl_R5393_; -#endif - - default: - break; - } - break; - - default: - break; - } - - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_ -- "IMPLICIT" type-spec - - return ffestb_decl_R539letters_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_R539letters_ (ffelexToken t) -{ - ffelex_set_names (FALSE); - - switch (ffelex_token_type (t)) - { - case FFELEX_typeOPEN_PAREN: - ffestb_local_.decl.imps = ffestt_implist_create (); - return (ffelexHandler) ffestb_decl_R539letters_1_; - - default: - break; - } - - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_1_ -- "IMPLICIT" type-spec OPEN_PAREN - - return ffestb_decl_R539letters_1_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_R539letters_1_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (ffelex_token_length (t) != 1) - break; - ffesta_tokens[1] = ffelex_token_use (t); - return (ffelexHandler) ffestb_decl_R539letters_2_; - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_2_ -- "IMPLICIT" type-spec OPEN_PAREN NAME - - return ffestb_decl_R539letters_2_; // to lexer - - Handle COMMA or MINUS. */ - -static ffelexHandler -ffestb_decl_R539letters_2_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], NULL); - return (ffelexHandler) ffestb_decl_R539letters_1_; - - case FFELEX_typeCLOSE_PAREN: - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], NULL); - return (ffelexHandler) ffestb_decl_R539letters_5_; - - case FFELEX_typeMINUS: - return (ffelexHandler) ffestb_decl_R539letters_3_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_3_ -- "IMPLICIT" type-spec OPEN_PAREN NAME MINUS - - return ffestb_decl_R539letters_3_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_R539letters_3_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (ffelex_token_length (t) != 1) - break; - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], - ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539letters_4_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_4_ -- "IMPLICIT" type-spec OPEN_PAREN NAME MINUS - NAME - - return ffestb_decl_R539letters_4_; // to lexer - - Handle COMMA or CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_R539letters_4_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - return (ffelexHandler) ffestb_decl_R539letters_1_; - - case FFELEX_typeCLOSE_PAREN: - return (ffelexHandler) ffestb_decl_R539letters_5_; - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539letters_5_ -- "IMPLICIT" type-spec OPEN_PAREN - letter-spec-list CLOSE_PAREN - - return ffestb_decl_R539letters_5_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_R539letters_5_ (ffelexToken t) -{ - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - if (!ffestb_local_.decl.imp_started) - { - ffestb_local_.decl.imp_started = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R539start (); - } - if (!ffesta_is_inhibited ()) - ffestc_R539item (ffestb_local_.decl.type, ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_local_.decl.len, - ffestb_local_.decl.lent, ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_decl_R5395_; - if (!ffesta_is_inhibited ()) - ffestc_R539finish (); - return (ffelexHandler) ffesta_zero (t); - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} - -/* ffestb_decl_R539maybe_ -- "IMPLICIT" generic-type-spec - - return ffestb_decl_R539maybe_; // to lexer - - Handle OPEN_PAREN. */ - -static ffelexHandler -ffestb_decl_R539maybe_ (ffelexToken t) -{ - assert (ffelex_token_type (t) == FFELEX_typeOPEN_PAREN); - ffestb_local_.decl.imps = ffestt_implist_create (); - ffestb_local_.decl.toklist = ffestt_tokenlist_create (); - ffestb_local_.decl.imp_seen_comma - = (ffestb_local_.decl.type != FFESTP_typeCHARACTER); - return (ffelexHandler) ffestb_decl_R539maybe_1_; -} - -/* ffestb_decl_R539maybe_1_ -- "IMPLICIT" generic-type-spec OPEN_PAREN - - return ffestb_decl_R539maybe_1_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_R539maybe_1_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (ffelex_token_length (t) != 1) - break; - ffesta_tokens[1] = ffelex_token_use (t); - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_2_; - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_local_.decl.imp_handler); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_R539maybe_2_ -- "IMPLICIT" generic-type-spec OPEN_PAREN NAME - - return ffestb_decl_R539maybe_2_; // to lexer - - Handle COMMA or MINUS. */ - -static ffelexHandler -ffestb_decl_R539maybe_2_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], NULL); - if (ffestb_local_.decl.imp_seen_comma) - { - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) ffestb_decl_R539letters_1_; - } - ffestb_local_.decl.imp_seen_comma = TRUE; - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_1_; - - case FFELEX_typeCLOSE_PAREN: - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], NULL); - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_5_; - - case FFELEX_typeMINUS: - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_3_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffestt_implist_kill (ffestb_local_.decl.imps); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_local_.decl.imp_handler); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_R539maybe_3_ -- "IMPLICIT" type-spec OPEN_PAREN NAME MINUS - - return ffestb_decl_R539maybe_3_; // to lexer - - Handle NAME. */ - -static ffelexHandler -ffestb_decl_R539maybe_3_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeNAME: - if (ffelex_token_length (t) != 1) - break; - ffestt_implist_append (ffestb_local_.decl.imps, ffesta_tokens[1], - ffelex_token_use (t)); - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_4_; - - default: - break; - } - - ffelex_token_kill (ffesta_tokens[1]); - ffestt_implist_kill (ffestb_local_.decl.imps); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_local_.decl.imp_handler); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_R539maybe_4_ -- "IMPLICIT" type-spec OPEN_PAREN NAME MINUS - NAME - - return ffestb_decl_R539maybe_4_; // to lexer - - Handle COMMA or CLOSE_PAREN. */ - -static ffelexHandler -ffestb_decl_R539maybe_4_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - if (ffestb_local_.decl.imp_seen_comma) - { - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) ffestb_decl_R539letters_1_; - } - ffestb_local_.decl.imp_seen_comma = TRUE; - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_1_; - - case FFELEX_typeCLOSE_PAREN: - ffestt_tokenlist_append (ffestb_local_.decl.toklist, ffelex_token_use (t)); - return (ffelexHandler) ffestb_decl_R539maybe_5_; - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_local_.decl.imp_handler); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); -} - -/* ffestb_decl_R539maybe_5_ -- "IMPLICIT" type-spec OPEN_PAREN - letter-spec-list CLOSE_PAREN - - return ffestb_decl_R539maybe_5_; // to lexer - - Handle COMMA or EOS/SEMICOLON. */ - -static ffelexHandler -ffestb_decl_R539maybe_5_ (ffelexToken t) -{ - ffelexHandler next; - - switch (ffelex_token_type (t)) - { - case FFELEX_typeCOMMA: - case FFELEX_typeEOS: - case FFELEX_typeSEMICOLON: - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - if (!ffestb_local_.decl.imp_started) - { - ffestb_local_.decl.imp_started = TRUE; - ffesta_confirmed (); - if (!ffesta_is_inhibited ()) - ffestc_R539start (); - } - if (!ffesta_is_inhibited ()) - ffestc_R539item (ffestb_local_.decl.type, ffestb_local_.decl.kind, - ffestb_local_.decl.kindt, ffestb_local_.decl.len, - ffestb_local_.decl.lent, ffestb_local_.decl.imps); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - ffestt_implist_kill (ffestb_local_.decl.imps); - if (ffelex_token_type (t) == FFELEX_typeCOMMA) - return (ffelexHandler) ffestb_decl_R5395_; - if (!ffesta_is_inhibited ()) - ffestc_R539finish (); - return (ffelexHandler) ffesta_zero (t); - - case FFELEX_typeOPEN_PAREN: - ffesta_confirmed (); - ffestt_implist_kill (ffestb_local_.decl.imps); - next = (ffelexHandler) ffestt_tokenlist_handle (ffestb_local_.decl.toklist, - (ffelexHandler) ffestb_local_.decl.imp_handler); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - return (ffelexHandler) (*next) (t); - - default: - break; - } - - ffestt_implist_kill (ffestb_local_.decl.imps); - ffestt_tokenlist_kill (ffestb_local_.decl.toklist); - if (ffestb_local_.decl.kindt != NULL) - ffelex_token_kill (ffestb_local_.decl.kindt); - if (ffestb_local_.decl.lent != NULL) - ffelex_token_kill (ffestb_local_.decl.lent); - if (ffestb_local_.decl.imp_started && !ffesta_is_inhibited ()) - ffestc_R539finish (); - ffesta_ffebad_1st (FFEBAD_INVALID_STMT_FORM, "IMPLICIT", t); - return (ffelexHandler) ffelex_swallow_tokens (t, (ffelexHandler) ffesta_zero); -} diff --git a/gcc/f/stb.h b/gcc/f/stb.h deleted file mode 100755 index 7338bcf..0000000 --- a/gcc/f/stb.h +++ /dev/null @@ -1,253 +0,0 @@ -/* stb.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stb.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stb -#define _H_f_stb - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bad.h" -#include "expr.h" -#include "lex.h" -#include "stp.h" -#include "str.h" - -/* Structure definitions. */ - -struct _ffestb_args_ - { - struct - { - char *badname; - ffeTokenLength len; /* Length of "ENTRY/FUNCTION/SUBROUTINE". */ - bool is_subr; /* TRUE if SUBROUTINE or if ENTRY within - SUBROUTINE. */ - } - dummy; - struct - { - char *badname; - ffeTokenLength len; /* Length of - "BACKSPACE/ENDFILE/REWIND/UNLOCK". */ - } - beru; - struct - { - ffeTokenLength len; /* Length of keyword including "END". */ - ffestrSecond second; /* Second keyword. */ - } - endxyz; - struct - { - ffestrSecond second; /* Second keyword. */ - } - elsexyz; - struct - { - ffeTokenLength len; /* Length of "STOP/PAUSE". */ - } - halt; -#if FFESTR_F90 - struct - { - char *badname; - ffeTokenLength len; /* Length of "ALLOCATE/DEALLOCATE". */ - ffeexprContext ctx; /* Either ALLOCATE or DEALLOCATE. */ - } - heap; -#endif - struct - { - char *badname; - ffeTokenLength len; /* Length of - "EXTERNAL/INTENT/INTRINSIC/OPTIONAL/PUBLIC/ - PRIVATE". */ - } - varlist; -#if FFESTR_VXT - struct - { - char *badname; - ffeTokenLength len; /* Length of "ENCODE/DECODE". */ - } - vxtcode; -#endif -#if FFESTR_F90 - struct - { - char *badname; - ffeTokenLength len; /* Length of "ALLOCATABLE/POINTER/TARGET". */ - } - dimlist; -#endif - struct - { - char *badname; - ffeTokenLength len; /* Length of "DIMENSION/VIRTUAL". */ - } - R524; - struct - { - ffeTokenLength len; /* Length of first keyword. */ - ffestpType type; /* Type of declaration. */ - } - decl; - }; - -/* Global objects accessed by users of this module. */ - -extern struct _ffestb_args_ ffestb_args; - -/* Declare functions with prototypes. */ - -ffelexHandler ffestb_beru (ffelexToken t); -ffelexHandler ffestb_block (ffelexToken t); -ffelexHandler ffestb_blockdata (ffelexToken t); -ffelexHandler ffestb_decl_chartype (ffelexToken t); -ffelexHandler ffestb_construct (ffelexToken t); -ffelexHandler ffestb_decl_dbltype (ffelexToken t); -ffelexHandler ffestb_decl_double (ffelexToken t); -ffelexHandler ffestb_dimlist (ffelexToken t); -ffelexHandler ffestb_do (ffelexToken t); -ffelexHandler ffestb_dowhile (ffelexToken t); -ffelexHandler ffestb_dummy (ffelexToken t); -ffelexHandler ffestb_else (ffelexToken t); -ffelexHandler ffestb_elsexyz (ffelexToken t); -ffelexHandler ffestb_end (ffelexToken t); -ffelexHandler ffestb_endxyz (ffelexToken t); -ffelexHandler ffestb_decl_gentype (ffelexToken t); -ffelexHandler ffestb_goto (ffelexToken t); -ffelexHandler ffestb_halt (ffelexToken t); -#if FFESTR_F90 -ffelexHandler ffestb_heap (ffelexToken t); -#endif -ffelexHandler ffestb_if (ffelexToken t); -ffelexHandler ffestb_let (ffelexToken t); -#if FFESTR_F90 -ffelexHandler ffestb_module (ffelexToken t); -#endif -#if FFESTR_F90 -ffelexHandler ffestb_decl_recursive (ffelexToken t); -#endif -#if FFESTR_F90 -ffelexHandler ffestb_type (ffelexToken t); -#endif -#if FFESTR_F90 -ffelexHandler ffestb_decl_typetype (ffelexToken t); -#endif -ffelexHandler ffestb_varlist (ffelexToken t); -#if FFESTR_VXT -ffelexHandler ffestb_vxtcode (ffelexToken t); -#endif -#if FFESTR_F90 -ffelexHandler ffestb_where (ffelexToken t); -#endif -#if HARD_F90 -ffelexHandler ffestb_R423B (ffelexToken t); -#endif -ffelexHandler ffestb_R522 (ffelexToken t); -ffelexHandler ffestb_R524 (ffelexToken t); -ffelexHandler ffestb_R528 (ffelexToken t); -ffelexHandler ffestb_R537 (ffelexToken t); -ffelexHandler ffestb_decl_R539 (ffelexToken t); -ffelexHandler ffestb_R542 (ffelexToken t); -ffelexHandler ffestb_R544 (ffelexToken t); -ffelexHandler ffestb_R547 (ffelexToken t); -#if FFESTR_F90 -ffelexHandler ffestb_R624 (ffelexToken t); -#endif -ffelexHandler ffestb_R809 (ffelexToken t); -ffelexHandler ffestb_R810 (ffelexToken t); -ffelexHandler ffestb_R834 (ffelexToken t); -ffelexHandler ffestb_R835 (ffelexToken t); -ffelexHandler ffestb_R838 (ffelexToken t); -ffelexHandler ffestb_R840 (ffelexToken t); -ffelexHandler ffestb_R841 (ffelexToken t); -ffelexHandler ffestb_R904 (ffelexToken t); -ffelexHandler ffestb_R907 (ffelexToken t); -ffelexHandler ffestb_R909 (ffelexToken t); -ffelexHandler ffestb_R910 (ffelexToken t); -ffelexHandler ffestb_R911 (ffelexToken t); -ffelexHandler ffestb_R923 (ffelexToken t); -ffelexHandler ffestb_R1001 (ffelexToken t); -ffelexHandler ffestb_R1102 (ffelexToken t); -#if FFESTR_F90 -ffelexHandler ffestb_R1107 (ffelexToken t); -#endif -#if FFESTR_F90 -ffelexHandler ffestb_R1202 (ffelexToken t); -#endif -ffelexHandler ffestb_R1212 (ffelexToken t); -ffelexHandler ffestb_R1227 (ffelexToken t); -#if FFESTR_F90 -ffelexHandler ffestb_R1228 (ffelexToken t); -#endif -ffelexHandler ffestb_R1229 (ffelexToken t); -ffelexHandler ffestb_S3P4 (ffelexToken t); -#if FFESTR_VXT -ffelexHandler ffestb_V003 (ffelexToken t); -ffelexHandler ffestb_V009 (ffelexToken t); -ffelexHandler ffestb_V012 (ffelexToken t); -#endif -ffelexHandler ffestb_V014 (ffelexToken t); -#if FFESTR_VXT -ffelexHandler ffestb_V016 (ffelexToken t); -ffelexHandler ffestb_V018 (ffelexToken t); -ffelexHandler ffestb_V019 (ffelexToken t); -#endif -ffelexHandler ffestb_V020 (ffelexToken t); -#if FFESTR_VXT -ffelexHandler ffestb_V021 (ffelexToken t); -ffelexHandler ffestb_V025 (ffelexToken t); -ffelexHandler ffestb_V026 (ffelexToken t); -#endif -ffelexHandler ffestb_V027 (ffelexToken t); - -/* Define macros. */ - -#define ffestb_init_0() -#define ffestb_init_1() -#define ffestb_init_2() -#define ffestb_init_3() -#define ffestb_init_4() -#define ffestb_terminate_0() -#define ffestb_terminate_1() -#define ffestb_terminate_2() -#define ffestb_terminate_3() -#define ffestb_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stc.c b/gcc/f/stc.c deleted file mode 100755 index e720f9d..0000000 --- a/gcc/f/stc.c +++ /dev/null @@ -1,13898 +0,0 @@ -/* stc.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - st.c - - Description: - Verifies the proper semantics for statements, checking expressions already - semantically analyzed individually, collectively, checking label defs and - refs, and so on. Uses ffebad to indicate errors in semantics. - - In many cases, both a token and a keyword (ffestrFirst, ffestrSecond, - or ffestrOther) is provided. ONLY USE THE TOKEN as a pointer to the - source-code location for an error message or similar; use the keyword - as the semantic matching for the token, since the token's text might - not match the keyword's code. For example, INTENT(IN OUT) A in free - source form passes to ffestc_R519_start the token "IN" but the keyword - FFESTR_otherINOUT, and the latter is correct. - - Generally, either a single ffestc function handles an entire statement, - in which case its name is ffestc_xyz_, or more than one function is - needed, in which case its names are ffestc_xyz_start_, - ffestc_xyz_item_ or ffestc_xyz_item_abc_, and ffestc_xyz_finish_. - The caller must call _start_ before calling any _item_ functions, and - must call _finish_ afterwards. If it is clearly a syntactic matter as - to restrictions on the number and variety of _item_ calls, then the caller - should report any errors and ffestc_ should presume it has been taken - care of and handle any semantic problems with grace and no error messages. - If the permitted number and variety of _item_ calls has some basis in - semantics, then the caller should not generate any messages and ffestc - should do all the checking. - - A few ffestc functions have names rather than grammar numbers, like - ffestc_elsewhere and ffestc_end. These are cases where the actual - statement depends on its context rather than just its form; ELSE WHERE - may be the obvious (WHERE...ELSE WHERE...END WHERE) or something a little - more subtle (WHERE: IF THEN...ELSE WHERE...END IF WHERE). The actual - ffestc functions do exist and do work, but may or may not be invoked - by ffestb depending on whether some form of resolution is possible. - For example, ffestc_R1103 end-program-stmt is reachable directly when - END PROGRAM [name] is specified, or via ffestc_end when END is specified - and the context is a main program. So ffestc_xyz_ should make a quick - determination of the context and pick the appropriate ffestc_Nxyz_ - function to invoke, without a lot of ceremony. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stc.h" -#include "bad.h" -#include "bld.h" -#include "data.h" -#include "expr.h" -#include "global.h" -#include "implic.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#include "sta.h" -#include "std.h" -#include "stp.h" -#include "str.h" -#include "stt.h" -#include "stw.h" - -/* Externals defined here. */ - -ffeexprContext ffestc_iolist_context_ = FFEEXPR_contextIOLIST; -/* Valid only from READ/WRITE start to finish. */ - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFESTC_orderOK_, /* Statement ok in this context, process. */ - FFESTC_orderBAD_, /* Statement not ok in this context, don't - process. */ - FFESTC_orderBADOK_, /* Don't process but push block if - applicable. */ - FFESTC - } ffestcOrder_; - -typedef enum - { - FFESTC_stateletSIMPLE_, /* Expecting simple/start. */ - FFESTC_stateletATTRIB_, /* Expecting attrib/item/itemstart. */ - FFESTC_stateletITEM_, /* Expecting item/itemstart/finish. */ - FFESTC_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */ - FFESTC_ - } ffestcStatelet_; - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - -union ffestc_local_u_ - { - struct - { - ffebld initlist; /* For list of one sym in INTEGER I/3/ case. */ - ffetargetCharacterSize stmt_size; - ffetargetCharacterSize size; - ffeinfoBasictype basic_type; - ffeinfoKindtype stmt_kind_type; - ffeinfoKindtype kind_type; - bool per_var_kind_ok; - char is_R426; /* 1=R426, 2=R501. */ - } - decl; - struct - { - ffebld objlist; /* For list of target objects. */ - ffebldListBottom list_bottom; /* For building lists. */ - } - data; - struct - { - ffebldListBottom list_bottom; /* For building lists. */ - int entry_num; - } - dummy; - struct - { - ffesymbol symbol; /* NML symbol. */ - } - namelist; - struct - { - ffelexToken t; /* First token in list. */ - ffeequiv eq; /* Current equivalence being built up. */ - ffebld list; /* List of expressions in equivalence. */ - ffebldListBottom bottom; - bool ok; /* TRUE while current list still being - processed. */ - bool save; /* TRUE if any var in list is SAVEd. */ - } - equiv; - struct - { - ffesymbol symbol; /* BCB/NCB symbol. */ - } - common; - struct - { - ffesymbol symbol; /* SFN symbol. */ - } - sfunc; -#if FFESTR_VXT - struct - { - char list_state; /* 0=>no field names allowed, 1=>error - reported already, 2=>field names req'd, - 3=>have a field name. */ - } - V003; -#endif - }; /* Merge with the one in ffestc later. */ - -/* Static objects accessed by functions in this module. */ - -static bool ffestc_ok_; /* _start_ fn's send this to _xyz_ fn's. */ -static bool ffestc_parent_ok_; /* Parent sym for baby sym fn's ok. */ -static char ffestc_namelist_; /* 0=>not namelist, 1=>namelist, 2=>error. */ -static union ffestc_local_u_ ffestc_local_; -static ffestcStatelet_ ffestc_statelet_ = FFESTC_stateletSIMPLE_; -static ffestwShriek ffestc_shriek_after1_ = NULL; -static unsigned long ffestc_blocknum_ = 0; /* Next block# to assign. */ -static int ffestc_entry_num_; -static int ffestc_sfdummy_argno_; -static int ffestc_saved_entry_num_; -static ffelab ffestc_label_; - -/* Static functions (internal). */ - -static void ffestc_R544_equiv_ (ffebld expr, ffelexToken t); -static void ffestc_establish_declinfo_ (ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent); -static void ffestc_establish_declstmt_ (ffestpType type, ffelexToken typet, - ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent); -static void ffestc_establish_impletter_ (ffelexToken first, ffelexToken last); -static ffeinfoKindtype ffestc_kindtype_kind_ (ffeinfoBasictype bt, - ffetargetCharacterSize val); -static ffeinfoKindtype ffestc_kindtype_star_ (ffeinfoBasictype bt, - ffetargetCharacterSize val); -static void ffestc_labeldef_any_ (void); -static bool ffestc_labeldef_begin_ (void); -static void ffestc_labeldef_branch_begin_ (void); -static void ffestc_labeldef_branch_end_ (void); -static void ffestc_labeldef_endif_ (void); -static void ffestc_labeldef_format_ (void); -static void ffestc_labeldef_invalid_ (void); -static void ffestc_labeldef_notloop_ (void); -static void ffestc_labeldef_notloop_begin_ (void); -static void ffestc_labeldef_useless_ (void); -static bool ffestc_labelref_is_assignable_ (ffelexToken label_token, - ffelab *label); -static bool ffestc_labelref_is_branch_ (ffelexToken label_token, - ffelab *label); -static bool ffestc_labelref_is_format_ (ffelexToken label_token, - ffelab *label); -static bool ffestc_labelref_is_loopend_ (ffelexToken label_token, - ffelab *label); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_access_ (void); -#endif -static ffestcOrder_ ffestc_order_actiondo_ (void); -static ffestcOrder_ ffestc_order_actionif_ (void); -static ffestcOrder_ ffestc_order_actionwhere_ (void); -static void ffestc_order_any_ (void); -static void ffestc_order_bad_ (void); -static ffestcOrder_ ffestc_order_blockdata_ (void); -static ffestcOrder_ ffestc_order_blockspec_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_component_ (void); -#endif -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_contains_ (void); -#endif -static ffestcOrder_ ffestc_order_data_ (void); -static ffestcOrder_ ffestc_order_data77_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_derivedtype_ (void); -#endif -static ffestcOrder_ ffestc_order_do_ (void); -static ffestcOrder_ ffestc_order_entry_ (void); -static ffestcOrder_ ffestc_order_exec_ (void); -static ffestcOrder_ ffestc_order_format_ (void); -static ffestcOrder_ ffestc_order_function_ (void); -static ffestcOrder_ ffestc_order_iface_ (void); -static ffestcOrder_ ffestc_order_ifthen_ (void); -static ffestcOrder_ ffestc_order_implicit_ (void); -static ffestcOrder_ ffestc_order_implicitnone_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_interface_ (void); -#endif -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_map_ (void); -#endif -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_module_ (void); -#endif -static ffestcOrder_ ffestc_order_parameter_ (void); -static ffestcOrder_ ffestc_order_program_ (void); -static ffestcOrder_ ffestc_order_progspec_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_record_ (void); -#endif -static ffestcOrder_ ffestc_order_selectcase_ (void); -static ffestcOrder_ ffestc_order_sfunc_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_spec_ (void); -#endif -#if FFESTR_VXT -static ffestcOrder_ ffestc_order_structure_ (void); -#endif -static ffestcOrder_ ffestc_order_subroutine_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_type_ (void); -#endif -static ffestcOrder_ ffestc_order_typedecl_ (void); -#if FFESTR_VXT -static ffestcOrder_ ffestc_order_union_ (void); -#endif -static ffestcOrder_ ffestc_order_unit_ (void); -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_use_ (void); -#endif -#if FFESTR_VXT -static ffestcOrder_ ffestc_order_vxtstructure_ (void); -#endif -#if FFESTR_F90 -static ffestcOrder_ ffestc_order_where_ (void); -#endif -static void ffestc_promote_dummy_ (ffelexToken t); -static void ffestc_promote_execdummy_ (ffelexToken t); -static void ffestc_promote_sfdummy_ (ffelexToken t); -static void ffestc_shriek_begin_program_ (void); -#if FFESTR_F90 -static void ffestc_shriek_begin_uses_ (void); -#endif -static void ffestc_shriek_blockdata_ (bool ok); -static void ffestc_shriek_do_ (bool ok); -static void ffestc_shriek_end_program_ (bool ok); -#if FFESTR_F90 -static void ffestc_shriek_end_uses_ (bool ok); -#endif -static void ffestc_shriek_function_ (bool ok); -static void ffestc_shriek_if_ (bool ok); -static void ffestc_shriek_ifthen_ (bool ok); -#if FFESTR_F90 -static void ffestc_shriek_interface_ (bool ok); -#endif -#if FFESTR_F90 -static void ffestc_shriek_map_ (bool ok); -#endif -#if FFESTR_F90 -static void ffestc_shriek_module_ (bool ok); -#endif -static void ffestc_shriek_select_ (bool ok); -#if FFESTR_VXT -static void ffestc_shriek_structure_ (bool ok); -#endif -static void ffestc_shriek_subroutine_ (bool ok); -#if FFESTR_F90 -static void ffestc_shriek_type_ (bool ok); -#endif -#if FFESTR_VXT -static void ffestc_shriek_union_ (bool ok); -#endif -#if FFESTR_F90 -static void ffestc_shriek_where_ (bool ok); -#endif -#if FFESTR_F90 -static void ffestc_shriek_wherethen_ (bool ok); -#endif -static int ffestc_subr_binsrch_ (char **list, int size, ffestpFile *spec, - char *whine); -static ffestvFormat ffestc_subr_format_ (ffestpFile *spec); -static bool ffestc_subr_is_branch_ (ffestpFile *spec); -static bool ffestc_subr_is_format_ (ffestpFile *spec); -static bool ffestc_subr_is_present_ (char *name, ffestpFile *spec); -static int ffestc_subr_speccmp_ (char *string, ffestpFile *spec, - char **target, int *length); -static ffestvUnit ffestc_subr_unit_ (ffestpFile *spec); -static void ffestc_try_shriek_do_ (void); - -/* Internal macros. */ - -#define ffestc_check_simple_() \ - assert(ffestc_statelet_ == FFESTC_stateletSIMPLE_) -#define ffestc_check_start_() \ - assert(ffestc_statelet_ == FFESTC_stateletSIMPLE_); \ - ffestc_statelet_ = FFESTC_stateletATTRIB_ -#define ffestc_check_attrib_() \ - assert(ffestc_statelet_ == FFESTC_stateletATTRIB_) -#define ffestc_check_item_() \ - assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ - || ffestc_statelet_ == FFESTC_stateletITEM_); \ - ffestc_statelet_ = FFESTC_stateletITEM_ -#define ffestc_check_item_startvals_() \ - assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ - || ffestc_statelet_ == FFESTC_stateletITEM_); \ - ffestc_statelet_ = FFESTC_stateletITEMVALS_ -#define ffestc_check_item_value_() \ - assert(ffestc_statelet_ == FFESTC_stateletITEMVALS_) -#define ffestc_check_item_endvals_() \ - assert(ffestc_statelet_ == FFESTC_stateletITEMVALS_); \ - ffestc_statelet_ = FFESTC_stateletITEM_ -#define ffestc_check_finish_() \ - assert(ffestc_statelet_ == FFESTC_stateletATTRIB_ \ - || ffestc_statelet_ == FFESTC_stateletITEM_); \ - ffestc_statelet_ = FFESTC_stateletSIMPLE_ -#define ffestc_order_action_() ffestc_order_exec_() -#if FFESTR_F90 -#define ffestc_order_interfacespec_() ffestc_order_derivedtype_() -#endif -#define ffestc_shriek_if_lost_ ffestc_shriek_if_ -#if FFESTR_F90 -#define ffestc_shriek_where_lost_ ffestc_shriek_where_ -#endif - -/* ffestc_establish_declinfo_ -- Determine specific type/params info for entity - - ffestc_establish_declinfo_(kind,kind_token,len,len_token); - - Must be called after _declstmt_ called to establish base type. */ - -static void -ffestc_establish_declinfo_ (ffebld kind, ffelexToken kindt, ffebld len, - ffelexToken lent) -{ - ffeinfoBasictype bt = ffestc_local_.decl.basic_type; - ffeinfoKindtype kt; - ffetargetCharacterSize val; - - if (kindt == NULL) - kt = ffestc_local_.decl.stmt_kind_type; - else if (!ffestc_local_.decl.per_var_kind_ok) - { - ffebad_start (FFEBAD_KINDTYPE); - ffebad_here (0, ffelex_token_where_line (kindt), - ffelex_token_where_column (kindt)); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - kt = ffestc_local_.decl.stmt_kind_type; - } - else - { - if (kind == NULL) - { - assert (ffelex_token_type (kindt) == FFELEX_typeNUMBER); - val = atol (ffelex_token_text (kindt)); - kt = ffestc_kindtype_star_ (bt, val); - } - else if (ffebld_op (kind) == FFEBLD_opANY) - kt = ffestc_local_.decl.stmt_kind_type; - else - { - assert (ffebld_op (kind) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (kind)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (kind)) - == FFEINFO_kindtypeINTEGERDEFAULT); - val = ffebld_constant_integerdefault (ffebld_conter (kind)); - kt = ffestc_kindtype_kind_ (bt, val); - } - - if (kt == FFEINFO_kindtypeNONE) - { /* Not valid kind type. */ - ffebad_start (FFEBAD_KINDTYPE); - ffebad_here (0, ffelex_token_where_line (kindt), - ffelex_token_where_column (kindt)); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - kt = ffestc_local_.decl.stmt_kind_type; - } - } - - ffestc_local_.decl.kind_type = kt; - - /* Now check length specification for CHARACTER data type. */ - - if (((len == NULL) && (lent == NULL)) - || (bt != FFEINFO_basictypeCHARACTER)) - val = ffestc_local_.decl.stmt_size; - else - { - if (len == NULL) - { - assert (ffelex_token_type (lent) == FFELEX_typeNUMBER); - val = atol (ffelex_token_text (lent)); - } - else if (ffebld_op (len) == FFEBLD_opSTAR) - val = FFETARGET_charactersizeNONE; - else if (ffebld_op (len) == FFEBLD_opANY) - val = FFETARGET_charactersizeNONE; - else - { - assert (ffebld_op (len) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (len)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (len)) - == FFEINFO_kindtypeINTEGERDEFAULT); - val = ffebld_constant_integerdefault (ffebld_conter (len)); - } - } - - if ((val == 0) && !(0 && ffe_is_90 ())) - { - val = 1; - ffebad_start (FFEBAD_ZERO_SIZE); - ffebad_here (0, ffelex_token_where_line (lent), ffelex_token_where_column (lent)); - ffebad_finish (); - } - ffestc_local_.decl.size = val; -} - -/* ffestc_establish_declstmt_ -- Establish host-specific type/params info - - ffestc_establish_declstmt_(type,type_token,kind,kind_token,len, - len_token); */ - -static void -ffestc_establish_declstmt_ (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent) -{ - ffeinfoBasictype bt; - ffeinfoKindtype ktd; /* Default kindtype. */ - ffeinfoKindtype kt; - ffetargetCharacterSize val; - bool per_var_kind_ok = TRUE; - - /* Determine basictype and default kindtype. */ - - switch (type) - { - case FFESTP_typeINTEGER: - bt = FFEINFO_basictypeINTEGER; - ktd = FFEINFO_kindtypeINTEGERDEFAULT; - break; - - case FFESTP_typeBYTE: - bt = FFEINFO_basictypeINTEGER; - ktd = FFEINFO_kindtypeINTEGER2; - break; - - case FFESTP_typeWORD: - bt = FFEINFO_basictypeINTEGER; - ktd = FFEINFO_kindtypeINTEGER3; - break; - - case FFESTP_typeREAL: - bt = FFEINFO_basictypeREAL; - ktd = FFEINFO_kindtypeREALDEFAULT; - break; - - case FFESTP_typeCOMPLEX: - bt = FFEINFO_basictypeCOMPLEX; - ktd = FFEINFO_kindtypeREALDEFAULT; - break; - - case FFESTP_typeLOGICAL: - bt = FFEINFO_basictypeLOGICAL; - ktd = FFEINFO_kindtypeLOGICALDEFAULT; - break; - - case FFESTP_typeCHARACTER: - bt = FFEINFO_basictypeCHARACTER; - ktd = FFEINFO_kindtypeCHARACTERDEFAULT; - break; - - case FFESTP_typeDBLPRCSN: - bt = FFEINFO_basictypeREAL; - ktd = FFEINFO_kindtypeREALDOUBLE; - per_var_kind_ok = FALSE; - break; - - case FFESTP_typeDBLCMPLX: - bt = FFEINFO_basictypeCOMPLEX; -#if FFETARGET_okCOMPLEX2 - ktd = FFEINFO_kindtypeREALDOUBLE; -#else - ktd = FFEINFO_kindtypeREALDEFAULT; - ffebad_start (FFEBAD_BAD_DBLCMPLX); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); -#endif - per_var_kind_ok = FALSE; - break; - - default: - assert ("Unexpected type (F90 TYPE?)!" == NULL); - bt = FFEINFO_basictypeNONE; - ktd = FFEINFO_kindtypeNONE; - break; - } - - if (kindt == NULL) - kt = ktd; - else - { /* Not necessarily default kind type. */ - if (kind == NULL) - { /* Shouldn't happen for CHARACTER. */ - assert (ffelex_token_type (kindt) == FFELEX_typeNUMBER); - val = atol (ffelex_token_text (kindt)); - kt = ffestc_kindtype_star_ (bt, val); - } - else if (ffebld_op (kind) == FFEBLD_opANY) - kt = ktd; - else - { - assert (ffebld_op (kind) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (kind)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (kind)) - == FFEINFO_kindtypeINTEGERDEFAULT); - val = ffebld_constant_integerdefault (ffebld_conter (kind)); - kt = ffestc_kindtype_kind_ (bt, val); - } - - if (kt == FFEINFO_kindtypeNONE) - { /* Not valid kind type. */ - ffebad_start (FFEBAD_KINDTYPE); - ffebad_here (0, ffelex_token_where_line (kindt), - ffelex_token_where_column (kindt)); - ffebad_here (1, ffelex_token_where_line (typet), - ffelex_token_where_column (typet)); - ffebad_finish (); - kt = ktd; - } - } - - ffestc_local_.decl.basic_type = bt; - ffestc_local_.decl.stmt_kind_type = kt; - ffestc_local_.decl.per_var_kind_ok = per_var_kind_ok; - - /* Now check length specification for CHARACTER data type. */ - - if (((len == NULL) && (lent == NULL)) - || (type != FFESTP_typeCHARACTER)) - val = (type == FFESTP_typeCHARACTER) ? 1 : FFETARGET_charactersizeNONE; - else - { - if (len == NULL) - { - assert (ffelex_token_type (lent) == FFELEX_typeNUMBER); - val = atol (ffelex_token_text (lent)); - } - else if (ffebld_op (len) == FFEBLD_opSTAR) - val = FFETARGET_charactersizeNONE; - else if (ffebld_op (len) == FFEBLD_opANY) - val = FFETARGET_charactersizeNONE; - else - { - assert (ffebld_op (len) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (len)) - == FFEINFO_basictypeINTEGER); - assert (ffeinfo_kindtype (ffebld_info (len)) - == FFEINFO_kindtypeINTEGERDEFAULT); - val = ffebld_constant_integerdefault (ffebld_conter (len)); - } - } - - if ((val == 0) && !(0 && ffe_is_90 ())) - { - val = 1; - ffebad_start (FFEBAD_ZERO_SIZE); - ffebad_here (0, ffelex_token_where_line (lent), ffelex_token_where_column (lent)); - ffebad_finish (); - } - ffestc_local_.decl.stmt_size = val; -} - -/* ffestc_establish_impletter_ -- Establish type/params for IMPLICIT letter(s) - - ffestc_establish_impletter_(first_letter_token,last_letter_token); */ - -static void -ffestc_establish_impletter_ (ffelexToken first, ffelexToken last) -{ - bool ok = FALSE; /* Stays FALSE if first letter > last. */ - char c; - - if (last == NULL) - ok = ffeimplic_establish_initial (c = *(ffelex_token_text (first)), - ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - ffestc_local_.decl.size); - else - { - for (c = *(ffelex_token_text (first)); - c <= *(ffelex_token_text (last)); - c++) - { - ok = ffeimplic_establish_initial (c, - ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - ffestc_local_.decl.size); - if (!ok) - break; - } - } - - if (!ok) - { - char cs[2]; - - cs[0] = c; - cs[1] = '\0'; - - ffebad_start (FFEBAD_BAD_IMPLICIT); - ffebad_here (0, ffelex_token_where_line (first), ffelex_token_where_column (first)); - ffebad_string (cs); - ffebad_finish (); - } -} - -/* ffestc_init_3 -- Initialize ffestc for new program unit - - ffestc_init_3(); */ - -void -ffestc_init_3 () -{ - ffestv_save_state_ = FFESTV_savestateNONE; - ffestc_entry_num_ = 0; - ffestv_num_label_defines_ = 0; -} - -/* ffestc_init_4 -- Initialize ffestc for new scoping unit - - ffestc_init_4(); - - For SUBROUTINEs/FUNCTIONs within INTERFACE/END INTERFACE, derived-TYPE- - defs, and statement function defs. */ - -void -ffestc_init_4 () -{ - ffestc_saved_entry_num_ = ffestc_entry_num_; - ffestc_entry_num_ = 0; -} - -/* ffestc_kindtype_kind_ -- Determine kindtype from basictype and KIND= value - - ffeinfoKindtype kt; - ffeinfoBasictype bt; - ffetargetCharacterSize val; - kt = ffestc_kindtype_kind_(bt,val); - if (kt == FFEINFO_kindtypeNONE) - // unsupported/invalid KIND= value for type */ - -static ffeinfoKindtype -ffestc_kindtype_kind_ (ffeinfoBasictype bt, ffetargetCharacterSize val) -{ - ffetype type; - ffetype base_type; - ffeinfoKindtype kt; - - base_type = ffeinfo_type (bt, 1); /* ~~ */ - assert (base_type != NULL); - - type = ffetype_lookup_kind (base_type, (int) val); - if (type == NULL) - return FFEINFO_kindtypeNONE; - - for (kt = 1; kt < FFEINFO_kindtype; ++kt) - if (ffeinfo_type (bt, kt) == type) - return kt; - - return FFEINFO_kindtypeNONE; -} - -/* ffestc_kindtype_star_ -- Determine kindtype from basictype and * value - - ffeinfoKindtype kt; - ffeinfoBasictype bt; - ffetargetCharacterSize val; - kt = ffestc_kindtype_star_(bt,val); - if (kt == FFEINFO_kindtypeNONE) - // unsupported/invalid * value for type */ - -static ffeinfoKindtype -ffestc_kindtype_star_ (ffeinfoBasictype bt, ffetargetCharacterSize val) -{ - ffetype type; - ffetype base_type; - ffeinfoKindtype kt; - - base_type = ffeinfo_type (bt, 1); /* ~~ */ - assert (base_type != NULL); - - type = ffetype_lookup_star (base_type, (int) val); - if (type == NULL) - return FFEINFO_kindtypeNONE; - - for (kt = 1; kt < FFEINFO_kindtype; ++kt) - if (ffeinfo_type (bt, kt) == type) - return kt; - - return FFEINFO_kindtypeNONE; -} - -/* Define label as usable for anything without complaint. */ - -static void -ffestc_labeldef_any_ () -{ - if ((ffesta_label_token == NULL) - || !ffestc_labeldef_begin_ ()) - return; - - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_labeldef_begin_ -- Define label as unknown, initially - - ffestc_labeldef_begin_(); */ - -static bool -ffestc_labeldef_begin_ () -{ - ffelabValue label_value; - ffelab label; - - label_value = (ffelabValue) atol (ffelex_token_text (ffesta_label_token)); - if ((label_value == 0) || (label_value > FFELAB_valueMAX)) - { - ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - } - - label = ffelab_find (label_value); - if (label == NULL) - { - label = ffestc_label_ = ffelab_new (label_value); - ffestv_num_label_defines_++; - ffelab_set_definition_line (label, - ffewhere_line_use (ffelex_token_where_line (ffesta_label_token))); - ffelab_set_definition_column (label, - ffewhere_column_use (ffelex_token_where_column (ffesta_label_token))); - - return TRUE; - } - - if (ffewhere_line_is_unknown (ffelab_definition_line (label))) - { - ffestv_num_label_defines_++; - ffestc_label_ = label; - ffelab_set_definition_line (label, - ffewhere_line_use (ffelex_token_where_line (ffesta_label_token))); - ffelab_set_definition_column (label, - ffewhere_column_use (ffelex_token_where_column (ffesta_label_token))); - - return TRUE; - } - - ffebad_start (FFEBAD_LABEL_ALREADY_DEFINED); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_definition_line (label), - ffelab_definition_column (label)); - ffebad_string (ffelex_token_text (ffesta_label_token)); - ffebad_finish (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; - return FALSE; -} - -/* ffestc_labeldef_branch_begin_ -- Define label as a branch target one - - ffestc_labeldef_branch_begin_(); */ - -static void -ffestc_labeldef_branch_begin_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL) - || !ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_branch (ffestc_label_); - break; - - case FFELAB_typeNOTLOOP: - if (ffelab_blocknum (ffestc_label_) - < ffestw_blocknum (ffestw_stack_top ())) - { - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - } - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_branch (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffestd_labeldef_branch (ffestc_label_); - /* Leave something around for _branch_end_() to handle. */ - return; - - case FFELAB_typeFORMAT: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* Define possible end of labeled-DO-loop. Call only after calling - ffestc_labeldef_branch_begin_, or when other branch_* functions - recognize that a label might also be serving as a branch end (in - which case they must issue a diagnostic). */ - -static void -ffestc_labeldef_branch_end_ () -{ - if (ffesta_label_token == NULL) - return; - - assert (ffestc_label_ != NULL); - assert ((ffelab_type (ffestc_label_) == FFELAB_typeLOOPEND) - || (ffelab_type (ffestc_label_) == FFELAB_typeANY)); - - while ((ffestw_state (ffestw_stack_top ()) == FFESTV_stateDO) - && (ffestw_label (ffestw_stack_top ()) == ffestc_label_)) - ffestc_shriek_do_ (TRUE); - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* ffestc_labeldef_endif_ -- Define label as an END IF one - - ffestc_labeldef_endif_(); */ - -static void -ffestc_labeldef_endif_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL) - || !ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (ffestc_label_, FFELAB_typeENDIF); - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))); - ffestd_labeldef_endif (ffestc_label_); - break; - - case FFELAB_typeNOTLOOP: - if (ffelab_blocknum (ffestc_label_) - < ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))) - { - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - } - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_previous (ffestw_stack_top ()))); - ffestd_labeldef_endif (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffestd_labeldef_endif (ffestc_label_); - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_finish (); - ffestc_labeldef_branch_end_ (); - return; - - case FFELAB_typeFORMAT: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* ffestc_labeldef_format_ -- Define label as a FORMAT one - - ffestc_labeldef_format_(); */ - -static void -ffestc_labeldef_format_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL)) - { - ffebad_start (FFEBAD_FORMAT_NO_LABEL_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - return; - } - - if (!ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (ffestc_label_, FFELAB_typeFORMAT); - ffestd_labeldef_format (ffestc_label_); - break; - - case FFELAB_typeFORMAT: - ffestd_labeldef_format (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffestd_labeldef_format (ffestc_label_); - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_finish (); - ffestc_labeldef_branch_end_ (); - return; - - case FFELAB_typeNOTLOOP: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* ffestc_labeldef_invalid_ -- Label definition invalid, complain if present - - ffestc_labeldef_invalid_(); */ - -static void -ffestc_labeldef_invalid_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL) - || !ffestc_labeldef_begin_ ()) - return; - - ffebad_start (FFEBAD_INVALID_LABEL_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* Define label as a non-loop-ending one on a statement that can't - be in the "then" part of a logical IF, such as a block-IF statement. */ - -static void -ffestc_labeldef_notloop_ () -{ - if (ffesta_label_token == NULL) - return; - - assert (ffestc_shriek_after1_ == NULL); - - if (!ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (ffestc_label_); - break; - - case FFELAB_typeNOTLOOP: - if (ffelab_blocknum (ffestc_label_) - < ffestw_blocknum (ffestw_stack_top ())) - { - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - } - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffestd_labeldef_notloop (ffestc_label_); - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_finish (); - ffestc_labeldef_branch_end_ (); - return; - - case FFELAB_typeFORMAT: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* Define label as a non-loop-ending one. Use this when it is - possible that the pending label is inhibited because we're in - the midst of a logical-IF, and thus _branch_end_ is going to - be called after the current statement to resolve a potential - loop-ending label. */ - -static void -ffestc_labeldef_notloop_begin_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL) - || !ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (ffestc_label_, FFELAB_typeNOTLOOP); - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (ffestc_label_); - break; - - case FFELAB_typeNOTLOOP: - if (ffelab_blocknum (ffestc_label_) - < ffestw_blocknum (ffestw_stack_top ())) - { - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - } - ffelab_set_blocknum (ffestc_label_, - ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffestd_labeldef_branch (ffestc_label_); - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_finish (); - return; - - case FFELAB_typeFORMAT: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* ffestc_labeldef_useless_ -- Define label as a useless one - - ffestc_labeldef_useless_(); */ - -static void -ffestc_labeldef_useless_ () -{ - if ((ffesta_label_token == NULL) - || (ffestc_shriek_after1_ != NULL) - || !ffestc_labeldef_begin_ ()) - return; - - switch (ffelab_type (ffestc_label_)) - { - case FFELAB_typeUNKNOWN: - ffelab_set_type (ffestc_label_, FFELAB_typeUSELESS); - ffestd_labeldef_useless (ffestc_label_); - break; - - case FFELAB_typeLOOPEND: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != ffestc_label_)) - { /* Unterminated block. */ - ffebad_start (FFEBAD_LABEL_DO_BLOCK_END); - ffebad_here (0, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_finish (); - break; - } - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_doref_line (ffestc_label_), - ffelab_doref_column (ffestc_label_)); - ffebad_finish (); - ffestc_labeldef_branch_end_ (); - return; - - case FFELAB_typeASSIGNABLE: - case FFELAB_typeFORMAT: - case FFELAB_typeNOTLOOP: - ffelab_set_type (ffestc_label_, FFELAB_typeANY); - ffestd_labeldef_any (ffestc_label_); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelex_token_where_line (ffesta_label_token), - ffelex_token_where_column (ffesta_label_token)); - ffebad_here (1, ffelab_firstref_line (ffestc_label_), - ffelab_firstref_column (ffestc_label_)); - ffebad_finish (); - break; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - ffelex_token_kill (ffesta_label_token); - ffesta_label_token = NULL; -} - -/* ffestc_labelref_is_assignable_ -- Reference to label in ASSIGN stmt - - if (ffestc_labelref_is_assignable_(label_token,&label)) - // label ref is ok, label is filled in with ffelab object */ - -static bool -ffestc_labelref_is_assignable_ (ffelexToken label_token, ffelab *x_label) -{ - ffelab label; - ffelabValue label_value; - - label_value = (ffelabValue) atol (ffelex_token_text (label_token)); - if ((label_value == 0) || (label_value > FFELAB_valueMAX)) - { - ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); - ffebad_here (0, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - return FALSE; - } - - label = ffelab_find (label_value); - if (label == NULL) - { - label = ffelab_new (label_value); - ffelab_set_firstref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_firstref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - } - - switch (ffelab_type (label)) - { - case FFELAB_typeUNKNOWN: - ffelab_set_type (label, FFELAB_typeASSIGNABLE); - break; - - case FFELAB_typeASSIGNABLE: - case FFELAB_typeLOOPEND: - case FFELAB_typeFORMAT: - case FFELAB_typeNOTLOOP: - case FFELAB_typeENDIF: - break; - - case FFELAB_typeUSELESS: - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - *x_label = label; - return TRUE; -} - -/* ffestc_labelref_is_branch_ -- Reference to label in branch stmt - - if (ffestc_labelref_is_branch_(label_token,&label)) - // label ref is ok, label is filled in with ffelab object */ - -static bool -ffestc_labelref_is_branch_ (ffelexToken label_token, ffelab *x_label) -{ - ffelab label; - ffelabValue label_value; - ffestw block; - unsigned long blocknum; - - label_value = (ffelabValue) atol (ffelex_token_text (label_token)); - if ((label_value == 0) || (label_value > FFELAB_valueMAX)) - { - ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); - ffebad_here (0, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - return FALSE; - } - - label = ffelab_find (label_value); - if (label == NULL) - { - label = ffelab_new (label_value); - ffelab_set_firstref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_firstref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - } - - switch (ffelab_type (label)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (label, FFELAB_typeNOTLOOP); - ffelab_set_blocknum (label, ffestw_blocknum (ffestw_stack_top ())); - break; - - case FFELAB_typeLOOPEND: - if (ffelab_blocknum (label) != 0) - break; /* Already taken care of. */ - for (block = ffestw_top_do (ffestw_stack_top ()); - (block != NULL) && (ffestw_label (block) != label); - block = ffestw_top_do (ffestw_previous (block))) - ; /* Find most recent DO <label> ancestor. */ - if (block == NULL) - { /* Reference to within a (dead) block. */ - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelab_definition_line (label), - ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - break; - } - ffelab_set_blocknum (label, ffestw_blocknum (block)); - ffelab_set_firstref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_firstref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - break; - - case FFELAB_typeNOTLOOP: - case FFELAB_typeENDIF: - if (ffelab_blocknum (label) == ffestw_blocknum (ffestw_stack_top ())) - break; - blocknum = ffelab_blocknum (label); - for (block = ffestw_stack_top (); - ffestw_blocknum (block) > blocknum; - block = ffestw_previous (block)) - ; /* Find most recent common ancestor. */ - if (ffelab_blocknum (label) == ffestw_blocknum (block)) - break; /* Check again. */ - if (!ffewhere_line_is_unknown (ffelab_definition_line (label))) - { /* Reference to within a (dead) block. */ - ffebad_start (FFEBAD_LABEL_BLOCK); - ffebad_here (0, ffelab_definition_line (label), - ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - break; - } - ffelab_set_blocknum (label, ffestw_blocknum (block)); - break; - - case FFELAB_typeFORMAT: - if (ffewhere_line_is_unknown (ffelab_definition_line (label))) - { - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_USE); - ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - /* Fall through. */ - case FFELAB_typeUSELESS: - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - *x_label = label; - return TRUE; -} - -/* ffestc_labelref_is_format_ -- Reference to label in [FMT=] specification - - if (ffestc_labelref_is_format_(label_token,&label)) - // label ref is ok, label is filled in with ffelab object */ - -static bool -ffestc_labelref_is_format_ (ffelexToken label_token, ffelab *x_label) -{ - ffelab label; - ffelabValue label_value; - - label_value = (ffelabValue) atol (ffelex_token_text (label_token)); - if ((label_value == 0) || (label_value > FFELAB_valueMAX)) - { - ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); - ffebad_here (0, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - return FALSE; - } - - label = ffelab_find (label_value); - if (label == NULL) - { - label = ffelab_new (label_value); - ffelab_set_firstref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_firstref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - } - - switch (ffelab_type (label)) - { - case FFELAB_typeUNKNOWN: - case FFELAB_typeASSIGNABLE: - ffelab_set_type (label, FFELAB_typeFORMAT); - break; - - case FFELAB_typeFORMAT: - break; - - case FFELAB_typeLOOPEND: - case FFELAB_typeNOTLOOP: - if (ffewhere_line_is_unknown (ffelab_definition_line (label))) - { - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_USE); - ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - /* Fall through. */ - case FFELAB_typeUSELESS: - case FFELAB_typeENDIF: - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - ffestc_try_shriek_do_ (); - - *x_label = label; - return TRUE; -} - -/* ffestc_labelref_is_loopend_ -- Reference to label in DO stmt - - if (ffestc_labelref_is_loopend_(label_token,&label)) - // label ref is ok, label is filled in with ffelab object */ - -static bool -ffestc_labelref_is_loopend_ (ffelexToken label_token, ffelab *x_label) -{ - ffelab label; - ffelabValue label_value; - - label_value = (ffelabValue) atol (ffelex_token_text (label_token)); - if ((label_value == 0) || (label_value > FFELAB_valueMAX)) - { - ffebad_start (FFEBAD_LABEL_NUMBER_INVALID); - ffebad_here (0, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - return FALSE; - } - - label = ffelab_find (label_value); - if (label == NULL) - { - label = ffelab_new (label_value); - ffelab_set_doref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_doref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - } - - switch (ffelab_type (label)) - { - case FFELAB_typeASSIGNABLE: - ffelab_set_doref_line (label, - ffewhere_line_use (ffelex_token_where_line (label_token))); - ffelab_set_doref_column (label, - ffewhere_column_use (ffelex_token_where_column (label_token))); - ffewhere_line_kill (ffelab_firstref_line (label)); - ffelab_set_firstref_line (label, ffewhere_line_unknown ()); - ffewhere_column_kill (ffelab_firstref_column (label)); - ffelab_set_firstref_column (label, ffewhere_column_unknown ()); - /* Fall through. */ - case FFELAB_typeUNKNOWN: - ffelab_set_type (label, FFELAB_typeLOOPEND); - ffelab_set_blocknum (label, 0); - break; - - case FFELAB_typeLOOPEND: - if (!ffewhere_line_is_unknown (ffelab_definition_line (label))) - { /* Def must follow all refs. */ - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_DEF_DO); - ffebad_here (0, ffelab_definition_line (label), - ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - if (ffelab_blocknum (label) != 0) - { /* Had a branch ref earlier, can't go inside - this new block! */ - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_USE); - ffebad_here (0, ffelab_firstref_line (label), - ffelab_firstref_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - if ((ffestw_state (ffestw_stack_top ()) != FFESTV_stateDO) - || (ffestw_label (ffestw_stack_top ()) != label)) - { /* Top of stack interrupts flow between two - DOs specifying label. */ - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_DO_BLOCK_DO); - ffebad_here (0, ffelab_doref_line (label), - ffelab_doref_column (label)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_here (2, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - break; - - case FFELAB_typeNOTLOOP: - case FFELAB_typeFORMAT: - if (ffewhere_line_is_unknown (ffelab_definition_line (label))) - { - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_USE); - ffebad_here (0, ffelab_firstref_line (label), ffelab_firstref_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - } - /* Fall through. */ - case FFELAB_typeUSELESS: - case FFELAB_typeENDIF: - ffelab_set_type (label, FFELAB_typeANY); - ffestd_labeldef_any (label); - - ffebad_start (FFEBAD_LABEL_USE_DEF); - ffebad_here (0, ffelab_definition_line (label), ffelab_definition_column (label)); - ffebad_here (1, ffelex_token_where_line (label_token), - ffelex_token_where_column (label_token)); - ffebad_finish (); - - ffestc_try_shriek_do_ (); - - return FALSE; - - default: - assert ("bad label" == NULL); - /* Fall through. */ - case FFELAB_typeANY: - break; - } - - *x_label = label; - return TRUE; -} - -/* ffestc_order_access_ -- Check ordering on <access> statement - - if (ffestc_order_access_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_access_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_actiondo_ -- Check ordering on <actiondo> statement - - if (ffestc_order_actiondo_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_actiondo_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateDO: - return FFESTC_orderOK_; - - case FFESTV_stateIFTHEN: - case FFESTV_stateSELECT1: - if (ffestw_top_do (ffestw_stack_top ()) == NULL) - break; - return FFESTC_orderOK_; - - case FFESTV_stateIF: - if (ffestw_top_do (ffestw_stack_top ()) == NULL) - break; - ffestc_shriek_after1_ = ffestc_shriek_if_; - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - default: - break; - } - ffestc_order_bad_ (); - return FFESTC_orderBAD_; -} - -/* ffestc_order_actionif_ -- Check ordering on <actionif> statement - - if (ffestc_order_actionif_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_actionif_ () -{ - bool update; - -recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); - update = TRUE; - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); - update = TRUE; - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); - update = TRUE; - break; - - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - update = FALSE; - break; - - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateIF: - ffestc_shriek_after1_ = ffestc_shriek_if_; - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateINTERFACE0: - ffestc_order_bad_ (); - if (update) - ffestw_update (NULL); - return FFESTC_orderBAD_; - - default: - if (update) - ffestw_update (NULL); - return FFESTC_orderOK_; - } -} - -/* ffestc_order_actionwhere_ -- Check ordering on <actionwhere> statement - - if (ffestc_order_actionwhere_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_actionwhere_ () -{ - bool update; - -recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); - update = TRUE; - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); - update = TRUE; - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); - update = TRUE; - break; - - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - update = FALSE; - break; - - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: -#if FFESTR_F90 - ffestc_shriek_after1_ = ffestc_shriek_where_; -#endif - return FFESTC_orderOK_; - - case FFESTV_stateIF: - ffestc_shriek_after1_ = ffestc_shriek_if_; - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateINTERFACE0: - ffestc_order_bad_ (); - if (update) - ffestw_update (NULL); - return FFESTC_orderBAD_; - - default: - if (update) - ffestw_update (NULL); - return FFESTC_orderOK_; - } -} - -/* Check ordering on "any" statement. Like _actionwhere_, but - doesn't produce any diagnostics. */ - -static void -ffestc_order_any_ () -{ - bool update; - -recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); - update = TRUE; - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); - update = TRUE; - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); - update = TRUE; - break; - - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - update = FALSE; - break; - - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT1: - return; - - case FFESTV_stateWHERE: -#if FFESTR_F90 - ffestc_shriek_after1_ = ffestc_shriek_where_; -#endif - return; - - case FFESTV_stateIF: - ffestc_shriek_after1_ = ffestc_shriek_if_; - return; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - default: - return; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateINTERFACE0: - if (update) - ffestw_update (NULL); - return; - - default: - if (update) - ffestw_update (NULL); - return; - } -} - -/* ffestc_order_bad_ -- Whine about statement ordering violation - - ffestc_order_bad_(); - - Uses current ffesta_tokens[0] and, if available, info on where current - state started to produce generic message. Someday we should do - fancier things than this, but this just gets things creaking along for - now. */ - -static void -ffestc_order_bad_ () -{ - if (ffewhere_line_is_unknown (ffestw_line (ffestw_stack_top ()))) - { - ffebad_start (FFEBAD_ORDER_1); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - else - { - ffebad_start (FFEBAD_ORDER_2); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - ffestc_labeldef_useless_ (); /* Any label definition is useless. */ -} - -/* ffestc_order_blockdata_ -- Check ordering on <blockdata> statement - - if (ffestc_order_blockdata_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_blockdata_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateBLOCKDATA4: - case FFESTV_stateBLOCKDATA5: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_blockspec_ -- Check ordering on <blockspec> statement - - if (ffestc_order_blockspec_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_blockspec_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_component_ -- Check ordering on <component-decl> statement - - if (ffestc_order_component_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_component_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateTYPE: - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_contains_ -- Check ordering on CONTAINS statement - - if (ffestc_order_contains_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_contains_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - case FFESTV_statePROGRAM4: - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM5); - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateSUBROUTINE4: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE5); - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - case FFESTV_stateFUNCTION4: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION5); - break; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - case FFESTV_stateMODULE3: - case FFESTV_stateMODULE4: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE5); - break; - - case FFESTV_stateUSE: - ffestc_shriek_end_uses_ (TRUE); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateNIL: - ffestw_update (NULL); - return FFESTC_orderOK_; - - default: - ffestc_order_bad_ (); - ffestw_update (NULL); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_data_ -- Check ordering on DATA statement - - if (ffestc_order_data_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_data_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION2: - case FFESTV_stateBLOCKDATA2: - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateBLOCKDATA3: - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - case FFESTV_stateBLOCKDATA4: - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT0: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_data77_ -- Check ordering on pedantic-F77 DATA statement - - if (ffestc_order_data77_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_data77_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - case FFESTV_stateBLOCKDATA3: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA4); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - case FFESTV_stateBLOCKDATA4: - return FFESTC_orderOK_; - - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT0: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_derivedtype_ -- Check ordering on derived TYPE statement - - if (ffestc_order_derivedtype_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_derivedtype_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: - ffestc_shriek_end_uses_ (TRUE); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_do_ -- Check ordering on <do> statement - - if (ffestc_order_do_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_do_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateDO: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_entry_ -- Check ordering on ENTRY statement - - if (ffestc_order_entry_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_entry_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateSUBROUTINE0: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); - break; - - case FFESTV_stateFUNCTION0: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); - break; - - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - break; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateNIL: - case FFESTV_stateMODULE5: - ffestw_update (NULL); - return FFESTC_orderOK_; - - default: - ffestc_order_bad_ (); - ffestw_update (NULL); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_exec_ -- Check ordering on <exec> statement - - if (ffestc_order_exec_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_exec_ () -{ - bool update; - -recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM4); - update = TRUE; - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE4); - update = TRUE; - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION4); - update = TRUE; - break; - - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - update = FALSE; - break; - - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } - - switch (ffestw_state (ffestw_previous (ffestw_stack_top ()))) - { - case FFESTV_stateINTERFACE0: - ffestc_order_bad_ (); - if (update) - ffestw_update (NULL); - return FFESTC_orderBAD_; - - default: - if (update) - ffestw_update (NULL); - return FFESTC_orderOK_; - } -} - -/* ffestc_order_format_ -- Check ordering on FORMAT statement - - if (ffestc_order_format_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_format_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT0: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_function_ -- Check ordering on <function> statement - - if (ffestc_order_function_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_function_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - case FFESTV_stateFUNCTION4: - case FFESTV_stateFUNCTION5: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_iface_ -- Check ordering on <iface> statement - - if (ffestc_order_iface_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_iface_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - case FFESTV_statePROGRAM5: - case FFESTV_stateSUBROUTINE5: - case FFESTV_stateFUNCTION5: - case FFESTV_stateMODULE5: - case FFESTV_stateINTERFACE0: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_ifthen_ -- Check ordering on <ifthen> statement - - if (ffestc_order_ifthen_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_ifthen_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateIFTHEN: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_implicit_ -- Check ordering on IMPLICIT statement - - if (ffestc_order_implicit_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_implicit_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE2); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION2: - case FFESTV_stateMODULE2: - case FFESTV_stateBLOCKDATA2: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_implicitnone_ -- Check ordering on IMPLICIT NONE statement - - if (ffestc_order_implicitnone_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_implicitnone_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_interface_ -- Check ordering on <interface> statement - - if (ffestc_order_interface_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_interface_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateINTERFACE0: - case FFESTV_stateINTERFACE1: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_map_ -- Check ordering on <map> statement - - if (ffestc_order_map_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_VXT -static ffestcOrder_ -ffestc_order_map_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateMAP: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_module_ -- Check ordering on <module> statement - - if (ffestc_order_module_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_module_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - case FFESTV_stateMODULE3: - case FFESTV_stateMODULE4: - case FFESTV_stateMODULE5: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: - ffestc_shriek_end_uses_ (TRUE); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_parameter_ -- Check ordering on <parameter> statement - - if (ffestc_order_parameter_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_parameter_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM2); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE2); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION2); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE2); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION2: - case FFESTV_stateMODULE2: - case FFESTV_stateBLOCKDATA2: - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateTYPE: /* GNU extension here! */ - case FFESTV_stateSTRUCTURE: - case FFESTV_stateUNION: - case FFESTV_stateMAP: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_program_ -- Check ordering on <program> statement - - if (ffestc_order_program_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_program_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - case FFESTV_statePROGRAM3: - case FFESTV_statePROGRAM4: - case FFESTV_statePROGRAM5: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_progspec_ -- Check ordering on <progspec> statement - - if (ffestc_order_progspec_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_progspec_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA2); - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_BLOCKDATA_STMT); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_record_ -- Check ordering on RECORD statement - - if (ffestc_order_record_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_VXT -static ffestcOrder_ -ffestc_order_record_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_selectcase_ -- Check ordering on <selectcase> statement - - if (ffestc_order_selectcase_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_selectcase_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSELECT0: - case FFESTV_stateSELECT1: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_sfunc_ -- Check ordering on statement-function definition - - if (ffestc_order_sfunc_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_sfunc_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_spec_ -- Check ordering on <spec> statement - - if (ffestc_order_spec_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_spec_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_structure_ -- Check ordering on <structure> statement - - if (ffestc_order_structure_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_VXT -static ffestcOrder_ -ffestc_order_structure_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSTRUCTURE: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_subroutine_ -- Check ordering on <subroutine> statement - - if (ffestc_order_subroutine_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_subroutine_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateSUBROUTINE5: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_type_ -- Check ordering on <type> statement - - if (ffestc_order_type_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_type_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateTYPE: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_typedecl_ -- Check ordering on <typedecl> statement - - if (ffestc_order_typedecl_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_typedecl_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_union_ -- Check ordering on <union> statement - - if (ffestc_order_union_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_VXT -static ffestcOrder_ -ffestc_order_union_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateUNION: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_unit_ -- Check ordering on <unit> statement - - if (ffestc_order_unit_() != FFESTC_orderOK_) - return; */ - -static ffestcOrder_ -ffestc_order_unit_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -/* ffestc_order_use_ -- Check ordering on USE statement - - if (ffestc_order_use_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_use_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM1); - ffestc_shriek_begin_uses_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateSUBROUTINE0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE1); - ffestc_shriek_begin_uses_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateFUNCTION0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION1); - ffestc_shriek_begin_uses_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateMODULE0: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE1); - ffestc_shriek_begin_uses_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateUSE: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_vxtstructure_ -- Check ordering on STRUCTURE statement - - if (ffestc_order_vxtstructure_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_VXT -static ffestcOrder_ -ffestc_order_vxtstructure_ () -{ - recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_statePROGRAM1: - case FFESTV_statePROGRAM2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_statePROGRAM3); - return FFESTC_orderOK_; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSUBROUTINE3); - return FFESTC_orderOK_; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateFUNCTION3); - return FFESTC_orderOK_; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateMODULE3); - return FFESTC_orderOK_; - - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - ffestw_update (NULL); - ffestw_set_state (ffestw_stack_top (), FFESTV_stateBLOCKDATA3); - return FFESTC_orderOK_; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - return FFESTC_orderOK_; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); -#if FFESTR_F90 - ffestc_shriek_where_ (FALSE); -#endif - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* ffestc_order_where_ -- Check ordering on <where> statement - - if (ffestc_order_where_() != FFESTC_orderOK_) - return; */ - -#if FFESTR_F90 -static ffestcOrder_ -ffestc_order_where_ () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateWHERETHEN: - return FFESTC_orderOK_; - - case FFESTV_stateWHERE: - ffestc_order_bad_ (); - ffestc_shriek_where_ (FALSE); - return FFESTC_orderBAD_; - - case FFESTV_stateIF: - ffestc_order_bad_ (); - ffestc_shriek_if_ (FALSE); - return FFESTC_orderBAD_; - - default: - ffestc_order_bad_ (); - return FFESTC_orderBAD_; - } -} - -#endif -/* Invoked for each token in dummy arg list of FUNCTION, SUBROUTINE, and - ENTRY (prior to the first executable statement). */ - -static void -ffestc_promote_dummy_ (ffelexToken t) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffebld e; - bool sfref_ok; - - assert (t != NULL); - - if (ffelex_token_type (t) == FFELEX_typeASTERISK) - { - ffebld_append_item (&ffestc_local_.dummy.list_bottom, - ffebld_new_star ()); - return; /* Don't bother with alternate returns! */ - } - - s = ffesymbol_declare_local (t, FALSE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - sfref_ok = FALSE; - - if (sa & FFESYMBOL_attrsANY) - na = sa; - else if (sa & FFESYMBOL_attrsDUMMY) - { - if (ffestc_entry_num_ == ffesymbol_maxentrynum (s)) - { /* Seen this one twice in this list! */ - na = FFESYMBOL_attrsetNONE; - } - else - na = sa; - sfref_ok = TRUE; /* Ok for sym to be ref'd in sfuncdef - previously, since already declared as a - dummy arg. */ - } - else if (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsANY - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsDUMMY; - else - na = FFESYMBOL_attrsetNONE; - - if (!ffesymbol_is_specable (s) - && (!sfref_ok - || (ffesymbol_where (s) != FFEINFO_whereDUMMY))) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_maxentrynum (s, ffestc_entry_num_); - ffesymbol_set_numentries (s, ffesymbol_numentries (s) + 1); - e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (e, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE)); - ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); - ffesymbol_signal_unreported (s); - } -} - -/* ffestc_promote_execdummy_ -- Declare token as dummy variable in exec context - - ffestc_promote_execdummy_(t); - - Invoked for each token in dummy arg list of ENTRY when the statement - follows the first executable statement. */ - -static void -ffestc_promote_execdummy_ (ffelexToken t) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffesymbolState ss; - ffesymbolState ns; - ffeinfoKind kind; - ffeinfoWhere where; - ffebld e; - - assert (t != NULL); - - if (ffelex_token_type (t) == FFELEX_typeASTERISK) - { - ffebld_append_item (&ffestc_local_.dummy.list_bottom, - ffebld_new_star ()); - return; /* Don't bother with alternate returns! */ - } - - s = ffesymbol_declare_local (t, FALSE); - na = sa = ffesymbol_attrs (s); - ss = ffesymbol_state (s); - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - if (ffestc_entry_num_ == ffesymbol_maxentrynum (s)) - { /* Seen this one twice in this list! */ - na = FFESYMBOL_attrsetNONE; - } - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - ns = FFESYMBOL_stateUNDERSTOOD; /* Assume we know it all know. */ - - switch (kind) - { - case FFEINFO_kindENTITY: - case FFEINFO_kindFUNCTION: - case FFEINFO_kindSUBROUTINE: - break; /* These are fine, as far as we know. */ - - case FFEINFO_kindNONE: - if (sa & FFESYMBOL_attrsDUMMY) - ns = FFESYMBOL_stateUNCERTAIN; /* Learned nothing new. */ - else if (sa & FFESYMBOL_attrsANYLEN) - { - kind = FFEINFO_kindENTITY; - where = FFEINFO_whereDUMMY; - } - else if (sa & FFESYMBOL_attrsACTUALARG) - na = FFESYMBOL_attrsetNONE; - else - { - na = sa | FFESYMBOL_attrsDUMMY; - ns = FFESYMBOL_stateUNCERTAIN; - } - break; - - default: - na = FFESYMBOL_attrsetNONE; /* Error. */ - break; - } - - switch (where) - { - case FFEINFO_whereDUMMY: - break; /* This is fine. */ - - case FFEINFO_whereNONE: - where = FFEINFO_whereDUMMY; - break; - - default: - na = FFESYMBOL_attrsetNONE; /* Error. */ - break; - } - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, t); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, ns); - ffesymbol_set_maxentrynum (s, ffestc_entry_num_); - ffesymbol_set_numentries (s, ffesymbol_numentries (s) + 1); - if ((ns == FFESYMBOL_stateUNDERSTOOD) - && (kind != FFEINFO_kindSUBROUTINE) - && !ffeimplic_establish_symbol (s)) - { - ffesymbol_error (s, t); - return; - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - kind, - where, - ffesymbol_size (s))); - e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (e, ffeinfo_use (ffesymbol_info (s))); - ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } -} - -/* ffestc_promote_sfdummy_ -- Declare token as stmt-func dummy variable - - ffestc_promote_sfdummy_(t); - - Invoked for each token in dummy arg list of statement function. - - 22-Oct-91 JCB 1.1 - Reject arg if CHARACTER*(*). */ - -static void -ffestc_promote_sfdummy_ (ffelexToken t) -{ - ffesymbol s; - ffesymbol sp; /* Parent symbol. */ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffebld e; - - assert (t != NULL); - - s = ffesymbol_declare_sfdummy (t); /* Sets maxentrynum to 0 for new obj; - also sets sfa_dummy_parent to - parent symbol. */ - if (ffesymbol_state (s) != FFESYMBOL_stateNONE) - { - ffesymbol_error (s, t); /* Dummy already in list. */ - return; - } - - sp = ffesymbol_sfdummyparent (s); /* Now flag dummy's parent as used - for dummy. */ - sa = ffesymbol_attrs (sp); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (sp) - && ((ffesymbol_kind (sp) != FFEINFO_kindENTITY) - || ((ffesymbol_where (sp) != FFEINFO_whereLOCAL) - && (ffesymbol_where (sp) != FFEINFO_whereCOMMON) - && (ffesymbol_where (sp) != FFEINFO_whereDUMMY) - && (ffesymbol_where (sp) != FFEINFO_whereNONE)))) - na = FFESYMBOL_attrsetNONE; /* Can't be PARAMETER etc., must be a var. */ - else if (sa & FFESYMBOL_attrsANY) - na = sa; - else if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsSFARG; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - { - ffesymbol_error (sp, t); - ffesymbol_set_info (s, ffeinfo_new_any ()); - } - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_state (sp, FFESYMBOL_stateSEEN); - ffesymbol_set_attrs (sp, na); - if (!ffeimplic_establish_symbol (sp) - || ((ffesymbol_basictype (sp) == FFEINFO_basictypeCHARACTER) - && (ffesymbol_size (sp) == FFETARGET_charactersizeNONE))) - ffesymbol_error (sp, t); - else - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (sp), - ffesymbol_kindtype (sp), - 0, - FFEINFO_kindENTITY, - FFEINFO_whereDUMMY, - ffesymbol_size (sp))); - - ffesymbol_signal_unreported (sp); - } - - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_maxentrynum (s, ffestc_sfdummy_argno_++); - ffesymbol_signal_unreported (s); - e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (e, ffeinfo_use (ffesymbol_info (s))); - ffebld_append_item (&ffestc_local_.dummy.list_bottom, e); -} - -/* ffestc_shriek_begin_program_ -- Implicit PROGRAM statement - - ffestc_shriek_begin_program_(); - - Invoked only when a PROGRAM statement is NOT present at the beginning - of a main program unit. */ - -static void -ffestc_shriek_begin_program_ () -{ - ffestw b; - ffesymbol s; - - ffestc_blocknum_ = 0; - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_statePROGRAM0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_end_program_); - ffestw_set_name (b, NULL); - - s = ffesymbol_declare_programunit (NULL, - ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - - /* Special case: this is one symbol that won't go through - ffestu_exec_transition_ when the first statement in a main program is - executable, because the transition happens in ffest before ffestc is - reached and triggers the implicit generation of a main program. So we - do the exec transition for the implicit main program right here, just - for cleanliness' sake (at the very least). */ - - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindPROGRAM, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - - ffesymbol_signal_unreported (s); - - ffestd_R1102 (s, NULL); -} - -/* ffestc_shriek_begin_uses_ -- Start a bunch of USE statements - - ffestc_shriek_begin_uses_(); - - Invoked before handling the first USE statement in a block of one or - more USE statements. _end_uses_(bool ok) is invoked before handling - the first statement after the block (there are no BEGIN USE and END USE - statements, but the semantics of USE statements effectively requires - handling them as a single block rather than one statement at a time). */ - -#if FFESTR_F90 -static void -ffestc_shriek_begin_uses_ () -{ - ffestw b; - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateUSE); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_end_uses_); - - ffestd_begin_uses (); -} - -#endif -/* ffestc_shriek_blockdata_ -- End a BLOCK DATA - - ffestc_shriek_blockdata_(TRUE); */ - -static void -ffestc_shriek_blockdata_ (bool ok) -{ - if (!ffesta_seen_first_exec) - { - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - } - - ffestd_R1112 (ok); - - ffestd_exec_end (); - - if (ffestw_name (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - - ffe_terminate_2 (); - ffe_init_2 (); -} - -/* ffestc_shriek_do_ -- End of statement following DO-term-stmt etc - - ffestc_shriek_do_(TRUE); - - Also invoked by _labeldef_branch_end_ (or, in cases - of errors, other _labeldef_ functions) when the label definition is - for a DO-target (LOOPEND) label, once per matching/outstanding DO - block on the stack. These cases invoke this function with ok==TRUE, so - only forced stack popping (via ffestc_eof()) invokes it with ok==FALSE. */ - -static void -ffestc_shriek_do_ (bool ok) -{ - ffelab l; - - if (((l = ffestw_label (ffestw_stack_top ())) != NULL) - && (ffewhere_line_is_unknown (ffelab_definition_line (l)))) - { /* DO target is label that is still - undefined. */ - assert ((ffelab_type (l) == FFELAB_typeLOOPEND) - || (ffelab_type (l) == FFELAB_typeANY)); - if (ffelab_type (l) != FFELAB_typeANY) - { - ffelab_set_definition_line (l, - ffewhere_line_use (ffelab_doref_line (l))); - ffelab_set_definition_column (l, - ffewhere_column_use (ffelab_doref_column (l))); - ffestv_num_label_defines_++; - } - ffestd_labeldef_branch (l); - } - - ffestd_do (ok); - - if (ffestw_name (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - if (ffestw_do_iter_var_t (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_do_iter_var_t (ffestw_stack_top ())); - if (ffestw_do_iter_var (ffestw_stack_top ()) != NULL) - ffesymbol_set_is_doiter (ffestw_do_iter_var (ffestw_stack_top ()), FALSE); - ffestw_kill (ffestw_pop ()); -} - -/* ffestc_shriek_end_program_ -- End a PROGRAM - - ffestc_shriek_end_program_(); */ - -static void -ffestc_shriek_end_program_ (bool ok) -{ - if (!ffesta_seen_first_exec) - { - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - } - - ffestd_R1103 (ok); - - ffestd_exec_end (); - - if (ffestw_name (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - - ffe_terminate_2 (); - ffe_init_2 (); -} - -/* ffestc_shriek_end_uses_ -- End a bunch of USE statements - - ffestc_shriek_end_uses_(TRUE); - - ok==TRUE means simply not popping due to ffestc_eof() - being called, because there is no formal END USES statement in Fortran. */ - -#if FFESTR_F90 -static void -ffestc_shriek_end_uses_ (bool ok) -{ - ffestd_end_uses (ok); - - ffestw_kill (ffestw_pop ()); -} - -#endif -/* ffestc_shriek_function_ -- End a FUNCTION - - ffestc_shriek_function_(TRUE); */ - -static void -ffestc_shriek_function_ (bool ok) -{ - if (!ffesta_seen_first_exec) - { - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - } - - ffestd_R1221 (ok); - - ffestd_exec_end (); - - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - ffesta_is_entry_valid = FALSE; - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffe_terminate_2 (); - ffe_init_2 (); - break; - - default: - ffe_terminate_3 (); - ffe_init_3 (); - break; - - case FFESTV_stateINTERFACE0: - ffe_terminate_4 (); - ffe_init_4 (); - break; - } -} - -/* ffestc_shriek_if_ -- End of statement following logical IF - - ffestc_shriek_if_(TRUE); - - Applies ONLY to logical IF, not to IF-THEN. For example, does not - ffelex_token_kill the construct name for an IF-THEN block (the name - field is invalid for logical IF). ok==TRUE iff statement following - logical IF (substatement) is valid; else, statement is invalid or - stack forcibly popped due to ffestc_eof(). */ - -static void -ffestc_shriek_if_ (bool ok) -{ - ffestd_end_R807 (ok); - - ffestw_kill (ffestw_pop ()); - ffestc_shriek_after1_ = NULL; - - ffestc_try_shriek_do_ (); -} - -/* ffestc_shriek_ifthen_ -- End an IF-THEN - - ffestc_shriek_ifthen_(TRUE); */ - -static void -ffestc_shriek_ifthen_ (bool ok) -{ - ffestd_R806 (ok); - - if (ffestw_name (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -/* ffestc_shriek_interface_ -- End an INTERFACE - - ffestc_shriek_interface_(TRUE); */ - -#if FFESTR_F90 -static void -ffestc_shriek_interface_ (bool ok) -{ - ffestd_R1203 (ok); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_map_ -- End a MAP - - ffestc_shriek_map_(TRUE); */ - -#if FFESTR_VXT -static void -ffestc_shriek_map_ (bool ok) -{ - ffestd_V013 (ok); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_module_ -- End a MODULE - - ffestc_shriek_module_(TRUE); */ - -#if FFESTR_F90 -static void -ffestc_shriek_module_ (bool ok) -{ - if (!ffesta_seen_first_exec) - { - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - } - - ffestd_R1106 (ok); - - ffestd_exec_end (); - - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - - ffe_terminate_2 (); - ffe_init_2 (); -} - -#endif -/* ffestc_shriek_select_ -- End a SELECT - - ffestc_shriek_select_(TRUE); */ - -static void -ffestc_shriek_select_ (bool ok) -{ - ffestwSelect s; - ffestwCase c; - - ffestd_R811 (ok); - - if (ffestw_name (ffestw_stack_top ()) != NULL) - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - s = ffestw_select (ffestw_stack_top ()); - ffelex_token_kill (s->t); - for (c = s->first_rel; c != (ffestwCase) &s->first_rel; c = c->next_rel) - ffelex_token_kill (c->t); - malloc_pool_kill (s->pool); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -/* ffestc_shriek_structure_ -- End a STRUCTURE - - ffestc_shriek_structure_(TRUE); */ - -#if FFESTR_VXT -static void -ffestc_shriek_structure_ (bool ok) -{ - ffestd_V004 (ok); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_subroutine_ -- End a SUBROUTINE - - ffestc_shriek_subroutine_(TRUE); */ - -static void -ffestc_shriek_subroutine_ (bool ok) -{ - if (!ffesta_seen_first_exec) - { - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - } - - ffestd_R1225 (ok); - - ffestd_exec_end (); - - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - ffesta_is_entry_valid = FALSE; - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffe_terminate_2 (); - ffe_init_2 (); - break; - - default: - ffe_terminate_3 (); - ffe_init_3 (); - break; - - case FFESTV_stateINTERFACE0: - ffe_terminate_4 (); - ffe_init_4 (); - break; - } -} - -/* ffestc_shriek_type_ -- End a TYPE - - ffestc_shriek_type_(TRUE); */ - -#if FFESTR_F90 -static void -ffestc_shriek_type_ (bool ok) -{ - ffestd_R425 (ok); - - ffe_terminate_4 (); - - ffelex_token_kill (ffestw_name (ffestw_stack_top ())); - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_union_ -- End a UNION - - ffestc_shriek_union_(TRUE); */ - -#if FFESTR_VXT -static void -ffestc_shriek_union_ (bool ok) -{ - ffestd_V010 (ok); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_where_ -- Implicit END WHERE statement - - ffestc_shriek_where_(TRUE); - - Implement the end of the current WHERE "block". ok==TRUE iff statement - following WHERE (substatement) is valid; else, statement is invalid - or stack forcibly popped due to ffestc_eof(). */ - -#if FFESTR_F90 -static void -ffestc_shriek_where_ (bool ok) -{ - ffestd_R745 (ok); - - ffestw_kill (ffestw_pop ()); - ffestc_shriek_after1_ = NULL; - if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateIF) - ffestc_shriek_if_ (TRUE); /* "IF (x) WHERE (y) stmt" is only valid - case. */ - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_shriek_wherethen_ -- End a WHERE(-THEN) - - ffestc_shriek_wherethen_(TRUE); */ - -#if FFESTR_F90 -static void -ffestc_shriek_wherethen_ (bool ok) -{ - ffestd_end_R740 (ok); - - ffestw_kill (ffestw_pop ()); - - ffestc_try_shriek_do_ (); -} - -#endif -/* ffestc_subr_binsrch_ -- Binary search of char const in list of strings - - i = ffestc_subr_binsrch_(search_list,search_list_size,&spec,"etc"); - - search_list contains search_list_size char *'s, spec is checked to see - if it is a char constant and, if so, is binary-searched against the list. - 0 is returned if not found, else the "classic" index (beginning with 1) - is returned. Before returning 0 where the search was performed but - fruitless, if "etc" is a non-NULL char *, an error message is displayed - using "etc" as the pick-one-of-these string. */ - -static int -ffestc_subr_binsrch_ (char **list, int size, ffestpFile *spec, char *whine) -{ - int lowest_tested; - int highest_tested; - int halfway; - int offset; - int c; - char *str; - int len; - - if (size == 0) - return 0; /* Nobody should pass size == 0, but for - elegance.... */ - - lowest_tested = -1; - highest_tested = size; - halfway = size >> 1; - - list += halfway; - - c = ffestc_subr_speccmp_ (*list, spec, &str, &len); - if (c == 2) - return 0; - c = -c; /* Sigh. */ - -next: /* :::::::::::::::::::: */ - switch (c) - { - case -1: - offset = (halfway - lowest_tested) >> 1; - if (offset == 0) - goto nope; /* :::::::::::::::::::: */ - highest_tested = halfway; - list -= offset; - halfway -= offset; - c = ffesrc_strcmp_1ns2i (ffe_case_match (), str, len, *list); - goto next; /* :::::::::::::::::::: */ - - case 0: - return halfway + 1; - - case 1: - offset = (highest_tested - halfway) >> 1; - if (offset == 0) - goto nope; /* :::::::::::::::::::: */ - lowest_tested = halfway; - list += offset; - halfway += offset; - c = ffesrc_strcmp_1ns2i (ffe_case_match (), str, len, *list); - goto next; /* :::::::::::::::::::: */ - - default: - assert ("unexpected return from ffesrc_strcmp_1ns2i" == NULL); - break; - } - -nope: /* :::::::::::::::::::: */ - ffebad_start (FFEBAD_SPEC_VALUE); - ffebad_here (0, ffelex_token_where_line (spec->value), - ffelex_token_where_column (spec->value)); - ffebad_string (whine); - ffebad_finish (); - return 0; -} - -/* ffestc_subr_format_ -- Return summary of format specifier - - ffestc_subr_format_(&specifier); */ - -static ffestvFormat -ffestc_subr_format_ (ffestpFile *spec) -{ - if (!spec->kw_or_val_present) - return FFESTV_formatNONE; - assert (spec->value_present); - if (spec->value_is_label) - return FFESTV_formatLABEL; /* Ok if not a label. */ - - assert (spec->value != NULL); - if (ffebld_op (spec->u.expr) == FFEBLD_opSTAR) - return FFESTV_formatASTERISK; - - if (ffeinfo_kind (ffebld_info (spec->u.expr)) == FFEINFO_kindNAMELIST) - return FFESTV_formatNAMELIST; - - if (ffeinfo_rank (ffebld_info (spec->u.expr)) != 0) - return FFESTV_formatCHAREXPR; /* F77 C5. */ - - switch (ffeinfo_basictype (ffebld_info (spec->u.expr))) - { - case FFEINFO_basictypeINTEGER: - return FFESTV_formatINTEXPR; - - case FFEINFO_basictypeCHARACTER: - return FFESTV_formatCHAREXPR; - - case FFEINFO_basictypeANY: - return FFESTV_formatASTERISK; - - default: - assert ("bad basictype" == NULL); - return FFESTV_formatINTEXPR; - } -} - -/* ffestc_subr_is_branch_ -- Handle specifier as branch target label - - ffestc_subr_is_branch_(&specifier); */ - -static bool -ffestc_subr_is_branch_ (ffestpFile *spec) -{ - if (!spec->kw_or_val_present) - return TRUE; - assert (spec->value_present); - assert (spec->value_is_label); - spec->value_is_label++; /* For checking purposes only; 1=>2. */ - return ffestc_labelref_is_branch_ (spec->value, &spec->u.label); -} - -/* ffestc_subr_is_format_ -- Handle specifier as format target label - - ffestc_subr_is_format_(&specifier); */ - -static bool -ffestc_subr_is_format_ (ffestpFile *spec) -{ - if (!spec->kw_or_val_present) - return TRUE; - assert (spec->value_present); - if (!spec->value_is_label) - return TRUE; /* Ok if not a label. */ - - spec->value_is_label++; /* For checking purposes only; 1=>2. */ - return ffestc_labelref_is_format_ (spec->value, &spec->u.label); -} - -/* ffestc_subr_is_present_ -- Ensure specifier is present, else error - - ffestc_subr_is_present_("SPECIFIER",&specifier); */ - -static bool -ffestc_subr_is_present_ (char *name, ffestpFile *spec) -{ - if (spec->kw_or_val_present) - { - assert (spec->value_present); - return TRUE; - } - - ffebad_start (FFEBAD_MISSING_SPECIFIER); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_string (name); - ffebad_finish (); - return FALSE; -} - -/* ffestc_subr_speccmp_ -- Compare string to constant expression, if present - - if (ffestc_subr_speccmp_("Constant",&specifier,NULL,NULL) == 0) - // specifier value is present and is a char constant "CONSTANT" - - Like strcmp, except the return values are defined as: -1 returned in place - of strcmp's generic negative value, 1 in place of it's generic positive - value, and 2 when there is no character constant string to compare. Also, - a case-insensitive comparison is performed, where string is assumed to - already be in InitialCaps form. - - If a non-NULL pointer is provided as the char **target, then *target is - written with NULL if 2 is returned, a pointer to the constant string - value of the specifier otherwise. Similarly, length is written with - 0 if 2 is returned, the length of the constant string value otherwise. */ - -static int -ffestc_subr_speccmp_ (char *string, ffestpFile *spec, char **target, - int *length) -{ - ffebldConstant c; - int i; - - if (!spec->kw_or_val_present || !spec->value_present - || (spec->u.expr == NULL) - || (ffebld_op (spec->u.expr) != FFEBLD_opCONTER)) - { - if (target != NULL) - *target = NULL; - if (length != NULL) - *length = 0; - return 2; - } - - if (ffebld_constant_type (c = ffebld_conter (spec->u.expr)) - != FFEBLD_constCHARACTERDEFAULT) - { - if (target != NULL) - *target = NULL; - if (length != NULL) - *length = 0; - return 2; - } - - if (target != NULL) - *target = ffebld_constant_characterdefault (c).text; - if (length != NULL) - *length = ffebld_constant_characterdefault (c).length; - - i = ffesrc_strcmp_1ns2i (ffe_case_match (), - ffebld_constant_characterdefault (c).text, - ffebld_constant_characterdefault (c).length, - string); - if (i == 0) - return 0; - if (i > 0) - return -1; /* Yes indeed, we reverse the strings to - _strcmpin_. */ - return 1; -} - -/* ffestc_subr_unit_ -- Return summary of unit specifier - - ffestc_subr_unit_(&specifier); */ - -static ffestvUnit -ffestc_subr_unit_ (ffestpFile *spec) -{ - if (!spec->kw_or_val_present) - return FFESTV_unitNONE; - assert (spec->value_present); - assert (spec->value != NULL); - - if (ffebld_op (spec->u.expr) == FFEBLD_opSTAR) - return FFESTV_unitASTERISK; - - switch (ffeinfo_basictype (ffebld_info (spec->u.expr))) - { - case FFEINFO_basictypeINTEGER: - return FFESTV_unitINTEXPR; - - case FFEINFO_basictypeCHARACTER: - return FFESTV_unitCHAREXPR; - - case FFEINFO_basictypeANY: - return FFESTV_unitASTERISK; - - default: - assert ("bad basictype" == NULL); - return FFESTV_unitINTEXPR; - } -} - -/* Call this function whenever it's possible that one or more top - stack items are label-targeting DO blocks that have had their - labels defined, but at a time when they weren't at the top of the - stack. This prevents uninformative diagnostics for programs - like "DO 10", "IF (...) THEN", "10 ELSE", "END IF", "END". */ - -static void -ffestc_try_shriek_do_ () -{ - ffelab lab; - ffelabType ty; - - while ((ffestw_state (ffestw_stack_top ()) == FFESTV_stateDO) - && ((lab = (ffestw_label (ffestw_stack_top ()))) != NULL) - && (((ty = (ffelab_type (lab))) - == FFELAB_typeANY) - || (ty == FFELAB_typeUSELESS) - || (ty == FFELAB_typeFORMAT) - || (ty == FFELAB_typeNOTLOOP) - || (ty == FFELAB_typeENDIF))) - ffestc_shriek_do_ (FALSE); -} - -/* ffestc_decl_start -- R426 or R501 - - ffestc_decl_start(...); - - Verify that R426 component-def-stmt or R501 type-declaration-stmt are - valid here, figure out which one, and implement. */ - -void -ffestc_decl_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent) -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - case FFESTV_statePROGRAM0: - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateFUNCTION0: - case FFESTV_stateMODULE0: - case FFESTV_stateBLOCKDATA0: - case FFESTV_statePROGRAM1: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateFUNCTION1: - case FFESTV_stateMODULE1: - case FFESTV_stateBLOCKDATA1: - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION2: - case FFESTV_stateMODULE2: - case FFESTV_stateBLOCKDATA2: - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateMODULE3: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateUSE: - ffestc_local_.decl.is_R426 = 2; - break; - - case FFESTV_stateTYPE: - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - ffestc_local_.decl.is_R426 = 1; - break; - - default: - ffestc_order_bad_ (); - ffestc_labeldef_useless_ (); - ffestc_local_.decl.is_R426 = 0; - return; - } - - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_start (type, typet, kind, kindt, len, lent); - break; -#endif - - case 2: - ffestc_R501_start (type, typet, kind, kindt, len, lent); - break; - - default: - ffestc_labeldef_useless_ (); - break; - } -} - -/* ffestc_decl_attrib -- R426 or R501 type attribute - - ffestc_decl_attrib(...); - - Verify that R426 component-def-stmt or R501 type-declaration-stmt attribute - is valid here and implement. */ - -void -ffestc_decl_attrib (ffestpAttrib attrib UNUSED, - ffelexToken attribt UNUSED, - ffestrOther intent_kw UNUSED, - ffesttDimList dims UNUSED) -{ -#if FFESTR_F90 - switch (ffestc_local_.decl.is_R426) - { - case 1: - ffestc_R426_attrib (attrib, attribt, intent_kw, dims); - break; - - case 2: - ffestc_R501_attrib (attrib, attribt, intent_kw, dims); - break; - - default: - break; - } -#else - ffebad_start (FFEBAD_F90); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - return; -#endif -} - -/* ffestc_decl_item -- R426 or R501 - - ffestc_decl_item(...); - - Establish type for a particular object. */ - -void -ffestc_decl_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, - ffelexToken initt, bool clist) -{ - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_item (name, kind, kindt, dims, len, lent, init, initt, - clist); - break; -#endif - - case 2: - ffestc_R501_item (name, kind, kindt, dims, len, lent, init, initt, - clist); - break; - - default: - break; - } -} - -/* ffestc_decl_itemstartvals -- R426 or R501 start list of values - - ffestc_decl_itemstartvals(); - - Gonna specify values for the object now. */ - -void -ffestc_decl_itemstartvals () -{ - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_itemstartvals (); - break; -#endif - - case 2: - ffestc_R501_itemstartvals (); - break; - - default: - break; - } -} - -/* ffestc_decl_itemvalue -- R426 or R501 source value - - ffestc_decl_itemvalue(repeat,repeat_token,value,value_token); - - Make sure repeat and value are valid for the object being initialized. */ - -void -ffestc_decl_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token) -{ - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_itemvalue (repeat, repeat_token, value, value_token); - break; -#endif - - case 2: - ffestc_R501_itemvalue (repeat, repeat_token, value, value_token); - break; - - default: - break; - } -} - -/* ffestc_decl_itemendvals -- R426 or R501 end list of values - - ffelexToken t; // the SLASH token that ends the list. - ffestc_decl_itemendvals(t); - - No more values, might specify more objects now. */ - -void -ffestc_decl_itemendvals (ffelexToken t) -{ - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_itemendvals (t); - break; -#endif - - case 2: - ffestc_R501_itemendvals (t); - break; - - default: - break; - } -} - -/* ffestc_decl_finish -- R426 or R501 - - ffestc_decl_finish(); - - Just wrap up any local activities. */ - -void -ffestc_decl_finish () -{ - switch (ffestc_local_.decl.is_R426) - { -#if FFESTR_F90 - case 1: - ffestc_R426_finish (); - break; -#endif - - case 2: - ffestc_R501_finish (); - break; - - default: - break; - } -} - -/* ffestc_elsewhere -- Generic ELSE WHERE statement - - ffestc_end(); - - Decide whether ELSEWHERE or ELSE w/if-construct-name=="WHERE" is meant. */ - -void -ffestc_elsewhere (ffelexToken where) -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateIFTHEN: - ffestc_R805 (where); - break; - - default: -#if FFESTR_F90 - ffestc_R744 (); -#endif - break; - } -} - -/* ffestc_end -- Generic END statement - - ffestc_end(); - - Make sure a generic END is valid in the current context, and implement - it. */ - -void -ffestc_end () -{ - ffestw b; - - b = ffestw_stack_top (); - -recurse: - - switch (ffestw_state (b)) - { - case FFESTV_stateBLOCKDATA0: - case FFESTV_stateBLOCKDATA1: - case FFESTV_stateBLOCKDATA2: - case FFESTV_stateBLOCKDATA3: - case FFESTV_stateBLOCKDATA4: - case FFESTV_stateBLOCKDATA5: - ffestc_R1112 (NULL); - break; - - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - case FFESTV_stateFUNCTION4: - case FFESTV_stateFUNCTION5: - if ((ffestw_state (ffestw_previous (b)) != FFESTV_stateNIL) - && (ffestw_state (ffestw_previous (b)) != FFESTV_stateINTERFACE0)) - { - ffebad_start (FFEBAD_END_WO); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_previous (b)), ffestw_col (ffestw_previous (b))); - ffebad_string ("FUNCTION"); - ffebad_finish (); - } - ffestc_R1221 (NULL); - break; - - case FFESTV_stateMODULE0: - case FFESTV_stateMODULE1: - case FFESTV_stateMODULE2: - case FFESTV_stateMODULE3: - case FFESTV_stateMODULE4: - case FFESTV_stateMODULE5: -#if FFESTR_F90 - ffestc_R1106 (NULL); -#endif - break; - - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateSUBROUTINE5: - if ((ffestw_state (ffestw_previous (b)) != FFESTV_stateNIL) - && (ffestw_state (ffestw_previous (b)) != FFESTV_stateINTERFACE0)) - { - ffebad_start (FFEBAD_END_WO); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_previous (b)), ffestw_col (ffestw_previous (b))); - ffebad_string ("SUBROUTINE"); - ffebad_finish (); - } - ffestc_R1225 (NULL); - break; - - case FFESTV_stateUSE: - b = ffestw_previous (ffestw_stack_top ()); - goto recurse; /* :::::::::::::::::::: */ - - default: - ffestc_R1103 (NULL); - break; - } -} - -/* ffestc_eof -- Generic EOF - - ffestc_eof(); - - Make sure we're at state NIL, or issue an error message and use each - block's shriek function to clean up to state NIL. */ - -void -ffestc_eof () -{ - if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateNIL) - { - ffebad_start (FFEBAD_EOF_BEFORE_BLOCK_END); - ffebad_here (0, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - do - (*ffestw_shriek (ffestw_stack_top ()))(FALSE); - while (ffestw_state (ffestw_stack_top ()) != FFESTV_stateNIL); - } -} - -/* ffestc_exec_transition -- Check if ok and move stmt state to executable - - if (ffestc_exec_transition()) - // Transition successful (kind of like a CONTINUE stmt was seen). - - If the current statement state is a non-nested specification state in - which, say, a CONTINUE statement would be valid, then enter the state - we'd be in after seeing CONTINUE (without, of course, generating any - CONTINUE code), call ffestd_exec_begin, and return TRUE. Otherwise - return FALSE. - - This function cannot be invoked once the first executable statement - is seen. This function may choose to always return TRUE by shrieking - away any interceding state stack entries to reach the base level of - specification state, but right now it doesn't, and it is (or should - be) purely an issue of how one wishes errors to be handled (for example, - an unrecognized statement in the middle of a STRUCTURE construct: after - the error message, should subsequent statements still be interpreted as - being within the construct, or should the construct be terminated upon - seeing the unrecognized statement? we do the former at the moment). */ - -bool -ffestc_exec_transition () -{ - bool update; - -recurse: - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - ffestc_shriek_begin_program_ (); - goto recurse; /* :::::::::::::::::::: */ - - case FFESTV_statePROGRAM0: - case FFESTV_stateSUBROUTINE0: - case FFESTV_stateFUNCTION0: - case FFESTV_stateBLOCKDATA0: - ffestw_state (ffestw_stack_top ()) += 4; /* To state UNIT4. */ - update = TRUE; - break; - - case FFESTV_statePROGRAM1: - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateFUNCTION1: - case FFESTV_stateBLOCKDATA1: - ffestw_state (ffestw_stack_top ()) += 3; /* To state UNIT4. */ - update = TRUE; - break; - - case FFESTV_statePROGRAM2: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateFUNCTION2: - case FFESTV_stateBLOCKDATA2: - ffestw_state (ffestw_stack_top ()) += 2; /* To state UNIT4. */ - update = TRUE; - break; - - case FFESTV_statePROGRAM3: - case FFESTV_stateSUBROUTINE3: - case FFESTV_stateFUNCTION3: - case FFESTV_stateBLOCKDATA3: - ffestw_state (ffestw_stack_top ()) += 1; /* To state UNIT4. */ - update = TRUE; - break; - - case FFESTV_stateUSE: -#if FFESTR_F90 - ffestc_shriek_end_uses_ (TRUE); -#endif - goto recurse; /* :::::::::::::::::::: */ - - default: - return FALSE; - } - - if (update) - ffestw_update (NULL); /* Update state line/col info. */ - - ffesta_seen_first_exec = TRUE; - ffestd_exec_begin (); - - return TRUE; -} - -/* ffestc_ffebad_here_doiter -- Calls ffebad_here with ptr to DO iter var - - ffesymbol s; - // call ffebad_start first, of course. - ffestc_ffebad_here_doiter(0,s); - // call ffebad_finish afterwards, naturally. - - Searches the stack of blocks backwards for a DO loop that has s - as its iteration variable, then calls ffebad_here with pointers to - that particular reference to the variable. Crashes if the DO loop - can't be found. */ - -void -ffestc_ffebad_here_doiter (ffebadIndex i, ffesymbol s) -{ - ffestw block; - - for (block = ffestw_top_do (ffestw_stack_top ()); - (block != NULL) && (ffestw_blocknum (block) != 0); - block = ffestw_top_do (ffestw_previous (block))) - { - if (ffestw_do_iter_var (block) == s) - { - ffebad_here (i, ffelex_token_where_line (ffestw_do_iter_var_t (block)), - ffelex_token_where_column (ffestw_do_iter_var_t (block))); - return; - } - } - assert ("no do block found" == NULL); -} - -/* ffestc_is_decl_not_R1219 -- Context information for FFESTB - - if (ffestc_is_decl_not_R1219()) ... - - When a statement with the form "type[RECURSIVE]FUNCTIONname(name-list)" - is seen, call this function. It returns TRUE if the statement's context - is such that it is a declaration of an object named - "[RECURSIVE]FUNCTIONname" with an array-decl spec of "name-list", FALSE - if the statement's context is such that it begins the definition of a - function named "name" havin the dummy argument list "name-list" (this - is the R1219 function-stmt case). */ - -bool -ffestc_is_decl_not_R1219 () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateNIL: - case FFESTV_statePROGRAM5: - case FFESTV_stateSUBROUTINE5: - case FFESTV_stateFUNCTION5: - case FFESTV_stateMODULE5: - case FFESTV_stateINTERFACE0: - return FALSE; - - default: - return TRUE; - } -} - -/* ffestc_is_entry_in_subr -- Context information for FFESTB - - if (ffestc_is_entry_in_subr()) ... - - When a statement with the form "ENTRY name(name-list)" - is seen, call this function. It returns TRUE if the statement's context - is such that it may have "*", meaning alternate return, in place of - names in the name list (i.e. if the ENTRY is in a subroutine context). - It also returns TRUE if the ENTRY is not in a function context (invalid - but prevents extra complaints about "*", if present). It returns FALSE - if the ENTRY is in a function context. */ - -bool -ffestc_is_entry_in_subr () -{ - ffestvState s; - - s = ffestw_state (ffestw_stack_top ()); - -recurse: - - switch (s) - { - case FFESTV_stateFUNCTION0: - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - case FFESTV_stateFUNCTION4: - return FALSE; - - case FFESTV_stateUSE: - s = ffestw_state (ffestw_previous (ffestw_stack_top ())); - goto recurse; /* :::::::::::::::::::: */ - - default: - return TRUE; - } -} - -/* ffestc_is_let_not_V027 -- Context information for FFESTB - - if (ffestc_is_let_not_V027()) ... - - When a statement with the form "PARAMETERname=expr" - is seen, call this function. It returns TRUE if the statement's context - is such that it is an assignment to an object named "PARAMETERname", FALSE - if the statement's context is such that it is a V-extension PARAMETER - statement that is like a PARAMETER(name=expr) statement except that the - type of name is determined by the type of expr, not the implicit or - explicit typing of name. */ - -bool -ffestc_is_let_not_V027 () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - case FFESTV_stateWHERETHEN: - case FFESTV_stateIFTHEN: - case FFESTV_stateDO: - case FFESTV_stateSELECT0: - case FFESTV_stateSELECT1: - case FFESTV_stateWHERE: - case FFESTV_stateIF: - return TRUE; - - default: - return FALSE; - } -} - -/* ffestc_module -- MODULE or MODULE PROCEDURE statement - - ffestc_module(module_name_token,procedure_name_token); - - Decide which is intended, and implement it by calling _R1105_ or - _R1205_. */ - -#if FFESTR_F90 -void -ffestc_module (ffelexToken module, ffelexToken procedure) -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateINTERFACE0: - case FFESTV_stateINTERFACE1: - ffestc_R1205_start (); - ffestc_R1205_item (procedure); - ffestc_R1205_finish (); - break; - - default: - ffestc_R1105 (module); - break; - } -} - -#endif -/* ffestc_private -- Generic PRIVATE statement - - ffestc_end(); - - This is either a PRIVATE within R422 derived-type statement or an - R521 PRIVATE statement. Figure it out based on context and implement - it, or produce an error. */ - -#if FFESTR_F90 -void -ffestc_private () -{ - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateTYPE: - ffestc_R423A (); - break; - - default: - ffestc_R521B (); - break; - } -} - -#endif -/* ffestc_terminate_4 -- Terminate ffestc after scoping unit - - ffestc_terminate_4(); - - For SUBROUTINEs/FUNCTIONs within INTERFACE/END INTERFACE, derived-TYPE- - defs, and statement function defs. */ - -void -ffestc_terminate_4 () -{ - ffestc_entry_num_ = ffestc_saved_entry_num_; -} - -/* ffestc_R423A -- PRIVATE statement (in R422 derived-type statement) - - ffestc_R423A(); */ - -#if FFESTR_F90 -void -ffestc_R423A () -{ - ffestc_check_simple_ (); - if (ffestc_order_type_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - return; - } - - if (ffestw_state (ffestw_previous (ffestw_stack_top ())) != FFESTV_stateMODULE3) - { - ffebad_start (FFEBAD_DERIVTYP_ACCESS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - return; - } - - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen - private-sequence-stmt. */ - - ffestd_R423A (); -} - -/* ffestc_R423B -- SEQUENCE statement (in R422 derived-type-stmt) - - ffestc_R423B(); */ - -void -ffestc_R423B () -{ - ffestc_check_simple_ (); - if (ffestc_order_type_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_DERIVTYP_ACCESS_FIRST); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - return; - } - - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen - private-sequence-stmt. */ - - ffestd_R423B (); -} - -/* ffestc_R424 -- derived-TYPE-def statement - - ffestc_R424(access_token,access_kw,name_token); - - Handle a derived-type definition. */ - -void -ffestc_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name) -{ - ffestw b; - - assert (name != NULL); - - ffestc_check_simple_ (); - if (ffestc_order_derivedtype_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if ((access != NULL) - && (ffestw_state (ffestw_stack_top ()) != FFESTV_stateMODULE3)) - { - ffebad_start (FFEBAD_DERIVTYP_ACCESS); - ffebad_here (0, ffelex_token_where_line (access), - ffelex_token_where_column (access)); - ffebad_finish (); - access = NULL; - } - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateTYPE); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_type_); - ffestw_set_name (b, ffelex_token_use (name)); - ffestw_set_substate (b, 0); /* Awaiting private-sequence-stmt and one - component-def-stmt. */ - - ffestd_R424 (access, access_kw, name); - - ffe_init_4 (); -} - -/* ffestc_R425 -- END TYPE statement - - ffestc_R425(name_token); - - Make sure ffestc_kind_ identifies a TYPE definition. If not - NULL, make sure name_token gives the correct name. Implement the end - of the type definition. */ - -void -ffestc_R425 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_type_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 2) - { - ffebad_start (FFEBAD_DERIVTYP_NO_COMPONENTS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - if ((name != NULL) - && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) - { - ffebad_start (FFEBAD_TYPE_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - - ffestc_shriek_type_ (TRUE); -} - -/* ffestc_R426_start -- component-declaration-stmt - - ffestc_R426_start(...); - - Verify that R426 component-declaration-stmt is - valid here and implement. */ - -void -ffestc_R426_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent) -{ - ffestc_check_start_ (); - if (ffestc_order_component_ () != FFESTC_orderOK_) - { - ffestc_local_.decl.is_R426 = 0; - return; - } - ffestc_labeldef_useless_ (); - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one - member. */ - break; - - case FFESTV_stateTYPE: - ffestw_set_substate (ffestw_stack_top (), 2); - break; - - default: - assert ("Component parent state invalid" == NULL); - break; - } -} - -/* ffestc_R426_attrib -- type attribute - - ffestc_R426_attrib(...); - - Verify that R426 component-declaration-stmt attribute - is valid here and implement. */ - -void -ffestc_R426_attrib (ffestpAttrib attrib, ffelexToken attribt, - ffestrOther intent_kw, ffesttDimList dims) -{ - ffestc_check_attrib_ (); -} - -/* ffestc_R426_item -- declared object - - ffestc_R426_item(...); - - Establish type for a particular object. */ - -void -ffestc_R426_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, - ffelexToken initt, bool clist) -{ - ffestc_check_item_ (); - assert (name != NULL); - assert (ffelex_token_type (name) == FFELEX_typeNAME); /* Not NAMES. */ - assert (kind == NULL); /* No way an expression should get here. */ - - if ((dims != NULL) || (init != NULL) || clist) - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); -} - -/* ffestc_R426_itemstartvals -- Start list of values - - ffestc_R426_itemstartvals(); - - Gonna specify values for the object now. */ - -void -ffestc_R426_itemstartvals () -{ - ffestc_check_item_startvals_ (); -} - -/* ffestc_R426_itemvalue -- Source value - - ffestc_R426_itemvalue(repeat,repeat_token,value,value_token); - - Make sure repeat and value are valid for the object being initialized. */ - -void -ffestc_R426_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token) -{ - ffestc_check_item_value_ (); -} - -/* ffestc_R426_itemendvals -- End list of values - - ffelexToken t; // the SLASH token that ends the list. - ffestc_R426_itemendvals(t); - - No more values, might specify more objects now. */ - -void -ffestc_R426_itemendvals (ffelexToken t) -{ - ffestc_check_item_endvals_ (); -} - -/* ffestc_R426_finish -- Done - - ffestc_R426_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R426_finish () -{ - ffestc_check_finish_ (); -} - -#endif -/* ffestc_R501_start -- type-declaration-stmt - - ffestc_R501_start(...); - - Verify that R501 type-declaration-stmt is - valid here and implement. */ - -void -ffestc_R501_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent) -{ - ffestc_check_start_ (); - if (ffestc_order_typedecl_ () != FFESTC_orderOK_) - { - ffestc_local_.decl.is_R426 = 0; - return; - } - ffestc_labeldef_useless_ (); - - ffestc_establish_declstmt_ (type, typet, kind, kindt, len, lent); -} - -/* ffestc_R501_attrib -- type attribute - - ffestc_R501_attrib(...); - - Verify that R501 type-declaration-stmt attribute - is valid here and implement. */ - -void -ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt, - ffestrOther intent_kw UNUSED, - ffesttDimList dims UNUSED) -{ - ffestc_check_attrib_ (); - - switch (attrib) - { -#if FFESTR_F90 - case FFESTP_attribALLOCATABLE: - break; -#endif - - case FFESTP_attribDIMENSION: - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - break; - - case FFESTP_attribEXTERNAL: - break; - -#if FFESTR_F90 - case FFESTP_attribINTENT: - break; -#endif - - case FFESTP_attribINTRINSIC: - break; - -#if FFESTR_F90 - case FFESTP_attribOPTIONAL: - break; -#endif - - case FFESTP_attribPARAMETER: - break; - -#if FFESTR_F90 - case FFESTP_attribPOINTER: - break; -#endif - -#if FFESTR_F90 - case FFESTP_attribPRIVATE: - break; - - case FFESTP_attribPUBLIC: - break; -#endif - - case FFESTP_attribSAVE: - switch (ffestv_save_state_) - { - case FFESTV_savestateNONE: - ffestv_save_state_ = FFESTV_savestateSPECIFIC; - ffestv_save_line_ - = ffewhere_line_use (ffelex_token_where_line (attribt)); - ffestv_save_col_ - = ffewhere_column_use (ffelex_token_where_column (attribt)); - break; - - case FFESTV_savestateSPECIFIC: - case FFESTV_savestateANY: - break; - - case FFESTV_savestateALL: - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_CONFLICTING_SAVES); - ffebad_here (0, ffestv_save_line_, ffestv_save_col_); - ffebad_here (1, ffelex_token_where_line (attribt), - ffelex_token_where_column (attribt)); - ffebad_finish (); - } - ffestv_save_state_ = FFESTV_savestateANY; - break; - - default: - assert ("unexpected save state" == NULL); - break; - } - break; - -#if FFESTR_F90 - case FFESTP_attribTARGET: - break; -#endif - - default: - assert ("unexpected attribute" == NULL); - break; - } -} - -/* ffestc_R501_item -- declared object - - ffestc_R501_item(...); - - Establish type for a particular object. */ - -void -ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, - ffebld init, ffelexToken initt, bool clist) -{ - ffesymbol s; - ffesymbol sfn; /* FUNCTION symbol. */ - ffebld array_size; - ffebld extents; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffestpDimtype nd; - bool is_init = (init != NULL) || clist; - bool is_assumed; - bool is_ugly_assumed; - ffeinfoRank rank; - - ffestc_check_item_ (); - assert (name != NULL); - assert (ffelex_token_type (name) == FFELEX_typeNAME); /* Not NAMES. */ - assert (kind == NULL); /* No way an expression should get here. */ - - ffestc_establish_declinfo_ (kind, kindt, len, lent); - - is_assumed = (ffestc_local_.decl.basic_type == FFEINFO_basictypeCHARACTER) - && (ffestc_local_.decl.size == FFETARGET_charactersizeNONE); - - if ((dims != NULL) || is_init) - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - s = ffesymbol_declare_local (name, TRUE); - sa = ffesymbol_attrs (s); - - /* First figure out what kind of object this is based solely on the current - object situation (type params, dimension list, and initialization). */ - - na = FFESYMBOL_attrsTYPE; - - if (is_assumed) - na |= FFESYMBOL_attrsANYLEN; - - is_ugly_assumed = (ffe_is_ugly_assumed () - && ((sa & FFESYMBOL_attrsDUMMY) - || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); - - nd = ffestt_dimlist_type (dims, is_ugly_assumed); - switch (nd) - { - case FFESTP_dimtypeNONE: - break; - - case FFESTP_dimtypeKNOWN: - na |= FFESYMBOL_attrsARRAY; - break; - - case FFESTP_dimtypeADJUSTABLE: - na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE; - break; - - case FFESTP_dimtypeASSUMED: - na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYSIZE; - break; - - case FFESTP_dimtypeADJUSTABLEASSUMED: - na |= FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE; - break; - - default: - assert ("unexpected dimtype" == NULL); - na = FFESYMBOL_attrsetNONE; - break; - } - - if (!ffesta_is_entry_valid - && (((na & (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsARRAY)) - == (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsARRAY)))) - na = FFESYMBOL_attrsetNONE; - - if (is_init) - { - if (na == FFESYMBOL_attrsetNONE) - ; - else if (na & (FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE)) - na = FFESYMBOL_attrsetNONE; - else - na |= FFESYMBOL_attrsINIT; - } - - /* Now figure out what kind of object we've got based on previous - declarations of or references to the object. */ - - if (na == FFESYMBOL_attrsetNONE) - ; - else if (!ffesymbol_is_specable (s) - && (((ffesymbol_where (s) != FFEINFO_whereCONSTANT) - && (ffesymbol_where (s) != FFEINFO_whereINTRINSIC)) - || (na & (FFESYMBOL_attrsARRAY | FFESYMBOL_attrsINIT)))) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef, and can't - dimension/init UNDERSTOODs. */ - else if (sa & FFESYMBOL_attrsANY) - na = sa; - else if ((sa & na) - || ((sa & (FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsADJUSTS)) - && (na & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsANYLEN))) - || ((sa & FFESYMBOL_attrsRESULT) - && (na & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsINIT))) - || ((sa & (FFESYMBOL_attrsSFUNC - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsINTRINSIC - | FFESYMBOL_attrsINIT)) - && (na & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsINIT))) - || ((sa & FFESYMBOL_attrsARRAY) - && !ffesta_is_entry_valid - && (na & FFESYMBOL_attrsANYLEN)) - || ((sa & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsDUMMY)) - && (na & FFESYMBOL_attrsINIT)) - || ((sa & (FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV)) - && (na & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE)))) - na = FFESYMBOL_attrsetNONE; - else if ((ffesymbol_kind (s) == FFEINFO_kindENTITY) - && (ffesymbol_where (s) == FFEINFO_whereCONSTANT) - && (na & FFESYMBOL_attrsANYLEN)) - { /* If CHARACTER*(*) FOO after PARAMETER FOO. */ - na |= FFESYMBOL_attrsTYPE; - ffestc_local_.decl.size = ffebld_size (ffesymbol_init (s)); - } - else - na |= sa; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - { - ffesymbol_error (s, name); - ffestc_parent_ok_ = FALSE; - } - else if (na & FFESYMBOL_attrsANY) - ffestc_parent_ok_ = FALSE; - else - { - ffesymbol_set_attrs (s, na); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - rank = ffesymbol_rank (s); - if (dims != NULL) - { - ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, - &array_size, - &extents, - is_ugly_assumed)); - ffesymbol_set_arraysize (s, array_size); - ffesymbol_set_extents (s, extents); - if (!(0 && ffe_is_90 ()) - && (ffebld_op (array_size) == FFEBLD_opCONTER) - && (ffebld_constant_integerdefault (ffebld_conter (array_size)) - == 0)) - { - ffebad_start (FFEBAD_ZERO_ARRAY); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - } - if (init != NULL) - { - ffesymbol_set_init (s, - ffeexpr_convert (init, initt, name, - ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - rank, - ffestc_local_.decl.size, - FFEEXPR_contextDATA)); - ffecom_notify_init_symbol (s); - ffesymbol_update_init (s); -#if FFEGLOBAL_ENABLED - if (ffesymbol_common (s) != NULL) - ffeglobal_init_common (ffesymbol_common (s), initt); -#endif - } - else if (clist) - { - ffebld symter; - - symter = ffebld_new_symter (s, FFEINTRIN_genNONE, - FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - - ffebld_set_info (symter, - ffeinfo_new (ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - rank, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - ffestc_local_.decl.size)); - ffestc_local_.decl.initlist = ffebld_new_item (symter, NULL); - } - if (ffesymbol_basictype (s) == FFEINFO_basictypeNONE) - { - ffesymbol_set_info (s, - ffeinfo_new (ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - rank, - ffesymbol_kind (s), - ffesymbol_where (s), - ffestc_local_.decl.size)); - if ((na & FFESYMBOL_attrsRESULT) - && ((sfn = ffesymbol_funcresult (s)) != NULL)) - { - ffesymbol_set_info (sfn, - ffeinfo_new (ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - rank, - ffesymbol_kind (sfn), - ffesymbol_where (sfn), - ffestc_local_.decl.size)); - ffesymbol_signal_unreported (sfn); - } - } - else if ((ffestc_local_.decl.basic_type != ffesymbol_basictype (s)) - || (ffestc_local_.decl.kind_type != ffesymbol_kindtype (s)) - || ((ffestc_local_.decl.basic_type - == FFEINFO_basictypeCHARACTER) - && (ffestc_local_.decl.size != ffesymbol_size (s)))) - { /* Explicit type disagrees with established - implicit type. */ - ffesymbol_error (s, name); - } - - if ((na & FFESYMBOL_attrsADJUSTS) - && ((ffestc_local_.decl.basic_type != FFEINFO_basictypeINTEGER) - || (ffestc_local_.decl.kind_type != FFEINFO_kindtypeINTEGER1))) - ffesymbol_error (s, name); - - ffesymbol_signal_unreported (s); - ffestc_parent_ok_ = TRUE; - } -} - -/* ffestc_R501_itemstartvals -- Start list of values - - ffestc_R501_itemstartvals(); - - Gonna specify values for the object now. */ - -void -ffestc_R501_itemstartvals () -{ - ffestc_check_item_startvals_ (); - - if (ffestc_parent_ok_) - ffedata_begin (ffestc_local_.decl.initlist); -} - -/* ffestc_R501_itemvalue -- Source value - - ffestc_R501_itemvalue(repeat,repeat_token,value,value_token); - - Make sure repeat and value are valid for the object being initialized. */ - -void -ffestc_R501_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token) -{ - ffetargetIntegerDefault rpt; - - ffestc_check_item_value_ (); - - if (!ffestc_parent_ok_) - return; - - if (repeat == NULL) - rpt = 1; - else if (ffebld_op (repeat) == FFEBLD_opCONTER) - rpt = ffebld_constant_integerdefault (ffebld_conter (repeat)); - else - { - ffestc_parent_ok_ = FALSE; - ffedata_end (TRUE, NULL); - return; - } - - if (!(ffestc_parent_ok_ = ffedata_value (rpt, value, - (repeat_token == NULL) ? value_token : repeat_token))) - ffedata_end (TRUE, NULL); -} - -/* ffestc_R501_itemendvals -- End list of values - - ffelexToken t; // the SLASH token that ends the list. - ffestc_R501_itemendvals(t); - - No more values, might specify more objects now. */ - -void -ffestc_R501_itemendvals (ffelexToken t) -{ - ffestc_check_item_endvals_ (); - - if (ffestc_parent_ok_) - ffestc_parent_ok_ = ffedata_end (FALSE, t); - - if (ffestc_parent_ok_) - ffesymbol_signal_unreported (ffebld_symter (ffebld_head - (ffestc_local_.decl.initlist))); -} - -/* ffestc_R501_finish -- Done - - ffestc_R501_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R501_finish () -{ - ffestc_check_finish_ (); -} - -/* ffestc_R519_start -- INTENT statement list begin - - ffestc_R519_start(); - - Verify that INTENT is valid here, and begin accepting items in the list. */ - -#if FFESTR_F90 -void -ffestc_R519_start (ffelexToken intent, ffestrOther intent_kw) -{ - ffestc_check_start_ (); - if (ffestc_order_spec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R519_start (intent_kw); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R519_item -- INTENT statement for name - - ffestc_R519_item(name_token); - - Make sure name_token identifies a valid object to be INTENTed. */ - -void -ffestc_R519_item (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_R519_item (name); -} - -/* ffestc_R519_finish -- INTENT statement list complete - - ffestc_R519_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R519_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R519_finish (); -} - -/* ffestc_R520_start -- OPTIONAL statement list begin - - ffestc_R520_start(); - - Verify that OPTIONAL is valid here, and begin accepting items in the list. */ - -void -ffestc_R520_start () -{ - ffestc_check_start_ (); - if (ffestc_order_spec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R520_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R520_item -- OPTIONAL statement for name - - ffestc_R520_item(name_token); - - Make sure name_token identifies a valid object to be OPTIONALed. */ - -void -ffestc_R520_item (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_R520_item (name); -} - -/* ffestc_R520_finish -- OPTIONAL statement list complete - - ffestc_R520_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R520_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R520_finish (); -} - -/* ffestc_R521A -- PUBLIC statement - - ffestc_R521A(); - - Verify that PUBLIC is valid here. */ - -void -ffestc_R521A () -{ - ffestc_check_simple_ (); - if (ffestc_order_access_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - switch (ffestv_access_state_) - { - case FFESTV_accessstateNONE: - ffestv_access_state_ = FFESTV_accessstatePUBLIC; - ffestv_access_line_ - = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - ffestv_access_col_ - = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - break; - - case FFESTV_accessstateANY: - break; - - case FFESTV_accessstatePUBLIC: - case FFESTV_accessstatePRIVATE: - ffebad_start (FFEBAD_CONFLICTING_ACCESSES); - ffebad_here (0, ffestv_access_line_, ffestv_access_col_); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - ffestv_access_state_ = FFESTV_accessstateANY; - break; - - default: - assert ("unexpected access state" == NULL); - break; - } - - ffestd_R521A (); -} - -/* ffestc_R521Astart -- PUBLIC statement list begin - - ffestc_R521Astart(); - - Verify that PUBLIC is valid here, and begin accepting items in the list. */ - -void -ffestc_R521Astart () -{ - ffestc_check_start_ (); - if (ffestc_order_access_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R521Astart (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R521Aitem -- PUBLIC statement for name - - ffestc_R521Aitem(name_token); - - Make sure name_token identifies a valid object to be PUBLICed. */ - -void -ffestc_R521Aitem (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_R521Aitem (name); -} - -/* ffestc_R521Afinish -- PUBLIC statement list complete - - ffestc_R521Afinish(); - - Just wrap up any local activities. */ - -void -ffestc_R521Afinish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R521Afinish (); -} - -/* ffestc_R521B -- PRIVATE statement - - ffestc_R521B(); - - Verify that PRIVATE is valid here (outside a derived-type statement). */ - -void -ffestc_R521B () -{ - ffestc_check_simple_ (); - if (ffestc_order_access_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - switch (ffestv_access_state_) - { - case FFESTV_accessstateNONE: - ffestv_access_state_ = FFESTV_accessstatePRIVATE; - ffestv_access_line_ - = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - ffestv_access_col_ - = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - break; - - case FFESTV_accessstateANY: - break; - - case FFESTV_accessstatePUBLIC: - case FFESTV_accessstatePRIVATE: - ffebad_start (FFEBAD_CONFLICTING_ACCESSES); - ffebad_here (0, ffestv_access_line_, ffestv_access_col_); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - ffestv_access_state_ = FFESTV_accessstateANY; - break; - - default: - assert ("unexpected access state" == NULL); - break; - } - - ffestd_R521B (); -} - -/* ffestc_R521Bstart -- PRIVATE statement list begin - - ffestc_R521Bstart(); - - Verify that PRIVATE is valid here, and begin accepting items in the list. */ - -void -ffestc_R521Bstart () -{ - ffestc_check_start_ (); - if (ffestc_order_access_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R521Bstart (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R521Bitem -- PRIVATE statement for name - - ffestc_R521Bitem(name_token); - - Make sure name_token identifies a valid object to be PRIVATEed. */ - -void -ffestc_R521Bitem (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_R521Bitem (name); -} - -/* ffestc_R521Bfinish -- PRIVATE statement list complete - - ffestc_R521Bfinish(); - - Just wrap up any local activities. */ - -void -ffestc_R521Bfinish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R521Bfinish (); -} - -#endif -/* ffestc_R522 -- SAVE statement with no list - - ffestc_R522(); - - Verify that SAVE is valid here, and flag everything as SAVEd. */ - -void -ffestc_R522 () -{ - ffestc_check_simple_ (); - if (ffestc_order_blockspec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - switch (ffestv_save_state_) - { - case FFESTV_savestateNONE: - ffestv_save_state_ = FFESTV_savestateALL; - ffestv_save_line_ - = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - ffestv_save_col_ - = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - break; - - case FFESTV_savestateANY: - break; - - case FFESTV_savestateSPECIFIC: - case FFESTV_savestateALL: - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_CONFLICTING_SAVES); - ffebad_here (0, ffestv_save_line_, ffestv_save_col_); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - ffestv_save_state_ = FFESTV_savestateALL; - break; - - default: - assert ("unexpected save state" == NULL); - break; - } - - ffe_set_is_saveall (TRUE); - - ffestd_R522 (); -} - -/* ffestc_R522start -- SAVE statement list begin - - ffestc_R522start(); - - Verify that SAVE is valid here, and begin accepting items in the list. */ - -void -ffestc_R522start () -{ - ffestc_check_start_ (); - if (ffestc_order_blockspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - switch (ffestv_save_state_) - { - case FFESTV_savestateNONE: - ffestv_save_state_ = FFESTV_savestateSPECIFIC; - ffestv_save_line_ - = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - ffestv_save_col_ - = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - break; - - case FFESTV_savestateSPECIFIC: - case FFESTV_savestateANY: - break; - - case FFESTV_savestateALL: - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_CONFLICTING_SAVES); - ffebad_here (0, ffestv_save_line_, ffestv_save_col_); - ffebad_here (1, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - ffestv_save_state_ = FFESTV_savestateANY; - break; - - default: - assert ("unexpected save state" == NULL); - break; - } - - ffestd_R522start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R522item_object -- SAVE statement for object-name - - ffestc_R522item_object(name_token); - - Make sure name_token identifies a valid object to be SAVEd. */ - -void -ffestc_R522item_object (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s) - && ((ffesymbol_kind (s) != FFEINFO_kindENTITY) - || (ffesymbol_where (s) != FFEINFO_whereLOCAL))) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = sa; - else if (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsSAVE; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_update_save (s); - ffesymbol_signal_unreported (s); - } - - ffestd_R522item_object (name); -} - -/* ffestc_R522item_cblock -- SAVE statement for common-block-name - - ffestc_R522item_cblock(name_token); - - Make sure name_token identifies a valid common block to be SAVEd. */ - -void -ffestc_R522item_cblock (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - s = ffesymbol_declare_cblock (name, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; - else if (sa & FFESYMBOL_attrsANY) - na = sa; /* Already have an error here, say nothing. */ - else if (!(sa & ~(FFESYMBOL_attrsCBLOCK))) - na = sa | FFESYMBOL_attrsSAVECBLOCK; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, (name == NULL) ? ffesta_tokens[0] : name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_update_save (s); - ffesymbol_signal_unreported (s); - } - - ffestd_R522item_cblock (name); -} - -/* ffestc_R522finish -- SAVE statement list complete - - ffestc_R522finish(); - - Just wrap up any local activities. */ - -void -ffestc_R522finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R522finish (); -} - -/* ffestc_R524_start -- DIMENSION statement list begin - - ffestc_R524_start(bool virtual); - - Verify that DIMENSION is valid here, and begin accepting items in the - list. */ - -void -ffestc_R524_start (bool virtual) -{ - ffestc_check_start_ (); - if (ffestc_order_blockspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R524_start (virtual); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R524_item -- DIMENSION statement for object-name - - ffestc_R524_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be DIMENSIONd. */ - -void -ffestc_R524_item (ffelexToken name, ffesttDimList dims) -{ - ffesymbol s; - ffebld array_size; - ffebld extents; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffestpDimtype nd; - ffeinfoRank rank; - bool is_ugly_assumed; - - ffestc_check_item_ (); - assert (name != NULL); - assert (dims != NULL); - if (!ffestc_ok_) - return; - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* First figure out what kind of object this is based solely on the current - object situation (dimension list). */ - - is_ugly_assumed = (ffe_is_ugly_assumed () - && ((sa & FFESYMBOL_attrsDUMMY) - || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); - - nd = ffestt_dimlist_type (dims, is_ugly_assumed); - switch (nd) - { - case FFESTP_dimtypeKNOWN: - na = FFESYMBOL_attrsARRAY; - break; - - case FFESTP_dimtypeADJUSTABLE: - na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE; - break; - - case FFESTP_dimtypeASSUMED: - na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsANYSIZE; - break; - - case FFESTP_dimtypeADJUSTABLEASSUMED: - na = FFESYMBOL_attrsARRAY | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE; - break; - - default: - assert ("Unexpected dims type" == NULL); - na = FFESYMBOL_attrsetNONE; - break; - } - - /* Now figure out what kind of object we've got based on previous - declarations of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (!ffesta_is_entry_valid - && (sa & FFESYMBOL_attrsANYLEN)) - na = FFESYMBOL_attrsetNONE; - else if ((sa & FFESYMBOL_attrsARRAY) - || ((sa & (FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE)) - && (na & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE)))) - na = FFESYMBOL_attrsetNONE; - else if (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsTYPE))) - na |= sa; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, - &array_size, - &extents, - is_ugly_assumed)); - ffesymbol_set_arraysize (s, array_size); - ffesymbol_set_extents (s, extents); - if (!(0 && ffe_is_90 ()) - && (ffebld_op (array_size) == FFEBLD_opCONTER) - && (ffebld_constant_integerdefault (ffebld_conter (array_size)) - == 0)) - { - ffebad_start (FFEBAD_ZERO_ARRAY); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - rank, - ffesymbol_kind (s), - ffesymbol_where (s), - ffesymbol_size (s))); - } - - ffesymbol_signal_unreported (s); - - ffestd_R524_item (name, dims); -} - -/* ffestc_R524_finish -- DIMENSION statement list complete - - ffestc_R524_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R524_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R524_finish (); -} - -/* ffestc_R525_start -- ALLOCATABLE statement list begin - - ffestc_R525_start(); - - Verify that ALLOCATABLE is valid here, and begin accepting items in the - list. */ - -#if FFESTR_F90 -void -ffestc_R525_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R525_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R525_item -- ALLOCATABLE statement for object-name - - ffestc_R525_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be ALLOCATABLEd. */ - -void -ffestc_R525_item (ffelexToken name, ffesttDimList dims) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_R525_item (name, dims); -} - -/* ffestc_R525_finish -- ALLOCATABLE statement list complete - - ffestc_R525_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R525_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R525_finish (); -} - -/* ffestc_R526_start -- POINTER statement list begin - - ffestc_R526_start(); - - Verify that POINTER is valid here, and begin accepting items in the - list. */ - -void -ffestc_R526_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R526_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R526_item -- POINTER statement for object-name - - ffestc_R526_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be POINTERd. */ - -void -ffestc_R526_item (ffelexToken name, ffesttDimList dims) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_R526_item (name, dims); -} - -/* ffestc_R526_finish -- POINTER statement list complete - - ffestc_R526_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R526_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R526_finish (); -} - -/* ffestc_R527_start -- TARGET statement list begin - - ffestc_R527_start(); - - Verify that TARGET is valid here, and begin accepting items in the - list. */ - -void -ffestc_R527_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R527_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R527_item -- TARGET statement for object-name - - ffestc_R527_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be TARGETd. */ - -void -ffestc_R527_item (ffelexToken name, ffesttDimList dims) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_R527_item (name, dims); -} - -/* ffestc_R527_finish -- TARGET statement list complete - - ffestc_R527_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R527_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R527_finish (); -} - -#endif -/* ffestc_R528_start -- DATA statement list begin - - ffestc_R528_start(); - - Verify that DATA is valid here, and begin accepting items in the list. */ - -void -ffestc_R528_start () -{ - ffestcOrder_ order; - - ffestc_check_start_ (); - if (ffe_is_pedantic_not_90 ()) - order = ffestc_order_data77_ (); - else - order = ffestc_order_data_ (); - if (order != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - -#if 1 - ffestc_local_.data.objlist = NULL; -#else - ffestd_R528_start_ (); -#endif - - ffestc_ok_ = TRUE; -} - -/* ffestc_R528_item_object -- DATA statement target object - - ffestc_R528_item_object(object,object_token); - - Make sure object is valid to be DATAd. */ - -void -ffestc_R528_item_object (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - -#if 1 - if (ffestc_local_.data.objlist == NULL) - ffebld_init_list (&ffestc_local_.data.objlist, - &ffestc_local_.data.list_bottom); - - ffebld_append_item (&ffestc_local_.data.list_bottom, expr); -#else - ffestd_R528_item_object_ (expr, expr_token); -#endif -} - -/* ffestc_R528_item_startvals -- DATA statement start list of values - - ffestc_R528_item_startvals(); - - No more objects, gonna specify values for the list of objects now. */ - -void -ffestc_R528_item_startvals () -{ - ffestc_check_item_startvals_ (); - if (!ffestc_ok_) - return; - -#if 1 - assert (ffestc_local_.data.objlist != NULL); - ffebld_end_list (&ffestc_local_.data.list_bottom); - ffedata_begin (ffestc_local_.data.objlist); -#else - ffestd_R528_item_startvals_ (); -#endif -} - -/* ffestc_R528_item_value -- DATA statement source value - - ffestc_R528_item_value(repeat,repeat_token,value,value_token); - - Make sure repeat and value are valid for the objects being initialized. */ - -void -ffestc_R528_item_value (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token) -{ - ffetargetIntegerDefault rpt; - - ffestc_check_item_value_ (); - if (!ffestc_ok_) - return; - -#if 1 - if (repeat == NULL) - rpt = 1; - else if (ffebld_op (repeat) == FFEBLD_opCONTER) - rpt = ffebld_constant_integerdefault (ffebld_conter (repeat)); - else - { - ffestc_ok_ = FALSE; - ffedata_end (TRUE, NULL); - return; - } - - if (!(ffestc_ok_ = ffedata_value (rpt, value, - (repeat_token == NULL) - ? value_token - : repeat_token))) - ffedata_end (TRUE, NULL); - -#else - ffestd_R528_item_value_ (repeat, value); -#endif -} - -/* ffestc_R528_item_endvals -- DATA statement start list of values - - ffelexToken t; // the SLASH token that ends the list. - ffestc_R528_item_endvals(t); - - No more values, might specify more objects now. */ - -void -ffestc_R528_item_endvals (ffelexToken t) -{ - ffestc_check_item_endvals_ (); - if (!ffestc_ok_) - return; - -#if 1 - ffedata_end (!ffestc_ok_, t); - ffestc_local_.data.objlist = NULL; -#else - ffestd_R528_item_endvals_ (t); -#endif -} - -/* ffestc_R528_finish -- DATA statement list complete - - ffestc_R528_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R528_finish () -{ - ffestc_check_finish_ (); - -#if 1 -#else - ffestd_R528_finish_ (); -#endif -} - -/* ffestc_R537_start -- PARAMETER statement list begin - - ffestc_R537_start(); - - Verify that PARAMETER is valid here, and begin accepting items in the - list. */ - -void -ffestc_R537_start () -{ - ffestc_check_start_ (); - if (ffestc_order_parameter_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_R537_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R537_item -- PARAMETER statement assignment - - ffestc_R537_item(dest,dest_token,source,source_token); - - Make sure the source is a valid source for the destination; make the - assignment. */ - -void -ffestc_R537_item (ffebld dest, ffelexToken dest_token, ffebld source, - ffelexToken source_token) -{ - ffesymbol s; - - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if ((ffebld_op (dest) == FFEBLD_opANY) - || (ffebld_op (source) == FFEBLD_opANY)) - { - if (ffebld_op (dest) == FFEBLD_opSYMTER) - { - s = ffebld_symter (dest); - ffesymbol_set_init (s, ffebld_new_any ()); - ffebld_set_info (ffesymbol_init (s), ffeinfo_new_any ()); - ffesymbol_signal_unreported (s); - } - ffestd_R537_item (dest, source); - return; - } - - assert (ffebld_op (dest) == FFEBLD_opSYMTER); - assert (ffebld_op (source) == FFEBLD_opCONTER); - - s = ffebld_symter (dest); - if ((ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) - && (ffesymbol_size (s) == FFETARGET_charactersizeNONE)) - { /* Destination has explicit/implicit - CHARACTER*(*) type; set length. */ - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - ffesymbol_kind (s), - ffesymbol_where (s), - ffebld_size (source))); - ffebld_set_info (dest, ffeinfo_use (ffesymbol_info (s))); - } - - source = ffeexpr_convert_expr (source, source_token, dest, dest_token, - FFEEXPR_contextDATA); - - ffesymbol_set_init (s, source); - - ffesymbol_signal_unreported (s); - - ffestd_R537_item (dest, source); -} - -/* ffestc_R537_finish -- PARAMETER statement list complete - - ffestc_R537_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R537_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R537_finish (); -} - -/* ffestc_R539 -- IMPLICIT NONE statement - - ffestc_R539(); - - Verify that the IMPLICIT NONE statement is ok here and implement. */ - -void -ffestc_R539 () -{ - ffestc_check_simple_ (); - if (ffestc_order_implicitnone_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffeimplic_none (); - - ffestd_R539 (); -} - -/* ffestc_R539start -- IMPLICIT statement - - ffestc_R539start(); - - Verify that the IMPLICIT statement is ok here and implement. */ - -void -ffestc_R539start () -{ - ffestc_check_start_ (); - if (ffestc_order_implicit_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R539start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R539item -- IMPLICIT statement specification (R540) - - ffestc_R539item(...); - - Verify that the type and letter list are all ok and implement. */ - -void -ffestc_R539item (ffestpType type, ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent, ffesttImpList letters) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if ((type == FFESTP_typeCHARACTER) && (len != NULL) - && (ffebld_op (len) == FFEBLD_opSTAR)) - { /* Complain and pretend they're CHARACTER - [*1]. */ - ffebad_start (FFEBAD_IMPLICIT_ADJLEN); - ffebad_here (0, ffelex_token_where_line (lent), - ffelex_token_where_column (lent)); - ffebad_finish (); - len = NULL; - lent = NULL; - } - ffestc_establish_declstmt_ (type, ffesta_tokens[0], kind, kindt, len, lent); - ffestc_establish_declinfo_ (NULL, NULL, NULL, NULL); - - ffestt_implist_drive (letters, ffestc_establish_impletter_); - - ffestd_R539item (type, kind, kindt, len, lent, letters); -} - -/* ffestc_R539finish -- IMPLICIT statement - - ffestc_R539finish(); - - Finish up any local activities. */ - -void -ffestc_R539finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R539finish (); -} - -/* ffestc_R542_start -- NAMELIST statement list begin - - ffestc_R542_start(); - - Verify that NAMELIST is valid here, and begin accepting items in the - list. */ - -void -ffestc_R542_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - if (ffe_is_f2c_library () - && (ffe_case_source () == FFE_caseNONE)) - { - ffebad_start (FFEBAD_NAMELIST_CASE); - ffesta_ffebad_here_current_stmt (0); - ffebad_finish (); - } - - ffestd_R542_start (); - - ffestc_local_.namelist.symbol = NULL; - - ffestc_ok_ = TRUE; -} - -/* ffestc_R542_item_nlist -- NAMELIST statement for group-name - - ffestc_R542_item_nlist(groupname_token); - - Make sure name_token identifies a valid object to be NAMELISTd. */ - -void -ffestc_R542_item_nlist (ffelexToken name) -{ - ffesymbol s; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - if (ffestc_local_.namelist.symbol != NULL) - ffesymbol_signal_unreported (ffestc_local_.namelist.symbol); - - s = ffesymbol_declare_local (name, FALSE); - - if ((ffesymbol_state (s) == FFESYMBOL_stateNONE) - || ((ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - && (ffesymbol_kind (s) == FFEINFO_kindNAMELIST))) - { - ffestc_parent_ok_ = TRUE; - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffebld_init_list (ffesymbol_ptr_to_namelist (s), - ffesymbol_ptr_to_listbottom (s)); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNAMELIST, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - } - } - else - { - if (ffesymbol_kind (s) != FFEINFO_kindANY) - ffesymbol_error (s, name); - ffestc_parent_ok_ = FALSE; - } - - ffestc_local_.namelist.symbol = s; - - ffestd_R542_item_nlist (name); -} - -/* ffestc_R542_item_nitem -- NAMELIST statement for variable-name - - ffestc_R542_item_nitem(name_token); - - Make sure name_token identifies a valid object to be NAMELISTd. */ - -void -ffestc_R542_item_nitem (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffebld e; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s) - && ((ffesymbol_kind (s) != FFEINFO_kindENTITY) - || ((ffesymbol_where (s) != FFEINFO_whereLOCAL) - && (ffesymbol_where (s) != FFEINFO_whereCOMMON)))) - na = FFESYMBOL_attrsetNONE; - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsNAMELIST; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_namelisted (s, TRUE); - ffesymbol_signal_unreported (s); -#if 0 /* No need to establish type yet! */ - if (!ffeimplic_establish_symbol (s)) - ffesymbol_error (s, name); -#endif - } - - if (ffestc_parent_ok_) - { - e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (e, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE)); - ffebld_append_item - (ffesymbol_ptr_to_listbottom (ffestc_local_.namelist.symbol), e); - } - - ffestd_R542_item_nitem (name); -} - -/* ffestc_R542_finish -- NAMELIST statement list complete - - ffestc_R542_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R542_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffesymbol_signal_unreported (ffestc_local_.namelist.symbol); - - ffestd_R542_finish (); -} - -/* ffestc_R544_start -- EQUIVALENCE statement list begin - - ffestc_R544_start(); - - Verify that EQUIVALENCE is valid here, and begin accepting items in the - list. */ - -void -ffestc_R544_start () -{ - ffestc_check_start_ (); - if (ffestc_order_blockspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R544_item -- EQUIVALENCE statement assignment - - ffestc_R544_item(exprlist); - - Make sure the equivalence is valid, then implement it. */ - -void -ffestc_R544_item (ffesttExprList exprlist) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - /* First we go through the list and come up with one ffeequiv object that - will describe all items in the list. When an ffeequiv object is first - found, it is used (else we create one as a "local equiv" for the time - being). If subsequent ffeequiv objects are found, they are merged with - the first so we end up with one. However, if more than one COMMON - variable is involved, then an error condition occurs. */ - - ffestc_local_.equiv.ok = TRUE; - ffestc_local_.equiv.t = NULL; /* No token yet. */ - ffestc_local_.equiv.eq = NULL;/* No equiv yet. */ - ffestc_local_.equiv.save = FALSE; /* No SAVEd variables yet. */ - - ffebld_init_list (&ffestc_local_.equiv.list, &ffestc_local_.equiv.bottom); - ffestt_exprlist_drive (exprlist, ffestc_R544_equiv_); /* Get one equiv. */ - ffebld_end_list (&ffestc_local_.equiv.bottom); - - if (!ffestc_local_.equiv.ok) - return; /* Something went wrong, stop bothering with - this stuff. */ - - if (ffestc_local_.equiv.eq == NULL) - ffestc_local_.equiv.eq = ffeequiv_new (); /* Make local equivalence. */ - - /* Append this list of equivalences to list of such lists for this - equivalence. */ - - ffeequiv_add (ffestc_local_.equiv.eq, ffestc_local_.equiv.list, - ffestc_local_.equiv.t); - if (ffestc_local_.equiv.save) - ffeequiv_update_save (ffestc_local_.equiv.eq); -} - -/* ffestc_R544_equiv_ -- EQUIVALENCE statement handler for item in list - - ffebld expr; - ffelexToken t; - ffestc_R544_equiv_(expr,t); - - Record information, if any, on symbol in expr; if symbol has equivalence - object already, merge with outstanding object if present or make it - the outstanding object. */ - -static void -ffestc_R544_equiv_ (ffebld expr, ffelexToken t) -{ - ffesymbol s; - - if (!ffestc_local_.equiv.ok) - return; - - if (ffestc_local_.equiv.t == NULL) - ffestc_local_.equiv.t = t; - - switch (ffebld_op (expr)) - { - case FFEBLD_opANY: - return; /* Don't put this on the list. */ - - case FFEBLD_opSYMTER: - case FFEBLD_opARRAYREF: - case FFEBLD_opSUBSTR: - break; /* All of these are ok. */ - - default: - assert ("ffestc_R544_equiv_ bad op" == NULL); - return; - } - - ffebld_append_item (&ffestc_local_.equiv.bottom, expr); - - s = ffeequiv_symbol (expr); - - /* See if symbol has an equivalence object already. */ - - if (ffesymbol_equiv (s) != NULL) - { - if (ffestc_local_.equiv.eq == NULL) - ffestc_local_.equiv.eq = ffesymbol_equiv (s); /* New equiv obj. */ - else if (ffestc_local_.equiv.eq != ffesymbol_equiv (s)) - { - ffestc_local_.equiv.eq = ffeequiv_merge (ffesymbol_equiv (s), - ffestc_local_.equiv.eq, - t); - if (ffestc_local_.equiv.eq == NULL) - ffestc_local_.equiv.ok = FALSE; /* Couldn't merge. */ - } - } - - if (ffesymbol_is_save (s)) - ffestc_local_.equiv.save = TRUE; -} - -/* ffestc_R544_finish -- EQUIVALENCE statement list complete - - ffestc_R544_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R544_finish () -{ - ffestc_check_finish_ (); -} - -/* ffestc_R547_start -- COMMON statement list begin - - ffestc_R547_start(); - - Verify that COMMON is valid here, and begin accepting items in the list. */ - -void -ffestc_R547_start () -{ - ffestc_check_start_ (); - if (ffestc_order_blockspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestc_local_.common.symbol = NULL; /* Blank common is the default. */ - ffestc_parent_ok_ = TRUE; - - ffestd_R547_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R547_item_object -- COMMON statement for object-name - - ffestc_R547_item_object(name_token,dim_list); - - Make sure name_token identifies a valid object to be COMMONd. */ - -void -ffestc_R547_item_object (ffelexToken name, ffesttDimList dims) -{ - ffesymbol s; - ffebld array_size; - ffebld extents; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffestpDimtype nd; - ffebld e; - ffeinfoRank rank; - bool is_ugly_assumed; - - if (ffestc_parent_ok_ && (ffestc_local_.common.symbol == NULL)) - ffestc_R547_item_cblock (NULL); /* As if "COMMON [//] ...". */ - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - if (dims != NULL) - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* First figure out what kind of object this is based solely on the current - object situation (dimension list). */ - - is_ugly_assumed = (ffe_is_ugly_assumed () - && ((sa & FFESYMBOL_attrsDUMMY) - || (ffesymbol_where (s) == FFEINFO_whereDUMMY))); - - nd = ffestt_dimlist_type (dims, is_ugly_assumed); - switch (nd) - { - case FFESTP_dimtypeNONE: - na = FFESYMBOL_attrsCOMMON; - break; - - case FFESTP_dimtypeKNOWN: - na = FFESYMBOL_attrsCOMMON | FFESYMBOL_attrsARRAY; - break; - - default: - na = FFESYMBOL_attrsetNONE; - break; - } - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (na == FFESYMBOL_attrsetNONE) - ; - else if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if ((sa & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsSFARG)) - && (na & FFESYMBOL_attrsARRAY)) - na = FFESYMBOL_attrsetNONE; - else if (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))) - na |= sa; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if ((ffesymbol_equiv (s) != NULL) - && (ffeequiv_common (ffesymbol_equiv (s)) != NULL) - && (ffeequiv_common (ffesymbol_equiv (s)) - != ffestc_local_.common.symbol)) - { - /* Oops, just COMMONed a symbol to a different area (via equiv). */ - ffebad_start (FFEBAD_EQUIV_COMMON); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_string (ffesymbol_text (ffestc_local_.common.symbol)); - ffebad_string (ffesymbol_text (ffeequiv_common (ffesymbol_equiv (s)))); - ffebad_finish (); - ffesymbol_set_attr (s, na | FFESYMBOL_attrANY); - ffesymbol_set_info (s, ffeinfo_new_any ()); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_signal_unreported (s); - } - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_common (s, ffestc_local_.common.symbol); -#if FFEGLOBAL_ENABLED - if (ffesymbol_is_init (s)) - ffeglobal_init_common (ffestc_local_.common.symbol, name); -#endif - if (ffesymbol_is_save (ffestc_local_.common.symbol)) - ffesymbol_update_save (s); - if (ffesymbol_equiv (s) != NULL) - { /* Is this newly COMMONed symbol involved in - an equivalence? */ - if (ffeequiv_common (ffesymbol_equiv (s)) == NULL) - ffeequiv_set_common (ffesymbol_equiv (s), /* Yes, tell equiv obj. */ - ffestc_local_.common.symbol); -#if FFEGLOBAL_ENABLED - if (ffeequiv_is_init (ffesymbol_equiv (s))) - ffeglobal_init_common (ffestc_local_.common.symbol, name); -#endif - if (ffesymbol_is_save (ffestc_local_.common.symbol)) - ffeequiv_update_save (ffesymbol_equiv (s)); - } - if (dims != NULL) - { - ffesymbol_set_dims (s, ffestt_dimlist_as_expr (dims, &rank, - &array_size, - &extents, - is_ugly_assumed)); - ffesymbol_set_arraysize (s, array_size); - ffesymbol_set_extents (s, extents); - if (!(0 && ffe_is_90 ()) - && (ffebld_op (array_size) == FFEBLD_opCONTER) - && (ffebld_constant_integerdefault (ffebld_conter (array_size)) - == 0)) - { - ffebad_start (FFEBAD_ZERO_ARRAY); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - rank, - ffesymbol_kind (s), - ffesymbol_where (s), - ffesymbol_size (s))); - } - ffesymbol_signal_unreported (s); - } - - if (ffestc_parent_ok_) - { - e = ffebld_new_symter (s, FFEINTRIN_genNONE, FFEINTRIN_specNONE, - FFEINTRIN_impNONE); - ffebld_set_info (e, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - FFETARGET_charactersizeNONE)); - ffebld_append_item - (ffesymbol_ptr_to_listbottom (ffestc_local_.common.symbol), e); - } - - ffestd_R547_item_object (name, dims); -} - -/* ffestc_R547_item_cblock -- COMMON statement for common-block-name - - ffestc_R547_item_cblock(name_token); - - Make sure name_token identifies a valid common block to be COMMONd. */ - -void -ffestc_R547_item_cblock (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_local_.common.symbol != NULL) - ffesymbol_signal_unreported (ffestc_local_.common.symbol); - - s = ffesymbol_declare_cblock (name, - ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; /* Already have an error here, say nothing. */ - else if (!(sa & ~(FFESYMBOL_attrsCBLOCK - | FFESYMBOL_attrsSAVECBLOCK))) - { - if (!(sa & FFESYMBOL_attrsCBLOCK)) - ffebld_init_list (ffesymbol_ptr_to_commonlist (s), - ffesymbol_ptr_to_listbottom (s)); - na = sa | FFESYMBOL_attrsCBLOCK; - } - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - { - ffesymbol_error (s, name == NULL ? ffesta_tokens[0] : name); - ffestc_parent_ok_ = FALSE; - } - else if (na & FFESYMBOL_attrsANY) - ffestc_parent_ok_ = FALSE; - else - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - if (name == NULL) - ffesymbol_update_save (s); - ffestc_parent_ok_ = TRUE; - } - - ffestc_local_.common.symbol = s; - - ffestd_R547_item_cblock (name); -} - -/* ffestc_R547_finish -- COMMON statement list complete - - ffestc_R547_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R547_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - if (ffestc_local_.common.symbol != NULL) - ffesymbol_signal_unreported (ffestc_local_.common.symbol); - - ffestd_R547_finish (); -} - -/* ffestc_R620 -- ALLOCATE statement - - ffestc_R620(exprlist,stat,stat_token); - - Make sure the expression list is valid, then implement it. */ - -#if FFESTR_F90 -void -ffestc_R620 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R620 (exprlist, stat); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R624 -- NULLIFY statement - - ffestc_R624(pointer_name_list); - - Make sure pointer_name_list identifies valid pointers for a NULLIFY. */ - -void -ffestc_R624 (ffesttExprList pointers) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R624 (pointers); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R625 -- DEALLOCATE statement - - ffestc_R625(exprlist,stat,stat_token); - - Make sure the equivalence is valid, then implement it. */ - -void -ffestc_R625 (ffesttExprList exprlist, ffebld stat, ffelexToken stat_token) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R625 (exprlist, stat); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -#endif -/* ffestc_let -- R1213 or R737 - - ffestc_let(...); - - Verify that R1213 defined-assignment or R737 assignment-stmt are - valid here, figure out which one, and implement. */ - -#if FFESTR_F90 -void -ffestc_let (ffebld dest, ffebld source, ffelexToken source_token) -{ - ffestc_R737 (dest, source, source_token); -} - -#endif -/* ffestc_R737 -- Assignment statement - - ffestc_R737(dest_expr,source_expr,source_token); - - Make sure the assignment is valid. */ - -void -ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token) -{ - ffestc_check_simple_ (); - - switch (ffestw_state (ffestw_stack_top ())) - { -#if FFESTR_F90 - case FFESTV_stateWHERE: - case FFESTV_stateWHERETHEN: - if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestd_R737B (dest, source); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - return; -#endif - - default: - break; - } - - if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - source = ffeexpr_convert_expr (source, source_token, dest, ffesta_tokens[0], - FFEEXPR_contextLET); - - ffestd_R737A (dest, source); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R738 -- Pointer assignment statement - - ffestc_R738(dest_expr,source_expr,source_token); - - Make sure the assignment is valid. */ - -#if FFESTR_F90 -void -ffestc_R738 (ffebld dest, ffebld source, ffelexToken source_token) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R738 (dest, source); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R740 -- WHERE statement - - ffestc_R740(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R740 (ffebld expr, ffelexToken expr_token) -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); - ffestw_set_state (b, FFESTV_stateWHERE); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_where_lost_); - - ffestd_R740 (expr); - - /* Leave label finishing to next statement. */ - -} - -/* ffestc_R742 -- WHERE-construct statement - - ffestc_R742(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R742 (ffebld expr, ffelexToken expr_token) -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_probably_this_wont_work_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); - ffestw_set_state (b, FFESTV_stateWHERETHEN); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_wherethen_); - ffestw_set_substate (b, 0); /* Haven't seen ELSEWHERE yet. */ - - ffestd_R742 (expr); -} - -/* ffestc_R744 -- ELSE WHERE statement - - ffestc_R744(); - - Make sure ffestc_kind_ identifies a WHERE block. - Implement the ELSE of the current WHERE block. */ - -void -ffestc_R744 () -{ - ffestc_check_simple_ (); - if (ffestc_order_where_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_SECOND_ELSE_WHERE); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSEWHERE. */ - - ffestd_R744 (); -} - -/* ffestc_R745 -- END WHERE statement - - ffestc_R745(); - - Make sure ffestc_kind_ identifies a WHERE block. - Implement the end of the current WHERE block. */ - -void -ffestc_R745 () -{ - ffestc_check_simple_ (); - if (ffestc_order_where_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_shriek_wherethen_ (TRUE); -} - -#endif -/* ffestc_R803 -- Block IF (IF-THEN) statement - - ffestc_R803(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R803 (ffelexToken construct_name, ffebld expr, - ffelexToken expr_token UNUSED) -{ - ffestw b; - ffesymbol s; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); - ffestw_set_state (b, FFESTV_stateIFTHEN); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_ifthen_); - ffestw_set_substate (b, 0); /* Haven't seen ELSE yet. */ - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - s = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, construct_name); - } - - ffestd_R803 (construct_name, expr); -} - -/* ffestc_R804 -- ELSE IF statement - - ffestc_R804(expr,expr_token,name_token); - - Make sure ffestc_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the else - of the IF block. */ - -void -ffestc_R804 (ffebld expr, ffelexToken expr_token UNUSED, - ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_ifthen_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (name != NULL) - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, - ffestw_name (ffestw_stack_top ())) - != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_AFTER_ELSE); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - return; /* Don't upset back end with ELSEIF - after ELSE. */ - } - - ffestd_R804 (expr, name); -} - -/* ffestc_R805 -- ELSE statement - - ffestc_R805(name_token); - - Make sure ffestc_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the ELSE - of the IF block. */ - -void -ffestc_R805 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_ifthen_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (name != NULL) - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_AFTER_ELSE); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - return; /* Tell back end about only one ELSE. */ - } - - ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSE. */ - - ffestd_R805 (name); -} - -/* ffestc_R806 -- END IF statement - - ffestc_R806(name_token); - - Make sure ffestc_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the end - of the IF block. */ - -void -ffestc_R806 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_ifthen_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_endif_ (); - - if (name == NULL) - { - if (ffestw_name (ffestw_stack_top ()) != NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NAMED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - } - else - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - ffestc_shriek_ifthen_ (TRUE); -} - -/* ffestc_R807 -- Logical IF statement - - ffestc_R807(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R807 (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_action_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); - ffestw_set_state (b, FFESTV_stateIF); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_if_lost_); - - ffestd_R807 (expr); - - /* Do the label finishing in the next statement. */ - -} - -/* ffestc_R809 -- SELECT CASE statement - - ffestc_R809(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R809 (ffelexToken construct_name, ffebld expr, ffelexToken expr_token) -{ - ffestw b; - mallocPool pool; - ffestwSelect s; - ffesymbol sym; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, ffestw_top_do (ffestw_previous (b))); - ffestw_set_state (b, FFESTV_stateSELECT0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_select_); - ffestw_set_substate (b, 0); /* Haven't seen CASE DEFAULT yet. */ - - /* Init block to manage CASE list. */ - - pool = malloc_pool_new ("Select", ffe_pool_any_unit (), 1024); - s = (ffestwSelect) malloc_new_kp (pool, "Select", sizeof (*s)); - s->first_rel = (ffestwCase) &s->first_rel; - s->last_rel = (ffestwCase) &s->first_rel; - s->first_stmt = (ffestwCase) &s->first_rel; - s->last_stmt = (ffestwCase) &s->first_rel; - s->pool = pool; - s->cases = 1; - s->t = ffelex_token_use (expr_token); - s->type = ffeinfo_basictype (ffebld_info (expr)); - s->kindtype = ffeinfo_kindtype (ffebld_info (expr)); - ffestw_set_select (b, s); - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - sym = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (sym) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (sym, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (sym, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - sym = ffecom_sym_learned (sym); - ffesymbol_signal_unreported (sym); - } - else - ffesymbol_error (sym, construct_name); - } - - ffestd_R809 (construct_name, expr); -} - -/* ffestc_R810 -- CASE statement - - ffestc_R810(case_value_range_list,name); - - If case_value_range_list is NULL, it's CASE DEFAULT. name is the case- - construct-name. Make sure no more than one CASE DEFAULT is present for - a given case-construct and that there aren't any overlapping ranges or - duplicate case values. */ - -void -ffestc_R810 (ffesttCaseList cases, ffelexToken name) -{ - ffesttCaseList caseobj; - ffestwSelect s; - ffestwCase c, nc; - ffebldConstant expr1c, expr2c; - - ffestc_check_simple_ (); - if (ffestc_order_selectcase_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - s = ffestw_select (ffestw_stack_top ()); - - if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateSELECT0) - { -#if 0 /* Not sure we want to have msgs point here - instead of SELECT CASE. */ - ffestw_update (NULL); /* Update state line/col info. */ -#endif - ffestw_set_state (ffestw_stack_top (), FFESTV_stateSELECT1); - } - - if (name != NULL) - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, - ffestw_name (ffestw_stack_top ())) - != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - if (cases == NULL) - { - if (ffestw_substate (ffestw_stack_top ()) != 0) - { - ffebad_start (FFEBAD_CASE_SECOND_DEFAULT); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestw_set_substate (ffestw_stack_top (), 1); /* Saw ELSE. */ - } - else - { /* For each case, try to fit into sorted list - of ranges. */ - for (caseobj = cases->next; caseobj != cases; caseobj = caseobj->next) - { - if ((caseobj->expr1 == NULL) - && (!caseobj->range - || (caseobj->expr2 == NULL))) - { /* "CASE (:)". */ - ffebad_start (FFEBAD_CASE_BAD_RANGE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_finish (); - continue; - } - - if (((caseobj->expr1 != NULL) - && ((ffeinfo_basictype (ffebld_info (caseobj->expr1)) - != s->type) - || (ffeinfo_kindtype (ffebld_info (caseobj->expr1)) - != s->kindtype))) - || ((caseobj->range) - && (caseobj->expr2 != NULL) - && ((ffeinfo_basictype (ffebld_info (caseobj->expr2)) - != s->type) - || (ffeinfo_kindtype (ffebld_info (caseobj->expr2)) - != s->kindtype)))) - { - ffebad_start (FFEBAD_CASE_TYPE_DISAGREE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_here (1, ffelex_token_where_line (s->t), - ffelex_token_where_column (s->t)); - ffebad_finish (); - continue; - } - - if ((s->type == FFEINFO_basictypeLOGICAL) && (caseobj->range)) - { - ffebad_start (FFEBAD_CASE_LOGICAL_RANGE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_finish (); - continue; - } - - if (caseobj->expr1 == NULL) - expr1c = NULL; - else if (ffebld_op (caseobj->expr1) != FFEBLD_opCONTER) - continue; /* opANY. */ - else - expr1c = ffebld_conter (caseobj->expr1); - - if (!caseobj->range) - expr2c = expr1c; /* expr1c and expr2c are NOT NULL in this - case. */ - else if (caseobj->expr2 == NULL) - expr2c = NULL; - else if (ffebld_op (caseobj->expr2) != FFEBLD_opCONTER) - continue; /* opANY. */ - else - expr2c = ffebld_conter (caseobj->expr2); - - if (expr1c == NULL) - { /* "CASE (:high)", must be first in list. */ - c = s->first_rel; - if ((c != (ffestwCase) &s->first_rel) - && ((c->low == NULL) - || (ffebld_constant_cmp (expr2c, c->low) >= 0))) - { /* Other "CASE (:high)" or lowest "CASE - (low[:high])" low. */ - ffebad_start (FFEBAD_CASE_DUPLICATE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_here (1, ffelex_token_where_line (c->t), - ffelex_token_where_column (c->t)); - ffebad_finish (); - continue; - } - } - else if (expr2c == NULL) - { /* "CASE (low:)", must be last in list. */ - c = s->last_rel; - if ((c != (ffestwCase) &s->first_rel) - && ((c->high == NULL) - || (ffebld_constant_cmp (expr1c, c->high) <= 0))) - { /* Other "CASE (low:)" or lowest "CASE - ([low:]high)" high. */ - ffebad_start (FFEBAD_CASE_DUPLICATE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_here (1, ffelex_token_where_line (c->t), - ffelex_token_where_column (c->t)); - ffebad_finish (); - continue; - } - c = c->next_rel; /* Same as c = (ffestwCase) &s->first;. */ - } - else - { /* (expr1c != NULL) && (expr2c != NULL). */ - if (ffebld_constant_cmp (expr1c, expr2c) > 0) - { /* Such as "CASE (3:1)" or "CASE ('B':'A')". */ - ffebad_start (FFEBAD_CASE_RANGE_USELESS); /* Warn/inform only. */ - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_finish (); - continue; - } - for (c = s->first_rel; - (c != (ffestwCase) &s->first_rel) - && ((c->low == NULL) - || (ffebld_constant_cmp (expr1c, c->low) > 0)); - c = c->next_rel) - ; - nc = c; /* Which one to report? */ - if (((c != (ffestwCase) &s->first_rel) - && (ffebld_constant_cmp (expr2c, c->low) >= 0)) - || (((nc = c->previous_rel) != (ffestwCase) &s->first_rel) - && (ffebld_constant_cmp (expr1c, nc->high) <= 0))) - { /* Interference with range in case nc. */ - ffebad_start (FFEBAD_CASE_DUPLICATE); - ffebad_here (0, ffelex_token_where_line (caseobj->t), - ffelex_token_where_column (caseobj->t)); - ffebad_here (1, ffelex_token_where_line (nc->t), - ffelex_token_where_column (nc->t)); - ffebad_finish (); - continue; - } - } - - /* If we reach here for this case range/value, it's ok (sorts into - the list of ranges/values) so we give it its own case object - sorted into the list of case statements. */ - - nc = malloc_new_kp (s->pool, "Case range", sizeof (*nc)); - nc->next_rel = c; - nc->previous_rel = c->previous_rel; - nc->next_stmt = (ffestwCase) &s->first_rel; - nc->previous_stmt = s->last_stmt; - nc->low = expr1c; - nc->high = expr2c; - nc->casenum = s->cases; - nc->t = ffelex_token_use (caseobj->t); - nc->next_rel->previous_rel = nc; - nc->previous_rel->next_rel = nc; - nc->next_stmt->previous_stmt = nc; - nc->previous_stmt->next_stmt = nc; - } - } - - ffestd_R810 ((cases == NULL) ? 0 : s->cases); - - s->cases++; /* Increment # of cases. */ -} - -/* ffestc_R811 -- END SELECT statement - - ffestc_R811(name_token); - - Make sure ffestc_kind_ identifies a SELECT block. If not - NULL, make sure name_token gives the correct name. Implement the end - of the SELECT block. */ - -void -ffestc_R811 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_selectcase_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if (name == NULL) - { - if (ffestw_name (ffestw_stack_top ()) != NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NAMED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - } - else - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, - ffestw_name (ffestw_stack_top ())) - != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - ffestc_shriek_select_ (TRUE); -} - -/* ffestc_R819A -- Iterative labeled DO statement - - ffestc_R819A(construct_name,label_token,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R819A (ffelexToken construct_name, ffelexToken label_token, ffebld var, - ffelexToken var_token, ffebld start, ffelexToken start_token, ffebld end, - ffelexToken end_token, ffebld incr, ffelexToken incr_token) -{ - ffestw b; - ffelab label; - ffesymbol s; - ffesymbol varsym; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if (!ffestc_labelref_is_loopend_ (label_token, &label)) - return; - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, b); - ffestw_set_state (b, FFESTV_stateDO); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_do_); - ffestw_set_label (b, label); - switch (ffebld_op (var)) - { - case FFEBLD_opSYMTER: - if ((ffeinfo_basictype (ffebld_info (var)) == FFEINFO_basictypeREAL) - && ffe_is_warn_surprising ()) - { - ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ - ffebad_here (0, ffelex_token_where_line (var_token), - ffelex_token_where_column (var_token)); - ffebad_string (ffesymbol_text (ffebld_symter (var))); - ffebad_finish (); - } - if (!ffesymbol_is_doiter (varsym = ffebld_symter (var))) - { /* Presumably already complained about by - ffeexpr_lhs_. */ - ffesymbol_set_is_doiter (varsym, TRUE); - ffestw_set_do_iter_var (b, varsym); - ffestw_set_do_iter_var_t (b, ffelex_token_use (var_token)); - break; - } - /* Fall through. */ - case FFEBLD_opANY: - ffestw_set_do_iter_var (b, NULL); - ffestw_set_do_iter_var_t (b, NULL); - break; - - default: - assert ("bad iter var" == NULL); - break; - } - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - s = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, construct_name); - } - - if (incr == NULL) - { - incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); - ffebld_set_info (incr, ffeinfo_new - (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - } - - start = ffeexpr_convert_expr (start, start_token, var, var_token, - FFEEXPR_contextLET); - end = ffeexpr_convert_expr (end, end_token, var, var_token, - FFEEXPR_contextLET); - incr = ffeexpr_convert_expr (incr, incr_token, var, var_token, - FFEEXPR_contextLET); - - ffestd_R819A (construct_name, label, var, - start, start_token, - end, end_token, - incr, incr_token); -} - -/* ffestc_R819B -- Labeled DO WHILE statement - - ffestc_R819B(construct_name,label_token,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R819B (ffelexToken construct_name, ffelexToken label_token, - ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestw b; - ffelab label; - ffesymbol s; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if (!ffestc_labelref_is_loopend_ (label_token, &label)) - return; - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, b); - ffestw_set_state (b, FFESTV_stateDO); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_do_); - ffestw_set_label (b, label); - ffestw_set_do_iter_var (b, NULL); - ffestw_set_do_iter_var_t (b, NULL); - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - s = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, construct_name); - } - - ffestd_R819B (construct_name, label, expr); -} - -/* ffestc_R820A -- Iterative nonlabeled DO statement - - ffestc_R820A(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R820A (ffelexToken construct_name, ffebld var, ffelexToken var_token, - ffebld start, ffelexToken start_token, ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token) -{ - ffestw b; - ffesymbol s; - ffesymbol varsym; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, b); - ffestw_set_state (b, FFESTV_stateDO); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_do_); - ffestw_set_label (b, NULL); - switch (ffebld_op (var)) - { - case FFEBLD_opSYMTER: - if ((ffeinfo_basictype (ffebld_info (var)) == FFEINFO_basictypeREAL) - && ffe_is_warn_surprising ()) - { - ffebad_start (FFEBAD_DO_REAL); /* See error message!!! */ - ffebad_here (0, ffelex_token_where_line (var_token), - ffelex_token_where_column (var_token)); - ffebad_string (ffesymbol_text (ffebld_symter (var))); - ffebad_finish (); - } - if (!ffesymbol_is_doiter (varsym = ffebld_symter (var))) - { /* Presumably already complained about by - ffeexpr_lhs_. */ - ffesymbol_set_is_doiter (varsym, TRUE); - ffestw_set_do_iter_var (b, varsym); - ffestw_set_do_iter_var_t (b, ffelex_token_use (var_token)); - break; - } - /* Fall through. */ - case FFEBLD_opANY: - ffestw_set_do_iter_var (b, NULL); - ffestw_set_do_iter_var_t (b, NULL); - break; - - default: - assert ("bad iter var" == NULL); - break; - } - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - s = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, construct_name); - } - - if (incr == NULL) - { - incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); - ffebld_set_info (incr, ffeinfo_new - (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - } - - start = ffeexpr_convert_expr (start, start_token, var, var_token, - FFEEXPR_contextLET); - end = ffeexpr_convert_expr (end, end_token, var, var_token, - FFEEXPR_contextLET); - incr = ffeexpr_convert_expr (incr, incr_token, var, var_token, - FFEEXPR_contextLET); - -#if 0 - if ((ffebld_op (incr) == FFEBLD_opCONTER) - && (ffebld_constant_is_zero (ffebld_conter (incr)))) - { - ffebad_start (FFEBAD_DO_STEP_ZERO); - ffebad_here (0, ffelex_token_where_line (incr_token), - ffelex_token_where_column (incr_token)); - ffebad_string ("Iterative DO loop"); - ffebad_finish (); - } -#endif - - ffestd_R819A (construct_name, NULL, var, - start, start_token, - end, end_token, - incr, incr_token); -} - -/* ffestc_R820B -- Nonlabeled DO WHILE statement - - ffestc_R820B(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R820B (ffelexToken construct_name, ffebld expr, - ffelexToken expr_token UNUSED) -{ - ffestw b; - ffesymbol s; - - ffestc_check_simple_ (); - if (ffestc_order_exec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, b); - ffestw_set_state (b, FFESTV_stateDO); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_do_); - ffestw_set_label (b, NULL); - ffestw_set_do_iter_var (b, NULL); - ffestw_set_do_iter_var_t (b, NULL); - - if (construct_name == NULL) - ffestw_set_name (b, NULL); - else - { - ffestw_set_name (b, ffelex_token_use (construct_name)); - - s = ffesymbol_declare_local (construct_name, FALSE); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindCONSTRUCT, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, construct_name); - } - - ffestd_R819B (construct_name, NULL, expr); -} - -/* ffestc_R825 -- END DO statement - - ffestc_R825(name_token); - - Make sure ffestc_kind_ identifies a DO block. If not - NULL, make sure name_token gives the correct name. Implement the end - of the DO block. */ - -void -ffestc_R825 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_do_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (name == NULL) - { - if (ffestw_name (ffestw_stack_top ()) != NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NAMED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - } - else - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_CONSTRUCT_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, - ffestw_name (ffestw_stack_top ())) - != 0) - { - ffebad_start (FFEBAD_CONSTRUCT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - if (ffesta_label_token == NULL) - { /* If top of stack has label, its an error! */ - if (ffestw_label (ffestw_stack_top ()) != NULL) - { - ffebad_start (FFEBAD_DO_HAD_LABEL); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestc_shriek_do_ (TRUE); - - ffestc_try_shriek_do_ (); - - return; - } - - ffestd_R825 (name); - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R834 -- CYCLE statement - - ffestc_R834(name_token); - - Handle a CYCLE within a loop. */ - -void -ffestc_R834 (ffelexToken name) -{ - ffestw block; - - ffestc_check_simple_ (); - if (ffestc_order_actiondo_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - if (name == NULL) - block = ffestw_top_do (ffestw_stack_top ()); - else - { /* Search for name. */ - for (block = ffestw_top_do (ffestw_stack_top ()); - (block != NULL) && (ffestw_blocknum (block) != 0); - block = ffestw_top_do (ffestw_previous (block))) - { - if ((ffestw_name (block) != NULL) - && (ffelex_token_strcmp (name, ffestw_name (block)) == 0)) - break; - } - if ((block == NULL) || (ffestw_blocknum (block) == 0)) - { - block = ffestw_top_do (ffestw_stack_top ()); - ffebad_start (FFEBAD_CONSTRUCT_NO_DO_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - } - - ffestd_R834 (block); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) CYCLE". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R835 -- EXIT statement - - ffestc_R835(name_token); - - Handle a EXIT within a loop. */ - -void -ffestc_R835 (ffelexToken name) -{ - ffestw block; - - ffestc_check_simple_ (); - if (ffestc_order_actiondo_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - if (name == NULL) - block = ffestw_top_do (ffestw_stack_top ()); - else - { /* Search for name. */ - for (block = ffestw_top_do (ffestw_stack_top ()); - (block != NULL) && (ffestw_blocknum (block) != 0); - block = ffestw_top_do (ffestw_previous (block))) - { - if ((ffestw_name (block) != NULL) - && (ffelex_token_strcmp (name, ffestw_name (block)) == 0)) - break; - } - if ((block == NULL) || (ffestw_blocknum (block) == 0)) - { - block = ffestw_top_do (ffestw_stack_top ()); - ffebad_start (FFEBAD_CONSTRUCT_NO_DO_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - } - - ffestd_R835 (block); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) EXIT". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R836 -- GOTO statement - - ffestc_R836(label_token); - - Make sure label_token identifies a valid label for a GOTO. Update - that label's info to indicate it is the target of a GOTO. */ - -void -ffestc_R836 (ffelexToken label_token) -{ - ffelab label; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - if (ffestc_labelref_is_branch_ (label_token, &label)) - ffestd_R836 (label); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) GOTO 100". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R837 -- Computed GOTO statement - - ffestc_R837(label_list,expr,expr_token); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffestc_R837 (ffesttTokenList label_toks, ffebld expr, - ffelexToken expr_token UNUSED) -{ - ffesttTokenItem ti; - bool ok = TRUE; - int i; - ffelab *labels; - - assert (label_toks != NULL); - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - labels = malloc_new_kp (ffesta_output_pool, "FFESTC labels", - sizeof (*labels) - * ffestt_tokenlist_count (label_toks)); - - for (ti = label_toks->first, i = 0; - ti != (ffesttTokenItem) &label_toks->first; - ti = ti->next, ++i) - { - if (!ffestc_labelref_is_branch_ (ti->t, &labels[i])) - { - ok = FALSE; - break; - } - } - - if (ok) - ffestd_R837 (labels, ffestt_tokenlist_count (label_toks), expr); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R838 -- ASSIGN statement - - ffestc_R838(label_token,target_variable,target_token); - - Make sure label_token identifies a valid label for an assignment. Update - that label's info to indicate it is the source of an assignment. Update - target_variable's info to indicate it is the target the assignment of that - label. */ - -void -ffestc_R838 (ffelexToken label_token, ffebld target, - ffelexToken target_token UNUSED) -{ - ffelab label; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_labelref_is_assignable_ (label_token, &label)) - ffestd_R838 (label, target); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R839 -- Assigned GOTO statement - - ffestc_R839(target,target_token,label_list); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffestc_R839 (ffebld target, ffelexToken target_token UNUSED, - ffesttTokenList label_toks) -{ - ffesttTokenItem ti; - bool ok = TRUE; - int i; - ffelab *labels; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - if (label_toks == NULL) - { - labels = NULL; - i = 0; - } - else - { - labels = malloc_new_kp (ffesta_output_pool, "FFESTC labels", - sizeof (*labels) * ffestt_tokenlist_count (label_toks)); - - for (ti = label_toks->first, i = 0; - ti != (ffesttTokenItem) &label_toks->first; - ti = ti->next, ++i) - { - if (!ffestc_labelref_is_branch_ (ti->t, &labels[i])) - { - ok = FALSE; - break; - } - } - } - - if (ok) - ffestd_R839 (target, labels, i); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) GOTO I". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R840 -- Arithmetic IF statement - - ffestc_R840(expr,expr_token,neg,zero,pos); - - Make sure the labels are valid; implement. */ - -void -ffestc_R840 (ffebld expr, ffelexToken expr_token UNUSED, - ffelexToken neg_token, ffelexToken zero_token, - ffelexToken pos_token) -{ - ffelab neg; - ffelab zero; - ffelab pos; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - if (ffestc_labelref_is_branch_ (neg_token, &neg) - && ffestc_labelref_is_branch_ (zero_token, &zero) - && ffestc_labelref_is_branch_ (pos_token, &pos)) - ffestd_R840 (expr, neg, zero, pos); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) GOTO (100,200,300), I". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R841 -- CONTINUE statement - - ffestc_R841(); */ - -void -ffestc_R841 () -{ - ffestc_check_simple_ (); - - if (ffestc_order_actionwhere_ () != FFESTC_orderOK_) - return; - - switch (ffestw_state (ffestw_stack_top ())) - { -#if FFESTR_F90 - case FFESTV_stateWHERE: - case FFESTV_stateWHERETHEN: - ffestc_labeldef_useless_ (); - - ffestd_R841 (TRUE); - - /* It's okay that we call ffestc_labeldef_branch_end_ () below, - since that will be a no-op after calling _useless_ () above. */ - break; -#endif - - default: - ffestc_labeldef_branch_begin_ (); - - ffestd_R841 (FALSE); - - break; - } - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R842 -- STOP statement - - ffestc_R842(expr,expr_token); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffestc_R842 (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - ffestd_R842 (expr); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) STOP". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R843 -- PAUSE statement - - ffestc_R843(expr,expr_token); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffestc_R843 (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R843 (expr); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R904 -- OPEN statement - - ffestc_R904(); - - Make sure an OPEN is valid in the current context, and implement it. */ - -void -ffestc_R904 () -{ - int i; - int expect_file; - char *status_strs[] - = - { - "New", - "Old", - "Replace", - "Scratch", - "Unknown" - }; - char *access_strs[] - = - { - "Append", - "Direct", - "Keyed", - "Sequential" - }; - char *blank_strs[] - = - { - "Null", - "Zero" - }; - char *carriagecontrol_strs[] - = - { - "Fortran", - "List", - "None" - }; - char *dispose_strs[] - = - { - "Delete", - "Keep", - "Print", - "Print/Delete", - "Save", - "Submit", - "Submit/Delete" - }; - char *form_strs[] - = - { - "Formatted", - "Unformatted" - }; - char *organization_strs[] - = - { - "Indexed", - "Relative", - "Sequential" - }; - char *position_strs[] - = - { - "Append", - "AsIs", - "Rewind" - }; - char *action_strs[] - = - { - "Read", - "ReadWrite", - "Write" - }; - char *delim_strs[] - = - { - "Apostrophe", - "None", - "Quote" - }; - char *recordtype_strs[] - = - { - "Fixed", - "Segmented", - "Stream", - "Stream_CR", - "Stream_LF", - "Variable" - }; - char *pad_strs[] - = - { - "No", - "Yes" - }; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.open.open_spec[FFESTP_openixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.open.open_spec[FFESTP_openixUNIT])) - { - i = ffestc_subr_binsrch_ (status_strs, - ARRAY_SIZE (status_strs), - &ffestp_file.open.open_spec[FFESTP_openixSTATUS], - "NEW, OLD, REPLACE, SCRATCH, or UNKNOWN"); - switch (i) - { - case 0: /* Unknown. */ - case 5: /* UNKNOWN. */ - expect_file = 2; /* Unknown, don't care about FILE=. */ - break; - - case 1: /* NEW. */ - case 2: /* OLD. */ - if (ffe_is_pedantic ()) - expect_file = 1; /* Yes, need FILE=. */ - else - expect_file = 2; /* f2clib doesn't care about FILE=. */ - break; - - case 3: /* REPLACE. */ - expect_file = 1; /* Yes, need FILE=. */ - break; - - case 4: /* SCRATCH. */ - expect_file = 0; /* No, disallow FILE=. */ - break; - - default: - assert ("invalid _binsrch_ result" == NULL); - expect_file = 0; - break; - } - if ((expect_file == 0) - && ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present) - { - ffebad_start (FFEBAD_CONFLICTING_SPECS); - assert (ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present); - if (ffestp_file.open.open_spec[FFESTP_openixFILE].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixFILE].kw), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixFILE].kw)); - } - else - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixFILE].value), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixFILE].value)); - } - assert (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_or_val_present); - if (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_present) - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw)); - } - else - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value)); - } - ffebad_finish (); - } - else if ((expect_file == 1) - && !ffestp_file.open.open_spec[FFESTP_openixFILE].kw_or_val_present) - { - ffebad_start (FFEBAD_MISSING_SPECIFIER); - assert (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_or_val_present); - if (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].kw)); - } - else - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value), - ffelex_token_where_column - (ffestp_file.open.open_spec[FFESTP_openixSTATUS].value)); - } - ffebad_string ("FILE="); - ffebad_finish (); - } - - ffestc_subr_binsrch_ (access_strs, ARRAY_SIZE (access_strs), - &ffestp_file.open.open_spec[FFESTP_openixACCESS], - "APPEND, DIRECT, KEYED, or SEQUENTIAL"); - - ffestc_subr_binsrch_ (blank_strs, ARRAY_SIZE (blank_strs), - &ffestp_file.open.open_spec[FFESTP_openixBLANK], - "NULL or ZERO"); - - ffestc_subr_binsrch_ (carriagecontrol_strs, - ARRAY_SIZE (carriagecontrol_strs), - &ffestp_file.open.open_spec[FFESTP_openixCARRIAGECONTROL], - "FORTRAN, LIST, or NONE"); - - ffestc_subr_binsrch_ (dispose_strs, ARRAY_SIZE (dispose_strs), - &ffestp_file.open.open_spec[FFESTP_openixDISPOSE], - "DELETE, KEEP, PRINT, PRINT/DELETE, SAVE, SUBMIT, or SUBMIT/DELETE"); - - ffestc_subr_binsrch_ (form_strs, ARRAY_SIZE (form_strs), - &ffestp_file.open.open_spec[FFESTP_openixFORM], - "FORMATTED or UNFORMATTED"); - - ffestc_subr_binsrch_ (organization_strs, ARRAY_SIZE (organization_strs), - &ffestp_file.open.open_spec[FFESTP_openixORGANIZATION], - "INDEXED, RELATIVE, or SEQUENTIAL"); - - ffestc_subr_binsrch_ (position_strs, ARRAY_SIZE (position_strs), - &ffestp_file.open.open_spec[FFESTP_openixPOSITION], - "APPEND, ASIS, or REWIND"); - - ffestc_subr_binsrch_ (action_strs, ARRAY_SIZE (action_strs), - &ffestp_file.open.open_spec[FFESTP_openixACTION], - "READ, READWRITE, or WRITE"); - - ffestc_subr_binsrch_ (delim_strs, ARRAY_SIZE (delim_strs), - &ffestp_file.open.open_spec[FFESTP_openixDELIM], - "APOSTROPHE, NONE, or QUOTE"); - - ffestc_subr_binsrch_ (recordtype_strs, ARRAY_SIZE (recordtype_strs), - &ffestp_file.open.open_spec[FFESTP_openixRECORDTYPE], - "FIXED, SEGMENTED, STREAM, STREAM_CR, STREAM_LF, or VARIABLE"); - - ffestc_subr_binsrch_ (pad_strs, ARRAY_SIZE (pad_strs), - &ffestp_file.open.open_spec[FFESTP_openixPAD], - "NO or YES"); - - ffestd_R904 (); - } - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R907 -- CLOSE statement - - ffestc_R907(); - - Make sure a CLOSE is valid in the current context, and implement it. */ - -void -ffestc_R907 () -{ - char *status_strs[] - = - { - "Delete", - "Keep", - "Print", - "Print/Delete", - "Save", - "Submit", - "Submit/Delete" - }; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.close.close_spec[FFESTP_closeixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.close.close_spec[FFESTP_closeixUNIT])) - { - ffestc_subr_binsrch_ (status_strs, ARRAY_SIZE (status_strs), - &ffestp_file.close.close_spec[FFESTP_closeixSTATUS], - "DELETE, KEEP, PRINT, PRINT/DELETE, SAVE, SUBMIT, or SUBMIT/DELETE"); - - ffestd_R907 (); - } - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R909_start -- READ(...) statement list begin - - ffestc_R909_start(FALSE); - - Verify that READ is valid here, and begin accepting items in the - list. */ - -void -ffestc_R909_start (bool only_format) -{ - ffestvUnit unit; - ffestvFormat format; - bool rec; - bool key; - ffestpReadIx keyn; - ffestpReadIx spec1; - ffestpReadIx spec2; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_format_ - (&ffestp_file.read.read_spec[FFESTP_readixFORMAT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.read.read_spec[FFESTP_readixFORMAT]); - ffestc_namelist_ = (format == FFESTV_formatNAMELIST); - - if (only_format) - { - ffestd_R909_start (TRUE, FFESTV_unitNONE, format, FALSE, FALSE); - - ffestc_ok_ = TRUE; - return; - } - - if (!ffestc_subr_is_branch_ - (&ffestp_file.read.read_spec[FFESTP_readixEOR]) - || !ffestc_subr_is_branch_ - (&ffestp_file.read.read_spec[FFESTP_readixERR]) - || !ffestc_subr_is_branch_ - (&ffestp_file.read.read_spec[FFESTP_readixEND])) - { - ffestc_ok_ = FALSE; - return; - } - - unit = ffestc_subr_unit_ - (&ffestp_file.read.read_spec[FFESTP_readixUNIT]); - if (unit == FFESTV_unitNONE) - { - ffebad_start (FFEBAD_NO_UNIT_SPEC); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - } - - rec = ffestp_file.read.read_spec[FFESTP_readixREC].kw_or_val_present; - - if (ffestp_file.read.read_spec[FFESTP_readixKEYEQ].kw_or_val_present) - { - key = TRUE; - keyn = spec1 = FFESTP_readixKEYEQ; - } - else - { - key = FALSE; - keyn = spec1 = FFESTP_readix; - } - - if (ffestp_file.read.read_spec[FFESTP_readixKEYGT].kw_or_val_present) - { - if (key) - { - spec2 = FFESTP_readixKEYGT; - whine: /* :::::::::::::::::::: */ - ffebad_start (FFEBAD_CONFLICTING_SPECS); - assert (ffestp_file.read.read_spec[spec1].kw_or_val_present); - if (ffestp_file.read.read_spec[spec1].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.read.read_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec1].kw)); - } - else - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.read.read_spec[spec1].value), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec1].value)); - } - assert (ffestp_file.read.read_spec[spec2].kw_or_val_present); - if (ffestp_file.read.read_spec[spec2].kw_present) - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.read.read_spec[spec2].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec2].kw)); - } - else - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.read.read_spec[spec2].value), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec2].value)); - } - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - } - key = TRUE; - keyn = spec1 = FFESTP_readixKEYGT; - } - - if (ffestp_file.read.read_spec[FFESTP_readixKEYGE].kw_or_val_present) - { - if (key) - { - spec2 = FFESTP_readixKEYGT; - goto whine; /* :::::::::::::::::::: */ - } - key = TRUE; - keyn = FFESTP_readixKEYGT; - } - - if (rec) - { - spec1 = FFESTP_readixREC; - if (key) - { - spec2 = keyn; - goto whine; /* :::::::::::::::::::: */ - } - if (unit == FFESTV_unitCHAREXPR) - { - spec2 = FFESTP_readixUNIT; - goto whine; /* :::::::::::::::::::: */ - } - if ((format == FFESTV_formatASTERISK) - || (format == FFESTV_formatNAMELIST)) - { - spec2 = FFESTP_readixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) - { - spec2 = FFESTP_readixADVANCE; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixEND].kw_or_val_present) - { - spec2 = FFESTP_readixEND; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) - { - spec2 = FFESTP_readixNULLS; - goto whine; /* :::::::::::::::::::: */ - } - } - else if (key) - { - spec1 = keyn; - if (unit == FFESTV_unitCHAREXPR) - { - spec2 = FFESTP_readixUNIT; - goto whine; /* :::::::::::::::::::: */ - } - if ((format == FFESTV_formatASTERISK) - || (format == FFESTV_formatNAMELIST)) - { - spec2 = FFESTP_readixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) - { - spec2 = FFESTP_readixADVANCE; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixEND].kw_or_val_present) - { - spec2 = FFESTP_readixEND; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixEOR].kw_or_val_present) - { - spec2 = FFESTP_readixEOR; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) - { - spec2 = FFESTP_readixNULLS; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixREC].kw_or_val_present) - { - spec2 = FFESTP_readixREC; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixSIZE].kw_or_val_present) - { - spec2 = FFESTP_readixSIZE; - goto whine; /* :::::::::::::::::::: */ - } - } - else - { /* Sequential/Internal. */ - if (unit == FFESTV_unitCHAREXPR) - { /* Internal file. */ - spec1 = FFESTP_readixUNIT; - if (format == FFESTV_formatNAMELIST) - { - spec2 = FFESTP_readixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) - { - spec2 = FFESTP_readixADVANCE; - goto whine; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw_or_val_present) - { /* ADVANCE= specified. */ - spec1 = FFESTP_readixADVANCE; - if (format == FFESTV_formatNONE) - { - ffebad_start (FFEBAD_MISSING_FORMAT_SPEC); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.read.read_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec1].kw)); - ffebad_finish (); - - ffestc_ok_ = FALSE; - return; - } - if (format == FFESTV_formatNAMELIST) - { - spec2 = FFESTP_readixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.read.read_spec[FFESTP_readixEOR].kw_or_val_present) - { /* EOR= specified. */ - spec1 = FFESTP_readixEOR; - if (ffestc_subr_speccmp_ ("No", - &ffestp_file.read.read_spec[FFESTP_readixADVANCE], - NULL, NULL) != 0) - { - goto whine_advance; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.read.read_spec[FFESTP_readixNULLS].kw_or_val_present) - { /* NULLS= specified. */ - spec1 = FFESTP_readixNULLS; - if (format != FFESTV_formatASTERISK) - { - spec2 = FFESTP_readixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.read.read_spec[FFESTP_readixSIZE].kw_or_val_present) - { /* SIZE= specified. */ - spec1 = FFESTP_readixSIZE; - if (ffestc_subr_speccmp_ ("No", - &ffestp_file.read.read_spec[FFESTP_readixADVANCE], - NULL, NULL) != 0) - { - whine_advance: /* :::::::::::::::::::: */ - if (ffestp_file.read.read_spec[FFESTP_readixADVANCE] - .kw_or_val_present) - { - ffebad_start (FFEBAD_CONFLICTING_SPECS); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.read.read_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec1].kw)); - ffebad_here (1, ffelex_token_where_line - (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[FFESTP_readixADVANCE].kw)); - ffebad_finish (); - } - else - { - ffebad_start (FFEBAD_MISSING_ADVANCE_SPEC); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.read.read_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.read.read_spec[spec1].kw)); - ffebad_finish (); - } - - ffestc_ok_ = FALSE; - return; - } - } - } - - if (unit == FFESTV_unitCHAREXPR) - ffestc_iolist_context_ = FFEEXPR_contextIOLISTDF; - else - ffestc_iolist_context_ = FFEEXPR_contextIOLIST; - - ffestd_R909_start (FALSE, unit, format, rec, key); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R909_item -- READ statement i/o item - - ffestc_R909_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_R909_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_namelist_ != 0) - { - if (ffestc_namelist_ == 1) - { - ffestc_namelist_ = 2; - ffebad_start (FFEBAD_NAMELIST_ITEMS); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - } - return; - } - - ffestd_R909_item (expr, expr_token); -} - -/* ffestc_R909_finish -- READ statement list complete - - ffestc_R909_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R909_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R909_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R910_start -- WRITE(...) statement list begin - - ffestc_R910_start(); - - Verify that WRITE is valid here, and begin accepting items in the - list. */ - -void -ffestc_R910_start () -{ - ffestvUnit unit; - ffestvFormat format; - bool rec; - ffestpWriteIx spec1; - ffestpWriteIx spec2; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_branch_ - (&ffestp_file.write.write_spec[FFESTP_writeixEOR]) - || !ffestc_subr_is_branch_ - (&ffestp_file.write.write_spec[FFESTP_writeixERR]) - || !ffestc_subr_is_format_ - (&ffestp_file.write.write_spec[FFESTP_writeixFORMAT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.write.write_spec[FFESTP_writeixFORMAT]); - ffestc_namelist_ = (format == FFESTV_formatNAMELIST); - - unit = ffestc_subr_unit_ - (&ffestp_file.write.write_spec[FFESTP_writeixUNIT]); - if (unit == FFESTV_unitNONE) - { - ffebad_start (FFEBAD_NO_UNIT_SPEC); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - } - - rec = ffestp_file.write.write_spec[FFESTP_writeixREC].kw_or_val_present; - - if (rec) - { - spec1 = FFESTP_writeixREC; - if (unit == FFESTV_unitCHAREXPR) - { - spec2 = FFESTP_writeixUNIT; - whine: /* :::::::::::::::::::: */ - ffebad_start (FFEBAD_CONFLICTING_SPECS); - assert (ffestp_file.write.write_spec[spec1].kw_or_val_present); - if (ffestp_file.write.write_spec[spec1].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.write.write_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec1].kw)); - } - else - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.write.write_spec[spec1].value), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec1].value)); - } - assert (ffestp_file.write.write_spec[spec2].kw_or_val_present); - if (ffestp_file.write.write_spec[spec2].kw_present) - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.write.write_spec[spec2].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec2].kw)); - } - else - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.write.write_spec[spec2].value), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec2].value)); - } - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - } - if ((format == FFESTV_formatASTERISK) - || (format == FFESTV_formatNAMELIST)) - { - spec2 = FFESTP_writeixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) - { - spec2 = FFESTP_writeixADVANCE; - goto whine; /* :::::::::::::::::::: */ - } - } - else - { /* Sequential/Indexed/Internal. */ - if (unit == FFESTV_unitCHAREXPR) - { /* Internal file. */ - spec1 = FFESTP_writeixUNIT; - if (format == FFESTV_formatNAMELIST) - { - spec2 = FFESTP_writeixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) - { - spec2 = FFESTP_writeixADVANCE; - goto whine; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw_or_val_present) - { /* ADVANCE= specified. */ - spec1 = FFESTP_writeixADVANCE; - if (format == FFESTV_formatNONE) - { - ffebad_start (FFEBAD_MISSING_FORMAT_SPEC); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.write.write_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec1].kw)); - ffebad_finish (); - - ffestc_ok_ = FALSE; - return; - } - if (format == FFESTV_formatNAMELIST) - { - spec2 = FFESTP_writeixFORMAT; - goto whine; /* :::::::::::::::::::: */ - } - } - if (ffestp_file.write.write_spec[FFESTP_writeixEOR].kw_or_val_present) - { /* EOR= specified. */ - spec1 = FFESTP_writeixEOR; - if (ffestc_subr_speccmp_ ("No", - &ffestp_file.write.write_spec[FFESTP_writeixADVANCE], - NULL, NULL) != 0) - { - if (ffestp_file.write.write_spec[FFESTP_writeixADVANCE] - .kw_or_val_present) - { - ffebad_start (FFEBAD_CONFLICTING_SPECS); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.write.write_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec1].kw)); - ffebad_here (1, ffelex_token_where_line - (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[FFESTP_writeixADVANCE].kw)); - ffebad_finish (); - } - else - { - ffebad_start (FFEBAD_MISSING_ADVANCE_SPEC); - ffebad_here (0, ffelex_token_where_line - (ffestp_file.write.write_spec[spec1].kw), - ffelex_token_where_column - (ffestp_file.write.write_spec[spec1].kw)); - ffebad_finish (); - } - - ffestc_ok_ = FALSE; - return; - } - } - } - - if (unit == FFESTV_unitCHAREXPR) - ffestc_iolist_context_ = FFEEXPR_contextIOLISTDF; - else - ffestc_iolist_context_ = FFEEXPR_contextIOLIST; - - ffestd_R910_start (unit, format, rec); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R910_item -- WRITE statement i/o item - - ffestc_R910_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_R910_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_namelist_ != 0) - { - if (ffestc_namelist_ == 1) - { - ffestc_namelist_ = 2; - ffebad_start (FFEBAD_NAMELIST_ITEMS); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - } - return; - } - - ffestd_R910_item (expr, expr_token); -} - -/* ffestc_R910_finish -- WRITE statement list complete - - ffestc_R910_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R910_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R910_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R911_start -- PRINT(...) statement list begin - - ffestc_R911_start(); - - Verify that PRINT is valid here, and begin accepting items in the - list. */ - -void -ffestc_R911_start () -{ - ffestvFormat format; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_format_ - (&ffestp_file.print.print_spec[FFESTP_printixFORMAT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.print.print_spec[FFESTP_printixFORMAT]); - ffestc_namelist_ = (format == FFESTV_formatNAMELIST); - - ffestd_R911_start (format); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R911_item -- PRINT statement i/o item - - ffestc_R911_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_R911_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_namelist_ != 0) - { - if (ffestc_namelist_ == 1) - { - ffestc_namelist_ = 2; - ffebad_start (FFEBAD_NAMELIST_ITEMS); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - } - return; - } - - ffestd_R911_item (expr, expr_token); -} - -/* ffestc_R911_finish -- PRINT statement list complete - - ffestc_R911_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R911_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R911_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R919 -- BACKSPACE statement - - ffestc_R919(); - - Make sure a BACKSPACE is valid in the current context, and implement it. */ - -void -ffestc_R919 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) - ffestd_R919 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R920 -- ENDFILE statement - - ffestc_R920(); - - Make sure a ENDFILE is valid in the current context, and implement it. */ - -void -ffestc_R920 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) - ffestd_R920 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R921 -- REWIND statement - - ffestc_R921(); - - Make sure a REWIND is valid in the current context, and implement it. */ - -void -ffestc_R921 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) - ffestd_R921 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R923A -- INQUIRE statement (non-IOLENGTH version) - - ffestc_R923A(); - - Make sure an INQUIRE is valid in the current context, and implement it. */ - -void -ffestc_R923A () -{ - bool by_file; - bool by_unit; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.inquire.inquire_spec[FFESTP_inquireixERR])) - { - by_file = ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE] - .kw_or_val_present; - by_unit = ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT] - .kw_or_val_present; - if (by_file && by_unit) - { - ffebad_start (FFEBAD_CONFLICTING_SPECS); - assert (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_or_val_present); - if (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw), - ffelex_token_where_column - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].kw)); - } - else - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value), - ffelex_token_where_column - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixUNIT].value)); - } - assert (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw_or_val_present); - if (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw_present) - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw), - ffelex_token_where_column - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].kw)); - } - else - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].value), - ffelex_token_where_column - (ffestp_file.inquire.inquire_spec[FFESTP_inquireixFILE].value)); - } - ffebad_finish (); - } - else if (!by_file && !by_unit) - { - ffebad_start (FFEBAD_MISSING_SPECIFIER); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_string ("UNIT= or FILE="); - ffebad_finish (); - } - else - ffestd_R923A (by_file); - } - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R923B_start -- INQUIRE(IOLENGTH=expr) statement list begin - - ffestc_R923B_start(); - - Verify that INQUIRE is valid here, and begin accepting items in the - list. */ - -void -ffestc_R923B_start () -{ - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - ffestd_R923B_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R923B_item -- INQUIRE statement i/o item - - ffestc_R923B_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_R923B_item (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_R923B_item (expr); -} - -/* ffestc_R923B_finish -- INQUIRE statement list complete - - ffestc_R923B_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R923B_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R923B_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R1001 -- FORMAT statement - - ffestc_R1001(format_list); - - Make sure format_list is valid. Update label's info to indicate it is a - FORMAT label, and (perhaps) warn if there is no label! */ - -void -ffestc_R1001 (ffesttFormatList f) -{ - ffestc_check_simple_ (); - if (ffestc_order_format_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_format_ (); - - ffestd_R1001 (f); -} - -/* ffestc_R1102 -- PROGRAM statement - - ffestc_R1102(name_token); - - Make sure ffestc_kind_ identifies an empty block. Make sure name_token - gives a valid name. Implement the beginning of a main program. */ - -void -ffestc_R1102 (ffelexToken name) -{ - ffestw b; - ffesymbol s; - - assert (name != NULL); - - ffestc_check_simple_ (); - if (ffestc_order_unit_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_blocknum_ = 0; - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_statePROGRAM0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_end_program_); - - ffestw_set_name (b, ffelex_token_use (name)); - - s = ffesymbol_declare_programunit (name, - ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindPROGRAM, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, name); - - ffestd_R1102 (s, name); -} - -/* ffestc_R1103 -- END PROGRAM statement - - ffestc_R1103(name_token); - - Make sure ffestc_kind_ identifies the current kind of program unit. If not - NULL, make sure name_token gives the correct name. Implement the end - of the current program unit. */ - -void -ffestc_R1103 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_program_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if (name != NULL) - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_PROGRAM_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) - { - ffebad_start (FFEBAD_UNIT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - ffestc_shriek_end_program_ (TRUE); -} - -/* ffestc_R1105 -- MODULE statement - - ffestc_R1105(name_token); - - Make sure ffestc_kind_ identifies an empty block. Make sure name_token - gives a valid name. Implement the beginning of a module. */ - -#if FFESTR_F90 -void -ffestc_R1105 (ffelexToken name) -{ - ffestw b; - - assert (name != NULL); - - ffestc_check_simple_ (); - if (ffestc_order_unit_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_blocknum_ = 0; - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateMODULE0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_module_); - ffestw_set_name (b, ffelex_token_use (name)); - - ffestd_R1105 (name); -} - -/* ffestc_R1106 -- END MODULE statement - - ffestc_R1106(name_token); - - Make sure ffestc_kind_ identifies the current kind of program unit. If not - NULL, make sure name_token gives the correct name. Implement the end - of the current program unit. */ - -void -ffestc_R1106 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_module_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if ((name != NULL) - && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) - { - ffebad_start (FFEBAD_UNIT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - - ffestc_shriek_module_ (TRUE); -} - -/* ffestc_R1107_start -- USE statement list begin - - ffestc_R1107_start(); - - Verify that USE is valid here, and begin accepting items in the list. */ - -void -ffestc_R1107_start (ffelexToken name, bool only) -{ - ffestc_check_start_ (); - if (ffestc_order_use_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R1107_start (name, only); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R1107_item -- USE statement for name - - ffestc_R1107_item(local_token,use_token); - - Make sure name_token identifies a valid object to be USEed. local_token - may be NULL if _start_ was called with only==TRUE. */ - -void -ffestc_R1107_item (ffelexToken local, ffelexToken use) -{ - ffestc_check_item_ (); - assert (use != NULL); - if (!ffestc_ok_) - return; - - ffestd_R1107_item (local, use); -} - -/* ffestc_R1107_finish -- USE statement list complete - - ffestc_R1107_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R1107_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R1107_finish (); -} - -#endif -/* ffestc_R1111 -- BLOCK DATA statement - - ffestc_R1111(name_token); - - Make sure ffestc_kind_ identifies no current program unit. If not - NULL, make sure name_token gives a valid name. Implement the beginning - of a block data program unit. */ - -void -ffestc_R1111 (ffelexToken name) -{ - ffestw b; - ffesymbol s; - - ffestc_check_simple_ (); - if (ffestc_order_unit_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_blocknum_ = 0; - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateBLOCKDATA0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_blockdata_); - - if (name == NULL) - ffestw_set_name (b, NULL); - else - ffestw_set_name (b, ffelex_token_use (name)); - - s = ffesymbol_declare_blockdataunit (name, - ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindBLOCKDATA, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - ffesymbol_signal_unreported (s); - } - else - ffesymbol_error (s, name); - - ffestd_R1111 (s, name); -} - -/* ffestc_R1112 -- END BLOCK DATA statement - - ffestc_R1112(name_token); - - Make sure ffestc_kind_ identifies the current kind of program unit. If not - NULL, make sure name_token gives the correct name. Implement the end - of the current program unit. */ - -void -ffestc_R1112 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_blockdata_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (name != NULL) - { - if (ffestw_name (ffestw_stack_top ()) == NULL) - { - ffebad_start (FFEBAD_BLOCKDATA_NOT_NAMED); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - else if (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0) - { - ffebad_start (FFEBAD_UNIT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - } - - ffestc_shriek_blockdata_ (TRUE); -} - -/* ffestc_R1202 -- INTERFACE statement - - ffestc_R1202(operator,defined_name); - - Make sure ffestc_kind_ identifies an INTERFACE block. - Implement the end of the current interface. - - 15-May-90 JCB 1.1 - Allow no operator or name to mean INTERFACE by itself; missed this - valid form when originally doing syntactic analysis code. */ - -#if FFESTR_F90 -void -ffestc_R1202 (ffestpDefinedOperator operator, ffelexToken name) -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_interfacespec_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateINTERFACE0); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_interface_); - - if ((operator == FFESTP_definedoperatorNone) && (name == NULL)) - ffestw_set_substate (b, 0); /* No generic-spec, so disallow MODULE - PROCEDURE. */ - else - ffestw_set_substate (b, 1); /* MODULE PROCEDURE ok. */ - - ffestd_R1202 (operator, name); - - ffe_init_4 (); -} - -/* ffestc_R1203 -- END INTERFACE statement - - ffestc_R1203(); - - Make sure ffestc_kind_ identifies an INTERFACE block. - Implement the end of the current interface. */ - -void -ffestc_R1203 () -{ - ffestc_check_simple_ (); - if (ffestc_order_interface_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_shriek_interface_ (TRUE); - - ffe_terminate_4 (); -} - -/* ffestc_R1205_start -- MODULE PROCEDURE statement list begin - - ffestc_R1205_start(); - - Verify that MODULE PROCEDURE is valid here, and begin accepting items in - the list. */ - -void -ffestc_R1205_start () -{ - ffestc_check_start_ (); - if (ffestc_order_interface_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) == 0) - { - ffebad_start (FFEBAD_INVALID_MODULE_PROCEDURE); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - } - - if (ffestw_state (ffestw_stack_top ()) == FFESTV_stateINTERFACE0) - { - ffestw_update (NULL); /* Update state line/col info. */ - ffestw_set_state (ffestw_stack_top (), FFESTV_stateINTERFACE1); - } - - ffestd_R1205_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R1205_item -- MODULE PROCEDURE statement for name - - ffestc_R1205_item(name_token); - - Make sure name_token identifies a valid object to be MODULE PROCEDUREed. */ - -void -ffestc_R1205_item (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_R1205_item (name); -} - -/* ffestc_R1205_finish -- MODULE PROCEDURE statement list complete - - ffestc_R1205_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R1205_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R1205_finish (); -} - -#endif -/* ffestc_R1207_start -- EXTERNAL statement list begin - - ffestc_R1207_start(); - - Verify that EXTERNAL is valid here, and begin accepting items in the list. */ - -void -ffestc_R1207_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R1207_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R1207_item -- EXTERNAL statement for name - - ffestc_R1207_item(name_token); - - Make sure name_token identifies a valid object to be EXTERNALd. */ - -void -ffestc_R1207_item (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsEXTERNAL; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_explicitwhere (s, TRUE); - ffesymbol_reference (s, name, FALSE); - ffesymbol_signal_unreported (s); - } - - ffestd_R1207_item (name); -} - -/* ffestc_R1207_finish -- EXTERNAL statement list complete - - ffestc_R1207_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R1207_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R1207_finish (); -} - -/* ffestc_R1208_start -- INTRINSIC statement list begin - - ffestc_R1208_start(); - - Verify that INTRINSIC is valid here, and begin accepting items in the list. */ - -void -ffestc_R1208_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_R1208_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R1208_item -- INTRINSIC statement for name - - ffestc_R1208_item(name_token); - - Make sure name_token identifies a valid object to be INTRINSICd. */ - -void -ffestc_R1208_item (ffelexToken name) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - s = ffesymbol_declare_local (name, TRUE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = sa; - else if (!(sa & ~FFESYMBOL_attrsTYPE)) - { - if (ffeintrin_is_intrinsic (ffelex_token_text (name), name, TRUE, - &gen, &spec, &imp) - && ((imp == FFEINTRIN_impNONE) -#if 0 /* Don't bother with this for now. */ - || ((ffeintrin_basictype (spec) - == ffesymbol_basictype (s)) - && (ffeintrin_kindtype (spec) - == ffesymbol_kindtype (s))) -#else - || 1 -#endif - || !(sa & FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsINTRINSIC; - else - na = FFESYMBOL_attrsetNONE; - } - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, name); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindNONE, - FFEINFO_whereINTRINSIC, - ffesymbol_size (s))); - ffesymbol_set_explicitwhere (s, TRUE); - ffesymbol_reference (s, name, TRUE); - } - - ffesymbol_signal_unreported (s); - - ffestd_R1208_item (name); -} - -/* ffestc_R1208_finish -- INTRINSIC statement list complete - - ffestc_R1208_finish(); - - Just wrap up any local activities. */ - -void -ffestc_R1208_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_R1208_finish (); -} - -/* ffestc_R1212 -- CALL statement - - ffestc_R1212(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestc_R1212 (ffebld expr, ffelexToken expr_token UNUSED) -{ - ffebld item; /* ITEM. */ - ffebld labexpr; /* LABTOK=>LABTER. */ - ffelab label; - bool ok; /* TRUE if all LABTOKs were ok. */ - bool ok1; /* TRUE if a particular LABTOK is ok. */ - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffebld_op (expr) != FFEBLD_opSUBRREF) - ffestd_R841 (FALSE); /* CONTINUE. */ - else - { - ok = TRUE; - - for (item = ffebld_right (expr); - item != NULL; - item = ffebld_trail (item)) - { - if (((labexpr = ffebld_head (item)) != NULL) - && (ffebld_op (labexpr) == FFEBLD_opLABTOK)) - { - ok1 = ffestc_labelref_is_branch_ (ffebld_labtok (labexpr), - &label); - ffelex_token_kill (ffebld_labtok (labexpr)); - if (!ok1) - { - label = NULL; - ok = FALSE; - } - ffebld_set_op (labexpr, FFEBLD_opLABTER); - ffebld_set_labter (labexpr, label); - } - } - - if (ok) - ffestd_R1212 (expr); - } - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R1213 -- Defined assignment statement - - ffestc_R1213(dest_expr,source_expr,source_token); - - Make sure the assignment is valid. */ - -#if FFESTR_F90 -void -ffestc_R1213 (ffebld dest, ffebld source, ffelexToken source_token) -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - ffestd_R1213 (dest, source); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -#endif -/* ffestc_R1219 -- FUNCTION statement - - ffestc_R1219(funcname,arglist,ending_token,kind,kindt,len,lent, - recursive); - - Make sure statement is valid here, register arguments for the - function name, and so on. - - 06-Apr-90 JCB 2.0 - Added the kind, len, and recursive arguments. */ - -void -ffestc_R1219 (ffelexToken funcname, ffesttTokenList args, - ffelexToken final UNUSED, ffestpType type, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent, - ffelexToken recursive, ffelexToken result) -{ - ffestw b; - ffesymbol s; - ffesymbol fs; /* FUNCTION symbol when dealing with RESULT - symbol. */ - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffelexToken res; - bool separate_result; - - assert ((funcname != NULL) - && (ffelex_token_type (funcname) == FFELEX_typeNAME)); - - ffestc_check_simple_ (); - if (ffestc_order_iface_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_blocknum_ = 0; - ffesta_is_entry_valid = - (ffestw_state (ffestw_stack_top ()) == FFESTV_stateNIL); - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateFUNCTION0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_function_); - ffestw_set_name (b, ffelex_token_use (funcname)); - - if (type == FFESTP_typeNone) - { - ffestc_local_.decl.basic_type = FFEINFO_basictypeNONE; - ffestc_local_.decl.kind_type = FFEINFO_kindtypeNONE; - ffestc_local_.decl.size = FFETARGET_charactersizeNONE; - } - else - { - ffestc_establish_declstmt_ (type, ffesta_tokens[0], - kind, kindt, len, lent); - ffestc_establish_declinfo_ (NULL, NULL, NULL, NULL); - } - - separate_result = (result != NULL) - && (ffelex_token_strcmp (funcname, result) != 0); - - if (separate_result) - fs = ffesymbol_declare_funcnotresunit (funcname); /* Global/local. */ - else - fs = ffesymbol_declare_funcunit (funcname); /* Global only. */ - - if (ffesymbol_state (fs) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (fs, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_signal_unreported (fs); - - /* Note that .basic_type and .kind_type might be NONE here. */ - - ffesymbol_set_info (fs, - ffeinfo_new (ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - 0, - FFEINFO_kindFUNCTION, - FFEINFO_whereLOCAL, - ffestc_local_.decl.size)); - - /* Check whether the type info fits the filewide expectations; - set ok flag accordingly. */ - - ffesymbol_reference (fs, funcname, FALSE); - if (ffesymbol_attrs (fs) & FFESYMBOL_attrsANY) - ffestc_parent_ok_ = FALSE; - else - ffestc_parent_ok_ = TRUE; - } - else - { - if (ffesymbol_kind (fs) != FFEINFO_kindANY) - ffesymbol_error (fs, funcname); - ffestc_parent_ok_ = FALSE; - } - - if (ffestc_parent_ok_) - { - ffebld_init_list (&fs->dummy_args, &ffestc_local_.dummy.list_bottom); - ffestt_tokenlist_drive (args, ffestc_promote_dummy_); - ffebld_end_list (&ffestc_local_.dummy.list_bottom); - } - - if (result == NULL) - res = funcname; - else - res = result; - - s = ffesymbol_declare_funcresult (res); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (ffesymbol_state (s) != FFESYMBOL_stateNONE) - na = FFESYMBOL_attrsetNONE; - else - { - na = FFESYMBOL_attrsRESULT; - if (ffestc_local_.decl.basic_type != FFEINFO_basictypeNONE) - { - na |= FFESYMBOL_attrsTYPE; - if ((ffestc_local_.decl.basic_type == FFEINFO_basictypeCHARACTER) - && (ffestc_local_.decl.size == FFETARGET_charactersizeNONE)) - na |= FFESYMBOL_attrsANYLEN; - } - } - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if ((na & ~FFESYMBOL_attrsANY) == FFESYMBOL_attrsetNONE) - { - if (!(na & FFESYMBOL_attrsANY)) - ffesymbol_error (s, res); - ffesymbol_set_funcresult (fs, NULL); - ffesymbol_set_funcresult (s, NULL); - ffestc_parent_ok_ = FALSE; - } - else - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - ffesymbol_set_funcresult (fs, s); - ffesymbol_set_funcresult (s, fs); - if (ffestc_local_.decl.basic_type != FFEINFO_basictypeNONE) - { - ffesymbol_set_info (s, - ffeinfo_new (ffestc_local_.decl.basic_type, - ffestc_local_.decl.kind_type, - 0, - FFEINFO_kindNONE, - FFEINFO_whereNONE, - ffestc_local_.decl.size)); - } - } - - ffesymbol_signal_unreported (fs); - - ffestd_R1219 (fs, funcname, args, type, kind, kindt, len, lent, - (recursive != NULL), result, separate_result); -} - -/* ffestc_R1221 -- END FUNCTION statement - - ffestc_R1221(name_token); - - Make sure ffestc_kind_ identifies the current kind of program unit. If - not NULL, make sure name_token gives the correct name. Implement the end - of the current program unit. */ - -void -ffestc_R1221 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_function_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if ((name != NULL) - && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) - { - ffebad_start (FFEBAD_UNIT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - - ffestc_shriek_function_ (TRUE); -} - -/* ffestc_R1223 -- SUBROUTINE statement - - ffestc_R1223(subrname,arglist,ending_token,recursive_token); - - Make sure statement is valid here, register arguments for the - subroutine name, and so on. - - 06-Apr-90 JCB 2.0 - Added the recursive argument. */ - -void -ffestc_R1223 (ffelexToken subrname, ffesttTokenList args, - ffelexToken final, ffelexToken recursive) -{ - ffestw b; - ffesymbol s; - - assert ((subrname != NULL) - && (ffelex_token_type (subrname) == FFELEX_typeNAME)); - - ffestc_check_simple_ (); - if (ffestc_order_iface_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestc_blocknum_ = 0; - ffesta_is_entry_valid - = (ffestw_state (ffestw_stack_top ()) == FFESTV_stateNIL); - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateSUBROUTINE0); - ffestw_set_blocknum (b, ffestc_blocknum_++); - ffestw_set_shriek (b, ffestc_shriek_subroutine_); - ffestw_set_name (b, ffelex_token_use (subrname)); - - s = ffesymbol_declare_subrunit (subrname); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindSUBROUTINE, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - ffestc_parent_ok_ = TRUE; - } - else - { - if (ffesymbol_kind (s) != FFEINFO_kindANY) - ffesymbol_error (s, subrname); - ffestc_parent_ok_ = FALSE; - } - - if (ffestc_parent_ok_) - { - ffebld_init_list (&s->dummy_args, &ffestc_local_.dummy.list_bottom); - ffestt_tokenlist_drive (args, ffestc_promote_dummy_); - ffebld_end_list (&ffestc_local_.dummy.list_bottom); - } - - ffesymbol_signal_unreported (s); - - ffestd_R1223 (s, subrname, args, final, (recursive != NULL)); -} - -/* ffestc_R1225 -- END SUBROUTINE statement - - ffestc_R1225(name_token); - - Make sure ffestc_kind_ identifies the current kind of program unit. If - not NULL, make sure name_token gives the correct name. Implement the end - of the current program unit. */ - -void -ffestc_R1225 (ffelexToken name) -{ - ffestc_check_simple_ (); - if (ffestc_order_subroutine_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_ (); - - if ((name != NULL) - && (ffelex_token_strcmp (name, ffestw_name (ffestw_stack_top ())) != 0)) - { - ffebad_start (FFEBAD_UNIT_WRONG_NAME); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_here (1, ffelex_token_where_line (ffestw_name (ffestw_stack_top ())), - ffelex_token_where_column (ffestw_name (ffestw_stack_top ()))); - ffebad_finish (); - } - - ffestc_shriek_subroutine_ (TRUE); -} - -/* ffestc_R1226 -- ENTRY statement - - ffestc_R1226(entryname,arglist,ending_token); - - Make sure we're in a SUBROUTINE or FUNCTION, register arguments for the - entry point name, and so on. */ - -void -ffestc_R1226 (ffelexToken entryname, ffesttTokenList args, - ffelexToken final UNUSED) -{ - ffesymbol s; - ffesymbol fs; - ffesymbolAttrs sa; - ffesymbolAttrs na; - bool in_spec; /* TRUE if further specification statements - may follow, FALSE if executable stmts. */ - bool in_func; /* TRUE if ENTRY is a FUNCTION, not - SUBROUTINE. */ - - assert ((entryname != NULL) - && (ffelex_token_type (entryname) == FFELEX_typeNAME)); - - ffestc_check_simple_ (); - if (ffestc_order_entry_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateFUNCTION1: - case FFESTV_stateFUNCTION2: - case FFESTV_stateFUNCTION3: - in_func = TRUE; - in_spec = TRUE; - break; - - case FFESTV_stateFUNCTION4: - in_func = TRUE; - in_spec = FALSE; - break; - - case FFESTV_stateSUBROUTINE1: - case FFESTV_stateSUBROUTINE2: - case FFESTV_stateSUBROUTINE3: - in_func = FALSE; - in_spec = TRUE; - break; - - case FFESTV_stateSUBROUTINE4: - in_func = FALSE; - in_spec = FALSE; - break; - - default: - assert ("ENTRY not in FUNCTION or SUBROUTINE?" == NULL); - in_func = FALSE; - in_spec = FALSE; - break; - } - - if (in_func) - fs = ffesymbol_declare_funcunit (entryname); - else - fs = ffesymbol_declare_subrunit (entryname); - - if (ffesymbol_state (fs) == FFESYMBOL_stateNONE) - ffesymbol_set_state (fs, FFESYMBOL_stateUNDERSTOOD); - else - { - if (ffesymbol_kind (fs) != FFEINFO_kindANY) - ffesymbol_error (fs, entryname); - } - - ++ffestc_entry_num_; - - ffebld_init_list (&fs->dummy_args, &ffestc_local_.dummy.list_bottom); - if (in_spec) - ffestt_tokenlist_drive (args, ffestc_promote_dummy_); - else - ffestt_tokenlist_drive (args, ffestc_promote_execdummy_); - ffebld_end_list (&ffestc_local_.dummy.list_bottom); - - if (in_func) - { - s = ffesymbol_declare_funcresult (entryname); - ffesymbol_set_funcresult (fs, s); - ffesymbol_set_funcresult (s, fs); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous - declarations of or references to the object. */ - - if (ffesymbol_state (s) == FFESYMBOL_stateUNDERSTOOD) - na = FFESYMBOL_attrsetNONE; - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (!(sa & ~(FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsTYPE))) - na = sa | FFESYMBOL_attrsRESULT; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error - cropped up; ANY means an old error to be ignored; otherwise, - everything's ok, update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - { - ffesymbol_error (s, entryname); - ffestc_parent_ok_ = FALSE; - } - else if (na & FFESYMBOL_attrsANY) - { - ffestc_parent_ok_ = FALSE; - } - else - { - ffesymbol_set_attrs (s, na); - if (ffesymbol_state (s) == FFESYMBOL_stateNONE) - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - else if (ffesymbol_state (s) == FFESYMBOL_stateUNCERTAIN) - { - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindENTITY, - FFEINFO_whereRESULT, - ffesymbol_size (s))); - ffesymbol_resolve_intrin (s); - ffestorag_exec_layout (s); - } - } - - /* Since ENTRY might appear after executable stmts, do what would have - been done if it hadn't -- give symbol implicit type and - exec-transition it. */ - - if (!in_spec && ffesymbol_is_specable (s)) - { - if (!ffeimplic_establish_symbol (s)) /* Do implicit typing. */ - ffesymbol_error (s, entryname); - s = ffecom_sym_exec_transition (s); - } - - /* Use whatever type info is available for ENTRY to set up type for its - global-name-space function symbol relative. */ - - ffesymbol_set_info (fs, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - 0, - FFEINFO_kindFUNCTION, - FFEINFO_whereLOCAL, - ffesymbol_size (s))); - - - /* Check whether the type info fits the filewide expectations; - set ok flag accordingly. */ - - ffesymbol_reference (fs, entryname, FALSE); - - /* ~~Question??: - When ENTRY FOO() RESULT(IBAR) is supported, what will the typing be - if FOO and IBAR would normally end up with different types? I think - the answer is that FOO is always given whatever type would be chosen - for IBAR, rather than the other way around, and I think it ends up - working that way for FUNCTION FOO() RESULT(IBAR), but this should be - checked out in all its different combos. Related question is, is - there any way that FOO in either case ends up without type info - filled in? Does anyone care? */ - - ffesymbol_signal_unreported (s); - } - else - { - ffesymbol_set_info (fs, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindSUBROUTINE, - FFEINFO_whereLOCAL, - FFETARGET_charactersizeNONE)); - } - - if (!in_spec) - fs = ffecom_sym_exec_transition (fs); - - ffesymbol_signal_unreported (fs); - - ffestd_R1226 (fs); -} - -/* ffestc_R1227 -- RETURN statement - - ffestc_R1227(expr,expr_token); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffestc_R1227 (ffebld expr, ffelexToken expr_token) -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_notloop_begin_ (); - - for (b = ffestw_stack_top (); ; b = ffestw_previous (b)) - { - switch (ffestw_state (b)) - { - case FFESTV_statePROGRAM4: - case FFESTV_stateSUBROUTINE4: - case FFESTV_stateFUNCTION4: - goto base; /* :::::::::::::::::::: */ - - case FFESTV_stateNIL: - assert ("bad state" == NULL); - break; - - default: - break; - } - } - - base: - switch (ffestw_state (b)) - { - case FFESTV_statePROGRAM4: - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_RETURN_IN_MAIN); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - if (expr != NULL) - { - ffebad_start (FFEBAD_ALTRETURN_IN_PROGRAM); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - expr = NULL; - } - break; - - case FFESTV_stateSUBROUTINE4: - break; - - case FFESTV_stateFUNCTION4: - if (expr != NULL) - { - ffebad_start (FFEBAD_ALTRETURN_IN_FUNCTION); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - expr = NULL; - } - break; - - default: - assert ("bad state #2" == NULL); - break; - } - - ffestd_R1227 (expr); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - - /* notloop's that are actionif's can be the target of a loop-end - statement if they're in the "then" part of a logical IF, as - in "DO 10", "10 IF (...) RETURN". */ - - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_R1228 -- CONTAINS statement - - ffestc_R1228(); */ - -#if FFESTR_F90 -void -ffestc_R1228 () -{ - ffestc_check_simple_ (); - if (ffestc_order_contains_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestd_R1228 (); - - ffe_terminate_3 (); - ffe_init_3 (); -} - -#endif -/* ffestc_R1229_start -- STMTFUNCTION statement begin - - ffestc_R1229_start(func_name,func_arg_list,close_paren); - - Verify that STMTFUNCTION is valid here, establish func_arg_list in a new - "live" scope within the current scope, and expect the actual expression - (or NULL) in ffestc_R1229_finish. The reason there are two ffestc - functions to handle this is so the scope can be established, allowing - ffeexpr to assign proper characteristics to references to the dummy - arguments. */ - -void -ffestc_R1229_start (ffelexToken name, ffesttTokenList args, - ffelexToken final UNUSED) -{ - ffesymbol s; - ffesymbolAttrs sa; - ffesymbolAttrs na; - - ffestc_check_start_ (); - if (ffestc_order_sfunc_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - assert (name != NULL); - assert (args != NULL); - - s = ffesymbol_declare_local (name, FALSE); - sa = ffesymbol_attrs (s); - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (!ffesymbol_is_specable (s)) - na = FFESYMBOL_attrsetNONE; /* Can't dcl sym ref'd in sfuncdef. */ - else if (sa & FFESYMBOL_attrsANY) - na = FFESYMBOL_attrsANY; - else if (!(sa & ~FFESYMBOL_attrsTYPE)) - na = sa | FFESYMBOL_attrsSFUNC; - else - na = FFESYMBOL_attrsetNONE; - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - { - ffesymbol_error (s, name); - ffestc_parent_ok_ = FALSE; - } - else if (na & FFESYMBOL_attrsANY) - ffestc_parent_ok_ = FALSE; - else - { - ffesymbol_set_attrs (s, na); - ffesymbol_set_state (s, FFESYMBOL_stateSEEN); - if (!ffeimplic_establish_symbol (s) - || ((ffesymbol_basictype (s) == FFEINFO_basictypeCHARACTER) - && (ffesymbol_size (s) == FFETARGET_charactersizeNONE))) - { - ffesymbol_error (s, ffesta_tokens[0]); - ffestc_parent_ok_ = FALSE; - } - else - { - /* Tell ffeexpr that sfunc def is in progress. */ - ffesymbol_set_sfexpr (s, ffebld_new_any ()); - ffebld_set_info (ffesymbol_sfexpr (s), ffeinfo_new_any ()); - ffestc_parent_ok_ = TRUE; - } - } - - ffe_init_4 (); - - if (ffestc_parent_ok_) - { - ffebld_init_list (&s->dummy_args, &ffestc_local_.dummy.list_bottom); - ffestc_sfdummy_argno_ = 0; - ffestt_tokenlist_drive (args, ffestc_promote_sfdummy_); - ffebld_end_list (&ffestc_local_.dummy.list_bottom); - } - - ffestc_local_.sfunc.symbol = s; - - ffestd_R1229_start (name, args); - - ffestc_ok_ = TRUE; -} - -/* ffestc_R1229_finish -- STMTFUNCTION statement list complete - - ffestc_R1229_finish(expr,expr_token); - - If expr is NULL, an error occurred parsing the expansion expression, so - just cancel the effects of ffestc_R1229_start and pretend nothing - happened. Otherwise, install the expression as the expansion for the - statement function named in _start_, then clean up. */ - -void -ffestc_R1229_finish (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - if (ffestc_parent_ok_ && (expr != NULL)) - ffesymbol_set_sfexpr (ffestc_local_.sfunc.symbol, - ffeexpr_convert_to_sym (expr, - expr_token, - ffestc_local_.sfunc.symbol, - ffesta_tokens[0])); - - ffestd_R1229_finish (ffestc_local_.sfunc.symbol); - - ffesymbol_signal_unreported (ffestc_local_.sfunc.symbol); - - ffe_terminate_4 (); -} - -/* ffestc_S3P4 -- INCLUDE line - - ffestc_S3P4(filename,filename_token); - - Make sure INCLUDE not preceded by any semicolons or a label def; implement. */ - -void -ffestc_S3P4 (ffebld filename, ffelexToken filename_token UNUSED) -{ - ffestc_check_simple_ (); - ffestc_labeldef_invalid_ (); - - ffestd_S3P4 (filename); -} - -/* ffestc_V003_start -- STRUCTURE statement list begin - - ffestc_V003_start(structure_name); - - Verify that STRUCTURE is valid here, and begin accepting items in the list. */ - -#if FFESTR_VXT -void -ffestc_V003_start (ffelexToken structure_name) -{ - ffestw b; - - ffestc_check_start_ (); - if (ffestc_order_vxtstructure_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - ffestc_local_.V003.list_state = 2; /* Require at least one field - name. */ - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one - member. */ - break; - - default: - ffestc_local_.V003.list_state = 0; /* No field names required. */ - if (structure_name == NULL) - { - ffebad_start (FFEBAD_STRUCT_MISSING_NAME); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - break; - } - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateSTRUCTURE); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_structure_); - ffestw_set_substate (b, 0); /* No field-declarations seen yet. */ - - ffestd_V003_start (structure_name); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V003_item -- STRUCTURE statement for object-name - - ffestc_V003_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be STRUCTUREd. */ - -void -ffestc_V003_item (ffelexToken name, ffesttDimList dims) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - if (ffestc_local_.V003.list_state < 2) - { - if (ffestc_local_.V003.list_state == 0) - { - ffestc_local_.V003.list_state = 1; - ffebad_start (FFEBAD_STRUCT_IGNORING_FIELD); - ffebad_here (0, ffelex_token_where_line (name), - ffelex_token_where_column (name)); - ffebad_finish (); - } - return; - } - ffestc_local_.V003.list_state = 3; /* Have at least one field name. */ - - if (dims != NULL) - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_V003_item (name, dims); -} - -/* ffestc_V003_finish -- STRUCTURE statement list complete - - ffestc_V003_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V003_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - if (ffestc_local_.V003.list_state == 2) - { - ffebad_start (FFEBAD_STRUCT_MISSING_FIELD); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_previous (ffestw_stack_top ())), - ffestw_col (ffestw_previous (ffestw_stack_top ()))); - ffebad_finish (); - } - - ffestd_V003_finish (); -} - -/* ffestc_V004 -- END STRUCTURE statement - - ffestc_V004(); - - Make sure ffestc_kind_ identifies a STRUCTURE block. - Implement the end of the current STRUCTURE block. */ - -void -ffestc_V004 () -{ - ffestc_check_simple_ (); - if (ffestc_order_structure_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 1) - { - ffebad_start (FFEBAD_STRUCT_NO_COMPONENTS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestc_shriek_structure_ (TRUE); -} - -/* ffestc_V009 -- UNION statement - - ffestc_V009(); */ - -void -ffestc_V009 () -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_structure_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one member. */ - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateUNION); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_union_); - ffestw_set_substate (b, 0); /* No map decls seen yet. */ - - ffestd_V009 (); -} - -/* ffestc_V010 -- END UNION statement - - ffestc_V010(); - - Make sure ffestc_kind_ identifies a UNION block. - Implement the end of the current UNION block. */ - -void -ffestc_V010 () -{ - ffestc_check_simple_ (); - if (ffestc_order_union_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 2) - { - ffebad_start (FFEBAD_UNION_NO_TWO_MAPS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestc_shriek_union_ (TRUE); -} - -/* ffestc_V012 -- MAP statement - - ffestc_V012(); */ - -void -ffestc_V012 () -{ - ffestw b; - - ffestc_check_simple_ (); - if (ffestc_order_union_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 2) - ffestw_substate (ffestw_stack_top ())++; /* 0=>1, 1=>2. */ - - b = ffestw_update (ffestw_push (NULL)); - ffestw_set_top_do (b, NULL); - ffestw_set_state (b, FFESTV_stateMAP); - ffestw_set_blocknum (b, 0); - ffestw_set_shriek (b, ffestc_shriek_map_); - ffestw_set_substate (b, 0); /* No field-declarations seen yet. */ - - ffestd_V012 (); -} - -/* ffestc_V013 -- END MAP statement - - ffestc_V013(); - - Make sure ffestc_kind_ identifies a MAP block. - Implement the end of the current MAP block. */ - -void -ffestc_V013 () -{ - ffestc_check_simple_ (); - if (ffestc_order_map_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_useless_ (); - - if (ffestw_substate (ffestw_stack_top ()) != 1) - { - ffebad_start (FFEBAD_MAP_NO_COMPONENTS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_here (1, ffestw_line (ffestw_stack_top ()), ffestw_col (ffestw_stack_top ())); - ffebad_finish (); - } - - ffestc_shriek_map_ (TRUE); -} - -#endif -/* ffestc_V014_start -- VOLATILE statement list begin - - ffestc_V014_start(); - - Verify that VOLATILE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V014_start () -{ - ffestc_check_start_ (); - if (ffestc_order_progspec_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_V014_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V014_item_object -- VOLATILE statement for object-name - - ffestc_V014_item_object(name_token); - - Make sure name_token identifies a valid object to be VOLATILEd. */ - -void -ffestc_V014_item_object (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_V014_item_object (name); -} - -/* ffestc_V014_item_cblock -- VOLATILE statement for common-block-name - - ffestc_V014_item_cblock(name_token); - - Make sure name_token identifies a valid common block to be VOLATILEd. */ - -void -ffestc_V014_item_cblock (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_V014_item_cblock (name); -} - -/* ffestc_V014_finish -- VOLATILE statement list complete - - ffestc_V014_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V014_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V014_finish (); -} - -/* ffestc_V016_start -- RECORD statement list begin - - ffestc_V016_start(); - - Verify that RECORD is valid here, and begin accepting items in the list. */ - -#if FFESTR_VXT -void -ffestc_V016_start () -{ - ffestc_check_start_ (); - if (ffestc_order_record_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - switch (ffestw_state (ffestw_stack_top ())) - { - case FFESTV_stateSTRUCTURE: - case FFESTV_stateMAP: - ffestw_set_substate (ffestw_stack_top (), 1); /* Seen at least one - member. */ - break; - - default: - break; - } - - ffestd_V016_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V016_item_structure -- RECORD statement for common-block-name - - ffestc_V016_item_structure(name_token); - - Make sure name_token identifies a valid structure to be RECORDed. */ - -void -ffestc_V016_item_structure (ffelexToken name) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - ffestd_V016_item_structure (name); -} - -/* ffestc_V016_item_object -- RECORD statement for object-name - - ffestc_V016_item_object(name_token,dim_list); - - Make sure name_token identifies a valid object to be RECORDd. */ - -void -ffestc_V016_item_object (ffelexToken name, ffesttDimList dims) -{ - ffestc_check_item_ (); - assert (name != NULL); - if (!ffestc_ok_) - return; - - if (dims != NULL) - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - - ffestd_V016_item_object (name, dims); -} - -/* ffestc_V016_finish -- RECORD statement list complete - - ffestc_V016_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V016_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V016_finish (); -} - -/* ffestc_V018_start -- REWRITE(...) statement list begin - - ffestc_V018_start(); - - Verify that REWRITE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V018_start () -{ - ffestvFormat format; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_branch_ - (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixERR]) - || !ffestc_subr_is_format_ - (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT]) - || !ffestc_subr_is_present_ ("UNIT", - &ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixUNIT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT]); - switch (format) - { - case FFESTV_formatNAMELIST: - case FFESTV_formatASTERISK: - ffebad_start (FFEBAD_CONFLICTING_SPECS); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - assert (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_or_val_present); - if (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw_present) - { - ffebad_here (0, ffelex_token_where_line - (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw), - ffelex_token_where_column - (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].kw)); - } - else - { - ffebad_here (1, ffelex_token_where_line - (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value), - ffelex_token_where_column - (ffestp_file.rewrite.rewrite_spec[FFESTP_rewriteixFMT].value)); - } - ffebad_finish (); - ffestc_ok_ = FALSE; - return; - - default: - break; - } - - ffestd_V018_start (format); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V018_item -- REWRITE statement i/o item - - ffestc_V018_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_V018_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_V018_item (expr); -} - -/* ffestc_V018_finish -- REWRITE statement list complete - - ffestc_V018_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V018_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V018_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V019_start -- ACCEPT statement list begin - - ffestc_V019_start(); - - Verify that ACCEPT is valid here, and begin accepting items in the - list. */ - -void -ffestc_V019_start () -{ - ffestvFormat format; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_format_ - (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.accept.accept_spec[FFESTP_acceptixFORMAT]); - ffestc_namelist_ = (format == FFESTV_formatNAMELIST); - - ffestd_V019_start (format); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V019_item -- ACCEPT statement i/o item - - ffestc_V019_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_V019_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_namelist_ != 0) - { - if (ffestc_namelist_ == 1) - { - ffestc_namelist_ = 2; - ffebad_start (FFEBAD_NAMELIST_ITEMS); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - } - return; - } - - ffestd_V019_item (expr); -} - -/* ffestc_V019_finish -- ACCEPT statement list complete - - ffestc_V019_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V019_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V019_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -#endif -/* ffestc_V020_start -- TYPE statement list begin - - ffestc_V020_start(); - - Verify that TYPE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V020_start () -{ - ffestvFormat format; - - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_format_ - (&ffestp_file.type.type_spec[FFESTP_typeixFORMAT])) - { - ffestc_ok_ = FALSE; - return; - } - - format = ffestc_subr_format_ - (&ffestp_file.type.type_spec[FFESTP_typeixFORMAT]); - ffestc_namelist_ = (format == FFESTV_formatNAMELIST); - - ffestd_V020_start (format); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V020_item -- TYPE statement i/o item - - ffestc_V020_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_V020_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - if (ffestc_namelist_ != 0) - { - if (ffestc_namelist_ == 1) - { - ffestc_namelist_ = 2; - ffebad_start (FFEBAD_NAMELIST_ITEMS); - ffebad_here (0, ffelex_token_where_line (expr_token), - ffelex_token_where_column (expr_token)); - ffebad_finish (); - } - return; - } - - ffestd_V020_item (expr); -} - -/* ffestc_V020_finish -- TYPE statement list complete - - ffestc_V020_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V020_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V020_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V021 -- DELETE statement - - ffestc_V021(); - - Make sure a DELETE is valid in the current context, and implement it. */ - -#if FFESTR_VXT -void -ffestc_V021 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.delete.delete_spec[FFESTP_deleteixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.delete.delete_spec[FFESTP_deleteixUNIT])) - ffestd_V021 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V022 -- UNLOCK statement - - ffestc_V022(); - - Make sure a UNLOCK is valid in the current context, and implement it. */ - -void -ffestc_V022 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.beru.beru_spec[FFESTP_beruixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.beru.beru_spec[FFESTP_beruixUNIT])) - ffestd_V022 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V023_start -- ENCODE(...) statement list begin - - ffestc_V023_start(); - - Verify that ENCODE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V023_start () -{ - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_branch_ - (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR])) - { - ffestc_ok_ = FALSE; - return; - } - - ffestd_V023_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V023_item -- ENCODE statement i/o item - - ffestc_V023_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_V023_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_V023_item (expr); -} - -/* ffestc_V023_finish -- ENCODE statement list complete - - ffestc_V023_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V023_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V023_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V024_start -- DECODE(...) statement list begin - - ffestc_V024_start(); - - Verify that DECODE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V024_start () -{ - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - if (!ffestc_subr_is_branch_ - (&ffestp_file.vxtcode.vxtcode_spec[FFESTP_vxtcodeixERR])) - { - ffestc_ok_ = FALSE; - return; - } - - ffestd_V024_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V024_item -- DECODE statement i/o item - - ffestc_V024_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestc_V024_item (ffebld expr, ffelexToken expr_token) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_V024_item (expr); -} - -/* ffestc_V024_finish -- DECODE statement list complete - - ffestc_V024_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V024_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V024_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V025_start -- DEFINEFILE statement list begin - - ffestc_V025_start(); - - Verify that DEFINEFILE is valid here, and begin accepting items in the - list. */ - -void -ffestc_V025_start () -{ - ffestc_check_start_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_branch_begin_ (); - - ffestd_V025_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V025_item -- DEFINE FILE statement item - - ffestc_V025_item(u,ut,m,mt,n,nt,asv,asvt); - - Implement item. */ - -void -ffestc_V025_item (ffebld u, ffelexToken ut, ffebld m, ffelexToken mt, - ffebld n, ffelexToken nt, ffebld asv, ffelexToken asvt) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_V025_item (u, m, n, asv); -} - -/* ffestc_V025_finish -- DEFINE FILE statement list complete - - ffestc_V025_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V025_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V025_finish (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -/* ffestc_V026 -- FIND statement - - ffestc_V026(); - - Make sure a FIND is valid in the current context, and implement it. */ - -void -ffestc_V026 () -{ - ffestc_check_simple_ (); - if (ffestc_order_actionif_ () != FFESTC_orderOK_) - return; - ffestc_labeldef_branch_begin_ (); - - if (ffestc_subr_is_branch_ - (&ffestp_file.find.find_spec[FFESTP_findixERR]) - && ffestc_subr_is_present_ ("UNIT", - &ffestp_file.find.find_spec[FFESTP_findixUNIT]) - && ffestc_subr_is_present_ ("REC", - &ffestp_file.find.find_spec[FFESTP_findixREC])) - ffestd_V026 (); - - if (ffestc_shriek_after1_ != NULL) - (*ffestc_shriek_after1_) (TRUE); - ffestc_labeldef_branch_end_ (); -} - -#endif -/* ffestc_V027_start -- VXT PARAMETER statement list begin - - ffestc_V027_start(); - - Verify that PARAMETER is valid here, and begin accepting items in the list. */ - -void -ffestc_V027_start () -{ - ffestc_check_start_ (); - if (ffestc_order_parameter_ () != FFESTC_orderOK_) - { - ffestc_ok_ = FALSE; - return; - } - ffestc_labeldef_useless_ (); - - ffestd_V027_start (); - - ffestc_ok_ = TRUE; -} - -/* ffestc_V027_item -- VXT PARAMETER statement assignment - - ffestc_V027_item(dest,dest_token,source,source_token); - - Make sure the source is a valid source for the destination; make the - assignment. */ - -void -ffestc_V027_item (ffelexToken dest_token, ffebld source, - ffelexToken source_token UNUSED) -{ - ffestc_check_item_ (); - if (!ffestc_ok_) - return; - - ffestd_V027_item (dest_token, source); -} - -/* ffestc_V027_finish -- VXT PARAMETER statement list complete - - ffestc_V027_finish(); - - Just wrap up any local activities. */ - -void -ffestc_V027_finish () -{ - ffestc_check_finish_ (); - if (!ffestc_ok_) - return; - - ffestd_V027_finish (); -} - -/* Any executable statement. Mainly make sure that one-shot things - like the statement for a logical IF are reset. */ - -void -ffestc_any () -{ - ffestc_check_simple_ (); - - ffestc_order_any_ (); - - ffestc_labeldef_any_ (); - - if (ffestc_shriek_after1_ == NULL) - return; - - ffestd_any (); - - (*ffestc_shriek_after1_) (TRUE); -} diff --git a/gcc/f/stc.h b/gcc/f/stc.h deleted file mode 100755 index c26fca1..0000000 --- a/gcc/f/stc.h +++ /dev/null @@ -1,360 +0,0 @@ -/* stc.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stc.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stc -#define _H_f_stc - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bad.h" -#include "bld.h" -#include "expr.h" -#include "lex.h" -#include "stp.h" -#include "str.h" -#include "stt.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern ffeexprContext ffestc_iolist_context_; - -/* Declare functions with prototypes. */ - -void ffestc_decl_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent); -void ffestc_decl_attrib (ffestpAttrib attrib, ffelexToken attribt, - ffestrOther intent_kw, ffesttDimList dims); -void ffestc_decl_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, - ffebld init, ffelexToken initt, bool clist); -void ffestc_decl_itemstartvals (void); -void ffestc_decl_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token); -void ffestc_decl_itemendvals (ffelexToken t); -void ffestc_decl_finish (void); -void ffestc_elsewhere (ffelexToken where_token); -void ffestc_end (void); -void ffestc_eof (void); -bool ffestc_exec_transition (void); -void ffestc_ffebad_here_doiter (ffebadIndex i, ffesymbol s); -void ffestc_init_3 (void); -void ffestc_init_4 (void); -bool ffestc_is_decl_not_R1219 (void); -bool ffestc_is_entry_in_subr (void); -bool ffestc_is_let_not_V027 (void); -#if FFESTR_F90 -void ffestc_let (ffebld dest, ffebld source, ffelexToken source_token); -#else -#define ffestc_let ffestc_R737 -#endif -#if FFESTR_F90 -void ffestc_module (ffelexToken module_name, ffelexToken procedure_name); -#endif -#if FFESTR_F90 -void ffestc_private (void); -#endif -void ffestc_terminate_4 (void); -#if FFESTR_F90 -void ffestc_R423A (void); -void ffestc_R423B (void); -void ffestc_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name); -void ffestc_R425 (ffelexToken name); -void ffestc_R426_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent); -void ffestc_R426_attrib (ffestpAttrib attrib, ffelexToken attribt, - ffestrOther intent_kw, ffesttDimList dims); -void ffestc_R426_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, - ffelexToken initt, bool clist); -void ffestc_R426_itemstartvals (void); -void ffestc_R426_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token); -void ffestc_R426_itemendvals (ffelexToken t); -void ffestc_R426_finish (void); -#endif -void ffestc_R501_start (ffestpType type, ffelexToken typet, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent); -void ffestc_R501_attrib (ffestpAttrib attrib, ffelexToken attribt, - ffestrOther intent_kw, ffesttDimList dims); -void ffestc_R501_item (ffelexToken name, ffebld kind, ffelexToken kindt, - ffesttDimList dims, ffebld len, ffelexToken lent, ffebld init, - ffelexToken initt, bool clist); -void ffestc_R501_itemstartvals (void); -void ffestc_R501_itemvalue (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token); -void ffestc_R501_itemendvals (ffelexToken t); -void ffestc_R501_finish (void); -#if FFESTR_F90 -void ffestc_R519_start (ffelexToken intent, ffestrOther intent_kw); -void ffestc_R519_item (ffelexToken name); -void ffestc_R519_finish (void); -void ffestc_R520_start (void); -void ffestc_R520_item (ffelexToken name); -void ffestc_R520_finish (void); -void ffestc_R521A (void); -void ffestc_R521Astart (void); -void ffestc_R521Aitem (ffelexToken name); -void ffestc_R521Afinish (void); -void ffestc_R521B (void); -void ffestc_R521Bstart (void); -void ffestc_R521Bitem (ffelexToken name); -void ffestc_R521Bfinish (void); -#endif -void ffestc_R522 (void); -void ffestc_R522start (void); -void ffestc_R522item_object (ffelexToken name); -void ffestc_R522item_cblock (ffelexToken name); -void ffestc_R522finish (void); -void ffestc_R524_start (bool virtual); -void ffestc_R524_item (ffelexToken name, ffesttDimList dims); -void ffestc_R524_finish (void); -#if FFESTR_F90 -void ffestc_R525_start (void); -void ffestc_R525_item (ffelexToken name, ffesttDimList dims); -void ffestc_R525_finish (void); -void ffestc_R526_start (void); -void ffestc_R526_item (ffelexToken name, ffesttDimList dims); -void ffestc_R526_finish (void); -void ffestc_R527_start (void); -void ffestc_R527_item (ffelexToken name, ffesttDimList dims); -void ffestc_R527_finish (void); -#endif -void ffestc_R528_start (void); -void ffestc_R528_item_object (ffebld expr, ffelexToken expr_token); -void ffestc_R528_item_startvals (void); -void ffestc_R528_item_value (ffebld repeat, ffelexToken repeat_token, - ffebld value, ffelexToken value_token); -void ffestc_R528_item_endvals (ffelexToken t); -void ffestc_R528_finish (void); -void ffestc_R537_start (void); -void ffestc_R537_item (ffebld dest, ffelexToken dest_token, ffebld source, - ffelexToken source_token); -void ffestc_R537_finish (void); -void ffestc_R539 (void); -void ffestc_R539start (void); -void ffestc_R539item (ffestpType type, ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent, ffesttImpList letters); -void ffestc_R539finish (void); -void ffestc_R542_start (void); -void ffestc_R542_item_nlist (ffelexToken name); -void ffestc_R542_item_nitem (ffelexToken name); -void ffestc_R542_finish (void); -void ffestc_R544_start (void); -void ffestc_R544_item (ffesttExprList exprlist); -void ffestc_R544_finish (void); -void ffestc_R547_start (void); -void ffestc_R547_item_object (ffelexToken name, ffesttDimList dims); -void ffestc_R547_item_cblock (ffelexToken name); -void ffestc_R547_finish (void); -#if FFESTR_F90 -void ffestc_R620 (ffesttExprList objects, ffebld stat, - ffelexToken stat_token); -void ffestc_R624 (ffesttExprList pointers); -void ffestc_R625 (ffesttExprList objects, ffebld stat, - ffelexToken stat_token); -#endif -void ffestc_R737 (ffebld dest, ffebld source, ffelexToken source_token); -#if FFESTR_F90 -void ffestc_R738 (ffebld dest, ffebld source, ffelexToken source_token); -void ffestc_R740 (ffebld expr, ffelexToken expr_token); -void ffestc_R742 (ffebld expr, ffelexToken expr_token); -void ffestc_R744 (void); -void ffestc_R745 (void); -#endif -void ffestc_R803 (ffelexToken construct_name, ffebld expr, - ffelexToken expr_token); -void ffestc_R804 (ffebld expr, ffelexToken expr_token, ffelexToken name); -void ffestc_R805 (ffelexToken name); -void ffestc_R806 (ffelexToken name); -void ffestc_R807 (ffebld expr, ffelexToken expr_token); -void ffestc_R809 (ffelexToken construct_name, ffebld expr, - ffelexToken expr_token); -void ffestc_R810 (ffesttCaseList cases, ffelexToken name); -void ffestc_R811 (ffelexToken name); -void ffestc_R819A (ffelexToken construct_name, ffelexToken label, ffebld var, - ffelexToken var_token, ffebld start, ffelexToken start_token, ffebld end, - ffelexToken end_token, ffebld incr, ffelexToken incr_token); -void ffestc_R819B (ffelexToken construct_name, ffelexToken label, ffebld expr, - ffelexToken expr_token); -void ffestc_R820A (ffelexToken construct_name, ffebld var, - ffelexToken var_token, ffebld start, ffelexToken start_token, ffebld end, - ffelexToken end_token, ffebld incr, ffelexToken incr_token); -void ffestc_R820B (ffelexToken construct_name, ffebld expr, - ffelexToken expr_token); -void ffestc_R825 (ffelexToken name); -void ffestc_R834 (ffelexToken name); -void ffestc_R835 (ffelexToken name); -void ffestc_R836 (ffelexToken label); -void ffestc_R837 (ffesttTokenList label_toks, ffebld expr, - ffelexToken expr_token); -void ffestc_R838 (ffelexToken label, ffebld target, ffelexToken target_token); -void ffestc_R839 (ffebld target, ffelexToken target_token, - ffesttTokenList label_toks); -void ffestc_R840 (ffebld expr, ffelexToken expr_token, ffelexToken neg, - ffelexToken zero, ffelexToken pos); -void ffestc_R841 (void); -void ffestc_R842 (ffebld expr, ffelexToken expr_token); -void ffestc_R843 (ffebld expr, ffelexToken expr_token); -void ffestc_R904 (void); -void ffestc_R907 (void); -void ffestc_R909_start (bool only_format); -void ffestc_R909_item (ffebld expr, ffelexToken expr_token); -void ffestc_R909_finish (void); -void ffestc_R910_start (void); -void ffestc_R910_item (ffebld expr, ffelexToken expr_token); -void ffestc_R910_finish (void); -void ffestc_R911_start (void); -void ffestc_R911_item (ffebld expr, ffelexToken expr_token); -void ffestc_R911_finish (void); -void ffestc_R919 (void); -void ffestc_R920 (void); -void ffestc_R921 (void); -void ffestc_R923A (void); -void ffestc_R923B_start (void); -void ffestc_R923B_item (ffebld expr, ffelexToken expr_token); -void ffestc_R923B_finish (void); -void ffestc_R1001 (ffesttFormatList f); -void ffestc_R1102 (ffelexToken name); -void ffestc_R1103 (ffelexToken name); -#if FFESTR_F90 -void ffestc_R1105 (ffelexToken name); -void ffestc_R1106 (ffelexToken name); -void ffestc_R1107_start (ffelexToken name, bool only); -void ffestc_R1107_item (ffelexToken local, ffelexToken use); -void ffestc_R1107_finish (void); -#endif -void ffestc_R1111 (ffelexToken name); -void ffestc_R1112 (ffelexToken name); -#if FFESTR_F90 -void ffestc_R1202 (ffestpDefinedOperator operator, ffelexToken name); -void ffestc_R1203 (void); -void ffestc_R1205_start (void); -void ffestc_R1205_item (ffelexToken name); -void ffestc_R1205_finish (void); -#endif -void ffestc_R1207_start (void); -void ffestc_R1207_item (ffelexToken name); -void ffestc_R1207_finish (void); -void ffestc_R1208_start (void); -void ffestc_R1208_item (ffelexToken name); -void ffestc_R1208_finish (void); -void ffestc_R1212 (ffebld expr, ffelexToken expr_token); -#if FFESTR_F90 -void ffestc_R1213 (ffebld dest, ffebld source, ffelexToken source_token); -#endif -void ffestc_R1219 (ffelexToken funcname, ffesttTokenList args, - ffelexToken final, ffestpType type, ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent, ffelexToken recursive, ffelexToken result); -void ffestc_R1221 (ffelexToken name); -void ffestc_R1223 (ffelexToken subrname, ffesttTokenList args, - ffelexToken final, ffelexToken recursive); -void ffestc_R1225 (ffelexToken name); -void ffestc_R1226 (ffelexToken entryname, ffesttTokenList args, - ffelexToken final); -void ffestc_R1227 (ffebld expr, ffelexToken expr_token); -#if FFESTR_F90 -void ffestc_R1228 (void); -#endif -void ffestc_R1229_start (ffelexToken name, ffesttTokenList args, - ffelexToken final); -void ffestc_R1229_finish (ffebld expr, ffelexToken expr_token); -void ffestc_S3P4 (ffebld filename, ffelexToken filename_token); -#if FFESTR_VXT -void ffestc_V003_start (ffelexToken structure_name); -void ffestc_V003_item (ffelexToken name, ffesttDimList dims); -void ffestc_V003_finish (void); -void ffestc_V004 (void); -void ffestc_V009 (void); -void ffestc_V010 (void); -void ffestc_V012 (void); -void ffestc_V013 (void); -#endif -void ffestc_V014_start (void); -void ffestc_V014_item_object (ffelexToken name); -void ffestc_V014_item_cblock (ffelexToken name); -void ffestc_V014_finish (void); -#if FFESTR_VXT -void ffestc_V016_start (void); -void ffestc_V016_item_structure (ffelexToken name); -void ffestc_V016_item_object (ffelexToken name, ffesttDimList dims); -void ffestc_V016_finish (void); -void ffestc_V018_start (void); -void ffestc_V018_item (ffebld expr, ffelexToken expr_token); -void ffestc_V018_finish (void); -void ffestc_V019_start (void); -void ffestc_V019_item (ffebld expr, ffelexToken expr_token); -void ffestc_V019_finish (void); -#endif -void ffestc_V020_start (void); -void ffestc_V020_item (ffebld expr, ffelexToken expr_token); -void ffestc_V020_finish (void); -#if FFESTR_VXT -void ffestc_V021 (void); -void ffestc_V022 (void); -void ffestc_V023_start (void); -void ffestc_V023_item (ffebld expr, ffelexToken expr_token); -void ffestc_V023_finish (void); -void ffestc_V024_start (void); -void ffestc_V024_item (ffebld expr, ffelexToken expr_token); -void ffestc_V024_finish (void); -void ffestc_V025_start (void); -void ffestc_V025_item (ffebld u, ffelexToken ut, ffebld m, ffelexToken mt, - ffebld n, ffelexToken nt, ffebld asv, ffelexToken asvt); -void ffestc_V025_finish (void); -void ffestc_V026 (void); -#endif -void ffestc_V027_start (void); -void ffestc_V027_item (ffelexToken dest_token, ffebld source, - ffelexToken source_token); -void ffestc_V027_finish (void); -void ffestc_any (void); - -/* Define macros. */ - -#define ffestc_context_iolist() ffestc_iolist_context_ -#define ffestc_init_0() -#define ffestc_init_1() -#define ffestc_init_2() -#define ffestc_terminate_0() -#define ffestc_terminate_1() -#define ffestc_terminate_2() -#define ffestc_terminate_3() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/std.c b/gcc/f/std.c deleted file mode 100755 index 540da6c..0000000 --- a/gcc/f/std.c +++ /dev/null @@ -1,6905 +0,0 @@ -/* std.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - st.c - - Description: - Implements the various statements and such like. - - Modifications: - 21-Nov-91 JCB 2.0 - Split out actual code generation to ffeste. -*/ - -/* Include files. */ - -#include "proj.h" -#include "std.h" -#include "bld.h" -#include "com.h" -#include "lab.h" -#include "lex.h" -#include "malloc.h" -#include "sta.h" -#include "ste.h" -#include "stp.h" -#include "str.h" -#include "sts.h" -#include "stt.h" -#include "stv.h" -#include "stw.h" -#include "symbol.h" -#include "target.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - -#define FFESTD_COPY_EASY_ 1 /* 1 for only one _subr_copy_xyz_ fn. */ - -#define FFESTD_IS_END_OPTIMIZED_ 1 /* 0=always gen STOP/RETURN before - END. */ - -typedef enum - { - FFESTD_stateletSIMPLE_, /* Expecting simple/start. */ - FFESTD_stateletATTRIB_, /* Expecting attrib/item/itemstart. */ - FFESTD_stateletITEM_, /* Expecting item/itemstart/finish. */ - FFESTD_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */ - FFESTD_ - } ffestdStatelet_; - -#if FFECOM_TWOPASS -typedef enum - { - FFESTD_stmtidENDDOLOOP_, - FFESTD_stmtidENDLOGIF_, - FFESTD_stmtidEXECLABEL_, - FFESTD_stmtidFORMATLABEL_, - FFESTD_stmtidR737A_, /* let */ - FFESTD_stmtidR803_, /* IF-block */ - FFESTD_stmtidR804_, /* ELSE IF */ - FFESTD_stmtidR805_, /* ELSE */ - FFESTD_stmtidR806_, /* END IF */ - FFESTD_stmtidR807_, /* IF-logical */ - FFESTD_stmtidR809_, /* SELECT CASE */ - FFESTD_stmtidR810_, /* CASE */ - FFESTD_stmtidR811_, /* END SELECT */ - FFESTD_stmtidR819A_, /* DO-iterative */ - FFESTD_stmtidR819B_, /* DO WHILE */ - FFESTD_stmtidR825_, /* END DO */ - FFESTD_stmtidR834_, /* CYCLE */ - FFESTD_stmtidR835_, /* EXIT */ - FFESTD_stmtidR836_, /* GOTO */ - FFESTD_stmtidR837_, /* GOTO-computed */ - FFESTD_stmtidR838_, /* ASSIGN */ - FFESTD_stmtidR839_, /* GOTO-assigned */ - FFESTD_stmtidR840_, /* IF-arithmetic */ - FFESTD_stmtidR841_, /* CONTINUE */ - FFESTD_stmtidR842_, /* STOP */ - FFESTD_stmtidR843_, /* PAUSE */ - FFESTD_stmtidR904_, /* OPEN */ - FFESTD_stmtidR907_, /* CLOSE */ - FFESTD_stmtidR909_, /* READ */ - FFESTD_stmtidR910_, /* WRITE */ - FFESTD_stmtidR911_, /* PRINT */ - FFESTD_stmtidR919_, /* BACKSPACE */ - FFESTD_stmtidR920_, /* ENDFILE */ - FFESTD_stmtidR921_, /* REWIND */ - FFESTD_stmtidR923A_, /* INQUIRE */ - FFESTD_stmtidR923B_, /* INQUIRE-iolength */ - FFESTD_stmtidR1001_, /* FORMAT */ - FFESTD_stmtidR1103_, /* END_PROGRAM */ - FFESTD_stmtidR1112_, /* END_BLOCK_DATA */ - FFESTD_stmtidR1212_, /* CALL */ - FFESTD_stmtidR1221_, /* END_FUNCTION */ - FFESTD_stmtidR1225_, /* END_SUBROUTINE */ - FFESTD_stmtidR1226_, /* ENTRY */ - FFESTD_stmtidR1227_, /* RETURN */ -#if FFESTR_VXT - FFESTD_stmtidV018_, /* REWRITE */ - FFESTD_stmtidV019_, /* ACCEPT */ -#endif - FFESTD_stmtidV020_, /* TYPE */ -#if FFESTR_VXT - FFESTD_stmtidV021_, /* DELETE */ - FFESTD_stmtidV022_, /* UNLOCK */ - FFESTD_stmtidV023_, /* ENCODE */ - FFESTD_stmtidV024_, /* DECODE */ - FFESTD_stmtidV025start_, /* DEFINEFILE (start) */ - FFESTD_stmtidV025item_, /* (DEFINEFILE item) */ - FFESTD_stmtidV025finish_, /* (DEFINEFILE finish) */ - FFESTD_stmtidV026_, /* FIND */ -#endif - FFESTD_stmtid_, - } ffestdStmtId_; - -#endif - -/* Internal typedefs. */ - -typedef struct _ffestd_expr_item_ *ffestdExprItem_; -#if FFECOM_TWOPASS -typedef struct _ffestd_stmt_ *ffestdStmt_; -#endif - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffestd_expr_item_ - { - ffestdExprItem_ next; - ffebld expr; - ffelexToken token; - }; - -#if FFECOM_TWOPASS -struct _ffestd_stmt_ - { - ffestdStmt_ next; - ffestdStmt_ previous; - ffestdStmtId_ id; -#if FFECOM_targetCURRENT == FFECOM_targetGCC - char *filename; - int filelinenum; -#endif - union - { - struct - { - ffestw block; - } - enddoloop; - struct - { - ffelab label; - } - execlabel; - struct - { - ffelab label; - } - formatlabel; - struct - { - mallocPool pool; - ffebld dest; - ffebld source; - } - R737A; - struct - { - mallocPool pool; - ffebld expr; - } - R803; - struct - { - mallocPool pool; - ffebld expr; - } - R804; - struct - { - mallocPool pool; - ffebld expr; - } - R807; - struct - { - mallocPool pool; - ffestw block; - ffebld expr; - } - R809; - struct - { - mallocPool pool; - ffestw block; - unsigned long casenum; - } - R810; - struct - { - ffestw block; - } - R811; - struct - { - mallocPool pool; - ffestw block; - ffelab label; - ffebld var; - ffebld start; - ffelexToken start_token; - ffebld end; - ffelexToken end_token; - ffebld incr; - ffelexToken incr_token; - } - R819A; - struct - { - mallocPool pool; - ffestw block; - ffelab label; - ffebld expr; - } - R819B; - struct - { - ffestw block; - } - R834; - struct - { - ffestw block; - } - R835; - struct - { - ffelab label; - } - R836; - struct - { - mallocPool pool; - ffelab *labels; - int count; - ffebld expr; - } - R837; - struct - { - mallocPool pool; - ffelab label; - ffebld target; - } - R838; - struct - { - mallocPool pool; - ffebld target; - } - R839; - struct - { - mallocPool pool; - ffebld expr; - ffelab neg; - ffelab zero; - ffelab pos; - } - R840; - struct - { - mallocPool pool; - ffebld expr; - } - R842; - struct - { - mallocPool pool; - ffebld expr; - } - R843; - struct - { - mallocPool pool; - ffestpOpenStmt *params; - } - R904; - struct - { - mallocPool pool; - ffestpCloseStmt *params; - } - R907; - struct - { - mallocPool pool; - ffestpReadStmt *params; - bool only_format; - ffestvUnit unit; - ffestvFormat format; - bool rec; - bool key; - ffestdExprItem_ list; - } - R909; - struct - { - mallocPool pool; - ffestpWriteStmt *params; - ffestvUnit unit; - ffestvFormat format; - bool rec; - ffestdExprItem_ list; - } - R910; - struct - { - mallocPool pool; - ffestpPrintStmt *params; - ffestvFormat format; - ffestdExprItem_ list; - } - R911; - struct - { - mallocPool pool; - ffestpBeruStmt *params; - } - R919; - struct - { - mallocPool pool; - ffestpBeruStmt *params; - } - R920; - struct - { - mallocPool pool; - ffestpBeruStmt *params; - } - R921; - struct - { - mallocPool pool; - ffestpInquireStmt *params; - bool by_file; - } - R923A; - struct - { - mallocPool pool; - ffestpInquireStmt *params; - ffestdExprItem_ list; - } - R923B; - struct - { - ffestsHolder str; - } - R1001; - struct - { - mallocPool pool; - ffebld expr; - } - R1212; - struct - { - ffesymbol entry; - int entrynum; - } - R1226; - struct - { - mallocPool pool; - ffestw block; - ffebld expr; - } - R1227; -#if FFESTR_VXT - struct - { - mallocPool pool; - ffestpRewriteStmt *params; - ffestvFormat format; - ffestdExprItem_ list; - } - V018; - struct - { - mallocPool pool; - ffestpAcceptStmt *params; - ffestvFormat format; - ffestdExprItem_ list; - } - V019; -#endif - struct - { - mallocPool pool; - ffestpTypeStmt *params; - ffestvFormat format; - ffestdExprItem_ list; - } - V020; -#if FFESTR_VXT - struct - { - mallocPool pool; - ffestpDeleteStmt *params; - } - V021; - struct - { - mallocPool pool; - ffestpBeruStmt *params; - } - V022; - struct - { - mallocPool pool; - ffestpVxtcodeStmt *params; - ffestdExprItem_ list; - } - V023; - struct - { - mallocPool pool; - ffestpVxtcodeStmt *params; - ffestdExprItem_ list; - } - V024; - struct - { - ffebld u; - ffebld m; - ffebld n; - ffebld asv; - } - V025item; - struct - { - mallocPool pool; - } V025finish; - struct - { - mallocPool pool; - ffestpFindStmt *params; - } - V026; -#endif - } - u; - }; - -#endif - -/* Static objects accessed by functions in this module. */ - -static ffestdStatelet_ ffestd_statelet_ = FFESTD_stateletSIMPLE_; -static int ffestd_block_level_ = 0; /* Block level for reachableness. */ -static bool ffestd_is_reachable_; /* Is the current stmt reachable? */ -static ffelab ffestd_label_formatdef_ = NULL; -#if FFECOM_TWOPASS -static ffestdExprItem_ *ffestd_expr_list_; -static struct - { - ffestdStmt_ first; - ffestdStmt_ last; - } - -ffestd_stmt_list_ -= -{ - NULL, NULL -}; - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static int ffestd_2pass_entrypoints_ = 0; /* # ENTRY statements - pending. */ -#endif - -/* Static functions (internal). */ - -#if FFECOM_TWOPASS -static void ffestd_stmt_append_ (ffestdStmt_ stmt); -static ffestdStmt_ ffestd_stmt_new_ (ffestdStmtId_ id); -static void ffestd_stmt_pass_ (void); -#endif -#if FFESTD_COPY_EASY_ && FFECOM_TWOPASS -static ffestpInquireStmt *ffestd_subr_copy_easy_ (ffestpInquireIx max); -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void ffestd_subr_vxt_ (void); -#endif -#if FFESTR_F90 -static void ffestd_subr_f90_ (void); -#endif -static void ffestd_subr_labels_ (bool unexpected); -static void ffestd_R1001dump_ (ffests s, ffesttFormatList list); -static void ffestd_R1001dump_1005_1_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1005_2_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1005_3_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1005_4_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1005_5_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1010_1_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1010_2_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1010_3_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1010_4_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001dump_1010_5_ (ffests s, ffesttFormatList f, - char *string); -static void ffestd_R1001error_ (ffesttFormatList f); -static void ffestd_R1001rtexpr_ (ffests s, ffesttFormatList f, ffebld expr); - -/* Internal macros. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define ffestd_subr_line_now_() \ - ffeste_set_line (ffelex_token_where_filename (ffesta_tokens[0]), \ - ffelex_token_where_filelinenum (ffesta_tokens[0])) -#define ffestd_subr_line_restore_(s) \ - ffeste_set_line ((s)->filename, (s)->filelinenum) -#define ffestd_subr_line_save_(s) \ - ((s)->filename = ffelex_token_where_filename (ffesta_tokens[0]), \ - (s)->filelinenum = ffelex_token_where_filelinenum (ffesta_tokens[0])) -#else -#define ffestd_subr_line_now_() -#if FFECOM_TWOPASS -#define ffestd_subr_line_restore_(s) -#define ffestd_subr_line_save_(s) -#endif /* FFECOM_TWOPASS */ -#endif /* FFECOM_targetCURRENT != FFECOM_targetGCC */ -#define ffestd_check_simple_() \ - assert(ffestd_statelet_ == FFESTD_stateletSIMPLE_) -#define ffestd_check_start_() \ - assert(ffestd_statelet_ == FFESTD_stateletSIMPLE_); \ - ffestd_statelet_ = FFESTD_stateletATTRIB_ -#define ffestd_check_attrib_() \ - assert(ffestd_statelet_ == FFESTD_stateletATTRIB_) -#define ffestd_check_item_() \ - assert(ffestd_statelet_ == FFESTD_stateletATTRIB_ \ - || ffestd_statelet_ == FFESTD_stateletITEM_); \ - ffestd_statelet_ = FFESTD_stateletITEM_ -#define ffestd_check_item_startvals_() \ - assert(ffestd_statelet_ == FFESTD_stateletATTRIB_ \ - || ffestd_statelet_ == FFESTD_stateletITEM_); \ - ffestd_statelet_ = FFESTD_stateletITEMVALS_ -#define ffestd_check_item_value_() \ - assert(ffestd_statelet_ == FFESTD_stateletITEMVALS_) -#define ffestd_check_item_endvals_() \ - assert(ffestd_statelet_ == FFESTD_stateletITEMVALS_); \ - ffestd_statelet_ = FFESTD_stateletITEM_ -#define ffestd_check_finish_() \ - assert(ffestd_statelet_ == FFESTD_stateletATTRIB_ \ - || ffestd_statelet_ == FFESTD_stateletITEM_); \ - ffestd_statelet_ = FFESTD_stateletSIMPLE_ - -#if FFESTD_COPY_EASY_ && FFECOM_TWOPASS -#define ffestd_subr_copy_accept_() (ffestpAcceptStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_acceptix) -#define ffestd_subr_copy_beru_() (ffestpBeruStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_beruix) -#define ffestd_subr_copy_close_() (ffestpCloseStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_closeix) -#define ffestd_subr_copy_delete_() (ffestpDeleteStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_deleteix) -#define ffestd_subr_copy_find_() (ffestpFindStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_findix) -#define ffestd_subr_copy_inquire_() (ffestpInquireStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_inquireix) -#define ffestd_subr_copy_open_() (ffestpOpenStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_openix) -#define ffestd_subr_copy_print_() (ffestpPrintStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_printix) -#define ffestd_subr_copy_read_() (ffestpReadStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_readix) -#define ffestd_subr_copy_rewrite_() (ffestpRewriteStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_rewriteix) -#define ffestd_subr_copy_type_() (ffestpTypeStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_typeix) -#define ffestd_subr_copy_vxtcode_() (ffestpVxtcodeStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_vxtcodeix) -#define ffestd_subr_copy_write_() (ffestpWriteStmt *) \ - ffestd_subr_copy_easy_((ffestpInquireIx) FFESTP_writeix) -#endif - -/* ffestd_stmt_append_ -- Append statement to end of stmt list - - ffestd_stmt_append_(ffestd_stmt_new_(FFESTD_stmtidR737A_)); */ - -#if FFECOM_TWOPASS -static void -ffestd_stmt_append_ (ffestdStmt_ stmt) -{ - stmt->next = (ffestdStmt_) &ffestd_stmt_list_.first; - stmt->previous = ffestd_stmt_list_.last; - stmt->next->previous = stmt; - stmt->previous->next = stmt; -} - -#endif -/* ffestd_stmt_new_ -- Make new statement with given id - - ffestdStmt_ stmt; - stmt = ffestd_stmt_new_(FFESTD_stmtidR737A_); */ - -#if FFECOM_TWOPASS -static ffestdStmt_ -ffestd_stmt_new_ (ffestdStmtId_ id) -{ - ffestdStmt_ stmt; - - stmt = malloc_new_kp (ffe_pool_any_unit (), "ffestdStmt_", sizeof (*stmt)); - stmt->id = id; - return stmt; -} - -#endif -/* ffestd_stmt_pass_ -- Pass all statements on list to ffeste - - ffestd_stmt_pass_(); */ - -#if FFECOM_TWOPASS -static void -ffestd_stmt_pass_ () -{ - ffestdStmt_ stmt; - ffestdExprItem_ expr; /* For traversing lists. */ - bool okay = (TREE_CODE (current_function_decl) != ERROR_MARK); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - if ((ffestd_2pass_entrypoints_ != 0) && okay) - { - tree which = ffecom_which_entrypoint_decl (); - tree value; - tree label; - int pushok; - int ents = ffestd_2pass_entrypoints_; - tree duplicate; - - expand_start_case (0, which, TREE_TYPE (which), "entrypoint dispatch"); - push_momentary (); - - stmt = ffestd_stmt_list_.first; - do - { - while (stmt->id != FFESTD_stmtidR1226_) - stmt = stmt->next; - - if (stmt->u.R1226.entry != NULL) - { - value = build_int_2 (stmt->u.R1226.entrynum, 0); - /* Yes, we really want to build a null LABEL_DECL here and not - put it on any list. That's what pushcase wants, so that's - what it gets! */ - label = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - pushok = pushcase (value, convert, label, &duplicate); - assert (pushok == 0); - - label = ffecom_temp_label (); - TREE_USED (label) = 1; - expand_goto (label); - clear_momentary (); - - ffesymbol_hook (stmt->u.R1226.entry).length_tree = label; - } - stmt = stmt->next; - } - while (--ents != 0); - - pop_momentary (); - expand_end_case (which); - clear_momentary (); - } -#endif - - for (stmt = ffestd_stmt_list_.first; - stmt != (ffestdStmt_) &ffestd_stmt_list_.first; - stmt = stmt->next) - { - switch (stmt->id) - { - case FFESTD_stmtidENDDOLOOP_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_do (stmt->u.enddoloop.block); - ffestw_kill (stmt->u.enddoloop.block); - break; - - case FFESTD_stmtidENDLOGIF_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_end_R807 (); - break; - - case FFESTD_stmtidEXECLABEL_: - if (okay) - ffeste_labeldef_branch (stmt->u.execlabel.label); - break; - - case FFESTD_stmtidFORMATLABEL_: - if (okay) - ffeste_labeldef_format (stmt->u.formatlabel.label); - break; - - case FFESTD_stmtidR737A_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R737A (stmt->u.R737A.dest, stmt->u.R737A.source); - malloc_pool_kill (stmt->u.R737A.pool); - break; - - case FFESTD_stmtidR803_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R803 (stmt->u.R803.expr); - malloc_pool_kill (stmt->u.R803.pool); - break; - - case FFESTD_stmtidR804_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R804 (stmt->u.R804.expr); - malloc_pool_kill (stmt->u.R804.pool); - break; - - case FFESTD_stmtidR805_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R805 (); - break; - - case FFESTD_stmtidR806_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R806 (); - break; - - case FFESTD_stmtidR807_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R807 (stmt->u.R807.expr); - malloc_pool_kill (stmt->u.R807.pool); - break; - - case FFESTD_stmtidR809_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R809 (stmt->u.R809.block, stmt->u.R809.expr); - malloc_pool_kill (stmt->u.R809.pool); - break; - - case FFESTD_stmtidR810_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R810 (stmt->u.R810.block, stmt->u.R810.casenum); - malloc_pool_kill (stmt->u.R810.pool); - break; - - case FFESTD_stmtidR811_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R811 (stmt->u.R811.block); - malloc_pool_kill (ffestw_select (stmt->u.R811.block)->pool); - ffestw_kill (stmt->u.R811.block); - break; - - case FFESTD_stmtidR819A_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R819A (stmt->u.R819A.block, stmt->u.R819A.label, - stmt->u.R819A.var, - stmt->u.R819A.start, stmt->u.R819A.start_token, - stmt->u.R819A.end, stmt->u.R819A.end_token, - stmt->u.R819A.incr, stmt->u.R819A.incr_token); - ffelex_token_kill (stmt->u.R819A.start_token); - ffelex_token_kill (stmt->u.R819A.end_token); - if (stmt->u.R819A.incr_token != NULL) - ffelex_token_kill (stmt->u.R819A.incr_token); - malloc_pool_kill (stmt->u.R819A.pool); - break; - - case FFESTD_stmtidR819B_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R819B (stmt->u.R819B.block, stmt->u.R819B.label, - stmt->u.R819B.expr); - malloc_pool_kill (stmt->u.R819B.pool); - break; - - case FFESTD_stmtidR825_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R825 (); - break; - - case FFESTD_stmtidR834_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R834 (stmt->u.R834.block); - break; - - case FFESTD_stmtidR835_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R835 (stmt->u.R835.block); - break; - - case FFESTD_stmtidR836_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R836 (stmt->u.R836.label); - break; - - case FFESTD_stmtidR837_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R837 (stmt->u.R837.labels, stmt->u.R837.count, - stmt->u.R837.expr); - malloc_pool_kill (stmt->u.R837.pool); - break; - - case FFESTD_stmtidR838_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R838 (stmt->u.R838.label, stmt->u.R838.target); - malloc_pool_kill (stmt->u.R838.pool); - break; - - case FFESTD_stmtidR839_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R839 (stmt->u.R839.target); - malloc_pool_kill (stmt->u.R839.pool); - break; - - case FFESTD_stmtidR840_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R840 (stmt->u.R840.expr, stmt->u.R840.neg, stmt->u.R840.zero, - stmt->u.R840.pos); - malloc_pool_kill (stmt->u.R840.pool); - break; - - case FFESTD_stmtidR841_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R841 (); - break; - - case FFESTD_stmtidR842_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R842 (stmt->u.R842.expr); - if (stmt->u.R842.pool != NULL) - malloc_pool_kill (stmt->u.R842.pool); - break; - - case FFESTD_stmtidR843_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R843 (stmt->u.R843.expr); - malloc_pool_kill (stmt->u.R843.pool); - break; - - case FFESTD_stmtidR904_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R904 (stmt->u.R904.params); - malloc_pool_kill (stmt->u.R904.pool); - break; - - case FFESTD_stmtidR907_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R907 (stmt->u.R907.params); - malloc_pool_kill (stmt->u.R907.pool); - break; - - case FFESTD_stmtidR909_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R909_start (stmt->u.R909.params, stmt->u.R909.only_format, - stmt->u.R909.unit, stmt->u.R909.format, - stmt->u.R909.rec, stmt->u.R909.key); - for (expr = stmt->u.R909.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_R909_item (expr->expr, expr->token); - ffelex_token_kill (expr->token); - } - if (okay) - ffeste_R909_finish (); - malloc_pool_kill (stmt->u.R909.pool); - break; - - case FFESTD_stmtidR910_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R910_start (stmt->u.R910.params, stmt->u.R910.unit, - stmt->u.R910.format, stmt->u.R910.rec); - for (expr = stmt->u.R910.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_R910_item (expr->expr, expr->token); - ffelex_token_kill (expr->token); - } - if (okay) - ffeste_R910_finish (); - malloc_pool_kill (stmt->u.R910.pool); - break; - - case FFESTD_stmtidR911_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R911_start (stmt->u.R911.params, stmt->u.R911.format); - for (expr = stmt->u.R911.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_R911_item (expr->expr, expr->token); - ffelex_token_kill (expr->token); - } - if (okay) - ffeste_R911_finish (); - malloc_pool_kill (stmt->u.R911.pool); - break; - - case FFESTD_stmtidR919_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R919 (stmt->u.R919.params); - malloc_pool_kill (stmt->u.R919.pool); - break; - - case FFESTD_stmtidR920_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R920 (stmt->u.R920.params); - malloc_pool_kill (stmt->u.R920.pool); - break; - - case FFESTD_stmtidR921_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R921 (stmt->u.R921.params); - malloc_pool_kill (stmt->u.R921.pool); - break; - - case FFESTD_stmtidR923A_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R923A (stmt->u.R923A.params, stmt->u.R923A.by_file); - malloc_pool_kill (stmt->u.R923A.pool); - break; - - case FFESTD_stmtidR923B_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R923B_start (stmt->u.R923B.params); - for (expr = stmt->u.R923B.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_R923B_item (expr->expr); - } - if (okay) - ffeste_R923B_finish (); - malloc_pool_kill (stmt->u.R923B.pool); - break; - - case FFESTD_stmtidR1001_: - if (okay) - ffeste_R1001 (&stmt->u.R1001.str); - ffests_kill (&stmt->u.R1001.str); - break; - - case FFESTD_stmtidR1103_: - if (okay) - ffeste_R1103 (); - break; - - case FFESTD_stmtidR1112_: - if (okay) - ffeste_R1112 (); - break; - - case FFESTD_stmtidR1212_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R1212 (stmt->u.R1212.expr); - malloc_pool_kill (stmt->u.R1212.pool); - break; - - case FFESTD_stmtidR1221_: - if (okay) - ffeste_R1221 (); - break; - - case FFESTD_stmtidR1225_: - if (okay) - ffeste_R1225 (); - break; - - case FFESTD_stmtidR1226_: - ffestd_subr_line_restore_ (stmt); - if (stmt->u.R1226.entry != NULL) - { - if (okay) - ffeste_R1226 (stmt->u.R1226.entry); - } - break; - - case FFESTD_stmtidR1227_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_R1227 (stmt->u.R1227.block, stmt->u.R1227.expr); - malloc_pool_kill (stmt->u.R1227.pool); - break; - -#if FFESTR_VXT - case FFESTD_stmtidV018_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V018_start (stmt->u.V018.params, stmt->u.V018.format); - for (expr = stmt->u.V018.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_V018_item (expr->expr); - } - if (okay) - ffeste_V018_finish (); - malloc_pool_kill (stmt->u.V018.pool); - break; - - case FFESTD_stmtidV019_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V019_start (stmt->u.V019.params, stmt->u.V019.format); - for (expr = stmt->u.V019.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_V019_item (expr->expr); - } - if (okay) - ffeste_V019_finish (); - malloc_pool_kill (stmt->u.V019.pool); - break; -#endif - - case FFESTD_stmtidV020_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V020_start (stmt->u.V020.params, stmt->u.V020.format); - for (expr = stmt->u.V020.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_V020_item (expr->expr); - } - if (okay) - ffeste_V020_finish (); - malloc_pool_kill (stmt->u.V020.pool); - break; - -#if FFESTR_VXT - case FFESTD_stmtidV021_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V021 (stmt->u.V021.params); - malloc_pool_kill (stmt->u.V021.pool); - break; - - case FFESTD_stmtidV023_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V023_start (stmt->u.V023.params); - for (expr = stmt->u.V023.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_V023_item (expr->expr); - } - if (okay) - ffeste_V023_finish (); - malloc_pool_kill (stmt->u.V023.pool); - break; - - case FFESTD_stmtidV024_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V024_start (stmt->u.V024.params); - for (expr = stmt->u.V024.list; expr != NULL; expr = expr->next) - { - if (okay) - ffeste_V024_item (expr->expr); - } - if (okay) - ffeste_V024_finish (); - malloc_pool_kill (stmt->u.V024.pool); - break; - - case FFESTD_stmtidV025start_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V025_start (); - break; - - case FFESTD_stmtidV025item_: - if (okay) - ffeste_V025_item (stmt->u.V025item.u, stmt->u.V025item.m, - stmt->u.V025item.n, stmt->u.V025item.asv); - break; - - case FFESTD_stmtidV025finish_: - if (okay) - ffeste_V025_finish (); - malloc_pool_kill (stmt->u.V025finish.pool); - break; - - case FFESTD_stmtidV026_: - ffestd_subr_line_restore_ (stmt); - if (okay) - ffeste_V026 (stmt->u.V026.params); - malloc_pool_kill (stmt->u.V026.pool); - break; -#endif - - default: - assert ("bad stmt->id" == NULL); - break; - } - } -} - -#endif -/* ffestd_subr_copy_easy_ -- Copy I/O statement data structure - - ffestd_subr_copy_easy_(); - - Copies all data except tokens in the I/O data structure into a new - structure that lasts as long as the output pool for the current - statement. Assumes that they are - overlaid with each other (union) in stp.h and the typing - and structure references assume (though not necessarily dangerous if - FALSE) that INQUIRE has the most file elements. */ - -#if FFESTD_COPY_EASY_ && FFECOM_TWOPASS -static ffestpInquireStmt * -ffestd_subr_copy_easy_ (ffestpInquireIx max) -{ - ffestpInquireStmt *stmt; - ffestpInquireIx ix; - - stmt = (ffestpInquireStmt *) malloc_new_kp (ffesta_output_pool, - "FFESTD easy", sizeof (ffestpFile) * max); - - for (ix = 0; ix < max; ++ix) - { - if ((stmt->inquire_spec[ix].kw_or_val_present - = ffestp_file.inquire.inquire_spec[ix].kw_or_val_present) - && (stmt->inquire_spec[ix].value_present - = ffestp_file.inquire.inquire_spec[ix].value_present)) - { - if ((stmt->inquire_spec[ix].value_is_label - = ffestp_file.inquire.inquire_spec[ix].value_is_label)) - stmt->inquire_spec[ix].u.label - = ffestp_file.inquire.inquire_spec[ix].u.label; - else - stmt->inquire_spec[ix].u.expr - = ffestp_file.inquire.inquire_spec[ix].u.expr; - } - } - - return stmt; -} - -#endif -/* ffestd_subr_labels_ -- Handle any undefined labels - - ffestd_subr_labels_(FALSE); - - For every undefined label, generate an error message and either define - label as a FORMAT() statement (for FORMAT labels) or as a STOP statement - (for all other labels). */ - -static void -ffestd_subr_labels_ (bool unexpected) -{ - ffelab l; - ffelabHandle h; - ffelabNumber undef; - ffesttFormatList f; - - undef = ffelab_number () - ffestv_num_label_defines_; - - for (h = ffelab_handle_first (); h != NULL; h = ffelab_handle_next (h)) - { - l = ffelab_handle_target (h); - if (ffewhere_line_is_unknown (ffelab_definition_line (l))) - { /* Undefined label. */ - assert (!unexpected); - assert (undef > 0); - undef--; - ffebad_start (FFEBAD_UNDEF_LABEL); - if (ffelab_type (l) == FFELAB_typeLOOPEND) - ffebad_here (0, ffelab_doref_line (l), ffelab_doref_column (l)); - else if (ffelab_type (l) != FFELAB_typeANY) - ffebad_here (0, ffelab_firstref_line (l), ffelab_firstref_column (l)); - else if (!ffewhere_line_is_unknown (ffelab_firstref_line (l))) - ffebad_here (0, ffelab_firstref_line (l), ffelab_firstref_column (l)); - else if (!ffewhere_line_is_unknown (ffelab_doref_line (l))) - ffebad_here (0, ffelab_doref_line (l), ffelab_doref_column (l)); - else - ffebad_here (0, ffelab_definition_line (l), ffelab_definition_column (l)); - ffebad_finish (); - - switch (ffelab_type (l)) - { - case FFELAB_typeFORMAT: - ffelab_set_definition_line (l, - ffewhere_line_use (ffelab_firstref_line (l))); - ffelab_set_definition_column (l, - ffewhere_column_use (ffelab_firstref_column (l))); - ffestv_num_label_defines_++; - f = ffestt_formatlist_create (NULL, NULL); - ffestd_labeldef_format (l); - ffestd_R1001 (f); - ffestt_formatlist_kill (f); - break; - - case FFELAB_typeASSIGNABLE: - ffelab_set_definition_line (l, - ffewhere_line_use (ffelab_firstref_line (l))); - ffelab_set_definition_column (l, - ffewhere_column_use (ffelab_firstref_column (l))); - ffestv_num_label_defines_++; - ffelab_set_type (l, FFELAB_typeNOTLOOP); - ffelab_set_blocknum (l, ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (l); - ffestd_R842 (NULL); - break; - - case FFELAB_typeNOTLOOP: - ffelab_set_definition_line (l, - ffewhere_line_use (ffelab_firstref_line (l))); - ffelab_set_definition_column (l, - ffewhere_column_use (ffelab_firstref_column (l))); - ffestv_num_label_defines_++; - ffelab_set_blocknum (l, ffestw_blocknum (ffestw_stack_top ())); - ffestd_labeldef_notloop (l); - ffestd_R842 (NULL); - break; - - default: - assert ("bad label type" == NULL); - /* Fall through. */ - case FFELAB_typeUNKNOWN: - case FFELAB_typeANY: - break; - } - } - } - ffelab_handle_done (h); - assert (undef == 0); -} - -/* ffestd_subr_f90_ -- Report error about lack of full F90 support - - ffestd_subr_f90_(); */ - -#if FFESTR_F90 -static void -ffestd_subr_f90_ () -{ - ffebad_start (FFEBAD_F90); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); -} - -#endif -/* ffestd_subr_vxt_ -- Report error about lack of full VXT support - - ffestd_subr_vxt_(); */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffestd_subr_vxt_ () -{ - ffebad_start (FFEBAD_VXT_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); -} - -#endif -/* ffestd_begin_uses -- Start a bunch of USE statements - - ffestd_begin_uses(); - - Invoked before handling the first USE statement in a block of one or - more USE statements. _end_uses_(bool ok) is invoked before handling - the first statement after the block (there are no BEGIN USE and END USE - statements, but the semantics of USE statements effectively requires - handling them as a single block rather than one statement at a time). */ - -void -ffestd_begin_uses () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("; begin_uses\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_do -- End of statement following DO-term-stmt etc - - ffestd_do(TRUE); - - Also invoked by _labeldef_branch_finish_ (or, in cases - of errors, other _labeldef_ functions) when the label definition is - for a DO-target (LOOPEND) label, once per matching/outstanding DO - block on the stack. These cases invoke this function with ok==TRUE, so - only forced stack popping (via ffestd_eof_()) invokes it with ok==FALSE. */ - -void -ffestd_do (bool ok UNUSED) -{ -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_do (ffestw_stack_top ()); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidENDDOLOOP_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.enddoloop.block = ffestw_stack_top (); - } -#endif - - --ffestd_block_level_; - assert (ffestd_block_level_ >= 0); -} - -/* ffestd_end_uses -- End a bunch of USE statements - - ffestd_end_uses(TRUE); - - ok==TRUE means simply not popping due to ffestd_eof_() - being called, because there is no formal END USES statement in Fortran. */ - -#if FFESTR_F90 -void -ffestd_end_uses (bool ok) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("; end_uses\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_end_R740 -- End a WHERE(-THEN) - - ffestd_end_R740(TRUE); */ - -void -ffestd_end_R740 (bool ok) -{ - return; /* F90. */ -} - -#endif -/* ffestd_end_R807 -- End of statement following logical IF - - ffestd_end_R807(TRUE); - - Applies ONLY to logical IF, not to IF-THEN. For example, does not - ffelex_token_kill the construct name for an IF-THEN block (the name - field is invalid for logical IF). ok==TRUE iff statement following - logical IF (substatement) is valid; else, statement is invalid or - stack forcibly popped due to ffestd_eof_(). */ - -void -ffestd_end_R807 (bool ok UNUSED) -{ -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_end_R807 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidENDLOGIF_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif - - --ffestd_block_level_; - assert (ffestd_block_level_ >= 0); -} - -/* ffestd_exec_begin -- Executable statements can start coming in now - - ffestd_exec_begin(); */ - -void -ffestd_exec_begin () -{ - ffecom_exec_transition (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("{ begin_exec\n", dmpout); -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - if (ffestd_2pass_entrypoints_ != 0) - { /* Process pending ENTRY statements now that - info filled in. */ - ffestdStmt_ stmt; - int ents = ffestd_2pass_entrypoints_; - - stmt = ffestd_stmt_list_.first; - do - { - while (stmt->id != FFESTD_stmtidR1226_) - stmt = stmt->next; - - if (!ffecom_2pass_advise_entrypoint (stmt->u.R1226.entry)) - { - stmt->u.R1226.entry = NULL; - --ffestd_2pass_entrypoints_; - } - stmt = stmt->next; - } - while (--ents != 0); - } -#endif -} - -/* ffestd_exec_end -- Executable statements can no longer come in now - - ffestd_exec_end(); */ - -void -ffestd_exec_end () -{ -#if FFECOM_targetCURRENT == FFECOM_targetGCC - int old_lineno = lineno; - char *old_input_filename = input_filename; -#endif - - ffecom_end_transition (); - -#if FFECOM_TWOPASS - ffestd_stmt_pass_ (); -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("} end_exec\n", dmpout); - fputs ("> end_unit\n", dmpout); -#endif - -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffecom_finish_progunit (); - - if (ffestd_2pass_entrypoints_ != 0) - { - int ents = ffestd_2pass_entrypoints_; - ffestdStmt_ stmt = ffestd_stmt_list_.first; - - do - { - while (stmt->id != FFESTD_stmtidR1226_) - stmt = stmt->next; - - if (stmt->u.R1226.entry != NULL) - { - ffestd_subr_line_restore_ (stmt); - ffecom_2pass_do_entrypoint (stmt->u.R1226.entry); - } - stmt = stmt->next; - } - while (--ents != 0); - } - - ffestd_stmt_list_.first = NULL; - ffestd_stmt_list_.last = NULL; - ffestd_2pass_entrypoints_ = 0; - - lineno = old_lineno; - input_filename = old_input_filename; -#endif -} - -/* ffestd_init_3 -- Initialize for any program unit - - ffestd_init_3(); */ - -void -ffestd_init_3 () -{ -#if FFECOM_TWOPASS - ffestd_stmt_list_.first = (ffestdStmt_) &ffestd_stmt_list_.first; - ffestd_stmt_list_.last = (ffestdStmt_) &ffestd_stmt_list_.first; -#endif -} - -/* Generate "code" for "any" label def. */ - -void -ffestd_labeldef_any (ffelab label UNUSED) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "; any_label_def %lu\n", ffelab_value (label)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_labeldef_branch -- Generate "code" for branch label def - - ffestd_labeldef_branch(label); */ - -void -ffestd_labeldef_branch (ffelab label) -{ -#if FFECOM_ONEPASS - ffeste_labeldef_branch (label); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidEXECLABEL_); - ffestd_stmt_append_ (stmt); - stmt->u.execlabel.label = label; - } -#endif - - ffestd_is_reachable_ = TRUE; -} - -/* ffestd_labeldef_format -- Generate "code" for FORMAT label def - - ffestd_labeldef_format(label); */ - -void -ffestd_labeldef_format (ffelab label) -{ - ffestd_label_formatdef_ = label; - -#if FFECOM_ONEPASS - ffeste_labeldef_format (label); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidFORMATLABEL_); - ffestd_stmt_append_ (stmt); - stmt->u.formatlabel.label = label; - } -#endif -} - -/* ffestd_labeldef_useless -- Generate "code" for useless label def - - ffestd_labeldef_useless(label); */ - -void -ffestd_labeldef_useless (ffelab label UNUSED) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "; useless_label_def %lu\n", ffelab_value (label)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R423A -- PRIVATE statement (in R422 derived-type statement) - - ffestd_R423A(); */ - -#if FFESTR_F90 -void -ffestd_R423A () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* PRIVATE_derived_type\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R423B -- SEQUENCE statement (in R422 derived-type-stmt) - - ffestd_R423B(); */ - -void -ffestd_R423B () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* SEQUENCE_derived_type\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R424 -- derived-TYPE-def statement - - ffestd_R424(access_token,access_kw,name_token); - - Handle a derived-type definition. */ - -void -ffestd_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - char *a; - - if (access == NULL) - fprintf (dmpout, "* TYPE %s\n", ffelex_token_text (name)); - else - { - switch (access_kw) - { - case FFESTR_otherPUBLIC: - a = "PUBLIC"; - break; - - case FFESTR_otherPRIVATE: - a = "PRIVATE"; - break; - - default: - assert (FALSE); - } - fprintf (dmpout, "* TYPE,%s: %s\n", a, ffelex_token_text (name)); - } -#endif -} - -/* ffestd_R425 -- End a TYPE - - ffestd_R425(TRUE); */ - -void -ffestd_R425 (bool ok) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "* END_TYPE %s\n", ffelex_token_text (ffestw_name (ffestw_stack_top ()))); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R519_start -- INTENT statement list begin - - ffestd_R519_start(); - - Verify that INTENT is valid here, and begin accepting items in the list. */ - -void -ffestd_R519_start (ffestrOther intent_kw) -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - char *a; - - switch (intent_kw) - { - case FFESTR_otherIN: - a = "IN"; - break; - - case FFESTR_otherOUT: - a = "OUT"; - break; - - case FFESTR_otherINOUT: - a = "INOUT"; - break; - - default: - assert (FALSE); - } - fprintf (dmpout, "* INTENT (%s) ", a); -#endif -} - -/* ffestd_R519_item -- INTENT statement for name - - ffestd_R519_item(name_token); - - Make sure name_token identifies a valid object to be INTENTed. */ - -void -ffestd_R519_item (ffelexToken name) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#endif -} - -/* ffestd_R519_finish -- INTENT statement list complete - - ffestd_R519_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R519_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R520_start -- OPTIONAL statement list begin - - ffestd_R520_start(); - - Verify that OPTIONAL is valid here, and begin accepting items in the list. */ - -void -ffestd_R520_start () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* OPTIONAL ", dmpout); -#endif -} - -/* ffestd_R520_item -- OPTIONAL statement for name - - ffestd_R520_item(name_token); - - Make sure name_token identifies a valid object to be OPTIONALed. */ - -void -ffestd_R520_item (ffelexToken name) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#endif -} - -/* ffestd_R520_finish -- OPTIONAL statement list complete - - ffestd_R520_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R520_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R521A -- PUBLIC statement - - ffestd_R521A(); - - Verify that PUBLIC is valid here. */ - -void -ffestd_R521A () -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* PUBLIC\n", dmpout); -#endif -} - -/* ffestd_R521Astart -- PUBLIC statement list begin - - ffestd_R521Astart(); - - Verify that PUBLIC is valid here, and begin accepting items in the list. */ - -void -ffestd_R521Astart () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* PUBLIC ", dmpout); -#endif -} - -/* ffestd_R521Aitem -- PUBLIC statement for name - - ffestd_R521Aitem(name_token); - - Make sure name_token identifies a valid object to be PUBLICed. */ - -void -ffestd_R521Aitem (ffelexToken name) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#endif -} - -/* ffestd_R521Afinish -- PUBLIC statement list complete - - ffestd_R521Afinish(); - - Just wrap up any local activities. */ - -void -ffestd_R521Afinish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R521B -- PRIVATE statement - - ffestd_R521B(); - - Verify that PRIVATE is valid here (outside a derived-type statement). */ - -void -ffestd_R521B () -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* PRIVATE_outside_of_R422_derived_type_def\n", dmpout); -#endif -} - -/* ffestd_R521Bstart -- PRIVATE statement list begin - - ffestd_R521Bstart(); - - Verify that PRIVATE is valid here, and begin accepting items in the list. */ - -void -ffestd_R521Bstart () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* PRIVATE ", dmpout); -#endif -} - -/* ffestd_R521Bitem -- PRIVATE statement for name - - ffestd_R521Bitem(name_token); - - Make sure name_token identifies a valid object to be PRIVATEed. */ - -void -ffestd_R521Bitem (ffelexToken name) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#endif -} - -/* ffestd_R521Bfinish -- PRIVATE statement list complete - - ffestd_R521Bfinish(); - - Just wrap up any local activities. */ - -void -ffestd_R521Bfinish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -#endif -/* ffestd_R522 -- SAVE statement with no list - - ffestd_R522(); - - Verify that SAVE is valid here, and flag everything as SAVEd. */ - -void -ffestd_R522 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* SAVE_all\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R522start -- SAVE statement list begin - - ffestd_R522start(); - - Verify that SAVE is valid here, and begin accepting items in the list. */ - -void -ffestd_R522start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* SAVE ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R522item_object -- SAVE statement for object-name - - ffestd_R522item_object(name_token); - - Make sure name_token identifies a valid object to be SAVEd. */ - -void -ffestd_R522item_object (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R522item_cblock -- SAVE statement for common-block-name - - ffestd_R522item_cblock(name_token); - - Make sure name_token identifies a valid common block to be SAVEd. */ - -void -ffestd_R522item_cblock (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "/%s/,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R522finish -- SAVE statement list complete - - ffestd_R522finish(); - - Just wrap up any local activities. */ - -void -ffestd_R522finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R524_start -- DIMENSION statement list begin - - ffestd_R524_start(bool virtual); - - Verify that DIMENSION is valid here, and begin accepting items in the list. */ - -void -ffestd_R524_start (bool virtual UNUSED) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (virtual) - fputs ("* VIRTUAL ", dmpout); /* V028. */ - else - fputs ("* DIMENSION ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R524_item -- DIMENSION statement for object-name - - ffestd_R524_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be DIMENSIONd. */ - -void -ffestd_R524_item (ffelexToken name UNUSED, ffesttDimList dims UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (ffelex_token_text (name), dmpout); - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputs ("),", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R524_finish -- DIMENSION statement list complete - - ffestd_R524_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R524_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R525_start -- ALLOCATABLE statement list begin - - ffestd_R525_start(); - - Verify that ALLOCATABLE is valid here, and begin accepting items in the - list. */ - -#if FFESTR_F90 -void -ffestd_R525_start () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* ALLOCATABLE ", dmpout); -#endif -} - -/* ffestd_R525_item -- ALLOCATABLE statement for object-name - - ffestd_R525_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be ALLOCATABLEd. */ - -void -ffestd_R525_item (ffelexToken name, ffesttDimList dims) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#endif -} - -/* ffestd_R525_finish -- ALLOCATABLE statement list complete - - ffestd_R525_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R525_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R526_start -- POINTER statement list begin - - ffestd_R526_start(); - - Verify that POINTER is valid here, and begin accepting items in the - list. */ - -void -ffestd_R526_start () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* POINTER ", dmpout); -#endif -} - -/* ffestd_R526_item -- POINTER statement for object-name - - ffestd_R526_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be POINTERd. */ - -void -ffestd_R526_item (ffelexToken name, ffesttDimList dims) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#endif -} - -/* ffestd_R526_finish -- POINTER statement list complete - - ffestd_R526_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R526_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R527_start -- TARGET statement list begin - - ffestd_R527_start(); - - Verify that TARGET is valid here, and begin accepting items in the - list. */ - -void -ffestd_R527_start () -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("* TARGET ", dmpout); -#endif -} - -/* ffestd_R527_item -- TARGET statement for object-name - - ffestd_R527_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be TARGETd. */ - -void -ffestd_R527_item (ffelexToken name, ffesttDimList dims) -{ - ffestd_check_item_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#endif -} - -/* ffestd_R527_finish -- TARGET statement list complete - - ffestd_R527_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R527_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -#endif -/* ffestd_R537_start -- PARAMETER statement list begin - - ffestd_R537_start(); - - Verify that PARAMETER is valid here, and begin accepting items in the list. */ - -void -ffestd_R537_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* PARAMETER (", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R537_item -- PARAMETER statement assignment - - ffestd_R537_item(dest,dest_token,source,source_token); - - Make sure the source is a valid source for the destination; make the - assignment. */ - -void -ffestd_R537_item (ffebld dest UNUSED, ffebld source UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (dest); - fputc ('=', dmpout); - ffebld_dump (source); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R537_finish -- PARAMETER statement list complete - - ffestd_R537_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R537_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R539 -- IMPLICIT NONE statement - - ffestd_R539(); - - Verify that the IMPLICIT NONE statement is ok here and implement. */ - -void -ffestd_R539 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* IMPLICIT_NONE\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R539start -- IMPLICIT statement - - ffestd_R539start(); - - Verify that the IMPLICIT statement is ok here and implement. */ - -void -ffestd_R539start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* IMPLICIT ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R539item -- IMPLICIT statement specification (R540) - - ffestd_R539item(...); - - Verify that the type and letter list are all ok and implement. */ - -void -ffestd_R539item (ffestpType type UNUSED, ffebld kind UNUSED, - ffelexToken kindt UNUSED, ffebld len UNUSED, - ffelexToken lent UNUSED, ffesttImpList letters UNUSED) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - char *a; -#endif - - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (type) - { - case FFESTP_typeINTEGER: - a = "INTEGER"; - break; - - case FFESTP_typeBYTE: - a = "BYTE"; - break; - - case FFESTP_typeWORD: - a = "WORD"; - break; - - case FFESTP_typeREAL: - a = "REAL"; - break; - - case FFESTP_typeCOMPLEX: - a = "COMPLEX"; - break; - - case FFESTP_typeLOGICAL: - a = "LOGICAL"; - break; - - case FFESTP_typeCHARACTER: - a = "CHARACTER"; - break; - - case FFESTP_typeDBLPRCSN: - a = "DOUBLE PRECISION"; - break; - - case FFESTP_typeDBLCMPLX: - a = "DOUBLE COMPLEX"; - break; - -#if FFESTR_F90 - case FFESTP_typeTYPE: - a = "TYPE"; - break; -#endif - - default: - assert (FALSE); - a = "?"; - break; - } - fprintf (dmpout, "%s(", a); - if (kindt != NULL) - { - fputs ("kind=", dmpout); - if (kind == NULL) - fputs (ffelex_token_text (kindt), dmpout); - else - ffebld_dump (kind); - if (lent != NULL) - fputc (',', dmpout); - } - if (lent != NULL) - { - fputs ("len=", dmpout); - if (len == NULL) - fputs (ffelex_token_text (lent), dmpout); - else - ffebld_dump (len); - } - fputs (")(", dmpout); - ffestt_implist_dump (letters); - fputs ("),", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R539finish -- IMPLICIT statement - - ffestd_R539finish(); - - Finish up any local activities. */ - -void -ffestd_R539finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R542_start -- NAMELIST statement list begin - - ffestd_R542_start(); - - Verify that NAMELIST is valid here, and begin accepting items in the list. */ - -void -ffestd_R542_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* NAMELIST ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R542_item_nlist -- NAMELIST statement for group-name - - ffestd_R542_item_nlist(groupname_token); - - Make sure name_token identifies a valid object to be NAMELISTd. */ - -void -ffestd_R542_item_nlist (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "/%s/", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R542_item_nitem -- NAMELIST statement for variable-name - - ffestd_R542_item_nitem(name_token); - - Make sure name_token identifies a valid object to be NAMELISTd. */ - -void -ffestd_R542_item_nitem (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R542_finish -- NAMELIST statement list complete - - ffestd_R542_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R542_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R544_start -- EQUIVALENCE statement list begin - - ffestd_R544_start(); - - Verify that EQUIVALENCE is valid here, and begin accepting items in the - list. */ - -#if 0 -void -ffestd_R544_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* EQUIVALENCE (", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif -/* ffestd_R544_item -- EQUIVALENCE statement assignment - - ffestd_R544_item(exprlist); - - Make sure the equivalence is valid, then implement it. */ - -#if 0 -void -ffestd_R544_item (ffesttExprList exprlist) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffestt_exprlist_dump (exprlist); - fputs ("),", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif -/* ffestd_R544_finish -- EQUIVALENCE statement list complete - - ffestd_R544_finish(); - - Just wrap up any local activities. */ - -#if 0 -void -ffestd_R544_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif -/* ffestd_R547_start -- COMMON statement list begin - - ffestd_R547_start(); - - Verify that COMMON is valid here, and begin accepting items in the list. */ - -void -ffestd_R547_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* COMMON ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R547_item_object -- COMMON statement for object-name - - ffestd_R547_item_object(name_token,dim_list); - - Make sure name_token identifies a valid object to be COMMONd. */ - -void -ffestd_R547_item_object (ffelexToken name UNUSED, - ffesttDimList dims UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R547_item_cblock -- COMMON statement for common-block-name - - ffestd_R547_item_cblock(name_token); - - Make sure name_token identifies a valid common block to be COMMONd. */ - -void -ffestd_R547_item_cblock (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (name == NULL) - fputs ("//,", dmpout); - else - fprintf (dmpout, "/%s/,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R547_finish -- COMMON statement list complete - - ffestd_R547_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R547_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R620 -- ALLOCATE statement - - ffestd_R620(exprlist,stat,stat_token); - - Make sure the expression list is valid, then implement it. */ - -#if FFESTR_F90 -void -ffestd_R620 (ffesttExprList exprlist, ffebld stat) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ ALLOCATE (", dmpout); - ffestt_exprlist_dump (exprlist); - if (stat != NULL) - { - fputs (",stat=", dmpout); - ffebld_dump (stat); - } - fputs (")\n", dmpout); -#endif -} - -/* ffestd_R624 -- NULLIFY statement - - ffestd_R624(pointer_name_list); - - Make sure pointer_name_list identifies valid pointers for a NULLIFY. */ - -void -ffestd_R624 (ffesttExprList pointers) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ NULLIFY (", dmpout); - assert (pointers != NULL); - ffestt_exprlist_dump (pointers); - fputs (")\n", dmpout); -#endif -} - -/* ffestd_R625 -- DEALLOCATE statement - - ffestd_R625(exprlist,stat,stat_token); - - Make sure the equivalence is valid, then implement it. */ - -void -ffestd_R625 (ffesttExprList exprlist, ffebld stat) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ DEALLOCATE (", dmpout); - ffestt_exprlist_dump (exprlist); - if (stat != NULL) - { - fputs (",stat=", dmpout); - ffebld_dump (stat); - } - fputs (")\n", dmpout); -#endif -} - -#endif -/* ffestd_R737A -- Assignment statement outside of WHERE - - ffestd_R737A(dest_expr,source_expr); */ - -void -ffestd_R737A (ffebld dest, ffebld source) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R737A (dest, source); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR737A_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R737A.pool = ffesta_output_pool; - stmt->u.R737A.dest = dest; - stmt->u.R737A.source = source; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R737B -- Assignment statement inside of WHERE - - ffestd_R737B(dest_expr,source_expr); */ - -#if FFESTR_F90 -void -ffestd_R737B (ffebld dest, ffebld source) -{ - ffestd_check_simple_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs ("+ let_inside_where ", dmpout); - ffebld_dump (dest); - fputs ("=", dmpout); - ffebld_dump (source); - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R738 -- Pointer assignment statement - - ffestd_R738(dest_expr,source_expr,source_token); - - Make sure the assignment is valid. */ - -void -ffestd_R738 (ffebld dest, ffebld source) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ let_pointer ", dmpout); - ffebld_dump (dest); - fputs ("=>", dmpout); - ffebld_dump (source); - fputc ('\n', dmpout); -#endif -} - -/* ffestd_R740 -- WHERE statement - - ffestd_R740(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R740 (ffebld expr) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ WHERE (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -#endif -} - -/* ffestd_R742 -- WHERE-construct statement - - ffestd_R742(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R742 (ffebld expr) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ WHERE_construct (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -#endif -} - -/* ffestd_R744 -- ELSE WHERE statement - - ffestd_R744(); - - Make sure ffestd_kind_ identifies a WHERE block. - Implement the ELSE of the current WHERE block. */ - -void -ffestd_R744 () -{ - ffestd_check_simple_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs ("+ ELSE_WHERE\n", dmpout); -#endif -} - -/* ffestd_R745 -- Implicit END WHERE statement - - ffestd_R745(TRUE); - - Implement the end of the current WHERE "block". ok==TRUE iff statement - following WHERE (substatement) is valid; else, statement is invalid - or stack forcibly popped due to ffestd_eof_(). */ - -void -ffestd_R745 (bool ok) -{ - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs ("+ END_WHERE\n", dmpout); /* Also see ffestd_R745. */ - - --ffestd_block_level_; - assert (ffestd_block_level_ >= 0); -#endif -} - -#endif -/* ffestd_R803 -- Block IF (IF-THEN) statement - - ffestd_R803(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R803 (ffelexToken construct_name UNUSED, ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R803 (expr); /* Don't bother with name. */ -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR803_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R803.pool = ffesta_output_pool; - stmt->u.R803.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -} - -/* ffestd_R804 -- ELSE IF statement - - ffestd_R804(expr,expr_token,name_token); - - Make sure ffestd_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the else - of the IF block. */ - -void -ffestd_R804 (ffebld expr, ffelexToken name UNUSED) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R804 (expr); /* Don't bother with name. */ -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR804_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R804.pool = ffesta_output_pool; - stmt->u.R804.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R805 -- ELSE statement - - ffestd_R805(name_token); - - Make sure ffestd_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the ELSE - of the IF block. */ - -void -ffestd_R805 (ffelexToken name UNUSED) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R805 (); /* Don't bother with name. */ -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR805_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif -} - -/* ffestd_R806 -- End an IF-THEN - - ffestd_R806(TRUE); */ - -void -ffestd_R806 (bool ok UNUSED) -{ -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R806 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR806_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif - - --ffestd_block_level_; - assert (ffestd_block_level_ >= 0); -} - -/* ffestd_R807 -- Logical IF statement - - ffestd_R807(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R807 (ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R807 (expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR807_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R807.pool = ffesta_output_pool; - stmt->u.R807.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -} - -/* ffestd_R809 -- SELECT CASE statement - - ffestd_R809(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R809 (ffelexToken construct_name UNUSED, ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R809 (ffestw_stack_top (), expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR809_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R809.pool = ffesta_output_pool; - stmt->u.R809.block = ffestw_use (ffestw_stack_top ()); - stmt->u.R809.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - malloc_pool_use (ffestw_select (ffestw_stack_top ())->pool); - } -#endif - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -} - -/* ffestd_R810 -- CASE statement - - ffestd_R810(case_value_range_list,name); - - If casenum is 0, it's CASE DEFAULT. Else it's the case ranges at - the start of the first_stmt list in the select object at the top of - the stack that match casenum. */ - -void -ffestd_R810 (unsigned long casenum) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R810 (ffestw_stack_top (), casenum); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR810_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R810.pool = ffesta_output_pool; - stmt->u.R810.block = ffestw_stack_top (); - stmt->u.R810.casenum = casenum; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R811 -- End a SELECT - - ffestd_R811(TRUE); */ - -void -ffestd_R811 (bool ok UNUSED) -{ -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R811 (ffestw_stack_top ()); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR811_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R811.block = ffestw_stack_top (); - } -#endif - - --ffestd_block_level_; - assert (ffestd_block_level_ >= 0); -} - -/* ffestd_R819A -- Iterative DO statement - - ffestd_R819A(construct_name,label_token,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R819A (ffelexToken construct_name UNUSED, ffelab label, - ffebld var, ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R819A (ffestw_stack_top (), label, var, start, end, incr, - incr_token); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR819A_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R819A.pool = ffesta_output_pool; - stmt->u.R819A.block = ffestw_use (ffestw_stack_top ()); - stmt->u.R819A.label = label; - stmt->u.R819A.var = var; - stmt->u.R819A.start = start; - stmt->u.R819A.start_token = ffelex_token_use (start_token); - stmt->u.R819A.end = end; - stmt->u.R819A.end_token = ffelex_token_use (end_token); - stmt->u.R819A.incr = incr; - stmt->u.R819A.incr_token = (incr_token == NULL) ? NULL - : ffelex_token_use (incr_token); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -} - -/* ffestd_R819B -- DO WHILE statement - - ffestd_R819B(construct_name,label_token,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R819B (ffelexToken construct_name UNUSED, ffelab label, - ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R819B (ffestw_stack_top (), label, expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR819B_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R819B.pool = ffesta_output_pool; - stmt->u.R819B.block = ffestw_use (ffestw_stack_top ()); - stmt->u.R819B.label = label; - stmt->u.R819B.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - ++ffestd_block_level_; - assert (ffestd_block_level_ > 0); -} - -/* ffestd_R825 -- END DO statement - - ffestd_R825(name_token); - - Make sure ffestd_kind_ identifies a DO block. If not - NULL, make sure name_token gives the correct name. Do whatever - is specific to seeing END DO with a DO-target label definition on it, - where the END DO is really treated as a CONTINUE (i.e. generate th - same code you would for CONTINUE). ffestd_do handles the actual - generation of end-loop code. */ - -void -ffestd_R825 (ffelexToken name UNUSED) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R825 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR825_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif -} - -/* ffestd_R834 -- CYCLE statement - - ffestd_R834(name_token); - - Handle a CYCLE within a loop. */ - -void -ffestd_R834 (ffestw block) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R834 (block); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR834_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R834.block = block; - } -#endif -} - -/* ffestd_R835 -- EXIT statement - - ffestd_R835(name_token); - - Handle a EXIT within a loop. */ - -void -ffestd_R835 (ffestw block) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R835 (block); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR835_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R835.block = block; - } -#endif -} - -/* ffestd_R836 -- GOTO statement - - ffestd_R836(label); - - Make sure label_token identifies a valid label for a GOTO. Update - that label's info to indicate it is the target of a GOTO. */ - -void -ffestd_R836 (ffelab label) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R836 (label); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR836_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R836.label = label; - } -#endif - - if (ffestd_block_level_ == 0) - ffestd_is_reachable_ = FALSE; -} - -/* ffestd_R837 -- Computed GOTO statement - - ffestd_R837(labels,expr); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffestd_R837 (ffelab *labels, int count, ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R837 (labels, count, expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR837_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R837.pool = ffesta_output_pool; - stmt->u.R837.labels = labels; - stmt->u.R837.count = count; - stmt->u.R837.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R838 -- ASSIGN statement - - ffestd_R838(label_token,target_variable,target_token); - - Make sure label_token identifies a valid label for an assignment. Update - that label's info to indicate it is the source of an assignment. Update - target_variable's info to indicate it is the target the assignment of that - label. */ - -void -ffestd_R838 (ffelab label, ffebld target) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R838 (label, target); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR838_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R838.pool = ffesta_output_pool; - stmt->u.R838.label = label; - stmt->u.R838.target = target; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R839 -- Assigned GOTO statement - - ffestd_R839(target,labels); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffestd_R839 (ffebld target, ffelab *labels UNUSED, int count UNUSED) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R839 (target); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR839_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R839.pool = ffesta_output_pool; - stmt->u.R839.target = target; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - if (ffestd_block_level_ == 0) - ffestd_is_reachable_ = FALSE; -} - -/* ffestd_R840 -- Arithmetic IF statement - - ffestd_R840(expr,expr_token,neg,zero,pos); - - Make sure the labels are valid; implement. */ - -void -ffestd_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R840 (expr, neg, zero, pos); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR840_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R840.pool = ffesta_output_pool; - stmt->u.R840.expr = expr; - stmt->u.R840.neg = neg; - stmt->u.R840.zero = zero; - stmt->u.R840.pos = pos; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - if (ffestd_block_level_ == 0) - ffestd_is_reachable_ = FALSE; -} - -/* ffestd_R841 -- CONTINUE statement - - ffestd_R841(); */ - -void -ffestd_R841 (bool in_where UNUSED) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R841 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR841_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif -} - -/* ffestd_R842 -- STOP statement - - ffestd_R842(expr); */ - -void -ffestd_R842 (ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R842 (expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR842_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - if (ffesta_outpooldisp () == FFESTA_pooldispPRESERVE) - { - /* This is a "spurious" (automatically-generated) STOP - that follows a previous STOP or other statement. - Make sure we don't have an expression in the pool, - and then mark that the pool has already been killed. */ - assert (expr == NULL); - stmt->u.R842.pool = NULL; - stmt->u.R842.expr = NULL; - } - else - { - stmt->u.R842.pool = ffesta_output_pool; - stmt->u.R842.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } - } -#endif - - if (ffestd_block_level_ == 0) - ffestd_is_reachable_ = FALSE; -} - -/* ffestd_R843 -- PAUSE statement - - ffestd_R843(expr,expr_token); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffestd_R843 (ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R843 (expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR843_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R843.pool = ffesta_output_pool; - stmt->u.R843.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R904 -- OPEN statement - - ffestd_R904(); - - Make sure an OPEN is valid in the current context, and implement it. */ - -void -ffestd_R904 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define specified(something) \ - (ffestp_file.open.open_spec[something].kw_or_val_present) - - /* Warn if there are any thing we don't handle via f2c libraries. */ - - if (specified (FFESTP_openixACTION) - || specified (FFESTP_openixASSOCIATEVARIABLE) - || specified (FFESTP_openixBLOCKSIZE) - || specified (FFESTP_openixBUFFERCOUNT) - || specified (FFESTP_openixCARRIAGECONTROL) - || specified (FFESTP_openixDEFAULTFILE) - || specified (FFESTP_openixDELIM) - || specified (FFESTP_openixDISPOSE) - || specified (FFESTP_openixEXTENDSIZE) - || specified (FFESTP_openixINITIALSIZE) - || specified (FFESTP_openixKEY) - || specified (FFESTP_openixMAXREC) - || specified (FFESTP_openixNOSPANBLOCKS) - || specified (FFESTP_openixORGANIZATION) - || specified (FFESTP_openixPAD) - || specified (FFESTP_openixPOSITION) - || specified (FFESTP_openixREADONLY) - || specified (FFESTP_openixRECORDTYPE) - || specified (FFESTP_openixSHARED) - || specified (FFESTP_openixUSEROPEN)) - { - ffebad_start (FFEBAD_OPEN_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - -#undef specified -#endif - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R904 (&ffestp_file.open); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR904_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R904.pool = ffesta_output_pool; - stmt->u.R904.params = ffestd_subr_copy_open_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R907 -- CLOSE statement - - ffestd_R907(); - - Make sure a CLOSE is valid in the current context, and implement it. */ - -void -ffestd_R907 () -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R907 (&ffestp_file.close); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR907_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R907.pool = ffesta_output_pool; - stmt->u.R907.params = ffestd_subr_copy_close_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R909_start -- READ(...) statement list begin - - ffestd_R909_start(FALSE); - - Verify that READ is valid here, and begin accepting items in the - list. */ - -void -ffestd_R909_start (bool only_format, ffestvUnit unit, - ffestvFormat format, bool rec, bool key) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define specified(something) \ - (ffestp_file.read.read_spec[something].kw_or_val_present) - - /* Warn if there are any thing we don't handle via f2c libraries. */ - if (specified (FFESTP_readixADVANCE) - || specified (FFESTP_readixEOR) - || specified (FFESTP_readixKEYEQ) - || specified (FFESTP_readixKEYGE) - || specified (FFESTP_readixKEYGT) - || specified (FFESTP_readixKEYID) - || specified (FFESTP_readixNULLS) - || specified (FFESTP_readixSIZE)) - { - ffebad_start (FFEBAD_READ_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - -#undef specified -#endif - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R909_start (&ffestp_file.read, only_format, unit, format, rec, key); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR909_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R909.pool = ffesta_output_pool; - stmt->u.R909.params = ffestd_subr_copy_read_ (); - stmt->u.R909.only_format = only_format; - stmt->u.R909.unit = unit; - stmt->u.R909.format = format; - stmt->u.R909.rec = rec; - stmt->u.R909.key = key; - stmt->u.R909.list = NULL; - ffestd_expr_list_ = &stmt->u.R909.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R909_item -- READ statement i/o item - - ffestd_R909_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_R909_item (ffebld expr, ffelexToken expr_token) -{ - ffestd_check_item_ (); - -#if FFECOM_ONEPASS - ffeste_R909_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - item->token = ffelex_token_use (expr_token); - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif -} - -/* ffestd_R909_finish -- READ statement list complete - - ffestd_R909_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R909_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_ONEPASS - ffeste_R909_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif -} - -/* ffestd_R910_start -- WRITE(...) statement list begin - - ffestd_R910_start(); - - Verify that WRITE is valid here, and begin accepting items in the - list. */ - -void -ffestd_R910_start (ffestvUnit unit, ffestvFormat format, bool rec) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define specified(something) \ - (ffestp_file.write.write_spec[something].kw_or_val_present) - - /* Warn if there are any thing we don't handle via f2c libraries. */ - if (specified (FFESTP_writeixADVANCE) - || specified (FFESTP_writeixEOR)) - { - ffebad_start (FFEBAD_WRITE_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - -#undef specified -#endif - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R910_start (&ffestp_file.write, unit, format, rec); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR910_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R910.pool = ffesta_output_pool; - stmt->u.R910.params = ffestd_subr_copy_write_ (); - stmt->u.R910.unit = unit; - stmt->u.R910.format = format; - stmt->u.R910.rec = rec; - stmt->u.R910.list = NULL; - ffestd_expr_list_ = &stmt->u.R910.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R910_item -- WRITE statement i/o item - - ffestd_R910_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_R910_item (ffebld expr, ffelexToken expr_token) -{ - ffestd_check_item_ (); - -#if FFECOM_ONEPASS - ffeste_R910_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - item->token = ffelex_token_use (expr_token); - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif -} - -/* ffestd_R910_finish -- WRITE statement list complete - - ffestd_R910_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R910_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_ONEPASS - ffeste_R910_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif -} - -/* ffestd_R911_start -- PRINT statement list begin - - ffestd_R911_start(); - - Verify that PRINT is valid here, and begin accepting items in the - list. */ - -void -ffestd_R911_start (ffestvFormat format) -{ - ffestd_check_start_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R911_start (&ffestp_file.print, format); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR911_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R911.pool = ffesta_output_pool; - stmt->u.R911.params = ffestd_subr_copy_print_ (); - stmt->u.R911.format = format; - stmt->u.R911.list = NULL; - ffestd_expr_list_ = &stmt->u.R911.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R911_item -- PRINT statement i/o item - - ffestd_R911_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_R911_item (ffebld expr, ffelexToken expr_token) -{ - ffestd_check_item_ (); - -#if FFECOM_ONEPASS - ffeste_R911_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - item->token = ffelex_token_use (expr_token); - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif -} - -/* ffestd_R911_finish -- PRINT statement list complete - - ffestd_R911_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R911_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_ONEPASS - ffeste_R911_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif -} - -/* ffestd_R919 -- BACKSPACE statement - - ffestd_R919(); - - Make sure a BACKSPACE is valid in the current context, and implement it. */ - -void -ffestd_R919 () -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R919 (&ffestp_file.beru); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR919_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R919.pool = ffesta_output_pool; - stmt->u.R919.params = ffestd_subr_copy_beru_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R920 -- ENDFILE statement - - ffestd_R920(); - - Make sure a ENDFILE is valid in the current context, and implement it. */ - -void -ffestd_R920 () -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R920 (&ffestp_file.beru); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR920_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R920.pool = ffesta_output_pool; - stmt->u.R920.params = ffestd_subr_copy_beru_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R921 -- REWIND statement - - ffestd_R921(); - - Make sure a REWIND is valid in the current context, and implement it. */ - -void -ffestd_R921 () -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R921 (&ffestp_file.beru); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR921_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R921.pool = ffesta_output_pool; - stmt->u.R921.params = ffestd_subr_copy_beru_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R923A -- INQUIRE statement (non-IOLENGTH version) - - ffestd_R923A(bool by_file); - - Make sure an INQUIRE is valid in the current context, and implement it. */ - -void -ffestd_R923A (bool by_file) -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define specified(something) \ - (ffestp_file.inquire.inquire_spec[something].kw_or_val_present) - - /* Warn if there are any thing we don't handle via f2c libraries. */ - if (specified (FFESTP_inquireixACTION) - || specified (FFESTP_inquireixCARRIAGECONTROL) - || specified (FFESTP_inquireixDEFAULTFILE) - || specified (FFESTP_inquireixDELIM) - || specified (FFESTP_inquireixKEYED) - || specified (FFESTP_inquireixORGANIZATION) - || specified (FFESTP_inquireixPAD) - || specified (FFESTP_inquireixPOSITION) - || specified (FFESTP_inquireixREAD) - || specified (FFESTP_inquireixREADWRITE) - || specified (FFESTP_inquireixRECORDTYPE) - || specified (FFESTP_inquireixWRITE)) - { - ffebad_start (FFEBAD_INQUIRE_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - ffebad_finish (); - } - -#undef specified -#endif - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R923A (&ffestp_file.inquire, by_file); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR923A_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R923A.pool = ffesta_output_pool; - stmt->u.R923A.params = ffestd_subr_copy_inquire_ (); - stmt->u.R923A.by_file = by_file; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R923B_start -- INQUIRE(IOLENGTH=expr) statement list begin - - ffestd_R923B_start(); - - Verify that INQUIRE is valid here, and begin accepting items in the - list. */ - -void -ffestd_R923B_start () -{ - ffestd_check_start_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R923B_start (&ffestp_file.inquire); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR923B_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R923B.pool = ffesta_output_pool; - stmt->u.R923B.params = ffestd_subr_copy_inquire_ (); - stmt->u.R923B.list = NULL; - ffestd_expr_list_ = &stmt->u.R923B.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R923B_item -- INQUIRE statement i/o item - - ffestd_R923B_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_R923B_item (ffebld expr) -{ - ffestd_check_item_ (); - -#if FFECOM_ONEPASS - ffeste_R923B_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif -} - -/* ffestd_R923B_finish -- INQUIRE statement list complete - - ffestd_R923B_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R923B_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_ONEPASS - ffeste_R923B_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif -} - -/* ffestd_R1001 -- FORMAT statement - - ffestd_R1001(format_list); */ - -void -ffestd_R1001 (ffesttFormatList f) -{ - ffestsHolder str; - ffests s = &str; - - ffestd_check_simple_ (); - - if (ffestd_label_formatdef_ == NULL) - return; /* Nothing to hook it up to (no label def). */ - - ffests_new (s, malloc_pool_image (), 80); - ffests_putc (s, '('); - ffestd_R1001dump_ (s, f); /* Build the string in s. */ - ffests_putc (s, ')'); - -#if FFECOM_ONEPASS - ffeste_R1001 (s); - ffests_kill (s); /* Kill the string in s. */ -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1001_); - ffestd_stmt_append_ (stmt); - stmt->u.R1001.str = str; - } -#endif - - ffestd_label_formatdef_ = NULL; -} - -/* ffestd_R1001dump_ -- Dump list of formats - - ffesttFormatList list; - ffestd_R1001dump_(list,0); - - The formats in the list are dumped. */ - -static void -ffestd_R1001dump_ (ffests s, ffesttFormatList list) -{ - ffesttFormatList next; - - for (next = list->next; next != list; next = next->next) - { - if (next != list->next) - ffests_putc (s, ','); - switch (next->type) - { - case FFESTP_formattypeI: - ffestd_R1001dump_1005_3_ (s, next, "I"); - break; - - case FFESTP_formattypeB: -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffestd_R1001dump_1005_3_ (s, next, "B"); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_R1001error_ (next); -#else -#error -#endif - break; - - case FFESTP_formattypeO: - ffestd_R1001dump_1005_3_ (s, next, "O"); - break; - - case FFESTP_formattypeZ: - ffestd_R1001dump_1005_3_ (s, next, "Z"); - break; - - case FFESTP_formattypeF: - ffestd_R1001dump_1005_4_ (s, next, "F"); - break; - - case FFESTP_formattypeE: - ffestd_R1001dump_1005_5_ (s, next, "E"); - break; - - case FFESTP_formattypeEN: -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffestd_R1001dump_1005_5_ (s, next, "EN"); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_R1001error_ (next); -#else -#error -#endif - break; - - case FFESTP_formattypeG: - ffestd_R1001dump_1005_5_ (s, next, "G"); - break; - - case FFESTP_formattypeL: - ffestd_R1001dump_1005_2_ (s, next, "L"); - break; - - case FFESTP_formattypeA: - ffestd_R1001dump_1005_1_ (s, next, "A"); - break; - - case FFESTP_formattypeD: - ffestd_R1001dump_1005_4_ (s, next, "D"); - break; - - case FFESTP_formattypeQ: -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffestd_R1001dump_1010_1_ (s, next, "Q"); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_R1001error_ (next); -#else -#error -#endif - break; - - case FFESTP_formattypeDOLLAR: - ffestd_R1001dump_1010_1_ (s, next, "$"); - break; - - case FFESTP_formattypeP: - ffestd_R1001dump_1010_4_ (s, next, "P"); - break; - - case FFESTP_formattypeT: - ffestd_R1001dump_1010_5_ (s, next, "T"); - break; - - case FFESTP_formattypeTL: - ffestd_R1001dump_1010_5_ (s, next, "TL"); - break; - - case FFESTP_formattypeTR: - ffestd_R1001dump_1010_5_ (s, next, "TR"); - break; - - case FFESTP_formattypeX: - ffestd_R1001dump_1010_3_ (s, next, "X"); - break; - - case FFESTP_formattypeS: - ffestd_R1001dump_1010_1_ (s, next, "S"); - break; - - case FFESTP_formattypeSP: - ffestd_R1001dump_1010_1_ (s, next, "SP"); - break; - - case FFESTP_formattypeSS: - ffestd_R1001dump_1010_1_ (s, next, "SS"); - break; - - case FFESTP_formattypeBN: - ffestd_R1001dump_1010_1_ (s, next, "BN"); - break; - - case FFESTP_formattypeBZ: - ffestd_R1001dump_1010_1_ (s, next, "BZ"); - break; - - case FFESTP_formattypeSLASH: - ffestd_R1001dump_1010_2_ (s, next, "/"); - break; - - case FFESTP_formattypeCOLON: - ffestd_R1001dump_1010_1_ (s, next, ":"); - break; - - case FFESTP_formattypeR1016: - switch (ffelex_token_type (next->t)) - { - case FFELEX_typeCHARACTER: - { - char *p = ffelex_token_text (next->t); - ffeTokenLength i = ffelex_token_length (next->t); - - ffests_putc (s, '\002'); - while (i-- != 0) - { - if (*p == '\002') - ffests_putc (s, '\002'); - ffests_putc (s, *p); - ++p; - } - ffests_putc (s, '\002'); - } - break; - - case FFELEX_typeHOLLERITH: - { - char *p = ffelex_token_text (next->t); - ffeTokenLength i = ffelex_token_length (next->t); - - ffests_printf_1U (s, - "%" ffeTokenLength_f "uH", - i); - while (i-- != 0) - { - ffests_putc (s, *p); - ++p; - } - } - break; - - default: - assert (FALSE); - } - break; - - case FFESTP_formattypeFORMAT: - if (next->u.R1003D.R1004.present) - { - if (next->u.R1003D.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, next, next->u.R1003D.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", - next->u.R1003D.R1004.u.unsigned_val); - } - - ffests_putc (s, '('); - ffestd_R1001dump_ (s, next->u.R1003D.format); - ffests_putc (s, ')'); - break; - - default: - assert (FALSE); - } - } -} - -/* ffestd_R1001dump_1005_1_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1005_1_(f,"I"); - - The format is dumped with form [r]X[w]. */ - -static void -ffestd_R1001dump_1005_1_ (ffests s, ffesttFormatList f, char *string) -{ - assert (!f->u.R1005.R1007_or_R1008.present); - assert (!f->u.R1005.R1009.present); - - if (f->u.R1005.R1004.present) - { - if (f->u.R1005.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1004.u.unsigned_val); - } - - ffests_puts (s, string); - - if (f->u.R1005.R1006.present) - { - if (f->u.R1005.R1006.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1006.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1006.u.unsigned_val); - } -} - -/* ffestd_R1001dump_1005_2_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1005_2_(f,"I"); - - The format is dumped with form [r]Xw. */ - -static void -ffestd_R1001dump_1005_2_ (ffests s, ffesttFormatList f, char *string) -{ - assert (!f->u.R1005.R1007_or_R1008.present); - assert (!f->u.R1005.R1009.present); - assert (f->u.R1005.R1006.present); - - if (f->u.R1005.R1004.present) - { - if (f->u.R1005.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1004.u.unsigned_val); - } - - ffests_puts (s, string); - - if (f->u.R1005.R1006.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1006.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1006.u.unsigned_val); -} - -/* ffestd_R1001dump_1005_3_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1005_3_(f,"I"); - - The format is dumped with form [r]Xw[.m]. */ - -static void -ffestd_R1001dump_1005_3_ (ffests s, ffesttFormatList f, char *string) -{ - assert (!f->u.R1005.R1009.present); - assert (f->u.R1005.R1006.present); - - if (f->u.R1005.R1004.present) - { - if (f->u.R1005.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1004.u.unsigned_val); - } - - ffests_puts (s, string); - - if (f->u.R1005.R1006.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1006.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1006.u.unsigned_val); - - if (f->u.R1005.R1007_or_R1008.present) - { - ffests_putc (s, '.'); - if (f->u.R1005.R1007_or_R1008.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1007_or_R1008.u.expr); - else - ffests_printf_1U (s, "%lu", - f->u.R1005.R1007_or_R1008.u.unsigned_val); - } -} - -/* ffestd_R1001dump_1005_4_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1005_4_(f,"I"); - - The format is dumped with form [r]Xw.d. */ - -static void -ffestd_R1001dump_1005_4_ (ffests s, ffesttFormatList f, char *string) -{ - assert (!f->u.R1005.R1009.present); - assert (f->u.R1005.R1007_or_R1008.present); - assert (f->u.R1005.R1006.present); - - if (f->u.R1005.R1004.present) - { - if (f->u.R1005.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1004.u.unsigned_val); - } - - ffests_puts (s, string); - - if (f->u.R1005.R1006.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1006.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1006.u.unsigned_val); - - ffests_putc (s, '.'); - if (f->u.R1005.R1007_or_R1008.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1007_or_R1008.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1007_or_R1008.u.unsigned_val); -} - -/* ffestd_R1001dump_1005_5_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1005_5_(f,"I"); - - The format is dumped with form [r]Xw.d[Ee]. */ - -static void -ffestd_R1001dump_1005_5_ (ffests s, ffesttFormatList f, char *string) -{ - assert (f->u.R1005.R1007_or_R1008.present); - assert (f->u.R1005.R1006.present); - - if (f->u.R1005.R1004.present) - { - if (f->u.R1005.R1004.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1004.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1004.u.unsigned_val); - } - - ffests_puts (s, string); - - if (f->u.R1005.R1006.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1006.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1006.u.unsigned_val); - - ffests_putc (s, '.'); - if (f->u.R1005.R1007_or_R1008.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1007_or_R1008.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1007_or_R1008.u.unsigned_val); - - if (f->u.R1005.R1009.present) - { - ffests_putc (s, 'E'); - if (f->u.R1005.R1009.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1005.R1009.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1005.R1009.u.unsigned_val); - } -} - -/* ffestd_R1001dump_1010_1_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1010_1_(f,"I"); - - The format is dumped with form X. */ - -static void -ffestd_R1001dump_1010_1_ (ffests s, ffesttFormatList f, char *string) -{ - assert (!f->u.R1010.val.present); - - ffests_puts (s, string); -} - -/* ffestd_R1001dump_1010_2_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1010_2_(f,"I"); - - The format is dumped with form [r]X. */ - -static void -ffestd_R1001dump_1010_2_ (ffests s, ffesttFormatList f, char *string) -{ - if (f->u.R1010.val.present) - { - if (f->u.R1010.val.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1010.val.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1010.val.u.unsigned_val); - } - - ffests_puts (s, string); -} - -/* ffestd_R1001dump_1010_3_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1010_3_(f,"I"); - - The format is dumped with form nX. */ - -static void -ffestd_R1001dump_1010_3_ (ffests s, ffesttFormatList f, char *string) -{ - assert (f->u.R1010.val.present); - - if (f->u.R1010.val.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1010.val.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1010.val.u.unsigned_val); - - ffests_puts (s, string); -} - -/* ffestd_R1001dump_1010_4_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1010_4_(f,"I"); - - The format is dumped with form kX. Note that k is signed. */ - -static void -ffestd_R1001dump_1010_4_ (ffests s, ffesttFormatList f, char *string) -{ - assert (f->u.R1010.val.present); - - if (f->u.R1010.val.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1010.val.u.expr); - else - ffests_printf_1D (s, "%ld", f->u.R1010.val.u.signed_val); - - ffests_puts (s, string); -} - -/* ffestd_R1001dump_1010_5_ -- Dump a particular format - - ffesttFormatList f; - ffestd_R1001dump_1010_5_(f,"I"); - - The format is dumped with form Xn. */ - -static void -ffestd_R1001dump_1010_5_ (ffests s, ffesttFormatList f, char *string) -{ - assert (f->u.R1010.val.present); - - ffests_puts (s, string); - - if (f->u.R1010.val.rtexpr) - ffestd_R1001rtexpr_ (s, f, f->u.R1010.val.u.expr); - else - ffests_printf_1U (s, "%lu", f->u.R1010.val.u.unsigned_val); -} - -/* ffestd_R1001error_ -- Complain about FORMAT specification not supported - - ffesttFormatList f; - ffestd_R1001error_(f); - - An error message is produced. */ - -static void -ffestd_R1001error_ (ffesttFormatList f) -{ - ffebad_start (FFEBAD_FORMAT_UNSUPPORTED); - ffebad_here (0, ffelex_token_where_line (f->t), ffelex_token_where_column (f->t)); - ffebad_finish (); -} - -static void -ffestd_R1001rtexpr_ (ffests s, ffesttFormatList f, ffebld expr) -{ - if ((expr == NULL) - || (ffebld_op (expr) != FFEBLD_opCONTER) - || (ffeinfo_basictype (ffebld_info (expr)) != FFEINFO_basictypeINTEGER) - || (ffeinfo_kindtype (ffebld_info (expr)) == FFEINFO_kindtypeINTEGER4)) - { - ffebad_start (FFEBAD_FORMAT_VARIABLE); - ffebad_here (0, ffelex_token_where_line (f->t), ffelex_token_where_column (f->t)); - ffebad_finish (); - } - else - { - int val; - - switch (ffeinfo_kindtype (ffebld_info (expr))) - { -#if FFETARGET_okINTEGER1 - case FFEINFO_kindtypeINTEGER1: - val = ffebld_constant_integer1 (ffebld_conter (expr)); - break; -#endif - -#if FFETARGET_okINTEGER2 - case FFEINFO_kindtypeINTEGER2: - val = ffebld_constant_integer2 (ffebld_conter (expr)); - break; -#endif - -#if FFETARGET_okINTEGER3 - case FFEINFO_kindtypeINTEGER3: - val = ffebld_constant_integer3 (ffebld_conter (expr)); - break; -#endif - - default: - assert ("bad INTEGER constant kind type" == NULL); - /* Fall through. */ - case FFEINFO_kindtypeANY: - return; - } - ffests_printf_1D (s, "%ld", val); - } -} - -/* ffestd_R1102 -- PROGRAM statement - - ffestd_R1102(name_token); - - Make sure ffestd_kind_ identifies an empty block. Make sure name_token - gives a valid name. Implement the beginning of a main program. */ - -void -ffestd_R1102 (ffesymbol s, ffelexToken name UNUSED) -{ - ffestd_check_simple_ (); - - assert (ffestd_block_level_ == 0); - ffestd_is_reachable_ = TRUE; - - ffecom_notify_primary_entry (s); - ffe_set_is_mainprog (TRUE); /* Is a main program. */ - ffe_set_is_saveall (TRUE); /* Main program always has implicit SAVE. */ - - ffestw_set_sym (ffestw_stack_top (), s); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (name == NULL) - fputs ("< PROGRAM_unnamed\n", dmpout); - else - fprintf (dmpout, "< PROGRAM %s\n", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1103 -- End a PROGRAM - - ffestd_R1103(); */ - -void -ffestd_R1103 (bool ok UNUSED) -{ - assert (ffestd_block_level_ == 0); - - if (FFESTD_IS_END_OPTIMIZED_ && ffestd_is_reachable_) - ffestd_R842 (NULL); /* Generate STOP. */ - - if (ffestw_state (ffestw_stack_top ()) != FFESTV_statePROGRAM5) - ffestd_subr_labels_ (FALSE);/* Handle any undefined labels. */ - -#if FFECOM_ONEPASS - ffeste_R1103 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1103_); - ffestd_stmt_append_ (stmt); - } -#endif -} - -/* ffestd_R1105 -- MODULE statement - - ffestd_R1105(name_token); - - Make sure ffestd_kind_ identifies an empty block. Make sure name_token - gives a valid name. Implement the beginning of a module. */ - -#if FFESTR_F90 -void -ffestd_R1105 (ffelexToken name) -{ - assert (ffestd_block_level_ == 0); - - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fprintf (dmpout, "* MODULE %s\n", ffelex_token_text (name)); -#endif -} - -/* ffestd_R1106 -- End a MODULE - - ffestd_R1106(TRUE); */ - -void -ffestd_R1106 (bool ok) -{ - assert (ffestd_block_level_ == 0); - - /* Generate any wrap-up code here (unlikely in MODULE!). */ - - if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateMODULE5) - ffestd_subr_labels_ (TRUE); /* Handle any undefined labels (unlikely). */ - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "< END_MODULE %s\n", - ffelex_token_text (ffestw_name (ffestw_stack_top ()))); -#endif -} - -/* ffestd_R1107_start -- USE statement list begin - - ffestd_R1107_start(); - - Verify that USE is valid here, and begin accepting items in the list. */ - -void -ffestd_R1107_start (ffelexToken name, bool only) -{ - ffestd_check_start_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fprintf (dmpout, "* USE %s,", ffelex_token_text (name)); /* NB - _shriek_begin_uses_. */ - if (only) - fputs ("only: ", dmpout); -#endif -} - -/* ffestd_R1107_item -- USE statement for name - - ffestd_R1107_item(local_token,use_token); - - Make sure name_token identifies a valid object to be USEed. local_token - may be NULL if _start_ was called with only==TRUE. */ - -void -ffestd_R1107_item (ffelexToken local, ffelexToken use) -{ - ffestd_check_item_ (); - assert (use != NULL); - - return; /* F90. */ - -#ifdef FFESTD_F90 - if (local != NULL) - fprintf (dmpout, "%s=>", ffelex_token_text (local)); - fprintf (dmpout, "%s,", ffelex_token_text (use)); -#endif -} - -/* ffestd_R1107_finish -- USE statement list complete - - ffestd_R1107_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R1107_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -#endif -/* ffestd_R1111 -- BLOCK DATA statement - - ffestd_R1111(name_token); - - Make sure ffestd_kind_ identifies no current program unit. If not - NULL, make sure name_token gives a valid name. Implement the beginning - of a block data program unit. */ - -void -ffestd_R1111 (ffesymbol s, ffelexToken name UNUSED) -{ - assert (ffestd_block_level_ == 0); - ffestd_is_reachable_ = TRUE; - - ffestd_check_simple_ (); - - ffecom_notify_primary_entry (s); - ffestw_set_sym (ffestw_stack_top (), s); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (name == NULL) - fputs ("< BLOCK_DATA_unnamed\n", dmpout); - else - fprintf (dmpout, "< BLOCK_DATA %s\n", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1112 -- End a BLOCK DATA - - ffestd_R1112(TRUE); */ - -void -ffestd_R1112 (bool ok UNUSED) -{ - assert (ffestd_block_level_ == 0); - - /* Generate any return-like code here (not likely for BLOCK DATA!). */ - - if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateBLOCKDATA5) - ffestd_subr_labels_ (TRUE); /* Handle any undefined labels. */ - -#if FFECOM_ONEPASS - ffeste_R1112 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1112_); - ffestd_stmt_append_ (stmt); - } -#endif -} - -/* ffestd_R1202 -- INTERFACE statement - - ffestd_R1202(operator,defined_name); - - Make sure ffestd_kind_ identifies an INTERFACE block. - Implement the end of the current interface. - - 06-Jun-90 JCB 1.1 - Allow no operator or name to mean INTERFACE by itself; missed this - valid form when originally doing syntactic analysis code. */ - -#if FFESTR_F90 -void -ffestd_R1202 (ffestpDefinedOperator operator, ffelexToken name) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - switch (operator) - { - case FFESTP_definedoperatorNone: - if (name == NULL) - fputs ("* INTERFACE_unnamed\n", dmpout); - else - fprintf (dmpout, "* INTERFACE %s\n", ffelex_token_text (name)); - break; - - case FFESTP_definedoperatorOPERATOR: - fprintf (dmpout, "* INTERFACE_OPERATOR (.%s.)\n", ffelex_token_text (name)); - break; - - case FFESTP_definedoperatorASSIGNMENT: - fputs ("* INTERFACE_ASSIGNMENT (=)\n", dmpout); - break; - - case FFESTP_definedoperatorPOWER: - fputs ("* INTERFACE_OPERATOR (**)\n", dmpout); - break; - - case FFESTP_definedoperatorMULT: - fputs ("* INTERFACE_OPERATOR (*)\n", dmpout); - break; - - case FFESTP_definedoperatorADD: - fputs ("* INTERFACE_OPERATOR (+)\n", dmpout); - break; - - case FFESTP_definedoperatorCONCAT: - fputs ("* INTERFACE_OPERATOR (//)\n", dmpout); - break; - - case FFESTP_definedoperatorDIVIDE: - fputs ("* INTERFACE_OPERATOR (/)\n", dmpout); - break; - - case FFESTP_definedoperatorSUBTRACT: - fputs ("* INTERFACE_OPERATOR (-)\n", dmpout); - break; - - case FFESTP_definedoperatorNOT: - fputs ("* INTERFACE_OPERATOR (.not.)\n", dmpout); - break; - - case FFESTP_definedoperatorAND: - fputs ("* INTERFACE_OPERATOR (.and.)\n", dmpout); - break; - - case FFESTP_definedoperatorOR: - fputs ("* INTERFACE_OPERATOR (.or.)\n", dmpout); - break; - - case FFESTP_definedoperatorEQV: - fputs ("* INTERFACE_OPERATOR (.eqv.)\n", dmpout); - break; - - case FFESTP_definedoperatorNEQV: - fputs ("* INTERFACE_OPERATOR (.neqv.)\n", dmpout); - break; - - case FFESTP_definedoperatorEQ: - fputs ("* INTERFACE_OPERATOR (==)\n", dmpout); - break; - - case FFESTP_definedoperatorNE: - fputs ("* INTERFACE_OPERATOR (/=)\n", dmpout); - break; - - case FFESTP_definedoperatorLT: - fputs ("* INTERFACE_OPERATOR (<)\n", dmpout); - break; - - case FFESTP_definedoperatorLE: - fputs ("* INTERFACE_OPERATOR (<=)\n", dmpout); - break; - - case FFESTP_definedoperatorGT: - fputs ("* INTERFACE_OPERATOR (>)\n", dmpout); - break; - - case FFESTP_definedoperatorGE: - fputs ("* INTERFACE_OPERATOR (>=)\n", dmpout); - break; - - default: - assert (FALSE); - break; - } -#endif -} - -/* ffestd_R1203 -- End an INTERFACE - - ffestd_R1203(TRUE); */ - -void -ffestd_R1203 (bool ok) -{ - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs ("* END_INTERFACE\n", dmpout); -#endif -} - -/* ffestd_R1205_start -- MODULE PROCEDURE statement list begin - - ffestd_R1205_start(); - - Verify that MODULE PROCEDURE is valid here, and begin accepting items in - the list. */ - -void -ffestd_R1205_start () -{ - ffestd_check_start_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputs ("* MODULE_PROCEDURE ", dmpout); -#endif -} - -/* ffestd_R1205_item -- MODULE PROCEDURE statement for name - - ffestd_R1205_item(name_token); - - Make sure name_token identifies a valid object to be MODULE PROCEDUREed. */ - -void -ffestd_R1205_item (ffelexToken name) -{ - ffestd_check_item_ (); - assert (name != NULL); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#endif -} - -/* ffestd_R1205_finish -- MODULE PROCEDURE statement list complete - - ffestd_R1205_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R1205_finish () -{ - ffestd_check_finish_ (); - - return; /* F90. */ - -#ifdef FFESTD_F90 - fputc ('\n', dmpout); -#endif -} - -#endif -/* ffestd_R1207_start -- EXTERNAL statement list begin - - ffestd_R1207_start(); - - Verify that EXTERNAL is valid here, and begin accepting items in the list. */ - -void -ffestd_R1207_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* EXTERNAL (", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1207_item -- EXTERNAL statement for name - - ffestd_R1207_item(name_token); - - Make sure name_token identifies a valid object to be EXTERNALd. */ - -void -ffestd_R1207_item (ffelexToken name) -{ - ffestd_check_item_ (); - assert (name != NULL); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1207_finish -- EXTERNAL statement list complete - - ffestd_R1207_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R1207_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1208_start -- INTRINSIC statement list begin - - ffestd_R1208_start(); - - Verify that INTRINSIC is valid here, and begin accepting items in the list. */ - -void -ffestd_R1208_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* INTRINSIC (", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1208_item -- INTRINSIC statement for name - - ffestd_R1208_item(name_token); - - Make sure name_token identifies a valid object to be INTRINSICd. */ - -void -ffestd_R1208_item (ffelexToken name) -{ - ffestd_check_item_ (); - assert (name != NULL); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1208_finish -- INTRINSIC statement list complete - - ffestd_R1208_finish(); - - Just wrap up any local activities. */ - -void -ffestd_R1208_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1212 -- CALL statement - - ffestd_R1212(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffestd_R1212 (ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R1212 (expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1212_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R1212.pool = ffesta_output_pool; - stmt->u.R1212.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif -} - -/* ffestd_R1213 -- Defined assignment statement - - ffestd_R1213(dest_expr,source_expr,source_token); - - Make sure the assignment is valid. */ - -#if FFESTR_F90 -void -ffestd_R1213 (ffebld dest, ffebld source) -{ - ffestd_check_simple_ (); - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("+ let_defined ", dmpout); - ffebld_dump (dest); - fputs ("=", dmpout); - ffebld_dump (source); - fputc ('\n', dmpout); -#endif -} - -#endif -/* ffestd_R1219 -- FUNCTION statement - - ffestd_R1219(funcname,arglist,ending_token,kind,kindt,len,lent, - recursive); - - Make sure statement is valid here, register arguments for the - function name, and so on. - - 06-Jun-90 JCB 2.0 - Added the kind, len, and recursive arguments. */ - -void -ffestd_R1219 (ffesymbol s, ffelexToken funcname UNUSED, - ffesttTokenList args UNUSED, ffestpType type UNUSED, - ffebld kind UNUSED, ffelexToken kindt UNUSED, - ffebld len UNUSED, ffelexToken lent UNUSED, - bool recursive UNUSED, ffelexToken result UNUSED, - bool separate_result UNUSED) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - char *a; -#endif - - assert (ffestd_block_level_ == 0); - ffestd_is_reachable_ = TRUE; - - ffestd_check_simple_ (); - - ffecom_notify_primary_entry (s); - ffestw_set_sym (ffestw_stack_top (), s); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (type) - { - case FFESTP_typeINTEGER: - a = "INTEGER"; - break; - - case FFESTP_typeBYTE: - a = "BYTE"; - break; - - case FFESTP_typeWORD: - a = "WORD"; - break; - - case FFESTP_typeREAL: - a = "REAL"; - break; - - case FFESTP_typeCOMPLEX: - a = "COMPLEX"; - break; - - case FFESTP_typeLOGICAL: - a = "LOGICAL"; - break; - - case FFESTP_typeCHARACTER: - a = "CHARACTER"; - break; - - case FFESTP_typeDBLPRCSN: - a = "DOUBLE PRECISION"; - break; - - case FFESTP_typeDBLCMPLX: - a = "DOUBLE COMPLEX"; - break; - -#if FFESTR_F90 - case FFESTP_typeTYPE: - a = "TYPE"; - break; -#endif - - case FFESTP_typeNone: - a = ""; - break; - - default: - assert (FALSE); - a = "?"; - break; - } - fprintf (dmpout, "< FUNCTION %s ", ffelex_token_text (funcname)); - if (recursive) - fputs ("RECURSIVE ", dmpout); - fprintf (dmpout, "%s(", a); - if (kindt != NULL) - { - fputs ("kind=", dmpout); - if (kind == NULL) - fputs (ffelex_token_text (kindt), dmpout); - else - ffebld_dump (kind); - if (lent != NULL) - fputc (',', dmpout); - } - if (lent != NULL) - { - fputs ("len=", dmpout); - if (len == NULL) - fputs (ffelex_token_text (lent), dmpout); - else - ffebld_dump (len); - } - fprintf (dmpout, ")"); - if (args != NULL) - { - fputs (" (", dmpout); - ffestt_tokenlist_dump (args); - fputc (')', dmpout); - } - if (result != NULL) - fprintf (dmpout, " result(%s)", ffelex_token_text (result)); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1221 -- End a FUNCTION - - ffestd_R1221(TRUE); */ - -void -ffestd_R1221 (bool ok UNUSED) -{ - assert (ffestd_block_level_ == 0); - - if (FFESTD_IS_END_OPTIMIZED_ && ffestd_is_reachable_) - ffestd_R1227 (NULL); /* Generate RETURN. */ - - if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateFUNCTION5) - ffestd_subr_labels_ (FALSE);/* Handle any undefined labels. */ - -#if FFECOM_ONEPASS - ffeste_R1221 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1221_); - ffestd_stmt_append_ (stmt); - } -#endif -} - -/* ffestd_R1223 -- SUBROUTINE statement - - ffestd_R1223(subrname,arglist,ending_token,recursive_token); - - Make sure statement is valid here, register arguments for the - subroutine name, and so on. - - 06-Jun-90 JCB 2.0 - Added the recursive argument. */ - -void -ffestd_R1223 (ffesymbol s, ffelexToken subrname UNUSED, - ffesttTokenList args UNUSED, ffelexToken final UNUSED, - bool recursive UNUSED) -{ - assert (ffestd_block_level_ == 0); - ffestd_is_reachable_ = TRUE; - - ffestd_check_simple_ (); - - ffecom_notify_primary_entry (s); - ffestw_set_sym (ffestw_stack_top (), s); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "< SUBROUTINE %s ", ffelex_token_text (subrname)); - if (recursive) - fputs ("recursive ", dmpout); - if (args != NULL) - { - fputc ('(', dmpout); - ffestt_tokenlist_dump (args); - fputc (')', dmpout); - } - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1225 -- End a SUBROUTINE - - ffestd_R1225(TRUE); */ - -void -ffestd_R1225 (bool ok UNUSED) -{ - assert (ffestd_block_level_ == 0); - - if (FFESTD_IS_END_OPTIMIZED_ && ffestd_is_reachable_) - ffestd_R1227 (NULL); /* Generate RETURN. */ - - if (ffestw_state (ffestw_stack_top ()) != FFESTV_stateSUBROUTINE5) - ffestd_subr_labels_ (FALSE);/* Handle any undefined labels. */ - -#if FFECOM_ONEPASS - ffeste_R1225 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1225_); - ffestd_stmt_append_ (stmt); - } -#endif -} - -/* ffestd_R1226 -- ENTRY statement - - ffestd_R1226(entryname,arglist,ending_token); - - Make sure we're in a SUBROUTINE or FUNCTION, register arguments for the - entry point name, and so on. */ - -void -ffestd_R1226 (ffesymbol entry) -{ - ffestd_check_simple_ (); - -#if (FFECOM_targetCURRENT == FFECOM_targetFFE) || FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R1226 (entry); -#else - if (!ffesta_seen_first_exec || ffecom_2pass_advise_entrypoint (entry)) - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1226_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R1226.entry = entry; - stmt->u.R1226.entrynum = ++ffestd_2pass_entrypoints_; - } -#endif - - ffestd_is_reachable_ = TRUE; -} - -/* ffestd_R1227 -- RETURN statement - - ffestd_R1227(expr); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffestd_R1227 (ffebld expr) -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R1227 (ffestw_stack_top (), expr); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR1227_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.R1227.pool = ffesta_output_pool; - stmt->u.R1227.block = ffestw_stack_top (); - stmt->u.R1227.expr = expr; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - - if (ffestd_block_level_ == 0) - ffestd_is_reachable_ = FALSE; -} - -/* ffestd_R1228 -- CONTAINS statement - - ffestd_R1228(); */ - -#if FFESTR_F90 -void -ffestd_R1228 () -{ - assert (ffestd_block_level_ == 0); - - ffestd_check_simple_ (); - - /* Generate RETURN/STOP code here */ - - ffestd_subr_labels_ (ffestw_state (ffestw_stack_top ()) - == FFESTV_stateMODULE5); /* Handle any undefined - labels. */ - - ffestd_subr_f90_ (); - return; - -#ifdef FFESTD_F90 - fputs ("- CONTAINS\n", dmpout); -#endif -} - -#endif -/* ffestd_R1229_start -- STMTFUNCTION statement begin - - ffestd_R1229_start(func_name,func_arg_list,close_paren); - - This function does not really need to do anything, since _finish_ - gets all the info needed, and ffestc_R1229_start has already - done all the stuff that makes a two-phase operation (start and - finish) for handling statement functions necessary. - - 03-Jan-91 JCB 2.0 - Do nothing, now that _finish_ does everything. */ - -void -ffestd_R1229_start (ffelexToken name UNUSED, ffesttTokenList args UNUSED) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_R1229_finish -- STMTFUNCTION statement list complete - - ffestd_R1229_finish(s); - - The statement function's symbol is passed. Its list of dummy args is - accessed via ffesymbol_dummyargs and its expansion expression (expr) - is accessed via ffesymbol_sfexpr. - - If sfexpr is NULL, an error occurred parsing the expansion expression, so - just cancel the effects of ffestd_R1229_start and pretend nothing - happened. Otherwise, install the expression as the expansion for the - statement function, then clean up. - - 03-Jan-91 JCB 2.0 - Takes sfunc sym instead of just the expansion expression as an - argument, so this function can do all the work, and _start_ is just - a nicety than can do nothing in a back end. */ - -void -ffestd_R1229_finish (ffesymbol s) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld args = ffesymbol_dummyargs (s); -#endif - ffebld expr = ffesymbol_sfexpr (s); - - ffestd_check_finish_ (); - - if (expr == NULL) - return; /* Nothing to do, definition didn't work. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "* stmtfunction %s(", ffesymbol_text (s)); - for (; args != NULL; args = ffebld_trail (args)) - fprintf (dmpout, "%s,", ffesymbol_text (ffebld_symter (ffebld_head (args)))); - fputs (")=", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); -#if 0 /* Normally no need to preserve the - expression. */ - ffesymbol_set_sfexpr (s, NULL); /* Except expr.c sees NULL - as recursive reference! - So until we can use something - convenient, like a "permanent" - expression, don't worry about - wasting some memory in the - stand-alone FFE. */ -#else - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); -#endif -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - /* With gcc, cannot do anything here, because the backend hasn't even - (necessarily) been notified that we're compiling a program unit! */ - -#if 0 /* Must preserve the expression for gcc. */ - ffesymbol_set_sfexpr (s, NULL); -#else - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); -#endif -#else -#error -#endif -} - -/* ffestd_S3P4 -- INCLUDE line - - ffestd_S3P4(filename,filename_token); - - Make sure INCLUDE not preceded by any semicolons or a label def; implement. */ - -void -ffestd_S3P4 (ffebld filename) -{ - FILE *fi; - ffetargetCharacterDefault buildname; - ffewhereFile wf; - - ffestd_check_simple_ (); - - assert (filename != NULL); - if (ffebld_op (filename) != FFEBLD_opANY) - { - assert (ffebld_op (filename) == FFEBLD_opCONTER); - assert (ffeinfo_basictype (ffebld_info (filename)) - == FFEINFO_basictypeCHARACTER); - assert (ffeinfo_kindtype (ffebld_info (filename)) - == FFEINFO_kindtypeCHARACTERDEFAULT); - buildname = ffebld_constant_characterdefault (ffebld_conter (filename)); - wf = ffewhere_file_new (ffetarget_text_characterdefault (buildname), - ffetarget_length_characterdefault (buildname)); - fi = ffecom_open_include (ffewhere_file_name (wf), - ffelex_token_where_line (ffesta_tokens[0]), - ffelex_token_where_column (ffesta_tokens[0])); - if (fi == NULL) - ffewhere_file_kill (wf); - else - ffelex_set_include (wf, (ffelex_token_type (ffesta_tokens[0]) - == FFELEX_typeNAME), fi); - } -} - -/* ffestd_V003_start -- STRUCTURE statement list begin - - ffestd_V003_start(structure_name); - - Verify that STRUCTURE is valid here, and begin accepting items in the list. */ - -#if FFESTR_VXT -void -ffestd_V003_start (ffelexToken structure_name) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (structure_name == NULL) - fputs ("* STRUCTURE_unnamed ", dmpout); - else - fprintf (dmpout, "* STRUCTURE %s ", ffelex_token_text (structure_name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#else -#error -#endif -} - -/* ffestd_V003_item -- STRUCTURE statement for object-name - - ffestd_V003_item(name_token,dim_list); - - Make sure name_token identifies a valid object to be STRUCTUREd. */ - -void -ffestd_V003_item (ffelexToken name, ffesttDimList dims) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V003_finish -- STRUCTURE statement list complete - - ffestd_V003_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V003_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V004 -- End a STRUCTURE - - ffestd_V004(TRUE); */ - -void -ffestd_V004 (bool ok) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* END_STRUCTURE\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V009 -- UNION statement - - ffestd_V009(); */ - -void -ffestd_V009 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* UNION\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V010 -- End a UNION - - ffestd_V010(TRUE); */ - -void -ffestd_V010 (bool ok) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* END_UNION\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V012 -- MAP statement - - ffestd_V012(); */ - -void -ffestd_V012 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* MAP\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V013 -- End a MAP - - ffestd_V013(TRUE); */ - -void -ffestd_V013 (bool ok) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* END_MAP\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif -/* ffestd_V014_start -- VOLATILE statement list begin - - ffestd_V014_start(); - - Verify that VOLATILE is valid here, and begin accepting items in the list. */ - -void -ffestd_V014_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* VOLATILE (", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#else -#error -#endif -} - -/* ffestd_V014_item_object -- VOLATILE statement for object-name - - ffestd_V014_item_object(name_token); - - Make sure name_token identifies a valid object to be VOLATILEd. */ - -void -ffestd_V014_item_object (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "%s,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V014_item_cblock -- VOLATILE statement for common-block-name - - ffestd_V014_item_cblock(name_token); - - Make sure name_token identifies a valid common block to be VOLATILEd. */ - -void -ffestd_V014_item_cblock (ffelexToken name UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "/%s/,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V014_finish -- VOLATILE statement list complete - - ffestd_V014_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V014_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V016_start -- RECORD statement list begin - - ffestd_V016_start(); - - Verify that RECORD is valid here, and begin accepting items in the list. */ - -#if FFESTR_VXT -void -ffestd_V016_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* RECORD ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#else -#error -#endif -} - -/* ffestd_V016_item_structure -- RECORD statement for common-block-name - - ffestd_V016_item_structure(name_token); - - Make sure name_token identifies a valid structure to be RECORDed. */ - -void -ffestd_V016_item_structure (ffelexToken name) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "/%s/,", ffelex_token_text (name)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V016_item_object -- RECORD statement for object-name - - ffestd_V016_item_object(name_token,dim_list); - - Make sure name_token identifies a valid object to be RECORDd. */ - -void -ffestd_V016_item_object (ffelexToken name, ffesttDimList dims) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (ffelex_token_text (name), dmpout); - if (dims != NULL) - { - fputc ('(', dmpout); - ffestt_dimlist_dump (dims); - fputc (')', dmpout); - } - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V016_finish -- RECORD statement list complete - - ffestd_V016_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V016_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V018_start -- REWRITE(...) statement list begin - - ffestd_V018_start(); - - Verify that REWRITE is valid here, and begin accepting items in the - list. */ - -void -ffestd_V018_start (ffestvFormat format) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V018_start (&ffestp_file.rewrite, format); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV018_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V018.pool = ffesta_output_pool; - stmt->u.V018.params = ffestd_subr_copy_rewrite_ (); - stmt->u.V018.format = format; - stmt->u.V018.list = NULL; - ffestd_expr_list_ = &stmt->u.V018.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V018_item -- REWRITE statement i/o item - - ffestd_V018_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_V018_item (ffebld expr) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V018_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V018_finish -- REWRITE statement list complete - - ffestd_V018_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V018_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V018_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V019_start -- ACCEPT statement list begin - - ffestd_V019_start(); - - Verify that ACCEPT is valid here, and begin accepting items in the - list. */ - -void -ffestd_V019_start (ffestvFormat format) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V019_start (&ffestp_file.accept, format); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV019_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V019.pool = ffesta_output_pool; - stmt->u.V019.params = ffestd_subr_copy_accept_ (); - stmt->u.V019.format = format; - stmt->u.V019.list = NULL; - ffestd_expr_list_ = &stmt->u.V019.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V019_item -- ACCEPT statement i/o item - - ffestd_V019_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_V019_item (ffebld expr) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V019_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V019_finish -- ACCEPT statement list complete - - ffestd_V019_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V019_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V019_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -#endif -/* ffestd_V020_start -- TYPE statement list begin - - ffestd_V020_start(); - - Verify that TYPE is valid here, and begin accepting items in the - list. */ - -void -ffestd_V020_start (ffestvFormat format UNUSED) -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V020_start (&ffestp_file.type, format); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV020_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V020.pool = ffesta_output_pool; - stmt->u.V020.params = ffestd_subr_copy_type_ (); - stmt->u.V020.format = format; - stmt->u.V020.list = NULL; - ffestd_expr_list_ = &stmt->u.V020.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V020_item -- TYPE statement i/o item - - ffestd_V020_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_V020_item (ffebld expr UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V020_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V020_finish -- TYPE statement list complete - - ffestd_V020_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V020_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V020_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V021 -- DELETE statement - - ffestd_V021(); - - Make sure a DELETE is valid in the current context, and implement it. */ - -#if FFESTR_VXT -void -ffestd_V021 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V021 (&ffestp_file.delete); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV021_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V021.pool = ffesta_output_pool; - stmt->u.V021.params = ffestd_subr_copy_delete_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V022 -- UNLOCK statement - - ffestd_V022(); - - Make sure a UNLOCK is valid in the current context, and implement it. */ - -void -ffestd_V022 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V022 (&ffestp_file.beru); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV022_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V022.pool = ffesta_output_pool; - stmt->u.V022.params = ffestd_subr_copy_beru_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V023_start -- ENCODE(...) statement list begin - - ffestd_V023_start(); - - Verify that ENCODE is valid here, and begin accepting items in the - list. */ - -void -ffestd_V023_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V023_start (&ffestp_file.vxtcode); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV023_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V023.pool = ffesta_output_pool; - stmt->u.V023.params = ffestd_subr_copy_vxtcode_ (); - stmt->u.V023.list = NULL; - ffestd_expr_list_ = &stmt->u.V023.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V023_item -- ENCODE statement i/o item - - ffestd_V023_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_V023_item (ffebld expr) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V023_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V023_finish -- ENCODE statement list complete - - ffestd_V023_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V023_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V023_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V024_start -- DECODE(...) statement list begin - - ffestd_V024_start(); - - Verify that DECODE is valid here, and begin accepting items in the - list. */ - -void -ffestd_V024_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V024_start (&ffestp_file.vxtcode); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV024_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V024.pool = ffesta_output_pool; - stmt->u.V024.params = ffestd_subr_copy_vxtcode_ (); - stmt->u.V024.list = NULL; - ffestd_expr_list_ = &stmt->u.V024.list; - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V024_item -- DECODE statement i/o item - - ffestd_V024_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffestd_V024_item (ffebld expr) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V024_item (expr); -#else - { - ffestdExprItem_ item - = (ffestdExprItem_) malloc_new_kp (ffesta_output_pool, "ffestdExprItem_", - sizeof (*item)); - - item->next = NULL; - item->expr = expr; - *ffestd_expr_list_ = item; - ffestd_expr_list_ = &item->next; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V024_finish -- DECODE statement list complete - - ffestd_V024_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V024_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V024_finish (); -#else - /* Nothing to do, it's implicit. */ -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V025_start -- DEFINEFILE statement list begin - - ffestd_V025_start(); - - Verify that DEFINEFILE is valid here, and begin accepting items in the - list. */ - -void -ffestd_V025_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V025_start (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV025start_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -/* ffestd_V025_item -- DEFINE FILE statement item - - ffestd_V025_item(u,ut,m,mt,n,nt,asv,asvt); - - Implement item. Treat each item kind of like a separate statement, - since there's really no need to treat them as an aggregate. */ - -void -ffestd_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V025_item (u, m, n, asv); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV025item_); - ffestd_stmt_append_ (stmt); - stmt->u.V025item.u = u; - stmt->u.V025item.m = m; - stmt->u.V025item.n = n; - stmt->u.V025item.asv = asv; - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V025_finish -- DEFINE FILE statement list complete - - ffestd_V025_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V025_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffeste_V025_finish (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV025finish_); - stmt->u.V025finish.pool = ffesta_output_pool; - ffestd_stmt_append_ (stmt); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#endif -} - -/* ffestd_V026 -- FIND statement - - ffestd_V026(); - - Make sure a FIND is valid in the current context, and implement it. */ - -void -ffestd_V026 () -{ - ffestd_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_V026 (&ffestp_file.find); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidV026_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - stmt->u.V026.pool = ffesta_output_pool; - stmt->u.V026.params = ffestd_subr_copy_find_ (); - ffesta_set_outpooldisp (FFESTA_pooldispPRESERVE); - } -#endif - -#endif -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -} - -#endif -/* ffestd_V027_start -- VXT PARAMETER statement list begin - - ffestd_V027_start(); - - Verify that PARAMETER is valid here, and begin accepting items in the list. */ - -void -ffestd_V027_start () -{ - ffestd_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* PARAMETER_vxt ", dmpout); -#else -#if FFECOM_targetCURRENT == FFECOM_targetGCC - ffestd_subr_vxt_ (); -#endif -#endif -} - -/* ffestd_V027_item -- VXT PARAMETER statement assignment - - ffestd_V027_item(dest,dest_token,source,source_token); - - Make sure the source is a valid source for the destination; make the - assignment. */ - -void -ffestd_V027_item (ffelexToken dest_token UNUSED, ffebld source UNUSED) -{ - ffestd_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs (ffelex_token_text (dest_token), dmpout); - fputc ('=', dmpout); - ffebld_dump (source); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffestd_V027_finish -- VXT PARAMETER statement list complete - - ffestd_V027_finish(); - - Just wrap up any local activities. */ - -void -ffestd_V027_finish () -{ - ffestd_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* Any executable statement. */ - -void -ffestd_any () -{ - ffestd_check_simple_ (); - -#if FFECOM_ONEPASS - ffestd_subr_line_now_ (); - ffeste_R841 (); -#else - { - ffestdStmt_ stmt; - - stmt = ffestd_stmt_new_ (FFESTD_stmtidR841_); - ffestd_stmt_append_ (stmt); - ffestd_subr_line_save_ (stmt); - } -#endif -} diff --git a/gcc/f/std.h b/gcc/f/std.h deleted file mode 100755 index 810f427..0000000 --- a/gcc/f/std.h +++ /dev/null @@ -1,298 +0,0 @@ -/* std.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - std.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_std -#define _H_f_std - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lab.h" -#include "lex.h" -#include "stp.h" -#include "str.h" -#include "stt.h" -#include "stv.h" -#include "stw.h" -#include "symbol.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffestd_begin_uses (void); -void ffestd_do (bool ok); -#if FFESTR_F90 -void ffestd_end_uses (bool ok); -void ffestd_end_R740 (bool ok); -#endif -void ffestd_end_R807 (bool ok); -void ffestd_exec_begin (void); -void ffestd_exec_end (void); -void ffestd_init_3 (void); -void ffestd_labeldef_any (ffelab label); -void ffestd_labeldef_branch (ffelab label); -void ffestd_labeldef_format (ffelab label); -void ffestd_labeldef_useless (ffelab label); -#if FFESTR_F90 -void ffestd_R423A (void); -void ffestd_R423B (void); -void ffestd_R424 (ffelexToken access, ffestrOther access_kw, ffelexToken name); -void ffestd_R425 (bool ok); -void ffestd_R519_start (ffestrOther intent_kw); -void ffestd_R519_item (ffelexToken name); -void ffestd_R519_finish (void); -void ffestd_R520_start (void); -void ffestd_R520_item (ffelexToken name); -void ffestd_R520_finish (void); -void ffestd_R521A (void); -void ffestd_R521Astart (void); -void ffestd_R521Aitem (ffelexToken name); -void ffestd_R521Afinish (void); -void ffestd_R521B (void); -void ffestd_R521Bstart (void); -void ffestd_R521Bitem (ffelexToken name); -void ffestd_R521Bfinish (void); -#endif -void ffestd_R522 (void); -void ffestd_R522start (void); -void ffestd_R522item_object (ffelexToken name); -void ffestd_R522item_cblock (ffelexToken name); -void ffestd_R522finish (void); -void ffestd_R524_start (bool virtual); -void ffestd_R524_item (ffelexToken name, ffesttDimList dims); -void ffestd_R524_finish (void); -#if FFESTR_F90 -void ffestd_R525_start (void); -void ffestd_R525_item (ffelexToken name, ffesttDimList dims); -void ffestd_R525_finish (void); -void ffestd_R526_start (void); -void ffestd_R526_item (ffelexToken name, ffesttDimList dims); -void ffestd_R526_finish (void); -void ffestd_R527_start (void); -void ffestd_R527_item (ffelexToken name, ffesttDimList dims); -void ffestd_R527_finish (void); -#endif -void ffestd_R537_start (void); -void ffestd_R537_item (ffebld dest, ffebld source); -void ffestd_R537_finish (void); -void ffestd_R539 (void); -void ffestd_R539start (void); -void ffestd_R539item (ffestpType type, ffebld kind, ffelexToken kindt, - ffebld len, ffelexToken lent, ffesttImpList letters); -void ffestd_R539finish (void); -void ffestd_R542_start (void); -void ffestd_R542_item_nlist (ffelexToken name); -void ffestd_R542_item_nitem (ffelexToken name); -void ffestd_R542_finish (void); -void ffestd_R544_start (void); -void ffestd_R544_item (ffesttExprList exprlist); -void ffestd_R544_finish (void); -void ffestd_R547_start (void); -void ffestd_R547_item_object (ffelexToken name, ffesttDimList dims); -void ffestd_R547_item_cblock (ffelexToken name); -void ffestd_R547_finish (void); -#if FFESTR_F90 -void ffestd_R620 (ffesttExprList exprlist, ffebld stat); -void ffestd_R624 (ffesttExprList pointers); -void ffestd_R625 (ffesttExprList exprlist, ffebld stat); -#endif -void ffestd_R737A (ffebld dest, ffebld source); -#if FFESTR_F90 -void ffestd_R737B (ffebld dest, ffebld source); -void ffestd_R738 (ffebld dest, ffebld source); -void ffestd_R740 (ffebld expr); -void ffestd_R742 (ffebld expr); -void ffestd_R744 (void); -void ffestd_R745 (bool ok); -#endif -void ffestd_R803 (ffelexToken construct_name, ffebld expr); -void ffestd_R804 (ffebld expr, ffelexToken name); -void ffestd_R805 (ffelexToken name); -void ffestd_R806 (bool ok); -void ffestd_R807 (ffebld expr); -void ffestd_R809 (ffelexToken construct_name, ffebld expr); -void ffestd_R810 (unsigned long casenum); -void ffestd_R811 (bool ok); -void ffestd_R819A (ffelexToken construct_name, ffelab label, ffebld var, - ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token); -void ffestd_R819B (ffelexToken construct_name, ffelab label, ffebld expr); -void ffestd_R825 (ffelexToken name); -void ffestd_R834 (ffestw block); -void ffestd_R835 (ffestw block); -void ffestd_R836 (ffelab label); -void ffestd_R837 (ffelab *labels, int count, ffebld expr); -void ffestd_R838 (ffelab label, ffebld target); -void ffestd_R839 (ffebld target, ffelab *labels, int count); -void ffestd_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos); -void ffestd_R841 (bool in_where); -void ffestd_R842 (ffebld expr); -void ffestd_R843 (ffebld expr); -void ffestd_R904 (void); -void ffestd_R907 (void); -void ffestd_R909_start (bool only_format, ffestvUnit unit, - ffestvFormat format, bool rec, bool key); -void ffestd_R909_item (ffebld expr, ffelexToken expr_token); -void ffestd_R909_finish (void); -void ffestd_R910_start (ffestvUnit unit, ffestvFormat format, bool rec); -void ffestd_R910_item (ffebld expr, ffelexToken expr_token); -void ffestd_R910_finish (void); -void ffestd_R911_start (ffestvFormat format); -void ffestd_R911_item (ffebld expr, ffelexToken expr_token); -void ffestd_R911_finish (void); -void ffestd_R919 (void); -void ffestd_R920 (void); -void ffestd_R921 (void); -void ffestd_R923A (bool by_file); -void ffestd_R923B_start (void); -void ffestd_R923B_item (ffebld expr); -void ffestd_R923B_finish (void); -void ffestd_R1001 (ffesttFormatList f); -void ffestd_R1102 (ffesymbol s, ffelexToken name); -void ffestd_R1103 (bool ok); -#if FFESTR_F90 -void ffestd_R1105 (ffelexToken name); -void ffestd_R1106 (bool ok); -void ffestd_R1107_start (ffelexToken name, bool only); -void ffestd_R1107_item (ffelexToken local, ffelexToken use); -void ffestd_R1107_finish (void); -#endif -void ffestd_R1111 (ffesymbol s, ffelexToken name); -void ffestd_R1112 (bool ok); -#if FFESTR_F90 -void ffestd_R1202 (ffestpDefinedOperator operator, ffelexToken name); -void ffestd_R1203 (bool ok); -void ffestd_R1205_start (void); -void ffestd_R1205_item (ffelexToken name); -void ffestd_R1205_finish (void); -#endif -void ffestd_R1207_start (void); -void ffestd_R1207_item (ffelexToken name); -void ffestd_R1207_finish (void); -void ffestd_R1208_start (void); -void ffestd_R1208_item (ffelexToken name); -void ffestd_R1208_finish (void); -void ffestd_R1212 (ffebld expr); -#if FFESTR_F90 -void ffestd_R1213 (ffebld dest, ffebld source); -#endif -void ffestd_R1219 (ffesymbol s, ffelexToken funcname, - ffesttTokenList args, ffestpType type, ffebld kind, - ffelexToken kindt, ffebld len, ffelexToken lent, - bool recursive, ffelexToken result, - bool separate_result); -void ffestd_R1221 (bool ok); -void ffestd_R1223 (ffesymbol s, ffelexToken subrname, ffesttTokenList args, - ffelexToken final, bool recursive); -void ffestd_R1225 (bool ok); -void ffestd_R1226 (ffesymbol entry); -void ffestd_R1227 (ffebld expr); -#if FFESTR_F90 -void ffestd_R1228 (void); -#endif -void ffestd_R1229_start (ffelexToken name, ffesttTokenList args); -void ffestd_R1229_finish (ffesymbol s); -void ffestd_S3P4 (ffebld filename); -#if FFESTR_VXT -void ffestd_V003_start (ffelexToken structure_name); -void ffestd_V003_item (ffelexToken name, ffesttDimList dims); -void ffestd_V003_finish (void); -void ffestd_V004 (bool ok); -void ffestd_V009 (void); -void ffestd_V010 (bool ok); -void ffestd_V012 (void); -void ffestd_V013 (bool ok); -#endif -void ffestd_V014_start (void); -void ffestd_V014_item_object (ffelexToken name); -void ffestd_V014_item_cblock (ffelexToken name); -void ffestd_V014_finish (void); -#if FFESTR_VXT -void ffestd_V016_start (void); -void ffestd_V016_item_structure (ffelexToken name); -void ffestd_V016_item_object (ffelexToken name, ffesttDimList dims); -void ffestd_V016_finish (void); -void ffestd_V018_start (ffestvFormat format); -void ffestd_V018_item (ffebld expr); -void ffestd_V018_finish (void); -void ffestd_V019_start (ffestvFormat format); -void ffestd_V019_item (ffebld expr); -void ffestd_V019_finish (void); -#endif -void ffestd_V020_start (ffestvFormat format); -void ffestd_V020_item (ffebld expr); -void ffestd_V020_finish (void); -#if FFESTR_VXT -void ffestd_V021 (void); -void ffestd_V022 (void); -void ffestd_V023_start (void); -void ffestd_V023_item (ffebld expr); -void ffestd_V023_finish (void); -void ffestd_V024_start (void); -void ffestd_V024_item (ffebld expr); -void ffestd_V024_finish (void); -void ffestd_V025_start (void); -void ffestd_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv); -void ffestd_V025_finish (void); -void ffestd_V026 (void); -#endif -void ffestd_V027_start (void); -void ffestd_V027_item (ffelexToken dest_token, ffebld source); -void ffestd_V027_finish (void); -void ffestd_any (void); - -/* Define macros. */ - -#define ffestd_init_0() -#define ffestd_init_1() -#define ffestd_init_2() -#define ffestd_init_4() -#define ffestd_labeldef_notloop(l) ffestd_labeldef_branch(l) -#define ffestd_labeldef_endif(l) ffestd_labeldef_branch(l) -#define ffestd_terminate_0() -#define ffestd_terminate_1() -#define ffestd_terminate_2() -#define ffestd_terminate_3() -#define ffestd_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/ste.c b/gcc/f/ste.c deleted file mode 100755 index 4a2476d..0000000 --- a/gcc/f/ste.c +++ /dev/null @@ -1,5419 +0,0 @@ -/* ste.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - ste.c - - Description: - Implements the various statements and such like. - - Modifications: -*/ - -/* As of 0.5.4, any statement that calls on ffecom to transform an - expression might need to be wrapped in ffecom_push_calltemps () - and ffecom_pop_calltemps () as are some other cases. That is - the case when the transformation might involve generation of - a temporary that must be auto-popped, the specific case being - when a COMPLEX operation requiring a call to libf2c being - generated, whereby a temp is needed to hold the result since - libf2c doesn't return COMPLEX results directly. Cases where it - is known that ffecom_expr () won't need to do this, such as - the CALL statement (where it's the transformation of the - call expr itself that does the wrapping), don't need to bother - with this wrapping. Forgetting to do the wrapping currently - means a crash at an assertion when the wrapping would be helpful - to keep temporaries from being wasted -- see ffecom_push_tempvar. */ - -/* Include files. */ - -#include "proj.h" - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#include "rtl.j" -#include "toplev.j" -#endif - -#include "ste.h" -#include "bld.h" -#include "com.h" -#include "expr.h" -#include "lab.h" -#include "lex.h" -#include "sta.h" -#include "stp.h" -#include "str.h" -#include "sts.h" -#include "stt.h" -#include "stv.h" -#include "stw.h" -#include "symbol.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFESTE_stateletSIMPLE_, /* Expecting simple/start. */ - FFESTE_stateletATTRIB_, /* Expecting attrib/item/itemstart. */ - FFESTE_stateletITEM_, /* Expecting item/itemstart/finish. */ - FFESTE_stateletITEMVALS_, /* Expecting itemvalue/itemendvals. */ - FFESTE_ - } ffesteStatelet_; - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -static ffesteStatelet_ ffeste_statelet_ = FFESTE_stateletSIMPLE_; -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static ffelab ffeste_label_formatdef_ = NULL; -static tree (*ffeste_io_driver_) (ffebld expr); /* do?io. */ -static ffecomGfrt ffeste_io_endgfrt_; /* end function to call. */ -static tree ffeste_io_abort_; /* abort-io label or NULL_TREE. */ -static bool ffeste_io_abort_is_temp_; /* abort-io label is a temp. */ -static tree ffeste_io_end_; /* END= label or NULL_TREE. */ -static tree ffeste_io_err_; /* ERR= label or NULL_TREE. */ -static tree ffeste_io_iostat_; /* IOSTAT= var or NULL_TREE. */ -static bool ffeste_io_iostat_is_temp_; /* IOSTAT= var is a temp. */ -#endif - -/* Static functions (internal). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void ffeste_begin_iterdo_ (ffestw block, tree *tvar, tree *tincr, - tree *xitersvar, ffebld var, - ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token, - char *msg); -static void ffeste_end_iterdo_ (tree tvar, tree tincr, tree itersvar); -static void ffeste_io_call_ (tree call, bool do_check); -static tree ffeste_io_dofio_ (ffebld expr); -static tree ffeste_io_dolio_ (ffebld expr); -static tree ffeste_io_douio_ (ffebld expr); -static tree ffeste_io_ialist_ (bool have_err, ffestvUnit unit, - ffebld unit_expr, int unit_dflt); -static tree ffeste_io_cilist_ (bool have_err, ffestvUnit unit, - ffebld unit_expr, int unit_dflt, - bool have_end, ffestvFormat format, - ffestpFile *format_spec, bool rec, - ffebld rec_expr); -static tree ffeste_io_cllist_ (bool have_err, ffebld unit_expr, - ffestpFile *stat_spec); -static tree ffeste_io_icilist_ (bool have_err, ffebld unit_expr, - bool have_end, ffestvFormat format, - ffestpFile *format_spec); -static void ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token); -static tree ffeste_io_olist_ (bool have_err, ffebld unit_expr, - ffestpFile *file_spec, - ffestpFile *stat_spec, - ffestpFile *access_spec, - ffestpFile *form_spec, - ffestpFile *recl_spec, - ffestpFile *blank_spec); -static void ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt); -#elif FFECOM_targetCURRENT == FFECOM_targetFFE -static void ffeste_subr_file_ (char *kw, ffestpFile *spec); -#else -#error -#endif - -/* Internal macros. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define ffeste_emit_line_note_() \ - emit_line_note (input_filename, lineno) -#endif -#define ffeste_check_simple_() \ - assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_) -#define ffeste_check_start_() \ - assert(ffeste_statelet_ == FFESTE_stateletSIMPLE_); \ - ffeste_statelet_ = FFESTE_stateletATTRIB_ -#define ffeste_check_attrib_() \ - assert(ffeste_statelet_ == FFESTE_stateletATTRIB_) -#define ffeste_check_item_() \ - assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \ - || ffeste_statelet_ == FFESTE_stateletITEM_); \ - ffeste_statelet_ = FFESTE_stateletITEM_ -#define ffeste_check_item_startvals_() \ - assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \ - || ffeste_statelet_ == FFESTE_stateletITEM_); \ - ffeste_statelet_ = FFESTE_stateletITEMVALS_ -#define ffeste_check_item_value_() \ - assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_) -#define ffeste_check_item_endvals_() \ - assert(ffeste_statelet_ == FFESTE_stateletITEMVALS_); \ - ffeste_statelet_ = FFESTE_stateletITEM_ -#define ffeste_check_finish_() \ - assert(ffeste_statelet_ == FFESTE_stateletATTRIB_ \ - || ffeste_statelet_ == FFESTE_stateletITEM_); \ - ffeste_statelet_ = FFESTE_stateletSIMPLE_ - -#define ffeste_f2c_charnolenspec_(Spec,Exp,Init) \ - do \ - { \ - if (Spec->kw_or_val_present) \ - Exp = ffecom_arg_ptr_to_expr(Spec->u.expr,&ignore); \ - else \ - Exp = null_pointer_node; \ - if (TREE_CONSTANT(Exp)) \ - { \ - Init = Exp; \ - Exp = NULL_TREE; \ - } \ - else \ - { \ - Init = null_pointer_node; \ - constantp = FALSE; \ - } \ - } while(0) - -#define ffeste_f2c_charspec_(Spec,Exp,Init,Lenexp,Leninit) \ - do \ - { \ - if (Spec->kw_or_val_present) \ - Exp = ffecom_arg_ptr_to_expr(Spec->u.expr,&Lenexp); \ - else \ - { \ - Exp = null_pointer_node; \ - Lenexp = ffecom_f2c_ftnlen_zero_node; \ - } \ - if (TREE_CONSTANT(Exp)) \ - { \ - Init = Exp; \ - Exp = NULL_TREE; \ - } \ - else \ - { \ - Init = null_pointer_node; \ - constantp = FALSE; \ - } \ - if ((Lenexp != NULL_TREE) && TREE_CONSTANT(Lenexp)) \ - { \ - Leninit = Lenexp; \ - Lenexp = NULL_TREE; \ - } \ - else \ - { \ - Leninit = ffecom_f2c_ftnlen_zero_node; \ - constantp = FALSE; \ - } \ - } while(0) - -#define ffeste_f2c_exp_(Field,Exp) \ - do \ - { \ - if (Exp != NULL_TREE) \ - { \ - Exp = ffecom_modify(void_type_node,ffecom_2(COMPONENT_REF, \ - TREE_TYPE(Field),t,Field),Exp); \ - expand_expr_stmt(Exp); \ - } \ - } while(0) - -#define ffeste_f2c_init_(Init) \ - do \ - { \ - TREE_CHAIN(initn) = build_tree_list((field = TREE_CHAIN(field)),Init); \ - initn = TREE_CHAIN(initn); \ - } while(0) - -#define ffeste_f2c_flagspec_(Flag,Init) \ - do { Init = convert (ffecom_f2c_flag_type_node, \ - Flag ? integer_one_node : integer_zero_node); } \ - while(0) - -#define ffeste_f2c_intspec_(Spec,Exp,Init) \ - do \ - { \ - if (Spec->kw_or_val_present) \ - Exp = ffecom_expr(Spec->u.expr); \ - else \ - Exp = ffecom_integer_zero_node; \ - if (TREE_CONSTANT(Exp)) \ - { \ - Init = Exp; \ - Exp = NULL_TREE; \ - } \ - else \ - { \ - Init = ffecom_integer_zero_node; \ - constantp = FALSE; \ - } \ - } while(0) - -#define ffeste_f2c_ptrtointspec_(Spec,Exp,Init) \ - do \ - { \ - if (Spec->kw_or_val_present) \ - Exp = ffecom_ptr_to_expr(Spec->u.expr); \ - else \ - Exp = null_pointer_node; \ - if (TREE_CONSTANT(Exp)) \ - { \ - Init = Exp; \ - Exp = NULL_TREE; \ - } \ - else \ - { \ - Init = null_pointer_node; \ - constantp = FALSE; \ - } \ - } while(0) - - -/* Begin an iterative DO loop. Pass the block to start if applicable. - - NOTE: Does _two_ push_momentary () calls, which the caller must - undo (by calling ffeste_end_iterdo_). */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffeste_begin_iterdo_ (ffestw block, tree *xtvar, tree *xtincr, - tree *xitersvar, ffebld var, - ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token, - char *msg) -{ - tree tvar; - tree expr; - tree tstart; - tree tend; - tree tincr; - tree tincr_saved; - tree niters; - - push_momentary (); /* Want to save these throughout the loop. */ - - tvar = ffecom_expr_rw (var); - tincr = ffecom_expr (incr); - - /* Check whether incr is known to be zero, complain and fix. */ - - if (integer_zerop (tincr) || real_zerop (tincr)) - { - ffebad_start (FFEBAD_DO_STEP_ZERO); - ffebad_here (0, ffelex_token_where_line (incr_token), - ffelex_token_where_column (incr_token)); - ffebad_string (msg); - ffebad_finish (); - tincr = convert (TREE_TYPE (tvar), integer_one_node); - } - - tincr_saved = ffecom_save_tree (tincr); - - push_momentary (); /* Want to discard the rest after the loop. */ - - tstart = ffecom_expr (start); - tend = ffecom_expr (end); - - { /* For warnings only, nothing else - happens here. */ - tree try; - - if (!ffe_is_onetrip ()) - { - try = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar), - tend, - tstart); - - try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar), - try, - tincr); - - if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE) - try = ffecom_2 (TRUNC_DIV_EXPR, integer_type_node, try, - tincr); - else - try = convert (integer_type_node, - ffecom_2 (RDIV_EXPR, TREE_TYPE (tvar), - try, - tincr)); - - /* Warn if loop never executed, since we've done the evaluation - of the unofficial iteration count already. */ - - try = ffecom_truth_value (ffecom_2 (LE_EXPR, integer_type_node, - try, - convert (TREE_TYPE (tvar), - integer_zero_node))); - - if (integer_onep (try)) - { - ffebad_start (FFEBAD_DO_NULL); - ffebad_here (0, ffelex_token_where_line (start_token), - ffelex_token_where_column (start_token)); - ffebad_string (msg); - ffebad_finish (); - } - } - - /* Warn if end plus incr would overflow. */ - - try = ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar), - tend, - tincr); - - if ((TREE_CODE_CLASS (TREE_CODE (try)) == 'c') - && TREE_CONSTANT_OVERFLOW (try)) - { - ffebad_start (FFEBAD_DO_END_OVERFLOW); - ffebad_here (0, ffelex_token_where_line (end_token), - ffelex_token_where_column (end_token)); - ffebad_string (msg); - ffebad_finish (); - } - } - - /* Do the initial assignment into the DO var. */ - - tstart = ffecom_save_tree (tstart); - - expr = ffecom_2 (MINUS_EXPR, TREE_TYPE (tvar), - tend, - tstart); - - if (!ffe_is_onetrip ()) - { - expr = ffecom_2 (PLUS_EXPR, TREE_TYPE (expr), - expr, - convert (TREE_TYPE (expr), tincr_saved)); - } - - if (TREE_CODE (TREE_TYPE (tvar)) != REAL_TYPE) - expr = ffecom_2 (TRUNC_DIV_EXPR, TREE_TYPE (expr), - expr, - tincr_saved); - else - expr = ffecom_2 (RDIV_EXPR, TREE_TYPE (expr), - expr, - tincr_saved); - -#if 1 /* New, F90-approved approach: convert to default INTEGER. */ - if (TREE_TYPE (tvar) != error_mark_node) - expr = convert (ffecom_integer_type_node, expr); -#else /* Old approach; convert to INTEGER unless that's a narrowing. */ - if ((TREE_TYPE (tvar) != error_mark_node) - && ((TREE_CODE (TREE_TYPE (tvar)) != INTEGER_TYPE) - || ((TYPE_SIZE (TREE_TYPE (tvar)) != NULL_TREE) - && ((TREE_CODE (TYPE_SIZE (TREE_TYPE (tvar))) - != INTEGER_CST) - || (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (tvar))) - <= TREE_INT_CST_LOW (TYPE_SIZE (ffecom_integer_type_node))))))) - /* Convert unless promoting INTEGER type of any kind downward to - default INTEGER; else leave as, say, INTEGER*8 (long long int). */ - expr = convert (ffecom_integer_type_node, expr); -#endif - - niters = ffecom_push_tempvar (TREE_TYPE (expr), - FFETARGET_charactersizeNONE, -1, FALSE); - expr = ffecom_modify (void_type_node, niters, expr); - expand_expr_stmt (expr); - - expr = ffecom_modify (void_type_node, tvar, tstart); - expand_expr_stmt (expr); - - if (block == NULL) - expand_start_loop_continue_elsewhere (0); - else - ffestw_set_do_hook (block, - expand_start_loop_continue_elsewhere (1)); - - if (!ffe_is_onetrip ()) - { - expr = ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - ffecom_2 (PREDECREMENT_EXPR, - TREE_TYPE (niters), - niters, - convert (TREE_TYPE (niters), - ffecom_integer_one_node)), - convert (TREE_TYPE (niters), - ffecom_integer_zero_node))); - - expand_exit_loop_if_false (0, expr); - } - - clear_momentary (); /* Discard the above now that we're done with - DO stmt. */ - - if (block == NULL) - { - *xtvar = tvar; - *xtincr = tincr_saved; - *xitersvar = niters; - } - else - { - ffestw_set_do_tvar (block, tvar); - ffestw_set_do_incr_saved (block, tincr_saved); - ffestw_set_do_count_var (block, niters); - } -} - -#endif - -/* End an iterative DO loop. Pass the same iteration variable and increment - value trees that were generated in the paired _begin_ call. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffeste_end_iterdo_ (tree tvar, tree tincr, tree itersvar) -{ - tree expr; - tree niters = itersvar; - - expand_loop_continue_here (); - - if (ffe_is_onetrip ()) - { - expr = ffecom_truth_value - (ffecom_2 (GE_EXPR, integer_type_node, - ffecom_2 (PREDECREMENT_EXPR, - TREE_TYPE (niters), - niters, - convert (TREE_TYPE (niters), - ffecom_integer_one_node)), - convert (TREE_TYPE (niters), - ffecom_integer_zero_node))); - - expand_exit_loop_if_false (0, expr); - } - - expr = ffecom_modify (void_type_node, tvar, - ffecom_2 (PLUS_EXPR, TREE_TYPE (tvar), - tvar, - tincr)); - expand_expr_stmt (expr); - expand_end_loop (); - - ffecom_pop_tempvar (itersvar); /* Free #iters var. */ - - clear_momentary (); - pop_momentary (); /* Lose the stuff we just built. */ - - clear_momentary (); - pop_momentary (); /* Lose the tvar and incr_saved trees. */ -} - -#endif -/* ffeste_io_call_ -- Generate call to run-time I/O routine - - tree callexpr = build(CALL_EXPR,...); - ffeste_io_call_(callexpr,TRUE); - - Sets TREE_SIDE_EFFECTS(callexpr) = 1. If ffeste_io_iostat_ is not - NULL_TREE, replaces callexpr with "iostat = callexpr;". Expands the - result. If ffeste_io_abort_ is not NULL_TREE and the second argument - is TRUE, generates "if (iostat != 0) goto ffeste_io_abort_;". */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffeste_io_call_ (tree call, bool do_check) -{ - /* Generate the call and optional assignment into iostat var. */ - - TREE_SIDE_EFFECTS (call) = 1; - if (ffeste_io_iostat_ != NULL_TREE) - { - call = ffecom_modify (do_check ? NULL_TREE : void_type_node, - ffeste_io_iostat_, call); - } - expand_expr_stmt (call); - - if (!do_check - || (ffeste_io_abort_ == NULL_TREE) - || (TREE_CODE (ffeste_io_abort_) == ERROR_MARK)) - return; - - /* Generate optional test. */ - - expand_start_cond (ffecom_truth_value (ffeste_io_iostat_), 0); - expand_goto (ffeste_io_abort_); - expand_end_cond (); -} - -#endif -/* ffeste_io_dofio_ -- Generate call to do_fio for formatted I/O item - - ffebld expr; - tree call; - call = ffeste_io_dofio_(expr); - - Returns a tree for a CALL_EXPR to the do_fio function, which handles - a formatted I/O list item, along with the appropriate arguments for - the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag - for the CALL_EXPR, expand (emit) the expression, emit any assignment - of the result to an IOSTAT= variable, and emit any checking of the - result for errors. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_dofio_ (ffebld expr) -{ - tree num_elements; - tree variable; - tree size; - tree arglist; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - bool is_complex; - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - - if ((bt == FFEINFO_basictypeANY) - || (kt == FFEINFO_kindtypeANY)) - return error_mark_node; - - if (bt == FFEINFO_basictypeCOMPLEX) - { - is_complex = TRUE; - bt = FFEINFO_basictypeREAL; - } - else - is_complex = FALSE; - - ffecom_push_calltemps (); - - variable = ffecom_arg_ptr_to_expr (expr, &size); - - if ((variable == error_mark_node) - || (size == error_mark_node)) - { - ffecom_pop_calltemps (); - return error_mark_node; - } - - if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ - { /* "(ftnlen) sizeof(type)" */ - size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); -#if 0 /* Assume that while it is possible that char * is wider than - ftnlen, no object in Fortran space can get big enough for its - size to be wider than ftnlen. I really hope nobody wastes - time debugging a case where it can! */ - assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node) - >= TYPE_PRECISION (TREE_TYPE (size))); -#endif - size = convert (ffecom_f2c_ftnlen_type_node, size); - } - - if ((ffeinfo_rank (ffebld_info (expr)) == 0) - || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)) - num_elements = is_complex ? ffecom_f2c_ftnlen_two_node - : ffecom_f2c_ftnlen_one_node; - else - { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size); - num_elements = size_binop (CEIL_DIV_EXPR, - num_elements, - size_int (TYPE_PRECISION - (char_type_node))); - num_elements = convert (ffecom_f2c_ftnlen_type_node, - num_elements); - } - - num_elements - = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node, - num_elements); - - variable = convert (string_type_node, variable); - - arglist = build_tree_list (NULL_TREE, num_elements); - TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable); - TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size); - - ffecom_pop_calltemps (); - - return ffecom_call_gfrt (FFECOM_gfrtDOFIO, arglist); -} - -#endif -/* ffeste_io_dolio_ -- Generate call to do_lio for list-directed I/O item - - ffebld expr; - tree call; - call = ffeste_io_dolio_(expr); - - Returns a tree for a CALL_EXPR to the do_lio function, which handles - a list-directed I/O list item, along with the appropriate arguments for - the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag - for the CALL_EXPR, expand (emit) the expression, emit any assignment - of the result to an IOSTAT= variable, and emit any checking of the - result for errors. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_dolio_ (ffebld expr) -{ - tree type_id; - tree num_elements; - tree variable; - tree size; - tree arglist; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - int tc; - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - - if ((bt == FFEINFO_basictypeANY) - || (kt == FFEINFO_kindtypeANY)) - return error_mark_node; - - ffecom_push_calltemps (); - - tc = ffecom_f2c_typecode (bt, kt); - assert (tc != -1); - type_id = build_int_2 (tc, 0); - - type_id - = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnint_type_node, - convert (ffecom_f2c_ftnint_type_node, - type_id)); - - variable = ffecom_arg_ptr_to_expr (expr, &size); - - if ((type_id == error_mark_node) - || (variable == error_mark_node) - || (size == error_mark_node)) - { - ffecom_pop_calltemps (); - return error_mark_node; - } - - if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ - { /* "(ftnlen) sizeof(type)" */ - size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); -#if 0 /* Assume that while it is possible that char * is wider than - ftnlen, no object in Fortran space can get big enough for its - size to be wider than ftnlen. I really hope nobody wastes - time debugging a case where it can! */ - assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node) - >= TYPE_PRECISION (TREE_TYPE (size))); -#endif - size = convert (ffecom_f2c_ftnlen_type_node, size); - } - - if ((ffeinfo_rank (ffebld_info (expr)) == 0) - || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)) - num_elements = ffecom_integer_one_node; - else - { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size); - num_elements = size_binop (CEIL_DIV_EXPR, - num_elements, - size_int (TYPE_PRECISION - (char_type_node))); - num_elements = convert (ffecom_f2c_ftnlen_type_node, - num_elements); - } - - num_elements - = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node, - num_elements); - - variable = convert (string_type_node, variable); - - arglist = build_tree_list (NULL_TREE, type_id); - TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, num_elements); - TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, variable); - TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (arglist))) - = build_tree_list (NULL_TREE, size); - - ffecom_pop_calltemps (); - - return ffecom_call_gfrt (FFECOM_gfrtDOLIO, arglist); -} - -#endif -/* ffeste_io_douio_ -- Generate call to do_uio for unformatted I/O item - - ffebld expr; - tree call; - call = ffeste_io_douio_(expr); - - Returns a tree for a CALL_EXPR to the do_uio function, which handles - an unformatted I/O list item, along with the appropriate arguments for - the function. It is up to the caller to set the TREE_SIDE_EFFECTS flag - for the CALL_EXPR, expand (emit) the expression, emit any assignment - of the result to an IOSTAT= variable, and emit any checking of the - result for errors. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_douio_ (ffebld expr) -{ - tree num_elements; - tree variable; - tree size; - tree arglist; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - bool is_complex; - - bt = ffeinfo_basictype (ffebld_info (expr)); - kt = ffeinfo_kindtype (ffebld_info (expr)); - - if ((bt == FFEINFO_basictypeANY) - || (kt == FFEINFO_kindtypeANY)) - return error_mark_node; - - if (bt == FFEINFO_basictypeCOMPLEX) - { - is_complex = TRUE; - bt = FFEINFO_basictypeREAL; - } - else - is_complex = FALSE; - - ffecom_push_calltemps (); - - variable = ffecom_arg_ptr_to_expr (expr, &size); - - if ((variable == error_mark_node) - || (size == error_mark_node)) - { - ffecom_pop_calltemps (); - return error_mark_node; - } - - if (size == NULL_TREE) /* Already filled in for CHARACTER type. */ - { /* "(ftnlen) sizeof(type)" */ - size = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (ffecom_tree_type[bt][kt]), - size_int (TYPE_PRECISION (char_type_node))); -#if 0 /* Assume that while it is possible that char * is wider than - ftnlen, no object in Fortran space can get big enough for its - size to be wider than ftnlen. I really hope nobody wastes - time debugging a case where it can! */ - assert (TYPE_PRECISION (ffecom_f2c_ftnlen_type_node) - >= TYPE_PRECISION (TREE_TYPE (size))); -#endif - size = convert (ffecom_f2c_ftnlen_type_node, size); - } - - if ((ffeinfo_rank (ffebld_info (expr)) == 0) - || (TREE_CODE (TREE_TYPE (TREE_TYPE (variable))) != ARRAY_TYPE)) - num_elements = is_complex ? ffecom_f2c_ftnlen_two_node - : ffecom_f2c_ftnlen_one_node; - else - { - num_elements = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (variable))), size); - num_elements = size_binop (CEIL_DIV_EXPR, num_elements, - size_int (TYPE_PRECISION - (char_type_node))); - num_elements = convert (ffecom_f2c_ftnlen_type_node, - num_elements); - } - - num_elements - = ffecom_1 (ADDR_EXPR, ffecom_f2c_ptr_to_ftnlen_type_node, - num_elements); - - variable = convert (string_type_node, variable); - - arglist = build_tree_list (NULL_TREE, num_elements); - TREE_CHAIN (arglist) = build_tree_list (NULL_TREE, variable); - TREE_CHAIN (TREE_CHAIN (arglist)) = build_tree_list (NULL_TREE, size); - - ffecom_pop_calltemps (); - - return ffecom_call_gfrt (FFECOM_gfrtDOUIO, arglist); -} - -#endif -/* ffeste_io_ialist_ -- Make arglist with ptr to B/E/R control list - - tree arglist; - arglist = ffeste_io_ialist_(...); - - Returns a tree suitable as an argument list containing a pointer to - a BACKSPACE/ENDFILE/REWIND control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_ialist_ (bool have_err, - ffestvUnit unit, - ffebld unit_expr, - int unit_dflt) -{ - static tree f2c_alist_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - bool constantp = TRUE; - static tree errfield, unitfield; - tree errinit, unitinit; - tree unitexp; - static int mynumber = 0; - - if (f2c_alist_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - ffecom_f2c_ftnint_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_alist_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - - switch (unit) - { - case FFESTV_unitNONE: - case FFESTV_unitASTERISK: - unitinit = build_int_2 (unit_dflt, 0); - unitexp = NULL_TREE; - break; - - case FFESTV_unitINTEXPR: - unitexp = ffecom_expr (unit_expr); - if (TREE_CONSTANT (unitexp)) - { - unitinit = unitexp; - unitexp = NULL_TREE; - } - else - { - unitinit = ffecom_integer_zero_node; - constantp = FALSE; - } - break; - - default: - assert ("bad unit spec" == NULL); - unitexp = NULL_TREE; - unitinit = ffecom_integer_zero_node; - break; - } - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_alist_struct)), errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - - inits = build (CONSTRUCTOR, f2c_alist_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_alist_%d", NULL, - mynumber++), - f2c_alist_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_io_cilist_ -- Make arglist with ptr to external I/O control list - - tree arglist; - arglist = ffeste_io_cilist_(...); - - Returns a tree suitable as an argument list containing a pointer to - an external-file I/O control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_cilist_ (bool have_err, - ffestvUnit unit, - ffebld unit_expr, - int unit_dflt, - bool have_end, - ffestvFormat format, - ffestpFile *format_spec, - bool rec, - ffebld rec_expr) -{ - static tree f2c_cilist_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - bool constantp = TRUE; - static tree errfield, unitfield, endfield, formatfield, recfield; - tree errinit, unitinit, endinit, formatinit, recinit; - tree unitexp, formatexp, recexp; - static int mynumber = 0; - - if (f2c_cilist_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - ffecom_f2c_ftnint_type_node); - endfield = ffecom_decl_field (ref, unitfield, "end", - ffecom_f2c_flag_type_node); - formatfield = ffecom_decl_field (ref, endfield, "format", - string_type_node); - recfield = ffecom_decl_field (ref, formatfield, "rec", - ffecom_f2c_ftnint_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_cilist_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - - switch (unit) - { - case FFESTV_unitNONE: - case FFESTV_unitASTERISK: - unitinit = build_int_2 (unit_dflt, 0); - unitexp = NULL_TREE; - break; - - case FFESTV_unitINTEXPR: - unitexp = ffecom_expr (unit_expr); - if (TREE_CONSTANT (unitexp)) - { - unitinit = unitexp; - unitexp = NULL_TREE; - } - else - { - unitinit = ffecom_integer_zero_node; - constantp = FALSE; - } - break; - - default: - assert ("bad unit spec" == NULL); - unitexp = NULL_TREE; - unitinit = ffecom_integer_zero_node; - break; - } - - switch (format) - { - case FFESTV_formatNONE: - formatinit = null_pointer_node; - formatexp = NULL_TREE; - break; - - case FFESTV_formatLABEL: - formatexp = NULL_TREE; - formatinit = ffecom_lookup_label (format_spec->u.label); - if ((formatinit == NULL_TREE) - || (TREE_CODE (formatinit) == ERROR_MARK)) - break; - formatinit = ffecom_1 (ADDR_EXPR, - build_pointer_type (void_type_node), - formatinit); - TREE_CONSTANT (formatinit) = 1; - break; - - case FFESTV_formatCHAREXPR: - formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, NULL); - if (TREE_CONSTANT (formatexp)) - { - formatinit = formatexp; - formatexp = NULL_TREE; - } - else - { - formatinit = null_pointer_node; - constantp = FALSE; - } - break; - - case FFESTV_formatASTERISK: - formatinit = null_pointer_node; - formatexp = NULL_TREE; - break; - - case FFESTV_formatINTEXPR: - formatinit = null_pointer_node; - formatexp = ffecom_expr_assign (format_spec->u.expr); - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp))) - < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) - error ("ASSIGNed FORMAT specifier is too small"); - formatexp = convert (string_type_node, formatexp); - break; - - case FFESTV_formatNAMELIST: - formatinit = ffecom_expr (format_spec->u.expr); - formatexp = NULL_TREE; - break; - - default: - assert ("bad format spec" == NULL); - formatexp = NULL_TREE; - formatinit = integer_zero_node; - break; - } - - ffeste_f2c_flagspec_ (have_end, endinit); - - if (rec) - recexp = ffecom_expr (rec_expr); - else - recexp = ffecom_integer_zero_node; - if (TREE_CONSTANT (recexp)) - { - recinit = recexp; - recexp = NULL_TREE; - } - else - { - recinit = ffecom_integer_zero_node; - constantp = FALSE; - } - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_cilist_struct)), errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - ffeste_f2c_init_ (endinit); - ffeste_f2c_init_ (formatinit); - ffeste_f2c_init_ (recinit); - - inits = build (CONSTRUCTOR, f2c_cilist_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_cilist_%d", NULL, - mynumber++), - f2c_cilist_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - ffeste_f2c_exp_ (formatfield, formatexp); - ffeste_f2c_exp_ (recfield, recexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_io_cllist_ -- Make arglist with ptr to CLOSE control list - - tree arglist; - arglist = ffeste_io_cllist_(...); - - Returns a tree suitable as an argument list containing a pointer to - a CLOSE-statement control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_cllist_ (bool have_err, - ffebld unit_expr, - ffestpFile *stat_spec) -{ - static tree f2c_close_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - tree ignore; /* Ignore length info for certain fields. */ - bool constantp = TRUE; - static tree errfield, unitfield, statfield; - tree errinit, unitinit, statinit; - tree unitexp, statexp; - static int mynumber = 0; - - if (f2c_close_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - ffecom_f2c_ftnint_type_node); - statfield = ffecom_decl_field (ref, unitfield, "stat", - string_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_close_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - - unitexp = ffecom_expr (unit_expr); - if (TREE_CONSTANT (unitexp)) - { - unitinit = unitexp; - unitexp = NULL_TREE; - } - else - { - unitinit = ffecom_integer_zero_node; - constantp = FALSE; - } - - ffeste_f2c_charnolenspec_ (stat_spec, statexp, statinit); - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_close_struct)), errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - ffeste_f2c_init_ (statinit); - - inits = build (CONSTRUCTOR, f2c_close_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_cllist_%d", NULL, - mynumber++), - f2c_close_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - ffeste_f2c_exp_ (statfield, statexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_io_icilist_ -- Make arglist with ptr to internal I/O control list - - tree arglist; - arglist = ffeste_io_icilist_(...); - - Returns a tree suitable as an argument list containing a pointer to - an internal-file I/O control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_icilist_ (bool have_err, - ffebld unit_expr, - bool have_end, - ffestvFormat format, - ffestpFile *format_spec) -{ - static tree f2c_icilist_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - bool constantp = TRUE; - static tree errfield, unitfield, endfield, formatfield, unitlenfield, - unitnumfield; - tree errinit, unitinit, endinit, formatinit, unitleninit, unitnuminit; - tree unitexp, formatexp, unitlenexp, unitnumexp; - static int mynumber = 0; - - if (f2c_icilist_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - string_type_node); - endfield = ffecom_decl_field (ref, unitfield, "end", - ffecom_f2c_flag_type_node); - formatfield = ffecom_decl_field (ref, endfield, "format", - string_type_node); - unitlenfield = ffecom_decl_field (ref, formatfield, "unitlen", - ffecom_f2c_ftnint_type_node); - unitnumfield = ffecom_decl_field (ref, unitlenfield, "unitnum", - ffecom_f2c_ftnint_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_icilist_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - - unitexp = ffecom_arg_ptr_to_expr (unit_expr, &unitlenexp); - if ((ffeinfo_rank (ffebld_info (unit_expr)) == 0) - || (TREE_CODE (TREE_TYPE (TREE_TYPE (unitexp))) != ARRAY_TYPE)) - unitnumexp = ffecom_integer_one_node; - else - { - unitnumexp = size_binop (CEIL_DIV_EXPR, - TYPE_SIZE (TREE_TYPE (TREE_TYPE (unitexp))), unitlenexp); - unitnumexp = size_binop (CEIL_DIV_EXPR, - unitnumexp, size_int (TYPE_PRECISION - (char_type_node))); - } - if (TREE_CONSTANT (unitexp)) - { - unitinit = unitexp; - unitexp = NULL_TREE; - } - else - { - unitinit = null_pointer_node; - constantp = FALSE; - } - if ((unitlenexp != NULL_TREE) && TREE_CONSTANT (unitlenexp)) - { - unitleninit = unitlenexp; - unitlenexp = NULL_TREE; - } - else - { - unitleninit = ffecom_integer_zero_node; - constantp = FALSE; - } - if (TREE_CONSTANT (unitnumexp)) - { - unitnuminit = unitnumexp; - unitnumexp = NULL_TREE; - } - else - { - unitnuminit = ffecom_integer_zero_node; - constantp = FALSE; - } - - switch (format) - { - case FFESTV_formatNONE: - formatinit = null_pointer_node; - formatexp = NULL_TREE; - break; - - case FFESTV_formatLABEL: - formatexp = NULL_TREE; - formatinit = ffecom_lookup_label (format_spec->u.label); - if ((formatinit == NULL_TREE) - || (TREE_CODE (formatinit) == ERROR_MARK)) - break; - formatinit = ffecom_1 (ADDR_EXPR, - build_pointer_type (void_type_node), - formatinit); - TREE_CONSTANT (formatinit) = 1; - break; - - case FFESTV_formatCHAREXPR: - formatexp = ffecom_arg_ptr_to_expr (format_spec->u.expr, NULL); - if (TREE_CONSTANT (formatexp)) - { - formatinit = formatexp; - formatexp = NULL_TREE; - } - else - { - formatinit = null_pointer_node; - constantp = FALSE; - } - break; - - case FFESTV_formatASTERISK: - formatinit = null_pointer_node; - formatexp = NULL_TREE; - break; - - case FFESTV_formatINTEXPR: - formatinit = null_pointer_node; - formatexp = ffecom_expr_assign (format_spec->u.expr); - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (formatexp))) - < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) - error ("ASSIGNed FORMAT specifier is too small"); - formatexp = convert (string_type_node, formatexp); - break; - - default: - assert ("bad format spec" == NULL); - formatexp = NULL_TREE; - formatinit = ffecom_integer_zero_node; - break; - } - - ffeste_f2c_flagspec_ (have_end, endinit); - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_icilist_struct)), - errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - ffeste_f2c_init_ (endinit); - ffeste_f2c_init_ (formatinit); - ffeste_f2c_init_ (unitleninit); - ffeste_f2c_init_ (unitnuminit); - - inits = build (CONSTRUCTOR, f2c_icilist_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_icilist_%d", NULL, - mynumber++), - f2c_icilist_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - ffeste_f2c_exp_ (formatfield, formatexp); - ffeste_f2c_exp_ (unitlenfield, unitlenexp); - ffeste_f2c_exp_ (unitnumfield, unitnumexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_io_impdo_ -- Handle implied-DO in I/O list - - ffebld expr; - ffeste_io_impdo_(expr); - - Expands code to start up the DO loop. Then for each item in the - DO loop, handles appropriately (possibly including recursively calling - itself). Then expands code to end the DO loop. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffeste_io_impdo_ (ffebld impdo, ffelexToken impdo_token) -{ - ffebld var = ffebld_head (ffebld_right (impdo)); - ffebld start = ffebld_head (ffebld_trail (ffebld_right (impdo))); - ffebld end = ffebld_head (ffebld_trail (ffebld_trail - (ffebld_right (impdo)))); - ffebld incr = ffebld_head (ffebld_trail (ffebld_trail - (ffebld_trail (ffebld_right (impdo))))); - ffebld list; /* Used for list of items in left part of - impdo. */ - ffebld item; /* I/O item from head of given list. */ - tree tvar; - tree tincr; - tree titervar; - - if (incr == NULL) - { - incr = ffebld_new_conter (ffebld_constant_new_integerdefault_val (1)); - ffebld_set_info (incr, ffeinfo_new - (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - } - - /* Start the DO loop. */ - - start = ffeexpr_convert_expr (start, impdo_token, var, impdo_token, - FFEEXPR_contextLET); - end = ffeexpr_convert_expr (end, impdo_token, var, impdo_token, - FFEEXPR_contextLET); - incr = ffeexpr_convert_expr (incr, impdo_token, var, impdo_token, - FFEEXPR_contextLET); - - ffeste_begin_iterdo_ (NULL, &tvar, &tincr, &titervar, var, - start, impdo_token, - end, impdo_token, - incr, impdo_token, - "Implied DO loop"); - - /* Handle the list of items. */ - - for (list = ffebld_left (impdo); list != NULL; list = ffebld_trail (list)) - { - item = ffebld_head (list); - if (item == NULL) - continue; - while (ffebld_op (item) == FFEBLD_opPAREN) - item = ffebld_left (item); - if (ffebld_op (item) == FFEBLD_opANY) - continue; - if (ffebld_op (item) == FFEBLD_opIMPDO) - ffeste_io_impdo_ (item, impdo_token); - else - ffeste_io_call_ ((*ffeste_io_driver_) (item), TRUE); - clear_momentary (); - } - - /* Generate end of implied-do construct. */ - - ffeste_end_iterdo_ (tvar, tincr, titervar); -} - -#endif -/* ffeste_io_inlist_ -- Make arglist with ptr to INQUIRE control list - - tree arglist; - arglist = ffeste_io_inlist_(...); - - Returns a tree suitable as an argument list containing a pointer to - an INQUIRE-statement control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_inlist_ (bool have_err, - ffestpFile *unit_spec, - ffestpFile *file_spec, - ffestpFile *exist_spec, - ffestpFile *open_spec, - ffestpFile *number_spec, - ffestpFile *named_spec, - ffestpFile *name_spec, - ffestpFile *access_spec, - ffestpFile *sequential_spec, - ffestpFile *direct_spec, - ffestpFile *form_spec, - ffestpFile *formatted_spec, - ffestpFile *unformatted_spec, - ffestpFile *recl_spec, - ffestpFile *nextrec_spec, - ffestpFile *blank_spec) -{ - static tree f2c_inquire_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - bool constantp = TRUE; - static tree errfield, unitfield, filefield, filelenfield, existfield, - openfield, numberfield, namedfield, namefield, namelenfield, accessfield, - accesslenfield, sequentialfield, sequentiallenfield, directfield, directlenfield, - formfield, formlenfield, formattedfield, formattedlenfield, unformattedfield, - unformattedlenfield, reclfield, nextrecfield, blankfield, blanklenfield; - tree errinit, unitinit, fileinit, fileleninit, existinit, openinit, numberinit, - namedinit, nameinit, nameleninit, accessinit, accessleninit, sequentialinit, - sequentialleninit, directinit, directleninit, forminit, formleninit, - formattedinit, formattedleninit, unformattedinit, unformattedleninit, - reclinit, nextrecinit, blankinit, blankleninit; - tree - unitexp, fileexp, filelenexp, existexp, openexp, numberexp, namedexp, - nameexp, namelenexp, accessexp, accesslenexp, sequentialexp, sequentiallenexp, - directexp, directlenexp, formexp, formlenexp, formattedexp, formattedlenexp, - unformattedexp, unformattedlenexp, reclexp, nextrecexp, blankexp, blanklenexp; - static int mynumber = 0; - - if (f2c_inquire_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - ffecom_f2c_ftnint_type_node); - filefield = ffecom_decl_field (ref, unitfield, "file", - string_type_node); - filelenfield = ffecom_decl_field (ref, filefield, "filelen", - ffecom_f2c_ftnlen_type_node); - existfield = ffecom_decl_field (ref, filelenfield, "exist", - ffecom_f2c_ptr_to_ftnint_type_node); - openfield = ffecom_decl_field (ref, existfield, "open", - ffecom_f2c_ptr_to_ftnint_type_node); - numberfield = ffecom_decl_field (ref, openfield, "number", - ffecom_f2c_ptr_to_ftnint_type_node); - namedfield = ffecom_decl_field (ref, numberfield, "named", - ffecom_f2c_ptr_to_ftnint_type_node); - namefield = ffecom_decl_field (ref, namedfield, "name", - string_type_node); - namelenfield = ffecom_decl_field (ref, namefield, "namelen", - ffecom_f2c_ftnlen_type_node); - accessfield = ffecom_decl_field (ref, namelenfield, "access", - string_type_node); - accesslenfield = ffecom_decl_field (ref, accessfield, "accesslen", - ffecom_f2c_ftnlen_type_node); - sequentialfield = ffecom_decl_field (ref, accesslenfield, "sequential", - string_type_node); - sequentiallenfield = ffecom_decl_field (ref, sequentialfield, - "sequentiallen", - ffecom_f2c_ftnlen_type_node); - directfield = ffecom_decl_field (ref, sequentiallenfield, "direct", - string_type_node); - directlenfield = ffecom_decl_field (ref, directfield, "directlen", - ffecom_f2c_ftnlen_type_node); - formfield = ffecom_decl_field (ref, directlenfield, "form", - string_type_node); - formlenfield = ffecom_decl_field (ref, formfield, "formlen", - ffecom_f2c_ftnlen_type_node); - formattedfield = ffecom_decl_field (ref, formlenfield, "formatted", - string_type_node); - formattedlenfield = ffecom_decl_field (ref, formattedfield, - "formattedlen", - ffecom_f2c_ftnlen_type_node); - unformattedfield = ffecom_decl_field (ref, formattedlenfield, - "unformatted", - string_type_node); - unformattedlenfield = ffecom_decl_field (ref, unformattedfield, - "unformattedlen", - ffecom_f2c_ftnlen_type_node); - reclfield = ffecom_decl_field (ref, unformattedlenfield, "recl", - ffecom_f2c_ptr_to_ftnint_type_node); - nextrecfield = ffecom_decl_field (ref, reclfield, "nextrec", - ffecom_f2c_ptr_to_ftnint_type_node); - blankfield = ffecom_decl_field (ref, nextrecfield, "blank", - string_type_node); - blanklenfield = ffecom_decl_field (ref, blankfield, "blanklen", - ffecom_f2c_ftnlen_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_inquire_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - ffeste_f2c_intspec_ (unit_spec, unitexp, unitinit); - ffeste_f2c_charspec_ (file_spec, fileexp, fileinit, filelenexp, fileleninit); - ffeste_f2c_ptrtointspec_ (exist_spec, existexp, existinit); - ffeste_f2c_ptrtointspec_ (open_spec, openexp, openinit); - ffeste_f2c_ptrtointspec_ (number_spec, numberexp, numberinit); - ffeste_f2c_ptrtointspec_ (named_spec, namedexp, namedinit); - ffeste_f2c_charspec_ (name_spec, nameexp, nameinit, namelenexp, nameleninit); - ffeste_f2c_charspec_ (access_spec, accessexp, accessinit, accesslenexp, - accessleninit); - ffeste_f2c_charspec_ (sequential_spec, sequentialexp, sequentialinit, - sequentiallenexp, sequentialleninit); - ffeste_f2c_charspec_ (direct_spec, directexp, directinit, directlenexp, - directleninit); - ffeste_f2c_charspec_ (form_spec, formexp, forminit, formlenexp, formleninit); - ffeste_f2c_charspec_ (formatted_spec, formattedexp, formattedinit, - formattedlenexp, formattedleninit); - ffeste_f2c_charspec_ (unformatted_spec, unformattedexp, unformattedinit, - unformattedlenexp, unformattedleninit); - ffeste_f2c_ptrtointspec_ (recl_spec, reclexp, reclinit); - ffeste_f2c_ptrtointspec_ (nextrec_spec, nextrecexp, nextrecinit); - ffeste_f2c_charspec_ (blank_spec, blankexp, blankinit, blanklenexp, - blankleninit); - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_inquire_struct)), - errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - ffeste_f2c_init_ (fileinit); - ffeste_f2c_init_ (fileleninit); - ffeste_f2c_init_ (existinit); - ffeste_f2c_init_ (openinit); - ffeste_f2c_init_ (numberinit); - ffeste_f2c_init_ (namedinit); - ffeste_f2c_init_ (nameinit); - ffeste_f2c_init_ (nameleninit); - ffeste_f2c_init_ (accessinit); - ffeste_f2c_init_ (accessleninit); - ffeste_f2c_init_ (sequentialinit); - ffeste_f2c_init_ (sequentialleninit); - ffeste_f2c_init_ (directinit); - ffeste_f2c_init_ (directleninit); - ffeste_f2c_init_ (forminit); - ffeste_f2c_init_ (formleninit); - ffeste_f2c_init_ (formattedinit); - ffeste_f2c_init_ (formattedleninit); - ffeste_f2c_init_ (unformattedinit); - ffeste_f2c_init_ (unformattedleninit); - ffeste_f2c_init_ (reclinit); - ffeste_f2c_init_ (nextrecinit); - ffeste_f2c_init_ (blankinit); - ffeste_f2c_init_ (blankleninit); - - inits = build (CONSTRUCTOR, f2c_inquire_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_inlist_%d", NULL, - mynumber++), - f2c_inquire_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - ffeste_f2c_exp_ (filefield, fileexp); - ffeste_f2c_exp_ (filelenfield, filelenexp); - ffeste_f2c_exp_ (existfield, existexp); - ffeste_f2c_exp_ (openfield, openexp); - ffeste_f2c_exp_ (numberfield, numberexp); - ffeste_f2c_exp_ (namedfield, namedexp); - ffeste_f2c_exp_ (namefield, nameexp); - ffeste_f2c_exp_ (namelenfield, namelenexp); - ffeste_f2c_exp_ (accessfield, accessexp); - ffeste_f2c_exp_ (accesslenfield, accesslenexp); - ffeste_f2c_exp_ (sequentialfield, sequentialexp); - ffeste_f2c_exp_ (sequentiallenfield, sequentiallenexp); - ffeste_f2c_exp_ (directfield, directexp); - ffeste_f2c_exp_ (directlenfield, directlenexp); - ffeste_f2c_exp_ (formfield, formexp); - ffeste_f2c_exp_ (formlenfield, formlenexp); - ffeste_f2c_exp_ (formattedfield, formattedexp); - ffeste_f2c_exp_ (formattedlenfield, formattedlenexp); - ffeste_f2c_exp_ (unformattedfield, unformattedexp); - ffeste_f2c_exp_ (unformattedlenfield, unformattedlenexp); - ffeste_f2c_exp_ (reclfield, reclexp); - ffeste_f2c_exp_ (nextrecfield, nextrecexp); - ffeste_f2c_exp_ (blankfield, blankexp); - ffeste_f2c_exp_ (blanklenfield, blanklenexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_io_olist_ -- Make arglist with ptr to OPEN control list - - tree arglist; - arglist = ffeste_io_olist_(...); - - Returns a tree suitable as an argument list containing a pointer to - an OPEN-statement control list. First, generates that control - list, if necessary, along with any static and run-time initializations - that are needed as specified by the arguments to this function. */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static tree -ffeste_io_olist_ (bool have_err, - ffebld unit_expr, - ffestpFile *file_spec, - ffestpFile *stat_spec, - ffestpFile *access_spec, - ffestpFile *form_spec, - ffestpFile *recl_spec, - ffestpFile *blank_spec) -{ - static tree f2c_open_struct = NULL_TREE; - tree t; - tree ttype; - int yes; - tree field; - tree inits, initn; - tree ignore; /* Ignore length info for certain fields. */ - bool constantp = TRUE; - static tree errfield, unitfield, filefield, filelenfield, statfield, - accessfield, formfield, reclfield, blankfield; - tree errinit, unitinit, fileinit, fileleninit, statinit, accessinit, - forminit, reclinit, blankinit; - tree - unitexp, fileexp, filelenexp, statexp, accessexp, formexp, reclexp, - blankexp; - static int mynumber = 0; - - if (f2c_open_struct == NULL_TREE) - { - tree ref; - - push_obstacks_nochange (); - end_temporary_allocation (); - - ref = make_node (RECORD_TYPE); - - errfield = ffecom_decl_field (ref, NULL_TREE, "err", - ffecom_f2c_flag_type_node); - unitfield = ffecom_decl_field (ref, errfield, "unit", - ffecom_f2c_ftnint_type_node); - filefield = ffecom_decl_field (ref, unitfield, "file", - string_type_node); - filelenfield = ffecom_decl_field (ref, filefield, "filelen", - ffecom_f2c_ftnlen_type_node); - statfield = ffecom_decl_field (ref, filelenfield, "stat", - string_type_node); - accessfield = ffecom_decl_field (ref, statfield, "access", - string_type_node); - formfield = ffecom_decl_field (ref, accessfield, "form", - string_type_node); - reclfield = ffecom_decl_field (ref, formfield, "recl", - ffecom_f2c_ftnint_type_node); - blankfield = ffecom_decl_field (ref, reclfield, "blank", - string_type_node); - - TYPE_FIELDS (ref) = errfield; - layout_type (ref); - - resume_temporary_allocation (); - pop_obstacks (); - - f2c_open_struct = ref; - } - - ffeste_f2c_flagspec_ (have_err, errinit); - - unitexp = ffecom_expr (unit_expr); - if (TREE_CONSTANT (unitexp)) - { - unitinit = unitexp; - unitexp = NULL_TREE; - } - else - { - unitinit = ffecom_integer_zero_node; - constantp = FALSE; - } - - ffeste_f2c_charspec_ (file_spec, fileexp, fileinit, filelenexp, fileleninit); - ffeste_f2c_charnolenspec_ (stat_spec, statexp, statinit); - ffeste_f2c_charnolenspec_ (access_spec, accessexp, accessinit); - ffeste_f2c_charnolenspec_ (form_spec, formexp, forminit); - ffeste_f2c_intspec_ (recl_spec, reclexp, reclinit); - ffeste_f2c_charnolenspec_ (blank_spec, blankexp, blankinit); - - inits = build_tree_list ((field = TYPE_FIELDS (f2c_open_struct)), errinit); - initn = inits; - ffeste_f2c_init_ (unitinit); - ffeste_f2c_init_ (fileinit); - ffeste_f2c_init_ (fileleninit); - ffeste_f2c_init_ (statinit); - ffeste_f2c_init_ (accessinit); - ffeste_f2c_init_ (forminit); - ffeste_f2c_init_ (reclinit); - ffeste_f2c_init_ (blankinit); - - inits = build (CONSTRUCTOR, f2c_open_struct, NULL_TREE, inits); - TREE_CONSTANT (inits) = constantp ? 1 : 0; - TREE_STATIC (inits) = 1; - - yes = suspend_momentary (); - - t = build_decl (VAR_DECL, - ffecom_get_invented_identifier ("__g77_olist_%d", NULL, - mynumber++), - f2c_open_struct); - TREE_STATIC (t) = 1; - t = ffecom_start_decl (t, 1); - ffecom_finish_decl (t, inits, 0); - - resume_momentary (yes); - - ffeste_f2c_exp_ (unitfield, unitexp); - ffeste_f2c_exp_ (filefield, fileexp); - ffeste_f2c_exp_ (filelenfield, filelenexp); - ffeste_f2c_exp_ (statfield, statexp); - ffeste_f2c_exp_ (accessfield, accessexp); - ffeste_f2c_exp_ (formfield, formexp); - ffeste_f2c_exp_ (reclfield, reclexp); - ffeste_f2c_exp_ (blankfield, blankexp); - - ttype = build_pointer_type (TREE_TYPE (t)); - t = ffecom_1 (ADDR_EXPR, ttype, t); - - t = build_tree_list (NULL_TREE, t); - - return t; -} - -#endif -/* ffeste_subr_file_ -- Display file-statement specifier - - ffeste_subr_file_(&specifier); */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -static void -ffeste_subr_file_ (char *kw, ffestpFile *spec) -{ - if (!spec->kw_or_val_present) - return; - fputs (kw, dmpout); - if (spec->value_present) - { - fputc ('=', dmpout); - if (spec->value_is_label) - { - assert (spec->value_is_label == 2); /* Temporary checking only. */ - fprintf (dmpout, "%" ffelabValue_f "u", - ffelab_value (spec->u.label)); - } - else - ffebld_dump (spec->u.expr); - } - fputc (',', dmpout); -} -#endif - -/* ffeste_subr_beru_ -- Generate code for BACKSPACE/ENDFILE/REWIND - - ffeste_subr_beru_(FFECOM_gfrtFBACK); */ - -#if FFECOM_targetCURRENT == FFECOM_targetGCC -static void -ffeste_subr_beru_ (ffestpBeruStmt *info, ffecomGfrt rt) -{ - tree alist; - bool iostat; - bool errl; - -#define specified(something) (info->beru_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - /* Do the real work. */ - - iostat = specified (FFESTP_beruixIOSTAT); - errl = specified (FFESTP_beruixERR); - - /* ~~For now, we assume the unit number is specified and is not ASTERISK, - because the FFE doesn't support BACKSPACE(*) and rejects a BACKSPACE - without any unit specifier. f2c, however, supports the former - construct. When it is time to add this feature to the FFE, which - probably is fairly easy, ffestc_R919 and company will want to pass an - ffestvUnit indicator of FFESTV_unitINTEXPR or _unitASTERISK to - ffeste_R919 and company, and they will want to pass that same value to - this function, and that argument will replace the constant _unitINTEXPR_ - in the call below. Right now, the default unit number, 6, is ignored. */ - - ffecom_push_calltemps (); - - alist = ffeste_io_ialist_ (errl || iostat, FFESTV_unitINTEXPR, - info->beru_spec[FFESTP_beruixUNIT].u.expr, 6); - - if (errl) - { /* ERR= */ - ffeste_io_err_ - = ffeste_io_abort_ - = ffecom_lookup_label - (info->beru_spec[FFESTP_beruixERR].u.label); - ffeste_io_abort_is_temp_ = FALSE; - } - else - { /* no ERR= */ - ffeste_io_err_ = NULL_TREE; - - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->beru_spec[FFESTP_beruixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, or ERR= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (rt, alist), - !ffeste_io_abort_is_temp_); - - /* If we've got a temp label, generate its code here. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - assert (ffeste_io_err_ == NULL_TREE); - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - -#undef specified - - clear_momentary (); -} - -#endif -/* ffeste_do -- End of statement following DO-term-stmt etc - - ffeste_do(TRUE); - - Also invoked by _labeldef_branch_finish_ (or, in cases - of errors, other _labeldef_ functions) when the label definition is - for a DO-target (LOOPEND) label, once per matching/outstanding DO - block on the stack. These cases invoke this function with ok==TRUE, so - only forced stack popping (via ffeste_eof_()) invokes it with ok==FALSE. */ - -void -ffeste_do (ffestw block) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_DO\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - if (ffestw_do_tvar (block) == 0) - expand_end_loop (); /* DO WHILE and just DO. */ - else - ffeste_end_iterdo_ (ffestw_do_tvar (block), - ffestw_do_incr_saved (block), - ffestw_do_count_var (block)); - - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_end_R807 -- End of statement following logical IF - - ffeste_end_R807(TRUE); - - Applies ONLY to logical IF, not to IF-THEN. For example, does not - ffelex_token_kill the construct name for an IF-THEN block (the name - field is invalid for logical IF). ok==TRUE iff statement following - logical IF (substatement) is valid; else, statement is invalid or - stack forcibly popped due to ffeste_eof_(). */ - -void -ffeste_end_R807 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_IF\n", dmpout); /* Also see ffeste_R806. */ -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - expand_end_cond (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_labeldef_branch -- Generate "code" for branch label def - - ffeste_labeldef_branch(label); */ - -void -ffeste_labeldef_branch (ffelab label) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ label %lu\n", ffelab_value (label)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree glabel; - - glabel = ffecom_lookup_label (label); - assert (glabel != NULL_TREE); - if (TREE_CODE (glabel) == ERROR_MARK) - return; - assert (DECL_INITIAL (glabel) == NULL_TREE); - DECL_INITIAL (glabel) = error_mark_node; - DECL_SOURCE_FILE (glabel) = ffelab_definition_filename (label); - DECL_SOURCE_LINE (glabel) = ffelab_definition_filelinenum (label); - emit_nop (); - expand_label (glabel); - } -#else -#error -#endif -} - -/* ffeste_labeldef_format -- Generate "code" for FORMAT label def - - ffeste_labeldef_format(label); */ - -void -ffeste_labeldef_format (ffelab label) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "$ label %lu\n", ffelab_value (label)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_label_formatdef_ = label; -#else -#error -#endif -} - -/* ffeste_R737A -- Assignment statement outside of WHERE - - ffeste_R737A(dest_expr,source_expr); */ - -void -ffeste_R737A (ffebld dest, ffebld source) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ let ", dmpout); - ffebld_dump (dest); - fputs ("=", dmpout); - ffebld_dump (source); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - ffecom_expand_let_stmt (dest, source); - - ffecom_pop_calltemps (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R803 -- Block IF (IF-THEN) statement - - ffeste_R803(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffeste_R803 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ IF_block (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - expand_start_cond (ffecom_truth_value (ffecom_expr (expr)), 0); - - ffecom_pop_calltemps (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R804 -- ELSE IF statement - - ffeste_R804(expr,expr_token,name_token); - - Make sure ffeste_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the else - of the IF block. */ - -void -ffeste_R804 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ ELSE_IF (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - expand_start_elseif (ffecom_truth_value (ffecom_expr (expr))); - - ffecom_pop_calltemps (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R805 -- ELSE statement - - ffeste_R805(name_token); - - Make sure ffeste_kind_ identifies an IF block. If not - NULL, make sure name_token gives the correct name. Implement the ELSE - of the IF block. */ - -void -ffeste_R805 () -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ ELSE\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - expand_start_else (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R806 -- End an IF-THEN - - ffeste_R806(TRUE); */ - -void -ffeste_R806 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_IF_then\n", dmpout); /* Also see ffeste_shriek_if_. */ -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - expand_end_cond (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R807 -- Logical IF statement - - ffeste_R807(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffeste_R807 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ IF_logical (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - expand_start_cond (ffecom_truth_value (ffecom_expr (expr)), 0); - - ffecom_pop_calltemps (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R809 -- SELECT CASE statement - - ffeste_R809(construct_name,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffeste_R809 (ffestw block, ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ SELECT_CASE (", dmpout); - ffebld_dump (expr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffecom_push_calltemps (); - - { - tree texpr; - - ffeste_emit_line_note_ (); - - if ((expr == NULL) - || (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeANY)) - { - ffestw_set_select_texpr (block, error_mark_node); - clear_momentary (); - } - else - { - texpr = ffecom_expr (expr); - if (ffeinfo_basictype (ffebld_info (expr)) - != FFEINFO_basictypeCHARACTER) - { - expand_start_case (1, texpr, TREE_TYPE (texpr), - "SELECT CASE statement"); - ffestw_set_select_texpr (block, texpr); - ffestw_set_select_break (block, FALSE); - push_momentary (); - } - else - { - ffebad_start_msg ("SELECT CASE on CHARACTER type (at %0) not supported -- sorry", - FFEBAD_severityFATAL); - ffebad_here (0, ffestw_line (block), ffestw_col (block)); - ffebad_finish (); - ffestw_set_select_texpr (block, error_mark_node); - } - } - } - - ffecom_pop_calltemps (); -#else -#error -#endif -} - -/* ffeste_R810 -- CASE statement - - ffeste_R810(case_value_range_list,name); - - If casenum is 0, it's CASE DEFAULT. Else it's the case ranges at - the start of the first_stmt list in the select object at the top of - the stack that match casenum. */ - -void -ffeste_R810 (ffestw block, unsigned long casenum) -{ - ffestwSelect s = ffestw_select (block); - ffestwCase c; - - ffeste_check_simple_ (); - - if (s->first_stmt == (ffestwCase) &s->first_rel) - c = NULL; - else - c = s->first_stmt; - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if ((c == NULL) || (casenum != c->casenum)) - { - if (casenum == 0) /* Intentional CASE DEFAULT. */ - fputs ("+ CASE_DEFAULT", dmpout); - } - else - { - bool comma = FALSE; - - fputs ("+ CASE (", dmpout); - do - { - if (comma) - fputc (',', dmpout); - else - comma = TRUE; - if (c->low != NULL) - ffebld_constant_dump (c->low); - if (c->low != c->high) - { - fputc (':', dmpout); - if (c->high != NULL) - ffebld_constant_dump (c->high); - } - c = c->next_stmt; - /* Unlink prev. */ - c->previous_stmt->previous_stmt->next_stmt = c; - c->previous_stmt = c->previous_stmt->previous_stmt; - } - while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum)); - fputc (')', dmpout); - } - - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree texprlow; - tree texprhigh; - tree tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - int pushok; - tree duplicate; - - ffeste_emit_line_note_ (); - - if (TREE_CODE (ffestw_select_texpr (block)) == ERROR_MARK) - { - clear_momentary (); - return; - } - - if (ffestw_select_break (block)) - expand_exit_something (); - else - ffestw_set_select_break (block, TRUE); - - if ((c == NULL) || (casenum != c->casenum)) - { - if (casenum == 0) /* Intentional CASE DEFAULT. */ - { - pushok = pushcase (NULL_TREE, 0, tlabel, &duplicate); - assert (pushok == 0); - } - } - else - do - { - texprlow = (c->low == NULL) ? NULL_TREE - : ffecom_constantunion (&ffebld_constant_union (c->low), s->type, - s->kindtype, ffecom_tree_type[s->type][s->kindtype]); - if (c->low != c->high) - { - texprhigh = (c->high == NULL) ? NULL_TREE - : ffecom_constantunion (&ffebld_constant_union (c->high), - s->type, s->kindtype, ffecom_tree_type[s->type][s->kindtype]); - pushok = pushcase_range (texprlow, texprhigh, convert, - tlabel, &duplicate); - } - else - pushok = pushcase (texprlow, convert, tlabel, &duplicate); - assert (pushok == 0); - c = c->next_stmt; - /* Unlink prev. */ - c->previous_stmt->previous_stmt->next_stmt = c; - c->previous_stmt = c->previous_stmt->previous_stmt; - } - while ((c != (ffestwCase) &s->first_rel) && (casenum == c->casenum)); - - clear_momentary (); - } /* ~~~handle character, character*1 */ -#else -#error -#endif -} - -/* ffeste_R811 -- End a SELECT - - ffeste_R811(TRUE); */ - -void -ffeste_R811 (ffestw block) -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_SELECT\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - - if (TREE_CODE (ffestw_select_texpr (block)) == ERROR_MARK) - { - clear_momentary (); - return; - } - - expand_end_case (ffestw_select_texpr (block)); - pop_momentary (); - clear_momentary (); /* ~~~handle character and character*1 */ -#else -#error -#endif -} - -/* Iterative DO statement. */ - -void -ffeste_R819A (ffestw block, ffelab label UNUSED, ffebld var, - ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if ((ffebld_op (incr) == FFEBLD_opCONTER) - && (ffebld_constant_is_zero (ffebld_conter (incr)))) - { - ffebad_start (FFEBAD_DO_STEP_ZERO); - ffebad_here (0, ffelex_token_where_line (incr_token), - ffelex_token_where_column (incr_token)); - ffebad_string ("Iterative DO loop"); - ffebad_finish (); - /* Don't bother replacing it with 1 yet. */ - } - - if (label == NULL) - fputs ("+ DO_iterative_nonlabeled (", dmpout); - else - fprintf (dmpout, "+ DO_iterative_labeled %lu (", ffelab_value (label)); - ffebld_dump (var); - fputc ('=', dmpout); - ffebld_dump (start); - fputc (',', dmpout); - ffebld_dump (end); - fputc (',', dmpout); - ffebld_dump (incr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - /* Start the DO loop. */ - - ffeste_begin_iterdo_ (block, NULL, NULL, NULL, - var, - start, start_token, - end, end_token, - incr, incr_token, - "Iterative DO loop"); - - ffecom_pop_calltemps (); - } -#else -#error -#endif -} - -/* ffeste_R819B -- DO WHILE statement - - ffeste_R819B(construct_name,label_token,expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffeste_R819B (ffestw block, ffelab label UNUSED, ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (label == NULL) - fputs ("+ DO_WHILE_nonlabeled (", dmpout); - else - fprintf (dmpout, "+ DO_WHILE_labeled %lu (", ffelab_value (label)); - ffebld_dump (expr); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - ffestw_set_do_hook (block, expand_start_loop (1)); - ffestw_set_do_tvar (block, 0); /* Means DO WHILE vs. iter DO. */ - if (expr != NULL) - expand_exit_loop_if_false (0, ffecom_truth_value (ffecom_expr (expr))); - - ffecom_pop_calltemps (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R825 -- END DO statement - - ffeste_R825(name_token); - - Make sure ffeste_kind_ identifies a DO block. If not - NULL, make sure name_token gives the correct name. Do whatever - is specific to seeing END DO with a DO-target label definition on it, - where the END DO is really treated as a CONTINUE (i.e. generate th - same code you would for CONTINUE). ffeste_do handles the actual - generation of end-loop code. */ - -void -ffeste_R825 () -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_DO_sugar\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - emit_nop (); -#else -#error -#endif -} - -/* ffeste_R834 -- CYCLE statement - - ffeste_R834(name_token); - - Handle a CYCLE within a loop. */ - -void -ffeste_R834 (ffestw block) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ CYCLE block #%lu\n", ffestw_blocknum (block)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - expand_continue_loop (ffestw_do_hook (block)); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R835 -- EXIT statement - - ffeste_R835(name_token); - - Handle a EXIT within a loop. */ - -void -ffeste_R835 (ffestw block) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ EXIT block #%lu\n", ffestw_blocknum (block)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - expand_exit_loop (ffestw_do_hook (block)); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R836 -- GOTO statement - - ffeste_R836(label); - - Make sure label_token identifies a valid label for a GOTO. Update - that label's info to indicate it is the target of a GOTO. */ - -void -ffeste_R836 (ffelab label) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ GOTO %lu\n", ffelab_value (label)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree glabel; - - ffeste_emit_line_note_ (); - glabel = ffecom_lookup_label (label); - if ((glabel != NULL_TREE) - && (TREE_CODE (glabel) != ERROR_MARK)) - { - TREE_USED (glabel) = 1; - expand_goto (glabel); - clear_momentary (); - } - } -#else -#error -#endif -} - -/* ffeste_R837 -- Computed GOTO statement - - ffeste_R837(labels,count,expr); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffeste_R837 (ffelab *labels, int count, ffebld expr) -{ - int i; - - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ CGOTO (", dmpout); - for (i = 0; i < count; ++i) - { - if (i != 0) - fputc (',', dmpout); - fprintf (dmpout, "%" ffelabValue_f "u", ffelab_value (labels[i])); - } - fputs ("),", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree texpr; - tree value; - tree tlabel; - int pushok; - tree duplicate; - - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - texpr = ffecom_expr (expr); - expand_start_case (0, texpr, TREE_TYPE (texpr), "computed GOTO statement"); - push_momentary (); /* In case of lots of labels, keep clearing - them out. */ - for (i = 0; i < count; ++i) - { - value = build_int_2 (i + 1, 0); - tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - pushok = pushcase (value, convert, tlabel, &duplicate); - assert (pushok == 0); - tlabel = ffecom_lookup_label (labels[i]); - if ((tlabel == NULL_TREE) - || (TREE_CODE (tlabel) == ERROR_MARK)) - continue; - TREE_USED (tlabel) = 1; - expand_goto (tlabel); - clear_momentary (); - } - pop_momentary (); - expand_end_case (texpr); - - ffecom_pop_calltemps (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R838 -- ASSIGN statement - - ffeste_R838(label_token,target_variable,target_token); - - Make sure label_token identifies a valid label for an assignment. Update - that label's info to indicate it is the source of an assignment. Update - target_variable's info to indicate it is the target the assignment of that - label. */ - -void -ffeste_R838 (ffelab label, ffebld target) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ ASSIGN %lu TO ", ffelab_value (label)); - ffebld_dump (target); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree expr_tree; - tree label_tree; - tree target_tree; - - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - label_tree = ffecom_lookup_label (label); - if ((label_tree != NULL_TREE) - && (TREE_CODE (label_tree) != ERROR_MARK)) - { - label_tree = ffecom_1 (ADDR_EXPR, - build_pointer_type (void_type_node), - label_tree); - TREE_CONSTANT (label_tree) = 1; - target_tree = ffecom_expr_assign_w (target); - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (target_tree))) - < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (label_tree)))) - error ("ASSIGN to variable that is too small"); - label_tree = convert (TREE_TYPE (target_tree), label_tree); - expr_tree = ffecom_modify (void_type_node, - target_tree, - label_tree); - expand_expr_stmt (expr_tree); - clear_momentary (); - } - - ffecom_pop_calltemps (); - } -#else -#error -#endif -} - -/* ffeste_R839 -- Assigned GOTO statement - - ffeste_R839(target,target_token,label_list); - - Make sure label_list identifies valid labels for a GOTO. Update - each label's info to indicate it is the target of a GOTO. */ - -void -ffeste_R839 (ffebld target) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ AGOTO ", dmpout); - ffebld_dump (target); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree t; - - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - t = ffecom_expr_assign (target); - if (GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (t))) - < GET_MODE_SIZE (TYPE_MODE (TREE_TYPE (null_pointer_node)))) - error ("ASSIGNed GOTO target variable is too small"); - expand_computed_goto (convert (TREE_TYPE (null_pointer_node), t)); - - ffecom_pop_calltemps (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R840 -- Arithmetic IF statement - - ffeste_R840(expr,expr_token,neg,zero,pos); - - Make sure the labels are valid; implement. */ - -void -ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ IF_arithmetic (", dmpout); - ffebld_dump (expr); - fprintf (dmpout, ") %" ffelabValue_f "u,%" ffelabValue_f "u,%" ffelabValue_f "u\n", - ffelab_value (neg), ffelab_value (zero), ffelab_value (pos)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree gneg = ffecom_lookup_label (neg); - tree gzero = ffecom_lookup_label (zero); - tree gpos = ffecom_lookup_label (pos); - tree texpr; - - if ((gneg == NULL_TREE) || (gzero == NULL_TREE) || (gpos == NULL_TREE)) - return; - if ((TREE_CODE (gneg) == ERROR_MARK) - || (TREE_CODE (gzero) == ERROR_MARK) - || (TREE_CODE (gpos) == ERROR_MARK)) - return; - - ffecom_push_calltemps (); - - if (neg == zero) - { - if (neg == pos) - expand_goto (gzero); - else - { /* IF (expr.LE.0) THEN GOTO neg/zero ELSE - GOTO pos. */ - texpr = ffecom_expr (expr); - texpr = ffecom_2 (LE_EXPR, integer_type_node, - texpr, - convert (TREE_TYPE (texpr), - integer_zero_node)); - expand_start_cond (ffecom_truth_value (texpr), 0); - expand_goto (gzero); - expand_start_else (); - expand_goto (gpos); - expand_end_cond (); - } - } - else if (neg == pos) - { /* IF (expr.NE.0) THEN GOTO neg/pos ELSE GOTO - zero. */ - texpr = ffecom_expr (expr); - texpr = ffecom_2 (NE_EXPR, integer_type_node, - texpr, - convert (TREE_TYPE (texpr), - integer_zero_node)); - expand_start_cond (ffecom_truth_value (texpr), 0); - expand_goto (gneg); - expand_start_else (); - expand_goto (gzero); - expand_end_cond (); - } - else if (zero == pos) - { /* IF (expr.GE.0) THEN GOTO zero/pos ELSE - GOTO neg. */ - texpr = ffecom_expr (expr); - texpr = ffecom_2 (GE_EXPR, integer_type_node, - texpr, - convert (TREE_TYPE (texpr), - integer_zero_node)); - expand_start_cond (ffecom_truth_value (texpr), 0); - expand_goto (gzero); - expand_start_else (); - expand_goto (gneg); - expand_end_cond (); - } - else - { /* Use a SAVE_EXPR in combo with: - IF (expr.LT.0) THEN GOTO neg - ELSEIF (expr.GT.0) THEN GOTO pos - ELSE GOTO zero. */ - tree expr_saved = ffecom_save_tree (ffecom_expr (expr)); - - texpr = ffecom_2 (LT_EXPR, integer_type_node, - expr_saved, - convert (TREE_TYPE (expr_saved), - integer_zero_node)); - expand_start_cond (ffecom_truth_value (texpr), 0); - expand_goto (gneg); - texpr = ffecom_2 (GT_EXPR, integer_type_node, - expr_saved, - convert (TREE_TYPE (expr_saved), - integer_zero_node)); - expand_start_elseif (ffecom_truth_value (texpr)); - expand_goto (gpos); - expand_start_else (); - expand_goto (gzero); - expand_end_cond (); - } - ffeste_emit_line_note_ (); - - ffecom_pop_calltemps (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R841 -- CONTINUE statement - - ffeste_R841(); */ - -void -ffeste_R841 () -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ CONTINUE\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_emit_line_note_ (); - emit_nop (); -#else -#error -#endif -} - -/* ffeste_R842 -- STOP statement - - ffeste_R842(expr); */ - -void -ffeste_R842 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (expr == NULL) - { - fputs ("+ STOP\n", dmpout); - } - else - { - fputs ("+ STOP_coded ", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); - } -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree callit; - ffelexToken msg; - - ffeste_emit_line_note_ (); - if ((expr == NULL) - || (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeANY)) - { - msg = ffelex_token_new_character ("", ffelex_token_where_line - (ffesta_tokens[0]), ffelex_token_where_column - (ffesta_tokens[0])); - expr = ffebld_new_conter (ffebld_constant_new_characterdefault - (msg)); - ffelex_token_kill (msg); - ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, 0)); - } - else if (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeINTEGER) - { - char num[50]; - - assert (ffebld_op (expr) == FFEBLD_opCONTER); - assert (ffeinfo_kindtype (ffebld_info (expr)) - == FFEINFO_kindtypeINTEGERDEFAULT); - sprintf (num, "%" ffetargetIntegerDefault_f "d", - ffebld_constant_integer1 (ffebld_conter (expr))); - msg = ffelex_token_new_character (num, ffelex_token_where_line - (ffesta_tokens[0]), ffelex_token_where_column - (ffesta_tokens[0])); - expr = ffebld_new_conter (ffebld_constant_new_characterdefault - (msg)); - ffelex_token_kill (msg); - ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, 0)); - } - else - { - assert (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeCHARACTER); - assert (ffebld_op (expr) == FFEBLD_opCONTER); - assert (ffeinfo_kindtype (ffebld_info (expr)) - == FFEINFO_kindtypeCHARACTERDEFAULT); - } - - ffecom_push_calltemps (); - callit = ffecom_call_gfrt (FFECOM_gfrtSTOP, - ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL))); - ffecom_pop_calltemps (); - TREE_SIDE_EFFECTS (callit) = 1; - expand_expr_stmt (callit); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R843 -- PAUSE statement - - ffeste_R843(expr,expr_token); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffeste_R843 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (expr == NULL) - { - fputs ("+ PAUSE\n", dmpout); - } - else - { - fputs ("+ PAUSE_coded ", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); - } -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree callit; - ffelexToken msg; - - ffeste_emit_line_note_ (); - if ((expr == NULL) - || (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeANY)) - { - msg = ffelex_token_new_character ("", ffelex_token_where_line - (ffesta_tokens[0]), ffelex_token_where_column - (ffesta_tokens[0])); - expr = ffebld_new_conter (ffebld_constant_new_characterdefault - (msg)); - ffelex_token_kill (msg); - ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, 0)); - } - else if (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeINTEGER) - { - char num[50]; - - assert (ffebld_op (expr) == FFEBLD_opCONTER); - assert (ffeinfo_kindtype (ffebld_info (expr)) - == FFEINFO_kindtypeINTEGERDEFAULT); - sprintf (num, "%" ffetargetIntegerDefault_f "d", - ffebld_constant_integer1 (ffebld_conter (expr))); - msg = ffelex_token_new_character (num, ffelex_token_where_line - (ffesta_tokens[0]), ffelex_token_where_column - (ffesta_tokens[0])); - expr = ffebld_new_conter (ffebld_constant_new_characterdefault - (msg)); - ffelex_token_kill (msg); - ffebld_set_info (expr, ffeinfo_new (FFEINFO_basictypeCHARACTER, - FFEINFO_kindtypeCHARACTERDEFAULT, 0, FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, 0)); - } - else - { - assert (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeCHARACTER); - assert (ffebld_op (expr) == FFEBLD_opCONTER); - assert (ffeinfo_kindtype (ffebld_info (expr)) - == FFEINFO_kindtypeCHARACTERDEFAULT); - } - - ffecom_push_calltemps (); - callit = ffecom_call_gfrt (FFECOM_gfrtPAUSE, - ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL))); - ffecom_pop_calltemps (); - TREE_SIDE_EFFECTS (callit) = 1; - expand_expr_stmt (callit); - clear_momentary (); - } -#if 0 /* Old approach for phantom g77 run-time - library. */ - { - tree callit; - - ffeste_emit_line_note_ (); - if (expr == NULL) - callit = ffecom_call_gfrt (FFECOM_gfrtPAUSENIL, NULL_TREE); - else if (ffeinfo_basictype (ffebld_info (expr)) - == FFEINFO_basictypeINTEGER) - { - ffecom_push_calltemps (); - callit = ffecom_call_gfrt (FFECOM_gfrtPAUSEINT, - ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL))); - ffecom_pop_calltemps (); - } - else - { - if (ffeinfo_basictype (ffebld_info (expr)) - != FFEINFO_basictypeCHARACTER) - break; - ffecom_push_calltemps (); - callit = ffecom_call_gfrt (FFECOM_gfrtPAUSECHAR, - ffecom_list_ptr_to_expr (ffebld_new_item (expr, NULL))); - ffecom_pop_calltemps (); - } - TREE_SIDE_EFFECTS (callit) = 1; - expand_expr_stmt (callit); - clear_momentary (); - } -#endif -#else -#error -#endif -} - -/* ffeste_R904 -- OPEN statement - - ffeste_R904(); - - Make sure an OPEN is valid in the current context, and implement it. */ - -void -ffeste_R904 (ffestpOpenStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ OPEN (", dmpout); - ffeste_subr_file_ ("UNIT", &info->open_spec[FFESTP_openixUNIT]); - ffeste_subr_file_ ("ACCESS", &info->open_spec[FFESTP_openixACCESS]); - ffeste_subr_file_ ("ACTION", &info->open_spec[FFESTP_openixACTION]); - ffeste_subr_file_ ("ASSOCIATEVARIABLE", &info->open_spec[FFESTP_openixASSOCIATEVARIABLE]); - ffeste_subr_file_ ("BLANK", &info->open_spec[FFESTP_openixBLANK]); - ffeste_subr_file_ ("BLOCKSIZE", &info->open_spec[FFESTP_openixBLOCKSIZE]); - ffeste_subr_file_ ("BUFFERCOUNT", &info->open_spec[FFESTP_openixBUFFERCOUNT]); - ffeste_subr_file_ ("CARRIAGECONTROL", &info->open_spec[FFESTP_openixCARRIAGECONTROL]); - ffeste_subr_file_ ("DEFAULTFILE", &info->open_spec[FFESTP_openixDEFAULTFILE]); - ffeste_subr_file_ ("DELIM", &info->open_spec[FFESTP_openixDELIM]); - ffeste_subr_file_ ("DISPOSE", &info->open_spec[FFESTP_openixDISPOSE]); - ffeste_subr_file_ ("ERR", &info->open_spec[FFESTP_openixERR]); - ffeste_subr_file_ ("EXTENDSIZE", &info->open_spec[FFESTP_openixEXTENDSIZE]); - ffeste_subr_file_ ("FILE", &info->open_spec[FFESTP_openixFILE]); - ffeste_subr_file_ ("FORM", &info->open_spec[FFESTP_openixFORM]); - ffeste_subr_file_ ("INITIALSIZE", &info->open_spec[FFESTP_openixINITIALSIZE]); - ffeste_subr_file_ ("IOSTAT", &info->open_spec[FFESTP_openixIOSTAT]); - ffeste_subr_file_ ("KEY", &info->open_spec[FFESTP_openixKEY]); - ffeste_subr_file_ ("MAXREC", &info->open_spec[FFESTP_openixMAXREC]); - ffeste_subr_file_ ("NOSPANBLOCKS", &info->open_spec[FFESTP_openixNOSPANBLOCKS]); - ffeste_subr_file_ ("ORGANIZATION", &info->open_spec[FFESTP_openixORGANIZATION]); - ffeste_subr_file_ ("PAD", &info->open_spec[FFESTP_openixPAD]); - ffeste_subr_file_ ("POSITION", &info->open_spec[FFESTP_openixPOSITION]); - ffeste_subr_file_ ("READONLY", &info->open_spec[FFESTP_openixREADONLY]); - ffeste_subr_file_ ("RECL", &info->open_spec[FFESTP_openixRECL]); - ffeste_subr_file_ ("RECORDTYPE", &info->open_spec[FFESTP_openixRECORDTYPE]); - ffeste_subr_file_ ("SHARED", &info->open_spec[FFESTP_openixSHARED]); - ffeste_subr_file_ ("STATUS", &info->open_spec[FFESTP_openixSTATUS]); - ffeste_subr_file_ ("USEROPEN", &info->open_spec[FFESTP_openixUSEROPEN]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree args; - bool iostat; - bool errl; - -#define specified(something) (info->open_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - iostat = specified (FFESTP_openixIOSTAT); - errl = specified (FFESTP_openixERR); - - ffecom_push_calltemps (); - - args = ffeste_io_olist_ (errl || iostat, - info->open_spec[FFESTP_openixUNIT].u.expr, - &info->open_spec[FFESTP_openixFILE], - &info->open_spec[FFESTP_openixSTATUS], - &info->open_spec[FFESTP_openixACCESS], - &info->open_spec[FFESTP_openixFORM], - &info->open_spec[FFESTP_openixRECL], - &info->open_spec[FFESTP_openixBLANK]); - - if (errl) - { - ffeste_io_err_ - = ffeste_io_abort_ - = ffecom_lookup_label - (info->open_spec[FFESTP_openixERR].u.label); - ffeste_io_abort_is_temp_ = FALSE; - } - else - { - ffeste_io_err_ = NULL_TREE; - - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->open_spec[FFESTP_openixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, or ERR= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFOPEN, args), - !ffeste_io_abort_is_temp_); - - /* If we've got a temp label, generate its code here. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - assert (ffeste_io_err_ == NULL_TREE); - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - -#undef specified - } - - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R907 -- CLOSE statement - - ffeste_R907(); - - Make sure a CLOSE is valid in the current context, and implement it. */ - -void -ffeste_R907 (ffestpCloseStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ CLOSE (", dmpout); - ffeste_subr_file_ ("UNIT", &info->close_spec[FFESTP_closeixUNIT]); - ffeste_subr_file_ ("ERR", &info->close_spec[FFESTP_closeixERR]); - ffeste_subr_file_ ("IOSTAT", &info->close_spec[FFESTP_closeixIOSTAT]); - ffeste_subr_file_ ("STATUS", &info->close_spec[FFESTP_closeixSTATUS]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree args; - bool iostat; - bool errl; - -#define specified(something) (info->close_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - iostat = specified (FFESTP_closeixIOSTAT); - errl = specified (FFESTP_closeixERR); - - ffecom_push_calltemps (); - - args = ffeste_io_cllist_ (errl || iostat, - info->close_spec[FFESTP_closeixUNIT].u.expr, - &info->close_spec[FFESTP_closeixSTATUS]); - - if (errl) - { - ffeste_io_err_ - = ffeste_io_abort_ - = ffecom_lookup_label - (info->close_spec[FFESTP_closeixERR].u.label); - ffeste_io_abort_is_temp_ = FALSE; - } - else - { - ffeste_io_err_ = NULL_TREE; - - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->close_spec[FFESTP_closeixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, or ERR= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFCLOS, args), - !ffeste_io_abort_is_temp_); - - /* If we've got a temp label, generate its code here. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - assert (ffeste_io_err_ == NULL_TREE); - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - -#undef specified - } - - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R909_start -- READ(...) statement list begin - - ffeste_R909_start(FALSE); - - Verify that READ is valid here, and begin accepting items in the - list. */ - -void -ffeste_R909_start (ffestpReadStmt *info, bool only_format UNUSED, - ffestvUnit unit, ffestvFormat format, bool rec, - bool key UNUSED) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatNONE: - if (rec) - fputs ("+ READ_ufdac", dmpout); - else if (key) - fputs ("+ READ_ufidx", dmpout); - else - fputs ("+ READ_ufseq", dmpout); - break; - - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - if (rec) - fputs ("+ READ_fmdac", dmpout); - else if (key) - fputs ("+ READ_fmidx", dmpout); - else if (unit == FFESTV_unitCHAREXPR) - fputs ("+ READ_fmint", dmpout); - else - fputs ("+ READ_fmseq", dmpout); - break; - - case FFESTV_formatASTERISK: - if (unit == FFESTV_unitCHAREXPR) - fputs ("+ READ_lsint", dmpout); - else - fputs ("+ READ_lsseq", dmpout); - break; - - case FFESTV_formatNAMELIST: - fputs ("+ READ_nlseq", dmpout); - break; - - default: - assert ("Unexpected kind of format item in R909 READ" == NULL); - } - - if (only_format) - { - fputc (' ', dmpout); - ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]); - fputc (' ', dmpout); - - return; - } - - fputs (" (", dmpout); - ffeste_subr_file_ ("UNIT", &info->read_spec[FFESTP_readixUNIT]); - ffeste_subr_file_ ("FORMAT", &info->read_spec[FFESTP_readixFORMAT]); - ffeste_subr_file_ ("ADVANCE", &info->read_spec[FFESTP_readixADVANCE]); - ffeste_subr_file_ ("EOR", &info->read_spec[FFESTP_readixEOR]); - ffeste_subr_file_ ("ERR", &info->read_spec[FFESTP_readixERR]); - ffeste_subr_file_ ("END", &info->read_spec[FFESTP_readixEND]); - ffeste_subr_file_ ("IOSTAT", &info->read_spec[FFESTP_readixIOSTAT]); - ffeste_subr_file_ ("KEYEQ", &info->read_spec[FFESTP_readixKEYEQ]); - ffeste_subr_file_ ("KEYGE", &info->read_spec[FFESTP_readixKEYGE]); - ffeste_subr_file_ ("KEYGT", &info->read_spec[FFESTP_readixKEYGT]); - ffeste_subr_file_ ("KEYID", &info->read_spec[FFESTP_readixKEYID]); - ffeste_subr_file_ ("NULLS", &info->read_spec[FFESTP_readixNULLS]); - ffeste_subr_file_ ("REC", &info->read_spec[FFESTP_readixREC]); - ffeste_subr_file_ ("SIZE", &info->read_spec[FFESTP_readixSIZE]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - -#define specified(something) (info->read_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - /* Do the real work. */ - - { - ffecomGfrt start; - ffecomGfrt end; - tree cilist; - bool iostat; - bool errl; - bool endl; - - /* First determine the start, per-item, and end run-time functions to - call. The per-item function is picked by choosing an ffeste functio - to call to handle a given item; it knows how to generate a call to the - appropriate run-time function, and is called an "io driver". It - handles the implied-DO construct, for example. */ - - switch (format) - { - case FFESTV_formatNONE: /* no FMT= */ - ffeste_io_driver_ = ffeste_io_douio_; - if (rec) - start = FFECOM_gfrtSRDUE, end = FFECOM_gfrtERDUE; -#if 0 - else if (key) - start = FFECOM_gfrtSRIUE, end = FFECOM_gfrtERIUE; -#endif - else - start = FFECOM_gfrtSRSUE, end = FFECOM_gfrtERSUE; - break; - - case FFESTV_formatLABEL: /* FMT=10 */ - case FFESTV_formatCHAREXPR: /* FMT='(I10)' */ - case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */ - ffeste_io_driver_ = ffeste_io_dofio_; - if (rec) - start = FFECOM_gfrtSRDFE, end = FFECOM_gfrtERDFE; -#if 0 - else if (key) - start = FFECOM_gfrtSRIFE, end = FFECOM_gfrtERIFE; -#endif - else if (unit == FFESTV_unitCHAREXPR) - start = FFECOM_gfrtSRSFI, end = FFECOM_gfrtERSFI; - else - start = FFECOM_gfrtSRSFE, end = FFECOM_gfrtERSFE; - break; - - case FFESTV_formatASTERISK: /* FMT=* */ - ffeste_io_driver_ = ffeste_io_dolio_; - if (unit == FFESTV_unitCHAREXPR) - start = FFECOM_gfrtSRSLI, end = FFECOM_gfrtERSLI; - else - start = FFECOM_gfrtSRSLE, end = FFECOM_gfrtERSLE; - break; - - case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST - /FOO/] */ - ffeste_io_driver_ = NULL; /* No start or driver function. */ - start = FFECOM_gfrtSRSNE, end = FFECOM_gfrt; - break; - - default: - assert ("Weird stuff" == NULL); - start = FFECOM_gfrt, end = FFECOM_gfrt; - break; - } - ffeste_io_endgfrt_ = end; - - iostat = specified (FFESTP_readixIOSTAT); - errl = specified (FFESTP_readixERR); - endl = specified (FFESTP_readixEND); - - ffecom_push_calltemps (); - - if (unit == FFESTV_unitCHAREXPR) - { - cilist = ffeste_io_icilist_ (errl || iostat, - info->read_spec[FFESTP_readixUNIT].u.expr, - endl || iostat, format, - &info->read_spec[FFESTP_readixFORMAT]); - } - else - { - cilist = ffeste_io_cilist_ (errl || iostat, unit, - info->read_spec[FFESTP_readixUNIT].u.expr, - 5, endl || iostat, format, - &info->read_spec[FFESTP_readixFORMAT], - rec, - info->read_spec[FFESTP_readixREC].u.expr); - } - - if (errl) - { /* ERR= */ - ffeste_io_err_ - = ffecom_lookup_label - (info->read_spec[FFESTP_readixERR].u.label); - - if (endl) - { /* ERR= END= */ - ffeste_io_end_ - = ffecom_lookup_label - (info->read_spec[FFESTP_readixEND].u.label); - ffeste_io_abort_is_temp_ = TRUE; - ffeste_io_abort_ = ffecom_temp_label (); - } - else - { /* ERR= but no END= */ - ffeste_io_end_ = NULL_TREE; - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = ffeste_io_err_; - } - } - else - { /* no ERR= */ - ffeste_io_err_ = NULL_TREE; - if (endl) - { /* END= but no ERR= */ - ffeste_io_end_ - = ffecom_lookup_label - (info->read_spec[FFESTP_readixEND].u.label); - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = ffeste_io_end_; - } - else - { /* no ERR= or END= */ - ffeste_io_end_ = NULL_TREE; - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->read_spec[FFESTP_readixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= or END= or both */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, ERR=, or END= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* If there is no end function, then there are no item functions (i.e. - it's a NAMELIST), and vice versa by the way. In this situation, don't - generate the "if (iostat != 0) goto label;" if the label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (start, cilist), - !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt)); - } - -#undef specified - - push_momentary (); -#else -#error -#endif -} - -/* ffeste_R909_item -- READ statement i/o item - - ffeste_R909_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_R909_item (ffebld expr, ffelexToken expr_token) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - if (expr == NULL) - return; - while (ffebld_op (expr) == FFEBLD_opPAREN) - expr = ffebld_left (expr); /* "READ *,(A)" -- really a bug in the user's - code, but I've been told lots of code does - this (blech)! */ - if (ffebld_op (expr) == FFEBLD_opANY) - return; - if (ffebld_op (expr) == FFEBLD_opIMPDO) - ffeste_io_impdo_ (expr, expr_token); - else - ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R909_finish -- READ statement list complete - - ffeste_R909_finish(); - - Just wrap up any local activities. */ - -void -ffeste_R909_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - { - if (ffeste_io_endgfrt_ != FFECOM_gfrt) - ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE), - !ffeste_io_abort_is_temp_); - - clear_momentary (); - pop_momentary (); - - /* If we've got a temp label, generate its code here and have it fan out - to the END= or ERR= label as appropriate. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - /* if (iostat<0) goto end_label; */ - - if ((ffeste_io_end_ != NULL_TREE) - && (TREE_CODE (ffeste_io_end_) != ERROR_MARK)) - { - expand_start_cond (ffecom_truth_value - (ffecom_2 (LT_EXPR, integer_type_node, - ffeste_io_iostat_, - ffecom_integer_zero_node)), - 0); - expand_goto (ffeste_io_end_); - expand_end_cond (); - } - - /* if (iostat>0) goto err_label; */ - - if ((ffeste_io_err_ != NULL_TREE) - && (TREE_CODE (ffeste_io_err_) != ERROR_MARK)) - { - expand_start_cond (ffecom_truth_value - (ffecom_2 (GT_EXPR, integer_type_node, - ffeste_io_iostat_, - ffecom_integer_zero_node)), - 0); - expand_goto (ffeste_io_err_); - expand_end_cond (); - } - - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R910_start -- WRITE(...) statement list begin - - ffeste_R910_start(); - - Verify that WRITE is valid here, and begin accepting items in the - list. */ - -void -ffeste_R910_start (ffestpWriteStmt *info, ffestvUnit unit, - ffestvFormat format, bool rec) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatNONE: - if (rec) - fputs ("+ WRITE_ufdac (", dmpout); - else - fputs ("+ WRITE_ufseq_or_idx (", dmpout); - break; - - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - if (rec) - fputs ("+ WRITE_fmdac (", dmpout); - else if (unit == FFESTV_unitCHAREXPR) - fputs ("+ WRITE_fmint (", dmpout); - else - fputs ("+ WRITE_fmseq_or_idx (", dmpout); - break; - - case FFESTV_formatASTERISK: - if (unit == FFESTV_unitCHAREXPR) - fputs ("+ WRITE_lsint (", dmpout); - else - fputs ("+ WRITE_lsseq (", dmpout); - break; - - case FFESTV_formatNAMELIST: - fputs ("+ WRITE_nlseq (", dmpout); - break; - - default: - assert ("Unexpected kind of format item in R910 WRITE" == NULL); - } - - ffeste_subr_file_ ("UNIT", &info->write_spec[FFESTP_writeixUNIT]); - ffeste_subr_file_ ("FORMAT", &info->write_spec[FFESTP_writeixFORMAT]); - ffeste_subr_file_ ("ADVANCE", &info->write_spec[FFESTP_writeixADVANCE]); - ffeste_subr_file_ ("EOR", &info->write_spec[FFESTP_writeixEOR]); - ffeste_subr_file_ ("ERR", &info->write_spec[FFESTP_writeixERR]); - ffeste_subr_file_ ("IOSTAT", &info->write_spec[FFESTP_writeixIOSTAT]); - ffeste_subr_file_ ("REC", &info->write_spec[FFESTP_writeixREC]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - -#define specified(something) (info->write_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - /* Do the real work. */ - - { - ffecomGfrt start; - ffecomGfrt end; - tree cilist; - bool iostat; - bool errl; - - /* First determine the start, per-item, and end run-time functions to - call. The per-item function is picked by choosing an ffeste functio - to call to handle a given item; it knows how to generate a call to the - appropriate run-time function, and is called an "io driver". It - handles the implied-DO construct, for example. */ - - switch (format) - { - case FFESTV_formatNONE: /* no FMT= */ - ffeste_io_driver_ = ffeste_io_douio_; - if (rec) - start = FFECOM_gfrtSWDUE, end = FFECOM_gfrtEWDUE; - else - start = FFECOM_gfrtSWSUE, end = FFECOM_gfrtEWSUE; - break; - - case FFESTV_formatLABEL: /* FMT=10 */ - case FFESTV_formatCHAREXPR: /* FMT='(I10)' */ - case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */ - ffeste_io_driver_ = ffeste_io_dofio_; - if (rec) - start = FFECOM_gfrtSWDFE, end = FFECOM_gfrtEWDFE; - else if (unit == FFESTV_unitCHAREXPR) - start = FFECOM_gfrtSWSFI, end = FFECOM_gfrtEWSFI; - else - start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE; - break; - - case FFESTV_formatASTERISK: /* FMT=* */ - ffeste_io_driver_ = ffeste_io_dolio_; - if (unit == FFESTV_unitCHAREXPR) - start = FFECOM_gfrtSWSLI, end = FFECOM_gfrtEWSLI; - else - start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE; - break; - - case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST - /FOO/] */ - ffeste_io_driver_ = NULL; /* No start or driver function. */ - start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt; - break; - - default: - assert ("Weird stuff" == NULL); - start = FFECOM_gfrt, end = FFECOM_gfrt; - break; - } - ffeste_io_endgfrt_ = end; - - iostat = specified (FFESTP_writeixIOSTAT); - errl = specified (FFESTP_writeixERR); - - ffecom_push_calltemps (); - - if (unit == FFESTV_unitCHAREXPR) - { - cilist = ffeste_io_icilist_ (errl || iostat, - info->write_spec[FFESTP_writeixUNIT].u.expr, - FALSE, format, - &info->write_spec[FFESTP_writeixFORMAT]); - } - else - { - cilist = ffeste_io_cilist_ (errl || iostat, unit, - info->write_spec[FFESTP_writeixUNIT].u.expr, - 6, FALSE, format, - &info->write_spec[FFESTP_writeixFORMAT], - rec, - info->write_spec[FFESTP_writeixREC].u.expr); - } - - ffeste_io_end_ = NULL_TREE; - - if (errl) - { /* ERR= */ - ffeste_io_err_ - = ffeste_io_abort_ - = ffecom_lookup_label - (info->write_spec[FFESTP_writeixERR].u.label); - ffeste_io_abort_is_temp_ = FALSE; - } - else - { /* no ERR= */ - ffeste_io_err_ = NULL_TREE; - - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->write_spec[FFESTP_writeixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, or ERR= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* If there is no end function, then there are no item functions (i.e. - it's a NAMELIST), and vice versa by the way. In this situation, don't - generate the "if (iostat != 0) goto label;" if the label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (start, cilist), - !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt)); - } - -#undef specified - - push_momentary (); -#else -#error -#endif -} - -/* ffeste_R910_item -- WRITE statement i/o item - - ffeste_R910_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_R910_item (ffebld expr, ffelexToken expr_token) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - if (expr == NULL) - return; - if (ffebld_op (expr) == FFEBLD_opANY) - return; - if (ffebld_op (expr) == FFEBLD_opIMPDO) - ffeste_io_impdo_ (expr, expr_token); - else - ffeste_io_call_ ((*ffeste_io_driver_) (expr), TRUE); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R910_finish -- WRITE statement list complete - - ffeste_R910_finish(); - - Just wrap up any local activities. */ - -void -ffeste_R910_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - { - if (ffeste_io_endgfrt_ != FFECOM_gfrt) - ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE), - !ffeste_io_abort_is_temp_); - - clear_momentary (); - pop_momentary (); - - /* If we've got a temp label, generate its code here. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - assert (ffeste_io_err_ == NULL_TREE); - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R911_start -- PRINT statement list begin - - ffeste_R911_start(); - - Verify that PRINT is valid here, and begin accepting items in the - list. */ - -void -ffeste_R911_start (ffestpPrintStmt *info, ffestvFormat format) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - fputs ("+ PRINT_fm ", dmpout); - break; - - case FFESTV_formatASTERISK: - fputs ("+ PRINT_ls ", dmpout); - break; - - case FFESTV_formatNAMELIST: - fputs ("+ PRINT_nl ", dmpout); - break; - - default: - assert ("Unexpected kind of format item in R911 PRINT" == NULL); - } - ffeste_subr_file_ ("FORMAT", &info->print_spec[FFESTP_printixFORMAT]); - fputc (' ', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - - ffeste_emit_line_note_ (); - - /* Do the real work. */ - - { - ffecomGfrt start; - ffecomGfrt end; - tree cilist; - - /* First determine the start, per-item, and end run-time functions to - call. The per-item function is picked by choosing an ffeste functio - to call to handle a given item; it knows how to generate a call to the - appropriate run-time function, and is called an "io driver". It - handles the implied-DO construct, for example. */ - - switch (format) - { - case FFESTV_formatLABEL: /* FMT=10 */ - case FFESTV_formatCHAREXPR: /* FMT='(I10)' */ - case FFESTV_formatINTEXPR: /* FMT=I [after ASSIGN 10 TO I] */ - ffeste_io_driver_ = ffeste_io_dofio_; - start = FFECOM_gfrtSWSFE, end = FFECOM_gfrtEWSFE; - break; - - case FFESTV_formatASTERISK: /* FMT=* */ - ffeste_io_driver_ = ffeste_io_dolio_; - start = FFECOM_gfrtSWSLE, end = FFECOM_gfrtEWSLE; - break; - - case FFESTV_formatNAMELIST: /* FMT=FOO or NML=FOO [NAMELIST - /FOO/] */ - ffeste_io_driver_ = NULL; /* No start or driver function. */ - start = FFECOM_gfrtSWSNE, end = FFECOM_gfrt; - break; - - default: - assert ("Weird stuff" == NULL); - start = FFECOM_gfrt, end = FFECOM_gfrt; - break; - } - ffeste_io_endgfrt_ = end; - - ffecom_push_calltemps (); - - cilist = ffeste_io_cilist_ (FALSE, FFESTV_unitNONE, NULL, 6, FALSE, format, - &info->print_spec[FFESTP_printixFORMAT], FALSE, NULL); - - ffeste_io_end_ = NULL_TREE; - ffeste_io_err_ = NULL_TREE; - ffeste_io_abort_ = NULL_TREE; - ffeste_io_abort_is_temp_ = FALSE; - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - - /* If there is no end function, then there are no item functions (i.e. - it's a NAMELIST), and vice versa by the way. In this situation, don't - generate the "if (iostat != 0) goto label;" if the label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (start, cilist), - !ffeste_io_abort_is_temp_ || (end != FFECOM_gfrt)); - } - - push_momentary (); -#else -#error -#endif -} - -/* ffeste_R911_item -- PRINT statement i/o item - - ffeste_R911_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_R911_item (ffebld expr, ffelexToken expr_token) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - if (expr == NULL) - return; - if (ffebld_op (expr) == FFEBLD_opANY) - return; - if (ffebld_op (expr) == FFEBLD_opIMPDO) - ffeste_io_impdo_ (expr, expr_token); - else - ffeste_io_call_ ((*ffeste_io_driver_) (expr), FALSE); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R911_finish -- PRINT statement list complete - - ffeste_R911_finish(); - - Just wrap up any local activities. */ - -void -ffeste_R911_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - if (ffeste_io_endgfrt_ != FFECOM_gfrt) - ffeste_io_call_ (ffecom_call_gfrt (ffeste_io_endgfrt_, NULL_TREE), - FALSE); - - ffecom_pop_calltemps (); - - clear_momentary (); - pop_momentary (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R919 -- BACKSPACE statement - - ffeste_R919(); - - Make sure a BACKSPACE is valid in the current context, and implement it. */ - -void -ffeste_R919 (ffestpBeruStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ BACKSPACE (", dmpout); - ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]); - ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]); - ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_subr_beru_ (info, FFECOM_gfrtFBACK); -#else -#error -#endif -} - -/* ffeste_R920 -- ENDFILE statement - - ffeste_R920(); - - Make sure a ENDFILE is valid in the current context, and implement it. */ - -void -ffeste_R920 (ffestpBeruStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ ENDFILE (", dmpout); - ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]); - ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]); - ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_subr_beru_ (info, FFECOM_gfrtFEND); -#else -#error -#endif -} - -/* ffeste_R921 -- REWIND statement - - ffeste_R921(); - - Make sure a REWIND is valid in the current context, and implement it. */ - -void -ffeste_R921 (ffestpBeruStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ REWIND (", dmpout); - ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]); - ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]); - ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - ffeste_subr_beru_ (info, FFECOM_gfrtFREW); -#else -#error -#endif -} - -/* ffeste_R923A -- INQUIRE statement (non-IOLENGTH version) - - ffeste_R923A(bool by_file); - - Make sure an INQUIRE is valid in the current context, and implement it. */ - -void -ffeste_R923A (ffestpInquireStmt *info, bool by_file UNUSED) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (by_file) - { - fputs ("+ INQUIRE_file (", dmpout); - ffeste_subr_file_ ("FILE", &info->inquire_spec[FFESTP_inquireixFILE]); - } - else - { - fputs ("+ INQUIRE_unit (", dmpout); - ffeste_subr_file_ ("UNIT", &info->inquire_spec[FFESTP_inquireixUNIT]); - } - ffeste_subr_file_ ("ACCESS", &info->inquire_spec[FFESTP_inquireixACCESS]); - ffeste_subr_file_ ("ACTION", &info->inquire_spec[FFESTP_inquireixACTION]); - ffeste_subr_file_ ("BLANK", &info->inquire_spec[FFESTP_inquireixBLANK]); - ffeste_subr_file_ ("CARRIAGECONTROL", &info->inquire_spec[FFESTP_inquireixCARRIAGECONTROL]); - ffeste_subr_file_ ("DEFAULTFILE", &info->inquire_spec[FFESTP_inquireixDEFAULTFILE]); - ffeste_subr_file_ ("DELIM", &info->inquire_spec[FFESTP_inquireixDELIM]); - ffeste_subr_file_ ("DIRECT", &info->inquire_spec[FFESTP_inquireixDIRECT]); - ffeste_subr_file_ ("ERR", &info->inquire_spec[FFESTP_inquireixERR]); - ffeste_subr_file_ ("EXIST", &info->inquire_spec[FFESTP_inquireixEXIST]); - ffeste_subr_file_ ("FORM", &info->inquire_spec[FFESTP_inquireixFORM]); - ffeste_subr_file_ ("FORMATTED", &info->inquire_spec[FFESTP_inquireixFORMATTED]); - ffeste_subr_file_ ("IOSTAT", &info->inquire_spec[FFESTP_inquireixIOSTAT]); - ffeste_subr_file_ ("KEYED", &info->inquire_spec[FFESTP_inquireixKEYED]); - ffeste_subr_file_ ("NAME", &info->inquire_spec[FFESTP_inquireixNAME]); - ffeste_subr_file_ ("NAMED", &info->inquire_spec[FFESTP_inquireixNAMED]); - ffeste_subr_file_ ("NEXTREC", &info->inquire_spec[FFESTP_inquireixNEXTREC]); - ffeste_subr_file_ ("NUMBER", &info->inquire_spec[FFESTP_inquireixNUMBER]); - ffeste_subr_file_ ("OPENED", &info->inquire_spec[FFESTP_inquireixOPENED]); - ffeste_subr_file_ ("ORGANIZATION", &info->inquire_spec[FFESTP_inquireixORGANIZATION]); - ffeste_subr_file_ ("PAD", &info->inquire_spec[FFESTP_inquireixPAD]); - ffeste_subr_file_ ("POSITION", &info->inquire_spec[FFESTP_inquireixPOSITION]); - ffeste_subr_file_ ("READ", &info->inquire_spec[FFESTP_inquireixREAD]); - ffeste_subr_file_ ("READWRITE", &info->inquire_spec[FFESTP_inquireixREADWRITE]); - ffeste_subr_file_ ("RECL", &info->inquire_spec[FFESTP_inquireixRECL]); - ffeste_subr_file_ ("RECORDTYPE", &info->inquire_spec[FFESTP_inquireixRECORDTYPE]); - ffeste_subr_file_ ("SEQUENTIAL", &info->inquire_spec[FFESTP_inquireixSEQUENTIAL]); - ffeste_subr_file_ ("UNFORMATTED", &info->inquire_spec[FFESTP_inquireixUNFORMATTED]); - ffeste_subr_file_ ("WRITE", &info->inquire_spec[FFESTP_inquireixWRITE]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree args; - bool iostat; - bool errl; - -#define specified(something) (info->inquire_spec[something].kw_or_val_present) - - ffeste_emit_line_note_ (); - - iostat = specified (FFESTP_inquireixIOSTAT); - errl = specified (FFESTP_inquireixERR); - - ffecom_push_calltemps (); - - args = ffeste_io_inlist_ (errl || iostat, - &info->inquire_spec[FFESTP_inquireixUNIT], - &info->inquire_spec[FFESTP_inquireixFILE], - &info->inquire_spec[FFESTP_inquireixEXIST], - &info->inquire_spec[FFESTP_inquireixOPENED], - &info->inquire_spec[FFESTP_inquireixNUMBER], - &info->inquire_spec[FFESTP_inquireixNAMED], - &info->inquire_spec[FFESTP_inquireixNAME], - &info->inquire_spec[FFESTP_inquireixACCESS], - &info->inquire_spec[FFESTP_inquireixSEQUENTIAL], - &info->inquire_spec[FFESTP_inquireixDIRECT], - &info->inquire_spec[FFESTP_inquireixFORM], - &info->inquire_spec[FFESTP_inquireixFORMATTED], - &info->inquire_spec[FFESTP_inquireixUNFORMATTED], - &info->inquire_spec[FFESTP_inquireixRECL], - &info->inquire_spec[FFESTP_inquireixNEXTREC], - &info->inquire_spec[FFESTP_inquireixBLANK]); - - if (errl) - { - ffeste_io_err_ - = ffeste_io_abort_ - = ffecom_lookup_label - (info->inquire_spec[FFESTP_inquireixERR].u.label); - ffeste_io_abort_is_temp_ = FALSE; - } - else - { - ffeste_io_err_ = NULL_TREE; - - if ((ffeste_io_abort_is_temp_ = iostat)) - ffeste_io_abort_ = ffecom_temp_label (); - else - ffeste_io_abort_ = NULL_TREE; - } - - if (iostat) - { /* IOSTAT= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = ffecom_expr - (info->inquire_spec[FFESTP_inquireixIOSTAT].u.expr); - } - else if (ffeste_io_abort_ != NULL_TREE) - { /* no IOSTAT= but ERR= */ - ffeste_io_iostat_is_temp_ = TRUE; - ffeste_io_iostat_ - = ffecom_push_tempvar (ffecom_integer_type_node, - FFETARGET_charactersizeNONE, -1, FALSE); - } - else - { /* no IOSTAT=, or ERR= */ - ffeste_io_iostat_is_temp_ = FALSE; - ffeste_io_iostat_ = NULL_TREE; - } - - /* Don't generate "if (iostat != 0) goto label;" if label is temp abort - label, since we're gonna fall through to there anyway. */ - - ffeste_io_call_ (ffecom_call_gfrt (FFECOM_gfrtFINQU, args), - !ffeste_io_abort_is_temp_); - - /* If we've got a temp label, generate its code here. */ - - if (ffeste_io_abort_is_temp_) - { - DECL_INITIAL (ffeste_io_abort_) = error_mark_node; - emit_nop (); - expand_label (ffeste_io_abort_); - - assert (ffeste_io_err_ == NULL_TREE); - } - - /* If we've got a temp iostat, pop the temp. */ - - if (ffeste_io_iostat_is_temp_) - ffecom_pop_tempvar (ffeste_io_iostat_); - - ffecom_pop_calltemps (); - -#undef specified - } - - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R923B_start -- INQUIRE(IOLENGTH=expr) statement list begin - - ffeste_R923B_start(); - - Verify that INQUIRE is valid here, and begin accepting items in the - list. */ - -void -ffeste_R923B_start (ffestpInquireStmt *info UNUSED) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ INQUIRE (", dmpout); - ffeste_subr_file_ ("IOLENGTH", &info->inquire_spec[FFESTP_inquireixIOLENGTH]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - assert ("INQUIRE(IOLENGTH=<var>) not implemented yet! ~~~" == NULL); - ffeste_emit_line_note_ (); - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R923B_item -- INQUIRE statement i/o item - - ffeste_R923B_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_R923B_item (ffebld expr UNUSED) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R923B_finish -- INQUIRE statement list complete - - ffeste_R923B_finish(); - - Just wrap up any local activities. */ - -void -ffeste_R923B_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - clear_momentary (); -#else -#error -#endif -} - -/* ffeste_R1001 -- FORMAT statement - - ffeste_R1001(format_list); */ - -void -ffeste_R1001 (ffests s) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "$ FORMAT %.*s\n", (int) ffests_length (s), ffests_text (s)); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree t; - tree ttype; - tree maxindex; - tree var; - - assert (ffeste_label_formatdef_ != NULL); - - ffeste_emit_line_note_ (); - - t = build_string (ffests_length (s), ffests_text (s)); - - TREE_TYPE (t) - = build_type_variant (build_array_type - (char_type_node, - build_range_type (integer_type_node, - integer_one_node, - build_int_2 (ffests_length (s), - 0))), - 1, 0); - TREE_CONSTANT (t) = 1; - TREE_STATIC (t) = 1; - - push_obstacks_nochange (); - end_temporary_allocation (); - - var = ffecom_lookup_label (ffeste_label_formatdef_); - if ((var != NULL_TREE) - && (TREE_CODE (var) == VAR_DECL)) - { - DECL_INITIAL (var) = t; - maxindex = build_int_2 (ffests_length (s) - 1, 0); - ttype = TREE_TYPE (var); - TYPE_DOMAIN (ttype) = build_range_type (integer_type_node, - integer_zero_node, - maxindex); - if (!TREE_TYPE (maxindex)) - TREE_TYPE (maxindex) = TYPE_DOMAIN (ttype); - layout_type (ttype); - rest_of_decl_compilation (var, NULL, 1, 0); - expand_decl (var); - expand_decl_init (var); - } - - resume_temporary_allocation (); - pop_obstacks (); - - ffeste_label_formatdef_ = NULL; - } -#else -#error -#endif -} - -/* ffeste_R1103 -- End a PROGRAM - - ffeste_R1103(); */ - -void -ffeste_R1103 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_PROGRAM\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_R1112 -- End a BLOCK DATA - - ffeste_R1112(TRUE); */ - -void -ffeste_R1112 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("* END_BLOCK_DATA\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_R1212 -- CALL statement - - ffeste_R1212(expr,expr_token); - - Make sure statement is valid here; implement. */ - -void -ffeste_R1212 (ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ CALL ", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - ffebld args = ffebld_right (expr); - ffebld arg; - ffebld labels = NULL; /* First in list of LABTERs. */ - ffebld prevlabels = NULL; - ffebld prevargs = NULL; - - ffeste_emit_line_note_ (); - - /* Here we split the list at ffebld_right(expr) into two lists: one at - ffebld_right(expr) consisting of all items that are not LABTERs, the - other at labels consisting of all items that are LABTERs. Then, if - the latter list is NULL, we have an ordinary call, else we have a call - with alternate returns. */ - - for (args = ffebld_right (expr); args != NULL; args = ffebld_trail (args)) - { - if (((arg = ffebld_head (args)) == NULL) - || (ffebld_op (arg) != FFEBLD_opLABTER)) - { - if (prevargs == NULL) - { - prevargs = args; - ffebld_set_right (expr, args); - } - else - { - ffebld_set_trail (prevargs, args); - prevargs = args; - } - } - else - { - if (prevlabels == NULL) - { - prevlabels = labels = args; - } - else - { - ffebld_set_trail (prevlabels, args); - prevlabels = args; - } - } - } - if (prevlabels == NULL) - labels = NULL; - else - ffebld_set_trail (prevlabels, NULL); - if (prevargs == NULL) - ffebld_set_right (expr, NULL); - else - ffebld_set_trail (prevargs, NULL); - - if (labels == NULL) - expand_expr_stmt (ffecom_expr (expr)); - else - { - tree texpr; - tree value; - tree tlabel; - int caseno; - int pushok; - tree duplicate; - - texpr = ffecom_expr (expr); - expand_start_case (0, texpr, TREE_TYPE (texpr), "CALL statement"); - push_momentary (); /* In case of many labels, keep 'em cleared - out. */ - for (caseno = 1; - labels != NULL; - ++caseno, labels = ffebld_trail (labels)) - { - value = build_int_2 (caseno, 0); - tlabel = build_decl (LABEL_DECL, NULL_TREE, NULL_TREE); - - pushok = pushcase (value, convert, tlabel, &duplicate); - assert (pushok == 0); - tlabel - = ffecom_lookup_label (ffebld_labter (ffebld_head (labels))); - if ((tlabel == NULL_TREE) - || (TREE_CODE (tlabel) == ERROR_MARK)) - continue; - TREE_USED (tlabel) = 1; - expand_goto (tlabel); - clear_momentary (); - } - - pop_momentary (); - expand_end_case (texpr); - } - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R1221 -- End a FUNCTION - - ffeste_R1221(TRUE); */ - -void -ffeste_R1221 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ END_FUNCTION\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_R1225 -- End a SUBROUTINE - - ffeste_R1225(TRUE); */ - -void -ffeste_R1225 () -{ -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ END_SUBROUTINE\n"); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_R1226 -- ENTRY statement - - ffeste_R1226(entryname,arglist,ending_token); - - Make sure we're in a SUBROUTINE or FUNCTION, register arguments for the - entry point name, and so on. */ - -void -ffeste_R1226 (ffesymbol entry) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fprintf (dmpout, "+ ENTRY %s", ffesymbol_text (entry)); - if (ffesymbol_dummyargs (entry) != NULL) - { - ffebld argh; - - fputc ('(', dmpout); - for (argh = ffesymbol_dummyargs (entry); - argh != NULL; - argh = ffebld_trail (argh)) - { - assert (ffebld_head (argh) != NULL); - switch (ffebld_op (ffebld_head (argh))) - { - case FFEBLD_opSYMTER: - fputs (ffesymbol_text (ffebld_symter (ffebld_head (argh))), - dmpout); - break; - - case FFEBLD_opSTAR: - fputc ('*', dmpout); - break; - - default: - fputc ('?', dmpout); - ffebld_dump (ffebld_head (argh)); - fputc ('?', dmpout); - break; - } - if (ffebld_trail (argh) != NULL) - fputc (',', dmpout); - } - fputc (')', dmpout); - } - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree label = ffesymbol_hook (entry).length_tree; - - ffeste_emit_line_note_ (); - - DECL_INITIAL (label) = error_mark_node; - emit_nop (); - expand_label (label); - - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_R1227 -- RETURN statement - - ffeste_R1227(expr); - - Make sure statement is valid here; implement. expr and expr_token are - both NULL if there was no expression. */ - -void -ffeste_R1227 (ffestw block UNUSED, ffebld expr) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - if (expr == NULL) - { - fputs ("+ RETURN\n", dmpout); - } - else - { - fputs ("+ RETURN_alternate ", dmpout); - ffebld_dump (expr); - fputc ('\n', dmpout); - } -#elif FFECOM_targetCURRENT == FFECOM_targetGCC - { - tree rtn; - - ffeste_emit_line_note_ (); - ffecom_push_calltemps (); - - rtn = ffecom_return_expr (expr); - - if ((rtn == NULL_TREE) - || (rtn == error_mark_node)) - expand_null_return (); - else - { - tree result = DECL_RESULT (current_function_decl); - - if ((result != error_mark_node) - && (TREE_TYPE (result) != error_mark_node)) - expand_return (ffecom_modify (NULL_TREE, - result, - convert (TREE_TYPE (result), - rtn))); - else - expand_null_return (); - } - - ffecom_pop_calltemps (); - clear_momentary (); - } -#else -#error -#endif -} - -/* ffeste_V018_start -- REWRITE(...) statement list begin - - ffeste_V018_start(); - - Verify that REWRITE is valid here, and begin accepting items in the - list. */ - -#if FFESTR_VXT -void -ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatNONE: - fputs ("+ REWRITE_uf (", dmpout); - break; - - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - fputs ("+ REWRITE_fm (", dmpout); - break; - - default: - assert ("Unexpected kind of format item in V018 REWRITE" == NULL); - } - ffeste_subr_file_ ("UNIT", &info->rewrite_spec[FFESTP_rewriteixUNIT]); - ffeste_subr_file_ ("FMT", &info->rewrite_spec[FFESTP_rewriteixFMT]); - ffeste_subr_file_ ("ERR", &info->rewrite_spec[FFESTP_rewriteixERR]); - ffeste_subr_file_ ("IOSTAT", &info->rewrite_spec[FFESTP_rewriteixIOSTAT]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V018_item -- REWRITE statement i/o item - - ffeste_V018_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_V018_item (ffebld expr) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V018_finish -- REWRITE statement list complete - - ffeste_V018_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V018_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V019_start -- ACCEPT statement list begin - - ffeste_V019_start(); - - Verify that ACCEPT is valid here, and begin accepting items in the - list. */ - -void -ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - fputs ("+ ACCEPT_fm ", dmpout); - break; - - case FFESTV_formatASTERISK: - fputs ("+ ACCEPT_ls ", dmpout); - break; - - case FFESTV_formatNAMELIST: - fputs ("+ ACCEPT_nl ", dmpout); - break; - - default: - assert ("Unexpected kind of format item in V019 ACCEPT" == NULL); - } - ffeste_subr_file_ ("FORMAT", &info->accept_spec[FFESTP_acceptixFORMAT]); - fputc (' ', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V019_item -- ACCEPT statement i/o item - - ffeste_V019_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_V019_item (ffebld expr) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V019_finish -- ACCEPT statement list complete - - ffeste_V019_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V019_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif -/* ffeste_V020_start -- TYPE statement list begin - - ffeste_V020_start(); - - Verify that TYPE is valid here, and begin accepting items in the - list. */ - -void -ffeste_V020_start (ffestpTypeStmt *info UNUSED, - ffestvFormat format UNUSED) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - switch (format) - { - case FFESTV_formatLABEL: - case FFESTV_formatCHAREXPR: - case FFESTV_formatINTEXPR: - fputs ("+ TYPE_fm ", dmpout); - break; - - case FFESTV_formatASTERISK: - fputs ("+ TYPE_ls ", dmpout); - break; - - case FFESTV_formatNAMELIST: - fputs ("* TYPE_nl ", dmpout); - break; - - default: - assert ("Unexpected kind of format item in V020 TYPE" == NULL); - } - ffeste_subr_file_ ("FORMAT", &info->type_spec[FFESTP_typeixFORMAT]); - fputc (' ', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V020_item -- TYPE statement i/o item - - ffeste_V020_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_V020_item (ffebld expr UNUSED) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V020_finish -- TYPE statement list complete - - ffeste_V020_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V020_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V021 -- DELETE statement - - ffeste_V021(); - - Make sure a DELETE is valid in the current context, and implement it. */ - -#if FFESTR_VXT -void -ffeste_V021 (ffestpDeleteStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ DELETE (", dmpout); - ffeste_subr_file_ ("UNIT", &info->delete_spec[FFESTP_deleteixUNIT]); - ffeste_subr_file_ ("REC", &info->delete_spec[FFESTP_deleteixREC]); - ffeste_subr_file_ ("ERR", &info->delete_spec[FFESTP_deleteixERR]); - ffeste_subr_file_ ("IOSTAT", &info->delete_spec[FFESTP_deleteixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V022 -- UNLOCK statement - - ffeste_V022(); - - Make sure a UNLOCK is valid in the current context, and implement it. */ - -void -ffeste_V022 (ffestpBeruStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ UNLOCK (", dmpout); - ffeste_subr_file_ ("UNIT", &info->beru_spec[FFESTP_beruixUNIT]); - ffeste_subr_file_ ("ERR", &info->beru_spec[FFESTP_beruixERR]); - ffeste_subr_file_ ("IOSTAT", &info->beru_spec[FFESTP_beruixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V023_start -- ENCODE(...) statement list begin - - ffeste_V023_start(); - - Verify that ENCODE is valid here, and begin accepting items in the - list. */ - -void -ffeste_V023_start (ffestpVxtcodeStmt *info) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ ENCODE (", dmpout); - ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]); - ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]); - ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]); - ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]); - ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V023_item -- ENCODE statement i/o item - - ffeste_V023_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_V023_item (ffebld expr) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V023_finish -- ENCODE statement list complete - - ffeste_V023_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V023_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V024_start -- DECODE(...) statement list begin - - ffeste_V024_start(); - - Verify that DECODE is valid here, and begin accepting items in the - list. */ - -void -ffeste_V024_start (ffestpVxtcodeStmt *info) -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ DECODE (", dmpout); - ffeste_subr_file_ ("C", &info->vxtcode_spec[FFESTP_vxtcodeixC]); - ffeste_subr_file_ ("F", &info->vxtcode_spec[FFESTP_vxtcodeixF]); - ffeste_subr_file_ ("B", &info->vxtcode_spec[FFESTP_vxtcodeixB]); - ffeste_subr_file_ ("ERR", &info->vxtcode_spec[FFESTP_vxtcodeixERR]); - ffeste_subr_file_ ("IOSTAT", &info->vxtcode_spec[FFESTP_vxtcodeixIOSTAT]); - fputs (") ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V024_item -- DECODE statement i/o item - - ffeste_V024_item(expr,expr_token); - - Implement output-list expression. */ - -void -ffeste_V024_item (ffebld expr) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (expr); - fputc (',', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V024_finish -- DECODE statement list complete - - ffeste_V024_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V024_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V025_start -- DEFINEFILE statement list begin - - ffeste_V025_start(); - - Verify that DEFINEFILE is valid here, and begin accepting items in the - list. */ - -void -ffeste_V025_start () -{ - ffeste_check_start_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ DEFINE_FILE ", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V025_item -- DEFINE FILE statement item - - ffeste_V025_item(u,ut,m,mt,n,nt,asv,asvt); - - Implement item. */ - -void -ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv) -{ - ffeste_check_item_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - ffebld_dump (u); - fputc ('(', dmpout); - ffebld_dump (m); - fputc (',', dmpout); - ffebld_dump (n); - fputs (",U,", dmpout); - ffebld_dump (asv); - fputs ("),", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V025_finish -- DEFINE FILE statement list complete - - ffeste_V025_finish(); - - Just wrap up any local activities. */ - -void -ffeste_V025_finish () -{ - ffeste_check_finish_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputc ('\n', dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -/* ffeste_V026 -- FIND statement - - ffeste_V026(); - - Make sure a FIND is valid in the current context, and implement it. */ - -void -ffeste_V026 (ffestpFindStmt *info) -{ - ffeste_check_simple_ (); - -#if FFECOM_targetCURRENT == FFECOM_targetFFE - fputs ("+ FIND (", dmpout); - ffeste_subr_file_ ("UNIT", &info->find_spec[FFESTP_findixUNIT]); - ffeste_subr_file_ ("REC", &info->find_spec[FFESTP_findixREC]); - ffeste_subr_file_ ("ERR", &info->find_spec[FFESTP_findixERR]); - ffeste_subr_file_ ("IOSTAT", &info->find_spec[FFESTP_findixIOSTAT]); - fputs (")\n", dmpout); -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -#else -#error -#endif -} - -#endif diff --git a/gcc/f/ste.h b/gcc/f/ste.h deleted file mode 100755 index 0ee0d0f..0000000 --- a/gcc/f/ste.h +++ /dev/null @@ -1,168 +0,0 @@ -/* ste.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - ste.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_ste -#define _H_f_ste - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lab.h" -#include "lex.h" -#include "stp.h" -#include "str.h" -#include "sts.h" -#include "stt.h" -#include "stv.h" -#include "stw.h" -#include "symbol.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffeste_do (ffestw block); -void ffeste_end_R807 (void); -void ffeste_labeldef_branch (ffelab label); -void ffeste_labeldef_format (ffelab label); -void ffeste_R737A (ffebld dest, ffebld source); -void ffeste_R803 (ffebld expr); -void ffeste_R804 (ffebld expr); -void ffeste_R805 (void); -void ffeste_R806 (void); -void ffeste_R807 (ffebld expr); -void ffeste_R809 (ffestw block, ffebld expr); -void ffeste_R810 (ffestw block, unsigned long casenum); -void ffeste_R811 (ffestw block); -void ffeste_R819A (ffestw block, ffelab label, ffebld var, - ffebld start, ffelexToken start_token, - ffebld end, ffelexToken end_token, - ffebld incr, ffelexToken incr_token); -void ffeste_R819B (ffestw block, ffelab label, ffebld expr); -void ffeste_R825 (void); -void ffeste_R834 (ffestw block); -void ffeste_R835 (ffestw block); -void ffeste_R836 (ffelab label); -void ffeste_R837 (ffelab *labels, int count, ffebld expr); -void ffeste_R838 (ffelab label, ffebld target); -void ffeste_R839 (ffebld target); -void ffeste_R840 (ffebld expr, ffelab neg, ffelab zero, ffelab pos); -void ffeste_R841 (void); -void ffeste_R842 (ffebld expr); -void ffeste_R843 (ffebld expr); -void ffeste_R904 (ffestpOpenStmt *info); -void ffeste_R907 (ffestpCloseStmt *info); -void ffeste_R909_start (ffestpReadStmt *info, bool only_format, - ffestvUnit unit, ffestvFormat format, bool rec, bool key); -void ffeste_R909_item (ffebld expr, ffelexToken expr_token); -void ffeste_R909_finish (void); -void ffeste_R910_start (ffestpWriteStmt *info, ffestvUnit unit, - ffestvFormat format, bool rec); -void ffeste_R910_item (ffebld expr, ffelexToken expr_token); -void ffeste_R910_finish (void); -void ffeste_R911_start (ffestpPrintStmt *info, ffestvFormat format); -void ffeste_R911_item (ffebld expr, ffelexToken expr_token); -void ffeste_R911_finish (void); -void ffeste_R919 (ffestpBeruStmt *info); -void ffeste_R920 (ffestpBeruStmt *info); -void ffeste_R921 (ffestpBeruStmt *info); -void ffeste_R923A (ffestpInquireStmt *info, bool by_file); -void ffeste_R923B_start (ffestpInquireStmt *info); -void ffeste_R923B_item (ffebld expr); -void ffeste_R923B_finish (void); -void ffeste_R1001 (ffests s); -void ffeste_R1103 (void); -void ffeste_R1112 (void); -void ffeste_R1212 (ffebld expr); -void ffeste_R1221 (void); -void ffeste_R1225 (void); -void ffeste_R1226 (ffesymbol entry); -void ffeste_R1227 (ffestw block, ffebld expr); -#if FFESTR_VXT -void ffeste_V018_start (ffestpRewriteStmt *info, ffestvFormat format); -void ffeste_V018_item (ffebld expr); -void ffeste_V018_finish (void); -void ffeste_V019_start (ffestpAcceptStmt *info, ffestvFormat format); -void ffeste_V019_item (ffebld expr); -void ffeste_V019_finish (void); -#endif -void ffeste_V020_start (ffestpTypeStmt *info, ffestvFormat format); -void ffeste_V020_item (ffebld expr); -void ffeste_V020_finish (void); -#if FFESTR_VXT -void ffeste_V021 (ffestpDeleteStmt *info); -void ffeste_V022 (ffestpBeruStmt *info); -void ffeste_V023_start (ffestpVxtcodeStmt *info); -void ffeste_V023_item (ffebld expr); -void ffeste_V023_finish (void); -void ffeste_V024_start (ffestpVxtcodeStmt *info); -void ffeste_V024_item (ffebld expr); -void ffeste_V024_finish (void); -void ffeste_V025_start (void); -void ffeste_V025_item (ffebld u, ffebld m, ffebld n, ffebld asv); -void ffeste_V025_finish (void); -void ffeste_V026 (ffestpFindStmt *info); -#endif - -/* Define macros. */ - -#define ffeste_init_0() -#define ffeste_init_1() -#define ffeste_init_2() -#define ffeste_init_3() -#define ffeste_init_4() -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#define ffeste_filename() input_filename -#define ffeste_filelinenum() lineno -#define ffeste_set_line(name,num) \ - (input_filename = (name), lineno = (num)) -#elif FFECOM_targetCURRENT == FFECOM_targetFFE -#define ffeste_set_line(name,num) -#else -#error -#endif /* FFECOM_targetCURRENT == FFECOM_targetFFE */ -#define ffeste_terminate_0() -#define ffeste_terminate_1() -#define ffeste_terminate_2() -#define ffeste_terminate_3() -#define ffeste_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/storag.c b/gcc/f/storag.c deleted file mode 100755 index 76f5cd3..0000000 --- a/gcc/f/storag.c +++ /dev/null @@ -1,573 +0,0 @@ -/* storag.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Maintains information on storage (memory) relationships between - COMMON, dummy, and local variables, plus their equivalences (dummies - don't have equivalences, however). - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "storag.h" -#include "data.h" -#include "malloc.h" -#include "symbol.h" -#include "target.h" - -/* Externals defined here. */ - -ffestoragList_ ffestorag_list_; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - -static ffetargetOffset ffestorag_local_size_; /* #units allocated so far. */ -static bool ffestorag_reported_;/* Reports happen only once. */ - -/* Static functions (internal). */ - - -/* Internal macros. */ - -#define ffestorag_next_(s) ((s)->next) -#define ffestorag_previous_(s) ((s)->previous) - -/* ffestorag_drive -- Drive fn from list of storage objects - - ffestoragList sl; - void (*fn)(ffestorag mst,ffestorag st); - ffestorag mst; // the master ffestorag object (or whatever) - ffestorag_drive(sl,fn,mst); - - Calls (*fn)(mst,st) for every st in the list sl. */ - -void -ffestorag_drive (ffestoragList sl, void (*fn) (ffestorag mst, ffestorag st), - ffestorag mst) -{ - ffestorag st; - - for (st = sl->first; - st != (ffestorag) &sl->first; - st = st->next) - (*fn) (mst, st); -} - -/* ffestorag_dump -- Dump information on storage object - - ffestorag s; // the ffestorag object - ffestorag_dump(s); - - Dumps information in the storage object. */ - -void -ffestorag_dump (ffestorag s) -{ - if (s == NULL) - { - fprintf (dmpout, "(no storage object)"); - return; - } - - switch (s->type) - { - case FFESTORAG_typeCBLOCK: - fprintf (dmpout, "CBLOCK "); - break; - - case FFESTORAG_typeCOMMON: - fprintf (dmpout, "COMMON "); - break; - - case FFESTORAG_typeLOCAL: - fprintf (dmpout, "LOCAL "); - break; - - case FFESTORAG_typeEQUIV: - fprintf (dmpout, "EQUIV "); - break; - - default: - fprintf (dmpout, "?%d? ", s->type); - break; - } - - if (s->symbol != NULL) - fprintf (dmpout, "\"%s\" ", ffesymbol_text (s->symbol)); - - fprintf (dmpout, "at %" ffetargetOffset_f "d size %" ffetargetOffset_f - "d, align loc%%%" - ffetargetAlign_f "u=%" ffetargetAlign_f "u, bt=%s, kt=%s", - s->offset, - s->size, (unsigned int) s->alignment, (unsigned int) s->modulo, - ffeinfo_basictype_string (s->basic_type), - ffeinfo_kindtype_string (s->kind_type)); - - if (s->equivs_.first != (ffestorag) &s->equivs_.first) - { - ffestorag sq; - - fprintf (dmpout, " with equivs"); - for (sq = s->equivs_.first; - sq != (ffestorag) &s->equivs_.first; - sq = ffestorag_next_ (sq)) - { - if (ffestorag_previous_ (sq) == (ffestorag) &s->equivs_.first) - fputc (' ', dmpout); - else - fputc (',', dmpout); - fprintf (dmpout, "%s", ffesymbol_text (ffestorag_symbol (sq))); - } - } -} - -/* ffestorag_init_2 -- Initialize for new program unit - - ffestorag_init_2(); */ - -void -ffestorag_init_2 () -{ - ffestorag_list_.first = ffestorag_list_.last - = (ffestorag) &ffestorag_list_.first; - ffestorag_local_size_ = 0; - ffestorag_reported_ = FALSE; -} - -/* ffestorag_end_layout -- Do final layout for symbol - - ffesymbol s; - ffestorag_end_layout(s); */ - -void -ffestorag_end_layout (ffesymbol s) -{ - if (ffesymbol_storage (s) != NULL) - return; /* Already laid out. */ - - ffestorag_exec_layout (s); /* Do what we have in common. */ -#if 0 - assert (ffesymbol_storage (s) == NULL); /* I'd like to know what - cases miss going through - ffecom_sym_learned, and - why; I don't think we - should have to do the - exec_layout thing at all - here. */ - /* Now I think I know: we have to do exec_layout here, because equivalence - handling could encounter an error that takes a variable off of its - equivalence object (and vice versa), and we should then layout the var - as a local entity. */ -#endif -} - -/* ffestorag_exec_layout -- Do initial layout for symbol - - ffesymbol s; - ffestorag_exec_layout(s); */ - -void -ffestorag_exec_layout (ffesymbol s) -{ - ffetargetAlign alignment; - ffetargetAlign modulo; - ffetargetOffset size; - ffetargetOffset num_elements; - ffetargetAlign pad; - ffestorag st; - ffestorag stv; - ffebld list; - ffebld item; - ffesymbol var; - bool init; - - if (ffesymbol_storage (s) != NULL) - return; /* Already laid out. */ - - switch (ffesymbol_kind (s)) - { - default: - return; /* Do nothing. */ - - case FFEINFO_kindENTITY: - switch (ffesymbol_where (s)) - { - case FFEINFO_whereLOCAL: - if (ffesymbol_equiv (s) != NULL) - return; /* Let ffeequiv handle this guy. */ - if (ffesymbol_rank (s) == 0) - num_elements = 1; - else - { - if (ffebld_op (ffesymbol_arraysize (s)) - != FFEBLD_opCONTER) - return; /* An adjustable local array, just like a dummy. */ - num_elements - = ffebld_constant_integerdefault (ffebld_conter - (ffesymbol_arraysize (s))); - } - ffetarget_layout (ffesymbol_text (s), &alignment, &modulo, - &size, ffesymbol_basictype (s), - ffesymbol_kindtype (s), ffesymbol_size (s), - num_elements); - st = ffestorag_new (ffestorag_list_master ()); - st->parent = NULL; /* Initializations happen at sym level. */ - st->init = NULL; - st->accretion = NULL; - st->symbol = s; - st->size = size; - st->offset = 0; - st->alignment = alignment; - st->modulo = modulo; - st->type = FFESTORAG_typeLOCAL; - st->basic_type = ffesymbol_basictype (s); - st->kind_type = ffesymbol_kindtype (s); - st->type_symbol = s; - st->is_save = ffesymbol_is_save (s); - st->is_init = ffesymbol_is_init (s); - ffesymbol_set_storage (s, st); - if (ffesymbol_is_init (s)) - ffecom_notify_init_symbol (s); /* Init completed before, but - we didn't have a storage - object for it; maybe back - end wants to see the sym - again now. */ - ffesymbol_signal_unreported (s); - return; - - case FFEINFO_whereCOMMON: - return; /* Allocate storage for entire common block - at once. */ - - case FFEINFO_whereDUMMY: - return; /* Don't do anything about dummies for now. */ - - case FFEINFO_whereRESULT: - case FFEINFO_whereIMMEDIATE: - case FFEINFO_whereCONSTANT: - case FFEINFO_whereNONE: - return; /* These don't get storage (esp. NONE, which - is UNCERTAIN). */ - - default: - assert ("bad ENTITY where" == NULL); - return; - } - break; - - case FFEINFO_kindCOMMON: - assert (ffesymbol_where (s) == FFEINFO_whereLOCAL); - st = ffestorag_new (ffestorag_list_master ()); - st->parent = NULL; /* Initializations happen here. */ - st->init = NULL; - st->accretion = NULL; - st->symbol = s; - st->size = 0; - st->offset = 0; - st->alignment = 1; - st->modulo = 0; - st->type = FFESTORAG_typeCBLOCK; - if (ffesymbol_commonlist (s) != NULL) - { - var = ffebld_symter (ffebld_head (ffesymbol_commonlist (s))); - st->basic_type = ffesymbol_basictype (var); - st->kind_type = ffesymbol_kindtype (var); - st->type_symbol = var; - } - else - { /* Special case for empty common area: - NONE/NONE means nothing. */ - st->basic_type = FFEINFO_basictypeNONE; - st->kind_type = FFEINFO_kindtypeNONE; - st->type_symbol = NULL; - } - st->is_save = ffesymbol_is_save (s); - st->is_init = ffesymbol_is_init (s); - if (!ffe_is_mainprog ()) - ffeglobal_save_common (s, - st->is_save || ffe_is_saveall (), - ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffesymbol_set_storage (s, st); - - init = FALSE; - for (list = ffesymbol_commonlist (s); - list != NULL; - list = ffebld_trail (list)) - { - item = ffebld_head (list); - assert (ffebld_op (item) == FFEBLD_opSYMTER); - var = ffebld_symter (item); - if (ffesymbol_basictype (var) == FFEINFO_basictypeANY) - continue; /* Ignore any symbols that have errors. */ - if (ffesymbol_rank (var) == 0) - num_elements = 1; - else - num_elements = ffebld_constant_integerdefault (ffebld_conter - (ffesymbol_arraysize (var))); - ffetarget_layout (ffesymbol_text (var), &alignment, &modulo, - &size, ffesymbol_basictype (var), - ffesymbol_kindtype (var), ffesymbol_size (var), - num_elements); - pad = ffetarget_align (&st->alignment, &st->modulo, st->size, - alignment, modulo); - if (pad != 0) - { /* Warn about padding in the midst of a - common area. */ - char padding[20]; - - sprintf (&padding[0], "%" ffetargetAlign_f "u", pad); - ffebad_start (FFEBAD_COMMON_PAD); - ffebad_string (padding); - ffebad_string (ffesymbol_text (var)); - ffebad_string (ffesymbol_text (s)); - ffebad_string ((pad == 1) - ? FFECOM_SIZE_UNIT : FFECOM_SIZE_UNITS); - ffebad_here (0, ffesymbol_where_line (s), ffesymbol_where_column (s)); - ffebad_finish (); - } - stv = ffestorag_new (ffestorag_list_master ()); - stv->parent = st; /* Initializations happen in COMMON block. */ - stv->init = NULL; - stv->accretion = NULL; - stv->symbol = var; - stv->size = size; - if (!ffetarget_offset_add (&stv->offset, st->size, pad)) - { /* Common block size plus pad, complain if - overflow. */ - ffetarget_offset_overflow (ffesymbol_text (s)); - } - if (!ffetarget_offset_add (&st->size, stv->offset, stv->size)) - { /* Adjust size of common block, complain if - overflow. */ - ffetarget_offset_overflow (ffesymbol_text (s)); - } - stv->alignment = alignment; - stv->modulo = modulo; - stv->type = FFESTORAG_typeCOMMON; - stv->basic_type = ffesymbol_basictype (var); - stv->kind_type = ffesymbol_kindtype (var); - stv->type_symbol = var; - stv->is_save = st->is_save; - stv->is_init = st->is_init; - ffesymbol_set_storage (var, stv); - ffesymbol_signal_unreported (var); - ffestorag_update (st, var, ffesymbol_basictype (var), - ffesymbol_kindtype (var)); - if (ffesymbol_is_init (var)) - init = TRUE; /* Must move inits over to COMMON's - ffestorag. */ - } - if (ffeequiv_layout_cblock (st)) - init = TRUE; - ffeglobal_pad_common (s, st->modulo, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - if (init) - ffedata_gather (st); /* Gather subordinate inits into one init. */ - ffesymbol_signal_unreported (s); - return; - } -} - -/* ffestorag_new -- Create new ffestorag object, append to list - - ffestorag s; - ffestoragList sl; - s = ffestorag_new(sl); */ - -ffestorag -ffestorag_new (ffestoragList sl) -{ - ffestorag s; - - s = (ffestorag) malloc_new_kp (ffe_pool_program_unit (), "ffestorag", - sizeof (*s)); - s->next = (ffestorag) &sl->first; - s->previous = sl->last; -#ifdef FFECOM_storageHOOK - s->hook = FFECOM_storageNULL; -#endif - s->previous->next = s; - sl->last = s; - s->equivs_.first = s->equivs_.last = (ffestorag) &s->equivs_.first; - - return s; -} - -/* Report info on LOCAL non-sym-assoc'ed entities if needed. */ - -void -ffestorag_report () -{ - ffestorag s; - - if (ffestorag_reported_) - return; - - for (s = ffestorag_list_.first; - s != (ffestorag) &ffestorag_list_.first; - s = s->next) - { - if (s->symbol == NULL) - { - ffestorag_reported_ = TRUE; - fputs ("Storage area: ", dmpout); - ffestorag_dump (s); - fputc ('\n', dmpout); - } - } -} - -/* ffestorag_update -- Update type info for ffestorag object - - ffestorag s; // existing object - ffeinfoBasictype bt; // basic type for newly added member of object - ffeinfoKindtype kt; // kind type for it - ffestorag_update(s,bt,kt); - - If the existing type for the storage object agrees with the new type - info, just returns. If the basic types agree but not the kind types, - sets the kind type for the object to NONE. If the basic types - disagree, sets the kind type to NONE, and the basic type to NONE if the - basic types both are not CHARACTER, otherwise to ANY. If the basic - type for the object already is NONE, it is set to ANY if the new basic - type is CHARACTER. Any time a transition is made to ANY and pedantic - mode is on, a message is issued that mixing CHARACTER and non-CHARACTER - stuff in the same COMMON/EQUIVALENCE is invalid. */ - -void -ffestorag_update (ffestorag s, ffesymbol sym, ffeinfoBasictype bt, - ffeinfoKindtype kt) -{ - if (s->basic_type == bt) - { - if (s->kind_type == kt) - return; - s->kind_type = FFEINFO_kindtypeNONE; - return; - } - - switch (s->basic_type) - { - case FFEINFO_basictypeANY: - return; /* No need to do anything further. */ - - case FFEINFO_basictypeCHARACTER: - any: /* :::::::::::::::::::: */ - s->basic_type = FFEINFO_basictypeANY; - s->kind_type = FFEINFO_kindtypeANY; - if (ffe_is_pedantic ()) - { - ffebad_start (FFEBAD_MIXED_TYPES); - ffebad_string (ffesymbol_text (s->type_symbol)); - ffebad_string (ffesymbol_text (sym)); - ffebad_finish (); - } - return; - - default: - if (bt == FFEINFO_basictypeCHARACTER) - goto any; /* :::::::::::::::::::: */ - s->basic_type = FFEINFO_basictypeNONE; - s->kind_type = FFEINFO_kindtypeNONE; - return; - } -} - -/* Update INIT flag for storage object. - - If the INIT flag for the <s> object is already TRUE, return. Else, - set it to TRUE and call ffe*_update_init for all contained objects. */ - -void -ffestorag_update_init (ffestorag s) -{ - ffestorag sq; - - if (s->is_init) - return; - - s->is_init = TRUE; - - if ((s->symbol != NULL) - && !ffesymbol_is_init (s->symbol)) - ffesymbol_update_init (s->symbol); - - if (s->parent != NULL) - ffestorag_update_init (s->parent); - - for (sq = s->equivs_.first; - sq != (ffestorag) &s->equivs_.first; - sq = ffestorag_next_ (sq)) - { - if (!sq->is_init) - ffestorag_update_init (sq); - } -} - -/* Update SAVE flag for storage object. - - If the SAVE flag for the <s> object is already TRUE, return. Else, - set it to TRUE and call ffe*_update_save for all contained objects. */ - -void -ffestorag_update_save (ffestorag s) -{ - ffestorag sq; - - if (s->is_save) - return; - - s->is_save = TRUE; - - if ((s->symbol != NULL) - && !ffesymbol_is_save (s->symbol)) - ffesymbol_update_save (s->symbol); - - if (s->parent != NULL) - ffestorag_update_save (s->parent); - - for (sq = s->equivs_.first; - sq != (ffestorag) &s->equivs_.first; - sq = ffestorag_next_ (sq)) - { - if (!sq->is_save) - ffestorag_update_save (sq); - } -} diff --git a/gcc/f/storag.h b/gcc/f/storag.h deleted file mode 100755 index 5addab5..0000000 --- a/gcc/f/storag.h +++ /dev/null @@ -1,167 +0,0 @@ -/* storag.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - storag.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_storag -#define _H_f_storag - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFESTORAG_typeNONE, - FFESTORAG_typeCBLOCK, /* A COMMON block. */ - FFESTORAG_typeCOMMON, /* A COMMON variable. */ - FFESTORAG_typeLOCAL, /* A local entity (var/array/equivalence). */ - FFESTORAG_typeEQUIV, /* An entity equivalenced into a COMMON/LOCAL - entity. */ - FFESTORAG_type - } ffestoragType; - -/* Typedefs. */ - -typedef struct _ffestorag_ *ffestorag; -typedef struct _ffestorag_list_ *ffestoragList; -typedef struct _ffestorag_list_ ffestoragList_; - -/* Include files needed by this one. */ - -#include "bld.h" -#include "info.h" -#include "symbol.h" -#include "target.h" - -/* Structure definitions. */ - -struct _ffestorag_list_ - { - ffestorag first; /* First storage area in list. */ - ffestorag last; /* Last storage area in list. */ - }; - -struct _ffestorag_ - { - ffestorag next; /* Next storage area in list. */ - ffestorag previous; /* Previous storage area in list. */ - ffestorag parent; /* Parent who holds aggregate - initializations. */ - ffebld init; /* Initialization expression. */ - ffebld accretion; /* Initializations seen so far for aggregate. */ - ffetargetOffset accretes; /* # inits needed to fill entire aggregate. */ - ffesymbol symbol; /* NULL if typeLOCAL and non-NULL equivs - and the first "rooted" symbol not known. */ - ffestoragList_ equivs_; /* NULL if typeLOCAL and not an EQUIVALENCE - area. */ - ffetargetOffset size; /* Size of area. */ - ffetargetOffset offset; /* Offset of entity within area, 0 for CBLOCK - and non-equivalence LOCAL, <= 0 for equivalence - LOCAL. */ - ffetargetAlign alignment; /* Initial alignment for entity. */ - ffetargetAlign modulo; /* Modulo within alignment. */ -#ifdef FFECOM_storageHOOK - ffecomStorage hook; /* Whatever the backend needs here. */ -#endif - ffestoragType type; - ffeinfoBasictype basic_type;/* NONE= >1 non-CHARACTER; ANY= - CHAR+non-CHAR. */ - ffeinfoKindtype kind_type; /* NONE= >1 kind type or NONE/ANY basic_type. */ - ffesymbol type_symbol; /* First symbol for basic_type/kind_type. */ - bool is_save; /* SAVE flag set for this storage area. */ - bool is_init; /* INIT flag set for this storage area. */ - }; - -/* Global objects accessed by users of this module. */ - -extern ffestoragList_ ffestorag_list_; - -/* Declare functions with prototypes. */ - -void ffestorag_drive (ffestoragList sl, void (*fn) (ffestorag mst, ffestorag st), - ffestorag mst); -void ffestorag_dump (ffestorag s); -void ffestorag_end_layout (ffesymbol s); -void ffestorag_exec_layout (ffesymbol s); -void ffestorag_init_2 (void); -ffestorag ffestorag_new (ffestoragList sl); -void ffestorag_report (void); -void ffestorag_update (ffestorag s, ffesymbol sym, ffeinfoBasictype bt, - ffeinfoKindtype kt); -void ffestorag_update_init (ffestorag s); -void ffestorag_update_save (ffestorag s); - -/* Define macros. */ - -#define ffestorag_accretes(s) ((s)->accretes) -#define ffestorag_accretion(s) ((s)->accretion) -#define ffestorag_alignment(s) ((s)->alignment) -#define ffestorag_basictype(s) ((s)->basic_type) -#define ffestorag_hook(s) ((s)->hook) -#define ffestorag_init(s) ((s)->init) -#define ffestorag_init_0() -#define ffestorag_init_1() -#define ffestorag_init_3() -#define ffestorag_init_4() -#define ffestorag_is_init(s) ((s)->is_init) -#define ffestorag_is_save(s) ((s)->is_save) -#define ffestorag_kindtype(s) ((s)->kind_type) -#define ffestorag_list_equivs(s) (&(s)->equivs_) -#define ffestorag_list_master() (&ffestorag_list_) -#define ffestorag_modulo(s) ((s)->modulo) -#define ffestorag_offset(s) ((s)->offset) -#define ffestorag_parent(s) ((s)->parent) -#define ffestorag_ptr_to_alignment(s) (&(s)->alignment) -#define ffestorag_ptr_to_modulo(s) (&(s)->modulo) -#define ffestorag_set_accretes(s,a) ((s)->accretes = (a)) -#define ffestorag_set_accretion(s,a) ((s)->accretion = (a)) -#define ffestorag_set_alignment(s,a) ((s)->alignment = (a)) -#define ffestorag_set_basictype(s,b) ((s)->basic_type = (b)) -#define ffestorag_set_hook(s,h) ((s)->hook = (h)) -#define ffestorag_set_init(s,i) ((s)->init = (i)) -#define ffestorag_set_is_init(s,in) ((s)->is_init = (in)) -#define ffestorag_set_is_save(s,sa) ((s)->is_save = (sa)) -#define ffestorag_set_kindtype(s,k) ((s)->kind_type = (k)) -#define ffestorag_set_modulo(s,m) ((s)->modulo = (m)) -#define ffestorag_set_offset(s,o) ((s)->offset = (o)) -#define ffestorag_set_parent(s,p) ((s)->parent = (p)) -#define ffestorag_set_size(s,si) ((s)->size = (si)) -#define ffestorag_set_symbol(s,sy) ((s)->symbol = (sy)) -#define ffestorag_set_type(s,t) ((s)->type = (t)) -#define ffestorag_set_typesymbol(s,sy) ((s)->type_symbol = (sy)) -#define ffestorag_size(s) ((s)->size) -#define ffestorag_symbol(s) ((s)->symbol) -#define ffestorag_terminate_0() -#define ffestorag_terminate_1() -#define ffestorag_terminate_2() -#define ffestorag_terminate_3() -#define ffestorag_terminate_4() -#define ffestorag_type(s) ((s)->type) -#define ffestorag_typesymbol(s) ((s)->type_symbol) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stp.c b/gcc/f/stp.c deleted file mode 100755 index 6c95c74..0000000 --- a/gcc/f/stp.c +++ /dev/null @@ -1,59 +0,0 @@ -/* stp.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Keeps track of some information needed while parsing (and usually - before the exact statement is not confirmed). - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stp.h" - -/* Externals defined here. */ - -union _ffestp_fileu_ ffestp_file; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ diff --git a/gcc/f/stp.h b/gcc/f/stp.h deleted file mode 100755 index edfccc6..0000000 --- a/gcc/f/stp.h +++ /dev/null @@ -1,508 +0,0 @@ -/* stp.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stp.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stp -#define _H_f_stp - -/* Simple definitions and enumerations. */ - -enum _ffestp_acceptix_ - { - FFESTP_acceptixFORMAT, - FFESTP_acceptix - }; -typedef enum _ffestp_acceptix_ ffestpAcceptIx; - -enum _ffestp_attrib_ - { -#if FFESTR_F90 - FFESTP_attribALLOCATABLE, -#endif - FFESTP_attribDIMENSION, - FFESTP_attribEXTERNAL, -#if FFESTR_F90 - FFESTP_attribINTENT, -#endif - FFESTP_attribINTRINSIC, -#if FFESTR_F90 - FFESTP_attribOPTIONAL, -#endif - FFESTP_attribPARAMETER, -#if FFESTR_F90 - FFESTP_attribPOINTER, -#endif -#if FFESTR_F90 - FFESTP_attribPRIVATE, - FFESTP_attribPUBLIC, -#endif - FFESTP_attribSAVE, -#if FFESTR_F90 - FFESTP_attribTARGET, -#endif - FFESTP_attrib - }; -typedef enum _ffestp_attrib_ ffestpAttrib; - -enum _ffestp_beruix_ - { - FFESTP_beruixERR, - FFESTP_beruixIOSTAT, - FFESTP_beruixUNIT, - FFESTP_beruix - }; -typedef enum _ffestp_beruix_ ffestpBeruIx; - -enum _ffestp_closeix_ - { - FFESTP_closeixERR, - FFESTP_closeixIOSTAT, - FFESTP_closeixSTATUS, - FFESTP_closeixUNIT, - FFESTP_closeix - }; -typedef enum _ffestp_closeix_ ffestpCloseIx; - -enum _ffestp_deleteix_ - { - FFESTP_deleteixERR, - FFESTP_deleteixIOSTAT, - FFESTP_deleteixREC, - FFESTP_deleteixUNIT, - FFESTP_deleteix - }; -typedef enum _ffestp_deleteix_ ffestpDeleteIx; - -enum _ffestp_findix_ - { - FFESTP_findixERR, - FFESTP_findixIOSTAT, - FFESTP_findixREC, - FFESTP_findixUNIT, - FFESTP_findix - }; -typedef enum _ffestp_findix_ ffestpFindIx; - -enum _ffestp_inquireix_ - { - FFESTP_inquireixACCESS, - FFESTP_inquireixACTION, - FFESTP_inquireixBLANK, - FFESTP_inquireixCARRIAGECONTROL, - FFESTP_inquireixDEFAULTFILE, - FFESTP_inquireixDELIM, - FFESTP_inquireixDIRECT, - FFESTP_inquireixERR, - FFESTP_inquireixEXIST, - FFESTP_inquireixFILE, - FFESTP_inquireixFORM, - FFESTP_inquireixFORMATTED, - FFESTP_inquireixIOLENGTH, - FFESTP_inquireixIOSTAT, - FFESTP_inquireixKEYED, - FFESTP_inquireixNAME, - FFESTP_inquireixNAMED, - FFESTP_inquireixNEXTREC, - FFESTP_inquireixNUMBER, - FFESTP_inquireixOPENED, - FFESTP_inquireixORGANIZATION, - FFESTP_inquireixPAD, - FFESTP_inquireixPOSITION, - FFESTP_inquireixREAD, - FFESTP_inquireixREADWRITE, - FFESTP_inquireixRECL, - FFESTP_inquireixRECORDTYPE, - FFESTP_inquireixSEQUENTIAL, - FFESTP_inquireixUNFORMATTED, - FFESTP_inquireixUNIT, - FFESTP_inquireixWRITE, - FFESTP_inquireix - }; -typedef enum _ffestp_inquireix_ ffestpInquireIx; - -enum _ffestp_openix_ - { - FFESTP_openixACCESS, - FFESTP_openixACTION, - FFESTP_openixASSOCIATEVARIABLE, - FFESTP_openixBLANK, - FFESTP_openixBLOCKSIZE, - FFESTP_openixBUFFERCOUNT, - FFESTP_openixCARRIAGECONTROL, - FFESTP_openixDEFAULTFILE, - FFESTP_openixDELIM, - FFESTP_openixDISPOSE, - FFESTP_openixERR, - FFESTP_openixEXTENDSIZE, - FFESTP_openixFILE, - FFESTP_openixFORM, - FFESTP_openixINITIALSIZE, - FFESTP_openixIOSTAT, - FFESTP_openixKEY, - FFESTP_openixMAXREC, - FFESTP_openixNOSPANBLOCKS, - FFESTP_openixORGANIZATION, - FFESTP_openixPAD, - FFESTP_openixPOSITION, - FFESTP_openixREADONLY, - FFESTP_openixRECL, - FFESTP_openixRECORDTYPE, - FFESTP_openixSHARED, - FFESTP_openixSTATUS, - FFESTP_openixUNIT, - FFESTP_openixUSEROPEN, - FFESTP_openix - }; -typedef enum _ffestp_openix_ ffestpOpenIx; - -enum _ffestp_printix_ - { - FFESTP_printixFORMAT, - FFESTP_printix - }; -typedef enum _ffestp_printix_ ffestpPrintIx; - -enum _ffestp_readix_ - { - FFESTP_readixADVANCE, - FFESTP_readixEND, - FFESTP_readixEOR, - FFESTP_readixERR, - FFESTP_readixFORMAT, /* Or NAMELIST (use expr info to - distinguish). */ - FFESTP_readixIOSTAT, - FFESTP_readixKEYEQ, - FFESTP_readixKEYGE, - FFESTP_readixKEYGT, - FFESTP_readixKEYID, - FFESTP_readixNULLS, - FFESTP_readixREC, - FFESTP_readixSIZE, - FFESTP_readixUNIT, - FFESTP_readix - }; -typedef enum _ffestp_readix_ ffestpReadIx; - -enum _ffestp_rewriteix_ - { - FFESTP_rewriteixERR, - FFESTP_rewriteixFMT, - FFESTP_rewriteixIOSTAT, - FFESTP_rewriteixUNIT, - FFESTP_rewriteix - }; -typedef enum _ffestp_rewriteix_ ffestpRewriteIx; - -enum _ffestp_typeix_ - { - FFESTP_typeixFORMAT, - FFESTP_typeix - }; -typedef enum _ffestp_typeix_ ffestpTypeIx; - -enum _ffestp_vxtcodeix_ - { - FFESTP_vxtcodeixB, - FFESTP_vxtcodeixC, - FFESTP_vxtcodeixERR, - FFESTP_vxtcodeixF, - FFESTP_vxtcodeixIOSTAT, - FFESTP_vxtcodeix - }; -typedef enum _ffestp_vxtcodeix_ ffestpVxtcodeIx; - -enum _ffestp_writeix_ - { - FFESTP_writeixADVANCE, - FFESTP_writeixEOR, - FFESTP_writeixERR, - FFESTP_writeixFORMAT, /* Or NAMELIST (use expr info to - distinguish). */ - FFESTP_writeixIOSTAT, - FFESTP_writeixREC, - FFESTP_writeixUNIT, - FFESTP_writeix - }; -typedef enum _ffestp_writeix_ ffestpWriteIx; - -#if FFESTR_F90 -enum _ffestp_definedoperator_ - { - FFESTP_definedoperatorNone, /* INTERFACE generic-name. */ - FFESTP_definedoperatorOPERATOR, /* INTERFACE - OPERATOR(defined-operator). */ - FFESTP_definedoperatorASSIGNMENT, /* INTERFACE ASSIGNMENT(=). */ - FFESTP_definedoperatorPOWER, - FFESTP_definedoperatorMULT, - FFESTP_definedoperatorADD, - FFESTP_definedoperatorCONCAT, - FFESTP_definedoperatorDIVIDE, - FFESTP_definedoperatorSUBTRACT, - FFESTP_definedoperatorNOT, - FFESTP_definedoperatorAND, - FFESTP_definedoperatorOR, - FFESTP_definedoperatorEQV, - FFESTP_definedoperatorNEQV, - FFESTP_definedoperatorEQ, - FFESTP_definedoperatorNE, - FFESTP_definedoperatorLT, - FFESTP_definedoperatorLE, - FFESTP_definedoperatorGT, - FFESTP_definedoperatorGE, - FFESTP_definedoperator - }; -typedef enum _ffestp_definedoperator_ ffestpDefinedOperator; -#endif - -enum _ffestp_dimtype_ - { - FFESTP_dimtypeNONE, - FFESTP_dimtypeKNOWN, /* Known-bounds dimension list. */ - FFESTP_dimtypeADJUSTABLE, /* Adjustable dimension list. */ - FFESTP_dimtypeASSUMED, /* Assumed dimension list (known except for - last). */ - FFESTP_dimtypeADJUSTABLEASSUMED, /* Both. */ - FFESTP_dimtype - }; -typedef enum _ffestp_dimtype_ ffestpDimtype; - -enum _ffestp_formattype_ - { - FFESTP_formattypeNone, - FFESTP_formattypeI, - FFESTP_formattypeB, - FFESTP_formattypeO, - FFESTP_formattypeZ, - FFESTP_formattypeF, - FFESTP_formattypeE, - FFESTP_formattypeEN, - FFESTP_formattypeG, - FFESTP_formattypeL, - FFESTP_formattypeA, - FFESTP_formattypeD, - FFESTP_formattypeQ, - FFESTP_formattypeDOLLAR, /* $ (V-extension). */ - FFESTP_formattypeP, - FFESTP_formattypeT, - FFESTP_formattypeTL, - FFESTP_formattypeTR, - FFESTP_formattypeX, - FFESTP_formattypeS, - FFESTP_formattypeSP, - FFESTP_formattypeSS, - FFESTP_formattypeBN, - FFESTP_formattypeBZ, - FFESTP_formattypeH, /* Hollerith, used only for error-reporting. */ - FFESTP_formattypeSLASH, - FFESTP_formattypeCOLON, - FFESTP_formattypeR1016, /* char-literal-constant or cHchars. */ - FFESTP_formattypeFORMAT, /* [r](format-item-list). */ - FFESTP_formattype - }; -typedef enum _ffestp_formattype_ ffestpFormatType; - -enum _ffestp_type_ - { - FFESTP_typeNone, - FFESTP_typeINTEGER, - FFESTP_typeREAL, - FFESTP_typeCOMPLEX, - FFESTP_typeLOGICAL, - FFESTP_typeCHARACTER, - FFESTP_typeDBLPRCSN, - FFESTP_typeDBLCMPLX, - FFESTP_typeBYTE, - FFESTP_typeWORD, -#if FFESTR_F90 - FFESTP_typeTYPE, -#endif - FFESTP_type - }; -typedef enum _ffestp_type_ ffestpType; - -/* Typedefs. */ - -typedef struct _ffest_accept_stmt_ ffestpAcceptStmt; -typedef struct _ffest_beru_stmt_ ffestpBeruStmt; -typedef struct _ffest_close_stmt_ ffestpCloseStmt; -typedef struct _ffest_delete_stmt_ ffestpDeleteStmt; -typedef struct _ffestp_file ffestpFile; -typedef struct _ffest_find_stmt_ ffestpFindStmt; -typedef struct _ffest_inquire_stmt_ ffestpInquireStmt; -typedef struct _ffest_open_stmt_ ffestpOpenStmt; -typedef struct _ffest_print_stmt_ ffestpPrintStmt; -typedef struct _ffest_read_stmt_ ffestpReadStmt; -typedef struct _ffest_rewrite_stmt_ ffestpRewriteStmt; -typedef struct _ffest_type_stmt_ ffestpTypeStmt; -typedef struct _ffest_vxtcode_stmt_ ffestpVxtcodeStmt; -typedef struct _ffest_write_stmt_ ffestpWriteStmt; - -/* Include files needed by this one. */ - -#include "bld.h" -#include "lab.h" -#include "lex.h" -#include "stp.h" -#include "stt.h" - -/* Structure definitions. */ - -struct _ffestp_file - { - bool kw_or_val_present; /* If FALSE, all else is n/a. */ - bool kw_present; /* Indicates whether kw has a token. */ - bool value_present; /* Indicates whether value/expr are valid. */ - bool value_is_label; /* TRUE if expr has no expression, value is - NUMBER. */ - ffelexToken kw; /* The keyword, iff kw_or_val_present && - kw_present. */ - ffelexToken value; /* The value, iff kw_or_val_present && - value_present. */ - union - { - ffebld expr; /* The expr, iff kw_or_val_present && - value_present && !value_is_label. */ - ffelab label; /* The label, iff kw_or_val_present && - value_present && value_is_label. */ - } - u; - }; - -struct _ffest_accept_stmt_ - { - ffestpFile accept_spec[FFESTP_acceptix]; - }; - -struct _ffest_beru_stmt_ - { - ffestpFile beru_spec[FFESTP_beruix]; - }; - -struct _ffest_close_stmt_ - { - ffestpFile close_spec[FFESTP_closeix]; - }; - -struct _ffest_delete_stmt_ - { - ffestpFile delete_spec[FFESTP_deleteix]; - }; - -struct _ffest_find_stmt_ - { - ffestpFile find_spec[FFESTP_findix]; - }; - -struct _ffest_imp_list_ - { - ffesttImpList next; - ffesttImpList previous; - ffelexToken first; - ffelexToken last; /* NULL if a single letter. */ - }; - -struct _ffest_inquire_stmt_ - { - ffestpFile inquire_spec[FFESTP_inquireix]; - }; - -struct _ffest_open_stmt_ - { - ffestpFile open_spec[FFESTP_openix]; - }; - -struct _ffest_print_stmt_ - { - ffestpFile print_spec[FFESTP_printix]; - }; - -struct _ffest_read_stmt_ - { - ffestpFile read_spec[FFESTP_readix]; - }; - -struct _ffest_rewrite_stmt_ - { - ffestpFile rewrite_spec[FFESTP_rewriteix]; - }; - -struct _ffest_type_stmt_ - { - ffestpFile type_spec[FFESTP_typeix]; - }; - -struct _ffest_vxtcode_stmt_ - { - ffestpFile vxtcode_spec[FFESTP_vxtcodeix]; - }; - -struct _ffest_write_stmt_ - { - ffestpFile write_spec[FFESTP_writeix]; - }; - -union _ffestp_fileu_ - { - ffestpAcceptStmt accept; - ffestpBeruStmt beru; - ffestpCloseStmt close; - ffestpDeleteStmt delete; - ffestpFindStmt find; - ffestpInquireStmt inquire; - ffestpOpenStmt open; - ffestpPrintStmt print; - ffestpReadStmt read; - ffestpRewriteStmt rewrite; - ffestpTypeStmt type; - ffestpVxtcodeStmt vxtcode; - ffestpWriteStmt write; - }; - -/* Global objects accessed by users of this module. */ - -extern union _ffestp_fileu_ ffestp_file; - -/* Declare functions with prototypes. */ - - -/* Define macros. */ - -#define ffestp_init_0() -#define ffestp_init_1() -#define ffestp_init_2() -#define ffestp_init_3() -#define ffestp_init_4() -#define ffestp_terminate_0() -#define ffestp_terminate_1() -#define ffestp_terminate_2() -#define ffestp_terminate_3() -#define ffestp_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/str-1t.fin b/gcc/f/str-1t.fin deleted file mode 100755 index 674c92d..0000000 --- a/gcc/f/str-1t.fin +++ /dev/null @@ -1,135 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_first // // ffestrFirst ffestr_first 1 1 -;Accept ACCEPT -;Allocatable ALLOCATABLE -;Allocate ALLOCATE -Assign ASSIGN -Backspace BACKSPACE -Block BLOCK -BlockData BLOCKDATA -Byte BYTE -Call CALL -Case CASE -CaseDefault CASEDEFAULT -Character CHRCTR -Close CLOSE -Common COMMON -Complex CMPLX -;Contains CONTAINS -Continue CONTINUE -Cycle CYCLE -Data DATA -;Deallocate DEALLOCATE -Decode DECODE -Define DEFINE -;DefineFile DEFINEFILE -Delete DELETE -Dimension DIMENSION -Do DO -Double DBL -DoubleComplex DBLCMPLX -DoublePrecision DBLPRCSN -DoWhile DOWHILE -Else ELSE -ElseIf ELSEIF -;ElseWhere ELSEWHERE -Encode ENCODE -End END -EndBlock ENDBLOCK -EndBlockData ENDBLOCKDATA -EndDo ENDDO -EndFile ENDFILE -EndFunction ENDFUNCTION -EndIf ENDIF -;EndInterface ENDINTERFACE -;EndMap ENDMAP -;EndModule ENDMODULE -EndProgram ENDPROGRAM -EndSelect ENDSELECT -;EndStructure ENDSTRUCTURE -EndSubroutine ENDSUBROUTINE -;EndType ENDTYPE -;EndUnion ENDUNION -;EndWhere ENDWHERE -Entry ENTRY -Equivalence EQUIVALENCE -Exit EXIT -External EXTERNAL -Find FIND -Format FORMAT -Function FUNCTION -Go GO -GoTo GOTO -If IF -Implicit IMPLICIT -Include INCLUDE -Inquire INQUIRE -Integer INTGR -;Intent INTENT -;Interface INTERFACE -;InterfaceAssignment INTERFACEASSGNMNT -;InterfaceOperator INTERFACEOPERATOR -Intrinsic INTRINSIC -Logical LGCL -;Map MAP -;Module MODULE -;ModuleProcedure MODULEPROCEDURE -NameList NAMELIST -;Nullify NULLIFY -Open OPEN -;Optional OPTIONAL -Parameter PARAMETER -Pause PAUSE -;Pointer POINTER -Print PRINT -;Private PRIVATE -Program PROGRAM -;Public PUBLIC -Read READ -Real REAL -;Record RECORD -;Recursive RECURSIVE -;RecursiveFunction RECURSIVEFNCTN -Return RETURN -Rewind REWIND -;Rewrite REWRITE -Save SAVE -Select SELECT -SelectCase SELECTCASE -;Sequence SEQUENCE -Stop STOP -;Structure STRUCTURE -Subroutine SUBROUTINE -;Target TARGET -Then THEN -Type TYPE -;Union UNION -;Unlock UNLOCK -;Use USE -Virtual VIRTUAL -Volatile VOLATILE -;Where WHERE -Word WORD -Write WRITE diff --git a/gcc/f/str-2t.fin b/gcc/f/str-2t.fin deleted file mode 100755 index ea86819..0000000 --- a/gcc/f/str-2t.fin +++ /dev/null @@ -1,60 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_second // // ffestrSecond ffestr_second 1 0 -;Assignment ASSIGNMENT -Block BLOCK -BlockData BLOCKDATA -Byte BYTE -Case CASE -Character CHARACTER -Complex COMPLEX -Data DATA -Default DEFAULT -Do DO -Double DOUBLE -DoubleComplex DOUBLECOMPLEX -DoublePrecision DOUBLEPRECISION -File FILE -Function FUNCTION -If IF -Integer INTEGER -;Interface INTERFACE -Logical LOGICAL -;Map MAP -;Module MODULE -None NONE -;Operator OPERATOR -Precision PRECISION -;Procedure PROCEDURE -Program PROGRAM -Real REAL -Select SELECT -;Structure STRUCTURE -Subroutine SUBROUTINE -To TO -;Type TYPE -;Union UNION -;Where WHERE -While WHILE -Word WORD diff --git a/gcc/f/str-fo.fin b/gcc/f/str-fo.fin deleted file mode 100755 index 243941f..0000000 --- a/gcc/f/str-fo.fin +++ /dev/null @@ -1,55 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_format // // ffestrFormat ffestr_format 0 1 -$ DOLLAR -A A -B B -BN BN -BZ BZ -D D -E E -En EN -F F -G G -H H -I I -L L -N N -O O -P P -PD PD -PE PE -PEn PEN -PF PF -PG PG -Q Q -R R -S S -SP SP -SS SS -T T -TL TL -TR TR -X X -Z Z diff --git a/gcc/f/str-io.fin b/gcc/f/str-io.fin deleted file mode 100755 index 4124da6..0000000 --- a/gcc/f/str-io.fin +++ /dev/null @@ -1,43 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_genio // // ffestrGenio ffestr_genio 1 0 -Advance ADVANCE -Disp DISP -Dispose DISPOSE -End END -EoR EOR -Err ERR -Fmt FMT -IOStat IOSTAT -Key KEY -KeyEQ KEYEQ -KeyGE KEYGE -KeyGT KEYGT -KeyID KEYID -Nml NML -Nulls NULLS -Rec REC -Size SIZE -Status STATUS -Unit UNIT diff --git a/gcc/f/str-nq.fin b/gcc/f/str-nq.fin deleted file mode 100755 index cce8745..0000000 --- a/gcc/f/str-nq.fin +++ /dev/null @@ -1,55 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_inquire // // ffestrInquire ffestr_inquire 1 0 -Access ACCESS -Action ACTION -Blank BLANK -CarriageControl CARRIAGECONTROL -DefaultFile DEFAULTFILE -Delim DELIM -Direct DIRECT -Err ERR -Exist EXIST -File FILE -Form FORM -Formatted FORMATTED -IOLength IOLENGTH -IOStat IOSTAT -Keyed KEYED -Name NAME -Named NAMED -NextRec NEXTREC -Number NUMBER -Opened OPENED -Organization ORGANIZATION -Pad PAD -Position POSITION -Read READ -ReadWrite READWRITE -RecL RECL -RecordType RECORDTYPE -Sequential SEQUENTIAL -Unformatted UNFORMATTED -Unit UNIT -Write WRITE diff --git a/gcc/f/str-op.fin b/gcc/f/str-op.fin deleted file mode 100755 index 62396f2..0000000 --- a/gcc/f/str-op.fin +++ /dev/null @@ -1,57 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_open // // ffestrOpen ffestr_open 1 0 -Access ACCESS -Action ACTION -AssociateVariable ASSOCIATEVARIABLE -Blank BLANK -BlockSize BLOCKSIZE -BufferCount BUFFERCOUNT -CarriageControl CARRIAGECONTROL -DefaultFile DEFAULTFILE -Delim DELIM -Disp DISP -Dispose DISPOSE -Err ERR -ExtendSize EXTENDSIZE -File FILE -Form FORM -InitialSize INITIALSIZE -IOStat IOSTAT -Key KEY -MaxRec MAXREC -Name NAME -NoSpanBlocks NOSPANBLOCKS -Organization ORGANIZATION -Pad PAD -Position POSITION -Readonly READONLY -Recl RECL -RecordSize RECORDSIZE -RecordType RECORDTYPE -Shared SHARED -Status STATUS -Type TYPE -Unit UNIT -UserOpen USEROPEN diff --git a/gcc/f/str-ot.fin b/gcc/f/str-ot.fin deleted file mode 100755 index a4ad768..0000000 --- a/gcc/f/str-ot.fin +++ /dev/null @@ -1,50 +0,0 @@ -{ - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -} - -FFESTR_other // // ffestrOther ffestr_other 1 1 -And AND -;Dimension DIMENSION -Eq EQ -Eqv EQV -False FALSE -GE GE -GT GT -In IN -InOut INOUT -Kind KIND -LE LE -Len LEN -LT LT -NE NE -NEqv NEQV -Not NOT -;Only ONLY -Or OR -Out OUT -;Pointer POINTER -;Private PRIVATE -;Public PUBLIC -Result RESULT -;Stat STAT -True TRUE -XOr XOR diff --git a/gcc/f/str.c b/gcc/f/str.c deleted file mode 100755 index 8622789..0000000 --- a/gcc/f/str.c +++ /dev/null @@ -1,217 +0,0 @@ -/* str.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Handles recognition of keywords. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "src.h" -#include "str.h" -#include "lex.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffestr_first -- Look up the first names in a statement - - ffestrFirst kw; - ffelexToken t; - kw = ffestr_first(t); - - Returns FFESTR_firstNone if no matches, else FFESTR_firstXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_first.fini", consisting primarily of a - list of statements (ASSIGN, IF, DO, DOWHILE), and outputs a C file, - "str-1t.j", that contains the definition of the - ffestr_first function. We #include that file here. - - 30-Jan-90 JCB 2.0 - Updated for Fortran 90. -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-1t.j" -#endif -/* ffestr_format -- Look up format names in a statement - - ffestrFormat kw; - ffelexToken t; - kw = ffestr_format(t); - - Returns FFESTR_formatNone if no matches, else FFESTR_formatXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_format.fini", consisting primarily of a - list of format keywords (I, F, TL, TR), and outputs a C file, - "str-fo.j", that contains the definition of the - ffestr_format function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-fo.j" -#endif -/* ffestr_genio -- Look up genio names in a statement - - ffestrGenio kw; - ffelexToken t; - kw = ffestr_genio(t); - - Returns FFESTR_genioNone if no matches, else FFESTR_genioXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_genio.fini", consisting primarily of a - list of statement keywords (TO, FUNCTION), and outputs a C file, - "str-io.j", that contains the definition of the - ffestr_genio function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-io.j" -#endif -/* ffestr_inquire -- Look up inquire names in a statement - - ffestrInquire kw; - ffelexToken t; - kw = ffestr_inquire(t); - - Returns FFESTR_inquireNone if no matches, else FFESTR_inquireXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_inquire.fini", consisting primarily of a - list of statement keywords (TO, FUNCTION), and outputs a C file, - "str-nq.j", that contains the definition of the - ffestr_inquire function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-nq.j" -#endif -/* ffestr_open -- Look up open names in a statement - - ffestrOpen kw; - ffelexToken t; - kw = ffestr_open(t); - - Returns FFESTR_openNone if no matches, else FFESTR_openXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_open.fini", consisting primarily of a - list of statement keywords (TO, FUNCTION), and outputs a C file, - "str-op.j", that contains the definition of the - ffestr_open function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-op.j" -#endif -/* ffestr_other -- Look up other names in a statement - - ffestrOther kw; - ffelexToken t; - kw = ffestr_other(t); - - Returns FFESTR_otherNone if no matches, else FFESTR_otherXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_other.fini", consisting primarily of a - list of statement keywords (TO, FUNCTION), and outputs a C file, - "str-ot.j", that contains the definition of the - ffestr_other function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-ot.j" -#endif -/* ffestr_second -- Look up the second name in a statement - - ffestrSecond kw; - ffelexToken t; - kw = ffestr_second(t); - - Returns FFESTR_secondNone if no matches, else FFESTR_secondXYZ if the - NAME or NAMES token matches XYZ. t must be a NAME or NAMES token or this - routine will crash. - - This routine's code is actually written by a utility called FINI, itself - written specifically for the Gnu Fortran project. FINI takes an input - file, in this case "ffe_second.fini", consisting primarily of a - list of statement keywords (TO, FUNCTION), and outputs a C file, - "str-2t.j", that contains the definition of the - ffestr_second function. We #include that file here. - -*/ - -#ifndef MAKING_DEPENDENCIES -#include "str-2t.j" -#endif diff --git a/gcc/f/str.h b/gcc/f/str.h deleted file mode 100755 index 17b58ea..0000000 --- a/gcc/f/str.h +++ /dev/null @@ -1,85 +0,0 @@ -/* str.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - str.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_str -#define _H_f_str - -/* Simple definitions and enumerations. */ - -#define FFESTR_F90 0 /* Unsupported F90 stuff. */ -#define FFESTR_VXT 0 /* Unsupported VXT stuff. */ - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "lex.h" -#ifndef MAKING_DEPENDENCIES -#include "str-1t.h" -#include "str-fo.h" -#include "str-io.h" -#include "str-nq.h" -#include "str-ot.h" -#include "str-op.h" -#include "str-2t.h" -#endif - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -ffestrFirst ffestr_first (ffelexToken t); -ffestrFormat ffestr_format (ffelexToken t); -ffestrGenio ffestr_genio (ffelexToken t); -ffestrInquire ffestr_inquire (ffelexToken t); -ffestrOpen ffestr_open (ffelexToken t); -ffestrOther ffestr_other (ffelexToken t); -ffestrSecond ffestr_second (ffelexToken t); - -/* Define macros. */ - -#define ffestr_init_0() -#define ffestr_init_1() -#define ffestr_init_2() -#define ffestr_init_3() -#define ffestr_init_4() -#define ffestr_terminate_0() -#define ffestr_terminate_1() -#define ffestr_terminate_2() -#define ffestr_terminate_3() -#define ffestr_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/sts.c b/gcc/f/sts.c deleted file mode 100755 index 1229ad5..0000000 --- a/gcc/f/sts.c +++ /dev/null @@ -1,273 +0,0 @@ -/* sts.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None (despite the name, it doesn't really depend on ffest*) - - Description: - Provides an arbitrary-length string facility for the limited needs of - GNU Fortran FORMAT statement generation. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "sts.h" -#include "com.h" -#include "malloc.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffests_kill -- Kill a varying-length string - - ffests s; - ffests_kill(s); - - The storage associated with the string <s> is freed. */ - -void -ffests_kill (ffests s) -{ - if (s->text_ != NULL) - malloc_kill_ksr (s->pool_, s->text_, s->max_); -} - -/* ffests_new -- Make a varying-length string - - ffests s; - ffests_new(s,malloc_pool_image(),0); - - The string is initialized to hold, in this case, 0 characters, and - current and future heap manipulations to hold the string will use - the image pool. */ - -void -ffests_new (ffests s, mallocPool pool, ffestsLength size) -{ - s->pool_ = pool; - s->len_ = 0; - s->max_ = size; - - if (size == 0) - s->text_ = NULL; - else - s->text_ = malloc_new_ksr (pool, "ffests", size); -} - -/* ffests_printf_1D -- printf("...%ld...",(long)) to a string - - ffests s; - ffests_printf_1D(s,"...%ld...",1); - - Like printf, but into a string. */ - -void -ffests_printf_1D (ffests s, char *ctl, long arg1) -{ - char quickbuf[40]; - char *buff; - ffestsLength len; - - if ((len = strlen (ctl) + 21) < ARRAY_SIZE (quickbuf)) - /* No # bigger than 20 digits. */ - { - sprintf (&quickbuf[0], ctl, arg1); - ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); - } - else - { - buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1D", len); - sprintf (buff, ctl, arg1); - ffests_puttext (s, buff, strlen (buff)); - malloc_kill_ks (malloc_pool_image (), buff, len); - } -} - -/* ffests_printf_1U -- printf("...%lu...",(unsigned long)) to a string - - ffests s; - ffests_printf_1U(s,"...%lu...",1); - - Like printf, but into a string. */ - -void -ffests_printf_1U (ffests s, char *ctl, unsigned long arg1) -{ - char quickbuf[40]; - char *buff; - ffestsLength len; - - if ((len = strlen (ctl) + 21) < ARRAY_SIZE (quickbuf)) - /* No # bigger than 20 digits. */ - { - sprintf (&quickbuf[0], ctl, arg1); - ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); - } - else - { - buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1U", len); - sprintf (buff, ctl, arg1); - ffests_puttext (s, buff, strlen (buff)); - malloc_kill_ks (malloc_pool_image (), buff, len); - } -} - -/* ffests_printf_1s -- printf("...%s...",(char *)) to a string - - ffests s; - ffests_printf_1s(s,"...%s...","hi there!"); - - Like printf, but into a string. */ - -void -ffests_printf_1s (ffests s, char *ctl, char *arg1) -{ - char quickbuf[40]; - char *buff; - ffestsLength len; - - if ((len = strlen (ctl) + strlen (arg1) - 1) < ARRAY_SIZE (quickbuf)) - { - sprintf (&quickbuf[0], ctl, arg1); - ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); - } - else - { - buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_1s", len); - sprintf (buff, ctl, arg1); - ffests_puttext (s, buff, strlen (buff)); - malloc_kill_ks (malloc_pool_image (), buff, len); - } -} - -/* ffests_printf_2Us -- printf("...%lu...%s...",...) to a string - - ffests s; - ffests_printf_2Us(s,"...%lu...%s...",1,"hi there!"); - - Like printf, but into a string. */ - -void -ffests_printf_2Us (ffests s, char *ctl, unsigned long arg1, char *arg2) -{ - char quickbuf[60]; - char *buff; - ffestsLength len; - - if ((len = strlen (ctl) + 21 + strlen (arg2) - 1) < ARRAY_SIZE (quickbuf)) - /* No # bigger than 20 digits. */ - { - sprintf (&quickbuf[0], ctl, arg1, arg2); - ffests_puttext (s, &quickbuf[0], strlen (quickbuf)); - } - else - { - buff = malloc_new_ks (malloc_pool_image (), "ffests_printf_2Us", len); - sprintf (buff, ctl, arg1, arg2); - ffests_puttext (s, buff, strlen (buff)); - malloc_kill_ks (malloc_pool_image (), buff, len); - } -} - -/* ffests_putc -- Put a single character into string - - ffests s; - ffests_putc(s,'*'); */ - -void -ffests_putc (ffests s, char c) -{ - ffests_puttext (s, &c, 1); -} - -/* ffests_puts -- Put a zero-terminated (C-style) string into string - - ffests s; - ffests_puts(s,"append me"); */ - -void -ffests_puts (ffests s, char *string) -{ - ffests_puttext (s, string, strlen (string)); -} - -/* ffests_puttext -- Put a number of characters into string - - ffests s; - ffests_puttext(s,"hi there",8); - - The string need not be 0-terminated, because the passed length is used, - and may be 0. */ - -void -ffests_puttext (ffests s, char *text, ffestsLength length) -{ - ffestsLength newlen; - ffestsLength newmax; - - if (length <= 0) - return; - - newlen = s->len_ + length; - if (newlen > s->max_) - { - if (s->text_ == NULL) - { - s->max_ = 40; - s->text_ = malloc_new_ksr (s->pool_, "ffests", s->max_); - } - else - { - newmax = s->max_ << 1; - while (newmax < newlen) - newmax <<= 1; - s->text_ = malloc_resize_ksr (s->pool_, s->text_, newmax, s->max_); - s->max_ = newmax; - } - } - - memcpy (s->text_ + s->len_, text, length); - s->len_ = newlen; -} diff --git a/gcc/f/sts.h b/gcc/f/sts.h deleted file mode 100755 index d2c2b6e..0000000 --- a/gcc/f/sts.h +++ /dev/null @@ -1,89 +0,0 @@ -/* sts.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - sts.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_sts -#define _H_f_sts - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffests_ *ffests; -typedef struct _ffests_ ffestsHolder; -typedef unsigned long int ffestsLength; - -/* Include files needed by this one. */ - -#include "malloc.h" - -/* Structure definitions. */ - -struct _ffests_ - { - char *text_; - mallocPool pool_; - ffestsLength len_; - ffestsLength max_; - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffests_kill (ffests s); -void ffests_new (ffests s, mallocPool pool, ffestsLength size); -void ffests_printf_1D (ffests s, char *ctl, long arg1); -void ffests_printf_1U (ffests s, char *ctl, unsigned long arg1); -void ffests_printf_1s (ffests s, char *ctl, char *arg1); -void ffests_printf_2Us (ffests s, char *ctl, unsigned long arg1, - char *arg2); -void ffests_putc (ffests s, char c); -void ffests_puts (ffests s, char *string); -void ffests_puttext (ffests s, char *text, ffestsLength length); - -/* Define macros. */ - -#define ffests_init_0() -#define ffests_init_1() -#define ffests_init_2() -#define ffests_init_3() -#define ffests_init_4() -#define ffests_length(s) ((s)->len_) -#define ffests_terminate_0() -#define ffests_terminate_1() -#define ffests_terminate_2() -#define ffests_terminate_3() -#define ffests_terminate_4() -#define ffests_text(s) ((s)->text_) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stt.c b/gcc/f/stt.c deleted file mode 100755 index d2db379..0000000 --- a/gcc/f/stt.c +++ /dev/null @@ -1,1044 +0,0 @@ -/* stt.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995, 1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Manages lists of tokens and related info for parsing. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stt.h" -#include "bld.h" -#include "expr.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" -#include "sta.h" -#include "stp.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffestt_caselist_append -- Append case to list of cases - - ffesttCaseList list; - ffelexToken t; - ffestt_caselist_append(list,range,case1,case2,t); - - list must have already been created by ffestt_caselist_create. The - list is allocated out of the scratch pool. The token is consumed. */ - -void -ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1, - ffebld case2, ffelexToken t) -{ - ffesttCaseList new; - - new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool, - "FFEST case list", sizeof (*new)); - new->next = list->previous->next; - new->previous = list->previous; - new->next->previous = new; - new->previous->next = new; - new->expr1 = case1; - new->expr2 = case2; - new->range = range; - new->t = t; -} - -/* ffestt_caselist_create -- Create new list of cases - - ffesttCaseList list; - list = ffestt_caselist_create(); - - The list is allocated out of the scratch pool. */ - -ffesttCaseList -ffestt_caselist_create () -{ - ffesttCaseList new; - - new = (ffesttCaseList) malloc_new_kp (ffesta_scratch_pool, - "FFEST case list root", - sizeof (*new)); - new->next = new->previous = new; - new->t = NULL; - new->expr1 = NULL; - new->expr2 = NULL; - new->range = FALSE; - return new; -} - -/* ffestt_caselist_dump -- Dump list of cases - - ffesttCaseList list; - ffestt_caselist_dump(list); - - The cases in the list are dumped with commas separating them. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffestt_caselist_dump (ffesttCaseList list) -{ - ffesttCaseList next; - - for (next = list->next; next != list; next = next->next) - { - if (next != list->next) - fputc (',', dmpout); - if (next->expr1 != NULL) - ffebld_dump (next->expr1); - if (next->range) - { - fputc (':', dmpout); - if (next->expr2 != NULL) - ffebld_dump (next->expr2); - } - } -} -#endif - -/* ffestt_caselist_kill -- Kill list of cases - - ffesttCaseList list; - ffestt_caselist_kill(list); - - The tokens on the list are killed. - - 02-Mar-90 JCB 1.1 - Don't kill the list itself or change it, since it will be trashed when - ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */ - -void -ffestt_caselist_kill (ffesttCaseList list) -{ - ffesttCaseList next; - - for (next = list->next; next != list; next = next->next) - { - ffelex_token_kill (next->t); - } -} - -/* ffestt_dimlist_append -- Append dim to list of dims - - ffesttDimList list; - ffelexToken t; - ffestt_dimlist_append(list,lower,upper,t); - - list must have already been created by ffestt_dimlist_create. The - list is allocated out of the scratch pool. The token is consumed. */ - -void -ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper, - ffelexToken t) -{ - ffesttDimList new; - - new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool, - "FFEST dim list", sizeof (*new)); - new->next = list->previous->next; - new->previous = list->previous; - new->next->previous = new; - new->previous->next = new; - new->lower = lower; - new->upper = upper; - new->t = t; -} - -/* Convert list of dims into ffebld format. - - ffesttDimList list; - ffeinfoRank rank; - ffebld array_size; - ffebld extents; - ffestt_dimlist_as_expr (list, &rank, &array_size, &extents); - - The dims in the list are converted to a list of ITEMs; the rank of the - array, an expression representing the array size, a list of extent - expressions, and the list of ITEMs are returned. - - If is_ugly_assumed, treat a final dimension with no lower bound - and an upper bound of 1 as a * bound. */ - -ffebld -ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank, - ffebld *array_size, ffebld *extents, - bool is_ugly_assumed) -{ - ffesttDimList next; - ffebld expr; - ffebld as; - ffebld ex; /* List of extents. */ - ffebld ext; /* Extent of a given dimension. */ - ffebldListBottom bottom; - ffeinfoRank r; - ffeinfoKindtype nkt; - ffetargetIntegerDefault low; - ffetargetIntegerDefault high; - bool zero = FALSE; /* Zero-size array. */ - bool any = FALSE; - bool star = FALSE; /* Adjustable array. */ - - assert (list != NULL); - - r = 0; - ffebld_init_list (&expr, &bottom); - for (next = list->next; next != list; next = next->next) - { - ++r; - if (((next->lower == NULL) - || (ffebld_op (next->lower) == FFEBLD_opCONTER)) - && (ffebld_op (next->upper) == FFEBLD_opCONTER)) - { - if (next->lower == NULL) - low = 1; - else - low = ffebld_constant_integerdefault (ffebld_conter (next->lower)); - high = ffebld_constant_integerdefault (ffebld_conter (next->upper)); - if (low - > high) - zero = TRUE; - if ((next->next == list) - && is_ugly_assumed - && (next->lower == NULL) - && (high == 1) - && (ffebld_conter_orig (next->upper) == NULL)) - { - star = TRUE; - ffebld_append_item (&bottom, - ffebld_new_bounds (NULL, ffebld_new_star ())); - continue; - } - } - else if (((next->lower != NULL) - && (ffebld_op (next->lower) == FFEBLD_opANY)) - || (ffebld_op (next->upper) == FFEBLD_opANY)) - any = TRUE; - else if (ffebld_op (next->upper) == FFEBLD_opSTAR) - star = TRUE; - ffebld_append_item (&bottom, - ffebld_new_bounds (next->lower, next->upper)); - } - ffebld_end_list (&bottom); - - if (zero) - { - as = ffebld_new_conter (ffebld_constant_new_integerdefault_val (0)); - ffebld_set_info (as, ffeinfo_new - (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - ex = NULL; - } - else if (any) - { - as = ffebld_new_any (); - ffebld_set_info (as, ffeinfo_new_any ()); - ex = ffebld_copy (as); - } - else if (star) - { - as = ffebld_new_star (); - ex = ffebld_new_star (); /* ~~Should really be list as below. */ - } - else - { - as = NULL; - ffebld_init_list (&ex, &bottom); - for (next = list->next; next != list; next = next->next) - { - if ((next->lower == NULL) - || ((ffebld_op (next->lower) == FFEBLD_opCONTER) - && (ffebld_constant_integerdefault (ffebld_conter - (next->lower)) == 1))) - ext = ffebld_copy (next->upper); - else - { - ext = ffebld_new_subtract (next->upper, next->lower); - nkt - = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER, - ffeinfo_kindtype (ffebld_info - (next->lower)), - ffeinfo_kindtype (ffebld_info - (next->upper))); - ffebld_set_info (ext, - ffeinfo_new (FFEINFO_basictypeINTEGER, - nkt, - 0, - FFEINFO_kindENTITY, - ((ffebld_op (ffebld_left (ext)) - == FFEBLD_opCONTER) - && (ffebld_op (ffebld_right - (ext)) - == FFEBLD_opCONTER)) - ? FFEINFO_whereCONSTANT - : FFEINFO_whereFLEETING, - FFETARGET_charactersizeNONE)); - ffebld_set_left (ext, - ffeexpr_convert_expr (ffebld_left (ext), - next->t, ext, next->t, - FFEEXPR_contextLET)); - ffebld_set_right (ext, - ffeexpr_convert_expr (ffebld_right (ext), - next->t, ext, - next->t, - FFEEXPR_contextLET)); - ext = ffeexpr_collapse_subtract (ext, next->t); - - nkt - = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER, - ffeinfo_kindtype (ffebld_info (ext)), - FFEINFO_kindtypeINTEGERDEFAULT); - ext - = ffebld_new_add (ext, - ffebld_new_conter - (ffebld_constant_new_integerdefault_val - (1))); - ffebld_set_info (ffebld_right (ext), ffeinfo_new - (FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, - 0, - FFEINFO_kindENTITY, - FFEINFO_whereCONSTANT, - FFETARGET_charactersizeNONE)); - ffebld_set_info (ext, - ffeinfo_new (FFEINFO_basictypeINTEGER, - nkt, 0, FFEINFO_kindENTITY, - (ffebld_op (ffebld_left (ext)) - == FFEBLD_opCONTER) - ? FFEINFO_whereCONSTANT - : FFEINFO_whereFLEETING, - FFETARGET_charactersizeNONE)); - ffebld_set_left (ext, - ffeexpr_convert_expr (ffebld_left (ext), - next->t, ext, - next->t, - FFEEXPR_contextLET)); - ffebld_set_right (ext, - ffeexpr_convert_expr (ffebld_right (ext), - next->t, ext, - next->t, - FFEEXPR_contextLET)); - ext = ffeexpr_collapse_add (ext, next->t); - } - ffebld_append_item (&bottom, ext); - if (as == NULL) - as = ext; - else - { - nkt - = ffeinfo_kindtype_max (FFEINFO_basictypeINTEGER, - ffeinfo_kindtype (ffebld_info (as)), - ffeinfo_kindtype (ffebld_info (ext))); - as = ffebld_new_multiply (as, ext); - ffebld_set_info (as, - ffeinfo_new (FFEINFO_basictypeINTEGER, - nkt, 0, FFEINFO_kindENTITY, - ((ffebld_op (ffebld_left (as)) - == FFEBLD_opCONTER) - && (ffebld_op (ffebld_right - (as)) - == FFEBLD_opCONTER)) - ? FFEINFO_whereCONSTANT - : FFEINFO_whereFLEETING, - FFETARGET_charactersizeNONE)); - ffebld_set_left (as, - ffeexpr_convert_expr (ffebld_left (as), - next->t, as, next->t, - FFEEXPR_contextLET)); - ffebld_set_right (as, - ffeexpr_convert_expr (ffebld_right (as), - next->t, as, - next->t, - FFEEXPR_contextLET)); - as = ffeexpr_collapse_multiply (as, next->t); - } - } - ffebld_end_list (&bottom); - as = ffeexpr_convert (as, list->next->t, NULL, - FFEINFO_basictypeINTEGER, - FFEINFO_kindtypeINTEGERDEFAULT, 0, - FFETARGET_charactersizeNONE, - FFEEXPR_contextLET); - } - - *rank = r; - *array_size = as; - *extents = ex; - return expr; -} - -/* ffestt_dimlist_create -- Create new list of dims - - ffesttDimList list; - list = ffestt_dimlist_create(); - - The list is allocated out of the scratch pool. */ - -ffesttDimList -ffestt_dimlist_create () -{ - ffesttDimList new; - - new = (ffesttDimList) malloc_new_kp (ffesta_scratch_pool, - "FFEST dim list root", sizeof (*new)); - new->next = new->previous = new; - new->t = NULL; - new->lower = NULL; - new->upper = NULL; - return new; -} - -/* ffestt_dimlist_dump -- Dump list of dims - - ffesttDimList list; - ffestt_dimlist_dump(list); - - The dims in the list are dumped with commas separating them. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffestt_dimlist_dump (ffesttDimList list) -{ - ffesttDimList next; - - for (next = list->next; next != list; next = next->next) - { - if (next != list->next) - fputc (',', dmpout); - if (next->lower != NULL) - ffebld_dump (next->lower); - fputc (':', dmpout); - if (next->upper != NULL) - ffebld_dump (next->upper); - } -} -#endif - -/* ffestt_dimlist_kill -- Kill list of dims - - ffesttDimList list; - ffestt_dimlist_kill(list); - - The tokens on the list are killed. */ - -void -ffestt_dimlist_kill (ffesttDimList list) -{ - ffesttDimList next; - - for (next = list->next; next != list; next = next->next) - { - ffelex_token_kill (next->t); - } -} - -/* Determine type of list of dimensions. - - Return KNOWN for all-constant bounds, ADJUSTABLE for constant - and variable but no * bounds, ASSUMED for constant and * but - not variable bounds, ADJUSTABLEASSUMED for constant and variable - and * bounds. - - If is_ugly_assumed, treat a final dimension with no lower bound - and an upper bound of 1 as a * bound. */ - -ffestpDimtype -ffestt_dimlist_type (ffesttDimList list, bool is_ugly_assumed) -{ - ffesttDimList next; - ffestpDimtype type; - - if (list == NULL) - return FFESTP_dimtypeNONE; - - type = FFESTP_dimtypeKNOWN; - for (next = list->next; next != list; next = next->next) - { - bool ugly_assumed = FALSE; - - if ((next->next == list) - && is_ugly_assumed - && (next->lower == NULL) - && (next->upper != NULL) - && (ffebld_op (next->upper) == FFEBLD_opCONTER) - && (ffebld_constant_integerdefault (ffebld_conter (next->upper)) - == 1) - && (ffebld_conter_orig (next->upper) == NULL)) - ugly_assumed = TRUE; - - if (next->lower != NULL) - { - if (ffebld_op (next->lower) != FFEBLD_opCONTER) - { - if (type == FFESTP_dimtypeASSUMED) - type = FFESTP_dimtypeADJUSTABLEASSUMED; - else - type = FFESTP_dimtypeADJUSTABLE; - } - } - if (next->upper != NULL) - { - if (ugly_assumed - || (ffebld_op (next->upper) == FFEBLD_opSTAR)) - { - if (type == FFESTP_dimtypeADJUSTABLE) - type = FFESTP_dimtypeADJUSTABLEASSUMED; - else - type = FFESTP_dimtypeASSUMED; - } - else if (ffebld_op (next->upper) != FFEBLD_opCONTER) - type = FFESTP_dimtypeADJUSTABLE; - } - } - - return type; -} - -/* ffestt_exprlist_append -- Append expr to list of exprs - - ffesttExprList list; - ffelexToken t; - ffestt_exprlist_append(list,expr,t); - - list must have already been created by ffestt_exprlist_create. The - list is allocated out of the scratch pool. The token is consumed. */ - -void -ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t) -{ - ffesttExprList new; - - new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool, - "FFEST expr list", sizeof (*new)); - new->next = list->previous->next; - new->previous = list->previous; - new->next->previous = new; - new->previous->next = new; - new->expr = expr; - new->t = t; -} - -/* ffestt_exprlist_create -- Create new list of exprs - - ffesttExprList list; - list = ffestt_exprlist_create(); - - The list is allocated out of the scratch pool. */ - -ffesttExprList -ffestt_exprlist_create () -{ - ffesttExprList new; - - new = (ffesttExprList) malloc_new_kp (ffesta_scratch_pool, - "FFEST expr list root", sizeof (*new)); - new->next = new->previous = new; - new->expr = NULL; - new->t = NULL; - return new; -} - -/* ffestt_exprlist_drive -- Drive list of token pairs into function - - ffesttExprList list; - void fn(ffebld expr,ffelexToken t); - ffestt_exprlist_drive(list,fn); - - The expr/token pairs in the list are passed to the function one pair - at a time. */ - -void -ffestt_exprlist_drive (ffesttExprList list, void (*fn) ()) -{ - ffesttExprList next; - - if (list == NULL) - return; - - for (next = list->next; next != list; next = next->next) - { - (*fn) (next->expr, next->t); - } -} - -/* ffestt_exprlist_dump -- Dump list of exprs - - ffesttExprList list; - ffestt_exprlist_dump(list); - - The exprs in the list are dumped with commas separating them. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffestt_exprlist_dump (ffesttExprList list) -{ - ffesttExprList next; - - for (next = list->next; next != list; next = next->next) - { - if (next != list->next) - fputc (',', dmpout); - ffebld_dump (next->expr); - } -} -#endif - -/* ffestt_exprlist_kill -- Kill list of exprs - - ffesttExprList list; - ffestt_exprlist_kill(list); - - The tokens on the list are killed. - - 02-Mar-90 JCB 1.1 - Don't kill the list itself or change it, since it will be trashed when - ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */ - -void -ffestt_exprlist_kill (ffesttExprList list) -{ - ffesttExprList next; - - for (next = list->next; next != list; next = next->next) - { - ffelex_token_kill (next->t); - } -} - -/* ffestt_formatlist_append -- Append null format to list of formats - - ffesttFormatList list, new; - new = ffestt_formatlist_append(list); - - list must have already been created by ffestt_formatlist_create. The - new item is allocated out of the scratch pool. The caller must initialize - it appropriately. */ - -ffesttFormatList -ffestt_formatlist_append (ffesttFormatList list) -{ - ffesttFormatList new; - - new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool, - "FFEST format list", sizeof (*new)); - new->next = list->previous->next; - new->previous = list->previous; - new->next->previous = new; - new->previous->next = new; - return new; -} - -/* ffestt_formatlist_create -- Create new list of formats - - ffesttFormatList list; - list = ffestt_formatlist_create(NULL); - - The list is allocated out of the scratch pool. */ - -ffesttFormatList -ffestt_formatlist_create (ffesttFormatList parent, ffelexToken t) -{ - ffesttFormatList new; - - new = (ffesttFormatList) malloc_new_kp (ffesta_scratch_pool, - "FFEST format list root", sizeof (*new)); - new->next = new->previous = new; - new->type = FFESTP_formattypeNone; - new->t = t; - new->u.root.parent = parent; - return new; -} - -/* ffestt_formatlist_kill -- Kill tokens on list of formats - - ffesttFormatList list; - ffestt_formatlist_kill(list); - - The tokens on the list are killed. */ - -void -ffestt_formatlist_kill (ffesttFormatList list) -{ - ffesttFormatList next; - - /* Always kill from the very top on down. */ - - while (list->u.root.parent != NULL) - list = list->u.root.parent->next; - - /* Kill first token for this list. */ - - if (list->t != NULL) - ffelex_token_kill (list->t); - - /* Kill each item in this list. */ - - for (next = list->next; next != list; next = next->next) - { - ffelex_token_kill (next->t); - switch (next->type) - { - case FFESTP_formattypeI: - case FFESTP_formattypeB: - case FFESTP_formattypeO: - case FFESTP_formattypeZ: - case FFESTP_formattypeF: - case FFESTP_formattypeE: - case FFESTP_formattypeEN: - case FFESTP_formattypeG: - case FFESTP_formattypeL: - case FFESTP_formattypeA: - case FFESTP_formattypeD: - if (next->u.R1005.R1004.t != NULL) - ffelex_token_kill (next->u.R1005.R1004.t); - if (next->u.R1005.R1006.t != NULL) - ffelex_token_kill (next->u.R1005.R1006.t); - if (next->u.R1005.R1007_or_R1008.t != NULL) - ffelex_token_kill (next->u.R1005.R1007_or_R1008.t); - if (next->u.R1005.R1009.t != NULL) - ffelex_token_kill (next->u.R1005.R1009.t); - break; - - case FFESTP_formattypeQ: - case FFESTP_formattypeDOLLAR: - case FFESTP_formattypeP: - case FFESTP_formattypeT: - case FFESTP_formattypeTL: - case FFESTP_formattypeTR: - case FFESTP_formattypeX: - case FFESTP_formattypeS: - case FFESTP_formattypeSP: - case FFESTP_formattypeSS: - case FFESTP_formattypeBN: - case FFESTP_formattypeBZ: - case FFESTP_formattypeSLASH: - case FFESTP_formattypeCOLON: - if (next->u.R1010.val.t != NULL) - ffelex_token_kill (next->u.R1010.val.t); - break; - - case FFESTP_formattypeR1016: - break; /* Nothing more to do. */ - - case FFESTP_formattypeFORMAT: - if (next->u.R1003D.R1004.t != NULL) - ffelex_token_kill (next->u.R1003D.R1004.t); - next->u.R1003D.format->u.root.parent = NULL; /* Parent already dying. */ - ffestt_formatlist_kill (next->u.R1003D.format); - break; - - default: - assert (FALSE); - } - } -} - -/* ffestt_implist_append -- Append token pair to list of token pairs - - ffesttImpList list; - ffelexToken t; - ffestt_implist_append(list,start_token,end_token); - - list must have already been created by ffestt_implist_create. The - list is allocated out of the scratch pool. The tokens are consumed. */ - -void -ffestt_implist_append (ffesttImpList list, ffelexToken first, ffelexToken last) -{ - ffesttImpList new; - - new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool, - "FFEST token list", sizeof (*new)); - new->next = list->previous->next; - new->previous = list->previous; - new->next->previous = new; - new->previous->next = new; - new->first = first; - new->last = last; -} - -/* ffestt_implist_create -- Create new list of token pairs - - ffesttImpList list; - list = ffestt_implist_create(); - - The list is allocated out of the scratch pool. */ - -ffesttImpList -ffestt_implist_create () -{ - ffesttImpList new; - - new = (ffesttImpList) malloc_new_kp (ffesta_scratch_pool, - "FFEST token list root", - sizeof (*new)); - new->next = new->previous = new; - new->first = NULL; - new->last = NULL; - return new; -} - -/* ffestt_implist_drive -- Drive list of token pairs into function - - ffesttImpList list; - void fn(ffelexToken first,ffelexToken last); - ffestt_implist_drive(list,fn); - - The token pairs in the list are passed to the function one pair at a time. */ - -void -ffestt_implist_drive (ffesttImpList list, void (*fn) ()) -{ - ffesttImpList next; - - if (list == NULL) - return; - - for (next = list->next; next != list; next = next->next) - { - (*fn) (next->first, next->last); - } -} - -/* ffestt_implist_dump -- Dump list of token pairs - - ffesttImpList list; - ffestt_implist_dump(list); - - The token pairs in the list are dumped with commas separating them. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffestt_implist_dump (ffesttImpList list) -{ - ffesttImpList next; - - for (next = list->next; next != list; next = next->next) - { - if (next != list->next) - fputc (',', dmpout); - assert (ffelex_token_type (next->first) == FFELEX_typeNAME); - fputs (ffelex_token_text (next->first), dmpout); - if (next->last != NULL) - { - fputc ('-', dmpout); - assert (ffelex_token_type (next->last) == FFELEX_typeNAME); - fputs (ffelex_token_text (next->last), dmpout); - } - } -} -#endif - -/* ffestt_implist_kill -- Kill list of token pairs - - ffesttImpList list; - ffestt_implist_kill(list); - - The tokens on the list are killed. */ - -void -ffestt_implist_kill (ffesttImpList list) -{ - ffesttImpList next; - - for (next = list->next; next != list; next = next->next) - { - ffelex_token_kill (next->first); - if (next->last != NULL) - ffelex_token_kill (next->last); - } -} - -/* ffestt_tokenlist_append -- Append token to list of tokens - - ffesttTokenList tl; - ffelexToken t; - ffestt_tokenlist_append(tl,t); - - tl must have already been created by ffestt_tokenlist_create. The - list is allocated out of the scratch pool. The token is consumed. */ - -void -ffestt_tokenlist_append (ffesttTokenList tl, ffelexToken t) -{ - ffesttTokenItem ti; - - ti = (ffesttTokenItem) malloc_new_kp (ffesta_scratch_pool, - "FFEST token item", sizeof (*ti)); - ti->next = (ffesttTokenItem) &tl->first; - ti->previous = tl->last; - ti->next->previous = ti; - ti->previous->next = ti; - ti->t = t; - ++tl->count; -} - -/* ffestt_tokenlist_create -- Create new list of tokens - - ffesttTokenList tl; - tl = ffestt_tokenlist_create(); - - The list is allocated out of the scratch pool. */ - -ffesttTokenList -ffestt_tokenlist_create () -{ - ffesttTokenList tl; - - tl = (ffesttTokenList) malloc_new_kp (ffesta_scratch_pool, - "FFEST token list", sizeof (*tl)); - tl->first = tl->last = (ffesttTokenItem) &tl->first; - tl->count = 0; - return tl; -} - -/* ffestt_tokenlist_drive -- Drive list of tokens - - ffesttTokenList tl; - void fn(ffelexToken t); - ffestt_tokenlist_drive(tl,fn); - - The tokens in the list are passed to the given function. */ - -void -ffestt_tokenlist_drive (ffesttTokenList tl, void (*fn) ()) -{ - ffesttTokenItem ti; - - if (tl == NULL) - return; - - for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next) - { - (*fn) (ti->t); - } -} - -/* ffestt_tokenlist_dump -- Dump list of tokens - - ffesttTokenList tl; - ffestt_tokenlist_dump(tl); - - The tokens in the list are dumped with commas separating them. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffestt_tokenlist_dump (ffesttTokenList tl) -{ - ffesttTokenItem ti; - - for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next) - { - if (ti != tl->first) - fputc (',', dmpout); - switch (ffelex_token_type (ti->t)) - { - case FFELEX_typeNUMBER: - case FFELEX_typeNAME: - case FFELEX_typeNAMES: - fputs (ffelex_token_text (ti->t), dmpout); - break; - - case FFELEX_typeASTERISK: - fputc ('*', dmpout); - break; - - default: - assert (FALSE); - fputc ('?', dmpout); - break; - } - } -} -#endif - -/* ffestt_tokenlist_handle -- Handle list of tokens - - ffesttTokenList tl; - ffelexHandler handler; - handler = ffestt_tokenlist_handle(tl,handler); - - The tokens in the list are passed to the handler(s). */ - -ffelexHandler -ffestt_tokenlist_handle (ffesttTokenList tl, ffelexHandler handler) -{ - ffesttTokenItem ti; - - for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next) - handler = (ffelexHandler) (*handler) (ti->t); - - return (ffelexHandler) handler; -} - -/* ffestt_tokenlist_kill -- Kill list of tokens - - ffesttTokenList tl; - ffestt_tokenlist_kill(tl); - - The tokens on the list are killed. - - 02-Mar-90 JCB 1.1 - Don't kill the list itself or change it, since it will be trashed when - ffesta_scratch_pool is killed anyway, so kill only the lex tokens. */ - -void -ffestt_tokenlist_kill (ffesttTokenList tl) -{ - ffesttTokenItem ti; - - for (ti = tl->first; ti != (ffesttTokenItem) &tl->first; ti = ti->next) - { - ffelex_token_kill (ti->t); - } -} diff --git a/gcc/f/stt.h b/gcc/f/stt.h deleted file mode 100755 index 38ffa41..0000000 --- a/gcc/f/stt.h +++ /dev/null @@ -1,230 +0,0 @@ -/* stt.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stt.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stt -#define _H_f_stt - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffest_case_list_ *ffesttCaseList; -typedef struct _ffest_dim_list_ *ffesttDimList; -typedef struct _ffest_expr_list_ *ffesttExprList; -typedef struct _ffest_format_value_ ffesttFormatValue; -typedef struct _ffest_format_list_ *ffesttFormatList; -typedef struct _ffest_imp_list_ *ffesttImpList; -typedef struct _ffest_token_item_ *ffesttTokenItem; -typedef struct _ffest_token_list_ *ffesttTokenList; - -/* Include files needed by this one. */ - -#include "top.h" -#include "bld.h" -#include "info.h" -#include "lex.h" -#include "stp.h" - -/* Structure definitions. */ - -struct _ffest_case_list_ - { - ffesttCaseList next; - ffesttCaseList previous; - ffelexToken t; - ffebld expr1; - ffebld expr2; - bool range; /* TRUE if "[expr1]:[expr2]", FALSE if - "expr1". */ - }; - -struct _ffest_dim_list_ - { - ffesttDimList next; - ffesttDimList previous; - ffelexToken t; - ffebld lower; - ffebld upper; - }; - -struct _ffest_expr_list_ - { - ffesttExprList next; - ffesttExprList previous; - ffelexToken t; - ffebld expr; - }; - -struct _ffest_token_item_ - { - ffesttTokenItem next; - ffesttTokenItem previous; - ffelexToken t; - }; - -struct _ffest_token_list_ - { - ffesttTokenItem first; - ffesttTokenItem last; - int count; /* Number of tokens in list. */ - }; - -struct _ffest_format_value_ - { - bool present; /* TRUE if value supplied (needed for - optional values only). */ - bool rtexpr; /* FALSE if constant value here, TRUE if - run-time expr (VXT). */ - ffelexToken t; /* The first token, or perhaps just prior if - can't get it. */ - union - { - ffeUnionLongPtr unused; /* Make sure all the info gets copied. */ - long signed_val; /* for R1011. */ - unsigned long unsigned_val; /* For other constant values. */ - ffebld expr; /* For run-time expression (VXT). */ - } - u; - }; - -struct _ffest_format_list_ - { - ffesttFormatList next; - ffesttFormatList previous; - ffelexToken t; /* The NAME, CHARACTER, or HOLLERITH token. */ - ffestpFormatType type; - union ffest_format_ - { - struct - { - ffesttFormatValue R1004; /* r, the repeat count. */ - ffesttFormatValue R1006; /* w, the field width. */ - ffesttFormatValue R1007_or_R1008; /* m, the minimum number of - digits; d, the number of - decimal digits. */ - ffesttFormatValue R1009; /* e, the number of exponent digits. */ - } - R1005; /* data-edit-desc. */ - struct - { - ffesttFormatValue val; /* r, the repeat count; k, the - precision magnitude adjustment; n, - the column number (abs or rel). */ - } - R1010; /* control-edit-desc. */ - struct - { - ffesttFormatValue R1004; /* r, the repeat count. */ - ffesttFormatList format; /* the parenthesized - format-item-list. */ - } - R1003D; /* format-item of for [r](format-item-list). */ - struct - { - ffesttFormatList parent; /* NULL if outer list, else parent - item. */ - } - root; /* FFESTP_formattypeNone case. */ - } - u; - }; - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -void ffestt_caselist_append (ffesttCaseList list, bool range, ffebld case1, - ffebld case2, ffelexToken t); -ffesttCaseList ffestt_caselist_create (void); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_caselist_dump (ffesttCaseList list); -#endif -void ffestt_caselist_kill (ffesttCaseList list); -void ffestt_dimlist_append (ffesttDimList list, ffebld lower, ffebld upper, - ffelexToken t); -ffebld ffestt_dimlist_as_expr (ffesttDimList list, ffeinfoRank *rank, - ffebld *array_size, ffebld *extents, - bool is_ugly_assumed); -ffesttDimList ffestt_dimlist_create (void); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_dimlist_dump (ffesttDimList list); -#endif -void ffestt_dimlist_kill (ffesttDimList list); -ffestpDimtype ffestt_dimlist_type (ffesttDimList dims, bool is_ugly_assumed); -void ffestt_exprlist_append (ffesttExprList list, ffebld expr, ffelexToken t); -ffesttExprList ffestt_exprlist_create (void); -void ffestt_exprlist_drive (ffesttExprList list, void (*fn) ()); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_exprlist_dump (ffesttExprList list); -#endif -void ffestt_exprlist_kill (ffesttExprList list); -ffesttFormatList ffestt_formatlist_append (ffesttFormatList list); -ffesttFormatList ffestt_formatlist_create (ffesttFormatList parent, - ffelexToken t); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_formatlist_dump (ffesttFormatList list); -#endif -void ffestt_formatlist_kill (ffesttFormatList list); -void ffestt_implist_append (ffesttImpList list, ffelexToken first, - ffelexToken last); -ffesttImpList ffestt_implist_create (void); -void ffestt_implist_drive (ffesttImpList list, void (*fn) ()); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_implist_dump (ffesttImpList list); -#endif -void ffestt_implist_kill (ffesttImpList list); -void ffestt_tokenlist_append (ffesttTokenList list, ffelexToken t); -ffesttTokenList ffestt_tokenlist_create (void); -void ffestt_tokenlist_drive (ffesttTokenList list, void (*fn) ()); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffestt_tokenlist_dump (ffesttTokenList list); -#endif -ffelexHandler ffestt_tokenlist_handle (ffesttTokenList list, - ffelexHandler handler); -void ffestt_tokenlist_kill (ffesttTokenList list); - -/* Define macros. */ - -#define ffestt_init_0() -#define ffestt_init_1() -#define ffestt_init_2() -#define ffestt_init_3() -#define ffestt_init_4() -#define ffestt_terminate_0() -#define ffestt_terminate_1() -#define ffestt_terminate_2() -#define ffestt_terminate_3() -#define ffestt_terminate_4() -#define ffestt_tokenlist_count(tl) ((tl)->count) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stu.c b/gcc/f/stu.c deleted file mode 100755 index 7dcbdcb..0000000 --- a/gcc/f/stu.c +++ /dev/null @@ -1,1161 +0,0 @@ -/* stu.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - -*/ - -/* Include files. */ - -#include "proj.h" -#include "bld.h" -#include "com.h" -#include "equiv.h" -#include "global.h" -#include "info.h" -#include "implic.h" -#include "intrin.h" -#include "stu.h" -#include "storag.h" -#include "sta.h" -#include "symbol.h" -#include "target.h" - -/* Externals defined here. */ - - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - -static void ffestu_list_exec_transition_ (ffebld list); -static bool ffestu_symter_end_transition_ (ffebld expr); -static bool ffestu_symter_exec_transition_ (ffebld expr); -static bool ffestu_dummies_transition_ (ffesymbol (*symfunc) (), - ffebld list); - -/* Internal macros. */ - -#define ffestu_equiv_(s) (((ffesymbol_equiv (s) == NULL) \ - || (ffeequiv_common (ffesymbol_equiv (s)) == NULL)) ? FFEINFO_whereLOCAL \ - : FFEINFO_whereCOMMON) - -/* Update symbol info just before end of unit. */ - -ffesymbol -ffestu_sym_end_transition (ffesymbol s) -{ - ffeinfoKind skd; - ffeinfoWhere swh; - ffeinfoKind nkd; - ffeinfoWhere nwh; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffesymbolState ss; - ffesymbolState ns; - bool needs_type = TRUE; /* Implicit type assignment might be - necessary. */ - - assert (s != NULL); - ss = ffesymbol_state (s); - sa = ffesymbol_attrs (s); - skd = ffesymbol_kind (s); - swh = ffesymbol_where (s); - - switch (ss) - { - case FFESYMBOL_stateUNCERTAIN: - if ((swh == FFEINFO_whereDUMMY) - && (ffesymbol_numentries (s) == 0)) - { /* Not actually in any dummy list! */ - ffesymbol_error (s, ffesta_tokens[0]); - return s; - } - else if (((swh == FFEINFO_whereLOCAL) - || (swh == FFEINFO_whereNONE)) - && (skd == FFEINFO_kindENTITY) - && ffestu_symter_end_transition_ (ffesymbol_dims (s))) - { /* Bad dimension expressions. */ - ffesymbol_error (s, NULL); - return s; - } - break; - - case FFESYMBOL_stateUNDERSTOOD: - if ((swh == FFEINFO_whereLOCAL) - && ((skd == FFEINFO_kindFUNCTION) - || (skd == FFEINFO_kindSUBROUTINE))) - { - int n_args; - ffebld list; - ffebld item; - ffeglobalArgSummary as; - ffeinfoBasictype bt; - ffeinfoKindtype kt; - bool array; - char *name = NULL; - - ffestu_dummies_transition_ (ffecom_sym_end_transition, - ffesymbol_dummyargs (s)); - - n_args = ffebld_list_length (ffesymbol_dummyargs (s)); - ffeglobal_proc_def_nargs (s, n_args); - for (list = ffesymbol_dummyargs (s), n_args = 0; - list != NULL; - list = ffebld_trail (list), ++n_args) - { - item = ffebld_head (list); - array = FALSE; - if (item != NULL) - { - bt = ffeinfo_basictype (ffebld_info (item)); - kt = ffeinfo_kindtype (ffebld_info (item)); - array = (ffeinfo_rank (ffebld_info (item)) > 0); - switch (ffebld_op (item)) - { - case FFEBLD_opSTAR: - as = FFEGLOBAL_argsummaryALTRTN; - break; - - case FFEBLD_opSYMTER: - name = ffesymbol_text (ffebld_symter (item)); - as = FFEGLOBAL_argsummaryNONE; - - switch (ffeinfo_kind (ffebld_info (item))) - { - case FFEINFO_kindFUNCTION: - as = FFEGLOBAL_argsummaryFUNC; - break; - - case FFEINFO_kindSUBROUTINE: - as = FFEGLOBAL_argsummarySUBR; - break; - - case FFEINFO_kindNONE: - as = FFEGLOBAL_argsummaryPROC; - break; - - default: - break; - } - - if (as != FFEGLOBAL_argsummaryNONE) - break; - - /* Fall through. */ - default: - if (bt == FFEINFO_basictypeCHARACTER) - as = FFEGLOBAL_argsummaryDESCR; - else - as = FFEGLOBAL_argsummaryREF; - break; - } - } - else - { - as = FFEGLOBAL_argsummaryNONE; - bt = FFEINFO_basictypeNONE; - kt = FFEINFO_kindtypeNONE; - } - ffeglobal_proc_def_arg (s, n_args, name, as, bt, kt, array); - } - } - else if (swh == FFEINFO_whereDUMMY) - { - if (ffesymbol_numentries (s) == 0) - { /* Not actually in any dummy list! */ - ffesymbol_error (s, ffesta_tokens[0]); - return s; - } - if (ffestu_symter_end_transition_ (ffesymbol_dims (s))) - { /* Bad dimension expressions. */ - ffesymbol_error (s, NULL); - return s; - } - } - else if ((swh == FFEINFO_whereLOCAL) - && ffestu_symter_end_transition_ (ffesymbol_dims (s))) - { /* Bad dimension expressions. */ - ffesymbol_error (s, NULL); - return s; - } - - ffestorag_end_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - - default: - assert ("bad status" == NULL); - return s; - } - - ns = FFESYMBOL_stateUNDERSTOOD; - na = sa = ffesymbol_attrs (s); - - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - nkd = skd; - nwh = swh; - - /* Figure out what kind of object we've got based on previous declarations - of or references to the object. */ - - if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsACTUALARG - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - nwh = FFEINFO_whereGLOBAL; - else - /* Not TYPE. */ - { - if (sa & FFESYMBOL_attrsDUMMY) - { /* Not TYPE. */ - ns = FFESYMBOL_stateUNCERTAIN; /* FUNCTION/SUBROUTINE. */ - needs_type = FALSE; /* Don't assign type to SUBROUTINE! */ - } - else if (sa & FFESYMBOL_attrsACTUALARG) - { /* Not DUMMY or TYPE. */ - ns = FFESYMBOL_stateUNCERTAIN; /* FUNCTION/SUBROUTINE. */ - needs_type = FALSE; /* Don't assign type to SUBROUTINE! */ - } - else - /* Not ACTUALARG, DUMMY, or TYPE. */ - { /* This is an assumption, essentially. */ - nkd = FFEINFO_kindBLOCKDATA; - nwh = FFEINFO_whereGLOBAL; - needs_type = FALSE; - } - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - /* Honestly, this appears to be a guess. I can't find anyplace in the - standard that makes clear whether this unreferenced dummy argument - is an ENTITY or a FUNCTION. And yet, for the f2c interface, picking - one is critical for CHARACTER entities because it determines whether - to expect an additional argument specifying the length of an ENTITY - that is not expected (or needed) for a FUNCTION. HOWEVER, F90 makes - this guess a correct one, and it does seem that the Section 18 Notes - in Appendix B of F77 make it clear the F77 standard at least - intended to make this guess correct as well, so this seems ok. */ - - nkd = FFEINFO_kindENTITY; - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsTYPE))); - - if (ffestu_symter_end_transition_ (ffesymbol_dims (s))) - { - ffesymbol_error (s, NULL); - return s; - } - - if (sa & FFESYMBOL_attrsADJUSTABLE) - { /* Not actually in any dummy list! */ - if (ffe_is_pedantic () - && ffebad_start_msg ("Local adjustable symbol `%A' at %0", - FFEBAD_severityPEDANTIC)) - { - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffesymbol_where_line (s), - ffesymbol_where_column (s)); - ffebad_finish (); - } - } - nwh = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & ~(FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - nwh = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsTYPE - | FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG))); - - if (sa & FFESYMBOL_attrsANYLEN) - { /* Can't touch this. */ - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, NULL, FALSE); - ffestorag_end_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - } - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereLOCAL; - } - else - assert ("unexpected attribute set" == NULL); - - /* Now see what we've got for a new object: NONE means a new error cropped - up; ANY means an old error to be ignored; otherwise, everything's ok, - update the object (symbol) and continue on. */ - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, ffesta_tokens[0]); - else if (!(na & FFESYMBOL_attrsANY)) - { - ffesymbol_signal_change (s); - ffesymbol_set_attrs (s, na); /* Establish new info. */ - ffesymbol_set_state (s, ns); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - nkd, - nwh, - ffesymbol_size (s))); - if (needs_type && !ffeimplic_establish_symbol (s)) - ffesymbol_error (s, ffesta_tokens[0]); - else - ffesymbol_resolve_intrin (s); - s = ffecom_sym_learned (s); - ffesymbol_reference (s, NULL, FALSE); - ffestorag_end_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* ffestu_sym_exec_transition -- Update symbol just before first exec stmt - - ffesymbol s; - ffestu_sym_exec_transition(s); */ - -ffesymbol -ffestu_sym_exec_transition (ffesymbol s) -{ - ffeinfoKind skd; - ffeinfoWhere swh; - ffeinfoKind nkd; - ffeinfoWhere nwh; - ffesymbolAttrs sa; - ffesymbolAttrs na; - ffesymbolState ss; - ffesymbolState ns; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - bool needs_type = TRUE; /* Implicit type assignment might be - necessary. */ - bool resolve_intrin = TRUE; /* Might need to resolve intrinsic. */ - - assert (s != NULL); - - sa = ffesymbol_attrs (s); - skd = ffesymbol_kind (s); - swh = ffesymbol_where (s); - ss = ffesymbol_state (s); - - switch (ss) - { - case FFESYMBOL_stateNONE: - return s; /* Assume caller will handle it. */ - - case FFESYMBOL_stateSEEN: - break; - - case FFESYMBOL_stateUNCERTAIN: - ffestorag_exec_layout (s); - return s; /* Already processed this one, or not - necessary. */ - - case FFESYMBOL_stateUNDERSTOOD: - if (skd == FFEINFO_kindNAMELIST) - { - ffebld_end_list (ffesymbol_ptr_to_listbottom (s)); - ffestu_list_exec_transition_ (ffesymbol_namelist (s)); - } - else if ((swh == FFEINFO_whereLOCAL) - && ((skd == FFEINFO_kindFUNCTION) - || (skd == FFEINFO_kindSUBROUTINE))) - { - ffestu_dummies_transition_ (ffecom_sym_exec_transition, - ffesymbol_dummyargs (s)); - if ((skd == FFEINFO_kindFUNCTION) - && !ffeimplic_establish_symbol (s)) - ffesymbol_error (s, ffesta_tokens[0]); - } - - ffesymbol_reference (s, NULL, FALSE); - ffestorag_exec_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - - default: - assert ("bad status" == NULL); - return s; - } - - ns = FFESYMBOL_stateUNDERSTOOD; /* Only a few UNCERTAIN exceptions. */ - - na = sa; - nkd = skd; - nwh = swh; - - assert (!(sa & FFESYMBOL_attrsANY)); - - if (sa & FFESYMBOL_attrsCOMMON) - { - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereCOMMON; - } - else if (sa & FFESYMBOL_attrsRESULT) - { /* Result variable for function. */ - assert (!(sa & ~(FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereRESULT; - } - else if (sa & FFESYMBOL_attrsSFUNC) - { /* Statement function. */ - assert (!(sa & ~(FFESYMBOL_attrsSFUNC - | FFESYMBOL_attrsTYPE))); - - nkd = FFEINFO_kindFUNCTION; - nwh = FFEINFO_whereCONSTANT; - } - else if (sa & FFESYMBOL_attrsEXTERNAL) - { - assert (!(sa & ~(FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsTYPE))); - - if (sa & FFESYMBOL_attrsTYPE) - { - nkd = FFEINFO_kindFUNCTION; - - if (sa & FFESYMBOL_attrsDUMMY) - nwh = FFEINFO_whereDUMMY; - else - { - if (ffesta_is_entry_valid) - { - nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL. */ - ns = FFESYMBOL_stateUNCERTAIN; - } - else - nwh = FFEINFO_whereGLOBAL; - } - } - else - /* No TYPE. */ - { - nkd = FFEINFO_kindNONE; /* FUNCTION, SUBROUTINE, BLOCKDATA. */ - needs_type = FALSE; /* Only gets type if FUNCTION. */ - ns = FFESYMBOL_stateUNCERTAIN; - - if (sa & FFESYMBOL_attrsDUMMY) - nwh = FFEINFO_whereDUMMY; /* Not BLOCKDATA. */ - else - { - if (ffesta_is_entry_valid) - nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL. */ - else - nwh = FFEINFO_whereGLOBAL; - } - } - } - else if (sa & FFESYMBOL_attrsDUMMY) - { - assert (!(sa & FFESYMBOL_attrsEXTERNAL)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE /* Possible. */ - | FFESYMBOL_attrsADJUSTS /* Possible. */ - | FFESYMBOL_attrsANYLEN /* Possible. */ - | FFESYMBOL_attrsANYSIZE /* Possible. */ - | FFESYMBOL_attrsARRAY /* Possible. */ - | FFESYMBOL_attrsDUMMY /* Have it. */ - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsSFARG /* Possible. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nwh = FFEINFO_whereDUMMY; - - if (ffestu_symter_exec_transition_ (ffesymbol_dims (s))) - na = FFESYMBOL_attrsetNONE; - - if (sa & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSFARG)) - nkd = FFEINFO_kindENTITY; - else if (sa & FFESYMBOL_attrsDUMMY) /* Still okay. */ - { - if (!(sa & FFESYMBOL_attrsTYPE)) - needs_type = FALSE; /* Don't assign type to SUBROUTINE! */ - nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION, SUBROUTINE. */ - ns = FFESYMBOL_stateUNCERTAIN; - } - } - else if (sa & FFESYMBOL_attrsADJUSTS) - { /* Must be DUMMY or COMMON at some point. */ - assert (!(sa & (FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS /* Have it. */ - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV /* Possible. */ - | FFESYMBOL_attrsINIT /* Possible. */ - | FFESYMBOL_attrsNAMELIST /* Possible. */ - | FFESYMBOL_attrsSFARG /* Possible. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - - if (sa & FFESYMBOL_attrsEQUIV) - { - if ((ffesymbol_equiv (s) == NULL) - || (ffeequiv_common (ffesymbol_equiv (s)) == NULL)) - na = FFESYMBOL_attrsetNONE; /* Not equiv'd into COMMON. */ - else - nwh = FFEINFO_whereCOMMON; - } - else if (!ffesta_is_entry_valid - || (sa & (FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST))) - na = FFESYMBOL_attrsetNONE; - else - nwh = FFEINFO_whereDUMMY; - } - else if (sa & FFESYMBOL_attrsSAVE) - { - assert (!(sa & ~(FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsTYPE))); - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsEQUIV) - { - assert (!(sa & FFESYMBOL_attrsCOMMON)); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS /* Possible. */ - | FFESYMBOL_attrsARRAY /* Possible. */ - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV /* Have it. */ - | FFESYMBOL_attrsINIT /* Possible. */ - | FFESYMBOL_attrsNAMELIST /* Possible. */ - | FFESYMBOL_attrsSAVE /* Possible. */ - | FFESYMBOL_attrsSFARG /* Possible. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - nwh = ffestu_equiv_ (s); - } - else if (sa & FFESYMBOL_attrsNAMELIST) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsSAVE))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY /* Possible. */ - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT /* Possible. */ - | FFESYMBOL_attrsNAMELIST /* Have it. */ - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG /* Possible. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsINIT) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsARRAY /* Possible. */ - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT /* Have it. */ - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG /* Possible. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - nwh = FFEINFO_whereLOCAL; - } - else if (sa & FFESYMBOL_attrsSFARG) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG /* Have it. */ - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - - if (ffesta_is_entry_valid) - { - nwh = FFEINFO_whereNONE; /* DUMMY, LOCAL. */ - ns = FFESYMBOL_stateUNCERTAIN; - } - else - nwh = FFEINFO_whereLOCAL; - } - else if (sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE)) - { - assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsTYPE))); - - nkd = FFEINFO_kindENTITY; - - if (ffestu_symter_exec_transition_ (ffesymbol_dims (s))) - na = FFESYMBOL_attrsetNONE; - - if (sa & (FFESYMBOL_attrsANYLEN | FFESYMBOL_attrsANYSIZE)) - nwh = FFEINFO_whereDUMMY; - else if (sa & (FFESYMBOL_attrsADJUSTABLE | FFESYMBOL_attrsANYSIZE)) - /* Still okay. */ - { - nwh = FFEINFO_whereNONE; /* DUMMY, LOCAL. */ - ns = FFESYMBOL_stateUNCERTAIN; - } - } - else if (sa & FFESYMBOL_attrsARRAY) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN /* Possible. */ - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY /* Have it. */ - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsTYPE))); /* Possible. */ - - nkd = FFEINFO_kindENTITY; - - if (sa & FFESYMBOL_attrsANYLEN) - { - assert (ffesta_is_entry_valid); /* Already diagnosed. */ - nwh = FFEINFO_whereDUMMY; - } - else - { - if (ffesta_is_entry_valid) - { - nwh = FFEINFO_whereNONE; /* DUMMY, LOCAL. */ - ns = FFESYMBOL_stateUNCERTAIN; - } - else - nwh = FFEINFO_whereLOCAL; - } - } - else if (sa & FFESYMBOL_attrsANYLEN) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsRESULT))); /* Handled above. */ - assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsANYLEN /* Have it. */ - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsTYPE))); /* Have it too. */ - - if (ffesta_is_entry_valid) - { - nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION. */ - nwh = FFEINFO_whereNONE; /* DUMMY, INTRINSIC, RESULT. */ - ns = FFESYMBOL_stateUNCERTAIN; - resolve_intrin = FALSE; - } - else if (ffeintrin_is_intrinsic (ffesymbol_text (s), NULL, FALSE, - &gen, &spec, &imp)) - { - ffesymbol_signal_change (s); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_set_generic (s, gen); - ffesymbol_set_specific (s, spec); - ffesymbol_set_implementation (s, imp); - ffesymbol_set_info (s, - ffeinfo_new (FFEINFO_basictypeNONE, - FFEINFO_kindtypeNONE, - 0, - FFEINFO_kindNONE, - FFEINFO_whereINTRINSIC, - FFETARGET_charactersizeNONE)); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, NULL, FALSE); - ffestorag_exec_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - } - else - { /* SPECIAL: can't have CHAR*(*) var in - PROGRAM/BLOCKDATA, unless it isn't - referenced anywhere in the code. */ - ffesymbol_signal_change (s); /* Can't touch this. */ - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, NULL, FALSE); - ffestorag_exec_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - return s; - } - } - else if (sa & FFESYMBOL_attrsTYPE) - { - assert (!(sa & (FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsSFUNC))); - assert (!(sa & ~(FFESYMBOL_attrsADJUSTABLE - | FFESYMBOL_attrsADJUSTS - | FFESYMBOL_attrsANYLEN - | FFESYMBOL_attrsANYSIZE - | FFESYMBOL_attrsARRAY - | FFESYMBOL_attrsCOMMON - | FFESYMBOL_attrsDUMMY - | FFESYMBOL_attrsEQUIV - | FFESYMBOL_attrsEXTERNAL - | FFESYMBOL_attrsINIT - | FFESYMBOL_attrsINTRINSIC /* UNDERSTOOD. */ - | FFESYMBOL_attrsNAMELIST - | FFESYMBOL_attrsRESULT - | FFESYMBOL_attrsSAVE - | FFESYMBOL_attrsSFARG - | FFESYMBOL_attrsSFUNC - | FFESYMBOL_attrsTYPE))); /* Have it. */ - - nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION. */ - nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL, INTRINSIC, LOCAL, RESULT. */ - ns = FFESYMBOL_stateUNCERTAIN; - resolve_intrin = FALSE; - } - else if (sa & (FFESYMBOL_attrsCBLOCK | FFESYMBOL_attrsSAVECBLOCK)) - { /* COMMON block. */ - assert (!(sa & ~(FFESYMBOL_attrsCBLOCK - | FFESYMBOL_attrsSAVECBLOCK))); - - if (sa & FFESYMBOL_attrsCBLOCK) - ffebld_end_list (ffesymbol_ptr_to_listbottom (s)); - else - ffesymbol_set_commonlist (s, NULL); - ffestu_list_exec_transition_ (ffesymbol_commonlist (s)); - nkd = FFEINFO_kindCOMMON; - nwh = FFEINFO_whereLOCAL; - needs_type = FALSE; - } - else - { /* First seen in stmt func definition. */ - assert (sa == FFESYMBOL_attrsetNONE); - assert ("Why are we here again?" == NULL); /* ~~~~~ */ - - nkd = FFEINFO_kindNONE; /* ENTITY, FUNCTION. */ - nwh = FFEINFO_whereNONE; /* DUMMY, GLOBAL, LOCAL. */ - ns = FFESYMBOL_stateUNCERTAIN; /* Will get repromoted by caller. */ - needs_type = FALSE; - } - - if (na == FFESYMBOL_attrsetNONE) - ffesymbol_error (s, ffesta_tokens[0]); - else if (!(na & FFESYMBOL_attrsANY) - && (needs_type || (nkd != skd) || (nwh != swh) - || (na != sa) || (ns != ss))) - { - ffesymbol_signal_change (s); - ffesymbol_set_attrs (s, na); /* Establish new info. */ - ffesymbol_set_state (s, ns); - if ((ffesymbol_common (s) == NULL) - && (ffesymbol_equiv (s) != NULL)) - ffesymbol_set_common (s, ffeequiv_common (ffesymbol_equiv (s))); - ffesymbol_set_info (s, - ffeinfo_new (ffesymbol_basictype (s), - ffesymbol_kindtype (s), - ffesymbol_rank (s), - nkd, - nwh, - ffesymbol_size (s))); - if (needs_type && !ffeimplic_establish_symbol (s)) - ffesymbol_error (s, ffesta_tokens[0]); - else if (resolve_intrin) - ffesymbol_resolve_intrin (s); - ffesymbol_reference (s, NULL, FALSE); - ffestorag_exec_layout (s); - ffesymbol_signal_unreported (s); /* For debugging purposes. */ - } - - return s; -} - -/* ffestu_list_exec_transition_ -- Update SYMTERs in ITEM list w/in symbol - - ffebld list; - ffestu_list_exec_transition_(list); - - list contains an FFEBLD_opITEM list of SYMTERs (possibly STARs and - other things, too, but we'll ignore the known ones). For each SYMTER, - we run sym_exec_transition_ on the corresponding ffesymbol (a recursive - call, since that's the function that's calling us) to update it's - information. Then we copy that information into the SYMTER. - - Make sure we don't get called recursively ourselves! */ - -static void -ffestu_list_exec_transition_ (ffebld list) -{ - static bool in_progress = FALSE; - ffebld item; - ffesymbol symbol; - - assert (!in_progress); - in_progress = TRUE; - - for (; list != NULL; list = ffebld_trail (list)) - { - if ((item = ffebld_head (list)) == NULL) - continue; /* Try next item. */ - - switch (ffebld_op (item)) - { - case FFEBLD_opSTAR: - break; - - case FFEBLD_opSYMTER: - symbol = ffebld_symter (item); - if (symbol == NULL) - break; /* Detached from stmt func dummy list. */ - symbol = ffecom_sym_exec_transition (symbol); - assert (ffesymbol_kind (symbol) != FFEINFO_kindNONE); - assert (ffesymbol_where (symbol) != FFEINFO_whereNONE); - ffebld_set_info (item, ffesymbol_info (symbol)); - break; - - default: - assert ("Unexpected item on list" == NULL); - break; - } - } - - in_progress = FALSE; -} - -/* ffestu_symter_end_transition_ -- Update SYMTERs in expr w/in symbol - - ffebld expr; - ffestu_symter_end_transition_(expr); - - Any SYMTER in expr's tree with whereNONE gets updated to the - (recursively transitioned) sym it identifies (DUMMY or COMMON). */ - -static bool -ffestu_symter_end_transition_ (ffebld expr) -{ - ffesymbol symbol; - bool any = FALSE; - - /* Label used for tail recursion (reset expr and go here instead of calling - self). */ - -tail: /* :::::::::::::::::::: */ - - if (expr == NULL) - return any; - - switch (ffebld_op (expr)) - { - case FFEBLD_opITEM: - while (ffebld_trail (expr) != NULL) - { - if (ffestu_symter_end_transition_ (ffebld_head (expr))) - any = TRUE; - expr = ffebld_trail (expr); - } - expr = ffebld_head (expr); - goto tail; /* :::::::::::::::::::: */ - - case FFEBLD_opSYMTER: - symbol = ffecom_sym_end_transition (ffebld_symter (expr)); - if ((symbol != NULL) - && ffesymbol_attr (symbol, FFESYMBOL_attrANY)) - any = TRUE; - ffebld_set_info (expr, ffesymbol_info (symbol)); - break; - - case FFEBLD_opANY: - return TRUE; - - default: - break; - } - - switch (ffebld_arity (expr)) - { - case 2: - if (ffestu_symter_end_transition_ (ffebld_left (expr))) - any = TRUE; - expr = ffebld_right (expr); - goto tail; /* :::::::::::::::::::: */ - - case 1: - expr = ffebld_left (expr); - goto tail; /* :::::::::::::::::::: */ - - default: - break; - } - - return any; -} - -/* ffestu_symter_exec_transition_ -- Update SYMTERs in expr w/in symbol - - ffebld expr; - ffestu_symter_exec_transition_(expr); - - Any SYMTER in expr's tree with whereNONE gets updated to the - (recursively transitioned) sym it identifies (DUMMY or COMMON). */ - -static bool -ffestu_symter_exec_transition_ (ffebld expr) -{ - ffesymbol symbol; - bool any = FALSE; - - /* Label used for tail recursion (reset expr and go here instead of calling - self). */ - -tail: /* :::::::::::::::::::: */ - - if (expr == NULL) - return any; - - switch (ffebld_op (expr)) - { - case FFEBLD_opITEM: - while (ffebld_trail (expr) != NULL) - { - if (ffestu_symter_exec_transition_ (ffebld_head (expr))) - any = TRUE; - expr = ffebld_trail (expr); - } - expr = ffebld_head (expr); - goto tail; /* :::::::::::::::::::: */ - - case FFEBLD_opSYMTER: - symbol = ffecom_sym_exec_transition (ffebld_symter (expr)); - if ((symbol != NULL) - && ffesymbol_attr (symbol, FFESYMBOL_attrANY)) - any = TRUE; - ffebld_set_info (expr, ffesymbol_info (symbol)); - break; - - case FFEBLD_opANY: - return TRUE; - - default: - break; - } - - switch (ffebld_arity (expr)) - { - case 2: - if (ffestu_symter_exec_transition_ (ffebld_left (expr))) - any = TRUE; - expr = ffebld_right (expr); - goto tail; /* :::::::::::::::::::: */ - - case 1: - expr = ffebld_left (expr); - goto tail; /* :::::::::::::::::::: */ - - default: - break; - } - - return any; -} - -/* ffestu_dummies_transition_ -- Update SYMTERs in ITEM list w/in entry - - ffebld list; - ffesymbol symfunc(ffesymbol s); - if (ffestu_dummies_transition_(symfunc,list)) - // One or more items are still UNCERTAIN. - - list contains an FFEBLD_opITEM list of SYMTERs (possibly STARs and - other things, too, but we'll ignore the known ones). For each SYMTER, - we run symfunc on the corresponding ffesymbol (a recursive - call, since that's the function that's calling us) to update it's - information. Then we copy that information into the SYMTER. - - Return TRUE if any of the SYMTER's has incomplete information. - - Make sure we don't get called recursively ourselves! */ - -static bool -ffestu_dummies_transition_ (ffesymbol (*symfunc) (), ffebld list) -{ - static bool in_progress = FALSE; - ffebld item; - ffesymbol symbol; - bool uncertain = FALSE; - - assert (!in_progress); - in_progress = TRUE; - - for (; list != NULL; list = ffebld_trail (list)) - { - if ((item = ffebld_head (list)) == NULL) - continue; /* Try next item. */ - - switch (ffebld_op (item)) - { - case FFEBLD_opSTAR: - break; - - case FFEBLD_opSYMTER: - symbol = ffebld_symter (item); - if (symbol == NULL) - break; /* Detached from stmt func dummy list. */ - symbol = (*symfunc) (symbol); - if (ffesymbol_state (symbol) == FFESYMBOL_stateUNCERTAIN) - uncertain = TRUE; - else - { - assert (ffesymbol_kind (symbol) != FFEINFO_kindNONE); - assert (ffesymbol_where (symbol) != FFEINFO_whereNONE); - } - ffebld_set_info (item, ffesymbol_info (symbol)); - break; - - default: - assert ("Unexpected item on list" == NULL); - break; - } - } - - in_progress = FALSE; - - return uncertain; -} diff --git a/gcc/f/stu.h b/gcc/f/stu.h deleted file mode 100755 index 61d7b40..0000000 --- a/gcc/f/stu.h +++ /dev/null @@ -1,69 +0,0 @@ -/* stu.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stu.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stu -#define _H_f_stu - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "symbol.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - - -/* Declare functions with prototypes. */ - -ffesymbol ffestu_sym_end_transition (ffesymbol s); -ffesymbol ffestu_sym_exec_transition (ffesymbol s); - -/* Define macros. */ - -#define ffestu_init_0() -#define ffestu_init_1() -#define ffestu_init_2() -#define ffestu_init_3() -#define ffestu_init_4() -#define ffestu_terminate_0() -#define ffestu_terminate_1() -#define ffestu_terminate_2() -#define ffestu_terminate_3() -#define ffestu_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stv.c b/gcc/f/stv.c deleted file mode 100755 index c652356..0000000 --- a/gcc/f/stv.c +++ /dev/null @@ -1,66 +0,0 @@ -/* stv.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None (despite the name, it doesn't really depend on ffest*) - - Description: - Various and sundry info. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stv.h" -#include "lab.h" -#include "where.h" - -/* Externals defined here. */ - -ffestvSavestate ffestv_save_state_; -ffewhereLine ffestv_save_line_; -ffewhereColumn ffestv_save_col_; -ffestvAccessstate ffestv_access_state_; -ffewhereLine ffestv_access_line_; -ffewhereColumn ffestv_access_col_; -ffelabNumber ffestv_num_label_defines_; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ diff --git a/gcc/f/stv.h b/gcc/f/stv.h deleted file mode 100755 index 9ecdd80..0000000 --- a/gcc/f/stv.h +++ /dev/null @@ -1,165 +0,0 @@ -/* stv.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stv.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stv -#define _H_f_stv - -/* Simple definitions and enumerations. */ - -typedef enum - { - FFESTV_accessstateNONE, /* Haven't seen PUBLIC or PRIVATE yet. */ - FFESTV_accessstatePUBLIC, /* Seen PUBLIC stmt w/o args. */ - FFESTV_accessstatePRIVATE, /* Seen PRIVATE stmt w/o args. */ - FFESTV_accessstateANY, /* Conflict seen and reported, so stop - whining. */ - FFESTV_accessstate - } ffestvAccessstate; - -typedef enum - { /* Format specifier in an I/O statement. */ - FFESTV_formatNONE, /* None. */ - FFESTV_formatLABEL, /* Label (normal format). */ - FFESTV_formatCHAREXPR, /* Character expression (normal format). */ - FFESTV_formatASTERISK, /* Asterisk (list-directed). */ - FFESTV_formatINTEXPR, /* Integer expression (assigned label). */ - FFESTV_formatNAMELIST, /* Namelist (namelist-directed). */ - FFESTV_format - } ffestvFormat; - -typedef enum - { - FFESTV_savestateNONE, /* Haven't seen SAVE stmt or attribute yet. */ - FFESTV_savestateSPECIFIC, /* Seen SAVE stmt w/args or SAVE attr. */ - FFESTV_savestateALL, /* Seen SAVE stmt w/o args. */ - FFESTV_savestateANY, /* Conflict seen and reported, so stop - whining. */ - FFESTV_savestate - } ffestvSavestate; - -typedef enum - { - FFESTV_stateNIL, /* Initial state, and after end of outer prog - unit. */ - FFESTV_statePROGRAM0, /* After PROGRAM. */ - FFESTV_statePROGRAM1, /* Before first non-USE statement. */ - FFESTV_statePROGRAM2, /* After IMPLICIT NONE. */ - FFESTV_statePROGRAM3, /* After IMPLICIT, PARAMETER, FORMAT. */ - FFESTV_statePROGRAM4, /* Before executable stmt or CONTAINS. */ - FFESTV_statePROGRAM5, /* After CONTAINS. */ - FFESTV_stateSUBROUTINE0, /* After SUBROUTINE. */ - FFESTV_stateSUBROUTINE1, /* Before first non-USE statement. */ - FFESTV_stateSUBROUTINE2, /* After IMPLICIT NONE. */ - FFESTV_stateSUBROUTINE3, /* After IMPLICIT, PARAMETER, FORMAT, ENTRY. */ - FFESTV_stateSUBROUTINE4, /* Before executable stmt or CONTAINS. */ - FFESTV_stateSUBROUTINE5, /* After CONTAINS. */ - FFESTV_stateFUNCTION0, /* After FUNCTION. */ - FFESTV_stateFUNCTION1, /* Before first non-USE statement. */ - FFESTV_stateFUNCTION2, /* After IMPLICIT NONE. */ - FFESTV_stateFUNCTION3, /* After IMPLICIT, PARAMETER, FORMAT, ENTRY. */ - FFESTV_stateFUNCTION4, /* Before executable stmt or CONTAINS. */ - FFESTV_stateFUNCTION5, /* After CONTAINS. */ - FFESTV_stateMODULE0, /* After MODULE. */ - FFESTV_stateMODULE1, /* Before first non-USE statement. */ - FFESTV_stateMODULE2, /* After IMPLICIT NONE. */ - FFESTV_stateMODULE3, /* After IMPLICIT, PARAMETER, FORMAT, ENTRY. */ - FFESTV_stateMODULE4, /* Before executable stmt or CONTAINS. */ - FFESTV_stateMODULE5, /* After CONTAINS. */ - FFESTV_stateBLOCKDATA0, /* After BLOCKDATA. */ - FFESTV_stateBLOCKDATA1, /* Before first non-USE statement. */ - FFESTV_stateBLOCKDATA2, /* After IMPLICIT NONE. */ - FFESTV_stateBLOCKDATA3, /* After IMPLICIT, PARAMETER, FORMAT, ENTRY. */ - FFESTV_stateBLOCKDATA4, /* Before executable stmt or CONTAINS. */ - FFESTV_stateBLOCKDATA5, /* After CONTAINS. */ - FFESTV_stateUSE, /* Before first USE thru last USE. */ - FFESTV_stateTYPE, /* After TYPE thru END TYPE. */ - FFESTV_stateINTERFACE0, /* After INTERFACE thru MODULE PROCEDURE. */ - FFESTV_stateINTERFACE1, /* After MODULE PROCEDURE thru END INTERFACE. */ - FFESTV_stateSTRUCTURE, /* After STRUCTURE thru END STRUCTURE. */ - FFESTV_stateUNION, /* After UNION thru END UNION. */ - FFESTV_stateMAP, /* After MAP thru END MAP. */ - FFESTV_stateWHERETHEN, /* After WHERE-construct thru END WHERE. */ - FFESTV_stateWHERE, /* After WHERE-stmt thru next stmt. */ - FFESTV_stateIFTHEN, /* After IF THEN thru END IF. */ - FFESTV_stateIF, /* After IF thru next stmt. */ - FFESTV_stateDO, /* After DO thru END DO or terminating label. */ - FFESTV_stateSELECT0, /* After SELECT to before first CASE. */ - FFESTV_stateSELECT1, /* First CASE in SELECT thru END SELECT. */ - FFESTV_state - } ffestvState; - -typedef enum - { /* Unit specifier. */ - FFESTV_unitNONE, /* None. */ - FFESTV_unitINTEXPR, /* Integer expression (external file unit). */ - FFESTV_unitASTERISK, /* Default unit. */ - FFESTV_unitCHAREXPR, /* Character expression (internal file unit). */ - FFESTV_unit - } ffestvUnit; - -/* Typedefs. */ - - -/* Include files needed by this one. */ - -#include "lab.h" -#include "where.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern ffestvSavestate ffestv_save_state_; -extern ffewhereLine ffestv_save_line_; -extern ffewhereColumn ffestv_save_col_; -extern ffestvAccessstate ffestv_access_state_; -extern ffewhereLine ffestv_access_line_; -extern ffewhereColumn ffestv_access_col_; -extern ffelabNumber ffestv_num_label_defines_; - -/* Declare functions with prototypes. */ - - -/* Define macros. */ - -#define ffestv_init_0() -#define ffestv_init_1() -#define ffestv_init_2() -#define ffestv_init_3() -#define ffestv_init_4() -#define ffestv_terminate_0() -#define ffestv_terminate_1() -#define ffestv_terminate_2() -#define ffestv_terminate_3() -#define ffestv_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/f/stw.c b/gcc/f/stw.c deleted file mode 100755 index 90a19a5..0000000 --- a/gcc/f/stw.c +++ /dev/null @@ -1,428 +0,0 @@ -/* stw.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None (despite the name, it doesn't really depend on ffest*) - - Description: - Provides abstraction and stack mechanism to track the block structure - of a Fortran program. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "stw.h" -#include "bld.h" -#include "com.h" -#include "info.h" -#include "lab.h" -#include "lex.h" -#include "malloc.h" -#include "sta.h" -#include "stv.h" -#include "symbol.h" -#include "where.h" - -/* Externals defined here. */ - -ffestw ffestw_stack_top_ = NULL; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - - -/* Internal macros. */ - - -/* ffestw_display_state -- DEBUGGING; display current block state - - ffestw_display_state(); */ - -void -ffestw_display_state () -{ - assert (ffestw_stack_top_ != NULL); - - if (!ffe_is_ffedebug ()) - return; - - fprintf (dmpout, "; block %lu, state ", ffestw_stack_top_->blocknum_); - switch (ffestw_stack_top_->state_) - { - case FFESTV_stateNIL: - fputs ("NIL", dmpout); - break; - - case FFESTV_statePROGRAM0: - fputs ("PROGRAM0", dmpout); - break; - - case FFESTV_statePROGRAM1: - fputs ("PROGRAM1", dmpout); - break; - - case FFESTV_statePROGRAM2: - fputs ("PROGRAM2", dmpout); - break; - - case FFESTV_statePROGRAM3: - fputs ("PROGRAM3", dmpout); - break; - - case FFESTV_statePROGRAM4: - fputs ("PROGRAM4", dmpout); - break; - - case FFESTV_statePROGRAM5: - fputs ("PROGRAM5", dmpout); - break; - - case FFESTV_stateSUBROUTINE0: - fputs ("SUBROUTINE0", dmpout); - break; - - case FFESTV_stateSUBROUTINE1: - fputs ("SUBROUTINE1", dmpout); - break; - - case FFESTV_stateSUBROUTINE2: - fputs ("SUBROUTINE2", dmpout); - break; - - case FFESTV_stateSUBROUTINE3: - fputs ("SUBROUTINE3", dmpout); - break; - - case FFESTV_stateSUBROUTINE4: - fputs ("SUBROUTINE4", dmpout); - break; - - case FFESTV_stateSUBROUTINE5: - fputs ("SUBROUTINE5", dmpout); - break; - - case FFESTV_stateFUNCTION0: - fputs ("FUNCTION0", dmpout); - break; - - case FFESTV_stateFUNCTION1: - fputs ("FUNCTION1", dmpout); - break; - - case FFESTV_stateFUNCTION2: - fputs ("FUNCTION2", dmpout); - break; - - case FFESTV_stateFUNCTION3: - fputs ("FUNCTION3", dmpout); - break; - - case FFESTV_stateFUNCTION4: - fputs ("FUNCTION4", dmpout); - break; - - case FFESTV_stateFUNCTION5: - fputs ("FUNCTION5", dmpout); - break; - - case FFESTV_stateMODULE0: - fputs ("MODULE0", dmpout); - break; - - case FFESTV_stateMODULE1: - fputs ("MODULE1", dmpout); - break; - - case FFESTV_stateMODULE2: - fputs ("MODULE2", dmpout); - break; - - case FFESTV_stateMODULE3: - fputs ("MODULE3", dmpout); - break; - - case FFESTV_stateMODULE4: - fputs ("MODULE4", dmpout); - break; - - case FFESTV_stateMODULE5: - fputs ("MODULE5", dmpout); - break; - - case FFESTV_stateBLOCKDATA0: - fputs ("BLOCKDATA0", dmpout); - break; - - case FFESTV_stateBLOCKDATA1: - fputs ("BLOCKDATA1", dmpout); - break; - - case FFESTV_stateBLOCKDATA2: - fputs ("BLOCKDATA2", dmpout); - break; - - case FFESTV_stateBLOCKDATA3: - fputs ("BLOCKDATA3", dmpout); - break; - - case FFESTV_stateBLOCKDATA4: - fputs ("BLOCKDATA4", dmpout); - break; - - case FFESTV_stateBLOCKDATA5: - fputs ("BLOCKDATA5", dmpout); - break; - - case FFESTV_stateUSE: - fputs ("USE", dmpout); - break; - - case FFESTV_stateTYPE: - fputs ("TYPE", dmpout); - break; - - case FFESTV_stateINTERFACE0: - fputs ("INTERFACE0", dmpout); - break; - - case FFESTV_stateINTERFACE1: - fputs ("INTERFACE1", dmpout); - break; - - case FFESTV_stateSTRUCTURE: - fputs ("STRUCTURE", dmpout); - break; - - case FFESTV_stateUNION: - fputs ("UNION", dmpout); - break; - - case FFESTV_stateMAP: - fputs ("MAP", dmpout); - break; - - case FFESTV_stateWHERETHEN: - fputs ("WHERETHEN", dmpout); - break; - - case FFESTV_stateWHERE: - fputs ("WHERE", dmpout); - break; - - case FFESTV_stateIFTHEN: - fputs ("IFTHEN", dmpout); - break; - - case FFESTV_stateIF: - fputs ("IF", dmpout); - break; - - case FFESTV_stateDO: - fputs ("DO", dmpout); - break; - - case FFESTV_stateSELECT0: - fputs ("SELECT0", dmpout); - break; - - case FFESTV_stateSELECT1: - fputs ("SELECT1", dmpout); - break; - - default: - assert ("bad state" == NULL); - break; - } - if (ffestw_stack_top_->top_do_ != NULL) - fputs (" (within DO)", dmpout); - fputc ('\n', dmpout); -} - -/* ffestw_init_0 -- Initialize ffestw structures - - ffestw_init_0(); */ - -void -ffestw_init_0 () -{ - ffestw b; - - ffestw_stack_top_ = b = (ffestw) malloc_new_kp (malloc_pool_image (), - "FFESTW stack base", sizeof (*b)); - b->uses_ = 0; /* catch if anyone uses, kills, &c this - block. */ - b->next_ = NULL; - b->previous_ = NULL; - b->top_do_ = NULL; - b->blocknum_ = 0; - b->shriek_ = NULL; - b->state_ = FFESTV_stateNIL; - b->line_ = ffewhere_line_unknown (); - b->col_ = ffewhere_column_unknown (); -} - -/* ffestw_kill -- Kill block - - ffestw b; - ffestw_kill(b); */ - -void -ffestw_kill (ffestw b) -{ - assert (b != NULL); - assert (b->uses_ > 0); - - if (--b->uses_ != 0) - return; - - ffewhere_line_kill (b->line_); - ffewhere_column_kill (b->col_); -} - -/* ffestw_new -- Create block - - ffestw b; - b = ffestw_new(); */ - -ffestw -ffestw_new () -{ - ffestw b; - - b = (ffestw) malloc_new_kp (malloc_pool_image (), "FFESTW", sizeof (*b)); - b->uses_ = 1; - - return b; -} - -/* ffestw_pop -- Pop block off stack - - ffestw_pop(); */ - -ffestw -ffestw_pop () -{ - ffestw b; - ffestw oldb = ffestw_stack_top_; - - assert (oldb != NULL); - ffestw_stack_top_ = b = ffestw_stack_top_->previous_; - assert (b != NULL); - if ((ffewhere_line_is_unknown (b->line_) || ffewhere_column_is_unknown (b->col_)) - && (ffesta_tokens[0] != NULL)) - { - assert (b->state_ == FFESTV_stateNIL); - if (ffewhere_line_is_unknown (b->line_)) - b->line_ - = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - if (ffewhere_column_is_unknown (b->col_)) - b->col_ - = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - } - - return oldb; -} - -/* ffestw_push -- Push block onto stack, return its address - - ffestw b; // NULL if new block to be obtained first. - ffestw_push(b); - - Returns address of block if desired, also updates ffestw_stack_top_ - to point to it. - - 30-Oct-91 JCB 2.0 - Takes block as arg, or NULL if new block needed. */ - -ffestw -ffestw_push (ffestw b) -{ - if (b == NULL) - b = ffestw_new (); - - b->next_ = NULL; - b->previous_ = ffestw_stack_top_; - b->line_ = ffewhere_line_unknown (); - b->col_ = ffewhere_column_unknown (); - ffestw_stack_top_ = b; - return b; -} - -/* ffestw_update -- Update current block line/col info - - ffestw_update(); - - Updates block to point to current statement. */ - -ffestw -ffestw_update (ffestw b) -{ - if (b == NULL) - { - b = ffestw_stack_top_; - assert (b != NULL); - } - - if (ffesta_tokens[0] == NULL) - return b; - - ffewhere_line_kill (b->line_); - ffewhere_column_kill (b->col_); - b->line_ = ffewhere_line_use (ffelex_token_where_line (ffesta_tokens[0])); - b->col_ = ffewhere_column_use (ffelex_token_where_column (ffesta_tokens[0])); - - return b; -} - -/* ffestw_use -- Mark extra use of block - - ffestw b; - b = ffestw_use(b); // will always return original copy of b - - Increments use counter for b. */ - -ffestw -ffestw_use (ffestw b) -{ - assert (b != NULL); - assert (b->uses_ != 0); - - ++b->uses_; - - return b; -} diff --git a/gcc/f/stw.h b/gcc/f/stw.h deleted file mode 100755 index 8caefbd..0000000 --- a/gcc/f/stw.h +++ /dev/null @@ -1,184 +0,0 @@ -/* stw.h -- Private #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - stw.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_stw -#define _H_f_stw - -/* Simple definitions and enumerations. */ - - -/* Typedefs. */ - -typedef struct _ffestw_ *ffestw; -typedef struct _ffestw_case_ *ffestwCase; -typedef struct _ffestw_select_ *ffestwSelect; -typedef void (*ffestwShriek) (bool ok); - -/* Include files needed by this one. */ - -#include "bld.h" -#include "com.h" -#include "info.h" -#include "lab.h" -#include "lex.h" -#include "malloc.h" -#include "stv.h" -#include "symbol.h" -#include "where.h" - -/* Structure definitions. */ - -struct _ffestw_ - { - ffestw next_; /* Next (unused) block, or NULL. */ - ffestw previous_; /* Previous block, NULL if this is NIL state. */ - ffestw top_do_; /* Previous or current DO state, or NULL. */ - unsigned long blocknum_; /* Block # w/in procedure/program. */ - ffestwShriek shriek_; /* Call me to pop block in a hurry. */ - ffesymbol sym_; /* Related symbol (if there is one). */ - ffelexToken name_; /* Construct name (IFTHEN, SELECT, DO only). */ - ffestwSelect select_; /* Info for SELECT CASE blocks. */ - ffelab label_; /* For DO blocks w/labels, the target label. */ - ffesymbol do_iter_var_; /* For iter DO blocks, the iter var or NULL. */ - ffelexToken do_iter_var_t_; /* The token for do_iter_var. */ - ffewhereLine line_; /* Where first token of statement triggering - state */ - ffewhereColumn col_; /* was seen in source file. */ - char uses_; /* # uses (new+use-kill calls). */ - ffestvState state_; - int substate_; /* Used on a per-block-state basis. */ -#if FFECOM_targetCURRENT == FFECOM_targetGCC - struct nesting *do_hook_; /* backend id for given loop (EXIT/CYCLE). */ - tree do_tvar_; /* tree form of do_iter_var. */ - tree do_incr_saved_; /* tree SAVED_EXPR of incr expr. */ - tree do_count_var_; /* tree of countdown variable. */ - tree select_texpr_; /* tree for end case. */ - bool select_break_; /* TRUE when CASE should start with gen - "break;". */ -#endif /* FFECOM_targetCURRENT == FFECOM_targetGCC*/ - }; - -struct _ffestw_case_ - { - ffestwCase next_rel; /* Next case range in relational order. */ - ffestwCase previous_rel; /* Previous case range in relational order. */ - ffestwCase next_stmt; /* Next range in stmt or first in next stmt. */ - ffestwCase previous_stmt; /* Previous range. */ - ffebldConstant low; /* Low value in range. */ - ffebldConstant high; /* High value in range. */ - unsigned long casenum; /* CASE stmt index for this range/value. */ - ffelexToken t; /* Token for this range/value; ffestc only. */ - }; - -struct _ffestw_select_ - { - ffestwCase first_rel; /* First CASE range (after low) in order. */ - ffestwCase last_rel; /* Last CASE range (before high) in order. */ - ffestwCase first_stmt; /* First range in first CASE stmt. */ - ffestwCase last_stmt; /* Last range in last CASE stmt. */ - mallocPool pool; /* Pool in which this and all cases are - allocated. */ - unsigned long cases; /* Number of CASE stmts seen so far. */ - ffelexToken t; /* First token of selected expression; ffestc - only. */ - ffeinfoBasictype type; /* Basic type (integer, character, or - logical). */ - ffeinfoKindtype kindtype; /* Kind type. */ - }; - -/* Global objects accessed by users of this module. */ - -extern ffestw ffestw_stack_top_; - -/* Declare functions with prototypes. */ - -void ffestw_display_state (); -void ffestw_kill (ffestw block); -void ffestw_init_0 (void); -ffestw ffestw_new (); -ffestw ffestw_pop (); -ffestw ffestw_push (ffestw block); -ffestw ffestw_update (ffestw block); -ffestw ffestw_use (ffestw block); - -/* Define macros. */ - -#define ffestw_blocknum(b) ((b)->blocknum_) -#define ffestw_col(b) ((b)->col_) -#define ffestw_do_count_var(b) ((b)->do_count_var_) -#define ffestw_do_hook(b) ((b)->do_hook_) -#define ffestw_do_incr_saved(b) ((b)->do_incr_saved_) -#define ffestw_do_iter_var(b) ((b)->do_iter_var_) -#define ffestw_do_iter_var_t(b) ((b)->do_iter_var_t_) -#define ffestw_do_tvar(b) ((b)->do_tvar_) -#define ffestw_init_1() -#define ffestw_init_2() -#define ffestw_init_3() -#define ffestw_init_4() -#define ffestw_label(b) ((b)->label_) -#define ffestw_line(b) ((b)->line_) -#define ffestw_name(b) ((b)->name_) -#define ffestw_previous(b) ((b)->previous_) -#define ffestw_select(b) ((b)->select_) -#define ffestw_select_break(b) ((b)->select_break_) -#define ffestw_select_texpr(b) ((b)->select_texpr_) -#define ffestw_set_blocknum(b,bl) ((b)->blocknum_ = (bl)) -#define ffestw_set_col(b,c) ((b)->col_ = (c)) -#define ffestw_set_do_count_var(b,d) ((b)->do_count_var_ = (d)) -#define ffestw_set_do_hook(b,d) ((b)->do_hook_ = (d)) -#define ffestw_set_do_incr_saved(b,d) ((b)->do_incr_saved_ = (d)) -#define ffestw_set_do_iter_var(b,v) ((b)->do_iter_var_ = (v)) -#define ffestw_set_do_iter_var_t(b,t) ((b)->do_iter_var_t_ = (t)) -#define ffestw_set_do_tvar(b,d) ((b)->do_tvar_ = (d)) -#define ffestw_set_label(b,l) ((b)->label_ = (l)) -#define ffestw_set_line(b,l) ((b)->line_ = (l)) -#define ffestw_set_name(b,n) ((b)->name_ = (n)) -#define ffestw_set_select(b,s) ((b)->select_ = (s)) -#define ffestw_set_select_break(b,br) ((b)->select_break_ = (br)) -#define ffestw_set_select_texpr(b,t) ((b)->select_texpr_ = (t)) -#define ffestw_set_shriek(b,s) ((b)->shriek_ = (s)) -#define ffestw_set_state(b,s) ((b)->state_ = (s)) -#define ffestw_set_substate(b,s) ((b)->substate_ = (s)) -#define ffestw_set_sym(b,s) ((b)->sym_= (s)) -#define ffestw_set_top_do(b,t) ((b)->top_do_ = (t)) -#define ffestw_shriek(b) ((b)->shriek_) -#define ffestw_stack_top() ffestw_stack_top_ -#define ffestw_state(b) ((b)->state_) -#define ffestw_substate(b) ((b)->substate_) -#define ffestw_sym(b) ((b)->sym_) -#define ffestw_terminate_0() -#define ffestw_terminate_1() -#define ffestw_terminate_2() -#define ffestw_terminate_3() -#define ffestw_terminate_4() -#define ffestw_top_do(b) ((b)->top_do_) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/symbol.c b/gcc/f/symbol.c deleted file mode 100755 index 8aa7230..0000000 --- a/gcc/f/symbol.c +++ /dev/null @@ -1,1477 +0,0 @@ -/* Implementation of Fortran symbol manager - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#include "proj.h" -#include "symbol.h" -#include "bad.h" -#include "bld.h" -#include "com.h" -#include "equiv.h" -#include "global.h" -#include "info.h" -#include "intrin.h" -#include "lex.h" -#include "malloc.h" -#include "src.h" -#include "st.h" -#include "storag.h" -#include "target.h" -#include "where.h" - -/* Choice of how to handle global symbols -- either global only within the - program unit being defined or global within the entire source file. - The former is appropriate for systems where an object file can - easily be taken apart program unit by program unit, the latter is the - UNIX/C model where the object file is essentially a monolith. */ - -#define FFESYMBOL_globalPROGUNIT_ 1 -#define FFESYMBOL_globalFILE_ 2 - -/* Choose how to handle global symbols here. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -#define FFESYMBOL_globalCURRENT_ FFESYMBOL_globalPROGUNIT_ -#elif FFECOM_targetCURRENT == FFECOM_targetGCC -/* Would be good to understand why PROGUNIT in this case too. - (1995-08-22). */ -#define FFESYMBOL_globalCURRENT_ FFESYMBOL_globalPROGUNIT_ -#else -#error -#endif - -/* Choose how to handle memory pools based on global symbol stuff. */ - -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_ -#define FFESYMBOL_SPACE_POOL_ ffe_pool_program_unit() -#elif FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_ -#define FFESYMBOL_SPACE_POOL_ ffe_pool_file() -#else -#error -#endif - -/* What kind of retraction is needed for a symbol? */ - -enum _ffesymbol_retractcommand_ - { - FFESYMBOL_retractcommandDELETE_, - FFESYMBOL_retractcommandRETRACT_, - FFESYMBOL_retractcommand_ - }; -typedef enum _ffesymbol_retractcommand_ ffesymbolRetractCommand_; - -/* This object keeps track of retraction for a symbol and links to the next - such object. */ - -typedef struct _ffesymbol_retract_ *ffesymbolRetract_; -struct _ffesymbol_retract_ - { - ffesymbolRetract_ next; - ffesymbolRetractCommand_ command; - ffesymbol live; /* Live symbol. */ - ffesymbol symbol; /* Backup copy of symbol. */ - }; - -static ffebad ffesymbol_check_token_ (ffelexToken t, char *c); -static void ffesymbol_kill_manifest_ (void); -static ffesymbol ffesymbol_new_ (ffename n); -static ffesymbol ffesymbol_unhook_ (ffesymbol s); -static void ffesymbol_whine_state_ (ffebad bad, ffelexToken t, char c); - -/* Manifest names for unnamed things (as tokens) so we make them only - once. */ - -static ffelexToken ffesymbol_token_blank_common_ = NULL; -static ffelexToken ffesymbol_token_unnamed_main_ = NULL; -static ffelexToken ffesymbol_token_unnamed_blockdata_ = NULL; - -/* Name spaces currently in force. */ - -static ffenameSpace ffesymbol_global_ = NULL; -static ffenameSpace ffesymbol_local_ = NULL; -static ffenameSpace ffesymbol_sfunc_ = NULL; - -/* Keep track of retraction. */ - -static bool ffesymbol_retractable_ = FALSE; -static mallocPool ffesymbol_retract_pool_; -static ffesymbolRetract_ ffesymbol_retract_first_; -static ffesymbolRetract_ *ffesymbol_retract_list_; - -/* List of state names. */ - -static char *ffesymbol_state_name_[] = -{ - "?", - "@", - "&", - "$", -}; - -/* List of attribute names. */ - -static char *ffesymbol_attr_name_[] = -{ -#define DEFATTR(ATTR,ATTRS,NAME) NAME, -#include "symbol.def" -#undef DEFATTR -}; - - -/* Check whether the token text has any invalid characters. If not, - return FALSE. If so, if error messages inhibited, return TRUE - so caller knows to try again later, else report error and return - FALSE. */ - -static ffebad -ffesymbol_check_token_ (ffelexToken t, char *c) -{ - char *p = ffelex_token_text (t); - ffeTokenLength len = ffelex_token_length (t); - ffebad bad; - ffeTokenLength i = 0; - ffebad skip_me = ((ffe_case_symbol () == FFE_caseINITCAP) - ? FFEBAD_SYMBOL_NOLOWER_INITCAP : FFEBAD + 1); - ffebad stop_me = ((ffe_case_symbol () == FFE_caseINITCAP) - ? FFEBAD : FFEBAD + 1); - if (len == 0) - return FFEBAD; - - bad = ffesrc_bad_char_symbol_init (*p); - if (bad == FFEBAD) - { - for (++i, ++p; i < len; ++i, ++p) - { - bad = ffesrc_bad_char_symbol_noninit (*p); - if (bad == skip_me) - continue; /* Keep looking for good InitCap character. */ - if (bad == stop_me) - break; /* Found good InitCap character. */ - if (bad != FFEBAD) - break; /* Bad character found. */ - } - } - - if (bad != FFEBAD) - { - if (i >= len) - *c = *(ffelex_token_text (t)); - else - *c = *p; - } - - return bad; -} - -/* Kill manifest (g77-picked) names. */ - -static void -ffesymbol_kill_manifest_ () -{ - if (ffesymbol_token_blank_common_ != NULL) - ffelex_token_kill (ffesymbol_token_blank_common_); - if (ffesymbol_token_unnamed_main_ != NULL) - ffelex_token_kill (ffesymbol_token_unnamed_main_); - if (ffesymbol_token_unnamed_blockdata_ != NULL) - ffelex_token_kill (ffesymbol_token_unnamed_blockdata_); - - ffesymbol_token_blank_common_ = NULL; - ffesymbol_token_unnamed_main_ = NULL; - ffesymbol_token_unnamed_blockdata_ = NULL; -} - -/* Make new symbol. - - If the "retractable" flag is not set, just return the new symbol. - Else, add symbol to the "retract" list as a delete item, set - the "have_old" flag, and return the new symbol. */ - -static ffesymbol -ffesymbol_new_ (ffename n) -{ - ffesymbol s; - ffesymbolRetract_ r; - - assert (n != NULL); - - s = (ffesymbol) malloc_new_ks (FFESYMBOL_SPACE_POOL_, "FFESYMBOL", - sizeof (*s)); - s->name = n; - s->other_space_name = NULL; -#if FFEGLOBAL_ENABLED - s->global = NULL; -#endif - s->attrs = FFESYMBOL_attrsetNONE; - s->state = FFESYMBOL_stateNONE; - s->info = ffeinfo_new_null (); - s->dims = NULL; - s->extents = NULL; - s->dim_syms = NULL; - s->array_size = NULL; - s->init = NULL; - s->accretion = NULL; - s->accretes = 0; - s->dummy_args = NULL; - s->namelist = NULL; - s->common_list = NULL; - s->sfunc_expr = NULL; - s->list_bottom = NULL; - s->common = NULL; - s->equiv = NULL; - s->storage = NULL; -#ifdef FFECOM_symbolHOOK - s->hook = FFECOM_symbolNULL; -#endif - s->sfa_dummy_parent = NULL; - s->func_result = NULL; - s->value = 0; - s->check_state = FFESYMBOL_checkstateNONE_; - s->check_token = NULL; - s->max_entry_num = 0; - s->num_entries = 0; - s->generic = FFEINTRIN_genNONE; - s->specific = FFEINTRIN_specNONE; - s->implementation = FFEINTRIN_impNONE; - s->is_save = FALSE; - s->is_init = FALSE; - s->do_iter = FALSE; - s->reported = FALSE; - s->explicit_where = FALSE; - s->namelisted = FALSE; - - ffename_set_symbol (n, s); - - if (!ffesymbol_retractable_) - { - s->have_old = FALSE; - return s; - } - - r = (ffesymbolRetract_) malloc_new_kp (ffesymbol_retract_pool_, - "FFESYMBOL retract", sizeof (*r)); - r->next = NULL; - r->command = FFESYMBOL_retractcommandDELETE_; - r->live = s; - r->symbol = NULL; /* No backup copy. */ - - *ffesymbol_retract_list_ = r; - ffesymbol_retract_list_ = &r->next; - - s->have_old = TRUE; - return s; -} - -/* Unhook a symbol from its (soon-to-be-killed) name obj. - - NULLify the names to which this symbol points. Do other cleanup as - needed. */ - -static ffesymbol -ffesymbol_unhook_ (ffesymbol s) -{ - s->other_space_name = s->name = NULL; - if ((ffesymbol_attrs (s) & FFESYMBOL_attrsCBLOCK) - || (ffesymbol_kind (s) == FFEINFO_kindNAMELIST)) - ffebld_end_list (ffesymbol_ptr_to_listbottom (s)); - if (s->check_state == FFESYMBOL_checkstatePENDING_) - ffelex_token_kill (s->check_token); - - return s; -} - -/* Issue diagnostic about bad character in token representing user-defined - symbol name. */ - -static void -ffesymbol_whine_state_ (ffebad bad, ffelexToken t, char c) -{ - char badstr[2]; - - badstr[0] = c; - badstr[1] = '\0'; - - ffebad_start (bad); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_string (badstr); - ffebad_finish (); -} - -/* Returns a string representing the attributes set. */ - -char * -ffesymbol_attrs_string (ffesymbolAttrs attrs) -{ - static char string[FFESYMBOL_attr * 12 + 20]; - char *p; - ffesymbolAttr attr; - - p = &string[0]; - - if (attrs == FFESYMBOL_attrsetNONE) - { - strcpy (p, "NONE"); - return &string[0]; - } - - for (attr = 0; attr < FFESYMBOL_attr; ++attr) - { - if (attrs & ((ffesymbolAttrs) 1 << attr)) - { - attrs &= ~((ffesymbolAttrs) 1 << attr); - strcpy (p, ffesymbol_attr_name_[attr]); - while (*p) - ++p; - *(p++) = '|'; - } - } - if (attrs == FFESYMBOL_attrsetNONE) - *--p = '\0'; - else - sprintf (p, "?0x%" ffesymbolAttrs_f "x?", attrs); - assert (((size_t) (p - &string[0])) < ARRAY_SIZE (string)); - return &string[0]; -} - -/* Check symbol's name for validity, considering that it might actually - be an intrinsic and thus should not be complained about just yet. */ - -void -ffesymbol_check (ffesymbol s, ffelexToken t, bool maybe_intrin) -{ - char c; - ffebad bad; - ffeintrinGen gen; - ffeintrinSpec spec; - ffeintrinImp imp; - - if (!ffesrc_check_symbol () - || ((s->check_state != FFESYMBOL_checkstateNONE_) - && ((s->check_state != FFESYMBOL_checkstateINHIBITED_) - || ffebad_inhibit ()))) - return; - - bad = ffesymbol_check_token_ (t, &c); - - if (bad == FFEBAD) - { - s->check_state = FFESYMBOL_checkstateCHECKED_; - return; - } - - if (maybe_intrin - && ffeintrin_is_intrinsic (ffelex_token_text (t), NULL, FALSE, - &gen, &spec, &imp)) - { - s->check_state = FFESYMBOL_checkstatePENDING_; - s->check_token = ffelex_token_use (t); - return; - } - - if (ffebad_inhibit ()) - { - s->check_state = FFESYMBOL_checkstateINHIBITED_; - return; /* Don't complain now, do it later. */ - } - - s->check_state = FFESYMBOL_checkstateCHECKED_; - - ffesymbol_whine_state_ (bad, t, c); -} - -/* Declare a BLOCKDATA unit. - - Retrieves or creates the ffesymbol for the specified BLOCKDATA (unnamed - if t is NULL). Doesn't actually ensure the named item is a - BLOCKDATA; the caller must handle that. */ - -ffesymbol -ffesymbol_declare_blockdataunit (ffelexToken t, ffewhereLine wl, - ffewhereColumn wc) -{ - ffename n; - ffesymbol s; - bool user = (t != NULL); - - assert (!ffesymbol_retractable_); - - if (t == NULL) - { - if (ffesymbol_token_unnamed_blockdata_ == NULL) - ffesymbol_token_unnamed_blockdata_ - = ffelex_token_new_name (FFETARGET_nameUNNAMED_BLOCK_DATA, wl, wc); - t = ffesymbol_token_unnamed_blockdata_; - } - - n = ffename_lookup (ffesymbol_local_, t); - if (n != NULL) - return ffename_symbol (n); /* This will become an error. */ - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - if (user) - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - if (user) - ffesymbol_check (s, t, FALSE); - - /* A program unit name also is in the local name space. */ - - n = ffename_find (ffesymbol_local_, t); - ffename_set_symbol (n, s); - s->other_space_name = n; - - ffeglobal_new_blockdata (s, t); /* Detect conflicts, when - appropriate. */ - - return s; -} - -/* Declare a common block (named or unnamed). - - Retrieves or creates the ffesymbol for the specified common block (blank - common if t is NULL). Doesn't actually ensure the named item is a - common block; the caller must handle that. */ - -ffesymbol -ffesymbol_declare_cblock (ffelexToken t, ffewhereLine wl, ffewhereColumn wc) -{ - ffename n; - ffesymbol s; - bool blank; - - assert (!ffesymbol_retractable_); - - if (t == NULL) - { - blank = TRUE; - if (ffesymbol_token_blank_common_ == NULL) - ffesymbol_token_blank_common_ - = ffelex_token_new_name (FFETARGET_nameBLANK_COMMON, wl, wc); - t = ffesymbol_token_blank_common_; - } - else - blank = FALSE; - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - if (!blank) - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - if (!blank) - ffesymbol_check (s, t, FALSE); - - ffeglobal_new_common (s, t, blank); /* Detect conflicts. */ - - return s; -} - -/* Declare a FUNCTION program unit (with distinct RESULT() name). - - Retrieves or creates the ffesymbol for the specified function. Doesn't - actually ensure the named item is a function; the caller must handle - that. - - If FUNCTION with RESULT() is specified but the names are the same, - pretend as though RESULT() was not specified, and don't call this - function; use ffesymbol_declare_funcunit() instead. */ - -ffesymbol -ffesymbol_declare_funcnotresunit (ffelexToken t) -{ - ffename n; - ffesymbol s; - - assert (t != NULL); - assert (!ffesymbol_retractable_); - - n = ffename_lookup (ffesymbol_local_, t); - if (n != NULL) - return ffename_symbol (n); /* This will become an error. */ - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - ffesymbol_check (s, t, FALSE); - - /* A FUNCTION program unit name also is in the local name space; handle it - here since RESULT() is a different name and is handled separately. */ - - n = ffename_find (ffesymbol_local_, t); - ffename_set_symbol (n, s); - s->other_space_name = n; - - ffeglobal_new_function (s, t);/* Detect conflicts, when appropriate. */ - - return s; -} - -/* Declare a function result. - - Retrieves or creates the ffesymbol for the specified function result, - whether specified via a distinct RESULT() or by default in a FUNCTION or - ENTRY statement. */ - -ffesymbol -ffesymbol_declare_funcresult (ffelexToken t) -{ - ffename n; - ffesymbol s; - - assert (t != NULL); - assert (!ffesymbol_retractable_); - - n = ffename_find (ffesymbol_local_, t); - s = ffename_symbol (n); - if (s != NULL) - return s; - - return ffesymbol_new_ (n); -} - -/* Declare a FUNCTION program unit with no RESULT(). - - Retrieves or creates the ffesymbol for the specified function. Doesn't - actually ensure the named item is a function; the caller must handle - that. - - This is the function to call when the FUNCTION or ENTRY statement has - no separate and distinct name specified via RESULT(). That's because - this function enters the global name of the function in only the global - name space. ffesymbol_declare_funcresult() must still be called to - declare the name for the function result in the local name space. */ - -ffesymbol -ffesymbol_declare_funcunit (ffelexToken t) -{ - ffename n; - ffesymbol s; - - assert (t != NULL); - assert (!ffesymbol_retractable_); - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - ffesymbol_check (s, t, FALSE); - - ffeglobal_new_function (s, t);/* Detect conflicts. */ - - return s; -} - -/* Declare a local entity. - - Retrieves or creates the ffesymbol for the specified local entity. - Set maybe_intrin TRUE if this name might turn out to name an - intrinsic (legitimately); otherwise if the name doesn't meet the - requirements for a user-defined symbol name, a diagnostic will be - issued right away rather than waiting until the intrinsicness of the - symbol is determined. */ - -ffesymbol -ffesymbol_declare_local (ffelexToken t, bool maybe_intrin) -{ - ffename n; - ffesymbol s; - - assert (t != NULL); - - /* If we're parsing within a statement function definition, return the - symbol if already known (a dummy argument for the statement function). - Otherwise continue on, which means the symbol is declared within the - containing (local) program unit rather than the statement function - definition. */ - - if ((ffesymbol_sfunc_ != NULL) - && ((n = ffename_lookup (ffesymbol_sfunc_, t)) != NULL)) - return ffename_symbol (n); - - n = ffename_find (ffesymbol_local_, t); - s = ffename_symbol (n); - if (s != NULL) - { - ffesymbol_check (s, t, maybe_intrin); - return s; - } - - s = ffesymbol_new_ (n); - ffesymbol_check (s, t, maybe_intrin); - return s; -} - -/* Declare a main program unit. - - Retrieves or creates the ffesymbol for the specified main program unit - (unnamed main program unit if t is NULL). Doesn't actually ensure the - named item is a program; the caller must handle that. */ - -ffesymbol -ffesymbol_declare_programunit (ffelexToken t, ffewhereLine wl, - ffewhereColumn wc) -{ - ffename n; - ffesymbol s; - bool user = (t != NULL); - - assert (!ffesymbol_retractable_); - - if (t == NULL) - { - if (ffesymbol_token_unnamed_main_ == NULL) - ffesymbol_token_unnamed_main_ - = ffelex_token_new_name (FFETARGET_nameUNNAMED_MAIN, wl, wc); - t = ffesymbol_token_unnamed_main_; - } - - n = ffename_lookup (ffesymbol_local_, t); - if (n != NULL) - return ffename_symbol (n); /* This will become an error. */ - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - if (user) - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - if (user) - ffesymbol_check (s, t, FALSE); - - /* A program unit name also is in the local name space. */ - - n = ffename_find (ffesymbol_local_, t); - ffename_set_symbol (n, s); - s->other_space_name = n; - - ffeglobal_new_program (s, t); /* Detect conflicts. */ - - return s; -} - -/* Declare a statement-function dummy. - - Retrieves or creates the ffesymbol for the specified statement - function dummy. Also ensures that it has a link to the parent (local) - ffesymbol with the same name, creating it if necessary. */ - -ffesymbol -ffesymbol_declare_sfdummy (ffelexToken t) -{ - ffename n; - ffesymbol s; - ffesymbol sp; /* Parent symbol in local area. */ - - assert (t != NULL); - - n = ffename_find (ffesymbol_local_, t); - sp = ffename_symbol (n); - if (sp == NULL) - sp = ffesymbol_new_ (n); - ffesymbol_check (sp, t, FALSE); - - n = ffename_find (ffesymbol_sfunc_, t); - s = ffename_symbol (n); - if (s == NULL) - { - s = ffesymbol_new_ (n); - s->sfa_dummy_parent = sp; - } - else - assert (s->sfa_dummy_parent == sp); - - return s; -} - -/* Declare a subroutine program unit. - - Retrieves or creates the ffesymbol for the specified subroutine - Doesn't actually ensure the named item is a subroutine; the caller must - handle that. */ - -ffesymbol -ffesymbol_declare_subrunit (ffelexToken t) -{ - ffename n; - ffesymbol s; - - assert (!ffesymbol_retractable_); - assert (t != NULL); - - n = ffename_lookup (ffesymbol_local_, t); - if (n != NULL) - return ffename_symbol (n); /* This will become an error. */ - - n = ffename_find (ffesymbol_global_, t); - s = ffename_symbol (n); - if (s != NULL) - { - ffesymbol_check (s, t, FALSE); - return s; - } - - s = ffesymbol_new_ (n); - ffesymbol_check (s, t, FALSE); - - /* A program unit name also is in the local name space. */ - - n = ffename_find (ffesymbol_local_, t); - ffename_set_symbol (n, s); - s->other_space_name = n; - - ffeglobal_new_subroutine (s, t); /* Detect conflicts, when - appropriate. */ - - return s; -} - -/* Call given fn with all local/global symbols. - - ffesymbol (*fn) (ffesymbol s); - ffesymbol_drive (fn); */ - -void -ffesymbol_drive (ffesymbol (*fn) ()) -{ - assert (ffesymbol_sfunc_ == NULL); /* Might be ok, but not for current - uses. */ - ffename_space_drive_symbol (ffesymbol_local_, fn); - ffename_space_drive_symbol (ffesymbol_global_, fn); -} - -/* Call given fn with all sfunc-only symbols. - - ffesymbol (*fn) (ffesymbol s); - ffesymbol_drive_sfnames (fn); */ - -void -ffesymbol_drive_sfnames (ffesymbol (*fn) ()) -{ - ffename_space_drive_symbol (ffesymbol_sfunc_, fn); -} - -/* Dump info on the symbol for debugging purposes. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffesymbol_dump (ffesymbol s) -{ - ffeinfoKind k; - ffeinfoWhere w; - - assert (s != NULL); - - if (ffeinfo_size (s->info) != FFETARGET_charactersizeNONE) - fprintf (dmpout, "%s:%d%s%s*%" ffetargetCharacterSize_f "u", - ffesymbol_text (s), - (int) ffeinfo_rank (s->info), - ffeinfo_basictype_string (ffeinfo_basictype (s->info)), - ffeinfo_kindtype_string (ffeinfo_kindtype (s->info)), - ffeinfo_size (s->info)); - else - fprintf (dmpout, "%s:%d%s%s", - ffesymbol_text (s), - (int) ffeinfo_rank (s->info), - ffeinfo_basictype_string (ffeinfo_basictype (s->info)), - ffeinfo_kindtype_string (ffeinfo_kindtype (s->info))); - if ((k = ffeinfo_kind (s->info)) != FFEINFO_kindNONE) - fprintf (dmpout, "/%s", ffeinfo_kind_string (k)); - if ((w = ffeinfo_where (s->info)) != FFEINFO_whereNONE) - fprintf (dmpout, "@%s", ffeinfo_where_string (w)); - - if ((s->generic != FFEINTRIN_genNONE) - || (s->specific != FFEINTRIN_specNONE) - || (s->implementation != FFEINTRIN_impNONE)) - fprintf (dmpout, "{%s:%s:%s}", - ffeintrin_name_generic (s->generic), - ffeintrin_name_specific (s->specific), - ffeintrin_name_implementation (s->implementation)); -} -#endif - -/* Produce generic error message about a symbol. - - For now, just output error message using symbol's name and pointing to - the token. */ - -void -ffesymbol_error (ffesymbol s, ffelexToken t) -{ - if ((t != NULL) - && ffest_ffebad_start (FFEBAD_SYMERR)) - { - ffebad_string (ffesymbol_text (s)); - ffebad_here (0, ffelex_token_where_line (t), - ffelex_token_where_column (t)); - ffebad_here (1, ffesymbol_where_line (s), ffesymbol_where_column (s)); - ffebad_finish (); - } - - if (ffesymbol_attr (s, FFESYMBOL_attrANY)) - return; - - ffesymbol_signal_change (s); /* May need to back up to previous version. */ - if ((ffesymbol_attrs (s) & FFESYMBOL_attrsCBLOCK) - || (ffesymbol_kind (s) == FFEINFO_kindNAMELIST)) - ffebld_end_list (ffesymbol_ptr_to_listbottom (s)); - ffesymbol_set_attr (s, FFESYMBOL_attrANY); - ffesymbol_set_info (s, ffeinfo_new_any ()); - ffesymbol_set_state (s, FFESYMBOL_stateUNDERSTOOD); - if (s->check_state == FFESYMBOL_checkstatePENDING_) - ffelex_token_kill (s->check_token); - s->check_state = FFESYMBOL_checkstateCHECKED_; - s = ffecom_sym_learned (s); - ffesymbol_signal_unreported (s); -} - -void -ffesymbol_init_0 () -{ - ffesymbolAttrs attrs = FFESYMBOL_attrsetNONE; - - assert (FFESYMBOL_state == ARRAY_SIZE (ffesymbol_state_name_)); - assert (FFESYMBOL_attr == ARRAY_SIZE (ffesymbol_attr_name_)); - assert (attrs == FFESYMBOL_attrsetNONE); - attrs = ((ffesymbolAttrs) 1 << FFESYMBOL_attr); - assert (attrs != 0); -} - -void -ffesymbol_init_1 () -{ -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_ - ffesymbol_global_ = ffename_space_new (ffe_pool_file ()); -#endif -} - -void -ffesymbol_init_2 () -{ -} - -void -ffesymbol_init_3 () -{ -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_ - ffesymbol_global_ = ffename_space_new (ffe_pool_program_unit ()); -#endif - ffesymbol_local_ = ffename_space_new (ffe_pool_program_unit ()); -} - -void -ffesymbol_init_4 () -{ - ffesymbol_sfunc_ = ffename_space_new (ffe_pool_program_unit ()); -} - -/* Look up a local entity. - - Retrieves the ffesymbol for the specified local entity, or returns NULL - if no local entity by that name exists. */ - -ffesymbol -ffesymbol_lookup_local (ffelexToken t) -{ - ffename n; - ffesymbol s; - - assert (t != NULL); - - n = ffename_lookup (ffesymbol_local_, t); - if (n == NULL) - return NULL; - - s = ffename_symbol (n); - return s; /* May be NULL here, too. */ -} - -/* Registers the symbol as one that is referenced by the - current program unit. Currently applies only to - symbols known to have global interest (globals and - intrinsics). - - s is the (global/intrinsic) symbol referenced; t is the - referencing token; explicit is TRUE if the reference - is, e.g., INTRINSIC FOO. */ - -void -ffesymbol_reference (ffesymbol s, ffelexToken t, bool explicit) -{ - ffename gn; - ffesymbol gs = NULL; - ffeinfoKind kind; - ffeinfoWhere where; - bool okay; - - if (ffesymbol_retractable_) - return; - - if (t == NULL) - t = ffename_token (s->name); /* Use the first reference in this program unit. */ - - kind = ffesymbol_kind (s); - where = ffesymbol_where (s); - - if (where == FFEINFO_whereINTRINSIC) - { - ffeglobal_ref_intrinsic (s, t, - explicit - || s->explicit_where - || ffeintrin_is_standard (s->generic, s->specific)); - return; - } - - if ((where != FFEINFO_whereGLOBAL) - && ((where != FFEINFO_whereLOCAL) - || ((kind != FFEINFO_kindFUNCTION) - && (kind != FFEINFO_kindSUBROUTINE)))) - return; - - gn = ffename_lookup (ffesymbol_global_, t); - if (gn != NULL) - gs = ffename_symbol (gn); - if ((gs != NULL) && (gs != s)) - { - /* We have just discovered another global symbol with the same name - but a different `nature'. Complain. Note that COMMON /FOO/ can - coexist with local symbol FOO, e.g. local variable, just not with - CALL FOO, hence the separate namespaces. */ - - ffesymbol_error (gs, t); - ffesymbol_error (s, NULL); - return; - } - - switch (kind) - { - case FFEINFO_kindBLOCKDATA: - okay = ffeglobal_ref_blockdata (s, t); - break; - - case FFEINFO_kindSUBROUTINE: - okay = ffeglobal_ref_subroutine (s, t); - break; - - case FFEINFO_kindFUNCTION: - okay = ffeglobal_ref_function (s, t); - break; - - case FFEINFO_kindNONE: - okay = ffeglobal_ref_external (s, t); - break; - - default: - assert ("bad kind in global ref" == NULL); - return; - } - - if (! okay) - ffesymbol_error (s, NULL); -} - -/* Report info on the symbol for debugging purposes. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -ffesymbol -ffesymbol_report (ffesymbol s) -{ - ffeinfoKind k; - ffeinfoWhere w; - - assert (s != NULL); - - if (s->reported) - return s; - - s->reported = TRUE; - - if (ffeinfo_size (s->info) != FFETARGET_charactersizeNONE) - fprintf (dmpout, "\"%s\": %s %s %d%s%s*%" ffetargetCharacterSize_f "u", - ffesymbol_text (s), - ffesymbol_state_string (s->state), - ffesymbol_attrs_string (s->attrs), - (int) ffeinfo_rank (s->info), - ffeinfo_basictype_string (ffeinfo_basictype (s->info)), - ffeinfo_kindtype_string (ffeinfo_kindtype (s->info)), - ffeinfo_size (s->info)); - else - fprintf (dmpout, "\"%s\": %s %s %d%s%s", - ffesymbol_text (s), - ffesymbol_state_string (s->state), - ffesymbol_attrs_string (s->attrs), - (int) ffeinfo_rank (s->info), - ffeinfo_basictype_string (ffeinfo_basictype (s->info)), - ffeinfo_kindtype_string (ffeinfo_kindtype (s->info))); - if ((k = ffeinfo_kind (s->info)) != FFEINFO_kindNONE) - fprintf (dmpout, "/%s", ffeinfo_kind_string (k)); - if ((w = ffeinfo_where (s->info)) != FFEINFO_whereNONE) - fprintf (dmpout, "@%s", ffeinfo_where_string (w)); - fputc ('\n', dmpout); - - if (s->dims != NULL) - { - fprintf (dmpout, " dims: "); - ffebld_dump (s->dims); - fputs ("\n", dmpout); - } - - if (s->extents != NULL) - { - fprintf (dmpout, " extents: "); - ffebld_dump (s->extents); - fputs ("\n", dmpout); - } - - if (s->dim_syms != NULL) - { - fprintf (dmpout, " dim syms: "); - ffebld_dump (s->dim_syms); - fputs ("\n", dmpout); - } - - if (s->array_size != NULL) - { - fprintf (dmpout, " array size: "); - ffebld_dump (s->array_size); - fputs ("\n", dmpout); - } - - if (s->init != NULL) - { - fprintf (dmpout, " init-value: "); - if (ffebld_op (s->init) == FFEBLD_opANY) - fputs ("<any>\n", dmpout); - else - { - ffebld_dump (s->init); - fputs ("\n", dmpout); - } - } - - if (s->accretion != NULL) - { - fprintf (dmpout, " accretion (%" ffetargetOffset_f "d left): ", - s->accretes); - ffebld_dump (s->accretion); - fputs ("\n", dmpout); - } - else if (s->accretes != 0) - fprintf (dmpout, " accretes!! = %" ffetargetOffset_f "d left\n", - s->accretes); - - if (s->dummy_args != NULL) - { - fprintf (dmpout, " dummies: "); - ffebld_dump (s->dummy_args); - fputs ("\n", dmpout); - } - - if (s->namelist != NULL) - { - fprintf (dmpout, " namelist: "); - ffebld_dump (s->namelist); - fputs ("\n", dmpout); - } - - if (s->common_list != NULL) - { - fprintf (dmpout, " common-list: "); - ffebld_dump (s->common_list); - fputs ("\n", dmpout); - } - - if (s->sfunc_expr != NULL) - { - fprintf (dmpout, " sfunc expression: "); - ffebld_dump (s->sfunc_expr); - fputs ("\n", dmpout); - } - - if (s->is_save) - { - fprintf (dmpout, " SAVEd\n"); - } - - if (s->is_init) - { - fprintf (dmpout, " initialized\n"); - } - - if (s->do_iter) - { - fprintf (dmpout, " DO-loop iteration variable (currently)\n"); - } - - if (s->explicit_where) - { - fprintf (dmpout, " Explicit INTRINSIC/EXTERNAL\n"); - } - - if (s->namelisted) - { - fprintf (dmpout, " Namelisted\n"); - } - - if (s->common != NULL) - { - fprintf (dmpout, " COMMON area: %s\n", ffesymbol_text (s->common)); - } - - if (s->equiv != NULL) - { - fprintf (dmpout, " EQUIVALENCE information: "); - ffeequiv_dump (s->equiv); - fputs ("\n", dmpout); - } - - if (s->storage != NULL) - { - fprintf (dmpout, " Storage: "); - ffestorag_dump (s->storage); - fputs ("\n", dmpout); - } - - return s; -} -#endif - -/* Report info on the symbols. */ - -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void -ffesymbol_report_all () -{ - ffename_space_drive_symbol (ffesymbol_sfunc_, ffesymbol_report); - ffename_space_drive_symbol (ffesymbol_local_, ffesymbol_report); - ffename_space_drive_symbol (ffesymbol_global_, ffesymbol_report); -} -#endif - -/* Resolve symbol that has become known intrinsic or non-intrinsic. */ - -void -ffesymbol_resolve_intrin (ffesymbol s) -{ - char c; - ffebad bad; - - if (!ffesrc_check_symbol ()) - return; - if (s->check_state != FFESYMBOL_checkstatePENDING_) - return; - if (ffebad_inhibit ()) - return; /* We'll get back to this later. */ - - if (ffesymbol_where (s) != FFEINFO_whereINTRINSIC) - { - bad = ffesymbol_check_token_ (s->check_token, &c); - assert (bad != FFEBAD); /* How did this suddenly become ok? */ - ffesymbol_whine_state_ (bad, s->check_token, c); - } - - s->check_state = FFESYMBOL_checkstateCHECKED_; - ffelex_token_kill (s->check_token); -} - -/* Retract or cancel retract list. */ - -void -ffesymbol_retract (bool retract) -{ - ffesymbolRetract_ r; - ffename name; - ffename other_space_name; - ffesymbol ls; - ffesymbol os; - - assert (ffesymbol_retractable_); - - ffesymbol_retractable_ = FALSE; - - for (r = ffesymbol_retract_first_; r != NULL; r = r->next) - { - ls = r->live; - os = r->symbol; - switch (r->command) - { - case FFESYMBOL_retractcommandDELETE_: - if (retract) - { - ffecom_sym_retract (ls); - name = ls->name; - other_space_name = ls->other_space_name; - ffesymbol_unhook_ (ls); - malloc_kill_ks (FFESYMBOL_SPACE_POOL_, ls, sizeof (*ls)); - if (name != NULL) - ffename_set_symbol (name, NULL); - if (other_space_name != NULL) - ffename_set_symbol (other_space_name, NULL); - } - else - { - ffecom_sym_commit (ls); - ls->have_old = FALSE; - } - break; - - case FFESYMBOL_retractcommandRETRACT_: - if (retract) - { - ffecom_sym_retract (ls); - ffesymbol_unhook_ (ls); - *ls = *os; - malloc_kill_ks (FFESYMBOL_SPACE_POOL_, os, sizeof (*os)); - } - else - { - ffecom_sym_commit (ls); - ffesymbol_unhook_ (os); - malloc_kill_ks (FFESYMBOL_SPACE_POOL_, os, sizeof (*os)); - ls->have_old = FALSE; - } - break; - - default: - assert ("bad command" == NULL); - break; - } - } -} - -/* Return retractable flag. */ - -bool -ffesymbol_retractable () -{ - return ffesymbol_retractable_; -} - -/* Set retractable flag, retract pool. - - Between this call and ffesymbol_retract, any changes made to existing - symbols cause the previous versions of those symbols to be saved, and any - newly created symbols to have their previous nonexistence saved. When - ffesymbol_retract is called, this information either is used to retract - the changes and new symbols, or is discarded. */ - -void -ffesymbol_set_retractable (mallocPool pool) -{ - assert (!ffesymbol_retractable_); - - ffesymbol_retractable_ = TRUE; - ffesymbol_retract_pool_ = pool; - ffesymbol_retract_list_ = &ffesymbol_retract_first_; - ffesymbol_retract_first_ = NULL; -} - -/* Existing symbol about to be changed; save? - - Call this function before changing a symbol if it is possible that - the current actions may need to be undone (i.e. one of several possible - statement forms are being used to analyze the current system). - - If the "retractable" flag is not set, just return. - Else, if the symbol's "have_old" flag is set, just return. - Else, make a copy of the symbol and add it to the "retract" list, set - the "have_old" flag, and return. */ - -void -ffesymbol_signal_change (ffesymbol s) -{ - ffesymbolRetract_ r; - ffesymbol sym; - - if (!ffesymbol_retractable_ || s->have_old) - return; - - r = (ffesymbolRetract_) malloc_new_kp (ffesymbol_retract_pool_, - "FFESYMBOL retract", sizeof (*r)); - r->next = NULL; - r->command = FFESYMBOL_retractcommandRETRACT_; - r->live = s; - r->symbol = sym = (ffesymbol) malloc_new_ks (FFESYMBOL_SPACE_POOL_, - "FFESYMBOL", sizeof (*sym)); - *sym = *s; /* Make an exact copy of the symbol in case - we need it back. */ - sym->info = ffeinfo_use (s->info); - if (s->check_state == FFESYMBOL_checkstatePENDING_) - sym->check_token = ffelex_token_use (s->check_token); - - *ffesymbol_retract_list_ = r; - ffesymbol_retract_list_ = &r->next; - - s->have_old = TRUE; -} - -/* Returns the string based on the state. */ - -char * -ffesymbol_state_string (ffesymbolState state) -{ - if (state >= ARRAY_SIZE (ffesymbol_state_name_)) - return "?\?\?"; - return ffesymbol_state_name_[state]; -} - -void -ffesymbol_terminate_0 () -{ -} - -void -ffesymbol_terminate_1 () -{ -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalFILE_ - ffename_space_drive_symbol (ffesymbol_global_, ffesymbol_unhook_); - ffename_space_kill (ffesymbol_global_); - ffesymbol_global_ = NULL; - - ffesymbol_kill_manifest_ (); -#endif -} - -void -ffesymbol_terminate_2 () -{ -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_ - ffesymbol_kill_manifest_ (); -#endif -} - -void -ffesymbol_terminate_3 () -{ -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_ - ffename_space_drive_symbol (ffesymbol_global_, ffesymbol_unhook_); - ffename_space_kill (ffesymbol_global_); -#endif - ffename_space_drive_symbol (ffesymbol_local_, ffesymbol_unhook_); - ffename_space_kill (ffesymbol_local_); -#if FFESYMBOL_globalCURRENT_ == FFESYMBOL_globalPROGUNIT_ - ffesymbol_global_ = NULL; -#endif - ffesymbol_local_ = NULL; -} - -void -ffesymbol_terminate_4 () -{ - ffename_space_drive_symbol (ffesymbol_sfunc_, ffesymbol_unhook_); - ffename_space_kill (ffesymbol_sfunc_); - ffesymbol_sfunc_ = NULL; -} - -/* Update INIT info to TRUE and all equiv/storage too. - - If INIT flag is TRUE, does nothing. Else sets it to TRUE and calls - on the ffeequiv and ffestorag modules to update their INIT flags if - the <s> symbol has those objects, and also updates the common area if - it exists. */ - -void -ffesymbol_update_init (ffesymbol s) -{ - ffebld item; - - if (s->is_init) - return; - - s->is_init = TRUE; - - if ((s->equiv != NULL) - && !ffeequiv_is_init (s->equiv)) - ffeequiv_update_init (s->equiv); - - if ((s->storage != NULL) - && !ffestorag_is_init (s->storage)) - ffestorag_update_init (s->storage); - - if ((s->common != NULL) - && (!ffesymbol_is_init (s->common))) - ffesymbol_update_init (s->common); - - for (item = s->common_list; item != NULL; item = ffebld_trail (item)) - { - if (!ffesymbol_is_init (ffebld_symter (ffebld_head (item)))) - ffesymbol_update_init (ffebld_symter (ffebld_head (item))); - } -} - -/* Update SAVE info to TRUE and all equiv/storage too. - - If SAVE flag is TRUE, does nothing. Else sets it to TRUE and calls - on the ffeequiv and ffestorag modules to update their SAVE flags if - the <s> symbol has those objects, and also updates the common area if - it exists. */ - -void -ffesymbol_update_save (ffesymbol s) -{ - ffebld item; - - if (s->is_save) - return; - - s->is_save = TRUE; - - if ((s->equiv != NULL) - && !ffeequiv_is_save (s->equiv)) - ffeequiv_update_save (s->equiv); - - if ((s->storage != NULL) - && !ffestorag_is_save (s->storage)) - ffestorag_update_save (s->storage); - - if ((s->common != NULL) - && (!ffesymbol_is_save (s->common))) - ffesymbol_update_save (s->common); - - for (item = s->common_list; item != NULL; item = ffebld_trail (item)) - { - if (!ffesymbol_is_save (ffebld_symter (ffebld_head (item)))) - ffesymbol_update_save (ffebld_symter (ffebld_head (item))); - } -} diff --git a/gcc/f/symbol.def b/gcc/f/symbol.def deleted file mode 100755 index 343f80e..0000000 --- a/gcc/f/symbol.def +++ /dev/null @@ -1,654 +0,0 @@ -/* Definitions and documentations for attributes used in GNU F77 compiler - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -/* "How g77 learns about symbols" - - There are three primary things in a symbol that g77 uses to keep - track of what it has learned about that symbol: - - 1. The state - 2. The attributes - 3. The info - - State, attributes, and info (see f-info* files) all start out with - "NONE" fields when a symbol is first created. - - In a PROGRAM or BLOCK DATA program unit, info where cannot be DUMMY - or RESULT. Any combinations including those possibilities are not - considered possible in such program units. - - As soon as a symbol is created, it _must_ have its state changed to - SEEN, UNCERTAIN, or UNDERSTOOD. - - If SEEN, some info might be set, such as the type info (as in when - the TYPE attribute is present) or kind/where info. - - If UNCERTAIN, the permitted combinations of attributes and info are - listed below. Only the attributes ACTUALARG, ADJUSTABLE, ANYLEN, ARRAY, - DUMMY, EXTERNAL, SFARG, and TYPE are permitted. (All these attributes - are contrasted to each attribute below, even though some combinations - wouldn't be permitted in SEEN state either.) Note that DUMMY and - RESULT are not permitted in a PROGRAM/BLOCKDATA program unit, which - results in some of the combinations below not occurring (not UNCERTAIN, - but UNDERSTOOD). - - ANYLEN|TYPE & ~(ACTUALARG|ADJUSTABLE|ARRAY|DUMMY|EXTERNAL|SFARG): - ENTITY/DUMMY, ENTITY/RESULT, FUNCTION/INTRINSIC. - - ARRAY & ~(ACTUALARG|ANYLEN|DUMMY|EXTERNAL|SFARG|TYPE): - ENTITY/DUMMY, ENTITY/LOCAL. - - ARRAY|TYPE & ~(ACTUALARG|ANYLEN|DUMMY|EXTERNAL|SFARG): - ENTITY/DUMMY, ENTITY/LOCAL. - - DUMMY & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|EXTERNAL|SFARG|TYPE): - ENTITY/DUMMY, FUNCTION/DUMMY, SUBROUTINE/DUMMY. - - DUMMY|TYPE & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|EXTERNAL|SFARG): - ENTITY/DUMMY, FUNCTION/DUMMY. - - EXTERNAL & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|DUMMY|SFARG|TYPE): - FUNCTION/DUMMY, FUNCTION/GLOBAL, SUBROUTINE/DUMMY, - SUBROUTINE/GLOBAL, BLOCKDATA/GLOBAL. - - EXTERNAL|ACTUALARG & ~(ADJUSTABLE|ANYLEN|ARRAY|DUMMY|SFARG|TYPE): - FUNCTION/GLOBAL, SUBROUTINE/GLOBAL. - - EXTERNAL|DUMMY & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|SFARG|TYPE): - FUNCTION/DUMMY, SUBROUTINE/DUMMY. - - EXTERNAL|TYPE & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|DUMMY|SFARG): - FUNCTION/DUMMY, FUNCTION/GLOBAL. - - SFARG & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|DUMMY|EXTERNAL|TYPE): - ENTITY/DUMMY, ENTITY/LOCAL. - - SFARG|TYPE & ~(ACTUALARG|ADJUSTABLE|ANYLEN|ARRAY|DUMMY|EXTERNAL): - ENTITY/DUMMY, ENTITY/LOCAL. - - TYPE & ~(ACTUALARG|ANYLEN|ARRAY|DUMMY|EXTERNAL|SFARG): - ENTITY/DUMMY, ENTITY/LOCAL, ENTITY/RESULT, FUNCTION/DUMMY, - FUNCTION/GLOBAL, FUNCTION/INTRINSIC. - - If UNDERSTOOD, the attributes are no longer considered, and the info - field is considered to be as fully filled in as possible by analyzing - a single program unit. - - Each of the attributes (used only for SEEN/UNCERTAIN states) is - defined and described below. In many cases, a symbol starts out as - SEEN and has attributes set as it is seen in various contexts prior - to the first executable statement being seen (the "exec transition"). - Once that happens, either it becomes immediately UNDERSTOOD and all - its info filled in, or it becomes UNCERTAIN and its info only partially - filled in until it becomes UNDERSTOOD. While UNCERTAIN, only a - subset of attributes are possible/important. - - Not all symbols reach the UNDERSTOOD state, and in some cases symbols - go immediately from NONE to the UNDERSTOOD or even UNCERTAIN state. - For example, given "PROGRAM FOO", everything is known about the name - "FOO", so it becomes immediately UNDERSTOOD. - - Also, there are multiple name spaces, and not all attributes are - possible/permitted in all name spaces. - - The only attributes permitted in the global name space are: - - ANY, CBLOCK, SAVECBLOCK. - - The only attributes permitted in the local name space are: - - ANY, ACTUALARG, ADJUSTABLE, ADJUSTS, ANYLEN, ANYSIZE, ARRAY, COMMON, - DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, RESULT, SAVE, SFARG, - SFUNC, TYPE. - - In the stmt-func name space, no attributes are used, just the states. - -*/ - - -/* Actual argument. Always accompanied by EXTERNAL. - - Context is a name used as an actual argument passed to a procedure - other than a statement function. - - Valid in UNCERTAIN state and local name space only. - - This attribute is used only to flag the fact that an EXTERNAL'ed name - has been seen as an actual argument, and therefore cannot be - discovered later to be a DUMMY argument (via an ENTRY statement). - - If DUMMY + EXTERNAL already, it is permitted to see the name - as an actual argument, but ACTUALARG is not added as an attribute since - that fact does not improve knowledge about the name. Hence it is not - permitted to transition ACTUALARG + EXTERNAL += DUMMY, and the - transition DUMMY + EXTERNAL += ACTUALARG is not actually done. - - Cannot be combined with: ANYLEN, ARRAY, DUMMY, SFARG, TYPE. - - Can be combined with: ACTUALARG, ANY, EXTERNAL. - - Unrelated: ADJUSTABLE, ADJUSTS, ANYSIZE, CBLOCK, COMMON, EQUIV, INIT, - INTRINSIC, NAMELIST, RESULT, SAVE, SAVECBLOCK, SFUNC. - -*/ - -DEFATTR (FFESYMBOL_attrACTUALARG, FFESYMBOL_attrsACTUALARG, "ACTUALARG") -#ifndef FFESYMBOL_attrsACTUALARG -#define FFESYMBOL_attrsACTUALARG ((ffesymbolAttrs) 1 << FFESYMBOL_attrACTUALARG) -#endif - -/* Has adjustable dimension(s). Always accompanied by ARRAY. - - Context is an ARRAY-attributed name with an adjustable dimension (at - least one dimension containing a variable reference). - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ADJUSTS, COMMON, EQUIV, EXTERNAL, - NAMELIST, INIT, INTRINSIC, RESULT, SAVE, SFARG, SFUNC. - - Can be combined with: ANY, ANYLEN, ANYSIZE, ARRAY, TYPE. - - Must be combined with: DUMMY. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrADJUSTABLE, FFESYMBOL_attrsADJUSTABLE, "ADJUSTABLE") -#ifndef FFESYMBOL_attrsADJUSTABLE -#define FFESYMBOL_attrsADJUSTABLE ((ffesymbolAttrs) 1 << FFESYMBOL_attrADJUSTABLE) -#endif - -/* Adjusts an array. - - Context is an expression in an array declarator, such as in a - DIMENSION, COMMON, or type-specification statement. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ANYLEN, ANYSIZE, ARRAY, - EXTERNAL, INTRINSIC, RESULT, SAVE, SFUNC. - - Can be combined with: ADJUSTS, ANY, COMMON, DUMMY, EQUIV, INIT, - NAMELIST, SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrADJUSTS, FFESYMBOL_attrsADJUSTS, "ADJUSTS") -#ifndef FFESYMBOL_attrsADJUSTS -#define FFESYMBOL_attrsADJUSTS ((ffesymbolAttrs) 1 << FFESYMBOL_attrADJUSTS) -#endif - -/* Can be anything now, diagnostic has been issued at least once. - - Valid in UNDERSTOOD state only. Valid in any name space. - - Can be combined with anything. - -*/ - -DEFATTR (FFESYMBOL_attrANY, FFESYMBOL_attrsANY, "ANY") -#ifndef FFESYMBOL_attrsANY -#define FFESYMBOL_attrsANY ((ffesymbolAttrs) 1 << FFESYMBOL_attrANY) -#endif - -/* Assumed (any) length. Always accompanied by TYPE. - - Context is a name listed in a CHARACTER statement and given a length - specification of (*). - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with ANYLEN, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Any other subsequent mentioning - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ACTUALARG=, ADJUSTS+, ANYLEN, COMMON+, EQUIV+, - EXTERNAL, INIT+, INTRINSIC+, NAMELIST+, SAVE+, SFARG, SFUNC+. - - Can be combined with: ADJUSTABLE+, ANY, ANYSIZE+, ARRAY-, DUMMY!, RESULT+, - TYPE. - - Unrelated: CBLOCK, SAVECBLOCK. - - In PROGRAM/BLOCKDATA, cannot be combined with ARRAY. - -*/ - -DEFATTR (FFESYMBOL_attrANYLEN, FFESYMBOL_attrsANYLEN, "ANYLEN") -#ifndef FFESYMBOL_attrsANYLEN -#define FFESYMBOL_attrsANYLEN ((ffesymbolAttrs) 1 << FFESYMBOL_attrANYLEN) -#endif - -/* Has assumed (any) size. Always accompanied by ARRAY. - - Context is an ARRAY-attributed name with its last dimension having - an upper bound of "*". - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTS, ANYSIZE, COMMON, EQUIV, EXTERNAL, - NAMELIST, INIT, INTRINSIC, RESULT, SAVE, SFARG, SFUNC. - - Can be combined with: ADJUSTABLE, ANY, ANYLEN, ARRAY, TYPE. - - Must be combined with: DUMMY. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrANYSIZE, FFESYMBOL_attrsANYSIZE, "ANYSIZE") -#ifndef FFESYMBOL_attrsANYSIZE -#define FFESYMBOL_attrsANYSIZE ((ffesymbolAttrs) 1 << FFESYMBOL_attrANYSIZE) -#endif - -/* Array. - - Context is a name followed by an array declarator, such as in a - type-statement-decl, a DIMENSION statement, or a COMMON statement. - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with ARRAY, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Any other subsequent mentioning - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ACTUALARG=, ADJUSTS+, ARRAY, EXTERNAL, - INTRINSIC+, RESULT+, SFARG, SFUNC+. - - Can be combined with: ADJUSTABLE+, ANY, ANYLEN-, ANYSIZE+, COMMON+, - DUMMY!, EQUIV+, INIT+, NAMELIST+, SAVE+, TYPE. - - Unrelated: CBLOCK, SAVECBLOCK. - - In PROGRAM/BLOCKDATA, cannot be combined with ANYLEN. - Cannot follow INIT. - -*/ - -DEFATTR (FFESYMBOL_attrARRAY, FFESYMBOL_attrsARRAY, "ARRAY") -#ifndef FFESYMBOL_attrsARRAY -#define FFESYMBOL_attrsARRAY ((ffesymbolAttrs) 1 << FFESYMBOL_attrARRAY) -#endif - -/* COMMON block. - - Context is a name enclosed in slashes in a COMMON statement. - - Valid in SEEN state and global name space only. - - Cannot be combined with: - - Can be combined with: CBLOCK, SAVECBLOCK. - - Unrelated: ACTUALARG, ADJUSTABLE, ADJUSTS, ANY, ANYLEN, ANYSIZE, - ARRAY, COMMON, DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, - RESULT, SAVE, SFARG, SFUNC, TYPE. - -*/ - -DEFATTR (FFESYMBOL_attrCBLOCK, FFESYMBOL_attrsCBLOCK, "CBLOCK") -#ifndef FFESYMBOL_attrsCBLOCK -#define FFESYMBOL_attrsCBLOCK ((ffesymbolAttrs) 1 << FFESYMBOL_attrCBLOCK) -#endif - -/* Placed in COMMON. - - Context is a name listed in a COMMON statement but not enclosed in - slashes. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ANYLEN, ANYSIZE, COMMON, DUMMY, - EXTERNAL, INTRINSIC, RESULT, SAVE, SFUNC. - - Can be combined with: ADJUSTS, ANY, ARRAY, EQUIV, INIT, NAMELIST, - SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrCOMMON, FFESYMBOL_attrsCOMMON, "COMMON") -#ifndef FFESYMBOL_attrsCOMMON -#define FFESYMBOL_attrsCOMMON ((ffesymbolAttrs) 1 << FFESYMBOL_attrCOMMON) -#endif - -/* Dummy argument. - - Context is a name listed in the arglist of FUNCTION, SUBROUTINE, ENTRY. - (Statement-function definitions have dummy arguments, but since they're - the only possible entities in the statement-function name space, this - attribution mechanism isn't used for them.) - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with DUMMY, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Any other subsequent mentioning - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ACTUALARG=, COMMON+, EQUIV+, INIT+, INTRINSIC+, - NAMELIST+, RESULT+, SAVE+, SFUNC+. - - Can be combined with: ADJUSTABLE+, ADJUSTS+, ANY, ANYLEN-, ANYSIZE+, - ARRAY-, DUMMY, EXTERNAL, SFARG-, TYPE. - - Unrelated: CBLOCK, SAVECBLOCK. - - VXT Fortran disallows DUMMY + NAMELIST. - F90 allows DUMMY + NAMELIST (with some restrictions), g77 doesn't yet. - -*/ - -DEFATTR (FFESYMBOL_attrDUMMY, FFESYMBOL_attrsDUMMY, "DUMMY") -#ifndef FFESYMBOL_attrsDUMMY -#define FFESYMBOL_attrsDUMMY ((ffesymbolAttrs) 1 << FFESYMBOL_attrDUMMY) -#endif - -/* EQUIVALENCE'd. - - Context is a name given in an EQUIVALENCE statement. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ANYLEN, ANYSIZE, DUMMY, - EXTERNAL, INTRINSIC, RESULT, SFUNC. - - Can be combined with: ADJUSTS, ANY, ARRAY, COMMON, EQUIV, INIT, - NAMELIST, SAVE, SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrEQUIV, FFESYMBOL_attrsEQUIV, "EQUIV") -#ifndef FFESYMBOL_attrsEQUIV -#define FFESYMBOL_attrsEQUIV ((ffesymbolAttrs) 1 << FFESYMBOL_attrEQUIV) -#endif - -/* EXTERNAL. - - Context is a name listed in an EXTERNAL statement. - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with EXTERNAL, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Many other subsequent mentionings - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ADJUSTABLE+, ADJUSTS+, ANYLEN, ANYSIZE+, - ARRAY, COMMON+, EQUIV+, EXTERNAL, INIT+, INTRINSIC+, NAMELIST+, RESULT+, - SAVE+, SFARG, SFUNC+. - - Can be combined with: ACTUALARG=, ANY, DUMMY, TYPE. - - Unrelated: CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrEXTERNAL, FFESYMBOL_attrsEXTERNAL, "EXTERNAL") -#ifndef FFESYMBOL_attrsEXTERNAL -#define FFESYMBOL_attrsEXTERNAL ((ffesymbolAttrs) 1 << FFESYMBOL_attrEXTERNAL) -#endif - -/* Given an initial value. - - Context is a name listed in a type-def-stmt such as INTEGER or REAL - and given an initial value or values. Someday will also include - names in DATA statements, which currently immediately exec-transition - their targets. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ANYLEN, ANYSIZE, DUMMY, EXTERNAL, - INIT, INTRINSIC, RESULT, SFUNC. - - Can be combined with: ADJUSTS, ANY, ARRAY, COMMON, EQUIV, NAMELIST, - SAVE, SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - - Cannot be followed by ARRAY. - -*/ - -DEFATTR (FFESYMBOL_attrINIT, FFESYMBOL_attrsINIT, "INIT") -#ifndef FFESYMBOL_attrsINIT -#define FFESYMBOL_attrsINIT ((ffesymbolAttrs) 1 << FFESYMBOL_attrINIT) -#endif - -/* INTRINSIC. - - Context is a name listed in an INTRINSIC statement. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ADJUSTS, ANYLEN, ANYSIZE, ARRAY, - COMMON, DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, RESULT, - SAVE, SFARG, SFUNC. - - Can be combined with: ANY, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrINTRINSIC, FFESYMBOL_attrsINTRINSIC, "INTRINSIC") -#ifndef FFESYMBOL_attrsINTRINSIC -#define FFESYMBOL_attrsINTRINSIC ((ffesymbolAttrs) 1 << FFESYMBOL_attrINTRINSIC) -#endif - -/* NAMELISTed. - - Context is a name listed in a NAMELIST statement but not enclosed in - slashes. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ANYLEN, ANYSIZE, DUMMY, EXTERNAL, - INTRINSIC, RESULT, SFUNC. - - Can be combined with: ADJUSTS, ANY, ARRAY, COMMON, EQUIV, INIT, - NAMELIST, SAVE, SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrNAMELIST, FFESYMBOL_attrsNAMELIST, "NAMELIST") -#ifndef FFESYMBOL_attrsNAMELIST -#define FFESYMBOL_attrsNAMELIST ((ffesymbolAttrs) 1 << FFESYMBOL_attrNAMELIST) -#endif - -/* RESULT of a function. - - Context is name in RESULT() clause in FUNCTION or ENTRY statement, or - the name in a FUNCTION or ENTRY statement (within a FUNCTION subprogram) - that has no RESULT() clause. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ADJUSTS, ANYSIZE, ARRAY, COMMON, - DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, RESULT, SAVE, SFUNC. - - Can be combined with: ANY, ANYLEN, SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - - Cannot be preceded by SFARG. - -*/ - -DEFATTR (FFESYMBOL_attrRESULT, FFESYMBOL_attrsRESULT, "RESULT") -#ifndef FFESYMBOL_attrsRESULT -#define FFESYMBOL_attrsRESULT ((ffesymbolAttrs) 1 << FFESYMBOL_attrRESULT) -#endif - -/* SAVEd (not enclosed in slashes). - - Context is a name listed in a SAVE statement but not enclosed in slashes. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADUSTABLE, ADJUSTS, ANYLEN, ANYSIZE, COMMON, - DUMMY, EXTERNAL, INTRINSIC, RESULT, SAVE, SFUNC. - - Can be combined with: ANY, ARRAY, EQUIV, INIT, NAMELIST, - SFARG, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrSAVE, FFESYMBOL_attrsSAVE, "SAVE") -#ifndef FFESYMBOL_attrsSAVE -#define FFESYMBOL_attrsSAVE ((ffesymbolAttrs) 1 << FFESYMBOL_attrSAVE) -#endif - -/* SAVEd (enclosed in slashes). - - Context is a name enclosed in slashes in a SAVE statement. - - Valid in SEEN state and global name space only. - - Cannot be combined with: SAVECBLOCK. - - Can be combined with: CBLOCK. - - Unrelated: ACTUALARG, ADJUSTABLE, ADJUSTS, ANY, ANYLEN, ANYSIZE, - ARRAY, COMMON, DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, - RESULT, SAVE, SFARG, SFUNC, TYPE. - -*/ - -DEFATTR (FFESYMBOL_attrSAVECBLOCK, FFESYMBOL_attrsSAVECBLOCK, "SAVECBLOCK") -#ifndef FFESYMBOL_attrsSAVECBLOCK -#define FFESYMBOL_attrsSAVECBLOCK ((ffesymbolAttrs) 1 << FFESYMBOL_attrSAVECBLOCK) -#endif - -/* Name used as a statement function arg or DATA implied-DO iterator. - - Context is a name listed in the arglist of statement-function-definition - or as the iterator in an implied-DO construct in a DATA statement. - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with SFARG, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Any other subsequent mentioning - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ACTUALARG=, ADJUSTABLE+, ANYLEN, ANYSIZE+, - ARRAY, EXTERNAL, INTRINSIC+, SFUNC+. - - Can be combined with: ADJUSTS+, ANY, COMMON+, DUMMY!, EQUIV+, INIT+, - NAMELIST+, RESULT+, SAVE+, SFARG, TYPE. - - Unrelated: CBLOCK, SAVECBLOCK. - - Cannot be followed by RESULT. - -*/ - -DEFATTR (FFESYMBOL_attrSFARG, FFESYMBOL_attrsSFARG, "SFARG") -#ifndef FFESYMBOL_attrsSFARG -#define FFESYMBOL_attrsSFARG ((ffesymbolAttrs) 1 << FFESYMBOL_attrSFARG) -#endif - -/* Statement function name. - - Context is a statement-function-definition statement, the name being - defined. - - Valid in SEEN state and local name space only. - - Cannot be combined with: ADJUSTABLE, ADJUSTS, ANYLEN, ANYSIZE, ARRAY, - COMMON, DUMMY, EQUIV, EXTERNAL, INIT, INTRINSIC, NAMELIST, RESULT, - SAVE, SFARG, SFUNC. - - Can be combined with: ANY, TYPE. - - Unrelated: ACTUALARG, CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrSFUNC, FFESYMBOL_attrsSFUNC, "SFUNC") -#ifndef FFESYMBOL_attrsSFUNC -#define FFESYMBOL_attrsSFUNC ((ffesymbolAttrs) 1 << FFESYMBOL_attrSFUNC) -#endif - -/* Explicitly typed. - - Context is a name listed in a type-def-stmt such as INTEGER or REAL. - - Valid in SEEN and UNCERTAIN states. Valid in local name space only. - - In SEEN state, attributes marked below with "=" are unrelated. - - In UNCERTAIN state, attributes marked below with "+" are unrelated, - attributes marked below with "-" cannot be combined with TYPE, - and attributes marked below with "!" transition to state UNDERSTOOD - instead of acquiring the new attribute. Many other subsequent mentionings - of the name transitions to state UNDERSTOOD. UNCERTAIN state is not - valid for this attribute in PROGRAM/BLOCKDATA program unit. - - Cannot be combined with: ACTUALARG=, TYPE. - - Can be combined with: ADJUSTABLE+, ADJUSTS+, ANY, ANYLEN, ANYSIZE+, - ARRAY, COMMON+, DUMMY, EQUIV+, EXTERNAL, INIT+, INTRINSIC+, NAMELIST+, - RESULT+, SAVE+, SFARG, SFUNC+. - - Unrelated: CBLOCK, SAVECBLOCK. - -*/ - -DEFATTR (FFESYMBOL_attrTYPE, FFESYMBOL_attrsTYPE, "TYPE") -#ifndef FFESYMBOL_attrsTYPE -#define FFESYMBOL_attrsTYPE ((ffesymbolAttrs) 1 << FFESYMBOL_attrTYPE) -#endif diff --git a/gcc/f/symbol.h b/gcc/f/symbol.h deleted file mode 100755 index b534ae6..0000000 --- a/gcc/f/symbol.h +++ /dev/null @@ -1,293 +0,0 @@ -/* Interface definitions for Fortran symbol manager - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef _H_f_symbol -#define _H_f_symbol - -/* The main symbol type. */ - -typedef struct _ffesymbol_ *ffesymbol; - -/* State of understanding about what the symbol represents. */ - -enum _ffesymbol_state_ - { -/* See ffesymbol_state_is_exec() macro below when making changes. */ - FFESYMBOL_stateNONE, /* Never before seen. */ - FFESYMBOL_stateSEEN, /* Seen before exec transition and not yet - understood (info not filled in, etc). */ - FFESYMBOL_stateUNCERTAIN, /* Almost understood (info partly filled in). */ - FFESYMBOL_stateUNDERSTOOD, /* Fully understood (info filled in). */ - FFESYMBOL_state - }; -typedef enum _ffesymbol_state_ ffesymbolState; -#define ffesymbolState_f "" - -/* Attributes. Symbols acquire attributes while their state is SEEN. - These attributes are basically ignored once the symbol becomes - UNDERSTOOD. */ - -typedef long int ffesymbolAttrs;/* Holds set of attributes. */ -#define ffesymbolAttrs_f "l" - -enum _ffesymbol_attr_ - { -#define DEFATTR(ATTR,ATTRS,NAME) ATTR, -#include "symbol.def" -#undef DEFATTR - FFESYMBOL_attr - }; /* A given attribute. */ -typedef enum _ffesymbol_attr_ ffesymbolAttr; -#define ffesymbolAttr_f "" - -#define FFESYMBOL_attrsetNONE 0 -#define FFESYMBOL_attrsetALL (((ffesymbolAttrs) 1 << FFESYMBOL_attr) - 1) - -/* This is just for avoiding complaining about, e.g., "I = IABS(3)", that - IABS doesn't meet the requirements for a user-defined symbol name as - a result of, say, --symbol-case-lower, if IABS turns out to indeed be - a reference to the intrinsic IABS (in which case it's a Fortran keyword - like CALL) and not a user-defined name. */ - -enum _ffesymbol_checkstate_ - { - FFESYMBOL_checkstateNONE_, /* Not checked/never necessary to check. */ - FFESYMBOL_checkstateINHIBITED_, /* Bad name, but inhibited. */ - FFESYMBOL_checkstatePENDING_, /* Bad name, might be intrinsic. */ - FFESYMBOL_checkstateCHECKED_, /* Ok name, intrinsic, or bad name - reported. */ - FFESYMBOL_checkstate_ - }; -typedef enum _ffesymbol_checkstate_ ffesymbolCheckState_; -#define ffesymbolCheckState_f_ "" - -#include "bld.h" -#include "com.h" -#include "equiv.h" -#include "global.h" -#include "info.h" -#include "intrin.h" -#include "lex.h" -#include "malloc.h" -#include "name.h" -#include "storag.h" -#include "target.h" -#include "top.h" -#include "where.h" - -struct _ffesymbol_ - { - ffename name; - ffename other_space_name; /* For dual-space objects. */ - ffeglobal global; /* In filewide name space. */ - ffesymbolAttrs attrs; /* What kind of symbol am I? */ - ffesymbolState state; /* What state am I in? */ - ffeinfo info; /* Info filled in when _stateUNDERSTOOD. */ - ffebld dims; /* Dimension list expression. */ - ffebld extents; /* Extents list expression. */ - ffebld dim_syms; /* List of SYMTERs of all symbols in dims. */ - ffebld array_size; /* Size as an expression involving some of - dims. */ - ffebld init; /* Initialization expression or expr list or - PARAMETER value. */ - ffebld accretion; /* Initializations seen so far for - array/substr. */ - ffetargetOffset accretes; /* # inits needed to fill entire array. */ - ffebld dummy_args; /* For functions, subroutines, and entry - points. */ - ffebld namelist; /* List of symbols in NML. */ - ffebld common_list; /* List of entities in BCB/NCB. */ - ffebld sfunc_expr; /* SFN's expression. */ - ffebldListBottom list_bottom; /* For BCB, NCB, NML. */ - ffesymbol common; /* Who is my containing COMMON area? */ - ffeequiv equiv; /* Who have I been equivalenced with? */ - ffestorag storage; /* Where am I in relation to my outside - world? */ -#ifdef FFECOM_symbolHOOK - ffecomSymbol hook; /* Whatever the compiler/backend wants! */ -#endif - ffesymbol sfa_dummy_parent; /* "X" outside sfunc "CIRC(X) = 3.14 * X". */ - ffesymbol func_result; /* FUN sym's corresponding RES sym, & vice - versa. */ - ffetargetIntegerDefault value; /* IMMEDIATE (DATA impdo) value. */ - ffesymbolCheckState_ check_state; /* Valid name? */ - ffelexToken check_token; /* checkstatePENDING_ only. */ - int max_entry_num; /* For detecting dummy arg listed twice/IMPDO - iterator nesting violation; also for id of - sfunc dummy arg. */ - int num_entries; /* Number of entry points in which this - symbol appears as a dummy arg; helps - determine whether arg might not be passed, - for example. */ - ffeintrinGen generic; /* Generic intrinsic id, if any. */ - ffeintrinSpec specific; /* Specific intrinsic id, if any. */ - ffeintrinImp implementation;/* Implementation id, if any. */ - bool is_save; /* SAVE flag set for this symbol (see also - ffe_is_saveall()). */ - bool is_init; /* INIT flag set for this symbol. */ - bool do_iter; /* Is currently a DO-loop iter (can't be - changed in loop). */ - bool reported; /* (Debug) TRUE if the latest version has - been reported. */ - bool have_old; /* TRUE if old copy of this symbol saved - away. */ - bool explicit_where; /* TRUE if INTRINSIC/EXTERNAL explicit. */ - bool namelisted; /* TRUE if in NAMELIST (needs static alloc). */ - }; - -#define ffesymbol_accretes(s) ((s)->accretes) -#define ffesymbol_accretion(s) ((s)->accretion) -#define ffesymbol_arraysize(s) ((s)->array_size) -#define ffesymbol_attr(s,a) ((s)->attrs & ((ffesymbolAttrs) 1 << (a))) -#define ffesymbol_attrs(s) ((s)->attrs) -char *ffesymbol_attrs_string (ffesymbolAttrs attrs); -#define ffesymbol_basictype(s) ffeinfo_basictype((s)->info) -void ffesymbol_check (ffesymbol s, ffelexToken t, bool maybe_intrin); -#define ffesymbol_common(s) ((s)->common) -#define ffesymbol_commonlist(s) ((s)->common_list) -ffesymbol ffesymbol_declare_blockdataunit (ffelexToken t, ffewhereLine wl, - ffewhereColumn wc); -ffesymbol ffesymbol_declare_cblock (ffelexToken t, ffewhereLine wl, - ffewhereColumn wc); -ffesymbol ffesymbol_declare_funcnotresunit (ffelexToken t); -ffesymbol ffesymbol_declare_funcresult (ffelexToken t); -ffesymbol ffesymbol_declare_funcunit (ffelexToken t); -ffesymbol ffesymbol_declare_local (ffelexToken t, bool maybe_intrin); -ffesymbol ffesymbol_declare_programunit (ffelexToken t, ffewhereLine wl, - ffewhereColumn wc); -ffesymbol ffesymbol_declare_sfdummy (ffelexToken t); -ffesymbol ffesymbol_declare_subrunit (ffelexToken t); -#define ffesymbol_dims(s) ((s)->dims) -#define ffesymbol_dim_syms(s) ((s)->dim_syms) -void ffesymbol_drive (ffesymbol (*fn) ()); -void ffesymbol_drive_sfnames (ffesymbol (*fn) ()); -#define ffesymbol_dummyargs(s) ((s)->dummy_args) -#if FFECOM_targetCURRENT == FFECOM_targetFFE -void ffesymbol_dump (ffesymbol s); -#endif -void ffesymbol_error (ffesymbol s, ffelexToken t); -#define ffesymbol_equiv(s) ((s)->equiv) -#define ffesymbol_explicitwhere(s) ((s)->explicit_where) -#define ffesymbol_extents(s) ((s)->extents) -#define ffesymbol_first_token(s) ((s)->name == NULL ? NULL \ - : ffename_first_token((s)->name)) -#define ffesymbol_funcresult(s) ((s)->func_result) -#define ffesymbol_generic(s) ((s)->generic) -#define ffesymbol_global(s) ((s)->global) -#define ffesymbol_hook(s) ((s)->hook) -#define ffesymbol_implementation(s) ((s)->implementation) -#define ffesymbol_info(s) ((s)->info) -#define ffesymbol_init(s) ((s)->init) -void ffesymbol_init_0 (void); -void ffesymbol_init_1 (void); -void ffesymbol_init_2 (void); -void ffesymbol_init_3 (void); -void ffesymbol_init_4 (void); -#define ffesymbol_is_doiter(s) ((s)->do_iter) -#define ffesymbol_is_dualspace(s) ((s)->other_space_name != NULL) -#define ffesymbol_is_f2c(s) (ffe_is_f2c()) -#define ffesymbol_is_init(s) ((s)->is_init) -#define ffesymbol_is_reported(s) ((s)->reported) -#define ffesymbol_is_save(s) ((s)->is_save) -#define ffesymbol_is_specable(s) ffesymbol_state_is_specable(s->state) -#define ffesymbol_kindtype(s) ffeinfo_kindtype((s)->info) -#define ffesymbol_kind(s) ffeinfo_kind((s)->info) -ffesymbol ffesymbol_lookup_local (ffelexToken t); -#define ffesymbol_maxentrynum(s) ((s)->max_entry_num) -#define ffesymbol_name(s) ((s)->name) -#define ffesymbol_namelist(s) ((s)->namelist) -#define ffesymbol_namelisted(s) ((s)->namelisted) -#define ffesymbol_numentries(s) ((s)->num_entries) -#define ffesymbol_ptr_to_commonlist(s) (&(s)->common_list) -#define ffesymbol_ptr_to_listbottom(s) (&(s)->list_bottom) -#define ffesymbol_ptr_to_namelist(s) (&(s)->namelist) -#define ffesymbol_rank(s) ffeinfo_rank((s)->info) -void ffesymbol_reference (ffesymbol s, ffelexToken t, bool explicit); -#if FFECOM_targetCURRENT == FFECOM_targetFFE -ffesymbol ffesymbol_report (ffesymbol s); -void ffesymbol_report_all (void); -#endif -void ffesymbol_resolve_intrin (ffesymbol s); -void ffesymbol_retract (bool retract); -bool ffesymbol_retractable (void); -#define ffesymbol_set_accretes(s,a) ((s)->accretes = (a)) -#define ffesymbol_set_accretion(s,a) ((s)->accretion = (a)) -#define ffesymbol_set_arraysize(s,a) ((s)->array_size = (a)) -#define ffesymbol_set_attr(s,a) ((s)->attrs |= ((ffesymbolAttrs) 1 << (a))) -#define ffesymbol_set_attrs(s,a) ((s)->attrs = (a)) -#define ffesymbol_set_common(s,c) ((s)->common = (c)) -#define ffesymbol_set_commonlist(s,c) ((s)->common_list = (c)) -#define ffesymbol_set_dims(s,d) ((s)->dims = (d)) -#define ffesymbol_set_dim_syms(s,d) ((s)->dim_syms = (d)) -#define ffesymbol_set_dummyargs(s,d) ((s)->dummy_args = (d)) -#define ffesymbol_set_equiv(s,e) ((s)->equiv = (e)) -#define ffesymbol_set_explicitwhere(s,e) ((s)->explicit_where = (e)) -#define ffesymbol_set_extents(s,e) ((s)->extents = (e)) -#define ffesymbol_set_funcresult(s,f) ((s)->func_result = (f)) -#define ffesymbol_set_generic(s,g) ((s)->generic = (g)) -#define ffesymbol_set_global(s,g) ((s)->global = (g)) -#define ffesymbol_set_hook(s,h) ((s)->hook = (h)) -#define ffesymbol_set_implementation(s,im) ((s)->implementation = (im)) -#define ffesymbol_set_init(s,i) ((s)->init = (i)) -#define ffesymbol_set_info(s,i) ((s)->info = (i)) -#define ffesymbol_set_is_doiter(s,f) ((s)->do_iter = (f)) -#define ffesymbol_set_is_init(s,in) ((s)->is_init = (in)) -#define ffesymbol_set_is_save(s,sa) ((s)->is_save = (sa)) -#define ffesymbol_set_maxentrynum(s,m) ((s)->max_entry_num = (m)) -#define ffesymbol_set_namelist(s,n) ((s)->namelist = (n)) -#define ffesymbol_set_namelisted(s,n) ((s)->namelisted = (n)) -#define ffesymbol_set_numentries(s,n) ((s)->num_entries = (n)) -void ffesymbol_set_retractable (mallocPool pool); -#define ffesymbol_set_sfexpr(s,e) ((s)->sfunc_expr = (e)) -#define ffesymbol_set_specific(s,sp) ((s)->specific = (sp)) -#define ffesymbol_set_state(s,st) ((s)->state = (st)) -#define ffesymbol_set_storage(s,st) ((s)->storage = (st)) -#define ffesymbol_set_value(s,v) ((s)->value = (v)) -#define ffesymbol_sfdummyparent(s) ((s)->sfa_dummy_parent) -#define ffesymbol_sfexpr(s) ((s)->sfunc_expr) -void ffesymbol_signal_change (ffesymbol s); -#define ffesymbol_signal_unreported(s) ((s)->reported = FALSE) -#define ffesymbol_size(s) ffeinfo_size((s)->info) -#define ffesymbol_specific(s) ((s)->specific) -#define ffesymbol_state(s) ((s)->state) -#define ffesymbol_state_is_specable(s) ((s) <= FFESYMBOL_stateSEEN) -char *ffesymbol_state_string (ffesymbolState state); -#define ffesymbol_storage(s) ((s)->storage) -void ffesymbol_terminate_0 (void); -void ffesymbol_terminate_1 (void); -void ffesymbol_terminate_2 (void); -void ffesymbol_terminate_3 (void); -void ffesymbol_terminate_4 (void); -#define ffesymbol_text(s) (((s)->name == NULL) ? "<->" : ffename_text((s)->name)) -void ffesymbol_update_init (ffesymbol s); -void ffesymbol_update_save (ffesymbol s); -#define ffesymbol_value(s) ((s)->value) -#define ffesymbol_where(s) ffeinfo_where((s)->info) -#define ffesymbol_where_column(s) (((s)->name == NULL) \ - ? ffewhere_column_unknown() : ffename_where_column((s)->name)) -#define ffesymbol_where_filename(s) \ - ffewhere_line_filename(ffesymbol_where_line(s)) -#define ffesymbol_where_filelinenum(s) \ - ffewhere_line_filelinenum(ffesymbol_where_line(s)) -#define ffesymbol_where_line(s) (((s)->name == NULL) ? ffewhere_line_unknown() \ - : ffename_where_line((s)->name)) - -#endif diff --git a/gcc/f/system.j b/gcc/f/system.j deleted file mode 100755 index 6a37324..0000000 --- a/gcc/f/system.j +++ /dev/null @@ -1,27 +0,0 @@ -/* system.j -- Wrapper for GCC's system.h - Copyright (C) 1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_system -#define _J_f_system -#include "system.h" -#endif -#endif diff --git a/gcc/f/target.c b/gcc/f/target.c deleted file mode 100755 index 5de05ff..0000000 --- a/gcc/f/target.c +++ /dev/null @@ -1,2564 +0,0 @@ -/* target.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None - - Description: - Implements conversion of lexer tokens to machine-dependent numerical - form and accordingly issues diagnostic messages when necessary. - - Also, this module, especially its .h file, provides nearly all of the - information on the target machine's data type, kind type, and length - type capabilities. The idea is that by carefully going through - target.h and changing things properly, one can accomplish much - towards the porting of the FFE to a new machine. There are limits - to how much this can accomplish towards that end, however. For one - thing, the ffeexpr_collapse_convert function doesn't contain all the - conversion cases necessary, because the text file would be - enormous (even though most of the function would be cut during the - cpp phase because of the absence of the types), so when adding to - the number of supported kind types for a given type, one must look - to see if ffeexpr_collapse_convert needs modification in this area, - in addition to providing the appropriate macros and functions in - ffetarget. Note that if combinatorial explosion actually becomes a - problem for a given machine, one might have to modify the way conversion - expressions are built so that instead of just one conversion expr, a - series of conversion exprs are built to make a path from one type to - another that is not a "near neighbor". For now, however, with a handful - of each of the numeric types and only one character type, things appear - manageable. - - A nonobvious change to ffetarget would be if the target machine was - not a 2's-complement machine. Any item with the word "magical" (case- - insensitive) in the FFE's source code (at least) indicates an assumption - that a 2's-complement machine is the target, and thus that there exists - a magnitude that can be represented as a negative number but not as - a positive number. It is possible that this situation can be dealt - with by changing only ffetarget, for example, on a 1's-complement - machine, perhaps #defineing ffetarget_constant_is_magical to simply - FALSE along with making the appropriate changes in ffetarget's number - parsing functions would be sufficient to effectively "comment out" code - in places like ffeexpr that do certain magical checks. But it is - possible there are other 2's-complement dependencies lurking in the - FFE (as possibly is true of any large program); if you find any, please - report them so we can replace them with dependencies on ffetarget - instead. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "glimits.j" -#include "target.h" -#include "bad.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" - -/* Externals defined here. */ - -char ffetarget_string_[40]; /* Temp for ascii-to-double (atof). */ -HOST_WIDE_INT ffetarget_long_val_; -HOST_WIDE_INT ffetarget_long_junk_; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - -static void ffetarget_print_char_ (FILE *f, unsigned char c); - -/* Internal macros. */ - -#ifdef REAL_VALUE_ATOF -#define FFETARGET_ATOF_(p,m) REAL_VALUE_ATOF ((p),(m)) -#else -#define FFETARGET_ATOF_(p,m) atof ((p)) -#endif - - -/* ffetarget_print_char_ -- Print a single character (in apostrophe context) - - See prototype. - - Outputs char so it prints or is escaped C style. */ - -static void -ffetarget_print_char_ (FILE *f, unsigned char c) -{ - switch (c) - { - case '\\': - fputs ("\\\\", f); - break; - - case '\'': - fputs ("\\\'", f); - break; - - default: - if (ISPRINT (c)) - fputc (c, f); - else - fprintf (f, "\\%03o", (unsigned int) c); - break; - } -} - -/* ffetarget_aggregate_info -- Determine type for aggregate storage area - - See prototype. - - If aggregate type is distinct, just return it. Else return a type - representing a common denominator for the nondistinct type (for now, - just return default character, since that'll work on almost all target - machines). - - The rules for abt/akt are (as implemented by ffestorag_update): - - abt == FFEINFO_basictypeANY (akt == FFEINFO_kindtypeANY also, by - definition): CHARACTER and non-CHARACTER types mixed. - - abt == FFEINFO_basictypeNONE (akt == FFEINFO_kindtypeNONE also, by - definition): More than one non-CHARACTER type mixed, but no CHARACTER - types mixed in. - - abt some other value, akt == FFEINFO_kindtypeNONE: abt indicates the - only basic type mixed in, but more than one kind type is mixed in. - - abt some other value, akt some other value: abt and akt indicate the - only type represented in the aggregation. */ - -void -ffetarget_aggregate_info (ffeinfoBasictype *ebt, ffeinfoKindtype *ekt, - ffetargetAlign *units, ffeinfoBasictype abt, - ffeinfoKindtype akt) -{ - ffetype type; - - if ((abt == FFEINFO_basictypeNONE) || (abt == FFEINFO_basictypeANY) - || (akt == FFEINFO_kindtypeNONE)) - { - *ebt = FFEINFO_basictypeCHARACTER; - *ekt = FFEINFO_kindtypeCHARACTERDEFAULT; - } - else - { - *ebt = abt; - *ekt = akt; - } - - type = ffeinfo_type (*ebt, *ekt); - assert (type != NULL); - - *units = ffetype_size (type); -} - -/* ffetarget_align -- Align one storage area to superordinate, update super - - See prototype. - - updated_alignment/updated_modulo contain the already existing - alignment requirements for the storage area at whose offset the - object with alignment requirements alignment/modulo is to be placed. - Find the smallest pad such that the requirements are maintained and - return it, but only after updating the updated_alignment/_modulo - requirements as necessary to indicate the placement of the new object. */ - -ffetargetAlign -ffetarget_align (ffetargetAlign *updated_alignment, - ffetargetAlign *updated_modulo, ffetargetOffset offset, - ffetargetAlign alignment, ffetargetAlign modulo) -{ - ffetargetAlign pad; - ffetargetAlign min_pad; /* Minimum amount of padding needed. */ - ffetargetAlign min_m = 0; /* Minimum-padding m. */ - ffetargetAlign ua; /* Updated alignment. */ - ffetargetAlign um; /* Updated modulo. */ - ffetargetAlign ucnt; /* Multiplier applied to ua. */ - ffetargetAlign m; /* Copy of modulo. */ - ffetargetAlign cnt; /* Multiplier applied to alignment. */ - ffetargetAlign i; - ffetargetAlign j; - - assert (alignment > 0); - assert (*updated_alignment > 0); - - assert (*updated_modulo < *updated_alignment); - assert (modulo < alignment); - - /* The easy case: similar alignment requirements. */ - if (*updated_alignment == alignment) - { - if (modulo > *updated_modulo) - pad = alignment - (modulo - *updated_modulo); - else - pad = *updated_modulo - modulo; - if (offset < 0) - /* De-negatize offset, since % wouldn't do the expected thing. */ - offset = alignment - ((- offset) % alignment); - pad = (offset + pad) % alignment; - if (pad != 0) - pad = alignment - pad; - return pad; - } - - /* Sigh, find LCM (Least Common Multiple) for the two alignment factors. */ - - for (ua = *updated_alignment, ucnt = 1; - ua % alignment != 0; - ua += *updated_alignment) - ++ucnt; - - cnt = ua / alignment; - - if (offset < 0) - /* De-negatize offset, since % wouldn't do the expected thing. */ - offset = ua - ((- offset) % ua); - - /* Set to largest value. */ - min_pad = ~(ffetargetAlign) 0; - - /* Find all combinations of modulo values the two alignment requirements - have; pick the combination that results in the smallest padding - requirement. Of course, if a zero-pad requirement is encountered, just - use that one. */ - - for (um = *updated_modulo, i = 0; i < ucnt; um += *updated_alignment, ++i) - { - for (m = modulo, j = 0; j < cnt; m += alignment, ++j) - { - /* This code is similar to the "easy case" code above. */ - if (m > um) - pad = ua - (m - um); - else - pad = um - m; - pad = (offset + pad) % ua; - if (pad == 0) - { - /* A zero pad means we've got something useful. */ - *updated_alignment = ua; - *updated_modulo = um; - return 0; - } - pad = ua - pad; - if (pad < min_pad) - { /* New minimum padding value. */ - min_pad = pad; - min_m = um; - } - } - } - - *updated_alignment = ua; - *updated_modulo = min_m; - return min_pad; -} - -/* Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -bool -ffetarget_character1 (ffetargetCharacter1 *val, ffelexToken character, - mallocPool pool) -{ - val->length = ffelex_token_length (character); - if (val->length == 0) - val->text = NULL; - else - { - val->text = malloc_new_kp (pool, "ffetargetCharacter1", val->length + 1); - memcpy (val->text, ffelex_token_text (character), val->length); - val->text[val->length] = '\0'; - } - - return TRUE; -} - -#endif -/* Produce orderable comparison between two constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -int -ffetarget_cmp_character1 (ffetargetCharacter1 l, ffetargetCharacter1 r) -{ - if (l.length < r.length) - return -1; - if (l.length > r.length) - return 1; - if (l.length == 0) - return 0; - return memcmp (l.text, r.text, l.length); -} - -#endif -/* ffetarget_concatenate_character1 -- Perform CONCAT op on two constants - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_concatenate_character1 (ffetargetCharacter1 *res, - ffetargetCharacter1 l, ffetargetCharacter1 r, mallocPool pool, - ffetargetCharacterSize *len) -{ - res->length = *len = l.length + r.length; - if (*len == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "ffetargetCharacter1(CONCAT)", *len + 1); - if (l.length != 0) - memcpy (res->text, l.text, l.length); - if (r.length != 0) - memcpy (res->text + l.length, r.text, r.length); - res->text[*len] = '\0'; - } - - return FFEBAD; -} - -#endif -/* ffetarget_eq_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_eq_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) == 0); - return FFEBAD; -} - -#endif -/* ffetarget_le_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_le_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) <= 0); - return FFEBAD; -} - -#endif -/* ffetarget_lt_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_lt_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) < 0); - return FFEBAD; -} - -#endif -/* ffetarget_ge_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_ge_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) >= 0); - return FFEBAD; -} - -#endif -/* ffetarget_gt_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_gt_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) > 0); - return FFEBAD; -} -#endif - -#if FFETARGET_okCHARACTER1 -bool -ffetarget_iszero_character1 (ffetargetCharacter1 constant) -{ - ffetargetCharacterSize i; - - for (i = 0; i < constant.length; ++i) - if (constant.text[i] != 0) - return FALSE; - return TRUE; -} -#endif - -bool -ffetarget_iszero_hollerith (ffetargetHollerith constant) -{ - ffetargetHollerithSize i; - - for (i = 0; i < constant.length; ++i) - if (constant.text[i] != 0) - return FALSE; - return TRUE; -} - -/* ffetarget_layout -- Do storage requirement analysis for entity - - Return the alignment/modulo requirements along with the size, given the - data type info and the number of elements an array (1 for a scalar). */ - -void -ffetarget_layout (char *error_text UNUSED, ffetargetAlign *alignment, - ffetargetAlign *modulo, ffetargetOffset *size, - ffeinfoBasictype bt, ffeinfoKindtype kt, - ffetargetCharacterSize charsize, - ffetargetIntegerDefault num_elements) -{ - bool ok; /* For character type. */ - ffetargetOffset numele; /* Converted from num_elements. */ - ffetype type; - - type = ffeinfo_type (bt, kt); - assert (type != NULL); - - *alignment = ffetype_alignment (type); - *modulo = ffetype_modulo (type); - if (bt == FFEINFO_basictypeCHARACTER) - { - ok = ffetarget_offset_charsize (size, charsize, ffetype_size (type)); -#ifdef ffetarget_offset_overflow - if (!ok) - ffetarget_offset_overflow (error_text); -#endif - } - else - *size = ffetype_size (type); - - if ((num_elements < 0) - || !ffetarget_offset (&numele, num_elements) - || !ffetarget_offset_multiply (size, *size, numele)) - { - ffetarget_offset_overflow (error_text); - *alignment = 1; - *modulo = 0; - *size = 0; - } -} - -/* ffetarget_ne_character1 -- Perform relational comparison on char constants - - Compare lengths, if equal then use memcmp. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_ne_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r) -{ - assert (l.length == r.length); - *res = (memcmp (l.text, r.text, l.length) != 0); - return FFEBAD; -} - -#endif -/* ffetarget_substr_character1 -- Perform SUBSTR op on three constants - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_substr_character1 (ffetargetCharacter1 *res, - ffetargetCharacter1 l, - ffetargetCharacterSize first, - ffetargetCharacterSize last, mallocPool pool, - ffetargetCharacterSize *len) -{ - if (last < first) - { - res->length = *len = 0; - res->text = NULL; - } - else - { - res->length = *len = last - first + 1; - res->text = malloc_new_kp (pool, "ffetargetCharacter1(SUBSTR)", *len + 1); - memcpy (res->text, l.text + first - 1, *len); - res->text[*len] = '\0'; - } - - return FFEBAD; -} - -#endif -/* ffetarget_cmp_hollerith -- Produce orderable comparison between two - constants - - Compare lengths, if equal then use memcmp. */ - -int -ffetarget_cmp_hollerith (ffetargetHollerith l, ffetargetHollerith r) -{ - if (l.length < r.length) - return -1; - if (l.length > r.length) - return 1; - return memcmp (l.text, r.text, l.length); -} - -ffebad -ffetarget_convert_any_character1_ (char *res, size_t size, - ffetargetCharacter1 l) -{ - if (size <= (size_t) l.length) - { - char *p; - ffetargetCharacterSize i; - - memcpy (res, l.text, size); - for (p = &l.text[0] + size, i = l.length - size; - i > 0; - ++p, --i) - if (*p != ' ') - return FFEBAD_TRUNCATING_CHARACTER; - } - else - { - memcpy (res, l.text, size); - memset (res + l.length, ' ', size - l.length); - } - - return FFEBAD; -} - -ffebad -ffetarget_convert_any_hollerith_ (char *res, size_t size, - ffetargetHollerith l) -{ - if (size <= (size_t) l.length) - { - char *p; - ffetargetCharacterSize i; - - memcpy (res, l.text, size); - for (p = &l.text[0] + size, i = l.length - size; - i > 0; - ++p, --i) - if (*p != ' ') - return FFEBAD_TRUNCATING_HOLLERITH; - } - else - { - memcpy (res, l.text, size); - memset (res + l.length, ' ', size - l.length); - } - - return FFEBAD; -} - -ffebad -ffetarget_convert_any_typeless_ (char *res, size_t size, - ffetargetTypeless l) -{ - unsigned long long int l1; - unsigned long int l2; - unsigned int l3; - unsigned short int l4; - unsigned char l5; - size_t size_of; - char *p; - - if (size >= sizeof (l1)) - { - l1 = l; - p = (char *) &l1; - size_of = sizeof (l1); - } - else if (size >= sizeof (l2)) - { - l2 = l; - p = (char *) &l2; - size_of = sizeof (l2); - l1 = l2; - } - else if (size >= sizeof (l3)) - { - l3 = l; - p = (char *) &l3; - size_of = sizeof (l3); - l1 = l3; - } - else if (size >= sizeof (l4)) - { - l4 = l; - p = (char *) &l4; - size_of = sizeof (l4); - l1 = l4; - } - else if (size >= sizeof (l5)) - { - l5 = l; - p = (char *) &l5; - size_of = sizeof (l5); - l1 = l5; - } - else - { - assert ("stumped by conversion from typeless!" == NULL); - abort (); - } - - if (size <= size_of) - { - int i = size_of - size; - - memcpy (res, p + i, size); - for (; i > 0; ++p, --i) - if (*p != '\0') - return FFEBAD_TRUNCATING_TYPELESS; - } - else - { - int i = size - size_of; - - memset (res, 0, i); - memcpy (res + i, p, size_of); - } - - if (l1 != l) - return FFEBAD_TRUNCATING_TYPELESS; - return FFEBAD; -} - -/* Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_convert_character1_character1 (ffetargetCharacter1 *res, - ffetargetCharacterSize size, - ffetargetCharacter1 l, - mallocPool pool) -{ - res->length = size; - if (size == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "FFETARGET cvt char1", size + 1); - if (size <= l.length) - memcpy (res->text, l.text, size); - else - { - memcpy (res->text, l.text, l.length); - memset (res->text + l.length, ' ', size - l.length); - } - res->text[size] = '\0'; - } - - return FFEBAD; -} - -#endif - -/* Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_convert_character1_hollerith (ffetargetCharacter1 *res, - ffetargetCharacterSize size, - ffetargetHollerith l, mallocPool pool) -{ - res->length = size; - if (size == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "FFETARGET cvt char1", size + 1); - res->text[size] = '\0'; - if (size <= l.length) - { - char *p; - ffetargetCharacterSize i; - - memcpy (res->text, l.text, size); - for (p = &l.text[0] + size, i = l.length - size; - i > 0; - ++p, --i) - if (*p != ' ') - return FFEBAD_TRUNCATING_HOLLERITH; - } - else - { - memcpy (res->text, l.text, l.length); - memset (res->text + l.length, ' ', size - l.length); - } - } - - return FFEBAD; -} - -#endif -/* ffetarget_convert_character1_integer4 -- Raw conversion. - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_convert_character1_integer4 (ffetargetCharacter1 *res, - ffetargetCharacterSize size, - ffetargetInteger4 l, mallocPool pool) -{ - long long int l1; - long int l2; - int l3; - short int l4; - char l5; - size_t size_of; - char *p; - - if (((size_t) size) >= sizeof (l1)) - { - l1 = l; - p = (char *) &l1; - size_of = sizeof (l1); - } - else if (((size_t) size) >= sizeof (l2)) - { - l2 = l; - p = (char *) &l2; - size_of = sizeof (l2); - l1 = l2; - } - else if (((size_t) size) >= sizeof (l3)) - { - l3 = l; - p = (char *) &l3; - size_of = sizeof (l3); - l1 = l3; - } - else if (((size_t) size) >= sizeof (l4)) - { - l4 = l; - p = (char *) &l4; - size_of = sizeof (l4); - l1 = l4; - } - else if (((size_t) size) >= sizeof (l5)) - { - l5 = l; - p = (char *) &l5; - size_of = sizeof (l5); - l1 = l5; - } - else - { - assert ("stumped by conversion from integer1!" == NULL); - abort (); - } - - res->length = size; - if (size == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "FFETARGET cvt char1", size + 1); - res->text[size] = '\0'; - if (((size_t) size) <= size_of) - { - int i = size_of - size; - - memcpy (res->text, p + i, size); - for (; i > 0; ++p, --i) - if (*p != 0) - return FFEBAD_TRUNCATING_NUMERIC; - } - else - { - int i = size - size_of; - - memset (res->text, 0, i); - memcpy (res->text + i, p, size_of); - } - } - - if (l1 != l) - return FFEBAD_TRUNCATING_NUMERIC; - return FFEBAD; -} - -#endif -/* ffetarget_convert_character1_logical4 -- Raw conversion. - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_convert_character1_logical4 (ffetargetCharacter1 *res, - ffetargetCharacterSize size, - ffetargetLogical4 l, mallocPool pool) -{ - long long int l1; - long int l2; - int l3; - short int l4; - char l5; - size_t size_of; - char *p; - - if (((size_t) size) >= sizeof (l1)) - { - l1 = l; - p = (char *) &l1; - size_of = sizeof (l1); - } - else if (((size_t) size) >= sizeof (l2)) - { - l2 = l; - p = (char *) &l2; - size_of = sizeof (l2); - l1 = l2; - } - else if (((size_t) size) >= sizeof (l3)) - { - l3 = l; - p = (char *) &l3; - size_of = sizeof (l3); - l1 = l3; - } - else if (((size_t) size) >= sizeof (l4)) - { - l4 = l; - p = (char *) &l4; - size_of = sizeof (l4); - l1 = l4; - } - else if (((size_t) size) >= sizeof (l5)) - { - l5 = l; - p = (char *) &l5; - size_of = sizeof (l5); - l1 = l5; - } - else - { - assert ("stumped by conversion from logical1!" == NULL); - abort (); - } - - res->length = size; - if (size == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "FFETARGET cvt char1", size + 1); - res->text[size] = '\0'; - if (((size_t) size) <= size_of) - { - int i = size_of - size; - - memcpy (res->text, p + i, size); - for (; i > 0; ++p, --i) - if (*p != 0) - return FFEBAD_TRUNCATING_NUMERIC; - } - else - { - int i = size - size_of; - - memset (res->text, 0, i); - memcpy (res->text + i, p, size_of); - } - } - - if (l1 != l) - return FFEBAD_TRUNCATING_NUMERIC; - return FFEBAD; -} - -#endif -/* ffetarget_convert_character1_typeless -- Raw conversion. - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -#if FFETARGET_okCHARACTER1 -ffebad -ffetarget_convert_character1_typeless (ffetargetCharacter1 *res, - ffetargetCharacterSize size, - ffetargetTypeless l, mallocPool pool) -{ - unsigned long long int l1; - unsigned long int l2; - unsigned int l3; - unsigned short int l4; - unsigned char l5; - size_t size_of; - char *p; - - if (((size_t) size) >= sizeof (l1)) - { - l1 = l; - p = (char *) &l1; - size_of = sizeof (l1); - } - else if (((size_t) size) >= sizeof (l2)) - { - l2 = l; - p = (char *) &l2; - size_of = sizeof (l2); - l1 = l2; - } - else if (((size_t) size) >= sizeof (l3)) - { - l3 = l; - p = (char *) &l3; - size_of = sizeof (l3); - l1 = l3; - } - else if (((size_t) size) >= sizeof (l4)) - { - l4 = l; - p = (char *) &l4; - size_of = sizeof (l4); - l1 = l4; - } - else if (((size_t) size) >= sizeof (l5)) - { - l5 = l; - p = (char *) &l5; - size_of = sizeof (l5); - l1 = l5; - } - else - { - assert ("stumped by conversion from typeless!" == NULL); - abort (); - } - - res->length = size; - if (size == 0) - res->text = NULL; - else - { - res->text = malloc_new_kp (pool, "FFETARGET cvt char1", size + 1); - res->text[size] = '\0'; - if (((size_t) size) <= size_of) - { - int i = size_of - size; - - memcpy (res->text, p + i, size); - for (; i > 0; ++p, --i) - if (*p != 0) - return FFEBAD_TRUNCATING_TYPELESS; - } - else - { - int i = size - size_of; - - memset (res->text, 0, i); - memcpy (res->text + i, p, size_of); - } - } - - if (l1 != l) - return FFEBAD_TRUNCATING_TYPELESS; - return FFEBAD; -} - -#endif -/* ffetarget_divide_complex1 -- Divide function - - See prototype. */ - -#if FFETARGET_okCOMPLEX1 -ffebad -ffetarget_divide_complex1 (ffetargetComplex1 *res, ffetargetComplex1 l, - ffetargetComplex1 r) -{ - ffebad bad; - ffetargetReal1 tmp1, tmp2, tmp3, tmp4; - - bad = ffetarget_multiply_real1 (&tmp1, r.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, r.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real1 (&tmp3, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - - if (ffetarget_iszero_real1 (tmp3)) - { - ffetarget_real1_zero (&(res)->real); - ffetarget_real1_zero (&(res)->imaginary); - return FFEBAD_DIV_BY_ZERO; - } - - bad = ffetarget_multiply_real1 (&tmp1, l.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real1 (&tmp4, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real1 (&res->real, tmp4, tmp3); - if (bad != FFEBAD) - return bad; - - bad = ffetarget_multiply_real1 (&tmp1, r.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.real, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real1 (&tmp4, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real1 (&res->imaginary, tmp4, tmp3); - - return FFEBAD; -} - -#endif -/* ffetarget_divide_complex2 -- Divide function - - See prototype. */ - -#if FFETARGET_okCOMPLEX2 -ffebad -ffetarget_divide_complex2 (ffetargetComplex2 *res, ffetargetComplex2 l, - ffetargetComplex2 r) -{ - ffebad bad; - ffetargetReal2 tmp1, tmp2, tmp3, tmp4; - - bad = ffetarget_multiply_real2 (&tmp1, r.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, r.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real2 (&tmp3, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - - if (ffetarget_iszero_real2 (tmp3)) - { - ffetarget_real2_zero (&(res)->real); - ffetarget_real2_zero (&(res)->imaginary); - return FFEBAD_DIV_BY_ZERO; - } - - bad = ffetarget_multiply_real2 (&tmp1, l.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real2 (&tmp4, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real2 (&res->real, tmp4, tmp3); - if (bad != FFEBAD) - return bad; - - bad = ffetarget_multiply_real2 (&tmp1, r.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.real, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real2 (&tmp4, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real2 (&res->imaginary, tmp4, tmp3); - - return FFEBAD; -} - -#endif -/* ffetarget_hollerith -- Convert token to a hollerith constant - - Always append a null byte to the end, in case this is wanted in - a special case such as passing a string as a FORMAT or %REF. - Done to save a bit of hassle, nothing more, but it's a kludge anyway, - because it isn't a "feature" that is self-documenting. Use the - string "FFETARGET-NULL-KLUDGE" to flag anyplace you use this feature - in the code. */ - -bool -ffetarget_hollerith (ffetargetHollerith *val, ffelexToken integer, - mallocPool pool) -{ - val->length = ffelex_token_length (integer); - val->text = malloc_new_kp (pool, "ffetargetHollerith", val->length + 1); - memcpy (val->text, ffelex_token_text (integer), val->length); - val->text[val->length] = '\0'; - - return TRUE; -} - -/* ffetarget_integer_bad_magical -- Complain about a magical number - - Just calls ffebad with the arguments. */ - -void -ffetarget_integer_bad_magical (ffelexToken t) -{ - ffebad_start (FFEBAD_BAD_MAGICAL); - ffebad_here (0, ffelex_token_where_line (t), ffelex_token_where_column (t)); - ffebad_finish (); -} - -/* ffetarget_integer_bad_magical_binary -- Complain about a magical number - - Just calls ffebad with the arguments. */ - -void -ffetarget_integer_bad_magical_binary (ffelexToken integer, - ffelexToken minus) -{ - ffebad_start (FFEBAD_BAD_MAGICAL_BINARY); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_here (1, ffelex_token_where_line (minus), - ffelex_token_where_column (minus)); - ffebad_finish (); -} - -/* ffetarget_integer_bad_magical_precedence -- Complain about a magical - number - - Just calls ffebad with the arguments. */ - -void -ffetarget_integer_bad_magical_precedence (ffelexToken integer, - ffelexToken uminus, - ffelexToken higher_op) -{ - ffebad_start (FFEBAD_BAD_MAGICAL_PRECEDENCE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_here (1, ffelex_token_where_line (uminus), - ffelex_token_where_column (uminus)); - ffebad_here (2, ffelex_token_where_line (higher_op), - ffelex_token_where_column (higher_op)); - ffebad_finish (); -} - -/* ffetarget_integer_bad_magical_precedence_binary -- Complain... - - Just calls ffebad with the arguments. */ - -void -ffetarget_integer_bad_magical_precedence_binary (ffelexToken integer, - ffelexToken minus, - ffelexToken higher_op) -{ - ffebad_start (FFEBAD_BAD_MAGICAL_PRECEDENCE_BINARY); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_here (1, ffelex_token_where_line (minus), - ffelex_token_where_column (minus)); - ffebad_here (2, ffelex_token_where_line (higher_op), - ffelex_token_where_column (higher_op)); - ffebad_finish (); -} - -/* ffetarget_integer1 -- Convert token to an integer - - See prototype. - - Token use count not affected overall. */ - -#if FFETARGET_okINTEGER1 -bool -ffetarget_integer1 (ffetargetInteger1 *val, ffelexToken integer) -{ - ffetargetInteger1 x; - char *p; - char c; - - assert (ffelex_token_type (integer) == FFELEX_typeNUMBER); - - p = ffelex_token_text (integer); - x = 0; - - /* Skip past leading zeros. */ - - while (((c = *p) != '\0') && (c == '0')) - ++p; - - /* Interpret rest of number. */ - - while (c != '\0') - { - if ((x == FFETARGET_integerALMOST_BIG_MAGICAL) - && (c == '0' + FFETARGET_integerFINISH_BIG_MAGICAL) - && (*(p + 1) == '\0')) - { - *val = (ffetargetInteger1) FFETARGET_integerBIG_MAGICAL; - return TRUE; - } - else if (x == FFETARGET_integerALMOST_BIG_MAGICAL) - { - if ((c > '0' + FFETARGET_integerFINISH_BIG_MAGICAL) - || (*(p + 1) != '\0')) - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - } - else if (x > FFETARGET_integerALMOST_BIG_MAGICAL) - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - x = x * 10 + c - '0'; - c = *(++p); - }; - - *val = x; - return TRUE; -} - -#endif -/* ffetarget_integerbinary -- Convert token to a binary integer - - ffetarget_integerbinary x; - if (ffetarget_integerdefault_8(&x,integer_token)) - // conversion ok. - - Token use count not affected overall. */ - -bool -ffetarget_integerbinary (ffetargetIntegerDefault *val, ffelexToken integer) -{ - ffetargetIntegerDefault x; - char *p; - char c; - bool bad_digit; - - assert ((ffelex_token_type (integer) == FFELEX_typeNAME) - || (ffelex_token_type (integer) == FFELEX_typeNUMBER)); - - p = ffelex_token_text (integer); - x = 0; - - /* Skip past leading zeros. */ - - while (((c = *p) != '\0') && (c == '0')) - ++p; - - /* Interpret rest of number. */ - - bad_digit = FALSE; - while (c != '\0') - { - if ((c >= '0') && (c <= '1')) - c -= '0'; - else - { - bad_digit = TRUE; - c = 0; - } - -#if 0 /* Don't complain about signed overflow; just - unsigned overflow. */ - if ((x == FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY) - && (c == FFETARGET_integerFINISH_BIG_OVERFLOW_BINARY) - && (*(p + 1) == '\0')) - { - *val = FFETARGET_integerBIG_OVERFLOW_BINARY; - return TRUE; - } - else -#endif -#if FFETARGET_integerFINISH_BIG_OVERFLOW_BINARY == 0 - if ((x & FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY) != 0) -#else - if (x == FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY) - { - if ((c > FFETARGET_integerFINISH_BIG_OVERFLOW_BINARY) - || (*(p + 1) != '\0')) - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - } - else if (x > FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY) -#endif - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - x = (x << 1) + c; - c = *(++p); - }; - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_BINARY_DIGIT); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - } - - *val = x; - return !bad_digit; -} - -/* ffetarget_integerhex -- Convert token to a hex integer - - ffetarget_integerhex x; - if (ffetarget_integerdefault_8(&x,integer_token)) - // conversion ok. - - Token use count not affected overall. */ - -bool -ffetarget_integerhex (ffetargetIntegerDefault *val, ffelexToken integer) -{ - ffetargetIntegerDefault x; - char *p; - char c; - bool bad_digit; - - assert ((ffelex_token_type (integer) == FFELEX_typeNAME) - || (ffelex_token_type (integer) == FFELEX_typeNUMBER)); - - p = ffelex_token_text (integer); - x = 0; - - /* Skip past leading zeros. */ - - while (((c = *p) != '\0') && (c == '0')) - ++p; - - /* Interpret rest of number. */ - - bad_digit = FALSE; - while (c != '\0') - { - if ((c >= 'A') && (c <= 'F')) - c = c - 'A' + 10; - else if ((c >= 'a') && (c <= 'f')) - c = c - 'a' + 10; - else if ((c >= '0') && (c <= '9')) - c -= '0'; - else - { - bad_digit = TRUE; - c = 0; - } - -#if 0 /* Don't complain about signed overflow; just - unsigned overflow. */ - if ((x == FFETARGET_integerALMOST_BIG_OVERFLOW_HEX) - && (c == FFETARGET_integerFINISH_BIG_OVERFLOW_HEX) - && (*(p + 1) == '\0')) - { - *val = FFETARGET_integerBIG_OVERFLOW_HEX; - return TRUE; - } - else -#endif -#if FFETARGET_integerFINISH_BIG_OVERFLOW_HEX == 0 - if (x >= FFETARGET_integerALMOST_BIG_OVERFLOW_HEX) -#else - if (x == FFETARGET_integerALMOST_BIG_OVERFLOW_HEX) - { - if ((c > FFETARGET_integerFINISH_BIG_OVERFLOW_HEX) - || (*(p + 1) != '\0')) - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - } - else if (x > FFETARGET_integerALMOST_BIG_OVERFLOW_HEX) -#endif - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - x = (x << 4) + c; - c = *(++p); - }; - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_HEX_DIGIT); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - } - - *val = x; - return !bad_digit; -} - -/* ffetarget_integeroctal -- Convert token to an octal integer - - ffetarget_integeroctal x; - if (ffetarget_integerdefault_8(&x,integer_token)) - // conversion ok. - - Token use count not affected overall. */ - -bool -ffetarget_integeroctal (ffetargetIntegerDefault *val, ffelexToken integer) -{ - ffetargetIntegerDefault x; - char *p; - char c; - bool bad_digit; - - assert ((ffelex_token_type (integer) == FFELEX_typeNAME) - || (ffelex_token_type (integer) == FFELEX_typeNUMBER)); - - p = ffelex_token_text (integer); - x = 0; - - /* Skip past leading zeros. */ - - while (((c = *p) != '\0') && (c == '0')) - ++p; - - /* Interpret rest of number. */ - - bad_digit = FALSE; - while (c != '\0') - { - if ((c >= '0') && (c <= '7')) - c -= '0'; - else - { - bad_digit = TRUE; - c = 0; - } - -#if 0 /* Don't complain about signed overflow; just - unsigned overflow. */ - if ((x == FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL) - && (c == FFETARGET_integerFINISH_BIG_OVERFLOW_OCTAL) - && (*(p + 1) == '\0')) - { - *val = FFETARGET_integerBIG_OVERFLOW_OCTAL; - return TRUE; - } - else -#endif -#if FFETARGET_integerFINISH_BIG_OVERFLOW_OCTAL == 0 - if (x >= FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL) -#else - if (x == FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL) - { - if ((c > FFETARGET_integerFINISH_BIG_OVERFLOW_OCTAL) - || (*(p + 1) != '\0')) - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - } - else if (x > FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL) -#endif - { - ffebad_start (FFEBAD_INTEGER_TOO_LARGE); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - *val = 0; - return FALSE; - } - x = (x << 3) + c; - c = *(++p); - }; - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_OCTAL_DIGIT); - ffebad_here (0, ffelex_token_where_line (integer), - ffelex_token_where_column (integer)); - ffebad_finish (); - } - - *val = x; - return !bad_digit; -} - -/* ffetarget_multiply_complex1 -- Multiply function - - See prototype. */ - -#if FFETARGET_okCOMPLEX1 -ffebad -ffetarget_multiply_complex1 (ffetargetComplex1 *res, ffetargetComplex1 l, - ffetargetComplex1 r) -{ - ffebad bad; - ffetargetReal1 tmp1, tmp2; - - bad = ffetarget_multiply_real1 (&tmp1, l.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real1 (&res->real, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp1, l.imaginary, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.real, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real1 (&res->imaginary, tmp1, tmp2); - - return bad; -} - -#endif -/* ffetarget_multiply_complex2 -- Multiply function - - See prototype. */ - -#if FFETARGET_okCOMPLEX2 -ffebad -ffetarget_multiply_complex2 (ffetargetComplex2 *res, ffetargetComplex2 l, - ffetargetComplex2 r) -{ - ffebad bad; - ffetargetReal2 tmp1, tmp2; - - bad = ffetarget_multiply_real2 (&tmp1, l.real, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.imaginary, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real2 (&res->real, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp1, l.imaginary, r.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.real, r.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real2 (&res->imaginary, tmp1, tmp2); - - return bad; -} - -#endif -/* ffetarget_power_complexdefault_integerdefault -- Power function - - See prototype. */ - -ffebad -ffetarget_power_complexdefault_integerdefault (ffetargetComplexDefault *res, - ffetargetComplexDefault l, - ffetargetIntegerDefault r) -{ - ffebad bad; - ffetargetRealDefault tmp; - ffetargetRealDefault tmp1; - ffetargetRealDefault tmp2; - ffetargetRealDefault two; - - if (ffetarget_iszero_real1 (l.real) - && ffetarget_iszero_real1 (l.imaginary)) - { - ffetarget_real1_zero (&res->real); - ffetarget_real1_zero (&res->imaginary); - return FFEBAD; - } - - if (r == 0) - { - ffetarget_real1_one (&res->real); - ffetarget_real1_zero (&res->imaginary); - return FFEBAD; - } - - if (r < 0) - { - r = -r; - bad = ffetarget_multiply_real1 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real1 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real1 (&l.real, l.real, tmp); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real1 (&l.imaginary, l.imaginary, tmp); - if (bad != FFEBAD) - return bad; - bad = ffetarget_uminus_real1 (&l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - } - - ffetarget_real1_two (&two); - - while ((r & 1) == 0) - { - bad = ffetarget_multiply_real1 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real1 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&l.imaginary, l.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&l.imaginary, l.imaginary, two); - if (bad != FFEBAD) - return bad; - l.real = tmp; - r >>= 1; - } - - *res = l; - r >>= 1; - - while (r != 0) - { - bad = ffetarget_multiply_real1 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real1 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&l.imaginary, l.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&l.imaginary, l.imaginary, two); - if (bad != FFEBAD) - return bad; - l.real = tmp; - if ((r & 1) == 1) - { - bad = ffetarget_multiply_real1 (&tmp1, res->real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, res->imaginary, - l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real1 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp1, res->imaginary, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real1 (&tmp2, res->real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real1 (&res->imaginary, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - res->real = tmp; - } - r >>= 1; - } - - return FFEBAD; -} - -/* ffetarget_power_complexdouble_integerdefault -- Power function - - See prototype. */ - -#if FFETARGET_okCOMPLEXDOUBLE -ffebad -ffetarget_power_complexdouble_integerdefault (ffetargetComplexDouble *res, - ffetargetComplexDouble l, ffetargetIntegerDefault r) -{ - ffebad bad; - ffetargetRealDouble tmp; - ffetargetRealDouble tmp1; - ffetargetRealDouble tmp2; - ffetargetRealDouble two; - - if (ffetarget_iszero_real2 (l.real) - && ffetarget_iszero_real2 (l.imaginary)) - { - ffetarget_real2_zero (&res->real); - ffetarget_real2_zero (&res->imaginary); - return FFEBAD; - } - - if (r == 0) - { - ffetarget_real2_one (&res->real); - ffetarget_real2_zero (&res->imaginary); - return FFEBAD; - } - - if (r < 0) - { - r = -r; - bad = ffetarget_multiply_real2 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real2 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real2 (&l.real, l.real, tmp); - if (bad != FFEBAD) - return bad; - bad = ffetarget_divide_real2 (&l.imaginary, l.imaginary, tmp); - if (bad != FFEBAD) - return bad; - bad = ffetarget_uminus_real2 (&l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - } - - ffetarget_real2_two (&two); - - while ((r & 1) == 0) - { - bad = ffetarget_multiply_real2 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real2 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&l.imaginary, l.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&l.imaginary, l.imaginary, two); - if (bad != FFEBAD) - return bad; - l.real = tmp; - r >>= 1; - } - - *res = l; - r >>= 1; - - while (r != 0) - { - bad = ffetarget_multiply_real2 (&tmp1, l.real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, l.imaginary, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real2 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&l.imaginary, l.real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&l.imaginary, l.imaginary, two); - if (bad != FFEBAD) - return bad; - l.real = tmp; - if ((r & 1) == 1) - { - bad = ffetarget_multiply_real2 (&tmp1, res->real, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, res->imaginary, - l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_subtract_real2 (&tmp, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp1, res->imaginary, l.real); - if (bad != FFEBAD) - return bad; - bad = ffetarget_multiply_real2 (&tmp2, res->real, l.imaginary); - if (bad != FFEBAD) - return bad; - bad = ffetarget_add_real2 (&res->imaginary, tmp1, tmp2); - if (bad != FFEBAD) - return bad; - res->real = tmp; - } - r >>= 1; - } - - return FFEBAD; -} - -#endif -/* ffetarget_power_integerdefault_integerdefault -- Power function - - See prototype. */ - -ffebad -ffetarget_power_integerdefault_integerdefault (ffetargetIntegerDefault *res, - ffetargetIntegerDefault l, ffetargetIntegerDefault r) -{ - if (l == 0) - { - *res = 0; - return FFEBAD; - } - - if (r == 0) - { - *res = 1; - return FFEBAD; - } - - if (r < 0) - { - if (l == 1) - *res = 1; - else if (l == 0) - *res = 1; - else if (l == -1) - *res = ((-r) & 1) == 0 ? 1 : -1; - else - *res = 0; - return FFEBAD; - } - - while ((r & 1) == 0) - { - l *= l; - r >>= 1; - } - - *res = l; - r >>= 1; - - while (r != 0) - { - l *= l; - if ((r & 1) == 1) - *res *= l; - r >>= 1; - } - - return FFEBAD; -} - -/* ffetarget_power_realdefault_integerdefault -- Power function - - See prototype. */ - -ffebad -ffetarget_power_realdefault_integerdefault (ffetargetRealDefault *res, - ffetargetRealDefault l, ffetargetIntegerDefault r) -{ - ffebad bad; - - if (ffetarget_iszero_real1 (l)) - { - ffetarget_real1_zero (res); - return FFEBAD; - } - - if (r == 0) - { - ffetarget_real1_one (res); - return FFEBAD; - } - - if (r < 0) - { - ffetargetRealDefault one; - - ffetarget_real1_one (&one); - r = -r; - bad = ffetarget_divide_real1 (&l, one, l); - if (bad != FFEBAD) - return bad; - } - - while ((r & 1) == 0) - { - bad = ffetarget_multiply_real1 (&l, l, l); - if (bad != FFEBAD) - return bad; - r >>= 1; - } - - *res = l; - r >>= 1; - - while (r != 0) - { - bad = ffetarget_multiply_real1 (&l, l, l); - if (bad != FFEBAD) - return bad; - if ((r & 1) == 1) - { - bad = ffetarget_multiply_real1 (res, *res, l); - if (bad != FFEBAD) - return bad; - } - r >>= 1; - } - - return FFEBAD; -} - -/* ffetarget_power_realdouble_integerdefault -- Power function - - See prototype. */ - -ffebad -ffetarget_power_realdouble_integerdefault (ffetargetRealDouble *res, - ffetargetRealDouble l, - ffetargetIntegerDefault r) -{ - ffebad bad; - - if (ffetarget_iszero_real2 (l)) - { - ffetarget_real2_zero (res); - return FFEBAD; - } - - if (r == 0) - { - ffetarget_real2_one (res); - return FFEBAD; - } - - if (r < 0) - { - ffetargetRealDouble one; - - ffetarget_real2_one (&one); - r = -r; - bad = ffetarget_divide_real2 (&l, one, l); - if (bad != FFEBAD) - return bad; - } - - while ((r & 1) == 0) - { - bad = ffetarget_multiply_real2 (&l, l, l); - if (bad != FFEBAD) - return bad; - r >>= 1; - } - - *res = l; - r >>= 1; - - while (r != 0) - { - bad = ffetarget_multiply_real2 (&l, l, l); - if (bad != FFEBAD) - return bad; - if ((r & 1) == 1) - { - bad = ffetarget_multiply_real2 (res, *res, l); - if (bad != FFEBAD) - return bad; - } - r >>= 1; - } - - return FFEBAD; -} - -/* ffetarget_print_binary -- Output typeless binary integer - - ffetargetTypeless val; - ffetarget_typeless_binary(dmpout,val); */ - -void -ffetarget_print_binary (FILE *f, ffetargetTypeless value) -{ - char *p; - char digits[sizeof (value) * CHAR_BIT + 1]; - - if (f == NULL) - f = dmpout; - - p = &digits[ARRAY_SIZE (digits) - 1]; - *p = '\0'; - do - { - *--p = (value & 1) + '0'; - value >>= 1; - } while (value == 0); - - fputs (p, f); -} - -/* ffetarget_print_character1 -- Output character string - - ffetargetCharacter1 val; - ffetarget_print_character1(dmpout,val); */ - -void -ffetarget_print_character1 (FILE *f, ffetargetCharacter1 value) -{ - unsigned char *p; - ffetargetCharacterSize i; - - fputc ('\'', dmpout); - for (i = 0, p = value.text; i < value.length; ++i, ++p) - ffetarget_print_char_ (f, *p); - fputc ('\'', dmpout); -} - -/* ffetarget_print_hollerith -- Output hollerith string - - ffetargetHollerith val; - ffetarget_print_hollerith(dmpout,val); */ - -void -ffetarget_print_hollerith (FILE *f, ffetargetHollerith value) -{ - unsigned char *p; - ffetargetHollerithSize i; - - fputc ('\'', dmpout); - for (i = 0, p = value.text; i < value.length; ++i, ++p) - ffetarget_print_char_ (f, *p); - fputc ('\'', dmpout); -} - -/* ffetarget_print_octal -- Output typeless octal integer - - ffetargetTypeless val; - ffetarget_print_octal(dmpout,val); */ - -void -ffetarget_print_octal (FILE *f, ffetargetTypeless value) -{ - char *p; - char digits[sizeof (value) * CHAR_BIT / 3 + 1]; - - if (f == NULL) - f = dmpout; - - p = &digits[ARRAY_SIZE (digits) - 3]; - *p = '\0'; - do - { - *--p = (value & 3) + '0'; - value >>= 3; - } while (value == 0); - - fputs (p, f); -} - -/* ffetarget_print_hex -- Output typeless hex integer - - ffetargetTypeless val; - ffetarget_print_hex(dmpout,val); */ - -void -ffetarget_print_hex (FILE *f, ffetargetTypeless value) -{ - char *p; - char digits[sizeof (value) * CHAR_BIT / 4 + 1]; - static char hexdigits[16] = "0123456789ABCDEF"; - - if (f == NULL) - f = dmpout; - - p = &digits[ARRAY_SIZE (digits) - 3]; - *p = '\0'; - do - { - *--p = hexdigits[value & 4]; - value >>= 4; - } while (value == 0); - - fputs (p, f); -} - -/* ffetarget_real1 -- Convert token to a single-precision real number - - See prototype. - - Pass NULL for any token not provided by the user, but a valid Fortran - real number must be provided somehow. For example, it is ok for - exponent_sign_token and exponent_digits_token to be NULL as long as - exponent_token not only starts with "E" or "e" but also contains at least - one digit following it. Token use counts not affected overall. */ - -#if FFETARGET_okREAL1 -bool -ffetarget_real1 (ffetargetReal1 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits) -{ - size_t sz = 1; /* Allow room for '\0' byte at end. */ - char *ptr = &ffetarget_string_[0]; - char *p = ptr; - char *q; - -#define dotok(x) if (x != NULL) ++sz; -#define dotoktxt(x) if (x != NULL) sz += ffelex_token_length(x) - - dotoktxt (integer); - dotok (decimal); - dotoktxt (fraction); - dotoktxt (exponent); - dotok (exponent_sign); - dotoktxt (exponent_digits); - -#undef dotok -#undef dotoktxt - - if (sz > ARRAY_SIZE (ffetarget_string_)) - p = ptr = (char *) malloc_new_ks (malloc_pool_image (), "ffetarget_real1", - sz); - -#define dotoktxt(x) if (x != NULL) \ - { \ - for (q = ffelex_token_text(x); *q != '\0'; ++q) \ - *p++ = *q; \ - } - - dotoktxt (integer); - - if (decimal != NULL) - *p++ = '.'; - - dotoktxt (fraction); - dotoktxt (exponent); - - if (exponent_sign != NULL) - { - if (ffelex_token_type (exponent_sign) == FFELEX_typePLUS) - *p++ = '+'; - else - { - assert (ffelex_token_type (exponent_sign) == FFELEX_typeMINUS); - *p++ = '-'; - } - } - - dotoktxt (exponent_digits); - -#undef dotoktxt - - *p = '\0'; - - ffetarget_make_real1 (value, - FFETARGET_ATOF_ (ptr, - SFmode)); - - if (sz > ARRAY_SIZE (ffetarget_string_)) - malloc_kill_ks (malloc_pool_image (), ptr, sz); - - return TRUE; -} - -#endif -/* ffetarget_real2 -- Convert token to a single-precision real number - - See prototype. - - Pass NULL for any token not provided by the user, but a valid Fortran - real number must be provided somehow. For example, it is ok for - exponent_sign_token and exponent_digits_token to be NULL as long as - exponent_token not only starts with "E" or "e" but also contains at least - one digit following it. Token use counts not affected overall. */ - -#if FFETARGET_okREAL2 -bool -ffetarget_real2 (ffetargetReal2 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits) -{ - size_t sz = 1; /* Allow room for '\0' byte at end. */ - char *ptr = &ffetarget_string_[0]; - char *p = ptr; - char *q; - -#define dotok(x) if (x != NULL) ++sz; -#define dotoktxt(x) if (x != NULL) sz += ffelex_token_length(x) - - dotoktxt (integer); - dotok (decimal); - dotoktxt (fraction); - dotoktxt (exponent); - dotok (exponent_sign); - dotoktxt (exponent_digits); - -#undef dotok -#undef dotoktxt - - if (sz > ARRAY_SIZE (ffetarget_string_)) - p = ptr = (char *) malloc_new_ks (malloc_pool_image (), "ffetarget_real1", sz); - -#define dotoktxt(x) if (x != NULL) \ - { \ - for (q = ffelex_token_text(x); *q != '\0'; ++q) \ - *p++ = *q; \ - } -#define dotoktxtexp(x) if (x != NULL) \ - { \ - *p++ = 'E'; \ - for (q = ffelex_token_text(x) + 1; *q != '\0'; ++q) \ - *p++ = *q; \ - } - - dotoktxt (integer); - - if (decimal != NULL) - *p++ = '.'; - - dotoktxt (fraction); - dotoktxtexp (exponent); - - if (exponent_sign != NULL) - { - if (ffelex_token_type (exponent_sign) == FFELEX_typePLUS) - *p++ = '+'; - else - { - assert (ffelex_token_type (exponent_sign) == FFELEX_typeMINUS); - *p++ = '-'; - } - } - - dotoktxt (exponent_digits); - -#undef dotoktxt - - *p = '\0'; - - ffetarget_make_real2 (value, - FFETARGET_ATOF_ (ptr, - DFmode)); - - if (sz > ARRAY_SIZE (ffetarget_string_)) - malloc_kill_ks (malloc_pool_image (), ptr, sz); - - return TRUE; -} - -#endif -bool -ffetarget_typeless_binary (ffetargetTypeless *xvalue, ffelexToken token) -{ - char *p; - char c; - ffetargetTypeless value = 0; - ffetargetTypeless new_value = 0; - bool bad_digit = FALSE; - bool overflow = FALSE; - - p = ffelex_token_text (token); - - for (c = *p; c != '\0'; c = *++p) - { - new_value <<= 1; - if ((new_value >> 1) != value) - overflow = TRUE; - if (ISDIGIT (c)) - new_value += c - '0'; - else - bad_digit = TRUE; - value = new_value; - } - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_TYPELESS_BINARY_DIGIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - else if (overflow) - { - ffebad_start (FFEBAD_TYPELESS_OVERFLOW); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - - *xvalue = value; - - return !bad_digit && !overflow; -} - -bool -ffetarget_typeless_octal (ffetargetTypeless *xvalue, ffelexToken token) -{ - char *p; - char c; - ffetargetTypeless value = 0; - ffetargetTypeless new_value = 0; - bool bad_digit = FALSE; - bool overflow = FALSE; - - p = ffelex_token_text (token); - - for (c = *p; c != '\0'; c = *++p) - { - new_value <<= 3; - if ((new_value >> 3) != value) - overflow = TRUE; - if (ISDIGIT (c)) - new_value += c - '0'; - else - bad_digit = TRUE; - value = new_value; - } - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_TYPELESS_OCTAL_DIGIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - else if (overflow) - { - ffebad_start (FFEBAD_TYPELESS_OVERFLOW); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - - *xvalue = value; - - return !bad_digit && !overflow; -} - -bool -ffetarget_typeless_hex (ffetargetTypeless *xvalue, ffelexToken token) -{ - char *p; - char c; - ffetargetTypeless value = 0; - ffetargetTypeless new_value = 0; - bool bad_digit = FALSE; - bool overflow = FALSE; - - p = ffelex_token_text (token); - - for (c = *p; c != '\0'; c = *++p) - { - new_value <<= 4; - if ((new_value >> 4) != value) - overflow = TRUE; - if (ISDIGIT (c)) - new_value += c - '0'; - else if ((c >= 'A') && (c <= 'F')) - new_value += c - 'A' + 10; - else if ((c >= 'a') && (c <= 'f')) - new_value += c - 'a' + 10; - else - bad_digit = TRUE; - value = new_value; - } - - if (bad_digit) - { - ffebad_start (FFEBAD_INVALID_TYPELESS_HEX_DIGIT); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - else if (overflow) - { - ffebad_start (FFEBAD_TYPELESS_OVERFLOW); - ffebad_here (0, ffelex_token_where_line (token), - ffelex_token_where_column (token)); - ffebad_finish (); - } - - *xvalue = value; - - return !bad_digit && !overflow; -} - -void -ffetarget_verify_character1 (mallocPool pool, ffetargetCharacter1 val) -{ - if (val.length != 0) - malloc_verify_kp (pool, val.text, val.length); -} - -/* This is like memcpy. It is needed because some systems' header files - don't declare memcpy as a function but instead - "#define memcpy(to,from,len) something". */ - -void * -ffetarget_memcpy_ (void *dst, void *src, size_t len) -{ - return (void *) memcpy (dst, src, len); -} - -/* ffetarget_num_digits_ -- Determine number of non-space characters in token - - ffetarget_num_digits_(token); - - All non-spaces are assumed to be binary, octal, or hex digits. */ - -int -ffetarget_num_digits_ (ffelexToken token) -{ - int i; - char *c; - - switch (ffelex_token_type (token)) - { - case FFELEX_typeNAME: - case FFELEX_typeNUMBER: - return ffelex_token_length (token); - - case FFELEX_typeCHARACTER: - i = 0; - for (c = ffelex_token_text (token); *c != '\0'; ++c) - { - if (*c != ' ') - ++i; - } - return i; - - default: - assert ("weird token" == NULL); - return 1; - } -} diff --git a/gcc/f/target.h b/gcc/f/target.h deleted file mode 100755 index ef59f90..0000000 --- a/gcc/f/target.h +++ /dev/null @@ -1,1865 +0,0 @@ -/* target.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995, 1996 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - target.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_target -#define _H_f_target - -#ifdef FFE_STANDALONE -#define HOST_WIDE_INT long -#else -#ifndef TREE_CODE -#include "tree.j" -#endif -#endif - -/* For now, g77 requires the ability to determine the exact bit pattern - of a float on the target machine. (Hopefully this will be changed - soon). Make sure we can do this. */ - -#if !defined (REAL_ARITHMETIC) \ - && ((TARGET_FLOAT_FORMAT != HOST_FLOAT_FORMAT) \ - || (FLOAT_WORDS_BIG_ENDIAN != HOST_FLOAT_WORDS_BIG_ENDIAN)) -#error "g77 requires ability to access exact FP representation of target machine" -#endif - -/* Simple definitions and enumerations. */ - -#define FFETARGET_charactersizeNONE (-1) -#ifndef FFETARGET_charactersizeMAXIMUM -#define FFETARGET_charactersizeMAXIMUM 2147483647 -#endif - -#ifndef FFETARGET_defaultIS_90 -#define FFETARGET_defaultIS_90 0 -#endif -#ifndef FFETARGET_defaultIS_AUTOMATIC -#define FFETARGET_defaultIS_AUTOMATIC 1 -#endif -#ifndef FFETARGET_defaultIS_BACKSLASH -#define FFETARGET_defaultIS_BACKSLASH 1 -#endif -#ifndef FFETARGET_defaultIS_INIT_LOCAL_ZERO -#define FFETARGET_defaultIS_INIT_LOCAL_ZERO 0 -#endif -#ifndef FFETARGET_defaultIS_DOLLAR_OK -#define FFETARGET_defaultIS_DOLLAR_OK 0 -#endif -#ifndef FFETARGET_defaultIS_F2C -#define FFETARGET_defaultIS_F2C 1 -#endif -#ifndef FFETARGET_defaultIS_F2C_LIBRARY -#define FFETARGET_defaultIS_F2C_LIBRARY 1 -#endif -#ifndef FFETARGET_defaultIS_FREE_FORM -#define FFETARGET_defaultIS_FREE_FORM 0 -#endif -#ifndef FFETARGET_defaultIS_PEDANTIC -#define FFETARGET_defaultIS_PEDANTIC 0 -#endif -#ifndef FFETARGET_defaultCASE_INTRIN -#define FFETARGET_defaultCASE_INTRIN FFE_caseLOWER -#endif -#ifndef FFETARGET_defaultCASE_MATCH -#define FFETARGET_defaultCASE_MATCH FFE_caseLOWER -#endif -#ifndef FFETARGET_defaultCASE_SOURCE -#define FFETARGET_defaultCASE_SOURCE FFE_caseLOWER -#endif -#ifndef FFETARGET_defaultCASE_SYMBOL -#define FFETARGET_defaultCASE_SYMBOL FFE_caseNONE -#endif - -#ifndef FFETARGET_defaultFIXED_LINE_LENGTH -#define FFETARGET_defaultFIXED_LINE_LENGTH 72 -#endif - -/* 1 if external Fortran names ("FOO" in SUBROUTINE FOO, COMMON /FOO/, - and even enforced/default-for-unnamed PROGRAM, blank-COMMON, and - BLOCK DATA names, but not names of library functions implementing - intrinsics or names of local/internal variables) should have an - underscore appended (for compatibility with existing systems). */ - -#ifndef FFETARGET_defaultEXTERNAL_UNDERSCORED -#define FFETARGET_defaultEXTERNAL_UNDERSCORED 1 -#endif - -/* 1 if external Fortran names with underscores already in them should - have an extra underscore appended (in addition to the one they - might already have appened if FFETARGET_defaultEXTERNAL_UNDERSCORED). */ - -#ifndef FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED -#define FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED 1 -#endif - -/* If FFETARGET_defaultEXTERNAL_UNDERSCORED is 0, the following definitions - might also need to be overridden to make g77 objects compatible with - f2c+gcc objects. Although I don't think the unnamed BLOCK DATA one - is an issue at all. Of course, on some systems it isn't f2c - compatibility that is the issue -- maybe compatibility with some - other compiler(s). I don't know what to recommend for systems where - there is no existing Fortran compiler -- I suppose porting f2c and - pretending it's the existing one is best for now. */ - -/* 1 if the "FOO" in "PROGRAM FOO" should be overridden and a particular - name imposed in place of it in the actual code (normally the case, - because the library's main entry point on most systems calls the main - function by a particular name). Someday g77 might do the f2c trick - of also outputting a "FOO" procedure that just calls the main procedure, - but that'll wait until somebody shows why it is needed. */ - -#ifndef FFETARGET_isENFORCED_MAIN -#define FFETARGET_isENFORCED_MAIN 1 -#endif - -/* The enforced name of the main program if ENFORCED_MAIN is 1. */ - -#ifndef FFETARGET_nameENFORCED_MAIN_NAME -#define FFETARGET_nameENFORCED_MAIN_NAME "MAIN__" -#endif - -/* The name used for an unnamed main program if ENFORCED_MAIN is 0. */ - -#ifndef FFETARGET_nameUNNAMED_MAIN -#define FFETARGET_nameUNNAMED_MAIN "MAIN__" -#endif - -/* The name used for an unnamed block data program. */ - -#ifndef FFETARGET_nameUNNAMED_BLOCK_DATA -#define FFETARGET_nameUNNAMED_BLOCK_DATA "_BLOCK_DATA__" -#endif - -/* The name used for blank common. */ - -#ifndef FFETARGET_nameBLANK_COMMON -#define FFETARGET_nameBLANK_COMMON "_BLNK__" -#endif - -#ifndef FFETARGET_integerSMALLEST_POSITIVE -#define FFETARGET_integerSMALLEST_POSITIVE 0 -#endif -#ifndef FFETARGET_integerLARGEST_POSITIVE -#define FFETARGET_integerLARGEST_POSITIVE 2147483647 -#endif -#ifndef FFETARGET_integerBIG_MAGICAL -#define FFETARGET_integerBIG_MAGICAL 020000000000 /* 2147483648 */ -#endif -#ifndef FFETARGET_integerALMOST_BIG_MAGICAL -#define FFETARGET_integerALMOST_BIG_MAGICAL 214748364 -#endif -#ifndef FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY -#define FFETARGET_integerALMOST_BIG_OVERFLOW_BINARY 0x80000000 -#endif -#ifndef FFETARGET_integerALMOST_BIG_OVERFLOW_HEX -#define FFETARGET_integerALMOST_BIG_OVERFLOW_HEX 0x10000000 -#endif -#ifndef FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL -#define FFETARGET_integerALMOST_BIG_OVERFLOW_OCTAL 0x20000000 -#endif -#ifndef FFETARGET_integerFINISH_BIG_MAGICAL -#define FFETARGET_integerFINISH_BIG_MAGICAL 8 -#endif -#ifndef FFETARGET_integerFINISH_BIG_OVERFLOW_BINARY -#define FFETARGET_integerFINISH_BIG_OVERFLOW_BINARY 0 -#endif -#ifndef FFETARGET_integerFINISH_BIG_OVERFLOW_HEX -#define FFETARGET_integerFINISH_BIG_OVERFLOW_HEX 0 -#endif -#ifndef FFETARGET_integerFINISH_BIG_OVERFLOW_OCTAL -#define FFETARGET_integerFINISH_BIG_OVERFLOW_OCTAL 0 -#endif - -#ifndef FFETARGET_offsetNONE -#define FFETARGET_offsetNONE 0 /* Not used by FFE, for backend if needed. */ -#endif - -#define FFETARGET_okINTEGER1 1 -#define FFETARGET_okINTEGER2 1 -#define FFETARGET_okINTEGER3 1 -#define FFETARGET_okINTEGER4 1 -#define FFETARGET_okLOGICAL1 1 -#define FFETARGET_okLOGICAL2 1 -#define FFETARGET_okLOGICAL3 1 -#define FFETARGET_okLOGICAL4 1 -#define FFETARGET_okREAL1 1 -#define FFETARGET_okREAL2 1 -#define FFETARGET_okREAL3 0 -#define FFETARGET_okREALQUAD FFETARGET_okREAL3 -#define FFETARGET_okCOMPLEX1 1 -#define FFETARGET_okCOMPLEX2 1 -#define FFETARGET_okCOMPLEX3 0 -#define FFETARGET_okCOMPLEXDOUBLE FFETARGET_okCOMPLEX2 -#define FFETARGET_okCOMPLEXQUAD FFETARGET_okCOMPLEX3 -#define FFETARGET_okCHARACTER1 1 - -#define FFETARGET_f2cTYUNKNOWN 0 -#define FFETARGET_f2cTYADDR 1 -#define FFETARGET_f2cTYSHORT 2 -#define FFETARGET_f2cTYLONG 3 -#define FFETARGET_f2cTYREAL 4 -#define FFETARGET_f2cTYDREAL 5 -#define FFETARGET_f2cTYCOMPLEX 6 -#define FFETARGET_f2cTYDCOMPLEX 7 -#define FFETARGET_f2cTYLOGICAL 8 -#define FFETARGET_f2cTYCHAR 9 -#define FFETARGET_f2cTYSUBR 10 -#define FFETARGET_f2cTYINT1 11 -#define FFETARGET_f2cTYLOGICAL1 12 -#define FFETARGET_f2cTYLOGICAL2 13 -#define FFETARGET_f2cTYQUAD 14 - -/* Typedefs. */ - -typedef unsigned char ffetargetAlign; /* ffetargetOffset for alignment. */ -#define ffetargetAlign_f "" -typedef long ffetargetCharacterSize; -#define ffetargetCharacterSize_f "l" -typedef void (*ffetargetCopyfunc) (void *, void *, size_t); -typedef ffetargetCharacterSize ffetargetHollerithSize; -#define ffetargetHollerithSize_f "l" -typedef long long ffetargetOffset; -#define ffetargetOffset_f "ll" - -#if FFETARGET_okINTEGER1 -#ifndef __alpha__ -typedef long int ffetargetInteger1; -#define ffetargetInteger1_f "l" -#else -typedef int ffetargetInteger1; -#define ffetargetInteger1_f "" -#endif -#endif -#if FFETARGET_okINTEGER2 -typedef signed char ffetargetInteger2; -#define ffetargetInteger2_f "" -#endif -#if FFETARGET_okINTEGER3 -typedef short int ffetargetInteger3; -#define ffetargetInteger3_f "" -#endif -#if FFETARGET_okINTEGER4 -typedef long long int ffetargetInteger4; -#define ffetargetInteger4_f "ll" -#endif -#if FFETARGET_okINTEGER5 -typedef ? ffetargetInteger5; -#define ffetargetInteger5_f -? -#endif -#if FFETARGET_okINTEGER6 -typedef ? ffetargetInteger6; -#define ffetargetInteger6_f -? -#endif -#if FFETARGET_okINTEGER7 -typedef ? ffetargetInteger7; -#define ffetargetInteger7_f -? -#endif -#if FFETARGET_okINTEGER8 -typedef ? ffetargetInteger8; -#define ffetargetInteger8_f -? -#endif -#if FFETARGET_okLOGICAL1 -#ifndef __alpha__ -typedef long int ffetargetLogical1; -#define ffetargetLogical1_f "l" -#else -typedef int ffetargetLogical1; -#define ffetargetLogical1_f "" -#endif -#endif -#if FFETARGET_okLOGICAL2 -typedef signed char ffetargetLogical2; -#define ffetargetLogical2_f "" -#endif -#if FFETARGET_okLOGICAL3 -typedef short int ffetargetLogical3; -#define ffetargetLogical3_f "" -#endif -#if FFETARGET_okLOGICAL4 -typedef long long int ffetargetLogical4; -#define ffetargetLogical4_f "ll" -#endif -#if FFETARGET_okLOGICAL5 -typedef ? ffetargetLogical5; -#define ffetargetLogical5_f -? -#endif -#if FFETARGET_okLOGICAL6 -typedef ? ffetargetLogical6; -#define ffetargetLogical6_f -? -#endif -#if FFETARGET_okLOGICAL7 -typedef ? ffetargetLogical7; -#define ffetargetLogical7_f -? -#endif -#if FFETARGET_okLOGICAL8 -typedef ? ffetargetLogical8; -#define ffetargetLogical8_f -? -#endif -#if FFETARGET_okREAL1 -#ifdef REAL_ARITHMETIC -#ifndef __alpha__ -typedef long int ffetargetReal1; -#define ffetargetReal1_f "l" -#define ffetarget_cvt_r1_to_rv_ REAL_VALUE_UNTO_TARGET_SINGLE -#define ffetarget_cvt_rv_to_r1_ REAL_VALUE_TO_TARGET_SINGLE -#else -typedef int ffetargetReal1; -#define ffetargetReal1_f "" -#define ffetarget_cvt_r1_to_rv_(in) \ - ({ REAL_VALUE_TYPE _rv; \ - _rv = REAL_VALUE_UNTO_TARGET_SINGLE ((long) (in)); \ - _rv; }) -#define ffetarget_cvt_rv_to_r1_(in, out) \ - ({ long _tmp; \ - REAL_VALUE_TO_TARGET_SINGLE ((in), _tmp); \ - (out) = (ffetargetReal1) _tmp; }) -#endif -#else /* REAL_ARITHMETIC */ -typedef float ffetargetReal1; -#define ffetargetReal1_f "" -#endif /* REAL_ARITHMETIC */ -#endif -#if FFETARGET_okREAL2 -#ifdef REAL_ARITHMETIC -#ifndef __alpha__ -typedef struct - { - long int v[2]; - } -ffetargetReal2; -#define ffetargetReal2_f "l" -#define ffetarget_cvt_r2_to_rv_ REAL_VALUE_UNTO_TARGET_DOUBLE -#define ffetarget_cvt_rv_to_r2_ REAL_VALUE_TO_TARGET_DOUBLE -#else -typedef struct - { - int v[2]; - } -ffetargetReal2; -#define ffetargetReal2_f "" -#define ffetarget_cvt_r2_to_rv_(in) \ - ({ REAL_VALUE_TYPE _rv; \ - long _tmp[2]; \ - _tmp[0] = (in)[0]; \ - _tmp[1] = (in)[1]; \ - _rv = REAL_VALUE_UNTO_TARGET_DOUBLE (_tmp); \ - _rv; }) -#define ffetarget_cvt_rv_to_r2_(in, out) \ - ({ long _tmp[2]; \ - REAL_VALUE_TO_TARGET_DOUBLE ((in), _tmp); \ - (out)[0] = (int) (_tmp[0]); \ - (out)[1] = (int) (_tmp[1]); }) -#endif -#else -typedef double ffetargetReal2; -#define ffetargetReal2_f "" -#endif -#endif -#if FFETARGET_okREAL3 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal3[?]; -#else -typedef ? ffetargetReal3; -#define ffetargetReal3_f -#endif -? -#endif -#if FFETARGET_okREAL4 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal4[?]; -#else -typedef ? ffetargetReal4; -#define ffetargetReal4_f -#endif -? -#endif -#if FFETARGET_okREAL5 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal5[?]; -#else -typedef ? ffetargetReal5; -#define ffetargetReal5_f -#endif -? -#endif -#if FFETARGET_okREAL6 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal6[?]; -#else -typedef ? ffetargetReal6; -#define ffetargetReal6_f -#endif -? -#endif -#if FFETARGET_okREAL7 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal7[?]; -#else -typedef ? ffetargetReal7; -#define ffetargetReal7_f -#endif -? -#endif -#if FFETARGET_okREAL8 -#ifdef REAL_ARITHMETIC -typedef long ffetargetReal8[?]; -#else -typedef ? ffetargetReal8; -#define ffetargetReal8_f -#endif -? -#endif -#if FFETARGET_okCOMPLEX1 -struct _ffetarget_complex_1_ - { - ffetargetReal1 real; - ffetargetReal1 imaginary; - }; -typedef struct _ffetarget_complex_1_ ffetargetComplex1; -#endif -#if FFETARGET_okCOMPLEX2 -struct _ffetarget_complex_2_ - { - ffetargetReal2 real; - ffetargetReal2 imaginary; - }; -typedef struct _ffetarget_complex_2_ ffetargetComplex2; -#endif -#if FFETARGET_okCOMPLEX3 -struct _ffetarget_complex_3_ - { - ffetargetReal3 real; - ffetargetReal3 imaginary; - }; -typedef struct _ffetarget_complex_3_ ffetargetComplex3; -#endif -#if FFETARGET_okCOMPLEX4 -struct _ffetarget_complex_4_ - { - ffetargetReal4 real; - ffetargetReal4 imaginary; - }; -typedef struct _ffetarget_complex_4_ ffetargetComplex4; -#endif -#if FFETARGET_okCOMPLEX5 -struct _ffetarget_complex_5_ - { - ffetargetReal5 real; - ffetargetReal5 imaginary; - }; -typedef struct _ffetarget_complex_5_ ffetargetComplex5; -#endif -#if FFETARGET_okCOMPLEX6 -struct _ffetarget_complex_6_ - { - ffetargetReal6 real; - ffetargetReal6 imaginary; - }; -typedef struct _ffetarget_complex_6_ ffetargetComplex6; -#endif -#if FFETARGET_okCOMPLEX7 -struct _ffetarget_complex_7_ - { - ffetargetReal7 real; - ffetargetReal7 imaginary; - }; -typedef struct _ffetarget_complex_7_ ffetargetComplex7; -#endif -#if FFETARGET_okCOMPLEX8 -struct _ffetarget_complex_8_ - { - ffetargetReal8 real; - ffetargetReal8 imaginary; - }; -typedef struct _ffetarget_complex_8_ ffetargetComplex8; -#endif -#if FFETARGET_okCHARACTER1 -struct _ffetarget_char_1_ - { - ffetargetCharacterSize length; - unsigned char *text; - }; -typedef struct _ffetarget_char_1_ ffetargetCharacter1; -typedef unsigned char ffetargetCharacterUnit1; -#endif -#if FFETARGET_okCHARACTER2 -typedef ? ffetargetCharacter2; -typedef ? ffetargetCharacterUnit2; -#endif -#if FFETARGET_okCHARACTER3 -typedef ? ffetargetCharacter3; -typedef ? ffetargetCharacterUnit3; -#endif -#if FFETARGET_okCHARACTER4 -typedef ? ffetargetCharacter4; -typedef ? ffetargetCharacterUnit4; -#endif -#if FFETARGET_okCHARACTER5 -typedef ? ffetargetCharacter5; -typedef ? ffetargetCharacterUnit5; -#endif -#if FFETARGET_okCHARACTER6 -typedef ? ffetargetCharacter6; -typedef ? ffetargetCharacterUnit6; -#endif -#if FFETARGET_okCHARACTER7 -typedef ? ffetargetCharacter7; -typedef ? ffetargetCharacterUnit7; -#endif -#if FFETARGET_okCHARACTER8 -typedef ? ffetargetCharacter8; -typedef ? ffetargetCharacterUnit8; -#endif - -typedef unsigned long long int ffetargetTypeless; - -struct _ffetarget_hollerith_ - { - ffetargetHollerithSize length; - unsigned char *text; - }; -typedef struct _ffetarget_hollerith_ ffetargetHollerith; - -typedef ffetargetCharacter1 ffetargetCharacterDefault; -typedef ffetargetComplex1 ffetargetComplexDefault; -#if FFETARGET_okCOMPLEXDOUBLE -typedef ffetargetComplex2 ffetargetComplexDouble; -#endif -#if FFETARGET_okCOMPLEXQUAD -typedef ffetargetComplex3 ffetargetComplexQuad; -#endif -typedef ffetargetInteger1 ffetargetIntegerDefault; -#define ffetargetIntegerDefault_f ffetargetInteger1_f -typedef ffetargetLogical1 ffetargetLogicalDefault; -#define ffetargetLogicalDefault_f ffetargetLogical1_f -typedef ffetargetReal1 ffetargetRealDefault; -#define ffetargetRealDefault_f ffetargetReal1_f -typedef ffetargetReal2 ffetargetRealDouble; -#define ffetargetRealDouble_f ffetargetReal2_f -#if FFETARGET_okREALQUAD -typedef ffetargetReal3 ffetargetRealQuad; -#define ffetargetRealQuad_f ffetargetReal3_f -#endif - -/* Include files needed by this one. */ - -#include "bad.h" -#include "info.h" -#include "lex.h" -#include "malloc.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern char ffetarget_string_[40]; /* Temp for ascii-to-double (atof). */ -extern HOST_WIDE_INT ffetarget_long_val_; -extern HOST_WIDE_INT ffetarget_long_junk_; - -/* Declare functions with prototypes. */ - -void ffetarget_aggregate_info (ffeinfoBasictype *ebt, ffeinfoKindtype *ekt, - ffetargetAlign *units, ffeinfoBasictype abt, - ffeinfoKindtype akt); -ffetargetAlign ffetarget_align (ffetargetAlign *updated_alignment, - ffetargetAlign *updated_modulo, - ffetargetOffset offset, - ffetargetAlign alignment, - ffetargetAlign modulo); -#if FFETARGET_okCHARACTER1 -bool ffetarget_character1 (ffetargetCharacter1 *val, ffelexToken character, - mallocPool pool); -int ffetarget_cmp_character1 (ffetargetCharacter1 l, ffetargetCharacter1 r); -ffebad ffetarget_concatenate_character1 (ffetargetCharacter1 *res, - ffetargetCharacter1 l, - ffetargetCharacter1 r, - mallocPool pool, - ffetargetCharacterSize *len); -ffebad ffetarget_convert_character1_character1 (ffetargetCharacter1 *res, - ffetargetCharacterSize res_size, - ffetargetCharacter1 l, - mallocPool pool); -ffebad ffetarget_convert_character1_hollerith (ffetargetCharacter1 *res, - ffetargetCharacterSize res_size, - ffetargetHollerith l, - mallocPool pool); -ffebad ffetarget_convert_character1_integer4 (ffetargetCharacter1 *res, - ffetargetCharacterSize res_size, - ffetargetInteger4 l, - mallocPool pool); -ffebad ffetarget_convert_character1_logical4 (ffetargetCharacter1 *res, - ffetargetCharacterSize res_size, - ffetargetLogical4 l, - mallocPool pool); -ffebad ffetarget_convert_character1_typeless (ffetargetCharacter1 *res, - ffetargetCharacterSize res_size, - ffetargetTypeless l, - mallocPool pool); -ffebad ffetarget_eq_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_le_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_ge_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_gt_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_lt_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_ne_character1 (bool *res, ffetargetCharacter1 l, - ffetargetCharacter1 r); -ffebad ffetarget_substr_character1 (ffetargetCharacter1 *res, - ffetargetCharacter1 l, - ffetargetCharacterSize first, - ffetargetCharacterSize last, - mallocPool pool, - ffetargetCharacterSize *len); -#endif -int ffetarget_cmp_hollerith (ffetargetHollerith l, ffetargetHollerith r); -bool ffetarget_hollerith (ffetargetHollerith *val, ffelexToken hollerith, - mallocPool pool); -int ffetarget_cmp_typeless (ffetargetTypeless l, ffetargetTypeless r); -ffebad ffetarget_convert_any_character1_ (char *res, size_t size, - ffetargetCharacter1 l); -ffebad ffetarget_convert_any_hollerith_ (char *res, size_t size, - ffetargetHollerith l); -ffebad ffetarget_convert_any_typeless_ (char *res, size_t size, - ffetargetTypeless l); -#if FFETARGET_okCOMPLEX1 -ffebad ffetarget_divide_complex1 (ffetargetComplex1 *res, ffetargetComplex1 l, - ffetargetComplex1 r); -#endif -#if FFETARGET_okCOMPLEX2 -ffebad ffetarget_divide_complex2 (ffetargetComplex2 *res, ffetargetComplex2 l, - ffetargetComplex2 r); -#endif -#if FFETARGET_okCOMPLEX3 -ffebad ffetarget_divide_complex3 (ffetargetComplex3 *res, ffetargetComplex3 l, - ffetargetComplex3 r); -#endif -#if FFETARGET_okCOMPLEX4 -ffebad ffetarget_divide_complex4 (ffetargetComplex4 *res, ffetargetComplex4 l, - ffetargetComplex4 r); -#endif -#if FFETARGET_okCOMPLEX5 -ffebad ffetarget_divide_complex5 (ffetargetComplex5 *res, ffetargetComplex5 l, - ffetargetComplex5 r); -#endif -#if FFETARGET_okCOMPLEX6 -ffebad ffetarget_divide_complex6 (ffetargetComplex6 *res, ffetargetComplex6 l, - ffetargetComplex6 r); -#endif -#if FFETARGET_okCOMPLEX7 -ffebad ffetarget_divide_complex7 (ffetargetComplex7 *res, ffetargetComplex7 l, - ffetargetComplex7 r); -#endif -#if FFETARGET_okCOMPLEX8 -ffebad ffetarget_divide_complex8 (ffetargetComplex8 *res, ffetargetComplex8 l, - ffetargetComplex8 r); -#endif -#if FFETARGET_okINTEGER1 -bool ffetarget_integer1 (ffetargetInteger1 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER2 -bool ffetarget_integer2 (ffetargetInteger2 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER3 -bool ffetarget_integer3 (ffetargetInteger3 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER4 -bool ffetarget_integer4 (ffetargetInteger4 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER5 -bool ffetarget_integer5 (ffetargetInteger5 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER6 -bool ffetarget_integer6 (ffetargetInteger6 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER7 -bool ffetarget_integer7 (ffetargetInteger7 *val, ffelexToken integer); -#endif -#if FFETARGET_okINTEGER8 -bool ffetarget_integer8 (ffetargetInteger8 *val, ffelexToken integer); -#endif -bool ffetarget_integerbinary (ffetargetIntegerDefault *val, - ffelexToken integer); -bool ffetarget_integerhex (ffetargetIntegerDefault *val, - ffelexToken integer); -bool ffetarget_integeroctal (ffetargetIntegerDefault *val, - ffelexToken integer); -void ffetarget_integer_bad_magical (ffelexToken t); -void ffetarget_integer_bad_magical_binary (ffelexToken integer, ffelexToken minus); -void ffetarget_integer_bad_magical_precedence (ffelexToken integer, - ffelexToken uminus, - ffelexToken higher_op); -void ffetarget_integer_bad_magical_precedence_binary (ffelexToken integer, - ffelexToken minus, - ffelexToken higher_op); -#if FFETARGET_okCHARACTER1 -bool ffetarget_iszero_character1 (ffetargetCharacter1 constant); -#endif -bool ffetarget_iszero_hollerith (ffetargetHollerith constant); -void ffetarget_layout (char *error_text, ffetargetAlign *alignment, - ffetargetAlign *modulo, ffetargetOffset *size, - ffeinfoBasictype bt, ffeinfoKindtype kt, - ffetargetCharacterSize charsize, - ffetargetIntegerDefault num_elements); -#if FFETARGET_okCOMPLEX1 -ffebad ffetarget_multiply_complex1 (ffetargetComplex1 *res, - ffetargetComplex1 l, - ffetargetComplex1 r); -#endif -#if FFETARGET_okCOMPLEX2 -ffebad ffetarget_multiply_complex2 (ffetargetComplex2 *res, - ffetargetComplex2 l, - ffetargetComplex2 r); -#endif -#if FFETARGET_okCOMPLEX3 -ffebad ffetarget_multiply_complex3 (ffetargetComplex3 *res, - ffetargetComplex3 l, - ffetargetComplex3 r); -#endif -#if FFETARGET_okCOMPLEX4 -ffebad ffetarget_multiply_complex4 (ffetargetComplex4 *res, - ffetargetComplex4 l, - ffetargetComplex4 r); -#endif -#if FFETARGET_okCOMPLEX5 -ffebad ffetarget_multiply_complex5 (ffetargetComplex5 *res, - ffetargetComplex5 l, - ffetargetComplex5 r); -#endif -#if FFETARGET_okCOMPLEX6 -ffebad ffetarget_multiply_complex6 (ffetargetComplex6 *res, - ffetargetComplex6 l, - ffetargetComplex6 r); -#endif -#if FFETARGET_okCOMPLEX7 -ffebad ffetarget_multiply_complex7 (ffetargetComplex7 *res, - ffetargetComplex7 l, - ffetargetComplex7 r); -#endif -#if FFETARGET_okCOMPLEX8 -ffebad ffetarget_multiply_complex8 (ffetargetComplex8 *res, - ffetargetComplex8 l, - ffetargetComplex8 r); -#endif -ffebad ffetarget_power_complexdefault_integerdefault (ffetargetComplexDefault *res, - ffetargetComplexDefault l, - ffetargetIntegerDefault r); -#if FFETARGET_okCOMPLEXDOUBLE -ffebad ffetarget_power_complexdouble_integerdefault (ffetargetComplexDouble *res, - ffetargetComplexDouble l, - ffetargetIntegerDefault r); -#endif -ffebad ffetarget_power_integerdefault_integerdefault (ffetargetIntegerDefault *res, - ffetargetIntegerDefault l, - ffetargetIntegerDefault r); -ffebad ffetarget_power_realdefault_integerdefault (ffetargetRealDefault *res, - ffetargetRealDefault l, - ffetargetIntegerDefault r); -ffebad ffetarget_power_realdouble_integerdefault (ffetargetRealDouble *res, - ffetargetRealDouble l, - ffetargetIntegerDefault r); -void ffetarget_print_binary (FILE *f, ffetargetTypeless val); -void ffetarget_print_character1 (FILE *f, ffetargetCharacter1 val); -void ffetarget_print_hollerith (FILE *f, ffetargetHollerith val); -void ffetarget_print_octal (FILE *f, ffetargetTypeless val); -void ffetarget_print_hex (FILE *f, ffetargetTypeless val); -#if FFETARGET_okREAL1 -bool ffetarget_real1 (ffetargetReal1 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL2 -bool ffetarget_real2 (ffetargetReal2 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL3 -bool ffetarget_real3 (ffetargetReal3 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL4 -bool ffetarget_real4 (ffetargetReal4 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL5 -bool ffetarget_real5 (ffetargetReal5 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL6 -bool ffetarget_real6 (ffetargetReal6 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL7 -bool ffetarget_real7 (ffetargetReal7 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -#if FFETARGET_okREAL8 -bool ffetarget_real8 (ffetargetReal8 *value, ffelexToken integer, - ffelexToken decimal, ffelexToken fraction, - ffelexToken exponent, ffelexToken exponent_sign, - ffelexToken exponent_digits); -#endif -bool ffetarget_typeless_binary (ffetargetTypeless *value, ffelexToken token); -bool ffetarget_typeless_octal (ffetargetTypeless *value, ffelexToken token); -bool ffetarget_typeless_hex (ffetargetTypeless *value, ffelexToken token); -void ffetarget_verify_character1 (mallocPool pool, ffetargetCharacter1 val); -int ffetarget_num_digits_ (ffelexToken t); -void *ffetarget_memcpy_ (void *dst, void *src, size_t len); - -/* Define macros. */ - -#if BUILT_FOR_280 -#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0), ((kt == 1) ? SFmode : DFmode)) -#else -#define FFETARGET_REAL_VALUE_FROM_INT_(resr, lf, kt) \ - REAL_VALUE_FROM_INT (resr, (long) lf, (long) ((lf < 0) ? -1 : 0)) -#endif - -#ifdef REAL_ARITHMETIC -#define ffetarget_add_complex1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ - ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ - REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - REAL_ARITHMETIC (resi, PLUS_EXPR, li, ri); \ - ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ - FFEBAD; }) -#define ffetarget_add_complex2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ - ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ - REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - REAL_ARITHMETIC (resi, PLUS_EXPR, li, ri); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ - FFEBAD; }) -#else -#define ffetarget_add_complex1(res,l,r) \ - ((res)->real = (l).real + (r).real, \ - (res)->imaginary = (l).imaginary + (r).imaginary, FFEBAD) -#define ffetarget_add_complex2(res,l,r) \ - ((res)->real = (l).real + (r).real, \ - (res)->imaginary = (l).imaginary + (r).imaginary, FFEBAD) -#endif -#define ffetarget_add_integer1(res,l,r) (*(res) = (l) + (r), FFEBAD) -#define ffetarget_add_integer2(res,l,r) (*(res) = (l) + (r), FFEBAD) -#define ffetarget_add_integer3(res,l,r) (*(res) = (l) + (r), FFEBAD) -#define ffetarget_add_integer4(res,l,r) (*(res) = (l) + (r), FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_add_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; }) -#define ffetarget_add_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - REAL_ARITHMETIC (resr, PLUS_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; }) -#else -#define ffetarget_add_real1(res,l,r) (*(res) = (l) + (r), FFEBAD) -#define ffetarget_add_real2(res,l,r) (*(res) = (l) + (r), FFEBAD) -#endif -#define ffetarget_aggregate_ptr_memcpy(dbt,dkt,sbt,skt) \ - ((ffetargetCopyfunc) ffetarget_memcpy_) -#define ffetarget_and_integer1(res,l,r) (*(res) = (l) & (r), FFEBAD) -#define ffetarget_and_integer2(res,l,r) (*(res) = (l) & (r), FFEBAD) -#define ffetarget_and_integer3(res,l,r) (*(res) = (l) & (r), FFEBAD) -#define ffetarget_and_integer4(res,l,r) (*(res) = (l) & (r), FFEBAD) -#define ffetarget_and_logical1(res,l,r) (*(res) = (l) && (r), FFEBAD) -#define ffetarget_and_logical2(res,l,r) (*(res) = (l) && (r), FFEBAD) -#define ffetarget_and_logical3(res,l,r) (*(res) = (l) && (r), FFEBAD) -#define ffetarget_and_logical4(res,l,r) (*(res) = (l) && (r), FFEBAD) -#define ffetarget_binarymil(v,t) ffetarget_typeless_binary (v, t) -#define ffetarget_binaryvxt(v,t) ffetarget_typeless_binary (v, t) -#define ffetarget_cmp_integer1(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_integer2(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_integer3(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_integer4(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_logical1(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_logical2(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_logical3(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_logical4(l,r) ((l) == (r) ? 0 : ((l) < (r) ? -1 : 1)) -#define ffetarget_cmp_real1(l,r) memcmp (&(l), &(r), sizeof(l)) -#define ffetarget_cmp_real2(l,r) memcmp (&(l), &(r), sizeof(l)) -#define ffetarget_cmp_real3(l,r) memcmp (&(l), &(r), sizeof(l)) -#define ffetarget_cmp_typeless(l,r) \ - memcmp (&(l), &(r), sizeof ((l))) -#define ffetarget_convert_character1_integer1(res,res_size,l,pool) \ - ffetarget_convert_character1_integer4(res,res_size,(ffetargetInteger4)l,pool) -#define ffetarget_convert_character1_integer2(res,res_size,l,pool) \ - ffetarget_convert_character1_integer4(res,res_size,(ffetargetInteger4)l,pool) -#define ffetarget_convert_character1_integer3(res,res_size,l,pool) \ - ffetarget_convert_character1_integer4(res,res_size,(ffetargetInteger4)l,pool) -#define ffetarget_convert_character1_logical1(res,res_size,l,pool) \ - ffetarget_convert_character1_logical4(res,res_size,(ffetargetLogical4)l,pool) -#define ffetarget_convert_character1_logical2(res,res_size,l,pool) \ - ffetarget_convert_character1_logical4(res,res_size,(ffetargetLogical4)l,pool) -#define ffetarget_convert_character1_logical3(res,res_size,l,pool) \ - ffetarget_convert_character1_logical4(res,res_size,(ffetargetLogical4)l,pool) -#define ffetarget_convert_complex1_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_complex1_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_complex1_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex1_complex2(res,l) \ - ({ REAL_VALUE_TYPE lr, li; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - ffetarget_cvt_rv_to_r1_ (lr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (li, (res)->imaginary), \ - FFEBAD; }) -#else -#define ffetarget_convert_complex1_complex2(res,l) \ - ((res)->real = (l).real, (res)->imaginary = (l).imaginary, FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex1_integer(res,l) \ - ({ REAL_VALUE_TYPE resi, resr; \ - ffetargetInteger1 lf = (l); \ - FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 1); \ - resi = dconst0; \ - ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ - FFEBAD; }) -#else -#define ffetarget_convert_complex1_integer(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#endif -#define ffetarget_convert_complex1_integer1 ffetarget_convert_complex1_integer -#define ffetarget_convert_complex1_integer2 ffetarget_convert_complex1_integer -#define ffetarget_convert_complex1_integer3 ffetarget_convert_complex1_integer -#define ffetarget_convert_complex1_integer4 ffetarget_convert_complex1_integer -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex1_real1(res,l) \ - ((res)->real = (l), \ - ffetarget_cvt_rv_to_r1_ (dconst0, (res)->imaginary), \ - FFEBAD) -#define ffetarget_convert_complex1_real2(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - ffetarget_cvt_rv_to_r1_ (lr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (dconst0, (res)->imaginary), \ - FFEBAD; }) -#else -#define ffetarget_convert_complex1_real1(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#define ffetarget_convert_complex1_real2(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#endif -#define ffetarget_convert_complex2_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_complex2_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_complex2_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex2_complex1(res,l) \ - ({ REAL_VALUE_TYPE lr, li; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - ffetarget_cvt_rv_to_r2_ (lr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (li, &((res)->imaginary.v[0])), \ - FFEBAD; }) -#else -#define ffetarget_convert_complex2_complex1(res,l) \ - ((res)->real = (l).real, (res)->imaginary = (l).imaginary, FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex2_integer(res,l) \ - ({ REAL_VALUE_TYPE resi, resr; \ - ffetargetInteger1 lf = (l); \ - FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 2); \ - resi = dconst0; \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ - FFEBAD; }) -#else -#define ffetarget_convert_complex2_integer(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#endif -#define ffetarget_convert_complex2_integer1 ffetarget_convert_complex2_integer -#define ffetarget_convert_complex2_integer2 ffetarget_convert_complex2_integer -#define ffetarget_convert_complex2_integer3 ffetarget_convert_complex2_integer -#define ffetarget_convert_complex2_integer4 ffetarget_convert_complex2_integer -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_complex2_real1(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ (l); \ - ffetarget_cvt_rv_to_r2_ (lr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->imaginary.v[0])), \ - FFEBAD; }) -#define ffetarget_convert_complex2_real2(res,l) \ - ((res)->real = (l), \ - ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->imaginary.v[0])), \ - FFEBAD) -#else -#define ffetarget_convert_complex2_real1(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#define ffetarget_convert_complex2_real2(res,l) \ - ((res)->real = (l), (res)->imaginary = 0, FFEBAD) -#endif -#define ffetarget_convert_integer2_character1(res,l) \ - ffetarget_convert_integer1_character1(res,l) -#define ffetarget_convert_integer2_complex1(res,l) \ - ffetarget_convert_integer1_complex1(res,l) -#define ffetarget_convert_integer2_complex2(res,l) \ - ffetarget_convert_integer1_complex2(res,l) -#define ffetarget_convert_integer2_hollerith(res,l) \ - ffetarget_convert_integer1_hollerith(res,l) -#define ffetarget_convert_integer2_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer2_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer2_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer2_logical1(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer2_logical2(res,l) \ - ffetarget_convert_integer2_logical1(res,l) -#define ffetarget_convert_integer2_logical3(res,l) \ - ffetarget_convert_integer2_logical1(res,l) -#define ffetarget_convert_integer2_logical4(res,l) \ - ffetarget_convert_integer2_logical1(res,l) -#define ffetarget_convert_integer2_real1(res,l) \ - ffetarget_convert_integer1_real1(res,l) -#define ffetarget_convert_integer2_real2(res,l) \ - ffetarget_convert_integer1_real2(res,l) -#define ffetarget_convert_integer2_typeless(res,l) \ - ffetarget_convert_integer1_typeless(res,l) -#define ffetarget_convert_integer3_character1(res,l) \ - ffetarget_convert_integer1_character1(res,l) -#define ffetarget_convert_integer3_complex1(res,l) \ - ffetarget_convert_integer1_complex1(res,l) -#define ffetarget_convert_integer3_complex2(res,l) \ - ffetarget_convert_integer1_complex2(res,l) -#define ffetarget_convert_integer3_hollerith(res,l) \ - ffetarget_convert_integer1_hollerith(res,l) -#define ffetarget_convert_integer3_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer3_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer3_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer3_logical1(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer3_logical2(res,l) \ - ffetarget_convert_integer3_logical1(res,l) -#define ffetarget_convert_integer3_logical3(res,l) \ - ffetarget_convert_integer3_logical1(res,l) -#define ffetarget_convert_integer3_logical4(res,l) \ - ffetarget_convert_integer3_logical1(res,l) -#define ffetarget_convert_integer3_real1(res,l) \ - ffetarget_convert_integer1_real1(res,l) -#define ffetarget_convert_integer3_real2(res,l) \ - ffetarget_convert_integer1_real2(res,l) -#define ffetarget_convert_integer3_typeless(res,l) \ - ffetarget_convert_integer1_typeless(res,l) -#define ffetarget_convert_integer4_character1(res,l) \ - ffetarget_convert_integer1_character1(res,l) -#define ffetarget_convert_integer4_complex1(res,l) \ - ffetarget_convert_integer1_complex1(res,l) -#define ffetarget_convert_integer4_complex2(res,l) \ - ffetarget_convert_integer1_complex2(res,l) -#define ffetarget_convert_integer4_hollerith(res,l) \ - ffetarget_convert_integer1_hollerith(res,l) -#define ffetarget_convert_integer4_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer4_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer4_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer4_logical1(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer4_logical2(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer4_logical3(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer4_logical4(res,l) \ - ffetarget_convert_integer1_logical1(res,l) -#define ffetarget_convert_integer4_real1(res,l) \ - ffetarget_convert_integer1_real1(res,l) -#define ffetarget_convert_integer4_real2(res,l) \ - ffetarget_convert_integer1_real2(res,l) -#define ffetarget_convert_integer4_typeless(res,l) \ - ffetarget_convert_integer1_typeless(res,l) -#define ffetarget_convert_logical1_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical1_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical1_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical1_logical2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_logical3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_logical4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical1_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical2_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical2_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical2_logical1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_logical3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_logical4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical2_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical3_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical3_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical3_logical1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_logical2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_logical4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical3_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical4_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical4_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_logical4_logical1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_logical2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_logical3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_integer1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_logical4_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_integer1_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_integer1_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_integer1_integer2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_integer3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_integer4(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_logical1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_logical2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_logical3(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_logical4(res,l) (*(res) = (l), FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_integer1_real1(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ (l); \ - REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ - *(res) = ffetarget_long_val_; \ - FFEBAD; }) -#define ffetarget_convert_integer1_real2(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ - *(res) = ffetarget_long_val_; \ - FFEBAD; }) -#define ffetarget_convert_integer1_complex1(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ - *(res) = ffetarget_long_val_; \ - FFEBAD; }) -#define ffetarget_convert_integer1_complex2(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - REAL_VALUE_TO_INT (&ffetarget_long_val_, &ffetarget_long_junk_, lr); \ - *(res) = ffetarget_long_val_; \ - FFEBAD; }) -#else -#define ffetarget_convert_integer1_real1(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_real2(res,l) (*(res) = (l), FFEBAD) -#define ffetarget_convert_integer1_complex1(res,l) (*(res) = (l).real, FFEBAD) -#define ffetarget_convert_integer1_complex2(res,l) (*(res) = (l).real, FFEBAD) -#endif -#define ffetarget_convert_real1_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real1_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real1_integer2(res,l) \ - ffetarget_convert_real1_integer1(res,l) -#define ffetarget_convert_real1_integer3(res,l) \ - ffetarget_convert_real1_integer1(res,l) -#define ffetarget_convert_real1_integer4(res,l) \ - ffetarget_convert_real1_integer1(res,l) -#define ffetarget_convert_real1_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real1_complex1(res,l) (*(res) = (l).real, FFEBAD) -#define ffetarget_convert_real1_complex2(res,l) \ - ffetarget_convert_real1_real2 ((res), (l).real) -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_real1_integer1(res,l) \ - ({ REAL_VALUE_TYPE resr; \ - ffetargetInteger1 lf = (l); \ - FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 1); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; }) -#else -#define ffetarget_convert_real1_integer1(res,l) (*(res) = (l), FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_real1_real2(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - ffetarget_cvt_rv_to_r1_ (lr, *(res)); \ - FFEBAD; }) -#else -#define ffetarget_convert_real1_real2(res,l) (*(res) = (l), FFEBAD) -#endif -#define ffetarget_convert_real2_character1(res,l) \ - ffetarget_convert_any_character1_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real2_hollerith(res,l) \ - ffetarget_convert_any_hollerith_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real2_integer2(res,l) \ - ffetarget_convert_real2_integer1(res,l) -#define ffetarget_convert_real2_integer3(res,l) \ - ffetarget_convert_real2_integer1(res,l) -#define ffetarget_convert_real2_integer4(res,l) \ - ffetarget_convert_real2_integer1(res,l) -#define ffetarget_convert_real2_typeless(res,l) \ - ffetarget_convert_any_typeless_ ((char *) (res), sizeof(*(res)), l) -#define ffetarget_convert_real2_complex1(res,l) \ - ffetarget_convert_real2_real1 ((res), (l).real) -#define ffetarget_convert_real2_complex2(res,l) (*(res) = (l).real, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_real2_integer(res,l) \ - ({ REAL_VALUE_TYPE resr; \ - ffetargetInteger1 lf = (l); \ - FFETARGET_REAL_VALUE_FROM_INT_ (resr, lf, 2); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; }) -#define ffetarget_convert_real2_integer1 ffetarget_convert_real2_integer -#else -#define ffetarget_convert_real2_integer1(res,l) (*(res) = (l), FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_convert_real2_real1(res,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - ffetarget_cvt_rv_to_r2_ (lr, &((res)->v[0])); \ - FFEBAD; }) -#else -#define ffetarget_convert_real2_real1(res,l) (*(res) = (l), FFEBAD) -#endif -#define ffetarget_divide_integer1(res,l,r) \ - (((r) == 0) ? (*(res) = 0, FFEBAD_DIV_BY_ZERO) \ - : (*(res) = (l) / (r), FFEBAD)) -#define ffetarget_divide_integer2(res,l,r) \ - ffetarget_divide_integer1(res,l,r) -#define ffetarget_divide_integer3(res,l,r) \ - ffetarget_divide_integer1(res,l,r) -#define ffetarget_divide_integer4(res,l,r) \ - ffetarget_divide_integer1(res,l,r) -#ifdef REAL_ARITHMETIC -#define ffetarget_divide_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - REAL_VALUES_EQUAL (rr, dconst0) \ - ? ({ ffetarget_cvt_rv_to_r1_ (dconst0, *(res)); \ - FFEBAD_DIV_BY_ZERO; \ - }) \ - : ({ REAL_ARITHMETIC (resr, RDIV_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; \ - }); \ - }) -#define ffetarget_divide_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - REAL_VALUES_EQUAL (rr, dconst0) \ - ? ({ ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->v[0])); \ - FFEBAD_DIV_BY_ZERO; \ - }) \ - : ({ REAL_ARITHMETIC (resr, RDIV_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; \ - }); \ - }) -#else -#define ffetarget_divide_real1(res,l,r) \ - (((r) == 0) ? (*(res) = 0, FFEBAD_DIV_BY_ZERO) \ - : (*(res) = (l) / (r), FFEBAD)) -#define ffetarget_divide_real2(res,l,r) \ - (((r) == 0) ? (*(res) = 0, FFEBAD_DIV_BY_ZERO) \ - : (*(res) = (l) / (r), FFEBAD)) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_eq_complex1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ - ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ - *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ - ? TRUE : FALSE; \ - FFEBAD; }) -#define ffetarget_eq_complex2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ - ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ - *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ - ? TRUE : FALSE; \ - FFEBAD; }) -#else -#define ffetarget_eq_complex1(res,l,r) \ - (*(res) = (((l).real == (r).real) && ((l).imaginary == (r).imaginary)) \ - ? TRUE : FALSE, FFEBAD) -#define ffetarget_eq_complex2(res,l,r) \ - (*(res) = (((l).real == (r).real) && ((l).imaginary == (r).imaginary)) \ - ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_eq_integer1(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_eq_integer2(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_eq_integer3(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_eq_integer4(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_eq_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = REAL_VALUES_EQUAL (lr, rr) ? TRUE : FALSE; \ - FFEBAD; }) -#define ffetarget_eq_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = REAL_VALUES_EQUAL (lr, rr) ? TRUE : FALSE; \ - FFEBAD; }) -#else -#define ffetarget_eq_real1(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_eq_real2(res,l,r) \ - (*(res) = ((l) == (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_eqv_integer1(res,l,r) (*(res) = (l) ^ ~(r), FFEBAD) -#define ffetarget_eqv_integer2(res,l,r) (*(res) = (l) ^ ~(r), FFEBAD) -#define ffetarget_eqv_integer3(res,l,r) (*(res) = (l) ^ ~(r), FFEBAD) -#define ffetarget_eqv_integer4(res,l,r) (*(res) = (l) ^ ~(r), FFEBAD) -#define ffetarget_eqv_logical1(res,l,r) (*(res) = (l) == (r), FFEBAD) -#define ffetarget_eqv_logical2(res,l,r) (*(res) = (l) == (r), FFEBAD) -#define ffetarget_eqv_logical3(res,l,r) (*(res) = (l) == (r), FFEBAD) -#define ffetarget_eqv_logical4(res,l,r) (*(res) = (l) == (r), FFEBAD) -#define ffetarget_ge_integer1(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ge_integer2(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ge_integer3(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ge_integer4(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_ge_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = REAL_VALUES_LESS (lr, rr) ? FALSE : TRUE; \ - FFEBAD; }) -#define ffetarget_ge_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = REAL_VALUES_LESS (lr, rr) ? FALSE : TRUE; \ - FFEBAD; }) -#else -#define ffetarget_ge_real1(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ge_real2(res,l,r) \ - (*(res) = ((l) >= (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_gt_integer1(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_gt_integer2(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_gt_integer3(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_gt_integer4(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_gt_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ - ? FALSE : TRUE; \ - FFEBAD; }) -#define ffetarget_gt_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ - ? FALSE : TRUE; \ - FFEBAD; }) -#else -#define ffetarget_gt_real1(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_gt_real2(res,l,r) \ - (*(res) = ((l) > (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_hexxmil(v,t) ffetarget_typeless_hex (v, t) -#define ffetarget_hexxvxt(v,t) ffetarget_typeless_hex (v, t) -#define ffetarget_hexzmil(v,t) ffetarget_typeless_hex (v, t) -#define ffetarget_hexzvxt(v,t) ffetarget_typeless_hex (v, t) -#define ffetarget_init_0() -#define ffetarget_init_1() -#define ffetarget_init_2() -#define ffetarget_init_3() -#define ffetarget_init_4() -#ifndef __alpha__ -#define ffetarget_integerdefault_is_magical(i) \ - (((unsigned long int) i) == FFETARGET_integerBIG_MAGICAL) -#else -#define ffetarget_integerdefault_is_magical(i) \ - (((unsigned int) i) == FFETARGET_integerBIG_MAGICAL) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_iszero_real1(l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - REAL_VALUES_EQUAL (lr, dconst0); \ - }) -#define ffetarget_iszero_real2(l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - REAL_VALUES_EQUAL (lr, dconst0); \ - }) -#else -#define ffetarget_iszero_real1(l) ((l) == 0.) -#define ffetarget_iszero_real2(l) ((l) == 0.) -#endif -#define ffetarget_iszero_typeless(l) ((l) == 0) -#define ffetarget_logical1(v,truth) (*(v) = truth ? 1 : 0) -#define ffetarget_le_integer1(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_le_integer2(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_le_integer3(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_le_integer4(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_le_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ - ? TRUE : FALSE; \ - FFEBAD; }) -#define ffetarget_le_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = (REAL_VALUES_LESS (lr, rr) || REAL_VALUES_EQUAL (lr, rr)) \ - ? TRUE : FALSE; \ - FFEBAD; }) -#else -#define ffetarget_le_real1(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_le_real2(res,l,r) \ - (*(res) = ((l) <= (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_lt_integer1(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_lt_integer2(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_lt_integer3(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_lt_integer4(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_lt_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = REAL_VALUES_LESS (lr, rr) ? TRUE : FALSE; \ - FFEBAD; }) -#define ffetarget_lt_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = REAL_VALUES_LESS (lr, rr) ? TRUE : FALSE; \ - FFEBAD; }) -#else -#define ffetarget_lt_real1(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_lt_real2(res,l,r) \ - (*(res) = ((l) < (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_length_character1(c) ((c).length) -#define ffetarget_length_characterdefault ffetarget_length_character1 -#ifdef REAL_ARITHMETIC -#define ffetarget_make_real1(res,lr) \ - ffetarget_cvt_rv_to_r1_ ((lr), *(res)) -#define ffetarget_make_real2(res,lr) \ - ffetarget_cvt_rv_to_r2_ ((lr), &((res)->v[0])) -#else -#define ffetarget_make_real1(res,lr) (*(res) = (lr)) -#define ffetarget_make_real2(res,lr) (*(res) = (lr)) -#endif -#define ffetarget_multiply_integer1(res,l,r) (*(res) = (l) * (r), FFEBAD) -#define ffetarget_multiply_integer2(res,l,r) (*(res) = (l) * (r), FFEBAD) -#define ffetarget_multiply_integer3(res,l,r) (*(res) = (l) * (r), FFEBAD) -#define ffetarget_multiply_integer4(res,l,r) (*(res) = (l) * (r), FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_multiply_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - REAL_ARITHMETIC (resr, MULT_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; }) -#define ffetarget_multiply_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - REAL_ARITHMETIC (resr, MULT_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; }) -#else -#define ffetarget_multiply_real1(res,l,r) (*(res) = (l) * (r), FFEBAD) -#define ffetarget_multiply_real2(res,l,r) (*(res) = (l) * (r), FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_ne_complex1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ - ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ - *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ - ? FALSE : TRUE; \ - FFEBAD; }) -#define ffetarget_ne_complex2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ - ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ - *(res) = (REAL_VALUES_EQUAL (lr, rr) && REAL_VALUES_EQUAL (li, ri)) \ - ? FALSE : TRUE; \ - FFEBAD; }) -#else -#define ffetarget_ne_complex1(res,l,r) \ - (*(res) = (((l).real != (r).real) || ((l).imaginary != (r).imaginary)) \ - ? TRUE : FALSE, FFEBAD) -#define ffetarget_ne_complex2(res,l,r) \ - (*(res) = (((l).real != (r).real) || ((l).imaginary != (r).imaginary)) \ - ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_ne_integer1(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ne_integer2(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ne_integer3(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ne_integer4(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_ne_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - *(res) = REAL_VALUES_EQUAL (lr, rr) ? FALSE : TRUE; \ - FFEBAD; }) -#define ffetarget_ne_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - *(res) = REAL_VALUES_EQUAL (lr, rr) ? FALSE : TRUE; \ - FFEBAD; }) -#else -#define ffetarget_ne_real1(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#define ffetarget_ne_real2(res,l,r) \ - (*(res) = ((l) != (r)) ? TRUE : FALSE, FFEBAD) -#endif -#define ffetarget_neqv_integer1(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_neqv_integer2(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_neqv_integer3(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_neqv_integer4(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_neqv_logical1(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_neqv_logical2(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_neqv_logical3(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_neqv_logical4(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_not_integer1(res,l) (*(res) = ~(l), FFEBAD) -#define ffetarget_not_integer2(res,l) (*(res) = ~(l), FFEBAD) -#define ffetarget_not_integer3(res,l) (*(res) = ~(l), FFEBAD) -#define ffetarget_not_integer4(res,l) (*(res) = ~(l), FFEBAD) -#define ffetarget_not_logical1(res,l) (*(res) = !(l), FFEBAD) -#define ffetarget_not_logical2(res,l) (*(res) = !(l), FFEBAD) -#define ffetarget_not_logical3(res,l) (*(res) = !(l), FFEBAD) -#define ffetarget_not_logical4(res,l) (*(res) = !(l), FFEBAD) -#define ffetarget_octalmil(v,t) ffetarget_typeless_octal (v, t) -#define ffetarget_octalvxt(v,t) ffetarget_typeless_octal (v, t) -#define ffetarget_offset(res,l) (*(res) = (l), TRUE) /* Overflow? */ -#define ffetarget_offset_add(res,l,r) (*(res) = (l) + (r), TRUE) /* Overflow? */ -#define ffetarget_offset_charsize(res,l,u) (*(res) = (l) * (u), TRUE) /* Ov? */ -#define ffetarget_offset_multiply(res,l,r) (*(res) = (l) * (r), TRUE) /* Ov? */ -#define ffetarget_offset_overflow(text) ((void) 0) /* ~~no message? */ -#define ffetarget_or_integer1(res,l,r) (*(res) = (l) | (r), FFEBAD) -#define ffetarget_or_integer2(res,l,r) (*(res) = (l) | (r), FFEBAD) -#define ffetarget_or_integer3(res,l,r) (*(res) = (l) | (r), FFEBAD) -#define ffetarget_or_integer4(res,l,r) (*(res) = (l) | (r), FFEBAD) -#define ffetarget_or_logical1(res,l,r) (*(res) = (l) || (r), FFEBAD) -#define ffetarget_or_logical2(res,l,r) (*(res) = (l) || (r), FFEBAD) -#define ffetarget_or_logical3(res,l,r) (*(res) = (l) || (r), FFEBAD) -#define ffetarget_or_logical4(res,l,r) (*(res) = (l) || (r), FFEBAD) -#define ffetarget_print_binarymil(f,v) ffetarget_print_binary (f, v) -#define ffetarget_print_binaryvxt(f,v) ffetarget_print_binary (f, v) -#define ffetarget_print_hexxmil(f,v) ffetarget_print_hex (f, v) -#define ffetarget_print_hexxvxt(f,v) ffetarget_print_hex (f, v) -#define ffetarget_print_hexzmil(f,v) ffetarget_print_hex (f, v) -#define ffetarget_print_hexzvxt(f,v) ffetarget_print_hex (f, v) -#define ffetarget_print_integer1(f,v) \ - fprintf ((f), "%" ffetargetInteger1_f "d", (v)) -#define ffetarget_print_integer2(f,v) \ - fprintf ((f), "%" ffetargetInteger2_f "d", (v)) -#define ffetarget_print_integer3(f,v) \ - fprintf ((f), "%" ffetargetInteger3_f "d", (v)) -#define ffetarget_print_integer4(f,v) \ - fprintf ((f), "%" ffetargetInteger4_f "d", (v)) -#define ffetarget_print_logical1(f,v) \ - fprintf ((f), "%" ffetargetLogical1_f "d", (v)) -#define ffetarget_print_logical2(f,v) \ - fprintf ((f), "%" ffetargetLogical2_f "d", (v)) -#define ffetarget_print_logical3(f,v) \ - fprintf ((f), "%" ffetargetLogical3_f "d", (v)) -#define ffetarget_print_logical4(f,v) \ - fprintf ((f), "%" ffetargetLogical4_f "d", (v)) -#define ffetarget_print_octalmil(f,v) ffetarget_print_octal(f,v) -#define ffetarget_print_octalvxt(f,v) ffetarget_print_octal(f,v) -#ifdef REAL_ARITHMETIC -#define ffetarget_print_real1(f,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - REAL_VALUE_TO_DECIMAL (lr, bad_fmt_val??, ffetarget_string_); \ - fputs (ffetarget_string_, (f)); \ - }) -#define ffetarget_print_real2(f,l) \ - ({ REAL_VALUE_TYPE lr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - REAL_VALUE_TO_DECIMAL (lr, bad_fmt_val??, ffetarget_string_); \ - fputs (ffetarget_string_, (f)); \ - }) -#else -#define ffetarget_print_real1(f,v) \ - fprintf ((f), "%" ffetargetReal1_f "g", (v)) -#define ffetarget_print_real2(f,v) \ - fprintf ((f), "%" ffetargetReal2_f "g", (v)) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_real1_one(res) ffetarget_cvt_rv_to_r1_ (dconst1, *(res)) -#define ffetarget_real2_one(res) ffetarget_cvt_rv_to_r2_ (dconst1, &((res)->v[0])) -#else -#define ffetarget_real1_one(res) (*(res) = (float) 1.) -#define ffetarget_real2_one(res) (*(res) = 1.) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_real1_two(res) ffetarget_cvt_rv_to_r1_ (dconst2, *(res)) -#define ffetarget_real2_two(res) ffetarget_cvt_rv_to_r2_ (dconst2, &((res)->v[0])) -#else -#define ffetarget_real1_two(res) (*(res) = (float) 2.) -#define ffetarget_real2_two(res) (*(res) = 2.) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_real1_zero(res) ffetarget_cvt_rv_to_r1_ (dconst0, *(res)) -#define ffetarget_real2_zero(res) ffetarget_cvt_rv_to_r2_ (dconst0, &((res)->v[0])) -#else -#define ffetarget_real1_zero(res) (*(res) = (float) 0.) -#define ffetarget_real2_zero(res) (*(res) = 0.) -#endif -#define ffetarget_size_typeless_binary(t) ((ffetarget_num_digits_(t) + 7) / 8) -#define ffetarget_size_typeless_octal(t) \ - ((ffetarget_num_digits_(t) * 3 + 7) / 8) -#define ffetarget_size_typeless_hex(t) ((ffetarget_num_digits_(t) + 1) / 2) -#ifdef REAL_ARITHMETIC -#define ffetarget_subtract_complex1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - rr = ffetarget_cvt_r1_to_rv_ ((r).real); \ - ri = ffetarget_cvt_r1_to_rv_ ((r).imaginary); \ - REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - REAL_ARITHMETIC (resi, MINUS_EXPR, li, ri); \ - ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ - FFEBAD; }) -#define ffetarget_subtract_complex2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, li, rr, ri, resr, resi; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).real.v[0])); \ - ri = ffetarget_cvt_r2_to_rv_ (&((r).imaginary.v[0])); \ - REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - REAL_ARITHMETIC (resi, MINUS_EXPR, li, ri); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ - FFEBAD; }) -#else -#define ffetarget_subtract_complex1(res,l,r) \ - ((res)->real = (l).real - (r).real, \ - (res)->imaginary = (l).imaginary - (r).imaginary, FFEBAD) -#define ffetarget_subtract_complex2(res,l,r) \ - ((res)->real = (l).real - (r).real, \ - (res)->imaginary = (l).imaginary - (r).imaginary, FFEBAD) -#endif -#define ffetarget_subtract_integer1(res,l,r) (*(res) = (l) - (r), FFEBAD) -#define ffetarget_subtract_integer2(res,l,r) (*(res) = (l) - (r), FFEBAD) -#define ffetarget_subtract_integer3(res,l,r) (*(res) = (l) - (r), FFEBAD) -#define ffetarget_subtract_integer4(res,l,r) (*(res) = (l) - (r), FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_subtract_real1(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - rr = ffetarget_cvt_r1_to_rv_ ((r)); \ - REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; }) -#define ffetarget_subtract_real2(res,l,r) \ - ({ REAL_VALUE_TYPE lr, rr, resr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - rr = ffetarget_cvt_r2_to_rv_ (&((r).v[0])); \ - REAL_ARITHMETIC (resr, MINUS_EXPR, lr, rr); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; }) -#else -#define ffetarget_subtract_real1(res,l,r) (*(res) = (l) - (r), FFEBAD) -#define ffetarget_subtract_real2(res,l,r) (*(res) = (l) - (r), FFEBAD) -#endif -#define ffetarget_terminate_0() -#define ffetarget_terminate_1() -#define ffetarget_terminate_2() -#define ffetarget_terminate_3() -#define ffetarget_terminate_4() -#define ffetarget_text_character1(c) ((c).text) -#define ffetarget_text_characterdefault ffetarget_text_character1 -#ifdef REAL_ARITHMETIC -#define ffetarget_uminus_complex1(res,l) \ - ({ REAL_VALUE_TYPE lr, li, resr, resi; \ - lr = ffetarget_cvt_r1_to_rv_ ((l).real); \ - li = ffetarget_cvt_r1_to_rv_ ((l).imaginary); \ - resr = REAL_VALUE_NEGATE (lr); \ - resi = REAL_VALUE_NEGATE (li); \ - ffetarget_cvt_rv_to_r1_ (resr, (res)->real); \ - ffetarget_cvt_rv_to_r1_ (resi, (res)->imaginary); \ - FFEBAD; }) -#define ffetarget_uminus_complex2(res,l) \ - ({ REAL_VALUE_TYPE lr, li, resr, resi; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).real.v[0])); \ - li = ffetarget_cvt_r2_to_rv_ (&((l).imaginary.v[0])); \ - resr = REAL_VALUE_NEGATE (lr); \ - resi = REAL_VALUE_NEGATE (li); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->real.v[0])); \ - ffetarget_cvt_rv_to_r2_ (resi, &((res)->imaginary.v[0])); \ - FFEBAD; }) -#else -#define ffetarget_uminus_complex1(res,l) \ - ((res)->real = -(l).real, (res)->imaginary = -(l).imaginary, FFEBAD) -#define ffetarget_uminus_complex2(res,l) \ - ((res)->real = -(l).real, (res)->imaginary = -(l).imaginary, FFEBAD) -#endif -#define ffetarget_uminus_integer1(res,l) (*(res) = -(l), FFEBAD) -#define ffetarget_uminus_integer2(res,l) (*(res) = -(l), FFEBAD) -#define ffetarget_uminus_integer3(res,l) (*(res) = -(l), FFEBAD) -#define ffetarget_uminus_integer4(res,l) (*(res) = -(l), FFEBAD) -#ifdef REAL_ARITHMETIC -#define ffetarget_uminus_real1(res,l) \ - ({ REAL_VALUE_TYPE lr, resr; \ - lr = ffetarget_cvt_r1_to_rv_ ((l)); \ - resr = REAL_VALUE_NEGATE (lr); \ - ffetarget_cvt_rv_to_r1_ (resr, *(res)); \ - FFEBAD; }) -#define ffetarget_uminus_real2(res,l) \ - ({ REAL_VALUE_TYPE lr, resr; \ - lr = ffetarget_cvt_r2_to_rv_ (&((l).v[0])); \ - resr = REAL_VALUE_NEGATE (lr); \ - ffetarget_cvt_rv_to_r2_ (resr, &((res)->v[0])); \ - FFEBAD; }) -#else -#define ffetarget_uminus_real1(res,l) (*(res) = -(l), FFEBAD) -#define ffetarget_uminus_real2(res,l) (*(res) = -(l), FFEBAD) -#endif -#ifdef REAL_ARITHMETIC -#define ffetarget_value_real1(lr) ffetarget_cvt_r1_to_rv_ ((lr)) -#define ffetarget_value_real2(lr) ffetarget_cvt_r2_to_rv_ (&((lr).v[0])) -#else -#define ffetarget_value_real1 -#define ffetarget_value_real2 -#endif -#define ffetarget_xor_integer1(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_xor_integer2(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_xor_integer3(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_xor_integer4(res,l,r) (*(res) = (l) ^ (r), FFEBAD) -#define ffetarget_xor_logical1(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_xor_logical2(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_xor_logical3(res,l,r) (*(res) = (l) != (r), FFEBAD) -#define ffetarget_xor_logical4(res,l,r) (*(res) = (l) != (r), FFEBAD) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/tconfig.j b/gcc/f/tconfig.j deleted file mode 100755 index 4135291..0000000 --- a/gcc/f/tconfig.j +++ /dev/null @@ -1,27 +0,0 @@ -/* tconfig.j -- Wrapper for GCC's tconfig.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_tconfig -#define _J_f_tconfig -#include "tconfig.h" -#endif -#endif diff --git a/gcc/f/tm.j b/gcc/f/tm.j deleted file mode 100755 index 443fd53..0000000 --- a/gcc/f/tm.j +++ /dev/null @@ -1,27 +0,0 @@ -/* tm.j -- Wrapper for GCC's tm.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_tm -#define _J_f_tm -#include "tm.h" -#endif -#endif diff --git a/gcc/f/top.c b/gcc/f/top.c deleted file mode 100755 index fe5bc40..0000000 --- a/gcc/f/top.c +++ /dev/null @@ -1,922 +0,0 @@ -/* top.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - None. - - Description: - The GNU Fortran Front End. - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "top.h" -#include "bad.h" -#include "bit.h" -#include "bld.h" -#include "com.h" -#include "data.h" -#include "equiv.h" -#include "expr.h" -#include "global.h" -#include "implic.h" -#include "info.h" -#include "intrin.h" -#include "lab.h" -#include "lex.h" -#include "malloc.h" -#include "name.h" -#include "src.h" -#include "st.h" -#include "storag.h" -#include "symbol.h" -#include "target.h" -#include "where.h" -#if FFECOM_targetCURRENT == FFECOM_targetGCC -#include "flags.j" -#include "toplev.j" -#endif - -/* Externals defined here. */ - -int flag_traditional; /* Shouldn't need this (C front end only)! */ -bool ffe_is_do_internal_checks_ = FALSE; -bool ffe_is_90_ = FFETARGET_defaultIS_90; -bool ffe_is_automatic_ = FFETARGET_defaultIS_AUTOMATIC; -bool ffe_is_backslash_ = FFETARGET_defaultIS_BACKSLASH; -bool ffe_is_emulate_complex_ = TRUE; -bool ffe_is_underscoring_ = FFETARGET_defaultEXTERNAL_UNDERSCORED - || FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED; -bool ffe_is_second_underscore_ = FFETARGET_defaultUNDERSCORED_EXTERNAL_UNDERSCORED; -bool ffe_is_debug_kludge_ = FALSE; -bool ffe_is_dollar_ok_ = FFETARGET_defaultIS_DOLLAR_OK; -bool ffe_is_f2c_ = FFETARGET_defaultIS_F2C; -bool ffe_is_f2c_library_ = FFETARGET_defaultIS_F2C_LIBRARY; -bool ffe_is_ffedebug_ = FALSE; -bool ffe_is_free_form_ = FFETARGET_defaultIS_FREE_FORM; -bool ffe_is_globals_ = TRUE; -bool ffe_is_ident_ = TRUE; -bool ffe_is_init_local_zero_ = FFETARGET_defaultIS_INIT_LOCAL_ZERO; -bool ffe_is_mainprog_; /* TRUE if current prog unit known to be - main. */ -bool ffe_is_null_version_ = FALSE; -bool ffe_is_onetrip_ = FALSE; -bool ffe_is_silent_ = TRUE; -bool ffe_is_typeless_boz_ = FALSE; -bool ffe_is_pedantic_ = FFETARGET_defaultIS_PEDANTIC; -bool ffe_is_saveall_; /* TRUE if mainprog or SAVE (no args) seen. */ -bool ffe_is_ugly_args_ = TRUE; -bool ffe_is_ugly_assign_ = FALSE; /* Try and store pointer to ASSIGN labels in INTEGER vars. */ -bool ffe_is_ugly_assumed_ = FALSE; /* DIMENSION X([...,]1) => DIMENSION X([...,]*) */ -bool ffe_is_ugly_comma_ = FALSE; -bool ffe_is_ugly_complex_ = FALSE; -bool ffe_is_ugly_init_ = TRUE; -bool ffe_is_ugly_logint_ = FALSE; -bool ffe_is_version_ = FALSE; -bool ffe_is_vxt_ = FALSE; -bool ffe_is_warn_globals_ = TRUE; -bool ffe_is_warn_implicit_ = FALSE; -bool ffe_is_warn_surprising_ = FALSE; -bool ffe_is_zeros_ = FALSE; -ffeCase ffe_case_intrin_ = FFETARGET_defaultCASE_INTRIN; -ffeCase ffe_case_match_ = FFETARGET_defaultCASE_MATCH; -ffeCase ffe_case_source_ = FFETARGET_defaultCASE_SOURCE; -ffeCase ffe_case_symbol_ = FFETARGET_defaultCASE_SYMBOL; -ffeIntrinsicState ffe_intrinsic_state_badu77_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_gnu_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_f2c_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_f90_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_mil_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_unix_ = FFE_intrinsicstateENABLED; -ffeIntrinsicState ffe_intrinsic_state_vxt_ = FFE_intrinsicstateENABLED; -int ffe_fixed_line_length_ = FFETARGET_defaultFIXED_LINE_LENGTH; -mallocPool ffe_file_pool_ = NULL; -mallocPool ffe_any_unit_pool_ = NULL; -mallocPool ffe_program_unit_pool_ = NULL; -ffeCounter ffe_count_0 = 0; -ffeCounter ffe_count_1 = 0; -ffeCounter ffe_count_2 = 0; -ffeCounter ffe_count_3 = 0; -ffeCounter ffe_count_4 = 0; -bool ffe_in_0 = FALSE; -bool ffe_in_1 = FALSE; -bool ffe_in_2 = FALSE; -bool ffe_in_3 = FALSE; -bool ffe_in_4 = FALSE; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - - -/* Private include files. */ - - -/* Internal structure definitions. */ - - -/* Static objects accessed by functions in this module. */ - - -/* Static functions (internal). */ - -static bool ffe_is_digit_string_ (char *s); - -/* Internal macros. */ - -static bool -ffe_is_digit_string_ (char *s) -{ - char *p; - - for (p = s; ISDIGIT (*p); ++p) - ; - - return (p != s) && (*p == '\0'); -} - -/* Handle command-line options. Returns 0 if unrecognized, 1 if - recognized and handled. */ - -int -ffe_decode_option (argc, argv) - int argc ATTRIBUTE_UNUSED; - char **argv; -{ - char *opt = argv[0]; - if (opt[0] != '-') - return 0; - if (opt[1] == 'f') - { - if (strcmp (&opt[2], "version") == 0) - { - ffe_set_is_version (TRUE); - ffe_set_is_do_internal_checks (TRUE); - } - else if (strcmp (&opt[2], "null-version") == 0) - ffe_set_is_null_version (TRUE); - else if (strcmp (&opt[2], "ident") == 0) - ffe_set_is_ident (TRUE); - else if (strcmp (&opt[2], "no-ident") == 0) - ffe_set_is_ident (FALSE); - else if (strcmp (&opt[2], "f66") == 0) - { - ffe_set_is_onetrip (TRUE); - ffe_set_is_ugly_assumed (TRUE); - } - else if (strcmp (&opt[2], "no-f66") == 0) - { - ffe_set_is_onetrip (FALSE); - ffe_set_is_ugly_assumed (FALSE); - } - else if (strcmp (&opt[2], "f77") == 0) - { - ffe_set_is_backslash (TRUE); - ffe_set_is_typeless_boz (FALSE); - } - else if (strcmp (&opt[2], "no-f77") == 0) - { - ffe_set_is_backslash (FALSE); - } - else if (strcmp (&opt[2], "f90") == 0) - ffe_set_is_90 (TRUE); - else if (strcmp (&opt[2], "no-f90") == 0) - ffe_set_is_90 (FALSE); - else if (strcmp (&opt[2], "automatic") == 0) - ffe_set_is_automatic (TRUE); - else if (strcmp (&opt[2], "no-automatic") == 0) - ffe_set_is_automatic (FALSE); - else if (strcmp (&opt[2], "dollar-ok") == 0) - ffe_set_is_dollar_ok (TRUE); - else if (strcmp (&opt[2], "no-dollar-ok") == 0) - ffe_set_is_dollar_ok (FALSE); - else if (strcmp (&opt[2], "f2c") == 0) - ffe_set_is_f2c (TRUE); - else if (strcmp (&opt[2], "no-f2c") == 0) - ffe_set_is_f2c (FALSE); - else if (strcmp (&opt[2], "f2c-library") == 0) - ffe_set_is_f2c_library (TRUE); - else if (strcmp (&opt[2], "no-f2c-library") == 0) - ffe_set_is_f2c_library (FALSE); - else if (strcmp (&opt[2], "free-form") == 0) - ffe_set_is_free_form (TRUE); - else if (strcmp (&opt[2], "no-free-form") == 0) - ffe_set_is_free_form (FALSE); - else if (strcmp (&opt[2], "fixed-form") == 0) - ffe_set_is_free_form (FALSE); - else if (strcmp (&opt[2], "no-fixed-form") == 0) - ffe_set_is_free_form (TRUE); - else if (strcmp (&opt[2], "pedantic") == 0) - ffe_set_is_pedantic (TRUE); - else if (strcmp (&opt[2], "no-pedantic") == 0) - ffe_set_is_pedantic (FALSE); - else if (strcmp (&opt[2], "vxt") == 0) - ffe_set_is_vxt (TRUE); - else if (strcmp (&opt[2], "not-vxt") == 0) - ffe_set_is_vxt (FALSE); - else if (strcmp (&opt[2], "vxt-not-f90") == 0) - warning ("%s no longer supported -- try -fvxt", opt); - else if (strcmp (&opt[2], "f90-not-vxt") == 0) - warning ("%s no longer supported -- try -fno-vxt -ff90", opt); - else if (strcmp (&opt[2], "ugly") == 0) - { - warning ("%s is overloaded with meanings and likely to be removed;", opt); - warning ("use only the specific -fugly-* options you need"); - ffe_set_is_ugly_args (TRUE); - ffe_set_is_ugly_assign (TRUE); - ffe_set_is_ugly_assumed (TRUE); - ffe_set_is_ugly_comma (TRUE); - ffe_set_is_ugly_complex (TRUE); - ffe_set_is_ugly_init (TRUE); - ffe_set_is_ugly_logint (TRUE); - } - else if (strcmp (&opt[2], "no-ugly") == 0) - { - ffe_set_is_ugly_args (FALSE); - ffe_set_is_ugly_assign (FALSE); - ffe_set_is_ugly_assumed (FALSE); - ffe_set_is_ugly_comma (FALSE); - ffe_set_is_ugly_complex (FALSE); - ffe_set_is_ugly_init (FALSE); - ffe_set_is_ugly_logint (FALSE); - } - else if (strcmp (&opt[2], "ugly-args") == 0) - ffe_set_is_ugly_args (TRUE); - else if (strcmp (&opt[2], "no-ugly-args") == 0) - ffe_set_is_ugly_args (FALSE); - else if (strcmp (&opt[2], "ugly-assign") == 0) - ffe_set_is_ugly_assign (TRUE); - else if (strcmp (&opt[2], "no-ugly-assign") == 0) - ffe_set_is_ugly_assign (FALSE); - else if (strcmp (&opt[2], "ugly-assumed") == 0) - ffe_set_is_ugly_assumed (TRUE); - else if (strcmp (&opt[2], "no-ugly-assumed") == 0) - ffe_set_is_ugly_assumed (FALSE); - else if (strcmp (&opt[2], "ugly-comma") == 0) - ffe_set_is_ugly_comma (TRUE); - else if (strcmp (&opt[2], "no-ugly-comma") == 0) - ffe_set_is_ugly_comma (FALSE); - else if (strcmp (&opt[2], "ugly-complex") == 0) - ffe_set_is_ugly_complex (TRUE); - else if (strcmp (&opt[2], "no-ugly-complex") == 0) - ffe_set_is_ugly_complex (FALSE); - else if (strcmp (&opt[2], "ugly-init") == 0) - ffe_set_is_ugly_init (TRUE); - else if (strcmp (&opt[2], "no-ugly-init") == 0) - ffe_set_is_ugly_init (FALSE); - else if (strcmp (&opt[2], "ugly-logint") == 0) - ffe_set_is_ugly_logint (TRUE); - else if (strcmp (&opt[2], "no-ugly-logint") == 0) - ffe_set_is_ugly_logint (FALSE); - else if (strcmp (&opt[2], "xyzzy") == 0) - ffe_set_is_ffedebug (TRUE); - else if (strcmp (&opt[2], "no-xyzzy") == 0) - ffe_set_is_ffedebug (FALSE); - else if (strcmp (&opt[2], "init-local-zero") == 0) - ffe_set_is_init_local_zero (TRUE); - else if (strcmp (&opt[2], "no-init-local-zero") == 0) - ffe_set_is_init_local_zero (FALSE); - else if (strcmp (&opt[2], "emulate-complex") == 0) - ffe_set_is_emulate_complex (TRUE); - else if (strcmp (&opt[2], "no-emulate-complex") == 0) - ffe_set_is_emulate_complex (FALSE); - else if (strcmp (&opt[2], "backslash") == 0) - ffe_set_is_backslash (TRUE); - else if (strcmp (&opt[2], "no-backslash") == 0) - ffe_set_is_backslash (FALSE); - else if (strcmp (&opt[2], "underscoring") == 0) - ffe_set_is_underscoring (TRUE); - else if (strcmp (&opt[2], "no-underscoring") == 0) - ffe_set_is_underscoring (FALSE); - else if (strcmp (&opt[2], "second-underscore") == 0) - ffe_set_is_second_underscore (TRUE); - else if (strcmp (&opt[2], "no-second-underscore") == 0) - ffe_set_is_second_underscore (FALSE); - else if (strcmp (&opt[2], "zeros") == 0) - ffe_set_is_zeros (TRUE); - else if (strcmp (&opt[2], "no-zeros") == 0) - ffe_set_is_zeros (FALSE); - else if (strcmp (&opt[2], "debug-kludge") == 0) - ffe_set_is_debug_kludge (TRUE); - else if (strcmp (&opt[2], "no-debug-kludge") == 0) - ffe_set_is_debug_kludge (FALSE); - else if (strcmp (&opt[2], "onetrip") == 0) - ffe_set_is_onetrip (TRUE); - else if (strcmp (&opt[2], "no-onetrip") == 0) - ffe_set_is_onetrip (FALSE); - else if (strcmp (&opt[2], "silent") == 0) - ffe_set_is_silent (TRUE); - else if (strcmp (&opt[2], "no-silent") == 0) - ffe_set_is_silent (FALSE); - else if (strcmp (&opt[2], "globals") == 0) - ffe_set_is_globals (TRUE); - else if (strcmp (&opt[2], "no-globals") == 0) - ffe_set_is_globals (FALSE); - else if (strcmp (&opt[2], "typeless-boz") == 0) - ffe_set_is_typeless_boz (TRUE); - else if (strcmp (&opt[2], "no-typeless-boz") == 0) - ffe_set_is_typeless_boz (FALSE); - else if (strcmp (&opt[2], "intrin-case-initcap") == 0) - ffe_set_case_intrin (FFE_caseINITCAP); - else if (strcmp (&opt[2], "intrin-case-upper") == 0) - ffe_set_case_intrin (FFE_caseUPPER); - else if (strcmp (&opt[2], "intrin-case-lower") == 0) - ffe_set_case_intrin (FFE_caseLOWER); - else if (strcmp (&opt[2], "intrin-case-any") == 0) - ffe_set_case_intrin (FFE_caseNONE); - else if (strcmp (&opt[2], "match-case-initcap") == 0) - ffe_set_case_match (FFE_caseINITCAP); - else if (strcmp (&opt[2], "match-case-upper") == 0) - ffe_set_case_match (FFE_caseUPPER); - else if (strcmp (&opt[2], "match-case-lower") == 0) - ffe_set_case_match (FFE_caseLOWER); - else if (strcmp (&opt[2], "match-case-any") == 0) - ffe_set_case_match (FFE_caseNONE); - else if (strcmp (&opt[2], "source-case-upper") == 0) - ffe_set_case_source (FFE_caseUPPER); - else if (strcmp (&opt[2], "source-case-lower") == 0) - ffe_set_case_source (FFE_caseLOWER); - else if (strcmp (&opt[2], "source-case-preserve") == 0) - ffe_set_case_source (FFE_caseNONE); - else if (strcmp (&opt[2], "symbol-case-initcap") == 0) - ffe_set_case_symbol (FFE_caseINITCAP); - else if (strcmp (&opt[2], "symbol-case-upper") == 0) - ffe_set_case_symbol (FFE_caseUPPER); - else if (strcmp (&opt[2], "symbol-case-lower") == 0) - ffe_set_case_symbol (FFE_caseLOWER); - else if (strcmp (&opt[2], "symbol-case-any") == 0) - ffe_set_case_symbol (FFE_caseNONE); - else if (strcmp (&opt[2], "case-strict-upper") == 0) - { - ffe_set_case_intrin (FFE_caseUPPER); - ffe_set_case_match (FFE_caseUPPER); - ffe_set_case_source (FFE_caseNONE); - ffe_set_case_symbol (FFE_caseUPPER); - } - else if (strcmp (&opt[2], "case-strict-lower") == 0) - { - ffe_set_case_intrin (FFE_caseLOWER); - ffe_set_case_match (FFE_caseLOWER); - ffe_set_case_source (FFE_caseNONE); - ffe_set_case_symbol (FFE_caseLOWER); - } - else if (strcmp (&opt[2], "case-initcap") == 0) - { - ffe_set_case_intrin (FFE_caseINITCAP); - ffe_set_case_match (FFE_caseINITCAP); - ffe_set_case_source (FFE_caseNONE); - ffe_set_case_symbol (FFE_caseINITCAP); - } - else if (strcmp (&opt[2], "case-upper") == 0) - { - ffe_set_case_intrin (FFE_caseNONE); - ffe_set_case_match (FFE_caseNONE); - ffe_set_case_source (FFE_caseUPPER); - ffe_set_case_symbol (FFE_caseNONE); - } - else if (strcmp (&opt[2], "case-lower") == 0) - { - ffe_set_case_intrin (FFE_caseNONE); - ffe_set_case_match (FFE_caseNONE); - ffe_set_case_source (FFE_caseLOWER); - ffe_set_case_symbol (FFE_caseNONE); - } - else if (strcmp (&opt[2], "case-preserve") == 0) - { - ffe_set_case_intrin (FFE_caseNONE); - ffe_set_case_match (FFE_caseNONE); - ffe_set_case_source (FFE_caseNONE); - ffe_set_case_symbol (FFE_caseNONE); - } - else if (strcmp (&opt[2], "badu77-intrinsics-delete") == 0) - ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "badu77-intrinsics-hide") == 0) - ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "badu77-intrinsics-disable") == 0) - ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "badu77-intrinsics-enable") == 0) - ffe_set_intrinsic_state_badu77 (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "gnu-intrinsics-delete") == 0) - ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "gnu-intrinsics-hide") == 0) - ffe_set_intrinsic_state_gnu (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "gnu-intrinsics-disable") == 0) - ffe_set_intrinsic_state_gnu (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "gnu-intrinsics-enable") == 0) - ffe_set_intrinsic_state_gnu (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "f2c-intrinsics-delete") == 0) - ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "f2c-intrinsics-hide") == 0) - ffe_set_intrinsic_state_f2c (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "f2c-intrinsics-disable") == 0) - ffe_set_intrinsic_state_f2c (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "f2c-intrinsics-enable") == 0) - ffe_set_intrinsic_state_f2c (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "f90-intrinsics-delete") == 0) - ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "f90-intrinsics-hide") == 0) - ffe_set_intrinsic_state_f90 (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "f90-intrinsics-disable") == 0) - ffe_set_intrinsic_state_f90 (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "f90-intrinsics-enable") == 0) - ffe_set_intrinsic_state_f90 (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "mil-intrinsics-delete") == 0) - ffe_set_intrinsic_state_mil (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "mil-intrinsics-hide") == 0) - ffe_set_intrinsic_state_mil (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "mil-intrinsics-disable") == 0) - ffe_set_intrinsic_state_mil (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "mil-intrinsics-enable") == 0) - ffe_set_intrinsic_state_mil (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "unix-intrinsics-delete") == 0) - ffe_set_intrinsic_state_unix (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "unix-intrinsics-hide") == 0) - ffe_set_intrinsic_state_unix (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "unix-intrinsics-disable") == 0) - ffe_set_intrinsic_state_unix (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "unix-intrinsics-enable") == 0) - ffe_set_intrinsic_state_unix (FFE_intrinsicstateENABLED); - else if (strcmp (&opt[2], "vxt-intrinsics-delete") == 0) - ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDELETED); - else if (strcmp (&opt[2], "vxt-intrinsics-hide") == 0) - ffe_set_intrinsic_state_vxt (FFE_intrinsicstateHIDDEN); - else if (strcmp (&opt[2], "vxt-intrinsics-disable") == 0) - ffe_set_intrinsic_state_vxt (FFE_intrinsicstateDISABLED); - else if (strcmp (&opt[2], "vxt-intrinsics-enable") == 0) - ffe_set_intrinsic_state_vxt (FFE_intrinsicstateENABLED); - else if (strncmp (&opt[2], "fixed-line-length-", - strlen ("fixed-line-length-")) == 0) - { - char *len = &opt[2] + strlen ("fixed-line-length-"); - - if (strcmp (len, "none") == 0) - ffe_set_fixed_line_length (0); - else if (ffe_is_digit_string_ (len)) - ffe_set_fixed_line_length (atol (len)); - else - return 0; - } - else - return 0; - } - else if (opt[1] == 'W') - { - if (!strcmp (&opt[2], "comment")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "no-comment")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "comments")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "no-comments")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "no-trigraphs")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "import")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "no-import")) - ; /* cpp handles this one. */ - else if (!strcmp (&opt[2], "globals")) - ffe_set_is_warn_globals (TRUE); - else if (!strcmp (&opt[2], "no-globals")) - ffe_set_is_warn_globals (FALSE); - else if (!strcmp (&opt[2], "implicit")) - ffe_set_is_warn_implicit (TRUE); - else if (!strcmp (&opt[2], "no-implicit")) - ffe_set_is_warn_implicit (FALSE); - else if (!strcmp (&opt[2], "surprising")) - ffe_set_is_warn_surprising (TRUE); - else if (!strcmp (&opt[2], "no-surprising")) - ffe_set_is_warn_surprising (FALSE); - else if (!strcmp (&opt[2], "all")) - { - /* We save the value of warn_uninitialized, since if they put - -Wuninitialized on the command line, we need to generate a - warning about not using it without also specifying -O. */ - if (warn_uninitialized != 1) - warn_uninitialized = 2; - warn_unused = 1; - } - else - return 0; - } - else if (opt[1] == 'I') - return ffecom_decode_include_option (&opt[2]); - else - return 0; - - return 1; -} - -/* Run the FFE on a source file (not an INCLUDEd file). - - Runs the whole shebang. - - Prepare and invoke the appropriate lexer. */ - -void -ffe_file (ffewhereFile wf, FILE *f) -{ - ffe_init_1 (); - ffelex_set_handler ((ffelexHandler) ffest_first); - ffewhere_file_set (wf, TRUE, 0); - if (ffe_is_free_form_) - ffelex_file_free (wf, f); - else - ffelex_file_fixed (wf, f); - ffest_eof (); - ffe_terminate_1 (); -} - -/* ffe_init_0 -- Initialize the FFE per image invocation - - ffe_init_0(); - - Performs per-image invocation. */ - -void -ffe_init_0 () -{ - ++ffe_count_0; - ffe_in_0 = TRUE; - - ffebad_init_0 (); - ffebit_init_0 (); - ffebld_init_0 (); - ffecom_init_0 (); - ffedata_init_0 (); - ffeequiv_init_0 (); - ffeexpr_init_0 (); - ffeglobal_init_0 (); - ffeimplic_init_0 (); - ffeinfo_init_0 (); - ffeintrin_init_0 (); - ffelab_init_0 (); - ffelex_init_0 (); - ffename_init_0 (); - ffesrc_init_0 (); - ffest_init_0 (); - ffestorag_init_0 (); - ffesymbol_init_0 (); - ffetarget_init_0 (); - ffetype_init_0 (); - ffewhere_init_0 (); -} - -/* ffe_init_1 -- Initialize the FFE per source file - - ffe_init_1(); - - Performs per-source-file invocation (not including INCLUDEd files). */ - -void -ffe_init_1 () -{ - ++ffe_count_1; - ffe_in_1 = TRUE; - - assert (ffe_file_pool_ == NULL); - ffe_file_pool_ = malloc_pool_new ("File", malloc_pool_image (), 1024); - - ffebad_init_1 (); - ffebit_init_1 (); - ffebld_init_1 (); - ffecom_init_1 (); - ffedata_init_1 (); - ffeequiv_init_1 (); - ffeexpr_init_1 (); - ffeglobal_init_1 (); - ffeimplic_init_1 (); - ffeinfo_init_1 (); - ffeintrin_init_1 (); - ffelab_init_1 (); - ffelex_init_1 (); - ffename_init_1 (); - ffesrc_init_1 (); - ffest_init_1 (); - ffestorag_init_1 (); - ffesymbol_init_1 (); - ffetarget_init_1 (); - ffetype_init_1 (); - ffewhere_init_1 (); - - ffe_init_2 (); -} - -/* ffe_init_2 -- Initialize the FFE per outer program unit - - ffe_init_2(); - - Performs per-program-unit invocation. */ - -void -ffe_init_2 () -{ - ++ffe_count_2; - ffe_in_2 = TRUE; - - assert (ffe_program_unit_pool_ == NULL); - ffe_program_unit_pool_ = malloc_pool_new ("Program unit", ffe_file_pool_, 1024); - ffe_is_mainprog_ = FALSE; - ffe_is_saveall_ = !ffe_is_automatic_; - - ffebad_init_2 (); - ffebit_init_2 (); - ffebld_init_2 (); - ffecom_init_2 (); - ffedata_init_2 (); - ffeequiv_init_2 (); - ffeexpr_init_2 (); - ffeglobal_init_2 (); - ffeimplic_init_2 (); - ffeinfo_init_2 (); - ffeintrin_init_2 (); - ffelab_init_2 (); - ffelex_init_2 (); - ffename_init_2 (); - ffesrc_init_2 (); - ffest_init_2 (); - ffestorag_init_2 (); - ffesymbol_init_2 (); - ffetarget_init_2 (); - ffetype_init_2 (); - ffewhere_init_2 (); - - ffe_init_3 (); -} - -/* ffe_init_3 -- Initialize the FFE per any program unit - - ffe_init_3(); - - Performs per-any-unit initialization; does NOT do - per-statement-function-definition initialization (i.e. the chain - of inits, from 0-3, breaks here; level 4 must be invoked independently). */ - -void -ffe_init_3 () -{ - ++ffe_count_3; - ffe_in_3 = TRUE; - - assert (ffe_any_unit_pool_ == NULL); - ffe_any_unit_pool_ = malloc_pool_new ("Any unit", ffe_program_unit_pool_, 1024); - - ffebad_init_3 (); - ffebit_init_3 (); - ffebld_init_3 (); - ffecom_init_3 (); - ffedata_init_3 (); - ffeequiv_init_3 (); - ffeexpr_init_3 (); - ffeglobal_init_3 (); - ffeimplic_init_3 (); - ffeinfo_init_3 (); - ffeintrin_init_3 (); - ffelab_init_3 (); - ffelex_init_3 (); - ffename_init_3 (); - ffesrc_init_3 (); - ffest_init_3 (); - ffestorag_init_3 (); - ffesymbol_init_3 (); - ffetarget_init_3 (); - ffetype_init_3 (); - ffewhere_init_3 (); -} - -/* ffe_init_4 -- Initialize the FFE per statement function definition - - ffe_init_4(); */ - -void -ffe_init_4 () -{ - ++ffe_count_4; - ffe_in_4 = TRUE; - - ffebad_init_4 (); - ffebit_init_4 (); - ffebld_init_4 (); - ffecom_init_4 (); - ffedata_init_4 (); - ffeequiv_init_4 (); - ffeexpr_init_4 (); - ffeglobal_init_4 (); - ffeimplic_init_4 (); - ffeinfo_init_4 (); - ffeintrin_init_4 (); - ffelab_init_4 (); - ffelex_init_4 (); - ffename_init_4 (); - ffesrc_init_4 (); - ffest_init_4 (); - ffestorag_init_4 (); - ffesymbol_init_4 (); - ffetarget_init_4 (); - ffetype_init_4 (); - ffewhere_init_4 (); -} - -/* ffe_terminate_0 -- Terminate the FFE prior to image termination - - ffe_terminate_0(); */ - -void -ffe_terminate_0 () -{ - ffe_count_1 = 0; - ffe_in_0 = FALSE; - - ffebad_terminate_0 (); - ffebit_terminate_0 (); - ffebld_terminate_0 (); - ffecom_terminate_0 (); - ffedata_terminate_0 (); - ffeequiv_terminate_0 (); - ffeexpr_terminate_0 (); - ffeglobal_terminate_0 (); - ffeimplic_terminate_0 (); - ffeinfo_terminate_0 (); - ffeintrin_terminate_0 (); - ffelab_terminate_0 (); - ffelex_terminate_0 (); - ffename_terminate_0 (); - ffesrc_terminate_0 (); - ffest_terminate_0 (); - ffestorag_terminate_0 (); - ffesymbol_terminate_0 (); - ffetarget_terminate_0 (); - ffetype_terminate_0 (); - ffewhere_terminate_0 (); -} - -/* ffe_terminate_1 -- Terminate the FFE after seeing source file EOF - - ffe_terminate_1(); */ - -void -ffe_terminate_1 () -{ - ffe_count_2 = 0; - ffe_in_1 = FALSE; - - ffe_terminate_2 (); - - ffebad_terminate_1 (); - ffebit_terminate_1 (); - ffebld_terminate_1 (); - ffecom_terminate_1 (); - ffedata_terminate_1 (); - ffeequiv_terminate_1 (); - ffeexpr_terminate_1 (); - ffeglobal_terminate_1 (); - ffeimplic_terminate_1 (); - ffeinfo_terminate_1 (); - ffeintrin_terminate_1 (); - ffelab_terminate_1 (); - ffelex_terminate_1 (); - ffename_terminate_1 (); - ffesrc_terminate_1 (); - ffest_terminate_1 (); - ffestorag_terminate_1 (); - ffesymbol_terminate_1 (); - ffetarget_terminate_1 (); - ffetype_terminate_1 (); - ffewhere_terminate_1 (); - - assert (ffe_file_pool_ != NULL); - malloc_pool_kill (ffe_file_pool_); - ffe_file_pool_ = NULL; -} - -/* ffe_terminate_2 -- Terminate the FFE after seeing outer program unit END - - ffe_terminate_2(); */ - -void -ffe_terminate_2 () -{ - ffe_count_3 = 0; - ffe_in_2 = FALSE; - - ffe_terminate_3 (); - - ffebad_terminate_2 (); - ffebit_terminate_2 (); - ffebld_terminate_2 (); - ffecom_terminate_2 (); - ffedata_terminate_2 (); - ffeequiv_terminate_2 (); - ffeexpr_terminate_2 (); - ffeglobal_terminate_2 (); - ffeimplic_terminate_2 (); - ffeinfo_terminate_2 (); - ffeintrin_terminate_2 (); - ffelab_terminate_2 (); - ffelex_terminate_2 (); - ffename_terminate_2 (); - ffesrc_terminate_2 (); - ffest_terminate_2 (); - ffestorag_terminate_2 (); - ffesymbol_terminate_2 (); - ffetarget_terminate_2 (); - ffetype_terminate_2 (); - ffewhere_terminate_2 (); - - assert (ffe_program_unit_pool_ != NULL); - malloc_pool_kill (ffe_program_unit_pool_); - ffe_program_unit_pool_ = NULL; -} - -/* ffe_terminate_3 -- Terminate the FFE after seeing any program unit END - - ffe_terminate_3(); */ - -void -ffe_terminate_3 () -{ - ffe_count_4 = 0; - ffe_in_3 = FALSE; - - ffebad_terminate_3 (); - ffebit_terminate_3 (); - ffebld_terminate_3 (); - ffecom_terminate_3 (); - ffedata_terminate_3 (); - ffeequiv_terminate_3 (); - ffeexpr_terminate_3 (); - ffeglobal_terminate_3 (); - ffeimplic_terminate_3 (); - ffeinfo_terminate_3 (); - ffeintrin_terminate_3 (); - ffelab_terminate_3 (); - ffelex_terminate_3 (); - ffename_terminate_3 (); - ffesrc_terminate_3 (); - ffest_terminate_3 (); - ffestorag_terminate_3 (); - ffesymbol_terminate_3 (); - ffetarget_terminate_3 (); - ffetype_terminate_3 (); - ffewhere_terminate_3 (); - - assert (ffe_any_unit_pool_ != NULL); - malloc_pool_kill (ffe_any_unit_pool_); - ffe_any_unit_pool_ = NULL; -} - -/* ffe_terminate_4 -- Terminate the FFE after seeing sfunc def expression - - ffe_terminate_4(); */ - -void -ffe_terminate_4 () -{ - ffe_in_4 = FALSE; - - ffebad_terminate_4 (); - ffebit_terminate_4 (); - ffebld_terminate_4 (); - ffecom_terminate_4 (); - ffedata_terminate_4 (); - ffeequiv_terminate_4 (); - ffeexpr_terminate_4 (); - ffeglobal_terminate_4 (); - ffeimplic_terminate_4 (); - ffeinfo_terminate_4 (); - ffeintrin_terminate_4 (); - ffelab_terminate_4 (); - ffelex_terminate_4 (); - ffename_terminate_4 (); - ffesrc_terminate_4 (); - ffest_terminate_4 (); - ffestorag_terminate_4 (); - ffesymbol_terminate_4 (); - ffetarget_terminate_4 (); - ffetype_terminate_4 (); - ffewhere_terminate_4 (); -} diff --git a/gcc/f/top.h b/gcc/f/top.h deleted file mode 100755 index bae6787..0000000 --- a/gcc/f/top.h +++ /dev/null @@ -1,264 +0,0 @@ -/* top.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995-1997 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - top.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_parse -#define _H_f_parse - -/* Simple definitions and enumerations. */ - -enum _ffe_case_ - { - FFE_caseNONE, /* No case conversion, match - case-insensitive. */ - FFE_caseUPPER, /* Convert lowercase to uppercase, match - upper. */ - FFE_caseLOWER, /* Convert uppercase to lowercase, match - lower. */ - FFE_caseINITCAP, /* Match InitialCap (no meaning for - conversion). */ - FFE_case - }; -typedef enum _ffe_case_ ffeCase; - -enum _ffeintrinsic_state_ - { /* State of a family of intrinsics. NOTE: - order IS important, see - ffe_intrinsic_state_max (). */ - FFE_intrinsicstateDELETED, /* Doesn't exist at all. */ - FFE_intrinsicstateDISABLED, /* Diagnostic if used as intrinsic. */ - FFE_intrinsicstateHIDDEN, /* Exists only if INTRINSIC stmt. */ - FFE_intrinsicstateENABLED, /* Exists as normal. */ - FFE_intrinsicstate - }; -typedef enum _ffeintrinsic_state_ ffeIntrinsicState; - -/* Typedefs. */ - -typedef unsigned long ffeCounter; -#define ffeCounter_f "l" -typedef unsigned int ffeKwIndex; -typedef unsigned long int ffeTokenLength; -#define ffeTokenLength_f "l" -typedef void *ffeUnionLongPtr; /* unused type to cover union of long and - ptr. */ - -/* Include files needed by this one. */ - -#include "malloc.h" -#include "where.h" - -/* Structure definitions. */ - - -/* Global objects accessed by users of this module. */ - -extern bool ffe_is_do_internal_checks_; -extern bool ffe_is_90_; -extern bool ffe_is_automatic_; -extern bool ffe_is_backslash_; -extern bool ffe_is_emulate_complex_; -extern bool ffe_is_underscoring_; -extern bool ffe_is_second_underscore_; -extern bool ffe_is_debug_kludge_; -extern bool ffe_is_dollar_ok_; -extern bool ffe_is_f2c_; -extern bool ffe_is_f2c_library_; -extern bool ffe_is_ffedebug_; -extern bool ffe_is_free_form_; -extern bool ffe_is_globals_; -extern bool ffe_is_ident_; -extern bool ffe_is_init_local_zero_; -extern bool ffe_is_mainprog_; -extern bool ffe_is_null_version_; -extern bool ffe_is_onetrip_; -extern bool ffe_is_silent_; -extern bool ffe_is_typeless_boz_; -extern bool ffe_is_pedantic_; -extern bool ffe_is_saveall_; -extern bool ffe_is_ugly_args_; -extern bool ffe_is_ugly_assign_; -extern bool ffe_is_ugly_assumed_; -extern bool ffe_is_ugly_comma_; -extern bool ffe_is_ugly_complex_; -extern bool ffe_is_ugly_init_; -extern bool ffe_is_ugly_logint_; -extern bool ffe_is_version_; -extern bool ffe_is_vxt_; -extern bool ffe_is_warn_globals_; -extern bool ffe_is_warn_implicit_; -extern bool ffe_is_warn_surprising_; -extern bool ffe_is_zeros_; -extern ffeCase ffe_case_intrin_; -extern ffeCase ffe_case_match_; -extern ffeCase ffe_case_source_; -extern ffeCase ffe_case_symbol_; -extern ffeIntrinsicState ffe_intrinsic_state_badu77_; -extern ffeIntrinsicState ffe_intrinsic_state_gnu_; -extern ffeIntrinsicState ffe_intrinsic_state_f2c_; -extern ffeIntrinsicState ffe_intrinsic_state_f90_; -extern ffeIntrinsicState ffe_intrinsic_state_mil_; -extern ffeIntrinsicState ffe_intrinsic_state_unix_; -extern ffeIntrinsicState ffe_intrinsic_state_vxt_; -extern int ffe_fixed_line_length_; -extern mallocPool ffe_file_pool_; -extern mallocPool ffe_any_unit_pool_; -extern mallocPool ffe_program_unit_pool_; -extern ffeCounter ffe_count_0; -extern ffeCounter ffe_count_1; -extern ffeCounter ffe_count_2; -extern ffeCounter ffe_count_3; -extern ffeCounter ffe_count_4; -extern bool ffe_in_0; -extern bool ffe_in_1; -extern bool ffe_in_2; -extern bool ffe_in_3; -extern bool ffe_in_4; - -/* Declare functions with prototypes. */ - -int ffe_decode_option (int argc, char **argv); -void ffe_file (ffewhereFile wf, FILE *f); -void ffe_init_0 (void); -void ffe_init_1 (void); -void ffe_init_2 (void); -void ffe_init_3 (void); -void ffe_init_4 (void); -void ffe_terminate_0 (void); -void ffe_terminate_1 (void); -void ffe_terminate_2 (void); -void ffe_terminate_3 (void); -void ffe_terminate_4 (void); - -/* Define macros. */ - -#define ffe_case_intrin() ffe_case_intrin_ -#define ffe_case_match() ffe_case_match_ -#define ffe_case_source() ffe_case_source_ -#define ffe_case_symbol() ffe_case_symbol_ -#define ffe_intrinsic_state_badu77() ffe_intrinsic_state_badu77_ -#define ffe_intrinsic_state_f2c() ffe_intrinsic_state_f2c_ -#define ffe_intrinsic_state_f90() ffe_intrinsic_state_f90_ -#define ffe_intrinsic_state_gnu() ffe_intrinsic_state_gnu_ -#define ffe_intrinsic_state_mil() ffe_intrinsic_state_mil_ -#define ffe_intrinsic_state_unix() ffe_intrinsic_state_unix_ -#define ffe_intrinsic_state_vxt() ffe_intrinsic_state_vxt_ -#define ffe_is_90() ffe_is_90_ -#define ffe_is_automatic() ffe_is_automatic_ -#define ffe_is_backslash() ffe_is_backslash_ -#define ffe_is_debug_kludge() ffe_is_debug_kludge_ -#define ffe_is_do_internal_checks() ffe_is_do_internal_checks_ -#define ffe_is_dollar_ok() ffe_is_dollar_ok_ -#define ffe_is_emulate_complex() ffe_is_emulate_complex_ -#define ffe_is_f2c() ffe_is_f2c_ -#define ffe_is_f2c_library() ffe_is_f2c_library_ -#define ffe_is_ffedebug() ffe_is_ffedebug_ -#define ffe_is_free_form() ffe_is_free_form_ -#define ffe_is_globals() ffe_is_globals_ -#define ffe_is_ident() ffe_is_ident_ -#define ffe_is_init_local_zero() ffe_is_init_local_zero_ -#define ffe_is_mainprog() ffe_is_mainprog_ -#define ffe_is_null_version() ffe_is_null_version_ -#define ffe_is_onetrip() ffe_is_onetrip_ -#define ffe_is_pedantic() ffe_is_pedantic_ -#define ffe_is_pedantic_not_90() (ffe_is_pedantic_ && !ffe_is_90_) -#define ffe_is_saveall() ffe_is_saveall_ -#define ffe_is_second_underscore() ffe_is_second_underscore_ -#define ffe_is_silent() ffe_is_silent_ -#define ffe_is_typeless_boz() ffe_is_typeless_boz_ -#define ffe_is_ugly_args() ffe_is_ugly_args_ -#define ffe_is_ugly_assign() ffe_is_ugly_assign_ -#define ffe_is_ugly_assumed() ffe_is_ugly_assumed_ -#define ffe_is_ugly_comma() ffe_is_ugly_comma_ -#define ffe_is_ugly_complex() ffe_is_ugly_complex_ -#define ffe_is_ugly_init() ffe_is_ugly_init_ -#define ffe_is_ugly_logint() ffe_is_ugly_logint_ -#define ffe_is_underscoring() ffe_is_underscoring_ -#define ffe_is_version() ffe_is_version_ -#define ffe_is_vxt() ffe_is_vxt_ -#define ffe_is_warn_globals() ffe_is_warn_globals_ -#define ffe_is_warn_implicit() ffe_is_warn_implicit_ -#define ffe_is_warn_surprising() ffe_is_warn_surprising_ -#define ffe_is_zeros() ffe_is_zeros_ -#define ffe_fixed_line_length() ffe_fixed_line_length_ -#define ffe_pool_file() (ffe_file_pool_) -#define ffe_pool_any_unit() (ffe_any_unit_pool_) -#define ffe_pool_program_unit() (ffe_program_unit_pool_) -#define ffe_set_case_intrin(f) (ffe_case_intrin_ = (f)) -#define ffe_set_case_match(f) (ffe_case_match_ = (f)) -#define ffe_set_case_source(f) (ffe_case_source_ = (f)) -#define ffe_set_case_symbol(f) (ffe_case_symbol_ = (f)) -#define ffe_set_intrinsic_state_badu77(s) (ffe_intrinsic_state_badu77_ = (s)) -#define ffe_set_intrinsic_state_f2c(s) (ffe_intrinsic_state_f2c_ = (s)) -#define ffe_set_intrinsic_state_f90(s) (ffe_intrinsic_state_f90_ = (s)) -#define ffe_set_intrinsic_state_gnu(s) (ffe_intrinsic_state_gnu_ = (s)) -#define ffe_set_intrinsic_state_mil(s) (ffe_intrinsic_state_mil_ = (s)) -#define ffe_set_intrinsic_state_unix(s) (ffe_intrinsic_state_unix_ = (s)) -#define ffe_set_intrinsic_state_vxt(s) (ffe_intrinsic_state_vxt_ = (s)) -#define ffe_set_is_90(f) (ffe_is_90_ = (f)) -#define ffe_set_is_automatic(f) (ffe_is_automatic_ = (f)) -#define ffe_set_is_backslash(f) (ffe_is_backslash_ = (f)) -#define ffe_set_is_debug_kludge(f) (ffe_is_debug_kludge_ = (f)) -#define ffe_set_is_do_internal_checks(f) (ffe_is_do_internal_checks_ = (f)) -#define ffe_set_is_dollar_ok(f) (ffe_is_dollar_ok_ = (f)) -#define ffe_set_is_emulate_complex(f) (ffe_is_emulate_complex_ = (f)) -#define ffe_set_is_f2c(f) (ffe_is_f2c_ = (f)) -#define ffe_set_is_f2c_library(f) (ffe_is_f2c_library_ = (f)) -#define ffe_set_is_ffedebug(f) (ffe_is_ffedebug_ = (f)) -#define ffe_set_is_free_form(f) (ffe_is_free_form_ = (f)) -#define ffe_set_is_globals(f) (ffe_is_globals_ = (f)) -#define ffe_set_is_ident(f) (ffe_is_ident_ = (f)) -#define ffe_set_is_init_local_zero(f) (ffe_is_init_local_zero_ = (f)) -#define ffe_set_is_mainprog(f) (ffe_is_mainprog_ = (f)) -#define ffe_set_is_null_version(f) (ffe_is_null_version_ = (f)) -#define ffe_set_is_onetrip(f) (ffe_is_onetrip_ = (f)) -#define ffe_set_is_pedantic(f) (ffe_is_pedantic_ = (f)) -#define ffe_set_is_saveall(f) (ffe_is_saveall_ = (f)) -#define ffe_set_is_second_underscore(f) (ffe_is_second_underscore_ = (f)) -#define ffe_set_is_silent(f) (ffe_is_silent_ = (f)) -#define ffe_set_is_typeless_boz(f) (ffe_is_typeless_boz_ = (f)) -#define ffe_set_is_ugly_args(f) (ffe_is_ugly_args_ = (f)) -#define ffe_set_is_ugly_assign(f) (ffe_is_ugly_assign_ = (f)) -#define ffe_set_is_ugly_assumed(f) (ffe_is_ugly_assumed_ = (f)) -#define ffe_set_is_ugly_comma(f) (ffe_is_ugly_comma_ = (f)) -#define ffe_set_is_ugly_complex(f) (ffe_is_ugly_complex_ = (f)) -#define ffe_set_is_ugly_init(f) (ffe_is_ugly_init_ = (f)) -#define ffe_set_is_ugly_logint(f) (ffe_is_ugly_logint_ = (f)) -#define ffe_set_is_underscoring(f) (ffe_is_underscoring_ = (f)) -#define ffe_set_is_version(f) (ffe_is_version_ = (f)) -#define ffe_set_is_vxt(f) (ffe_is_vxt_ = (f)) -#define ffe_set_is_warn_globals(f) (ffe_is_warn_globals_ = (f)) -#define ffe_set_is_warn_implicit(f) (ffe_is_warn_implicit_ = (f)) -#define ffe_set_is_warn_surprising(f) (ffe_is_warn_surprising_ = (f)) -#define ffe_set_is_zeros(f) (ffe_is_zeros_ = (f)) -#define ffe_set_fixed_line_length(l) (ffe_fixed_line_length_ = (l)) -#define ffe_state_max(s1,s2) ((s1) > (s2) ? (s1) : (s2)) - -/* End of #include file. */ - -#endif diff --git a/gcc/f/toplev.j b/gcc/f/toplev.j deleted file mode 100755 index 9ee892b..0000000 --- a/gcc/f/toplev.j +++ /dev/null @@ -1,27 +0,0 @@ -/* toplev.j -- Wrapper for GCC's toplev.h - Copyright (C) 1998 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_toplev -#define _J_f_toplev -#include "toplev.h" -#endif -#endif diff --git a/gcc/f/tree.j b/gcc/f/tree.j deleted file mode 100755 index 009af12..0000000 --- a/gcc/f/tree.j +++ /dev/null @@ -1,28 +0,0 @@ -/* tree.j -- Wrapper for GCC's tree.h - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef MAKING_DEPENDENCIES -#ifndef _J_f_tree -#define _J_f_tree -#include "config.j" -#include "tree.h" -#endif -#endif diff --git a/gcc/f/type.c b/gcc/f/type.c deleted file mode 100755 index 76f0e87..0000000 --- a/gcc/f/type.c +++ /dev/null @@ -1,107 +0,0 @@ -/* Implementation of Fortran type abstraction - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#include "proj.h" -#include "type.h" -#include "malloc.h" - - -/* Look up a type given its base type and kind value. */ - -ffetype -ffetype_lookup_kind (ffetype base_type, int kind) -{ - if ((base_type->kinds_ == NULL) - || (kind < 0) - || (((size_t) kind) >= ARRAY_SIZE (base_type->kinds_->type_))) - return NULL; - - return base_type->kinds_->type_[kind]; -} - -ffetype -ffetype_lookup_star (ffetype base_type, int star) -{ - if ((base_type->stars_ == NULL) - || (star < 0) - || (((size_t) star) >= ARRAY_SIZE (base_type->stars_->type_))) - return NULL; - - return base_type->stars_->type_[star]; -} - -ffetype -ffetype_new (void) -{ - ffetype type; - - type = (ffetype) malloc_new_kp (malloc_pool_image (), "ffetype", - sizeof (*type)); - type->kinds_ = NULL; - type->stars_ = NULL; - type->alignment_ = 0; - type->modulo_ = 0; - type->size_ = 0; - - return type; -} - -void -ffetype_set_kind (ffetype base_type, int kind, ffetype type) -{ - assert (kind < (int) sizeof (*(base_type->kinds_))); - - if (base_type->kinds_ == NULL) - { - int i; - - base_type->kinds_ - = (ffetype_indexes_) malloc_new_kp (malloc_pool_image (), - "ffetype_indexes_[kinds]", - sizeof (*(base_type->kinds_))); - for (i = 0; ((size_t) i) < ARRAY_SIZE (base_type->kinds_->type_); ++i) - base_type->kinds_->type_[i] = NULL; - } - - assert (base_type->kinds_->type_[kind] == NULL); - - base_type->kinds_->type_[kind] = type; -} - -void -ffetype_set_star (ffetype base_type, int star, ffetype type) -{ - if (base_type->stars_ == NULL) - { - int i; - - base_type->stars_ - = (ffetype_indexes_) malloc_new_kp (malloc_pool_image (), - "ffetype_indexes_[stars]", - sizeof (*(base_type->stars_))); - for (i = 0; ((size_t) i) < ARRAY_SIZE (base_type->stars_->type_); ++i) - base_type->stars_->type_[i] = NULL; - } - - assert (base_type->stars_->type_[star] == NULL); - - base_type->stars_->type_[star] = type; -} diff --git a/gcc/f/type.h b/gcc/f/type.h deleted file mode 100755 index 94d6404..0000000 --- a/gcc/f/type.h +++ /dev/null @@ -1,64 +0,0 @@ -/* Interface definitions for Fortran type abstraction - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. */ - -#ifndef _H_f_type -#define _H_f_type - -typedef struct _ffetype_ *ffetype; -typedef struct _ffetype_indexes_ *ffetype_indexes_; - -struct _ffetype_ - { - ffetype_indexes_ kinds_; - ffetype_indexes_ stars_; - int alignment_; - int modulo_; - int size_; - }; - -struct _ffetype_indexes_ - { - ffetype type_[40]; /* *n, KIND=n: 0 <= n <= 39. */ - }; - -#define ffetype_alignment(t) ((t)->alignment_) -#define ffetype_init_0() -#define ffetype_init_1() -#define ffetype_init_2() -#define ffetype_init_3() -#define ffetype_init_4() -ffetype ffetype_lookup_kind (ffetype base_type, int kind); -ffetype ffetype_lookup_star (ffetype base_type, int star); -#define ffetype_modulo(t) ((t)->modulo_) -ffetype ffetype_new (void); -#define ffetype_set_ams(t,a,m,s) ((t)->alignment_ = (a), \ - (t)->modulo_ = (m), \ - (t)->size_ = (s)) -void ffetype_set_kind (ffetype base_type, int kind, ffetype type); -void ffetype_set_star (ffetype base_type, int star, ffetype type); -#define ffetype_size(t) ((t)->size_) -#define ffetype_terminate_0() -#define ffetype_terminate_1() -#define ffetype_terminate_2() -#define ffetype_terminate_3() -#define ffetype_terminate_4() - -#endif diff --git a/gcc/f/version.c b/gcc/f/version.c deleted file mode 100755 index 417a538..0000000 --- a/gcc/f/version.c +++ /dev/null @@ -1 +0,0 @@ -char *ffe_version_string = "0.5.24-19980804"; diff --git a/gcc/f/version.h b/gcc/f/version.h deleted file mode 100755 index cd578a8..0000000 --- a/gcc/f/version.h +++ /dev/null @@ -1,6 +0,0 @@ -#ifndef _H_f_version -#define _H_f_version - -extern char *ffe_version_string; - -#endif diff --git a/gcc/f/where.c b/gcc/f/where.c deleted file mode 100755 index b8b648c..0000000 --- a/gcc/f/where.c +++ /dev/null @@ -1,542 +0,0 @@ -/* where.c -- Implementation File (module.c template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Related Modules: - - Description: - Simple data abstraction for Fortran source lines (called card images). - - Modifications: -*/ - -/* Include files. */ - -#include "proj.h" -#include "where.h" -#include "lex.h" -#include "malloc.h" - -/* Externals defined here. */ - -struct _ffewhere_line_ ffewhere_unknown_line_ -= -{NULL, NULL, 0, 0, 0, {0}}; - -/* Simple definitions and enumerations. */ - - -/* Internal typedefs. */ - -typedef struct _ffewhere_ll_ *ffewhereLL_; - -/* Private include files. */ - - -/* Internal structure definitions. */ - -struct _ffewhere_ll_ - { - ffewhereLL_ next; - ffewhereLL_ previous; - ffewhereFile wf; - ffewhereLineNumber line_no; /* ffelex_line_number() at time of creation. */ - ffewhereLineNumber offset; /* User-desired offset (usually 1). */ - }; - -struct _ffewhere_root_ll_ - { - ffewhereLL_ first; - ffewhereLL_ last; - }; - -struct _ffewhere_root_line_ - { - ffewhereLine first; - ffewhereLine last; - ffewhereLineNumber none; - }; - -/* Static objects accessed by functions in this module. */ - -static struct _ffewhere_root_ll_ ffewhere_root_ll_; -static struct _ffewhere_root_line_ ffewhere_root_line_; - -/* Static functions (internal). */ - -static ffewhereLL_ ffewhere_ll_lookup_ (ffewhereLineNumber ln); - -/* Internal macros. */ - - -/* Look up line-to-line object from absolute line num. */ - -static ffewhereLL_ -ffewhere_ll_lookup_ (ffewhereLineNumber ln) -{ - ffewhereLL_ ll; - - if (ln == 0) - return ffewhere_root_ll_.first; - - for (ll = ffewhere_root_ll_.last; - ll != (ffewhereLL_) &ffewhere_root_ll_.first; - ll = ll->previous) - { - if (ll->line_no <= ln) - return ll; - } - - assert ("no line num" == NULL); - return NULL; -} - -/* Kill file object. - - Note that this object must not have been passed in a call - to any other ffewhere function except ffewhere_file_name and - ffewhere_file_namelen. */ - -void -ffewhere_file_kill (ffewhereFile wf) -{ - malloc_kill_ks (ffe_pool_file (), wf, - offsetof (struct _ffewhere_file_, text) - + wf->length + 1); -} - -/* Create file object. */ - -ffewhereFile -ffewhere_file_new (char *name, size_t length) -{ - ffewhereFile wf; - - wf = malloc_new_ks (ffe_pool_file (), "ffewhereFile", - offsetof (struct _ffewhere_file_, text) - + length + 1); - wf->length = length; - memcpy (&wf->text[0], name, length); - wf->text[length] = '\0'; - - return wf; -} - -/* Set file and first line number. - - Pass FALSE if no line number is specified. */ - -void -ffewhere_file_set (ffewhereFile wf, bool have_num, ffewhereLineNumber ln) -{ - ffewhereLL_ ll; - - ll = malloc_new_kp (ffe_pool_file (), "ffewhereLL_", sizeof (*ll)); - ll->next = (ffewhereLL_) &ffewhere_root_ll_.first; - ll->previous = ffewhere_root_ll_.last; - ll->next->previous = ll; - ll->previous->next = ll; - if (wf == NULL) - { - if (ll->previous == ll->next) - ll->wf = NULL; - else - ll->wf = ll->previous->wf; - } - else - ll->wf = wf; - ll->line_no = ffelex_line_number (); - if (have_num) - ll->offset = ln; - else - { - if (ll->previous == ll->next) - ll->offset = 1; - else - ll->offset - = ll->line_no - ll->previous->line_no + ll->previous->offset; - } -} - -/* Do initializations. */ - -void -ffewhere_init_1 () -{ - ffewhere_root_line_.first = ffewhere_root_line_.last - = (ffewhereLine) &ffewhere_root_line_.first; - ffewhere_root_line_.none = 0; - - ffewhere_root_ll_.first = ffewhere_root_ll_.last - = (ffewhereLL_) &ffewhere_root_ll_.first; -} - -/* Return the textual content of the line. */ - -char * -ffewhere_line_content (ffewhereLine wl) -{ - assert (wl != NULL); - return wl->content; -} - -/* Look up file object from line object. */ - -ffewhereFile -ffewhere_line_file (ffewhereLine wl) -{ - ffewhereLL_ ll; - - assert (wl != NULL); - ll = ffewhere_ll_lookup_ (wl->line_num); - return ll->wf; -} - -/* Lookup file object from line object, calc line#. */ - -ffewhereLineNumber -ffewhere_line_filelinenum (ffewhereLine wl) -{ - ffewhereLL_ ll; - - assert (wl != NULL); - ll = ffewhere_ll_lookup_ (wl->line_num); - return wl->line_num + ll->offset - ll->line_no; -} - -/* Decrement use count for line, deallocate if no uses left. */ - -void -ffewhere_line_kill (ffewhereLine wl) -{ -#if 0 - if (!ffewhere_line_is_unknown (wl)) - fprintf (dmpout, "; ffewhere_line_kill %" ffewhereLineNumber_f "u, uses=%" - ffewhereUses_f_ "u\n", - wl->line_num, wl->uses); -#endif - assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0)); - if (!ffewhere_line_is_unknown (wl) && (--wl->uses == 0)) - { - wl->previous->next = wl->next; - wl->next->previous = wl->previous; - malloc_kill_ks (ffe_pool_file (), wl, - offsetof (struct _ffewhere_line_, content) - + wl->length + 1); - } -} - -/* Make a new line or increment use count of existing one. - - Find out where line object is, if anywhere. If in lexer, it might also - be at the end of the list of lines, else put it on the end of the list. - Then, if in the list of lines, increment the use count and return the - line object. Else, make an empty line object (no line) and return - that. */ - -ffewhereLine -ffewhere_line_new (ffewhereLineNumber ln) -{ - ffewhereLine wl = ffewhere_root_line_.last; - - /* If this is the lexer's current line, see if it is already at the end of - the list, and if not, make it and return it. */ - - if (((ln == 0) /* Presumably asking for EOF pointer. */ - || (wl->line_num != ln)) - && (ffelex_line_number () == ln)) - { -#if 0 - fprintf (dmpout, - "; ffewhere_line_new %" ffewhereLineNumber_f "u, lexer\n", - ln); -#endif - wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line", - offsetof (struct _ffewhere_line_, content) - + (size_t) ffelex_line_length () + 1); - wl->next = (ffewhereLine) &ffewhere_root_line_; - wl->previous = ffewhere_root_line_.last; - wl->previous->next = wl; - wl->next->previous = wl; - wl->line_num = ln; - wl->uses = 1; - wl->length = ffelex_line_length (); - strcpy (wl->content, ffelex_line ()); - return wl; - } - - /* See if line is on list already. */ - - while (wl->line_num > ln) - wl = wl->previous; - - /* If line is there, increment its use count and return. */ - - if (wl->line_num == ln) - { -#if 0 - fprintf (dmpout, "; ffewhere_line_new %" ffewhereLineNumber_f "u, uses=%" - ffewhereUses_f_ "u\n", ln, - wl->uses); -#endif - wl->uses++; - return wl; - } - - /* Else, make a new one with a blank line (since we've obviously lost it, - which should never happen) and return it. */ - - fprintf (stderr, - "(Cannot resurrect line %lu for error reporting purposes.)\n", - ln); - - wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line", - offsetof (struct _ffewhere_line_, content) - + 1); - wl->next = (ffewhereLine) &ffewhere_root_line_; - wl->previous = ffewhere_root_line_.last; - wl->previous->next = wl; - wl->next->previous = wl; - wl->line_num = ln; - wl->uses = 1; - wl->length = 0; - *(wl->content) = '\0'; - return wl; -} - -/* Increment use count of line, as in a copy. */ - -ffewhereLine -ffewhere_line_use (ffewhereLine wl) -{ -#if 0 - fprintf (dmpout, "; ffewhere_line_use %" ffewhereLineNumber_f "u, uses=%" ffewhereUses_f_ - "u\n", wl->line_num, wl->uses); -#endif - assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0)); - if (!ffewhere_line_is_unknown (wl)) - ++wl->uses; - return wl; -} - -/* Set an ffewhere object based on a track index. - - Determines the absolute line and column number of a character at a given - index into an ffewhereTrack array. wr* is the reference position, wt is - the tracking information, and i is the index desired. wo* is set to wr* - plus the continual offsets described by wt[0...i-1], or unknown if any of - the continual offsets are not known. */ - -void -ffewhere_set_from_track (ffewhereLine *wol, ffewhereColumn *woc, - ffewhereLine wrl, ffewhereColumn wrc, - ffewhereTrack wt, ffewhereIndex i) -{ - ffewhereLineNumber ln; - ffewhereColumnNumber cn; - ffewhereIndex j; - ffewhereIndex k; - - if ((i == 0) || (i >= FFEWHERE_indexMAX)) - { - *wol = ffewhere_line_use (wrl); - *woc = ffewhere_column_use (wrc); - } - else - { - ln = ffewhere_line_number (wrl); - cn = ffewhere_column_number (wrc); - for (j = 0, k = 0; j < i; ++j, k += 2) - { - if ((wt[k] == FFEWHERE_indexUNKNOWN) - || (wt[k + 1] == FFEWHERE_indexUNKNOWN)) - { - *wol = ffewhere_line_unknown (); - *woc = ffewhere_column_unknown (); - return; - } - if (wt[k] == 0) - cn += wt[k + 1] + 1; - else - { - ln += wt[k]; - cn = wt[k + 1] + 1; - } - } - if (ln == ffewhere_line_number (wrl)) - { /* Already have the line object, just use it - directly. */ - *wol = ffewhere_line_use (wrl); - } - else /* Must search for the line object. */ - *wol = ffewhere_line_new (ln); - *woc = ffewhere_column_new (cn); - } -} - -/* Build next tracking index. - - Set wt[i-1] continual offset so that it offsets from w* to (ln,cn). Update - w* to contain (ln,cn). DO NOT call this routine if i >= FFEWHERE_indexMAX - or i == 0. */ - -void -ffewhere_track (ffewhereLine *wl, ffewhereColumn *wc, ffewhereTrack wt, - ffewhereIndex i, ffewhereLineNumber ln, - ffewhereColumnNumber cn) -{ - unsigned int lo; - unsigned int co; - - if ((ffewhere_line_is_unknown (*wl)) - || (ffewhere_column_is_unknown (*wc)) - || ((lo = ln - ffewhere_line_number (*wl)) >= FFEWHERE_indexUNKNOWN)) - { - wt[i * 2 - 2] = wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN; - ffewhere_line_kill (*wl); - ffewhere_column_kill (*wc); - *wl = FFEWHERE_lineUNKNOWN; - *wc = FFEWHERE_columnUNKNOWN; - } - else if (lo == 0) - { - wt[i * 2 - 2] = 0; - if ((co = cn - ffewhere_column_number (*wc)) > FFEWHERE_indexUNKNOWN) - { - wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN; - ffewhere_line_kill (*wl); - ffewhere_column_kill (*wc); - *wl = FFEWHERE_lineUNKNOWN; - *wc = FFEWHERE_columnUNKNOWN; - } - else - { - wt[i * 2 - 1] = co - 1; - ffewhere_column_kill (*wc); - *wc = ffewhere_column_use (ffewhere_column_new (cn)); - } - } - else - { - wt[i * 2 - 2] = lo; - if (cn > FFEWHERE_indexUNKNOWN) - { - wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN; - ffewhere_line_kill (*wl); - ffewhere_column_kill (*wc); - *wl = ffewhere_line_unknown (); - *wc = ffewhere_column_unknown (); - } - else - { - wt[i * 2 - 1] = cn - 1; - ffewhere_line_kill (*wl); - ffewhere_column_kill (*wc); - *wl = ffewhere_line_use (ffewhere_line_new (ln)); - *wc = ffewhere_column_use (ffewhere_column_new (cn)); - } - } -} - -/* Clear tracking index for internally created track. - - Set the tracking information to indicate that the tracking is at its - simplest (no spaces or newlines within the tracking). This means set - everything to zero in the current implementation. Length is the total - length of the token; length must be 2 or greater, since length-1 tracking - characters are set. */ - -void -ffewhere_track_clear (ffewhereTrack wt, ffewhereIndex length) -{ - ffewhereIndex i; - - if (length > FFEWHERE_indexMAX) - length = FFEWHERE_indexMAX; - - for (i = 1; i < length; ++i) - wt[i * 2 - 2] = wt[i * 2 - 1] = 0; -} - -/* Copy tracking index from one place to another. - - Copy tracking information from swt[start] to dwt[0] and so on, presumably - after an ffewhere_set_from_track call. Length is the total - length of the token; length must be 2 or greater, since length-1 tracking - characters are set. */ - -void -ffewhere_track_copy (ffewhereTrack dwt, ffewhereTrack swt, ffewhereIndex start, - ffewhereIndex length) -{ - ffewhereIndex i; - ffewhereIndex copy; - - if (length > FFEWHERE_indexMAX) - length = FFEWHERE_indexMAX; - - if (length + start > FFEWHERE_indexMAX) - copy = FFEWHERE_indexMAX - start; - else - copy = length; - - for (i = 1; i < copy; ++i) - { - dwt[i * 2 - 2] = swt[(i + start) * 2 - 2]; - dwt[i * 2 - 1] = swt[(i + start) * 2 - 1]; - } - - for (; i < length; ++i) - { - dwt[i * 2 - 2] = 0; - dwt[i * 2 - 1] = 0; - } -} - -/* Kill tracking data. - - Kill all the tracking information by killing incremented lines from the - first line number. */ - -void -ffewhere_track_kill (ffewhereLine wrl, ffewhereColumn wrc UNUSED, - ffewhereTrack wt, ffewhereIndex length) -{ - ffewhereLineNumber ln; - unsigned int lo; - ffewhereIndex i; - - ln = ffewhere_line_number (wrl); - - if (length > FFEWHERE_indexMAX) - length = FFEWHERE_indexMAX; - - for (i = 0; i < length - 1; ++i) - { - if ((lo = wt[i * 2]) == FFEWHERE_indexUNKNOWN) - break; - else if (lo != 0) - { - ln += lo; - wrl = ffewhere_line_new (ln); - ffewhere_line_kill (wrl); - } - } -} diff --git a/gcc/f/where.h b/gcc/f/where.h deleted file mode 100755 index 2091f36..0000000 --- a/gcc/f/where.h +++ /dev/null @@ -1,138 +0,0 @@ -/* where.h -- Public #include File (module.h template V1.0) - Copyright (C) 1995 Free Software Foundation, Inc. - Contributed by James Craig Burley (burley@gnu.org). - -This file is part of GNU Fortran. - -GNU Fortran 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 Fortran 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 Fortran; see the file COPYING. If not, write to -the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA -02111-1307, USA. - - Owning Modules: - where.c - - Modifications: -*/ - -/* Allow multiple inclusion to work. */ - -#ifndef _H_f_where -#define _H_f_where - -/* Simple definitions and enumerations. */ - -#define FFEWHERE_columnMAX UCHAR_MAX -#define FFEWHERE_columnUNKNOWN 0 -#define FFEWHERE_indexMAX 36 -#define FFEWHERE_indexUNKNOWN UCHAR_MAX -#define FFEWHERE_lineMAX ULONG_MAX -#define FFEWHERE_lineUNKNOWN (&ffewhere_unknown_line_) -#define FFEWHERE_filenameUNKNOWN ("(input file)") - -/* Typedefs. */ - -typedef unsigned char ffewhereColumnNumber; /* Change FFEWHERE_columnMAX - too. */ -#define ffewhereColumnNumber_f "" -typedef unsigned char ffewhereColumn; -typedef struct _ffewhere_file_ *ffewhereFile; -typedef unsigned short ffewhereLength_; -#define ffewhereLength_f_ "" -typedef unsigned long ffewhereLineNumber; /* Change FFEWHERE_lineMAX - too. */ -#define ffewhereLineNumber_f "l" -typedef struct _ffewhere_line_ *ffewhereLine; -typedef unsigned char ffewhereIndex; -#define ffewhereIndex_f "" -typedef ffewhereIndex ffewhereTrack[FFEWHERE_indexMAX * 2 - 2]; -typedef unsigned int ffewhereUses_; -#define ffewhereUses_f_ "" - -/* Include files needed by this one. */ - -#include "glimits.j" -#include "top.h" - -/* Structure definitions. */ - -struct _ffewhere_file_ - { - size_t length; - char text[1]; - }; - -struct _ffewhere_line_ - { - ffewhereLine next; - ffewhereLine previous; - ffewhereLineNumber line_num; - ffewhereUses_ uses; - ffewhereLength_ length; - char content[1]; - }; - -/* Global objects accessed by users of this module. */ - -extern struct _ffewhere_line_ ffewhere_unknown_line_; - -/* Declare functions with prototypes. */ - -void ffewhere_file_kill (ffewhereFile wf); -ffewhereFile ffewhere_file_new (char *name, size_t length); -void ffewhere_file_set (ffewhereFile wf, bool have_num, ffewhereLineNumber ln); -void ffewhere_init_1 (void); -char *ffewhere_line_content (ffewhereLine l); -ffewhereFile ffewhere_line_file (ffewhereLine l); -ffewhereLineNumber ffewhere_line_filelinenum (ffewhereLine l); -void ffewhere_line_kill (ffewhereLine l); -ffewhereLine ffewhere_line_new (ffewhereLineNumber ln); -ffewhereLine ffewhere_line_use (ffewhereLine wl); -void ffewhere_set_from_track (ffewhereLine *wol, ffewhereColumn *woc, - ffewhereLine wrl, ffewhereColumn wrc, ffewhereTrack wt, - ffewhereIndex i); -void ffewhere_track (ffewhereLine *wl, ffewhereColumn *wc, ffewhereTrack wt, - ffewhereIndex i, ffewhereLineNumber ln, ffewhereColumnNumber cn); -void ffewhere_track_clear (ffewhereTrack wt, ffewhereIndex length); -void ffewhere_track_copy (ffewhereTrack dwt, ffewhereTrack swt, - ffewhereIndex start, ffewhereIndex length); -void ffewhere_track_kill (ffewhereLine wrl, ffewhereColumn wrc, ffewhereTrack wt, - ffewhereIndex length); - -/* Define macros. */ - -#define ffewhere_column_is_unknown(c) (c == FFEWHERE_columnUNKNOWN) -#define ffewhere_column_kill(c) ((void) 0) -#define ffewhere_column_new(cn) (cn) -#define ffewhere_column_number(c) (c) -#define ffewhere_column_unknown() (FFEWHERE_columnUNKNOWN) -#define ffewhere_column_use(c) (c) -#define ffewhere_file_name(f) ((f)->text) -#define ffewhere_file_namelen(f) ((f)->length) -#define ffewhere_init_0() -#define ffewhere_init_2() -#define ffewhere_init_3() -#define ffewhere_init_4() -#define ffewhere_line_filename(l) (ffewhere_line_file(l)->text) -#define ffewhere_line_is_unknown(l) (l == FFEWHERE_lineUNKNOWN) -#define ffewhere_line_number(l) ((l)->line_num) -#define ffewhere_line_unknown() (FFEWHERE_lineUNKNOWN) -#define ffewhere_terminate_0() -#define ffewhere_terminate_1() -#define ffewhere_terminate_2() -#define ffewhere_terminate_3() -#define ffewhere_terminate_4() - -/* End of #include file. */ - -#endif diff --git a/gcc/frame.c b/gcc/frame.c deleted file mode 100755 index b5f643e..0000000 --- a/gcc/frame.c +++ /dev/null @@ -1,864 +0,0 @@ -/* Subroutines needed for unwinding stack frames for exception handling. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. - Contributed by Jason Merrill <jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* As a special exception, if you link this library with other files, - some of which are compiled with GCC, to produce an executable, - this library does not by itself cause the resulting executable - to be covered by the GNU General Public License. - This exception does not however invalidate any other reasons why - the executable file might be covered by the GNU General Public License. */ - -/* It is incorrect to include config.h here, because this file is being - compiled for the target, and hence definitions concerning only the host - do not apply. */ - -#include "tconfig.h" - -/* We disable this when inhibit_libc, so that gcc can still be built without - needing header files first. */ -/* ??? This is not a good solution, since prototypes may be required in - some cases for correct code. See also libgcc2.c. */ -#ifndef inhibit_libc -/* fixproto guarantees these system headers exist. */ -#include <stdlib.h> -#include <unistd.h> -#endif - -#include "defaults.h" - -#ifdef DWARF2_UNWIND_INFO -#include "dwarf2.h" -#include <stddef.h> -#include "frame.h" -#include "gthr.h" - -#ifdef __GTHREAD_MUTEX_INIT -static __gthread_mutex_t object_mutex = __GTHREAD_MUTEX_INIT; -#else -static __gthread_mutex_t object_mutex; -#endif - -/* Don't use `fancy_abort' here even if config.h says to use it. */ -#ifdef abort -#undef abort -#endif - -/* Some types used by the DWARF 2 spec. */ - -typedef int sword __attribute__ ((mode (SI))); -typedef unsigned int uword __attribute__ ((mode (SI))); -typedef unsigned int uaddr __attribute__ ((mode (pointer))); -typedef int saddr __attribute__ ((mode (pointer))); -typedef unsigned char ubyte; - -/* Terminology: - CIE - Common Information Element - FDE - Frame Descriptor Element - - There is one per function, and it describes where the function code - is located, and what the register lifetimes and stack layout are - within the function. - - The data structures are defined in the DWARF specfication, although - not in a very readable way (see LITERATURE). - - Every time an exception is thrown, the code needs to locate the FDE - for the current function, and starts to look for exception regions - from that FDE. This works in a two-level search: - a) in a linear search, find the shared image (i.e. DLL) containing - the PC - b) using the FDE table for that shared object, locate the FDE using - binary search (which requires the sorting). */ - -/* The first few fields of a CIE. The CIE_id field is 0 for a CIE, - to distinguish it from a valid FDE. FDEs are aligned to an addressing - unit boundary, but the fields within are unaligned. */ - -struct dwarf_cie { - uword length; - sword CIE_id; - ubyte version; - char augmentation[0]; -} __attribute__ ((packed, aligned (__alignof__ (void *)))); - -/* The first few fields of an FDE. */ - -struct dwarf_fde { - uword length; - sword CIE_delta; - void* pc_begin; - uaddr pc_range; -} __attribute__ ((packed, aligned (__alignof__ (void *)))); - -typedef struct dwarf_fde fde; - -/* Objects to be searched for frame unwind info. */ - -static struct object *objects; - -/* The information we care about from a CIE. */ - -struct cie_info { - char *augmentation; - void *eh_ptr; - int code_align; - int data_align; - unsigned ra_regno; -}; - -/* The current unwind state, plus a saved copy for DW_CFA_remember_state. */ - -struct frame_state_internal -{ - struct frame_state s; - struct frame_state_internal *saved_state; -}; - -/* This is undefined below if we need it to be an actual function. */ -#define init_object_mutex_once() - -#if __GTHREADS -#ifdef __GTHREAD_MUTEX_INIT_FUNCTION - -/* Helper for init_object_mutex_once. */ - -static void -init_object_mutex (void) -{ - __GTHREAD_MUTEX_INIT_FUNCTION (&object_mutex); -} - -/* Call this to arrange to initialize the object mutex. */ - -#undef init_object_mutex_once -static void -init_object_mutex_once (void) -{ - static __gthread_once_t once = __GTHREAD_ONCE_INIT; - __gthread_once (&once, init_object_mutex); -} - -#endif /* __GTHREAD_MUTEX_INIT_FUNCTION */ -#endif /* __GTHREADS */ - -/* Decode the unsigned LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. */ - -static void * -decode_uleb128 (unsigned char *buf, unsigned *r) -{ - unsigned shift = 0; - unsigned result = 0; - - while (1) - { - unsigned byte = *buf++; - result |= (byte & 0x7f) << shift; - if ((byte & 0x80) == 0) - break; - shift += 7; - } - *r = result; - return buf; -} - -/* Decode the signed LEB128 constant at BUF into the variable pointed to - by R, and return the new value of BUF. */ - -static void * -decode_sleb128 (unsigned char *buf, int *r) -{ - unsigned shift = 0; - unsigned result = 0; - unsigned byte; - - while (1) - { - byte = *buf++; - result |= (byte & 0x7f) << shift; - shift += 7; - if ((byte & 0x80) == 0) - break; - } - if (shift < (sizeof (*r) * 8) && (byte & 0x40) != 0) - result |= - (1 << shift); - - *r = result; - return buf; -} - -/* Read unaligned data from the instruction buffer. */ - -union unaligned { - void *p; - unsigned b2 __attribute__ ((mode (HI))); - unsigned b4 __attribute__ ((mode (SI))); - unsigned b8 __attribute__ ((mode (DI))); -} __attribute__ ((packed)); -static inline void * -read_pointer (void *p) -{ union unaligned *up = p; return up->p; } -static inline unsigned -read_1byte (void *p) -{ return *(unsigned char *)p; } -static inline unsigned -read_2byte (void *p) -{ union unaligned *up = p; return up->b2; } -static inline unsigned -read_4byte (void *p) -{ union unaligned *up = p; return up->b4; } -static inline unsigned long -read_8byte (void *p) -{ union unaligned *up = p; return up->b8; } - -/* Ordering function for FDEs. Functions can't overlap, so we just compare - their starting addresses. */ - -static inline saddr -fde_compare (fde *x, fde *y) -{ - return (saddr)x->pc_begin - (saddr)y->pc_begin; -} - -/* Return the address of the FDE after P. */ - -static inline fde * -next_fde (fde *p) -{ - return (fde *)(((char *)p) + p->length + sizeof (p->length)); -} - -/* Sorting an array of FDEs by address. - (Ideally we would have the linker sort the FDEs so we don't have to do - it at run time. But the linkers are not yet prepared for this.) */ - -/* This is a special mix of insertion sort and heap sort, optimized for - the data sets that actually occur. They look like - 101 102 103 127 128 105 108 110 190 111 115 119 125 160 126 129 130. - I.e. a linearly increasing sequence (coming from functions in the text - section), with additionally a few unordered elements (coming from functions - in gnu_linkonce sections) whose values are higher than the values in the - surrounding linear sequence (but not necessarily higher than the values - at the end of the linear sequence!). - The worst-case total run time is O(N) + O(n log (n)), where N is the - total number of FDEs and n is the number of erratic ones. */ - -typedef struct fde_vector -{ - fde **array; - size_t count; -} fde_vector; - -typedef struct fde_accumulator -{ - fde_vector linear; - fde_vector erratic; -} fde_accumulator; - -static inline void -start_fde_sort (fde_accumulator *accu, size_t count) -{ - accu->linear.array = (fde **) malloc (sizeof (fde *) * count); - accu->erratic.array = (fde **) malloc (sizeof (fde *) * count); - accu->linear.count = 0; - accu->erratic.count = 0; -} - -static inline void -fde_insert (fde_accumulator *accu, fde *this_fde) -{ - accu->linear.array[accu->linear.count++] = this_fde; -} - -/* Split LINEAR into a linear sequence with low values and an erratic - sequence with high values, put the linear one (of longest possible - length) into LINEAR and the erratic one into ERRATIC. This is O(N). */ -static inline void -fde_split (fde_vector *linear, fde_vector *erratic) -{ - size_t count = linear->count; - size_t linear_max = (size_t) -1; - size_t previous_max[count]; - size_t i, j; - - for (i = 0; i < count; i++) - { - for (j = linear_max; - j != (size_t) -1 - && fde_compare (linear->array[i], linear->array[j]) < 0; - j = previous_max[j]) - { - erratic->array[erratic->count++] = linear->array[j]; - linear->array[j] = (fde *) NULL; - } - previous_max[i] = j; - linear_max = i; - } - - for (i = 0, j = 0; i < count; i++) - if (linear->array[i] != (fde *) NULL) - linear->array[j++] = linear->array[i]; - linear->count = j; -} - -/* This is O(n log(n)). BSD/OS defines heapsort in stdlib.h, so we must - use a name that does not conflict. */ -static inline void -frame_heapsort (fde_vector *erratic) -{ - /* For a description of this algorithm, see: - Samuel P. Harbison, Guy L. Steele Jr.: C, a reference manual, 2nd ed., - p. 60-61. */ - fde ** a = erratic->array; - /* A portion of the array is called a "heap" if for all i>=0: - If i and 2i+1 are valid indices, then a[i] >= a[2i+1]. - If i and 2i+2 are valid indices, then a[i] >= a[2i+2]. */ -#define SWAP(x,y) do { fde * tmp = x; x = y; y = tmp; } while (0) - size_t n = erratic->count; - size_t m = n; - size_t i; - - while (m > 0) - { - /* Invariant: a[m..n-1] is a heap. */ - m--; - for (i = m; 2*i+1 < n; ) - { - if (2*i+2 < n - && fde_compare (a[2*i+2], a[2*i+1]) > 0 - && fde_compare (a[2*i+2], a[i]) > 0) - { - SWAP (a[i], a[2*i+2]); - i = 2*i+2; - } - else if (fde_compare (a[2*i+1], a[i]) > 0) - { - SWAP (a[i], a[2*i+1]); - i = 2*i+1; - } - else - break; - } - } - while (n > 1) - { - /* Invariant: a[0..n-1] is a heap. */ - n--; - SWAP (a[0], a[n]); - for (i = 0; 2*i+1 < n; ) - { - if (2*i+2 < n - && fde_compare (a[2*i+2], a[2*i+1]) > 0 - && fde_compare (a[2*i+2], a[i]) > 0) - { - SWAP (a[i], a[2*i+2]); - i = 2*i+2; - } - else if (fde_compare (a[2*i+1], a[i]) > 0) - { - SWAP (a[i], a[2*i+1]); - i = 2*i+1; - } - else - break; - } - } -#undef SWAP -} - -/* Merge V1 and V2, both sorted, and put the result into V1. */ -static void -fde_merge (fde_vector *v1, const fde_vector *v2) -{ - size_t i1, i2; - fde * fde2; - - i2 = v2->count; - if (i2 > 0) - { - i1 = v1->count; - do { - i2--; - fde2 = v2->array[i2]; - while (i1 > 0 && fde_compare (v1->array[i1-1], fde2) > 0) - { - v1->array[i1+i2] = v1->array[i1-1]; - i1--; - } - v1->array[i1+i2] = fde2; - } while (i2 > 0); - v1->count += v2->count; - } -} - -static fde ** -end_fde_sort (fde_accumulator *accu, size_t count) -{ - if (accu->linear.count != count) - abort (); - fde_split (&accu->linear, &accu->erratic); - if (accu->linear.count + accu->erratic.count != count) - abort (); - frame_heapsort (&accu->erratic); - fde_merge (&accu->linear, &accu->erratic); - free (accu->erratic.array); - return accu->linear.array; -} - -static size_t -count_fdes (fde *this_fde) -{ - size_t count; - - for (count = 0; this_fde->length != 0; this_fde = next_fde (this_fde)) - { - /* Skip CIEs and linked once FDE entries. */ - if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) - continue; - - ++count; - } - - return count; -} - -static void -add_fdes (fde *this_fde, fde_accumulator *accu, void **beg_ptr, void **end_ptr) -{ - void *pc_begin = *beg_ptr; - void *pc_end = *end_ptr; - - for (; this_fde->length != 0; this_fde = next_fde (this_fde)) - { - /* Skip CIEs and linked once FDE entries. */ - if (this_fde->CIE_delta == 0 || this_fde->pc_begin == 0) - continue; - - fde_insert (accu, this_fde); - - if (this_fde->pc_begin < pc_begin) - pc_begin = this_fde->pc_begin; - if (this_fde->pc_begin + this_fde->pc_range > pc_end) - pc_end = this_fde->pc_begin + this_fde->pc_range; - } - - *beg_ptr = pc_begin; - *end_ptr = pc_end; -} - -/* Set up a sorted array of pointers to FDEs for a loaded object. We - count up the entries before allocating the array because it's likely to - be faster. */ - -static void -frame_init (struct object* ob) -{ - size_t count; - fde_accumulator accu; - void *pc_begin, *pc_end; - - if (ob->fde_array) - { - fde **p = ob->fde_array; - for (count = 0; *p; ++p) - count += count_fdes (*p); - } - else - count = count_fdes (ob->fde_begin); - - ob->count = count; - - start_fde_sort (&accu, count); - pc_begin = (void*)(uaddr)-1; - pc_end = 0; - - if (ob->fde_array) - { - fde **p = ob->fde_array; - for (; *p; ++p) - add_fdes (*p, &accu, &pc_begin, &pc_end); - } - else - add_fdes (ob->fde_begin, &accu, &pc_begin, &pc_end); - - ob->fde_array = end_fde_sort (&accu, count); - ob->pc_begin = pc_begin; - ob->pc_end = pc_end; -} - -/* Return a pointer to the FDE for the function containing PC. */ - -static fde * -find_fde (void *pc) -{ - struct object *ob; - size_t lo, hi; - - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); - - for (ob = objects; ob; ob = ob->next) - { - if (ob->pc_begin == 0) - frame_init (ob); - if (pc >= ob->pc_begin && pc < ob->pc_end) - break; - } - - __gthread_mutex_unlock (&object_mutex); - - if (ob == 0) - return 0; - - /* Standard binary search algorithm. */ - for (lo = 0, hi = ob->count; lo < hi; ) - { - size_t i = (lo + hi) / 2; - fde *f = ob->fde_array[i]; - - if (pc < f->pc_begin) - hi = i; - else if (pc >= f->pc_begin + f->pc_range) - lo = i + 1; - else - return f; - } - - return 0; -} - -static inline struct dwarf_cie * -get_cie (fde *f) -{ - return ((void *)&f->CIE_delta) - f->CIE_delta; -} - -/* Extract any interesting information from the CIE for the translation - unit F belongs to. */ - -static void * -extract_cie_info (fde *f, struct cie_info *c) -{ - void *p; - int i; - - c->augmentation = get_cie (f)->augmentation; - - if (strcmp (c->augmentation, "") != 0 - && strcmp (c->augmentation, "eh") != 0 - && c->augmentation[0] != 'z') - return 0; - - p = c->augmentation + strlen (c->augmentation) + 1; - - if (strcmp (c->augmentation, "eh") == 0) - { - c->eh_ptr = read_pointer (p); - p += sizeof (void *); - } - else - c->eh_ptr = 0; - - p = decode_uleb128 (p, &c->code_align); - p = decode_sleb128 (p, &c->data_align); - c->ra_regno = *(unsigned char *)p++; - - /* If the augmentation starts with 'z', we now see the length of the - augmentation fields. */ - if (c->augmentation[0] == 'z') - { - p = decode_uleb128 (p, &i); - p += i; - } - - return p; -} - -/* Decode one instruction's worth of DWARF 2 call frame information. - Used by __frame_state_for. Takes pointers P to the instruction to - decode, STATE to the current register unwind information, INFO to the - current CIE information, and PC to the current PC value. Returns a - pointer to the next instruction. */ - -static void * -execute_cfa_insn (void *p, struct frame_state_internal *state, - struct cie_info *info, void **pc) -{ - unsigned insn = *(unsigned char *)p++; - unsigned reg; - int offset; - - if (insn & DW_CFA_advance_loc) - *pc += ((insn & 0x3f) * info->code_align); - else if (insn & DW_CFA_offset) - { - reg = (insn & 0x3f); - p = decode_uleb128 (p, &offset); - offset *= info->data_align; - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = offset; - } - else if (insn & DW_CFA_restore) - { - reg = (insn & 0x3f); - state->s.saved[reg] = REG_UNSAVED; - } - else switch (insn) - { - case DW_CFA_set_loc: - *pc = read_pointer (p); - p += sizeof (void *); - break; - case DW_CFA_advance_loc1: - *pc += read_1byte (p); - p += 1; - break; - case DW_CFA_advance_loc2: - *pc += read_2byte (p); - p += 2; - break; - case DW_CFA_advance_loc4: - *pc += read_4byte (p); - p += 4; - break; - - case DW_CFA_offset_extended: - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, &offset); - offset *= info->data_align; - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = offset; - break; - case DW_CFA_restore_extended: - p = decode_uleb128 (p, ®); - state->s.saved[reg] = REG_UNSAVED; - break; - - case DW_CFA_undefined: - case DW_CFA_same_value: - case DW_CFA_nop: - break; - - case DW_CFA_register: - { - unsigned reg2; - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, ®2); - state->s.saved[reg] = REG_SAVED_REG; - state->s.reg_or_offset[reg] = reg2; - } - break; - - case DW_CFA_def_cfa: - p = decode_uleb128 (p, ®); - p = decode_uleb128 (p, &offset); - state->s.cfa_reg = reg; - state->s.cfa_offset = offset; - break; - case DW_CFA_def_cfa_register: - p = decode_uleb128 (p, ®); - state->s.cfa_reg = reg; - break; - case DW_CFA_def_cfa_offset: - p = decode_uleb128 (p, &offset); - state->s.cfa_offset = offset; - break; - - case DW_CFA_remember_state: - { - struct frame_state_internal *save = - (struct frame_state_internal *) - malloc (sizeof (struct frame_state_internal)); - memcpy (save, state, sizeof (struct frame_state_internal)); - state->saved_state = save; - } - break; - case DW_CFA_restore_state: - { - struct frame_state_internal *save = state->saved_state; - memcpy (state, save, sizeof (struct frame_state_internal)); - free (save); - } - break; - - /* FIXME: Hardcoded for SPARC register window configuration. */ - case DW_CFA_GNU_window_save: - for (reg = 16; reg < 32; ++reg) - { - state->s.saved[reg] = REG_SAVED_OFFSET; - state->s.reg_or_offset[reg] = (reg - 16) * sizeof (void *); - } - break; - - case DW_CFA_GNU_args_size: - p = decode_uleb128 (p, &offset); - state->s.args_size = offset; - break; - - default: - abort (); - } - return p; -} - -/* Called from crtbegin.o to register the unwind info for an object. */ - -void -__register_frame_info (void *begin, struct object *ob) -{ - ob->fde_begin = begin; - - ob->pc_begin = ob->pc_end = 0; - ob->fde_array = 0; - ob->count = 0; - - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); - - ob->next = objects; - objects = ob; - - __gthread_mutex_unlock (&object_mutex); -} - -void -__register_frame (void *begin) -{ - struct object *ob = (struct object *) malloc (sizeof (struct object)); - __register_frame_info (begin, ob); -} - -/* Similar, but BEGIN is actually a pointer to a table of unwind entries - for different translation units. Called from the file generated by - collect2. */ - -void -__register_frame_info_table (void *begin, struct object *ob) -{ - ob->fde_begin = begin; - ob->fde_array = begin; - - ob->pc_begin = ob->pc_end = 0; - ob->count = 0; - - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); - - ob->next = objects; - objects = ob; - - __gthread_mutex_unlock (&object_mutex); -} - -void -__register_frame_table (void *begin) -{ - struct object *ob = (struct object *) malloc (sizeof (struct object)); - __register_frame_info_table (begin, ob); -} - -/* Called from crtbegin.o to deregister the unwind info for an object. */ - -void * -__deregister_frame_info (void *begin) -{ - struct object **p; - - init_object_mutex_once (); - __gthread_mutex_lock (&object_mutex); - - p = &objects; - while (*p) - { - if ((*p)->fde_begin == begin) - { - struct object *ob = *p; - *p = (*p)->next; - - /* If we've run init_frame for this object, free the FDE array. */ - if (ob->pc_begin) - free (ob->fde_array); - - __gthread_mutex_unlock (&object_mutex); - return (void *) ob; - } - p = &((*p)->next); - } - - __gthread_mutex_unlock (&object_mutex); - abort (); -} - -void -__deregister_frame (void *begin) -{ - free (__deregister_frame_info (begin)); -} - -/* Called from __throw to find the registers to restore for a given - PC_TARGET. The caller should allocate a local variable of `struct - frame_state' (declared in frame.h) and pass its address to STATE_IN. */ - -struct frame_state * -__frame_state_for (void *pc_target, struct frame_state *state_in) -{ - fde *f; - void *insn, *end, *pc; - struct cie_info info; - struct frame_state_internal state; - - f = find_fde (pc_target); - if (f == 0) - return 0; - - insn = extract_cie_info (f, &info); - if (insn == 0) - return 0; - - memset (&state, 0, sizeof (state)); - state.s.retaddr_column = info.ra_regno; - state.s.eh_ptr = info.eh_ptr; - - /* First decode all the insns in the CIE. */ - end = next_fde ((fde*) get_cie (f)); - while (insn < end) - insn = execute_cfa_insn (insn, &state, &info, 0); - - insn = ((fde *)f) + 1; - - if (info.augmentation[0] == 'z') - { - int i; - insn = decode_uleb128 (insn, &i); - insn += i; - } - - /* Then the insns in the FDE up to our target PC. */ - end = next_fde (f); - pc = f->pc_begin; - while (insn < end && pc <= pc_target) - insn = execute_cfa_insn (insn, &state, &info, &pc); - - memcpy (state_in, &state.s, sizeof (state.s)); - return state_in; -} -#endif /* DWARF2_UNWIND_INFO */ diff --git a/gcc/frame.h b/gcc/frame.h deleted file mode 100755 index 1ae0dea..0000000 --- a/gcc/frame.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Header file for unwinding stack frames for exception handling. */ -/* Compile this one with gcc. */ -/* Copyright (C) 1997, 1998 Free Software Foundation, Inc. - Contributed by Jason Merrill <jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -typedef struct frame_state -{ - void *cfa; - void *eh_ptr; - long cfa_offset; - long args_size; - long reg_or_offset[FIRST_PSEUDO_REGISTER+1]; - unsigned short cfa_reg; - unsigned short retaddr_column; - char saved[FIRST_PSEUDO_REGISTER+1]; -} frame_state; - -/* Values for 'saved' above. */ -#define REG_UNSAVED 0 -#define REG_SAVED_OFFSET 1 -#define REG_SAVED_REG 2 - -/* The representation for an "object" to be searched for frame unwind info. - For targets with named sections, one object is an executable or shared - library; for other targets, one object is one translation unit. - - A copy of this structure declaration is printed by collect2.c; - keep the copies synchronized! */ - -struct object { - void *pc_begin; - void *pc_end; - struct dwarf_fde *fde_begin; - struct dwarf_fde **fde_array; - size_t count; - struct object *next; -}; - -extern void __register_frame (void * ); -extern void __register_frame_table (void *); -extern void __deregister_frame (void *); - -/* Called either from crtbegin.o or a static constructor to register the - unwind info for an object or translation unit, respectively. */ - -extern void __register_frame_info (void *, struct object *); - -/* Similar, but BEGIN is actually a pointer to a table of unwind entries - for different translation units. Called from the file generated by - collect2. */ -extern void __register_frame_info_table (void *, struct object *); - -/* Called from crtend.o to deregister the unwind info for an object. */ - -extern void *__deregister_frame_info (void *); - -/* Called from __throw to find the registers to restore for a given - PC_TARGET. The caller should allocate a local variable of `struct - frame_state' (declared in frame.h) and pass its address to STATE_IN. - Returns NULL on failure, otherwise returns STATE_IN. */ - -extern struct frame_state *__frame_state_for (void *, struct frame_state *); diff --git a/gcc/gbl-ctors.h b/gcc/gbl-ctors.h deleted file mode 100755 index 86b1c0e..0000000 --- a/gcc/gbl-ctors.h +++ /dev/null @@ -1,92 +0,0 @@ -/* Definitions relating to the special __do_global_init function used - for getting g++ file-scope static objects constructed. This file - will get included either by libgcc2.c (for systems that don't support - a .init section) or by crtstuff.c (for those that do). - Copyright (C) 1991, 1995, 1996, 1998 Free Software Foundation, Inc. - Contributed by Ron Guilmette (rfg@segfault.us.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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file contains definitions and declarations of things - relating to the normal start-up-time invocation of C++ - file-scope static object constructors. These declarations - and definitions are used by *both* libgcc2.c and by crtstuff.c. - - Note that this file should only be compiled with GCC. -*/ - -#ifdef NEED_ATEXIT -#ifndef HAVE_ATEXIT -#define HAVE_ATEXIT 1 /* Take it from libgcc2.c */ -#endif -#endif - -#ifdef HAVE_ATEXIT -#if defined (WINNT) || defined (NEED_ATEXIT) -extern int atexit (void (*) (void)); -#endif -#define ON_EXIT(FUNC,ARG) atexit ((FUNC)) -#else -#ifdef sun -extern int on_exit (void *, void *); /* The man page says it returns int. */ -#define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG)) -#endif -#endif - -/* Declare a pointer to void function type. */ - -typedef void (*func_ptr) (void); - -/* Declare the set of symbols use as begin and end markers for the lists - of global object constructors and global object destructors. */ - -extern func_ptr __CTOR_LIST__[]; -extern func_ptr __DTOR_LIST__[]; - -/* Declare the routine which need to get invoked at program exit time. */ - -extern void __do_global_dtors (void); - -/* Define a macro with the code which needs to be executed at program - start-up time. This macro is used in two places in crtstuff.c (for - systems which support a .init section) and in one place in libgcc2.c - (for those system which do *not* support a .init section). For all - three places where this code might appear, it must be identical, so - we define it once here as a macro to avoid various instances getting - out-of-sync with one another. */ - -/* Some systems place the number of pointers - in the first word of the table. - On other systems, that word is -1. - In all cases, the table is null-terminated. - If the length is not recorded, count up to the null. */ - -/* Some systems use a different strategy for finding the ctors. - For example, svr3. */ -#ifndef DO_GLOBAL_CTORS_BODY -#define DO_GLOBAL_CTORS_BODY \ -do { \ - unsigned long nptrs = (unsigned long) __CTOR_LIST__[0]; \ - unsigned i; \ - if (nptrs == (unsigned long)-1) \ - for (nptrs = 0; __CTOR_LIST__[nptrs + 1] != 0; nptrs++); \ - for (i = nptrs; i >= 1; i--) \ - __CTOR_LIST__[i] (); \ -} while (0) -#endif - @@ -460,7 +460,7 @@ proper position among the other output files. */ #endif #ifndef LINKER_NAME -#define LINKER_NAME "collect2" +#define LINKER_NAME "ld" #endif static char *cpp_spec = CPP_SPEC; @@ -5523,13 +5523,6 @@ main (argc, argv) { int tmp = execution_count; - /* We'll use ld if we can't find collect2. */ - if (! strcmp (linker_name_spec, "collect2")) - { - char *s = find_a_file (&exec_prefixes, "collect2", X_OK); - if (s == NULL) - linker_name_spec = "ld"; - } /* Rebuild the COMPILER_PATH and LIBRARY_PATH environment variables for collect. */ putenv_from_prefixes (&exec_prefixes, "COMPILER_PATH="); diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 5eecd5d..c4c48f9 100755 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -36,17 +36,10 @@ Boston, MA 02111-1307, USA. */ needing header files first. */ /* ??? This is not a good solution, since prototypes may be required in some cases for correct code. See also frame.c. */ -#ifndef inhibit_libc -/* fixproto guarantees these system headers exist. */ -#include <stdlib.h> -#include <unistd.h> -#endif #include "machmode.h" #include "defaults.h" -#ifndef L_trampoline #include <stddef.h> -#endif /* Don't use `fancy_abort' here even if config.h says to use it. */ #ifdef abort @@ -60,9 +53,6 @@ Boston, MA 02111-1307, USA. */ /* In a cross-compilation situation, default to inhibiting compilation of routines that use libc. */ -#if defined(CROSS_COMPILE) && !defined(inhibit_libc) -#define inhibit_libc -#endif /* Permit the tm.h file to select the endianness to use just for this file. This is used when the endianness is determined when the @@ -154,7 +144,7 @@ extern DItype __fixunsxfdi (XFtype a); #if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128 extern DItype __fixunstfdi (TFtype a); #endif - + #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3) #if defined (L_divdi3) || defined (L_moddi3) static inline @@ -173,7 +163,7 @@ __negdi2 (DItype u) return w.ll; } #endif - + /* Unless shift functions are defined whith full ANSI prototypes, parameter b will be promoted to int if word_type is smaller than an int. */ #ifdef L_lshrdi3 @@ -266,7 +256,7 @@ __ashrdi3 (DItype u, word_type b) return w.ll; } #endif - + #ifdef L_ffsdi2 DItype __ffsdi2 (DItype u) @@ -286,7 +276,7 @@ __ffsdi2 (DItype u) return w.ll; } #endif - + #ifdef L_muldi3 DItype __muldi3 (DItype u, DItype v) @@ -304,7 +294,7 @@ __muldi3 (DItype u, DItype v) return w.ll; } #endif - + #ifdef L_udiv_w_sdiv #if defined (sdiv_qrnnd) USItype @@ -415,7 +405,7 @@ __udiv_w_sdiv (USItype *rp __attribute__ ((__unused__)), } #endif #endif - + #if (defined (L_udivdi3) || defined (L_divdi3) || \ defined (L_umoddi3) || defined (L_moddi3)) #define L_udivmoddi4 @@ -731,7 +721,7 @@ __udivdi3 (UDItype n, UDItype d) return __udivmoddi4 (n, d, (UDItype *) 0); } #endif - + #ifdef L_cmpdi2 word_type __cmpdi2 (DItype a, DItype b) @@ -771,7 +761,7 @@ __ucmpdi2 (DItype a, DItype b) return 1; } #endif - + #if defined(L_fixunstfdi) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128) #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) @@ -1134,7 +1124,7 @@ __fixunssfsi (SFtype a) return (SItype) a; } #endif - + /* From here on down, the routines use normal data types. */ #define SItype bogus_type @@ -1151,2853 +1141,3 @@ __fixunssfsi (SFtype a) #undef unsigned #undef float #undef double - -#ifdef L__gcc_bcmp - -/* Like bcmp except the sign is meaningful. - Result is negative if S1 is less than S2, - positive if S1 is greater, 0 if S1 and S2 are equal. */ - -int -__gcc_bcmp (unsigned char *s1, unsigned char *s2, size_t size) -{ - while (size > 0) - { - unsigned char c1 = *s1++, c2 = *s2++; - if (c1 != c2) - return c1 - c2; - size--; - } - return 0; -} - -#endif - -#ifdef L__dummy -void -__dummy () {} -#endif - -#ifdef L_varargs -#ifdef __i860__ -#if defined(__svr4__) || defined(__alliant__) - asm (" .text"); - asm (" .align 4"); - -/* The Alliant needs the added underscore. */ - asm (".globl __builtin_saveregs"); -asm ("__builtin_saveregs:"); - asm (".globl ___builtin_saveregs"); -asm ("___builtin_saveregs:"); - - asm (" andnot 0x0f,%sp,%sp"); /* round down to 16-byte boundary */ - asm (" adds -96,%sp,%sp"); /* allocate stack space for reg save - area and also for a new va_list - structure */ - /* Save all argument registers in the arg reg save area. The - arg reg save area must have the following layout (according - to the svr4 ABI): - - struct { - union { - float freg[8]; - double dreg[4]; - } float_regs; - long ireg[12]; - }; - */ - - asm (" fst.q %f8, 0(%sp)"); /* save floating regs (f8-f15) */ - asm (" fst.q %f12,16(%sp)"); - - asm (" st.l %r16,32(%sp)"); /* save integer regs (r16-r27) */ - asm (" st.l %r17,36(%sp)"); - asm (" st.l %r18,40(%sp)"); - asm (" st.l %r19,44(%sp)"); - asm (" st.l %r20,48(%sp)"); - asm (" st.l %r21,52(%sp)"); - asm (" st.l %r22,56(%sp)"); - asm (" st.l %r23,60(%sp)"); - asm (" st.l %r24,64(%sp)"); - asm (" st.l %r25,68(%sp)"); - asm (" st.l %r26,72(%sp)"); - asm (" st.l %r27,76(%sp)"); - - asm (" adds 80,%sp,%r16"); /* compute the address of the new - va_list structure. Put in into - r16 so that it will be returned - to the caller. */ - - /* Initialize all fields of the new va_list structure. This - structure looks like: - - typedef struct { - unsigned long ireg_used; - unsigned long freg_used; - long *reg_base; - long *mem_ptr; - } va_list; - */ - - asm (" st.l %r0, 0(%r16)"); /* nfixed */ - asm (" st.l %r0, 4(%r16)"); /* nfloating */ - asm (" st.l %sp, 8(%r16)"); /* __va_ctl points to __va_struct. */ - asm (" bri %r1"); /* delayed return */ - asm (" st.l %r28,12(%r16)"); /* pointer to overflow args */ - -#else /* not __svr4__ */ -#if defined(__PARAGON__) - /* - * we'll use SVR4-ish varargs but need SVR3.2 assembler syntax, - * and we stand a better chance of hooking into libraries - * compiled by PGI. [andyp@ssd.intel.com] - */ - asm (" .text"); - asm (" .align 4"); - asm (".globl __builtin_saveregs"); -asm ("__builtin_saveregs:"); - asm (".globl ___builtin_saveregs"); -asm ("___builtin_saveregs:"); - - asm (" andnot 0x0f,sp,sp"); /* round down to 16-byte boundary */ - asm (" adds -96,sp,sp"); /* allocate stack space for reg save - area and also for a new va_list - structure */ - /* Save all argument registers in the arg reg save area. The - arg reg save area must have the following layout (according - to the svr4 ABI): - - struct { - union { - float freg[8]; - double dreg[4]; - } float_regs; - long ireg[12]; - }; - */ - - asm (" fst.q f8, 0(sp)"); - asm (" fst.q f12,16(sp)"); - asm (" st.l r16,32(sp)"); - asm (" st.l r17,36(sp)"); - asm (" st.l r18,40(sp)"); - asm (" st.l r19,44(sp)"); - asm (" st.l r20,48(sp)"); - asm (" st.l r21,52(sp)"); - asm (" st.l r22,56(sp)"); - asm (" st.l r23,60(sp)"); - asm (" st.l r24,64(sp)"); - asm (" st.l r25,68(sp)"); - asm (" st.l r26,72(sp)"); - asm (" st.l r27,76(sp)"); - - asm (" adds 80,sp,r16"); /* compute the address of the new - va_list structure. Put in into - r16 so that it will be returned - to the caller. */ - - /* Initialize all fields of the new va_list structure. This - structure looks like: - - typedef struct { - unsigned long ireg_used; - unsigned long freg_used; - long *reg_base; - long *mem_ptr; - } va_list; - */ - - asm (" st.l r0, 0(r16)"); /* nfixed */ - asm (" st.l r0, 4(r16)"); /* nfloating */ - asm (" st.l sp, 8(r16)"); /* __va_ctl points to __va_struct. */ - asm (" bri r1"); /* delayed return */ - asm (" st.l r28,12(r16)"); /* pointer to overflow args */ -#else /* not __PARAGON__ */ - asm (" .text"); - asm (" .align 4"); - - asm (".globl ___builtin_saveregs"); - asm ("___builtin_saveregs:"); - asm (" mov sp,r30"); - asm (" andnot 0x0f,sp,sp"); - asm (" adds -96,sp,sp"); /* allocate sufficient space on the stack */ - -/* Fill in the __va_struct. */ - asm (" st.l r16, 0(sp)"); /* save integer regs (r16-r27) */ - asm (" st.l r17, 4(sp)"); /* int fixed[12] */ - asm (" st.l r18, 8(sp)"); - asm (" st.l r19,12(sp)"); - asm (" st.l r20,16(sp)"); - asm (" st.l r21,20(sp)"); - asm (" st.l r22,24(sp)"); - asm (" st.l r23,28(sp)"); - asm (" st.l r24,32(sp)"); - asm (" st.l r25,36(sp)"); - asm (" st.l r26,40(sp)"); - asm (" st.l r27,44(sp)"); - - asm (" fst.q f8, 48(sp)"); /* save floating regs (f8-f15) */ - asm (" fst.q f12,64(sp)"); /* int floating[8] */ - -/* Fill in the __va_ctl. */ - asm (" st.l sp, 80(sp)"); /* __va_ctl points to __va_struct. */ - asm (" st.l r28,84(sp)"); /* pointer to more args */ - asm (" st.l r0, 88(sp)"); /* nfixed */ - asm (" st.l r0, 92(sp)"); /* nfloating */ - - asm (" adds 80,sp,r16"); /* return address of the __va_ctl. */ - asm (" bri r1"); - asm (" mov r30,sp"); - /* recover stack and pass address to start - of data. */ -#endif /* not __PARAGON__ */ -#endif /* not __svr4__ */ -#else /* not __i860__ */ -#ifdef __sparc__ - asm (".global __builtin_saveregs"); - asm ("__builtin_saveregs:"); - asm (".global ___builtin_saveregs"); - asm ("___builtin_saveregs:"); -#ifdef NEED_PROC_COMMAND - asm (".proc 020"); -#endif - asm ("st %i0,[%fp+68]"); - asm ("st %i1,[%fp+72]"); - asm ("st %i2,[%fp+76]"); - asm ("st %i3,[%fp+80]"); - asm ("st %i4,[%fp+84]"); - asm ("retl"); - asm ("st %i5,[%fp+88]"); -#ifdef NEED_TYPE_COMMAND - asm (".type __builtin_saveregs,#function"); - asm (".size __builtin_saveregs,.-__builtin_saveregs"); -#endif -#else /* not __sparc__ */ -#if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__) - - asm (" .text"); -#ifdef __mips16 - asm (" .set nomips16"); -#endif - asm (" .ent __builtin_saveregs"); - asm (" .globl __builtin_saveregs"); - asm ("__builtin_saveregs:"); - asm (" sw $4,0($30)"); - asm (" sw $5,4($30)"); - asm (" sw $6,8($30)"); - asm (" sw $7,12($30)"); - asm (" j $31"); - asm (" .end __builtin_saveregs"); -#else /* not __mips__, etc. */ - -void * -__builtin_saveregs () -{ - abort (); -} - -#endif /* not __mips__ */ -#endif /* not __sparc__ */ -#endif /* not __i860__ */ -#endif - -#ifdef L_eprintf -#ifndef inhibit_libc - -#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ -#include <stdio.h> -/* This is used by the `assert' macro. */ -extern void __eprintf (const char *, const char *, unsigned int, const char *) - __attribute__ ((__noreturn__)); - -void -__eprintf (const char *string, const char *expression, - unsigned int line, const char *filename) -{ - fprintf (stderr, string, expression, line, filename); - fflush (stderr); - abort (); -} - -#endif -#endif - -#ifdef L_bb - -/* Structure emitted by -a */ -struct bb -{ - long zero_word; - const char *filename; - long *counts; - long ncounts; - struct bb *next; - const unsigned long *addresses; - - /* Older GCC's did not emit these fields. */ - long nwords; - const char **functions; - const long *line_nums; - const char **filenames; - char *flags; -}; - -#ifdef BLOCK_PROFILER_CODE -BLOCK_PROFILER_CODE -#else -#ifndef inhibit_libc - -/* Simple minded basic block profiling output dumper for - systems that don't provide tcov support. At present, - it requires atexit and stdio. */ - -#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ -#include <stdio.h> -char *ctime (); - -#include "gbl-ctors.h" -#include "gcov-io.h" -#include <string.h> - -static struct bb *bb_head; - -/* Return the number of digits needed to print a value */ -/* __inline__ */ static int num_digits (long value, int base) -{ - int minus = (value < 0 && base != 16); - unsigned long v = (minus) ? -value : value; - int ret = minus; - - do - { - v /= base; - ret++; - } - while (v); - - return ret; -} - -void -__bb_exit_func (void) -{ - FILE *da_file, *file; - long time_value; - int i; - - if (bb_head == 0) - return; - - i = strlen (bb_head->filename) - 3; - - if (!strcmp (bb_head->filename+i, ".da")) - { - /* Must be -fprofile-arcs not -a. - Dump data in a form that gcov expects. */ - - struct bb *ptr; - - for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) - { - /* If the file exists, and the number of counts in it is the same, - then merge them in. */ - - if ((da_file = fopen (ptr->filename, "r")) != 0) - { - long n_counts = 0; - - if (__read_long (&n_counts, da_file, 8) != 0) - { - fprintf (stderr, "arc profiling: Can't read output file %s.\n", - ptr->filename); - continue; - } - - if (n_counts == ptr->ncounts) - { - int i; - - for (i = 0; i < n_counts; i++) - { - long v = 0; - - if (__read_long (&v, da_file, 8) != 0) - { - fprintf (stderr, "arc profiling: Can't read output file %s.\n", - ptr->filename); - break; - } - ptr->counts[i] += v; - } - } - - if (fclose (da_file) == EOF) - fprintf (stderr, "arc profiling: Error closing output file %s.\n", - ptr->filename); - } - if ((da_file = fopen (ptr->filename, "w")) == 0) - { - fprintf (stderr, "arc profiling: Can't open output file %s.\n", - ptr->filename); - continue; - } - - /* ??? Should first write a header to the file. Preferably, a 4 byte - magic number, 4 bytes containing the time the program was - compiled, 4 bytes containing the last modification time of the - source file, and 4 bytes indicating the compiler options used. - - That way we can easily verify that the proper source/executable/ - data file combination is being used from gcov. */ - - if (__write_long (ptr->ncounts, da_file, 8) != 0) - { - - fprintf (stderr, "arc profiling: Error writing output file %s.\n", - ptr->filename); - } - else - { - int j; - long *count_ptr = ptr->counts; - int ret = 0; - for (j = ptr->ncounts; j > 0; j--) - { - if (__write_long (*count_ptr, da_file, 8) != 0) - { - ret=1; - break; - } - count_ptr++; - } - if (ret) - fprintf (stderr, "arc profiling: Error writing output file %s.\n", - ptr->filename); - } - - if (fclose (da_file) == EOF) - fprintf (stderr, "arc profiling: Error closing output file %s.\n", - ptr->filename); - } - - return; - } - - /* Must be basic block profiling. Emit a human readable output file. */ - - file = fopen ("bb.out", "a"); - - if (!file) - perror ("bb.out"); - - else - { - struct bb *ptr; - - /* This is somewhat type incorrect, but it avoids worrying about - exactly where time.h is included from. It should be ok unless - a void * differs from other pointer formats, or if sizeof (long) - is < sizeof (time_t). It would be nice if we could assume the - use of rationale standards here. */ - - time ((void *) &time_value); - fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value)); - - /* We check the length field explicitly in order to allow compatibility - with older GCC's which did not provide it. */ - - for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) - { - int i; - int func_p = (ptr->nwords >= sizeof (struct bb) - && ptr->nwords <= 1000 - && ptr->functions); - int line_p = (func_p && ptr->line_nums); - int file_p = (func_p && ptr->filenames); - int addr_p = (ptr->addresses != 0); - long ncounts = ptr->ncounts; - long cnt_max = 0; - long line_max = 0; - long addr_max = 0; - int file_len = 0; - int func_len = 0; - int blk_len = num_digits (ncounts, 10); - int cnt_len; - int line_len; - int addr_len; - - fprintf (file, "File %s, %ld basic blocks \n\n", - ptr->filename, ncounts); - - /* Get max values for each field. */ - for (i = 0; i < ncounts; i++) - { - const char *p; - int len; - - if (cnt_max < ptr->counts[i]) - cnt_max = ptr->counts[i]; - - if (addr_p && addr_max < ptr->addresses[i]) - addr_max = ptr->addresses[i]; - - if (line_p && line_max < ptr->line_nums[i]) - line_max = ptr->line_nums[i]; - - if (func_p) - { - p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>"; - len = strlen (p); - if (func_len < len) - func_len = len; - } - - if (file_p) - { - p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>"; - len = strlen (p); - if (file_len < len) - file_len = len; - } - } - - addr_len = num_digits (addr_max, 16); - cnt_len = num_digits (cnt_max, 10); - line_len = num_digits (line_max, 10); - - /* Now print out the basic block information. */ - for (i = 0; i < ncounts; i++) - { - fprintf (file, - " Block #%*d: executed %*ld time(s)", - blk_len, i+1, - cnt_len, ptr->counts[i]); - - if (addr_p) - fprintf (file, " address= 0x%.*lx", addr_len, - ptr->addresses[i]); - - if (func_p) - fprintf (file, " function= %-*s", func_len, - (ptr->functions[i]) ? ptr->functions[i] : "<none>"); - - if (line_p) - fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]); - - if (file_p) - fprintf (file, " file= %s", - (ptr->filenames[i]) ? ptr->filenames[i] : "<none>"); - - fprintf (file, "\n"); - } - - fprintf (file, "\n"); - fflush (file); - } - - fprintf (file, "\n\n"); - fclose (file); - } -} - -void -__bb_init_func (struct bb *blocks) -{ - /* User is supposed to check whether the first word is non-0, - but just in case.... */ - - if (blocks->zero_word) - return; - -#ifdef ON_EXIT - /* Initialize destructor. */ - if (!bb_head) - ON_EXIT (__bb_exit_func, 0); -#endif - - /* Set up linked list. */ - blocks->zero_word = 1; - blocks->next = bb_head; - bb_head = blocks; -} - -#ifndef MACHINE_STATE_SAVE -#define MACHINE_STATE_SAVE(ID) -#endif -#ifndef MACHINE_STATE_RESTORE -#define MACHINE_STATE_RESTORE(ID) -#endif - -/* Number of buckets in hashtable of basic block addresses. */ - -#define BB_BUCKETS 311 - -/* Maximum length of string in file bb.in. */ - -#define BBINBUFSIZE 500 - -/* BBINBUFSIZE-1 with double quotes. We could use #BBINBUFSIZE or - "BBINBUFSIZE" but want to avoid trouble with preprocessors. */ - -#define BBINBUFSIZESTR "499" - -struct bb_edge -{ - struct bb_edge *next; - unsigned long src_addr; - unsigned long dst_addr; - unsigned long count; -}; - -enum bb_func_mode -{ - TRACE_KEEP = 0, TRACE_ON = 1, TRACE_OFF = 2 -}; - -struct bb_func -{ - struct bb_func *next; - char *funcname; - char *filename; - enum bb_func_mode mode; -}; - -/* This is the connection to the outside world. - The BLOCK_PROFILER macro must set __bb.blocks - and __bb.blockno. */ - -struct { - unsigned long blockno; - struct bb *blocks; -} __bb; - -/* Vars to store addrs of source and destination basic blocks - of a jump. */ - -static unsigned long bb_src = 0; -static unsigned long bb_dst = 0; - -static FILE *bb_tracefile = (FILE *) 0; -static struct bb_edge **bb_hashbuckets = (struct bb_edge **) 0; -static struct bb_func *bb_func_head = (struct bb_func *) 0; -static unsigned long bb_callcount = 0; -static int bb_mode = 0; - -static unsigned long *bb_stack = (unsigned long *) 0; -static size_t bb_stacksize = 0; - -static int reported = 0; - -/* Trace modes: -Always : Print execution frequencies of basic blocks - to file bb.out. -bb_mode & 1 != 0 : Dump trace of basic blocks to file bbtrace[.gz] -bb_mode & 2 != 0 : Print jump frequencies to file bb.out. -bb_mode & 4 != 0 : Cut call instructions from basic block flow. -bb_mode & 8 != 0 : Insert return instructions in basic block flow. -*/ - -#ifdef HAVE_POPEN - -/*#include <sys/types.h>*/ -#include <sys/stat.h> -/*#include <malloc.h>*/ - -/* Commands executed by gopen. */ - -#define GOPENDECOMPRESS "gzip -cd " -#define GOPENCOMPRESS "gzip -c >" - -/* Like fopen but pipes through gzip. mode may only be "r" or "w". - If it does not compile, simply replace gopen by fopen and delete - '.gz' from any first parameter to gopen. */ - -static FILE * -gopen (char *fn, char *mode) -{ - int use_gzip; - char *p; - - if (mode[1]) - return (FILE *) 0; - - if (mode[0] != 'r' && mode[0] != 'w') - return (FILE *) 0; - - p = fn + strlen (fn)-1; - use_gzip = ((p[-1] == '.' && (p[0] == 'Z' || p[0] == 'z')) - || (p[-2] == '.' && p[-1] == 'g' && p[0] == 'z')); - - if (use_gzip) - { - if (mode[0]=='r') - { - FILE *f; - char *s = (char *) malloc (sizeof (char) * strlen (fn) - + sizeof (GOPENDECOMPRESS)); - strcpy (s, GOPENDECOMPRESS); - strcpy (s + (sizeof (GOPENDECOMPRESS)-1), fn); - f = popen (s, mode); - free (s); - return f; - } - - else - { - FILE *f; - char *s = (char *) malloc (sizeof (char) * strlen (fn) - + sizeof (GOPENCOMPRESS)); - strcpy (s, GOPENCOMPRESS); - strcpy (s + (sizeof (GOPENCOMPRESS)-1), fn); - if (!(f = popen (s, mode))) - f = fopen (s, mode); - free (s); - return f; - } - } - - else - return fopen (fn, mode); -} - -static int -gclose (FILE *f) -{ - struct stat buf; - - if (f != 0) - { - if (!fstat (fileno (f), &buf) && S_ISFIFO (buf.st_mode)) - return pclose (f); - - return fclose (f); - } - return 0; -} - -#endif /* HAVE_POPEN */ - -/* Called once per program. */ - -static void -__bb_exit_trace_func () -{ - FILE *file = fopen ("bb.out", "a"); - struct bb_func *f; - struct bb *b; - - if (!file) - perror ("bb.out"); - - if (bb_mode & 1) - { - if (!bb_tracefile) - perror ("bbtrace"); - else -#ifdef HAVE_POPEN - gclose (bb_tracefile); -#else - fclose (bb_tracefile); -#endif /* HAVE_POPEN */ - } - - /* Check functions in `bb.in'. */ - - if (file) - { - long time_value; - const struct bb_func *p; - int printed_something = 0; - struct bb *ptr; - long blk; - - /* This is somewhat type incorrect. */ - time ((void *) &time_value); - - for (p = bb_func_head; p != (struct bb_func *) 0; p = p->next) - { - for (ptr = bb_head; ptr != (struct bb *) 0; ptr = ptr->next) - { - if (!ptr->filename || (p->filename != (char *) 0 && strcmp (p->filename, ptr->filename))) - continue; - for (blk = 0; blk < ptr->ncounts; blk++) - { - if (!strcmp (p->funcname, ptr->functions[blk])) - goto found; - } - } - - if (!printed_something) - { - fprintf (file, "Functions in `bb.in' not executed during basic block profiling on %s\n", ctime ((void *) &time_value)); - printed_something = 1; - } - - fprintf (file, "\tFunction %s", p->funcname); - if (p->filename) - fprintf (file, " of file %s", p->filename); - fprintf (file, "\n" ); - -found: ; - } - - if (printed_something) - fprintf (file, "\n"); - - } - - if (bb_mode & 2) - { - if (!bb_hashbuckets) - { - if (!reported) - { - fprintf (stderr, "Profiler: out of memory\n"); - reported = 1; - } - return; - } - - else if (file) - { - long time_value; - int i; - unsigned long addr_max = 0; - unsigned long cnt_max = 0; - int cnt_len; - int addr_len; - - /* This is somewhat type incorrect, but it avoids worrying about - exactly where time.h is included from. It should be ok unless - a void * differs from other pointer formats, or if sizeof (long) - is < sizeof (time_t). It would be nice if we could assume the - use of rationale standards here. */ - - time ((void *) &time_value); - fprintf (file, "Basic block jump tracing"); - - switch (bb_mode & 12) - { - case 0: - fprintf (file, " (with call)"); - break; - - case 4: - /* Print nothing. */ - break; - - case 8: - fprintf (file, " (with call & ret)"); - break; - - case 12: - fprintf (file, " (with ret)"); - break; - } - - fprintf (file, " finished on %s\n", ctime ((void *) &time_value)); - - for (i = 0; i < BB_BUCKETS; i++) - { - struct bb_edge *bucket = bb_hashbuckets[i]; - for ( ; bucket; bucket = bucket->next ) - { - if (addr_max < bucket->src_addr) - addr_max = bucket->src_addr; - if (addr_max < bucket->dst_addr) - addr_max = bucket->dst_addr; - if (cnt_max < bucket->count) - cnt_max = bucket->count; - } - } - addr_len = num_digits (addr_max, 16); - cnt_len = num_digits (cnt_max, 10); - - for ( i = 0; i < BB_BUCKETS; i++) - { - struct bb_edge *bucket = bb_hashbuckets[i]; - for ( ; bucket; bucket = bucket->next ) - { - fprintf (file, "Jump from block 0x%.*lx to " - "block 0x%.*lx executed %*lu time(s)\n", - addr_len, bucket->src_addr, - addr_len, bucket->dst_addr, - cnt_len, bucket->count); - } - } - - fprintf (file, "\n"); - - } - } - - if (file) - fclose (file); - - /* Free allocated memory. */ - - f = bb_func_head; - while (f) - { - struct bb_func *old = f; - - f = f->next; - if (old->funcname) free (old->funcname); - if (old->filename) free (old->filename); - free (old); - } - - if (bb_stack) - free (bb_stack); - - if (bb_hashbuckets) - { - int i; - - for (i = 0; i < BB_BUCKETS; i++) - { - struct bb_edge *old, *bucket = bb_hashbuckets[i]; - - while (bucket) - { - old = bucket; - bucket = bucket->next; - free (old); - } - } - free (bb_hashbuckets); - } - - for (b = bb_head; b; b = b->next) - if (b->flags) free (b->flags); -} - -/* Called once per program. */ - -static void -__bb_init_prg () -{ - - FILE *file; - char buf[BBINBUFSIZE]; - const char *p; - const char *pos; - enum bb_func_mode m; - -#ifdef ON_EXIT - /* Initialize destructor. */ - ON_EXIT (__bb_exit_func, 0); -#endif - - if (!(file = fopen ("bb.in", "r"))) - return; - - while(fscanf (file, " %" BBINBUFSIZESTR "s ", buf) != EOF) - { - p = buf; - if (*p == '-') - { - m = TRACE_OFF; - p++; - } - else - { - m = TRACE_ON; - } - if (!strcmp (p, "__bb_trace__")) - bb_mode |= 1; - else if (!strcmp (p, "__bb_jumps__")) - bb_mode |= 2; - else if (!strcmp (p, "__bb_hidecall__")) - bb_mode |= 4; - else if (!strcmp (p, "__bb_showret__")) - bb_mode |= 8; - else - { - struct bb_func *f = (struct bb_func *) malloc (sizeof (struct bb_func)); - if (f) - { - unsigned long l; - f->next = bb_func_head; - if ((pos = strchr (p, ':'))) - { - if (!(f->funcname = (char *) malloc (strlen (pos+1)+1))) - continue; - strcpy (f->funcname, pos+1); - l = pos-p; - if ((f->filename = (char *) malloc (l+1))) - { - strncpy (f->filename, p, l); - f->filename[l] = '\0'; - } - else - f->filename = (char *) 0; - } - else - { - if (!(f->funcname = (char *) malloc (strlen (p)+1))) - continue; - strcpy (f->funcname, p); - f->filename = (char *) 0; - } - f->mode = m; - bb_func_head = f; - } - } - } - fclose (file); - -#ifdef HAVE_POPEN - - if (bb_mode & 1) - bb_tracefile = gopen ("bbtrace.gz", "w"); - -#else - - if (bb_mode & 1) - bb_tracefile = fopen ("bbtrace", "w"); - -#endif /* HAVE_POPEN */ - - if (bb_mode & 2) - { - bb_hashbuckets = (struct bb_edge **) - malloc (BB_BUCKETS * sizeof (struct bb_edge *)); - if (bb_hashbuckets) - memset (bb_hashbuckets, 0, BB_BUCKETS * sizeof (struct bb_edge *)); - } - - if (bb_mode & 12) - { - bb_stacksize = 10; - bb_stack = (unsigned long *) malloc (bb_stacksize * sizeof (*bb_stack)); - } - -#ifdef ON_EXIT - /* Initialize destructor. */ - ON_EXIT (__bb_exit_trace_func, 0); -#endif - -} - -/* Called upon entering a basic block. */ - -void -__bb_trace_func () -{ - struct bb_edge *bucket; - - MACHINE_STATE_SAVE("1") - - if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF))) - goto skip; - - bb_dst = __bb.blocks->addresses[__bb.blockno]; - __bb.blocks->counts[__bb.blockno]++; - - if (bb_tracefile) - { - fwrite (&bb_dst, sizeof (unsigned long), 1, bb_tracefile); - } - - if (bb_hashbuckets) - { - struct bb_edge **startbucket, **oldnext; - - oldnext = startbucket - = & bb_hashbuckets[ (((int) bb_src*8) ^ (int) bb_dst) % BB_BUCKETS ]; - bucket = *startbucket; - - for (bucket = *startbucket; bucket; - oldnext = &(bucket->next), bucket = *oldnext) - { - if (bucket->src_addr == bb_src - && bucket->dst_addr == bb_dst) - { - bucket->count++; - *oldnext = bucket->next; - bucket->next = *startbucket; - *startbucket = bucket; - goto ret; - } - } - - bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge)); - - if (!bucket) - { - if (!reported) - { - fprintf (stderr, "Profiler: out of memory\n"); - reported = 1; - } - } - - else - { - bucket->src_addr = bb_src; - bucket->dst_addr = bb_dst; - bucket->next = *startbucket; - *startbucket = bucket; - bucket->count = 1; - } - } - -ret: - bb_src = bb_dst; - -skip: - ; - - MACHINE_STATE_RESTORE("1") - -} - -/* Called when returning from a function and `__bb_showret__' is set. */ - -static void -__bb_trace_func_ret () -{ - struct bb_edge *bucket; - - if (!bb_callcount || (__bb.blocks->flags && (__bb.blocks->flags[__bb.blockno] & TRACE_OFF))) - goto skip; - - if (bb_hashbuckets) - { - struct bb_edge **startbucket, **oldnext; - - oldnext = startbucket - = & bb_hashbuckets[ (((int) bb_dst * 8) ^ (int) bb_src) % BB_BUCKETS ]; - bucket = *startbucket; - - for (bucket = *startbucket; bucket; - oldnext = &(bucket->next), bucket = *oldnext) - { - if (bucket->src_addr == bb_dst - && bucket->dst_addr == bb_src) - { - bucket->count++; - *oldnext = bucket->next; - bucket->next = *startbucket; - *startbucket = bucket; - goto ret; - } - } - - bucket = (struct bb_edge *) malloc (sizeof (struct bb_edge)); - - if (!bucket) - { - if (!reported) - { - fprintf (stderr, "Profiler: out of memory\n"); - reported = 1; - } - } - - else - { - bucket->src_addr = bb_dst; - bucket->dst_addr = bb_src; - bucket->next = *startbucket; - *startbucket = bucket; - bucket->count = 1; - } - } - -ret: - bb_dst = bb_src; - -skip: - ; - -} - -/* Called upon entering the first function of a file. */ - -static void -__bb_init_file (struct bb *blocks) -{ - - const struct bb_func *p; - long blk, ncounts = blocks->ncounts; - const char **functions = blocks->functions; - - /* Set up linked list. */ - blocks->zero_word = 1; - blocks->next = bb_head; - bb_head = blocks; - - blocks->flags = 0; - if (!bb_func_head - || !(blocks->flags = (char *) malloc (sizeof (char) * blocks->ncounts))) - return; - - for (blk = 0; blk < ncounts; blk++) - blocks->flags[blk] = 0; - - for (blk = 0; blk < ncounts; blk++) - { - for (p = bb_func_head; p; p = p->next) - { - if (!strcmp (p->funcname, functions[blk]) - && (!p->filename || !strcmp (p->filename, blocks->filename))) - { - blocks->flags[blk] |= p->mode; - } - } - } - -} - -/* Called when exiting from a function. */ - -void -__bb_trace_ret () -{ - - MACHINE_STATE_SAVE("2") - - if (bb_callcount) - { - if ((bb_mode & 12) && bb_stacksize > bb_callcount) - { - bb_src = bb_stack[bb_callcount]; - if (bb_mode & 8) - __bb_trace_func_ret (); - } - - bb_callcount -= 1; - } - - MACHINE_STATE_RESTORE("2") - -} - -/* Called when entering a function. */ - -void -__bb_init_trace_func (struct bb *blocks, unsigned long blockno) -{ - static int trace_init = 0; - - MACHINE_STATE_SAVE("3") - - if (!blocks->zero_word) - { - if (!trace_init) - { - trace_init = 1; - __bb_init_prg (); - } - __bb_init_file (blocks); - } - - if (bb_callcount) - { - - bb_callcount += 1; - - if (bb_mode & 12) - { - if (bb_callcount >= bb_stacksize) - { - size_t newsize = bb_callcount + 100; - - bb_stack = (unsigned long *) realloc (bb_stack, newsize); - if (! bb_stack) - { - if (!reported) - { - fprintf (stderr, "Profiler: out of memory\n"); - reported = 1; - } - bb_stacksize = 0; - goto stack_overflow; - } - bb_stacksize = newsize; - } - bb_stack[bb_callcount] = bb_src; - - if (bb_mode & 4) - bb_src = 0; - - } - -stack_overflow:; - - } - - else if (blocks->flags && (blocks->flags[blockno] & TRACE_ON)) - { - bb_callcount = 1; - bb_src = 0; - - if (bb_stack) - bb_stack[bb_callcount] = bb_src; - } - - MACHINE_STATE_RESTORE("3") -} - -#endif /* not inhibit_libc */ -#endif /* not BLOCK_PROFILER_CODE */ -#endif /* L_bb */ - -#ifdef L_shtab -unsigned int __shtab[] = { - 0x00000001, 0x00000002, 0x00000004, 0x00000008, - 0x00000010, 0x00000020, 0x00000040, 0x00000080, - 0x00000100, 0x00000200, 0x00000400, 0x00000800, - 0x00001000, 0x00002000, 0x00004000, 0x00008000, - 0x00010000, 0x00020000, 0x00040000, 0x00080000, - 0x00100000, 0x00200000, 0x00400000, 0x00800000, - 0x01000000, 0x02000000, 0x04000000, 0x08000000, - 0x10000000, 0x20000000, 0x40000000, 0x80000000 - }; -#endif - -#ifdef L_clear_cache -/* Clear part of an instruction cache. */ - -#define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH) - -void -__clear_cache (char *beg, char *end) -{ -#ifdef CLEAR_INSN_CACHE - CLEAR_INSN_CACHE (beg, end); -#else -#ifdef INSN_CACHE_SIZE - static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH]; - static int initialized; - int offset; - void *start_addr - void *end_addr; - typedef (*function_ptr) (); - -#if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16 - /* It's cheaper to clear the whole cache. - Put in a series of jump instructions so that calling the beginning - of the cache will clear the whole thing. */ - - if (! initialized) - { - int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) - & -INSN_CACHE_LINE_WIDTH); - int end_ptr = ptr + INSN_CACHE_SIZE; - - while (ptr < end_ptr) - { - *(INSTRUCTION_TYPE *)ptr - = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH; - ptr += INSN_CACHE_LINE_WIDTH; - } - *(INSTRUCTION_TYPE *) (ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION; - - initialized = 1; - } - - /* Call the beginning of the sequence. */ - (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1) - & -INSN_CACHE_LINE_WIDTH)) - ()); - -#else /* Cache is large. */ - - if (! initialized) - { - int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1) - & -INSN_CACHE_LINE_WIDTH); - - while (ptr < (int) array + sizeof array) - { - *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION; - ptr += INSN_CACHE_LINE_WIDTH; - } - - initialized = 1; - } - - /* Find the location in array that occupies the same cache line as BEG. */ - - offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1); - start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1) - & -INSN_CACHE_PLANE_SIZE) - + offset); - - /* Compute the cache alignment of the place to stop clearing. */ -#if 0 /* This is not needed for gcc's purposes. */ - /* If the block to clear is bigger than a cache plane, - we clear the entire cache, and OFFSET is already correct. */ - if (end < beg + INSN_CACHE_PLANE_SIZE) -#endif - offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1) - & -INSN_CACHE_LINE_WIDTH) - & (INSN_CACHE_PLANE_SIZE - 1)); - -#if INSN_CACHE_DEPTH > 1 - end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset; - if (end_addr <= start_addr) - end_addr += INSN_CACHE_PLANE_SIZE; - - for (plane = 0; plane < INSN_CACHE_DEPTH; plane++) - { - int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE; - int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE; - - while (addr != stop) - { - /* Call the return instruction at ADDR. */ - ((function_ptr) addr) (); - - addr += INSN_CACHE_LINE_WIDTH; - } - } -#else /* just one plane */ - do - { - /* Call the return instruction at START_ADDR. */ - ((function_ptr) start_addr) (); - - start_addr += INSN_CACHE_LINE_WIDTH; - } - while ((start_addr % INSN_CACHE_SIZE) != offset); -#endif /* just one plane */ -#endif /* Cache is large */ -#endif /* Cache exists */ -#endif /* CLEAR_INSN_CACHE */ -} - -#endif /* L_clear_cache */ - -#ifdef L_trampoline - -/* Jump to a trampoline, loading the static chain address. */ - -#if defined(WINNT) && ! defined(__CYGWIN__) - -long getpagesize() -{ -#ifdef _ALPHA_ - return 8192; -#else - return 4096; -#endif -} - -#ifdef i386 -extern int VirtualProtect (char *, int, int, int *) __attribute__((stdcall)); -#endif - -int -mprotect (char *addr, int len, int prot) -{ - int np, op; - - if (prot == 7) - np = 0x40; - else if (prot == 5) - np = 0x20; - else if (prot == 4) - np = 0x10; - else if (prot == 3) - np = 0x04; - else if (prot == 1) - np = 0x02; - else if (prot == 0) - np = 0x01; - - if (VirtualProtect (addr, len, np, &op)) - return 0; - else - return -1; -} - -#endif - -#ifdef TRANSFER_FROM_TRAMPOLINE -TRANSFER_FROM_TRAMPOLINE -#endif - -#if defined (NeXT) && defined (__MACH__) - -/* Make stack executable so we can call trampolines on stack. - This is called from INITIALIZE_TRAMPOLINE in next.h. */ -#ifdef NeXTStep21 - #include <mach.h> -#else - #include <mach/mach.h> -#endif - -void -__enable_execute_stack (char *addr) -{ - kern_return_t r; - char *eaddr = addr + TRAMPOLINE_SIZE; - vm_address_t a = (vm_address_t) addr; - - /* turn on execute access on stack */ - r = vm_protect (task_self (), a, TRAMPOLINE_SIZE, FALSE, VM_PROT_ALL); - if (r != KERN_SUCCESS) - { - mach_error("vm_protect VM_PROT_ALL", r); - exit(1); - } - - /* We inline the i-cache invalidation for speed */ - -#ifdef CLEAR_INSN_CACHE - CLEAR_INSN_CACHE (addr, eaddr); -#else - __clear_cache ((int) addr, (int) eaddr); -#endif -} - -#endif /* defined (NeXT) && defined (__MACH__) */ - -#ifdef __convex__ - -/* Make stack executable so we can call trampolines on stack. - This is called from INITIALIZE_TRAMPOLINE in convex.h. */ - -#include <sys/mman.h> -#include <sys/vmparam.h> -#include <machine/machparam.h> - -void -__enable_execute_stack () -{ - int fp; - static unsigned lowest = USRSTACK; - unsigned current = (unsigned) &fp & -NBPG; - - if (lowest > current) - { - unsigned len = lowest - current; - mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE); - lowest = current; - } - - /* Clear instruction cache in case an old trampoline is in it. */ - asm ("pich"); -} -#endif /* __convex__ */ - -#ifdef __sysV88__ - -/* Modified from the convex -code above. */ - -#include <sys/param.h> -#include <errno.h> -#include <sys/m88kbcs.h> - -void -__enable_execute_stack () -{ - int save_errno; - static unsigned long lowest = USRSTACK; - unsigned long current = (unsigned long) &save_errno & -NBPC; - - /* Ignore errno being set. memctl sets errno to EINVAL whenever the - address is seen as 'negative'. That is the case with the stack. */ - - save_errno=errno; - if (lowest > current) - { - unsigned len=lowest-current; - memctl(current,len,MCT_TEXT); - lowest = current; - } - else - memctl(current,NBPC,MCT_TEXT); - errno=save_errno; -} - -#endif /* __sysV88__ */ - -#ifdef __sysV68__ - -#include <sys/signal.h> -#include <errno.h> - -/* Motorola forgot to put memctl.o in the libp version of libc881.a, - so define it here, because we need it in __clear_insn_cache below */ -/* On older versions of this OS, no memctl or MCT_TEXT are defined; - hence we enable this stuff only if MCT_TEXT is #define'd. */ - -#ifdef MCT_TEXT -asm("\n\ - global memctl\n\ -memctl:\n\ - movq &75,%d0\n\ - trap &0\n\ - bcc.b noerror\n\ - jmp cerror%\n\ -noerror:\n\ - movq &0,%d0\n\ - rts"); -#endif - -/* Clear instruction cache so we can call trampolines on stack. - This is called from FINALIZE_TRAMPOLINE in mot3300.h. */ - -void -__clear_insn_cache () -{ -#ifdef MCT_TEXT - int save_errno; - - /* Preserve errno, because users would be surprised to have - errno changing without explicitly calling any system-call. */ - save_errno = errno; - - /* Keep it simple : memctl (MCT_TEXT) always fully clears the insn cache. - No need to use an address derived from _start or %sp, as 0 works also. */ - memctl(0, 4096, MCT_TEXT); - errno = save_errno; -#endif -} - -#endif /* __sysV68__ */ - -#ifdef __pyr__ - -#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ -#include <stdio.h> -#include <sys/mman.h> -#include <sys/types.h> -#include <sys/param.h> -#include <sys/vmmac.h> - -/* Modified from the convex -code above. - mremap promises to clear the i-cache. */ - -void -__enable_execute_stack () -{ - int fp; - if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ, - PROT_READ|PROT_WRITE|PROT_EXEC)) - { - perror ("mprotect in __enable_execute_stack"); - fflush (stderr); - abort (); - } -} -#endif /* __pyr__ */ - -#if defined (sony_news) && defined (SYSTYPE_BSD) - -#include <stdio.h> -#include <sys/types.h> -#include <sys/param.h> -#include <syscall.h> -#include <machine/sysnews.h> - -/* cacheflush function for NEWS-OS 4.2. - This function is called from trampoline-initialize code - defined in config/mips/mips.h. */ - -void -cacheflush (char *beg, int size, int flag) -{ - if (syscall (SYS_sysnews, NEWS_CACHEFLUSH, beg, size, FLUSH_BCACHE)) - { - perror ("cache_flush"); - fflush (stderr); - abort (); - } -} - -#endif /* sony_news */ -#endif /* L_trampoline */ - -#ifndef __CYGWIN__ -#ifdef L__main - -#include "gbl-ctors.h" -/* Some systems use __main in a way incompatible with its use in gcc, in these - cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to - give the same symbol without quotes for an alternative entry point. You - must define both, or neither. */ -#ifndef NAME__MAIN -#define NAME__MAIN "__main" -#define SYMBOL__MAIN __main -#endif - -#ifdef INIT_SECTION_ASM_OP -#undef HAS_INIT_SECTION -#define HAS_INIT_SECTION -#endif - -#if !defined (HAS_INIT_SECTION) || !defined (OBJECT_FORMAT_ELF) -/* Run all the global destructors on exit from the program. */ - -void -__do_global_dtors () -{ -#ifdef DO_GLOBAL_DTORS_BODY - DO_GLOBAL_DTORS_BODY; -#else - static func_ptr *p = __DTOR_LIST__ + 1; - while (*p) - { - p++; - (*(p-1)) (); - } -#endif -} -#endif - -#ifndef HAS_INIT_SECTION -/* Run all the global constructors on entry to the program. */ - -#ifndef ON_EXIT -#define ON_EXIT(a, b) -#else -/* Make sure the exit routine is pulled in to define the globals as - bss symbols, just in case the linker does not automatically pull - bss definitions from the library. */ - -extern int _exit_dummy_decl; -int *_exit_dummy_ref = &_exit_dummy_decl; -#endif /* ON_EXIT */ - -void -__do_global_ctors () -{ - DO_GLOBAL_CTORS_BODY; - ON_EXIT (__do_global_dtors, 0); -} -#endif /* no HAS_INIT_SECTION */ - -#if !defined (HAS_INIT_SECTION) || defined (INVOKE__main) -/* Subroutine called automatically by `main'. - Compiling a global function named `main' - produces an automatic call to this function at the beginning. - - For many systems, this routine calls __do_global_ctors. - For systems which support a .init section we use the .init section - to run __do_global_ctors, so we need not do anything here. */ - -void -SYMBOL__MAIN () -{ - /* Support recursive calls to `main': run initializers just once. */ - static int initialized; - if (! initialized) - { - initialized = 1; - __do_global_ctors (); - } -} -#endif /* no HAS_INIT_SECTION or INVOKE__main */ - -#endif /* L__main */ -#endif /* __CYGWIN__ */ - -#ifdef L_ctors - -#include "gbl-ctors.h" - -/* Provide default definitions for the lists of constructors and - destructors, so that we don't get linker errors. - - The old code sometimes put these into the data segment and sometimes - into the bss segment. Putting these into the data segment should always - work and avoids a little bit of complexity. */ - -/* We declare the lists here with two elements each, - so that they are valid empty lists if no other definition is loaded. */ -#if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY) -func_ptr __CTOR_LIST__[2] = {0, 0}; -func_ptr __DTOR_LIST__[2] = {0, 0}; -#endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */ -#endif /* L_ctors */ - -#ifdef L_exit - -#include "gbl-ctors.h" - -#ifdef NEED_ATEXIT -# ifdef ON_EXIT -# undef ON_EXIT -# endif -int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ -#endif - -#ifndef ON_EXIT - -#ifdef NEED_ATEXIT -# include <errno.h> - -static func_ptr *atexit_chain = 0; -static long atexit_chain_length = 0; -static volatile long last_atexit_chain_slot = -1; - -int atexit (func_ptr func) -{ - if (++last_atexit_chain_slot == atexit_chain_length) - { - atexit_chain_length += 32; - if (atexit_chain) - atexit_chain = (func_ptr *) realloc (atexit_chain, atexit_chain_length - * sizeof (func_ptr)); - else - atexit_chain = (func_ptr *) malloc (atexit_chain_length - * sizeof (func_ptr)); - if (! atexit_chain) - { - atexit_chain_length = 0; - last_atexit_chain_slot = -1; - errno = ENOMEM; - return (-1); - } - } - atexit_chain[last_atexit_chain_slot] = func; - return (0); -} -#endif /* NEED_ATEXIT */ - -/* If we have no known way of registering our own __do_global_dtors - routine so that it will be invoked at program exit time, then we - have to define our own exit routine which will get this to happen. */ - -extern void __do_global_dtors (); -extern void __bb_exit_func (); -extern void _cleanup (); -extern void _exit () __attribute__ ((noreturn)); - -void -exit (int status) -{ -#if !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) -#ifdef NEED_ATEXIT - if (atexit_chain) - { - for ( ; last_atexit_chain_slot-- >= 0; ) - { - (*atexit_chain[last_atexit_chain_slot + 1]) (); - atexit_chain[last_atexit_chain_slot + 1] = 0; - } - free (atexit_chain); - atexit_chain = 0; - } -#else /* No NEED_ATEXIT */ - __do_global_dtors (); -#endif /* No NEED_ATEXIT */ -#endif /* !defined (INIT_SECTION_ASM_OP) || !defined (OBJECT_FORMAT_ELF) */ -/* In gbl-ctors.h, ON_EXIT is defined if HAVE_ATEXIT is defined. In - __bb_init_func and _bb_init_prg, __bb_exit_func is registered with - ON_EXIT if ON_EXIT is defined. Thus we must not call __bb_exit_func here - if HAVE_ATEXIT is defined. */ -#ifndef HAVE_ATEXIT -#ifndef inhibit_libc - __bb_exit_func (); -#endif -#endif /* !HAVE_ATEXIT */ -#ifdef EXIT_BODY - EXIT_BODY; -#else - _cleanup (); -#endif - _exit (status); -} - -#else /* ON_EXIT defined */ -int _exit_dummy_decl = 0; /* prevent compiler & linker warnings */ - -# ifndef HAVE_ATEXIT -/* Provide a fake for atexit() using ON_EXIT. */ -int atexit (func_ptr func) -{ - return ON_EXIT (func, NULL); -} -# endif /* HAVE_ATEXIT */ -#endif /* ON_EXIT defined */ - -#endif /* L_exit */ - -#ifdef L_eh - -#include "gthr.h" - -/* Shared exception handling support routines. */ - -extern void __default_terminate (void) __attribute__ ((__noreturn__)); - -void -__default_terminate () -{ - abort (); -} - -void (*__terminate_func)() = __default_terminate; - -void -__terminate () -{ - (*__terminate_func)(); -} - -void * -__throw_type_match (void *catch_type, void *throw_type, void *obj) -{ -#if 0 - printf ("__throw_type_match (): catch_type = %s, throw_type = %s\n", - catch_type, throw_type); -#endif - if (strcmp ((const char *)catch_type, (const char *)throw_type) == 0) - return obj; - return 0; -} - -void -__empty () -{ -} - - -/* Include definitions of EH context and table layout */ - -#include "eh-common.h" -#ifndef inhibit_libc -#include <stdio.h> -#endif - -/* Allocate and return a new EH context structure. */ - -extern void __throw (); - -static void * -new_eh_context () -{ - struct eh_full_context { - struct eh_context c; - void *top_elt[2]; - } *ehfc = (struct eh_full_context *) malloc (sizeof *ehfc); - - if (! ehfc) - __terminate (); - - memset (ehfc, 0, sizeof *ehfc); - - ehfc->c.dynamic_handler_chain = (void **) ehfc->top_elt; - - /* This should optimize out entirely. This should always be true, - but just in case it ever isn't, don't allow bogus code to be - generated. */ - - if ((void*)(&ehfc->c) != (void*)ehfc) - __terminate (); - - return &ehfc->c; -} - -#if __GTHREADS -static __gthread_key_t eh_context_key; - -/* Destructor for struct eh_context. */ -static void -eh_context_free (void *ptr) -{ - __gthread_key_dtor (eh_context_key, ptr); - if (ptr) - free (ptr); -} -#endif - -/* Pointer to function to return EH context. */ - -static struct eh_context *eh_context_initialize (); -static struct eh_context *eh_context_static (); -#if __GTHREADS -static struct eh_context *eh_context_specific (); -#endif - -static struct eh_context *(*get_eh_context) () = &eh_context_initialize; - -/* Routine to get EH context. - This one will simply call the function pointer. */ - -void * -__get_eh_context () -{ - return (void *) (*get_eh_context) (); -} - -/* Get and set the language specific info pointer. */ - -void ** -__get_eh_info () -{ - struct eh_context *eh = (*get_eh_context) (); - return &eh->info; -} - -#if __GTHREADS -static void -eh_threads_initialize () -{ - /* Try to create the key. If it fails, revert to static method, - otherwise start using thread specific EH contexts. */ - if (__gthread_key_create (&eh_context_key, &eh_context_free) == 0) - get_eh_context = &eh_context_specific; - else - get_eh_context = &eh_context_static; -} -#endif /* no __GTHREADS */ - -/* Initialize EH context. - This will be called only once, since we change GET_EH_CONTEXT - pointer to another routine. */ - -static struct eh_context * -eh_context_initialize () -{ -#if __GTHREADS - - static __gthread_once_t once = __GTHREAD_ONCE_INIT; - /* Make sure that get_eh_context does not point to us anymore. - Some systems have dummy thread routines in their libc that - return a success (Solaris 2.6 for example). */ - if (__gthread_once (&once, eh_threads_initialize) != 0 - || get_eh_context == &eh_context_initialize) - { - /* Use static version of EH context. */ - get_eh_context = &eh_context_static; - } - -#else /* no __GTHREADS */ - - /* Use static version of EH context. */ - get_eh_context = &eh_context_static; - -#endif /* no __GTHREADS */ - - return (*get_eh_context) (); -} - -/* Return a static EH context. */ - -static struct eh_context * -eh_context_static () -{ - static struct eh_context eh; - static int initialized; - static void *top_elt[2]; - - if (! initialized) - { - initialized = 1; - memset (&eh, 0, sizeof eh); - eh.dynamic_handler_chain = top_elt; - } - return &eh; -} - -#if __GTHREADS -/* Return a thread specific EH context. */ - -static struct eh_context * -eh_context_specific () -{ - struct eh_context *eh; - eh = (struct eh_context *) __gthread_getspecific (eh_context_key); - if (! eh) - { - eh = new_eh_context (); - if (__gthread_setspecific (eh_context_key, (void *) eh) != 0) - __terminate (); - } - - return eh; -} -#endif __GTHREADS - -/* Support routines for setjmp/longjmp exception handling. */ - -/* Calls to __sjthrow are generated by the compiler when an exception - is raised when using the setjmp/longjmp exception handling codegen - method. */ - -#ifdef DONT_USE_BUILTIN_SETJMP -extern void longjmp (void *, int); -#endif - -/* Routine to get the head of the current thread's dynamic handler chain - use for exception handling. */ - -void *** -__get_dynamic_handler_chain () -{ - struct eh_context *eh = (*get_eh_context) (); - return &eh->dynamic_handler_chain; -} - -/* This is used to throw an exception when the setjmp/longjmp codegen - method is used for exception handling. - - We call __terminate if there are no handlers left. Otherwise we run the - cleanup actions off the dynamic cleanup stack, and pop the top of the - dynamic handler chain, and use longjmp to transfer back to the associated - handler. */ - -extern void __sjthrow (void) __attribute__ ((__noreturn__)); - -void -__sjthrow () -{ - struct eh_context *eh = (*get_eh_context) (); - void ***dhc = &eh->dynamic_handler_chain; - void *jmpbuf; - void (*func)(void *, int); - void *arg; - void ***cleanup; - - /* The cleanup chain is one word into the buffer. Get the cleanup - chain. */ - cleanup = (void***)&(*dhc)[1]; - - /* If there are any cleanups in the chain, run them now. */ - if (cleanup[0]) - { - double store[200]; - void **buf = (void**)store; - buf[1] = 0; - buf[0] = (*dhc); - - /* try { */ -#ifdef DONT_USE_BUILTIN_SETJMP - if (! setjmp (&buf[2])) -#else - if (! __builtin_setjmp (&buf[2])) -#endif - { - *dhc = buf; - while (cleanup[0]) - { - func = (void(*)(void*, int))cleanup[0][1]; - arg = (void*)cleanup[0][2]; - - /* Update this before running the cleanup. */ - cleanup[0] = (void **)cleanup[0][0]; - - (*func)(arg, 2); - } - *dhc = buf[0]; - } - /* catch (...) */ - else - { - __terminate (); - } - } - - /* We must call terminate if we try and rethrow an exception, when - there is no exception currently active and when there are no - handlers left. */ - if (! eh->info || (*dhc)[0] == 0) - __terminate (); - - /* Find the jmpbuf associated with the top element of the dynamic - handler chain. The jumpbuf starts two words into the buffer. */ - jmpbuf = &(*dhc)[2]; - - /* Then we pop the top element off the dynamic handler chain. */ - *dhc = (void**)(*dhc)[0]; - - /* And then we jump to the handler. */ - -#ifdef DONT_USE_BUILTIN_SETJMP - longjmp (jmpbuf, 1); -#else - __builtin_longjmp (jmpbuf, 1); -#endif -} - -/* Run cleanups on the dynamic cleanup stack for the current dynamic - handler, then pop the handler off the dynamic handler stack, and - then throw. This is used to skip the first handler, and transfer - control to the next handler in the dynamic handler stack. */ - -extern void __sjpopnthrow (void) __attribute__ ((__noreturn__)); - -void -__sjpopnthrow () -{ - struct eh_context *eh = (*get_eh_context) (); - void ***dhc = &eh->dynamic_handler_chain; - void (*func)(void *, int); - void *arg; - void ***cleanup; - - /* The cleanup chain is one word into the buffer. Get the cleanup - chain. */ - cleanup = (void***)&(*dhc)[1]; - - /* If there are any cleanups in the chain, run them now. */ - if (cleanup[0]) - { - double store[200]; - void **buf = (void**)store; - buf[1] = 0; - buf[0] = (*dhc); - - /* try { */ -#ifdef DONT_USE_BUILTIN_SETJMP - if (! setjmp (&buf[2])) -#else - if (! __builtin_setjmp (&buf[2])) -#endif - { - *dhc = buf; - while (cleanup[0]) - { - func = (void(*)(void*, int))cleanup[0][1]; - arg = (void*)cleanup[0][2]; - - /* Update this before running the cleanup. */ - cleanup[0] = (void **)cleanup[0][0]; - - (*func)(arg, 2); - } - *dhc = buf[0]; - } - /* catch (...) */ - else - { - __terminate (); - } - } - - /* Then we pop the top element off the dynamic handler chain. */ - *dhc = (void**)(*dhc)[0]; - - __sjthrow (); -} - -/* Support code for all exception region-based exception handling. */ - -int -__eh_rtime_match (void *rtime) -{ - void *info; - __eh_matcher matcher; - void *ret; - - info = *(__get_eh_info ()); - matcher = ((__eh_info *)info)->match_function; - if (! matcher) - { -#ifndef inhibit_libc - fprintf (stderr, "Internal Compiler Bug: No runtime type matcher."); -#endif - return 0; - } - ret = (*matcher) (info, rtime, (void *)0); - return (ret != NULL); -} - -/* This value identifies the place from which an exception is being - thrown. */ - -#ifdef EH_TABLE_LOOKUP - -EH_TABLE_LOOKUP - -#else - -#ifdef DWARF2_UNWIND_INFO - - -/* Return the table version of an exception descriptor */ - -short -__get_eh_table_version (exception_descriptor *table) -{ - return table->lang.version; -} - -/* Return the originating table language of an exception descriptor */ - -short -__get_eh_table_language (exception_descriptor *table) -{ - return table->lang.language; -} - -/* This routine takes a PC and a pointer to the exception region TABLE for - its translation unit, and returns the address of the exception handler - associated with the closest exception table handler entry associated - with that PC, or 0 if there are no table entries the PC fits in. - - In the advent of a tie, we have to give the last entry, as it represents - an inner block. */ - -static void * -old_find_exception_handler (void *pc, old_exception_table *table) -{ - if (table) - { - int pos; - int best = -1; - - /* We can't do a binary search because the table isn't guaranteed - to be sorted from function to function. */ - for (pos = 0; table[pos].start_region != (void *) -1; ++pos) - { - if (table[pos].start_region <= pc && table[pos].end_region > pc) - { - /* This can apply. Make sure it is at least as small as - the previous best. */ - if (best == -1 || (table[pos].end_region <= table[best].end_region - && table[pos].start_region >= table[best].start_region)) - best = pos; - } - /* But it is sorted by starting PC within a function. */ - else if (best >= 0 && table[pos].start_region > pc) - break; - } - if (best != -1) - return table[best].exception_handler; - } - - return (void *) 0; -} - -/* find_exception_handler finds the correct handler, if there is one, to - handle an exception. - returns a pointer to the handler which controlled should be transferred - to, or NULL if there is nothing left. - Parameters: - PC - pc where the exception originates. If this is a rethrow, - then this starts out as a pointer to the exception table - entry we wish to rethrow out of. - TABLE - exception table for the current module. - EH_INFO - eh info pointer for this exception. - RETHROW - 1 if this is a rethrow. (see incoming value of PC). - CLEANUP - returned flag indicating whether this is a cleanup handler. -*/ -static void * -find_exception_handler (void *pc, exception_descriptor *table, - __eh_info *eh_info, int rethrow, int *cleanup) -{ - - void *retval = NULL; - *cleanup = 1; - if (table) - { - int pos = 0; - /* The new model assumed the table is sorted inner-most out so the - first region we find which matches is the correct one */ - - exception_table *tab = &(table->table[0]); - - /* Subtract 1 from the PC to avoid hitting the next region */ - if (rethrow) - { - /* pc is actually the region table entry to rethrow out of */ - pos = ((exception_table *) pc) - tab; - pc = ((exception_table *) pc)->end_region - 1; - - /* The label is always on the LAST handler entry for a region, - so we know the next entry is a different region, even if the - addresses are the same. Make sure its not end of table tho. */ - if (tab[pos].start_region != (void *) -1) - pos++; - } - else - pc--; - - /* We can't do a binary search because the table is in inner-most - to outermost address ranges within functions */ - for ( ; tab[pos].start_region != (void *) -1; pos++) - { - if (tab[pos].start_region <= pc && tab[pos].end_region > pc) - { - if (tab[pos].match_info) - { - __eh_matcher matcher = eh_info->match_function; - /* match info but no matcher is NOT a match */ - if (matcher) - { - void *ret = (*matcher)((void *) eh_info, - tab[pos].match_info, table); - if (ret) - { - if (retval == NULL) - retval = tab[pos].exception_handler; - *cleanup = 0; - break; - } - } - } - else - { - if (retval == NULL) - retval = tab[pos].exception_handler; - } - } - } - } - return retval; -} -#endif /* DWARF2_UNWIND_INFO */ -#endif /* EH_TABLE_LOOKUP */ - -#ifdef DWARF2_UNWIND_INFO -/* Support code for exception handling using static unwind information. */ - -#include "frame.h" - -/* This type is used in get_reg and put_reg to deal with ABIs where a void* - is smaller than a word, such as the Irix 6 n32 ABI. We cast twice to - avoid a warning about casting between int and pointer of different - sizes. */ - -typedef int ptr_type __attribute__ ((mode (pointer))); - -#ifdef INCOMING_REGNO -/* Is the saved value for register REG in frame UDATA stored in a register - window in the previous frame? */ - -/* ??? The Sparc INCOMING_REGNO references TARGET_FLAT. This allows us - to use the macro here. One wonders, though, that perhaps TARGET_FLAT - compiled functions won't work with the frame-unwind stuff here. - Perhaps the entireity of in_reg_window should be conditional on having - seen a DW_CFA_GNU_window_save? */ -#define target_flags 0 - -static int -in_reg_window (int reg, frame_state *udata) -{ - if (udata->saved[reg] == REG_SAVED_REG) - return INCOMING_REGNO (reg) == reg; - if (udata->saved[reg] != REG_SAVED_OFFSET) - return 0; - -#ifdef STACK_GROWS_DOWNWARD - return udata->reg_or_offset[reg] > 0; -#else - return udata->reg_or_offset[reg] < 0; -#endif -} -#else -static inline int in_reg_window (int reg, frame_state *udata) { return 0; } -#endif /* INCOMING_REGNO */ - -/* Get the address of register REG as saved in UDATA, where SUB_UDATA is a - frame called by UDATA or 0. */ - -static word_type * -get_reg_addr (unsigned reg, frame_state *udata, frame_state *sub_udata) -{ - while (udata->saved[reg] == REG_SAVED_REG) - { - reg = udata->reg_or_offset[reg]; - if (in_reg_window (reg, udata)) - { - udata = sub_udata; - sub_udata = NULL; - } - } - if (udata->saved[reg] == REG_SAVED_OFFSET) - return (word_type *)(udata->cfa + udata->reg_or_offset[reg]); - else - abort (); -} - -/* Get the value of register REG as saved in UDATA, where SUB_UDATA is a - frame called by UDATA or 0. */ - -static inline void * -get_reg (unsigned reg, frame_state *udata, frame_state *sub_udata) -{ - return (void *)(ptr_type) *get_reg_addr (reg, udata, sub_udata); -} - -/* Overwrite the saved value for register REG in frame UDATA with VAL. */ - -static inline void -put_reg (unsigned reg, void *val, frame_state *udata) -{ - *get_reg_addr (reg, udata, NULL) = (word_type)(ptr_type) val; -} - -/* Copy the saved value for register REG from frame UDATA to frame - TARGET_UDATA. Unlike the previous two functions, this can handle - registers that are not one word large. */ - -static void -copy_reg (unsigned reg, frame_state *udata, frame_state *target_udata) -{ - word_type *preg = get_reg_addr (reg, udata, NULL); - word_type *ptreg = get_reg_addr (reg, target_udata, NULL); - - memcpy (ptreg, preg, __builtin_dwarf_reg_size (reg)); -} - -/* Retrieve the return address for frame UDATA. */ - -static inline void * -get_return_addr (frame_state *udata, frame_state *sub_udata) -{ - return __builtin_extract_return_addr - (get_reg (udata->retaddr_column, udata, sub_udata)); -} - -/* Overwrite the return address for frame UDATA with VAL. */ - -static inline void -put_return_addr (void *val, frame_state *udata) -{ - val = __builtin_frob_return_addr (val); - put_reg (udata->retaddr_column, val, udata); -} - -/* Given the current frame UDATA and its return address PC, return the - information about the calling frame in CALLER_UDATA. */ - -static void * -next_stack_level (void *pc, frame_state *udata, frame_state *caller_udata) -{ - caller_udata = __frame_state_for (pc, caller_udata); - if (! caller_udata) - return 0; - - /* Now go back to our caller's stack frame. If our caller's CFA register - was saved in our stack frame, restore it; otherwise, assume the CFA - register is SP and restore it to our CFA value. */ - if (udata->saved[caller_udata->cfa_reg]) - caller_udata->cfa = get_reg (caller_udata->cfa_reg, udata, 0); - else - caller_udata->cfa = udata->cfa; - caller_udata->cfa += caller_udata->cfa_offset; - - return caller_udata; -} - -/* Hook to call before __terminate if only cleanup handlers remain. */ -void -__unwinding_cleanup () -{ -} - -/* throw_helper performs some of the common grunt work for a throw. This - routine is called by throw and rethrows. This is pretty much split - out from the old __throw routine. An addition has been added which allows - for a dummy call to a routine __unwinding_cleanup() when there are nothing - but cleanups remaining. This allows a debugger to examine the state - at which the throw was executed, before any cleanups, rather than - at the terminate point after the stack has been unwound. - - EH is the current eh_context structure. - PC is the address of the call to __throw. - MY_UDATA is the unwind information for __throw. - OFFSET_P is where we return the SP adjustment offset. */ - -static void * -throw_helper (eh, pc, my_udata, offset_p) - struct eh_context *eh; - void *pc; - frame_state *my_udata; - long *offset_p; -{ - frame_state ustruct2, *udata = &ustruct2; - frame_state ustruct; - frame_state *sub_udata = &ustruct; - void *saved_pc = pc; - void *handler; - void *handler_p; - void *pc_p; - frame_state saved_ustruct; - int new_eh_model; - int cleanup = 0; - int only_cleanup = 0; - int rethrow = 0; - int saved_state = 0; - long args_size; - __eh_info *eh_info = (__eh_info *)eh->info; - - /* Do we find a handler based on a re-throw PC? */ - if (eh->table_index != (void *) 0) - rethrow = 1; - - memcpy (udata, my_udata, sizeof (*udata)); - - handler = (void *) 0; - for (;;) - { - frame_state *p = udata; - udata = next_stack_level (pc, udata, sub_udata); - sub_udata = p; - - /* If we couldn't find the next frame, we lose. */ - if (! udata) - break; - - if (udata->eh_ptr == NULL) - new_eh_model = 0; - else - new_eh_model = (((exception_descriptor *)(udata->eh_ptr))-> - runtime_id_field == NEW_EH_RUNTIME); - - if (rethrow) - { - rethrow = 0; - handler = find_exception_handler (eh->table_index, udata->eh_ptr, - eh_info, 1, &cleanup); - eh->table_index = (void *)0; - } - else - if (new_eh_model) - handler = find_exception_handler (pc, udata->eh_ptr, eh_info, - 0, &cleanup); - else - handler = old_find_exception_handler (pc, udata->eh_ptr); - - /* If we found one, we can stop searching, if its not a cleanup. - for cleanups, we save the state, and keep looking. This allows - us to call a debug hook if there are nothing but cleanups left. */ - if (handler) - if (cleanup) - { - if (!saved_state) - { - saved_ustruct = *udata; - handler_p = handler; - pc_p = pc; - saved_state = 1; - only_cleanup = 1; - } - } - else - { - only_cleanup = 0; - break; - } - - /* Otherwise, we continue searching. We subtract 1 from PC to avoid - hitting the beginning of the next region. */ - pc = get_return_addr (udata, sub_udata) - 1; - } - - if (saved_state) - { - udata = &saved_ustruct; - handler = handler_p; - pc = pc_p; - if (only_cleanup) - __unwinding_cleanup (); - } - - /* If we haven't found a handler by now, this is an unhandled - exception. */ - if (! handler) - __terminate(); - - eh->handler_label = handler; - - args_size = udata->args_size; - - if (pc == saved_pc) - /* We found a handler in the throw context, no need to unwind. */ - udata = my_udata; - else - { - int i; - - /* Unwind all the frames between this one and the handler by copying - their saved register values into our register save slots. */ - - /* Remember the PC where we found the handler. */ - void *handler_pc = pc; - - /* Start from the throw context again. */ - pc = saved_pc; - memcpy (udata, my_udata, sizeof (*udata)); - - while (pc != handler_pc) - { - frame_state *p = udata; - udata = next_stack_level (pc, udata, sub_udata); - sub_udata = p; - - for (i = 0; i < FIRST_PSEUDO_REGISTER; ++i) - if (i != udata->retaddr_column && udata->saved[i]) - { - /* If you modify the saved value of the return address - register on the SPARC, you modify the return address for - your caller's frame. Don't do that here, as it will - confuse get_return_addr. */ - if (in_reg_window (i, udata) - && udata->saved[udata->retaddr_column] == REG_SAVED_REG - && udata->reg_or_offset[udata->retaddr_column] == i) - continue; - copy_reg (i, udata, my_udata); - } - - pc = get_return_addr (udata, sub_udata) - 1; - } - - /* But we do need to update the saved return address register from - the last frame we unwind, or the handler frame will have the wrong - return address. */ - if (udata->saved[udata->retaddr_column] == REG_SAVED_REG) - { - i = udata->reg_or_offset[udata->retaddr_column]; - if (in_reg_window (i, udata)) - copy_reg (i, udata, my_udata); - } - } - /* udata now refers to the frame called by the handler frame. */ - - /* We adjust SP by the difference between __throw's CFA and the CFA for - the frame called by the handler frame, because those CFAs correspond - to the SP values at the two call sites. We need to further adjust by - the args_size of the handler frame itself to get the handler frame's - SP from before the args were pushed for that call. */ -#ifdef STACK_GROWS_DOWNWARD - *offset_p = udata->cfa - my_udata->cfa + args_size; -#else - *offset_p = my_udata->cfa - udata->cfa - args_size; -#endif - - return handler; -} - - -/* We first search for an exception handler, and if we don't find - it, we call __terminate on the current stack frame so that we may - use the debugger to walk the stack and understand why no handler - was found. - - If we find one, then we unwind the frames down to the one that - has the handler and transfer control into the handler. */ - -/*extern void __throw(void) __attribute__ ((__noreturn__));*/ - -void -__throw () -{ - struct eh_context *eh = (*get_eh_context) (); - void *pc, *handler; - long offset; - - /* XXX maybe make my_ustruct static so we don't have to look it up for - each throw. */ - frame_state my_ustruct, *my_udata = &my_ustruct; - - /* This is required for C++ semantics. We must call terminate if we - try and rethrow an exception, when there is no exception currently - active. */ - if (! eh->info) - __terminate (); - - /* Start at our stack frame. */ -label: - my_udata = __frame_state_for (&&label, my_udata); - if (! my_udata) - __terminate (); - - /* We need to get the value from the CFA register. */ - my_udata->cfa = __builtin_dwarf_cfa (); - - /* Do any necessary initialization to access arbitrary stack frames. - On the SPARC, this means flushing the register windows. */ - __builtin_unwind_init (); - - /* Now reset pc to the right throw point. */ - pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1; - - handler = throw_helper (eh, pc, my_udata, &offset); - - /* Now go! */ - - __builtin_eh_return ((void *)eh, offset, handler); - - /* Epilogue: restore the handler frame's register values and return - to the stub. */ -} - -/*extern void __rethrow(void *) __attribute__ ((__noreturn__));*/ - -void -__rethrow (index) - void *index; -{ - struct eh_context *eh = (*get_eh_context) (); - void *pc, *handler; - long offset; - - /* XXX maybe make my_ustruct static so we don't have to look it up for - each throw. */ - frame_state my_ustruct, *my_udata = &my_ustruct; - - /* This is required for C++ semantics. We must call terminate if we - try and rethrow an exception, when there is no exception currently - active. */ - if (! eh->info) - __terminate (); - - /* This is the table index we want to rethrow from. The value of - the END_REGION label is used for the PC of the throw, and the - search begins with the next table entry. */ - eh->table_index = index; - - /* Start at our stack frame. */ -label: - my_udata = __frame_state_for (&&label, my_udata); - if (! my_udata) - __terminate (); - - /* We need to get the value from the CFA register. */ - my_udata->cfa = __builtin_dwarf_cfa (); - - /* Do any necessary initialization to access arbitrary stack frames. - On the SPARC, this means flushing the register windows. */ - __builtin_unwind_init (); - - /* Now reset pc to the right throw point. */ - pc = __builtin_extract_return_addr (__builtin_return_address (0)) - 1; - - handler = throw_helper (eh, pc, my_udata, &offset); - - /* Now go! */ - - __builtin_eh_return ((void *)eh, offset, handler); - - /* Epilogue: restore the handler frame's register values and return - to the stub. */ -} -#endif /* DWARF2_UNWIND_INFO */ - -#endif /* L_eh */ - -#ifdef L_pure -#ifndef inhibit_libc -/* This gets us __GNU_LIBRARY__. */ -#undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch. */ -#include <stdio.h> - -#ifdef __GNU_LIBRARY__ - /* Avoid forcing the library's meaning of `write' on the user program - by using the "internal" name (for use within the library) */ -#define write(fd, buf, n) __write((fd), (buf), (n)) -#endif -#endif /* inhibit_libc */ - -#define MESSAGE "pure virtual method called\n" - -void -__pure_virtual () -{ -#ifndef inhibit_libc - write (2, MESSAGE, sizeof (MESSAGE) - 1); -#endif - __terminate (); -} -#endif diff --git a/gcc/objc/Make-lang.in b/gcc/objc/Make-lang.in deleted file mode 100755 index 1c0d877..0000000 --- a/gcc/objc/Make-lang.in +++ /dev/null @@ -1,173 +0,0 @@ -# Top level makefile fragment for GNU Objective-C -# Copyright (C) 1997, 1998 Free Software Foundation, Inc. - -#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 Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# This file provides the language dependent support in the main Makefile. -# Each language makefile fragment must provide the following targets: -# -# foo.all.build, foo.all.cross, foo.start.encap, foo.rest.encap, -# foo.info, foo.dvi, -# foo.install-normal, foo.install-common, foo.install-info, foo.install-man, -# foo.uninstall, foo.distdir, -# foo.mostlyclean, foo.clean, foo.distclean, foo.extraclean, -# foo.maintainer-clean, foo.stage1, foo.stage2, foo.stage3, foo.stage4 -# -# where `foo' is the name of the language. -# -# It should also provide rules for: -# -# - making any compiler driver (eg: g++) -# - the compiler proper (eg: cc1plus) -# - define the names for selecting the language in LANGUAGES. -# -# Extra flags to pass to recursive makes. -OBJC_FLAGS_TO_PASS = \ - "OBJC_FOR_BUILD=$(OBJC_FOR_BUILD)" \ - "OBJCFLAGS=$(OBJCFLAGS)" \ - "OBJC_FOR_TARGET=$(OBJC_FOR_TARGET)" \ - -# Actual names to use when installing a native compiler. -#OBJC_INSTALL_NAME = `t='$(program_transform_name)'; echo c++ | sed $$t` - -# Actual names to use when installing a cross-compiler. -#OBJC_CROSS_NAME = `t='$(program_transform_cross_name)'; echo c++ | sed $$t` - -# -# Define the names for selecting Objective-C in LANGUAGES. -OBJC objc: cc1obj$(exeext) -OBJECTIVE-C objective-c: cc1obj$(exeext) - -# Tell GNU make to ignore these if they exist. -.PHONY: objective-c objc ObjC - -# Language-specific object files for Objective C. -OBJC_OBJS = objc-parse.o objc-act.o $(C_AND_OBJC_OBJS) - -cc1obj$(exeext): $(P) $(OBJS) $(OBJC_OBJS) $(LIBDEPS) - $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $(OBJS) $(OBJC_OBJS) $(LIBS) - -# Objective C language specific files. - -# CYGNUS LOCAL built in build directory -objc-parse.o : objc-parse.c \ - $(CONFIG_H) $(TREE_H) $(srcdir)/toplev.h \ - $(srcdir)/c-lex.h $(srcdir)/c-tree.h $(srcdir)/input.h \ - $(srcdir)/flags.h $(srcdir)/output.h $(srcdir)/objc/objc-act.h system.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ - -c objc-parse.c - -# CYGNUS LOCAL built in build directory -objc-parse.c : objc-parse.y - $(BISON) $(BISONFLAGS) -o objc-parse.c objc-parse.y - -# CYGNUS LOCAL built in build directory -objc-parse.y: $(srcdir)/c-parse.in - echo '/*WARNING: This file is automatically generated!*/' >tmp-objc-prs.y - sed -e "/^ifc$$/,/^end ifc$$/d" \ - -e "/^ifobjc$$/d" -e "/^end ifobjc$$/d" \ - $(srcdir)/c-parse.in >>tmp-objc-prs.y - $(srcdir)/move-if-change tmp-objc-prs.y objc-parse.y - -# CYGNUS LOCAL built in build directory -objc-act.o : $(srcdir)/objc/objc-act.c \ - $(CONFIG_H) $(TREE_H) $(RTL_H) system.h \ - $(srcdir)/c-tree.h $(srcdir)/c-lex.h $(srcdir)/toplev.h \ - $(srcdir)/flags.h $(srcdir)/objc/objc-act.h $(srcdir)/input.h \ - $(srcdir)/function.h $(srcdir)/output.h c-parse.h - $(CC) $(ALL_CFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) -I$(srcdir)/objc \ - -c $(srcdir)/objc/objc-act.c - -# -# Build hooks: - -objc.all.build: -objc.all.cross: -objc.start.encap: -objc.rest.encap: - -objc.info: -objc.dvi: - -# -# Install hooks: -# cc1obj is installed elsewhere as part of $(COMPILERS). - -objc.install-normal: - -objc.install-common: - -objc.install-info: - -objc.install-man: - -objc.uninstall: -# -# Clean hooks: -# A lot of the ancillary files are deleted by the main makefile. -# We just have to delete files specific to us. -objc.mostlyclean: - -rm -f tmp-objc-prs.y - -rm -f objc/*$(objext) objc/xforward objc/fflags -# CYGNUS LOCAL: built in build directory - -rm -f objc-parse.c objc-parse.output -# END CYGNUS LOCAL -objc.clean: objc.mostlyclean - -rm -rf objc-headers -# CYGNUS LOCAL: built in build directory - -rm -f objc-parse.y -# END CYGNUS LOCAL -objc.distclean: - -rm -f objc/Makefile objc/Make-host objc/Make-target - -rm -f objc/config.status objc/config.cache - -rm -f objc-parse.output -objc.extraclean: -objc.maintainer-clean: - -rm -f objc/objc-parse.y - -rm -f objc/objc-parse.c objc/objc-parse.output - -# -# Stage hooks: - -objc.stage1: stage1-start - -mv objc/*$(objext) stage1/objc - -mv cc1obj$(exeext) stage1 -objc.stage2: stage2-start - -mv objc/*$(objext) stage2/objc - -mv cc1obj$(exeext) stage2 -objc.stage3: stage3-start - -mv objc/*$(objext) stage3/objc - -mv cc1obj$(exeext) stage3 -objc.stage4: stage4-start - -mv objc/*$(objext) stage4/objc - -mv cc1obj$(exeext) stage4 - -# -# Maintenance hooks: - -# This target creates the files that can be rebuilt, but go in the -# distribution anyway. It then copies the files to the distdir directory. -# ??? Note that this should be fixed once the Makefile is fixed to do -# the build in the inner directory. -objc.distdir: $(srcdir)/objc/objc-parse.c - mkdir tmp/objc -# cd objc ; $(MAKE) $(FLAGS_TO_PASS) objc-parse.c - cd objc; \ - for file in *[0-9a-zA-Z+]; do \ - ln $$file ../tmp/objc >/dev/null 2>&1 || cp $$file ../tmp/objc; \ - done diff --git a/gcc/objc/Makefile.in b/gcc/objc/Makefile.in deleted file mode 100755 index 71c564c..0000000 --- a/gcc/objc/Makefile.in +++ /dev/null @@ -1,73 +0,0 @@ -# GNU Objective C frontend Makefile -# Copyright (C) 1993, 1995, 1996, 1997, 1998 Free Software Foundation, Inc. -# -# 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 Software -# Foundation, 59 Temple Place - Suite 330, -# Boston, MA 02111-1307, USA. - -# The Makefile built from this file lives in the objc language subdirectory. -# Its purpose is to provide support for: -# -# 1. recursion where necessary, and only then (building .o's), and -# 2. building and debugging cc1objc from the language subdirectory. -# -# The parent Makefile handles all other chores, with help from the language -# Makefile fragment. -# -# The targets for external use are `all' and `mostlyclean'. - -SHELL=/bin/sh - -OPTIMIZE= -O - -srcdir = . -VPATH = $(srcdir) - -AR = ar -AR_FLAGS = rc - -# Define this as & to perform parallel make on a Sequent. -# Note that this has some bugs, and it seems currently necessary -# to compile all the gen* files first by hand to avoid erroneous results. -P = - -# Definition of `all' is here so that new rules inserted by sed -# do not specify the default target. -all: all.indirect - -# sed inserts variable overrides after the following line. -####target overrides -####host overrides -####cross overrides -####build overrides -# - -# Now figure out from those variables how to compile and link. -all.indirect: Makefile frontend - -frontend: - cd ..; $(MAKE) cc1obj$(exeext) - -Makefile: $(srcdir)/Makefile.in $(srcdir)/../configure - cd ..; $(SHELL) config.status - -mostlyclean: - -rm -f *.o xforward fflags -clean: mostlyclean -distclean: mostlyclean -extraclean: mostlyclean - -# For Sun VPATH. - diff --git a/gcc/objc/README b/gcc/objc/README deleted file mode 100755 index f478d67..0000000 --- a/gcc/objc/README +++ /dev/null @@ -1,97 +0,0 @@ - -GNU Objective C notes -********************* - -This document is to explain what has been done, and a little about how -specific features differ from other implementations. The runtime has -been completely rewritten in gcc 2.4. The earlier runtime had several -severe bugs and was rather incomplete. The compiler has had several -new features added as well. - -This is not documentation for Objective C, it is usable to someone -who knows Objective C from somewhere else. - - -Runtime API functions -===================== - -The runtime is modeled after the NeXT Objective C runtime. That is, -most functions have semantics as it is known from the NeXT. The -names, however, have changed. All runtime API functions have names -of lowercase letters and underscores as opposed to the -`traditional' mixed case names. - The runtime api functions are not documented as of now. -Someone offered to write it, and did it, but we were not allowed to -use it by his university (Very sad story). We have started writing -the documentation over again. This will be announced in appropriate -places when it becomes available. - - -Protocols -========= - -Protocols are now fully supported. The semantics is exactly as on the -NeXT. There is a flag to specify how protocols should be typechecked -when adopted to classes. The normal typechecker requires that all -methods in a given protocol must be implemented in the class that -adopts it -- it is not enough to inherit them. The flag -`-Wno-protocol' causes it to allow inherited methods, while -`-Wprotocols' is the default which requires them defined. - - -+initialize -=========== - -This method, if defined, is called before any other instance or class -methods of that particular class. This method is not inherited, and -is thus not called as initializer for a subclass that doesn't define -it itself. Thus, each +initialize method is called exactly once (or -never if no methods of that particular class is never called). -Besides this, it is allowed to have several +initialize methods, one -for each category. The order in which these (multiple methods) are -called is not well defined. I am not completely certain what the -semantics of this method is for other implementations, but this is -how it works for GNU Objective C. - - -Passivation/Activation/Typedstreams -=================================== - -This is supported in the style of NeXT TypedStream's. Consult the -headerfile Typedstreams.h for api functions. I (Kresten) have -rewritten it in Objective C, but this implementation is not part of -2.4, it is available from the GNU Objective C prerelease archive. - There is one difference worth noting concerning objects stored with -objc_write_object_reference (aka NXWriteObjectReference). When these -are read back in, their object is not guaranteed to be available until -the `-awake' method is called in the object that requests that object. -To objc_read_object you must pass a pointer to an id, which is valid -after exit from the function calling it (like e.g. an instance -variable). In general, you should not use objects read in until the --awake method is called. - - -Acknowledgements -================ - -The GNU Objective C team: Geoffrey Knauth <gsk@marble.com> (manager), -Tom Wood <wood@next.com> (compiler) and Kresten Krab Thorup -<krab@iesd.auc.dk> (runtime) would like to thank a some people for -participating in the development of the present GNU Objective C. - -Paul Burchard <burchard@geom.umn.edu> and Andrew McCallum -<mccallum@cs.rochester.edu> has been very helpful debugging the -runtime. Eric Herring <herring@iesd.auc.dk> has been very helpful -cleaning up after the documentation-copyright disaster and is now -helping with the new documentation. - -Steve Naroff <snaroff@next.com> and Richard Stallman -<rms@gnu.ai.mit.edu> has been very helpful with implementation details -in the compiler. - - -Bug Reports -=========== - -Please read the section `Submitting Bugreports' of the gcc manual -before you submit any bugs. diff --git a/gcc/objc/config-lang.in b/gcc/objc/config-lang.in deleted file mode 100755 index 5287c8d..0000000 --- a/gcc/objc/config-lang.in +++ /dev/null @@ -1,35 +0,0 @@ -# Top level configure fragment for the GNU Objective-C Runtime Library. -# Copyright (C) 1997, 1998 Free Software Foundation, Inc. - -#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 Software Foundation, 59 Temple Place - Suite 330, -#Boston, MA 02111-1307, USA. - -# Configure looks for the existence of this file to auto-config each language. -# We define several parameters used by configure: -# -# language - name of language as it would appear in $(LANGUAGES) -# compilers - value to add to $(COMPILERS) -# stagestuff - files to add to $(STAGESTUFF) -# diff_excludes - files to ignore when building diffs between two versions. - -language="objc" - -compilers="cc1obj\$(exeext)" - -stagestuff="" - -diff_excludes="-x objc-parse.c -x objc-parse.y " diff --git a/gcc/objc/lang-specs.h b/gcc/objc/lang-specs.h deleted file mode 100755 index 20d4ab3..0000000 --- a/gcc/objc/lang-specs.h +++ /dev/null @@ -1,93 +0,0 @@ -/* Definitions for specs for Objective-C. - Copyright (C) 1998 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This is the contribution to the `default_compilers' array in gcc.c for - objc. */ - - {".m", {"@objective-c"}}, - {"@objective-c", -#if USE_CPPLIB - {"%{E|M|MM:cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__OBJC__ -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{fleading-underscore} %{fno-leading-underscore}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}}\n}", - "%{!M:%{!MM:%{!E:cc1obj %i %1 \ - %{nostdinc*} %{A*} %{I*} %{P} %I\ - %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__OBJC__ -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"} -#else /* ! USE_CPPLIB */ - {"cpp -lang-objc %{nostdinc*} %{C} %{v} %{A*} %{I*} %{P} %I\ - %{C:%{!E:%eGNU C does not support -C without using -E}}\ - %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG}\ - -undef -D__OBJC__ -D__GNUC__=%v1 -D__GNUC_MINOR__=%v2\ - %{ansi:-trigraphs -D__STRICT_ANSI__}\ - %{!undef:%{!ansi:%p} %P} %{trigraphs}\ - %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\ - %{traditional} %{ftraditional:-traditional}\ - %{traditional-cpp:-traditional}\ - %{fleading-underscore} %{fno-leading-underscore}\ - %{g*} %{W*} %{w} %{pedantic*} %{H} %{d*} %C %{D*} %{U*} %{i*} %Z\ - %i %{!M:%{!MM:%{!E:%{!pipe:%g.mi}}}}%{E:%W{o*}}%{M:%W{o*}}%{MM:%W{o*}} |\n", - "%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.mi} %1 \ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n\ - %{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"} -#endif /* ! USE_CPPLIB */ - }, - {".mi", {"@objc-cpp-output"}}, - {"@objc-cpp-output", - {"%{!M:%{!MM:%{!E:cc1obj %{!pipe:%g.i} %1 \ - %{!Q:-quiet} -dumpbase %b.m %{d*} %{m*} %{a*}\ - %{g*} %{O*} %{W*} %{w} %{pedantic*} %{ansi} \ - %{traditional} %{v:-version} %{pg:-p} %{p} %{f*} \ - -lang-objc %{gen-decls} \ - %{aux-info*}\ - %{pg:%{fomit-frame-pointer:%e-pg and -fomit-frame-pointer are incompatible}}\ - %{S:%W{o*}%{!o*:-o %b.s}}%{!S:-o %{|!pipe:%g.s}} |\n", - "%{!S:as %a %Y\ - %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}\ - %{!pipe:%g.s} %A\n }}}}"}}, diff --git a/gcc/objc/objc-act.c b/gcc/objc/objc-act.c deleted file mode 100755 index e53b26f..0000000 --- a/gcc/objc/objc-act.c +++ /dev/null @@ -1,8555 +0,0 @@ -/* Implement classes and message passing for Objective C. - Copyright (C) 1992, 93-95, 97, 1998 Free Software Foundation, Inc. - Contributed by Steve Naroff. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* Purpose: This module implements the Objective-C 4.0 language. - - compatibility issues (with the Stepstone translator): - - - does not recognize the following 3.3 constructs. - @requires, @classes, @messages, = (...) - - methods with variable arguments must conform to ANSI standard. - - tagged structure definitions that appear in BOTH the interface - and implementation are not allowed. - - public/private: all instance variables are public within the - context of the implementation...I consider this to be a bug in - the translator. - - statically allocated objects are not supported. the user will - receive an error if this service is requested. - - code generation `options': - - - OBJC_INT_SELECTORS */ - -#include "config.h" -#include "system.h" -#include "tree.h" -#include "c-tree.h" -#include "c-lex.h" -#include "flags.h" -#include "objc-act.h" -#include "input.h" -#include "except.h" -#include "function.h" -#include "output.h" -#include "toplev.h" - -#if USE_CPPLIB -#include "cpplib.h" -extern cpp_reader parse_in; -extern cpp_options parse_options; -#endif - -/* This is the default way of generating a method name. */ -/* I am not sure it is really correct. - Perhaps there's a danger that it will make name conflicts - if method names contain underscores. -- rms. */ -#ifndef OBJC_GEN_METHOD_LABEL -#define OBJC_GEN_METHOD_LABEL(BUF, IS_INST, CLASS_NAME, CAT_NAME, SEL_NAME, NUM) \ - do { \ - char *temp; \ - sprintf ((BUF), "_%s_%s_%s_%s", \ - ((IS_INST) ? "i" : "c"), \ - (CLASS_NAME), \ - ((CAT_NAME)? (CAT_NAME) : ""), \ - (SEL_NAME)); \ - for (temp = (BUF); *temp; temp++) \ - if (*temp == ':') *temp = '_'; \ - } while (0) -#endif - -/* These need specifying. */ -#ifndef OBJC_FORWARDING_STACK_OFFSET -#define OBJC_FORWARDING_STACK_OFFSET 0 -#endif - -#ifndef OBJC_FORWARDING_MIN_OFFSET -#define OBJC_FORWARDING_MIN_OFFSET 0 -#endif - -/* Define the special tree codes that we use. */ - -/* Table indexed by tree code giving a string containing a character - classifying the tree code. Possibilities are - t, d, s, c, r, <, 1 and 2. See objc-tree.def for details. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) TYPE, - -char objc_tree_code_type[] = { - 'x', -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Table indexed by tree code giving number of expression - operands beyond the fixed part of the node structure. - Not used for types or decls. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) LENGTH, - -int objc_tree_code_length[] = { - 0, -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Names of tree components. - Used for printing out the tree and error messages. */ -#define DEFTREECODE(SYM, NAME, TYPE, LEN) NAME, - -char *objc_tree_code_name[] = { - "@@dummy", -#include "objc-tree.def" -}; -#undef DEFTREECODE - -/* Set up for use of obstacks. */ - -#include "obstack.h" - -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* This obstack is used to accumulate the encoding of a data type. */ -static struct obstack util_obstack; -/* This points to the beginning of obstack contents, - so we can free the whole contents. */ -char *util_firstobj; - -/* List of classes with list of their static instances. */ -static tree objc_static_instances = NULL_TREE; - -/* The declaration of the array administrating the static instances. */ -static tree static_instances_decl = NULL_TREE; - -/* for encode_method_def */ -#include "rtl.h" -#include "c-parse.h" - -#define OBJC_VERSION (flag_next_runtime ? 5 : 8) -#define PROTOCOL_VERSION 2 - -#define OBJC_ENCODE_INLINE_DEFS 0 -#define OBJC_ENCODE_DONT_INLINE_DEFS 1 - -/*** Private Interface (procedures) ***/ - -/* Used by compile_file. */ - -static void init_objc PROTO((void)); -static void finish_objc PROTO((void)); - -/* Code generation. */ - -static void synth_module_prologue PROTO((void)); -static tree build_constructor PROTO((tree, tree)); -static char *build_module_descriptor PROTO((void)); -static tree init_module_descriptor PROTO((tree)); -static tree build_objc_method_call PROTO((int, tree, tree, - tree, tree, tree)); -static void generate_strings PROTO((void)); -static tree get_proto_encoding PROTO((tree)); -static void build_selector_translation_table PROTO((void)); -static tree build_ivar_chain PROTO((tree, int)); - -static tree objc_add_static_instance PROTO((tree, tree)); - -static tree build_ivar_template PROTO((void)); -static tree build_method_template PROTO((void)); -static tree build_private_template PROTO((tree)); -static void build_class_template PROTO((void)); -static void build_selector_template PROTO((void)); -static void build_category_template PROTO((void)); -static tree build_super_template PROTO((void)); -static tree build_category_initializer PROTO((tree, tree, tree, - tree, tree, tree)); -static tree build_protocol_initializer PROTO((tree, tree, tree, - tree, tree)); - -static void synth_forward_declarations PROTO((void)); -static void generate_ivar_lists PROTO((void)); -static void generate_dispatch_tables PROTO((void)); -static void generate_shared_structures PROTO((void)); -static tree generate_protocol_list PROTO((tree)); -static void generate_forward_declaration_to_string_table PROTO((void)); -static void build_protocol_reference PROTO((tree)); - -#if 0 -static tree init_selector PROTO((int)); -#endif -static tree build_keyword_selector PROTO((tree)); -static tree synth_id_with_class_suffix PROTO((char *, tree)); - -static void generate_static_references PROTO((void)); -static int check_methods_accessible PROTO((tree, tree, - int)); -static void encode_aggregate_within PROTO((tree, int, int, - int, int)); - -/* We handle printing method names ourselves for ObjC */ -extern char *(*decl_printable_name) (); - -/* Misc. bookkeeping */ - -typedef struct hashed_entry *hash; -typedef struct hashed_attribute *attr; - -struct hashed_attribute -{ - attr next; - tree value; -}; -struct hashed_entry -{ - attr list; - hash next; - tree key; -}; - -static void hash_init PROTO((void)); -static void hash_enter PROTO((hash *, tree)); -static hash hash_lookup PROTO((hash *, tree)); -static void hash_add_attr PROTO((hash, tree)); -static tree lookup_method PROTO((tree, tree)); -static tree lookup_instance_method_static PROTO((tree, tree)); -static tree lookup_class_method_static PROTO((tree, tree)); -static tree add_class PROTO((tree)); -static void add_category PROTO((tree, tree)); - -enum string_section -{ - class_names, /* class, category, protocol, module names */ - meth_var_names, /* method and variable names */ - meth_var_types /* method and variable type descriptors */ -}; - -static tree add_objc_string PROTO((tree, - enum string_section)); -static tree get_objc_string_decl PROTO((tree, - enum string_section)); -static tree build_objc_string_decl PROTO((tree, - enum string_section)); -static tree build_selector_reference_decl PROTO((tree)); - -/* Protocol additions. */ - -static tree add_protocol PROTO((tree)); -static tree lookup_protocol PROTO((tree)); -static tree lookup_and_install_protocols PROTO((tree)); - -/* Type encoding. */ - -static void encode_type_qualifiers PROTO((tree)); -static void encode_pointer PROTO((tree, int, int)); -static void encode_array PROTO((tree, int, int)); -static void encode_aggregate PROTO((tree, int, int)); -static void encode_bitfield PROTO((int, int)); -static void encode_type PROTO((tree, int, int)); -static void encode_field_decl PROTO((tree, int, int)); - -static void really_start_method PROTO((tree, tree)); -static int comp_method_with_proto PROTO((tree, tree)); -static int comp_proto_with_proto PROTO((tree, tree)); -static tree get_arg_type_list PROTO((tree, int, int)); -static tree expr_last PROTO((tree)); - -/* Utilities for debugging and error diagnostics. */ - -static void warn_with_method PROTO((char *, int, tree)); -static void error_with_ivar PROTO((char *, tree, tree)); -static char *gen_method_decl PROTO((tree, char *)); -static char *gen_declaration PROTO((tree, char *)); -static char *gen_declarator PROTO((tree, char *, char *)); -static int is_complex_decl PROTO((tree)); -static void adorn_decl PROTO((tree, char *)); -static void dump_interface PROTO((FILE *, tree)); - -/* Everything else. */ - -static void objc_fatal PROTO((void)) - ATTRIBUTE_NORETURN; -static tree define_decl PROTO((tree, tree)); -static tree lookup_method_in_protocol_list PROTO((tree, tree, int)); -static tree lookup_protocol_in_reflist PROTO((tree, tree)); -static tree create_builtin_decl PROTO((enum tree_code, - tree, char *)); -static tree my_build_string PROTO((int, char *)); -static void build_objc_symtab_template PROTO((void)); -static tree init_def_list PROTO((tree)); -static tree init_objc_symtab PROTO((tree)); -static void forward_declare_categories PROTO((void)); -static void generate_objc_symtab_decl PROTO((void)); -static tree build_selector PROTO((tree)); -#if 0 -static tree build_msg_pool_reference PROTO((int)); -#endif -static tree build_typed_selector_reference PROTO((tree, tree)); -static tree build_selector_reference PROTO((tree)); -static tree build_class_reference_decl PROTO((tree)); -static void add_class_reference PROTO((tree)); -static tree objc_copy_list PROTO((tree, tree *)); -static tree build_protocol_template PROTO((void)); -static tree build_descriptor_table_initializer PROTO((tree, tree)); -static tree build_method_prototype_list_template PROTO((tree, int)); -static tree build_method_prototype_template PROTO((void)); -static int forwarding_offset PROTO((tree)); -static tree encode_method_prototype PROTO((tree, tree)); -static tree generate_descriptor_table PROTO((tree, char *, int, tree, tree)); -static void generate_method_descriptors PROTO((tree)); -static tree build_tmp_function_decl PROTO((void)); -static void hack_method_prototype PROTO((tree, tree)); -static void generate_protocol_references PROTO((tree)); -static void generate_protocols PROTO((void)); -static void check_ivars PROTO((tree, tree)); -static tree build_ivar_list_template PROTO((tree, int)); -static tree build_method_list_template PROTO((tree, int)); -static tree build_ivar_list_initializer PROTO((tree, tree)); -static tree generate_ivars_list PROTO((tree, char *, - int, tree)); -static tree build_dispatch_table_initializer PROTO((tree, tree)); -static tree generate_dispatch_table PROTO((tree, char *, - int, tree)); -static tree build_shared_structure_initializer PROTO((tree, tree, tree, tree, - tree, int, tree, tree, - tree)); -static void generate_category PROTO((tree)); -static int is_objc_type_qualifier PROTO((tree)); -static tree adjust_type_for_id_default PROTO((tree)); -static tree check_duplicates PROTO((hash)); -static tree receiver_is_class_object PROTO((tree)); -static int check_methods PROTO((tree, tree, int)); -static int conforms_to_protocol PROTO((tree, tree)); -static void check_protocols PROTO((tree, char *, char *)); -static tree encode_method_def PROTO((tree)); -static void gen_declspecs PROTO((tree, char *, int)); -static void generate_classref_translation_entry PROTO((tree)); -static void handle_class_ref PROTO((tree)); - -/*** Private Interface (data) ***/ - -/* Reserved tag definitions. */ - -#define TYPE_ID "id" -#define TAG_OBJECT "objc_object" -#define TAG_CLASS "objc_class" -#define TAG_SUPER "objc_super" -#define TAG_SELECTOR "objc_selector" - -#define UTAG_CLASS "_objc_class" -#define UTAG_IVAR "_objc_ivar" -#define UTAG_IVAR_LIST "_objc_ivar_list" -#define UTAG_METHOD "_objc_method" -#define UTAG_METHOD_LIST "_objc_method_list" -#define UTAG_CATEGORY "_objc_category" -#define UTAG_MODULE "_objc_module" -#define UTAG_STATICS "_objc_statics" -#define UTAG_SYMTAB "_objc_symtab" -#define UTAG_SUPER "_objc_super" -#define UTAG_SELECTOR "_objc_selector" - -#define UTAG_PROTOCOL "_objc_protocol" -#define UTAG_PROTOCOL_LIST "_objc_protocol_list" -#define UTAG_METHOD_PROTOTYPE "_objc_method_prototype" -#define UTAG_METHOD_PROTOTYPE_LIST "_objc__method_prototype_list" - -#define STRING_OBJECT_CLASS_NAME "NXConstantString" -#define PROTOCOL_OBJECT_CLASS_NAME "Protocol" - -static char *TAG_GETCLASS; -static char *TAG_GETMETACLASS; -static char *TAG_MSGSEND; -static char *TAG_MSGSENDSUPER; -static char *TAG_EXECCLASS; - -/* Set by `continue_class' and checked by `is_public'. */ - -#define TREE_STATIC_TEMPLATE(record_type) (TREE_PUBLIC (record_type)) -#define TYPED_OBJECT(type) \ - (TREE_CODE (type) == RECORD_TYPE && TREE_STATIC_TEMPLATE (type)) - -/* Some commonly used instances of "identifier_node". */ - -static tree self_id, ucmd_id; -static tree unused_list; - -static tree self_decl, umsg_decl, umsg_super_decl; -static tree objc_get_class_decl, objc_get_meta_class_decl; - -static tree super_type, selector_type, id_type, objc_class_type; -static tree instance_type, protocol_type; - -/* Type checking macros. */ - -#define IS_ID(TYPE) \ - (TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (id_type)) -#define IS_PROTOCOL_QUALIFIED_ID(TYPE) \ - (IS_ID (TYPE) && TYPE_PROTOCOL_LIST (TYPE)) -#define IS_SUPER(TYPE) \ - (super_type && TYPE_MAIN_VARIANT (TYPE) == TYPE_MAIN_VARIANT (super_type)) - -static tree class_chain = NULL_TREE; -static tree alias_chain = NULL_TREE; -static tree interface_chain = NULL_TREE; -static tree protocol_chain = NULL_TREE; - -/* Chains to manage selectors that are referenced and defined in the - module. */ - -static tree cls_ref_chain = NULL_TREE; /* Classes referenced. */ -static tree sel_ref_chain = NULL_TREE; /* Selectors referenced. */ - -/* Chains to manage uniquing of strings. */ - -static tree class_names_chain = NULL_TREE; -static tree meth_var_names_chain = NULL_TREE; -static tree meth_var_types_chain = NULL_TREE; - -/* Hash tables to manage the global pool of method prototypes. */ - -static hash *nst_method_hash_list = 0; -static hash *cls_method_hash_list = 0; - -/* Backend data declarations. */ - -static tree UOBJC_SYMBOLS_decl; -static tree UOBJC_INSTANCE_VARIABLES_decl, UOBJC_CLASS_VARIABLES_decl; -static tree UOBJC_INSTANCE_METHODS_decl, UOBJC_CLASS_METHODS_decl; -static tree UOBJC_CLASS_decl, UOBJC_METACLASS_decl; -static tree UOBJC_SELECTOR_TABLE_decl; -static tree UOBJC_MODULES_decl; -static tree UOBJC_STRINGS_decl; - -/* The following are used when compiling a class implementation. - implementation_template will normally be an interface, however if - none exists this will be equal to implementation_context...it is - set in start_class. */ - -static tree implementation_context = NULL_TREE; -static tree implementation_template = NULL_TREE; - -struct imp_entry -{ - struct imp_entry *next; - tree imp_context; - tree imp_template; - tree class_decl; /* _OBJC_CLASS_<my_name>; */ - tree meta_decl; /* _OBJC_METACLASS_<my_name>; */ -}; - -static void handle_impent PROTO((struct imp_entry *)); - -static struct imp_entry *imp_list = 0; -static int imp_count = 0; /* `@implementation' */ -static int cat_count = 0; /* `@category' */ - -static tree objc_class_template, objc_category_template, uprivate_record; -static tree objc_protocol_template, objc_selector_template; -static tree ucls_super_ref, uucls_super_ref; - -static tree objc_method_template, objc_ivar_template; -static tree objc_symtab_template, objc_module_template; -static tree objc_super_template, objc_object_reference; - -static tree objc_object_id, objc_class_id, objc_id_id; -static tree constant_string_id; -static tree constant_string_type; -static tree UOBJC_SUPER_decl; - -static tree method_context = NULL_TREE; -static int method_slot = 0; /* Used by start_method_def, */ - -#define BUFSIZE 1024 - -static char *errbuf; /* Buffer for error diagnostics */ - -/* Data imported from tree.c. */ - -extern enum debug_info_type write_symbols; - -/* Data imported from toplev.c. */ - -extern char *dump_base_name; - -/* Generate code for GNU or NeXT runtime environment. */ - -#ifdef NEXT_OBJC_RUNTIME -int flag_next_runtime = 1; -#else -int flag_next_runtime = 0; -#endif - -int flag_typed_selectors; - -/* Open and close the file for outputting class declarations, if requested. */ - -int flag_gen_declaration = 0; - -FILE *gen_declaration_file; - -/* Warn if multiple methods are seen for the same selector, but with - different argument types. */ - -int warn_selector = 0; - -/* Warn if methods required by a protocol are not implemented in the - class adopting it. When turned off, methods inherited to that - class are also considered implemented */ - -int flag_warn_protocol = 1; - -/* Tells "encode_pointer/encode_aggregate" whether we are generating - type descriptors for instance variables (as opposed to methods). - Type descriptors for instance variables contain more information - than methods (for static typing and embedded structures). This - was added to support features being planned for dbkit2. */ - -static int generating_instance_variables = 0; - -/* Tells the compiler that this is a special run. Do not perform - any compiling, instead we are to test some platform dependent - features and output a C header file with appropriate definitions. */ - -static int print_struct_values = 0; - -/* Some platforms pass small structures through registers versus through - an invisible pointer. Determine at what size structure is the - transition point between the two possibilities. */ - -void -generate_struct_by_value_array () -{ - tree type; - tree field_decl, field_decl_chain; - int i, j; - int aggregate_in_mem[32]; - int found = 0; - - /* Presumbaly no platform passes 32 byte structures in a register. */ - for (i = 1; i < 32; i++) - { - char buffer[5]; - - /* Create an unnamed struct that has `i' character components */ - type = start_struct (RECORD_TYPE, NULL_TREE); - - strcpy (buffer, "c1"); - field_decl = create_builtin_decl (FIELD_DECL, - char_type_node, - buffer); - field_decl_chain = field_decl; - - for (j = 1; j < i; j++) - { - sprintf (buffer, "c%d", j + 1); - field_decl = create_builtin_decl (FIELD_DECL, - char_type_node, - buffer); - chainon (field_decl_chain, field_decl); - } - finish_struct (type, field_decl_chain, NULL_TREE); - - aggregate_in_mem[i] = aggregate_value_p (type); - if (!aggregate_in_mem[i]) - found = 1; - } - - /* We found some structures that are returned in registers instead of memory - so output the necessary data. */ - if (found) - { - for (i = 31; i >= 0; i--) - if (!aggregate_in_mem[i]) - break; - printf ("#define OBJC_MAX_STRUCT_BY_VALUE %d\n\n", i); - - /* The first member of the structure is always 0 because we don't handle - structures with 0 members */ - printf ("static int struct_forward_array[] = {\n 0"); - - for (j = 1; j <= i; j++) - printf (", %d", aggregate_in_mem[j]); - printf ("\n};\n"); - } - - exit (0); -} - -#if USE_CPPLIB -extern char *yy_cur; -#endif - -void -lang_init_options () -{ -#if USE_CPPLIB - cpp_reader_init (&parse_in); - parse_in.opts = &parse_options; - cpp_options_init (&parse_options); -#endif -} - -void -lang_init () -{ -#if !USE_CPPLIB - /* The beginning of the file is a new line; check for #. - With luck, we discover the real source file's name from that - and put it in input_filename. */ - ungetc (check_newline (), finput); -#else - check_newline (); - yy_cur--; -#endif - - /* The line number can be -1 if we had -g3 and the input file - had a directive specifying line 0. But we want predefined - functions to have a line number of 0, not -1. */ - if (lineno == -1) - lineno = 0; - - /* If gen_declaration desired, open the output file. */ - if (flag_gen_declaration) - { - int dump_base_name_length = strlen (dump_base_name); - register char *dumpname = (char *) xmalloc (dump_base_name_length + 7); - strcpy (dumpname, dump_base_name); - strcat (dumpname, ".decl"); - gen_declaration_file = fopen (dumpname, "w"); - if (gen_declaration_file == 0) - pfatal_with_name (dumpname); - } - - if (flag_next_runtime) - { - TAG_GETCLASS = "objc_getClass"; - TAG_GETMETACLASS = "objc_getMetaClass"; - TAG_MSGSEND = "objc_msgSend"; - TAG_MSGSENDSUPER = "objc_msgSendSuper"; - TAG_EXECCLASS = "__objc_execClass"; - } - else - { - TAG_GETCLASS = "objc_get_class"; - TAG_GETMETACLASS = "objc_get_meta_class"; - TAG_MSGSEND = "objc_msg_lookup"; - TAG_MSGSENDSUPER = "objc_msg_lookup_super"; - TAG_EXECCLASS = "__objc_exec_class"; - flag_typed_selectors = 1; - } - - if (doing_objc_thang) - init_objc (); - - if (print_struct_values) - generate_struct_by_value_array (); -} - -static void -objc_fatal () -{ - fatal ("Objective-C text in C source file"); -} - -void -finish_file () -{ - if (doing_objc_thang) - finish_objc (); /* Objective-C finalization */ - - if (gen_declaration_file) - fclose (gen_declaration_file); -} - -void -lang_finish () -{ -} - -char * -lang_identify () -{ - return "objc"; -} - -int -lang_decode_option (argc, argv) - int argc; - char **argv; -{ - char *p = argv[0]; - if (!strcmp (p, "-lang-objc")) - doing_objc_thang = 1; - else if (!strcmp (p, "-gen-decls")) - flag_gen_declaration = 1; - else if (!strcmp (p, "-Wselector")) - warn_selector = 1; - else if (!strcmp (p, "-Wno-selector")) - warn_selector = 0; - else if (!strcmp (p, "-Wprotocol")) - flag_warn_protocol = 1; - else if (!strcmp (p, "-Wno-protocol")) - flag_warn_protocol = 0; - else if (!strcmp (p, "-fgnu-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-next-runtime")) - flag_next_runtime = 0; - else if (!strcmp (p, "-fno-gnu-runtime")) - flag_next_runtime = 1; - else if (!strcmp (p, "-fnext-runtime")) - flag_next_runtime = 1; - else if (!strcmp (p, "-print-objc-runtime-info")) - print_struct_values = 1; - else - return c_decode_option (argc, argv); - - return 1; -} - -/* used by print-tree.c */ - -void -lang_print_xnode (file, node, indent) - FILE *file ATTRIBUTE_UNUSED; - tree node ATTRIBUTE_UNUSED; - int indent ATTRIBUTE_UNUSED; -{ -} - - -static tree -define_decl (declarator, declspecs) - tree declarator; - tree declspecs; -{ - tree decl = start_decl (declarator, declspecs, 0, NULL_TREE, NULL_TREE); - finish_decl (decl, NULL_TREE, NULL_TREE); - return decl; -} - -/* Return 1 if LHS and RHS are compatible types for assignment or - various other operations. Return 0 if they are incompatible, and - return -1 if we choose to not decide. When the operation is - REFLEXIVE, check for compatibility in either direction. - - For statically typed objects, an assignment of the form `a' = `b' - is permitted if: - - `a' is of type "id", - `a' and `b' are the same class type, or - `a' and `b' are of class types A and B such that B is a descendant of A. */ - -int -maybe_objc_comptypes (lhs, rhs, reflexive) - tree lhs, rhs; - int reflexive; -{ - if (doing_objc_thang) - return objc_comptypes (lhs, rhs, reflexive); - return -1; -} - -static tree -lookup_method_in_protocol_list (rproto_list, sel_name, class_meth) - tree rproto_list; - tree sel_name; - int class_meth; -{ - tree rproto, p; - tree fnd = 0; - - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if ((fnd = lookup_method (class_meth - ? PROTOCOL_CLS_METHODS (p) - : PROTOCOL_NST_METHODS (p), sel_name))) - ; - else if (PROTOCOL_LIST (p)) - fnd = lookup_method_in_protocol_list (PROTOCOL_LIST (p), - sel_name, class_meth); - } - else - { - ; /* An identifier...if we could not find a protocol. */ - } - - if (fnd) - return fnd; - } - - return 0; -} - -static tree -lookup_protocol_in_reflist (rproto_list, lproto) - tree rproto_list; - tree lproto; -{ - tree rproto, p; - - /* Make sure the protocol is support by the object on the rhs. */ - if (TREE_CODE (lproto) == PROTOCOL_INTERFACE_TYPE) - { - tree fnd = 0; - for (rproto = rproto_list; rproto; rproto = TREE_CHAIN (rproto)) - { - p = TREE_VALUE (rproto); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - if (lproto == p) - fnd = lproto; - - else if (PROTOCOL_LIST (p)) - fnd = lookup_protocol_in_reflist (PROTOCOL_LIST (p), lproto); - } - - if (fnd) - return fnd; - } - } - else - { - ; /* An identifier...if we could not find a protocol. */ - } - - return 0; -} - -/* Return 1 if LHS and RHS are compatible types for assignment - or various other operations. Return 0 if they are incompatible, - and return -1 if we choose to not decide. When the operation - is REFLEXIVE, check for compatibility in either direction. */ - -int -objc_comptypes (lhs, rhs, reflexive) - tree lhs; - tree rhs; - int reflexive; -{ - /* New clause for protocols. */ - - if (TREE_CODE (lhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (lhs)) == RECORD_TYPE - && TREE_CODE (rhs) == POINTER_TYPE - && TREE_CODE (TREE_TYPE (rhs)) == RECORD_TYPE) - { - int lhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (lhs); - int rhs_is_proto = IS_PROTOCOL_QUALIFIED_ID (rhs); - - if (lhs_is_proto) - { - tree lproto, lproto_list = TYPE_PROTOCOL_LIST (lhs); - tree rproto, rproto_list; - tree p; - - if (rhs_is_proto) - { - rproto_list = TYPE_PROTOCOL_LIST (rhs); - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - if (!rproto) - warning ("object does not conform to the `%s' protocol", - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - else if (TYPED_OBJECT (TREE_TYPE (rhs))) - { - tree rname = TYPE_NAME (TREE_TYPE (rhs)); - tree rinter; - - /* Make sure the protocol is supported by the object - on the rhs. */ - for (lproto = lproto_list; lproto; lproto = TREE_CHAIN (lproto)) - { - p = TREE_VALUE (lproto); - rproto = 0; - rinter = lookup_interface (rname); - - while (rinter && !rproto) - { - tree cat; - - rproto_list = CLASS_PROTOCOL_LIST (rinter); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - /* Check for protocols adopted by categories. */ - cat = CLASS_CATEGORY_LIST (rinter); - while (cat && !rproto) - { - rproto_list = CLASS_PROTOCOL_LIST (cat); - rproto = lookup_protocol_in_reflist (rproto_list, p); - - cat = CLASS_CATEGORY_LIST (cat); - } - - rinter = lookup_interface (CLASS_SUPER_NAME (rinter)); - } - - if (!rproto) - warning ("class `%s' does not implement the `%s' protocol", - IDENTIFIER_POINTER (TYPE_NAME (TREE_TYPE (rhs))), - IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - } - } - - /* May change...based on whether there was any mismatch */ - return 1; - } - else if (rhs_is_proto) - /* Lhs is not a protocol...warn if it is statically typed */ - return (TYPED_OBJECT (TREE_TYPE (lhs)) != 0); - - else - /* Defer to comptypes .*/ - return -1; - } - - else if (TREE_CODE (lhs) == RECORD_TYPE && TREE_CODE (rhs) == RECORD_TYPE) - ; /* Fall thru. This is the case we have been handling all along */ - else - /* Defer to comptypes. */ - return -1; - - /* `id' = `<class> *', `<class> *' = `id' */ - - if ((TYPE_NAME (lhs) == objc_object_id && TYPED_OBJECT (rhs)) - || (TYPE_NAME (rhs) == objc_object_id && TYPED_OBJECT (lhs))) - return 1; - - /* `id' = `Class', `Class' = `id' */ - - else if ((TYPE_NAME (lhs) == objc_object_id - && TYPE_NAME (rhs) == objc_class_id) - || (TYPE_NAME (lhs) == objc_class_id - && TYPE_NAME (rhs) == objc_object_id)) - return 1; - - /* `<class> *' = `<class> *' */ - - else if (TYPED_OBJECT (lhs) && TYPED_OBJECT (rhs)) - { - tree lname = TYPE_NAME (lhs); - tree rname = TYPE_NAME (rhs); - tree inter; - - if (lname == rname) - return 1; - - /* If the left hand side is a super class of the right hand side, - allow it. */ - for (inter = lookup_interface (rname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (lname == CLASS_SUPER_NAME (inter)) - return 1; - - /* Allow the reverse when reflexive. */ - if (reflexive) - for (inter = lookup_interface (lname); inter; - inter = lookup_interface (CLASS_SUPER_NAME (inter))) - if (rname == CLASS_SUPER_NAME (inter)) - return 1; - - return 0; - } - else - /* Defer to comptypes. */ - return -1; -} - -/* Called from c-decl.c before all calls to rest_of_decl_compilation. */ - -void -objc_check_decl (decl) - tree decl; -{ - tree type = TREE_TYPE (decl); - - if (TREE_CODE (type) == RECORD_TYPE - && TREE_STATIC_TEMPLATE (type) - && type != constant_string_type) - { - error_with_decl (decl, "`%s' cannot be statically allocated"); - fatal ("statically allocated objects not supported"); - } -} - -void -maybe_objc_check_decl (decl) - tree decl; -{ - if (doing_objc_thang) - objc_check_decl (decl); -} - -/* Implement static typing. At this point, we know we have an interface. */ - -tree -get_static_reference (interface, protocols) - tree interface; - tree protocols; -{ - tree type = xref_tag (RECORD_TYPE, interface); - - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - - push_obstacks_nochange (); - end_temporary_allocation (); - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - pop_obstacks (); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - /* Look up protocols and install in lang specific list. */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = 0; - - type = t; - } - - return type; -} - -tree -get_object_reference (protocols) - tree protocols; -{ - tree type_decl = lookup_name (objc_id_id); - tree type; - - if (type_decl && TREE_CODE (type_decl) == TYPE_DECL) - { - type = TREE_TYPE (type_decl); - if (TYPE_MAIN_VARIANT (type) != id_type) - warning ("Unexpected type for `id' (%s)", - gen_declaration (type, errbuf)); - } - else - fatal ("Undefined type `id', please import <objc/objc.h>"); - - /* This clause creates a new pointer type that is qualified with - the protocol specification...this info is used later to do more - elaborate type checking. */ - - if (protocols) - { - tree t, m = TYPE_MAIN_VARIANT (type); - - push_obstacks_nochange (); - end_temporary_allocation (); - t = copy_node (type); - TYPE_BINFO (t) = make_tree_vec (2); - pop_obstacks (); - - /* Add this type to the chain of variants of TYPE. */ - TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (m); - TYPE_NEXT_VARIANT (m) = t; - - /* Look up protocols...and install in lang specific list */ - TYPE_PROTOCOL_LIST (t) = lookup_and_install_protocols (protocols); - - /* This forces a new pointer type to be created later - (in build_pointer_type)...so that the new template - we just created will actually be used...what a hack! */ - if (TYPE_POINTER_TO (t)) - TYPE_POINTER_TO (t) = NULL; - - type = t; - } - return type; -} - -static tree -lookup_and_install_protocols (protocols) - tree protocols; -{ - tree proto; - tree prev = NULL; - tree return_value = protocols; - - for (proto = protocols; proto; proto = TREE_CHAIN (proto)) - { - tree ident = TREE_VALUE (proto); - tree p = lookup_protocol (ident); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (ident)); - if (prev) - TREE_CHAIN (prev) = TREE_CHAIN (proto); - else - return_value = TREE_CHAIN (proto); - } - else - { - /* Replace identifier with actual protocol node. */ - TREE_VALUE (proto) = p; - prev = proto; - } - } - - return return_value; -} - -/* Create and push a decl for a built-in external variable or field NAME. - CODE says which. - TYPE is its data type. */ - -static tree -create_builtin_decl (code, type, name) - enum tree_code code; - tree type; - char *name; -{ - tree decl = build_decl (code, get_identifier (name), type); - - if (code == VAR_DECL) - { - TREE_STATIC (decl) = 1; - make_decl_rtl (decl, 0, 1); - pushdecl (decl); - } - - DECL_ARTIFICIAL (decl) = 1; - return decl; -} - -/* Purpose: "play" parser, creating/installing representations - of the declarations that are required by Objective-C. - - Model: - - type_spec--------->sc_spec - (tree_list) (tree_list) - | | - | | - identifier_node identifier_node */ - -static void -synth_module_prologue () -{ - tree temp_type; - tree super_p; - - /* Defined in `objc.h' */ - objc_object_id = get_identifier (TAG_OBJECT); - - objc_object_reference = xref_tag (RECORD_TYPE, objc_object_id); - - id_type = build_pointer_type (objc_object_reference); - - objc_id_id = get_identifier (TYPE_ID); - objc_class_id = get_identifier (TAG_CLASS); - - objc_class_type = build_pointer_type (xref_tag (RECORD_TYPE, objc_class_id)); - protocol_type = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (PROTOCOL_OBJECT_CLASS_NAME))); - - /* Declare type of selector-objects that represent an operation name. */ - -#ifdef OBJC_INT_SELECTORS - /* `unsigned int' */ - selector_type = unsigned_type_node; -#else - /* `struct objc_selector *' */ - selector_type - = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); -#endif /* not OBJC_INT_SELECTORS */ - - /* Forward declare type, or else the prototype for msgSendSuper will - complain. */ - - super_p = build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))); - - - /* id objc_msgSend (id, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, id_type, - tree_cons (NULL_TREE, selector_type, - NULL_TREE))); - - if (! flag_next_runtime) - { - umsg_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_MSGSEND), temp_type); - DECL_EXTERNAL (umsg_decl) = 1; - TREE_PUBLIC (umsg_decl) = 1; - DECL_INLINE (umsg_decl) = 1; - DECL_ARTIFICIAL (umsg_decl) = 1; - - if (flag_traditional && TAG_MSGSEND[0] != '_') - DECL_BUILT_IN_NONANSI (umsg_decl) = 1; - - make_decl_rtl (umsg_decl, NULL_PTR, 1); - pushdecl (umsg_decl); - } - else - umsg_decl = builtin_function (TAG_MSGSEND, temp_type, NOT_BUILT_IN, 0); - - /* id objc_msgSendSuper (struct objc_super *, SEL, ...); */ - - temp_type - = build_function_type (id_type, - tree_cons (NULL_TREE, super_p, - tree_cons (NULL_TREE, selector_type, - NULL_TREE))); - - umsg_super_decl = builtin_function (TAG_MSGSENDSUPER, - temp_type, NOT_BUILT_IN, 0); - - /* id objc_getClass (const char *); */ - - temp_type = build_function_type (id_type, - tree_cons (NULL_TREE, - const_string_type_node, - tree_cons (NULL_TREE, void_type_node, - NULL_TREE))); - - objc_get_class_decl - = builtin_function (TAG_GETCLASS, temp_type, NOT_BUILT_IN, 0); - - /* id objc_getMetaClass (const char *); */ - - objc_get_meta_class_decl - = builtin_function (TAG_GETMETACLASS, temp_type, NOT_BUILT_IN, 0); - - /* static SEL _OBJC_SELECTOR_TABLE[]; */ - - if (! flag_next_runtime) - { - if (flag_typed_selectors) - { - /* Suppress outputting debug symbols, because - dbxout_init hasn'r been called yet. */ - enum debug_info_type save_write_symbols = write_symbols; - write_symbols = NO_DEBUG; - - build_selector_template (); - temp_type = build_array_type (objc_selector_template, NULL_TREE); - - write_symbols = save_write_symbols; - } - else - temp_type = build_array_type (selector_type, NULL_TREE); - - layout_type (temp_type); - UOBJC_SELECTOR_TABLE_decl - = create_builtin_decl (VAR_DECL, temp_type, - "_OBJC_SELECTOR_TABLE"); - - /* Avoid warning when not sending messages. */ - TREE_USED (UOBJC_SELECTOR_TABLE_decl) = 1; - } - - generate_forward_declaration_to_string_table (); - - /* Forward declare constant_string_id and constant_string_type. */ - constant_string_id = get_identifier (STRING_OBJECT_CLASS_NAME); - constant_string_type = xref_tag (RECORD_TYPE, constant_string_id); -} - -/* Custom build_string which sets TREE_TYPE! */ - -static tree -my_build_string (len, str) - int len; - char *str; -{ - int wide_flag = 0; - tree a_string = build_string (len, str); - - /* Some code from combine_strings, which is local to c-parse.y. */ - if (TREE_TYPE (a_string) == int_array_type_node) - wide_flag = 1; - - TREE_TYPE (a_string) - = build_array_type (wide_flag ? integer_type_node : char_type_node, - build_index_type (build_int_2 (len - 1, 0))); - - TREE_CONSTANT (a_string) = 1; /* Puts string in the readonly segment */ - TREE_STATIC (a_string) = 1; - - return a_string; -} - -/* Return a newly constructed OBJC_STRING_CST node whose value is - the LEN characters at STR. - The TREE_TYPE is not initialized. */ - -tree -build_objc_string (len, str) - int len; - char *str; -{ - tree s = build_string (len, str); - - TREE_SET_CODE (s, OBJC_STRING_CST); - return s; -} - -/* Given a chain of OBJC_STRING_CST's, build a static instance of - NXConstanString which points at the concatenation of those strings. - We place the string object in the __string_objects section of the - __OBJC segment. The Objective-C runtime will initialize the isa - pointers of the string objects to point at the NXConstandString class - object. */ - -tree -build_objc_string_object (strings) - tree strings; -{ - tree string, initlist, constructor; - int length; - - if (!doing_objc_thang) - objc_fatal (); - - if (lookup_interface (constant_string_id) == NULL_TREE) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (constant_string_id)); - return error_mark_node; - } - - add_class_reference (constant_string_id); - - /* Combine_strings will work for OBJC_STRING_CST's too. */ - string = combine_strings (strings); - TREE_SET_CODE (string, STRING_CST); - length = TREE_STRING_LENGTH (string) - 1; - - if (! flag_next_runtime) - { - push_obstacks_nochange (); - end_temporary_allocation (); - if (! TREE_PERMANENT (strings)) - string = my_build_string (length + 1, - TREE_STRING_POINTER (string)); - } - - /* & ((NXConstantString) {0, string, length}) */ - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - initlist - = tree_cons (NULL_TREE, copy_node (build_unary_op (ADDR_EXPR, string, 1)), - initlist); - initlist = tree_cons (NULL_TREE, build_int_2 (length, 0), initlist); - constructor = build_constructor (constant_string_type, nreverse (initlist)); - - if (!flag_next_runtime) - { - constructor - = objc_add_static_instance (constructor, constant_string_type); - pop_obstacks (); - } - - return (build_unary_op (ADDR_EXPR, constructor, 1)); -} - -/* Declare a static instance of CLASS_DECL initialized by CONSTRUCTOR. */ - -static tree -objc_add_static_instance (constructor, class_decl) - tree constructor, class_decl; -{ - static int num_static_inst; - tree *chain, decl; - char buf[256]; - - push_obstacks_nochange (); - end_temporary_allocation (); - - /* Find the list of static instances for the CLASS_DECL. Create one if - not found. */ - for (chain = &objc_static_instances; - *chain && TREE_VALUE (*chain) != class_decl; - chain = &TREE_CHAIN (*chain)); - if (!*chain) - { - *chain = tree_cons (NULL_TREE, class_decl, NULL_TREE); - add_objc_string (TYPE_NAME (class_decl), class_names); - } - - sprintf (buf, "_OBJC_INSTANCE_%d", num_static_inst++); - decl = build_decl (VAR_DECL, get_identifier (buf), class_decl); - DECL_COMMON (decl) = 1; - TREE_STATIC (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - pushdecl_top_level (decl); - rest_of_decl_compilation (decl, 0, 1, 0); - - /* Do this here so it gets output later instead of possibly - inside something else we are writing. */ - DECL_INITIAL (decl) = constructor; - - /* Add the DECL to the head of this CLASS' list. */ - TREE_PURPOSE (*chain) = tree_cons (NULL_TREE, decl, TREE_PURPOSE (*chain)); - - pop_obstacks (); - return decl; -} - -/* Build a static constant CONSTRUCTOR - with type TYPE and elements ELTS. */ - -static tree -build_constructor (type, elts) - tree type, elts; -{ - tree constructor = build (CONSTRUCTOR, type, NULL_TREE, elts); - - TREE_CONSTANT (constructor) = 1; - TREE_STATIC (constructor) = 1; - TREE_READONLY (constructor) = 1; - - return constructor; -} - -/* Take care of defining and initializing _OBJC_SYMBOLS. */ - -/* Predefine the following data type: - - struct _objc_symtab - { - long sel_ref_cnt; - SEL *refs; - short cls_def_cnt; - short cat_def_cnt; - void *defs[cls_def_cnt + cat_def_cnt]; - }; */ - -static void -build_objc_symtab_template () -{ - tree field_decl, field_decl_chain, index; - - objc_symtab_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_SYMTAB)); - - /* long sel_ref_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - long_integer_type_node, - "sel_ref_cnt"); - field_decl_chain = field_decl; - - /* SEL *refs; */ - - field_decl = create_builtin_decl (FIELD_DECL, - build_pointer_type (selector_type), - "refs"); - chainon (field_decl_chain, field_decl); - - /* short cls_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cls_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* short cat_def_cnt; */ - - field_decl = create_builtin_decl (FIELD_DECL, - short_integer_type_node, - "cat_def_cnt"); - chainon (field_decl_chain, field_decl); - - /* void *defs[cls_def_cnt + cat_def_cnt]; */ - - if (!flag_next_runtime) - index = build_index_type (build_int_2 (imp_count + cat_count, 0)); - else - index = build_index_type (build_int_2 (imp_count + cat_count - 1, - imp_count == 0 && cat_count == 0 - ? -1 : 0)); - field_decl = create_builtin_decl (FIELD_DECL, - build_array_type (ptr_type_node, index), - "defs"); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_symtab_template, field_decl_chain, NULL_TREE); -} - -/* Create the initial value for the `defs' field of _objc_symtab. - This is a CONSTRUCTOR. */ - -static tree -init_def_list (type) - tree type; -{ - tree expr, initlist = NULL_TREE; - struct imp_entry *impent; - - if (imp_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - } - - if (cat_count) - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - expr = build_unary_op (ADDR_EXPR, impent->class_decl, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - } - - if (!flag_next_runtime) - { - /* statics = { ..., _OBJC_STATIC_INSTANCES, ... } */ - tree expr; - - if (static_instances_decl) - expr = build_unary_op (ADDR_EXPR, static_instances_decl, 0); - else - expr = build_int_2 (0, 0); - - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* Construct the initial value for all of _objc_symtab. */ - -static tree -init_objc_symtab (type) - tree type; -{ - tree initlist; - - /* sel_ref_cnt = { ..., 5, ... } */ - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - - /* refs = { ..., _OBJC_SELECTOR_TABLE, ... } */ - - if (flag_next_runtime || ! sel_ref_chain) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - initlist = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - UOBJC_SELECTOR_TABLE_decl, 1), - initlist); - - /* cls_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULL_TREE, build_int_2 (imp_count, 0), initlist); - - /* cat_def_cnt = { ..., 5, ... } */ - - initlist = tree_cons (NULL_TREE, build_int_2 (cat_count, 0), initlist); - - /* cls_def = { ..., { &Foo, &Bar, ...}, ... } */ - - if (imp_count || cat_count || static_instances_decl) - { - - tree field = TYPE_FIELDS (type); - field = TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (TREE_CHAIN (field)))); - - initlist = tree_cons (NULL_TREE, init_def_list (TREE_TYPE (field)), - initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* Push forward-declarations of all the categories - so that init_def_list can use them in a CONSTRUCTOR. */ - -static void -forward_declare_categories () -{ - struct imp_entry *impent; - tree sav = implementation_context; - - for (impent = imp_list; impent; impent = impent->next) - { - if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - /* Set an invisible arg to synth_id_with_class_suffix. */ - implementation_context = impent->imp_context; - impent->class_decl - = create_builtin_decl (VAR_DECL, objc_category_template, - IDENTIFIER_POINTER (synth_id_with_class_suffix ("_OBJC_CATEGORY", implementation_context))); - } - } - implementation_context = sav; -} - -/* Create the declaration of _OBJC_SYMBOLS, with type `strict _objc_symtab' - and initialized appropriately. */ - -static void -generate_objc_symtab_decl () -{ - tree sc_spec; - - if (!objc_category_template) - build_category_template (); - - /* forward declare categories */ - if (cat_count) - forward_declare_categories (); - - if (!objc_symtab_template) - build_objc_symtab_template (); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - UOBJC_SYMBOLS_decl = start_decl (get_identifier ("_OBJC_SYMBOLS"), - tree_cons (NULL_TREE, - objc_symtab_template, sc_spec), - 1, - NULL_TREE, NULL_TREE); - - TREE_USED (UOBJC_SYMBOLS_decl) = 1; - DECL_IGNORED_P (UOBJC_SYMBOLS_decl) = 1; - DECL_ARTIFICIAL (UOBJC_SYMBOLS_decl) = 1; - finish_decl (UOBJC_SYMBOLS_decl, - init_objc_symtab (TREE_TYPE (UOBJC_SYMBOLS_decl)), - NULL_TREE); -} - -static tree -init_module_descriptor (type) - tree type; -{ - tree initlist, expr; - - /* version = { 1, ... } */ - - expr = build_int_2 (OBJC_VERSION, 0); - initlist = build_tree_list (NULL_TREE, expr); - - /* size = { ..., sizeof (struct objc_module), ... } */ - - expr = size_in_bytes (objc_module_template); - initlist = tree_cons (NULL_TREE, expr, initlist); - - /* name = { ..., "foo.m", ... } */ - - expr = add_objc_string (get_identifier (input_filename), class_names); - initlist = tree_cons (NULL_TREE, expr, initlist); - - /* symtab = { ..., _OBJC_SYMBOLS, ... } */ - - if (UOBJC_SYMBOLS_decl) - expr = build_unary_op (ADDR_EXPR, UOBJC_SYMBOLS_decl, 0); - else - expr = build_int_2 (0, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - - return build_constructor (type, nreverse (initlist)); -} - -/* Write out the data structures to describe Objective C classes defined. - If appropriate, compile and output a setup function to initialize them. - Return a string which is the name of a function to call to initialize - the Objective C data structures for this file (and perhaps for other files - also). - - struct objc_module { ... } _OBJC_MODULE = { ... }; */ - -static char * -build_module_descriptor () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_module_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_MODULE)); - - /* Long version; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* long size; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("size"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_symtab *symtab; */ - - decl_specs = get_identifier (UTAG_SYMTAB); - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("symtab")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_module_template, field_decl_chain, NULL_TREE); - - /* Create an instance of "objc_module". */ - - decl_specs = tree_cons (NULL_TREE, objc_module_template, - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - - UOBJC_MODULES_decl = start_decl (get_identifier ("_OBJC_MODULES"), - decl_specs, 1, NULL_TREE, NULL_TREE); - - DECL_ARTIFICIAL (UOBJC_MODULES_decl) = 1; - DECL_IGNORED_P (UOBJC_MODULES_decl) = 1; - finish_decl (UOBJC_MODULES_decl, - init_module_descriptor (TREE_TYPE (UOBJC_MODULES_decl)), - NULL_TREE); - - /* Mark the decl to avoid "defined but not used" warning. */ - DECL_IN_SYSTEM_HEADER (UOBJC_MODULES_decl) = 1; - - /* Generate a constructor call for the module descriptor. - This code was generated by reading the grammar rules - of c-parse.in; Therefore, it may not be the most efficient - way of generating the requisite code. */ - - if (flag_next_runtime) - return 0; - - { - tree parms, function_decl, decelerator, void_list_node; - tree function_type; - tree init_function_name = get_file_function_name ('I'); - - /* Declare void __objc_execClass (void *); */ - - void_list_node = build_tree_list (NULL_TREE, void_type_node); - function_type - = build_function_type (void_type_node, - tree_cons (NULL_TREE, ptr_type_node, - void_list_node)); - function_decl = build_decl (FUNCTION_DECL, - get_identifier (TAG_EXECCLASS), - function_type); - DECL_EXTERNAL (function_decl) = 1; - DECL_ARTIFICIAL (function_decl) = 1; - TREE_PUBLIC (function_decl) = 1; - - pushdecl (function_decl); - rest_of_decl_compilation (function_decl, 0, 0, 0); - - parms - = build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, UOBJC_MODULES_decl, 0)); - decelerator = build_function_call (function_decl, parms); - - /* void _GLOBAL_$I$<gnyf> () {objc_execClass (&L_OBJC_MODULES);} */ - - start_function (void_list_node, - build_parse_node (CALL_EXPR, init_function_name, - /* This has the format of the output - of get_parm_info. */ - tree_cons (NULL_TREE, NULL_TREE, - void_list_node), - NULL_TREE), - NULL_TREE, NULL_TREE, 0); -#if 0 /* This should be turned back on later - for the systems where collect is not needed. */ - /* Make these functions nonglobal - so each file can use the same name. */ - TREE_PUBLIC (current_function_decl) = 0; -#endif - TREE_USED (current_function_decl) = 1; - store_parm_decls (); - - assemble_external (function_decl); - c_expand_expr_stmt (decelerator); - - TREE_PUBLIC (current_function_decl) = 1; - - function_decl = current_function_decl; - finish_function (0); - - /* Return the name of the constructor function. */ - return XSTR (XEXP (DECL_RTL (function_decl), 0), 0); - } -} - -/* extern const char _OBJC_STRINGS[]; */ - -static void -generate_forward_declaration_to_string_table () -{ - tree sc_spec, decl_specs, expr_decl; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_EXTERN], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - - expr_decl - = build_nt (ARRAY_REF, get_identifier ("_OBJC_STRINGS"), NULL_TREE); - - UOBJC_STRINGS_decl = define_decl (expr_decl, decl_specs); -} - -/* Return the DECL of the string IDENT in the SECTION. */ - -static tree -get_objc_string_decl (ident, section) - tree ident; - enum string_section section; -{ - tree chain; - - if (section == class_names) - chain = class_names_chain; - else if (section == meth_var_names) - chain = meth_var_names_chain; - else if (section == meth_var_types) - chain = meth_var_types_chain; - - for (; chain != 0; chain = TREE_VALUE (chain)) - if (TREE_VALUE (chain) == ident) - return (TREE_PURPOSE (chain)); - - abort (); - return NULL_TREE; -} - -/* Output references to all statically allocated objects. Return the DECL - for the array built. */ - -static void -generate_static_references () -{ - tree decls = NULL_TREE, ident, decl_spec, expr_decl, expr = NULL_TREE; - tree class_name, class, decl, initlist; - tree cl_chain, in_chain, type; - int num_inst, num_class; - char buf[256]; - - if (flag_next_runtime) - abort (); - - for (cl_chain = objc_static_instances, num_class = 0; - cl_chain; cl_chain = TREE_CHAIN (cl_chain), num_class++) - { - for (num_inst = 0, in_chain = TREE_PURPOSE (cl_chain); - in_chain; num_inst++, in_chain = TREE_CHAIN (in_chain)); - - sprintf (buf, "_OBJC_STATIC_INSTANCES_%d", num_class); - ident = get_identifier (buf); - - expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); - decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - decl = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - /* Output {class_name, ...}. */ - class = TREE_VALUE (cl_chain); - class_name = get_objc_string_decl (TYPE_NAME (class), class_names); - initlist = build_tree_list (NULL_TREE, - build_unary_op (ADDR_EXPR, class_name, 1)); - - /* Output {..., instance, ...}. */ - for (in_chain = TREE_PURPOSE (cl_chain); - in_chain; in_chain = TREE_CHAIN (in_chain)) - { - expr = build_unary_op (ADDR_EXPR, TREE_VALUE (in_chain), 1); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* Output {..., NULL}. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - expr = build_constructor (TREE_TYPE (decl), nreverse (initlist)); - finish_decl (decl, expr, NULL_TREE); - TREE_USED (decl) = 1; - - type = build_array_type (build_pointer_type (void_type_node), 0); - decl = build_decl (VAR_DECL, ident, type); - make_decl_rtl (decl, 0, 1); - TREE_USED (decl) = 1; - decls - = tree_cons (NULL_TREE, build_unary_op (ADDR_EXPR, decl, 1), decls); - } - - decls = tree_cons (NULL_TREE, build_int_2 (0, 0), decls); - ident = get_identifier ("_OBJC_STATIC_INSTANCES"); - expr_decl = build_nt (ARRAY_REF, ident, NULL_TREE); - decl_spec = tree_cons (NULL_TREE, build_pointer_type (void_type_node), - build_tree_list (NULL_TREE, - ridpointers[(int) RID_STATIC])); - static_instances_decl - = start_decl (expr_decl, decl_spec, 1, NULL_TREE, NULL_TREE); - TREE_USED (static_instances_decl) = 1; - DECL_CONTEXT (static_instances_decl) = 0; - DECL_ARTIFICIAL (static_instances_decl) = 1; - end_temporary_allocation (); - expr = build_constructor (TREE_TYPE (static_instances_decl), - nreverse (decls)); - finish_decl (static_instances_decl, expr, NULL_TREE); -} - -/* Output all strings. */ - -static void -generate_strings () -{ - tree sc_spec, decl_specs, expr_decl; - tree chain, string_expr; - tree string, decl; - - for (chain = class_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - end_temporary_allocation (); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } - - for (chain = meth_var_names_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } - - for (chain = meth_var_types_chain; chain; chain = TREE_CHAIN (chain)) - { - string = TREE_VALUE (chain); - decl = TREE_PURPOSE (chain); - sc_spec - = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], sc_spec); - expr_decl = build_nt (ARRAY_REF, DECL_NAME (decl), NULL_TREE); - decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - string_expr = my_build_string (IDENTIFIER_LENGTH (string) + 1, - IDENTIFIER_POINTER (string)); - finish_decl (decl, string_expr, NULL_TREE); - } -} - -static tree -build_selector_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - static int idx = 0; - - sprintf (buf, "_OBJC_SELECTOR_REFERENCES_%d", idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, selector_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - DECL_CONTEXT (decl) = 0; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - -/* Just a handy wrapper for add_objc_string. */ - -static tree -build_selector (ident) - tree ident; -{ - tree expr = add_objc_string (ident, meth_var_names); - if (flag_typed_selectors) - return expr; - else - return build_c_cast (selector_type, expr); /* cast! */ -} - -/* Synthesize the following expr: (char *)&_OBJC_STRINGS[<offset>] - The cast stops the compiler from issuing the following message: - grok.m: warning: initialization of non-const * pointer from const * - grok.m: warning: initialization between incompatible pointer types. */ - -#if 0 -static tree -build_msg_pool_reference (offset) - int offset; -{ - tree expr = build_int_2 (offset, 0); - tree cast; - - expr = build_array_ref (UOBJC_STRINGS_decl, expr); - expr = build_unary_op (ADDR_EXPR, expr, 0); - - cast = build_tree_list (build_tree_list (NULL_TREE, - ridpointers[(int) RID_CHAR]), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); - TREE_TYPE (expr) = groktypename (cast); - return expr; -} - -static tree -init_selector (offset) - int offset; -{ - tree expr = build_msg_pool_reference (offset); - TREE_TYPE (expr) = selector_type; - return expr; -} -#endif - -static void -build_selector_translation_table () -{ - tree sc_spec, decl_specs; - tree chain, initlist = NULL_TREE; - int offset = 0; - tree decl, var_decl, name; - - /* The corresponding pop_obstacks is in finish_decl, - called at the end of this function. */ - if (! flag_next_runtime) - push_obstacks_nochange (); - - for (chain = sel_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - tree expr; - - expr = build_selector (TREE_VALUE (chain)); - - if (flag_next_runtime) - { - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - /* static SEL _OBJC_SELECTOR_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULL_TREE, selector_type, sc_spec); - - var_decl = name; - - /* The `decl' that is returned from start_decl is the one that we - forward declared in `build_selector_reference' */ - decl = start_decl (var_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - } - - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (chain)) + 1; - - if (flag_next_runtime) - finish_decl (decl, expr, NULL_TREE); - else - { - if (flag_typed_selectors) - { - tree eltlist = NULL_TREE; - tree encoding = get_proto_encoding (TREE_PURPOSE (chain)); - eltlist = tree_cons (NULL_TREE, expr, NULL_TREE); - eltlist = tree_cons (NULL_TREE, encoding, eltlist); - expr = build_constructor (objc_selector_template, - nreverse (eltlist)); - } - initlist = tree_cons (NULL_TREE, expr, initlist); - - } - } - - if (! flag_next_runtime) - { - /* Cause the variable and its initial value to be actually output. */ - DECL_EXTERNAL (UOBJC_SELECTOR_TABLE_decl) = 0; - TREE_STATIC (UOBJC_SELECTOR_TABLE_decl) = 1; - /* NULL terminate the list and fix the decl for output. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - DECL_INITIAL (UOBJC_SELECTOR_TABLE_decl) = (tree) 1; - initlist = build_constructor (TREE_TYPE (UOBJC_SELECTOR_TABLE_decl), - nreverse (initlist)); - finish_decl (UOBJC_SELECTOR_TABLE_decl, initlist, NULL_TREE); - current_function_decl = NULL_TREE; - } -} - -static tree -get_proto_encoding (proto) - tree proto; -{ - tree encoding; - if (proto) - { - tree tmp_decl; - - if (! METHOD_ENCODING (proto)) - { - tmp_decl = build_tmp_function_decl (); - hack_method_prototype (proto, tmp_decl); - encoding = encode_method_prototype (proto, tmp_decl); - METHOD_ENCODING (proto) = encoding; - } - else - encoding = METHOD_ENCODING (proto); - - return add_objc_string (encoding, meth_var_types); - } - else - return build_int_2 (0, 0); -} - -/* sel_ref_chain is a list whose "value" fields will be instances of - identifier_node that represent the selector. */ - -static tree -build_typed_selector_reference (ident, proto) - tree ident, proto; -{ - tree *chain = &sel_ref_chain; - tree expr; - int index = 0; - - while (*chain) - { - if (TREE_PURPOSE (*chain) == ident && TREE_VALUE (*chain) == proto) - goto return_at_index; - - index++; - chain = &TREE_CHAIN (*chain); - } - - *chain = perm_tree_cons (proto, ident, NULL_TREE); - - return_at_index: - expr = build_unary_op (ADDR_EXPR, - build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0)), - 1); - return build_c_cast (selector_type, expr); -} - -static tree -build_selector_reference (ident) - tree ident; -{ - tree *chain = &sel_ref_chain; - tree expr; - int index = 0; - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return (flag_next_runtime - ? TREE_PURPOSE (*chain) - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); - - index++; - chain = &TREE_CHAIN (*chain); - } - - expr = build_selector_reference_decl (ident); - - *chain = perm_tree_cons (expr, ident, NULL_TREE); - - return (flag_next_runtime - ? expr - : build_array_ref (UOBJC_SELECTOR_TABLE_decl, - build_int_2 (index, 0))); -} - -static tree -build_class_reference_decl (name) - tree name; -{ - tree decl, ident; - char buf[256]; - static int idx = 0; - - sprintf (buf, "_OBJC_CLASS_REFERENCES_%d", idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, objc_class_type); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - -/* Create a class reference, but don't create a variable to reference - it. */ - -static void -add_class_reference (ident) - tree ident; -{ - tree chain; - - if ((chain = cls_ref_chain)) - { - tree tail; - do - { - if (ident == TREE_VALUE (chain)) - return; - - tail = chain; - chain = TREE_CHAIN (chain); - } - while (chain); - - /* Append to the end of the list */ - TREE_CHAIN (tail) = perm_tree_cons (NULL_TREE, ident, NULL_TREE); - } - else - cls_ref_chain = perm_tree_cons (NULL_TREE, ident, NULL_TREE); -} - -/* Get a class reference, creating it if necessary. Also create the - reference variable. */ - -tree -get_class_reference (ident) - tree ident; -{ - if (flag_next_runtime) - { - tree *chain; - tree decl; - - for (chain = &cls_ref_chain; *chain; chain = &TREE_CHAIN (*chain)) - if (TREE_VALUE (*chain) == ident) - { - if (! TREE_PURPOSE (*chain)) - TREE_PURPOSE (*chain) = build_class_reference_decl (ident); - - return TREE_PURPOSE (*chain); - } - - decl = build_class_reference_decl (ident); - *chain = perm_tree_cons (decl, ident, NULL_TREE); - return decl; - } - else - { - tree params; - - add_class_reference (ident); - - params = build_tree_list (NULL_TREE, - my_build_string (IDENTIFIER_LENGTH (ident) + 1, - IDENTIFIER_POINTER (ident))); - - assemble_external (objc_get_class_decl); - return build_function_call (objc_get_class_decl, params); - } -} - -/* SEL_REFDEF_CHAIN is a list whose "value" fields will be instances - of identifier_node that represent the selector. It returns the - offset of the selector from the beginning of the _OBJC_STRINGS - pool. This offset is typically used by init_selector during code - generation. - - For each string section we have a chain which maps identifier nodes - to decls for the strings. */ - -static tree -add_objc_string (ident, section) - tree ident; - enum string_section section; -{ - tree *chain, decl; - - if (section == class_names) - chain = &class_names_chain; - else if (section == meth_var_names) - chain = &meth_var_names_chain; - else if (section == meth_var_types) - chain = &meth_var_types_chain; - - while (*chain) - { - if (TREE_VALUE (*chain) == ident) - return build_unary_op (ADDR_EXPR, TREE_PURPOSE (*chain), 1); - - chain = &TREE_CHAIN (*chain); - } - - decl = build_objc_string_decl (ident, section); - - *chain = perm_tree_cons (decl, ident, NULL_TREE); - - return build_unary_op (ADDR_EXPR, decl, 1); -} - -static tree -build_objc_string_decl (name, section) - tree name; - enum string_section section; -{ - tree decl, ident; - char buf[256]; - static int class_names_idx = 0; - static int meth_var_names_idx = 0; - static int meth_var_types_idx = 0; - - if (section == class_names) - sprintf (buf, "_OBJC_CLASS_NAME_%d", class_names_idx++); - else if (section == meth_var_names) - sprintf (buf, "_OBJC_METH_VAR_NAME_%d", meth_var_names_idx++); - else if (section == meth_var_types) - sprintf (buf, "_OBJC_METH_VAR_TYPE_%d", meth_var_types_idx++); - - push_obstacks_nochange (); - end_temporary_allocation (); - ident = get_identifier (buf); - - decl = build_decl (VAR_DECL, ident, build_array_type (char_type_node, 0)); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - TREE_READONLY (decl) = 1; - TREE_CONSTANT (decl) = 1; - DECL_CONTEXT (decl) = 0; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - - pop_obstacks (); - - return decl; -} - - -void -objc_declare_alias (alias_ident, class_ident) - tree alias_ident; - tree class_ident; -{ - if (!doing_objc_thang) - objc_fatal (); - - if (is_class_name (class_ident) != class_ident) - warning ("Cannot find class `%s'", IDENTIFIER_POINTER (class_ident)); - else if (is_class_name (alias_ident)) - warning ("Class `%s' already exists", IDENTIFIER_POINTER (alias_ident)); - else - alias_chain = tree_cons (class_ident, alias_ident, alias_chain); -} - -void -objc_declare_class (ident_list) - tree ident_list; -{ - tree list; - - if (!doing_objc_thang) - objc_fatal (); - - for (list = ident_list; list; list = TREE_CHAIN (list)) - { - tree ident = TREE_VALUE (list); - tree decl; - - if ((decl = lookup_name (ident))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (ident)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (! is_class_name (ident)) - { - tree record = xref_tag (RECORD_TYPE, ident); - TREE_STATIC_TEMPLATE (record) = 1; - class_chain = tree_cons (NULL_TREE, ident, class_chain); - } - } -} - -tree -is_class_name (ident) - tree ident; -{ - tree chain; - - if (lookup_interface (ident)) - return ident; - - for (chain = class_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return ident; - } - - for (chain = alias_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == TREE_VALUE (chain)) - return TREE_PURPOSE (chain); - } - - return 0; -} - -tree -lookup_interface (ident) - tree ident; -{ - tree chain; - - for (chain = interface_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == CLASS_NAME (chain)) - return chain; - } - return NULL_TREE; -} - -static tree -objc_copy_list (list, head) - tree list; - tree *head; -{ - tree newlist = NULL_TREE, tail = NULL_TREE; - - while (list) - { - tail = copy_node (list); - - /* The following statement fixes a bug when inheriting instance - variables that are declared to be bitfields. finish_struct - expects to find the width of the bitfield in DECL_INITIAL, - which it nulls out after processing the decl of the super - class...rather than change the way finish_struct works (which - is risky), I create the situation it expects...s.naroff - (7/23/89). */ - - if (DECL_BIT_FIELD (tail) && DECL_INITIAL (tail) == 0) - DECL_INITIAL (tail) = build_int_2 (DECL_FIELD_SIZE (tail), 0); - - newlist = chainon (newlist, tail); - list = TREE_CHAIN (list); - } - - *head = newlist; - return tail; -} - -/* Used by: build_private_template, get_class_ivars, and - continue_class. COPY is 1 when called from @defs. In this case - copy all fields. Otherwise don't copy leaf ivars since we rely on - them being side-effected exactly once by finish_struct. */ - -static tree -build_ivar_chain (interface, copy) - tree interface; - int copy; -{ - tree my_name, super_name, ivar_chain; - - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - /* Possibly copy leaf ivars. */ - if (copy) - objc_copy_list (CLASS_IVARS (interface), &ivar_chain); - else - ivar_chain = CLASS_IVARS (interface); - - while (super_name) - { - tree op1; - tree super_interface = lookup_interface (super_name); - - if (!super_interface) - { - /* fatal did not work with 2 args...should fix */ - error ("Cannot find interface declaration for `%s', superclass of `%s'", - IDENTIFIER_POINTER (super_name), - IDENTIFIER_POINTER (my_name)); - exit (FATAL_EXIT_CODE); - } - - if (super_interface == interface) - { - fatal ("Circular inheritance in interface declaration for `%s'", - IDENTIFIER_POINTER (super_name)); - } - - interface = super_interface; - my_name = CLASS_NAME (interface); - super_name = CLASS_SUPER_NAME (interface); - - op1 = CLASS_IVARS (interface); - if (op1) - { - tree head, tail = objc_copy_list (op1, &head); - - /* Prepend super class ivars...make a copy of the list, we - do not want to alter the original. */ - TREE_CHAIN (tail) = ivar_chain; - ivar_chain = head; - } - } - return ivar_chain; -} - -/* struct <classname> { - struct objc_class *isa; - ... - }; */ - -static tree -build_private_template (class) - tree class; -{ - tree ivar_context; - - if (CLASS_STATIC_TEMPLATE (class)) - { - uprivate_record = CLASS_STATIC_TEMPLATE (class); - ivar_context = TYPE_FIELDS (CLASS_STATIC_TEMPLATE (class)); - } - else - { - uprivate_record = start_struct (RECORD_TYPE, CLASS_NAME (class)); - - ivar_context = build_ivar_chain (class, 0); - - finish_struct (uprivate_record, ivar_context, NULL_TREE); - - CLASS_STATIC_TEMPLATE (class) = uprivate_record; - - /* mark this record as class template - for class type checking */ - TREE_STATIC_TEMPLATE (uprivate_record) = 1; - } - - instance_type - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - uprivate_record), - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE))); - - return ivar_context; -} - -/* Begin code generation for protocols... */ - -/* struct objc_protocol { - char *protocol_name; - struct objc_protocol **protocol_list; - struct objc_method_desc *instance_methods; - struct objc_method_desc *class_methods; - }; */ - -static tree -build_protocol_template () -{ - tree decl_specs, field_decl, field_decl_chain; - tree template; - - template = start_struct (RECORD_TYPE, get_identifier (UTAG_PROTOCOL)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *protocol_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs - = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs - = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - return finish_struct (template, field_decl_chain, NULL_TREE); -} - -static tree -build_descriptor_table_initializer (type, entries) - tree type; - tree entries; -{ - tree initlist = NULL_TREE; - - do - { - tree eltlist = NULL_TREE; - - eltlist - = tree_cons (NULL_TREE, - build_selector (METHOD_SEL_NAME (entries)), NULL_TREE); - eltlist - = tree_cons (NULL_TREE, - add_objc_string (METHOD_ENCODING (entries), - meth_var_types), - eltlist); - - initlist - = tree_cons (NULL_TREE, - build_constructor (type, nreverse (eltlist)), initlist); - - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -/* struct objc_method_prototype_list { - int count; - struct objc_method_prototype { - SEL name; - char *types; - } list[1]; - }; */ - -static tree -build_method_prototype_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - /* Generate an unnamed struct definition. */ - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int method_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -static tree -build_method_prototype_template () -{ - tree proto_record; - tree decl_specs, field_decl, field_decl_chain; - - proto_record - = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD_PROTOTYPE)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs - = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd")); -#endif /* OBJC_INT_SELECTORS */ - - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_types")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (proto_record, field_decl_chain, NULL_TREE); - - return proto_record; -} - -/* True if last call to forwarding_offset yielded a register offset. */ -static int offset_is_register; - -static int -forwarding_offset (parm) - tree parm; -{ - int offset_in_bytes; - - if (GET_CODE (DECL_INCOMING_RTL (parm)) == MEM) - { - rtx addr = XEXP (DECL_INCOMING_RTL (parm), 0); - - /* ??? Here we assume that the parm address is indexed - off the frame pointer or arg pointer. - If that is not true, we produce meaningless results, - but do not crash. */ - if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - offset_in_bytes = INTVAL (XEXP (addr, 1)); - else - offset_in_bytes = 0; - - offset_in_bytes += OBJC_FORWARDING_STACK_OFFSET; - offset_is_register = 0; - } - else if (GET_CODE (DECL_INCOMING_RTL (parm)) == REG) - { - int regno = REGNO (DECL_INCOMING_RTL (parm)); - offset_in_bytes = apply_args_register_offset (regno); - offset_is_register = 1; - } - else - return 0; - - /* This is the case where the parm is passed as an int or double - and it is converted to a char, short or float and stored back - in the parmlist. In this case, describe the parm - with the variable's declared type, and adjust the address - if the least significant bytes (which we are using) are not - the first ones. */ - if (BYTES_BIG_ENDIAN && TREE_TYPE (parm) != DECL_ARG_TYPE (parm)) - offset_in_bytes += (GET_MODE_SIZE (TYPE_MODE (DECL_ARG_TYPE (parm))) - - GET_MODE_SIZE (GET_MODE (DECL_RTL (parm)))); - - return offset_in_bytes; -} - -static tree -encode_method_prototype (method_decl, func_decl) - tree method_decl; - tree func_decl; -{ - tree parms; - int stack_size, i; - tree user_args; - int max_parm_end = 0; - char buf[40]; - tree result; - - /* ONEWAY and BYCOPY, for remote object are the only method qualifiers. */ - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (method_decl))); - - /* C type. */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Stack size. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (!offset_is_register && max_parm_end < parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buf, "%d", stack_size); - obstack_grow (&util_obstack, buf, strlen (buf)); - - user_args = METHOD_SEL_ARGS (method_decl); - - /* Argument types. */ - for (parms = DECL_ARGUMENTS (func_decl), i = 0; parms; - parms = TREE_CHAIN (parms), i++) - { - /* Process argument qualifiers for user supplied arguments. */ - if (i > 1) - { - encode_type_qualifiers (TREE_PURPOSE (TREE_TYPE (user_args))); - user_args = TREE_CHAIN (user_args); - } - - /* Type. */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Compute offset. */ - sprintf (buf, "%d", forwarding_offset (parms)); - - /* Indicate register. */ - if (offset_is_register) - obstack_1grow (&util_obstack, '+'); - - obstack_grow (&util_obstack, buf, strlen (buf)); - } - - obstack_1grow (&util_obstack, '\0'); - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -static tree -generate_descriptor_table (type, name, size, list, proto) - tree type; - char *name; - int size; - tree list; - tree proto; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, proto), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0)); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, build_constructor (type, nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_method_descriptors (protocol) /* generate_dispatch_tables */ - tree protocol; -{ - static tree objc_method_prototype_template; - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_prototype_template) - objc_method_prototype_template = build_method_prototype_template (); - - cast = build_tree_list (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))), - NULL_TREE); - variable_length_type = groktypename (cast); - - chain = PROTOCOL_CLS_METHODS (protocol); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - - initlist - = build_descriptor_table_initializer (objc_method_prototype_template, - chain); - - UOBJC_CLASS_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_CLASS_METHODS", - size, initlist, protocol); - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = PROTOCOL_NST_METHODS (protocol); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_prototype_list_template (objc_method_prototype_template, - size); - initlist - = build_descriptor_table_initializer (objc_method_prototype_template, - chain); - - UOBJC_INSTANCE_METHODS_decl - = generate_descriptor_table (method_list_template, - "_OBJC_PROTOCOL_INSTANCE_METHODS", - size, initlist, protocol); - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -build_tmp_function_decl () -{ - tree decl_specs, expr_decl, parms; - static int xxx = 0; - char buffer[80]; - - /* struct objc_object *objc_xxx (id, SEL, ...); */ - pushlevel (0); - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE)), - build_tree_list (NULL_TREE, NULL_TREE))); - - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - expr_decl = build1 (INDIRECT_REF, NULL_TREE, NULL_TREE); - - push_parm_decl (build_tree_list (build_tree_list (decl_specs, expr_decl), - build_tree_list (NULL_TREE, NULL_TREE))); - parms = get_parm_info (0); - poplevel (0, 0, 0); - - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - sprintf (buffer, "__objc_tmp_%x", xxx++); - expr_decl = build_nt (CALL_EXPR, get_identifier (buffer), parms, NULL_TREE); - expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl); - - return define_decl (expr_decl, decl_specs); -} - -static void -hack_method_prototype (nst_methods, tmp_decl) - tree nst_methods; - tree tmp_decl; -{ - tree parms; - tree parm; - - /* Hack to avoid problem with static typing of self arg. */ - TREE_SET_CODE (nst_methods, CLASS_METHOD_DECL); - start_method_def (nst_methods); - TREE_SET_CODE (nst_methods, INSTANCE_METHOD_DECL); - - if (METHOD_ADD_ARGS (nst_methods) == (tree) 1) - parms = get_parm_info (0); /* we have a `, ...' */ - else - parms = get_parm_info (1); /* place a `void_at_end' */ - - poplevel (0, 0, 0); /* Must be called BEFORE start_function. */ - - /* Usually called from store_parm_decls -> init_function_start. */ - - DECL_ARGUMENTS (tmp_decl) = TREE_PURPOSE (parms); - current_function_decl = tmp_decl; - - { - /* Code taken from start_function. */ - tree restype = TREE_TYPE (TREE_TYPE (tmp_decl)); - /* Promote the value to int before returning it. */ - if (TREE_CODE (restype) == INTEGER_TYPE - && TYPE_PRECISION (restype) < TYPE_PRECISION (integer_type_node)) - restype = integer_type_node; - DECL_RESULT (tmp_decl) = build_decl (RESULT_DECL, 0, restype); - } - - for (parm = DECL_ARGUMENTS (tmp_decl); parm; parm = TREE_CHAIN (parm)) - DECL_CONTEXT (parm) = tmp_decl; - - init_function_start (tmp_decl, "objc-act", 0); - - /* Typically called from expand_function_start for function definitions. */ - assign_parms (tmp_decl, 0); - - /* install return type */ - TREE_TYPE (TREE_TYPE (tmp_decl)) = groktypename (TREE_TYPE (nst_methods)); - -} - -static void -generate_protocol_references (plist) - tree plist; -{ - tree lproto; - - /* Forward declare protocols referenced. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree proto = TREE_VALUE (lproto); - - if (TREE_CODE (proto) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_NAME (proto)) - { - if (! PROTOCOL_FORWARD_DECL (proto)) - build_protocol_reference (proto); - - if (PROTOCOL_LIST (proto)) - generate_protocol_references (PROTOCOL_LIST (proto)); - } - } -} - -static void -generate_protocols () -{ - tree p, tmp_decl, encoding; - tree sc_spec, decl_specs, decl; - tree initlist, protocol_name_expr, refs_decl, refs_expr; - tree cast_type2 = 0; - - tmp_decl = build_tmp_function_decl (); - - if (! objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - /* If a protocol was directly referenced, pull in indirect references. */ - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - if (PROTOCOL_FORWARD_DECL (p) && PROTOCOL_LIST (p)) - generate_protocol_references (PROTOCOL_LIST (p)); - - for (p = protocol_chain; p; p = TREE_CHAIN (p)) - { - tree nst_methods = PROTOCOL_NST_METHODS (p); - tree cls_methods = PROTOCOL_CLS_METHODS (p); - - /* If protocol wasn't referenced, don't generate any code. */ - if (! PROTOCOL_FORWARD_DECL (p)) - continue; - - /* Make sure we link in the Protocol class. */ - add_class_reference (get_identifier (PROTOCOL_OBJECT_CLASS_NAME)); - - while (nst_methods) - { - if (! METHOD_ENCODING (nst_methods)) - { - hack_method_prototype (nst_methods, tmp_decl); - encoding = encode_method_prototype (nst_methods, tmp_decl); - METHOD_ENCODING (nst_methods) = encoding; - } - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - if (! METHOD_ENCODING (cls_methods)) - { - hack_method_prototype (cls_methods, tmp_decl); - encoding = encode_method_prototype (cls_methods, tmp_decl); - METHOD_ENCODING (cls_methods) = encoding; - } - - cls_methods = TREE_CHAIN (cls_methods); - } - generate_method_descriptors (p); - - if (PROTOCOL_LIST (p)) - refs_decl = generate_protocol_list (p); - else - refs_decl = 0; - - /* static struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], - NULL_TREE); - decl_specs = tree_cons (NULL_TREE, objc_protocol_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_PROTOCOL", p), - decl_specs, 1, NULL_TREE, NULL_TREE); - - protocol_name_expr = add_objc_string (PROTOCOL_NAME (p), class_names); - - if (refs_decl) - { - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list (build_tree_list (NULL_TREE, - objc_protocol_template), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, - NULL_TREE)))); - - refs_expr = build_unary_op (ADDR_EXPR, refs_decl, 0); - TREE_TYPE (refs_expr) = cast_type2; - } - else - refs_expr = build_int_2 (0, 0); - - /* UOBJC_INSTANCE_METHODS_decl/UOBJC_CLASS_METHODS_decl are set - by generate_method_descriptors, which is called above. */ - initlist = build_protocol_initializer (TREE_TYPE (decl), - protocol_name_expr, refs_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl); - finish_decl (decl, initlist, NULL_TREE); - - /* Mark the decl as used to avoid "defined but not used" warning. */ - TREE_USED (decl) = 1; - } -} - -static tree -build_protocol_initializer (type, protocol_name, protocol_list, - instance_methods, class_methods) - tree type; - tree protocol_name; - tree protocol_list; - tree instance_methods; - tree class_methods; -{ - tree initlist = NULL_TREE, expr; - static tree cast_type = 0; - - if (!cast_type) - cast_type - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_CLASS))), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))); - - /* Filling the "isa" in with one allows the runtime system to - detect that the version change...should remove before final release. */ - - expr = build_int_2 (PROTOCOL_VERSION, 0); - TREE_TYPE (expr) = cast_type; - initlist = tree_cons (NULL_TREE, expr, initlist); - initlist = tree_cons (NULL_TREE, protocol_name, initlist); - initlist = tree_cons (NULL_TREE, protocol_list, initlist); - - if (!instance_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - if (!class_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* struct objc_category { - char *category_name; - char *class_name; - struct objc_method_list *instance_methods; - struct objc_method_list *class_methods; - struct objc_protocol_list *protocols; - }; */ - -static void -build_category_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_category_template = start_struct (RECORD_TYPE, - get_identifier (UTAG_CATEGORY)); - /* char *category_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("category_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *class_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *instance_methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("instance_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *class_methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class_methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_category_template, field_decl_chain, NULL_TREE); -} - -/* struct objc_selector { - void *sel_id; - char *sel_type; - }; */ - -static void -build_selector_template () -{ - - tree decl_specs, field_decl, field_decl_chain; - - objc_selector_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_SELECTOR)); - - /* void *sel_id; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *sel_type; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_type")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_selector_template, field_decl_chain, NULL_TREE); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - void *gc_object_type; - }; */ - -static void -build_class_template () -{ - tree decl_specs, field_decl, field_decl_chain; - - objc_class_template - = start_struct (RECORD_TYPE, get_identifier (UTAG_CLASS)); - - /* struct objc_class *isa; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("isa")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_class *super_class; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("super_class")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* char *name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("name")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long version; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("version"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long info; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("info"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* long instance_size; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_LONG]); - field_decl = get_identifier ("instance_size"); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_ivar_list *ivars; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivars")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method_list *methods; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("methods")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - if (flag_next_runtime) - { - /* struct objc_cache *cache; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier ("objc_cache"))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("cache")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - } - else - { - /* struct sarray *dtable; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier ("sarray"))); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("dtable")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *subclass_list; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("subclass_list")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_class *sibling_class; */ - - decl_specs = build_tree_list (NULL_TREE, objc_class_template); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sibling_class")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - } - - /* struct objc_protocol **protocol_list; */ - - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("protocol_list")); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* void *sel_id; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("sel_id")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* void *gc_object_type; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_VOID]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("gc_object_type")); - field_decl - = grokfield (input_filename, lineno, field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_class_template, field_decl_chain, NULL_TREE); -} - -/* Generate appropriate forward declarations for an implementation. */ - -static void -synth_forward_declarations () -{ - tree sc_spec, decl_specs, an_id; - - /* extern struct objc_class _OBJC_CLASS_<my_name>; */ - - an_id = synth_id_with_class_suffix ("_OBJC_CLASS", implementation_context); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec); - UOBJC_CLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_CLASS_decl) = 1; - DECL_ARTIFICIAL (UOBJC_CLASS_decl) = 1; - - /* extern struct objc_class _OBJC_METACLASS_<my_name>; */ - - an_id = synth_id_with_class_suffix ("_OBJC_METACLASS", - implementation_context); - - UOBJC_METACLASS_decl = define_decl (an_id, decl_specs); - TREE_USED (UOBJC_METACLASS_decl) = 1; - DECL_ARTIFICIAL(UOBJC_METACLASS_decl) = 1; - - /* Pre-build the following entities - for speed/convenience. */ - - an_id = get_identifier ("super_class"); - ucls_super_ref = build_component_ref (UOBJC_CLASS_decl, an_id); - uucls_super_ref = build_component_ref (UOBJC_METACLASS_decl, an_id); -} - -static void -error_with_ivar (message, decl, rawdecl) - char *message; - tree decl; - tree rawdecl; -{ - count_error (0); - - report_error_function (DECL_SOURCE_FILE (decl)); - - fprintf (stderr, "%s:%d: ", - DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%s'\n", message, gen_declaration (rawdecl, errbuf)); -} - -#define USERTYPE(t) \ - (TREE_CODE (t) == RECORD_TYPE || TREE_CODE (t) == UNION_TYPE \ - || TREE_CODE (t) == ENUMERAL_TYPE) - -static void -check_ivars (inter, imp) - tree inter; - tree imp; -{ - tree intdecls = CLASS_IVARS (inter); - tree impdecls = CLASS_IVARS (imp); - tree rawintdecls = CLASS_RAW_IVARS (inter); - tree rawimpdecls = CLASS_RAW_IVARS (imp); - - while (1) - { - tree t1, t2; - - if (intdecls == 0 && impdecls == 0) - break; - if (intdecls == 0 || impdecls == 0) - { - error ("inconsistent instance variable specification"); - break; - } - - t1 = TREE_TYPE (intdecls); t2 = TREE_TYPE (impdecls); - - if (!comptypes (t1, t2)) - { - if (DECL_NAME (intdecls) == DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable type", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - else /* both the type and the name don't match */ - { - error ("inconsistent instance variable specification"); - break; - } - } - - else if (DECL_NAME (intdecls) != DECL_NAME (impdecls)) - { - error_with_ivar ("conflicting instance variable name", - impdecls, rawimpdecls); - error_with_ivar ("previous declaration of", - intdecls, rawintdecls); - } - - intdecls = TREE_CHAIN (intdecls); - impdecls = TREE_CHAIN (impdecls); - rawintdecls = TREE_CHAIN (rawintdecls); - rawimpdecls = TREE_CHAIN (rawimpdecls); - } -} - -/* Set super_type to the data type node for struct objc_super *, - first defining struct objc_super itself. - This needs to be done just once per compilation. */ - -static tree -build_super_template () -{ - tree record, decl_specs, field_decl, field_decl_chain; - - record = start_struct (RECORD_TYPE, get_identifier (UTAG_SUPER)); - - /* struct objc_object *self; */ - - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - field_decl = get_identifier ("self"); - field_decl = build1 (INDIRECT_REF, NULL_TREE, field_decl); - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_class *class; */ - - decl_specs = get_identifier (UTAG_CLASS); - decl_specs = build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, decl_specs)); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("class")); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (record, field_decl_chain, NULL_TREE); - - /* `struct objc_super *' */ - super_type = groktypename (build_tree_list (build_tree_list (NULL_TREE, - record), - build1 (INDIRECT_REF, - NULL_TREE, NULL_TREE))); - return record; -} - -/* struct objc_ivar { - char *ivar_name; - char *ivar_type; - int ivar_offset; - }; */ - -static tree -build_ivar_template () -{ - tree objc_ivar_id, objc_ivar_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_id = get_identifier (UTAG_IVAR); - objc_ivar_record = start_struct (RECORD_TYPE, objc_ivar_id); - - /* char *ivar_name; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_name")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* char *ivar_type; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_CHAR]); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("ivar_type")); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* int ivar_offset; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_offset"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_record, field_decl_chain, NULL_TREE); - - return objc_ivar_record; -} - -/* struct { - int ivar_count; - struct objc_ivar ivar_list[ivar_count]; - }; */ - -static tree -build_ivar_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int ivar_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("ivar_count"); - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* struct objc_ivar ivar_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("ivar_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -/* struct { - int method_next; - int method_count; - struct objc_method method_list[method_count]; - }; */ - -static tree -build_method_list_template (list_type, size) - tree list_type; - int size; -{ - tree objc_ivar_list_record; - tree decl_specs, field_decl, field_decl_chain; - - objc_ivar_list_record = start_struct (RECORD_TYPE, NULL_TREE); - - /* int method_next; */ - - decl_specs - = build_tree_list - (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_PROTOTYPE_LIST))); - field_decl - = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("method_next")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - /* int method_count; */ - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_INT]); - field_decl = get_identifier ("method_count"); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* struct objc_method method_list[]; */ - - decl_specs = build_tree_list (NULL_TREE, list_type); - field_decl = build_nt (ARRAY_REF, get_identifier ("method_list"), - build_int_2 (size, 0)); - - field_decl = grokfield (input_filename, lineno, - field_decl, decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (objc_ivar_list_record, field_decl_chain, NULL_TREE); - - return objc_ivar_list_record; -} - -static tree -build_ivar_list_initializer (type, field_decl) - tree type; - tree field_decl; -{ - tree initlist = NULL_TREE; - - do - { - tree ivar = NULL_TREE; - - /* Set name. */ - if (DECL_NAME (field_decl)) - ivar = tree_cons (NULL_TREE, - add_objc_string (DECL_NAME (field_decl), - meth_var_names), - ivar); - else - /* Unnamed bit-field ivar (yuck). */ - ivar = tree_cons (NULL_TREE, build_int_2 (0, 0), ivar); - - /* Set type. */ - encode_field_decl (field_decl, - obstack_object_size (&util_obstack), - OBJC_ENCODE_DONT_INLINE_DEFS); - - /* Null terminate string. */ - obstack_1grow (&util_obstack, 0); - ivar - = tree_cons - (NULL_TREE, - add_objc_string (get_identifier (obstack_finish (&util_obstack)), - meth_var_types), - ivar); - obstack_free (&util_obstack, util_firstobj); - - /* set offset */ - ivar - = tree_cons - (NULL_TREE, - build_int_2 ((TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)) - / BITS_PER_UNIT), - 0), - ivar); - - initlist = tree_cons (NULL_TREE, - build_constructor (type, nreverse (ivar)), - initlist); - - field_decl = TREE_CHAIN (field_decl); - } - while (field_decl); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -static tree -generate_ivars_list (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (size, 0)); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, - build_constructor (TREE_TYPE (decl), nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_ivar_lists () -{ - tree initlist, ivar_list_template, chain; - tree cast, variable_length_type; - int size; - - generating_instance_variables = 1; - - if (!objc_ivar_template) - objc_ivar_template = build_ivar_template (); - - cast - = build_tree_list - (build_tree_list (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_IVAR_LIST))), - NULL_TREE); - variable_length_type = groktypename (cast); - - /* Only generate class variables for the root of the inheritance - hierarchy since these will be the same for every class. */ - - if (CLASS_SUPER_NAME (implementation_template) == NULL_TREE - && (chain = TYPE_FIELDS (objc_class_template))) - { - size = list_length (chain); - - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); - - UOBJC_CLASS_VARIABLES_decl - = generate_ivars_list (ivar_list_template, "_OBJC_CLASS_VARIABLES", - size, initlist); - TREE_TYPE (UOBJC_CLASS_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_CLASS_VARIABLES_decl = 0; - - chain = CLASS_IVARS (implementation_template); - if (chain) - { - size = list_length (chain); - ivar_list_template = build_ivar_list_template (objc_ivar_template, size); - initlist = build_ivar_list_initializer (objc_ivar_template, chain); - - UOBJC_INSTANCE_VARIABLES_decl - = generate_ivars_list (ivar_list_template, "_OBJC_INSTANCE_VARIABLES", - size, initlist); - TREE_TYPE (UOBJC_INSTANCE_VARIABLES_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_VARIABLES_decl = 0; - - generating_instance_variables = 0; -} - -static tree -build_dispatch_table_initializer (type, entries) - tree type; - tree entries; -{ - tree initlist = NULL_TREE; - - do - { - tree elemlist = NULL_TREE; - - elemlist = tree_cons (NULL_TREE, - build_selector (METHOD_SEL_NAME (entries)), - NULL_TREE); - - elemlist = tree_cons (NULL_TREE, - add_objc_string (METHOD_ENCODING (entries), - meth_var_types), - elemlist); - - elemlist = tree_cons (NULL_TREE, - build_unary_op (ADDR_EXPR, - METHOD_DEFINITION (entries), 1), - elemlist); - - initlist = tree_cons (NULL_TREE, - build_constructor (type, nreverse (elemlist)), - initlist); - - entries = TREE_CHAIN (entries); - } - while (entries); - - return build_constructor (build_array_type (type, 0), nreverse (initlist)); -} - -/* To accomplish method prototyping without generating all kinds of - inane warnings, the definition of the dispatch table entries were - changed from: - - struct objc_method { SEL _cmd; ...; id (*_imp)(); }; - to: - struct objc_method { SEL _cmd; ...; void *_imp; }; */ - -static tree -build_method_template () -{ - tree _SLT_record; - tree decl_specs, field_decl, field_decl_chain; - - _SLT_record = start_struct (RECORD_TYPE, get_identifier (UTAG_METHOD)); - -#ifdef OBJC_INT_SELECTORS - /* unsigned int _cmd; */ - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_UNSIGNED], - NULL_TREE); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - field_decl = get_identifier ("_cmd"); -#else /* not OBJC_INT_SELECTORS */ - /* struct objc_selector *_cmd; */ - decl_specs = tree_cons (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR)), - NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_cmd")); -#endif /* not OBJC_INT_SELECTORS */ - - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - field_decl_chain = field_decl; - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_CHAR], NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, - get_identifier ("method_types")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - /* void *_imp; */ - - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_VOID], NULL_TREE); - field_decl = build1 (INDIRECT_REF, NULL_TREE, get_identifier ("_imp")); - field_decl = grokfield (input_filename, lineno, field_decl, - decl_specs, NULL_TREE); - chainon (field_decl_chain, field_decl); - - finish_struct (_SLT_record, field_decl_chain, NULL_TREE); - - return _SLT_record; -} - - -static tree -generate_dispatch_table (type, name, size, list) - tree type; - char *name; - int size; - tree list; -{ - tree sc_spec, decl_specs, decl, initlist; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - decl = start_decl (synth_id_with_class_suffix (name, implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_tree_list (NULL_TREE, build_int_2 (0, 0)); - initlist = tree_cons (NULL_TREE, build_int_2 (size, 0), initlist); - initlist = tree_cons (NULL_TREE, list, initlist); - - finish_decl (decl, - build_constructor (TREE_TYPE (decl), nreverse (initlist)), - NULL_TREE); - - return decl; -} - -static void -generate_dispatch_tables () -{ - tree initlist, chain, method_list_template; - tree cast, variable_length_type; - int size; - - if (!objc_method_template) - objc_method_template = build_method_template (); - - cast - = build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_METHOD_LIST))), - NULL_TREE); - - variable_length_type = groktypename (cast); - - chain = CLASS_CLS_METHODS (implementation_context); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_list_template (objc_method_template, size); - initlist - = build_dispatch_table_initializer (objc_method_template, chain); - - UOBJC_CLASS_METHODS_decl - = generate_dispatch_table (method_list_template, - ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? "_OBJC_CLASS_METHODS" - : "_OBJC_CATEGORY_CLASS_METHODS"), - size, initlist); - TREE_TYPE (UOBJC_CLASS_METHODS_decl) = variable_length_type; - } - else - UOBJC_CLASS_METHODS_decl = 0; - - chain = CLASS_NST_METHODS (implementation_context); - if (chain) - { - size = list_length (chain); - - method_list_template - = build_method_list_template (objc_method_template, size); - initlist - = build_dispatch_table_initializer (objc_method_template, chain); - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - UOBJC_INSTANCE_METHODS_decl - = generate_dispatch_table (method_list_template, - "_OBJC_INSTANCE_METHODS", - size, initlist); - else - /* We have a category. */ - UOBJC_INSTANCE_METHODS_decl - = generate_dispatch_table (method_list_template, - "_OBJC_CATEGORY_INSTANCE_METHODS", - size, initlist); - TREE_TYPE (UOBJC_INSTANCE_METHODS_decl) = variable_length_type; - } - else - UOBJC_INSTANCE_METHODS_decl = 0; -} - -static tree -generate_protocol_list (i_or_p) - tree i_or_p; -{ - static tree cast_type = 0; - tree initlist, decl_specs, sc_spec; - tree refs_decl, expr_decl, lproto, e, plist; - int size = 0; - - if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE - || TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - plist = CLASS_PROTOCOL_LIST (i_or_p); - else if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - plist = PROTOCOL_LIST (i_or_p); - else - abort (); - - if (!cast_type) - cast_type - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE))); - - /* Compute size. */ - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - if (TREE_CODE (TREE_VALUE (lproto)) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (TREE_VALUE (lproto))) - size++; - - /* Build initializer. */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), NULL_TREE); - - e = build_int_2 (size, 0); - TREE_TYPE (e) = cast_type; - initlist = tree_cons (NULL_TREE, e, initlist); - - for (lproto = plist; lproto; lproto = TREE_CHAIN (lproto)) - { - tree pval = TREE_VALUE (lproto); - - if (TREE_CODE (pval) == PROTOCOL_INTERFACE_TYPE - && PROTOCOL_FORWARD_DECL (pval)) - { - e = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (pval), 0); - initlist = tree_cons (NULL_TREE, e, initlist); - } - } - - /* static struct objc_protocol *refs[n]; */ - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL)), - sc_spec); - - if (TREE_CODE (i_or_p) == PROTOCOL_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_PROTOCOL_REFS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CLASS_INTERFACE_TYPE) - expr_decl = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CLASS_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - else if (TREE_CODE (i_or_p) == CATEGORY_INTERFACE_TYPE) - expr_decl - = build_nt (ARRAY_REF, - synth_id_with_class_suffix ("_OBJC_CATEGORY_PROTOCOLS", - i_or_p), - build_int_2 (size + 2, 0)); - - expr_decl = build1 (INDIRECT_REF, NULL_TREE, expr_decl); - - refs_decl = start_decl (expr_decl, decl_specs, 1, NULL_TREE, NULL_TREE); - - finish_decl (refs_decl, build_constructor (TREE_TYPE (refs_decl), - nreverse (initlist)), - NULL_TREE); - - return refs_decl; -} - -static tree -build_category_initializer (type, cat_name, class_name, - instance_methods, class_methods, protocol_list) - tree type; - tree cat_name; - tree class_name; - tree instance_methods; - tree class_methods; - tree protocol_list; -{ - tree initlist = NULL_TREE, expr; - - initlist = tree_cons (NULL_TREE, cat_name, initlist); - initlist = tree_cons (NULL_TREE, class_name, initlist); - - if (!instance_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, instance_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - if (!class_methods) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, class_methods, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* protocol_list = */ - if (!protocol_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - return build_constructor (type, nreverse (initlist)); -} - -/* struct objc_class { - struct objc_class *isa; - struct objc_class *super_class; - char *name; - long version; - long info; - long instance_size; - struct objc_ivar_list *ivars; - struct objc_method_list *methods; - if (flag_next_runtime) - struct objc_cache *cache; - else { - struct sarray *dtable; - struct objc_class *subclass_list; - struct objc_class *sibling_class; - } - struct objc_protocol_list *protocols; - void *gc_object_type; - }; */ - -static tree -build_shared_structure_initializer (type, isa, super, name, size, status, - dispatch_table, ivar_list, protocol_list) - tree type; - tree isa; - tree super; - tree name; - tree size; - int status; - tree dispatch_table; - tree ivar_list; - tree protocol_list; -{ - tree initlist = NULL_TREE, expr; - - /* isa = */ - initlist = tree_cons (NULL_TREE, isa, initlist); - - /* super_class = */ - initlist = tree_cons (NULL_TREE, super, initlist); - - /* name = */ - initlist = tree_cons (NULL_TREE, default_conversion (name), initlist); - - /* version = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* info = */ - initlist = tree_cons (NULL_TREE, build_int_2 (status, 0), initlist); - - /* instance_size = */ - initlist = tree_cons (NULL_TREE, size, initlist); - - /* objc_ivar_list = */ - if (!ivar_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, ivar_list, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* objc_method_list = */ - if (!dispatch_table) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - expr = build_unary_op (ADDR_EXPR, dispatch_table, 0); - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - if (flag_next_runtime) - /* method_cache = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - /* dtable = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* subclass_list = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - /* sibling_class = */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - } - - /* protocol_list = */ - if (! protocol_list) - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - else - { - static tree cast_type2; - - if (!cast_type2) - cast_type2 - = groktypename - (build_tree_list - (build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (UTAG_PROTOCOL))), - build1 (INDIRECT_REF, NULL_TREE, - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)))); - - expr = build_unary_op (ADDR_EXPR, protocol_list, 0); - TREE_TYPE (expr) = cast_type2; - initlist = tree_cons (NULL_TREE, expr, initlist); - } - - /* gc_object_type = NULL */ - initlist = tree_cons (NULL_TREE, build_int_2 (0, 0), initlist); - - return build_constructor (type, nreverse (initlist)); -} - -/* static struct objc_category _OBJC_CATEGORY_<name> = { ... }; */ - -static void -generate_category (cat) - tree cat; -{ - tree sc_spec, decl_specs, decl; - tree initlist, cat_name_expr, class_name_expr; - tree protocol_decl, category; - - add_class_reference (CLASS_NAME (cat)); - cat_name_expr = add_objc_string (CLASS_SUPER_NAME (cat), class_names); - - class_name_expr = add_objc_string (CLASS_NAME (cat), class_names); - - category = CLASS_CATEGORY_LIST (implementation_template); - - /* find the category interface from the class it is associated with */ - while (category) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category && CLASS_PROTOCOL_LIST (category)) - { - generate_protocol_references (CLASS_PROTOCOL_LIST (category)); - protocol_decl = generate_protocol_list (category); - } - else - protocol_decl = 0; - - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - decl_specs = tree_cons (NULL_TREE, objc_category_template, sc_spec); - - decl = start_decl (synth_id_with_class_suffix ("_OBJC_CATEGORY", - implementation_context), - decl_specs, 1, NULL_TREE, NULL_TREE); - - initlist = build_category_initializer (TREE_TYPE (decl), - cat_name_expr, class_name_expr, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_CLASS_METHODS_decl, - protocol_decl); - - TREE_USED (decl) = 1; - finish_decl (decl, initlist, NULL_TREE); -} - -/* static struct objc_class _OBJC_METACLASS_Foo={ ... }; - static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - -static void -generate_shared_structures () -{ - tree sc_spec, decl_specs, decl; - tree name_expr, super_expr, root_expr; - tree my_root_id = NULL_TREE, my_super_id = NULL_TREE; - tree cast_type, initlist, protocol_decl; - - my_super_id = CLASS_SUPER_NAME (implementation_template); - if (my_super_id) - { - add_class_reference (my_super_id); - - /* Compute "my_root_id" - this is required for code generation. - the "isa" for all meta class structures points to the root of - the inheritance hierarchy (e.g. "__Object")... */ - my_root_id = my_super_id; - do - { - tree my_root_int = lookup_interface (my_root_id); - - if (my_root_int && CLASS_SUPER_NAME (my_root_int)) - my_root_id = CLASS_SUPER_NAME (my_root_int); - else - break; - } - while (1); - } - else - /* No super class. */ - my_root_id = CLASS_NAME (implementation_template); - - cast_type - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - objc_class_template), - build1 (INDIRECT_REF, - NULL_TREE, NULL_TREE))); - - name_expr = add_objc_string (CLASS_NAME (implementation_template), - class_names); - - /* Install class `isa' and `super' pointers at runtime. */ - if (my_super_id) - { - super_expr = add_objc_string (my_super_id, class_names); - super_expr = build_c_cast (cast_type, super_expr); /* cast! */ - } - else - super_expr = build_int_2 (0, 0); - - root_expr = add_objc_string (my_root_id, class_names); - root_expr = build_c_cast (cast_type, root_expr); /* cast! */ - - if (CLASS_PROTOCOL_LIST (implementation_template)) - { - generate_protocol_references - (CLASS_PROTOCOL_LIST (implementation_template)); - protocol_decl = generate_protocol_list (implementation_template); - } - else - protocol_decl = 0; - - /* static struct objc_class _OBJC_METACLASS_Foo = { ... }; */ - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - decl_specs = tree_cons (NULL_TREE, objc_class_template, sc_spec); - - decl = start_decl (DECL_NAME (UOBJC_METACLASS_decl), decl_specs, 1, - NULL_TREE, NULL_TREE); - - initlist - = build_shared_structure_initializer - (TREE_TYPE (decl), - root_expr, super_expr, name_expr, - build_int_2 ((TREE_INT_CST_LOW (TYPE_SIZE (objc_class_template)) - / BITS_PER_UNIT), - 0), - 2 /*CLS_META*/, - UOBJC_CLASS_METHODS_decl, - UOBJC_CLASS_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULL_TREE); - - /* static struct objc_class _OBJC_CLASS_Foo={ ... }; */ - - decl = start_decl (DECL_NAME (UOBJC_CLASS_decl), decl_specs, 1, - NULL_TREE, NULL_TREE); - - initlist - = build_shared_structure_initializer - (TREE_TYPE (decl), - build_unary_op (ADDR_EXPR, UOBJC_METACLASS_decl, 0), - super_expr, name_expr, - build_int_2 - ((TREE_INT_CST_LOW - (TYPE_SIZE (CLASS_STATIC_TEMPLATE (implementation_template))) - / BITS_PER_UNIT), - 0), - 1 /*CLS_FACTORY*/, - UOBJC_INSTANCE_METHODS_decl, - UOBJC_INSTANCE_VARIABLES_decl, - protocol_decl); - - finish_decl (decl, initlist, NULL_TREE); -} - -static tree -synth_id_with_class_suffix (preamble, ctxt) - char *preamble; - tree ctxt; -{ - char *string; - if (TREE_CODE (ctxt) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CLASS_INTERFACE_TYPE) - { - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) + strlen (class_name) + 3); - sprintf (string, "%s_%s", preamble, - IDENTIFIER_POINTER (CLASS_NAME (ctxt))); - } - else if (TREE_CODE (ctxt) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (ctxt) == CATEGORY_INTERFACE_TYPE) - { - /* We have a category. */ - char *class_name - = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context)); - string = (char *) alloca (strlen (preamble) - + strlen (class_name) - + strlen (class_super_name) - + 3); - sprintf (string, "%s_%s_%s", preamble, class_name, class_super_name); - } - else if (TREE_CODE (ctxt) == PROTOCOL_INTERFACE_TYPE) - { - char *protocol_name = IDENTIFIER_POINTER (PROTOCOL_NAME (ctxt)); - string - = (char *) alloca (strlen (preamble) + strlen (protocol_name) + 3); - sprintf (string, "%s_%s", preamble, protocol_name); - } - return get_identifier (string); -} - -static int -is_objc_type_qualifier (node) - tree node; -{ - return (TREE_CODE (node) == IDENTIFIER_NODE - && (node == ridpointers [(int) RID_CONST] - || node == ridpointers [(int) RID_VOLATILE] - || node == ridpointers [(int) RID_IN] - || node == ridpointers [(int) RID_OUT] - || node == ridpointers [(int) RID_INOUT] - || node == ridpointers [(int) RID_BYCOPY] - || node == ridpointers [(int) RID_BYREF] - || node == ridpointers [(int) RID_ONEWAY])); -} - -/* If type is empty or only type qualifiers are present, add default - type of id (otherwise grokdeclarator will default to int). */ - -static tree -adjust_type_for_id_default (type) - tree type; -{ - tree declspecs, chain; - - if (!type) - return build_tree_list (build_tree_list (NULL_TREE, objc_object_reference), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); - - declspecs = TREE_PURPOSE (type); - - /* Determine if a typespec is present. */ - for (chain = declspecs; - chain; - chain = TREE_CHAIN (chain)) - { - if (!is_objc_type_qualifier (TREE_VALUE (chain))) - return type; - } - - return build_tree_list (tree_cons (NULL_TREE, objc_object_reference, - declspecs), - build1 (INDIRECT_REF, NULL_TREE, NULL_TREE)); -} - -/* Usage: - keyworddecl: - selector ':' '(' typename ')' identifier - - Purpose: - Transform an Objective-C keyword argument into - the C equivalent parameter declarator. - - In: key_name, an "identifier_node" (optional). - arg_type, a "tree_list" (optional). - arg_name, an "identifier_node". - - Note: It would be really nice to strongly type the preceding - arguments in the function prototype; however, then I - could not use the "accessor" macros defined in "tree.h". - - Out: an instance of "keyword_decl". */ - -tree -build_keyword_decl (key_name, arg_type, arg_name) - tree key_name; - tree arg_type; - tree arg_name; -{ - tree keyword_decl; - - /* If no type is specified, default to "id". */ - arg_type = adjust_type_for_id_default (arg_type); - - keyword_decl = make_node (KEYWORD_DECL); - - TREE_TYPE (keyword_decl) = arg_type; - KEYWORD_ARG_NAME (keyword_decl) = arg_name; - KEYWORD_KEY_NAME (keyword_decl) = key_name; - - return keyword_decl; -} - -/* Given a chain of keyword_decl's, synthesize the full keyword selector. */ - -static tree -build_keyword_selector (selector) - tree selector; -{ - int len = 0; - tree key_chain, key_name; - char *buf; - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - - if (key_name) - len += IDENTIFIER_LENGTH (key_name) + 1; - else - /* Just a ':' arg. */ - len++; - } - - buf = (char *)alloca (len + 1); - bzero (buf, len + 1); - - for (key_chain = selector; key_chain; key_chain = TREE_CHAIN (key_chain)) - { - if (TREE_CODE (selector) == KEYWORD_DECL) - key_name = KEYWORD_KEY_NAME (key_chain); - else if (TREE_CODE (selector) == TREE_LIST) - key_name = TREE_PURPOSE (key_chain); - - if (key_name) - strcat (buf, IDENTIFIER_POINTER (key_name)); - strcat (buf, ":"); - } - - return get_identifier (buf); -} - -/* Used for declarations and definitions. */ - -tree -build_method_decl (code, ret_type, selector, add_args) - enum tree_code code; - tree ret_type; - tree selector; - tree add_args; -{ - tree method_decl; - - /* If no type is specified, default to "id". */ - ret_type = adjust_type_for_id_default (ret_type); - - method_decl = make_node (code); - TREE_TYPE (method_decl) = ret_type; - - /* If we have a keyword selector, create an identifier_node that - represents the full selector name (`:' included)... */ - if (TREE_CODE (selector) == KEYWORD_DECL) - { - METHOD_SEL_NAME (method_decl) = build_keyword_selector (selector); - METHOD_SEL_ARGS (method_decl) = selector; - METHOD_ADD_ARGS (method_decl) = add_args; - } - else - { - METHOD_SEL_NAME (method_decl) = selector; - METHOD_SEL_ARGS (method_decl) = NULL_TREE; - METHOD_ADD_ARGS (method_decl) = NULL_TREE; - } - - return method_decl; -} - -#define METHOD_DEF 0 -#define METHOD_REF 1 - -/* Used by `build_message_expr' and `comp_method_types'. Return an - argument list for method METH. CONTEXT is either METHOD_DEF or - METHOD_REF, saying whether we are trying to define a method or call - one. SUPERFLAG says this is for a send to super; this makes a - difference for the NeXT calling sequence in which the lookup and - the method call are done together. */ - -static tree -get_arg_type_list (meth, context, superflag) - tree meth; - int context; - int superflag; -{ - tree arglist, akey; - - /* Receiver type. */ - if (flag_next_runtime && superflag) - arglist = build_tree_list (NULL_TREE, super_type); - else if (context == METHOD_DEF) - arglist = build_tree_list (NULL_TREE, TREE_TYPE (self_decl)); - else - arglist = build_tree_list (NULL_TREE, id_type); - - /* Selector type - will eventually change to `int'. */ - chainon (arglist, build_tree_list (NULL_TREE, selector_type)); - - /* Build a list of argument types. */ - for (akey = METHOD_SEL_ARGS (meth); akey; akey = TREE_CHAIN (akey)) - { - tree arg_decl = groktypename_in_parm_context (TREE_TYPE (akey)); - chainon (arglist, build_tree_list (NULL_TREE, TREE_TYPE (arg_decl))); - } - - if (METHOD_ADD_ARGS (meth) == (tree)1) - /* We have a `, ...' immediately following the selector, - finalize the arglist...simulate get_parm_info (0). */ - ; - else if (METHOD_ADD_ARGS (meth)) - { - /* we have a variable length selector */ - tree add_arg_list = TREE_CHAIN (METHOD_ADD_ARGS (meth)); - chainon (arglist, add_arg_list); - } - else - /* finalize the arglist...simulate get_parm_info (1) */ - chainon (arglist, build_tree_list (NULL_TREE, void_type_node)); - - return arglist; -} - -static tree -check_duplicates (hsh) - hash hsh; -{ - tree meth = NULL_TREE; - - if (hsh) - { - meth = hsh->key; - - if (hsh->list) - { - /* We have two methods with the same name and different types. */ - attr loop; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL) ? '-' : '+'; - - warning ("multiple declarations for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - - warn_with_method ("using", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("also found", type, loop->value); - } - } - return meth; -} - -/* If RECEIVER is a class reference, return the identifier node for the - referenced class. RECEIVER is created by get_class_reference, so we - check the exact form created depending on which runtimes are used. */ - -static tree -receiver_is_class_object (receiver) - tree receiver; -{ - tree chain, exp, arg; - if (flag_next_runtime) - { - /* The receiver is a variable created by build_class_reference_decl. */ - if (TREE_CODE (receiver) == VAR_DECL - && TREE_TYPE (receiver) == objc_class_type) - /* Look up the identifier. */ - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - if (TREE_PURPOSE (chain) == receiver) - return TREE_VALUE (chain); - } - else - { - /* The receiver is a function call that returns an id. Check if - it is a call to objc_getClass, if so, pick up the class name. */ - if ((exp = TREE_OPERAND (receiver, 0)) - && TREE_CODE (exp) == ADDR_EXPR - && (exp = TREE_OPERAND (exp, 0)) - && TREE_CODE (exp) == FUNCTION_DECL - && exp == objc_get_class_decl - /* we have a call to objc_getClass! */ - && (arg = TREE_OPERAND (receiver, 1)) - && TREE_CODE (arg) == TREE_LIST - && (arg = TREE_VALUE (arg))) - { - STRIP_NOPS (arg); - if (TREE_CODE (arg) == ADDR_EXPR - && (arg = TREE_OPERAND (arg, 0)) - && TREE_CODE (arg) == STRING_CST) - /* Finally, we have the class name. */ - return get_identifier (TREE_STRING_POINTER (arg)); - } - } - return 0; -} - -/* If we are currently building a message expr, this holds - the identifier of the selector of the message. This is - used when printing warnings about argument mismatches. */ - -static tree building_objc_message_expr = 0; - -tree -maybe_building_objc_message_expr () -{ - return building_objc_message_expr; -} - -/* Construct an expression for sending a message. - MESS has the object to send to in TREE_PURPOSE - and the argument list (including selector) in TREE_VALUE. - - (*(<abstract_decl>(*)())_msg)(receiver, selTransTbl[n], ...); - (*(<abstract_decl>(*)())_msgSuper)(receiver, selTransTbl[n], ...); */ - -tree -build_message_expr (mess) - tree mess; -{ - tree receiver = TREE_PURPOSE (mess); - tree selector, self_object; - tree rtype, sel_name; - tree args = TREE_VALUE (mess); - tree method_params = NULL_TREE; - tree method_prototype = NULL_TREE; - tree retval; - int statically_typed = 0, statically_allocated = 0; - tree class_ident = 0; - - /* 1 if this is sending to the superclass. */ - int super; - - if (!doing_objc_thang) - objc_fatal (); - - if (TREE_CODE (receiver) == ERROR_MARK) - return error_mark_node; - - /* Determine receiver type. */ - rtype = TREE_TYPE (receiver); - super = IS_SUPER (rtype); - - if (! super) - { - if (TREE_STATIC_TEMPLATE (rtype)) - statically_allocated = 1; - else if (TREE_CODE (rtype) == POINTER_TYPE - && TREE_STATIC_TEMPLATE (TREE_TYPE (rtype))) - statically_typed = 1; - else if ((flag_next_runtime - || (TREE_CODE (receiver) == CALL_EXPR && IS_ID (rtype))) - && (class_ident = receiver_is_class_object (receiver))) - ; - else if (! IS_ID (rtype) - /* Allow any type that matches objc_class_type. */ - && ! comptypes (rtype, objc_class_type)) - { - bzero (errbuf, BUFSIZE); - warning ("invalid receiver type `%s'", - gen_declaration (rtype, errbuf)); - } - - if (statically_allocated) - receiver = build_unary_op (ADDR_EXPR, receiver, 0); - - /* Don't evaluate the receiver twice. */ - receiver = save_expr (receiver); - self_object = receiver; - } - else - /* If sending to `super', use current self as the object. */ - self_object = self_decl; - - /* Obtain the full selector name. */ - - if (TREE_CODE (args) == IDENTIFIER_NODE) - /* A unary selector. */ - sel_name = args; - else if (TREE_CODE (args) == TREE_LIST) - sel_name = build_keyword_selector (args); - - /* Build the parameter list to give to the method. */ - - method_params = NULL_TREE; - if (TREE_CODE (args) == TREE_LIST) - { - tree chain = args, prev = NULL_TREE; - - /* We have a keyword selector--check for comma expressions. */ - while (chain) - { - tree element = TREE_VALUE (chain); - - /* We have a comma expression, must collapse... */ - if (TREE_CODE (element) == TREE_LIST) - { - if (prev) - TREE_CHAIN (prev) = element; - else - args = element; - } - prev = chain; - chain = TREE_CHAIN (chain); - } - method_params = args; - } - - /* Determine operation return type. */ - - if (IS_SUPER (rtype)) - { - tree iface; - - if (CLASS_SUPER_NAME (implementation_template)) - { - iface - = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - method_prototype = lookup_instance_method_static (iface, sel_name); - else - method_prototype = lookup_class_method_static (iface, sel_name); - - if (iface && !method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_template)), - IDENTIFIER_POINTER (sel_name)); - } - else - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - } - else if (statically_allocated) - { - tree ctype = TREE_TYPE (rtype); - tree iface = lookup_interface (TYPE_NAME (rtype)); - - if (iface) - method_prototype = lookup_instance_method_static (iface, sel_name); - - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (rtype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (statically_typed) - { - tree ctype = TREE_TYPE (rtype); - - /* `self' is now statically_typed. All methods should be visible - within the context of the implementation. */ - if (implementation_context - && CLASS_NAME (implementation_context) == TYPE_NAME (ctype)) - { - method_prototype - = lookup_instance_method_static (implementation_template, - sel_name); - - if (! method_prototype && TYPE_PROTOCOL_LIST (ctype)) - method_prototype - = lookup_method_in_protocol_list (TYPE_PROTOCOL_LIST (ctype), - sel_name, 0); - - if (! method_prototype - && implementation_template != implementation_context) - /* The method is not published in the interface. Check - locally. */ - method_prototype - = lookup_method (CLASS_NST_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (TYPE_NAME (ctype)))) - method_prototype = lookup_instance_method_static (iface, sel_name); - - if (! method_prototype) - { - tree protocol_list = TYPE_PROTOCOL_LIST (ctype); - if (protocol_list) - method_prototype - = lookup_method_in_protocol_list (protocol_list, - sel_name, 0); - } - } - - if (!method_prototype) - warning ("`%s' does not respond to `%s'", - IDENTIFIER_POINTER (TYPE_NAME (ctype)), - IDENTIFIER_POINTER (sel_name)); - } - else if (class_ident) - { - if (implementation_context - && CLASS_NAME (implementation_context) == class_ident) - { - method_prototype - = lookup_class_method_static (implementation_template, sel_name); - - if (!method_prototype - && implementation_template != implementation_context) - /* The method is not published in the interface. Check - locally. */ - method_prototype - = lookup_method (CLASS_CLS_METHODS (implementation_context), - sel_name); - } - else - { - tree iface; - - if ((iface = lookup_interface (class_ident))) - method_prototype = lookup_class_method_static (iface, sel_name); - } - - if (!method_prototype) - { - warning ("cannot find class (factory) method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - else if (IS_PROTOCOL_QUALIFIED_ID (rtype)) - { - /* An anonymous object that has been qualified with a protocol. */ - - tree protocol_list = TYPE_PROTOCOL_LIST (rtype); - - method_prototype = lookup_method_in_protocol_list (protocol_list, - sel_name, 0); - - if (!method_prototype) - { - hash hsh; - - warning ("method `%s' not implemented by protocol.", - IDENTIFIER_POINTER (sel_name)); - - /* Try and find the method signature in the global pools. */ - - if (!(hsh = hash_lookup (nst_method_hash_list, sel_name))) - hsh = hash_lookup (cls_method_hash_list, sel_name); - - if (!(method_prototype = check_duplicates (hsh))) - warning ("return type defaults to id"); - } - } - else - { - hash hsh; - - /* We think we have an instance...loophole: extern id Object; */ - hsh = hash_lookup (nst_method_hash_list, sel_name); - if (!hsh) - /* For various loopholes, like sending messages to self in a - factory context. */ - hsh = hash_lookup (cls_method_hash_list, sel_name); - - method_prototype = check_duplicates (hsh); - if (!method_prototype) - { - warning ("cannot find method."); - warning ("return type for `%s' defaults to id", - IDENTIFIER_POINTER (sel_name)); - } - } - - /* Save the selector name for printing error messages. */ - building_objc_message_expr = sel_name; - - /* Build the parameters list for looking up the method. - These are the object itself and the selector. */ - - if (flag_typed_selectors) - selector = build_typed_selector_reference (sel_name, method_prototype); - else - selector = build_selector_reference (sel_name); - - retval = build_objc_method_call (super, method_prototype, - receiver, self_object, - selector, method_params); - - building_objc_message_expr = 0; - - return retval; -} - -/* Build a tree expression to send OBJECT the operation SELECTOR, - looking up the method on object LOOKUP_OBJECT (often same as OBJECT), - assuming the method has prototype METHOD_PROTOTYPE. - (That is an INSTANCE_METHOD_DECL or CLASS_METHOD_DECL.) - Use METHOD_PARAMS as list of args to pass to the method. - If SUPER_FLAG is nonzero, we look up the superclass's method. */ - -static tree -build_objc_method_call (super_flag, method_prototype, lookup_object, object, - selector, method_params) - int super_flag; - tree method_prototype, lookup_object, object, selector, method_params; -{ - tree sender = (super_flag ? umsg_super_decl : umsg_decl); - tree rcv_p = (super_flag - ? build_pointer_type (xref_tag (RECORD_TYPE, - get_identifier (TAG_SUPER))) - : id_type); - - if (flag_next_runtime) - { - if (! method_prototype) - { - method_params = tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - method_params)); - assemble_external (sender); - return build_function_call (sender, method_params); - } - else - { - /* This is a real kludge, but it is used only for the Next. - Clobber the data type of SENDER temporarily to accept - all the arguments for this operation, and to return - whatever this operation returns. */ - tree arglist = NULL_TREE; - tree retval; - - /* Save the proper contents of SENDER's data type. */ - tree savarg = TYPE_ARG_TYPES (TREE_TYPE (sender)); - tree savret = TREE_TYPE (TREE_TYPE (sender)); - - /* Install this method's argument types. */ - arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - TYPE_ARG_TYPES (TREE_TYPE (sender)) = arglist; - - /* Install this method's return type. */ - TREE_TYPE (TREE_TYPE (sender)) - = groktypename (TREE_TYPE (method_prototype)); - - /* Call SENDER with all the parameters. This will do type - checking using the arg types for this method. */ - method_params = tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - method_params)); - assemble_external (sender); - retval = build_function_call (sender, method_params); - - /* Restore SENDER's return/argument types. */ - TYPE_ARG_TYPES (TREE_TYPE (sender)) = savarg; - TREE_TYPE (TREE_TYPE (sender)) = savret; - return retval; - } - } - else - { - /* This is the portable way. - First call the lookup function to get a pointer to the method, - then cast the pointer, then call it with the method arguments. */ - tree method; - - /* Avoid trouble since we may evaluate each of these twice. */ - object = save_expr (object); - selector = save_expr (selector); - - lookup_object = build_c_cast (rcv_p, lookup_object); - - assemble_external (sender); - method - = build_function_call (sender, - tree_cons (NULL_TREE, lookup_object, - tree_cons (NULL_TREE, selector, - NULL_TREE))); - - /* If we have a method prototype, construct the data type this - method needs, and cast what we got from SENDER into a pointer - to that type. */ - if (method_prototype) - { - tree arglist = get_arg_type_list (method_prototype, METHOD_REF, - super_flag); - tree valtype = groktypename (TREE_TYPE (method_prototype)); - tree fake_function_type = build_function_type (valtype, arglist); - TREE_TYPE (method) = build_pointer_type (fake_function_type); - } - else - TREE_TYPE (method) - = build_pointer_type (build_function_type (ptr_type_node, NULL_TREE)); - - /* Pass the object to the method. */ - assemble_external (method); - return build_function_call (method, - tree_cons (NULL_TREE, object, - tree_cons (NULL_TREE, selector, - method_params))); - } -} - -static void -build_protocol_reference (p) - tree p; -{ - tree decl, ident, ptype; - - push_obstacks_nochange (); - end_temporary_allocation (); - - /* extern struct objc_protocol _OBJC_PROTOCOL_<mumble>; */ - - ident = synth_id_with_class_suffix ("_OBJC_PROTOCOL", p); - ptype - = groktypename (build_tree_list (build_tree_list (NULL_TREE, - objc_protocol_template), - NULL_TREE)); - - if (IDENTIFIER_GLOBAL_VALUE (ident)) - decl = IDENTIFIER_GLOBAL_VALUE (ident); /* Set by pushdecl. */ - else - { - decl = build_decl (VAR_DECL, ident, ptype); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - TREE_USED (decl) = 1; - DECL_ARTIFICIAL (decl) = 1; - - make_decl_rtl (decl, 0, 1); - pushdecl_top_level (decl); - } - - PROTOCOL_FORWARD_DECL (p) = decl; - pop_obstacks (); -} - -tree -build_protocol_expr (protoname) - tree protoname; -{ - tree expr; - tree p; - - if (!doing_objc_thang) - objc_fatal (); - - p = lookup_protocol (protoname); - - if (!p) - { - error ("Cannot find protocol declaration for `%s'", - IDENTIFIER_POINTER (protoname)); - return error_mark_node; - } - - if (!PROTOCOL_FORWARD_DECL (p)) - build_protocol_reference (p); - - expr = build_unary_op (ADDR_EXPR, PROTOCOL_FORWARD_DECL (p), 0); - - TREE_TYPE (expr) = protocol_type; - - return expr; -} - -tree -build_selector_expr (selnamelist) - tree selnamelist; -{ - tree selname; - - if (!doing_objc_thang) - objc_fatal (); - - /* Obtain the full selector name. */ - if (TREE_CODE (selnamelist) == IDENTIFIER_NODE) - /* A unary selector. */ - selname = selnamelist; - else if (TREE_CODE (selnamelist) == TREE_LIST) - selname = build_keyword_selector (selnamelist); - - if (flag_typed_selectors) - return build_typed_selector_reference (selname, 0); - else - return build_selector_reference (selname); -} - -tree -build_encode_expr (type) - tree type; -{ - tree result; - char *string; - - if (!doing_objc_thang) - objc_fatal (); - - encode_type (type, obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - obstack_1grow (&util_obstack, 0); /* null terminate string */ - string = obstack_finish (&util_obstack); - - /* Synthesize a string that represents the encoded struct/union. */ - result = my_build_string (strlen (string) + 1, string); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -tree -build_ivar_reference (id) - tree id; -{ - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - { - /* Historically, a class method that produced objects (factory - method) would assign `self' to the instance that it - allocated. This would effectively turn the class method into - an instance method. Following this assignment, the instance - variables could be accessed. That practice, while safe, - violates the simple rule that a class method should not refer - to an instance variable. It's better to catch the cases - where this is done unknowingly than to support the above - paradigm. */ - warning ("instance variable `%s' accessed in class method", - IDENTIFIER_POINTER (id)); - TREE_TYPE (self_decl) = instance_type; /* cast */ - } - - return build_component_ref (build_indirect_ref (self_decl, "->"), id); -} - -#define HASH_ALLOC_LIST_SIZE 170 -#define ATTR_ALLOC_LIST_SIZE 170 -#define SIZEHASHTABLE 257 - -/* make positive */ -#define HASHFUNCTION(key) ((HOST_WIDE_INT) key & 0x7fffffff) - -static void -hash_init () -{ - nst_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - cls_method_hash_list = (hash *)xmalloc (SIZEHASHTABLE * sizeof (hash)); - - if (!nst_method_hash_list || !cls_method_hash_list) - perror ("unable to allocate space in objc-tree.c"); - else - { - int i; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - nst_method_hash_list[i] = 0; - cls_method_hash_list[i] = 0; - } - } -} - -static void -hash_enter (hashlist, method) - hash *hashlist; - tree method; -{ - static hash hash_alloc_list = 0; - static int hash_alloc_index = 0; - hash obj; - int slot = HASHFUNCTION (METHOD_SEL_NAME (method)) % SIZEHASHTABLE; - - if (! hash_alloc_list || hash_alloc_index >= HASH_ALLOC_LIST_SIZE) - { - hash_alloc_index = 0; - hash_alloc_list = (hash) xmalloc (sizeof (struct hashed_entry) - * HASH_ALLOC_LIST_SIZE); - if (! hash_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &hash_alloc_list[hash_alloc_index++]; - obj->list = 0; - obj->next = hashlist[slot]; - obj->key = method; - - hashlist[slot] = obj; /* append to front */ -} - -static hash -hash_lookup (hashlist, sel_name) - hash *hashlist; - tree sel_name; -{ - hash target; - - target = hashlist[HASHFUNCTION (sel_name) % SIZEHASHTABLE]; - - while (target) - { - if (sel_name == METHOD_SEL_NAME (target->key)) - return target; - - target = target->next; - } - return 0; -} - -static void -hash_add_attr (entry, value) - hash entry; - tree value; -{ - static attr attr_alloc_list = 0; - static int attr_alloc_index = 0; - attr obj; - - if (! attr_alloc_list || attr_alloc_index >= ATTR_ALLOC_LIST_SIZE) - { - attr_alloc_index = 0; - attr_alloc_list = (attr) xmalloc (sizeof (struct hashed_attribute) - * ATTR_ALLOC_LIST_SIZE); - if (! attr_alloc_list) - perror ("unable to allocate in objc-tree.c"); - } - obj = &attr_alloc_list[attr_alloc_index++]; - obj->next = entry->list; - obj->value = value; - - entry->list = obj; /* append to front */ -} - -static tree -lookup_method (mchain, method) - tree mchain; - tree method; -{ - tree key; - - if (TREE_CODE (method) == IDENTIFIER_NODE) - key = method; - else - key = METHOD_SEL_NAME (method); - - while (mchain) - { - if (METHOD_SEL_NAME (mchain) == key) - return mchain; - mchain = TREE_CHAIN (mchain); - } - return NULL_TREE; -} - -static tree -lookup_instance_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_NST_METHODS (inter); - tree meth = NULL_TREE; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_NST_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* Check for instance methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 0)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_NST_METHODS (category); - } - while (category); - } - - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 0)))) - return meth; - } - - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_NST_METHODS (inter); - } - while (inter); - - return meth; -} - -static tree -lookup_class_method_static (interface, ident) - tree interface; - tree ident; -{ - tree inter = interface; - tree chain = CLASS_CLS_METHODS (inter); - tree meth = NULL_TREE; - tree root_inter = NULL_TREE; - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - if (CLASS_CATEGORY_LIST (inter)) - { - tree category = CLASS_CATEGORY_LIST (inter); - chain = CLASS_CLS_METHODS (category); - - do - { - if ((meth = lookup_method (chain, ident))) - return meth; - - /* Check for class methods in protocols in categories. */ - if (CLASS_PROTOCOL_LIST (category)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (category), ident, 1)))) - return meth; - } - - if ((category = CLASS_CATEGORY_LIST (category))) - chain = CLASS_CLS_METHODS (category); - } - while (category); - } - - /* Check for class methods in protocols. */ - if (CLASS_PROTOCOL_LIST (inter)) - { - if ((meth = (lookup_method_in_protocol_list - (CLASS_PROTOCOL_LIST (inter), ident, 1)))) - return meth; - } - - root_inter = inter; - if ((inter = lookup_interface (CLASS_SUPER_NAME (inter)))) - chain = CLASS_CLS_METHODS (inter); - } - while (inter); - - /* Simulate wrap around. */ - return lookup_instance_method_static (root_inter, ident); -} - -tree -add_class_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_CLS_METHODS (class), method))) - { - /* put method on list in reverse order */ - TREE_CHAIN (method) = CLASS_CLS_METHODS (class); - CLASS_CLS_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* Check types; if different, complain. */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of class method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (cls_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* Install on a global chain. */ - hash_enter (cls_method_hash_list, method); - } - else - { - /* Check types; if different, add to a list. */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -tree -add_instance_method (class, method) - tree class; - tree method; -{ - tree mth; - hash hsh; - - /* We will have allocated the method parameter declarations on the - maybepermanent_obstack. Need to make sure they stick around! */ - preserve_data (); - - if (!(mth = lookup_method (CLASS_NST_METHODS (class), method))) - { - /* Put method on list in reverse order. */ - TREE_CHAIN (method) = CLASS_NST_METHODS (class); - CLASS_NST_METHODS (class) = method; - } - else - { - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - error ("duplicate definition of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - else - { - /* Check types; if different, complain. */ - if (!comp_proto_with_proto (method, mth)) - error ("duplicate declaration of instance method `%s'.", - IDENTIFIER_POINTER (METHOD_SEL_NAME (mth))); - } - } - - if (!(hsh = hash_lookup (nst_method_hash_list, METHOD_SEL_NAME (method)))) - { - /* Install on a global chain. */ - hash_enter (nst_method_hash_list, method); - } - else - { - /* Check types; if different, add to a list. */ - if (!comp_proto_with_proto (method, hsh->key)) - hash_add_attr (hsh, method); - } - return method; -} - -static tree -add_class (class) - tree class; -{ - /* Put interfaces on list in reverse order. */ - TREE_CHAIN (class) = interface_chain; - interface_chain = class; - return interface_chain; -} - -static void -add_category (class, category) - tree class; - tree category; -{ - /* Put categories on list in reverse order. */ - tree cat = CLASS_CATEGORY_LIST (class); - - while (cat) - { - if (CLASS_SUPER_NAME (cat) == CLASS_SUPER_NAME (category)) - warning ("duplicate interface declaration for category `%s(%s)'", - IDENTIFIER_POINTER (CLASS_NAME (class)), - IDENTIFIER_POINTER (CLASS_SUPER_NAME (category))); - cat = CLASS_CATEGORY_LIST (cat); - } - - CLASS_CATEGORY_LIST (category) = CLASS_CATEGORY_LIST (class); - CLASS_CATEGORY_LIST (class) = category; -} - -/* Called after parsing each instance variable declaration. Necessary to - preserve typedefs and implement public/private... - - PUBLIC is 1 for public, 0 for protected, and 2 for private. */ - -tree -add_instance_variable (class, public, declarator, declspecs, width) - tree class; - int public; - tree declarator; - tree declspecs; - tree width; -{ - tree field_decl, raw_decl; - - raw_decl = build_tree_list (declspecs, declarator); - - if (CLASS_RAW_IVARS (class)) - chainon (CLASS_RAW_IVARS (class), raw_decl); - else - CLASS_RAW_IVARS (class) = raw_decl; - - field_decl = grokfield (input_filename, lineno, - declarator, declspecs, width); - - /* Overload the public attribute, it is not used for FIELD_DECLs. */ - switch (public) - { - case 0: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 1; - break; - - case 1: - TREE_PUBLIC (field_decl) = 1; - TREE_PRIVATE (field_decl) = 0; - TREE_PROTECTED (field_decl) = 0; - break; - - case 2: - TREE_PUBLIC (field_decl) = 0; - TREE_PRIVATE (field_decl) = 1; - TREE_PROTECTED (field_decl) = 0; - break; - - } - - if (CLASS_IVARS (class)) - chainon (CLASS_IVARS (class), field_decl); - else - CLASS_IVARS (class) = field_decl; - - return class; -} - -tree -is_ivar (decl_chain, ident) - tree decl_chain; - tree ident; -{ - for ( ; decl_chain; decl_chain = TREE_CHAIN (decl_chain)) - if (DECL_NAME (decl_chain) == ident) - return decl_chain; - return NULL_TREE; -} - -/* True if the ivar is private and we are not in its implementation. */ - -int -is_private (decl) - tree decl; -{ - if (TREE_PRIVATE (decl) - && ! is_ivar (CLASS_IVARS (implementation_template), DECL_NAME (decl))) - { - error ("instance variable `%s' is declared private", - IDENTIFIER_POINTER (DECL_NAME (decl))); - return 1; - } - else - return 0; -} - -/* We have an instance variable reference;, check to see if it is public. */ - -int -is_public (expr, identifier) - tree expr; - tree identifier; -{ - tree basetype = TREE_TYPE (expr); - enum tree_code code = TREE_CODE (basetype); - tree decl; - - if (code == RECORD_TYPE) - { - if (TREE_STATIC_TEMPLATE (basetype)) - { - if (!lookup_interface (TYPE_NAME (basetype))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (TYPE_NAME (basetype))); - return 0; - } - - if ((decl = is_ivar (TYPE_FIELDS (basetype), identifier))) - { - if (TREE_PUBLIC (decl)) - return 1; - - /* Important difference between the Stepstone translator: - all instance variables should be public within the context - of the implementation. */ - if (implementation_context - && (((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - || (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE)) - && (CLASS_NAME (implementation_context) - == TYPE_NAME (basetype)))) - return ! is_private (decl); - - error ("instance variable `%s' is declared %s", - IDENTIFIER_POINTER (identifier), - TREE_PRIVATE (decl) ? "private" : "protected"); - return 0; - } - } - - else if (implementation_context && (basetype == objc_object_reference)) - { - TREE_TYPE (expr) = uprivate_record; - warning ("static access to object of type `id'"); - } - } - - return 1; -} - -/* Implement @defs (<classname>) within struct bodies. */ - -tree -get_class_ivars (interface) - tree interface; -{ - if (!doing_objc_thang) - objc_fatal (); - - return build_ivar_chain (interface, 1); -} - -/* Make sure all entries in CHAIN are also in LIST. */ - -static int -check_methods (chain, list, mtype) - tree chain; - tree list; - int mtype; -{ - int first = 1; - - while (chain) - { - if (!lookup_method (list, chain)) - { - if (first) - { - if (TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - - chain = TREE_CHAIN (chain); - } - - return first; -} - -static int -conforms_to_protocol (class, protocol) - tree class; - tree protocol; -{ - while (protocol) - { - tree p = CLASS_PROTOCOL_LIST (class); - - while (p && TREE_VALUE (p) != TREE_VALUE (protocol)) - p = TREE_CHAIN (p); - - if (!p) - { - tree super = (CLASS_SUPER_NAME (class) - ? lookup_interface (CLASS_SUPER_NAME (class)) - : NULL_TREE); - int tmp = super ? conforms_to_protocol (super, protocol) : 0; - if (!tmp) - return 0; - } - - protocol = TREE_CHAIN (protocol); - } - - return 1; -} - -/* Make sure all methods in CHAIN are accessible as MTYPE methods in - CONTEXT. This is one of two mechanisms to check protocol integrity. */ - -static int -check_methods_accessible (chain, context, mtype) - tree chain; - tree context; - int mtype; -{ - int first = 1; - tree list; - tree base_context = context; - - while (chain) - { - context = base_context; - while (context) - { - if (mtype == '+') - list = CLASS_CLS_METHODS (context); - else - list = CLASS_NST_METHODS (context); - - if (lookup_method (list, chain)) - break; - - else if (TREE_CODE (context) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CLASS_INTERFACE_TYPE) - context = (CLASS_SUPER_NAME (context) - ? lookup_interface (CLASS_SUPER_NAME (context)) - : NULL_TREE); - - else if (TREE_CODE (context) == CATEGORY_IMPLEMENTATION_TYPE - || TREE_CODE (context) == CATEGORY_INTERFACE_TYPE) - context = (CLASS_NAME (context) - ? lookup_interface (CLASS_NAME (context)) - : NULL_TREE); - else - abort (); - } - - if (context == NULL_TREE) - { - if (first) - { - if (TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of class `%s'", - IDENTIFIER_POINTER - (CLASS_NAME (implementation_context))); - else if (TREE_CODE (implementation_context) - == CATEGORY_IMPLEMENTATION_TYPE) - warning ("incomplete implementation of category `%s'", - IDENTIFIER_POINTER - (CLASS_SUPER_NAME (implementation_context))); - first = 0; - } - warning ("method definition for `%c%s' not found", - mtype, IDENTIFIER_POINTER (METHOD_SEL_NAME (chain))); - } - - chain = TREE_CHAIN (chain); /* next method... */ - } - return first; -} - -static void -check_protocols (proto_list, type, name) - tree proto_list; - char *type; - char *name; -{ - for ( ; proto_list; proto_list = TREE_CHAIN (proto_list)) - { - tree p = TREE_VALUE (proto_list); - - if (TREE_CODE (p) == PROTOCOL_INTERFACE_TYPE) - { - int f1, f2; - - /* Ensure that all protocols have bodies. */ - if (flag_warn_protocol) { - f1 = check_methods (PROTOCOL_CLS_METHODS (p), - CLASS_CLS_METHODS (implementation_context), - '+'); - f2 = check_methods (PROTOCOL_NST_METHODS (p), - CLASS_NST_METHODS (implementation_context), - '-'); - } else { - f1 = check_methods_accessible (PROTOCOL_CLS_METHODS (p), - implementation_context, - '+'); - f2 = check_methods_accessible (PROTOCOL_NST_METHODS (p), - implementation_context, - '-'); - } - - if (!f1 || !f2) - warning ("%s `%s' does not fully implement the `%s' protocol", - type, name, IDENTIFIER_POINTER (PROTOCOL_NAME (p))); - - } - else - { - ; /* An identifier if we could not find a protocol. */ - } - - /* Check protocols recursively. */ - if (PROTOCOL_LIST (p)) - { - tree super_class - = lookup_interface (CLASS_SUPER_NAME (implementation_template)); - if (! conforms_to_protocol (super_class, PROTOCOL_LIST (p))) - check_protocols (PROTOCOL_LIST (p), type, name); - } - } -} - -/* Make sure that the class CLASS_NAME is defined - CODE says which kind of thing CLASS_NAME ought to be. - It can be CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, or CATEGORY_IMPLEMENTATION_TYPE. - - If CODE is CLASS_INTERFACE_TYPE, we also do a push_obstacks_nochange - whose matching pop is in continue_class. */ - -tree -start_class (code, class_name, super_name, protocol_list) - enum tree_code code; - tree class_name; - tree super_name; - tree protocol_list; -{ - tree class, decl; - - if (code == CLASS_INTERFACE_TYPE) - { - push_obstacks_nochange (); - end_temporary_allocation (); - } - - if (!doing_objc_thang) - objc_fatal (); - - class = make_node (code); - TYPE_BINFO (class) = make_tree_vec (5); - - CLASS_NAME (class) = class_name; - CLASS_SUPER_NAME (class) = super_name; - CLASS_CLS_METHODS (class) = NULL_TREE; - - if (! is_class_name (class_name) && (decl = lookup_name (class_name))) - { - error ("`%s' redeclared as different kind of symbol", - IDENTIFIER_POINTER (class_name)); - error_with_decl (decl, "previous declaration of `%s'"); - } - - if (code == CLASS_IMPLEMENTATION_TYPE) - { - { - static tree implemented_classes = 0; - tree chain = implemented_classes; - for (chain = implemented_classes; chain; chain = TREE_CHAIN (chain)) - if (TREE_VALUE (chain) == class_name) - { - error ("reimplementation of class `%s'", - IDENTIFIER_POINTER (class_name)); - return error_mark_node; - } - implemented_classes = perm_tree_cons (NULL_TREE, class_name, - implemented_classes); - } - - /* Pre-build the following entities - for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - if (!unused_list) - unused_list - = build_tree_list (get_identifier ("__unused__"), NULL_TREE); - if (!objc_super_template) - objc_super_template = build_super_template (); - - /* Reset for multiple classes per file. */ - method_slot = 0; - - implementation_context = class; - - /* Lookup the interface for this implementation. */ - - if (!(implementation_template = lookup_interface (class_name))) - { - warning ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - add_class (implementation_template = implementation_context); - } - - /* If a super class has been specified in the implementation, - insure it conforms to the one specified in the interface. */ - - if (super_name - && (super_name != CLASS_SUPER_NAME (implementation_template))) - { - tree previous_name = CLASS_SUPER_NAME (implementation_template); - char *name = previous_name ? IDENTIFIER_POINTER (previous_name) : ""; - error ("conflicting super class name `%s'", - IDENTIFIER_POINTER (super_name)); - error ("previous declaration of `%s'", name); - } - - else if (! super_name) - { - CLASS_SUPER_NAME (implementation_context) - = CLASS_SUPER_NAME (implementation_template); - } - } - - else if (code == CLASS_INTERFACE_TYPE) - { - if (lookup_interface (class_name)) - warning ("duplicate interface declaration for class `%s'", - IDENTIFIER_POINTER (class_name)); - else - add_class (class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - - else if (code == CATEGORY_INTERFACE_TYPE) - { - tree class_category_is_assoc_with; - - /* For a category, class_name is really the name of the class that - the following set of methods will be associated with. We must - find the interface so that can derive the objects template. */ - - if (!(class_category_is_assoc_with = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (FATAL_EXIT_CODE); - } - else - add_category (class_category_is_assoc_with, class); - - if (protocol_list) - CLASS_PROTOCOL_LIST (class) - = lookup_and_install_protocols (protocol_list); - } - - else if (code == CATEGORY_IMPLEMENTATION_TYPE) - { - /* Pre-build the following entities for speed/convenience. */ - if (!self_id) - self_id = get_identifier ("self"); - if (!ucmd_id) - ucmd_id = get_identifier ("_cmd"); - if (!unused_list) - unused_list - = build_tree_list (get_identifier ("__unused__"), NULL_TREE); - if (!objc_super_template) - objc_super_template = build_super_template (); - - /* Reset for multiple classes per file. */ - method_slot = 0; - - implementation_context = class; - - /* For a category, class_name is really the name of the class that - the following set of methods will be associated with. We must - find the interface so that can derive the objects template. */ - - if (!(implementation_template = lookup_interface (class_name))) - { - error ("Cannot find interface declaration for `%s'", - IDENTIFIER_POINTER (class_name)); - exit (FATAL_EXIT_CODE); - } - } - return class; -} - -tree -continue_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE - || TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - struct imp_entry *imp_entry; - tree ivar_context; - - /* Check consistency of the instance variables. */ - - if (CLASS_IVARS (class)) - check_ivars (implementation_template, class); - - /* code generation */ - - ivar_context = build_private_template (implementation_template); - - if (!objc_class_template) - build_class_template (); - - if (!(imp_entry - = (struct imp_entry *) xmalloc (sizeof (struct imp_entry)))) - perror ("unable to allocate in objc-tree.c"); - - imp_entry->next = imp_list; - imp_entry->imp_context = class; - imp_entry->imp_template = implementation_template; - - synth_forward_declarations (); - imp_entry->class_decl = UOBJC_CLASS_decl; - imp_entry->meta_decl = UOBJC_METACLASS_decl; - - /* Append to front and increment count. */ - imp_list = imp_entry; - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - imp_count++; - else - cat_count++; - - return ivar_context; - } - - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree record = xref_tag (RECORD_TYPE, CLASS_NAME (class)); - - if (!TYPE_FIELDS (record)) - { - finish_struct (record, build_ivar_chain (class, 0), NULL_TREE); - CLASS_STATIC_TEMPLATE (class) = record; - - /* Mark this record as a class template for static typing. */ - TREE_STATIC_TEMPLATE (record) = 1; - } - - return NULL_TREE; - } - - else - return error_mark_node; -} - -/* This is called once we see the "@end" in an interface/implementation. */ - -void -finish_class (class) - tree class; -{ - if (TREE_CODE (class) == CLASS_IMPLEMENTATION_TYPE) - { - /* All code generation is done in finish_objc. */ - - if (implementation_template != implementation_context) - { - /* Ensure that all method listed in the interface contain bodies. */ - check_methods (CLASS_CLS_METHODS (implementation_template), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (implementation_template), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (implementation_template)) - check_protocols (CLASS_PROTOCOL_LIST (implementation_template), - "class", - IDENTIFIER_POINTER (CLASS_NAME (implementation_context))); - } - } - - else if (TREE_CODE (class) == CATEGORY_IMPLEMENTATION_TYPE) - { - tree category = CLASS_CATEGORY_LIST (implementation_template); - - /* Find the category interface from the class it is associated with. */ - while (category) - { - if (CLASS_SUPER_NAME (class) == CLASS_SUPER_NAME (category)) - break; - category = CLASS_CATEGORY_LIST (category); - } - - if (category) - { - /* Ensure all method listed in the interface contain bodies. */ - check_methods (CLASS_CLS_METHODS (category), - CLASS_CLS_METHODS (implementation_context), '+'); - check_methods (CLASS_NST_METHODS (category), - CLASS_NST_METHODS (implementation_context), '-'); - - if (CLASS_PROTOCOL_LIST (category)) - check_protocols (CLASS_PROTOCOL_LIST (category), - "category", - IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - } - } - - else if (TREE_CODE (class) == CLASS_INTERFACE_TYPE) - { - tree decl_specs; - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (class)); - char *string = (char *) alloca (strlen (class_name) + 3); - - /* extern struct objc_object *_<my_name>; */ - - sprintf (string, "_%s", class_name); - - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_EXTERN]); - decl_specs = tree_cons (NULL_TREE, objc_object_reference, decl_specs); - define_decl (build1 (INDIRECT_REF, NULL_TREE, get_identifier (string)), - decl_specs); - } -} - -static tree -add_protocol (protocol) - tree protocol; -{ - /* Put protocol on list in reverse order. */ - TREE_CHAIN (protocol) = protocol_chain; - protocol_chain = protocol; - return protocol_chain; -} - -static tree -lookup_protocol (ident) - tree ident; -{ - tree chain; - - for (chain = protocol_chain; chain; chain = TREE_CHAIN (chain)) - { - if (ident == PROTOCOL_NAME (chain)) - return chain; - } - - return NULL_TREE; -} - -tree -start_protocol (code, name, list) - enum tree_code code; - tree name; - tree list; -{ - tree protocol; - - if (!doing_objc_thang) - objc_fatal (); - - /* This is as good a place as any. Need to invoke push_tag_toplevel. */ - if (!objc_protocol_template) - objc_protocol_template = build_protocol_template (); - - protocol = make_node (code); - TYPE_BINFO (protocol) = make_tree_vec (2); - - PROTOCOL_NAME (protocol) = name; - PROTOCOL_LIST (protocol) = list; - - lookup_and_install_protocols (list); - - if (lookup_protocol (name)) - warning ("duplicate declaration for protocol `%s'", - IDENTIFIER_POINTER (name)); - else - add_protocol (protocol); - - PROTOCOL_FORWARD_DECL (protocol) = NULL_TREE; - - return protocol; -} - -void -finish_protocol (protocol) - tree protocol ATTRIBUTE_UNUSED; -{ -} - - -/* "Encode" a data type into a string, which grows in util_obstack. - ??? What is the FORMAT? Someone please document this! */ - -static void -encode_type_qualifiers (declspecs) - tree declspecs; -{ - tree spec; - - for (spec = declspecs; spec; spec = TREE_CHAIN (spec)) - { - if (ridpointers[(int) RID_CONST] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'r'); - else if (ridpointers[(int) RID_IN] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'n'); - else if (ridpointers[(int) RID_INOUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'N'); - else if (ridpointers[(int) RID_OUT] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'o'); - else if (ridpointers[(int) RID_BYCOPY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'O'); - else if (ridpointers[(int) RID_BYREF] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'R'); - else if (ridpointers[(int) RID_ONEWAY] == TREE_VALUE (spec)) - obstack_1grow (&util_obstack, 'V'); - } -} - -/* Encode a pointer type. */ - -static void -encode_pointer (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree pointer_to = TREE_TYPE (type); - - if (TREE_CODE (pointer_to) == RECORD_TYPE) - { - if (TYPE_NAME (pointer_to) - && TREE_CODE (TYPE_NAME (pointer_to)) == IDENTIFIER_NODE) - { - char *name = IDENTIFIER_POINTER (TYPE_NAME (pointer_to)); - - if (strcmp (name, TAG_OBJECT) == 0) /* '@' */ - { - obstack_1grow (&util_obstack, '@'); - return; - } - else if (TREE_STATIC_TEMPLATE (pointer_to)) - { - if (generating_instance_variables) - { - obstack_1grow (&util_obstack, '@'); - obstack_1grow (&util_obstack, '"'); - obstack_grow (&util_obstack, name, strlen (name)); - obstack_1grow (&util_obstack, '"'); - return; - } - else - { - obstack_1grow (&util_obstack, '@'); - return; - } - } - else if (strcmp (name, TAG_CLASS) == 0) /* '#' */ - { - obstack_1grow (&util_obstack, '#'); - return; - } -#ifndef OBJC_INT_SELECTORS - else if (strcmp (name, TAG_SELECTOR) == 0) /* ':' */ - { - obstack_1grow (&util_obstack, ':'); - return; - } -#endif /* OBJC_INT_SELECTORS */ - } - } - else if (TREE_CODE (pointer_to) == INTEGER_TYPE - && TYPE_MODE (pointer_to) == QImode) - { - obstack_1grow (&util_obstack, '*'); - return; - } - - /* We have a type that does not get special treatment. */ - - /* NeXT extension */ - obstack_1grow (&util_obstack, '^'); - encode_type (pointer_to, curtype, format); -} - -static void -encode_array (type, curtype, format) - tree type; - int curtype; - int format; -{ - tree an_int_cst = TYPE_SIZE (type); - tree array_of = TREE_TYPE (type); - char buffer[40]; - - /* An incomplete array is treated like a pointer. */ - if (an_int_cst == NULL) - { - encode_pointer (type, curtype, format); - return; - } - - sprintf (buffer, "[%ld", - (long) (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - - obstack_grow (&util_obstack, buffer, strlen (buffer)); - encode_type (array_of, curtype, format); - obstack_1grow (&util_obstack, ']'); - return; -} - -static void -encode_aggregate_within (type, curtype, format, left, right) - tree type; - int curtype; - int format; - int left; - int right; -{ - if (obstack_object_size (&util_obstack) > 0 - && *(obstack_next_free (&util_obstack) - 1) == '^') - { - tree name = TYPE_NAME (type); - - /* we have a reference; this is a NeXT extension. */ - - if (obstack_object_size (&util_obstack) - curtype == 1 - && format == OBJC_ENCODE_INLINE_DEFS) - { - /* Output format of struct for first level only. */ - tree fields = TYPE_FIELDS (type); - - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, '='); - } - else - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, "?=", 2); - } - - for ( ; fields; fields = TREE_CHAIN (fields)) - encode_field_decl (fields, curtype, format); - - obstack_1grow (&util_obstack, right); - } - - else if (name && TREE_CODE (name) == IDENTIFIER_NODE) - { - obstack_1grow (&util_obstack, left); - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - obstack_1grow (&util_obstack, right); - } - - else - { - /* We have an untagged structure or a typedef. */ - obstack_1grow (&util_obstack, left); - obstack_1grow (&util_obstack, '?'); - obstack_1grow (&util_obstack, right); - } - } - - else - { - tree name = TYPE_NAME (type); - tree fields = TYPE_FIELDS (type); - - if (format == OBJC_ENCODE_INLINE_DEFS - || generating_instance_variables) - { - obstack_1grow (&util_obstack, left); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else - obstack_1grow (&util_obstack, '?'); - - obstack_1grow (&util_obstack, '='); - - for (; fields; fields = TREE_CHAIN (fields)) - { - if (generating_instance_variables) - { - tree fname = DECL_NAME (fields); - - obstack_1grow (&util_obstack, '"'); - if (fname && TREE_CODE (fname) == IDENTIFIER_NODE) - { - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (fname), - strlen (IDENTIFIER_POINTER (fname))); - } - - obstack_1grow (&util_obstack, '"'); - } - - encode_field_decl (fields, curtype, format); - } - - obstack_1grow (&util_obstack, right); - } - - else - { - obstack_1grow (&util_obstack, left); - if (name && TREE_CODE (name) == IDENTIFIER_NODE) - obstack_grow (&util_obstack, - IDENTIFIER_POINTER (name), - strlen (IDENTIFIER_POINTER (name))); - else - /* We have an untagged structure or a typedef. */ - obstack_1grow (&util_obstack, '?'); - - obstack_1grow (&util_obstack, right); - } - } -} - -static void -encode_aggregate (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - switch (code) - { - case RECORD_TYPE: - { - encode_aggregate_within(type, curtype, format, '{', '}'); - break; - } - case UNION_TYPE: - { - encode_aggregate_within(type, curtype, format, '(', ')'); - break; - } - - case ENUMERAL_TYPE: - obstack_1grow (&util_obstack, 'i'); - break; - - default: - break; - } -} - -/* Support bitfields. The current version of Objective-C does not support - them. The string will consist of one or more "b:n"'s where n is an - integer describing the width of the bitfield. Currently, classes in - the kit implement a method "-(char *)describeBitfieldStruct:" that - simulates this. If they do not implement this method, the archiver - assumes the bitfield is 16 bits wide (padded if necessary) and packed - according to the GNU compiler. After looking at the "kit", it appears - that all classes currently rely on this default behavior, rather than - hand generating this string (which is tedious). */ - -static void -encode_bitfield (width, format) - int width; - int format; -{ - char buffer[40]; - sprintf (buffer, "b%d", width); - obstack_grow (&util_obstack, buffer, strlen (buffer)); -} - -/* FORMAT will be OBJC_ENCODE_INLINE_DEFS or OBJC_ENCODE_DONT_INLINE_DEFS. */ - -static void -encode_type (type, curtype, format) - tree type; - int curtype; - int format; -{ - enum tree_code code = TREE_CODE (type); - - if (code == INTEGER_TYPE) - { - if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0 - && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0) - { - /* Unsigned integer types. */ - - if (TYPE_MODE (type) == QImode) - obstack_1grow (&util_obstack, 'C'); - else if (TYPE_MODE (type) == HImode) - obstack_1grow (&util_obstack, 'S'); - else if (TYPE_MODE (type) == SImode) - { - if (type == long_unsigned_type_node) - obstack_1grow (&util_obstack, 'L'); - else - obstack_1grow (&util_obstack, 'I'); - } - else if (TYPE_MODE (type) == DImode) - obstack_1grow (&util_obstack, 'Q'); - } - - else - /* Signed integer types. */ - { - if (TYPE_MODE (type) == QImode) - obstack_1grow (&util_obstack, 'c'); - else if (TYPE_MODE (type) == HImode) - obstack_1grow (&util_obstack, 's'); - else if (TYPE_MODE (type) == SImode) - { - if (type == long_integer_type_node) - obstack_1grow (&util_obstack, 'l'); - else - obstack_1grow (&util_obstack, 'i'); - } - - else if (TYPE_MODE (type) == DImode) - obstack_1grow (&util_obstack, 'q'); - } - } - - else if (code == REAL_TYPE) - { - /* Floating point types. */ - - if (TYPE_MODE (type) == SFmode) - obstack_1grow (&util_obstack, 'f'); - else if (TYPE_MODE (type) == DFmode - || TYPE_MODE (type) == TFmode) - obstack_1grow (&util_obstack, 'd'); - } - - else if (code == VOID_TYPE) - obstack_1grow (&util_obstack, 'v'); - - else if (code == ARRAY_TYPE) - encode_array (type, curtype, format); - - else if (code == POINTER_TYPE) - encode_pointer (type, curtype, format); - - else if (code == RECORD_TYPE || code == UNION_TYPE || code == ENUMERAL_TYPE) - encode_aggregate (type, curtype, format); - - else if (code == FUNCTION_TYPE) /* '?' */ - obstack_1grow (&util_obstack, '?'); -} - -static void -encode_complete_bitfield (int position, tree type, int size) -{ - enum tree_code code = TREE_CODE (type); - char buffer[40]; - char charType = '?'; - - if (code == INTEGER_TYPE) - { - if (TREE_INT_CST_LOW (TYPE_MIN_VALUE (type)) == 0 - && TREE_INT_CST_HIGH (TYPE_MIN_VALUE (type)) == 0) - { - /* Unsigned integer types. */ - - if (TYPE_MODE (type) == QImode) - charType = 'C'; - else if (TYPE_MODE (type) == HImode) - charType = 'S'; - else if (TYPE_MODE (type) == SImode) - { - if (type == long_unsigned_type_node) - charType = 'L'; - else - charType = 'I'; - } - else if (TYPE_MODE (type) == DImode) - charType = 'Q'; - } - - else - /* Signed integer types. */ - { - if (TYPE_MODE (type) == QImode) - charType = 'c'; - else if (TYPE_MODE (type) == HImode) - charType = 's'; - else if (TYPE_MODE (type) == SImode) - { - if (type == long_integer_type_node) - charType = 'l'; - else - charType = 'i'; - } - - else if (TYPE_MODE (type) == DImode) - charType = 'q'; - } - } - - else - abort (); - - sprintf (buffer, "b%d%c%d", position, charType, size); - obstack_grow (&util_obstack, buffer, strlen (buffer)); -} - -static void -encode_field_decl (field_decl, curtype, format) - tree field_decl; - int curtype; - int format; -{ - tree type; - - type = TREE_TYPE (field_decl); - - /* If this field is obviously a bitfield, or is a bitfield that has been - clobbered to look like a ordinary integer mode, go ahead and generate - the bitfield typing information. */ - if (flag_next_runtime) - { - if (DECL_BIT_FIELD (field_decl)) - encode_bitfield (DECL_FIELD_SIZE (field_decl), format); - else if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && DECL_FIELD_SIZE (field_decl) - && TYPE_MODE (type) > DECL_MODE (field_decl)) - encode_bitfield (DECL_FIELD_SIZE (field_decl), format); - else - encode_type (TREE_TYPE (field_decl), curtype, format); - } - else - { - if (DECL_BIT_FIELD (field_decl) - || (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST - && DECL_FIELD_SIZE (field_decl) - && TYPE_MODE (type) > DECL_MODE (field_decl))) - { - encode_complete_bitfield (TREE_INT_CST_LOW (DECL_FIELD_BITPOS (field_decl)), - DECL_BIT_FIELD_TYPE (field_decl), - DECL_FIELD_SIZE (field_decl)); - } - else - encode_type (TREE_TYPE (field_decl), curtype, format); - } -} - -static tree -expr_last (complex_expr) - tree complex_expr; -{ - tree next; - - if (complex_expr) - while ((next = TREE_OPERAND (complex_expr, 0))) - complex_expr = next; - - return complex_expr; -} - -/* The selector of the current method, - or NULL if we aren't compiling a method. */ - -tree -maybe_objc_method_name (decl) - tree decl; -{ - if (method_context) - return METHOD_SEL_NAME (method_context); - else - return 0; -} - -/* Transform a method definition into a function definition as follows: - - synthesize the first two arguments, "self" and "_cmd". */ - -void -start_method_def (method) - tree method; -{ - tree decl_specs; - - /* Required to implement _msgSuper. */ - method_context = method; - UOBJC_SUPER_decl = NULL_TREE; - - /* Must be called BEFORE start_function. */ - pushlevel (0); - - /* Generate prototype declarations for arguments..."new-style". */ - - if (TREE_CODE (method_context) == INSTANCE_METHOD_DECL) - decl_specs = build_tree_list (NULL_TREE, uprivate_record); - else - /* Really a `struct objc_class *'. However, we allow people to - assign to self, which changes its type midstream. */ - decl_specs = build_tree_list (NULL_TREE, objc_object_reference); - - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, self_id)), - build_tree_list (unused_list, NULL_TREE))); - -#ifdef OBJC_INT_SELECTORS - decl_specs = build_tree_list (NULL_TREE, ridpointers[(int) RID_UNSIGNED]); - decl_specs = tree_cons (NULL_TREE, ridpointers[(int) RID_INT], decl_specs); - push_parm_decl (build_tree_list (build_tree_list (decl_specs, ucmd_id), - build_tree_list (unused_list, NULL_TREE))); -#else /* not OBJC_INT_SELECTORS */ - decl_specs = build_tree_list (NULL_TREE, - xref_tag (RECORD_TYPE, - get_identifier (TAG_SELECTOR))); - push_parm_decl (build_tree_list - (build_tree_list (decl_specs, - build1 (INDIRECT_REF, NULL_TREE, ucmd_id)), - build_tree_list (unused_list, NULL_TREE))); -#endif /* not OBJC_INT_SELECTORS */ - - /* Generate argument declarations if a keyword_decl. */ - if (METHOD_SEL_ARGS (method)) - { - tree arglist = METHOD_SEL_ARGS (method); - do - { - tree arg_spec = TREE_PURPOSE (TREE_TYPE (arglist)); - tree arg_decl = TREE_VALUE (TREE_TYPE (arglist)); - - if (arg_decl) - { - tree last_expr = expr_last (arg_decl); - - /* Unite the abstract decl with its name. */ - TREE_OPERAND (last_expr, 0) = KEYWORD_ARG_NAME (arglist); - push_parm_decl (build_tree_list - (build_tree_list (arg_spec, arg_decl), - build_tree_list (NULL_TREE, NULL_TREE))); - - /* Unhook: restore the abstract declarator. */ - TREE_OPERAND (last_expr, 0) = NULL_TREE; - } - - else - push_parm_decl (build_tree_list - (build_tree_list (arg_spec, - KEYWORD_ARG_NAME (arglist)), - build_tree_list (NULL_TREE, NULL_TREE))); - - arglist = TREE_CHAIN (arglist); - } - while (arglist); - } - - if (METHOD_ADD_ARGS (method) > (tree)1) - { - /* We have a variable length selector - in "prototype" format. */ - tree akey = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - while (akey) - { - /* This must be done prior to calling pushdecl. pushdecl is - going to change our chain on us. */ - tree nextkey = TREE_CHAIN (akey); - pushdecl (akey); - akey = nextkey; - } - } -} - -static void -warn_with_method (message, mtype, method) - char *message; - int mtype; - tree method; -{ - if (count_error (1) == 0) - return; - - report_error_function (DECL_SOURCE_FILE (method)); - - fprintf (stderr, "%s:%d: warning: ", - DECL_SOURCE_FILE (method), DECL_SOURCE_LINE (method)); - bzero (errbuf, BUFSIZE); - fprintf (stderr, "%s `%c%s'\n", - message, mtype, gen_method_decl (method, errbuf)); -} - -/* Return 1 if METHOD is consistent with PROTO. */ - -static int -comp_method_with_proto (method, proto) - tree method, proto; -{ - static tree function_type = 0; - - /* Create a function_type node once. */ - if (!function_type) - { - push_obstacks_nochange (); - end_temporary_allocation (); - function_type = make_node (FUNCTION_TYPE); - pop_obstacks (); - } - - /* Install argument types - normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type) = get_arg_type_list (proto, METHOD_DEF, 0); - - /* install return type */ - TREE_TYPE (function_type) = groktypename (TREE_TYPE (proto)); - - return comptypes (TREE_TYPE (METHOD_DEFINITION (method)), function_type); -} - -/* Return 1 if PROTO1 is consistent with PROTO2. */ - -static int -comp_proto_with_proto (proto1, proto2) - tree proto1, proto2; -{ - static tree function_type1 = 0, function_type2 = 0; - - /* Create a couple function_type node's once. */ - if (!function_type1) - { - push_obstacks_nochange (); - end_temporary_allocation (); - function_type1 = make_node (FUNCTION_TYPE); - function_type2 = make_node (FUNCTION_TYPE); - pop_obstacks (); - } - - /* Install argument types; normally set by build_function_type. */ - TYPE_ARG_TYPES (function_type1) = get_arg_type_list (proto1, METHOD_REF, 0); - TYPE_ARG_TYPES (function_type2) = get_arg_type_list (proto2, METHOD_REF, 0); - - /* Install return type. */ - TREE_TYPE (function_type1) = groktypename (TREE_TYPE (proto1)); - TREE_TYPE (function_type2) = groktypename (TREE_TYPE (proto2)); - - return comptypes (function_type1, function_type2); -} - -/* - Generate an identifier for the function. the format is "_n_cls", - where 1 <= n <= nMethods, and cls is the name the implementation we - are processing. - - Install the return type from the method declaration. - - If we have a prototype, check for type consistency. */ - -static void -really_start_method (method, parmlist) - tree method, parmlist; -{ - tree sc_spec, ret_spec, ret_decl, decl_specs; - tree method_decl, method_id; - char *buf, *sel_name, *class_name, *cat_name; - - /* Synth the storage class & assemble the return type. */ - sc_spec = tree_cons (NULL_TREE, ridpointers[(int) RID_STATIC], NULL_TREE); - ret_spec = TREE_PURPOSE (TREE_TYPE (method)); - decl_specs = chainon (sc_spec, ret_spec); - - sel_name = IDENTIFIER_POINTER (METHOD_SEL_NAME (method)); - class_name = IDENTIFIER_POINTER (CLASS_NAME (implementation_context)); - cat_name = ((TREE_CODE (implementation_context) - == CLASS_IMPLEMENTATION_TYPE) - ? NULL - : IDENTIFIER_POINTER (CLASS_SUPER_NAME (implementation_context))); - method_slot++; - - /* Make sure this is big enough for any plausible method label. */ - buf = (char *) alloca (50 + strlen (sel_name) + strlen (class_name) - + (cat_name ? strlen (cat_name) : 0)); - - OBJC_GEN_METHOD_LABEL (buf, TREE_CODE (method) == INSTANCE_METHOD_DECL, - class_name, cat_name, sel_name, method_slot); - - method_id = get_identifier (buf); - - method_decl = build_nt (CALL_EXPR, method_id, parmlist, NULL_TREE); - - /* Check the declarator portion of the return type for the method. */ - if ((ret_decl = TREE_VALUE (TREE_TYPE (method)))) - { - /* Unite the complex decl (specified in the abstract decl) with the - function decl just synthesized..(int *), (int (*)()), (int (*)[]). */ - tree save_expr = expr_last (ret_decl); - - TREE_OPERAND (save_expr, 0) = method_decl; - method_decl = ret_decl; - - /* Fool the parser into thinking it is starting a function. */ - start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0); - - /* Unhook: this has the effect of restoring the abstract declarator. */ - TREE_OPERAND (save_expr, 0) = NULL_TREE; - } - - else - { - TREE_VALUE (TREE_TYPE (method)) = method_decl; - - /* Fool the parser into thinking it is starting a function. */ - start_function (decl_specs, method_decl, NULL_TREE, NULL_TREE, 0); - - /* Unhook: this has the effect of restoring the abstract declarator. */ - TREE_VALUE (TREE_TYPE (method)) = NULL_TREE; - } - - METHOD_DEFINITION (method) = current_function_decl; - - if (implementation_template != implementation_context) - { - tree proto; - - if (TREE_CODE (method) == INSTANCE_METHOD_DECL) - proto = lookup_instance_method_static (implementation_template, - METHOD_SEL_NAME (method)); - else - proto = lookup_class_method_static (implementation_template, - METHOD_SEL_NAME (method)); - - if (proto && ! comp_method_with_proto (method, proto)) - { - char type = (TREE_CODE (method) == INSTANCE_METHOD_DECL ? '-' : '+'); - - warn_with_method ("conflicting types for", type, method); - warn_with_method ("previous declaration of", type, proto); - } - } -} - -/* The following routine is always called...this "architecture" is to - accommodate "old-style" variable length selectors. - - - a:a b:b // prototype ; id c; id d; // old-style. */ - -void -continue_method_def () -{ - tree parmlist; - - if (METHOD_ADD_ARGS (method_context) == (tree)1) - /* We have a `, ...' immediately following the selector. */ - parmlist = get_parm_info (0); - else - parmlist = get_parm_info (1); /* place a `void_at_end' */ - - /* Set self_decl from the first argument...this global is used by - build_ivar_reference calling build_indirect_ref. */ - self_decl = TREE_PURPOSE (parmlist); - - poplevel (0, 0, 0); - really_start_method (method_context, parmlist); - store_parm_decls (); -} - -/* Called by the parser, from the `pushlevel' production. */ - -void -add_objc_decls () -{ - if (!UOBJC_SUPER_decl) - { - UOBJC_SUPER_decl = start_decl (get_identifier (UTAG_SUPER), - build_tree_list (NULL_TREE, - objc_super_template), - 0, NULL_TREE, NULL_TREE); - - finish_decl (UOBJC_SUPER_decl, NULL_TREE, NULL_TREE); - - /* This prevents `unused variable' warnings when compiling with -Wall. */ - TREE_USED (UOBJC_SUPER_decl) = 1; - DECL_ARTIFICIAL (UOBJC_SUPER_decl) = 1; - } -} - -/* _n_Method (id self, SEL sel, ...) - { - struct objc_super _S; - _msgSuper ((_S.self = self, _S.class = _cls, &_S), ...); - } */ - -tree -get_super_receiver () -{ - if (method_context) - { - tree super_expr, super_expr_list; - - /* Set receiver to self. */ - super_expr = build_component_ref (UOBJC_SUPER_decl, self_id); - super_expr = build_modify_expr (super_expr, NOP_EXPR, self_decl); - super_expr_list = build_tree_list (NULL_TREE, super_expr); - - /* Set class to begin searching. */ - super_expr = build_component_ref (UOBJC_SUPER_decl, - get_identifier ("class")); - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* [_cls, __cls]Super are "pre-built" in - synth_forward_declarations. */ - - super_expr = build_modify_expr (super_expr, NOP_EXPR, - ((TREE_CODE (method_context) - == INSTANCE_METHOD_DECL) - ? ucls_super_ref - : uucls_super_ref)); - } - - else - /* We have a category. */ - { - tree super_name = CLASS_SUPER_NAME (implementation_template); - tree super_class; - - if (!super_name) - { - error ("no super class declared in interface for `%s'", - IDENTIFIER_POINTER (CLASS_NAME (implementation_template))); - return error_mark_node; - } - - if (flag_next_runtime) - { - super_class = get_class_reference (super_name); - if (TREE_CODE (method_context) == CLASS_METHOD_DECL) - super_class - = build_component_ref (build_indirect_ref (super_class, "->"), - get_identifier ("isa")); - } - else - { - add_class_reference (super_name); - super_class = (TREE_CODE (method_context) == INSTANCE_METHOD_DECL - ? objc_get_class_decl : objc_get_meta_class_decl); - assemble_external (super_class); - super_class - = build_function_call - (super_class, - build_tree_list - (NULL_TREE, - my_build_string (IDENTIFIER_LENGTH (super_name) + 1, - IDENTIFIER_POINTER (super_name)))); - } - - TREE_TYPE (super_class) = TREE_TYPE (ucls_super_ref); - super_expr = build_modify_expr (super_expr, NOP_EXPR, super_class); - } - - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - super_expr = build_unary_op (ADDR_EXPR, UOBJC_SUPER_decl, 0); - chainon (super_expr_list, build_tree_list (NULL_TREE, super_expr)); - - return build_compound_expr (super_expr_list); - } - else - { - error ("[super ...] must appear in a method context"); - return error_mark_node; - } -} - -static tree -encode_method_def (func_decl) - tree func_decl; -{ - tree parms; - int stack_size; - int max_parm_end = 0; - char buffer[40]; - tree result; - - /* Return type. */ - encode_type (TREE_TYPE (TREE_TYPE (func_decl)), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Stack size. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - int parm_end = (forwarding_offset (parms) - + (TREE_INT_CST_LOW (TYPE_SIZE (TREE_TYPE (parms))) - / BITS_PER_UNIT)); - - if (!offset_is_register && parm_end > max_parm_end) - max_parm_end = parm_end; - } - - stack_size = max_parm_end - OBJC_FORWARDING_MIN_OFFSET; - - sprintf (buffer, "%d", stack_size); - obstack_grow (&util_obstack, buffer, strlen (buffer)); - - /* Argument types. */ - for (parms = DECL_ARGUMENTS (func_decl); parms; - parms = TREE_CHAIN (parms)) - { - /* Type. */ - encode_type (TREE_TYPE (parms), - obstack_object_size (&util_obstack), - OBJC_ENCODE_INLINE_DEFS); - - /* Compute offset. */ - sprintf (buffer, "%d", forwarding_offset (parms)); - - /* Indicate register. */ - if (offset_is_register) - obstack_1grow (&util_obstack, '+'); - - obstack_grow (&util_obstack, buffer, strlen (buffer)); - } - - obstack_1grow (&util_obstack, 0); - result = get_identifier (obstack_finish (&util_obstack)); - obstack_free (&util_obstack, util_firstobj); - return result; -} - -void -finish_method_def () -{ - METHOD_ENCODING (method_context) = encode_method_def (current_function_decl); - - finish_function (0); - - /* Required to implement _msgSuper. This must be done AFTER finish_function, - since the optimizer may find "may be used before set" errors. */ - method_context = NULL_TREE; -} - -#if 0 -int -lang_report_error_function (decl) - tree decl; -{ - if (method_context) - { - fprintf (stderr, "In method `%s'\n", - IDENTIFIER_POINTER (METHOD_SEL_NAME (method_context))); - return 1; - } - - else - return 0; -} -#endif - -static int -is_complex_decl (type) - tree type; -{ - return (TREE_CODE (type) == ARRAY_TYPE - || TREE_CODE (type) == FUNCTION_TYPE - || (TREE_CODE (type) == POINTER_TYPE && ! IS_ID (type))); -} - - -/* Code to convert a decl node into text for a declaration in C. */ - -static char tmpbuf[256]; - -static void -adorn_decl (decl, str) - tree decl; - char *str; -{ - enum tree_code code = TREE_CODE (decl); - - if (code == ARRAY_REF) - { - tree an_int_cst = TREE_OPERAND (decl, 1); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_CST) - sprintf (str + strlen (str), "[%ld]", - (long) TREE_INT_CST_LOW (an_int_cst)); - else - strcat (str, "[]"); - } - - else if (code == ARRAY_TYPE) - { - tree an_int_cst = TYPE_SIZE (decl); - tree array_of = TREE_TYPE (decl); - - if (an_int_cst && TREE_CODE (an_int_cst) == INTEGER_TYPE) - sprintf (str + strlen (str), "[%ld]", - (long) (TREE_INT_CST_LOW (an_int_cst) - / TREE_INT_CST_LOW (TYPE_SIZE (array_of)))); - else - strcat (str, "[]"); - } - - else if (code == CALL_EXPR) - { - tree chain = TREE_PURPOSE (TREE_OPERAND (decl, 1)); - - strcat (str, "("); - while (chain) - { - gen_declaration (chain, str); - chain = TREE_CHAIN (chain); - if (chain) - strcat (str, ", "); - } - strcat (str, ")"); - } - - else if (code == FUNCTION_TYPE) - { - tree chain = TYPE_ARG_TYPES (decl); - - strcat (str, "("); - while (chain && TREE_VALUE (chain) != void_type_node) - { - gen_declaration (TREE_VALUE (chain), str); - chain = TREE_CHAIN (chain); - if (chain && TREE_VALUE (chain) != void_type_node) - strcat (str, ", "); - } - strcat (str, ")"); - } - - else if (code == INDIRECT_REF) - { - strcpy (tmpbuf, "*"); - if (TREE_TYPE (decl) && TREE_CODE (TREE_TYPE (decl)) == TREE_LIST) - { - tree chain; - - for (chain = nreverse (copy_list (TREE_TYPE (decl))); - chain; - chain = TREE_CHAIN (chain)) - { - if (TREE_CODE (TREE_VALUE (chain)) == IDENTIFIER_NODE) - { - strcat (tmpbuf, " "); - strcat (tmpbuf, IDENTIFIER_POINTER (TREE_VALUE (chain))); - } - } - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } - - else if (code == POINTER_TYPE) - { - strcpy (tmpbuf, "*"); - if (TREE_READONLY (decl) || TYPE_VOLATILE (decl)) - { - if (TREE_READONLY (decl)) - strcat (tmpbuf, " const"); - if (TYPE_VOLATILE (decl)) - strcat (tmpbuf, " volatile"); - if (str[0]) - strcat (tmpbuf, " "); - } - strcat (tmpbuf, str); - strcpy (str, tmpbuf); - } -} - -static char * -gen_declarator (decl, buf, name) - tree decl; - char *buf; - char *name; -{ - if (decl) - { - enum tree_code code = TREE_CODE (decl); - char *str; - tree op; - int wrap = 0; - - switch (code) - { - case ARRAY_REF: - case INDIRECT_REF: - case CALL_EXPR: - op = TREE_OPERAND (decl, 0); - - /* We have a pointer to a function or array...(*)(), (*)[] */ - if ((code == ARRAY_REF || code == CALL_EXPR) - && op && TREE_CODE (op) == INDIRECT_REF) - wrap = 1; - - str = gen_declarator (op, buf, name); - - if (wrap) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - adorn_decl (decl, str); - break; - - case ARRAY_TYPE: - case FUNCTION_TYPE: - case POINTER_TYPE: - strcpy (buf, name); - str = buf; - - /* This clause is done iteratively rather than recursively. */ - do - { - op = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULL_TREE); - - adorn_decl (decl, str); - - /* We have a pointer to a function or array...(*)(), (*)[] */ - if (code == POINTER_TYPE - && op && (TREE_CODE (op) == FUNCTION_TYPE - || TREE_CODE (op) == ARRAY_TYPE)) - { - strcpy (tmpbuf, "("); - strcat (tmpbuf, str); - strcat (tmpbuf, ")"); - strcpy (str, tmpbuf); - } - - decl = (is_complex_decl (TREE_TYPE (decl)) - ? TREE_TYPE (decl) : NULL_TREE); - } - - while (decl && (code = TREE_CODE (decl))) - ; - - break; - - case IDENTIFIER_NODE: - /* Will only happen if we are processing a "raw" expr-decl. */ - strcpy (buf, IDENTIFIER_POINTER (decl)); - return buf; - - default: - break; - } - - return str; - } - - else - /* We have an abstract declarator or a _DECL node. */ - { - strcpy (buf, name); - return buf; - } -} - -static void -gen_declspecs (declspecs, buf, raw) - tree declspecs; - char *buf; - int raw; -{ - if (raw) - { - tree chain; - - for (chain = nreverse (copy_list (declspecs)); - chain; chain = TREE_CHAIN (chain)) - { - tree aspec = TREE_VALUE (chain); - - if (TREE_CODE (aspec) == IDENTIFIER_NODE) - strcat (buf, IDENTIFIER_POINTER (aspec)); - else if (TREE_CODE (aspec) == RECORD_TYPE) - { - if (TYPE_NAME (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - - /* NEW!!! */ - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - - else - strcat (buf, "untagged struct"); - } - - else if (TREE_CODE (aspec) == UNION_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged union"); - } - - else if (TREE_CODE (aspec) == ENUMERAL_TYPE) - { - if (TYPE_NAME (aspec)) - { - if (! TREE_STATIC_TEMPLATE (aspec)) - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (aspec))); - } - else - strcat (buf, "untagged enum"); - } - - else if (TREE_CODE (aspec) == TYPE_DECL && DECL_NAME (aspec)) - strcat (buf, IDENTIFIER_POINTER (DECL_NAME (aspec))); - - else if (IS_ID (aspec)) - { - tree protocol_list = TYPE_PROTOCOL_LIST (aspec); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - if (TREE_CHAIN (chain)) - strcat (buf, " "); - } - } - else - { - /* Type qualifiers. */ - if (TREE_READONLY (declspecs)) - strcat (buf, "const "); - if (TYPE_VOLATILE (declspecs)) - strcat (buf, "volatile "); - - switch (TREE_CODE (declspecs)) - { - /* Type specifiers. */ - - case INTEGER_TYPE: - declspecs = TYPE_MAIN_VARIANT (declspecs); - - /* Signed integer types. */ - - if (declspecs == short_integer_type_node) - strcat (buf, "short int "); - else if (declspecs == integer_type_node) - strcat (buf, "int "); - else if (declspecs == long_integer_type_node) - strcat (buf, "long int "); - else if (declspecs == long_long_integer_type_node) - strcat (buf, "long long int "); - else if (declspecs == signed_char_type_node - || declspecs == char_type_node) - strcat (buf, "char "); - - /* Unsigned integer types. */ - - else if (declspecs == short_unsigned_type_node) - strcat (buf, "unsigned short "); - else if (declspecs == unsigned_type_node) - strcat (buf, "unsigned int "); - else if (declspecs == long_unsigned_type_node) - strcat (buf, "unsigned long "); - else if (declspecs == long_long_unsigned_type_node) - strcat (buf, "unsigned long long "); - else if (declspecs == unsigned_char_type_node) - strcat (buf, "unsigned char "); - break; - - case REAL_TYPE: - declspecs = TYPE_MAIN_VARIANT (declspecs); - - if (declspecs == float_type_node) - strcat (buf, "float "); - else if (declspecs == double_type_node) - strcat (buf, "double "); - else if (declspecs == long_double_type_node) - strcat (buf, "long double "); - break; - - case RECORD_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - if (! TREE_STATIC_TEMPLATE (declspecs)) - strcat (buf, "struct "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - strcat (buf, ">"); - } - } - - else - strcat (buf, "untagged struct"); - - strcat (buf, " "); - break; - - case UNION_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "union "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - - else - strcat (buf, "untagged union "); - break; - - case ENUMERAL_TYPE: - if (TYPE_NAME (declspecs) - && TREE_CODE (TYPE_NAME (declspecs)) == IDENTIFIER_NODE) - { - strcat (buf, "enum "); - strcat (buf, IDENTIFIER_POINTER (TYPE_NAME (declspecs))); - strcat (buf, " "); - } - - else - strcat (buf, "untagged enum "); - break; - - case VOID_TYPE: - strcat (buf, "void "); - break; - - case POINTER_TYPE: - { - tree protocol_list = TYPE_PROTOCOL_LIST (declspecs); - - strcat (buf, "id"); - if (protocol_list) - { - tree chain = protocol_list; - - strcat (buf, " <"); - while (chain) - { - strcat (buf, - IDENTIFIER_POINTER - (PROTOCOL_NAME (TREE_VALUE (chain)))); - chain = TREE_CHAIN (chain); - if (chain) - strcat (buf, ", "); - } - - strcat (buf, ">"); - } - } - break; - - default: - break; - } - } -} - -static char * -gen_declaration (atype_or_adecl, buf) - tree atype_or_adecl; - char *buf; -{ - char declbuf[256]; - - if (TREE_CODE (atype_or_adecl) == TREE_LIST) - { - tree declspecs; /* "identifier_node", "record_type" */ - tree declarator; /* "array_ref", "indirect_ref", "call_expr"... */ - - /* We have a "raw", abstract declarator (typename). */ - declarator = TREE_VALUE (atype_or_adecl); - declspecs = TREE_PURPOSE (atype_or_adecl); - - gen_declspecs (declspecs, buf, 1); - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - - else - { - tree atype; - tree declspecs; /* "integer_type", "real_type", "record_type"... */ - tree declarator; /* "array_type", "function_type", "pointer_type". */ - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - atype = TREE_TYPE (atype_or_adecl); - else - /* Assume we have a *_type node. */ - atype = atype_or_adecl; - - if (is_complex_decl (atype)) - { - tree chain; - - /* Get the declaration specifier; it is at the end of the list. */ - declarator = chain = atype; - do - chain = TREE_TYPE (chain); /* not TREE_CHAIN (chain); */ - while (is_complex_decl (chain)); - declspecs = chain; - } - - else - { - declspecs = atype; - declarator = NULL_TREE; - } - - gen_declspecs (declspecs, buf, 0); - - if (TREE_CODE (atype_or_adecl) == FIELD_DECL - || TREE_CODE (atype_or_adecl) == PARM_DECL - || TREE_CODE (atype_or_adecl) == FUNCTION_DECL) - { - char *decl_name = (DECL_NAME (atype_or_adecl) - ? IDENTIFIER_POINTER (DECL_NAME (atype_or_adecl)) - : ""); - - if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, decl_name)); - } - - else if (decl_name[0]) - { - strcat (buf, " "); - strcat (buf, decl_name); - } - } - else if (declarator) - { - strcat (buf, " "); - strcat (buf, gen_declarator (declarator, declbuf, "")); - } - } - - return buf; -} - -#define RAW_TYPESPEC(meth) (TREE_VALUE (TREE_PURPOSE (TREE_TYPE (meth)))) - -static char * -gen_method_decl (method, buf) - tree method; - char *buf; -{ - tree chain; - - if (RAW_TYPESPEC (method) != objc_object_reference) - { - strcpy (buf, "("); - gen_declaration (TREE_TYPE (method), buf); - strcat (buf, ")"); - } - - chain = METHOD_SEL_ARGS (method); - if (chain) - { - /* We have a chain of keyword_decls. */ - do - { - if (KEYWORD_KEY_NAME (chain)) - strcat (buf, IDENTIFIER_POINTER (KEYWORD_KEY_NAME (chain))); - - strcat (buf, ":"); - if (RAW_TYPESPEC (chain) != objc_object_reference) - { - strcat (buf, "("); - gen_declaration (TREE_TYPE (chain), buf); - strcat (buf, ")"); - } - - strcat (buf, IDENTIFIER_POINTER (KEYWORD_ARG_NAME (chain))); - if ((chain = TREE_CHAIN (chain))) - strcat (buf, " "); - } - while (chain); - - if (METHOD_ADD_ARGS (method) == (tree)1) - strcat (buf, ", ..."); - else if (METHOD_ADD_ARGS (method)) - { - /* We have a tree list node as generate by get_parm_info. */ - chain = TREE_PURPOSE (METHOD_ADD_ARGS (method)); - - /* Know we have a chain of parm_decls. */ - while (chain) - { - strcat (buf, ", "); - gen_declaration (chain, buf); - chain = TREE_CHAIN (chain); - } - } - } - - else - /* We have a unary selector. */ - strcat (buf, IDENTIFIER_POINTER (METHOD_SEL_NAME (method))); - - return buf; -} - -/* Debug info. */ - -static void -dump_interface (fp, chain) - FILE *fp; - tree chain; -{ - char *buf = (char *)xmalloc (256); - char *my_name = IDENTIFIER_POINTER (CLASS_NAME (chain)); - tree ivar_decls = CLASS_RAW_IVARS (chain); - tree nst_methods = CLASS_NST_METHODS (chain); - tree cls_methods = CLASS_CLS_METHODS (chain); - - fprintf (fp, "\n@interface %s", my_name); - - if (CLASS_SUPER_NAME (chain)) - { - char *super_name = IDENTIFIER_POINTER (CLASS_SUPER_NAME (chain)); - fprintf (fp, " : %s\n", super_name); - } - else - fprintf (fp, "\n"); - - if (ivar_decls) - { - fprintf (fp, "{\n"); - do - { - bzero (buf, 256); - fprintf (fp, "\t%s;\n", gen_declaration (ivar_decls, buf)); - ivar_decls = TREE_CHAIN (ivar_decls); - } - while (ivar_decls); - fprintf (fp, "}\n"); - } - - while (nst_methods) - { - bzero (buf, 256); - fprintf (fp, "- %s;\n", gen_method_decl (nst_methods, buf)); - nst_methods = TREE_CHAIN (nst_methods); - } - - while (cls_methods) - { - bzero (buf, 256); - fprintf (fp, "+ %s;\n", gen_method_decl (cls_methods, buf)); - cls_methods = TREE_CHAIN (cls_methods); - } - fprintf (fp, "\n@end"); -} - -/* Demangle function for Objective-C */ -static const char * -objc_demangle (mangled) - const char *mangled; -{ - char *demangled, *cp; - - if (mangled[0] == '_' && - (mangled[1] == 'i' || mangled[1] == 'c') && - mangled[2] == '_') - { - cp = demangled = xmalloc(strlen(mangled) + 2); - if (mangled[1] == 'i') - *cp++ = '-'; /* for instance method */ - else - *cp++ = '+'; /* for class method */ - *cp++ = '['; /* opening left brace */ - strcpy(cp, mangled+3); /* tack on the rest of the mangled name */ - while (*cp && *cp == '_') - cp++; /* skip any initial underbars in class name */ - cp = strchr(cp, '_'); /* find first non-initial underbar */ - if (cp == NULL) - { - free(demangled); /* not mangled name */ - return mangled; - } - if (cp[1] == '_') /* easy case: no category name */ - { - *cp++ = ' '; /* replace two '_' with one ' ' */ - strcpy(cp, mangled + (cp - demangled) + 2); - } - else - { - *cp++ = '('; /* less easy case: category name */ - cp = strchr(cp, '_'); - if (cp == 0) - { - free(demangled); /* not mangled name */ - return mangled; - } - *cp++ = ')'; - *cp++ = ' '; /* overwriting 1st char of method name... */ - strcpy(cp, mangled + (cp - demangled)); /* get it back */ - } - while (*cp && *cp == '_') - cp++; /* skip any initial underbars in method name */ - for (; *cp; cp++) - if (*cp == '_') - *cp = ':'; /* replace remaining '_' with ':' */ - *cp++ = ']'; /* closing right brace */ - *cp++ = 0; /* string terminator */ - return demangled; - } - else - return mangled; /* not an objc mangled name */ -} - -static const char * -objc_printable_name (decl, kind) - tree decl; - char **kind; -{ - return objc_demangle (IDENTIFIER_POINTER (DECL_NAME (decl))); -} - -static void -init_objc () -{ - /* Add the special tree codes of Objective C to the tables. */ - -#define LAST_CODE LAST_AND_UNUSED_TREE_CODE - - gcc_obstack_init (&util_obstack); - util_firstobj = (char *) obstack_finish (&util_obstack); - - bcopy (objc_tree_code_type, - tree_code_type + (int) LAST_CODE, - (int) LAST_OBJC_TREE_CODE - (int) LAST_CODE); - bcopy ((char *) objc_tree_code_length, - (char *) (tree_code_length + (int) LAST_CODE), - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (int))); - bcopy ((char *) objc_tree_code_name, - (char *) (tree_code_name + (int) LAST_CODE), - (((int) LAST_OBJC_TREE_CODE - (int) LAST_CODE) - * sizeof (char *))); - - errbuf = (char *)xmalloc (BUFSIZE); - hash_init (); - synth_module_prologue (); - - /* Change the default error function */ - decl_printable_name = (char* (*)()) objc_printable_name; -} - -static void -finish_objc () -{ - struct imp_entry *impent; - tree chain; - /* The internally generated initializers appear to have missing braces. - Don't warn about this. */ - int save_warn_missing_braces = warn_missing_braces; - warn_missing_braces = 0; - - generate_forward_declaration_to_string_table (); - -#ifdef OBJC_PROLOGUE - OBJC_PROLOGUE; -#endif - - /* Process the static instances here because initialization of objc_symtab - depends on them. */ - if (objc_static_instances) - generate_static_references (); - - if (implementation_context || class_names_chain - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - generate_objc_symtab_decl (); - - for (impent = imp_list; impent; impent = impent->next) - { - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - UOBJC_CLASS_decl = impent->class_decl; - UOBJC_METACLASS_decl = impent->meta_decl; - - if (TREE_CODE (implementation_context) == CLASS_IMPLEMENTATION_TYPE) - { - /* all of the following reference the string pool... */ - generate_ivar_lists (); - generate_dispatch_tables (); - generate_shared_structures (); - } - else - { - generate_dispatch_tables (); - generate_category (implementation_context); - } - } - - /* If we are using an array of selectors, we must always - finish up the array decl even if no selectors were used. */ - if (! flag_next_runtime || sel_ref_chain) - build_selector_translation_table (); - - if (protocol_chain) - generate_protocols (); - - if (implementation_context || class_names_chain || objc_static_instances - || meth_var_names_chain || meth_var_types_chain || sel_ref_chain) - { - /* Arrange for Objc data structures to be initialized at run time. */ - char *init_name = build_module_descriptor (); - if (init_name) - assemble_constructor (init_name); - } - - /* Dump the class references. This forces the appropriate classes - to be linked into the executable image, preserving unix archive - semantics. This can be removed when we move to a more dynamically - linked environment. */ - - for (chain = cls_ref_chain; chain; chain = TREE_CHAIN (chain)) - { - handle_class_ref (chain); - if (TREE_PURPOSE (chain)) - generate_classref_translation_entry (chain); - } - - for (impent = imp_list; impent; impent = impent->next) - handle_impent (impent); - - /* Dump the string table last. */ - - generate_strings (); - - if (flag_gen_declaration) - { - add_class (implementation_context); - dump_interface (gen_declaration_file, implementation_context); - } - - if (warn_selector) - { - int slot; - hash hsh; - - /* Run through the selector hash tables and print a warning for any - selector which has multiple methods. */ - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = cls_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - - for (slot = 0; slot < SIZEHASHTABLE; slot++) - for (hsh = nst_method_hash_list[slot]; hsh; hsh = hsh->next) - if (hsh->list) - { - tree meth = hsh->key; - char type = (TREE_CODE (meth) == INSTANCE_METHOD_DECL - ? '-' : '+'); - attr loop; - - warning ("potential selector conflict for method `%s'", - IDENTIFIER_POINTER (METHOD_SEL_NAME (meth))); - warn_with_method ("found", type, meth); - for (loop = hsh->list; loop; loop = loop->next) - warn_with_method ("found", type, loop->value); - } - } - - warn_missing_braces = save_warn_missing_braces; -} - -/* Subroutines of finish_objc. */ - -static void -generate_classref_translation_entry (chain) - tree chain; -{ - tree expr, name, decl_specs, decl, sc_spec; - tree type; - - type = TREE_TYPE (TREE_PURPOSE (chain)); - - expr = add_objc_string (TREE_VALUE (chain), class_names); - expr = build_c_cast (type, expr); /* cast! */ - - name = DECL_NAME (TREE_PURPOSE (chain)); - - sc_spec = build_tree_list (NULL_TREE, ridpointers[(int) RID_STATIC]); - - /* static struct objc_class * _OBJC_CLASS_REFERENCES_n = ...; */ - decl_specs = tree_cons (NULL_TREE, type, sc_spec); - - /* The decl that is returned from start_decl is the one that we - forward declared in build_class_reference. */ - decl = start_decl (name, decl_specs, 1, NULL_TREE, NULL_TREE); - finish_decl (decl, expr, NULL_TREE); - return; -} - -static void -handle_class_ref (chain) - tree chain; -{ - char *name = IDENTIFIER_POINTER (TREE_VALUE (chain)); - if (! flag_next_runtime) - { - tree decl; - char *string = (char *) alloca (strlen (name) + 30); - tree exp; - - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), name); - - /* Make a decl for this name, so we can use its address in a tree. */ - decl = build_decl (VAR_DECL, get_identifier (string), char_type_node); - DECL_EXTERNAL (decl) = 1; - TREE_PUBLIC (decl) = 1; - - pushdecl (decl); - rest_of_decl_compilation (decl, 0, 0, 0); - - /* Make following constant read-only (why not)? */ - readonly_data_section (); - - exp = build1 (ADDR_EXPR, string_type_node, decl); - - /* Align the section properly. */ - assemble_constant_align (exp); - - /* Inform the assembler about this new external thing. */ - assemble_external (decl); - - /* Output a constant to reference this address. */ - output_constant (exp, int_size_in_bytes (string_type_node)); - } - else - { - /* This overreliance on our assembler (i.e. lack of portability) - should be dealt with at some point. The GNU strategy (above) - won't work either, but it is a start. */ - char *string = (char *) alloca (strlen (name) + 30); - sprintf (string, ".reference .objc_class_name_%s", name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } -} - -static void -handle_impent (impent) - struct imp_entry *impent; -{ - implementation_context = impent->imp_context; - implementation_template = impent->imp_template; - - if (TREE_CODE (impent->imp_context) == CLASS_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) + 30); - - if (flag_next_runtime) - { - /* Grossly unportable. - People should know better than to assume - such things about assembler syntax! */ - sprintf (string, ".objc_class_name_%s=0", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_class_name_%s", class_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - - else - { - sprintf (string, "%sobjc_class_name_%s", - (flag_next_runtime ? "." : "__"), class_name); - assemble_global (string); - assemble_label (string); - } - } - - else if (TREE_CODE (impent->imp_context) == CATEGORY_IMPLEMENTATION_TYPE) - { - char *class_name = IDENTIFIER_POINTER (CLASS_NAME (impent->imp_context)); - char *class_super_name - = IDENTIFIER_POINTER (CLASS_SUPER_NAME (impent->imp_context)); - char *string = (char *) alloca (strlen (class_name) - + strlen (class_super_name) + 30); - - /* Do the same for categories. Even though no references to these - symbols are generated automatically by the compiler, it gives - you a handle to pull them into an archive by hand. */ - if (flag_next_runtime) - { - /* Grossly unportable. */ - sprintf (string, ".objc_category_name_%s_%s=0", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - - sprintf (string, ".globl .objc_category_name_%s_%s", - class_name, class_super_name); - assemble_asm (my_build_string (strlen (string) + 1, string)); - } - - else - { - sprintf (string, "%sobjc_category_name_%s_%s", - (flag_next_runtime ? "." : "__"), - class_name, class_super_name); - assemble_global (string); - assemble_label (string); - } - } -} - -#ifdef DEBUG - -static void -objc_debug (fp) - FILE *fp; -{ - char *buf = (char *)xmalloc (256); - - { /* dump function prototypes */ - tree loop = UOBJC_MODULES_decl; - - fprintf (fp, "\n\nfunction prototypes:\n"); - while (loop) - { - if (TREE_CODE (loop) == FUNCTION_DECL && DECL_INITIAL (loop)) - { - /* We have a function definition: generate prototype. */ - bzero (errbuf, BUFSIZE); - gen_declaration (loop, errbuf); - fprintf (fp, "%s;\n", errbuf); - } - loop = TREE_CHAIN (loop); - } - } - { - /* Dump global chains. */ - tree loop; - int i, index = 0, offset = 0; - hash hashlist; - - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = nst_method_hash_list[i]) - { - fprintf (fp, "\n\nnst_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - - for (i = 0; i < SIZEHASHTABLE; i++) - { - if (hashlist = cls_method_hash_list[i]) - { - fprintf (fp, "\n\ncls_method_hash_list[%d]:\n", i); - do - { - bzero (buf, 256); - fprintf (fp, "-%s;\n", gen_method_decl (hashlist->key, buf)); - hashlist = hashlist->next; - } - while (hashlist); - } - } - - fprintf (fp, "\nsel_refdef_chain:\n"); - for (loop = sel_refdef_chain; loop; loop = TREE_CHAIN (loop)) - { - fprintf (fp, "(index: %4d offset: %4d) %s\n", index, offset, - IDENTIFIER_POINTER (TREE_VALUE (loop))); - index++; - /* add one for the '\0' character */ - offset += IDENTIFIER_LENGTH (TREE_VALUE (loop)) + 1; - } - - fprintf (fp, "\n (max_selector_index: %4d.\n", max_selector_index); - } -} -#endif - -void -print_lang_statistics () -{ -} diff --git a/gcc/objc/objc-act.h b/gcc/objc/objc-act.h deleted file mode 100755 index 65224de..0000000 --- a/gcc/objc/objc-act.h +++ /dev/null @@ -1,117 +0,0 @@ -/* Declarations for objc-act.c. - Copyright (C) 1990 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/*** Public Interface (procedures) ***/ - -/* used by yyparse */ - -void finish_file PROTO((void)); -tree start_class PROTO((enum tree_code, tree, tree, tree)); -tree continue_class PROTO((tree)); -void finish_class PROTO((tree)); -void start_method_def PROTO((tree)); -void continue_method_def PROTO((void)); -void finish_method_def PROTO((void)); -tree start_protocol PROTO((enum tree_code, tree, tree)); -void finish_protocol PROTO((tree)); -void add_objc_decls PROTO((void)); - -tree is_ivar PROTO((tree, tree)); -int is_private PROTO((tree)); -int is_public PROTO((tree, tree)); -tree add_instance_variable PROTO((tree, int, tree, tree, tree)); -tree add_class_method PROTO((tree, tree)); -tree add_instance_method PROTO((tree, tree)); -tree get_super_receiver PROTO((void)); -tree get_class_ivars PROTO((tree)); -tree get_class_reference PROTO((tree)); -tree get_static_reference PROTO((tree, tree)); -tree get_object_reference PROTO((tree)); -tree build_message_expr PROTO((tree)); -tree build_selector_expr PROTO((tree)); -tree build_ivar_reference PROTO((tree)); -tree build_keyword_decl PROTO((tree, tree, tree)); -tree build_method_decl PROTO((enum tree_code, tree, tree, tree)); -tree build_protocol_expr PROTO((tree)); -tree build_objc_string_object PROTO((tree)); - -extern tree objc_ivar_chain; -extern tree objc_method_context; - -void objc_declare_alias PROTO((tree, tree)); -void objc_declare_class PROTO((tree)); - -extern int objc_receiver_context; - -/* the following routines are used to implement statically typed objects */ - -int objc_comptypes PROTO((tree, tree, int)); -void objc_check_decl PROTO((tree)); - -/* NeXT extensions */ - -tree build_encode_expr PROTO((tree)); - -/* Objective-C structures */ - -/* KEYWORD_DECL */ -#define KEYWORD_KEY_NAME(DECL) ((DECL)->decl.name) -#define KEYWORD_ARG_NAME(DECL) ((DECL)->decl.arguments) - -/* INSTANCE_METHOD_DECL, CLASS_METHOD_DECL */ -#define METHOD_SEL_NAME(DECL) ((DECL)->decl.name) -#define METHOD_SEL_ARGS(DECL) ((DECL)->decl.arguments) -#define METHOD_ADD_ARGS(DECL) ((DECL)->decl.result) -#define METHOD_DEFINITION(DECL) ((DECL)->decl.initial) -#define METHOD_ENCODING(DECL) ((DECL)->decl.context) - -/* CLASS_INTERFACE_TYPE, CLASS_IMPLEMENTATION_TYPE, - CATEGORY_INTERFACE_TYPE, CATEGORY_IMPLEMENTATION_TYPE, - PROTOCOL_INTERFACE_TYPE */ -#define CLASS_NAME(CLASS) ((CLASS)->type.name) -#define CLASS_SUPER_NAME(CLASS) ((CLASS)->type.context) -#define CLASS_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define CLASS_RAW_IVARS(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define CLASS_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define CLASS_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define CLASS_STATIC_TEMPLATE(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 2) -#define CLASS_CATEGORY_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 3) -#define CLASS_PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 4) -#define PROTOCOL_NAME(CLASS) ((CLASS)->type.name) -#define PROTOCOL_LIST(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 0) -#define PROTOCOL_NST_METHODS(CLASS) ((CLASS)->type.minval) -#define PROTOCOL_CLS_METHODS(CLASS) ((CLASS)->type.maxval) -#define PROTOCOL_FORWARD_DECL(CLASS) TREE_VEC_ELT (TYPE_BINFO (CLASS), 1) -#define TYPE_PROTOCOL_LIST(TYPE) ((TYPE)->type.context) - -/* Define the Objective-C or Objective-C++ language-specific tree codes. */ - -#define DEFTREECODE(SYM, NAME, TYPE, LENGTH) SYM, -enum objc_tree_code { -#ifdef OBJCPLUS - dummy_tree_code = LAST_CPLUS_TREE_CODE, -#else - dummy_tree_code = LAST_AND_UNUSED_TREE_CODE, -#endif -#include "objc-tree.def" - LAST_OBJC_TREE_CODE -}; -#undef DEFTREECODE diff --git a/gcc/objc/objc-tree.def b/gcc/objc/objc-tree.def deleted file mode 100755 index a661624..0000000 --- a/gcc/objc/objc-tree.def +++ /dev/null @@ -1,37 +0,0 @@ -/* This file contains the definitions and documentation for the - additional tree codes used in the Objective C front end (see tree.def - for the standard codes). - Copyright (C) 1990, 1997 Free Software Foundation, Inc. - -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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - - -/* Objective-C types. */ -DEFTREECODE (CLASS_INTERFACE_TYPE, "class_interface_type", 't', 0) -DEFTREECODE (CLASS_IMPLEMENTATION_TYPE, "class_implementation_type", 't', 0) -DEFTREECODE (CATEGORY_INTERFACE_TYPE, "category_interface_type", 't', 0) -DEFTREECODE (CATEGORY_IMPLEMENTATION_TYPE,"category_implementation_type",'t',0) -DEFTREECODE (PROTOCOL_INTERFACE_TYPE, "protocol_interface_type", 't', 0) - -/* Objective-C decls. */ -DEFTREECODE (KEYWORD_DECL, "keyword_decl", 'd', 0) -DEFTREECODE (INSTANCE_METHOD_DECL, "instance_method_decl", 'd', 0) -DEFTREECODE (CLASS_METHOD_DECL, "class_method_decl", 'd', 0) - -/* Objective-C constants. */ -DEFTREECODE (OBJC_STRING_CST, "objc_string_cst", 'c', 3) diff --git a/gcc/objc/objc.gperf b/gcc/objc/objc.gperf deleted file mode 100755 index 407459f..0000000 --- a/gcc/objc/objc.gperf +++ /dev/null @@ -1,64 +0,0 @@ -%{ -/* Command-line: gperf -p -j1 -i 1 -g -o -t -N is_reserved_word -k1,3,$ objc.gperf */ -%} -struct resword { char *name; short token; enum rid rid; }; -%% -@defs, DEFS, NORID -@encode, ENCODE, NORID -@end, END, NORID -@implementation, IMPLEMENTATION, NORID -@interface, INTERFACE, NORID -@public, PUBLIC, NORID -@selector, SELECTOR, NORID -__alignof, ALIGNOF, NORID -__alignof__, ALIGNOF, NORID -__asm, ASM, NORID -__asm__, ASM, NORID -__attribute, ATTRIBUTE, NORID -__attribute__, ATTRIBUTE, NORID -__const, TYPE_QUAL, RID_CONST -__const__, TYPE_QUAL, RID_CONST -__extension__, EXTENSION, NORID -__inline, SCSPEC, RID_INLINE -__inline__, SCSPEC, RID_INLINE -__signed, TYPESPEC, RID_SIGNED -__signed__, TYPESPEC, RID_SIGNED -__typeof, TYPEOF, NORID -__typeof__, TYPEOF, NORID -__volatile, TYPE_QUAL, RID_VOLATILE -__volatile__, TYPE_QUAL, RID_VOLATILE -asm, ASM, NORID -auto, SCSPEC, RID_AUTO -break, BREAK, NORID -case, CASE, NORID -char, TYPESPEC, RID_CHAR -const, TYPE_QUAL, RID_CONST -continue, CONTINUE, NORID -default, DEFAULT, NORID -do, DO, NORID -double, TYPESPEC, RID_DOUBLE -else, ELSE, NORID -enum, ENUM, NORID -extern, SCSPEC, RID_EXTERN -float, TYPESPEC, RID_FLOAT -for, FOR, NORID -goto, GOTO, NORID -if, IF, NORID -inline, SCSPEC, RID_INLINE -int, TYPESPEC, RID_INT -long, TYPESPEC, RID_LONG -register, SCSPEC, RID_REGISTER -return, RETURN, NORID -short, TYPESPEC, RID_SHORT -signed, TYPESPEC, RID_SIGNED -sizeof, SIZEOF, NORID -static, SCSPEC, RID_STATIC -struct, STRUCT, NORID -switch, SWITCH, NORID -typedef, SCSPEC, RID_TYPEDEF -typeof, TYPEOF, NORID -union, UNION, NORID -unsigned, TYPESPEC, RID_UNSIGNED -void, TYPESPEC, RID_VOID -volatile, TYPE_QUAL, RID_VOLATILE -while, WHILE, NORID diff --git a/gcc/tlink.c b/gcc/tlink.c deleted file mode 100755 index e525b43..0000000 --- a/gcc/tlink.c +++ /dev/null @@ -1,647 +0,0 @@ -/* Scan linker error messages for missing template instantiations and provide - them. - - Copyright (C) 1995, 1998 Free Software Foundation, Inc. - Contributed by Jason Merrill (jason@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 Software Foundation, 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -#include "config.h" -#include "system.h" -#include "hash.h" -#include "demangle.h" -#include "toplev.h" -#include "collect2.h" - -#define MAX_ITERATIONS 17 - -/* Obstack allocation and deallocation routines. */ -#define obstack_chunk_alloc xmalloc -#define obstack_chunk_free free - -/* Defined in collect2.c. */ -extern int vflag, debug; -extern char *ldout; -extern char *c_file_name; -extern struct obstack temporary_obstack; -extern struct obstack permanent_obstack; -extern char * temporary_firstobj; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -static int tlink_verbose; - -/* Hash table code. */ - -typedef struct symbol_hash_entry -{ - struct hash_entry root; - struct file_hash_entry *file; - int chosen; - int tweaking; - int tweaked; -} symbol; - -typedef struct file_hash_entry -{ - struct hash_entry root; - const char *args; - const char *dir; - const char *main; - int tweaking; -} file; - -typedef struct demangled_hash_entry -{ - struct hash_entry root; - const char *mangled; -} demangled; - -static struct hash_table symbol_table; - -static struct hash_entry * -symbol_hash_newfunc (entry, table, string) - struct hash_entry *entry; - struct hash_table *table; - const char *string; -{ - struct symbol_hash_entry *ret = (struct symbol_hash_entry *) entry; - if (ret == NULL) - { - ret = ((struct symbol_hash_entry *) - hash_allocate (table, sizeof (struct symbol_hash_entry))); - if (ret == NULL) - return NULL; - } - ret = ((struct symbol_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, - (hash_table_key) string)); - ret->file = NULL; - ret->chosen = 0; - ret->tweaking = 0; - ret->tweaked = 0; - return (struct hash_entry *) ret; -} - -static struct symbol_hash_entry * -symbol_hash_lookup (string, create) - const char *string; - boolean create; -{ - return ((struct symbol_hash_entry *) - hash_lookup (&symbol_table, (hash_table_key) string, - create, &string_copy)); -} - -static struct hash_table file_table; - -static struct hash_entry * -file_hash_newfunc (entry, table, string) - struct hash_entry *entry; - struct hash_table *table; - const char *string; -{ - struct file_hash_entry *ret = (struct file_hash_entry *) entry; - if (ret == NULL) - { - ret = ((struct file_hash_entry *) - hash_allocate (table, sizeof (struct file_hash_entry))); - if (ret == NULL) - return NULL; - } - ret = ((struct file_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, - (hash_table_key) string)); - ret->args = NULL; - ret->dir = NULL; - ret->main = NULL; - ret->tweaking = 0; - return (struct hash_entry *) ret; -} - -static struct file_hash_entry * -file_hash_lookup (string) - const char *string; -{ - return ((struct file_hash_entry *) - hash_lookup (&file_table, (hash_table_key) string, true, - &string_copy)); -} - -static struct hash_table demangled_table; - -static struct hash_entry * -demangled_hash_newfunc (entry, table, string) - struct hash_entry *entry; - struct hash_table *table; - const char *string; -{ - struct demangled_hash_entry *ret = (struct demangled_hash_entry *) entry; - if (ret == NULL) - { - ret = ((struct demangled_hash_entry *) - hash_allocate (table, sizeof (struct demangled_hash_entry))); - if (ret == NULL) - return NULL; - } - ret = ((struct demangled_hash_entry *) - hash_newfunc ((struct hash_entry *) ret, table, - (hash_table_key) string)); - ret->mangled = NULL; - return (struct hash_entry *) ret; -} - -static struct demangled_hash_entry * -demangled_hash_lookup (string, create) - const char *string; - boolean create; -{ - return ((struct demangled_hash_entry *) - hash_lookup (&demangled_table, (hash_table_key) string, - create, &string_copy)); -} - -/* Stack code. */ - -struct symbol_stack_entry -{ - symbol *value; - struct symbol_stack_entry *next; -}; -struct obstack symbol_stack_obstack; -struct symbol_stack_entry *symbol_stack; - -struct file_stack_entry -{ - file *value; - struct file_stack_entry *next; -}; -struct obstack file_stack_obstack; -struct file_stack_entry *file_stack; - -static void -symbol_push (p) - symbol *p; -{ - struct symbol_stack_entry *ep = (struct symbol_stack_entry *) obstack_alloc - (&symbol_stack_obstack, sizeof (struct symbol_stack_entry)); - ep->value = p; - ep->next = symbol_stack; - symbol_stack = ep; -} - -static symbol * -symbol_pop () -{ - struct symbol_stack_entry *ep = symbol_stack; - symbol *p; - if (ep == NULL) - return NULL; - p = ep->value; - symbol_stack = ep->next; - obstack_free (&symbol_stack_obstack, ep); - return p; -} - -static void -file_push (p) - file *p; -{ - struct file_stack_entry *ep; - - if (p->tweaking) - return; - - ep = (struct file_stack_entry *) obstack_alloc - (&file_stack_obstack, sizeof (struct file_stack_entry)); - ep->value = p; - ep->next = file_stack; - file_stack = ep; - p->tweaking = 1; -} - -static file * -file_pop () -{ - struct file_stack_entry *ep = file_stack; - file *p; - if (ep == NULL) - return NULL; - p = ep->value; - file_stack = ep->next; - obstack_free (&file_stack_obstack, ep); - p->tweaking = 0; - return p; -} - -/* Other machinery. */ - -static void -tlink_init () -{ - char *p; - - hash_table_init (&symbol_table, symbol_hash_newfunc, &string_hash, - &string_compare); - hash_table_init (&file_table, file_hash_newfunc, &string_hash, - &string_compare); - hash_table_init (&demangled_table, demangled_hash_newfunc, - &string_hash, &string_compare); - obstack_begin (&symbol_stack_obstack, 0); - obstack_begin (&file_stack_obstack, 0); - - p = getenv ("TLINK_VERBOSE"); - if (p) - tlink_verbose = atoi (p); - else - { - tlink_verbose = 1; - if (vflag) - tlink_verbose = 2; - if (debug) - tlink_verbose = 3; - } -} - -static int -tlink_execute (prog, argv, redir) - char *prog; - char **argv; - char *redir; -{ - collect_execute (prog, argv, redir); - return collect_wait (prog); -} - -static char * -frob_extension (s, ext) - char *s, *ext; -{ - char *p = rindex (s, '/'); - if (! p) - p = s; - p = rindex (p, '.'); - if (! p) - p = s + strlen (s); - - obstack_grow (&temporary_obstack, s, p - s); - return obstack_copy0 (&temporary_obstack, ext, strlen (ext)); -} - -static char * -obstack_fgets (stream, ob) - FILE *stream; - struct obstack *ob; -{ - int c; - while ((c = getc (stream)) != EOF && c != '\n') - obstack_1grow (ob, c); - if (obstack_object_size (ob) == 0) - return NULL; - obstack_1grow (ob, '\0'); - return obstack_finish (ob); -} - -static char * -tfgets (stream) - FILE *stream; -{ - return obstack_fgets (stream, &temporary_obstack); -} - -static char * -pfgets (stream) - FILE *stream; -{ - return obstack_fgets (stream, &permanent_obstack); -} - -/* Real tlink code. */ - -static void -freadsym (stream, f, chosen) - FILE *stream; - file *f; - int chosen; -{ - symbol *sym; - - { - char *name = tfgets (stream); - sym = symbol_hash_lookup (name, true); - } - - if (sym->file == NULL) - { - symbol_push (sym); - sym->file = f; - sym->chosen = chosen; - } - else if (chosen) - { - if (sym->chosen && sym->file != f) - { - if (sym->chosen == 1) - file_push (sym->file); - else - { - file_push (f); - f = sym->file; - chosen = sym->chosen; - } - } - sym->file = f; - sym->chosen = chosen; - } -} - -static void -read_repo_file (f) - file *f; -{ - char c; - FILE *stream = fopen ((char*) f->root.key, "r"); - - if (tlink_verbose >= 2) - fprintf (stderr, "collect: reading %s\n", - (char*) f->root.key); - - while (fscanf (stream, "%c ", &c) == 1) - { - switch (c) - { - case 'A': - f->args = pfgets (stream); - break; - case 'D': - f->dir = pfgets (stream); - break; - case 'M': - f->main = pfgets (stream); - break; - case 'P': - freadsym (stream, f, 2); - break; - case 'C': - freadsym (stream, f, 1); - break; - case 'O': - freadsym (stream, f, 0); - break; - } - obstack_free (&temporary_obstack, temporary_firstobj); - } - fclose (stream); - if (f->args == NULL) - f->args = getenv ("COLLECT_GCC_OPTIONS"); - if (f->dir == NULL) - f->dir = "."; -} - -static void -maybe_tweak (line, f) - char *line; - file *f; -{ - symbol *sym = symbol_hash_lookup (line + 2, false); - - if ((sym->file == f && sym->tweaking) - || (sym->file != f && line[0] == 'C')) - { - sym->tweaking = 0; - sym->tweaked = 1; - - if (line[0] == 'O') - line[0] = 'C'; - else - line[0] = 'O'; - } -} - -static int -recompile_files () -{ - file *f; - - while ((f = file_pop ()) != NULL) - { - char *line, *command; - FILE *stream = fopen ((char*) f->root.key, "r"); - char *outname = frob_extension ((char*) f->root.key, ".rnw"); - FILE *output = fopen (outname, "w"); - - while ((line = tfgets (stream)) != NULL) - { - switch (line[0]) - { - case 'C': - case 'O': - maybe_tweak (line, f); - } - fprintf (output, "%s\n", line); - } - fclose (stream); - fclose (output); - rename (outname, (char*) f->root.key); - - obstack_grow (&temporary_obstack, "cd ", 3); - obstack_grow (&temporary_obstack, f->dir, strlen (f->dir)); - obstack_grow (&temporary_obstack, "; ", 2); - obstack_grow (&temporary_obstack, c_file_name, strlen (c_file_name)); - obstack_1grow (&temporary_obstack, ' '); - obstack_grow (&temporary_obstack, f->args, strlen (f->args)); - obstack_1grow (&temporary_obstack, ' '); - command = obstack_copy0 (&temporary_obstack, f->main, strlen (f->main)); - - if (tlink_verbose) - fprintf (stderr, "collect: recompiling %s\n", f->main); - if (tlink_verbose >= 3) - fprintf (stderr, "%s\n", command); - - if (system (command) != 0) - return 0; - - read_repo_file (f); - - obstack_free (&temporary_obstack, temporary_firstobj); - } - return 1; -} - -static int -read_repo_files (object_lst) - char **object_lst; -{ - char **object = object_lst; - - for (; *object; object++) - { - char *p = frob_extension (*object, ".rpo"); - file *f; - - if (! file_exists (p)) - continue; - - f = file_hash_lookup (p); - - read_repo_file (f); - } - - if (file_stack != NULL && ! recompile_files ()) - return 0; - - return (symbol_stack != NULL); -} - -static void -demangle_new_symbols () -{ - symbol *sym; - - while ((sym = symbol_pop ()) != NULL) - { - demangled *dem; - char *p = cplus_demangle ((char*) sym->root.key, - DMGL_PARAMS | DMGL_ANSI); - - if (! p) - continue; - - dem = demangled_hash_lookup (p, true); - dem->mangled = (char*) sym->root.key; - } -} - -static int -scan_linker_output (fname) - char *fname; -{ - FILE *stream = fopen (fname, "r"); - char *line; - - while ((line = tfgets (stream)) != NULL) - { - char *p = line, *q; - symbol *sym; - int end; - - while (*p && ISSPACE ((unsigned char)*p)) - ++p; - - if (! *p) - continue; - - for (q = p; *q && ! ISSPACE ((unsigned char)*q); ++q) - ; - - /* Try the first word on the line. */ - if (*p == '.') - ++p; - if (*p == '_' && prepends_underscore) - ++p; - - end = ! *q; - *q = 0; - sym = symbol_hash_lookup (p, false); - - if (! sym && ! end) - /* Try a mangled name in quotes. */ - { - char *oldq = q+1; - demangled *dem = 0; - q = 0; - - /* First try `GNU style'. */ - p = index (oldq, '`'); - if (p) - p++, q = index (p, '\''); - /* Then try "double quotes". */ - else if (p = index (oldq, '"'), p) - p++, q = index (p, '"'); - - if (q) - { - *q = 0; - dem = demangled_hash_lookup (p, false); - if (dem) - sym = symbol_hash_lookup (dem->mangled, false); - else - sym = symbol_hash_lookup (p, false); - } - } - - if (sym && sym->tweaked) - { - fclose (stream); - return 0; - } - if (sym && !sym->tweaking) - { - if (tlink_verbose >= 2) - fprintf (stderr, "collect: tweaking %s in %s\n", - (char*) sym->root.key, (char*) sym->file->root.key); - sym->tweaking = 1; - file_push (sym->file); - } - - obstack_free (&temporary_obstack, temporary_firstobj); - } - - fclose (stream); - return (file_stack != NULL); -} - -void -do_tlink (ld_argv, object_lst) - char **ld_argv, **object_lst; -{ - int exit = tlink_execute ("ld", ld_argv, ldout); - - tlink_init (); - - if (exit) - { - int i = 0; - - /* Until collect does a better job of figuring out which are object - files, assume that everything on the command line could be. */ - if (read_repo_files (ld_argv)) - while (exit && i++ < MAX_ITERATIONS) - { - if (tlink_verbose >= 3) - dump_file (ldout); - demangle_new_symbols (); - if (! scan_linker_output (ldout)) - break; - if (! recompile_files ()) - break; - if (tlink_verbose) - fprintf (stderr, "collect: relinking\n"); - exit = tlink_execute ("ld", ld_argv, ldout); - } - } - - dump_file (ldout); - unlink (ldout); - if (exit) - { - error ("ld returned %d exit status", exit); - collect_exit (exit); - } -} diff --git a/include/demangle.h b/include/demangle.h deleted file mode 100755 index 63fe5e2..0000000 --- a/include/demangle.h +++ /dev/null @@ -1,95 +0,0 @@ -/* Defs for interface to demanglers. - Copyright 1992, 1995, 1996 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. */ - - -#if !defined (DEMANGLE_H) -#define DEMANGLE_H - -#include <ansidecl.h> - -/* Options passed to cplus_demangle (in 2nd parameter). */ - -#define DMGL_NO_OPTS 0 /* For readability... */ -#define DMGL_PARAMS (1 << 0) /* Include function args */ -#define DMGL_ANSI (1 << 1) /* Include const, volatile, etc */ -#define DMGL_JAVA (1 << 2) /* Demangle as Java rather than C++. */ - -#define DMGL_AUTO (1 << 8) -#define DMGL_GNU (1 << 9) -#define DMGL_LUCID (1 << 10) -#define DMGL_ARM (1 << 11) -#define DMGL_HP (1 << 12) /* For the HP aCC compiler; same as ARM - except for template arguments, etc. */ -#define DMGL_EDG (1 << 13) - -/* If none of these are set, use 'current_demangling_style' as the default. */ -#define DMGL_STYLE_MASK (DMGL_AUTO|DMGL_GNU|DMGL_LUCID|DMGL_ARM|DMGL_HP|DMGL_EDG) - -/* Enumeration of possible demangling styles. - - Lucid and ARM styles are still kept logically distinct, even though - they now both behave identically. The resulting style is actual the - union of both. I.E. either style recognizes both "__pt__" and "__rf__" - for operator "->", even though the first is lucid style and the second - is ARM style. (FIXME?) */ - -extern enum demangling_styles -{ - unknown_demangling = 0, - auto_demangling = DMGL_AUTO, - gnu_demangling = DMGL_GNU, - lucid_demangling = DMGL_LUCID, - arm_demangling = DMGL_ARM, - hp_demangling = DMGL_HP, - edg_demangling = DMGL_EDG -} current_demangling_style; - -/* Define string names for the various demangling styles. */ - -#define AUTO_DEMANGLING_STYLE_STRING "auto" -#define GNU_DEMANGLING_STYLE_STRING "gnu" -#define LUCID_DEMANGLING_STYLE_STRING "lucid" -#define ARM_DEMANGLING_STYLE_STRING "arm" -#define HP_DEMANGLING_STYLE_STRING "hp" -#define EDG_DEMANGLING_STYLE_STRING "edg" - -/* Some macros to test what demangling style is active. */ - -#define CURRENT_DEMANGLING_STYLE current_demangling_style -#define AUTO_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_AUTO) -#define GNU_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_GNU) -#define LUCID_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_LUCID) -#define ARM_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_ARM) -#define HP_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_HP) -#define EDG_DEMANGLING (((int) CURRENT_DEMANGLING_STYLE) & DMGL_EDG) - -extern char * -cplus_demangle PARAMS ((const char *mangled, int options)); - -extern int -cplus_demangle_opname PARAMS ((const char *opname, char *result, int options)); - -extern const char * -cplus_mangle_opname PARAMS ((const char *opname, int options)); - -/* Note: This sets global state. FIXME if you care about multi-threading. */ - -extern void -set_cplus_marker_for_demangling PARAMS ((int ch)); - -#endif /* DEMANGLE_H */ diff --git a/libiberty/cplus-dem.c b/libiberty/cplus-dem.c deleted file mode 100755 index 0b85c29..0000000 --- a/libiberty/cplus-dem.c +++ /dev/null @@ -1,4508 +0,0 @@ -/* Demangler for GNU C++ - Copyright 1989, 91, 94, 95, 96, 97, 98, 1999 Free Software Foundation, Inc. - Written by James Clark (jjc@jclark.uucp) - Rewritten by Fred Fish (fnf@cygnus.com) for ARM and Lucid demangling - Modified by Satish Pai (pai@apollo.hp.com) for HP demangling - -This file is part of the libiberty library. -Libiberty is free software; you can redistribute it and/or -modify it under the terms of the GNU Library General Public -License as published by the Free Software Foundation; either -version 2 of the License, or (at your option) any later version. - -Libiberty 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 -Library General Public License for more details. - -You should have received a copy of the GNU Library General Public -License along with libiberty; see the file COPYING.LIB. If -not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, -Boston, MA 02111-1307, USA. */ - -/* This file exports two functions; cplus_mangle_opname and cplus_demangle. - - This file imports xmalloc and xrealloc, which are like malloc and - realloc except that they generate a fatal error if there is no - available memory. */ - -/* This file lives in both GCC and libiberty. When making changes, please - try not to break either. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include <ctype.h> -#include <sys/types.h> -#include <string.h> -#include <stdio.h> - -#ifdef HAVE_STDLIB_H -#include <stdlib.h> -#else -char * malloc (); -char * realloc (); -#endif - -#include <demangle.h> -#undef CURRENT_DEMANGLING_STYLE -#define CURRENT_DEMANGLING_STYLE work->options - -#include "libiberty.h" - -static const char *mystrstr PARAMS ((const char *, const char *)); - -static const char * -mystrstr (s1, s2) - const char *s1, *s2; -{ - register const char *p = s1; - register int len = strlen (s2); - - for (; (p = strchr (p, *s2)) != 0; p++) - { - if (strncmp (p, s2, len) == 0) - { - return (p); - } - } - return (0); -} - -/* In order to allow a single demangler executable to demangle strings - using various common values of CPLUS_MARKER, as well as any specific - one set at compile time, we maintain a string containing all the - commonly used ones, and check to see if the marker we are looking for - is in that string. CPLUS_MARKER is usually '$' on systems where the - assembler can deal with that. Where the assembler can't, it's usually - '.' (but on many systems '.' is used for other things). We put the - current defined CPLUS_MARKER first (which defaults to '$'), followed - by the next most common value, followed by an explicit '$' in case - the value of CPLUS_MARKER is not '$'. - - We could avoid this if we could just get g++ to tell us what the actual - cplus marker character is as part of the debug information, perhaps by - ensuring that it is the character that terminates the gcc<n>_compiled - marker symbol (FIXME). */ - -#if !defined (CPLUS_MARKER) -#define CPLUS_MARKER '$' -#endif - -enum demangling_styles current_demangling_style = gnu_demangling; - -static char cplus_markers[] = { CPLUS_MARKER, '.', '$', '\0' }; - -static char char_str[2] = { '\000', '\000' }; - -void -set_cplus_marker_for_demangling (ch) - int ch; -{ - cplus_markers[0] = ch; -} - -typedef struct string /* Beware: these aren't required to be */ -{ /* '\0' terminated. */ - char *b; /* pointer to start of string */ - char *p; /* pointer after last character */ - char *e; /* pointer after end of allocated space */ -} string; - -/* Stuff that is shared between sub-routines. - Using a shared structure allows cplus_demangle to be reentrant. */ - -struct work_stuff -{ - int options; - char **typevec; - char **ktypevec; - char **btypevec; - int numk; - int numb; - int ksize; - int bsize; - int ntypes; - int typevec_size; - int constructor; - int destructor; - int static_type; /* A static member function */ - int temp_start; /* index in demangled to start of template args */ - int type_quals; /* The type qualifiers. */ - int dllimported; /* Symbol imported from a PE DLL */ - char **tmpl_argvec; /* Template function arguments. */ - int ntmpl_args; /* The number of template function arguments. */ - int forgetting_types; /* Nonzero if we are not remembering the types - we see. */ - string* previous_argument; /* The last function argument demangled. */ - int nrepeats; /* The number of times to repeat the previous - argument. */ -}; - -#define PRINT_ANSI_QUALIFIERS (work -> options & DMGL_ANSI) -#define PRINT_ARG_TYPES (work -> options & DMGL_PARAMS) - -static const struct optable -{ - const char *in; - const char *out; - int flags; -} optable[] = { - {"nw", " new", DMGL_ANSI}, /* new (1.92, ansi) */ - {"dl", " delete", DMGL_ANSI}, /* new (1.92, ansi) */ - {"new", " new", 0}, /* old (1.91, and 1.x) */ - {"delete", " delete", 0}, /* old (1.91, and 1.x) */ - {"vn", " new []", DMGL_ANSI}, /* GNU, pending ansi */ - {"vd", " delete []", DMGL_ANSI}, /* GNU, pending ansi */ - {"as", "=", DMGL_ANSI}, /* ansi */ - {"ne", "!=", DMGL_ANSI}, /* old, ansi */ - {"eq", "==", DMGL_ANSI}, /* old, ansi */ - {"ge", ">=", DMGL_ANSI}, /* old, ansi */ - {"gt", ">", DMGL_ANSI}, /* old, ansi */ - {"le", "<=", DMGL_ANSI}, /* old, ansi */ - {"lt", "<", DMGL_ANSI}, /* old, ansi */ - {"plus", "+", 0}, /* old */ - {"pl", "+", DMGL_ANSI}, /* ansi */ - {"apl", "+=", DMGL_ANSI}, /* ansi */ - {"minus", "-", 0}, /* old */ - {"mi", "-", DMGL_ANSI}, /* ansi */ - {"ami", "-=", DMGL_ANSI}, /* ansi */ - {"mult", "*", 0}, /* old */ - {"ml", "*", DMGL_ANSI}, /* ansi */ - {"amu", "*=", DMGL_ANSI}, /* ansi (ARM/Lucid) */ - {"aml", "*=", DMGL_ANSI}, /* ansi (GNU/g++) */ - {"convert", "+", 0}, /* old (unary +) */ - {"negate", "-", 0}, /* old (unary -) */ - {"trunc_mod", "%", 0}, /* old */ - {"md", "%", DMGL_ANSI}, /* ansi */ - {"amd", "%=", DMGL_ANSI}, /* ansi */ - {"trunc_div", "/", 0}, /* old */ - {"dv", "/", DMGL_ANSI}, /* ansi */ - {"adv", "/=", DMGL_ANSI}, /* ansi */ - {"truth_andif", "&&", 0}, /* old */ - {"aa", "&&", DMGL_ANSI}, /* ansi */ - {"truth_orif", "||", 0}, /* old */ - {"oo", "||", DMGL_ANSI}, /* ansi */ - {"truth_not", "!", 0}, /* old */ - {"nt", "!", DMGL_ANSI}, /* ansi */ - {"postincrement","++", 0}, /* old */ - {"pp", "++", DMGL_ANSI}, /* ansi */ - {"postdecrement","--", 0}, /* old */ - {"mm", "--", DMGL_ANSI}, /* ansi */ - {"bit_ior", "|", 0}, /* old */ - {"or", "|", DMGL_ANSI}, /* ansi */ - {"aor", "|=", DMGL_ANSI}, /* ansi */ - {"bit_xor", "^", 0}, /* old */ - {"er", "^", DMGL_ANSI}, /* ansi */ - {"aer", "^=", DMGL_ANSI}, /* ansi */ - {"bit_and", "&", 0}, /* old */ - {"ad", "&", DMGL_ANSI}, /* ansi */ - {"aad", "&=", DMGL_ANSI}, /* ansi */ - {"bit_not", "~", 0}, /* old */ - {"co", "~", DMGL_ANSI}, /* ansi */ - {"call", "()", 0}, /* old */ - {"cl", "()", DMGL_ANSI}, /* ansi */ - {"alshift", "<<", 0}, /* old */ - {"ls", "<<", DMGL_ANSI}, /* ansi */ - {"als", "<<=", DMGL_ANSI}, /* ansi */ - {"arshift", ">>", 0}, /* old */ - {"rs", ">>", DMGL_ANSI}, /* ansi */ - {"ars", ">>=", DMGL_ANSI}, /* ansi */ - {"component", "->", 0}, /* old */ - {"pt", "->", DMGL_ANSI}, /* ansi; Lucid C++ form */ - {"rf", "->", DMGL_ANSI}, /* ansi; ARM/GNU form */ - {"indirect", "*", 0}, /* old */ - {"method_call", "->()", 0}, /* old */ - {"addr", "&", 0}, /* old (unary &) */ - {"array", "[]", 0}, /* old */ - {"vc", "[]", DMGL_ANSI}, /* ansi */ - {"compound", ", ", 0}, /* old */ - {"cm", ", ", DMGL_ANSI}, /* ansi */ - {"cond", "?:", 0}, /* old */ - {"cn", "?:", DMGL_ANSI}, /* pseudo-ansi */ - {"max", ">?", 0}, /* old */ - {"mx", ">?", DMGL_ANSI}, /* pseudo-ansi */ - {"min", "<?", 0}, /* old */ - {"mn", "<?", DMGL_ANSI}, /* pseudo-ansi */ - {"nop", "", 0}, /* old (for operator=) */ - {"rm", "->*", DMGL_ANSI}, /* ansi */ - {"sz", "sizeof ", DMGL_ANSI} /* pseudo-ansi */ -}; - -/* These values are used to indicate the various type varieties. - They are all non-zero so that they can be used as `success' - values. */ -typedef enum type_kind_t -{ - tk_none, - tk_pointer, - tk_reference, - tk_integral, - tk_bool, - tk_char, - tk_real -} type_kind_t; - -#define STRING_EMPTY(str) ((str) -> b == (str) -> p) -#define PREPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_prepend(str, " ");} -#define APPEND_BLANK(str) {if (!STRING_EMPTY(str)) \ - string_append(str, " ");} -#define LEN_STRING(str) ( (STRING_EMPTY(str))?0:((str)->p - (str)->b)) - -/* The scope separator appropriate for the language being demangled. */ -#define SCOPE_STRING(work) "::" - -#define ARM_VTABLE_STRING "__vtbl__" /* Lucid/ARM virtual table prefix */ -#define ARM_VTABLE_STRLEN 8 /* strlen (ARM_VTABLE_STRING) */ - -/* Prototypes for local functions */ - -static char * -mop_up PARAMS ((struct work_stuff *, string *, int)); - -static void -squangle_mop_up PARAMS ((struct work_stuff *)); - -#if 0 -static int -demangle_method_args PARAMS ((struct work_stuff *, const char **, string *)); -#endif - -static char * -internal_cplus_demangle PARAMS ((struct work_stuff *, const char *)); - -static int -demangle_template_template_parm PARAMS ((struct work_stuff *work, - const char **, string *)); - -static int -demangle_template PARAMS ((struct work_stuff *work, const char **, string *, - string *, int, int)); - -static int -arm_pt PARAMS ((struct work_stuff *, const char *, int, const char **, - const char **)); - -static int -demangle_class_name PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_qualified PARAMS ((struct work_stuff *, const char **, string *, - int, int)); - -static int -demangle_class PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_fund_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_signature PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_prefix PARAMS ((struct work_stuff *, const char **, string *)); - -static int -gnu_special PARAMS ((struct work_stuff *, const char **, string *)); - -static int -arm_special PARAMS ((const char **, string *)); - -static void -string_need PARAMS ((string *, int)); - -static void -string_delete PARAMS ((string *)); - -static void -string_init PARAMS ((string *)); - -static void -string_clear PARAMS ((string *)); - -#if 0 -static int -string_empty PARAMS ((string *)); -#endif - -static void -string_append PARAMS ((string *, const char *)); - -static void -string_appends PARAMS ((string *, string *)); - -static void -string_appendn PARAMS ((string *, const char *, int)); - -static void -string_prepend PARAMS ((string *, const char *)); - -static void -string_prependn PARAMS ((string *, const char *, int)); - -static int -get_count PARAMS ((const char **, int *)); - -static int -consume_count PARAMS ((const char **)); - -static int -consume_count_with_underscores PARAMS ((const char**)); - -static int -demangle_args PARAMS ((struct work_stuff *, const char **, string *)); - -static int -demangle_nested_args PARAMS ((struct work_stuff*, const char**, string*)); - -static int -do_type PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_arg PARAMS ((struct work_stuff *, const char **, string *)); - -static void -demangle_function_name PARAMS ((struct work_stuff *, const char **, string *, - const char *)); - -static void -remember_type PARAMS ((struct work_stuff *, const char *, int)); - -static void -remember_Btype PARAMS ((struct work_stuff *, const char *, int, int)); - -static int -register_Btype PARAMS ((struct work_stuff *)); - -static void -remember_Ktype PARAMS ((struct work_stuff *, const char *, int)); - -static void -forget_types PARAMS ((struct work_stuff *)); - -static void -forget_B_and_K_types PARAMS ((struct work_stuff *)); - -static void -string_prepends PARAMS ((string *, string *)); - -static int -demangle_template_value_parm PARAMS ((struct work_stuff*, const char**, - string*, type_kind_t)); - -static int -do_hpacc_template_const_value PARAMS ((struct work_stuff *, const char **, string *)); - -static int -do_hpacc_template_literal PARAMS ((struct work_stuff *, const char **, string *)); - -static int -snarf_numeric_literal PARAMS ((const char **, string *)); - -/* There is a TYPE_QUAL value for each type qualifier. They can be - combined by bitwise-or to form the complete set of qualifiers for a - type. */ - -#define TYPE_UNQUALIFIED 0x0 -#define TYPE_QUAL_CONST 0x1 -#define TYPE_QUAL_VOLATILE 0x2 -#define TYPE_QUAL_RESTRICT 0x4 - -static int -code_for_qualifier PARAMS ((int)); - -static const char* -qualifier_string PARAMS ((int)); - -static const char* -demangle_qualifier PARAMS ((int)); - -/* Translate count to integer, consuming tokens in the process. - Conversion terminates on the first non-digit character. - - Trying to consume something that isn't a count results in no - consumption of input and a return of -1. - - Overflow consumes the rest of the digits, and returns -1. */ - -static int -consume_count (type) - const char **type; -{ - int count = 0; - - if (! isdigit ((unsigned char)**type)) - return -1; - - while (isdigit ((unsigned char)**type)) - { - count *= 10; - - /* Check for overflow. - We assume that count is represented using two's-complement; - no power of two is divisible by ten, so if an overflow occurs - when multiplying by ten, the result will not be a multiple of - ten. */ - if ((count % 10) != 0) - { - while (isdigit ((unsigned char) **type)) - (*type)++; - return -1; - } - - count += **type - '0'; - (*type)++; - } - - return (count); -} - - -/* Like consume_count, but for counts that are preceded and followed - by '_' if they are greater than 10. Also, -1 is returned for - failure, since 0 can be a valid value. */ - -static int -consume_count_with_underscores (mangled) - const char **mangled; -{ - int idx; - - if (**mangled == '_') - { - (*mangled)++; - if (!isdigit ((unsigned char)**mangled)) - return -1; - - idx = consume_count (mangled); - if (**mangled != '_') - /* The trailing underscore was missing. */ - return -1; - - (*mangled)++; - } - else - { - if (**mangled < '0' || **mangled > '9') - return -1; - - idx = **mangled - '0'; - (*mangled)++; - } - - return idx; -} - -/* C is the code for a type-qualifier. Return the TYPE_QUAL - corresponding to this qualifier. */ - -static int -code_for_qualifier (c) - int c; -{ - switch (c) - { - case 'C': - return TYPE_QUAL_CONST; - - case 'V': - return TYPE_QUAL_VOLATILE; - - case 'u': - return TYPE_QUAL_RESTRICT; - - default: - break; - } - - /* C was an invalid qualifier. */ - abort (); -} - -/* Return the string corresponding to the qualifiers given by - TYPE_QUALS. */ - -static const char* -qualifier_string (type_quals) - int type_quals; -{ - switch (type_quals) - { - case TYPE_UNQUALIFIED: - return ""; - - case TYPE_QUAL_CONST: - return "const"; - - case TYPE_QUAL_VOLATILE: - return "volatile"; - - case TYPE_QUAL_RESTRICT: - return "__restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE: - return "const volatile"; - - case TYPE_QUAL_CONST | TYPE_QUAL_RESTRICT: - return "const __restrict"; - - case TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "volatile __restrict"; - - case TYPE_QUAL_CONST | TYPE_QUAL_VOLATILE | TYPE_QUAL_RESTRICT: - return "const volatile __restrict"; - - default: - break; - } - - /* TYPE_QUALS was an invalid qualifier set. */ - abort (); -} - -/* C is the code for a type-qualifier. Return the string - corresponding to this qualifier. This function should only be - called with a valid qualifier code. */ - -static const char* -demangle_qualifier (c) - int c; -{ - return qualifier_string (code_for_qualifier (c)); -} - -int -cplus_demangle_opname (opname, result, options) - const char *opname; - char *result; - int options; -{ - int len, len1, ret; - string type; - struct work_stuff work[1]; - const char *tem; - - len = strlen(opname); - result[0] = '\0'; - ret = 0; - memset ((char *) work, 0, sizeof (work)); - work->options = options; - - if (opname[0] == '_' && opname[1] == '_' - && opname[2] == 'o' && opname[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = opname + 4; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - else if (opname[0] == '_' && opname[1] == '_' - && opname[2] >= 'a' && opname[2] <= 'z' - && opname[3] >= 'a' && opname[3] <= 'z') - { - if (opname[4] == '\0') - { - /* Operator. */ - size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, opname + 2, 2) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - else - { - if (opname[2] == 'a' && opname[5] == '\0') - { - /* Assignment. */ - size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, opname + 2, 3) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - } - else if (len >= 3 - && opname[0] == 'o' - && opname[1] == 'p' - && strchr (cplus_markers, opname[2]) != NULL) - { - /* see if it's an assignment expression */ - if (len >= 10 /* op$assign_ */ - && memcmp (opname + 3, "assign_", 7) == 0) - { - size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - len1 = len - 10; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 10, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - strcat (result, "="); - ret = 1; - break; - } - } - } - else - { - size_t i; - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - len1 = len - 3; - if ((int) strlen (optable[i].in) == len1 - && memcmp (optable[i].in, opname + 3, len1) == 0) - { - strcat (result, "operator"); - strcat (result, optable[i].out); - ret = 1; - break; - } - } - } - } - else if (len >= 5 && memcmp (opname, "type", 4) == 0 - && strchr (cplus_markers, opname[4]) != NULL) - { - /* type conversion operator */ - tem = opname + 5; - if (do_type (work, &tem, &type)) - { - strcat (result, "operator "); - strncat (result, type.b, type.p - type.b); - string_delete (&type); - ret = 1; - } - } - squangle_mop_up (work); - return ret; - -} -/* Takes operator name as e.g. "++" and returns mangled - operator name (e.g. "postincrement_expr"), or NULL if not found. - - If OPTIONS & DMGL_ANSI == 1, return the ANSI name; - if OPTIONS & DMGL_ANSI == 0, return the old GNU name. */ - -const char * -cplus_mangle_opname (opname, options) - const char *opname; - int options; -{ - size_t i; - int len; - - len = strlen (opname); - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if ((int) strlen (optable[i].out) == len - && (options & DMGL_ANSI) == (optable[i].flags & DMGL_ANSI) - && memcmp (optable[i].out, opname, len) == 0) - return optable[i].in; - } - return (0); -} - -/* char *cplus_demangle (const char *mangled, int options) - - If MANGLED is a mangled function name produced by GNU C++, then - a pointer to a malloced string giving a C++ representation - of the name will be returned; otherwise NULL will be returned. - It is the caller's responsibility to free the string which - is returned. - - The OPTIONS arg may contain one or more of the following bits: - - DMGL_ANSI ANSI qualifiers such as `const' and `void' are - included. - DMGL_PARAMS Function parameters are included. - - For example, - - cplus_demangle ("foo__1Ai", DMGL_PARAMS) => "A::foo(int)" - cplus_demangle ("foo__1Ai", DMGL_PARAMS | DMGL_ANSI) => "A::foo(int)" - cplus_demangle ("foo__1Ai", 0) => "A::foo" - - cplus_demangle ("foo__1Afe", DMGL_PARAMS) => "A::foo(float,...)" - cplus_demangle ("foo__1Afe", DMGL_PARAMS | DMGL_ANSI)=> "A::foo(float,...)" - cplus_demangle ("foo__1Afe", 0) => "A::foo" - - Note that any leading underscores, or other such characters prepended by - the compilation system, are presumed to have already been stripped from - MANGLED. */ - -char * -cplus_demangle (mangled, options) - const char *mangled; - int options; -{ - char *ret; - struct work_stuff work[1]; - memset ((char *) work, 0, sizeof (work)); - work -> options = options; - if ((work -> options & DMGL_STYLE_MASK) == 0) - work -> options |= (int) current_demangling_style & DMGL_STYLE_MASK; - - ret = internal_cplus_demangle (work, mangled); - squangle_mop_up (work); - return (ret); -} - - -/* This function performs most of what cplus_demangle use to do, but - to be able to demangle a name with a B, K or n code, we need to - have a longer term memory of what types have been seen. The original - now intializes and cleans up the squangle code info, while internal - calls go directly to this routine to avoid resetting that info. */ - -static char * -internal_cplus_demangle (work, mangled) - struct work_stuff *work; - const char *mangled; -{ - - string decl; - int success = 0; - char *demangled = NULL; - int s1,s2,s3,s4; - s1 = work->constructor; - s2 = work->destructor; - s3 = work->static_type; - s4 = work->type_quals; - work->constructor = work->destructor = 0; - work->type_quals = TYPE_UNQUALIFIED; - work->dllimported = 0; - - if ((mangled != NULL) && (*mangled != '\0')) - { - string_init (&decl); - - /* First check to see if gnu style demangling is active and if the - string to be demangled contains a CPLUS_MARKER. If so, attempt to - recognize one of the gnu special forms rather than looking for a - standard prefix. In particular, don't worry about whether there - is a "__" string in the mangled string. Consider "_$_5__foo" for - example. */ - - if ((AUTO_DEMANGLING || GNU_DEMANGLING)) - { - success = gnu_special (work, &mangled, &decl); - } - if (!success) - { - success = demangle_prefix (work, &mangled, &decl); - } - if (success && (*mangled != '\0')) - { - success = demangle_signature (work, &mangled, &decl); - } - if (work->constructor == 2) - { - string_prepend (&decl, "global constructors keyed to "); - work->constructor = 0; - } - else if (work->destructor == 2) - { - string_prepend (&decl, "global destructors keyed to "); - work->destructor = 0; - } - else if (work->dllimported == 1) - { - string_prepend (&decl, "import stub for "); - work->dllimported = 0; - } - demangled = mop_up (work, &decl, success); - } - work->constructor = s1; - work->destructor = s2; - work->static_type = s3; - work->type_quals = s4; - return (demangled); -} - - -/* Clear out and squangling related storage */ -static void -squangle_mop_up (work) - struct work_stuff *work; -{ - /* clean up the B and K type mangling types. */ - forget_B_and_K_types (work); - if (work -> btypevec != NULL) - { - free ((char *) work -> btypevec); - } - if (work -> ktypevec != NULL) - { - free ((char *) work -> ktypevec); - } -} - -/* Clear out any mangled storage */ - -static char * -mop_up (work, declp, success) - struct work_stuff *work; - string *declp; - int success; -{ - char *demangled = NULL; - - /* Discard the remembered types, if any. */ - - forget_types (work); - if (work -> typevec != NULL) - { - free ((char *) work -> typevec); - work -> typevec = NULL; - } - if (work->tmpl_argvec) - { - int i; - - for (i = 0; i < work->ntmpl_args; i++) - if (work->tmpl_argvec[i]) - free ((char*) work->tmpl_argvec[i]); - - free ((char*) work->tmpl_argvec); - work->tmpl_argvec = NULL; - } - if (work->previous_argument) - { - string_delete (work->previous_argument); - free ((char*) work->previous_argument); - work->previous_argument = NULL; - } - - /* If demangling was successful, ensure that the demangled string is null - terminated and return it. Otherwise, free the demangling decl. */ - - if (!success) - { - string_delete (declp); - } - else - { - string_appendn (declp, "", 1); - demangled = declp -> b; - } - return (demangled); -} - -/* - -LOCAL FUNCTION - - demangle_signature -- demangle the signature part of a mangled name - -SYNOPSIS - - static int - demangle_signature (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the signature portion of the mangled name. - - DECLP is the string where demangled output is being built. At - entry it contains the demangled root name from the mangled name - prefix. I.E. either a demangled operator name or the root function - name. In some special cases, it may contain nothing. - - *MANGLED points to the current unconsumed location in the mangled - name. As tokens are consumed and demangling is performed, the - pointer is updated to continuously point at the next token to - be consumed. - - Demangling GNU style mangled names is nasty because there is no - explicit token that marks the start of the outermost function - argument list. */ - -static int -demangle_signature (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - int func_done = 0; - int expect_func = 0; - int expect_return_type = 0; - const char *oldmangled = NULL; - string trawname; - string tname; - - while (success && (**mangled != '\0')) - { - switch (**mangled) - { - case 'Q': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (success) - remember_type (work, oldmangled, *mangled - oldmangled); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - expect_func = 1; - oldmangled = NULL; - break; - - case 'K': - oldmangled = *mangled; - success = demangle_qualified (work, mangled, declp, 1, 0); - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'S': - /* Static member function */ - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - (*mangled)++; - work -> static_type = 1; - break; - - case 'C': - case 'V': - case 'u': - work->type_quals |= code_for_qualifier (**mangled); - - /* a qualified member function */ - if (oldmangled == NULL) - oldmangled = *mangled; - (*mangled)++; - break; - - case 'L': - /* Local class name follows after "Lnnn_" */ - if (HP_DEMANGLING) - { - while (**mangled && (**mangled != '_')) - (*mangled)++; - if (!**mangled) - success = 0; - else - (*mangled)++; - } - else - success = 0; - break; - - case '0': case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - work->temp_start = -1; /* uppermost call to demangle_class */ - success = demangle_class (work, mangled, declp); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - if (AUTO_DEMANGLING || GNU_DEMANGLING || EDG_DEMANGLING) - { - /* EDG and others will have the "F", so we let the loop cycle - if we are looking at one. */ - if (**mangled != 'F') - expect_func = 1; - } - oldmangled = NULL; - break; - - case 'B': - { - string s; - success = do_type (work, mangled, &s); - if (success) - { - string_append (&s, SCOPE_STRING (work)); - string_prepends (declp, &s); - } - oldmangled = NULL; - expect_func = 1; - } - break; - - case 'F': - /* Function */ - /* ARM/HP style demangling includes a specific 'F' character after - the class name. For GNU style, it is just implied. So we can - safely just consume any 'F' at this point and be compatible - with either style. */ - - oldmangled = NULL; - func_done = 1; - (*mangled)++; - - /* For lucid/ARM/HP style we have to forget any types we might - have remembered up to this point, since they were not argument - types. GNU style considers all types seen as available for - back references. See comment in demangle_args() */ - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* After picking off the function args, we expect to either - find the function return type (preceded by an '_') or the - end of the string. */ - if (success && (AUTO_DEMANGLING || EDG_DEMANGLING) && **mangled == '_') - { - ++(*mangled); - /* At this level, we do not care about the return type. */ - success = do_type (work, mangled, &tname); - string_delete (&tname); - } - - break; - - case 't': - /* G++ Template */ - string_init(&trawname); - string_init(&tname); - if (oldmangled == NULL) - { - oldmangled = *mangled; - } - success = demangle_template (work, mangled, &tname, - &trawname, 1, 1); - if (success) - { - remember_type (work, oldmangled, *mangled - oldmangled); - } - string_append (&tname, SCOPE_STRING (work)); - - string_prepends(declp, &tname); - if (work -> destructor & 1) - { - string_prepend (&trawname, "~"); - string_appends (declp, &trawname); - work->destructor -= 1; - } - if ((work->constructor & 1) || (work->destructor & 1)) - { - string_appends (declp, &trawname); - work->constructor -= 1; - } - string_delete(&trawname); - string_delete(&tname); - oldmangled = NULL; - expect_func = 1; - break; - - case '_': - if (GNU_DEMANGLING && expect_return_type) - { - /* Read the return type. */ - string return_type; - string_init (&return_type); - - (*mangled)++; - success = do_type (work, mangled, &return_type); - APPEND_BLANK (&return_type); - - string_prepends (declp, &return_type); - string_delete (&return_type); - break; - } - else - /* At the outermost level, we cannot have a return type specified, - so if we run into another '_' at this point we are dealing with - a mangled name that is either bogus, or has been mangled by - some algorithm we don't know how to deal with. So just - reject the entire demangling. */ - /* However, "_nnn" is an expected suffix for alternate entry point - numbered nnn for a function, with HP aCC, so skip over that - without reporting failure. pai/1997-09-04 */ - if (HP_DEMANGLING) - { - (*mangled)++; - while (**mangled && isdigit ((unsigned char)**mangled)) - (*mangled)++; - } - else - success = 0; - break; - - case 'H': - if (GNU_DEMANGLING) - { - /* A G++ template function. Read the template arguments. */ - success = demangle_template (work, mangled, declp, 0, 0, - 0); - if (!(work->constructor & 1)) - expect_return_type = 1; - (*mangled)++; - break; - } - else - /* fall through */ - {;} - - default: - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* Assume we have stumbled onto the first outermost function - argument token, and start processing args. */ - func_done = 1; - success = demangle_args (work, mangled, declp); - } - else - { - /* Non-GNU demanglers use a specific token to mark the start - of the outermost function argument tokens. Typically 'F', - for ARM/HP-demangling, for example. So if we find something - we are not prepared for, it must be an error. */ - success = 0; - } - break; - } - /* - if (AUTO_DEMANGLING || GNU_DEMANGLING) - */ - { - if (success && expect_func) - { - func_done = 1; - if (LUCID_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) - { - forget_types (work); - } - success = demangle_args (work, mangled, declp); - /* Since template include the mangling of their return types, - we must set expect_func to 0 so that we don't try do - demangle more arguments the next time we get here. */ - expect_func = 0; - } - } - } - if (success && !func_done) - { - if (AUTO_DEMANGLING || GNU_DEMANGLING) - { - /* With GNU style demangling, bar__3foo is 'foo::bar(void)', and - bar__3fooi is 'foo::bar(int)'. We get here when we find the - first case, and need to ensure that the '(void)' gets added to - the current declp. Note that with ARM/HP, the first case - represents the name of a static data member 'foo::bar', - which is in the current declp, so we leave it alone. */ - success = demangle_args (work, mangled, declp); - } - } - if (success && PRINT_ARG_TYPES) - { - if (work->static_type) - string_append (declp, " static"); - if (work->type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (declp); - string_append (declp, qualifier_string (work->type_quals)); - } - } - - return (success); -} - -#if 0 - -static int -demangle_method_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - return (success); -} - -#endif - -static int -demangle_template_template_parm (work, mangled, tname) - struct work_stuff *work; - const char **mangled; - string *tname; -{ - int i; - int r; - int need_comma = 0; - int success = 1; - string temp; - - string_append (tname, "template <"); - /* get size of template parameter list */ - if (get_count (mangled, &r)) - { - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - string_append (tname, "class"); - } - /* z for template parameters */ - else if (**mangled == 'z') - { - (*mangled)++; - success = - demangle_template_template_parm (work, mangled, tname); - if (!success) - { - break; - } - } - else - { - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - } - string_delete(&temp); - if (!success) - { - break; - } - } - need_comma = 1; - } - - } - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, "> class"); - return (success); -} - -static int -demangle_integral_value (work, mangled, s) - struct work_stuff *work; - const char** mangled; - string* s; -{ - int success; - - if (**mangled == 'E') - { - int need_operator = 0; - - success = 1; - string_appendn (s, "(", 1); - (*mangled)++; - while (success && **mangled != 'W' && **mangled != '\0') - { - if (need_operator) - { - size_t i; - size_t len; - - success = 0; - - len = strlen (*mangled); - - for (i = 0; - i < sizeof (optable) / sizeof (optable [0]); - ++i) - { - size_t l = strlen (optable[i].in); - - if (l <= len - && memcmp (optable[i].in, *mangled, l) == 0) - { - string_appendn (s, " ", 1); - string_append (s, optable[i].out); - string_appendn (s, " ", 1); - success = 1; - (*mangled) += l; - break; - } - } - - if (!success) - break; - } - else - need_operator = 1; - - success = demangle_template_value_parm (work, mangled, s, - tk_integral); - } - - if (**mangled != 'W') - success = 0; - else - { - string_appendn (s, ")", 1); - (*mangled)++; - } - } - else if (**mangled == 'Q' || **mangled == 'K') - success = demangle_qualified (work, mangled, s, 0, 1); - else - { - success = 0; - - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - success = 1; - } - } - - return success; -} - -static int -demangle_template_value_parm (work, mangled, s, tk) - struct work_stuff *work; - const char **mangled; - string* s; - type_kind_t tk; -{ - int success = 1; - - if (**mangled == 'Y') - { - /* The next argument is a template parameter. */ - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return -1; - if (work->tmpl_argvec) - string_append (s, work->tmpl_argvec[idx]); - else - { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (s, buf); - } - } - else if (tk == tk_integral) - success = demangle_integral_value (work, mangled, s); - else if (tk == tk_char) - { - char tmp[2]; - int val; - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - string_appendn (s, "'", 1); - val = consume_count(mangled); - if (val <= 0) - success = 0; - else - { - tmp[0] = (char)val; - tmp[1] = '\0'; - string_appendn (s, &tmp[0], 1); - string_appendn (s, "'", 1); - } - } - else if (tk == tk_bool) - { - int val = consume_count (mangled); - if (val == 0) - string_appendn (s, "false", 5); - else if (val == 1) - string_appendn (s, "true", 4); - else - success = 0; - } - else if (tk == tk_real) - { - if (**mangled == 'm') - { - string_appendn (s, "-", 1); - (*mangled)++; - } - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - if (**mangled == '.') /* fraction */ - { - string_appendn (s, ".", 1); - (*mangled)++; - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - if (**mangled == 'e') /* exponent */ - { - string_appendn (s, "e", 1); - (*mangled)++; - while (isdigit ((unsigned char)**mangled)) - { - string_appendn (s, *mangled, 1); - (*mangled)++; - } - } - } - else if (tk == tk_pointer || tk == tk_reference) - { - int symbol_len = consume_count (mangled); - if (symbol_len == -1) - return -1; - if (symbol_len == 0) - string_appendn (s, "0", 1); - else - { - char *p = xmalloc (symbol_len + 1), *q; - strncpy (p, *mangled, symbol_len); - p [symbol_len] = '\0'; - /* We use cplus_demangle here, rather than - internal_cplus_demangle, because the name of the entity - mangled here does not make use of any of the squangling - or type-code information we have built up thus far; it is - mangled independently. */ - q = cplus_demangle (p, work->options); - if (tk == tk_pointer) - string_appendn (s, "&", 1); - /* FIXME: Pointer-to-member constants should get a - qualifying class name here. */ - if (q) - { - string_append (s, q); - free (q); - } - else - string_append (s, p); - free (p); - } - *mangled += symbol_len; - } - - return success; -} - -/* Demangle the template name in MANGLED. The full name of the - template (e.g., S<int>) is placed in TNAME. The name without the - template parameters (e.g. S) is placed in TRAWNAME if TRAWNAME is - non-NULL. If IS_TYPE is nonzero, this template is a type template, - not a function template. If both IS_TYPE and REMEMBER are nonzero, - the tmeplate is remembered in the list of back-referenceable - types. */ - -static int -demangle_template (work, mangled, tname, trawname, is_type, remember) - struct work_stuff *work; - const char **mangled; - string *tname; - string *trawname; - int is_type; - int remember; -{ - int i; - int r; - int need_comma = 0; - int success = 0; - const char *start; - string temp; - int bindex = 0; - - (*mangled)++; - if (is_type) - { - if (remember) - bindex = register_Btype (work); - start = *mangled; - /* get template name */ - if (**mangled == 'z') - { - int idx; - (*mangled)++; - (*mangled)++; - - idx = consume_count_with_underscores (mangled); - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - return (0); - - if (work->tmpl_argvec) - { - string_append (tname, work->tmpl_argvec[idx]); - if (trawname) - string_append (trawname, work->tmpl_argvec[idx]); - } - else - { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (tname, buf); - if (trawname) - string_append (trawname, buf); - } - } - else - { - if ((r = consume_count (mangled)) <= 0 - || (int) strlen (*mangled) < r) - { - return (0); - } - string_appendn (tname, *mangled, r); - if (trawname) - string_appendn (trawname, *mangled, r); - *mangled += r; - } - } - string_append (tname, "<"); - /* get size of template parameter list */ - if (!get_count (mangled, &r)) - { - return (0); - } - if (!is_type) - { - /* Create an array for saving the template argument values. */ - work->tmpl_argvec = (char**) xmalloc (r * sizeof (char *)); - work->ntmpl_args = r; - for (i = 0; i < r; i++) - work->tmpl_argvec[i] = 0; - } - for (i = 0; i < r; i++) - { - if (need_comma) - { - string_append (tname, ", "); - } - /* Z for type parameters */ - if (**mangled == 'Z') - { - (*mangled)++; - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - if (success) - { - string_appends (tname, &temp); - - if (!is_type) - { - /* Save the template argument. */ - int len = temp.p - temp.b; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], temp.b, len); - work->tmpl_argvec[i][len] = '\0'; - } - } - string_delete(&temp); - if (!success) - { - break; - } - } - /* z for template parameters */ - else if (**mangled == 'z') - { - int r2; - (*mangled)++; - success = demangle_template_template_parm (work, mangled, tname); - - if (success - && (r2 = consume_count (mangled)) > 0 - && (int) strlen (*mangled) >= r2) - { - string_append (tname, " "); - string_appendn (tname, *mangled, r2); - if (!is_type) - { - /* Save the template argument. */ - int len = r2; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], *mangled, len); - work->tmpl_argvec[i][len] = '\0'; - } - *mangled += r2; - } - if (!success) - { - break; - } - } - else - { - string param; - string* s; - - /* otherwise, value parameter */ - - /* temp is initialized in do_type */ - success = do_type (work, mangled, &temp); - string_delete(&temp); - if (!success) - break; - - if (!is_type) - { - s = ¶m; - string_init (s); - } - else - s = tname; - - success = demangle_template_value_parm (work, mangled, s, - (type_kind_t) success); - - if (!success) - { - if (!is_type) - string_delete (s); - success = 0; - break; - } - - if (!is_type) - { - int len = s->p - s->b; - work->tmpl_argvec[i] = xmalloc (len + 1); - memcpy (work->tmpl_argvec[i], s->b, len); - work->tmpl_argvec[i][len] = '\0'; - - string_appends (tname, s); - string_delete (s); - } - } - need_comma = 1; - } - { - if (tname->p[-1] == '>') - string_append (tname, " "); - string_append (tname, ">"); - } - - if (is_type && remember) - remember_Btype (work, tname->b, LEN_STRING (tname), bindex); - - /* - if (work -> static_type) - { - string_append (declp, *mangled + 1); - *mangled += strlen (*mangled); - success = 1; - } - else - { - success = demangle_args (work, mangled, declp); - } - } - */ - return (success); -} - -static int -arm_pt (work, mangled, n, anchor, args) - struct work_stuff *work; - const char *mangled; - int n; - const char **anchor, **args; -{ - /* Check if ARM template with "__pt__" in it ("parameterized type") */ - /* Allow HP also here, because HP's cfront compiler follows ARM to some extent */ - if ((ARM_DEMANGLING || HP_DEMANGLING) && (*anchor = mystrstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - if (AUTO_DEMANGLING || EDG_DEMANGLING) - { - if ((*anchor = mystrstr (mangled, "__tm__")) - || (*anchor = mystrstr (mangled, "__ps__")) - || (*anchor = mystrstr (mangled, "__pt__"))) - { - int len; - *args = *anchor + 6; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - else if ((*anchor = mystrstr (mangled, "__S"))) - { - int len; - *args = *anchor + 3; - len = consume_count (args); - if (len == -1) - return 0; - if (*args + len == mangled + n && **args == '_') - { - ++*args; - return 1; - } - } - } - - return 0; -} - -static void -demangle_arm_hp_template (work, mangled, n, declp) - struct work_stuff *work; - const char **mangled; - int n; - string *declp; -{ - const char *p; - const char *args; - const char *e = *mangled + n; - string arg; - - /* Check for HP aCC template spec: classXt1t2 where t1, t2 are - template args */ - if (HP_DEMANGLING && ((*mangled)[n] == 'X')) - { - char *start_spec_args = NULL; - - /* First check for and omit template specialization pseudo-arguments, - such as in "Spec<#1,#1.*>" */ - start_spec_args = strchr (*mangled, '<'); - if (start_spec_args && (start_spec_args - *mangled < n)) - string_appendn (declp, *mangled, start_spec_args - *mangled); - else - string_appendn (declp, *mangled, n); - (*mangled) += n + 1; - string_init (&arg); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - string_append (declp, "<"); - while (1) - { - string_clear (&arg); - switch (**mangled) - { - case 'T': - /* 'T' signals a type parameter */ - (*mangled)++; - if (!do_type (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'U': - case 'S': - /* 'U' or 'S' signals an integral value */ - if (!do_hpacc_template_const_value (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - case 'A': - /* 'A' signals a named constant expression (literal) */ - if (!do_hpacc_template_literal (work, mangled, &arg)) - goto hpacc_template_args_done; - break; - - default: - /* Today, 1997-09-03, we have only the above types - of template parameters */ - /* FIXME: maybe this should fail and return null */ - goto hpacc_template_args_done; - } - string_appends (declp, &arg); - /* Check if we're at the end of template args. - 0 if at end of static member of template class, - _ if done with template args for a function */ - if ((**mangled == '\000') || (**mangled == '_')) - break; - else - string_append (declp, ","); - } - hpacc_template_args_done: - string_append (declp, ">"); - string_delete (&arg); - if (**mangled == '_') - (*mangled)++; - return; - } - /* ARM template? (Also handles HP cfront extensions) */ - else if (arm_pt (work, *mangled, n, &p, &args)) - { - string type_str; - - string_init (&arg); - string_appendn (declp, *mangled, p - *mangled); - if (work->temp_start == -1) /* non-recursive call */ - work->temp_start = declp->p - declp->b; - string_append (declp, "<"); - /* should do error checking here */ - while (args < e) { - string_clear (&arg); - - /* Check for type or literal here */ - switch (*args) - { - /* HP cfront extensions to ARM for template args */ - /* spec: Xt1Lv1 where t1 is a type, v1 is a literal value */ - /* FIXME: We handle only numeric literals for HP cfront */ - case 'X': - /* A typed constant value follows */ - args++; - if (!do_type (work, &args, &type_str)) - goto cfront_template_args_done; - string_append (&arg, "("); - string_appends (&arg, &type_str); - string_append (&arg, ")"); - if (*args != 'L') - goto cfront_template_args_done; - args++; - /* Now snarf a literal value following 'L' */ - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - - case 'L': - /* Snarf a literal following 'L' */ - args++; - if (!snarf_numeric_literal (&args, &arg)) - goto cfront_template_args_done; - break; - default: - /* Not handling other HP cfront stuff */ - if (!do_type (work, &args, &arg)) - goto cfront_template_args_done; - } - string_appends (declp, &arg); - string_append (declp, ","); - } - cfront_template_args_done: - string_delete (&arg); - if (args >= e) - --declp->p; /* remove extra comma */ - string_append (declp, ">"); - } - else if (n>10 && strncmp (*mangled, "_GLOBAL_", 8) == 0 - && (*mangled)[9] == 'N' - && (*mangled)[8] == (*mangled)[10] - && strchr (cplus_markers, (*mangled)[8])) - { - /* A member of the anonymous namespace. */ - string_append (declp, "{anonymous}"); - } - else - { - if (work->temp_start == -1) /* non-recursive call only */ - work->temp_start = 0; /* disable in recursive calls */ - string_appendn (declp, *mangled, n); - } - *mangled += n; -} - -/* Extract a class name, possibly a template with arguments, from the - mangled string; qualifiers, local class indicators, etc. have - already been dealt with */ - -static int -demangle_class_name (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 0; - - n = consume_count (mangled); - if (n == -1) - return 0; - if ((int) strlen (*mangled) >= n) - { - demangle_arm_hp_template (work, mangled, n, declp); - success = 1; - } - - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_class -- demangle a mangled class sequence - -SYNOPSIS - - static int - demangle_class (struct work_stuff *work, const char **mangled, - strint *declp) - -DESCRIPTION - - DECLP points to the buffer into which demangling is being done. - - *MANGLED points to the current token to be demangled. On input, - it points to a mangled class (I.E. "3foo", "13verylongclass", etc.) - On exit, it points to the next token after the mangled class on - success, or the first unconsumed token on failure. - - If the CONSTRUCTOR or DESTRUCTOR flags are set in WORK, then - we are demangling a constructor or destructor. In this case - we prepend "class::class" or "class::~class" to DECLP. - - Otherwise, we prepend "class::" to the current DECLP. - - Reset the constructor/destructor flags once they have been - "consumed". This allows demangle_class to be called later during - the same demangling, to do normal class demangling. - - Returns 1 if demangling is successful, 0 otherwise. - -*/ - -static int -demangle_class (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 0; - int btype; - string class_name; - char *save_class_name_end = 0; - - string_init (&class_name); - btype = register_Btype (work); - if (demangle_class_name (work, mangled, &class_name)) - { - save_class_name_end = class_name.p; - if ((work->constructor & 1) || (work->destructor & 1)) - { - /* adjust so we don't include template args */ - if (work->temp_start && (work->temp_start != -1)) - { - class_name.p = class_name.b + work->temp_start; - } - string_prepends (declp, &class_name); - if (work -> destructor & 1) - { - string_prepend (declp, "~"); - work -> destructor -= 1; - } - else - { - work -> constructor -= 1; - } - } - class_name.p = save_class_name_end; - remember_Ktype (work, class_name.b, LEN_STRING(&class_name)); - remember_Btype (work, class_name.b, LEN_STRING(&class_name), btype); - string_prepend (declp, SCOPE_STRING (work)); - string_prepends (declp, &class_name); - success = 1; - } - string_delete (&class_name); - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_prefix -- consume the mangled name prefix and find signature - -SYNOPSIS - - static int - demangle_prefix (struct work_stuff *work, const char **mangled, - string *declp); - -DESCRIPTION - - Consume and demangle the prefix of the mangled name. - - DECLP points to the string buffer into which demangled output is - placed. On entry, the buffer is empty. On exit it contains - the root function name, the demangled operator name, or in some - special cases either nothing or the completely demangled result. - - MANGLED points to the current pointer into the mangled name. As each - token of the mangled name is consumed, it is updated. Upon entry - the current mangled name pointer points to the first character of - the mangled name. Upon exit, it should point to the first character - of the signature if demangling was successful, or to the first - unconsumed character if demangling of the prefix was unsuccessful. - - Returns 1 on success, 0 otherwise. - */ - -static int -demangle_prefix (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int success = 1; - const char *scan; - int i; - - if (strlen(*mangled) > 6 - && (strncmp(*mangled, "_imp__", 6) == 0 - || strncmp(*mangled, "__imp_", 6) == 0)) - { - /* it's a symbol imported from a PE dynamic library. Check for both - new style prefix _imp__ and legacy __imp_ used by older versions - of dlltool. */ - (*mangled) += 6; - work->dllimported = 1; - } - else if (strlen(*mangled) >= 11 && strncmp(*mangled, "_GLOBAL_", 8) == 0) - { - char *marker = strchr (cplus_markers, (*mangled)[8]); - if (marker != NULL && *marker == (*mangled)[10]) - { - if ((*mangled)[9] == 'D') - { - /* it's a GNU global destructor to be executed at program exit */ - (*mangled) += 11; - work->destructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - else if ((*mangled)[9] == 'I') - { - /* it's a GNU global constructor to be executed at program init */ - (*mangled) += 11; - work->constructor = 2; - if (gnu_special (work, mangled, declp)) - return success; - } - } - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__std__", 7) == 0) - { - /* it's a ARM global destructor to be executed at program exit */ - (*mangled) += 7; - work->destructor = 2; - } - else if ((ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) && strncmp(*mangled, "__sti__", 7) == 0) - { - /* it's a ARM global constructor to be executed at program initial */ - (*mangled) += 7; - work->constructor = 2; - } - - /* This block of code is a reduction in strength time optimization - of: - scan = mystrstr (*mangled, "__"); */ - - { - scan = *mangled; - - do { - scan = strchr (scan, '_'); - } while (scan != NULL && *++scan != '_'); - - if (scan != NULL) --scan; - } - - if (scan != NULL) - { - /* We found a sequence of two or more '_', ensure that we start at - the last pair in the sequence. */ - i = strspn (scan, "_"); - if (i > 2) - { - scan += (i - 2); - } - } - - if (scan == NULL) - { - success = 0; - } - else if (work -> static_type) - { - if (!isdigit ((unsigned char)scan[0]) && (scan[0] != 't')) - { - success = 0; - } - } - else if ((scan == *mangled) - && (isdigit ((unsigned char)scan[2]) || (scan[2] == 'Q') - || (scan[2] == 't') || (scan[2] == 'K') || (scan[2] == 'H'))) - { - /* The ARM says nothing about the mangling of local variables. - But cfront mangles local variables by prepending __<nesting_level> - to them. As an extension to ARM demangling we handle this case. */ - if ((LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING) - && isdigit ((unsigned char)scan[2])) - { - *mangled = scan + 2; - consume_count (mangled); - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - else - { - /* A GNU style constructor starts with __[0-9Qt]. But cfront uses - names like __Q2_3foo3bar for nested type names. So don't accept - this style of constructor for cfront demangling. A GNU - style member-template constructor starts with 'H'. */ - if (!(LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING)) - work -> constructor += 1; - *mangled = scan + 2; - } - } - else if (ARM_DEMANGLING && scan[2] == 'p' && scan[3] == 't') - { - /* Cfront-style parameterized type. Handled later as a signature. */ - success = 1; - - /* ARM template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if (EDG_DEMANGLING && ((scan[2] == 't' && scan[3] == 'm') - || (scan[2] == 'p' && scan[3] == 's') - || (scan[2] == 'p' && scan[3] == 't'))) - { - /* EDG-style parameterized type. Handled later as a signature. */ - success = 1; - - /* EDG template? */ - demangle_arm_hp_template (work, mangled, strlen (*mangled), declp); - } - else if ((scan == *mangled) && !isdigit ((unsigned char)scan[2]) - && (scan[2] != 't')) - { - /* Mangled name starts with "__". Skip over any leading '_' characters, - then find the next "__" that separates the prefix from the signature. - */ - if (!(ARM_DEMANGLING || LUCID_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - || (arm_special (mangled, declp) == 0)) - { - while (*scan == '_') - { - scan++; - } - if ((scan = mystrstr (scan, "__")) == NULL || (*(scan + 2) == '\0')) - { - /* No separator (I.E. "__not_mangled"), or empty signature - (I.E. "__not_mangled_either__") */ - success = 0; - } - else - { - const char *tmp; - - /* Look for the LAST occurrence of __, allowing names to - have the '__' sequence embedded in them. */ - if (!(ARM_DEMANGLING || HP_DEMANGLING)) - { - while ((tmp = mystrstr (scan + 2, "__")) != NULL) - scan = tmp; - } - if (*(scan + 2) == '\0') - success = 0; - else - demangle_function_name (work, mangled, declp, scan); - } - } - } - else if (*(scan + 2) != '\0') - { - /* Mangled name does not start with "__" but does have one somewhere - in there with non empty stuff after it. Looks like a global - function name. */ - demangle_function_name (work, mangled, declp, scan); - } - else - { - /* Doesn't look like a mangled name */ - success = 0; - } - - if (!success && (work->constructor == 2 || work->destructor == 2)) - { - string_append (declp, *mangled); - *mangled += strlen (*mangled); - success = 1; - } - return (success); -} - -/* - -LOCAL FUNCTION - - gnu_special -- special handling of gnu mangled strings - -SYNOPSIS - - static int - gnu_special (struct work_stuff *work, const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special GNU style mangling forms that don't fit - the normal pattern. For example: - - _$_3foo (destructor for class foo) - _vt$foo (foo virtual table) - _vt$foo$bar (foo::bar virtual table) - __vt_foo (foo virtual table, new style with thunks) - _3foo$varname (static data member) - _Q22rs2tu$vw (static data member) - __t6vector1Zii (constructor with template) - __thunk_4__$_7ostream (virtual function thunk) - */ - -static int -gnu_special (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *p; - - if ((*mangled)[0] == '_' - && strchr (cplus_markers, (*mangled)[1]) != NULL - && (*mangled)[2] == '_') - { - /* Found a GNU style destructor, get past "_<CPLUS_MARKER>_" */ - (*mangled) += 3; - work -> destructor += 1; - } - else if ((*mangled)[0] == '_' - && (((*mangled)[1] == '_' - && (*mangled)[2] == 'v' - && (*mangled)[3] == 't' - && (*mangled)[4] == '_') - || ((*mangled)[1] == 'v' - && (*mangled)[2] == 't' - && strchr (cplus_markers, (*mangled)[3]) != NULL))) - { - /* Found a GNU style virtual table, get past "_vt<CPLUS_MARKER>" - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - if ((*mangled)[2] == 'v') - (*mangled) += 5; /* New style, with thunks: "__vt_" */ - else - (*mangled) += 4; /* Old style, no thunks: "_vt<CPLUS_MARKER>" */ - while (**mangled != '\0') - { - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, - 1); - break; - default: - if (isdigit((unsigned char)*mangled[0])) - { - n = consume_count(mangled); - /* We may be seeing a too-large size, or else a - ".<digits>" indicating a static local symbol. In - any case, declare victory and move on; *don't* try - to use n to allocate. */ - if (n > (int) strlen (*mangled)) - { - success = 1; - break; - } - } - else - { - n = strcspn (*mangled, cplus_markers); - } - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - - p = strpbrk (*mangled, cplus_markers); - if (success && ((p == NULL) || (p == *mangled))) - { - if (p != NULL) - { - string_append (declp, SCOPE_STRING (work)); - (*mangled)++; - } - } - else - { - success = 0; - break; - } - } - if (success) - string_append (declp, " virtual table"); - } - else if ((*mangled)[0] == '_' - && (strchr("0123456789Qt", (*mangled)[1]) != NULL) - && (p = strpbrk (*mangled, cplus_markers)) != NULL) - { - /* static data member, "_3foo$varname" for example */ - (*mangled)++; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - n = consume_count (mangled); - if (n < 0 || n > strlen (*mangled)) - { - success = 0; - break; - } - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - if (success && (p == *mangled)) - { - /* Consumed everything up to the cplus_marker, append the - variable name. */ - (*mangled)++; - string_append (declp, SCOPE_STRING (work)); - n = strlen (*mangled); - string_appendn (declp, *mangled, n); - (*mangled) += n; - } - else - { - success = 0; - } - } - else if (strncmp (*mangled, "__thunk_", 8) == 0) - { - int delta; - - (*mangled) += 8; - delta = consume_count (mangled); - if (delta == -1) - success = 0; - else - { - char *method = internal_cplus_demangle (work, ++*mangled); - - if (method) - { - char buf[50]; - sprintf (buf, "virtual function thunk (delta:%d) for ", -delta); - string_append (declp, buf); - string_append (declp, method); - free (method); - n = strlen (*mangled); - (*mangled) += n; - } - else - { - success = 0; - } - } - } - else if (strncmp (*mangled, "__t", 3) == 0 - && ((*mangled)[3] == 'i' || (*mangled)[3] == 'f')) - { - p = (*mangled)[3] == 'i' ? " type_info node" : " type_info function"; - (*mangled) += 4; - switch (**mangled) - { - case 'Q': - case 'K': - success = demangle_qualified (work, mangled, declp, 0, 1); - break; - case 't': - success = demangle_template (work, mangled, declp, 0, 1, 1); - break; - default: - success = demangle_fund_type (work, mangled, declp); - break; - } - if (success && **mangled != '\0') - success = 0; - if (success) - string_append (declp, p); - } - else - { - success = 0; - } - return (success); -} - -static void -recursively_demangle(work, mangled, result, namelength) - struct work_stuff *work; - const char **mangled; - string *result; - int namelength; -{ - char * recurse = (char *)NULL; - char * recurse_dem = (char *)NULL; - - recurse = (char *) xmalloc (namelength + 1); - memcpy (recurse, *mangled, namelength); - recurse[namelength] = '\000'; - - recurse_dem = cplus_demangle (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, namelength); - } - free (recurse); - *mangled += namelength; -} - -/* - -LOCAL FUNCTION - - arm_special -- special handling of ARM/lucid mangled strings - -SYNOPSIS - - static int - arm_special (const char **mangled, - string *declp); - - -DESCRIPTION - - Process some special ARM style mangling forms that don't fit - the normal pattern. For example: - - __vtbl__3foo (foo virtual table) - __vtbl__3foo__3bar (bar::foo virtual table) - - */ - -static int -arm_special (mangled, declp) - const char **mangled; - string *declp; -{ - int n; - int success = 1; - const char *scan; - - if (strncmp (*mangled, ARM_VTABLE_STRING, ARM_VTABLE_STRLEN) == 0) - { - /* Found a ARM style virtual table, get past ARM_VTABLE_STRING - and create the decl. Note that we consume the entire mangled - input string, which means that demangle_signature has no work - to do. */ - scan = *mangled + ARM_VTABLE_STRLEN; - while (*scan != '\0') /* first check it can be demangled */ - { - n = consume_count (&scan); - if (n == -1) - { - return (0); /* no good */ - } - scan += n; - if (scan[0] == '_' && scan[1] == '_') - { - scan += 2; - } - } - (*mangled) += ARM_VTABLE_STRLEN; - while (**mangled != '\0') - { - n = consume_count (mangled); - if (n == -1 - || n > strlen (*mangled)) - return 0; - string_prependn (declp, *mangled, n); - (*mangled) += n; - if ((*mangled)[0] == '_' && (*mangled)[1] == '_') - { - string_prepend (declp, "::"); - (*mangled) += 2; - } - } - string_append (declp, " virtual table"); - } - else - { - success = 0; - } - return (success); -} - -/* - -LOCAL FUNCTION - - demangle_qualified -- demangle 'Q' qualified name strings - -SYNOPSIS - - static int - demangle_qualified (struct work_stuff *, const char *mangled, - string *result, int isfuncname, int append); - -DESCRIPTION - - Demangle a qualified name, such as "Q25Outer5Inner" which is - the mangled form of "Outer::Inner". The demangled output is - prepended or appended to the result string according to the - state of the append flag. - - If isfuncname is nonzero, then the qualified name we are building - is going to be used as a member function name, so if it is a - constructor or destructor function, append an appropriate - constructor or destructor name. I.E. for the above example, - the result for use as a constructor is "Outer::Inner::Inner" - and the result for use as a destructor is "Outer::Inner::~Inner". - -BUGS - - Numeric conversion is ASCII dependent (FIXME). - - */ - -static int -demangle_qualified (work, mangled, result, isfuncname, append) - struct work_stuff *work; - const char **mangled; - string *result; - int isfuncname; - int append; -{ - int qualifiers = 0; - int success = 1; - const char *p; - char num[2]; - string temp; - string last_name; - int bindex = register_Btype (work); - - /* We only make use of ISFUNCNAME if the entity is a constructor or - destructor. */ - isfuncname = (isfuncname - && ((work->constructor & 1) || (work->destructor & 1))); - - string_init (&temp); - string_init (&last_name); - - if ((*mangled)[0] == 'K') - { - /* Squangling qualified name reuse */ - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work -> numk) - success = 0; - else - string_append (&temp, work -> ktypevec[idx]); - } - else - switch ((*mangled)[1]) - { - case '_': - /* GNU mangled name with more than 9 classes. The count is preceded - by an underscore (to distinguish it from the <= 9 case) and followed - by an underscore. */ - p = *mangled + 2; - qualifiers = atoi (p); - if (!isdigit ((unsigned char)*p) || *p == '0') - success = 0; - - /* Skip the digits. */ - while (isdigit ((unsigned char)*p)) - ++p; - - if (*p != '_') - success = 0; - - *mangled = p + 1; - break; - - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - /* The count is in a single digit. */ - num[0] = (*mangled)[1]; - num[1] = '\0'; - qualifiers = atoi (num); - - /* If there is an underscore after the digit, skip it. This is - said to be for ARM-qualified names, but the ARM makes no - mention of such an underscore. Perhaps cfront uses one. */ - if ((*mangled)[2] == '_') - { - (*mangled)++; - } - (*mangled) += 2; - break; - - case '0': - default: - success = 0; - } - - if (!success) - return success; - - /* Pick off the names and collect them in the temp buffer in the order - in which they are found, separated by '::'. */ - - while (qualifiers-- > 0) - { - int remember_K = 1; - string_clear (&last_name); - - if (*mangled[0] == '_') - (*mangled)++; - - if (*mangled[0] == 't') - { - /* Here we always append to TEMP since we will want to use - the template name without the template parameters as a - constructor or destructor name. The appropriate - (parameter-less) value is returned by demangle_template - in LAST_NAME. We do not remember the template type here, - in order to match the G++ mangling algorithm. */ - success = demangle_template(work, mangled, &temp, - &last_name, 1, 0); - if (!success) - break; - } - else if (*mangled[0] == 'K') - { - int idx; - (*mangled)++; - idx = consume_count_with_underscores (mangled); - if (idx == -1 || idx >= work->numk) - success = 0; - else - string_append (&temp, work->ktypevec[idx]); - remember_K = 0; - - if (!success) break; - } - else - { - if (EDG_DEMANGLING) - { - int namelength; - /* Now recursively demangle the qualifier - * This is necessary to deal with templates in - * mangling styles like EDG */ - namelength = consume_count (mangled); - if (namelength == -1) - { - success = 0; - break; - } - recursively_demangle(work, mangled, &temp, namelength); - } - else - { - success = do_type (work, mangled, &last_name); - if (!success) - break; - string_appends (&temp, &last_name); - } - } - - if (remember_K) - remember_Ktype (work, temp.b, LEN_STRING (&temp)); - - if (qualifiers > 0) - string_append (&temp, SCOPE_STRING (work)); - } - - remember_Btype (work, temp.b, LEN_STRING (&temp), bindex); - - /* If we are using the result as a function name, we need to append - the appropriate '::' separated constructor or destructor name. - We do this here because this is the most convenient place, where - we already have a pointer to the name and the length of the name. */ - - if (isfuncname) - { - string_append (&temp, SCOPE_STRING (work)); - if (work -> destructor & 1) - string_append (&temp, "~"); - string_appends (&temp, &last_name); - } - - /* Now either prepend the temp buffer to the result, or append it, - depending upon the state of the append flag. */ - - if (append) - string_appends (result, &temp); - else - { - if (!STRING_EMPTY (result)) - string_append (&temp, SCOPE_STRING (work)); - string_prepends (result, &temp); - } - - string_delete (&last_name); - string_delete (&temp); - return (success); -} - -/* - -LOCAL FUNCTION - - get_count -- convert an ascii count to integer, consuming tokens - -SYNOPSIS - - static int - get_count (const char **type, int *count) - -DESCRIPTION - - Assume that *type points at a count in a mangled name; set - *count to its value, and set *type to the next character after - the count. There are some weird rules in effect here. - - If *type does not point at a string of digits, return zero. - - If *type points at a string of digits followed by an - underscore, set *count to their value as an integer, advance - *type to point *after the underscore, and return 1. - - If *type points at a string of digits not followed by an - underscore, consume only the first digit. Set *count to its - value as an integer, leave *type pointing after that digit, - and return 1. - - The excuse for this odd behavior: in the ARM and HP demangling - styles, a type can be followed by a repeat count of the form - `Nxy', where: - - `x' is a single digit specifying how many additional copies - of the type to append to the argument list, and - - `y' is one or more digits, specifying the zero-based index of - the first repeated argument in the list. Yes, as you're - unmangling the name you can figure this out yourself, but - it's there anyway. - - So, for example, in `bar__3fooFPiN51', the first argument is a - pointer to an integer (`Pi'), and then the next five arguments - are the same (`N5'), and the first repeat is the function's - second argument (`1'). -*/ - -static int -get_count (type, count) - const char **type; - int *count; -{ - const char *p; - int n; - - if (!isdigit ((unsigned char)**type)) - { - return (0); - } - else - { - *count = **type - '0'; - (*type)++; - if (isdigit ((unsigned char)**type)) - { - p = *type; - n = *count; - do - { - n *= 10; - n += *p - '0'; - p++; - } - while (isdigit ((unsigned char)*p)); - if (*p == '_') - { - *type = p + 1; - *count = n; - } - } - } - return (1); -} - -/* RESULT will be initialised here; it will be freed on failure. The - value returned is really a type_kind_t. */ - -static int -do_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int n; - int done; - int success; - string decl; - const char *remembered_type; - int type_quals; - string btype; - type_kind_t tk = tk_none; - - string_init (&btype); - string_init (&decl); - string_init (result); - - done = 0; - success = 1; - while (success && !done) - { - int member; - switch (**mangled) - { - - /* A pointer type */ - case 'P': - case 'p': - (*mangled)++; - string_prepend (&decl, "*"); - if (tk == tk_none) - tk = tk_pointer; - break; - - /* A reference type */ - case 'R': - (*mangled)++; - string_prepend (&decl, "&"); - if (tk == tk_none) - tk = tk_reference; - break; - - /* An array */ - case 'A': - { - ++(*mangled); - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - string_append (&decl, "["); - if (**mangled != '_') - success = demangle_template_value_parm (work, mangled, &decl, - tk_integral); - if (**mangled == '_') - ++(*mangled); - string_append (&decl, "]"); - break; - } - - /* A back reference to a previously seen type */ - case 'T': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> ntypes) - { - success = 0; - } - else - { - remembered_type = work -> typevec[n]; - mangled = &remembered_type; - } - break; - - /* A function */ - case 'F': - (*mangled)++; - if (!STRING_EMPTY (&decl) - && (decl.b[0] == '*' || decl.b[0] == '&')) - { - string_prepend (&decl, "("); - string_append (&decl, ")"); - } - /* After picking off the function args, we expect to either find the - function return type (preceded by an '_') or the end of the - string. */ - if (!demangle_nested_args (work, mangled, &decl) - || (**mangled != '_' && **mangled != '\0')) - { - success = 0; - break; - } - if (success && (**mangled == '_')) - (*mangled)++; - break; - - case 'M': - case 'O': - { - type_quals = TYPE_UNQUALIFIED; - - member = **mangled == 'M'; - (*mangled)++; - if (!isdigit ((unsigned char)**mangled) && **mangled != 't') - { - success = 0; - break; - } - - string_append (&decl, ")"); - string_prepend (&decl, SCOPE_STRING (work)); - if (isdigit ((unsigned char)**mangled)) - { - n = consume_count (mangled); - if (n == -1 - || (int) strlen (*mangled) < n) - { - success = 0; - break; - } - string_prependn (&decl, *mangled, n); - *mangled += n; - } - else - { - string temp; - string_init (&temp); - success = demangle_template (work, mangled, &temp, - NULL, 1, 1); - if (success) - { - string_prependn (&decl, temp.b, temp.p - temp.b); - string_clear (&temp); - } - else - break; - } - string_prepend (&decl, "("); - if (member) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - type_quals |= code_for_qualifier (**mangled); - (*mangled)++; - break; - - default: - break; - } - - if (*(*mangled)++ != 'F') - { - success = 0; - break; - } - } - if ((member && !demangle_nested_args (work, mangled, &decl)) - || **mangled != '_') - { - success = 0; - break; - } - (*mangled)++; - if (! PRINT_ANSI_QUALIFIERS) - { - break; - } - if (type_quals != TYPE_UNQUALIFIED) - { - APPEND_BLANK (&decl); - string_append (&decl, qualifier_string (type_quals)); - } - break; - } - case 'G': - (*mangled)++; - break; - - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (&decl)) - string_prepend (&decl, " "); - - string_prepend (&decl, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - /* - } - */ - - /* fall through */ - default: - done = 1; - break; - } - } - - if (success) switch (**mangled) - { - /* A qualified name, such as "Outer::Inner". */ - case 'Q': - case 'K': - { - success = demangle_qualified (work, mangled, result, 0, 1); - break; - } - - /* A back reference to a previously seen squangled type */ - case 'B': - (*mangled)++; - if (!get_count (mangled, &n) || n >= work -> numb) - success = 0; - else - string_append (result, work->btypevec[n]); - break; - - case 'X': - case 'Y': - /* A template parm. We substitute the corresponding argument. */ - { - int idx; - - (*mangled)++; - idx = consume_count_with_underscores (mangled); - - if (idx == -1 - || (work->tmpl_argvec && idx >= work->ntmpl_args) - || consume_count_with_underscores (mangled) == -1) - { - success = 0; - break; - } - - if (work->tmpl_argvec) - string_append (result, work->tmpl_argvec[idx]); - else - { - char buf[10]; - sprintf(buf, "T%d", idx); - string_append (result, buf); - } - - success = 1; - } - break; - - default: - success = demangle_fund_type (work, mangled, result); - if (tk == tk_none) - tk = (type_kind_t) success; - break; - } - - if (success) - { - if (!STRING_EMPTY (&decl)) - { - string_append (result, " "); - string_appends (result, &decl); - } - } - else - string_delete (result); - string_delete (&decl); - - if (success) - /* Assume an integral type, if we're not sure. */ - return (int) ((tk == tk_none) ? tk_integral : tk); - else - return 0; -} - -/* Given a pointer to a type string that represents a fundamental type - argument (int, long, unsigned int, etc) in TYPE, a pointer to the - string in which the demangled output is being built in RESULT, and - the WORK structure, decode the types and add them to the result. - - For example: - - "Ci" => "const int" - "Sl" => "signed long" - "CUs" => "const unsigned short" - - The value returned is really a type_kind_t. */ - -static int -demangle_fund_type (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int done = 0; - int success = 1; - char buf[10]; - int dec = 0; - string btype; - type_kind_t tk = tk_integral; - - string_init (&btype); - - /* First pick off any type qualifiers. There can be more than one. */ - - while (!done) - { - switch (**mangled) - { - case 'C': - case 'V': - case 'u': - if (PRINT_ANSI_QUALIFIERS) - { - if (!STRING_EMPTY (result)) - string_prepend (result, " "); - string_prepend (result, demangle_qualifier (**mangled)); - } - (*mangled)++; - break; - case 'U': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "unsigned"); - break; - case 'S': /* signed char only */ - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "signed"); - break; - case 'J': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "__complex"); - break; - default: - done = 1; - break; - } - } - - /* Now pick off the fundamental type. There can be only one. */ - - switch (**mangled) - { - case '\0': - case '_': - break; - case 'v': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "void"); - break; - case 'x': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long long"); - break; - case 'l': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long"); - break; - case 'i': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "int"); - break; - case 's': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "short"); - break; - case 'b': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "bool"); - tk = tk_bool; - break; - case 'c': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "char"); - tk = tk_char; - break; - case 'w': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "wchar_t"); - tk = tk_char; - break; - case 'r': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "long double"); - tk = tk_real; - break; - case 'd': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "double"); - tk = tk_real; - break; - case 'f': - (*mangled)++; - APPEND_BLANK (result); - string_append (result, "float"); - tk = tk_real; - break; - case 'G': - (*mangled)++; - if (!isdigit ((unsigned char)**mangled)) - { - success = 0; - break; - } - case 'I': - ++(*mangled); - if (**mangled == '_') - { - int i; - ++(*mangled); - for (i = 0; **mangled != '_'; ++(*mangled), ++i) - buf[i] = **mangled; - buf[i] = '\0'; - ++(*mangled); - } - else - { - strncpy (buf, *mangled, 2); - *mangled += 2; - } - sscanf (buf, "%x", &dec); - sprintf (buf, "int%i_t", dec); - APPEND_BLANK (result); - string_append (result, buf); - break; - - /* fall through */ - /* An explicit type, such as "6mytype" or "7integer" */ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - int bindex = register_Btype (work); - string btype; - string_init (&btype); - if (demangle_class_name (work, mangled, &btype)) { - remember_Btype (work, btype.b, LEN_STRING (&btype), bindex); - APPEND_BLANK (result); - string_appends (result, &btype); - } - else - success = 0; - string_delete (&btype); - break; - } - case 't': - { - success = demangle_template (work, mangled, &btype, 0, 1, 1); - string_appends (result, &btype); - break; - } - default: - success = 0; - break; - } - - return success ? ((int) tk) : 0; -} - - -/* Handle a template's value parameter for HP aCC (extension from ARM) - **mangled points to 'S' or 'U' */ - -static int -do_hpacc_template_const_value (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int unsigned_const; - - if (**mangled != 'U' && **mangled != 'S') - return 0; - - unsigned_const = (**mangled == 'U'); - - (*mangled)++; - - switch (**mangled) - { - case 'N': - string_append (result, "-"); - /* fall through */ - case 'P': - (*mangled)++; - break; - case 'M': - /* special case for -2^31 */ - string_append (result, "-2147483648"); - (*mangled)++; - return 1; - default: - return 0; - } - - /* We have to be looking at an integer now */ - if (!(isdigit ((unsigned char)**mangled))) - return 0; - - /* We only deal with integral values for template - parameters -- so it's OK to look only for digits */ - while (isdigit ((unsigned char)**mangled)) - { - char_str[0] = **mangled; - string_append (result, char_str); - (*mangled)++; - } - - if (unsigned_const) - string_append (result, "U"); - - /* FIXME? Some day we may have 64-bit (or larger :-) ) constants - with L or LL suffixes. pai/1997-09-03 */ - - return 1; /* success */ -} - -/* Handle a template's literal parameter for HP aCC (extension from ARM) - **mangled is pointing to the 'A' */ - -static int -do_hpacc_template_literal (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - int literal_len = 0; - char * recurse; - char * recurse_dem; - - if (**mangled != 'A') - return 0; - - (*mangled)++; - - literal_len = consume_count (mangled); - - if (literal_len <= 0) - return 0; - - /* Literal parameters are names of arrays, functions, etc. and the - canonical representation uses the address operator */ - string_append (result, "&"); - - /* Now recursively demangle the literal name */ - recurse = (char *) xmalloc (literal_len + 1); - memcpy (recurse, *mangled, literal_len); - recurse[literal_len] = '\000'; - - recurse_dem = cplus_demangle (recurse, work->options); - - if (recurse_dem) - { - string_append (result, recurse_dem); - free (recurse_dem); - } - else - { - string_appendn (result, *mangled, literal_len); - } - (*mangled) += literal_len; - free (recurse); - - return 1; -} - -static int -snarf_numeric_literal (args, arg) - const char ** args; - string * arg; -{ - if (**args == '-') - { - char_str[0] = '-'; - string_append (arg, char_str); - (*args)++; - } - else if (**args == '+') - (*args)++; - - if (!isdigit ((unsigned char)**args)) - return 0; - - while (isdigit ((unsigned char)**args)) - { - char_str[0] = **args; - string_append (arg, char_str); - (*args)++; - } - - return 1; -} - -/* Demangle the next argument, given by MANGLED into RESULT, which - *should be an uninitialized* string. It will be initialized here, - and free'd should anything go wrong. */ - -static int -do_arg (work, mangled, result) - struct work_stuff *work; - const char **mangled; - string *result; -{ - /* Remember where we started so that we can record the type, for - non-squangling type remembering. */ - const char *start = *mangled; - - string_init (result); - - if (work->nrepeats > 0) - { - --work->nrepeats; - - if (work->previous_argument == 0) - return 0; - - /* We want to reissue the previous type in this argument list. */ - string_appends (result, work->previous_argument); - return 1; - } - - if (**mangled == 'n') - { - /* A squangling-style repeat. */ - (*mangled)++; - work->nrepeats = consume_count(mangled); - - if (work->nrepeats <= 0) - /* This was not a repeat count after all. */ - return 0; - - if (work->nrepeats > 9) - { - if (**mangled != '_') - /* The repeat count should be followed by an '_' in this - case. */ - return 0; - else - (*mangled)++; - } - - /* Now, the repeat is all set up. */ - return do_arg (work, mangled, result); - } - - /* Save the result in WORK->previous_argument so that we can find it - if it's repeated. Note that saving START is not good enough: we - do not want to add additional types to the back-referenceable - type vector when processing a repeated type. */ - if (work->previous_argument) - string_clear (work->previous_argument); - else - { - work->previous_argument = (string*) xmalloc (sizeof (string)); - string_init (work->previous_argument); - } - - if (!do_type (work, mangled, work->previous_argument)) - return 0; - - string_appends (result, work->previous_argument); - - remember_type (work, start, *mangled - start); - return 1; -} - -static void -remember_type (work, start, len) - struct work_stuff *work; - const char *start; - int len; -{ - char *tem; - - if (work->forgetting_types) - return; - - if (work -> ntypes >= work -> typevec_size) - { - if (work -> typevec_size == 0) - { - work -> typevec_size = 3; - work -> typevec - = (char **) xmalloc (sizeof (char *) * work -> typevec_size); - } - else - { - work -> typevec_size *= 2; - work -> typevec - = (char **) xrealloc ((char *)work -> typevec, - sizeof (char *) * work -> typevec_size); - } - } - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> typevec[work -> ntypes++] = tem; -} - - -/* Remember a K type class qualifier. */ -static void -remember_Ktype (work, start, len) - struct work_stuff *work; - const char *start; - int len; -{ - char *tem; - - if (work -> numk >= work -> ksize) - { - if (work -> ksize == 0) - { - work -> ksize = 5; - work -> ktypevec - = (char **) xmalloc (sizeof (char *) * work -> ksize); - } - else - { - work -> ksize *= 2; - work -> ktypevec - = (char **) xrealloc ((char *)work -> ktypevec, - sizeof (char *) * work -> ksize); - } - } - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> ktypevec[work -> numk++] = tem; -} - -/* Register a B code, and get an index for it. B codes are registered - as they are seen, rather than as they are completed, so map<temp<char> > - registers map<temp<char> > as B0, and temp<char> as B1 */ - -static int -register_Btype (work) - struct work_stuff *work; -{ - int ret; - - if (work -> numb >= work -> bsize) - { - if (work -> bsize == 0) - { - work -> bsize = 5; - work -> btypevec - = (char **) xmalloc (sizeof (char *) * work -> bsize); - } - else - { - work -> bsize *= 2; - work -> btypevec - = (char **) xrealloc ((char *)work -> btypevec, - sizeof (char *) * work -> bsize); - } - } - ret = work -> numb++; - work -> btypevec[ret] = NULL; - return(ret); -} - -/* Store a value into a previously registered B code type. */ - -static void -remember_Btype (work, start, len, index) - struct work_stuff *work; - const char *start; - int len, index; -{ - char *tem; - - tem = xmalloc (len + 1); - memcpy (tem, start, len); - tem[len] = '\0'; - work -> btypevec[index] = tem; -} - -/* Lose all the info related to B and K type codes. */ -static void -forget_B_and_K_types (work) - struct work_stuff *work; -{ - int i; - - while (work -> numk > 0) - { - i = --(work -> numk); - if (work -> ktypevec[i] != NULL) - { - free (work -> ktypevec[i]); - work -> ktypevec[i] = NULL; - } - } - - while (work -> numb > 0) - { - i = --(work -> numb); - if (work -> btypevec[i] != NULL) - { - free (work -> btypevec[i]); - work -> btypevec[i] = NULL; - } - } -} -/* Forget the remembered types, but not the type vector itself. */ - -static void -forget_types (work) - struct work_stuff *work; -{ - int i; - - while (work -> ntypes > 0) - { - i = --(work -> ntypes); - if (work -> typevec[i] != NULL) - { - free (work -> typevec[i]); - work -> typevec[i] = NULL; - } - } -} - -/* Process the argument list part of the signature, after any class spec - has been consumed, as well as the first 'F' character (if any). For - example: - - "__als__3fooRT0" => process "RT0" - "complexfunc5__FPFPc_PFl_i" => process "PFPc_PFl_i" - - DECLP must be already initialised, usually non-empty. It won't be freed - on failure. - - Note that g++ differs significantly from ARM and lucid style mangling - with regards to references to previously seen types. For example, given - the source fragment: - - class foo { - public: - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic); - }; - - foo::foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - void foo (int, foo &ia, int, foo &ib, int, foo &ic) { ia = ib = ic; } - - g++ produces the names: - - __3fooiRT0iT2iT2 - foo__FiR3fooiT1iT1 - - while lcc (and presumably other ARM style compilers as well) produces: - - foo__FiR3fooT1T2T1T2 - __ct__3fooFiR3fooT1T2T1T2 - - Note that g++ bases its type numbers starting at zero and counts all - previously seen types, while lucid/ARM bases its type numbers starting - at one and only considers types after it has seen the 'F' character - indicating the start of the function args. For lucid/ARM style, we - account for this difference by discarding any previously seen types when - we see the 'F' character, and subtracting one from the type number - reference. - - */ - -static int -demangle_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - string arg; - int need_comma = 0; - int r; - int t; - const char *tem; - char temptype; - - if (PRINT_ARG_TYPES) - { - string_append (declp, "("); - if (**mangled == '\0') - { - string_append (declp, "void"); - } - } - - while ((**mangled != '_' && **mangled != '\0' && **mangled != 'e') - || work->nrepeats > 0) - { - if ((**mangled == 'N') || (**mangled == 'T')) - { - temptype = *(*mangled)++; - - if (temptype == 'N') - { - if (!get_count (mangled, &r)) - { - return (0); - } - } - else - { - r = 1; - } - if ((HP_DEMANGLING || ARM_DEMANGLING || EDG_DEMANGLING) && work -> ntypes >= 10) - { - /* If we have 10 or more types we might have more than a 1 digit - index so we'll have to consume the whole count here. This - will lose if the next thing is a type name preceded by a - count but it's impossible to demangle that case properly - anyway. Eg if we already have 12 types is T12Pc "(..., type1, - Pc, ...)" or "(..., type12, char *, ...)" */ - if ((t = consume_count(mangled)) <= 0) - { - return (0); - } - } - else - { - if (!get_count (mangled, &t)) - { - return (0); - } - } - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - t--; - } - /* Validate the type index. Protect against illegal indices from - malformed type strings. */ - if ((t < 0) || (t >= work -> ntypes)) - { - return (0); - } - while (work->nrepeats > 0 || --r >= 0) - { - tem = work -> typevec[t]; - if (need_comma && PRINT_ARG_TYPES) - { - string_append (declp, ", "); - } - if (!do_arg (work, &tem, &arg)) - { - return (0); - } - if (PRINT_ARG_TYPES) - { - string_appends (declp, &arg); - } - string_delete (&arg); - need_comma = 1; - } - } - else - { - if (need_comma && PRINT_ARG_TYPES) - string_append (declp, ", "); - if (!do_arg (work, mangled, &arg)) - return (0); - if (PRINT_ARG_TYPES) - string_appends (declp, &arg); - string_delete (&arg); - need_comma = 1; - } - } - - if (**mangled == 'e') - { - (*mangled)++; - if (PRINT_ARG_TYPES) - { - if (need_comma) - { - string_append (declp, ","); - } - string_append (declp, "..."); - } - } - - if (PRINT_ARG_TYPES) - { - string_append (declp, ")"); - } - return (1); -} - -/* Like demangle_args, but for demangling the argument lists of function - and method pointers or references, not top-level declarations. */ - -static int -demangle_nested_args (work, mangled, declp) - struct work_stuff *work; - const char **mangled; - string *declp; -{ - string* saved_previous_argument; - int result; - int saved_nrepeats; - - /* The G++ name-mangling algorithm does not remember types on nested - argument lists, unless -fsquangling is used, and in that case the - type vector updated by remember_type is not used. So, we turn - off remembering of types here. */ - ++work->forgetting_types; - - /* For the repeat codes used with -fsquangling, we must keep track of - the last argument. */ - saved_previous_argument = work->previous_argument; - saved_nrepeats = work->nrepeats; - work->previous_argument = 0; - work->nrepeats = 0; - - /* Actually demangle the arguments. */ - result = demangle_args (work, mangled, declp); - - /* Restore the previous_argument field. */ - if (work->previous_argument) - string_delete (work->previous_argument); - work->previous_argument = saved_previous_argument; - --work->forgetting_types; - work->nrepeats = saved_nrepeats; - - return result; -} - -static void -demangle_function_name (work, mangled, declp, scan) - struct work_stuff *work; - const char **mangled; - string *declp; - const char *scan; -{ - size_t i; - string type; - const char *tem; - - string_appendn (declp, (*mangled), scan - (*mangled)); - string_need (declp, 1); - *(declp -> p) = '\0'; - - /* Consume the function name, including the "__" separating the name - from the signature. We are guaranteed that SCAN points to the - separator. */ - - (*mangled) = scan + 2; - /* We may be looking at an instantiation of a template function: - foo__Xt1t2_Ft3t4, where t1, t2, ... are template arguments and a - following _F marks the start of the function arguments. Handle - the template arguments first. */ - - if (HP_DEMANGLING && (**mangled == 'X')) - { - demangle_arm_hp_template (work, mangled, 0, declp); - /* This leaves MANGLED pointing to the 'F' marking func args */ - } - - if (LUCID_DEMANGLING || ARM_DEMANGLING || HP_DEMANGLING || EDG_DEMANGLING) - { - - /* See if we have an ARM style constructor or destructor operator. - If so, then just record it, clear the decl, and return. - We can't build the actual constructor/destructor decl until later, - when we recover the class name from the signature. */ - - if (strcmp (declp -> b, "__ct") == 0) - { - work -> constructor += 1; - string_clear (declp); - return; - } - else if (strcmp (declp -> b, "__dt") == 0) - { - work -> destructor += 1; - string_clear (declp); - return; - } - } - - if (declp->p - declp->b >= 3 - && declp->b[0] == 'o' - && declp->b[1] == 'p' - && strchr (cplus_markers, declp->b[2]) != NULL) - { - /* see if it's an assignment expression */ - if (declp->p - declp->b >= 10 /* op$assign_ */ - && memcmp (declp->b + 3, "assign_", 7) == 0) - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - int len = declp->p - declp->b - 10; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 10, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - string_append (declp, "="); - break; - } - } - } - else - { - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - int len = declp->p - declp->b - 3; - if ((int) strlen (optable[i].in) == len - && memcmp (optable[i].in, declp->b + 3, len) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - else if (declp->p - declp->b >= 5 && memcmp (declp->b, "type", 4) == 0 - && strchr (cplus_markers, declp->b[4]) != NULL) - { - /* type conversion operator */ - tem = declp->b + 5; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] == 'o' && declp->b[3] == 'p') - { - /* ANSI. */ - /* type conversion operator. */ - tem = declp->b + 4; - if (do_type (work, &tem, &type)) - { - string_clear (declp); - string_append (declp, "operator "); - string_appends (declp, &type); - string_delete (&type); - } - } - else if (declp->b[0] == '_' && declp->b[1] == '_' - && declp->b[2] >= 'a' && declp->b[2] <= 'z' - && declp->b[3] >= 'a' && declp->b[3] <= 'z') - { - if (declp->b[4] == '\0') - { - /* Operator. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 2 - && memcmp (optable[i].in, declp->b + 2, 2) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - else - { - if (declp->b[2] == 'a' && declp->b[5] == '\0') - { - /* Assignment. */ - for (i = 0; i < sizeof (optable) / sizeof (optable[0]); i++) - { - if (strlen (optable[i].in) == 3 - && memcmp (optable[i].in, declp->b + 2, 3) == 0) - { - string_clear (declp); - string_append (declp, "operator"); - string_append (declp, optable[i].out); - break; - } - } - } - } - } -} - -/* a mini string-handling package */ - -static void -string_need (s, n) - string *s; - int n; -{ - int tem; - - if (s->b == NULL) - { - if (n < 32) - { - n = 32; - } - s->p = s->b = xmalloc (n); - s->e = s->b + n; - } - else if (s->e - s->p < n) - { - tem = s->p - s->b; - n += tem; - n *= 2; - s->b = xrealloc (s->b, n); - s->p = s->b + tem; - s->e = s->b + n; - } -} - -static void -string_delete (s) - string *s; -{ - if (s->b != NULL) - { - free (s->b); - s->b = s->e = s->p = NULL; - } -} - -static void -string_init (s) - string *s; -{ - s->b = s->p = s->e = NULL; -} - -static void -string_clear (s) - string *s; -{ - s->p = s->b; -} - -#if 0 - -static int -string_empty (s) - string *s; -{ - return (s->b == s->p); -} - -#endif - -static void -string_append (p, s) - string *p; - const char *s; -{ - int n; - if (s == NULL || *s == '\0') - return; - n = strlen (s); - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; -} - -static void -string_appends (p, s) - string *p, *s; -{ - int n; - - if (s->b != s->p) - { - n = s->p - s->b; - string_need (p, n); - memcpy (p->p, s->b, n); - p->p += n; - } -} - -static void -string_appendn (p, s, n) - string *p; - const char *s; - int n; -{ - if (n != 0) - { - string_need (p, n); - memcpy (p->p, s, n); - p->p += n; - } -} - -static void -string_prepend (p, s) - string *p; - const char *s; -{ - if (s != NULL && *s != '\0') - { - string_prependn (p, s, strlen (s)); - } -} - -static void -string_prepends (p, s) - string *p, *s; -{ - if (s->b != s->p) - { - string_prependn (p, s->b, s->p - s->b); - } -} - -static void -string_prependn (p, s, n) - string *p; - const char *s; - int n; -{ - char *q; - - if (n != 0) - { - string_need (p, n); - for (q = p->p - 1; q >= p->b; q--) - { - q[n] = q[0]; - } - memcpy (p->b, s, n); - p->p += n; - } -} - -/* To generate a standalone demangler program for testing purposes, - just compile and link this file with -DMAIN and libiberty.a. When - run, it demangles each command line arg, or each stdin string, and - prints the result on stdout. */ - -#ifdef MAIN - -#include "getopt.h" - -static char *program_name; -static char *program_version = VERSION; -static int flags = DMGL_PARAMS | DMGL_ANSI; - -static void demangle_it PARAMS ((char *)); -static void usage PARAMS ((FILE *, int)); -static void fatal PARAMS ((char *)); - -static void -demangle_it (mangled_name) - char *mangled_name; -{ - char *result; - - result = cplus_demangle (mangled_name, flags); - if (result == NULL) - { - printf ("%s\n", mangled_name); - } - else - { - printf ("%s\n", result); - free (result); - } -} - -static void -usage (stream, status) - FILE *stream; - int status; -{ - fprintf (stream, "\ -Usage: %s [-_] [-n] [-s {gnu,lucid,arm,hp,edg}] [--strip-underscores]\n\ - [--no-strip-underscores] [--format={gnu,lucid,arm,hp,edg}]\n\ - [--help] [--version] [arg...]\n", - program_name); - exit (status); -} - -#define MBUF_SIZE 32767 -char mbuffer[MBUF_SIZE]; - -/* Defined in the automatically-generated underscore.c. */ -extern int prepends_underscore; - -int strip_underscore = 0; - -static struct option long_options[] = { - {"strip-underscores", no_argument, 0, '_'}, - {"format", required_argument, 0, 's'}, - {"help", no_argument, 0, 'h'}, - {"no-strip-underscores", no_argument, 0, 'n'}, - {"version", no_argument, 0, 'v'}, - {0, no_argument, 0, 0} -}; - -/* 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."); -} - -int -main (argc, argv) - int argc; - char **argv; -{ - char *result; - int c; - - program_name = argv[0]; - - strip_underscore = prepends_underscore; - - while ((c = getopt_long (argc, argv, "_ns:j", long_options, (int *) 0)) != EOF) - { - switch (c) - { - case '?': - usage (stderr, 1); - break; - case 'h': - usage (stdout, 0); - case 'n': - strip_underscore = 0; - break; - case 'v': - printf ("GNU %s (C++ demangler), version %s\n", program_name, program_version); - exit (0); - case '_': - strip_underscore = 1; - break; - case 's': - if (strcmp (optarg, "gnu") == 0) - { - current_demangling_style = gnu_demangling; - } - else if (strcmp (optarg, "lucid") == 0) - { - current_demangling_style = lucid_demangling; - } - else if (strcmp (optarg, "arm") == 0) - { - current_demangling_style = arm_demangling; - } - else if (strcmp (optarg, "hp") == 0) - { - current_demangling_style = hp_demangling; - } - else if (strcmp (optarg, "edg") == 0) - { - current_demangling_style = edg_demangling; - } - else - { - fprintf (stderr, "%s: unknown demangling style `%s'\n", - program_name, optarg); - exit (1); - } - break; - } - } - - if (optind < argc) - { - for ( ; optind < argc; optind++) - { - demangle_it (argv[optind]); - } - } - else - { - for (;;) - { - int i = 0; - c = getchar (); - /* Try to read a label. */ - while (c != EOF && (isalnum(c) || c == '_' || c == '$' || c == '.' || - c == '<' || c == '>' || c == '#' || c == ',' || c == '*' || c == '&' || - c == '[' || c == ']' || c == ':' || c == '(' || c == ')')) - /* the ones in the 2nd & 3rd lines were added to handle - HP aCC template specialization manglings */ - { - if (i >= MBUF_SIZE-1) - break; - mbuffer[i++] = c; - c = getchar (); - } - if (i > 0) - { - int skip_first = 0; - - if (mbuffer[0] == '.') - ++skip_first; - if (strip_underscore && mbuffer[skip_first] == '_') - ++skip_first; - - if (skip_first > i) - skip_first = i; - - mbuffer[i] = 0; - - result = cplus_demangle (mbuffer + skip_first, flags); - if (result) - { - if (mbuffer[0] == '.') - putc ('.', stdout); - fputs (result, stdout); - free (result); - } - else - fputs (mbuffer, stdout); - - fflush (stdout); - } - if (c == EOF) - break; - putchar (c); - } - } - - exit (0); -} - -static void -fatal (str) - char *str; -{ - fprintf (stderr, "%s: %s\n", program_name, str); - exit (1); -} - -PTR -xmalloc (size) - size_t size; -{ - register PTR value = (PTR) malloc (size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} - -PTR -xrealloc (ptr, size) - PTR ptr; - size_t size; -{ - register PTR value = (PTR) realloc (ptr, size); - if (value == 0) - fatal ("virtual memory exhausted"); - return value; -} -#endif /* main */ |